Merge branch '6275-support-redis-encrypted-secrets' into 'master'

Support specifying encrypted secrets path for Redis

Closes #6275

See merge request https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/7233

Merged-by: Robert Marshall <rmarshall@gitlab.com>
Approved-by: João Alexandre Cunha <j.a.cunha@gmail.com>
Approved-by: Ian Baum <ibaum@gitlab.com>
Approved-by: Jason Plum <jplum@gitlab.com>
Reviewed-by: Balasankar 'Balu' C <balasankar@gitlab.com>
Co-authored-by: Balasankar "Balu" C <balasankar@gitlab.com>
This commit is contained in:
Robert Marshall 2023-11-29 21:47:24 +00:00
commit 9586e15d11
5 changed files with 70 additions and 6 deletions

View File

@ -446,6 +446,7 @@ default['gitlab']['gitlab_rails']['redis_tls_ca_cert_file'] = "#{node['package']
default['gitlab']['gitlab_rails']['redis_tls_client_cert_file'] = nil
default['gitlab']['gitlab_rails']['redis_tls_client_key_file'] = nil
default['gitlab']['gitlab_rails']['redis_password'] = nil
default['gitlab']['gitlab_rails']['redis_encrypted_settings_file'] = nil
default['gitlab']['gitlab_rails']['redis_socket'] = "/var/opt/gitlab/redis/redis.socket"
default['gitlab']['gitlab_rails']['redis_enable_client'] = true
default['gitlab']['gitlab_rails']['redis_sentinels'] = []
@ -455,6 +456,7 @@ default['gitlab']['gitlab_rails']['redis_cache_sentinels'] = []
default['gitlab']['gitlab_rails']['redis_cache_sentinels_password'] = nil
default['gitlab']['gitlab_rails']['redis_cache_username'] = nil
default['gitlab']['gitlab_rails']['redis_cache_password'] = nil
default['gitlab']['gitlab_rails']['redis_cache_encrypted_settings_file'] = nil
default['gitlab']['gitlab_rails']['redis_cache_cluster_nodes'] = []
default['gitlab']['gitlab_rails']['redis_cache_ssl'] = false
default['gitlab']['gitlab_rails']['redis_cache_tls_ca_cert_dir'] = default['gitlab']['gitlab_rails']['redis_tls_ca_cert_dir'].dup
@ -464,6 +466,7 @@ default['gitlab']['gitlab_rails']['redis_cache_tls_client_key_file'] = nil
default['gitlab']['gitlab_rails']['redis_queues_instance'] = nil
default['gitlab']['gitlab_rails']['redis_queues_username'] = nil
default['gitlab']['gitlab_rails']['redis_queues_password'] = nil
default['gitlab']['gitlab_rails']['redis_queues_encrypted_settings_file'] = nil
default['gitlab']['gitlab_rails']['redis_queues_sentinels'] = []
default['gitlab']['gitlab_rails']['redis_queues_sentinels_password'] = nil
default['gitlab']['gitlab_rails']['redis_queues_cluster_nodes'] = []
@ -477,6 +480,7 @@ default['gitlab']['gitlab_rails']['redis_shared_state_sentinels'] = []
default['gitlab']['gitlab_rails']['redis_shared_state_sentinels_password'] = nil
default['gitlab']['gitlab_rails']['redis_shared_state_username'] = nil
default['gitlab']['gitlab_rails']['redis_shared_state_password'] = nil
default['gitlab']['gitlab_rails']['redis_shared_state_encrypted_settings_file'] = nil
default['gitlab']['gitlab_rails']['redis_shared_state_cluster_nodes'] = []
default['gitlab']['gitlab_rails']['redis_shared_state_ssl'] = false
default['gitlab']['gitlab_rails']['redis_shared_state_tls_ca_cert_dir'] = default['gitlab']['gitlab_rails']['redis_tls_ca_cert_dir'].dup
@ -488,6 +492,7 @@ default['gitlab']['gitlab_rails']['redis_trace_chunks_sentinels'] = []
default['gitlab']['gitlab_rails']['redis_trace_chunks_sentinels_password'] = nil
default['gitlab']['gitlab_rails']['redis_trace_chunks_username'] = nil
default['gitlab']['gitlab_rails']['redis_trace_chunks_password'] = nil
default['gitlab']['gitlab_rails']['redis_trace_chunks_encrypted_settings_file'] = nil
default['gitlab']['gitlab_rails']['redis_trace_chunks_cluster_nodes'] = []
default['gitlab']['gitlab_rails']['redis_trace_chunks_ssl'] = false
default['gitlab']['gitlab_rails']['redis_trace_chunks_tls_ca_cert_dir'] = default['gitlab']['gitlab_rails']['redis_tls_ca_cert_dir'].dup
@ -499,6 +504,7 @@ default['gitlab']['gitlab_rails']['redis_actioncable_sentinels'] = []
default['gitlab']['gitlab_rails']['redis_actioncable_sentinels_password'] = nil
default['gitlab']['gitlab_rails']['redis_actioncable_username'] = nil
default['gitlab']['gitlab_rails']['redis_actioncable_password'] = nil
default['gitlab']['gitlab_rails']['redis_actioncable_encrypted_settings_file'] = nil
default['gitlab']['gitlab_rails']['redis_actioncable_cluster_nodes'] = []
default['gitlab']['gitlab_rails']['redis_actioncable_ssl'] = false
default['gitlab']['gitlab_rails']['redis_actioncable_tls_ca_cert_dir'] = default['gitlab']['gitlab_rails']['redis_tls_ca_cert_dir'].dup
@ -510,6 +516,7 @@ default['gitlab']['gitlab_rails']['redis_rate_limiting_sentinels'] = []
default['gitlab']['gitlab_rails']['redis_rate_limiting_sentinels_password'] = nil
default['gitlab']['gitlab_rails']['redis_rate_limiting_username'] = nil
default['gitlab']['gitlab_rails']['redis_rate_limiting_password'] = nil
default['gitlab']['gitlab_rails']['redis_rate_limiting_encrypted_settings_file'] = nil
default['gitlab']['gitlab_rails']['redis_rate_limiting_cluster_nodes'] = []
default['gitlab']['gitlab_rails']['redis_rate_limiting_ssl'] = false
default['gitlab']['gitlab_rails']['redis_rate_limiting_tls_ca_cert_dir'] = default['gitlab']['gitlab_rails']['redis_tls_ca_cert_dir'].dup
@ -521,6 +528,7 @@ default['gitlab']['gitlab_rails']['redis_sessions_sentinels'] = []
default['gitlab']['gitlab_rails']['redis_sessions_sentinels_password'] = nil
default['gitlab']['gitlab_rails']['redis_sessions_username'] = nil
default['gitlab']['gitlab_rails']['redis_sessions_password'] = nil
default['gitlab']['gitlab_rails']['redis_sessions_encrypted_settings_file'] = nil
default['gitlab']['gitlab_rails']['redis_sessions_cluster_nodes'] = []
default['gitlab']['gitlab_rails']['redis_sessions_ssl'] = false
default['gitlab']['gitlab_rails']['redis_sessions_tls_ca_cert_dir'] = default['gitlab']['gitlab_rails']['redis_tls_ca_cert_dir'].dup
@ -532,6 +540,7 @@ default['gitlab']['gitlab_rails']['redis_repository_cache_sentinels'] = []
default['gitlab']['gitlab_rails']['redis_repository_cache_sentinels_password'] = nil
default['gitlab']['gitlab_rails']['redis_repository_cache_username'] = nil
default['gitlab']['gitlab_rails']['redis_repository_cache_password'] = nil
default['gitlab']['gitlab_rails']['redis_repository_cache_encrypted_settings_file'] = nil
default['gitlab']['gitlab_rails']['redis_repository_cache_cluster_nodes'] = []
default['gitlab']['gitlab_rails']['redis_repository_cache_ssl'] = false
default['gitlab']['gitlab_rails']['redis_repository_cache_tls_ca_cert_dir'] = default['gitlab']['gitlab_rails']['redis_tls_ca_cert_dir'].dup
@ -543,6 +552,7 @@ default['gitlab']['gitlab_rails']['redis_cluster_rate_limiting_sentinels'] = []
default['gitlab']['gitlab_rails']['redis_cluster_rate_limiting_sentinels_password'] = nil
default['gitlab']['gitlab_rails']['redis_cluster_rate_limiting_username'] = nil
default['gitlab']['gitlab_rails']['redis_cluster_rate_limiting_password'] = nil
default['gitlab']['gitlab_rails']['redis_cluster_rate_limiting_encrypted_settings_file'] = nil
default['gitlab']['gitlab_rails']['redis_cluster_rate_limiting_cluster_nodes'] = []
default['gitlab']['gitlab_rails']['redis_cluster_rate_limiting_ssl'] = false
default['gitlab']['gitlab_rails']['redis_cluster_rate_limiting_tls_ca_cert_dir'] = default['gitlab']['gitlab_rails']['redis_tls_ca_cert_dir'].dup

