From bb6ec8c05ed2b43d53bcd8ba4d16c65f8b42ecfe Mon Sep 17 00:00:00 2001 From: Fran Zekan Date: Tue, 27 Jun 2023 14:10:42 +0200 Subject: [PATCH 1/2] Ignore .vscode/.idea folders --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 6100dc73..80e6a543 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ coverage/* .DS_Store gemfiles/*.lock +.vscode/ +.idea/ \ No newline at end of file From c5ec8b15159614db06905a7b396baeaf6d3b01b8 Mon Sep 17 00:00:00 2001 From: Fran Zekan Date: Tue, 27 Jun 2023 14:11:06 +0200 Subject: [PATCH 2/2] Wip add base logic for optional secrets --- lib/mrsk/configuration/role.rb | 17 ++++++++++++++--- lib/mrsk/utils.rb | 14 ++++++++++++-- test/utils_test.rb | 16 ++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/lib/mrsk/configuration/role.rb b/lib/mrsk/configuration/role.rb index 048efe16..fecf2687 100644 --- a/lib/mrsk/configuration/role.rb +++ b/lib/mrsk/configuration/role.rb @@ -139,16 +139,27 @@ def merged_env # Secrets are stored in an array, which won't merge by default, so have to do it by hand. def merged_env_with_secrets merged_env.tap do |new_env| - new_env["secret"] = Array(config.env["secret"]) + Array(specialized_env["secret"]) - # If there's no secret/clear split, everything is clear clear_app_env = config.env["secret"] ? Array(config.env["clear"]) : Array(config.env["clear"] || config.env) clear_role_env = specialized_env["secret"] ? Array(specialized_env["clear"]) : Array(specialized_env["clear"] || specialized_env) - new_env["clear"] = (clear_app_env + clear_role_env).uniq + + secrets_app_env = Array(config.env["secret"]) + secrets_role_env = Array(specialized_env["secret"]) + new_env["secret"] = (secrets_app_env + secrets_role_env).uniq.filter { |secret| filter_secret_env(secret, new_env) } end end + def filter_secret_env(secret, new_env) + # allow clear to override secret + return false if new_env['clear'].include?(secret) + + # if we find FOO but FOO? exists, we keep the FOO? + return false if !secret.end_with?('?') && new_env['secret'].include?("#{secret}?") + + true + end + def http_health_check(port:, path:) "curl -f #{URI.join("http://localhost:#{port}", path)} || exit 1" if path.present? || port.present? end diff --git a/lib/mrsk/utils.rb b/lib/mrsk/utils.rb index e463f547..a3c43082 100644 --- a/lib/mrsk/utils.rb +++ b/lib/mrsk/utils.rb @@ -20,12 +20,22 @@ def argumentize(argument, attributes, sensitive: false) # but redacts and expands secrets. def argumentize_env_with_secrets(env) if (secrets = env["secret"]).present? - argumentize("-e", secrets.to_h { |key| [ key, ENV.fetch(key) ] }, sensitive: true) + argumentize("-e", env["clear"]) + argumentize("-e", handle_optional_secrets(secrets), sensitive: true) + argumentize("-e", env["clear"]) else - argumentize "-e", env.fetch("clear", env) + argumentize("-e", env.fetch("clear", env)) end end + def handle_optional_secrets(secrets) + secrets.to_h do |key| + if key.end_with? '?' + [ key.chop, ENV[key.chop] ] + else + [ key, ENV.fetch(key) ] + end + end.compact + end + # Returns a list of shell-dashed option arguments. If the value is true, it's treated like a value-less option. def optionize(args, with: nil) options = if with diff --git a/test/utils_test.rb b/test/utils_test.rb index 24a1b96b..0c067ae0 100644 --- a/test/utils_test.rb +++ b/test/utils_test.rb @@ -20,6 +20,22 @@ class UtilsTest < ActiveSupport::TestCase assert_equal [ "-e", "FOO=\"secret\"", "-e", "BAZ=\"qux\"" ], Mrsk::Utils.unredacted(args) end + test "argumentize_env_with_secrets with optional" do + ENV.expects(:[]).with("FOO").returns('secret') + + args = Mrsk::Utils.argumentize_env_with_secrets({ "secret" => [ "FOO?" ], "clear" => { BAZ: "qux" } }) + + assert_equal [ "-e", "FOO=[REDACTED]", "-e", "BAZ=\"qux\"" ], Mrsk::Utils.redacted(args) + assert_equal [ "-e", "FOO=\"secret\"", "-e", "BAZ=\"qux\"" ], Mrsk::Utils.unredacted(args) + end + + test "argumentize_env_with_secrets with missing optional" do + args = Mrsk::Utils.argumentize_env_with_secrets({ "secret" => [ "FOO?" ], "clear" => { BAZ: "qux" } }) + + assert_equal [ "-e", "BAZ=\"qux\"" ], Mrsk::Utils.redacted(args) + assert_equal [ "-e", "BAZ=\"qux\"" ], Mrsk::Utils.unredacted(args) + end + test "optionize" do assert_equal [ "--foo", "\"bar\"", "--baz", "\"qux\"", "--quux" ], \ Mrsk::Utils.optionize({ foo: "bar", baz: "qux", quux: true })