Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/services/clusters')
-rw-r--r--spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb44
-rw-r--r--spec/services/clusters/applications/check_installation_progress_service_spec.rb204
-rw-r--r--spec/services/clusters/applications/check_uninstall_progress_service_spec.rb155
-rw-r--r--spec/services/clusters/applications/check_upgrade_progress_service_spec.rb94
-rw-r--r--spec/services/clusters/applications/create_service_spec.rb279
-rw-r--r--spec/services/clusters/applications/patch_service_spec.rb80
-rw-r--r--spec/services/clusters/applications/prometheus_update_service_spec.rb111
-rw-r--r--spec/services/clusters/applications/update_service_spec.rb91
-rw-r--r--spec/services/clusters/gcp/provision_service_spec.rb2
-rw-r--r--spec/services/clusters/gcp/verify_provision_status_service_spec.rb10
-rw-r--r--spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb223
-rw-r--r--spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb2
12 files changed, 7 insertions, 1288 deletions
diff --git a/spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb b/spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb
deleted file mode 100644
index 605d9e67ab6..00000000000
--- a/spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Clusters::Applications::CheckIngressIpAddressService do
- include ExclusiveLeaseHelpers
-
- let(:application) { create(:clusters_applications_ingress, :installed) }
- let(:service) { described_class.new(application) }
- let(:kubeclient) { double(::Kubeclient::Client, get_service: kube_service) }
- let(:lease_key) { "check_ingress_ip_address_service:#{application.id}" }
-
- let(:ingress) do
- [
- {
- ip: '111.222.111.222',
- hostname: 'localhost.localdomain'
- }
- ]
- end
-
- let(:kube_service) do
- ::Kubeclient::Resource.new(
- {
- status: {
- loadBalancer: {
- ingress: ingress
- }
- }
- }
- )
- end
-
- subject { service.execute }
-
- before do
- stub_exclusive_lease(lease_key, timeout: 15.seconds.to_i)
- allow(application.cluster).to receive(:kubeclient).and_return(kubeclient)
- end
-
- include_examples 'check ingress ip executions', :clusters_applications_ingress
-
- include_examples 'check ingress ip executions', :clusters_applications_knative
-end
diff --git a/spec/services/clusters/applications/check_installation_progress_service_spec.rb b/spec/services/clusters/applications/check_installation_progress_service_spec.rb
deleted file mode 100644
index 698804ff6af..00000000000
--- a/spec/services/clusters/applications/check_installation_progress_service_spec.rb
+++ /dev/null
@@ -1,204 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Clusters::Applications::CheckInstallationProgressService, '#execute' do
- RESCHEDULE_PHASES = Gitlab::Kubernetes::Pod::PHASES - [Gitlab::Kubernetes::Pod::SUCCEEDED, Gitlab::Kubernetes::Pod::FAILED].freeze
-
- let(:application) { create(:clusters_applications_helm, :installing) }
- let(:service) { described_class.new(application) }
- let(:phase) { Gitlab::Kubernetes::Pod::UNKNOWN }
- let(:errors) { nil }
-
- shared_examples 'a not yet terminated installation' do |a_phase|
- let(:phase) { a_phase }
-
- before do
- expect(service).to receive(:pod_phase).once.and_return(phase)
- end
-
- context "when phase is #{a_phase}" do
- context 'when not timed_out' do
- it 'reschedule a new check' do
- expect(ClusterWaitForAppInstallationWorker).to receive(:perform_in).once
- expect(service).not_to receive(:remove_installation_pod)
-
- expect do
- service.execute
-
- application.reload
- end.not_to change(application, :status)
-
- expect(application.status_reason).to be_nil
- end
- end
- end
- end
-
- shared_examples 'error handling' do
- context 'when installation raises a Kubeclient::HttpError' do
- let(:cluster) { create(:cluster, :provided_by_user, :project) }
- let(:logger) { service.send(:logger) }
- let(:error) { Kubeclient::HttpError.new(401, 'Unauthorized', nil) }
-
- before do
- application.update!(cluster: cluster)
-
- expect(service).to receive(:pod_phase).and_raise(error)
- end
-
- include_examples 'logs kubernetes errors' do
- let(:error_name) { 'Kubeclient::HttpError' }
- let(:error_message) { 'Unauthorized' }
- let(:error_code) { 401 }
- end
-
- it 'shows the response code from the error' do
- service.execute
-
- expect(application).to be_errored.or(be_update_errored)
- expect(application.status_reason).to eq('Kubernetes error: 401')
- end
- end
- end
-
- before do
- allow(service).to receive(:installation_errors).and_return(errors)
- allow(service).to receive(:remove_installation_pod).and_return(nil)
- end
-
- context 'when application is updating' do
- let(:application) { create(:clusters_applications_helm, :updating) }
-
- include_examples 'error handling'
-
- RESCHEDULE_PHASES.each { |phase| it_behaves_like 'a not yet terminated installation', phase }
-
- context 'when installation POD succeeded' do
- let(:phase) { Gitlab::Kubernetes::Pod::SUCCEEDED }
-
- before do
- expect(service).to receive(:pod_phase).once.and_return(phase)
- end
-
- it 'removes the installation POD' do
- expect(service).to receive(:remove_installation_pod).once
-
- service.execute
- end
-
- it 'make the application installed' do
- expect(ClusterWaitForAppInstallationWorker).not_to receive(:perform_in)
-
- service.execute
-
- expect(application).to be_updated
- expect(application.status_reason).to be_nil
- end
- end
-
- context 'when installation POD failed' do
- let(:phase) { Gitlab::Kubernetes::Pod::FAILED }
- let(:errors) { 'test installation failed' }
-
- before do
- expect(service).to receive(:pod_phase).once.and_return(phase)
- end
-
- it 'make the application errored' do
- service.execute
-
- expect(application).to be_update_errored
- expect(application.status_reason).to eq('Operation failed. Check pod logs for install-helm for more details.')
- end
- end
-
- context 'when timed out' do
- let(:application) { create(:clusters_applications_helm, :timed_out, :updating) }
-
- before do
- expect(service).to receive(:pod_phase).once.and_return(phase)
- end
-
- it 'make the application errored' do
- expect(ClusterWaitForAppInstallationWorker).not_to receive(:perform_in)
-
- service.execute
-
- expect(application).to be_update_errored
- expect(application.status_reason).to eq('Operation timed out. Check pod logs for install-helm for more details.')
- end
- end
- end
-
- context 'when application is installing' do
- include_examples 'error handling'
-
- RESCHEDULE_PHASES.each { |phase| it_behaves_like 'a not yet terminated installation', phase }
-
- context 'when installation POD succeeded' do
- let(:phase) { Gitlab::Kubernetes::Pod::SUCCEEDED }
-
- before do
- expect(service).to receive(:pod_phase).once.and_return(phase)
- end
-
- it 'removes the installation POD' do
- expect_next_instance_of(Gitlab::Kubernetes::Helm::API) do |instance|
- expect(instance).to receive(:delete_pod!).with(kind_of(String)).once
- end
- expect(service).to receive(:remove_installation_pod).and_call_original
-
- service.execute
- end
-
- it 'make the application installed' do
- expect(ClusterWaitForAppInstallationWorker).not_to receive(:perform_in)
-
- service.execute
-
- expect(application).to be_installed
- expect(application.status_reason).to be_nil
- end
-
- it 'tracks application install', :snowplow do
- service.execute
-
- expect_snowplow_event(category: 'cluster:applications', action: 'cluster_application_helm_installed')
- end
- end
-
- context 'when installation POD failed' do
- let(:phase) { Gitlab::Kubernetes::Pod::FAILED }
- let(:errors) { 'test installation failed' }
-
- before do
- expect(service).to receive(:pod_phase).once.and_return(phase)
- end
-
- it 'make the application errored' do
- service.execute
-
- expect(application).to be_errored
- expect(application.status_reason).to eq('Operation failed. Check pod logs for install-helm for more details.')
- end
- end
-
- context 'when timed out' do
- let(:application) { create(:clusters_applications_helm, :timed_out) }
-
- before do
- expect(service).to receive(:pod_phase).once.and_return(phase)
- end
-
- it 'make the application errored' do
- expect(ClusterWaitForAppInstallationWorker).not_to receive(:perform_in)
-
- service.execute
-
- expect(application).to be_errored
- expect(application.status_reason).to eq('Operation timed out. Check pod logs for install-helm for more details.')
- end
- end
- end
-end
diff --git a/spec/services/clusters/applications/check_uninstall_progress_service_spec.rb b/spec/services/clusters/applications/check_uninstall_progress_service_spec.rb
deleted file mode 100644
index 4b8893429cf..00000000000
--- a/spec/services/clusters/applications/check_uninstall_progress_service_spec.rb
+++ /dev/null
@@ -1,155 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Clusters::Applications::CheckUninstallProgressService do
- reschedule_phases = Gitlab::Kubernetes::Pod::PHASES - [Gitlab::Kubernetes::Pod::SUCCEEDED, Gitlab::Kubernetes::Pod::FAILED].freeze
-
- let(:application) { create(:clusters_applications_prometheus, :uninstalling) }
- let(:service) { described_class.new(application) }
- let(:phase) { Gitlab::Kubernetes::Pod::UNKNOWN }
- let(:errors) { nil }
- let(:worker_class) { Clusters::Applications::WaitForUninstallAppWorker }
-
- before do
- allow(service).to receive(:installation_errors).and_return(errors)
- allow(service).to receive(:remove_installation_pod)
- end
-
- shared_examples 'a not yet terminated installation' do |a_phase|
- let(:phase) { a_phase }
-
- before do
- expect(service).to receive(:pod_phase).once.and_return(phase)
- end
-
- context "when phase is #{a_phase}" do
- context 'when not timed_out' do
- it 'reschedule a new check' do
- expect(worker_class).to receive(:perform_in).once
- expect(service).not_to receive(:remove_installation_pod)
-
- expect do
- service.execute
-
- application.reload
- end.not_to change(application, :status)
-
- expect(application.status_reason).to be_nil
- end
- end
- end
- end
-
- context 'when application is uninstalling' do
- reschedule_phases.each { |phase| it_behaves_like 'a not yet terminated installation', phase }
-
- context 'when installation POD succeeded' do
- let(:phase) { Gitlab::Kubernetes::Pod::SUCCEEDED }
-
- before do
- expect_next_instance_of(Gitlab::Kubernetes::Helm::API) do |instance|
- expect(instance).to receive(:delete_pod!).with(kind_of(String)).once
- end
- expect(service).to receive(:pod_phase).once.and_return(phase)
- end
-
- it 'removes the installation POD' do
- expect(service).to receive(:remove_uninstallation_pod).and_call_original
-
- service.execute
- end
-
- it 'runs application post_uninstall' do
- expect(application).to receive(:post_uninstall).and_call_original
-
- service.execute
- end
-
- it 'destroys the application' do
- expect(worker_class).not_to receive(:perform_in)
-
- service.execute
-
- expect(application).to be_destroyed
- end
-
- context 'an error occurs while destroying' do
- before do
- expect(application).to receive(:destroy!).once.and_raise("destroy failed")
- end
-
- it 'still removes the installation POD' do
- expect(service).to receive(:remove_uninstallation_pod).and_call_original
-
- service.execute
- end
-
- it 'makes the application uninstall_errored' do
- service.execute
-
- expect(application).to be_uninstall_errored
- expect(application.status_reason).to eq('Application uninstalled but failed to destroy: destroy failed')
- end
- end
- end
-
- context 'when installation POD failed' do
- let(:phase) { Gitlab::Kubernetes::Pod::FAILED }
- let(:errors) { 'test installation failed' }
-
- before do
- expect(service).to receive(:pod_phase).once.and_return(phase)
- end
-
- it 'make the application errored' do
- service.execute
-
- expect(application).to be_uninstall_errored
- expect(application.status_reason).to eq('Operation failed. Check pod logs for uninstall-prometheus for more details.')
- end
- end
-
- context 'when timed out' do
- let(:application) { create(:clusters_applications_prometheus, :timed_out, :uninstalling) }
-
- before do
- expect(service).to receive(:pod_phase).once.and_return(phase)
- end
-
- it 'make the application errored' do
- expect(worker_class).not_to receive(:perform_in)
-
- service.execute
-
- expect(application).to be_uninstall_errored
- expect(application.status_reason).to eq('Operation timed out. Check pod logs for uninstall-prometheus for more details.')
- end
- end
-
- context 'when installation raises a Kubeclient::HttpError' do
- let(:cluster) { create(:cluster, :provided_by_user, :project) }
- let(:logger) { service.send(:logger) }
- let(:error) { Kubeclient::HttpError.new(401, 'Unauthorized', nil) }
-
- before do
- application.update!(cluster: cluster)
-
- expect(service).to receive(:pod_phase).and_raise(error)
- end
-
- include_examples 'logs kubernetes errors' do
- let(:error_name) { 'Kubeclient::HttpError' }
- let(:error_message) { 'Unauthorized' }
- let(:error_code) { 401 }
- end
-
- it 'shows the response code from the error' do
- service.execute
-
- expect(application).to be_uninstall_errored
- expect(application.status_reason).to eq('Kubernetes error: 401')
- end
- end
- end
-end
diff --git a/spec/services/clusters/applications/check_upgrade_progress_service_spec.rb b/spec/services/clusters/applications/check_upgrade_progress_service_spec.rb
deleted file mode 100644
index dbde8cec9b9..00000000000
--- a/spec/services/clusters/applications/check_upgrade_progress_service_spec.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Clusters::Applications::CheckUpgradeProgressService do
- reschedule_phashes = ::Gitlab::Kubernetes::Pod::PHASES -
- [::Gitlab::Kubernetes::Pod::SUCCEEDED, ::Gitlab::Kubernetes::Pod::FAILED, ::Gitlab].freeze
-
- let(:application) { create(:clusters_applications_prometheus, :updating) }
- let(:service) { described_class.new(application) }
- let(:phase) { ::Gitlab::Kubernetes::Pod::UNKNOWN }
- let(:errors) { nil }
-
- shared_examples 'a terminated upgrade' do
- it 'removes the POD' do
- expect(service).to receive(:remove_pod).once
-
- service.execute
- end
- end
-
- shared_examples 'a not yet terminated upgrade' do |a_phase|
- let(:phase) { a_phase }
-
- context "when phase is #{a_phase}" do
- context 'when not timed out' do
- it 'reschedule a new check' do
- expect(::ClusterWaitForAppUpdateWorker).to receive(:perform_in).once
- expect(service).not_to receive(:remove_pod)
-
- service.execute
-
- expect(application).to be_updating
- expect(application.status_reason).to be_nil
- end
- end
-
- context 'when timed out' do
- let(:application) { create(:clusters_applications_prometheus, :timed_out, :updating) }
-
- it_behaves_like 'a terminated upgrade'
-
- it 'make the application update errored' do
- expect(::ClusterWaitForAppUpdateWorker).not_to receive(:perform_in)
-
- service.execute
-
- expect(application).to be_update_errored
- expect(application.status_reason).to eq("Update timed out")
- end
- end
- end
- end
-
- before do
- allow(service).to receive(:phase).once.and_return(phase)
-
- allow(service).to receive(:errors).and_return(errors)
- allow(service).to receive(:remove_pod).and_return(nil)
- end
-
- describe '#execute' do
- context 'when upgrade pod succeeded' do
- let(:phase) { ::Gitlab::Kubernetes::Pod::SUCCEEDED }
-
- it_behaves_like 'a terminated upgrade'
-
- it 'make the application upgraded' do
- expect(::ClusterWaitForAppUpdateWorker).not_to receive(:perform_in)
-
- service.execute
-
- expect(application).to be_updated
- expect(application.status_reason).to be_nil
- end
- end
-
- context 'when upgrade pod failed' do
- let(:phase) { ::Gitlab::Kubernetes::Pod::FAILED }
- let(:errors) { 'test installation failed' }
-
- it_behaves_like 'a terminated upgrade'
-
- it 'make the application update errored' do
- service.execute
-
- expect(application).to be_update_errored
- expect(application.status_reason).to eq(errors)
- end
- end
-
- reschedule_phashes.each { |phase| it_behaves_like 'a not yet terminated upgrade', phase }
- end
-end
diff --git a/spec/services/clusters/applications/create_service_spec.rb b/spec/services/clusters/applications/create_service_spec.rb
deleted file mode 100644
index 00a67a9b2ef..00000000000
--- a/spec/services/clusters/applications/create_service_spec.rb
+++ /dev/null
@@ -1,279 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Clusters::Applications::CreateService do
- include TestRequestHelpers
-
- let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
- let(:user) { create(:user) }
- let(:params) { { application: 'ingress' } }
- let(:service) { described_class.new(cluster, user, params) }
-
- describe '#execute' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
- allow(ClusterUpgradeAppWorker).to receive(:perform_async)
- end
-
- subject { service.execute(test_request) }
-
- it 'creates an application' do
- expect do
- subject
-
- cluster.reload
- end.to change(cluster, :application_ingress)
- end
-
- context 'application already installed' do
- let!(:application) { create(:clusters_applications_ingress, :installed, cluster: cluster) }
-
- it 'does not create a new application' do
- expect do
- subject
- end.not_to change(Clusters::Applications::Ingress, :count)
- end
-
- it 'schedules an upgrade for the application' do
- expect(ClusterUpgradeAppWorker).to receive(:perform_async)
-
- subject
- end
- end
-
- context 'known applications' do
- context 'ingress application' do
- let(:params) do
- {
- application: 'ingress'
- }
- end
-
- before do
- expect_any_instance_of(Clusters::Applications::Ingress)
- .to receive(:make_scheduled!)
- .and_call_original
- end
-
- it 'creates the application' do
- expect do
- subject
-
- cluster.reload
- end.to change(cluster, :application_ingress)
- end
- end
-
- context 'cert manager application' do
- let(:params) do
- {
- application: 'cert_manager',
- email: 'test@example.com'
- }
- end
-
- before do
- expect_any_instance_of(Clusters::Applications::CertManager)
- .to receive(:make_scheduled!)
- .and_call_original
- end
-
- it 'creates the application' do
- expect do
- subject
-
- cluster.reload
- end.to change(cluster, :application_cert_manager)
- end
-
- it 'sets the email' do
- expect(subject.email).to eq('test@example.com')
- end
- end
-
- context 'jupyter application' do
- let(:params) do
- {
- application: 'jupyter',
- hostname: 'example.com'
- }
- end
-
- before do
- create(:clusters_applications_ingress, :installed, external_ip: "127.0.0.0", cluster: cluster)
- expect_any_instance_of(Clusters::Applications::Jupyter)
- .to receive(:make_scheduled!)
- .and_call_original
- end
-
- it 'creates the application' do
- expect do
- subject
-
- cluster.reload
- end.to change(cluster, :application_jupyter)
- end
-
- it 'sets the hostname' do
- expect(subject.hostname).to eq('example.com')
- end
-
- it 'sets the oauth_application' do
- expect(subject.oauth_application).to be_present
- end
- end
-
- context 'knative application' do
- let(:params) do
- {
- application: 'knative',
- hostname: 'example.com',
- pages_domain_id: domain.id
- }
- end
-
- let(:domain) { create(:pages_domain, :instance_serverless) }
- let(:associate_domain_service) { double('AssociateDomainService') }
-
- before do
- expect_any_instance_of(Clusters::Applications::Knative)
- .to receive(:make_scheduled!)
- .and_call_original
- end
-
- it 'creates the application' do
- expect do
- subject
-
- cluster.reload
- end.to change(cluster, :application_knative)
- end
-
- it 'sets the hostname' do
- expect(subject.hostname).to eq('example.com')
- end
-
- it 'executes AssociateDomainService' do
- expect(Serverless::AssociateDomainService).to receive(:new) do |knative, args|
- expect(knative).to be_a(Clusters::Applications::Knative)
- expect(args[:pages_domain_id]).to eq(params[:pages_domain_id])
- expect(args[:creator]).to eq(user)
-
- associate_domain_service
- end
-
- expect(associate_domain_service).to receive(:execute)
-
- subject
- end
- end
- end
-
- context 'invalid application' do
- let(:params) { { application: 'non-existent' } }
-
- it 'raises an error' do
- expect { subject }.to raise_error(Clusters::Applications::CreateService::InvalidApplicationError)
- end
- end
-
- context 'group cluster' do
- let(:cluster) { create(:cluster, :provided_by_gcp, :group) }
-
- using RSpec::Parameterized::TableSyntax
-
- where(:application, :association, :allowed, :pre_create_ingress) do
- 'ingress' | :application_ingress | true | false
- 'runner' | :application_runner | true | false
- 'prometheus' | :application_prometheus | true | false
- 'jupyter' | :application_jupyter | true | true
- end
-
- with_them do
- before do
- klass = "Clusters::Applications::#{application.titleize}"
- allow_any_instance_of(klass.constantize).to receive(:make_scheduled!).and_call_original
- create(:clusters_applications_ingress, :installed, cluster: cluster, external_hostname: 'example.com') if pre_create_ingress
- end
-
- let(:params) { { application: application } }
-
- it 'executes for each application' do
- if allowed
- expect do
- subject
-
- cluster.reload
- end.to change(cluster, association)
- else
- expect { subject }.to raise_error(Clusters::Applications::CreateService::InvalidApplicationError)
- end
- end
- end
- end
-
- context 'when application is installable' do
- shared_examples 'installable applications' do
- it 'makes the application scheduled' do
- expect do
- subject
- end.to change { Clusters::Applications::Ingress.with_status(:scheduled).count }.by(1)
- end
-
- it 'schedules an install via worker' do
- expect(ClusterInstallAppWorker)
- .to receive(:perform_async)
- .with(*worker_arguments)
- .once
-
- subject
- end
- end
-
- context 'when application is associated with a cluster' do
- let(:application) { create(:clusters_applications_ingress, :installable, cluster: cluster) }
- let(:worker_arguments) { [application.name, application.id] }
-
- it_behaves_like 'installable applications'
- end
-
- context 'when application is not associated with a cluster' do
- let(:worker_arguments) { [params[:application], kind_of(Numeric)] }
-
- it_behaves_like 'installable applications'
- end
- end
-
- context 'when installation is already in progress' do
- let!(:application) { create(:clusters_applications_ingress, :installing, cluster: cluster) }
-
- it 'raises an exception' do
- expect { subject }
- .to raise_exception(StateMachines::InvalidTransition)
- .and not_change(application.class.with_status(:scheduled), :count)
- end
-
- it 'does not schedule a cluster worker' do
- expect(ClusterInstallAppWorker).not_to receive(:perform_async)
- end
- end
-
- context 'when application is installed' do
- %i(installed updated).each do |status|
- let(:application) { create(:clusters_applications_ingress, status, cluster: cluster) }
-
- it 'schedules an upgrade via worker' do
- expect(ClusterUpgradeAppWorker)
- .to receive(:perform_async)
- .with(application.name, application.id)
- .once
-
- subject
-
- expect(application.reload).to be_scheduled
- end
- end
- end
- end
-end
diff --git a/spec/services/clusters/applications/patch_service_spec.rb b/spec/services/clusters/applications/patch_service_spec.rb
deleted file mode 100644
index 281da62b80b..00000000000
--- a/spec/services/clusters/applications/patch_service_spec.rb
+++ /dev/null
@@ -1,80 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Clusters::Applications::PatchService do
- describe '#execute' do
- let(:application) { create(:clusters_applications_knative, :scheduled) }
- let!(:update_command) { application.update_command }
- let(:service) { described_class.new(application) }
- let(:helm_client) { instance_double(Gitlab::Kubernetes::Helm::API) }
-
- before do
- allow(service).to receive(:update_command).and_return(update_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(update_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(update_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_knative, :scheduled) }
- let(:error) { StandardError.new('something bad happened') }
-
- include_examples 'logs kubernetes errors' do
- let(:error_name) { 'StandardError' }
- let(:error_message) { 'something bad happened' }
- let(:error_code) { nil }
- end
-
- before do
- expect(helm_client).to receive(:update).with(update_command).and_raise(error)
- end
-
- it 'make the application errored' do
- service.execute
-
- expect(application).to be_update_errored
- expect(application.status_reason).to eq(_('Failed to update.'))
- end
- end
- end
-end
diff --git a/spec/services/clusters/applications/prometheus_update_service_spec.rb b/spec/services/clusters/applications/prometheus_update_service_spec.rb
deleted file mode 100644
index 615bfc44045..00000000000
--- a/spec/services/clusters/applications/prometheus_update_service_spec.rb
+++ /dev/null
@@ -1,111 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Clusters::Applications::PrometheusUpdateService do
- describe '#execute' do
- let(:project) { create(:project) }
- let(:environment) { create(:environment, project: project) }
- let(:cluster) { create(:cluster, :provided_by_user, :with_installed_helm, projects: [project]) }
- let(:application) { create(:clusters_applications_prometheus, :installed, cluster: cluster) }
- let(:empty_alerts_values_update_yaml) { "---\nalertmanager:\n enabled: false\nserverFiles:\n alerts: {}\n" }
- let(:helm_client) { instance_double(::Gitlab::Kubernetes::Helm::API) }
-
- subject(:service) { described_class.new(application, project) }
-
- context 'when prometheus is a Clusters::Integrations::Prometheus' do
- let(:application) { create(:clusters_integrations_prometheus, cluster: cluster) }
-
- it 'raises NotImplementedError' do
- expect { service.execute }.to raise_error(NotImplementedError)
- end
- end
-
- context 'when prometheus is externally installed' do
- let(:application) { create(:clusters_applications_prometheus, :externally_installed, cluster: cluster) }
-
- it 'raises NotImplementedError' do
- expect { service.execute }.to raise_error(NotImplementedError)
- end
- end
-
- context 'when prometheus is a Clusters::Applications::Prometheus' do
- let!(:patch_command) { application.patch_command(empty_alerts_values_update_yaml) }
-
- before do
- allow(service).to receive(:patch_command).with(empty_alerts_values_update_yaml).and_return(patch_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(patch_command)
-
- allow(::ClusterWaitForAppUpdateWorker)
- .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 'updates current config' do
- prometheus_config_service = spy(:prometheus_config_service)
-
- expect(Clusters::Applications::PrometheusConfigService)
- .to receive(:new)
- .with(project, cluster, application)
- .and_return(prometheus_config_service)
-
- expect(prometheus_config_service)
- .to receive(:execute)
- .and_return(YAML.safe_load(empty_alerts_values_update_yaml))
-
- service.execute
- end
-
- it 'schedules async update status check' do
- expect(::ClusterWaitForAppUpdateWorker).to receive(:perform_in).once
-
- service.execute
- end
- end
-
- context 'when k8s cluster communication fails' do
- before do
- error = ::Kubeclient::HttpError.new(500, 'system failure', nil)
- allow(helm_client).to receive(:update).and_raise(error)
- end
-
- it 'make the application update errored' do
- service.execute
-
- expect(application).to be_update_errored
- expect(application.status_reason).to match(/kubernetes error:/i)
- end
- end
-
- context 'when application cannot be persisted' do
- let(:application) { build(:clusters_applications_prometheus, :installed) }
-
- before do
- allow(application).to receive(:make_updating!).once
- .and_raise(ActiveRecord::RecordInvalid.new(application))
- end
-
- it 'make the application update errored' do
- expect(helm_client).not_to receive(:update)
-
- service.execute
-
- expect(application).to be_update_errored
- end
- end
- end
- end
-end
diff --git a/spec/services/clusters/applications/update_service_spec.rb b/spec/services/clusters/applications/update_service_spec.rb
deleted file mode 100644
index 4c05a12a4a1..00000000000
--- a/spec/services/clusters/applications/update_service_spec.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Clusters::Applications::UpdateService do
- include TestRequestHelpers
-
- let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
- let(:user) { create(:user) }
- let(:params) { { application: 'knative', hostname: 'update.example.com', pages_domain_id: domain.id } }
- let(:service) { described_class.new(cluster, user, params) }
- let(:domain) { create(:pages_domain, :instance_serverless) }
-
- subject { service.execute(test_request) }
-
- describe '#execute' do
- before do
- allow(ClusterPatchAppWorker).to receive(:perform_async)
- end
-
- context 'application is not installed' do
- it 'raises Clusters::Applications::BaseService::InvalidApplicationError' do
- expect(ClusterPatchAppWorker).not_to receive(:perform_async)
-
- expect { subject }
- .to raise_exception { Clusters::Applications::BaseService::InvalidApplicationError }
- .and not_change { Clusters::Applications::Knative.count }
- .and not_change { Clusters::Applications::Knative.with_status(:scheduled).count }
- end
- end
-
- context 'application is installed' do
- context 'application is schedulable' do
- let!(:application) do
- create(:clusters_applications_knative, status: 3, cluster: cluster)
- end
-
- it 'updates the application data' do
- expect do
- subject
- end.to change { application.reload.hostname }.to(params[:hostname])
- end
-
- it 'makes application scheduled!' do
- subject
-
- expect(application.reload).to be_scheduled
- end
-
- it 'schedules ClusterPatchAppWorker' do
- expect(ClusterPatchAppWorker).to receive(:perform_async)
-
- subject
- end
-
- context 'knative application' do
- let(:associate_domain_service) { double('AssociateDomainService') }
-
- it 'executes AssociateDomainService' do
- expect(Serverless::AssociateDomainService).to receive(:new) do |knative, args|
- expect(knative.id).to eq(application.id)
- expect(args[:pages_domain_id]).to eq(params[:pages_domain_id])
- expect(args[:creator]).to eq(user)
-
- associate_domain_service
- end
-
- expect(associate_domain_service).to receive(:execute)
-
- subject
- end
- end
- end
-
- context 'application is not schedulable' do
- let!(:application) do
- create(:clusters_applications_knative, status: 4, cluster: cluster)
- end
-
- it 'raises StateMachines::InvalidTransition' do
- expect(ClusterPatchAppWorker).not_to receive(:perform_async)
-
- expect { subject }
- .to raise_exception { StateMachines::InvalidTransition }
- .and not_change { application.reload.hostname }
- .and not_change { Clusters::Applications::Knative.with_status(:scheduled).count }
- end
- end
- end
- end
-end
diff --git a/spec/services/clusters/gcp/provision_service_spec.rb b/spec/services/clusters/gcp/provision_service_spec.rb
index c5778db6001..c8b7f628e5b 100644
--- a/spec/services/clusters/gcp/provision_service_spec.rb
+++ b/spec/services/clusters/gcp/provision_service_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe Clusters::Gcp::ProvisionService do
gcp_project_id, zone,
{
"status": 'unexpected'
- } )
+ })
end
it_behaves_like 'error'
diff --git a/spec/services/clusters/gcp/verify_provision_status_service_spec.rb b/spec/services/clusters/gcp/verify_provision_status_service_spec.rb
index ccb4b3b6c15..ffe4516c02b 100644
--- a/spec/services/clusters/gcp/verify_provision_status_service_spec.rb
+++ b/spec/services/clusters/gcp/verify_provision_status_service_spec.rb
@@ -44,7 +44,7 @@ RSpec.describe Clusters::Gcp::VerifyProvisionStatusService do
{
"status": 'RUNNING',
"startTime": 1.minute.ago.strftime("%FT%TZ")
- } )
+ })
end
it_behaves_like 'continue_creation'
@@ -56,7 +56,7 @@ RSpec.describe Clusters::Gcp::VerifyProvisionStatusService do
{
"status": 'RUNNING',
"startTime": 30.minutes.ago.strftime("%FT%TZ")
- } )
+ })
end
it_behaves_like 'error'
@@ -70,7 +70,7 @@ RSpec.describe Clusters::Gcp::VerifyProvisionStatusService do
{
"status": 'PENDING',
"startTime": 1.minute.ago.strftime("%FT%TZ")
- } )
+ })
end
it_behaves_like 'continue_creation'
@@ -82,7 +82,7 @@ RSpec.describe Clusters::Gcp::VerifyProvisionStatusService do
gcp_project_id, zone, operation_id,
{
"status": 'DONE'
- } )
+ })
end
it_behaves_like 'finalize_creation'
@@ -94,7 +94,7 @@ RSpec.describe Clusters::Gcp::VerifyProvisionStatusService do
gcp_project_id, zone, operation_id,
{
"status": 'unexpected'
- } )
+ })
end
it_behaves_like 'error'
diff --git a/spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb b/spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb
deleted file mode 100644
index f26177a56d0..00000000000
--- a/spec/services/clusters/kubernetes/configure_istio_ingress_service_spec.rb
+++ /dev/null
@@ -1,223 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Clusters::Kubernetes::ConfigureIstioIngressService, '#execute' do
- include KubernetesHelpers
-
- let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
- let(:api_url) { 'https://kubernetes.example.com' }
- let(:project) { cluster.project }
- let(:environment) { create(:environment, project: project) }
- let(:cluster_project) { cluster.cluster_project }
- let(:namespace) { "#{project.name}-#{project.id}-#{environment.slug}" }
- let(:kubeclient) { cluster.kubeclient }
-
- subject do
- described_class.new(
- cluster: cluster
- ).execute
- end
-
- before do
- stub_kubeclient_discover_istio(api_url)
- stub_kubeclient_create_secret(api_url, namespace: namespace)
- stub_kubeclient_put_secret(api_url, "#{namespace}-token", namespace: namespace)
-
- stub_kubeclient_get_secret(
- api_url,
- metadata_name: "#{namespace}-token",
- token: Base64.encode64('sample-token'),
- namespace: namespace
- )
-
- stub_kubeclient_get_secret(
- api_url,
- metadata_name: 'istio-ingressgateway-ca-certs',
- namespace: 'istio-system'
- )
-
- stub_kubeclient_get_secret(
- api_url,
- metadata_name: 'istio-ingressgateway-certs',
- namespace: 'istio-system'
- )
-
- stub_kubeclient_put_secret(api_url, 'istio-ingressgateway-ca-certs', namespace: 'istio-system')
- stub_kubeclient_put_secret(api_url, 'istio-ingressgateway-certs', namespace: 'istio-system')
- stub_kubeclient_get_gateway(api_url, 'knative-ingress-gateway', namespace: 'knative-serving')
- stub_kubeclient_put_gateway(api_url, 'knative-ingress-gateway', namespace: 'knative-serving')
- end
-
- context 'without a serverless_domain_cluster' do
- it 'configures gateway to use PASSTHROUGH' do
- subject
-
- expect(WebMock).to have_requested(:put, api_url + '/apis/networking.istio.io/v1alpha3/namespaces/knative-serving/gateways/knative-ingress-gateway').with(
- body: hash_including(
- apiVersion: "networking.istio.io/v1alpha3",
- kind: "Gateway",
- metadata: {
- generation: 1,
- labels: {
- "networking.knative.dev/ingress-provider" => "istio",
- "serving.knative.dev/release" => "v0.7.0"
- },
- name: "knative-ingress-gateway",
- namespace: "knative-serving",
- selfLink: "/apis/networking.istio.io/v1alpha3/namespaces/knative-serving/gateways/knative-ingress-gateway"
- },
- spec: {
- selector: {
- istio: "ingressgateway"
- },
- servers: [
- {
- hosts: ["*"],
- port: {
- name: "http",
- number: 80,
- protocol: "HTTP"
- }
- },
- {
- hosts: ["*"],
- port: {
- name: "https",
- number: 443,
- protocol: "HTTPS"
- },
- tls: {
- mode: "PASSTHROUGH"
- }
- }
- ]
- }
- )
- )
- end
- end
-
- context 'with a serverless_domain_cluster' do
- let(:serverless_domain_cluster) { create(:serverless_domain_cluster) }
- let(:certificate) { OpenSSL::X509::Certificate.new(serverless_domain_cluster.certificate) }
-
- before do
- cluster.application_knative = serverless_domain_cluster.knative
- end
-
- it 'configures certificates' do
- subject
-
- expect(serverless_domain_cluster.reload.key).not_to be_blank
- expect(serverless_domain_cluster.reload.certificate).not_to be_blank
-
- expect(certificate.subject.to_s).to include(serverless_domain_cluster.knative.hostname)
-
- expect(certificate.not_before).to be_within(1.minute).of(Time.current)
- expect(certificate.not_after).to be_within(1.minute).of(Time.current + 1000.years)
-
- expect(WebMock).to have_requested(:put, api_url + '/api/v1/namespaces/istio-system/secrets/istio-ingressgateway-ca-certs').with(
- body: hash_including(
- metadata: {
- name: 'istio-ingressgateway-ca-certs',
- namespace: 'istio-system'
- },
- type: 'Opaque'
- )
- )
-
- expect(WebMock).to have_requested(:put, api_url + '/api/v1/namespaces/istio-system/secrets/istio-ingressgateway-certs').with(
- body: hash_including(
- metadata: {
- name: 'istio-ingressgateway-certs',
- namespace: 'istio-system'
- },
- type: 'kubernetes.io/tls'
- )
- )
- end
-
- it 'configures gateway to use MUTUAL' do
- subject
-
- expect(WebMock).to have_requested(:put, api_url + '/apis/networking.istio.io/v1alpha3/namespaces/knative-serving/gateways/knative-ingress-gateway').with(
- body: {
- apiVersion: "networking.istio.io/v1alpha3",
- kind: "Gateway",
- metadata: {
- generation: 1,
- labels: {
- "networking.knative.dev/ingress-provider" => "istio",
- "serving.knative.dev/release" => "v0.7.0"
- },
- name: "knative-ingress-gateway",
- namespace: "knative-serving",
- selfLink: "/apis/networking.istio.io/v1alpha3/namespaces/knative-serving/gateways/knative-ingress-gateway"
- },
- spec: {
- selector: {
- istio: "ingressgateway"
- },
- servers: [
- {
- hosts: ["*"],
- port: {
- name: "http",
- number: 80,
- protocol: "HTTP"
- }
- },
- {
- hosts: ["*"],
- port: {
- name: "https",
- number: 443,
- protocol: "HTTPS"
- },
- tls: {
- mode: "MUTUAL",
- privateKey: "/etc/istio/ingressgateway-certs/tls.key",
- serverCertificate: "/etc/istio/ingressgateway-certs/tls.crt",
- caCertificates: "/etc/istio/ingressgateway-ca-certs/cert.pem"
- }
- }
- ]
- }
- }
- )
- end
- end
-
- context 'when there is an error' do
- before do
- cluster.application_knative = create(:clusters_applications_knative)
-
- allow_next_instance_of(described_class) do |instance|
- allow(instance).to receive(:configure_passthrough).and_raise(error)
- end
- end
-
- context 'Kubeclient::HttpError' do
- let(:error) { Kubeclient::HttpError.new(404, nil, nil) }
-
- it 'puts Knative into an errored state' do
- subject
-
- expect(cluster.application_knative).to be_errored
- expect(cluster.application_knative.status_reason).to eq('Kubernetes error: 404')
- end
- end
-
- context 'StandardError' do
- let(:error) { RuntimeError.new('something went wrong') }
-
- it 'puts Knative into an errored state' do
- subject
-
- expect(cluster.application_knative).to be_errored
- expect(cluster.application_knative.status_reason).to eq('Failed to update.')
- end
- end
- end
-end
diff --git a/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb
index 064f9e42e96..37478a0bcd9 100644
--- a/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb
+++ b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb
@@ -166,7 +166,7 @@ RSpec.describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do
expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{role_binding_name}").with(
body: hash_including(
- metadata: { name: "gitlab-#{namespace}", namespace: "#{namespace}" },
+ metadata: { name: "gitlab-#{namespace}", namespace: namespace.to_s },
roleRef: {
apiGroup: 'rbac.authorization.k8s.io',
kind: 'ClusterRole',