From 77cd29f5ad3abddbbe46faef19b01e89892a13c9 Mon Sep 17 00:00:00 2001 From: Ralf Schmitz Bongiolo Date: Mon, 4 Nov 2024 18:58:18 -0400 Subject: [PATCH] feat(cli): update secrets --account flag as optional depending on adapter --- lib/kamal/cli/secrets.rb | 12 +++++++++--- lib/kamal/secrets/adapters/base.rb | 9 ++++++++- .../secrets/adapters/test_optional_account.rb | 18 ++++++++++++++++++ test/cli/secrets_test.rb | 12 ++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 lib/kamal/secrets/adapters/test_optional_account.rb diff --git a/lib/kamal/cli/secrets.rb b/lib/kamal/cli/secrets.rb index b094be46..0cfcf628 100644 --- a/lib/kamal/cli/secrets.rb +++ b/lib/kamal/cli/secrets.rb @@ -1,11 +1,17 @@ class Kamal::Cli::Secrets < Kamal::Cli::Base desc "fetch [SECRETS...]", "Fetch secrets from a vault" option :adapter, type: :string, aliases: "-a", required: true, desc: "Which vault adapter to use" - option :account, type: :string, required: true, desc: "The account identifier or username" + option :account, type: :string, required: false, desc: "The account identifier or username" option :from, type: :string, required: false, desc: "A vault or folder to fetch the secrets from" option :inline, type: :boolean, required: false, hidden: true def fetch(*secrets) - results = adapter(options[:adapter]).fetch(secrets, **options.slice(:account, :from).symbolize_keys) + adapter = initialize_adapter(options[:adapter]) + + if adapter.requires_account? && options[:account].blank? + return puts "No value provided for required options '--account'" + end + + results = adapter.fetch(secrets, **options.slice(:account, :from).symbolize_keys) return_or_puts JSON.dump(results).shellescape, inline: options[:inline] end @@ -29,7 +35,7 @@ class Kamal::Cli::Secrets < Kamal::Cli::Base end private - def adapter(adapter) + def initialize_adapter(adapter) Kamal::Secrets::Adapters.lookup(adapter) end diff --git a/lib/kamal/secrets/adapters/base.rb b/lib/kamal/secrets/adapters/base.rb index 579414af..fc66bb34 100644 --- a/lib/kamal/secrets/adapters/base.rb +++ b/lib/kamal/secrets/adapters/base.rb @@ -1,13 +1,20 @@ class Kamal::Secrets::Adapters::Base delegate :optionize, to: Kamal::Utils - def fetch(secrets, account:, from: nil) + def fetch(secrets, account: nil, from: nil) + raise RuntimeError, "Missing required option '--account'" if requires_account? && account.blank? + check_dependencies! + session = login(account) full_secrets = secrets.map { |secret| [ from, secret ].compact.join("/") } fetch_secrets(full_secrets, account: account, session: session) end + def requires_account? + true + end + private def login(...) raise NotImplementedError diff --git a/lib/kamal/secrets/adapters/test_optional_account.rb b/lib/kamal/secrets/adapters/test_optional_account.rb new file mode 100644 index 00000000..1f85302f --- /dev/null +++ b/lib/kamal/secrets/adapters/test_optional_account.rb @@ -0,0 +1,18 @@ +class Kamal::Secrets::Adapters::TestOptionalAccount < Kamal::Secrets::Adapters::Base + def requires_account? + false + end + + private + def login(account) + true + end + + def fetch_secrets(secrets, account:, session:) + secrets.to_h { |secret| [ secret, secret.reverse ] } + end + + def check_dependencies! + # no op + end +end diff --git a/test/cli/secrets_test.rb b/test/cli/secrets_test.rb index 6014a7e7..bd412862 100644 --- a/test/cli/secrets_test.rb +++ b/test/cli/secrets_test.rb @@ -7,6 +7,18 @@ class CliSecretsTest < CliTestCase run_command("fetch", "foo", "bar", "baz", "--account", "myaccount", "--adapter", "test") end + test "fetch missing --acount" do + assert_equal \ + "No value provided for required options '--account'", + run_command("fetch", "foo", "bar", "baz", "--adapter", "test") + end + + test "fetch without required --account" do + assert_equal \ + "\\{\\\"foo\\\":\\\"oof\\\",\\\"bar\\\":\\\"rab\\\",\\\"baz\\\":\\\"zab\\\"\\}", + run_command("fetch", "foo", "bar", "baz", "--adapter", "test_optional_account") + end + test "extract" do assert_equal "oof", run_command("extract", "foo", "{\"foo\":\"oof\", \"bar\":\"rab\", \"baz\":\"zab\"}") end