1## This Source Code Form is subject to the terms of the Mozilla Public
2## License, v. 2.0. If a copy of the MPL was not distributed with this
3## file, You can obtain one at https://mozilla.org/MPL/2.0/.
4##
5## Copyright (c) 2007-2021 VMware, Inc. or its affiliates.  All rights reserved.
6
7defmodule RabbitMQ.CLI.Diagnostics.Commands.ListNodeAuthAttemptStatsCommand do
8  alias RabbitMQ.CLI.Core.DocGuide
9
10  @behaviour RabbitMQ.CLI.CommandBehaviour
11
12  def formatter(), do: RabbitMQ.CLI.Formatters.Table
13
14  def scopes(), do: [:ctl, :diagnostics]
15
16  use RabbitMQ.CLI.Core.RequiresRabbitAppRunning
17
18  def switches(), do: [by_source: :boolean]
19
20  def merge_defaults(args, opts) do
21    {args, Map.merge(%{by_source: false}, opts)}
22  end
23
24  def validate([], _), do: :ok
25  def validate(_, _), do: {:validation_failure, :too_many_args}
26
27  def run([], %{node: node_name, timeout: timeout, by_source: by_source}) do
28    case by_source do
29      :true ->
30        :rabbit_misc.rpc_call(
31          node_name, :rabbit_core_metrics, :get_auth_attempts_by_source, [], timeout)
32      :false ->
33        :rabbit_misc.rpc_call(
34          node_name, :rabbit_core_metrics, :get_auth_attempts, [], timeout)
35    end
36  end
37
38  def output([], %{node: node_name, formatter: "json"}) do
39    {:ok, %{"result" => "ok", "node" => node_name, "attempts" => []}}
40  end
41  def output([], %{node: node_name})  do
42    {:ok, "Node #{node_name} reported no authentication attempt stats"}
43  end
44  def output(rows, %{node: node_name, formatter: "json"}) do
45    maps = Enum.map(rows, &Map.new/1)
46    {:ok,
47     %{
48       "result"   => "ok",
49       "node"     => node_name,
50       "attempts" => maps
51     }}
52  end
53  use RabbitMQ.CLI.DefaultOutput
54
55  def usage, do: "list_node_auth_attempts [--by-source]"
56
57  def usage_additional do
58    [
59      ["--by-source", "list authentication attempts by remote address and username"]
60    ]
61  end
62
63  def usage_doc_guides() do
64    [
65      DocGuide.access_control(),
66      DocGuide.monitoring()
67    ]
68  end
69
70  def help_section(), do: :observability_and_health_checks
71  def description(), do: "Lists authentication attempts on the target node"
72
73  def banner([], %{node: node_name}), do: "Listing authentication
74 attempts for node \"#{node_name}\" ..."
75end
76