spec/chef/cookbooks/mattermost/recipes/mattermost_spec.rb (296 lines of code) (raw):

require 'chef_helper' RSpec.describe 'gitlab::mattermost' do let(:chef_run) { ChefSpec::SoloRunner.new(step_into: %w(runit_service)).converge('gitlab::default') } let(:default_vars) do { 'MM_FILESETTINGS_DIRECTORY' => '/var/opt/gitlab/mattermost/data', 'MM_GITLABSETTINGS_AUTHENDPOINT' => 'http://gitlab.example.com/oauth/authorize', 'MM_GITLABSETTINGS_ENABLE' => 'false', 'MM_GITLABSETTINGS_ID' => 'gitlab_secret', 'MM_GITLABSETTINGS_SCOPE' => '', 'MM_GITLABSETTINGS_SECRET' => 'gitlab_secret', 'MM_GITLABSETTINGS_TOKENENDPOINT' => 'http://gitlab.example.com/oauth/token', 'MM_GITLABSETTINGS_USERAPIENDPOINT' => 'http://gitlab.example.com/api/v4/user', 'MM_INSTALL_TYPE' => 'gitlab_omnibus', 'MM_LOGSETTINGS_FILELOCATION' => '/var/log/gitlab/mattermost', 'MM_PLUGINSETTINGS_CLIENTDIRECTORY' => '/var/opt/gitlab/mattermost/client-plugins', 'MM_PLUGINSETTINGS_DIRECTORY' => '/var/opt/gitlab/mattermost/plugins', 'MM_SERVICESETTINGS_ALLOWEDUNTRUSTEDINTERNALCONNECTIONS' => ' gitlab.example.com', 'MM_SERVICESETTINGS_ENABLEAPITEAMDELETION' => 'true', 'MM_SERVICESETTINGS_LISTENADDRESS' => '127.0.0.1:8065', 'MM_SERVICESETTINGS_SITEURL' => 'http://mattermost.example.com', 'MM_SQLSETTINGS_ATRESTENCRYPTKEY' => 'aabbccddeeff11223344556677889900', 'MM_SQLSETTINGS_DATASOURCE' => 'user=gitlab_mattermost host=/var/opt/gitlab/postgresql port=5432 dbname=mattermost_production', 'MM_SQLSETTINGS_DRIVERNAME' => 'postgres', 'MM_TEAMSETTINGS_SITENAME' => 'GitLab Mattermost', 'SSL_CERT_DIR' => '/opt/gitlab/embedded/ssl/certs/', } end before do allow(Gitlab).to receive(:[]).and_call_original stub_gitlab_rb(external_url: 'http://gitlab.example.com', mattermost_external_url: 'http://mattermost.example.com') allow_any_instance_of(PgHelper).to receive(:is_running?).and_return(true) allow_any_instance_of(PgHelper).to receive(:database_exists?).and_return(true) allow(SecretsHelper).to receive(:generate_hex).with(64).and_return('aaaabbbbccccddddeeeeffff1111222233334444555566667777888899990000') allow(SecretsHelper).to receive(:generate_hex).with(16).and_return('aabbccddeeff11223344556677889900') allow(SecretsHelper).to receive(:generate_urlsafe_base64).and_return('gitlab_secret') end context 'by default' do it 'creates a default VERSION file and restarts service' do expect(chef_run).to create_version_file('Create version file for Mattermost').with( version_file_path: '/var/opt/gitlab/mattermost/VERSION', version_check_cmd: 'cat /opt/gitlab/embedded/service/mattermost/VERSION' ) expect(chef_run.version_file('Create version file for Mattermost')).to notify('runit_service[mattermost]').to(:hup) end end context 'service user and group' do context 'default values' do it_behaves_like "enabled runit service", "mattermost", "root", "root" end context 'custom user and group' do before do stub_gitlab_rb( external_url: 'http://gitlab.example.com', mattermost_external_url: 'http://mattermost.example.com', mattermost: { username: 'foo', group: 'bar' } ) end it_behaves_like "enabled runit service", "mattermost", "root", "root" end end context 'SiteUrl setting' do context 'default value' do it 'creates necessary env variable files' do expect(chef_run).to create_env_dir('/opt/gitlab/etc/mattermost/env').with( variables: default_vars ) end end context 'when explicitly set' do before do stub_gitlab_rb(mattermost: { service_site_url: 'http://mattermost.gitlab.example' }) end it 'creates necessary env variable files' do expect(chef_run).to create_env_dir('/opt/gitlab/etc/mattermost/env').with( variables: default_vars.merge({ 'MM_SERVICESETTINGS_SITEURL' => 'http://mattermost.gitlab.example' }) ) end end end it 'authorizes mattermost with gitlab' do allow(MattermostHelper).to receive(:authorize_with_gitlab) expect(chef_run).to run_ruby_block('authorize mattermost with gitlab') .at_converge_time expect(MattermostHelper).to receive(:authorize_with_gitlab) .with 'http://gitlab.example.com' chef_run.ruby_block('authorize mattermost with gitlab').block.call end it 'populates mattermost configuration options to node attributes' do stub_gitlab_rb(mattermost: { enable: true, gitlab_id: 'old' }) allow(MattermostHelper).to receive(:authorize_with_gitlab) do |url| Gitlab['mattermost']['gitlab_id'] = 'new' end expect(chef_run).to run_ruby_block('populate mattermost configuration options') .at_converge_time chef_run.ruby_block('authorize mattermost with gitlab').block.call chef_run.ruby_block('populate mattermost configuration options').block.call expect(chef_run.node['mattermost']['gitlab_id']).to eq 'new' end context 'populate env variables based on provided gitlab settings' do before do stub_gitlab_rb(mattermost: { enable: true, gitlab_enable: true, gitlab_id: 'gitlab_id', gitlab_secret: 'gitlab_secret', gitlab_scope: 'scope', }) end it 'creates necessary env variable files' do expect(chef_run).to create_env_dir('/opt/gitlab/etc/mattermost/env').with( variables: default_vars.merge( { 'MM_GITLABSETTINGS_ENABLE' => 'true', 'MM_GITLABSETTINGS_SECRET' => 'gitlab_secret', 'MM_GITLABSETTINGS_ID' => 'gitlab_id', 'MM_GITLABSETTINGS_SCOPE' => 'scope', 'MM_GITLABSETTINGS_AUTHENDPOINT' => 'http://gitlab.example.com/oauth/authorize', 'MM_GITLABSETTINGS_TOKENENDPOINT' => 'http://gitlab.example.com/oauth/token', 'MM_GITLABSETTINGS_USERAPIENDPOINT' => 'http://gitlab.example.com/api/v4/user', } ) ) end end context 'allows overrides to the mattermost settings regarding GitLab endpoints' do before do stub_gitlab_rb(mattermost: { enable: true, gitlab_enable: true, gitlab_auth_endpoint: 'https://test-endpoint.example.com/test/auth', gitlab_token_endpoint: 'https://test-endpoint.example.com/test/token', gitlab_user_api_endpoint: 'https://test-endpoint.example.com/test/user/api' }) end it 'creates necessary env variable files' do expect(chef_run).to create_env_dir('/opt/gitlab/etc/mattermost/env').with( variables: default_vars.merge( { 'MM_GITLABSETTINGS_ENABLE' => 'true', 'MM_GITLABSETTINGS_AUTHENDPOINT' => 'https://test-endpoint.example.com/test/auth', 'MM_GITLABSETTINGS_TOKENENDPOINT' => 'https://test-endpoint.example.com/test/token', 'MM_GITLABSETTINGS_USERAPIENDPOINT' => 'https://test-endpoint.example.com/test/user/api' } ) ) end end context 'gitlab is added to untrusted internal connections list' do context 'when no allowed internal connections are provided by gitlab.rb' do it 'creates necessary env variable files' do expect(chef_run).to create_env_dir('/opt/gitlab/etc/mattermost/env').with(variables: default_vars) end end context 'when some allowed internal connections are provided by gitlab.rb' do before do stub_gitlab_rb(mattermost: { enable: true, service_allowed_untrusted_internal_connections: 'localhost' }) end it 'creates necessary env variable files' do expect(chef_run).to create_env_dir('/opt/gitlab/etc/mattermost/env').with( variables: default_vars.merge( { 'MM_SERVICESETTINGS_ALLOWEDUNTRUSTEDINTERNALCONNECTIONS' => 'localhost gitlab.example.com' } ) ) end end end shared_examples 'no gitlab authorization performed' do it 'does not authorize mattermost with gitlab' do expect(chef_run).not_to run_ruby_block('authorize mattermost with gitlab') end end context 'when gitlab-rails is disabled' do before { stub_gitlab_rb(gitlab_rails: { enable: false }) } it_behaves_like 'no gitlab authorization performed' it 'does not add gitlab automatically to the list of allowed internal addresses' do expect(chef_run).to create_env_dir('/opt/gitlab/etc/mattermost/env').with( variables: default_vars.merge( { 'MM_SERVICESETTINGS_ALLOWEDUNTRUSTEDINTERNALCONNECTIONS' => nil } ) ) end end context 'when database is not running' do before { allow_any_instance_of(PgHelper).to receive(:is_running?).and_return(false) } it_behaves_like 'no gitlab authorization performed' end context 'when mattermost database does not exist' do before { allow_any_instance_of(PgHelper).to receive(:database_exists?).and_return(false) } it_behaves_like 'no gitlab authorization performed' end context 'when a custom env variable is specified' do before do stub_gitlab_rb(mattermost: { env: { 'IAM' => 'CUSTOMVAR' } }) end it 'creates necessary env variable files' do expect(chef_run).to create_env_dir('/opt/gitlab/etc/mattermost/env').with( variables: default_vars.merge( { 'IAM' => 'CUSTOMVAR' } ) ) end end describe 'letsencrypt' do before do stub_gitlab_rb( external_url: 'https://gitlab.example.com', mattermost_external_url: 'https://mattermost.example.com' ) allow(File).to receive(:exist?).and_call_original end describe 'HTTP to HTTPS redirection' do context 'by default' do it 'is enabled' do expect(chef_run).to render_file('/var/opt/gitlab/nginx/conf/gitlab-mattermost-http.conf').with_content("return 301 https://mattermost.example.com:443$request_uri;") end end context 'if disabled in gitlab.rb' do before do stub_gitlab_rb( external_url: 'https://gitlab.example.com', mattermost_external_url: 'https://mattermost.example.com', mattermost_nginx: { redirect_http_to_https: false } ) end it 'is disabled' do expect(chef_run).to render_file('/var/opt/gitlab/nginx/conf/gitlab-mattermost-http.conf') expect(chef_run).not_to render_file('/var/opt/gitlab/nginx/conf/gitlab-mattermost.conf').with_content("return 301 https://mattermost.example.com:443$request_uri;") end end end context 'default certificate file is missing' do before do allow(File).to receive(:exist?).with('/etc/gitlab/ssl/mattermost.example.com.crt').and_return(false) end it 'adds itself to letsencrypt alt_names' do expect(chef_run.node['letsencrypt']['alt_names']).to match_array(['gitlab.example.com', 'mattermost.example.com']) end it 'is reflected in the acme_selfsigned' do expect(chef_run).to create_acme_selfsigned('gitlab.example.com').with( alt_names: match_array(['gitlab.example.com', 'mattermost.example.com']) ) end end context 'default certificate file is present' do before do allow(File).to receive(:exist?).with('/etc/gitlab/ssl/mattermost.example.com.crt').and_return(true) end it 'does not alter letsencrypt alt_names' do expect(chef_run.node['letsencrypt']['alt_names']).to eql(['gitlab.example.com']) end it 'is reflected in the acme_selfsigned' do expect(chef_run).to create_acme_selfsigned('gitlab.example.com').with( alt_names: ['gitlab.example.com'] ) end end end describe 'registering as an OAuth app with GitLab' do context 'by default when Mattermost is enabled' do it 'registers as an oauth app with GitLab' do expect(chef_run).to run_ruby_block('authorize mattermost with gitlab') end end context 'when generating gitlab-secrets.json file is disabled' do before do stub_gitlab_rb( package: { generate_secrets_json_file: false } ) allow(LoggingHelper).to receive(:warning).and_call_original end it 'does not register as an oauth app with GitLab' do expect(chef_run).not_to run_ruby_block('authorize mattermost with gitlab') end it 'displays a warning about disabling automatic oauth registration' do expect(LoggingHelper).to receive(:warning).with(/not automatically registering Mattermost as an Oauth App/) chef_run end end end end