summaryrefslogtreecommitdiff
path: root/deps/rabbitmq_cli/lib/rabbitmq/cli/plugins/commands/set_command.ex
blob: cc53de5ef43aa98a7da5a17860f6061fe2eb4b0c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
## 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
## at http://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.
## Copyright (c) 2007-2017 Pivotal Software, Inc.  All rights reserved.


defmodule RabbitMQ.CLI.Plugins.Commands.SetCommand do
  alias RabbitMQ.CLI.Plugins.Helpers, as: PluginHelpers
  alias RabbitMQ.CLI.Core.Helpers, as: Helpers
  alias RabbitMQ.CLI.Core.Validators, as: Validators
  alias RabbitMQ.CLI.Core.ExitCodes, as: ExitCodes

  @behaviour RabbitMQ.CLI.CommandBehaviour

  def formatter(), do: RabbitMQ.CLI.Formatters.Plugins

  def merge_defaults(args, opts) do
    {args, Map.merge(%{online: false, offline: false}, opts)}
  end

  def distribution(%{offline: true}),  do: :none
  def distribution(%{offline: false}), do: :cli

  def switches(), do: [online: :boolean,
                       offline: :boolean]

  def validate(_, %{online: true, offline: true}) do
    {:validation_failure, {:bad_argument, "Cannot set both online and offline"}}
  end
  def validate(_, _) do
    :ok
  end

  def validate_execution_environment(args, opts) do
    Validators.chain([&PluginHelpers.can_set_plugins_with_mode/2,
                      &Helpers.require_rabbit_and_plugins/2,
                      &PluginHelpers.enabled_plugins_file/2,
                      &Helpers.plugins_dir/2],
                     [args, opts])
  end

  def usage, do: "set [<plugin>] [--offline] [--online]"

  def banner(plugins, %{node: node_name}) do
      ["Enabling plugins on node #{node_name}:" | plugins]
  end


  def run(plugin_names, opts) do
    plugins = for s <- plugin_names, do: String.to_atom(s)
    case PluginHelpers.validate_plugins(plugins, opts) do
      :ok   -> do_run(plugins, opts)
      other -> other
    end
  end

  def do_run(plugins, %{node: node_name} = opts) do

    all = PluginHelpers.list(opts)
    mode = PluginHelpers.mode(opts)

    case PluginHelpers.set_enabled_plugins(plugins, opts) do
      {:ok, enabled_plugins} ->
        {:stream, Stream.concat(
            [[:rabbit_plugins.strictly_plugins(enabled_plugins, all)],
             RabbitMQ.CLI.Core.Helpers.defer(
               fn() ->
                 case PluginHelpers.update_enabled_plugins(enabled_plugins,
                                                           mode,
                                                           node_name,
                                                           opts) do
                   %{set: _} = map ->
                     filter_strictly_plugins(map, all, [:set, :started, :stopped]);
                   {:error, _} = err ->
                     err
                 end
               end)])};
      {:error, _} = err ->
        err
    end
  end

  defp filter_strictly_plugins(map, _all, []) do
    map
  end
  defp filter_strictly_plugins(map, all, [head | tail]) do
    case map[head] do
      nil ->
        filter_strictly_plugins(map, all, tail);
      other ->
        value = :rabbit_plugins.strictly_plugins(other, all)
        filter_strictly_plugins(Map.put(map, head, value), all, tail)
    end
  end

  def output({:error, {:plugins_not_found, missing}}, _opts) do
    {:error, ExitCodes.exit_dataerr(), "The following plugins were not found: #{Enum.join(Enum.to_list(missing), ", ")}"}
  end
  def output({:error, err}, _opts) do
    {:error, ExitCodes.exit_software(), to_string(err)}
  end
  def output({:stream, stream}, _opts) do
    {:stream, stream}
  end

end