From a28412846907121116c0523971e999b9566c69b5 Mon Sep 17 00:00:00 2001 From: Joe Rafaniello Date: Mon, 9 Dec 2024 17:54:12 -0500 Subject: [PATCH 1/2] Add a shared vcr spec helper for access to secrets We need a way to sanitize actual secrets with fake and consistent values so tests are reliable. This mechanism must allow us to provide overide values with real secrets when we're actually recording new or updated cassettes. For now, we're reusing the existing mechanism of specifying the secrets: * relative to the current directory - we run specs for plugins from the plugin's directory * config/secrets.yml - actual secrets * config/secrets.defaults.yml - defaults for sanitizing real values with consistent repeatable replacements Plugins can use this mechanism by adding: Object.include Spec::Shared::CassetteSecretsHelper to their spec_helper.rb. You can then access these values via helper methods with interfaces like below: default_vcr_secret_by_key_path(:vmware_infra, :hostname) vcr_secret_by_key_path(:vmware_tanzu, :hostname) Each plugin should define their own: config/secrets.default.yml, which can look something like this: ``` --- :vmware_cloud: :host: vmwarecloudhost :userid: VMWARE_CLOUD_USERID :password: VMWARE_CLOUD_PASSWORD :vmware_infra: :hostname: HOSTNAME :vmware_tanzu: :hostname: vmware-tanzu-hostname :userid: VMWARE_TANZU_USERID :password: VMWARE_TANZU_PASSWORD ``` Developers can then copy this file to config/secrets.yml and provide actual values for each of the keys. When recording, the cassettes will use the real values for connecting to environments, but store the resulting placeholder using the fake value for that key from the defaults. --- spec/shared/cassette_secrets_helper.rb | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 spec/shared/cassette_secrets_helper.rb diff --git a/spec/shared/cassette_secrets_helper.rb b/spec/shared/cassette_secrets_helper.rb new file mode 100644 index 00000000000..24e81cfa27f --- /dev/null +++ b/spec/shared/cassette_secrets_helper.rb @@ -0,0 +1,32 @@ +module Spec + module Shared + module CassetteSecretsHelper + DEFAULT_VCR_SECRETS_PATH = Pathname.new(Dir.pwd).join("config/secrets.defaults.yml") + VCR_SECRETS_PATH = Pathname.new(Dir.pwd).join("config/secrets.yml") + + def load_vcr_secrets(pathname) + if pathname.exist? + YAML.load_file(pathname) + else + {} + end + end + + def default_vcr_secrets + @default_vcr_secrets ||= load_vcr_secrets(DEFAULT_VCR_SECRETS_PATH) + end + + def vcr_secrets + @vcr_secrets ||= load_vcr_secrets(VCR_SECRETS_PATH) + end + + def default_vcr_secret_by_key_path(*args) + default_vcr_secrets.dig(*args) + end + + def vcr_secret_by_key_path(*args) + vcr_secrets.dig(*args) || default_vcr_secret_by_key_path(*args) + end + end + end +end From 69cd2d0017960061c87d89d9ae02bc69e7533417 Mon Sep 17 00:00:00 2001 From: Joe Rafaniello Date: Tue, 10 Dec 2024 15:57:05 -0500 Subject: [PATCH 2/2] Extract methods for constants and ensure loads of secrets happen once --- spec/shared/cassette_secrets_helper.rb | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/spec/shared/cassette_secrets_helper.rb b/spec/shared/cassette_secrets_helper.rb index 24e81cfa27f..a7bf76eb488 100644 --- a/spec/shared/cassette_secrets_helper.rb +++ b/spec/shared/cassette_secrets_helper.rb @@ -1,8 +1,15 @@ module Spec module Shared module CassetteSecretsHelper - DEFAULT_VCR_SECRETS_PATH = Pathname.new(Dir.pwd).join("config/secrets.defaults.yml") - VCR_SECRETS_PATH = Pathname.new(Dir.pwd).join("config/secrets.yml") + def default_vcr_secrets_path + Pathname.new(Dir.pwd).join("config/secrets.defaults.yml").tap do |path| + raise "Default vcr cassette secrets not found: #{path}! Create this file with placeholder secrets to be used in cassettes to avoid leaking actual secrets." unless path.exist? + end + end + + def vcr_secrets_path + Pathname.new(Dir.pwd).join("config/secrets.yml") + end def load_vcr_secrets(pathname) if pathname.exist? @@ -13,11 +20,11 @@ def load_vcr_secrets(pathname) end def default_vcr_secrets - @default_vcr_secrets ||= load_vcr_secrets(DEFAULT_VCR_SECRETS_PATH) + @@default_vcr_secrets ||= load_vcr_secrets(default_vcr_secrets_path) end def vcr_secrets - @vcr_secrets ||= load_vcr_secrets(VCR_SECRETS_PATH) + @@vcr_secrets ||= load_vcr_secrets(vcr_secrets_path) end def default_vcr_secret_by_key_path(*args)