Skip to content
Snippets Groups Projects
Commit 6b9157d5 authored by James Fargher's avatar James Fargher Committed by Thong Kuah
Browse files

Make KubernetesService readonly

We are deprecating this service in favor of instance wide clusters.
Therefore we removed some code that is not anymore needed for a
readonly cluster and also we added some flags to allow for this
deprecation. These flags are to be removed in the next release when
we finally completelly remove KubernetesService.
parent 04307096
No related branches found
No related tags found
No related merge requests found
Showing
with 108 additions and 225 deletions
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -340,6 +340,11 @@
 
.deprecated-service {
cursor: default;
a {
font-weight: $gl-font-weight-bold;
color: $white-light;
}
}
 
.personal-access-tokens-never-expires-label {
Loading
Loading
Loading
Loading
@@ -39,7 +39,7 @@ def service_save_button(service)
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
Loading
Loading
# 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
Loading
Loading
@@ -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
Loading
Loading
@@ -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,
Loading
Loading
@@ -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
Loading
Loading
@@ -56,11 +69,6 @@ def description
'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
Loading
Loading
@@ -153,14 +161,25 @@ def kubeclient
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") % {
deprecated_message_content: deprecated_message_content,
url: Gitlab::Routing.url_helpers.project_clusters_path(project)
}
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
 
Loading
Loading
@@ -243,10 +262,6 @@ def deprecation_validation
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
_("Fields on this page are now uneditable, you can configure")
end
end
# frozen_string_literal: true
 
class MockDeploymentService < DeploymentService
class MockDeploymentService < Service
default_value_for :category, 'deployment'
def title
'Mock deployment'
end
Loading
Loading
@@ -17,4 +19,16 @@ def self.to_param
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
Loading
Loading
@@ -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
 
.footer-block.row-content-block
= form.submit 'Save', class: 'btn btn-success'
- 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
Loading
Loading
@@ -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 ""
 
Loading
Loading
@@ -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 ""
 
Loading
Loading
Loading
Loading
@@ -123,7 +123,11 @@
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) }
 
Loading
Loading
@@ -143,22 +147,6 @@
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) }
 
Loading
Loading
Loading
Loading
@@ -141,20 +141,6 @@ def do_put
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) }
 
Loading
Loading
@@ -168,20 +154,10 @@ def do_put
 
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
Loading
Loading
Loading
Loading
@@ -24,6 +24,8 @@
api_url: 'https://kubernetes.example.com',
token: 'a' * 40
})
skip_deprecation_validation true
end
 
factory :mock_deployment_service do
Loading
Loading
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
Loading
Loading
@@ -155,7 +155,10 @@
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 }
 
Loading
Loading
@@ -191,19 +194,6 @@
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
Loading
Loading
Loading
Loading
@@ -248,7 +248,10 @@ def stop_button_selector
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 }
 
Loading
Loading
@@ -265,19 +268,6 @@ def stop_button_selector
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
 
Loading
Loading
Loading
Loading
@@ -4,24 +4,14 @@
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
 
Loading
Loading
Loading
Loading
@@ -962,7 +962,11 @@ def create_build(name, status)
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
 
Loading
Loading
@@ -971,21 +975,6 @@ def create_build(name, status)
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
Loading
Loading
@@ -1679,23 +1668,13 @@ def create_build(name, *traits, queued_at: current, started_from: 0, **opts)
 
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
 
Loading
Loading
Loading
Loading
@@ -515,29 +515,19 @@
 
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
Loading
Loading
@@ -546,8 +536,6 @@
end
 
context 'when the environment is unavailable' do
let(:project) { create(:kubernetes_project) }
before do
environment.stop
end
Loading
Loading
@@ -590,7 +578,10 @@
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)
Loading
Loading
@@ -599,19 +590,6 @@
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
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment