diff options
Diffstat (limited to 'spec/services/clusters')
5 files changed, 110 insertions, 322 deletions
diff --git a/spec/services/clusters/agents/filter_authorizations_service_spec.rb b/spec/services/clusters/agents/filter_authorizations_service_spec.rb new file mode 100644 index 00000000000..62cff405d0c --- /dev/null +++ b/spec/services/clusters/agents/filter_authorizations_service_spec.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Clusters::Agents::FilterAuthorizationsService, feature_category: :continuous_integration do + describe '#execute' do + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, group: group) } + + let(:agent_authorizations_without_env) do + [ + build(:agent_project_authorization, project: project, agent: build(:cluster_agent, project: project)), + build(:agent_group_authorization, group: group, agent: build(:cluster_agent, project: project)), + ::Clusters::Agents::ImplicitAuthorization.new(agent: build(:cluster_agent, project: project)) + ] + end + + let(:filter_params) { {} } + + subject(:execute_filter) { described_class.new(agent_authorizations, filter_params).execute } + + context 'when there are no filters' do + let(:agent_authorizations) { agent_authorizations_without_env } + + it 'returns the authorizations as is' do + expect(execute_filter).to eq agent_authorizations + end + end + + context 'when filtering by environment' do + let(:agent_authorizations_with_env) do + [ + build( + :agent_project_authorization, + project: project, + agent: build(:cluster_agent, project: project), + environments: ['staging', 'review/*', 'production'] + ), + build( + :agent_group_authorization, + group: group, + agent: build(:cluster_agent, project: project), + environments: ['staging', 'review/*', 'production'] + ) + ] + end + + let(:agent_authorizations_with_different_env) do + [ + build( + :agent_project_authorization, + project: project, + agent: build(:cluster_agent, project: project), + environments: ['staging'] + ), + build( + :agent_group_authorization, + group: group, + agent: build(:cluster_agent, project: project), + environments: ['staging'] + ) + ] + end + + let(:agent_authorizations) do + ( + agent_authorizations_without_env + + agent_authorizations_with_env + + agent_authorizations_with_different_env + ) + end + + let(:filter_params) { { environment: 'production' } } + + it 'returns the authorizations with the given environment AND authorizations without any environment' do + expected_authorizations = agent_authorizations_with_env + agent_authorizations_without_env + + expect(execute_filter).to match_array expected_authorizations + end + + context 'when environment filter has a wildcard' do + let(:filter_params) { { environment: 'review/123' } } + + it 'returns the authorizations with matching environments AND authorizations without any environment' do + expected_authorizations = agent_authorizations_with_env + agent_authorizations_without_env + + expect(execute_filter).to match_array expected_authorizations + end + end + + context 'when environment filter is nil' do + let(:filter_params) { { environment: nil } } + + it 'returns the authorizations without any environment' do + expect(execute_filter).to match_array agent_authorizations_without_env + end + end + end + end +end diff --git a/spec/services/clusters/agents/refresh_authorization_service_spec.rb b/spec/services/clusters/agents/refresh_authorization_service_spec.rb index 09bec7ae0e8..fa38bc202e7 100644 --- a/spec/services/clusters/agents/refresh_authorization_service_spec.rb +++ b/spec/services/clusters/agents/refresh_authorization_service_spec.rb @@ -113,6 +113,16 @@ RSpec.describe Clusters::Agents::RefreshAuthorizationService do expect(modified_authorization.config).to eq({ 'default_namespace' => 'new-namespace' }) end + context 'project does not belong to a group, and is in the same namespace as the agent' do + let(:root_ancestor) { create(:namespace) } + let(:added_project) { create(:project, namespace: root_ancestor) } + + it 'creates an authorization record for the project' do + expect(subject).to be_truthy + expect(agent.authorized_projects).to contain_exactly(added_project) + end + end + context 'project does not belong to a group, and is authorizing itself' do let(:root_ancestor) { create(:namespace) } let(:added_project) { project } diff --git a/spec/services/clusters/applications/install_service_spec.rb b/spec/services/clusters/applications/install_service_spec.rb deleted file mode 100644 index d34b4dd943c..00000000000 --- a/spec/services/clusters/applications/install_service_spec.rb +++ /dev/null @@ -1,80 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Clusters::Applications::InstallService do - describe '#execute' do - let(:application) { create(:clusters_applications_helm, :scheduled) } - let!(:install_command) { application.install_command } - let(:service) { described_class.new(application) } - let(:helm_client) { instance_double(Gitlab::Kubernetes::Helm::API) } - - before do - allow(service).to receive(:install_command).and_return(install_command) - allow(service).to receive(:helm_api).and_return(helm_client) - end - - context 'when there are no errors' do - before do - expect(helm_client).to receive(:install).with(install_command) - allow(ClusterWaitForAppInstallationWorker).to receive(:perform_in).and_return(nil) - end - - it 'make the application installing' do - expect(application.cluster).not_to be_nil - service.execute - - expect(application).to be_installing - end - - it 'schedule async installation status check' do - expect(ClusterWaitForAppInstallationWorker).to receive(:perform_in).once - - service.execute - end - end - - context 'when k8s cluster communication fails' do - let(:error) { Kubeclient::HttpError.new(500, 'system failure', nil) } - - before do - expect(helm_client).to receive(:install).with(install_command).and_raise(error) - end - - include_examples 'logs kubernetes errors' do - let(:error_name) { 'Kubeclient::HttpError' } - let(:error_message) { 'system failure' } - let(:error_code) { 500 } - end - - it 'make the application errored' do - service.execute - - expect(application).to be_errored - expect(application.status_reason).to match('Kubernetes error: 500') - end - end - - context 'a non kubernetes error happens' do - let(:application) { create(:clusters_applications_helm, :scheduled) } - let(:error) { StandardError.new('something bad happened') } - - before do - expect(helm_client).to receive(:install).with(install_command).and_raise(error) - end - - include_examples 'logs kubernetes errors' do - let(:error_name) { 'StandardError' } - let(:error_message) { 'something bad happened' } - let(:error_code) { nil } - end - - it 'make the application errored' do - service.execute - - expect(application).to be_errored - expect(application.status_reason).to eq('Failed to install.') - end - end - end -end diff --git a/spec/services/clusters/applications/prometheus_config_service_spec.rb b/spec/services/clusters/applications/prometheus_config_service_spec.rb deleted file mode 100644 index 7399f250248..00000000000 --- a/spec/services/clusters/applications/prometheus_config_service_spec.rb +++ /dev/null @@ -1,162 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Clusters::Applications::PrometheusConfigService do - include Gitlab::Routing.url_helpers - - let_it_be(:project) { create(:project) } - let_it_be(:production) { create(:environment, project: project) } - let_it_be(:cluster) { create(:cluster, :provided_by_user, projects: [project]) } - - let(:application) do - create(:clusters_applications_prometheus, :installed, cluster: cluster) - end - - subject { described_class.new(project, cluster, application).execute(input) } - - describe '#execute' do - let(:input) do - YAML.load_file(Rails.root.join('vendor/prometheus/values.yaml')) - end - - context 'with alerts' do - let!(:alert) do - create(:prometheus_alert, project: project, environment: production) - end - - it 'enables alertmanager' do - expect(subject.dig('alertmanager', 'enabled')).to eq(true) - end - - describe 'alertmanagerFiles' do - let(:alertmanager) do - subject.dig('alertmanagerFiles', 'alertmanager.yml') - end - - it 'contains receivers and route' do - expect(alertmanager.keys).to contain_exactly('receivers', 'route') - end - - describe 'receivers' do - let(:receiver) { alertmanager.dig('receivers', 0) } - let(:webhook_config) { receiver.dig('webhook_configs', 0) } - - let(:notify_url) do - notify_project_prometheus_alerts_url(project, format: :json) - end - - it 'sets receiver' do - expect(receiver['name']).to eq('gitlab') - end - - it 'sets webhook_config' do - expect(webhook_config).to eq( - 'url' => notify_url, - 'send_resolved' => true, - 'http_config' => { - 'bearer_token' => application.alert_manager_token - } - ) - end - end - - describe 'route' do - let(:route) { alertmanager.fetch('route') } - - it 'sets route' do - expect(route).to eq( - 'receiver' => 'gitlab', - 'group_wait' => '30s', - 'group_interval' => '5m', - 'repeat_interval' => '4h' - ) - end - end - end - - describe 'serverFiles' do - let(:groups) { subject.dig('serverFiles', 'alerts', 'groups') } - - it 'sets the alerts' do - rules = groups.dig(0, 'rules') - expect(rules.size).to eq(1) - - expect(rules.first['alert']).to eq(alert.title) - end - - context 'with parameterized queries' do - let!(:alert) do - create(:prometheus_alert, - project: project, - environment: production, - prometheus_metric: metric, - operator: PrometheusAlert.operators['gt'], - threshold: 0) - end - - let(:metric) do - create(:prometheus_metric, query: query, project: project) - end - - let(:query) { 'up{environment="{{ci_environment_slug}}"}' } - - it 'substitutes query variables' do - expect(Gitlab::Prometheus::QueryVariables) - .to receive(:call) - .with(production, start_time: nil, end_time: nil) - .and_call_original - - expr = groups.dig(0, 'rules', 0, 'expr') - expect(expr).to eq("up{environment=\"#{production.slug}\"} > 0.0") - end - end - - context 'with multiple environments' do - let(:staging) { create(:environment, project: project) } - - before do - create(:prometheus_alert, project: project, environment: production) - create(:prometheus_alert, project: project, environment: staging) - end - - it 'sets alerts for multiple environment' do - env_names = groups.map { |group| group['name'] } - expect(env_names).to contain_exactly( - "#{production.name}.rules", - "#{staging.name}.rules" - ) - end - - it 'substitutes query variables once per environment' do - allow(Gitlab::Prometheus::QueryVariables).to receive(:call).and_call_original - - expect(Gitlab::Prometheus::QueryVariables) - .to receive(:call) - .with(production, start_time: nil, end_time: nil) - - expect(Gitlab::Prometheus::QueryVariables) - .to receive(:call) - .with(staging, start_time: nil, end_time: nil) - - subject - end - end - end - end - - context 'without alerts' do - it 'disables alertmanager' do - expect(subject.dig('alertmanager', 'enabled')).to eq(false) - end - - it 'removes alertmanagerFiles' do - expect(subject).not_to include('alertmanagerFiles') - end - - it 'removes alerts' do - expect(subject.dig('serverFiles', 'alerts')).to eq({}) - end - end - end -end diff --git a/spec/services/clusters/applications/upgrade_service_spec.rb b/spec/services/clusters/applications/upgrade_service_spec.rb deleted file mode 100644 index 22fbb7ca6e3..00000000000 --- a/spec/services/clusters/applications/upgrade_service_spec.rb +++ /dev/null @@ -1,80 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Clusters::Applications::UpgradeService do - describe '#execute' do - let(:application) { create(:clusters_applications_helm, :scheduled) } - let!(:install_command) { application.install_command } - let(:service) { described_class.new(application) } - let(:helm_client) { instance_double(Gitlab::Kubernetes::Helm::API) } - - before do - allow(service).to receive(:install_command).and_return(install_command) - allow(service).to receive(:helm_api).and_return(helm_client) - end - - context 'when there are no errors' do - before do - expect(helm_client).to receive(:update).with(install_command) - allow(ClusterWaitForAppInstallationWorker).to receive(:perform_in).and_return(nil) - end - - it 'make the application updating' do - expect(application.cluster).not_to be_nil - service.execute - - expect(application).to be_updating - end - - it 'schedule async installation status check' do - expect(ClusterWaitForAppInstallationWorker).to receive(:perform_in).once - - service.execute - end - end - - context 'when kubernetes cluster communication fails' do - let(:error) { Kubeclient::HttpError.new(500, 'system failure', nil) } - - before do - expect(helm_client).to receive(:update).with(install_command).and_raise(error) - end - - include_examples 'logs kubernetes errors' do - let(:error_name) { 'Kubeclient::HttpError' } - let(:error_message) { 'system failure' } - let(:error_code) { 500 } - end - - it 'make the application errored' do - service.execute - - expect(application).to be_update_errored - expect(application.status_reason).to eq(_('Kubernetes error: %{error_code}') % { error_code: 500 }) - end - end - - context 'a non kubernetes error happens' do - let(:application) { create(:clusters_applications_helm, :scheduled) } - let(:error) { StandardError.new('something bad happened') } - - before do - expect(helm_client).to receive(:update).with(install_command).and_raise(error) - end - - include_examples 'logs kubernetes errors' do - let(:error_name) { 'StandardError' } - let(:error_message) { 'something bad happened' } - let(:error_code) { nil } - end - - it 'make the application errored' do - service.execute - - expect(application).to be_update_errored - expect(application.status_reason).to eq(_('Failed to upgrade.')) - end - end - end -end |