View File

@ -17,6 +17,7 @@
require_relative 'nginx.rb'
require_relative '../../gitaly/libraries/gitaly.rb'
require_relative '../../package/libraries/settings_dsl.rb'
require_relative 'redis_helper'
module GitlabRails
ALLOWED_DATABASES = %w[main ci geo embedding].freeze
@ -324,7 +325,16 @@ module GitlabRails
def parse_encrypted_settings_path
# This requires the parse_shared_dir to be executed before
Gitlab['gitlab_rails']['encrypted_settings_path'] ||= File.join(Gitlab['gitlab_rails']['shared_path'], 'encrypted_settings')
encrypted_settings_path = Gitlab['gitlab_rails']['encrypted_settings_path'] ||= File.join(Gitlab['gitlab_rails']['shared_path'], 'encrypted_settings')
RedisHelper::REDIS_INSTANCES.each do |instance|
Gitlab['gitlab_rails']["redis_#{instance}_encrypted_settings_file"] ||= Gitlab['gitlab_rails']['redis_encrypted_settings_file'] || File.join(encrypted_settings_path, "redis.#{instance}.yml.enc")
end
# NOTE: The default value of `redis_encrypted_settings_file` should be
# set only after the instance-specific ones are handled, or this default
# value will get used for the instance-specific settings.
Gitlab['gitlab_rails']['redis_encrypted_settings_file'] ||= File.join(encrypted_settings_path, 'redis.yml.enc')
end
def parse_pages_dir

View File

@ -217,6 +217,7 @@ redis_tls_ca_cert_dir = node['gitlab']['gitlab_rails']['redis_tls_ca_cert_dir']
redis_tls_ca_cert_file = node['gitlab']['gitlab_rails']['redis_tls_ca_cert_file']
redis_tls_client_cert_file = node['gitlab']['gitlab_rails']['redis_tls_client_cert_file']
redis_tls_client_key_file = node['gitlab']['gitlab_rails']['redis_tls_client_key_file']
redis_encrypted_settings_file = node['gitlab']['gitlab_rails']['redis_encrypted_settings_file']
templatesymlink "Create a secrets.yml and create a symlink to Rails root" do
link_from File.join(gitlab_rails_source_dir, "config/secrets.yml")
@ -253,7 +254,8 @@ templatesymlink "Create a resque.yml and create a symlink to Rails root" do
redis_tls_ca_cert_dir: redis_tls_ca_cert_dir,
redis_tls_ca_cert_file: redis_tls_ca_cert_file,
redis_tls_client_cert_file: redis_tls_client_cert_file,
redis_tls_client_key_file: redis_tls_client_key_file
redis_tls_client_key_file: redis_tls_client_key_file,
redis_encrypted_settings_file: redis_encrypted_settings_file
)
dependent_services.each { |svc| notifies :restart, svc }
sensitive true
@ -305,6 +307,7 @@ RedisHelper::REDIS_INSTANCES.each do |instance|
ca_cert_file = node['gitlab']['gitlab_rails']["redis_#{instance}_tls_ca_cert_file"]
certificate_file = node['gitlab']['gitlab_rails']["redis_#{instance}_tls_client_cert_file"]
key_file = node['gitlab']['gitlab_rails']["redis_#{instance}_tls_client_key_file"]
instance_encrypted_settings_file = node['gitlab']['gitlab_rails']["redis_#{instance}_encrypted_settings_file"]
from_filename = File.join(gitlab_rails_source_dir, "config/#{filename}")
to_filename = File.join(gitlab_rails_etc_dir, filename)
@ -329,7 +332,8 @@ RedisHelper::REDIS_INSTANCES.each do |instance|
redis_tls_ca_cert_dir: ca_cert_dir,
redis_tls_ca_cert_file: ca_cert_file,
redis_tls_client_cert_file: certificate_file,
redis_tls_client_key_file: key_file
redis_tls_client_key_file: key_file,
redis_encrypted_settings_file: instance_encrypted_settings_file
)
dependent_services.each { |svc| notifies :restart, svc }
action :delete if url.nil? && clusters.empty?

