From 9089c41f30f484b04e208bbc0fe164d0c2cfb026 Mon Sep 17 00:00:00 2001 From: Donal McBreen Date: Wed, 11 Sep 2024 13:38:18 +0100 Subject: [PATCH] Add secrets-common for shared secrets Add a shared secrets file used across all destinations. Useful for things Github tokens or registry passwords. The secrets are added to a new file called `secrets-common` to highlight they are shared, and to avoid acciedentally inheriting a secret from the `secrets` file to `secrets.destination`. --- lib/kamal/secrets.rb | 19 +++++++------------ .../docker/deployer/app/.kamal/secrets | 2 -- .../docker/deployer/app/.kamal/secrets-common | 2 ++ test/secrets_test.rb | 8 ++++++-- 4 files changed, 15 insertions(+), 16 deletions(-) create mode 100644 test/integration/docker/deployer/app/.kamal/secrets-common diff --git a/lib/kamal/secrets.rb b/lib/kamal/secrets.rb index 34d30aaea..2e9dd23dc 100644 --- a/lib/kamal/secrets.rb +++ b/lib/kamal/secrets.rb @@ -1,19 +1,20 @@ require "dotenv" class Kamal::Secrets - attr_reader :secrets_file + attr_reader :secrets_files Kamal::Secrets::Dotenv::InlineCommandSubstitution.install! def initialize(destination: nil) - @secrets_file = [ *(".kamal/secrets.#{destination}" if destination), ".kamal/secrets" ].find { |f| File.exist?(f) } + @secrets_files = \ + [ ".kamal/secrets-common", ".kamal/secrets#{(".#{destination}" if destination)}" ].select { |f| File.exist?(f) } end def [](key) secrets.fetch(key) rescue KeyError - if secrets_file - raise Kamal::ConfigurationError, "Secret '#{key}' not found in #{secrets_file}" + if secrets_files + raise Kamal::ConfigurationError, "Secret '#{key}' not found in #{secrets_files.join(", ")}" else raise Kamal::ConfigurationError, "Secret '#{key}' not found, no secret files provided" end @@ -25,14 +26,8 @@ def to_h private def secrets - @secrets ||= parse_secrets - end - - def parse_secrets - if secrets_file - ::Dotenv.parse(secrets_file) - else - {} + @secrets ||= secrets_files.inject({}) do |secrets, secrets_file| + secrets.merge!(::Dotenv.parse(secrets_file)) end end end diff --git a/test/integration/docker/deployer/app/.kamal/secrets b/test/integration/docker/deployer/app/.kamal/secrets index ee55e94c2..429499ce3 100644 --- a/test/integration/docker/deployer/app/.kamal/secrets +++ b/test/integration/docker/deployer/app/.kamal/secrets @@ -1,5 +1,3 @@ -SECRET_TOKEN='1234 with "中文"' -SECRET_TAG='TAGME' SECRETS=$(kamal secrets fetch --adapter test --account test INTERPOLATED_SECRET1 INTERPOLATED_SECRET2 INTERPOLATED_中文) INTERPOLATED_SECRET1=$(kamal secrets extract INTERPOLATED_SECRET1 ${SECRETS}) INTERPOLATED_SECRET2=$(kamal secrets extract INTERPOLATED_SECRET2 ${SECRETS}) diff --git a/test/integration/docker/deployer/app/.kamal/secrets-common b/test/integration/docker/deployer/app/.kamal/secrets-common new file mode 100644 index 000000000..ea15ab06e --- /dev/null +++ b/test/integration/docker/deployer/app/.kamal/secrets-common @@ -0,0 +1,2 @@ +SECRET_TOKEN='1234 with "中文"' +SECRET_TAG='TAGME' diff --git a/test/secrets_test.rb b/test/secrets_test.rb index 5909b0e12..bb77a1965 100644 --- a/test/secrets_test.rb +++ b/test/secrets_test.rb @@ -21,10 +21,14 @@ class SecretsTest < ActiveSupport::TestCase end test "destinations" do - with_test_secrets("secrets.dest" => "SECRET=DEF", "secrets" => "SECRET=ABC") do + with_test_secrets("secrets.dest" => "SECRET=DEF", "secrets" => "SECRET=ABC", "secrets-common" => "SECRET=GHI\nSECRET2=JKL") do assert_equal "ABC", Kamal::Secrets.new["SECRET"] assert_equal "DEF", Kamal::Secrets.new(destination: "dest")["SECRET"] - assert_equal "ABC", Kamal::Secrets.new(destination: "nodest")["SECRET"] + assert_equal "GHI", Kamal::Secrets.new(destination: "nodest")["SECRET"] + + assert_equal "JKL", Kamal::Secrets.new["SECRET2"] + assert_equal "JKL", Kamal::Secrets.new(destination: "dest")["SECRET2"] + assert_equal "JKL", Kamal::Secrets.new(destination: "nodest")["SECRET2"] end end end