rabbitmq-server/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/plugins_helpers.ex

242 lines
6.4 KiB
Elixir
Raw Normal View History

## The contents of this file are subject to the Mozilla Public License
## Version 1.1 (the "License"); you may not use this file except in
## compliance with the License. You may obtain a copy of the License
URL Cleanup This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener). # HTTP URLs that Could Not Be Fixed These URLs were unable to be fixed. Please review them to see if they can be manually resolved. * http://blog.listincomprehension.com/search/label/procket (200) with 1 occurrences could not be migrated: ([https](https://blog.listincomprehension.com/search/label/procket) result ClosedChannelException). * http://dozzie.jarowit.net/trac/wiki/TOML (200) with 1 occurrences could not be migrated: ([https](https://dozzie.jarowit.net/trac/wiki/TOML) result SSLHandshakeException). * http://dozzie.jarowit.net/trac/wiki/subproc (200) with 1 occurrences could not be migrated: ([https](https://dozzie.jarowit.net/trac/wiki/subproc) result SSLHandshakeException). * http://e2project.org (200) with 1 occurrences could not be migrated: ([https](https://e2project.org) result AnnotatedConnectException). * http://erlang.org/doc/reference_manual/distributed.html (200) with 1 occurrences could not be migrated: ([https](https://erlang.org/doc/reference_manual/distributed.html) result ConnectTimeoutException). * http://nitrogenproject.com/ (200) with 2 occurrences could not be migrated: ([https](https://nitrogenproject.com/) result ConnectTimeoutException). * http://proper.softlab.ntua.gr (200) with 1 occurrences could not be migrated: ([https](https://proper.softlab.ntua.gr) result SSLHandshakeException). * http://yaws.hyber.org (200) with 1 occurrences could not be migrated: ([https](https://yaws.hyber.org) result AnnotatedConnectException). * http://choven.ca (503) with 1 occurrences could not be migrated: ([https](https://choven.ca) result ConnectTimeoutException). # Fixed URLs ## Fixed But Review Recommended These URLs were fixed, but the https status was not OK. However, the https status was the same as the http request or http redirected to an https URL, so they were migrated. Your review is recommended. * http://fixprotocol.org/ (301) with 1 occurrences migrated to: https://fixtrading.org ([https](https://fixprotocol.org/) result SSLHandshakeException). * http://erldb.org (UnknownHostException) with 1 occurrences migrated to: https://erldb.org ([https](https://erldb.org) result UnknownHostException). * http://elixir-lang.org/docs/stable/elixir/OptionParser.html (301) with 1 occurrences migrated to: https://elixir-lang.org/docs/stable/elixir/OptionParser.html ([https](https://elixir-lang.org/docs/stable/elixir/OptionParser.html) result 404). * http://elixir-lang.org/docs/stable/elixir/Stream.html (301) with 1 occurrences migrated to: https://elixir-lang.org/docs/stable/elixir/Stream.html ([https](https://elixir-lang.org/docs/stable/elixir/Stream.html) result 404). ## Fixed Success These URLs were switched to an https URL with a 2xx status. While the status was successful, your review is still recommended. * http://cloudi.org/ with 27 occurrences migrated to: https://cloudi.org/ ([https](https://cloudi.org/) result 200). * http://elixir-lang.org with 1 occurrences migrated to: https://elixir-lang.org ([https](https://elixir-lang.org) result 200). * http://elixir-lang.org/ with 2 occurrences migrated to: https://elixir-lang.org/ ([https](https://elixir-lang.org/) result 200). * http://elixir-lang.org/getting-started/typespecs-and-behaviours.html with 1 occurrences migrated to: https://elixir-lang.org/getting-started/typespecs-and-behaviours.html ([https](https://elixir-lang.org/getting-started/typespecs-and-behaviours.html) result 200). * http://elixir-lang.org/install.html with 1 occurrences migrated to: https://elixir-lang.org/install.html ([https](https://elixir-lang.org/install.html) result 200). * http://erlware.org/ with 1 occurrences migrated to: https://erlware.org/ ([https](https://erlware.org/) result 200). * http://inaka.github.io/cowboy-trails/ with 1 occurrences migrated to: https://inaka.github.io/cowboy-trails/ ([https](https://inaka.github.io/cowboy-trails/) result 200). * http://ninenines.eu with 6 occurrences migrated to: https://ninenines.eu ([https](https://ninenines.eu) result 200). * http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html with 1 occurrences migrated to: https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html ([https](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) result 200). * http://www.actordb.com/ with 2 occurrences migrated to: https://www.actordb.com/ ([https](https://www.actordb.com/) result 200). * http://www.cs.kent.ac.uk/projects/wrangler/Home.html with 1 occurrences migrated to: https://www.cs.kent.ac.uk/projects/wrangler/Home.html ([https](https://www.cs.kent.ac.uk/projects/wrangler/Home.html) result 200). * http://www.rebar3.org with 1 occurrences migrated to: https://www.rebar3.org ([https](https://www.rebar3.org) result 200). * http://contributor-covenant.org with 1 occurrences migrated to: https://contributor-covenant.org ([https](https://contributor-covenant.org) result 301). * http://contributor-covenant.org/version/1/3/0/ with 1 occurrences migrated to: https://contributor-covenant.org/version/1/3/0/ ([https](https://contributor-covenant.org/version/1/3/0/) result 301). * http://inaka.github.com/apns4erl with 1 occurrences migrated to: https://inaka.github.com/apns4erl ([https](https://inaka.github.com/apns4erl) result 301). * http://inaka.github.com/edis/ with 1 occurrences migrated to: https://inaka.github.com/edis/ ([https](https://inaka.github.com/edis/) result 301). * http://lasp-lang.org/ with 1 occurrences migrated to: https://lasp-lang.org/ ([https](https://lasp-lang.org/) result 301). * http://rabbitmq.com/documentation.html with 1 occurrences migrated to: https://rabbitmq.com/documentation.html ([https](https://rabbitmq.com/documentation.html) result 301). * http://saleyn.github.com/erlexec with 1 occurrences migrated to: https://saleyn.github.com/erlexec ([https](https://saleyn.github.com/erlexec) result 301). * http://www.mozilla.org/MPL/ with 290 occurrences migrated to: https://www.mozilla.org/MPL/ ([https](https://www.mozilla.org/MPL/) result 301). * http://zhongwencool.github.io/observer_cli with 1 occurrences migrated to: https://zhongwencool.github.io/observer_cli ([https](https://zhongwencool.github.io/observer_cli) result 301).
2019-03-20 16:13:07 +08:00
## at https://www.mozilla.org/MPL/
##
## Software distributed under the License is distributed on an "AS IS"
## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
## the License for the specific language governing rights and
## limitations under the License.
##
## The Original Code is RabbitMQ.
##
## The Initial Developer of the Original Code is GoPivotal, Inc.
2020-03-10 22:39:56 +08:00
## Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved.
defmodule RabbitMQ.CLI.Plugins.Helpers do
2016-11-15 01:52:08 +08:00
import Rabbitmq.Atom.Coerce
2016-06-22 22:32:49 +08:00
import RabbitCommon.Records
import RabbitMQ.CLI.Core.Platform, only: [path_separator: 0]
import RabbitMQ.CLI.Core.{CodePath, Paths}
alias RabbitMQ.CLI.Core.{Config, Validators}
2016-06-22 22:32:49 +08:00
def mode(opts) do
%{online: online, offline: offline} = opts
2019-01-31 03:20:29 +08:00
case {online, offline} do
2019-01-31 03:20:29 +08:00
{true, false} -> :online
{false, true} -> :offline
{false, false} -> :best_effort
end
end
def can_set_plugins_with_mode(args, opts) do
case mode(opts) do
2017-11-28 04:39:14 +08:00
# can always set offline plugins list
2019-01-31 03:20:29 +08:00
:offline ->
:ok
2017-11-28 04:39:14 +08:00
# assume online mode, fall back to offline mode in case of errors
2019-01-31 03:20:29 +08:00
:best_effort ->
:ok
2017-11-28 04:39:14 +08:00
# a running node is required
:online ->
2019-01-31 03:20:29 +08:00
Validators.chain(
[&Validators.node_is_running/2, &Validators.rabbit_is_running/2],
[args, opts]
)
end
end
def list(opts) do
{:ok, dir} = plugins_dir(opts)
add_all_to_path(dir)
2017-06-26 18:59:46 +08:00
:lists.usort(:rabbit_plugins.list(to_charlist(dir)))
end
def list_names(opts) do
list(opts) |> plugin_names
end
def read_enabled(opts) do
case enabled_plugins_file(opts) do
{:ok, enabled} ->
2019-01-31 03:20:29 +08:00
:rabbit_plugins.read_enabled(to_charlist(enabled))
# Existence of enabled_plugins_file should be validated separately
{:error, :no_plugins_file} ->
[]
end
end
def enabled_plugins_file(opts) do
case Config.get_option(:enabled_plugins_file, opts) do
2019-01-31 03:20:29 +08:00
nil -> {:error, :no_plugins_file}
2016-10-26 23:25:39 +08:00
file -> {:ok, file}
end
end
def enabled_plugins_file(_, opts) do
enabled_plugins_file(opts)
end
def set_enabled_plugins(plugins, opts) do
plugin_atoms = :lists.usort(for plugin <- plugins, do: to_atom(plugin))
require_rabbit_and_plugins(opts)
2016-06-21 20:54:18 +08:00
{:ok, plugins_file} = enabled_plugins_file(opts)
write_enabled_plugins(plugin_atoms, plugins_file, opts)
end
2016-12-07 00:18:54 +08:00
2019-01-31 03:20:29 +08:00
@spec update_enabled_plugins(
[atom()],
:online | :offline | :best_effort,
node(),
map()
) :: map() | {:error, any()}
def update_enabled_plugins(enabled_plugins, mode, node_name, opts) do
{:ok, plugins_file} = enabled_plugins_file(opts)
2019-01-31 03:20:29 +08:00
case mode do
:online ->
case update_enabled_plugins(node_name, plugins_file) do
{:ok, started, stopped} ->
2019-01-31 03:20:29 +08:00
%{
mode: :online,
started: Enum.sort(started),
stopped: Enum.sort(stopped),
2019-01-31 03:20:29 +08:00
set: Enum.sort(enabled_plugins)
}
{:error, _} = err ->
err
end
:best_effort ->
case update_enabled_plugins(node_name, plugins_file) do
{:ok, started, stopped} ->
2019-01-31 03:20:29 +08:00
%{
mode: :online,
started: Enum.sort(started),
stopped: Enum.sort(stopped),
2019-01-31 03:20:29 +08:00
set: Enum.sort(enabled_plugins)
}
{:error, :offline} ->
2019-01-31 03:20:29 +08:00
%{mode: :offline, set: Enum.sort(enabled_plugins)}
{:error, {:enabled_plugins_mismatch, _, _}} = err ->
err
2019-01-31 03:20:29 +08:00
end
:offline ->
2019-01-31 03:20:29 +08:00
%{mode: :offline, set: Enum.sort(enabled_plugins)}
2016-06-21 20:54:18 +08:00
end
end
2016-12-07 00:18:54 +08:00
def validate_plugins(requested_plugins, opts) do
## Maybe check all plugins
2019-01-31 03:20:29 +08:00
plugins =
case opts do
%{all: true} -> plugin_names(list(opts))
_ -> requested_plugins
end
all = list(opts)
deps = :rabbit_plugins.dependencies(false, plugins, all)
2019-01-31 03:20:29 +08:00
deps_plugins =
Enum.filter(all, fn plugin ->
name = plugin_name(plugin)
Enum.member?(deps, name)
end)
case :rabbit_plugins.validate_plugins(deps_plugins) do
2019-01-31 03:20:29 +08:00
{_, []} -> :ok
{_, invalid} -> {:error, :rabbit_plugins.format_invalid_plugins(invalid)}
end
end
def plugin_name(plugin) when is_binary(plugin) do
plugin
end
def plugin_name(plugin) when is_atom(plugin) do
Atom.to_string(plugin)
end
def plugin_name(plugin) do
plugin(name: name) = plugin
name
end
def plugin_names(plugins) do
for plugin <- plugins, do: plugin_name(plugin)
end
def comma_separated_names(plugins) do
Enum.join(plugin_names(plugins), ", ")
end
#
# Implementation
#
defp to_list(str) when is_binary(str) do
:erlang.binary_to_list(str)
end
defp to_list(lst) when is_list(lst) do
lst
end
defp to_list(atm) when is_atom(atm) do
to_list(Atom.to_string(atm))
end
2016-06-21 20:54:18 +08:00
defp write_enabled_plugins(plugins, plugins_file, opts) do
2019-01-31 03:20:29 +08:00
all = list(opts)
all_plugin_names = Enum.map(all, &plugin_name/1)
missing = MapSet.difference(MapSet.new(plugins), MapSet.new(all_plugin_names))
2019-01-31 03:20:29 +08:00
case Enum.empty?(missing) do
true ->
2017-06-26 18:59:46 +08:00
case :rabbit_file.write_term_file(to_charlist(plugins_file), [plugins]) do
2016-06-21 20:54:18 +08:00
:ok ->
all_enabled = :rabbit_plugins.dependencies(false, plugins, all)
2019-01-31 03:20:29 +08:00
{:ok, Enum.sort(all_enabled)}
2016-06-21 20:54:18 +08:00
{:error, reason} ->
{:error, {:cannot_write_enabled_plugins_file, plugins_file, reason}}
2019-01-31 03:20:29 +08:00
end
false ->
{:error, {:plugins_not_found, Enum.to_list(missing)}}
2016-06-21 20:54:18 +08:00
end
end
defp update_enabled_plugins(node_name, plugins_file) do
2019-01-31 03:20:29 +08:00
case :rabbit_misc.rpc_call(node_name, :rabbit_plugins, :ensure, [to_list(plugins_file)]) do
{:badrpc, :nodedown} -> {:error, :offline}
{:error, :rabbit_not_running} -> {:error, :offline}
{:ok, start, stop} -> {:ok, start, stop}
{:error, _} = err -> err
2016-06-21 20:54:18 +08:00
end
end
defp add_all_to_path(plugins_directories) do
directories = String.split(to_string(plugins_directories), path_separator())
2019-01-31 03:20:29 +08:00
Enum.map(directories, fn directory ->
with {:ok, subdirs} <- File.ls(directory) do
for subdir <- subdirs do
Path.join([directory, subdir, "ebin"])
|> Code.append_path()
end
2019-01-31 03:20:29 +08:00
end
end)
2019-01-31 03:20:29 +08:00
:ok
end
end