## 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-2023 VMware, Inc. or its affiliates. All rights reserved. alias RabbitMQ.CLI.Formatters.FormatterHelpers defmodule RabbitMQ.CLI.Formatters.Plugins do @behaviour RabbitMQ.CLI.FormatterBehaviour def format_output( %{status: status, format: format, plugins: plugins}, options ) do legend(status, format, options) ++ format_plugins(plugins, format) end def format_output(%{enabled: enabled, mode: _} = output, options) do case length(enabled) do 0 -> ["Plugin configuration unchanged."] _ -> [ "The following plugins have been enabled:" | for plugin <- enabled do " #{plugin}" end ] ++ [""] ++ applying(output, options) ++ log_offline(output) end end def format_output(%{disabled: disabled, mode: _} = output, options) do case length(disabled) do 0 -> ["Plugin configuration unchanged."] _ -> [ "The following plugins have been disabled:" | for plugin <- disabled do " #{plugin}" end ] ++ [""] ++ applying(output, options) ++ log_offline(output) end end ## Do not print enabled/disabled for set command def format_output(%{} = output, options) do applying(output, options) end def format_output([], %{node: node}) do ["All plugins have been disabled.", "Applying plugin configuration to #{node}..."] end def format_output(plugins, %{node: node}) when is_list(plugins) do [ "The following plugins have been configured:" | for plugin <- plugins do " #{plugin}" end ] ++ ["Applying plugin configuration to #{node}..."] end def format_output(output, _) do :io_lib.format("~p", [output]) |> to_string end def format_stream(stream, options) do Stream.map( stream, FormatterHelpers.without_errors_1(fn element -> format_output(element, options) end) ) end defp format_plugins(plugins, format) do max_name_length = Enum.reduce(plugins, 0, fn %{name: name}, len -> max(String.length(to_string(name)), len) end) for plugin <- plugins do format_plugin(plugin, format, max_name_length) end |> List.flatten() end defp format_plugin(%{name: name}, :minimal, _) do to_string(name) end defp format_plugin(plugin, :normal, max_name_length) do [summary(plugin) <> inline_version(plugin, max_name_length)] end defp format_plugin(plugin, :verbose, _) do [summary(plugin) | verbose(plugin)] end defp summary(%{name: name, enabled: enabled, running: running}) do enabled_sign = case enabled do :implicit -> "e" :enabled -> "E" :not_enabled -> " " end running_sign = case running do true -> "*" false -> " " end "[#{enabled_sign}#{running_sign}] #{name}" end defp inline_version(%{name: name} = plugin, max_name_length) do spacing = String.duplicate( " ", max_name_length - String.length(to_string(name)) ) spacing <> " " <> augment_version(plugin) end defp verbose(%{dependencies: dependencies, description: description} = plugin) do prettified = to_string(:io_lib.format("~p", [dependencies])) [ " Version: \t#{augment_version(plugin)}", " Dependencies:\t#{prettified}", " Description: \t#{description}" ] end defp augment_version(%{version: version, running_version: nil}) do to_string(version) end defp augment_version(%{version: version, running_version: version}) do to_string(version) end defp augment_version(%{version: version, running_version: running_version}) do "#{running_version} (pending upgrade to #{version})" end ## Do not print legend in minimal, quiet or silent mode defp legend(_, :minimal, _) do [] end defp legend(_, _, %{quiet: true}) do [] end defp legend(_, _, %{silent: true}) do [] end defp legend(status, _, %{node: node}) do [ " Configured: E = explicitly enabled; e = implicitly enabled", " | Status: #{status_message(status, node)}", " |/" ] end defp status_message(:running, node) do "* = running on #{node}" end defp status_message(:node_down, node) do "[failed to contact #{node} - status not shown]" end defp applying(%{mode: :offline, set: set_plugins}, _) do set_plugins_message = case length(set_plugins) do 0 -> "nothing to do" len -> "set #{len} plugins" end [set_plugins_message <> "."] end defp applying(%{mode: :offline, enabled: enabled}, _) do enabled_message = case length(enabled) do 0 -> "nothing to do" len -> "enabled #{len} plugins" end [enabled_message <> "."] end defp applying(%{mode: :offline, disabled: disabled}, _) do disabled_message = case length(disabled) do 0 -> "nothing to do" len -> "disabled #{len} plugins" end [disabled_message <> "."] end defp applying(%{mode: :online, started: started, stopped: stopped}, _) do stopped_message = case length(stopped) do 0 -> [] len -> ["stopped #{len} plugins"] end started_message = case length(started) do 0 -> [] len -> ["started #{len} plugins"] end change_message = case Enum.join(started_message ++ stopped_message, " and ") do "" -> "nothing to do" msg -> msg end [change_message <> "."] end defp log_offline(%{mode: :offline}) do ["Offline change; changes will take effect at broker restart."] end defp log_offline(_) do [] end end