Merge branch 'master' into rabbitmq-cli-118

This commit is contained in:
Arnaud Cogoluègnes 2016-11-22 16:51:27 +01:00
commit 887a09644b
83 changed files with 146 additions and 212 deletions

View File

@ -3,6 +3,7 @@
/deps
/escript
/.erlang.mk/
/ebin
erl_crash.dump
mix.lock
*.ez

View File

@ -1,11 +1,7 @@
PROJECT = rabbitmq_cli
VERSION ?= 0.0.1
BUILD_DEPS = rabbit_common amqp_client amqp json csv
dep_amqp = git https://github.com/pma/amqp.git master
dep_json = hex 1.0.0
dep_csv = hex 1.4.4
BUILD_DEPS = rabbit_common amqp_client
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk
@ -35,7 +31,15 @@ app:: $(ESCRIPTS)
rabbitmqctl_srcs := mix.exs \
$(shell find config lib -name "*.ex" -o -name "*.exs")
escript/rabbitmqctl: $(rabbitmqctl_srcs)
ebin: $(rabbitmqctl_srcs)
mix deps.get
mix deps.compile
rm -rf ebin
mix compile
mkdir -p ebin
cp -r _build/dev/lib/rabbitmqctl/ebin/* ebin
escript/rabbitmqctl: ebin
mix escript.build
escript/rabbitmq-plugins escript/rabbitmq-diagnostics: escript/rabbitmqctl
@ -53,6 +57,7 @@ test:: all
clean::
rm -f $(ESCRIPTS)
- mix local.hex --force
rm -rf ebin
mix clean
repl:

View File

@ -15,7 +15,6 @@
defmodule Rabbitmq.CLI.AutoComplete do
alias RabbitMQ.CLI.Core.Helpers, as: Helpers
alias RabbitMQ.CLI.Core.Parser, as: Parser
alias RabbitMQ.CLI.Core.CommandModules, as: CommandModules
@ -50,7 +49,7 @@ defmodule Rabbitmq.CLI.AutoComplete do
end
def complete_command_opts(cmd, opt) do
commands = Helpers.commands
commands = CommandModules.module_map
case commands[cmd] do
nil ->
commands

View File

@ -16,7 +16,6 @@
defmodule RabbitMQ.CLI.CommandBehaviour do
@callback usage() :: String.t | [String.t]
@callback flags() :: [Atom.t]
@callback validate(List.t, Map.t) :: :ok | {:validation_failure, Atom.t | {Atom.t, String.t}}
@callback merge_defaults(List.t, Map.t) :: {List.t, Map.t}
@callback banner(List.t, Map.t) :: String.t

View File

@ -24,6 +24,9 @@ defmodule RabbitMQ.CLI.Core.CommandModules do
Application.get_env(:rabbitmqctl, :commands) || load(%{})
end
def is_command?([head | _]), do: is_command?(head)
def is_command?(str), do: module_map[str] != nil
def load(opts) do
scope = script_scope(opts)
commands = load_commands(scope, opts)
@ -51,7 +54,7 @@ defmodule RabbitMQ.CLI.Core.CommandModules do
|> Map.new
end
defp ctl_and_plugin_modules(opts) do
def ctl_and_plugin_modules(opts) do
Helpers.require_rabbit(opts)
enabled_plugins = PluginsHelpers.read_enabled(opts)
[:rabbitmqctl | enabled_plugins]

View File

@ -22,6 +22,9 @@ defmodule RabbitMQ.CLI.Core.Config do
normalize(name, raw_option)
end
def normalize(:node, node) when not is_atom(node) do
Rabbitmq.Atom.Coerce.to_atom(node)
end
def normalize(:longnames, true), do: :longnames
def normalize(:longnames, "true"), do: :longnames
def normalize(:longnames, 'true'), do: :longnames
@ -40,13 +43,13 @@ defmodule RabbitMQ.CLI.Core.Config do
:mnesia_dir -> "RABBITMQ_MNESIA_DIR";
:plugins_dir -> "RABBITMQ_PLUGINS_DIR";
:enabled_plugins_file -> "RABBITMQ_ENABLED_PLUGINS_FILE";
:nodename -> "RABBITMQ_NODENAME";
:node -> "RABBITMQ_NODENAME";
_ -> ""
end
System.get_env(system_env_option)
end
def default(:script_name), do: :rabbitmqctl
def default(:nodename), do: "rabbit"
def default(:node), do: :rabbit
def default(_), do: nil
end

View File

@ -16,37 +16,22 @@
# Small helper functions, mostly related to connecting to RabbitMQ and
# handling memory units.
alias RabbitMQ.CLI.Core.CommandModules, as: CommandModules
alias RabbitMQ.CLI.Core.Config, as: Config
defmodule RabbitMQ.CLI.Core.Helpers do
## module_map will use rabbitmqctl application environment
## to load enabled commands
def commands do
CommandModules.module_map
end
def is_command?([head | _]), do: is_command?(head)
def is_command?(str), do: commands[str] != nil
def get_rabbit_hostname() do
node_parts = RabbitMQ.CLI.Core.Config.get_option(:nodename)
|> String.split("@", [parts: 2])
name = node_parts |> Enum.at(0)
host = node_parts |> Enum.at(1) || hostname()
(name <> "@" <> host) |> String.to_atom
parse_node(RabbitMQ.CLI.Core.Config.get_option(:node))
end
def parse_node(nil), do: get_rabbit_hostname
def parse_node(host) when is_atom(host) do
parse_node(to_string(host))
def parse_node(name) when is_atom(name) do
parse_node(to_string(name))
end
def parse_node(host) do
case String.split(host, "@", parts: 2) do
[_,""] -> host <> "#{hostname}" |> String.to_atom
[_,_] -> host |> String.to_atom
[_] -> host <> "@#{hostname}" |> String.to_atom
def parse_node(name) do
case String.split(name, "@", parts: 2) do
[_,""] -> name <> "#{hostname}" |> String.to_atom
[_,_] -> name |> String.to_atom
[_] -> name <> "@#{hostname}" |> String.to_atom
end
end
@ -58,7 +43,7 @@ defmodule RabbitMQ.CLI.Core.Helpers do
|> :net_kernel.connect_node
end
defp hostname, do: :inet.gethostname() |> elem(1) |> List.to_string
def hostname, do: :inet.gethostname() |> elem(1) |> List.to_string
def memory_units do
["k", "kiB", "M", "MiB", "G", "GiB", "kB", "MB", "GB", ""]
@ -81,7 +66,9 @@ defmodule RabbitMQ.CLI.Core.Helpers do
def power_as_int(num, x, y), do: round(num * (:math.pow(x, y)))
def global_flags, do: [:node, :quiet, :timeout, :longnames, :formatter, :printer, :file]
def global_flags() do
RabbitMQ.CLI.Core.Parser.default_switches |> Keyword.keys
end
def nodes_in_cluster(node, timeout \\ :infinity) do
case :rpc.call(node, :rabbit_mnesia, :cluster_nodes, [:running], timeout) do

View File

@ -34,6 +34,7 @@ defmodule RabbitMQ.CLI.Core.Parser do
def default_switches() do
[node: :atom,
quiet: :boolean,
dry_run: :boolean,
timeout: :integer,
vhost: :string,
longnames: :boolean,
@ -44,13 +45,12 @@ defmodule RabbitMQ.CLI.Core.Parser do
rabbitmq_home: :string,
mnesia_dir: :string,
plugins_dir: :string,
enabled_plugins_file: :string,
nodename: :string
enabled_plugins_file: :string
]
end
defp build_switches(default) do
Enum.reduce(RabbitMQ.CLI.Core.Helpers.commands,
Enum.reduce(RabbitMQ.CLI.Core.CommandModules.module_map,
default,
fn({_, _}, {:error, _} = err) -> err;
({_, command}, switches) ->
@ -69,7 +69,7 @@ defmodule RabbitMQ.CLI.Core.Parser do
end
defp build_aliases(default) do
Enum.reduce(RabbitMQ.CLI.Core.Helpers.commands,
Enum.reduce(RabbitMQ.CLI.Core.CommandModules.module_map,
default,
fn({_, _}, {:error, _} = err) -> err;
({_, command}, aliases) ->

View File

@ -50,5 +50,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AddUserCommand do
def banner([username, _password], _), do: "Adding user \"#{username}\" ..."
def flags, do: @flags
end

View File

@ -35,5 +35,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AddVhostCommand do
def banner([vhost], _), do: "Adding vhost \"#{vhost}\" ..."
def flags, do: @flags
end

View File

@ -37,7 +37,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AuthenticateUserCommand do
def banner([username, _password], _), do: "Authenticating user \"#{username}\" ..."
def flags, do: @flags
def output({:refused, user, msg, args}, _) do
{:error, RabbitMQ.CLI.Core.ExitCodes.exit_dataerr,

View File

@ -21,7 +21,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.CancelSyncQueueCommand do
{args, Map.merge(default_opts, opts)}
end
def flags, do: [:vhost]
def switches, do: []
def aliases, do: []

View File

@ -17,7 +17,6 @@
defmodule RabbitMQ.CLI.Ctl.Commands.ChangeClusterNodeTypeCommand do
@behaviour RabbitMQ.CLI.CommandBehaviour
def flags, do: []
def switches(), do: []
def aliases(), do: []

View File

@ -37,5 +37,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ChangePasswordCommand do
def banner([user| _], _), do: "Changing password for user \"#{user}\" ..."
def flags, do: @flags
end

View File

@ -41,7 +41,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClearOperatorPolicyCommand do
def usage, do: "clear_operator_policy [-p <vhost>] <key>"
def flags, do: @flags
def banner([key], %{vhost: vhost}) do
"Clearing operator policy \"#{key}\" on vhost \"#{vhost}\" ..."

View File

@ -42,7 +42,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClearParameterCommand do
def usage, do: "clear_parameter [-p <vhost>] <component_name> <key>"
def flags, do: @flags
def banner([component_name, key], %{vhost: vhost}) do
"Clearing runtime parameter \"#{key}\" for component \"#{component_name}\" on vhost \"#{vhost}\" ..."

View File

@ -34,5 +34,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClearPasswordCommand do
def banner([user], _), do: "Clearing password for user \"#{user}\" ..."
def flags, do: @flags
end

View File

@ -43,5 +43,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClearPermissionsCommand do
def banner([username], %{vhost: vhost}), do: "Clearing permissions for user \"#{username}\" in vhost \"#{vhost}\" ..."
def flags, do: @flags
end

View File

@ -41,7 +41,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClearPolicyCommand do
def usage, do: "clear_policy [-p <vhost>] <key>"
def flags, do: @flags
def banner([key], %{vhost: vhost}) do
"Clearing policy \"#{key}\" on vhost \"#{vhost}\" ..."

View File

@ -43,7 +43,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClearVhostLimitsCommand do
def usage, do: "clear_vhost_limits [-p <vhost>]"
def flags, do: [:vhost]
def banner([], %{vhost: vhost}) do
"Clearing vhost \"#{vhost}\" limits ..."

View File

@ -35,7 +35,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.CloseConnectionCommand do
def usage, do: "close_connection <connectionpid> <explanation>"
def flags, do: @flags
def banner([pid, explanation], _), do: "Closing connection #{pid}, reason: #{explanation}..."
end

View File

@ -41,7 +41,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClusterStatusCommand do
def usage, do: "cluster_status"
def flags, do: @flags
defp alarms_by_node(node) do
alarms = :rabbit_misc.rpc_call(node, :rabbit, :alarms, [])

View File

@ -37,5 +37,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DeleteUserCommand do
def banner([arg], _), do: "Deleting user \"#{arg}\" ..."
def flags, do: @flags
end

View File

@ -33,6 +33,5 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DeleteVhostCommand do
def banner([arg], _), do: "Deleting vhost \"#{arg}\" ..."
def flags, do: @flags
end

View File

@ -33,5 +33,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EnvironmentCommand do
def banner(_, %{node: node_name}), do: "Application environment of node #{node_name} ..."
def flags, do: @flags
end

View File

@ -56,7 +56,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EvalCommand do
def banner(_, _), do: nil
def flags(), do: []
defp parse_expr(expr) do
expr_str = to_char_list(expr)

View File

@ -48,5 +48,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ExecCommand do
def banner(_, _), do: nil
def flags(), do: []
end

View File

@ -53,5 +53,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ForceBootCommand do
def banner(_, _), do: nil
def flags(), do: []
end

View File

@ -31,7 +31,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ForceResetCommand do
def usage, do: "force_reset"
def flags, do: @flags
def banner(_, %{node: node_name}), do: "Forcefully resetting node #{node_name} ..."

View File

@ -22,7 +22,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ForgetClusterNodeCommand do
@behaviour RabbitMQ.CLI.CommandBehaviour
use RabbitMQ.CLI.DefaultOutput
def flags, do: [:offline]
def switches(), do: [offline: :boolean]
def aliases(), do: []

View File

@ -16,7 +16,7 @@
defmodule RabbitMQ.CLI.Ctl.Commands.HelpCommand do
alias RabbitMQ.CLI.Core.Helpers, as: Helpers
alias RabbitMQ.CLI.Core.CommandModules, as: CommandModules
alias RabbitMQ.CLI.Core.ExitCodes, as: ExitCodes
@behaviour RabbitMQ.CLI.CommandBehaviour
@ -31,9 +31,9 @@ defmodule RabbitMQ.CLI.Ctl.Commands.HelpCommand do
def scopes(), do: [:ctl, :diagnostics, :plugins]
def run([command_name], _) do
case Helpers.is_command?(command_name) do
case CommandModules.is_command?(command_name) do
true ->
command = Helpers.commands[command_name]
command = CommandModules.module_map[command_name]
Enum.join([base_usage(program_name(), command)] ++
options_usage ++
input_types(command), "\n");
@ -128,7 +128,7 @@ to display results. The default value is \"/\".\n"]
["Commands:" |
# Enum.map obtains the usage string for each command module.
# Enum.each prints them all.
Helpers.commands
CommandModules.module_map
|> Map.values
|> Enum.sort
|> Enum.map(&(&1.usage))
@ -145,7 +145,7 @@ to display results. The default value is \"/\".\n"]
end
defp input_types() do
[Helpers.commands
[CommandModules.module_map
|> Map.values
|> Enum.filter_map(
&:erlang.function_exported(&1, :usage_additional, 0),
@ -154,5 +154,4 @@ to display results. The default value is \"/\".\n"]
end
def banner(_,_), do: nil
def flags, do: @flags
end

View File

@ -23,7 +23,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.JoinClusterCommand do
:ram
]
def flags, do: @flags
def switches() do
[
disc: :boolean,

View File

@ -45,9 +45,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListBindingsCommand do
def switches(), do: []
def aliases(), do: []
def flags() do
[:vhost]
end
def usage() do
"list_bindings [-p <vhost>] [<bindinginfoitem> ...]"

View File

@ -46,10 +46,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListChannelsCommand do
def switches(), do: []
def aliases(), do: []
def flags() do
[]
end
def usage() do
"list_channels [<channelinfoitem> ...]"
end

View File

@ -47,10 +47,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListConnectionsCommand do
def switches(), do: []
def aliases(), do: []
def flags() do
[]
end
def usage() do
"list_connections [<connectioninfoitem> ...]"
end

View File

@ -43,9 +43,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListConsumersCommand do
def switches(), do: []
def aliases(), do: []
def flags() do
[:vhost]
end
def usage() do
"list_consumers [-p vhost] [<consumerinfoitem> ...]"

View File

@ -45,9 +45,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListExchangesCommand do
def switches(), do: []
def aliases(), do: []
def flags() do
[:vhost]
end
def usage() do
"list_exchanges [-p <vhost>] [<exchangeinfoitem> ...]"

View File

@ -47,5 +47,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListOperatorPoliciesCommand do
def banner(_, %{vhost: vhost}), do: "Listing operator policy overrides for vhost \"#{vhost}\" ..."
def flags, do: @flags
end

View File

@ -46,5 +46,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListParametersCommand do
def banner(_, %{vhost: vhost}), do: "Listing runtime parameters for vhost \"#{vhost}\" ..."
def flags, do: @flags
end

View File

@ -48,5 +48,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListPermissionsCommand do
def banner(_, %{vhost: vhost}), do: "Listing permissions for vhost \"#{vhost}\" ..."
def flags, do: @flags
end

View File

@ -47,5 +47,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListPoliciesCommand do
def banner(_, %{vhost: vhost}), do: "Listing policies for vhost \"#{vhost}\" ..."
def flags, do: @flags
end

View File

@ -55,10 +55,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListQueuesCommand do
def aliases(), do: []
def flags() do
[:vhost | Keyword.keys(switches())]
end
def usage() do
"list_queues [-p <vhost>] [--online] [--offline] [<queueinfoitem> ...]"
end

View File

@ -43,5 +43,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListUserPermissionsCommand do
def banner([username], _), do: "Listing permissions for user \"#{username}\" ..."
def flags, do: @flags
end

View File

@ -39,5 +39,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListUsersCommand do
def banner(_,_), do: "Listing users ..."
def flags, do: @flags
end

View File

@ -76,5 +76,4 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListVhostsCommand do
def banner(_,_), do: "Listing vhosts ..."
def flags, do: @flags
end

View File

@ -32,10 +32,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.NodeHealthCheckCommand do
{args, Map.merge(opts, %{timeout: timeout})}
end
def flags() do
[:timeout]
end
def switches(), do: [timeout: :integer]
def aliases(), do: []

View File

@ -19,7 +19,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.PurgeQueueCommand do
use RabbitMQ.CLI.DefaultOutput
@flags []
def flags, do: []
def switches, do: []
def aliases, do: []
def usage, do: "purge_queue <queue>"

View File

@ -23,7 +23,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.RenameClusterNodeCommand do
@behaviour RabbitMQ.CLI.CommandBehaviour
use RabbitMQ.CLI.DefaultOutput
def flags, do: [:mnesia_dir, :rabbitmq_home]
def switches(), do: [mnesia_dir: :string, rabbitmq_home: :string]
def aliases(), do: []

View File

@ -71,7 +71,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ReportCommand do
def usage, do: "report"
def flags, do: @flags
def banner(_,%{node: node_name}), do: "Reporting server status of node #{node_name} ..."
end

View File

@ -31,7 +31,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ResetCommand do
def usage, do: "reset"
def flags, do: @flags
def banner(_, %{node: node_name}), do: "Resetting node #{node_name} ..."

View File

@ -32,7 +32,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.RotateLogsCommand do
def usage, do: "rotate_logs"
def flags, do: @flags
def banner(_, %{node: node_name}), do: "Rotating logs for node #{node_name} ..."
end

View File

@ -38,7 +38,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetClusterNameCommand do
"Setting cluster name to #{cluster_name} ..."
end
def flags, do: @flags
def run([cluster_name], %{node: node_name}) do
:rabbit_misc.rpc_call(node_name,

View File

@ -122,7 +122,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetDiskFreeLimitCommand do
def banner([arg], %{node: node_name}), do: "Setting disk free limit on #{node_name} to #{arg} bytes ..."
def flags, do: @flags
def usage, do: "set_disk_free_limit <disk_limit>\nset_disk_free_limit mem_relative <fraction>"
end

View File

@ -48,15 +48,14 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetOperatorPolicyCommand do
:parse_set_op,
[vhost,
name,
to_char_list(pattern),
to_char_list(definition),
to_char_list(priority),
pattern,
definition,
priority,
apply_to])
end
def usage, do: "set_operator_policy [-p <vhost>] [--priority <priority>] [--apply-to <apply-to>] <name> <pattern> <definition>"
def flags, do: Keyword.keys(switches())
def banner([name, pattern, definition], %{vhost: vhost, priority: priority}) do
"Setting operator policy override \"#{name}\" for pattern \"#{pattern}\" to \"#{definition}\" with priority \"#{priority}\" for vhost \"#{vhost}\" ..."

View File

@ -49,7 +49,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetParameterCommand do
def usage, do: "set_parameter [-p <vhost>] <component_name> <name> <value>"
def flags, do: @flags
def banner([component_name, name, value], _) do
"Setting runtime parameter \"#{component_name}\" for component \"#{name}\" to \"#{value}\" ..."

View File

@ -48,7 +48,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetPermissionsCommand do
def usage, do: "set_permissions [-p <vhost>] <user> <conf> <write> <read>"
def flags, do: @flags
def banner([user|_], %{vhost: vhost}), do: "Setting permissions for user \"#{user}\" in vhost \"#{vhost}\" ..."
end

View File

@ -48,15 +48,14 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetPolicyCommand do
:parse_set,
[vhost,
name,
to_char_list(pattern),
to_char_list(definition),
to_char_list(priority),
pattern,
definition,
priority,
apply_to])
end
def usage, do: "set_policy [-p <vhost>] [--priority <priority>] [--apply-to <apply-to>] <name> <pattern> <definition>"
def flags, do: Keyword.keys(switches())
def banner([name, pattern, definition], %{vhost: vhost, priority: priority}) do
"Setting policy \"#{name}\" for pattern \"#{pattern}\" to \"#{definition}\" with priority \"#{priority}\" for vhost \"#{vhost}\" ..."

View File

@ -34,7 +34,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetUserTagsCommand do
def usage, do: "set_user_tags <user> <tag> [...]"
def flags, do: @flags
def banner([user | tags], _) do
"Setting tags for user \"#{user}\" to [#{tags |> Enum.join(", ")}] ..."

View File

@ -42,7 +42,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetVhostLimitsCommand do
def usage, do: "set_vhost_limits [-p <vhost>] <definition>"
def flags, do: [:vhost]
def banner([definition], %{vhost: vhost}) do
"Setting vhost limits to \"#{definition}\" for vhost \"#{vhost}\" ..."

View File

@ -95,7 +95,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetVmMemoryHighWatermarkCommand do
def usage, do: ["set_vm_memory_high_watermark <fraction>", "set_vm_memory_high_watermark absolute <value>"]
def flags, do: @flags
def banner(["absolute", arg], %{node: node_name}), do: "Setting memory threshold on #{node_name} to #{arg} bytes ..."
def banner([arg], %{node: node_name}), do: "Setting memory threshold on #{node_name} to #{arg} ..."

View File

@ -32,7 +32,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StartAppCommand do
def usage, do: "start_app"
def flags, do: @flags
def banner(_, %{node: node_name}), do: "Starting node #{node_name} ..."
end

View File

@ -35,7 +35,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StatusCommand do
def usage, do: "status"
def flags, do: @flags
def banner(_, %{node: node_name}), do: "Status of node #{node_name} ..."
end

View File

@ -32,7 +32,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StopAppCommand do
def usage, do: "stop_app"
def flags, do: @flags
def banner(_, %{node: node_name}), do: "Stopping node #{node_name} ..."
end

View File

@ -32,7 +32,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StopCommand do
def usage, do: "stop"
def flags, do: @flags
def banner(_, %{node: node_name}), do: "Stopping and halting node #{node_name} ..."
end

View File

@ -21,7 +21,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SyncQueueCommand do
{args, Map.merge(default_opts, opts)}
end
def flags, do: [:vhost]
def switches, do: []
def aliases, do: []

View File

@ -33,7 +33,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.TraceOffCommand do
def usage, do: "trace_off [-p <vhost>]"
def flags, do: @flags
def banner(_, %{vhost: vhost}), do: "Stopping tracing for vhost \"#{vhost}\" ..."
end

View File

@ -33,7 +33,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.TraceOnCommand do
def usage, do: "trace_on [-p <vhost>]"
def flags, do: @flags
def banner(_, %{vhost: vhost}), do: "Starting tracing for vhost \"#{vhost}\" ..."
end

View File

@ -19,7 +19,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.UpdateClusterNodesCommand do
@behaviour RabbitMQ.CLI.CommandBehaviour
def flags, do: []
def switches(), do: []
def aliases(), do: []

View File

@ -35,7 +35,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.WaitCommand do
def usage, do: "wait <pid_file>"
def flags, do: @flags
def banner(_, %{node: node_name}), do: "Waiting for node #{node_name} ..."

View File

@ -30,7 +30,7 @@ defmodule RabbitMQ.CLI.Formatters.Csv do
false -> [element]
end
(other) ->
other
[other]
end)
## Add info_items names
|> Stream.transform(:init,

View File

@ -44,7 +44,7 @@ defmodule RabbitMQ.CLI.Formatters.Table do
case Keyword.keyword?(output) do
true -> format_line(output, escaped);
false ->
case Keyword.keyword?(first) do
case Keyword.keyword?(first) or is_map(first) do
true ->
Enum.map(output, fn(el) -> format_line(el, escaped) end);
false ->

View File

@ -60,7 +60,6 @@ defmodule RabbitMQ.CLI.Plugins.Commands.DisableCommand do
["Disabling plugins on node #{node_name}:" | plugins]
end
def flags, do: Keyword.keys(switches())
def run(plugin_names, %{node: node_name} = opts) do
plugins = for s <- plugin_names, do: String.to_atom(s)

View File

@ -60,7 +60,6 @@ defmodule RabbitMQ.CLI.Plugins.Commands.EnableCommand do
["Enabling plugins on node #{node_name}:" | plugins]
end
def flags, do: Keyword.keys(switches())
def run(plugin_names, %{node: node_name} = opts) do
plugins = for s <- plugin_names, do: String.to_atom(s)

View File

@ -67,7 +67,6 @@ defmodule RabbitMQ.CLI.Plugins.Commands.ListCommand do
def banner([pattern], _), do: "Listing plugins with pattern \"#{pattern}\" ..."
def flags, do: Keyword.keys(switches())
def run([pattern], %{node: node_name} = opts) do
%{verbose: verbose, minimal: minimal,

View File

@ -57,7 +57,6 @@ defmodule RabbitMQ.CLI.Plugins.Commands.SetCommand do
["Enabling plugins on node #{node_name}:" | plugins]
end
def flags, do: Keyword.keys(switches())
def run(plugins, %{node: node_name} = opts) do
%{online: online, offline: offline} = opts

View File

@ -35,7 +35,7 @@ defmodule RabbitMQCtl do
{parsed_cmd, parsed_options, invalid} = parse(unparsed_command)
options = parsed_options |> merge_all_defaults |> normalize_options
CommandModules.load(options)
case {is_command?(parsed_cmd), invalid} do
case {CommandModules.is_command?(parsed_cmd), invalid} do
## No such command
{false, _} ->
usage_string = HelpCommand.all_usage()
@ -48,10 +48,10 @@ defmodule RabbitMQCtl do
Distribution.start(options)
[command_name | arguments] = parsed_cmd
command = commands[command_name]
command = CommandModules.module_map[command_name]
case invalid_flags(command, options) do
[] ->
case run_command(options, command, arguments) do
case execute_command(options, command, arguments) do
{:error, _, _} = err ->
err;
{:validation_failure, err} ->
@ -128,23 +128,30 @@ defmodule RabbitMQCtl do
connect_to_rabbitmq(node)
end
defp run_command(options, command, arguments) do
defp execute_command(options, command, arguments) do
{arguments, options} = command.merge_defaults(arguments, options)
case command.validate(arguments, options) do
:ok ->
maybe_print_banner(command, arguments, options)
maybe_connect_to_rabbitmq(command, options[:node])
try do
command.run(arguments, options) |> command.output(options)
catch _error_type, error ->
{:error, ExitCodes.exit_software,
to_string(:io_lib.format("Error: ~n~p~n Stacktrace ~p~n",
[error, System.stacktrace()]))}
end
maybe_run_command(command, arguments, options)
{:validation_failure, _} = err -> err
end
end
defp maybe_run_command(_, _, %{dry_run: true}) do
:ok
end
defp maybe_run_command(command, arguments, options) do
try do
command.run(arguments, options) |> command.output(options)
catch _error_type, error ->
{:error, ExitCodes.exit_software,
to_string(:io_lib.format("Error: ~n~p~n Stacktrace ~p~n",
[error, System.stacktrace()]))}
end
end
defp get_formatter(command, %{formatter: formatter}) do
module_name = Module.safe_concat("RabbitMQ.CLI.Formatters", Macro.camelize(formatter))
case Code.ensure_loaded(module_name) do
@ -200,9 +207,9 @@ defmodule RabbitMQCtl do
err = format_validation_error(err_detail, command_name) # TODO format the error better
base_error = "Error: #{err}\nGiven:\n\t#{unparsed_command |> Enum.join(" ")}"
usage = case is_command?(command_name) do
usage = case CommandModules.is_command?(command_name) do
true ->
command = commands[command_name]
command = CommandModules.module_map[command_name]
HelpCommand.base_usage(HelpCommand.program_name(), command)
false ->
HelpCommand.all_usage()
@ -218,7 +225,7 @@ defmodule RabbitMQCtl do
defp format_validation_error(:bad_argument, _), do: "Bad argument."
defp format_validation_error({:bad_argument, detail}, _), do: "Bad argument. #{detail}"
defp format_validation_error({:bad_option, opts}, command_name) do
header = case is_command?(command_name) do
header = case CommandModules.is_command?(command_name) do
true -> "Invalid options for this command:";
false -> "Invalid options:"
end
@ -227,10 +234,14 @@ defmodule RabbitMQCtl do
defp format_validation_error(err, _), do: inspect err
defp invalid_flags(command, opts) do
Map.take(opts, Map.keys(opts) -- (command.flags ++ global_flags))
Map.take(opts, Map.keys(opts) -- (command_flags(command) ++ global_flags))
|> Map.to_list
end
defp command_flags(command) do
command.switches |> Keyword.keys
end
defp exit_program(code) do
:net_kernel.stop
exit({:shutdown, code})

View File

@ -103,21 +103,20 @@ defmodule RabbitMQCtl.MixfileBase do
},
{
:amqp_client,
only: :test,
path: Path.join(deps_dir, "amqp_client"),
compile: make,
override: true
},
{
:amqp,
path: Path.join(deps_dir, "amqp")
:amqp, "~> 0.1.5",
only: :test
},
{
:json, "~> 1.0.0",
path: Path.join(deps_dir, "json")
:json, "~> 1.0.0"
},
{
:csv, "~> 1.4.2",
path: Path.join(deps_dir, "csv")
:csv, "~> 1.4.2"
}
]
end

View File

@ -111,6 +111,61 @@ defmodule CommandModulesTest do
end
## ------------------- is_command?/1 tests --------------------
test "a valid implemented command returns true" do
set_scope(:ctl)
@subject.load(%{})
assert @subject.is_command?("status") == true
end
test "an invalid command returns false" do
set_scope(:ctl)
@subject.load(%{})
assert @subject.is_command?("quack") == false
end
test "a nil returns false" do
set_scope(:ctl)
@subject.load(%{})
assert @subject.is_command?(nil) == false
end
test "an empty array returns false" do
set_scope(:ctl)
@subject.load(%{})
assert @subject.is_command?([]) == false
end
test "an non-empty array tests the first element" do
set_scope(:ctl)
@subject.load(%{})
assert @subject.is_command?(["status", "quack"]) == true
assert @subject.is_command?(["quack", "status"]) == false
end
test "a non-string list returns false" do
set_scope(:ctl)
@subject.load(%{})
assert @subject.is_command?([{"status", "quack"}, {4, "Fantastic"}]) == false
end
## ------------------- commands/0 tests --------------------
test "command_modules has existing commands" do
set_scope(:ctl)
@subject.load(%{})
assert @subject.module_map["status"] == RabbitMQ.CLI.Ctl.Commands.StatusCommand
assert @subject.module_map["environment"] == RabbitMQ.CLI.Ctl.Commands.EnvironmentCommand
end
test "command_modules does not have non-existent commands" do
set_scope(:ctl)
@subject.load(%{})
assert @subject.module_map[:p_equals_np_proof] == nil
end
def set_scope(scope) do
script_name = Config.get_option(:script_name, %{})
scopes = Keyword.put(Application.get_env(:rabbitmqctl, :scopes), script_name, scope)
@ -124,7 +179,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DuckCommand do
@behaviour RabbitMQ.CLI.CommandBehaviour
use RabbitMQ.CLI.DefaultOutput
def usage(), do: ["duck"]
def flags(), do: []
def validate(_,_), do: :ok
def merge_defaults(_,_), do: {[], %{}}
def banner(_,_), do: ""
@ -137,7 +191,6 @@ defmodule RabbitMQ.CLI.Ctl.Commands.GrayGooseCommand do
@behaviour RabbitMQ.CLI.CommandBehaviour
use RabbitMQ.CLI.DefaultOutput
def usage(), do: ["gray_goose"]
def flags(), do: []
def validate(_,_), do: :ok
def merge_defaults(_,_), do: {[], %{}}
def banner(_,_), do: ""
@ -156,7 +209,6 @@ defmodule RabbitMQ.CLI.Plugins.Commands.StorkCommand do
@behaviour RabbitMQ.CLI.CommandBehaviour
use RabbitMQ.CLI.DefaultOutput
def usage(), do: ["stork"]
def flags(), do: []
def validate(_,_), do: :ok
def merge_defaults(_,_), do: {[], %{}}
def banner(_,_), do: ""
@ -169,7 +221,6 @@ defmodule RabbitMQ.CLI.Plugins.Commands.HeronCommand do
@behaviour RabbitMQ.CLI.CommandBehaviour
use RabbitMQ.CLI.DefaultOutput
def usage(), do: ["heron"]
def flags(), do: []
def validate(_,_), do: :ok
def merge_defaults(_,_), do: {[], %{}}
def banner(_,_), do: ""
@ -184,7 +235,6 @@ defmodule RabbitMQ.CLI.Custom.Commands.CrowCommand do
@behaviour RabbitMQ.CLI.CommandBehaviour
use RabbitMQ.CLI.DefaultOutput
def usage(), do: ["crow"]
def flags(), do: []
def validate(_,_), do: :ok
def merge_defaults(_,_), do: {[], %{}}
def banner(_,_), do: ""
@ -198,7 +248,6 @@ defmodule RabbitMQ.CLI.Custom.Commands.RavenCommand do
@behaviour RabbitMQ.CLI.CommandBehaviour
use RabbitMQ.CLI.DefaultOutput
def usage(), do: ["raven"]
def flags(), do: []
def validate(_,_), do: :ok
def merge_defaults(_,_), do: {[], %{}}
def banner(_,_), do: ""
@ -211,7 +260,6 @@ defmodule RabbitMQ.CLI.Seagull.Commands.SeagullCommand do
@behaviour RabbitMQ.CLI.CommandBehaviour
use RabbitMQ.CLI.DefaultOutput
def usage(), do: ["seagull"]
def flags(), do: []
def validate(_,_), do: :ok
def merge_defaults(_,_), do: {[], %{}}
def banner(_,_), do: ""

View File

@ -18,6 +18,7 @@ defmodule HelpCommandTest do
use ExUnit.Case, async: false
alias RabbitMQ.CLI.Core.Helpers, as: Helpers
alias RabbitMQ.CLI.Core.CommandModules, as: CommandModules
alias RabbitMQ.CLI.Core.ExitCodes, as: ExitCodes
@command RabbitMQ.CLI.Ctl.Commands.HelpCommand
@ -31,7 +32,7 @@ defmodule HelpCommandTest do
end
test "command usage info is printed if command is specified" do
Helpers.commands
CommandModules.module_map
|> Map.keys
|> Enum.each(
fn(command) ->
@ -43,7 +44,7 @@ defmodule HelpCommandTest do
assert @command.run([], %{}) =~ ~r/Commands:\n/
# Checks to verify that each module's command appears in the list.
Helpers.commands
CommandModules.module_map
|> Map.keys
|> Enum.each(
fn(command) ->

View File

@ -61,44 +61,6 @@ test "RabbitMQ hostname is properly formed" do
assert @subject.connect_to_rabbitmq(context[:target]) == false
end
## ------------------- commands/0 tests --------------------
test "command_modules has existing commands" do
assert @subject.commands["status"] == RabbitMQ.CLI.Ctl.Commands.StatusCommand
assert @subject.commands["environment"] == RabbitMQ.CLI.Ctl.Commands.EnvironmentCommand
end
test "command_modules does not have non-existent commands" do
assert @subject.commands[:p_equals_np_proof] == nil
end
## ------------------- is_command?/1 tests --------------------
test "a valid implemented command returns true" do
assert @subject.is_command?("status") == true
end
test "an invalid command returns false" do
assert @subject.is_command?("quack") == false
end
test "a nil returns false" do
assert @subject.is_command?(nil) == false
end
test "an empty array returns false" do
assert @subject.is_command?([]) == false
end
test "an non-empty array tests the first element" do
assert @subject.is_command?(["status", "quack"]) == true
assert @subject.is_command?(["quack", "status"]) == false
end
test "a non-string list returns false" do
assert @subject.is_command?([{"status", "quack"}, {4, "Fantastic"}]) == false
end
## ------------------- memory_unit* tests --------------------
test "an invalid memory unit fails " do

View File

@ -76,8 +76,8 @@ defmodule PurgeQueueCommandTest do
assert @command.run(["foo"], context[:opts]) == {:badrpc, :timeout}
end
test "has no flags" do
assert @command.flags == []
test "has no switches" do
assert @command.switches == []
end
test "shows up in help" do

View File

@ -45,8 +45,8 @@ defmodule SetClusterNameCommandTest do
assert @command.merge_defaults(["foo"], %{bar: "baz"}) == {["foo"], %{bar: "baz"}}
end
test "has no flags" do
assert @command.flags == []
test "has no switches" do
assert @command.switches == []
end
test "validate: with insufficient number of arguments, return arg count error" do

View File

@ -21,12 +21,11 @@ defmodule TestHelper do
alias RabbitMQ.CLI.Plugins.Helpers, as: PluginHelpers
def get_rabbit_hostname() do
name = RabbitMQ.CLI.Core.Config.get_option(:nodename)
name <> "@" <> hostname() |> String.to_atom()
RabbitMQ.CLI.Core.Helpers.get_rabbit_hostname
end
def hostname() do
elem(:inet.gethostname, 1) |> List.to_string()
RabbitMQ.CLI.Core.Helpers.hostname
end
def get_cluster_name() do