summaryrefslogtreecommitdiff
path: root/deps/rabbitmq_cli/lib/rabbitmq/cli/diagnostics/commands/cipher_suites_command.ex
blob: 86e8eee3a4657635beed1c87dfe2580a75198ca9 (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
117
118
119
120
121
122
## This Source Code Form is subject to the terms of the Mozilla Public
## License, v. 2.0. If a copy of the MPL was not distributed with this
## file, You can obtain one at https://mozilla.org/MPL/2.0/.
##
## Copyright (c) 2007-2020 VMware, Inc. or its affiliates.  All rights reserved.

defmodule RabbitMQ.CLI.Diagnostics.Commands.CipherSuitesCommand do
  alias RabbitMQ.CLI.Core.Helpers

  @behaviour RabbitMQ.CLI.CommandBehaviour

  def merge_defaults(args, opts) do
    {args, Map.merge(%{all: false, format: "openssl"}, Helpers.case_insensitive_format(opts))}
  end

  def switches(), do: [timeout: :integer,
                       format: :string,
                       all: :boolean]
  def aliases(), do: [t: :timeout]

  def validate(_, %{format: format})
      when format != "openssl" and format != "erlang" and format != "map" do
    {:validation_failure, {:bad_argument, "Format should be either openssl, erlang or map"}}
  end
  def validate(args, _) when length(args) > 0 do
    {:validation_failure, :too_many_args}
  end

  def validate(_, _), do: :ok

  def run([], %{node: node_name, timeout: timeout, format: format} = opts) do
    {mod, function} = case format do
      "openssl" -> {:rabbit_ssl, :cipher_suites_openssl};
      "erlang"  -> {:rabbit_ssl, :cipher_suites_erlang};
      "map"     -> {:rabbit_ssl, :cipher_suites}
    end
    args = case opts do
      %{all: true} -> [:all];
      %{}          -> [:default]
    end
    :rabbit_misc.rpc_call(node_name, mod, function, args, timeout)
  end

  use RabbitMQ.CLI.DefaultOutput

  def banner([], %{format: "openssl"}),  do: "Listing available cipher suites in OpenSSL format"
  def banner([], %{format: "erlang"}), do: "Listing available cipher suites in Erlang term format"
  def banner([], %{format: "map"}), do: "Listing available cipher suites in map format"

  def help_section(), do: :observability_and_health_checks

  def description(), do: "Lists cipher suites enabled by default. To list all available cipher suites, add the --all argument."

  def usage, do: "cipher_suites [--format <openssl | erlang | map>] [--all]"

  def usage_additional() do
    [
      ["--format", "output format to use: openssl, erlang or map"],
      ["--all", "list all available suites"]
    ]
  end

  defmodule Formatter do
    alias RabbitMQ.CLI.Formatters.FormatterHelpers

    @behaviour RabbitMQ.CLI.FormatterBehaviour

    def format_output(item, %{format: "erlang"}) do
      to_string(:io_lib.format("~p", [item]))
    end

    def format_output(item, %{format: "map"}) do
      to_string(:io_lib.format("~p", [item]))
    end

    def format_output(item, %{format: "openssl"} = opts) do
      RabbitMQ.CLI.Formatters.String.format_output(item, opts)
    end

    def format_stream(stream, %{format: "erlang"} = opts) do
      comma_separated(stream, opts)
    end

    def format_stream(stream, %{format: "map"} = opts) do
      comma_separated(stream, opts)
    end

    def format_stream(stream, %{format: "openssl"} = opts) do
      Stream.map(
        stream,
        FormatterHelpers.without_errors_1(fn el ->
          format_output(el, opts)
        end)
      )
    end

    defp comma_separated(stream, opts) do
      elements =
        Stream.scan(
          stream,
          :empty,
          FormatterHelpers.without_errors_2(fn element, previous ->
            separator =
              case previous do
                :empty -> ""
                _ -> ","
              end

            format_element(element, separator, opts)
          end)
        )

      Stream.concat([["["], elements, ["]"]])
    end

    defp format_element(val, separator, opts) do
      separator <> format_output(val, opts)
    end
  end

  def formatter(), do: Formatter
end