From 206795c23c08be3ca97166b2e77f22a076f398a2 Mon Sep 17 00:00:00 2001 From: Kevin Date: Fri, 10 Jan 2025 01:33:59 -0500 Subject: [PATCH 1/9] initial adjustment for password managers on windows, changing backticks to system calls, still failing tests --- lib/kamal/secrets/adapters/aws_secrets_manager.rb | 2 +- lib/kamal/secrets/adapters/bitwarden.rb | 2 +- lib/kamal/secrets/adapters/doppler.rb | 2 +- lib/kamal/secrets/adapters/last_pass.rb | 2 +- lib/kamal/secrets/adapters/one_password.rb | 2 +- test/secrets/bitwarden_adapter_test.rb | 2 +- test/test_helper.rb | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/kamal/secrets/adapters/aws_secrets_manager.rb b/lib/kamal/secrets/adapters/aws_secrets_manager.rb index 4bcac21d5..9ea8fb881 100644 --- a/lib/kamal/secrets/adapters/aws_secrets_manager.rb +++ b/lib/kamal/secrets/adapters/aws_secrets_manager.rb @@ -36,7 +36,7 @@ def check_dependencies! end def cli_installed? - `aws --version 2> /dev/null` + system("aws --version", out: File::NULL, err: File::NULL) $?.success? end end diff --git a/lib/kamal/secrets/adapters/bitwarden.rb b/lib/kamal/secrets/adapters/bitwarden.rb index 5dfb72dba..dfcd3718b 100644 --- a/lib/kamal/secrets/adapters/bitwarden.rb +++ b/lib/kamal/secrets/adapters/bitwarden.rb @@ -75,7 +75,7 @@ def check_dependencies! end def cli_installed? - `bw --version 2> /dev/null` + system("bw --version", out: File::NULL, err: File::NULL) $?.success? end end diff --git a/lib/kamal/secrets/adapters/doppler.rb b/lib/kamal/secrets/adapters/doppler.rb index 64d644f7e..1310ee29f 100644 --- a/lib/kamal/secrets/adapters/doppler.rb +++ b/lib/kamal/secrets/adapters/doppler.rb @@ -47,7 +47,7 @@ def check_dependencies! end def cli_installed? - `doppler --version 2> /dev/null` + system("doppler --version", out: File::NULL, err: File::NULL) $?.success? end end diff --git a/lib/kamal/secrets/adapters/last_pass.rb b/lib/kamal/secrets/adapters/last_pass.rb index 2f95148b0..455055bb1 100644 --- a/lib/kamal/secrets/adapters/last_pass.rb +++ b/lib/kamal/secrets/adapters/last_pass.rb @@ -33,7 +33,7 @@ def check_dependencies! end def cli_installed? - `lpass --version 2> /dev/null` + system("lpass --version", out: File::NULL, err: File::NULL) $?.success? end end diff --git a/lib/kamal/secrets/adapters/one_password.rb b/lib/kamal/secrets/adapters/one_password.rb index c7f9d5abd..a71adda36 100644 --- a/lib/kamal/secrets/adapters/one_password.rb +++ b/lib/kamal/secrets/adapters/one_password.rb @@ -64,7 +64,7 @@ def check_dependencies! end def cli_installed? - `op --version 2> /dev/null` + system("op --version", out: File::NULL, err: File::NULL) $?.success? end end diff --git a/test/secrets/bitwarden_adapter_test.rb b/test/secrets/bitwarden_adapter_test.rb index ad280791f..f1bb6cf64 100644 --- a/test/secrets/bitwarden_adapter_test.rb +++ b/test/secrets/bitwarden_adapter_test.rb @@ -182,7 +182,7 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_ticks_with("bw --version 2> /dev/null", succeed: false) + stub_ticks_with(system("bw --version", out: File::NULL, err: File::NULL), succeed: false) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "mynote"))) diff --git a/test/test_helper.rb b/test/test_helper.rb index f58118725..d3220d31f 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -75,7 +75,7 @@ def teardown_test_secrets class SecretAdapterTestCase < ActiveSupport::TestCase setup do - `true` # Ensure $? is 0 + `exit 0` # Ensure $? is 0 end private @@ -85,7 +85,7 @@ def stub_ticks def stub_ticks_with(command, succeed: true) # Sneakily run `false`/`true` after a match to set $? to 1/0 - stub_ticks.with { |c| c == command && (succeed ? `true` : `false`) } + stub_ticks.with { |c| c == command && (succeed ? `exit 0` : `exit 1`) } Kamal::Secrets::Adapters::Base.any_instance.stubs(:`) end From c9d06f67a4bdf89e482f65fbe03e54ab57ae72f3 Mon Sep 17 00:00:00 2001 From: Kevin Date: Fri, 10 Jan 2025 15:02:52 -0500 Subject: [PATCH 2/9] fixing bitwarden tests, combining system and backtick stubs into the same functions --- lib/kamal/secrets/adapters/bitwarden.rb | 2 +- test/secrets/bitwarden_adapter_test.rb | 69 +++++++++++++------------ test/test_helper.rb | 12 ++--- 3 files changed, 42 insertions(+), 41 deletions(-) diff --git a/lib/kamal/secrets/adapters/bitwarden.rb b/lib/kamal/secrets/adapters/bitwarden.rb index dfcd3718b..03a51f3f3 100644 --- a/lib/kamal/secrets/adapters/bitwarden.rb +++ b/lib/kamal/secrets/adapters/bitwarden.rb @@ -75,7 +75,7 @@ def check_dependencies! end def cli_installed? - system("bw --version", out: File::NULL, err: File::NULL) + system("bw --version", err: File::NULL) $?.success? end end diff --git a/test/secrets/bitwarden_adapter_test.rb b/test/secrets/bitwarden_adapter_test.rb index f1bb6cf64..12e6d2b24 100644 --- a/test/secrets/bitwarden_adapter_test.rb +++ b/test/secrets/bitwarden_adapter_test.rb @@ -2,10 +2,10 @@ class BitwardenAdapterTest < SecretAdapterTestCase test "fetch" do - stub_ticks.with("bw --version 2> /dev/null") + stub_command(:system).with("bw --version", err: File::NULL) stub_unlocked - stub_ticks.with("bw sync").returns("") + stub_command.with("bw sync").returns("") stub_mypassword json = JSON.parse(shellunescape(run_command("fetch", "mypassword"))) @@ -16,10 +16,10 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch with no login" do - stub_ticks.with("bw --version 2> /dev/null") + stub_command(:system).with("bw --version", err: File::NULL) stub_unlocked - stub_ticks.with("bw sync").returns("") + stub_command.with("bw sync").returns("") stub_noteitem error = assert_raises RuntimeError do @@ -29,10 +29,10 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch with from" do - stub_ticks.with("bw --version 2> /dev/null") + stub_command(:system).with("bw --version", err: File::NULL) stub_unlocked - stub_ticks.with("bw sync").returns("") + stub_command.with("bw sync").returns("") stub_myitem json = JSON.parse(shellunescape(run_command("fetch", "--from", "myitem", "field1", "field2", "field3"))) @@ -45,10 +45,10 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch all with from" do - stub_ticks.with("bw --version 2> /dev/null") + stub_command(:system).with("bw --version", err: File::NULL) stub_unlocked - stub_ticks.with("bw sync").returns("") + stub_command.with("bw sync").returns("") stub_noteitem_with_fields json = JSON.parse(shellunescape(run_command("fetch", "mynotefields"))) @@ -62,15 +62,15 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch with multiple items" do - stub_ticks.with("bw --version 2> /dev/null") + stub_command(:system).with("bw --version", err: File::NULL) stub_unlocked - stub_ticks.with("bw sync").returns("") + stub_command.with("bw sync").returns("") stub_mypassword stub_myitem - stub_ticks + stub_command .with("bw get item myitem2") .returns(<<~JSON) { @@ -105,9 +105,9 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch unauthenticated" do - stub_ticks.with("bw --version 2> /dev/null") + stub_command(:system).with("bw --version", err: File::NULL) - stub_ticks + stub_command .with("bw status") .returns( '{"serverUrl":null,"lastSync":null,"status":"unauthenticated"}', @@ -115,9 +115,9 @@ class BitwardenAdapterTest < SecretAdapterTestCase '{"serverUrl":null,"lastSync":"2024-09-04T10:11:12.433Z","userEmail":"email@example.com","userId":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","status":"unlocked"}' ) - stub_ticks.with("bw login email@example.com").returns("1234567890") - stub_ticks.with("bw unlock --raw").returns("") - stub_ticks.with("bw sync").returns("") + stub_command.with("bw login email@example.com").returns("1234567890") + stub_command.with("bw unlock --raw").returns("") + stub_command.with("bw sync").returns("") stub_mypassword json = JSON.parse(shellunescape(run_command("fetch", "mypassword"))) @@ -128,23 +128,23 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch locked" do - stub_ticks.with("bw --version 2> /dev/null") + stub_command(:system).with("bw --version", err: File::NULL) - stub_ticks + stub_command .with("bw status") .returns( '{"serverUrl":null,"lastSync":"2024-09-04T10:11:12.433Z","userEmail":"email@example.com","userId":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","status":"locked"}' ) - stub_ticks + stub_command .with("bw status") .returns( '{"serverUrl":null,"lastSync":"2024-09-04T10:11:12.433Z","userEmail":"email@example.com","userId":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","status":"unlocked"}' ) - stub_ticks.with("bw login email@example.com").returns("1234567890") - stub_ticks.with("bw unlock --raw").returns("") - stub_ticks.with("bw sync").returns("") + stub_command.with("bw login email@example.com").returns("1234567890") + stub_command.with("bw unlock --raw").returns("") + stub_command.with("bw sync").returns("") stub_mypassword json = JSON.parse(shellunescape(run_command("fetch", "mypassword"))) @@ -155,23 +155,24 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch locked with session" do - stub_ticks.with("bw --version 2> /dev/null") + stub_command(:system).with("bw --version", err: File::NULL) - stub_ticks + + stub_command .with("bw status") .returns( '{"serverUrl":null,"lastSync":"2024-09-04T10:11:12.433Z","userEmail":"email@example.com","userId":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","status":"locked"}' ) - stub_ticks + stub_command .with("BW_SESSION=0987654321 bw status") .returns( '{"serverUrl":null,"lastSync":"2024-09-04T10:11:12.433Z","userEmail":"email@example.com","userId":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","status":"unlocked"}' ) - stub_ticks.with("bw login email@example.com").returns("1234567890") - stub_ticks.with("bw unlock --raw").returns("0987654321") - stub_ticks.with("BW_SESSION=0987654321 bw sync").returns("") + stub_command.with("bw login email@example.com").returns("1234567890") + stub_command.with("bw unlock --raw").returns("0987654321") + stub_command.with("BW_SESSION=0987654321 bw sync").returns("") stub_mypassword(session: "0987654321") json = JSON.parse(shellunescape(run_command("fetch", "mypassword"))) @@ -182,7 +183,7 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_ticks_with(system("bw --version", out: File::NULL, err: File::NULL), succeed: false) + stub_command_with("bw --version", :system, false) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "mynote"))) @@ -202,7 +203,7 @@ def run_command(*command) end def stub_unlocked - stub_ticks + stub_command .with("bw status") .returns(<<~JSON) {"serverUrl":null,"lastSync":"2024-09-04T10:11:12.433Z","userEmail":"email@example.com","userId":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee","status":"unlocked"} @@ -210,7 +211,7 @@ def stub_unlocked end def stub_mypassword(session: nil) - stub_ticks + stub_command .with("#{"BW_SESSION=#{session} " if session}bw get item mypassword") .returns(<<~JSON) { @@ -233,7 +234,7 @@ def stub_mypassword(session: nil) end def stub_noteitem(session: nil) - stub_ticks + stub_command .with("#{"BW_SESSION=#{session} " if session}bw get item mynote") .returns(<<~JSON) { @@ -257,7 +258,7 @@ def stub_noteitem(session: nil) end def stub_noteitem_with_fields(session: nil) - stub_ticks + stub_command .with("#{"BW_SESSION=#{session} " if session}bw get item mynotefields") .returns(<<~JSON) { @@ -287,7 +288,7 @@ def stub_noteitem_with_fields(session: nil) end def stub_myitem - stub_ticks + stub_command .with("bw get item myitem") .returns(<<~JSON) { diff --git a/test/test_helper.rb b/test/test_helper.rb index d3220d31f..e06fb3800 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -79,14 +79,14 @@ class SecretAdapterTestCase < ActiveSupport::TestCase end private - def stub_ticks - Kamal::Secrets::Adapters::Base.any_instance.stubs(:`) + def stub_command(format = :`) + Kamal::Secrets::Adapters::Base.any_instance.stubs(format) end - def stub_ticks_with(command, succeed: true) - # Sneakily run `false`/`true` after a match to set $? to 1/0 - stub_ticks.with { |c| c == command && (succeed ? `exit 0` : `exit 1`) } - Kamal::Secrets::Adapters::Base.any_instance.stubs(:`) + def stub_command_with(command, format = :`, succeed = true) + # Sneakily run `exit 1`/`exit 0` after a match to set $? to 1/0 + stub_command(format).with { |c| c == command && (succeed ? `exit 0` : `exit 1`) } + Kamal::Secrets::Adapters::Base.any_instance.stubs(format) end def shellunescape(string) From 2d623dfa833ef10a656a67556541bdcca2d39c9b Mon Sep 17 00:00:00 2001 From: Kevin Date: Fri, 10 Jan 2025 16:35:35 -0500 Subject: [PATCH 3/9] fixing up tests for other adapters, removing stdout nullification --- .../secrets/adapters/aws_secrets_manager.rb | 2 +- lib/kamal/secrets/adapters/doppler.rb | 4 +-- lib/kamal/secrets/adapters/last_pass.rb | 2 +- lib/kamal/secrets/adapters/one_password.rb | 4 +-- .../aws_secrets_manager_adapter_test.rb | 18 +++++----- test/secrets/doppler_adapter_test.rb | 34 +++++++++---------- test/secrets/last_pass_adapter_test.rb | 24 ++++++------- test/secrets/one_password_adapter_test.rb | 32 ++++++++--------- 8 files changed, 60 insertions(+), 60 deletions(-) diff --git a/lib/kamal/secrets/adapters/aws_secrets_manager.rb b/lib/kamal/secrets/adapters/aws_secrets_manager.rb index 9ea8fb881..7d0860136 100644 --- a/lib/kamal/secrets/adapters/aws_secrets_manager.rb +++ b/lib/kamal/secrets/adapters/aws_secrets_manager.rb @@ -36,7 +36,7 @@ def check_dependencies! end def cli_installed? - system("aws --version", out: File::NULL, err: File::NULL) + system("aws --version", err: File::NULL) $?.success? end end diff --git a/lib/kamal/secrets/adapters/doppler.rb b/lib/kamal/secrets/adapters/doppler.rb index 1310ee29f..8dbcf6b0c 100644 --- a/lib/kamal/secrets/adapters/doppler.rb +++ b/lib/kamal/secrets/adapters/doppler.rb @@ -12,7 +12,7 @@ def login(*) end def loggedin? - `doppler me --json 2> /dev/null` + system("doppler me --json", err: File::NULL) $?.success? end @@ -47,7 +47,7 @@ def check_dependencies! end def cli_installed? - system("doppler --version", out: File::NULL, err: File::NULL) + system("doppler --version", err: File::NULL) $?.success? end end diff --git a/lib/kamal/secrets/adapters/last_pass.rb b/lib/kamal/secrets/adapters/last_pass.rb index 455055bb1..a46929120 100644 --- a/lib/kamal/secrets/adapters/last_pass.rb +++ b/lib/kamal/secrets/adapters/last_pass.rb @@ -33,7 +33,7 @@ def check_dependencies! end def cli_installed? - system("lpass --version", out: File::NULL, err: File::NULL) + system("lpass --version", err: File::NULL) $?.success? end end diff --git a/lib/kamal/secrets/adapters/one_password.rb b/lib/kamal/secrets/adapters/one_password.rb index a71adda36..112cdb854 100644 --- a/lib/kamal/secrets/adapters/one_password.rb +++ b/lib/kamal/secrets/adapters/one_password.rb @@ -11,7 +11,7 @@ def login(account) end def loggedin?(account) - `op account get --account #{account.shellescape} 2> /dev/null` + system("op account get --account #{account.shellescape}", err: File::NULL) $?.success? end @@ -64,7 +64,7 @@ def check_dependencies! end def cli_installed? - system("op --version", out: File::NULL, err: File::NULL) + system("op --version", err: File::NULL) $?.success? end end diff --git a/test/secrets/aws_secrets_manager_adapter_test.rb b/test/secrets/aws_secrets_manager_adapter_test.rb index 7616342db..0cf6a625a 100644 --- a/test/secrets/aws_secrets_manager_adapter_test.rb +++ b/test/secrets/aws_secrets_manager_adapter_test.rb @@ -2,8 +2,8 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase test "fails when errors are present" do - stub_ticks.with("aws --version 2> /dev/null") - stub_ticks + stub_command(:system).with("aws --version", err: File::NULL) + stub_command .with("aws secretsmanager batch-get-secret-value --secret-id-list unknown1 unknown2 --profile default") .returns(<<~JSON) { @@ -31,8 +31,8 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch" do - stub_ticks.with("aws --version 2> /dev/null") - stub_ticks + stub_command(:system).with("aws --version", err: File::NULL) + stub_command .with("aws secretsmanager batch-get-secret-value --secret-id-list secret/KEY1 secret/KEY2 secret2/KEY3 --profile default") .returns(<<~JSON) { @@ -74,8 +74,8 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch with string value" do - stub_ticks.with("aws --version 2> /dev/null") - stub_ticks + stub_command(:system).with("aws --version", err: File::NULL) + stub_command .with("aws secretsmanager batch-get-secret-value --secret-id-list secret secret2/KEY1 --profile default") .returns(<<~JSON) { @@ -116,8 +116,8 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch with secret names" do - stub_ticks.with("aws --version 2> /dev/null") - stub_ticks + stub_command(:system).with("aws --version", err: File::NULL) + stub_command .with("aws secretsmanager batch-get-secret-value --secret-id-list secret/KEY1 secret/KEY2 --profile default") .returns(<<~JSON) { @@ -148,7 +148,7 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_ticks_with("aws --version 2> /dev/null", succeed: false) + stub_command_with("aws --version", :system, false) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "SECRET1"))) diff --git a/test/secrets/doppler_adapter_test.rb b/test/secrets/doppler_adapter_test.rb index c2b164682..c401ef8fc 100644 --- a/test/secrets/doppler_adapter_test.rb +++ b/test/secrets/doppler_adapter_test.rb @@ -2,14 +2,14 @@ class DopplerAdapterTest < SecretAdapterTestCase setup do - `true` # Ensure $? is 0 + `exit 0` # Ensure $? is 0 end test "fetch" do - stub_ticks_with("doppler --version 2> /dev/null", succeed: true) - stub_ticks.with("doppler me --json 2> /dev/null") + stub_command_with("doppler --version", :system, true) + stub_command(:system).with("doppler me --json", err: File::NULL) - stub_ticks + stub_command .with("doppler secrets get SECRET1 FSECRET1 FSECRET2 --json -p my-project -c prd") .returns(<<~JSON) { @@ -47,10 +47,10 @@ class DopplerAdapterTest < SecretAdapterTestCase test "fetch having DOPPLER_TOKEN" do ENV["DOPPLER_TOKEN"] = "dp.st.xxxxxxxxxxxxxxxxxxxxxx" - stub_ticks_with("doppler --version 2> /dev/null", succeed: true) - stub_ticks.with("doppler me --json 2> /dev/null") + stub_command_with("doppler --version", :system, true) + stub_command(:system).with("doppler me --json", err: File::NULL) - stub_ticks + stub_command .with("doppler secrets get SECRET1 FSECRET1 FSECRET2 --json ") .returns(<<~JSON) { @@ -88,10 +88,10 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch with folder in secret" do - stub_ticks_with("doppler --version 2> /dev/null", succeed: true) - stub_ticks.with("doppler me --json 2> /dev/null") + stub_command_with("doppler --version", :system, true) + stub_command(:system).with("doppler me --json", err: File::NULL) - stub_ticks + stub_command .with("doppler secrets get SECRET1 FSECRET1 FSECRET2 --json -p my-project -c prd") .returns(<<~JSON) { @@ -127,8 +127,8 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch without --from" do - stub_ticks_with("doppler --version 2> /dev/null", succeed: true) - stub_ticks.with("doppler me --json 2> /dev/null") + stub_command_with("doppler --version", :system, true) + stub_command(:system).with("doppler me --json", err: File::NULL) error = assert_raises RuntimeError do run_command("fetch", "FSECRET1", "FSECRET2") @@ -138,10 +138,10 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch with signin" do - stub_ticks_with("doppler --version 2> /dev/null", succeed: true) - stub_ticks_with("doppler me --json 2> /dev/null", succeed: false) - stub_ticks_with("doppler login -y", succeed: true).returns("") - stub_ticks.with("doppler secrets get SECRET1 --json -p my-project -c prd").returns(single_item_json) + stub_command_with("doppler --version", :system, true) + stub_command_with("doppler me --json", :system, false) + stub_command_with("doppler login -y", :`, true).returns("") + stub_command.with("doppler secrets get SECRET1 --json -p my-project -c prd").returns(single_item_json) json = JSON.parse(shellunescape(run_command("fetch", "--from", "my-project/prd", "SECRET1"))) @@ -153,7 +153,7 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_ticks_with("doppler --version 2> /dev/null", succeed: false) + stub_command_with("doppler --version", :system, false) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "HOST", "PORT"))) diff --git a/test/secrets/last_pass_adapter_test.rb b/test/secrets/last_pass_adapter_test.rb index ca1f346ca..34e025c05 100644 --- a/test/secrets/last_pass_adapter_test.rb +++ b/test/secrets/last_pass_adapter_test.rb @@ -2,14 +2,14 @@ class LastPassAdapterTest < SecretAdapterTestCase setup do - `true` # Ensure $? is 0 + `exit 0` # Ensure $? is 0 end test "fetch" do - stub_ticks.with("lpass --version 2> /dev/null") - stub_ticks.with("lpass status --color never").returns("Logged in as email@example.com.") + stub_command(:system).with("lpass --version", err: File::NULL) + stub_command.with("lpass status --color never").returns("Logged in as email@example.com.") - stub_ticks + stub_command .with("lpass show SECRET1 FOLDER1/FSECRET1 FOLDER1/FSECRET2 --json") .returns(<<~JSON) [ @@ -64,10 +64,10 @@ class LastPassAdapterTest < SecretAdapterTestCase end test "fetch with from" do - stub_ticks.with("lpass --version 2> /dev/null") - stub_ticks.with("lpass status --color never").returns("Logged in as email@example.com.") + stub_command(:system).with("lpass --version", err: File::NULL) + stub_command.with("lpass status --color never").returns("Logged in as email@example.com.") - stub_ticks + stub_command .with("lpass show FOLDER1/FSECRET1 FOLDER1/FSECRET2 --json") .returns(<<~JSON) [ @@ -109,11 +109,11 @@ class LastPassAdapterTest < SecretAdapterTestCase end test "fetch with signin" do - stub_ticks.with("lpass --version 2> /dev/null") + stub_command(:system).with("lpass --version", err: File::NULL) - stub_ticks_with("lpass status --color never", succeed: false).returns("Not logged in.") - stub_ticks_with("lpass login email@example.com", succeed: true).returns("") - stub_ticks.with("lpass show SECRET1 --json").returns(single_item_json) + stub_command_with("lpass status --color never", :`, false).returns("Not logged in.") + stub_command_with("lpass login email@example.com", :`, true).returns("") + stub_command.with("lpass show SECRET1 --json").returns(single_item_json) json = JSON.parse(shellunescape(run_command("fetch", "SECRET1"))) @@ -125,7 +125,7 @@ class LastPassAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_ticks_with("lpass --version 2> /dev/null", succeed: false) + stub_command_with("lpass --version", :system, false) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "SECRET1", "FOLDER1/FSECRET1", "FOLDER1/FSECRET2"))) diff --git a/test/secrets/one_password_adapter_test.rb b/test/secrets/one_password_adapter_test.rb index 36fab7c36..c7730235c 100644 --- a/test/secrets/one_password_adapter_test.rb +++ b/test/secrets/one_password_adapter_test.rb @@ -2,10 +2,10 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase test "fetch" do - stub_ticks.with("op --version 2> /dev/null") - stub_ticks.with("op account get --account myaccount 2> /dev/null") + stub_command(:system).with("op --version", err: File::NULL) + stub_command(:system).with("op account get --account myaccount", err: File::NULL) - stub_ticks + stub_command .with("op item get myitem --vault \"myvault\" --fields \"label=section.SECRET1,label=section.SECRET2,label=section2.SECRET3\" --format \"json\" --account \"myaccount\"") .returns(<<~JSON) [ @@ -57,10 +57,10 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase end test "fetch with multiple items" do - stub_ticks.with("op --version 2> /dev/null") - stub_ticks.with("op account get --account myaccount 2> /dev/null") + stub_command(:system).with("op --version", err: File::NULL) + stub_command(:system).with("op account get --account myaccount", err: File::NULL) - stub_ticks + stub_command .with("op item get myitem --vault \"myvault\" --fields \"label=section.SECRET1,label=section.SECRET2\" --format \"json\" --account \"myaccount\"") .returns(<<~JSON) [ @@ -89,7 +89,7 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase ] JSON - stub_ticks + stub_command .with("op item get myitem2 --vault \"myvault\" --fields \"label=section2.SECRET3\" --format \"json\" --account \"myaccount\"") .returns(<<~JSON) { @@ -117,12 +117,12 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase end test "fetch with signin, no session" do - stub_ticks.with("op --version 2> /dev/null") + stub_command(:system).with("op --version", err: File::NULL) - stub_ticks_with("op account get --account myaccount 2> /dev/null", succeed: false) - stub_ticks_with("op signin --account \"myaccount\" --force --raw", succeed: true).returns("") + stub_command_with("op account get --account myaccount", :system, false) + stub_command_with("op signin --account \"myaccount\" --force --raw", :`, true).returns("") - stub_ticks + stub_command .with("op item get myitem --vault \"myvault\" --fields \"label=section.SECRET1\" --format \"json\" --account \"myaccount\"") .returns(single_item_json) @@ -136,12 +136,12 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase end test "fetch with signin and session" do - stub_ticks.with("op --version 2> /dev/null") + stub_command(:system).with("op --version", err: File::NULL) - stub_ticks_with("op account get --account myaccount 2> /dev/null", succeed: false) - stub_ticks_with("op signin --account \"myaccount\" --force --raw", succeed: true).returns("1234567890") + stub_command_with("op account get --account myaccount", :system, false) + stub_command_with("op signin --account \"myaccount\" --force --raw", :`, true).returns("1234567890") - stub_ticks + stub_command .with("op item get myitem --vault \"myvault\" --fields \"label=section.SECRET1\" --format \"json\" --account \"myaccount\" --session \"1234567890\"") .returns(single_item_json) @@ -155,7 +155,7 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_ticks_with("op --version 2> /dev/null", succeed: false) + stub_command_with("op --version", :system, false) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "--from", "op://myvault/myitem", "section/SECRET1", "section/SECRET2", "section2/SECRET3"))) From 659670d19c76b72443e4e479a41b6c9ef48a1173 Mon Sep 17 00:00:00 2001 From: Kevin Date: Fri, 10 Jan 2025 20:30:55 -0500 Subject: [PATCH 4/9] removing shellescape, as it's also not supported on Windows, still need to check tests --- lib/kamal/secrets/adapters/bitwarden.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/kamal/secrets/adapters/bitwarden.rb b/lib/kamal/secrets/adapters/bitwarden.rb index 03a51f3f3..511871171 100644 --- a/lib/kamal/secrets/adapters/bitwarden.rb +++ b/lib/kamal/secrets/adapters/bitwarden.rb @@ -65,7 +65,8 @@ def signedin?(account) end def run_command(command, session: nil, raw: false) - full_command = [ *("BW_SESSION=#{session.shellescape}" if session), "bw", command ].join(" ") + system("BW_SESSION=", session) if session + full_command = [ "bw", command ].join(" ") result = `#{full_command}`.strip raw ? result : JSON.parse(result) end From 56f1ec3e1c48587cf4a62c15a3ac7e3d146dc3f6 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 11 Jan 2025 12:49:43 -0500 Subject: [PATCH 5/9] Revert previous commit, can unlock through CLI --- lib/kamal/secrets/adapters/bitwarden.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/kamal/secrets/adapters/bitwarden.rb b/lib/kamal/secrets/adapters/bitwarden.rb index 511871171..03a51f3f3 100644 --- a/lib/kamal/secrets/adapters/bitwarden.rb +++ b/lib/kamal/secrets/adapters/bitwarden.rb @@ -65,8 +65,7 @@ def signedin?(account) end def run_command(command, session: nil, raw: false) - system("BW_SESSION=", session) if session - full_command = [ "bw", command ].join(" ") + full_command = [ *("BW_SESSION=#{session.shellescape}" if session), "bw", command ].join(" ") result = `#{full_command}`.strip raw ? result : JSON.parse(result) end From cf650fbc8c70fbb0f5ccd46154ebd1ecfefcc7fa Mon Sep 17 00:00:00 2001 From: Kevin Date: Mon, 13 Jan 2025 18:25:07 -0500 Subject: [PATCH 6/9] swapping positions and defaults for stub_command_with to make more sense, could use bool instead, but having a symbol leaves stub open to other command formats in the future --- test/secrets/aws_secrets_manager_adapter_test.rb | 2 +- test/secrets/bitwarden_adapter_test.rb | 2 +- test/secrets/doppler_adapter_test.rb | 16 ++++++++-------- test/secrets/last_pass_adapter_test.rb | 6 +++--- test/secrets/one_password_adapter_test.rb | 10 +++++----- test/test_helper.rb | 4 ++-- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/test/secrets/aws_secrets_manager_adapter_test.rb b/test/secrets/aws_secrets_manager_adapter_test.rb index 0cf6a625a..9a051c8fd 100644 --- a/test/secrets/aws_secrets_manager_adapter_test.rb +++ b/test/secrets/aws_secrets_manager_adapter_test.rb @@ -148,7 +148,7 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_command_with("aws --version", :system, false) + stub_command_with("aws --version", false) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "SECRET1"))) diff --git a/test/secrets/bitwarden_adapter_test.rb b/test/secrets/bitwarden_adapter_test.rb index 12e6d2b24..e16562b43 100644 --- a/test/secrets/bitwarden_adapter_test.rb +++ b/test/secrets/bitwarden_adapter_test.rb @@ -183,7 +183,7 @@ class BitwardenAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_command_with("bw --version", :system, false) + stub_command_with("bw --version", false, :system) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "mynote"))) diff --git a/test/secrets/doppler_adapter_test.rb b/test/secrets/doppler_adapter_test.rb index c401ef8fc..01b3896cc 100644 --- a/test/secrets/doppler_adapter_test.rb +++ b/test/secrets/doppler_adapter_test.rb @@ -6,7 +6,7 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch" do - stub_command_with("doppler --version", :system, true) + stub_command_with("doppler --version") stub_command(:system).with("doppler me --json", err: File::NULL) stub_command @@ -47,7 +47,7 @@ class DopplerAdapterTest < SecretAdapterTestCase test "fetch having DOPPLER_TOKEN" do ENV["DOPPLER_TOKEN"] = "dp.st.xxxxxxxxxxxxxxxxxxxxxx" - stub_command_with("doppler --version", :system, true) + stub_command_with("doppler --version") stub_command(:system).with("doppler me --json", err: File::NULL) stub_command @@ -88,7 +88,7 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch with folder in secret" do - stub_command_with("doppler --version", :system, true) + stub_command_with("doppler --version") stub_command(:system).with("doppler me --json", err: File::NULL) stub_command @@ -127,7 +127,7 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch without --from" do - stub_command_with("doppler --version", :system, true) + stub_command_with("doppler --version") stub_command(:system).with("doppler me --json", err: File::NULL) error = assert_raises RuntimeError do @@ -138,9 +138,9 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch with signin" do - stub_command_with("doppler --version", :system, true) - stub_command_with("doppler me --json", :system, false) - stub_command_with("doppler login -y", :`, true).returns("") + stub_command_with("doppler --version") + stub_command_with("doppler me --json", false) + stub_command_with("doppler login -y", true, :`).returns("") stub_command.with("doppler secrets get SECRET1 --json -p my-project -c prd").returns(single_item_json) json = JSON.parse(shellunescape(run_command("fetch", "--from", "my-project/prd", "SECRET1"))) @@ -153,7 +153,7 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_command_with("doppler --version", :system, false) + stub_command_with("doppler --version", false) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "HOST", "PORT"))) diff --git a/test/secrets/last_pass_adapter_test.rb b/test/secrets/last_pass_adapter_test.rb index 34e025c05..4d4d8e8dc 100644 --- a/test/secrets/last_pass_adapter_test.rb +++ b/test/secrets/last_pass_adapter_test.rb @@ -111,8 +111,8 @@ class LastPassAdapterTest < SecretAdapterTestCase test "fetch with signin" do stub_command(:system).with("lpass --version", err: File::NULL) - stub_command_with("lpass status --color never", :`, false).returns("Not logged in.") - stub_command_with("lpass login email@example.com", :`, true).returns("") + stub_command_with("lpass status --color never", false, :`).returns("Not logged in.") + stub_command_with("lpass login email@example.com", true, :`).returns("") stub_command.with("lpass show SECRET1 --json").returns(single_item_json) json = JSON.parse(shellunescape(run_command("fetch", "SECRET1"))) @@ -125,7 +125,7 @@ class LastPassAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_command_with("lpass --version", :system, false) + stub_command_with("lpass --version", false) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "SECRET1", "FOLDER1/FSECRET1", "FOLDER1/FSECRET2"))) diff --git a/test/secrets/one_password_adapter_test.rb b/test/secrets/one_password_adapter_test.rb index c7730235c..514cae071 100644 --- a/test/secrets/one_password_adapter_test.rb +++ b/test/secrets/one_password_adapter_test.rb @@ -119,8 +119,8 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase test "fetch with signin, no session" do stub_command(:system).with("op --version", err: File::NULL) - stub_command_with("op account get --account myaccount", :system, false) - stub_command_with("op signin --account \"myaccount\" --force --raw", :`, true).returns("") + stub_command_with("op account get --account myaccount", false) + stub_command_with("op signin --account \"myaccount\" --force --raw", true, :`).returns("") stub_command .with("op item get myitem --vault \"myvault\" --fields \"label=section.SECRET1\" --format \"json\" --account \"myaccount\"") @@ -138,8 +138,8 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase test "fetch with signin and session" do stub_command(:system).with("op --version", err: File::NULL) - stub_command_with("op account get --account myaccount", :system, false) - stub_command_with("op signin --account \"myaccount\" --force --raw", :`, true).returns("1234567890") + stub_command_with("op account get --account myaccount", false) + stub_command_with("op signin --account \"myaccount\" --force --raw", true, :`).returns("1234567890") stub_command .with("op item get myitem --vault \"myvault\" --fields \"label=section.SECRET1\" --format \"json\" --account \"myaccount\" --session \"1234567890\"") @@ -155,7 +155,7 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_command_with("op --version", :system, false) + stub_command_with("op --version", false) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "--from", "op://myvault/myitem", "section/SECRET1", "section/SECRET2", "section2/SECRET3"))) diff --git a/test/test_helper.rb b/test/test_helper.rb index e06fb3800..f652c52e8 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -80,10 +80,10 @@ class SecretAdapterTestCase < ActiveSupport::TestCase private def stub_command(format = :`) - Kamal::Secrets::Adapters::Base.any_instance.stubs(format) + Kamal::Secrets::Adapters::Base.any_instance.stubs(:`) end - def stub_command_with(command, format = :`, succeed = true) + def stub_command_with(command, succeed = true, format = :system) # Sneakily run `exit 1`/`exit 0` after a match to set $? to 1/0 stub_command(format).with { |c| c == command && (succeed ? `exit 0` : `exit 1`) } Kamal::Secrets::Adapters::Base.any_instance.stubs(format) From 65e2db25ade43baf9cabd028dafabb5a71c8ff9d Mon Sep 17 00:00:00 2001 From: Kevin Date: Wed, 29 Jan 2025 17:26:35 -0500 Subject: [PATCH 7/9] fixing error in stub_command function, applying change to new secret managers --- .../adapters/bitwarden_secrets_manager.rb | 2 +- lib/kamal/secrets/adapters/enpass.rb | 2 +- .../secrets/adapters/gcp_secret_manager.rb | 2 +- .../aws_secrets_manager_adapter_test.rb | 2 +- .../bitwarden_secrets_manager_adapter_test.rb | 36 +++++++++---------- test/secrets/doppler_adapter_test.rb | 16 ++++----- test/secrets/enpass_adapter_test.rb | 14 ++++---- .../gcp_secret_manager_adapter_test.rb | 19 +++++----- test/secrets/last_pass_adapter_test.rb | 6 ++-- test/secrets/one_password_adapter_test.rb | 10 +++--- test/test_helper.rb | 4 +-- 11 files changed, 56 insertions(+), 57 deletions(-) diff --git a/lib/kamal/secrets/adapters/bitwarden_secrets_manager.rb b/lib/kamal/secrets/adapters/bitwarden_secrets_manager.rb index 66afbe70a..789f38d0f 100644 --- a/lib/kamal/secrets/adapters/bitwarden_secrets_manager.rb +++ b/lib/kamal/secrets/adapters/bitwarden_secrets_manager.rb @@ -66,7 +66,7 @@ def check_dependencies! end def cli_installed? - `bws --version 2> /dev/null` + system("bws --version", err: File::NULL) $?.success? end end diff --git a/lib/kamal/secrets/adapters/enpass.rb b/lib/kamal/secrets/adapters/enpass.rb index 96dea11a5..272c8c0a2 100644 --- a/lib/kamal/secrets/adapters/enpass.rb +++ b/lib/kamal/secrets/adapters/enpass.rb @@ -27,7 +27,7 @@ def check_dependencies! end def cli_installed? - `enpass-cli version 2> /dev/null` + system("enpass-cli version", err: File::NULL) $?.success? end diff --git a/lib/kamal/secrets/adapters/gcp_secret_manager.rb b/lib/kamal/secrets/adapters/gcp_secret_manager.rb index 8ce381ff2..9c75438b0 100644 --- a/lib/kamal/secrets/adapters/gcp_secret_manager.rb +++ b/lib/kamal/secrets/adapters/gcp_secret_manager.rb @@ -94,7 +94,7 @@ def check_dependencies! end def cli_installed? - `gcloud --version 2> /dev/null` + system("gcloud --version", err: File::NULL) $?.success? end diff --git a/test/secrets/aws_secrets_manager_adapter_test.rb b/test/secrets/aws_secrets_manager_adapter_test.rb index 9a051c8fd..d40a88680 100644 --- a/test/secrets/aws_secrets_manager_adapter_test.rb +++ b/test/secrets/aws_secrets_manager_adapter_test.rb @@ -148,7 +148,7 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_command_with("aws --version", false) + stub_command_with("aws --version", false, :system) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "SECRET1"))) diff --git a/test/secrets/bitwarden_secrets_manager_adapter_test.rb b/test/secrets/bitwarden_secrets_manager_adapter_test.rb index 1723da420..05dba4d50 100644 --- a/test/secrets/bitwarden_secrets_manager_adapter_test.rb +++ b/test/secrets/bitwarden_secrets_manager_adapter_test.rb @@ -2,7 +2,7 @@ class BitwardenSecretsManagerAdapterTest < SecretAdapterTestCase test "fetch with no parameters" do - stub_ticks.with("bws --version 2> /dev/null") + stub_command(:system).with("bws --version", err: File::NULL) stub_login error = assert_raises RuntimeError do @@ -12,9 +12,9 @@ class BitwardenSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch all" do - stub_ticks.with("bws --version 2> /dev/null") + stub_command(:system).with("bws --version", err: File::NULL) stub_login - stub_ticks + stub_command .with("bws secret list -o env") .returns("KAMAL_REGISTRY_PASSWORD=\"some_password\"\nMY_OTHER_SECRET=\"my=weird\"secret\"") @@ -24,9 +24,9 @@ class BitwardenSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch all with from" do - stub_ticks.with("bws --version 2> /dev/null") + stub_command(:system).with("bws --version", err: File::NULL) stub_login - stub_ticks + stub_command .with("bws secret list -o env 82aeb5bd-6958-4a89-8197-eacab758acce") .returns("KAMAL_REGISTRY_PASSWORD=\"some_password\"\nMY_OTHER_SECRET=\"my=weird\"secret\"") @@ -36,9 +36,9 @@ class BitwardenSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch item" do - stub_ticks.with("bws --version 2> /dev/null") + stub_command(:system).with("bws --version", err: File::NULL) stub_login - stub_ticks + stub_command .with("bws secret get -o env 82aeb5bd-6958-4a89-8197-eacab758acce") .returns("KAMAL_REGISTRY_PASSWORD=\"some_password\"") @@ -48,12 +48,12 @@ class BitwardenSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch with multiple items" do - stub_ticks.with("bws --version 2> /dev/null") + stub_command(:system).with("bws --version", err: File::NULL) stub_login - stub_ticks + stub_command .with("bws secret get -o env 82aeb5bd-6958-4a89-8197-eacab758acce") .returns("KAMAL_REGISTRY_PASSWORD=\"some_password\"") - stub_ticks + stub_command .with("bws secret get -o env 6f8cdf27-de2b-4c77-a35d-07df8050e332") .returns("MY_OTHER_SECRET=\"my=weird\"secret\"") @@ -63,9 +63,9 @@ class BitwardenSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch all empty" do - stub_ticks.with("bws --version 2> /dev/null") + stub_command(:system).with("bws --version", err: File::NULL) stub_login - stub_ticks_with("bws secret list -o env", succeed: false).returns("Error:\n0: Received error message from server") + stub_command_with("bws secret list -o env").returns("Error:\n0: Received error message from server") error = assert_raises RuntimeError do (shellunescape(run_command("fetch", "all"))) @@ -74,9 +74,9 @@ class BitwardenSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch nonexistent item" do - stub_ticks.with("bws --version 2> /dev/null") + stub_command(:system).with("bws --version", err: File::NULL) stub_login - stub_ticks_with("bws secret get -o env 82aeb5bd-6958-4a89-8197-eacab758acce", succeed: false) + stub_command_with("bws secret get -o env 82aeb5bd-6958-4a89-8197-eacab758acce") .returns("ERROR (RuntimeError): Could not read 82aeb5bd-6958-4a89-8197-eacab758acce from Bitwarden Secrets Manager") error = assert_raises RuntimeError do @@ -86,8 +86,8 @@ class BitwardenSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch with no access token" do - stub_ticks.with("bws --version 2> /dev/null") - stub_ticks_with("bws run 'echo OK'", succeed: false) + stub_command(:system).with("bws --version", err: File::NULL) + stub_command_with("bws run 'echo OK'") error = assert_raises RuntimeError do (shellunescape(run_command("fetch", "all"))) @@ -96,7 +96,7 @@ class BitwardenSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_ticks_with("bws --version 2> /dev/null", succeed: false) + stub_command_with("bws --version", false, :system) error = assert_raises RuntimeError do shellunescape(run_command("fetch")) @@ -106,7 +106,7 @@ class BitwardenSecretsManagerAdapterTest < SecretAdapterTestCase private def stub_login - stub_ticks.with("bws run 'echo OK'").returns("OK") + stub_command.with("bws run 'echo OK'").returns("OK") end def run_command(*command) diff --git a/test/secrets/doppler_adapter_test.rb b/test/secrets/doppler_adapter_test.rb index 01b3896cc..062f8e79e 100644 --- a/test/secrets/doppler_adapter_test.rb +++ b/test/secrets/doppler_adapter_test.rb @@ -6,7 +6,7 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch" do - stub_command_with("doppler --version") + stub_command_with("doppler --version", true, :system) stub_command(:system).with("doppler me --json", err: File::NULL) stub_command @@ -47,7 +47,7 @@ class DopplerAdapterTest < SecretAdapterTestCase test "fetch having DOPPLER_TOKEN" do ENV["DOPPLER_TOKEN"] = "dp.st.xxxxxxxxxxxxxxxxxxxxxx" - stub_command_with("doppler --version") + stub_command_with("doppler --version", true, :system) stub_command(:system).with("doppler me --json", err: File::NULL) stub_command @@ -88,7 +88,7 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch with folder in secret" do - stub_command_with("doppler --version") + stub_command_with("doppler --version", true, :system) stub_command(:system).with("doppler me --json", err: File::NULL) stub_command @@ -127,7 +127,7 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch without --from" do - stub_command_with("doppler --version") + stub_command_with("doppler --version", true, :system) stub_command(:system).with("doppler me --json", err: File::NULL) error = assert_raises RuntimeError do @@ -138,9 +138,9 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch with signin" do - stub_command_with("doppler --version") - stub_command_with("doppler me --json", false) - stub_command_with("doppler login -y", true, :`).returns("") + stub_command_with("doppler --version", true, :system) + stub_command_with("doppler me --json") + stub_command_with("doppler login -y", true).returns("") stub_command.with("doppler secrets get SECRET1 --json -p my-project -c prd").returns(single_item_json) json = JSON.parse(shellunescape(run_command("fetch", "--from", "my-project/prd", "SECRET1"))) @@ -153,7 +153,7 @@ class DopplerAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_command_with("doppler --version", false) + stub_command_with("doppler --version", false, :system) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "HOST", "PORT"))) diff --git a/test/secrets/enpass_adapter_test.rb b/test/secrets/enpass_adapter_test.rb index edc49613c..6be0a4f3f 100644 --- a/test/secrets/enpass_adapter_test.rb +++ b/test/secrets/enpass_adapter_test.rb @@ -2,7 +2,7 @@ class EnpassAdapterTest < SecretAdapterTestCase test "fetch without CLI installed" do - stub_ticks_with("enpass-cli version 2> /dev/null", succeed: false) + stub_command_with("enpass-cli version", false, :system) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "mynote"))) @@ -12,9 +12,9 @@ class EnpassAdapterTest < SecretAdapterTestCase end test "fetch one item" do - stub_ticks_with("enpass-cli version 2> /dev/null") + stub_command_with("enpass-cli version", true, :system) - stub_ticks + stub_command .with("enpass-cli -json -vault vault-path show FooBar") .returns(<<~JSON) [{"category":"computer","label":"SECRET_1","login":"","password":"my-password-1","title":"FooBar","type":"password"}] @@ -28,9 +28,9 @@ class EnpassAdapterTest < SecretAdapterTestCase end test "fetch multiple items" do - stub_ticks_with("enpass-cli version 2> /dev/null") + stub_command_with("enpass-cli version", true, :system) - stub_ticks + stub_command .with("enpass-cli -json -vault vault-path show FooBar") .returns(<<~JSON) [ @@ -48,9 +48,9 @@ class EnpassAdapterTest < SecretAdapterTestCase end test "fetch all with from" do - stub_ticks_with("enpass-cli version 2> /dev/null") + stub_command_with("enpass-cli version", true, :system) - stub_ticks + stub_command .with("enpass-cli -json -vault vault-path show FooBar") .returns(<<~JSON) [ diff --git a/test/secrets/gcp_secret_manager_adapter_test.rb b/test/secrets/gcp_secret_manager_adapter_test.rb index 682db1f48..82e88e8e8 100644 --- a/test/secrets/gcp_secret_manager_adapter_test.rb +++ b/test/secrets/gcp_secret_manager_adapter_test.rb @@ -14,8 +14,7 @@ class GcpSecretManagerAdapterTest < SecretAdapterTestCase end test "fetch unauthenticated" do - stub_ticks.with("gcloud --version 2> /dev/null") - + stub_gcloud_version stub_mypassword stub_unauthenticated @@ -129,7 +128,7 @@ class GcpSecretManagerAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_gcloud_version(succeed: false) + stub_gcloud_version(false) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "item1"))) @@ -148,12 +147,12 @@ def run_command(*command, account: "default") end end - def stub_gcloud_version(succeed: true) - stub_ticks_with("gcloud --version 2> /dev/null", succeed: succeed) + def stub_gcloud_version(succeed = true) + stub_command_with("gcloud --version", succeed, :system) end def stub_authenticated - stub_ticks + stub_command .with("gcloud auth list --format=json") .returns(<<~JSON) [ @@ -166,11 +165,11 @@ def stub_authenticated end def stub_unauthenticated - stub_ticks + stub_command .with("gcloud auth list --format=json") .returns("[]") - stub_ticks + stub_command .with("gcloud auth login") .returns(<<~JSON) { @@ -181,7 +180,7 @@ def stub_unauthenticated end def stub_mypassword - stub_ticks + stub_command .with("gcloud secrets versions access latest --secret=mypassword --format=json") .returns(<<~JSON) { @@ -200,7 +199,7 @@ def stub_items(n, project: nil, account: nil, version: "latest", impersonate_ser { data: "c2VjcmV0Mg==", checksum: 2101741365 }, { data: "c2VjcmV0Mw==", checksum: 2402124854 } ] - stub_ticks + stub_command .with("gcloud secrets versions access #{version} " \ "--secret=item#{n + 1}" \ "#{" --project=#{project}" if project}" \ diff --git a/test/secrets/last_pass_adapter_test.rb b/test/secrets/last_pass_adapter_test.rb index 4d4d8e8dc..5dc5be404 100644 --- a/test/secrets/last_pass_adapter_test.rb +++ b/test/secrets/last_pass_adapter_test.rb @@ -111,8 +111,8 @@ class LastPassAdapterTest < SecretAdapterTestCase test "fetch with signin" do stub_command(:system).with("lpass --version", err: File::NULL) - stub_command_with("lpass status --color never", false, :`).returns("Not logged in.") - stub_command_with("lpass login email@example.com", true, :`).returns("") + stub_command_with("lpass status --color never").returns("Not logged in.") + stub_command_with("lpass login email@example.com", true).returns("") stub_command.with("lpass show SECRET1 --json").returns(single_item_json) json = JSON.parse(shellunescape(run_command("fetch", "SECRET1"))) @@ -125,7 +125,7 @@ class LastPassAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_command_with("lpass --version", false) + stub_command_with("lpass --version", false, :system) error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "SECRET1", "FOLDER1/FSECRET1", "FOLDER1/FSECRET2"))) diff --git a/test/secrets/one_password_adapter_test.rb b/test/secrets/one_password_adapter_test.rb index 514cae071..fd04e6d1b 100644 --- a/test/secrets/one_password_adapter_test.rb +++ b/test/secrets/one_password_adapter_test.rb @@ -119,8 +119,8 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase test "fetch with signin, no session" do stub_command(:system).with("op --version", err: File::NULL) - stub_command_with("op account get --account myaccount", false) - stub_command_with("op signin --account \"myaccount\" --force --raw", true, :`).returns("") + stub_command_with("op account get --account myaccount", false, :system) + stub_command_with("op signin --account \"myaccount\" --force --raw", true).returns("") stub_command .with("op item get myitem --vault \"myvault\" --fields \"label=section.SECRET1\" --format \"json\" --account \"myaccount\"") @@ -138,8 +138,8 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase test "fetch with signin and session" do stub_command(:system).with("op --version", err: File::NULL) - stub_command_with("op account get --account myaccount", false) - stub_command_with("op signin --account \"myaccount\" --force --raw", true, :`).returns("1234567890") + stub_command_with("op account get --account myaccount", false, :system) + stub_command_with("op signin --account \"myaccount\" --force --raw", true).returns("1234567890") stub_command .with("op item get myitem --vault \"myvault\" --fields \"label=section.SECRET1\" --format \"json\" --account \"myaccount\" --session \"1234567890\"") @@ -155,7 +155,7 @@ class SecretsOnePasswordAdapterTest < SecretAdapterTestCase end test "fetch without CLI installed" do - stub_command_with("op --version", false) + stub_command_with("op --version") error = assert_raises RuntimeError do JSON.parse(shellunescape(run_command("fetch", "--from", "op://myvault/myitem", "section/SECRET1", "section/SECRET2", "section2/SECRET3"))) diff --git a/test/test_helper.rb b/test/test_helper.rb index f652c52e8..55e9e75e3 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -80,10 +80,10 @@ class SecretAdapterTestCase < ActiveSupport::TestCase private def stub_command(format = :`) - Kamal::Secrets::Adapters::Base.any_instance.stubs(:`) + Kamal::Secrets::Adapters::Base.any_instance.stubs(format) end - def stub_command_with(command, succeed = true, format = :system) + def stub_command_with(command, succeed = false, format = :`) # Sneakily run `exit 1`/`exit 0` after a match to set $? to 1/0 stub_command(format).with { |c| c == command && (succeed ? `exit 0` : `exit 1`) } Kamal::Secrets::Adapters::Base.any_instance.stubs(format) From d631a8d1ab7285c8a3071dfe73581d00be9a9c3f Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 17 May 2025 12:06:51 -0400 Subject: [PATCH 8/9] fixing additional issue referencing old function --- test/secrets/aws_secrets_manager_adapter_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/secrets/aws_secrets_manager_adapter_test.rb b/test/secrets/aws_secrets_manager_adapter_test.rb index 9332b0624..62a0a03a3 100644 --- a/test/secrets/aws_secrets_manager_adapter_test.rb +++ b/test/secrets/aws_secrets_manager_adapter_test.rb @@ -157,8 +157,8 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase end test "fetch without account option omits --profile" do - stub_ticks.with("aws --version 2> /dev/null") - stub_ticks + stub_command(:system).with("aws --version", err: File::NULL) + stub_command .with("aws secretsmanager batch-get-secret-value --secret-id-list secret/KEY1 secret/KEY2 --output json") .returns(<<~JSON) { From e0eb7b51328dd5053118f4c07084f11821c329ab Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 17 May 2025 12:45:17 -0400 Subject: [PATCH 9/9] fixing linting errors --- test/secrets/aws_secrets_manager_adapter_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/secrets/aws_secrets_manager_adapter_test.rb b/test/secrets/aws_secrets_manager_adapter_test.rb index 62a0a03a3..e235e2fe9 100644 --- a/test/secrets/aws_secrets_manager_adapter_test.rb +++ b/test/secrets/aws_secrets_manager_adapter_test.rb @@ -27,7 +27,7 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase JSON.parse(shellunescape(run_command("fetch", "unknown1", "unknown2"))) end - assert_equal ["unknown1: Secrets Manager can't find the specified secret.", "unknown2: Secrets Manager can't find the specified secret."].join(" "), error.message + assert_equal [ "unknown1: Secrets Manager can't find the specified secret.", "unknown2: Secrets Manager can't find the specified secret." ].join(" "), error.message end test "fetch" do @@ -191,10 +191,10 @@ class AwsSecretsManagerAdapterTest < SecretAdapterTestCase def run_command(*command, account: "default") stdouted do - args = [*command, + args = [ *command, "-c", "test/fixtures/deploy_with_accessories.yml", - "--adapter", "aws_secrets_manager"] - args += ["--account", account] if account + "--adapter", "aws_secrets_manager" ] + args += [ "--account", account ] if account Kamal::Cli::Secrets.start(args) end end