Commit 1276ff85 authored by Thong Kuah's avatar Thong Kuah

Merge branch 'readonly_k8s_integration' into 'master'

Make Kubernetes service templates readonly

See merge request gitlab-org/gitlab-ce!29044
parents 04307096 6b9157d5
......@@ -799,7 +799,6 @@ Style/SelfAssignment:
Exclude:
- 'app/models/concerns/bulk_member_access_load.rb'
- 'app/serializers/base_serializer.rb'
- 'spec/features/projects/clusters/interchangeability_spec.rb'
- 'spec/support/import_export/configuration_helper.rb'
# Offense count: 50
......
......@@ -340,6 +340,11 @@
.deprecated-service {
cursor: default;
a {
font-weight: $gl-font-weight-bold;
color: $white-light;
}
}
.personal-access-tokens-never-expires-label {
......
......@@ -39,7 +39,7 @@ module ServicesHelper
end
def disable_fields_service?(service)
!current_controller?("admin/services") && service.deprecated?
service.is_a?(KubernetesService) || (!current_controller?("admin/services") && service.deprecated?)
end
extend self
......
# frozen_string_literal: true
# Base class for deployment services
#
# These services integrate with a deployment solution like Kubernetes/OpenShift,
# Mesosphere, etc, to provide additional features to environments.
class DeploymentService < Service
default_value_for :category, 'deployment'
def self.supported_events
%w()
end
def predefined_variables(project:)
[]
end
# Environments may have a number of terminals. Should return an array of
# hashes describing them, e.g.:
#
# [{
# :selectors => {"a" => "b", "foo" => "bar"},
# :url => "wss://external.example.com/exec",
# :headers => {"Authorization" => "Token xxx"},
# :subprotocols => ["foo"],
# :ca_pem => "----BEGIN CERTIFICATE...", # optional
# :created_at => Time.now.utc
# }]
#
# Selectors should be a set of values that uniquely identify a particular
# terminal
def terminals(environment)
raise NotImplementedError
end
def can_test?
false
end
end
......@@ -5,10 +5,12 @@
# We'll move this class to Clusters::Platforms::Kubernetes, which contains exactly the same logic.
# After we've migrated data, we'll remove KubernetesService. This would happen in a few months.
# If you're modyfiyng this class, please note that you should update the same change in Clusters::Platforms::Kubernetes.
class KubernetesService < DeploymentService
class KubernetesService < Service
include Gitlab::Kubernetes
include ReactiveCaching
default_value_for :category, 'deployment'
self.reactive_cache_key = ->(service) { [service.class.model_name.singular, service.project_id] }
# Namespace defaults to the project path, but can be overridden in case that
......@@ -32,7 +34,10 @@ class KubernetesService < DeploymentService
before_validation :enforce_namespace_to_lower_case
validate :deprecation_validation, unless: :template?
attr_accessor :skip_deprecation_validation
validate :deprecation_validation, unless: :skip_deprecation_validation
validates :namespace,
allow_blank: true,
length: 1..63,
......@@ -44,6 +49,14 @@ class KubernetesService < DeploymentService
after_save :clear_reactive_cache!
def self.supported_events
%w()
end
def can_test?
false
end
def initialize_properties
self.properties = {} if properties.nil?
end
......@@ -56,11 +69,6 @@ class KubernetesService < DeploymentService
'Kubernetes / OpenShift integration'
end
def help
'To enable terminal access to Kubernetes environments, label your ' \
'deployments with `app=$CI_ENVIRONMENT_SLUG`'
end
def self.to_param
'kubernetes'
end
......@@ -153,14 +161,25 @@ class KubernetesService < DeploymentService
end
def deprecated?
!active
true
end
def editable?
false
end
def deprecation_message
content = _("Kubernetes service integration has been deprecated. %{deprecated_message_content} your Kubernetes clusters using the new <a href=\"%{url}\"/>Kubernetes Clusters</a> page") % {
content = if project
_("Kubernetes service integration has been deprecated. %{deprecated_message_content} your Kubernetes clusters using the new <a href=\"%{url}\"/>Kubernetes Clusters</a> page") % {
deprecated_message_content: deprecated_message_content,
url: Gitlab::Routing.url_helpers.project_clusters_path(project)
}
else
_("The instance-level Kubernetes service integration is deprecated. Your data has been migrated to an <a href=\"%{url}\"/>instance-level cluster</a>.") % {
url: Gitlab::Routing.url_helpers.admin_clusters_path
}
end
content.html_safe
end
......@@ -243,10 +262,6 @@ class KubernetesService < DeploymentService
end
def deprecated_message_content
if active?
_("Your Kubernetes cluster information on this page is still editable, but you are advised to disable and reconfigure")
else
_("Fields on this page are now uneditable, you can configure")
end
end
end
# frozen_string_literal: true
class MockDeploymentService < DeploymentService
class MockDeploymentService < Service
default_value_for :category, 'deployment'
def title
'Mock deployment'
end
......@@ -17,4 +19,16 @@ class MockDeploymentService < DeploymentService
def terminals(environment)
[]
end
def self.supported_events
%w()
end
def predefined_variables(project:)
[]
end
def can_test?
false
end
end
.flash-container.flash-container-page
.flash-alert.deprecated-service
%span= @service.deprecation_message
......@@ -6,5 +6,6 @@
= form_for :service, url: admin_application_settings_service_path, method: :put, html: { class: 'fieldset-form' } do |form|
= render 'shared/service_settings', form: form, subject: @service
- unless @service.is_a?(KubernetesService)
.footer-block.row-content-block
= form.submit 'Save', class: 'btn btn-success'
- add_to_breadcrumbs "Service Templates", admin_application_settings_services_path
- breadcrumb_title @service.title
- page_title @service.title, "Service Templates"
= render 'deprecated_message' if @service.deprecation_message
= render 'form'
---
title: Make Kubernetes service templates readonly
merge_request: 29044
author:
type: removed
......@@ -9999,6 +9999,9 @@ msgstr ""
msgid "The import will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
msgid "The instance-level Kubernetes service integration is deprecated. Your data has been migrated to an <a href=\"%{url}\"/>instance-level cluster</a>."
msgstr ""
msgid "The invitation could not be accepted."
msgstr ""
......@@ -11943,9 +11946,6 @@ msgstr ""
msgid "Your Groups"
msgstr ""
msgid "Your Kubernetes cluster information on this page is still editable, but you are advised to disable and reconfigure"
msgstr ""
msgid "Your Primary Email will be used for avatar detection."
msgstr ""
......
......@@ -123,7 +123,11 @@ describe Projects::BranchesController do
expect(response).to redirect_to project_tree_path(project, branch)
end
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'when user configured kubernetes from CI/CD > Clusters' do
before do
create(:cluster, :provided_by_gcp, projects: [project])
end
it 'redirects to autodeploy setup page' do
result = { status: :success, branch: double(name: branch) }
......@@ -143,22 +147,6 @@ describe Projects::BranchesController do
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
before do
project.services << build(:kubernetes_service)
end
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
before do
create(:cluster, :provided_by_gcp, projects: [project])
end
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
it 'redirects to autodeploy setup page' do
result = { status: :success, branch: double(name: branch) }
......
......@@ -141,20 +141,6 @@ describe Projects::ServicesController do
end
end
context 'with a deprecated service' do
let(:service) { create(:kubernetes_service, project: project) }
before do
put :update,
params: { namespace_id: project.namespace, project_id: project, id: service.to_param, service: { namespace: 'updated_namespace' } }
end
it 'does not update the service' do
service.reload
expect(service.namespace).not_to eq('updated_namespace')
end
end
context 'when activating JIRA service from a template' do
let(:template_service) { create(:jira_service, project: project, template: true) }
......@@ -168,20 +154,10 @@ describe Projects::ServicesController do
describe "GET #edit" do
before do
get :edit, params: { namespace_id: project.namespace, project_id: project, id: service_id }
get :edit, params: { namespace_id: project.namespace, project_id: project, id: 'jira' }
end
context 'with approved services' do
let(:service_id) { 'jira' }
it 'renders edit page' do
expect(response).to be_success
end
end
context 'with a deprecated service' do
let(:service_id) { 'kubernetes' }
it 'renders edit page' do
expect(response).to be_success
end
......
......@@ -24,6 +24,8 @@ FactoryBot.define do
api_url: 'https://kubernetes.example.com',
token: 'a' * 40
})
skip_deprecation_validation true
end
factory :mock_deployment_service do
......
require 'spec_helper'
describe 'Interchangeability between KubernetesService and Platform::Kubernetes' do
EXCEPT_METHODS = %i[test title description help fields initialize_properties namespace namespace= api_url api_url= deprecated? deprecation_message].freeze
EXCEPT_METHODS_GREP_V = %w[_touched? _changed? _was].freeze
it 'Clusters::Platform::Kubernetes covers core interfaces in KubernetesService' do
expected_interfaces = KubernetesService.instance_methods(false)
expected_interfaces = expected_interfaces - EXCEPT_METHODS
EXCEPT_METHODS_GREP_V.each do |g|
expected_interfaces = expected_interfaces.grep_v(/#{Regexp.escape(g)}\z/)
end
expect(expected_interfaces - Clusters::Platforms::Kubernetes.instance_methods).to be_empty
end
end
......@@ -155,7 +155,10 @@ describe 'Environment' do
end
context 'with terminal' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
context 'for project maintainer' do
let(:role) { :maintainer }
......@@ -191,19 +194,6 @@ describe 'Environment' do
end
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project, :test_repo) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
context 'when environment is available' do
......
......@@ -248,7 +248,10 @@ describe 'Environments page', :js do
end
context 'when kubernetes terminal is available' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'when user configured kubernetes from CI/CD > Clusters' do
let(:cluster) { create(:cluster, :provided_by_gcp, projects: [create(:project, :repository)]) }
let(:project) { cluster.project }
context 'for project maintainer' do
let(:role) { :maintainer }
......@@ -265,19 +268,6 @@ describe 'Environments page', :js do
end
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project, :test_repo) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let(:cluster) { create(:cluster, :provided_by_gcp, projects: [create(:project, :repository)]) }
let(:project) { cluster.project }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
end
......
......@@ -4,24 +4,14 @@ describe Gitlab::Ci::Build::Policy::Kubernetes do
let(:pipeline) { create(:ci_pipeline, project: project) }
context 'when kubernetes service is active' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
it 'is satisfied by a kubernetes pipeline' do
expect(described_class.new('active'))
.to be_satisfied_by(pipeline)
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
it 'is satisfied by a kubernetes pipeline' do
expect(described_class.new('active'))
.to be_satisfied_by(pipeline)
end
end
end
......
......@@ -962,7 +962,11 @@ describe Ci::Pipeline, :mailer do
end
context 'when kubernetes is active' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
let(:pipeline) { build(:ci_pipeline, project: project, config: config) }
it 'returns seeds for kubernetes dependent job' do
seeds = pipeline.stage_seeds
......@@ -971,21 +975,6 @@ describe Ci::Pipeline, :mailer do
expect(seeds.dig(1, 0, :name)).to eq 'production'
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
let(:pipeline) { build(:ci_pipeline, project: project, config: config) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
let(:pipeline) { build(:ci_pipeline, project: project, config: config) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
context 'when kubernetes is not active' do
......@@ -1679,23 +1668,13 @@ describe Ci::Pipeline, :mailer do
describe '#has_kubernetes_active?' do
context 'when kubernetes is active' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
it 'returns true' do
expect(pipeline).to have_kubernetes_active
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
it 'returns true' do
expect(pipeline).to have_kubernetes_active
end
end
end
......
......@@ -515,29 +515,19 @@ describe Environment do
context 'when the environment is available' do
context 'with a deployment service' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'and a deployment' do
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
context 'with deployment' do
let!(:deployment) { create(:deployment, :success, environment: environment) }
it { is_expected.to be_truthy }
end
context 'but no deployments' do
context 'without deployments' do
it { is_expected.to be_falsy }
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
context 'without a deployment service' do
......@@ -546,8 +536,6 @@ describe Environment do
end
context 'when the environment is unavailable' do
let(:project) { create(:kubernetes_project) }
before do
environment.stop
end
......@@ -590,7 +578,10 @@ describe Environment do
allow(environment).to receive(:has_terminals?).and_return(true)
end
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it 'returns the terminals from the deployment service' do
expect(environment.deployment_platform)
.to receive(:terminals).with(environment)
......@@ -599,19 +590,6 @@ describe Environment do
is_expected.to eq(:fake_terminals)
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
context 'when the environment does not have terminals' do
......
......@@ -17,6 +17,7 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do
context 'when service is active' do
before do
subject.active = true
subject.skip_deprecation_validation = true
end
it { is_expected.not_to validate_presence_of(:namespace) }
......@@ -67,6 +68,7 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do
before do
kubernetes_service.update_attribute(:active, false)
kubernetes_service.skip_deprecation_validation = false
kubernetes_service.properties['namespace'] = "foo"
end
......@@ -80,19 +82,11 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do
end
end
context 'with a non-deprecated service' do
let(:kubernetes_service) { create(:kubernetes_service) }
it 'updates attributes' do
kubernetes_service.properties['namespace'] = 'foo'
expect(kubernetes_service.save).to be_truthy
end
end
context 'with an active and deprecated service' do
let(:kubernetes_service) { create(:kubernetes_service) }
before do
kubernetes_service.skip_deprecation_validation = false
kubernetes_service.active = false
kubernetes_service.properties['namespace'] = 'foo'
kubernetes_service.save
......@@ -110,19 +104,6 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do
expect(kubernetes_service.properties['namespace']).to eq("foo")
end
end
context 'with a template service' do
let(:kubernetes_service) { create(:kubernetes_service, template: true, active: false) }
before do
kubernetes_service.properties['namespace'] = 'foo'
end
it 'updates attributes' do
expect(kubernetes_service.save).to be_truthy
expect(kubernetes_service.properties['namespace']).to eq('foo')
end
end
end
describe '#initialize_properties' do
......@@ -393,19 +374,10 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do
describe "#deprecated?" do
let(:kubernetes_service) { create(:kubernetes_service) }
context 'with an active kubernetes service' do
it 'returns false' do
expect(kubernetes_service.deprecated?).to be_falsy
end
end
context 'with a inactive kubernetes service' do
it 'returns true' do
kubernetes_service.update_attribute(:active, false)
expect(kubernetes_service.deprecated?).to be_truthy
end
end
end
describe "#deprecation_message" do
let(:kubernetes_service) { create(:kubernetes_service) }
......@@ -414,12 +386,6 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do
expect(kubernetes_service.deprecation_message).to match(/Kubernetes service integration has been deprecated/)
end
context 'if the services is active' do
it 'returns a message' do
expect(kubernetes_service.deprecation_message).to match(/Your Kubernetes cluster information on this page is still editable/)
end
end
context 'if the service is not active' do
it 'returns a message' do
kubernetes_service.update_attribute(:active, false)
......
......@@ -2652,7 +2652,10 @@ describe Project do
end
context 'when project has a deployment service' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'when user configured kubernetes from CI/CD > Clusters and KubernetesNamespace migration has not been executed' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it 'returns variables from this service' do
expect(project.deployment_variables).to include(
{ key: 'KUBE_TOKEN', value: project.deployment_platform.token, public: false, masked: true }
......@@ -2660,19 +2663,6 @@ describe Project do
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters and KubernetesNamespace migration has not been executed' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters and KubernetesNamespace migration has been executed' do
let!(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, :with_token) }
let!(:cluster) { kubernetes_namespace.cluster }
......
......@@ -82,7 +82,7 @@ describe Service do
context 'when template is invalid' do
it 'sets service template to inactive when template is invalid' do
project = create(:project)
template = KubernetesService.new(template: true, active: true)
template = build(:prometheus_service, template: true, active: true, properties: {})
template.save(validate: false)
service = described_class.build_from_template(project.id, template)
......@@ -309,10 +309,10 @@ describe Service do
end
describe '.find_by_template' do
let!(:kubernetes_service) { create(:kubernetes_service, template: true) }
let!(:service) { create(:service, template: true) }
it 'returns service template' do
expect(KubernetesService.find_by_template).to eq(kubernetes_service)
expect(described_class.find_by_template).to eq(service)
end
end
......
......@@ -10,7 +10,10 @@ describe API::Services do
end
Service.available_services_names.each do |service|
describe "PUT /projects/:id/services/#{service.dasherize}" do
# TODO: Remove below `if: (service != "kubernetes")` in the next release
# KubernetesService was deprecated and it can't be updated. Right now it's
# only readable. It should be completely removed in the next iteration.
describe "PUT /projects/:id/services/#{service.dasherize}", if: (service != "kubernetes") do
include_context service
it "updates #{service} settings" do
......@@ -59,7 +62,10 @@ describe API::Services do
end
end
describe "DELETE /projects/:id/services/#{service.dasherize}" do
# TODO: Remove below `if: (service != "kubernetes")` in the next release
# KubernetesService was deprecated and it can't be updated. Right now it's
# only readable. It should be completely removed in the next iteration.
describe "DELETE /projects/:id/services/#{service.dasherize}", if: (service != "kubernetes") do
include_context service
before do
......
......@@ -59,15 +59,5 @@ describe EnvironmentEntity do
expect(subject[:cluster_type]).to eq('project_type')
end
end
context 'when deployment platform is a Kubernetes Service' do
before do
create(:kubernetes_service, project: project)
end
it 'does not include cluster_type' do
expect(subject).not_to include(:cluster_type)
end
end
end
end
......@@ -44,7 +44,9 @@ RSpec.shared_examples 'additional metrics query' do
end
describe 'project has Kubernetes service' do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
let(:environment) { create(:environment, slug: 'environment-slug', project: project) }
let(:kube_namespace) { project.deployment_platform.kubernetes_namespace_for(project) }
......@@ -56,19 +58,6 @@ RSpec.shared_examples 'additional metrics query' do
subject.query(*query_params)
end
end
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
it_behaves_like 'same behavior between KubernetesService and Platform::Kubernetes'
end
end
describe 'project without Kubernetes service' do
......
......@@ -37,8 +37,7 @@ Service.available_services_names.each do |service|
def initialize_service(service)
service_item = project.find_or_initialize_service(service)
service_item.properties = service_attrs
service_item.active = true if service == "kubernetes"
service_item.save
service_item.save!
service_item
end
end
......
......@@ -6,16 +6,6 @@ describe ReactiveCachingWorker do
let(:service) { project.deployment_platform }
describe '#perform' do
context 'when user configured kubernetes from Integration > Kubernetes' do
let(:project) { create(:kubernetes_project) }
it 'calls #exclusively_update_reactive_cache!' do
expect_any_instance_of(KubernetesService).to receive(:exclusively_update_reactive_cache!)
described_class.new.perform("KubernetesService", service.id)
end
end
context 'when user configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:project) { cluster.project }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment