spec/chef/cookbooks/gitlab/recipes/gitlab-shell_spec.rb (341 lines of code) (raw):
require 'chef_helper'
RSpec.describe 'gitlab::gitlab-shell' do
let(:chef_run) { ChefSpec::SoloRunner.new(step_into: %w(templatesymlink runit_service)).converge('gitlab::default') }
before do
allow(Gitlab).to receive(:[]).and_call_original
end
it 'defaults the auth_file to be within the user\'s home directory' do
stub_gitlab_rb(user: { home: '/tmp/user' })
expect(chef_run.node['gitlab']['gitlab_shell']['auth_file']).to eq('/tmp/user/.ssh/authorized_keys')
end
it 'uses custom auth_files set in gitlab.rb' do
stub_gitlab_rb(user: { home: '/tmp/user' }, gitlab_shell: { auth_file: '/tmp/authorized_keys' })
expect(chef_run.node['gitlab']['gitlab_shell']['auth_file']).to eq('/tmp/authorized_keys')
end
it 'creates authorized_keys file if missing' do
stub_gitlab_rb(gitlab_shell: { auth_file: '/tmp/authorized_keys' })
expect(chef_run).to create_file_if_missing('/tmp/authorized_keys')
end
context 'with default settings' do
it 'create config file in default location with default values' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_variables(
hash_including(
secret_file: '/var/opt/gitlab/gitlab-rails/etc/gitlab_shell_secret',
log_file: '/var/log/gitlab/gitlab-shell/gitlab-shell.log',
log_format: "json",
gitlab_url: 'http+unix://%2Fvar%2Fopt%2Fgitlab%2Fgitlab-workhorse%2Fsockets%2Fsocket',
gitlab_relative_path: '',
ssl_cert_dir: '/opt/gitlab/embedded/ssl/certs/',
gitlab_sshd: nil,
lfs_pure_ssh_protocol: false,
pat: { enabled: true, allowed_scopes: [] }
)
)
end
it 'renders gitlab-shell config' do
expect(chef_run).to render_file('/var/opt/gitlab/gitlab-shell/config.yml').with_content { |content|
data = YAML.safe_load(content)
expect(data['secret_file']).to eq('/var/opt/gitlab/gitlab-rails/etc/gitlab_shell_secret')
expect(data['log_file']).to eq('/var/log/gitlab/gitlab-shell/gitlab-shell.log')
expect(data['log_format']).to eq('json')
expect(data['gitlab_url']).to eq('http+unix://%2Fvar%2Fopt%2Fgitlab%2Fgitlab-workhorse%2Fsockets%2Fsocket')
expect(data['gitlab_relative_path']).to be_nil
expect(data['ssl_cert_dir']).to eq('/opt/gitlab/embedded/ssl/certs/')
expect(data['sshd']).to be_nil
expect(data['lfs']).to be_nil
expect(data['pat']).to eq({ "enabled" => true, "allowed_scopes" => [] })
}
end
end
context 'with a non-default directory' do
before do
stub_gitlab_rb(gitlab_shell: {
dir: '/export/gitlab/gitlab-shell',
})
end
it 'create config file in specified location with default values' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_link_to('/export/gitlab/gitlab-shell/config.yml')
end
end
context 'when using the default auth_file location' do
before { stub_gitlab_rb(user: { home: '/tmp/user' }) }
it 'creates the ssh dir in the user\'s home directory' do
expect(chef_run).to create_storage_directory('/tmp/user/.ssh').with(owner: 'git', group: 'git', mode: '0700')
end
it 'creates the config file with the auth_file within user\'s ssh directory' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_variables(
hash_including(
authorized_keys: '/tmp/user/.ssh/authorized_keys'
)
)
end
end
context 'when using a different location for auth_file' do
before { stub_gitlab_rb(user: { home: '/tmp/user' }, gitlab_shell: { auth_file: '/tmp/ssh/authorized_keys' }) }
it 'creates the ssh dir in the user\'s home directory' do
expect(chef_run).to create_storage_directory('/tmp/user/.ssh').with(owner: 'git', group: 'git', mode: '0700')
end
it 'creates the auth_file\'s parent directory' do
expect(chef_run).to create_storage_directory('/tmp/ssh').with(owner: 'git', group: 'git', mode: '0700')
end
it 'creates the config file with the auth_file at the specified location' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_variables(
hash_including(
authorized_keys: '/tmp/ssh/authorized_keys'
)
)
end
end
context 'when manage-storage-directories is disabled' do
before { stub_gitlab_rb(user: { home: '/tmp/user' }, manage_storage_directories: { enable: false }) }
it 'doesn\'t create the ssh dir in the user\'s home directory' do
expect(chef_run).not_to run_ruby_block('directory resource: /tmp/user/.ssh')
end
end
context 'with custom settings' do
before do
stub_gitlab_rb(
gitlab_shell: {
log_format: 'json'
}
)
end
it 'creates the config file with custom values' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_variables(
hash_including(
log_format: 'json'
)
)
end
context 'when pat is disabled (set to false)' do
before do
stub_gitlab_rb(
gitlab_shell: {
pat: {
enabled: false,
allowed_scopes: []
}
}
)
end
it 'creates the config file with pat disabled' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_variables(
hash_including(
pat: {
enabled: false,
allowed_scopes: []
}
)
)
end
end
context 'with a non-default workhorse unix socket' do
context 'without sockets_directory defined' do
before do
stub_gitlab_rb(gitlab_workhorse: { listen_addr: '/fake/workhorse/socket' })
end
it 'create config file with provided values' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_variables(
hash_including(
gitlab_url: 'http+unix://%2Ffake%2Fworkhorse%2Fsocket',
gitlab_relative_path: ''
)
)
end
end
context 'with sockets_directory defined' do
before do
stub_gitlab_rb(gitlab_workhorse: { 'sockets_directory': '/fake/workhorse/sockets/' })
end
it 'create config file with provided values' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_variables(
hash_including(
gitlab_url: 'http+unix://%2Ffake%2Fworkhorse%2Fsockets%2Fsocket',
gitlab_relative_path: ''
)
)
end
end
end
context 'with a tcp workhorse listener' do
before do
stub_gitlab_rb(
external_url: 'http://example.com/gitlab',
gitlab_workhorse: {
listen_network: 'tcp',
listen_addr: 'localhost:1234'
}
)
end
it 'create config file with provided values' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_variables(
hash_including(
gitlab_url: 'http://localhost:1234/gitlab',
gitlab_relative_path: nil,
secret_file: '/var/opt/gitlab/gitlab-rails/etc/gitlab_shell_secret'
)
)
end
end
context 'with relative path in external_url' do
before do
stub_gitlab_rb(external_url: 'http://example.com/gitlab')
end
it 'create config file with provided values' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_variables(
hash_including(
gitlab_url: 'http+unix://%2Fvar%2Fopt%2Fgitlab%2Fgitlab-workhorse%2Fsockets%2Fsocket',
gitlab_relative_path: '/gitlab',
secret_file: '/var/opt/gitlab/gitlab-rails/etc/gitlab_shell_secret'
)
)
end
end
context 'with internal_api_url specified' do
before do
stub_gitlab_rb(gitlab_rails: { internal_api_url: 'http://localhost:8080' })
end
it 'create config file with provided values' do
expect(chef_run).to create_templatesymlink('Create a config.yml and create a symlink to Rails root').with_variables(
hash_including(
gitlab_url: 'http://localhost:8080',
gitlab_relative_path: ''
)
)
end
end
context 'with lfs_pure_ssh_protocol enabled' do
it 'create config file with provided values' do
stub_gitlab_rb(gitlab_shell: { lfs_pure_ssh_protocol: true })
expect(chef_run).to render_file('/var/opt/gitlab/gitlab-shell/config.yml').with_content { |content|
data = YAML.safe_load(content)
expect(data['lfs']).to eq("pure_ssh_protocol" => true)
}
end
end
end
context 'log directory and runit group' do
context 'default values' do
it_behaves_like 'enabled logged service', 'gitlab-shell', false, { log_directory_owner: 'git' }
end
context 'custom values' do
before do
stub_gitlab_rb(
gitlab_shell: {
log_group: 'fugee'
}
)
end
it_behaves_like 'configured logrotate service', 'gitlab-shell', 'git', 'fugee'
it_behaves_like 'enabled logged service', 'gitlab-shell', false, { log_directory_owner: 'git', log_group: 'fugee' }
end
end
context 'with gitlab-sshd enabled' do
let(:templatesymlink) { chef_run.templatesymlink('Create a config.yml and create a symlink to Rails root') }
let(:expected_sshd_keys) do
%w[listen proxy_protocol proxy_policy web_listen concurrent_sessions_limit client_alive_interval
grace_period login_grace_time proxy_header_timeout macs kex_algorithms ciphers public_key_algorithms host_key_files host_key_certs]
end
before do
stub_gitlab_rb(
gitlab_sshd: {
enable: true,
}
)
end
before do
allow(Dir).to receive(:[]).and_call_original
end
context 'with default host key and cert globs' do
let(:host_key) { %w(/tmp/host_keys/ssh_key) }
let(:default_host_key_glob) { '/var/opt/gitlab/gitlab-sshd/ssh_host_*_key' }
let(:default_host_cert_glob) { '/var/opt/gitlab/gitlab-sshd/ssh_host_*-cert.pub' }
before do
allow(Dir).to receive(:[]).with(default_host_key_glob).and_return(host_key)
allow(Dir).to receive(:[]).with(default_host_cert_glob).and_return([])
end
it 'renders gitlab-sshd config' do
expect(chef_run).to render_file('/var/opt/gitlab/gitlab-shell/config.yml').with_content { |content|
data = YAML.safe_load(content)
expect(data['sshd'].keys).to match_array(expected_sshd_keys)
expect(data['sshd']['host_key_files']).to eq(host_key)
expect(data['sshd']['host_key_certs']).to be_empty
expect(data['sshd']['listen']).to eq('localhost:2222')
expect(data['sshd']['web_listen']).to eq('localhost:9122')
expect(data['sshd']['proxy_protocol']).to be false
}
end
it 'template triggers notifications' do
expect(templatesymlink).to notify('runit_service[gitlab-sshd]').to(:restart).delayed
end
it 'correctly renders out the gitlab_sshd service file' do
expect(chef_run).to render_file("/opt/gitlab/sv/gitlab-sshd/run")
.with_content { |content|
expect(content).to include('cd /var/opt/gitlab/gitlab-sshd')
expect(content).to include('/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-sshd')
expect(content).to include('-config-dir /var/opt/gitlab/gitlab-shell')
}
end
end
context 'with custom host key path' do
let(:host_key_glob) { '/tmp/host_keys/ssh_key*' }
let(:host_cert_glob) { '/tmp/host_keys/ssh_cert*' }
let(:host_keys) { %w(/tmp/host_keys/ssh_key1 /tmp/host_keys/ssh_key2) }
let(:host_certs) { %w(/tmp/host_keys/ssh_cert1 /tmp/host_keys/ssh_cert2) }
before do
stub_gitlab_rb(
gitlab_sshd: {
enable: true,
log_directory: '/tmp/log',
host_keys_dir: '/tmp/host_keys',
host_keys_glob: 'ssh_key*',
host_certs_dir: '/tmp/host_keys',
host_certs_glob: 'ssh_cert*'
}
)
allow(Dir).to receive(:[]).with(host_key_glob).and_return(host_keys)
allow(Dir).to receive(:[]).with(host_cert_glob).and_return(host_certs)
end
it 'renders gitlab-sshd config' do
expect(chef_run).to render_file('/var/opt/gitlab/gitlab-shell/config.yml').with_content { |content|
data = YAML.safe_load(content)
expect(data['sshd'].keys).to match_array(expected_sshd_keys)
expect(data['sshd']['host_key_files']).to eq(host_keys)
expect(data['sshd']['host_key_certs']).to eq(host_certs)
}
end
end
context 'with custom public_key_algorithms' do
before do
stub_gitlab_rb(
gitlab_sshd: {
enable: true,
public_key_algorithms: %w(ssh-ed25519 ecdsa-sha2-nistp256 rsa-sha2-256 rsa-sha2-512),
}
)
end
it 'renders gitlab-sshd config' do
expect(chef_run).to render_file('/var/opt/gitlab/gitlab-shell/config.yml').with_content { |content|
data = YAML.safe_load(content)
expect(data['sshd']['public_key_algorithms']).to eq(%w(ssh-ed25519 ecdsa-sha2-nistp256 rsa-sha2-256 rsa-sha2-512))
}
end
end
context 'log directory and runit group' do
context 'default values' do
it_behaves_like 'enabled logged service', 'gitlab-sshd', false, { log_directory_owner: 'git' }
end
context 'custom values' do
before do
stub_gitlab_rb(
gitlab_sshd: {
enable: true,
log_group: 'fugee'
}
)
end
# it_behaves_like 'configured logrotate service', 'gitlab-sshd', 'git', 'fugee'
it_behaves_like 'enabled logged service', 'gitlab-sshd', false, { log_directory_owner: 'git', log_group: 'fugee' }
end
end
end
end