spec/chef/cookbooks/gitlab/recipes/generate_secrets_spec.rb (92 lines of code) (raw):
# These tests confirm that calling the generate_secrets recipe works correctly
# both when using the default path and and when using anoptional path to the
# secrets file. It tests that the file is created and contains secrets. It does
# not exhaustively test the resulting secrets file contents. Those tests are
# left to secrets_helper_spec.rb.
require 'chef_helper'
require_relative '../../../../../files/gitlab-cookbooks/package/libraries/helpers/secrets_helper'
RSpec.describe 'generate_secrets' do
let(:chef_runner) { ChefSpec::SoloRunner.new }
let(:chef_run) { chef_runner.converge('gitlab::generate_secrets') }
let(:node) { chef_runner.node }
optional_path = '/etc/mygitlab/mysecrets.json'.freeze
hex_key = /\h{128}/.freeze
rsa_key = /\A-----BEGIN RSA PRIVATE KEY-----\n.+\n-----END RSA PRIVATE KEY-----\n\Z/m.freeze
alphanumeric_key_regex = /\A[A-Za-z0-9]{32}\Z/m.freeze
default_secrets_error_regexp = %r{You have enabled writing to the default secrets file location with package\['generate_secrets_json_file'].*}
before do
allow(File).to receive(:directory?).and_call_original
allow(File).to receive(:exist?).and_call_original
allow(File).to receive(:read).and_call_original
allow(File).to receive(:open).and_call_original
end
context 'when default directory does not exist' do
it 'does not write secrets to the file' do
allow(File).to receive(:directory?).with(File.dirname(SecretsHelper::SECRETS_FILE)).and_return(false)
expect(File).not_to receive(:open).with(SecretsHelper::SECRETS_FILE, 'w')
chef_run
end
end
context 'when optional path directory does not exist' do
it 'does not write secrets to the file' do
allow(File).to receive(:directory?).with(File.dirname(optional_path)).and_return(false)
expect(File).not_to receive(:open).with(optional_path, 'w')
node.normal[SecretsHelper::SECRETS_FILE_CHEF_ATTR] = optional_path
chef_run
end
end
context 'when optional path directory does exists and we request the optional secret path' do
let(:file) { double(:file) }
let(:new_secrets) { @new_secrets }
before do
allow(SecretsHelper).to receive(:system)
allow(File).to receive(:directory?).with(File.dirname(optional_path)).and_return(true)
allow(file).to receive(:puts) { |json| @new_secrets = JSON.parse(json) }
allow(file).to receive(:chmod).and_return(true)
end
context 'when there are no existing secrets and generate_secrets_json_file = false' do
before do
allow(File).to receive(:open).with(optional_path, 'w', 0600).and_yield(file).once
node.normal[SecretsHelper::SECRETS_FILE_CHEF_ATTR] = optional_path
node.normal['package']['generate_secrets_json_file'] = false
chef_run
end
it 'writes new secrets to the file, with different values for each' do
rails_keys = new_secrets['gitlab_rails']
hex_keys = rails_keys.values_at('db_key_base', 'otp_key_base', 'secret_key_base', 'encrypted_settings_key_base')
alphanumeric_keys = rails_keys.values_at(
'active_record_encryption_primary_key',
'active_record_encryption_deterministic_key',
'active_record_encryption_key_derivation_salt'
).flatten
rsa_keys = rails_keys.values_at('openid_connect_signing_key')
expect(rails_keys.to_a.uniq).to eq(rails_keys.to_a)
expect(hex_keys).to all(match(hex_key))
expect(alphanumeric_keys.flatten).to all(match(alphanumeric_key_regex))
expect(rsa_keys).to all(match(rsa_key))
end
end
end
context 'when there are no existing secrets and generate_secrets_json_file = true' do
before do
allow(File).to receive(:directory?).with(optional_path).and_return(false)
allow(File).to receive(:exist?).with(File.dirname(optional_path)).and_return(true)
node.normal[SecretsHelper::SECRETS_FILE_CHEF_ATTR] = optional_path
node.normal['package']['generate_secrets_json_file'] = true
end
it 'does not write secrets to the file' do
expect(File).not_to receive(:directory?).with(File.dirname(optional_path))
expect(File).not_to receive(:open).with(optional_path, 'w')
expect(LoggingHelper).to receive(:warning).with(default_secrets_error_regexp)
chef_run
end
end
context 'when there are no existing secrets and generate_secrets_json_file is not set' do
before do
allow(File).to receive(:directory?).with(optional_path).and_return(false)
allow(File).to receive(:exist?).with(File.dirname(optional_path)).and_return(true)
node.normal[SecretsHelper::SECRETS_FILE_CHEF_ATTR] = optional_path
end
it 'does not write secrets to the file' do
expect(File).not_to receive(:directory?).with(File.dirname(optional_path))
expect(File).not_to receive(:open).with(optional_path, 'w')
expect(LoggingHelper).to receive(:warning).with(default_secrets_error_regexp)
chef_run
end
end
end