Merge pull request #1236 from andrelaszlo/gcp_secret_manager_adapter
Add GCP Secret Manager adapter
This commit is contained in:
220
test/secrets/gcp_secret_manager_adapter_test.rb
Normal file
220
test/secrets/gcp_secret_manager_adapter_test.rb
Normal file
@@ -0,0 +1,220 @@
|
||||
require "test_helper"
|
||||
|
||||
class GcpSecretManagerAdapterTest < SecretAdapterTestCase
|
||||
test "fetch" do
|
||||
stub_gcloud_version
|
||||
stub_authenticated
|
||||
stub_mypassword
|
||||
|
||||
json = JSON.parse(shellunescape(run_command("fetch", "mypassword")))
|
||||
|
||||
expected_json = { "default/mypassword"=>"secret123" }
|
||||
|
||||
assert_equal expected_json, json
|
||||
end
|
||||
|
||||
test "fetch unauthenticated" do
|
||||
stub_ticks.with("gcloud --version 2> /dev/null")
|
||||
|
||||
stub_mypassword
|
||||
stub_unauthenticated
|
||||
|
||||
error = assert_raises RuntimeError do
|
||||
JSON.parse(shellunescape(run_command("fetch", "mypassword")))
|
||||
end
|
||||
|
||||
assert_match(/not authenticated/, error.message)
|
||||
end
|
||||
|
||||
test "fetch with from" do
|
||||
stub_gcloud_version
|
||||
stub_authenticated
|
||||
stub_items(0, project: "other-project")
|
||||
stub_items(1, project: "other-project")
|
||||
stub_items(2, project: "other-project")
|
||||
|
||||
json = JSON.parse(shellunescape(run_command("fetch", "--from", "other-project", "item1", "item2", "item3")))
|
||||
|
||||
expected_json = {
|
||||
"other-project/item1"=>"secret1", "other-project/item2"=>"secret2", "other-project/item3"=>"secret3"
|
||||
}
|
||||
|
||||
assert_equal expected_json, json
|
||||
end
|
||||
|
||||
test "fetch with multiple projects" do
|
||||
stub_gcloud_version
|
||||
stub_authenticated
|
||||
stub_items(0, project: "some-project")
|
||||
stub_items(1, project: "project-confidence")
|
||||
stub_items(2, project: "manhattan-project")
|
||||
|
||||
json = JSON.parse(shellunescape(run_command("fetch", "some-project/item1", "project-confidence/item2", "manhattan-project/item3")))
|
||||
|
||||
expected_json = {
|
||||
"some-project/item1"=>"secret1", "project-confidence/item2"=>"secret2", "manhattan-project/item3"=>"secret3"
|
||||
}
|
||||
|
||||
assert_equal expected_json, json
|
||||
end
|
||||
|
||||
test "fetch with specific version" do
|
||||
stub_gcloud_version
|
||||
stub_authenticated
|
||||
stub_items(0, project: "some-project", version: "123")
|
||||
|
||||
json = JSON.parse(shellunescape(run_command("fetch", "some-project/item1/123")))
|
||||
|
||||
expected_json = {
|
||||
"some-project/item1"=>"secret1"
|
||||
}
|
||||
|
||||
assert_equal expected_json, json
|
||||
end
|
||||
|
||||
test "fetch with non-default account" do
|
||||
stub_gcloud_version
|
||||
stub_authenticated
|
||||
stub_items(0, project: "some-project", version: "123", account: "email@example.com")
|
||||
|
||||
json = JSON.parse(shellunescape(run_command("fetch", "some-project/item1/123", account: "email@example.com")))
|
||||
|
||||
expected_json = {
|
||||
"some-project/item1"=>"secret1"
|
||||
}
|
||||
|
||||
assert_equal expected_json, json
|
||||
end
|
||||
|
||||
test "fetch with service account impersonation" do
|
||||
stub_gcloud_version
|
||||
stub_authenticated
|
||||
stub_items(0, project: "some-project", version: "123", impersonate_service_account: "service-user@example.com")
|
||||
|
||||
json = JSON.parse(shellunescape(run_command("fetch", "some-project/item1/123", account: "default|service-user@example.com")))
|
||||
|
||||
expected_json = {
|
||||
"some-project/item1"=>"secret1"
|
||||
}
|
||||
|
||||
assert_equal expected_json, json
|
||||
end
|
||||
|
||||
test "fetch with delegation chain and specific user" do
|
||||
stub_gcloud_version
|
||||
stub_authenticated
|
||||
stub_items(0, project: "some-project", version: "123", account: "user@example.com", impersonate_service_account: "service-user@example.com,service-user2@example.com")
|
||||
|
||||
json = JSON.parse(shellunescape(run_command("fetch", "some-project/item1/123", account: "user@example.com|service-user@example.com,service-user2@example.com")))
|
||||
|
||||
expected_json = {
|
||||
"some-project/item1"=>"secret1"
|
||||
}
|
||||
|
||||
assert_equal expected_json, json
|
||||
end
|
||||
|
||||
test "fetch with non-default account and service account impersonation" do
|
||||
stub_gcloud_version
|
||||
stub_authenticated
|
||||
stub_items(0, project: "some-project", version: "123", account: "email@example.com", impersonate_service_account: "service-user@example.com")
|
||||
|
||||
json = JSON.parse(shellunescape(run_command("fetch", "some-project/item1/123", account: "email@example.com|service-user@example.com")))
|
||||
|
||||
expected_json = {
|
||||
"some-project/item1"=>"secret1"
|
||||
}
|
||||
|
||||
assert_equal expected_json, json
|
||||
end
|
||||
|
||||
test "fetch without CLI installed" do
|
||||
stub_gcloud_version(succeed: false)
|
||||
|
||||
error = assert_raises RuntimeError do
|
||||
JSON.parse(shellunescape(run_command("fetch", "item1")))
|
||||
end
|
||||
assert_equal "gcloud CLI is not installed", error.message
|
||||
end
|
||||
|
||||
private
|
||||
def run_command(*command, account: "default")
|
||||
stdouted do
|
||||
Kamal::Cli::Secrets.start \
|
||||
[ *command,
|
||||
"-c", "test/fixtures/deploy_with_accessories.yml",
|
||||
"--adapter", "gcp_secret_manager",
|
||||
"--account", account ]
|
||||
end
|
||||
end
|
||||
|
||||
def stub_gcloud_version(succeed: true)
|
||||
stub_ticks_with("gcloud --version 2> /dev/null", succeed: succeed)
|
||||
end
|
||||
|
||||
def stub_authenticated
|
||||
stub_ticks
|
||||
.with("gcloud auth list --format=json")
|
||||
.returns(<<~JSON)
|
||||
[
|
||||
{
|
||||
"account": "email@example.com",
|
||||
"status": "ACTIVE"
|
||||
}
|
||||
]
|
||||
JSON
|
||||
end
|
||||
|
||||
def stub_unauthenticated
|
||||
stub_ticks
|
||||
.with("gcloud auth list --format=json")
|
||||
.returns("[]")
|
||||
|
||||
stub_ticks
|
||||
.with("gcloud auth login")
|
||||
.returns(<<~JSON)
|
||||
{
|
||||
"expired": false,
|
||||
"valid": true
|
||||
}
|
||||
JSON
|
||||
end
|
||||
|
||||
def stub_mypassword
|
||||
stub_ticks
|
||||
.with("gcloud secrets versions access latest --secret=mypassword --format=json")
|
||||
.returns(<<~JSON)
|
||||
{
|
||||
"name": "projects/000000000/secrets/mypassword/versions/1",
|
||||
"payload": {
|
||||
"data": "c2VjcmV0MTIz",
|
||||
"dataCrc32c": "2522602764"
|
||||
}
|
||||
}
|
||||
JSON
|
||||
end
|
||||
|
||||
def stub_items(n, project: nil, account: nil, version: "latest", impersonate_service_account: nil)
|
||||
payloads = [
|
||||
{ data: "c2VjcmV0MQ==", checksum: 1846998209 },
|
||||
{ data: "c2VjcmV0Mg==", checksum: 2101741365 },
|
||||
{ data: "c2VjcmV0Mw==", checksum: 2402124854 }
|
||||
]
|
||||
stub_ticks
|
||||
.with("gcloud secrets versions access #{version} " \
|
||||
"--secret=item#{n + 1}" \
|
||||
"#{" --project=#{project}" if project}" \
|
||||
"#{" --account=#{account}" if account}" \
|
||||
"#{" --impersonate-service-account=#{impersonate_service_account}" if impersonate_service_account} " \
|
||||
"--format=json")
|
||||
.returns(<<~JSON)
|
||||
{
|
||||
"name": "projects/000000001/secrets/item1/versions/1",
|
||||
"payload": {
|
||||
"data": "#{payloads[n][:data]}",
|
||||
"dataCrc32c": "#{payloads[n][:checksum]}"
|
||||
}
|
||||
}
|
||||
JSON
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user