View File

@ -13,6 +13,7 @@ production:
<% end %>
<% else %>
url: <%= @redis_url %>
secret_file: <%= @redis_encrypted_settings_file %>
<%- if @redis_ssl %>
ssl_params:
<%- if @redis_tls_ca_cert_dir %>ca_path: "<%= @redis_tls_ca_cert_dir %>"<% end %>

View File

@ -440,7 +440,8 @@ RSpec.describe 'gitlab::gitlab-rails' do
redis_tls_ca_cert_dir: "/opt/gitlab/embedded/ssl/certs/",
redis_tls_ca_cert_file: "/opt/gitlab/embedded/ssl/certs/cacert.pem",
redis_tls_client_cert_file: nil,
redis_tls_client_key_file: nil
redis_tls_client_key_file: nil,
redis_encrypted_settings_file: "/var/opt/gitlab/gitlab-rails/shared/encrypted_settings/redis.#{instance}.yml.enc"
)
expect(chef_run).to render_file("/var/opt/gitlab/gitlab-rails/etc/redis.#{instance}.yml").with_content { |content|
@ -482,7 +483,8 @@ RSpec.describe 'gitlab::gitlab-rails' do
redis_tls_ca_cert_dir: "/opt/gitlab/embedded/ssl/certs/",
redis_tls_ca_cert_file: "/opt/gitlab/embedded/ssl/certs/cacert.pem",
redis_tls_client_cert_file: nil,
redis_tls_client_key_file: nil
redis_tls_client_key_file: nil,
redis_encrypted_settings_file: "/var/opt/gitlab/gitlab-rails/shared/encrypted_settings/redis.#{instance}.yml.enc"
)
expect(chef_run).to render_file("/var/opt/gitlab/gitlab-rails/etc/redis.#{instance}.yml").with_content { |content|
@ -524,7 +526,8 @@ RSpec.describe 'gitlab::gitlab-rails' do
redis_tls_ca_cert_dir: "/opt/gitlab/embedded/ssl/certs/",
redis_tls_ca_cert_file: "/opt/gitlab/embedded/ssl/certs/cacert.pem",
redis_tls_client_cert_file: nil,
redis_tls_client_key_file: nil
redis_tls_client_key_file: nil,
redis_encrypted_settings_file: "/var/opt/gitlab/gitlab-rails/shared/encrypted_settings/redis.#{instance}.yml.enc"
)
expect(chef_run).to render_file("/var/opt/gitlab/gitlab-rails/etc/redis.#{instance}.yml").with_content { |content|
@ -545,6 +548,42 @@ RSpec.describe 'gitlab::gitlab-rails' do
expect(chef_run).to create_templatesymlink('Create a resque.yml and create a symlink to Rails root')
end
end
describe 'encrypted_settings_file' do
cached(:chef_run) do
ChefSpec::SoloRunner.new(step_into: %w(templatesymlink)).converge('gitlab::default')
end
let(:cache_secret_file) { '/etc/gitlab/cache.redis.enc' }
let(:global_secret_file) { '/etc/gitlab/global.redis.enc' }
context 'with separate file for an instance' do
before do
stub_gitlab_rb(
gitlab_rails: {
redis_encrypted_settings_file: global_secret_file,
redis_cache_instance: 'redis://redis.cache.instance',
redis_cache_encrypted_settings_file: cache_secret_file,
redis_shared_state_instance: 'redis://redis.shared_state.instance'
}
)
end
it 'uses specified path for the cache instance' do
expect(chef_run).to render_file("/var/opt/gitlab/gitlab-rails/etc/redis.cache.yml").with_content { |content|
generated_yml = YAML.safe_load(content)
expect(generated_yml.dig('production', 'secret_file')).to eq(cache_secret_file)
}
end
it 'uses global path for the shared state instance' do
expect(chef_run).to render_file("/var/opt/gitlab/gitlab-rails/etc/redis.shared_state.yml").with_content { |content|
generated_yml = YAML.safe_load(content)
expect(generated_yml.dig('production', 'secret_file')).to eq(global_secret_file)
}
end
end
end
end
context 'redis.yml override' do