From e3696bf20e4d646f46f847237da828eaee00253a Mon Sep 17 00:00:00 2001 From: Tiger Date: Thu, 1 Aug 2019 16:20:35 +1000 Subject: [PATCH] Final removal of KubernetesService Creating new records has been disabled, and all existing records been migrated to clusters as of https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/28534 --- app/helpers/services_helper.rb | 2 +- app/models/project.rb | 1 - .../project_services/kubernetes_service.rb | 133 -------------- app/models/service.rb | 1 - app/views/admin/services/_form.html.haml | 5 +- ...-remove-kubernetes-service-integration.yml | 5 + ...190801060809_delete_kubernetes_services.rb | 13 ++ doc/api/services.md | 38 ---- lib/api/helpers/services_helpers.rb | 27 --- locale/gitlab.pot | 6 - spec/factories/projects.rb | 4 - spec/factories/services.rb | 12 -- spec/lib/gitlab/import_export/all_models.yml | 1 - .../kubernetes_service_spec.rb | 167 ------------------ spec/requests/api/services_spec.rb | 10 +- 15 files changed, 23 insertions(+), 402 deletions(-) delete mode 100644 app/models/project_services/kubernetes_service.rb create mode 100644 changelogs/unreleased/39217-remove-kubernetes-service-integration.yml create mode 100644 db/migrate/20190801060809_delete_kubernetes_services.rb delete mode 100644 spec/models/project_services/kubernetes_service_spec.rb diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb index 01ccf163b45..d4b50b7ecfb 100644 --- a/app/helpers/services_helper.rb +++ b/app/helpers/services_helper.rb @@ -39,7 +39,7 @@ module ServicesHelper end def disable_fields_service?(service) - service.is_a?(KubernetesService) || (!current_controller?("admin/services") && service.deprecated?) + !current_controller?("admin/services") && service.deprecated? end extend self diff --git a/app/models/project.rb b/app/models/project.rb index 960795b73cb..816dd2f5d69 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -162,7 +162,6 @@ class Project < ApplicationRecord has_one :bugzilla_service has_one :gitlab_issue_tracker_service, inverse_of: :project has_one :external_wiki_service - has_one :kubernetes_service, inverse_of: :project has_one :prometheus_service, inverse_of: :project has_one :mock_ci_service has_one :mock_deployment_service diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb deleted file mode 100644 index 9f5c226f4c9..00000000000 --- a/app/models/project_services/kubernetes_service.rb +++ /dev/null @@ -1,133 +0,0 @@ -# frozen_string_literal: true - -class KubernetesService < Service - default_value_for :category, 'deployment' - - # Namespace defaults to the project path, but can be overridden in case that - # is an invalid or inappropriate name - prop_accessor :namespace - - # Access to kubernetes is directly through the API - prop_accessor :api_url - - # Bearer authentication - # TODO: user/password auth, client certificates - prop_accessor :token - - # Provide a custom CA bundle for self-signed deployments - prop_accessor :ca_pem - - with_options presence: true, if: :activated? do - validates :api_url, public_url: true - validates :token - end - - before_validation :enforce_namespace_to_lower_case - - attr_accessor :skip_deprecation_validation - - validate :deprecation_validation, unless: :skip_deprecation_validation - - validates :namespace, - allow_blank: true, - length: 1..63, - if: :activated?, - format: { - with: Gitlab::Regex.kubernetes_namespace_regex, - message: Gitlab::Regex.kubernetes_namespace_regex_message - } - - def self.supported_events - %w() - end - - def can_test? - false - end - - def initialize_properties - self.properties = {} if properties.nil? - end - - def title - 'Kubernetes' - end - - def description - 'Kubernetes / OpenShift integration' - end - - def self.to_param - 'kubernetes' - end - - def fields - [ - { type: 'text', - name: 'api_url', - title: 'API URL', - placeholder: 'Kubernetes API URL, like https://kube.example.com/' }, - { type: 'textarea', - name: 'ca_pem', - title: 'CA Certificate', - placeholder: 'Certificate Authority bundle (PEM format)' }, - { type: 'text', - name: 'namespace', - title: 'Project namespace (optional/unique)', - placeholder: namespace_placeholder }, - { type: 'text', - name: 'token', - title: 'Token', - placeholder: 'Service token' } - ] - end - - def deprecated? - true - end - - def editable? - false - end - - def deprecation_message - content = if project - _("Kubernetes service integration has been disabled. Fields on this page are not used by GitLab, you can configure your Kubernetes clusters using the new Kubernetes Clusters page") % { - url: Gitlab::Routing.url_helpers.project_clusters_path(project) - } - else - _("The instance-level Kubernetes service integration is disabled. Your data has been migrated to an instance-level cluster.") % { - url: Gitlab::Routing.url_helpers.admin_clusters_path - } - end - - content.html_safe - end - - TEMPLATE_PLACEHOLDER = 'Kubernetes namespace'.freeze - - private - - def namespace_placeholder - default_namespace || TEMPLATE_PLACEHOLDER - end - - def default_namespace - return unless project - - slug = "#{project.path}-#{project.id}".downcase - slug.gsub(/[^-a-z0-9]/, '-').gsub(/^-+/, '') - end - - def enforce_namespace_to_lower_case - self.namespace = self.namespace&.downcase - end - - def deprecation_validation - return if active_changed?(from: true, to: false) || (new_record? && !active?) - - if deprecated? - errors[:base] << deprecation_message - end - end -end diff --git a/app/models/service.rb b/app/models/service.rb index 752467622f2..f6d8fb1fb46 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -260,7 +260,6 @@ class Service < ApplicationRecord hipchat irker jira - kubernetes mattermost_slash_commands mattermost packagist diff --git a/app/views/admin/services/_form.html.haml b/app/views/admin/services/_form.html.haml index ab08d5c4906..495ee6a04ea 100644 --- a/app/views/admin/services/_form.html.haml +++ b/app/views/admin/services/_form.html.haml @@ -6,6 +6,5 @@ = 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' + .footer-block.row-content-block + = form.submit 'Save', class: 'btn btn-success' diff --git a/changelogs/unreleased/39217-remove-kubernetes-service-integration.yml b/changelogs/unreleased/39217-remove-kubernetes-service-integration.yml new file mode 100644 index 00000000000..e13e3e86a37 --- /dev/null +++ b/changelogs/unreleased/39217-remove-kubernetes-service-integration.yml @@ -0,0 +1,5 @@ +--- +title: Remove Kubernetes service integration page +merge_request: 31365 +author: +type: removed diff --git a/db/migrate/20190801060809_delete_kubernetes_services.rb b/db/migrate/20190801060809_delete_kubernetes_services.rb new file mode 100644 index 00000000000..018976584d4 --- /dev/null +++ b/db/migrate/20190801060809_delete_kubernetes_services.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class DeleteKubernetesServices < ActiveRecord::Migration[5.2] + DOWNTIME = false + + def up + Service.where(type: "KubernetesService").delete_all + end + + def down + # no-op + end +end diff --git a/doc/api/services.md b/doc/api/services.md index 45b49d7eb92..7d025cd3bdf 100644 --- a/doc/api/services.md +++ b/doc/api/services.md @@ -595,44 +595,6 @@ Remove all previously Jira settings from a project. DELETE /projects/:id/services/jira ``` -## Kubernetes - -Kubernetes / OpenShift integration - -CAUTION: **Warning:** -Kubernetes service integration has been deprecated in GitLab 10.3. API service endpoints will continue to work as long as the Kubernetes service is active, however if the service is inactive API endpoints will automatically return a `400 Bad Request`. Read [GitLab 10.3 release post](https://about.gitlab.com/2017/12/22/gitlab-10-3-released/#kubernetes-integration-service) for more information. - -### Create/Edit Kubernetes service - -Set Kubernetes service for a project. - -``` -PUT /projects/:id/services/kubernetes -``` - -Parameters: - -- `namespace` (**required**) - The Kubernetes namespace to use -- `api_url` (**required**) - The URL to the Kubernetes cluster API. For example, `https://kubernetes.example.com` -- `token` (**required**) - The service token to authenticate against the Kubernetes cluster with -- `ca_pem` (optional) - A custom certificate authority bundle to verify the Kubernetes cluster with (PEM format) - -### Delete Kubernetes service - -Delete Kubernetes service for a project. - -``` -DELETE /projects/:id/services/kubernetes -``` - -### Get Kubernetes service settings - -Get Kubernetes service settings for a project. - -``` -GET /projects/:id/services/kubernetes -``` - ## Slack slash commands Ability to receive slash commands from a Slack chat instance. diff --git a/lib/api/helpers/services_helpers.rb b/lib/api/helpers/services_helpers.rb index c4ecf55969c..422db5c7a50 100644 --- a/lib/api/helpers/services_helpers.rb +++ b/lib/api/helpers/services_helpers.rb @@ -489,32 +489,6 @@ module API desc: 'The ID of a transition that moves issues to a closed state. You can find this number under the Jira workflow administration (**Administration > Issues > Workflows**) by selecting **View** under **Operations** of the desired workflow of your project. The ID of each state can be found inside the parenthesis of each transition name under the **Transitions (id)** column ([see screenshot][trans]). By default, this ID is set to `2`' } ], - 'kubernetes' => [ - { - required: true, - name: :namespace, - type: String, - desc: 'The Kubernetes namespace to use' - }, - { - required: true, - name: :api_url, - type: String, - desc: 'The URL to the Kubernetes cluster API, e.g., https://kubernetes.example.com' - }, - { - required: true, - name: :token, - type: String, - desc: 'The service token to authenticate against the Kubernetes cluster with' - }, - { - required: false, - name: :ca_pem, - type: String, - desc: 'A custom certificate authority bundle to verify the Kubernetes cluster with (PEM format)' - } - ], 'mattermost-slash-commands' => [ { required: true, @@ -739,7 +713,6 @@ module API ::HipchatService, ::IrkerService, ::JiraService, - ::KubernetesService, ::MattermostSlashCommandsService, ::SlackSlashCommandsService, ::PackagistService, diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 7586fff2e7d..5b6f324c987 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -6153,9 +6153,6 @@ msgstr "" msgid "Kubernetes error: %{error_code}" msgstr "" -msgid "Kubernetes service integration has been disabled. Fields on this page are not used by GitLab, you can configure your Kubernetes clusters using the new Kubernetes Clusters page" -msgstr "" - msgid "LDAP" msgstr "" @@ -10903,9 +10900,6 @@ 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 disabled. Your data has been migrated to an instance-level cluster." -msgstr "" - msgid "The invitation could not be accepted." msgstr "" diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index afe27aaf1fb..ea89555b0d5 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -325,10 +325,6 @@ FactoryBot.define do jira_service end - factory :kubernetes_project, parent: :project do - kubernetes_service - end - factory :mock_deployment_project, parent: :project do mock_deployment_service end diff --git a/spec/factories/services.rb b/spec/factories/services.rb index 5ef39b3e818..f3e662ad4f5 100644 --- a/spec/factories/services.rb +++ b/spec/factories/services.rb @@ -16,18 +16,6 @@ FactoryBot.define do ) end - factory :kubernetes_service do - project - type 'KubernetesService' - active true - properties({ - api_url: 'https://kubernetes.example.com', - token: 'a' * 40 - }) - - skip_deprecation_validation true - end - factory :mock_deployment_service do project type 'MockDeploymentService' diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index ada8c649ff6..fddb5066d6f 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -277,7 +277,6 @@ project: - bugzilla_service - gitlab_issue_tracker_service - external_wiki_service -- kubernetes_service - mock_ci_service - mock_deployment_service - mock_monitoring_service diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb deleted file mode 100644 index d33bbb0470f..00000000000 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ /dev/null @@ -1,167 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe KubernetesService, :use_clean_rails_memory_store_caching do - include KubernetesHelpers - include ReactiveCachingHelpers - - let(:project) { create(:kubernetes_project) } - let(:service) { create(:kubernetes_service, project: project) } - - describe 'Associations' do - it { is_expected.to belong_to :project } - end - - describe 'Validations' 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) } - it { is_expected.to validate_presence_of(:api_url) } - it { is_expected.to validate_presence_of(:token) } - - context 'namespace format' do - before do - subject.project = project - subject.api_url = "http://example.com" - subject.token = "test" - end - - { - 'foo' => true, - '1foo' => true, - 'foo1' => true, - 'foo-bar' => true, - '-foo' => false, - 'foo-' => false, - 'a' * 63 => true, - 'a' * 64 => false, - 'a.b' => false, - 'a*b' => false, - 'FOO' => true - }.each do |namespace, validity| - it "validates #{namespace} as #{validity ? 'valid' : 'invalid'}" do - subject.namespace = namespace - - expect(subject.valid?).to eq(validity) - end - end - end - end - - context 'when service is inactive' do - before do - subject.project = project - subject.active = false - end - - it { is_expected.not_to validate_presence_of(:api_url) } - it { is_expected.not_to validate_presence_of(:token) } - end - - context 'with a deprecated service' do - let(:kubernetes_service) { create(:kubernetes_service) } - - before do - kubernetes_service.update_attribute(:active, false) - kubernetes_service.skip_deprecation_validation = false - kubernetes_service.properties['namespace'] = "foo" - end - - it 'does not update attributes' do - expect(kubernetes_service.save).to be_falsy - end - - it 'includes an error with a deprecation message' do - kubernetes_service.valid? - expect(kubernetes_service.errors[:base].first).to match(/Kubernetes service integration has been disabled/) - 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 - end - - it 'deactivates the service' do - expect(kubernetes_service.active?).to be_falsy - end - - it 'does not include a deprecation message as error' do - expect(kubernetes_service.errors.messages.count).to eq(0) - end - - it 'updates attributes' do - expect(kubernetes_service.properties['namespace']).to eq("foo") - end - end - end - - describe '#initialize_properties' do - context 'without a project' do - it 'leaves the namespace unset' do - expect(described_class.new.namespace).to be_nil - end - end - end - - describe '#fields' do - let(:kube_namespace) do - subject.fields.find { |h| h[:name] == 'namespace' } - end - - context 'as template' do - before do - subject.template = true - end - - it 'sets the namespace to the default' do - expect(kube_namespace).not_to be_nil - expect(kube_namespace[:placeholder]).to eq(subject.class::TEMPLATE_PLACEHOLDER) - end - end - - context 'with associated project' do - before do - subject.project = project - end - - it 'sets the namespace to the default' do - expect(kube_namespace).not_to be_nil - expect(kube_namespace[:placeholder]).to match(/\A#{Gitlab::PathRegex::PATH_REGEX_STR}-\d+\z/) - end - end - end - - describe "#deprecated?" do - let(:kubernetes_service) { create(:kubernetes_service) } - - it 'returns true' do - expect(kubernetes_service.deprecated?).to be_truthy - end - end - - describe "#deprecation_message" do - let(:kubernetes_service) { create(:kubernetes_service) } - - it 'indicates the service is deprecated' do - expect(kubernetes_service.deprecation_message).to match(/Kubernetes service integration has been disabled/) - end - - context 'if the service is not active' do - it 'returns a message' do - kubernetes_service.update_attribute(:active, false) - expect(kubernetes_service.deprecation_message).to match(/Fields on this page are not used by GitLab/) - end - end - end -end diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb index 91cb8760a04..76a70ab6e9e 100644 --- a/spec/requests/api/services_spec.rb +++ b/spec/requests/api/services_spec.rb @@ -10,10 +10,7 @@ describe API::Services do end Service.available_services_names.each do |service| - # 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 + describe "PUT /projects/:id/services/#{service.dasherize}" do include_context service it "updates #{service} settings" do @@ -62,10 +59,7 @@ describe API::Services do end end - # 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 + describe "DELETE /projects/:id/services/#{service.dasherize}" do include_context service before do