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:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-11-05 12:09:00 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-05 12:09:00 +0300
commit015890a1b77cd90e9ffeb704944d1fb63b0ce555 (patch)
treebcf07119c9492fb59e637e732b3427d752c0cc49
parentd10e04a10b5c7bf4e46589f05e8b63db30b3972d (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/notes/components/discussion_filter_note.vue37
-rw-r--r--app/graphql/types/release_links_type.rb7
-rw-r--r--app/models/clusters/applications/cert_manager.rb4
-rw-r--r--app/models/clusters/applications/crossplane.rb2
-rw-r--r--app/models/clusters/applications/elastic_stack.rb8
-rw-r--r--app/models/clusters/applications/fluentd.rb2
-rw-r--r--app/models/clusters/applications/helm.rb12
-rw-r--r--app/models/clusters/applications/ingress.rb2
-rw-r--r--app/models/clusters/applications/jupyter.rb2
-rw-r--r--app/models/clusters/applications/knative.rb4
-rw-r--r--app/models/clusters/applications/prometheus.rb6
-rw-r--r--app/models/clusters/applications/runner.rb2
-rw-r--r--app/models/clusters/cluster.rb3
-rw-r--r--app/models/clusters/concerns/application_core.rb11
-rw-r--r--app/models/clusters/concerns/application_data.rb2
-rw-r--r--app/models/pages_domain.rb2
-rw-r--r--changelogs/unreleased/241957-remove-v-html-from-app-assets-javascripts-notes-components-discuss.yml5
-rw-r--r--changelogs/unreleased/add-helm3-support-for-cluster-apps.yml5
-rw-r--r--config/initializers/0_inject_feature_flags.rb1
-rw-r--r--db/migrate/20201028184640_add_helm_major_version_to_clusters.rb12
-rw-r--r--db/schema_migrations/202010281846401
-rw-r--r--db/structure.sql3
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql10
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json28
-rw-r--r--doc/api/graphql/reference/index.md2
-rw-r--r--lib/api/entities/release.rb2
-rw-r--r--lib/gitlab/ci/config/entry/bridge.rb11
-rw-r--r--lib/gitlab/ci/config/entry/job.rb11
-rw-r--r--lib/gitlab/ci/config/entry/processable.rb11
-rw-r--r--lib/gitlab/import_export/importer.rb14
-rw-r--r--lib/gitlab/import_export/project/sample/relation_factory.rb42
-rw-r--r--lib/gitlab/import_export/project/sample/relation_tree_restorer.rb33
-rw-r--r--lib/gitlab/import_export/project/sample/sample_data_relation_tree_restorer.rb50
-rw-r--r--lib/gitlab/import_export/project/sample/tree_restorer.rb19
-rw-r--r--lib/gitlab/import_export/project/tree_restorer.rb6
-rw-r--r--lib/gitlab/kubernetes/helm/base_command.rb85
-rw-r--r--lib/gitlab/kubernetes/helm/certificate.rb73
-rw-r--r--lib/gitlab/kubernetes/helm/client_command.rb38
-rw-r--r--lib/gitlab/kubernetes/helm/delete_command.rb36
-rw-r--r--lib/gitlab/kubernetes/helm/init_command.rb43
-rw-r--r--lib/gitlab/kubernetes/helm/install_command.rb85
-rw-r--r--lib/gitlab/kubernetes/helm/patch_command.rb65
-rw-r--r--lib/gitlab/kubernetes/helm/pod.rb9
-rw-r--r--lib/gitlab/kubernetes/helm/reset_command.rb48
-rw-r--r--lib/gitlab/kubernetes/helm/v2/base_command.rb93
-rw-r--r--lib/gitlab/kubernetes/helm/v2/certificate.rb75
-rw-r--r--lib/gitlab/kubernetes/helm/v2/client_command.rb40
-rw-r--r--lib/gitlab/kubernetes/helm/v2/delete_command.rb38
-rw-r--r--lib/gitlab/kubernetes/helm/v2/init_command.rb45
-rw-r--r--lib/gitlab/kubernetes/helm/v2/install_command.rb87
-rw-r--r--lib/gitlab/kubernetes/helm/v2/patch_command.rb67
-rw-r--r--lib/gitlab/kubernetes/helm/v2/reset_command.rb50
-rw-r--r--lib/gitlab/kubernetes/helm/v3/base_command.rb101
-rw-r--r--lib/gitlab/kubernetes/helm/v3/delete_command.rb35
-rw-r--r--lib/gitlab/kubernetes/helm/v3/install_command.rb80
-rw-r--r--lib/gitlab/kubernetes/helm/v3/patch_command.rb60
-rw-r--r--locale/gitlab.pot6
-rw-r--r--spec/factories/clusters/applications/helm.rb4
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/release.json6
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/release/release_for_guest.json6
-rw-r--r--spec/frontend/notes/components/discussion_filter_note_spec.js21
-rw-r--r--spec/graphql/types/release_links_type_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/importer_spec.rb18
-rw-r--r--spec/lib/gitlab/import_export/project/sample/relation_factory_spec.rb168
-rw-r--r--spec/lib/gitlab/import_export/project/sample/relation_tree_restorer_spec.rb (renamed from spec/lib/gitlab/import_export/project/sample/sample_data_relation_tree_restorer_spec.rb)23
-rw-r--r--spec/lib/gitlab/import_export/project/tree_restorer_spec.rb35
-rw-r--r--spec/lib/gitlab/kubernetes/helm/api_spec.rb4
-rw-r--r--spec/lib/gitlab/kubernetes/helm/pod_spec.rb121
-rw-r--r--spec/lib/gitlab/kubernetes/helm/v2/base_command_spec.rb50
-rw-r--r--spec/lib/gitlab/kubernetes/helm/v2/certificate_spec.rb (renamed from spec/lib/gitlab/kubernetes/helm/certificate_spec.rb)2
-rw-r--r--spec/lib/gitlab/kubernetes/helm/v2/delete_command_spec.rb (renamed from spec/lib/gitlab/kubernetes/helm/delete_command_spec.rb)2
-rw-r--r--spec/lib/gitlab/kubernetes/helm/v2/init_command_spec.rb (renamed from spec/lib/gitlab/kubernetes/helm/init_command_spec.rb)2
-rw-r--r--spec/lib/gitlab/kubernetes/helm/v2/install_command_spec.rb (renamed from spec/lib/gitlab/kubernetes/helm/install_command_spec.rb)33
-rw-r--r--spec/lib/gitlab/kubernetes/helm/v2/patch_command_spec.rb (renamed from spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb)29
-rw-r--r--spec/lib/gitlab/kubernetes/helm/v2/reset_command_spec.rb (renamed from spec/lib/gitlab/kubernetes/helm/reset_command_spec.rb)2
-rw-r--r--spec/lib/gitlab/kubernetes/helm/v3/base_command_spec.rb (renamed from spec/lib/gitlab/kubernetes/helm/base_command_spec.rb)10
-rw-r--r--spec/lib/gitlab/kubernetes/helm/v3/delete_command_spec.rb35
-rw-r--r--spec/lib/gitlab/kubernetes/helm/v3/install_command_spec.rb168
-rw-r--r--spec/lib/gitlab/kubernetes/helm/v3/patch_command_spec.rb81
-rw-r--r--spec/models/clusters/applications/cert_manager_spec.rb4
-rw-r--r--spec/models/clusters/applications/crossplane_spec.rb2
-rw-r--r--spec/models/clusters/applications/elastic_stack_spec.rb8
-rw-r--r--spec/models/clusters/applications/fluentd_spec.rb2
-rw-r--r--spec/models/clusters/applications/helm_spec.rb6
-rw-r--r--spec/models/clusters/applications/ingress_spec.rb2
-rw-r--r--spec/models/clusters/applications/jupyter_spec.rb2
-rw-r--r--spec/models/clusters/applications/knative_spec.rb4
-rw-r--r--spec/models/clusters/applications/prometheus_spec.rb6
-rw-r--r--spec/models/clusters/applications/runner_spec.rb2
-rw-r--r--spec/models/clusters/cluster_spec.rb21
-rw-r--r--spec/requests/api/graphql/project/release_spec.rb6
-rw-r--r--spec/requests/api/graphql/project/releases_spec.rb6
-rw-r--r--spec/requests/api/releases_spec.rb16
-rw-r--r--spec/services/clusters/applications/uninstall_service_spec.rb6
-rw-r--r--spec/support/shared_examples/helm_commands_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/models/cluster_application_core_shared_examples.rb17
-rw-r--r--spec/support/shared_examples/models/cluster_application_helm_cert_shared_examples.rb2
97 files changed, 1688 insertions, 889 deletions
diff --git a/app/assets/javascripts/notes/components/discussion_filter_note.vue b/app/assets/javascripts/notes/components/discussion_filter_note.vue
index ff70c89cd39..83326279423 100644
--- a/app/assets/javascripts/notes/components/discussion_filter_note.vue
+++ b/app/assets/javascripts/notes/components/discussion_filter_note.vue
@@ -1,28 +1,19 @@
<script>
-/* eslint-disable vue/no-v-html */
-import { GlButton, GlIcon } from '@gitlab/ui';
-import { __, sprintf } from '~/locale';
+import { GlButton, GlIcon, GlSprintf } from '@gitlab/ui';
+import { s__ } from '~/locale';
import notesEventHub from '../event_hub';
export default {
+ i18n: {
+ information: s__(
+ "Notes|You're only seeing %{boldStart}other activity%{boldEnd} in the feed. To add a comment, switch to one of the following options.",
+ ),
+ },
components: {
GlButton,
GlIcon,
- },
- computed: {
- timelineContent() {
- return sprintf(
- __(
- "You're only seeing %{startTag}other activity%{endTag} in the feed. To add a comment, switch to one of the following options.",
- ),
- {
- startTag: `<b>`,
- endTag: `</b>`,
- },
- false,
- );
- },
+ GlSprintf,
},
methods: {
selectFilter(value) {
@@ -41,12 +32,18 @@ export default {
<gl-icon name="comment" />
</div>
<div class="timeline-content">
- <div ref="timelineContent" v-html="timelineContent"></div>
+ <div data-testid="discussion-filter-timeline-content">
+ <gl-sprintf :message="$options.i18n.information">
+ <template #bold="{ content }">
+ <b>{{ content }}</b>
+ </template>
+ </gl-sprintf>
+ </div>
<div class="discussion-filter-actions mt-2">
- <gl-button ref="showAllActivity" variant="default" @click="selectFilter(0)">
+ <gl-button variant="default" @click="selectFilter(0)">
{{ __('Show all activity') }}
</gl-button>
- <gl-button ref="showComments" variant="default" @click="selectFilter(1)">
+ <gl-button variant="default" @click="selectFilter(1)">
{{ __('Show comments only') }}
</gl-button>
</div>
diff --git a/app/graphql/types/release_links_type.rb b/app/graphql/types/release_links_type.rb
index da2ef4665f2..619bb1e6c3a 100644
--- a/app/graphql/types/release_links_type.rb
+++ b/app/graphql/types/release_links_type.rb
@@ -25,12 +25,5 @@ module Types
description: 'HTTP URL of the issues page, filtered by this release and `state=open`'
field :closed_issues_url, GraphQL::STRING_TYPE, null: true,
description: 'HTTP URL of the issues page, filtered by this release and `state=closed`'
-
- field :merge_requests_url, GraphQL::STRING_TYPE, null: true, method: :opened_merge_requests_url,
- description: 'HTTP URL of the merge request page filtered by this release',
- deprecated: { reason: 'Use `openedMergeRequestsUrl`', milestone: '13.6' }
- field :issues_url, GraphQL::STRING_TYPE, null: true, method: :opened_issues_url,
- description: 'HTTP URL of the issues page filtered by this release',
- deprecated: { reason: 'Use `openedIssuesUrl`', milestone: '13.6' }
end
end
diff --git a/app/models/clusters/applications/cert_manager.rb b/app/models/clusters/applications/cert_manager.rb
index 1efa44c39c5..d32fff14590 100644
--- a/app/models/clusters/applications/cert_manager.rb
+++ b/app/models/clusters/applications/cert_manager.rb
@@ -30,7 +30,7 @@ module Clusters
end
def install_command
- Gitlab::Kubernetes::Helm::InstallCommand.new(
+ helm_command_module::InstallCommand.new(
name: 'certmanager',
repository: repository,
version: VERSION,
@@ -43,7 +43,7 @@ module Clusters
end
def uninstall_command
- Gitlab::Kubernetes::Helm::DeleteCommand.new(
+ helm_command_module::DeleteCommand.new(
name: 'certmanager',
rbac: cluster.platform_kubernetes_rbac?,
files: files,
diff --git a/app/models/clusters/applications/crossplane.rb b/app/models/clusters/applications/crossplane.rb
index 420e56c1742..2b1a86706a4 100644
--- a/app/models/clusters/applications/crossplane.rb
+++ b/app/models/clusters/applications/crossplane.rb
@@ -29,7 +29,7 @@ module Clusters
end
def install_command
- Gitlab::Kubernetes::Helm::InstallCommand.new(
+ helm_command_module::InstallCommand.new(
name: 'crossplane',
repository: repository,
version: VERSION,
diff --git a/app/models/clusters/applications/elastic_stack.rb b/app/models/clusters/applications/elastic_stack.rb
index 77996748b81..db18a29ec84 100644
--- a/app/models/clusters/applications/elastic_stack.rb
+++ b/app/models/clusters/applications/elastic_stack.rb
@@ -26,7 +26,7 @@ module Clusters
end
def install_command
- Gitlab::Kubernetes::Helm::InstallCommand.new(
+ helm_command_module::InstallCommand.new(
name: 'elastic-stack',
version: VERSION,
rbac: cluster.platform_kubernetes_rbac?,
@@ -39,7 +39,7 @@ module Clusters
end
def uninstall_command
- Gitlab::Kubernetes::Helm::DeleteCommand.new(
+ helm_command_module::DeleteCommand.new(
name: 'elastic-stack',
rbac: cluster.platform_kubernetes_rbac?,
files: files,
@@ -96,7 +96,7 @@ module Clusters
def post_install_script
[
- "timeout -t60 sh /data/helm/elastic-stack/config/wait-for-elasticsearch.sh http://elastic-stack-elasticsearch-master:9200"
+ "timeout 60 sh /data/helm/elastic-stack/config/wait-for-elasticsearch.sh http://elastic-stack-elasticsearch-master:9200"
]
end
@@ -116,7 +116,7 @@ module Clusters
# Chart version 3.0.0 moves to our own chart at https://gitlab.com/gitlab-org/charts/elastic-stack
# and is not compatible with pre-existing resources. We first remove them.
[
- Gitlab::Kubernetes::Helm::DeleteCommand.new(
+ helm_command_module::DeleteCommand.new(
name: 'elastic-stack',
rbac: cluster.platform_kubernetes_rbac?,
files: files
diff --git a/app/models/clusters/applications/fluentd.rb b/app/models/clusters/applications/fluentd.rb
index c608d37be77..91aa422b859 100644
--- a/app/models/clusters/applications/fluentd.rb
+++ b/app/models/clusters/applications/fluentd.rb
@@ -30,7 +30,7 @@ module Clusters
end
def install_command
- Gitlab::Kubernetes::Helm::InstallCommand.new(
+ helm_command_module::InstallCommand.new(
name: 'fluentd',
repository: repository,
version: VERSION,
diff --git a/app/models/clusters/applications/helm.rb b/app/models/clusters/applications/helm.rb
index 4a1bcac4bb7..d1d6defb713 100644
--- a/app/models/clusters/applications/helm.rb
+++ b/app/models/clusters/applications/helm.rb
@@ -4,6 +4,8 @@ require 'openssl'
module Clusters
module Applications
+ # DEPRECATED: This model represents the Helm 2 Tiller server, and is no longer being actively used.
+ # It is being kept around for a potential cleanup of the unused Tiller server.
class Helm < ApplicationRecord
self.table_name = 'clusters_applications_helm'
@@ -49,7 +51,7 @@ module Clusters
end
def install_command
- Gitlab::Kubernetes::Helm::InitCommand.new(
+ Gitlab::Kubernetes::Helm::V2::InitCommand.new(
name: name,
files: files,
rbac: cluster.platform_kubernetes_rbac?
@@ -57,7 +59,7 @@ module Clusters
end
def uninstall_command
- Gitlab::Kubernetes::Helm::ResetCommand.new(
+ Gitlab::Kubernetes::Helm::V2::ResetCommand.new(
name: name,
files: files,
rbac: cluster.platform_kubernetes_rbac?
@@ -86,19 +88,19 @@ module Clusters
end
def create_keys_and_certs
- ca_cert = Gitlab::Kubernetes::Helm::Certificate.generate_root
+ ca_cert = Gitlab::Kubernetes::Helm::V2::Certificate.generate_root
self.ca_key = ca_cert.key_string
self.ca_cert = ca_cert.cert_string
end
def tiller_cert
- @tiller_cert ||= ca_cert_obj.issue(expires_in: Gitlab::Kubernetes::Helm::Certificate::INFINITE_EXPIRY)
+ @tiller_cert ||= ca_cert_obj.issue(expires_in: Gitlab::Kubernetes::Helm::V2::Certificate::INFINITE_EXPIRY)
end
def ca_cert_obj
return unless has_ssl?
- Gitlab::Kubernetes::Helm::Certificate
+ Gitlab::Kubernetes::Helm::V2::Certificate
.from_strings(ca_key, ca_cert)
end
end
diff --git a/app/models/clusters/applications/ingress.rb b/app/models/clusters/applications/ingress.rb
index d5412714858..36324e7f3e0 100644
--- a/app/models/clusters/applications/ingress.rb
+++ b/app/models/clusters/applications/ingress.rb
@@ -62,7 +62,7 @@ module Clusters
end
def install_command
- Gitlab::Kubernetes::Helm::InstallCommand.new(
+ helm_command_module::InstallCommand.new(
name: name,
repository: repository,
version: VERSION,
diff --git a/app/models/clusters/applications/jupyter.rb b/app/models/clusters/applications/jupyter.rb
index 056ea355de6..ff907c6847f 100644
--- a/app/models/clusters/applications/jupyter.rb
+++ b/app/models/clusters/applications/jupyter.rb
@@ -39,7 +39,7 @@ module Clusters
end
def install_command
- Gitlab::Kubernetes::Helm::InstallCommand.new(
+ helm_command_module::InstallCommand.new(
name: name,
version: VERSION,
rbac: cluster.platform_kubernetes_rbac?,
diff --git a/app/models/clusters/applications/knative.rb b/app/models/clusters/applications/knative.rb
index 3047da12dd9..b1c3116d77c 100644
--- a/app/models/clusters/applications/knative.rb
+++ b/app/models/clusters/applications/knative.rb
@@ -70,7 +70,7 @@ module Clusters
end
def install_command
- Gitlab::Kubernetes::Helm::InstallCommand.new(
+ helm_command_module::InstallCommand.new(
name: name,
version: VERSION,
rbac: cluster.platform_kubernetes_rbac?,
@@ -94,7 +94,7 @@ module Clusters
end
def uninstall_command
- Gitlab::Kubernetes::Helm::DeleteCommand.new(
+ helm_command_module::DeleteCommand.new(
name: name,
rbac: cluster.platform_kubernetes_rbac?,
files: files,
diff --git a/app/models/clusters/applications/prometheus.rb b/app/models/clusters/applications/prometheus.rb
index 7679296699f..55a9a0ccb81 100644
--- a/app/models/clusters/applications/prometheus.rb
+++ b/app/models/clusters/applications/prometheus.rb
@@ -67,7 +67,7 @@ module Clusters
end
def install_command
- Gitlab::Kubernetes::Helm::InstallCommand.new(
+ helm_command_module::InstallCommand.new(
name: name,
repository: repository,
version: VERSION,
@@ -79,7 +79,7 @@ module Clusters
end
def patch_command(values)
- ::Gitlab::Kubernetes::Helm::PatchCommand.new(
+ helm_command_module::PatchCommand.new(
name: name,
repository: repository,
version: version,
@@ -90,7 +90,7 @@ module Clusters
end
def uninstall_command
- Gitlab::Kubernetes::Helm::DeleteCommand.new(
+ helm_command_module::DeleteCommand.new(
name: name,
rbac: cluster.platform_kubernetes_rbac?,
files: files,
diff --git a/app/models/clusters/applications/runner.rb b/app/models/clusters/applications/runner.rb
index 6ddf552cd65..03f4caccccd 100644
--- a/app/models/clusters/applications/runner.rb
+++ b/app/models/clusters/applications/runner.rb
@@ -30,7 +30,7 @@ module Clusters
end
def install_command
- Gitlab::Kubernetes::Helm::InstallCommand.new(
+ helm_command_module::InstallCommand.new(
name: name,
version: VERSION,
rbac: cluster.platform_kubernetes_rbac?,
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index b94ec3c6dea..3cf5542ae76 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -79,6 +79,9 @@ module Clusters
validates :cluster_type, presence: true
validates :domain, allow_blank: true, hostname: { allow_numeric_hostname: true }
validates :namespace_per_environment, inclusion: { in: [true, false] }
+ validates :helm_major_version, inclusion: { in: [2, 3] }
+
+ default_value_for :helm_major_version, 3
validate :restrict_modification, on: :update
validate :no_groups, unless: :group_type?
diff --git a/app/models/clusters/concerns/application_core.rb b/app/models/clusters/concerns/application_core.rb
index 760576ea1eb..b82b1887308 100644
--- a/app/models/clusters/concerns/application_core.rb
+++ b/app/models/clusters/concerns/application_core.rb
@@ -12,6 +12,17 @@ module Clusters
after_initialize :set_initial_status
+ def helm_command_module
+ case cluster.helm_major_version
+ when 3
+ Gitlab::Kubernetes::Helm::V3
+ when 2
+ Gitlab::Kubernetes::Helm::V2
+ else
+ raise "Invalid Helm major version"
+ end
+ end
+
def set_initial_status
return unless not_installable?
diff --git a/app/models/clusters/concerns/application_data.rb b/app/models/clusters/concerns/application_data.rb
index 22e597e9747..00aeb7669ad 100644
--- a/app/models/clusters/concerns/application_data.rb
+++ b/app/models/clusters/concerns/application_data.rb
@@ -4,7 +4,7 @@ module Clusters
module Concerns
module ApplicationData
def uninstall_command
- Gitlab::Kubernetes::Helm::DeleteCommand.new(
+ helm_command_module::DeleteCommand.new(
name: name,
rbac: cluster.platform_kubernetes_rbac?,
files: files
diff --git a/app/models/pages_domain.rb b/app/models/pages_domain.rb
index 98db47deaa3..8192310ddfb 100644
--- a/app/models/pages_domain.rb
+++ b/app/models/pages_domain.rb
@@ -286,7 +286,7 @@ class PagesDomain < ApplicationRecord
return unless domain
if domain.downcase.ends_with?(Settings.pages.host.downcase)
- self.errors.add(:domain, "*.#{Settings.pages.host} is restricted")
+ self.errors.add(:domain, "*.#{Settings.pages.host} is restricted. Please compare our documentation at https://docs.gitlab.com/ee/administration/pages/#advanced-configuration against your configuration.")
end
end
diff --git a/changelogs/unreleased/241957-remove-v-html-from-app-assets-javascripts-notes-components-discuss.yml b/changelogs/unreleased/241957-remove-v-html-from-app-assets-javascripts-notes-components-discuss.yml
new file mode 100644
index 00000000000..ee781be5134
--- /dev/null
+++ b/changelogs/unreleased/241957-remove-v-html-from-app-assets-javascripts-notes-components-discuss.yml
@@ -0,0 +1,5 @@
+---
+title: Replace v-html with GlSprintf in notes/.../discussion_filter_note.vue
+merge_request: 41482
+author: Takuya Noguchi
+type: other
diff --git a/changelogs/unreleased/add-helm3-support-for-cluster-apps.yml b/changelogs/unreleased/add-helm3-support-for-cluster-apps.yml
new file mode 100644
index 00000000000..334f5e0ee36
--- /dev/null
+++ b/changelogs/unreleased/add-helm3-support-for-cluster-apps.yml
@@ -0,0 +1,5 @@
+---
+title: Use Helm 3 by default for GitLab-managed apps in new clusters
+merge_request: 46267
+author:
+type: changed
diff --git a/config/initializers/0_inject_feature_flags.rb b/config/initializers/0_inject_feature_flags.rb
index 4de762742d1..78fd67b97df 100644
--- a/config/initializers/0_inject_feature_flags.rb
+++ b/config/initializers/0_inject_feature_flags.rb
@@ -14,7 +14,6 @@ if Gitlab.ee? && Gitlab.dev_or_test_env?
# being unique to licensed names. These feature flags should be reworked to
# be "development" with explicit check
IGNORED_FEATURE_FLAGS = %i[
- feature_flags_related_issues
group_wikis
swimlanes
minimal_access_role
diff --git a/db/migrate/20201028184640_add_helm_major_version_to_clusters.rb b/db/migrate/20201028184640_add_helm_major_version_to_clusters.rb
new file mode 100644
index 00000000000..2169fd41826
--- /dev/null
+++ b/db/migrate/20201028184640_add_helm_major_version_to_clusters.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class AddHelmMajorVersionToClusters < ActiveRecord::Migration[6.0]
+ DOWNTIME = false
+
+ def change
+ add_column(:clusters, :helm_major_version, :integer, default: 2, null: false)
+ end
+end
diff --git a/db/schema_migrations/20201028184640 b/db/schema_migrations/20201028184640
new file mode 100644
index 00000000000..4cac95e4e7b
--- /dev/null
+++ b/db/schema_migrations/20201028184640
@@ -0,0 +1 @@
+5520cca016af07fb2e009c0e3254362f106a9cc808cbb61e280221be82be1b25 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 8c278442790..ee43e18c517 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -10967,7 +10967,8 @@ CREATE TABLE clusters (
namespace_per_environment boolean DEFAULT true NOT NULL,
management_project_id integer,
cleanup_status smallint DEFAULT 1 NOT NULL,
- cleanup_status_reason text
+ cleanup_status_reason text,
+ helm_major_version integer DEFAULT 2 NOT NULL
);
CREATE TABLE clusters_applications_cert_managers (
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index e39c8919706..39bcae58bdc 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -17420,16 +17420,6 @@ type ReleaseLinks {
editUrl: String
"""
- HTTP URL of the issues page filtered by this release. Deprecated in 13.6: Use `openedIssuesUrl`
- """
- issuesUrl: String @deprecated(reason: "Use `openedIssuesUrl`. Deprecated in 13.6")
-
- """
- HTTP URL of the merge request page filtered by this release. Deprecated in 13.6: Use `openedMergeRequestsUrl`
- """
- mergeRequestsUrl: String @deprecated(reason: "Use `openedMergeRequestsUrl`. Deprecated in 13.6")
-
- """
HTTP URL of the merge request page , filtered by this release and `state=merged`
"""
mergedMergeRequestsUrl: String
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 1e5ac96f3ea..1311991b485 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -50231,34 +50231,6 @@
"deprecationReason": null
},
{
- "name": "issuesUrl",
- "description": "HTTP URL of the issues page filtered by this release. Deprecated in 13.6: Use `openedIssuesUrl`",
- "args": [
-
- ],
- "type": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- },
- "isDeprecated": true,
- "deprecationReason": "Use `openedIssuesUrl`. Deprecated in 13.6"
- },
- {
- "name": "mergeRequestsUrl",
- "description": "HTTP URL of the merge request page filtered by this release. Deprecated in 13.6: Use `openedMergeRequestsUrl`",
- "args": [
-
- ],
- "type": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- },
- "isDeprecated": true,
- "deprecationReason": "Use `openedMergeRequestsUrl`. Deprecated in 13.6"
- },
- {
"name": "mergedMergeRequestsUrl",
"description": "HTTP URL of the merge request page , filtered by this release and `state=merged`",
"args": [
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 3d3aa2f4bcb..be355d77e31 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -2435,8 +2435,6 @@ Evidence for a release.
| `closedIssuesUrl` | String | HTTP URL of the issues page, filtered by this release and `state=closed` |
| `closedMergeRequestsUrl` | String | HTTP URL of the merge request page , filtered by this release and `state=closed` |
| `editUrl` | String | HTTP URL of the release's edit page |
-| `issuesUrl` **{warning-solid}** | String | **Deprecated:** Use `openedIssuesUrl`. Deprecated in 13.6 |
-| `mergeRequestsUrl` **{warning-solid}** | String | **Deprecated:** Use `openedMergeRequestsUrl`. Deprecated in 13.6 |
| `mergedMergeRequestsUrl` | String | HTTP URL of the merge request page , filtered by this release and `state=merged` |
| `openedIssuesUrl` | String | HTTP URL of the issues page, filtered by this release and `state=open` |
| `openedMergeRequestsUrl` | String | HTTP URL of the merge request page, filtered by this release and `state=open` |
diff --git a/lib/api/entities/release.rb b/lib/api/entities/release.rb
index ac43617914a..44a46c5861e 100644
--- a/lib/api/entities/release.rb
+++ b/lib/api/entities/release.rb
@@ -30,8 +30,6 @@ module API
expose :evidences, using: Entities::Releases::Evidence, expose_nil: false, if: ->(_, _) { can_download_code? }
expose :_links do
expose :self_url, as: :self, expose_nil: false
- expose :opened_merge_requests_url, as: :merge_requests_url, expose_nil: false
- expose :opened_issues_url, as: :issues_url, expose_nil: false
expose :edit_url, expose_nil: false
end
diff --git a/lib/gitlab/ci/config/entry/bridge.rb b/lib/gitlab/ci/config/entry/bridge.rb
index 1740032e5c7..70fcc1d586a 100644
--- a/lib/gitlab/ci/config/entry/bridge.rb
+++ b/lib/gitlab/ci/config/entry/bridge.rb
@@ -18,7 +18,6 @@ module Gitlab
validates :config, allowed_keys: ALLOWED_KEYS + PROCESSABLE_ALLOWED_KEYS
with_options allow_nil: true do
- validates :allow_failure, boolean: true
validates :when, inclusion: {
in: ALLOWED_WHEN,
message: "should be one of: #{ALLOWED_WHEN.join(', ')}"
@@ -48,7 +47,7 @@ module Gitlab
inherit: false,
metadata: { allowed_needs: %i[job bridge] }
- attributes :when, :allow_failure
+ attributes :when
def self.matching?(name, config)
!name.to_s.start_with?('.') &&
@@ -60,14 +59,6 @@ module Gitlab
true
end
- def manual_action?
- self.when == 'manual'
- end
-
- def ignored?
- allow_failure.nil? ? manual_action? : allow_failure
- end
-
def value
super.merge(
trigger: (trigger_value if trigger_defined?),
diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index ecc2c5cb729..1ce7060df22 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -24,7 +24,6 @@ module Gitlab
validates :script, presence: true
with_options allow_nil: true do
- validates :allow_failure, boolean: true
validates :when, inclusion: {
in: ALLOWED_WHEN,
message: "should be one of: #{ALLOWED_WHEN.join(', ')}"
@@ -118,7 +117,7 @@ module Gitlab
description: 'Parallel configuration for this job.',
inherit: false
- attributes :script, :tags, :allow_failure, :when, :dependencies,
+ attributes :script, :tags, :when, :dependencies,
:needs, :retry, :parallel, :start_in,
:interruptible, :timeout, :resource_group, :release
@@ -141,18 +140,10 @@ module Gitlab
end
end
- def manual_action?
- self.when == 'manual'
- end
-
def delayed?
self.when == 'delayed'
end
- def ignored?
- allow_failure.nil? ? manual_action? : allow_failure
- end
-
def value
super.merge(
before_script: before_script_value,
diff --git a/lib/gitlab/ci/config/entry/processable.rb b/lib/gitlab/ci/config/entry/processable.rb
index f10c509d0cc..c0315e5f901 100644
--- a/lib/gitlab/ci/config/entry/processable.rb
+++ b/lib/gitlab/ci/config/entry/processable.rb
@@ -32,6 +32,7 @@ module Gitlab
with_options allow_nil: true do
validates :extends, array_of_strings_or_string: true
validates :rules, array_of_hashes: true
+ validates :allow_failure, boolean: true
end
end
@@ -64,7 +65,7 @@ module Gitlab
inherit: false,
default: {}
- attributes :extends, :rules
+ attributes :extends, :rules, :allow_failure
end
def compose!(deps = nil)
@@ -136,6 +137,14 @@ module Gitlab
root_variables.merge(variables_value.to_h)
end
+
+ def manual_action?
+ self.when == 'manual'
+ end
+
+ def ignored?
+ allow_failure.nil? ? manual_action? : allow_failure
+ end
end
end
end
diff --git a/lib/gitlab/import_export/importer.rb b/lib/gitlab/import_export/importer.rb
index 7b8689069d8..8e78f6e274a 100644
--- a/lib/gitlab/import_export/importer.rb
+++ b/lib/gitlab/import_export/importer.rb
@@ -55,9 +55,17 @@ module Gitlab
end
def project_tree
- @project_tree ||= Gitlab::ImportExport::Project::TreeRestorer.new(user: current_user,
- shared: shared,
- project: project)
+ @project_tree ||= project_tree_class.new(user: current_user,
+ shared: shared,
+ project: project)
+ end
+
+ def project_tree_class
+ sample_data_template? ? Gitlab::ImportExport::Project::Sample::TreeRestorer : Gitlab::ImportExport::Project::TreeRestorer
+ end
+
+ def sample_data_template?
+ project&.import_data&.data&.dig('sample_data')
end
def avatar_restorer
diff --git a/lib/gitlab/import_export/project/sample/relation_factory.rb b/lib/gitlab/import_export/project/sample/relation_factory.rb
new file mode 100644
index 00000000000..6e59174f9a3
--- /dev/null
+++ b/lib/gitlab/import_export/project/sample/relation_factory.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module ImportExport
+ module Project
+ module Sample
+ class RelationFactory < Project::RelationFactory
+ DATE_MODELS = %i[issues milestones].freeze
+
+ def initialize(date_calculator:, **args)
+ super(**args)
+
+ @date_calculator = date_calculator
+ end
+
+ private
+
+ def setup_models
+ super
+
+ # Override due date attributes in data hash for Sample Data templates
+ # Dates are moved by taking the closest one to average and moving that (and rest around it) to the date of import
+ override_date_attributes
+ end
+
+ def override_date_attributes
+ return unless DATE_MODELS.include?(@relation_name)
+
+ @relation_hash['start_date'] = calculate_by_closest_date(@relation_hash['start_date']&.to_time)
+ @relation_hash['due_date'] = calculate_by_closest_date(@relation_hash['due_date']&.to_time)
+ end
+
+ def calculate_by_closest_date(date)
+ return unless date
+
+ @date_calculator.calculate_by_closest_date_to_average(date)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/import_export/project/sample/relation_tree_restorer.rb b/lib/gitlab/import_export/project/sample/relation_tree_restorer.rb
new file mode 100644
index 00000000000..44ccb67a531
--- /dev/null
+++ b/lib/gitlab/import_export/project/sample/relation_tree_restorer.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module ImportExport
+ module Project
+ module Sample
+ class RelationTreeRestorer < ImportExport::RelationTreeRestorer
+ def initialize(*args)
+ super
+
+ @date_calculator = Gitlab::ImportExport::Project::Sample::DateCalculator.new(dates)
+ end
+
+ private
+
+ def relation_factory_params(*args)
+ super.merge(date_calculator: @date_calculator)
+ end
+
+ def dates
+ return [] if relation_reader.legacy?
+
+ RelationFactory::DATE_MODELS.flat_map do |tag|
+ relation_reader.consume_relation(@importable_path, tag, mark_as_consumed: false).map do |model|
+ model.first['due_date']
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/import_export/project/sample/sample_data_relation_tree_restorer.rb b/lib/gitlab/import_export/project/sample/sample_data_relation_tree_restorer.rb
deleted file mode 100644
index 6285898fc63..00000000000
--- a/lib/gitlab/import_export/project/sample/sample_data_relation_tree_restorer.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module ImportExport
- module Project
- module Sample
- class SampleDataRelationTreeRestorer < RelationTreeRestorer
- DATE_MODELS = %i[issues milestones].freeze
-
- def initialize(*args)
- super
-
- date_calculator
- end
-
- private
-
- def build_relation(relation_key, relation_definition, data_hash)
- # Override due date attributes in data hash for Sample Data templates
- # Dates are moved by taking the closest one to average and moving that (and rest around it) to the date of import
- # TODO: To move this logic to RelationFactory (see: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41699#note_430465333)
- override_date_attributes!(relation_key, data_hash)
- super
- end
-
- def override_date_attributes!(relation_key, data_hash)
- return unless DATE_MODELS.include?(relation_key.to_sym)
-
- data_hash['start_date'] = date_calculator.calculate_by_closest_date_to_average(data_hash['start_date'].to_time) unless data_hash['start_date'].nil?
- data_hash['due_date'] = date_calculator.calculate_by_closest_date_to_average(data_hash['due_date'].to_time) unless data_hash['due_date'].nil?
- end
-
- def dates
- return if relation_reader.legacy?
-
- DATE_MODELS.flat_map do |tag|
- relation_reader.consume_relation(@importable_path, tag, mark_as_consumed: false).map do |model|
- model.first['due_date']
- end
- end
- end
-
- def date_calculator
- @date_calculator ||= Gitlab::ImportExport::Project::Sample::DateCalculator.new(dates)
- end
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/import_export/project/sample/tree_restorer.rb b/lib/gitlab/import_export/project/sample/tree_restorer.rb
new file mode 100644
index 00000000000..1d4b5328cb9
--- /dev/null
+++ b/lib/gitlab/import_export/project/sample/tree_restorer.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module ImportExport
+ module Project
+ module Sample
+ class TreeRestorer < Project::TreeRestorer
+ def relation_tree_restorer_class
+ RelationTreeRestorer
+ end
+
+ def relation_factory
+ RelationFactory
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/import_export/project/tree_restorer.rb b/lib/gitlab/import_export/project/tree_restorer.rb
index b1d647281ab..fb9e5be1877 100644
--- a/lib/gitlab/import_export/project/tree_restorer.rb
+++ b/lib/gitlab/import_export/project/tree_restorer.rb
@@ -85,11 +85,7 @@ module Gitlab
end
def relation_tree_restorer_class
- sample_data_template? ? Sample::SampleDataRelationTreeRestorer : RelationTreeRestorer
- end
-
- def sample_data_template?
- @project&.import_data&.data&.dig('sample_data')
+ RelationTreeRestorer
end
def members_mapper
diff --git a/lib/gitlab/kubernetes/helm/base_command.rb b/lib/gitlab/kubernetes/helm/base_command.rb
deleted file mode 100644
index 49d2969f7f3..00000000000
--- a/lib/gitlab/kubernetes/helm/base_command.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Kubernetes
- module Helm
- class BaseCommand
- attr_reader :name, :files
-
- def initialize(rbac:, name:, files:)
- @rbac = rbac
- @name = name
- @files = files
- end
-
- def rbac?
- @rbac
- end
-
- def pod_resource
- pod_service_account_name = rbac? ? service_account_name : nil
-
- Gitlab::Kubernetes::Helm::Pod.new(self, namespace, service_account_name: pod_service_account_name).generate
- end
-
- def generate_script
- <<~HEREDOC
- set -xeo pipefail
- HEREDOC
- end
-
- def pod_name
- "install-#{name}"
- end
-
- def config_map_resource
- Gitlab::Kubernetes::ConfigMap.new(name, files).generate
- end
-
- def service_account_resource
- return unless rbac?
-
- Gitlab::Kubernetes::ServiceAccount.new(service_account_name, namespace).generate
- end
-
- def cluster_role_binding_resource
- return unless rbac?
-
- subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: namespace }]
-
- Gitlab::Kubernetes::ClusterRoleBinding.new(
- cluster_role_binding_name,
- cluster_role_name,
- subjects
- ).generate
- end
-
- def file_names
- files.keys
- end
-
- private
-
- def files_dir
- "/data/helm/#{name}/config"
- end
-
- def namespace
- Gitlab::Kubernetes::Helm::NAMESPACE
- end
-
- def service_account_name
- Gitlab::Kubernetes::Helm::SERVICE_ACCOUNT
- end
-
- def cluster_role_binding_name
- Gitlab::Kubernetes::Helm::CLUSTER_ROLE_BINDING
- end
-
- def cluster_role_name
- Gitlab::Kubernetes::Helm::CLUSTER_ROLE
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/kubernetes/helm/certificate.rb b/lib/gitlab/kubernetes/helm/certificate.rb
deleted file mode 100644
index 598714e0874..00000000000
--- a/lib/gitlab/kubernetes/helm/certificate.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-# frozen_string_literal: true
-module Gitlab
- module Kubernetes
- module Helm
- class Certificate
- INFINITE_EXPIRY = 1000.years
- SHORT_EXPIRY = 30.minutes
-
- attr_reader :key, :cert
-
- def key_string
- @key.to_s
- end
-
- def cert_string
- @cert.to_pem
- end
-
- def self.from_strings(key_string, cert_string)
- key = OpenSSL::PKey::RSA.new(key_string)
- cert = OpenSSL::X509::Certificate.new(cert_string)
- new(key, cert)
- end
-
- def self.generate_root
- _issue(signed_by: nil, expires_in: INFINITE_EXPIRY, certificate_authority: true)
- end
-
- def issue(expires_in: SHORT_EXPIRY)
- self.class._issue(signed_by: self, expires_in: expires_in, certificate_authority: false)
- end
-
- private
-
- def self._issue(signed_by:, expires_in:, certificate_authority:)
- key = OpenSSL::PKey::RSA.new(4096)
- public_key = key.public_key
-
- subject = OpenSSL::X509::Name.parse("/C=US")
-
- cert = OpenSSL::X509::Certificate.new
- cert.subject = subject
-
- cert.issuer = signed_by&.cert&.subject || subject
-
- cert.not_before = Time.now
- cert.not_after = expires_in.from_now
- cert.public_key = public_key
- cert.serial = 0x0
- cert.version = 2
-
- if certificate_authority
- extension_factory = OpenSSL::X509::ExtensionFactory.new
- extension_factory.subject_certificate = cert
- extension_factory.issuer_certificate = cert
- cert.add_extension(extension_factory.create_extension('subjectKeyIdentifier', 'hash'))
- cert.add_extension(extension_factory.create_extension('basicConstraints', 'CA:TRUE', true))
- cert.add_extension(extension_factory.create_extension('keyUsage', 'cRLSign,keyCertSign', true))
- end
-
- cert.sign(signed_by&.key || key, OpenSSL::Digest::SHA256.new)
-
- new(key, cert)
- end
-
- def initialize(key, cert)
- @key = key
- @cert = cert
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/kubernetes/helm/client_command.rb b/lib/gitlab/kubernetes/helm/client_command.rb
deleted file mode 100644
index a9e93c0c90e..00000000000
--- a/lib/gitlab/kubernetes/helm/client_command.rb
+++ /dev/null
@@ -1,38 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Kubernetes
- module Helm
- module ClientCommand
- def init_command
- <<~SHELL.chomp
- export HELM_HOST="localhost:44134"
- tiller -listen ${HELM_HOST} -alsologtostderr &
- helm init --client-only
- SHELL
- end
-
- def repository_command
- ['helm', 'repo', 'add', name, repository].shelljoin if repository
- end
-
- private
-
- def repository_update_command
- 'helm repo update'
- end
-
- def optional_tls_flags
- return [] unless files.key?(:'ca.pem')
-
- [
- '--tls',
- '--tls-ca-cert', "#{files_dir}/ca.pem",
- '--tls-cert', "#{files_dir}/cert.pem",
- '--tls-key', "#{files_dir}/key.pem"
- ]
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/kubernetes/helm/delete_command.rb b/lib/gitlab/kubernetes/helm/delete_command.rb
deleted file mode 100644
index f8b9601bc98..00000000000
--- a/lib/gitlab/kubernetes/helm/delete_command.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Kubernetes
- module Helm
- class DeleteCommand < BaseCommand
- include ClientCommand
-
- attr_reader :predelete, :postdelete
-
- def initialize(predelete: nil, postdelete: nil, **args)
- super(**args)
- @predelete = predelete
- @postdelete = postdelete
- end
-
- def generate_script
- super + [
- init_command,
- predelete,
- delete_command,
- postdelete
- ].compact.join("\n")
- end
-
- def pod_name
- "uninstall-#{name}"
- end
-
- def delete_command
- ['helm', 'delete', '--purge', name].shelljoin
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/kubernetes/helm/init_command.rb b/lib/gitlab/kubernetes/helm/init_command.rb
deleted file mode 100644
index e4844e255c5..00000000000
--- a/lib/gitlab/kubernetes/helm/init_command.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Kubernetes
- module Helm
- class InitCommand < BaseCommand
- def generate_script
- super + [
- init_helm_command
- ].join("\n")
- end
-
- private
-
- def init_helm_command
- command = %w[helm init] + init_command_flags
-
- command.shelljoin
- end
-
- def init_command_flags
- tls_flags + optional_service_account_flag
- end
-
- def tls_flags
- [
- '--tiller-tls',
- '--tiller-tls-verify',
- '--tls-ca-cert', "#{files_dir}/ca.pem",
- '--tiller-tls-cert', "#{files_dir}/cert.pem",
- '--tiller-tls-key', "#{files_dir}/key.pem"
- ]
- end
-
- def optional_service_account_flag
- return [] unless rbac?
-
- ['--service-account', service_account_name]
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/kubernetes/helm/install_command.rb b/lib/gitlab/kubernetes/helm/install_command.rb
deleted file mode 100644
index d166842fce6..00000000000
--- a/lib/gitlab/kubernetes/helm/install_command.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Kubernetes
- module Helm
- class InstallCommand < BaseCommand
- include ClientCommand
-
- attr_reader :chart, :repository, :preinstall, :postinstall
- attr_accessor :version
-
- def initialize(chart:, version: nil, repository: nil, preinstall: nil, postinstall: nil, **args)
- super(**args)
- @chart = chart
- @version = version
- @repository = repository
- @preinstall = preinstall
- @postinstall = postinstall
- end
-
- def generate_script
- super + [
- init_command,
- repository_command,
- repository_update_command,
- preinstall,
- install_command,
- postinstall
- ].compact.join("\n")
- end
-
- private
-
- # Uses `helm upgrade --install` which means we can use this for both
- # installation and uprade of applications
- def install_command
- command = ['helm', 'upgrade', name, chart] +
- install_flag +
- rollback_support_flag +
- reset_values_flag +
- optional_version_flag +
- rbac_create_flag +
- namespace_flag +
- value_flag
-
- command.shelljoin
- end
-
- def install_flag
- ['--install']
- end
-
- def reset_values_flag
- ['--reset-values']
- end
-
- def value_flag
- ['-f', "/data/helm/#{name}/config/values.yaml"]
- end
-
- def namespace_flag
- ['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
- end
-
- def rbac_create_flag
- if rbac?
- %w[--set rbac.create=true,rbac.enabled=true]
- else
- %w[--set rbac.create=false,rbac.enabled=false]
- end
- end
-
- def optional_version_flag
- return [] unless version
-
- ['--version', version]
- end
-
- def rollback_support_flag
- ['--atomic', '--cleanup-on-fail']
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/kubernetes/helm/patch_command.rb b/lib/gitlab/kubernetes/helm/patch_command.rb
deleted file mode 100644
index a33dbdac134..00000000000
--- a/lib/gitlab/kubernetes/helm/patch_command.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-# frozen_string_literal: true
-
-# PatchCommand is for updating values in installed charts without overwriting
-# existing values.
-module Gitlab
- module Kubernetes
- module Helm
- class PatchCommand < BaseCommand
- include ClientCommand
-
- attr_reader :chart, :repository
- attr_accessor :version
-
- def initialize(chart:, version:, repository: nil, **args)
- super(**args)
-
- # version is mandatory to prevent chart mismatches
- # we do not want our values interpreted in the context of the wrong version
- raise ArgumentError, 'version is required' if version.blank?
-
- @chart = chart
- @version = version
- @repository = repository
- end
-
- def generate_script
- super + [
- init_command,
- repository_command,
- repository_update_command,
- upgrade_command
- ].compact.join("\n")
- end
-
- private
-
- def upgrade_command
- command = ['helm', 'upgrade', name, chart] +
- reuse_values_flag +
- version_flag +
- namespace_flag +
- value_flag
-
- command.shelljoin
- end
-
- def reuse_values_flag
- ['--reuse-values']
- end
-
- def value_flag
- ['-f', "/data/helm/#{name}/config/values.yaml"]
- end
-
- def namespace_flag
- ['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
- end
-
- def version_flag
- ['--version', version]
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/kubernetes/helm/pod.rb b/lib/gitlab/kubernetes/helm/pod.rb
index 75484f80070..9d0207e6b1f 100644
--- a/lib/gitlab/kubernetes/helm/pod.rb
+++ b/lib/gitlab/kubernetes/helm/pod.rb
@@ -27,7 +27,7 @@ module Gitlab
def container_specification
{
name: 'helm',
- image: "registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/#{Gitlab::Kubernetes::Helm::HELM_VERSION}-kube-#{Gitlab::Kubernetes::Helm::KUBECTL_VERSION}",
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/#{command.class::HELM_VERSION}-kube-#{Gitlab::Kubernetes::Helm::KUBECTL_VERSION}-alpine-3.12",
env: generate_pod_env(command),
command: %w(/bin/sh),
args: %w(-c $(COMMAND_SCRIPT))
@@ -50,11 +50,10 @@ module Gitlab
end
def generate_pod_env(command)
- {
- HELM_VERSION: Gitlab::Kubernetes::Helm::HELM_VERSION,
- TILLER_NAMESPACE: namespace_name,
+ command.env.merge(
+ HELM_VERSION: command.class::HELM_VERSION,
COMMAND_SCRIPT: command.generate_script
- }.map { |key, value| { name: key, value: value } }
+ ).map { |key, value| { name: key, value: value } }
end
def volumes_specification
diff --git a/lib/gitlab/kubernetes/helm/reset_command.rb b/lib/gitlab/kubernetes/helm/reset_command.rb
deleted file mode 100644
index f1f7938039c..00000000000
--- a/lib/gitlab/kubernetes/helm/reset_command.rb
+++ /dev/null
@@ -1,48 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Kubernetes
- module Helm
- class ResetCommand < BaseCommand
- include ClientCommand
-
- def generate_script
- super + [
- reset_helm_command,
- delete_tiller_replicaset,
- delete_tiller_clusterrolebinding
- ].join("\n")
- end
-
- def pod_name
- "uninstall-#{name}"
- end
-
- private
-
- # This method can be delete once we upgrade Helm to > 12.13.0
- # https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/27096#note_159695900
- #
- # Tracking this method to be removed here:
- # https://gitlab.com/gitlab-org/gitlab-foss/issues/52791#note_199374155
- def delete_tiller_replicaset
- delete_args = %w[replicaset -n gitlab-managed-apps -l name=tiller]
-
- Gitlab::Kubernetes::KubectlCmd.delete(*delete_args)
- end
-
- def delete_tiller_clusterrolebinding
- delete_args = %w[clusterrolebinding tiller-admin]
-
- Gitlab::Kubernetes::KubectlCmd.delete(*delete_args)
- end
-
- def reset_helm_command
- command = %w[helm reset] + optional_tls_flags
-
- command.shelljoin
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/kubernetes/helm/v2/base_command.rb b/lib/gitlab/kubernetes/helm/v2/base_command.rb
new file mode 100644
index 00000000000..931c2248310
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/v2/base_command.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Kubernetes
+ module Helm
+ module V2
+ class BaseCommand
+ attr_reader :name, :files
+
+ HELM_VERSION = '2.16.9'
+
+ def initialize(rbac:, name:, files:)
+ @rbac = rbac
+ @name = name
+ @files = files
+ end
+
+ def env
+ { TILLER_NAMESPACE: namespace }
+ end
+
+ def rbac?
+ @rbac
+ end
+
+ def pod_resource
+ pod_service_account_name = rbac? ? service_account_name : nil
+
+ Gitlab::Kubernetes::Helm::Pod.new(self, namespace, service_account_name: pod_service_account_name).generate
+ end
+
+ def generate_script
+ <<~HEREDOC
+ set -xeo pipefail
+ HEREDOC
+ end
+
+ def pod_name
+ "install-#{name}"
+ end
+
+ def config_map_resource
+ Gitlab::Kubernetes::ConfigMap.new(name, files).generate
+ end
+
+ def service_account_resource
+ return unless rbac?
+
+ Gitlab::Kubernetes::ServiceAccount.new(service_account_name, namespace).generate
+ end
+
+ def cluster_role_binding_resource
+ return unless rbac?
+
+ subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: namespace }]
+
+ Gitlab::Kubernetes::ClusterRoleBinding.new(
+ cluster_role_binding_name,
+ cluster_role_name,
+ subjects
+ ).generate
+ end
+
+ def file_names
+ files.keys
+ end
+
+ private
+
+ def files_dir
+ "/data/helm/#{name}/config"
+ end
+
+ def namespace
+ Gitlab::Kubernetes::Helm::NAMESPACE
+ end
+
+ def service_account_name
+ Gitlab::Kubernetes::Helm::SERVICE_ACCOUNT
+ end
+
+ def cluster_role_binding_name
+ Gitlab::Kubernetes::Helm::CLUSTER_ROLE_BINDING
+ end
+
+ def cluster_role_name
+ Gitlab::Kubernetes::Helm::CLUSTER_ROLE
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes/helm/v2/certificate.rb b/lib/gitlab/kubernetes/helm/v2/certificate.rb
new file mode 100644
index 00000000000..f603ff44ef3
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/v2/certificate.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+module Gitlab
+ module Kubernetes
+ module Helm
+ module V2
+ class Certificate
+ INFINITE_EXPIRY = 1000.years
+ SHORT_EXPIRY = 30.minutes
+
+ attr_reader :key, :cert
+
+ def key_string
+ @key.to_s
+ end
+
+ def cert_string
+ @cert.to_pem
+ end
+
+ def self.from_strings(key_string, cert_string)
+ key = OpenSSL::PKey::RSA.new(key_string)
+ cert = OpenSSL::X509::Certificate.new(cert_string)
+ new(key, cert)
+ end
+
+ def self.generate_root
+ _issue(signed_by: nil, expires_in: INFINITE_EXPIRY, certificate_authority: true)
+ end
+
+ def issue(expires_in: SHORT_EXPIRY)
+ self.class._issue(signed_by: self, expires_in: expires_in, certificate_authority: false)
+ end
+
+ private
+
+ def self._issue(signed_by:, expires_in:, certificate_authority:)
+ key = OpenSSL::PKey::RSA.new(4096)
+ public_key = key.public_key
+
+ subject = OpenSSL::X509::Name.parse("/C=US")
+
+ cert = OpenSSL::X509::Certificate.new
+ cert.subject = subject
+
+ cert.issuer = signed_by&.cert&.subject || subject
+
+ cert.not_before = Time.now.utc
+ cert.not_after = expires_in.from_now.utc
+ cert.public_key = public_key
+ cert.serial = 0x0
+ cert.version = 2
+
+ if certificate_authority
+ extension_factory = OpenSSL::X509::ExtensionFactory.new
+ extension_factory.subject_certificate = cert
+ extension_factory.issuer_certificate = cert
+ cert.add_extension(extension_factory.create_extension('subjectKeyIdentifier', 'hash'))
+ cert.add_extension(extension_factory.create_extension('basicConstraints', 'CA:TRUE', true))
+ cert.add_extension(extension_factory.create_extension('keyUsage', 'cRLSign,keyCertSign', true))
+ end
+
+ cert.sign(signed_by&.key || key, OpenSSL::Digest::SHA256.new)
+
+ new(key, cert)
+ end
+
+ def initialize(key, cert)
+ @key = key
+ @cert = cert
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes/helm/v2/client_command.rb b/lib/gitlab/kubernetes/helm/v2/client_command.rb
new file mode 100644
index 00000000000..88693a28d6c
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/v2/client_command.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Kubernetes
+ module Helm
+ module V2
+ module ClientCommand
+ def init_command
+ <<~SHELL.chomp
+ export HELM_HOST="localhost:44134"
+ tiller -listen ${HELM_HOST} -alsologtostderr &
+ helm init --client-only
+ SHELL
+ end
+
+ def repository_command
+ ['helm', 'repo', 'add', name, repository].shelljoin if repository
+ end
+
+ private
+
+ def repository_update_command
+ 'helm repo update'
+ end
+
+ def optional_tls_flags
+ return [] unless files.key?(:'ca.pem')
+
+ [
+ '--tls',
+ '--tls-ca-cert', "#{files_dir}/ca.pem",
+ '--tls-cert', "#{files_dir}/cert.pem",
+ '--tls-key', "#{files_dir}/key.pem"
+ ]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes/helm/v2/delete_command.rb b/lib/gitlab/kubernetes/helm/v2/delete_command.rb
new file mode 100644
index 00000000000..4d52fc1398f
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/v2/delete_command.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Kubernetes
+ module Helm
+ module V2
+ class DeleteCommand < BaseCommand
+ include ClientCommand
+
+ attr_reader :predelete, :postdelete
+
+ def initialize(predelete: nil, postdelete: nil, **args)
+ super(**args)
+ @predelete = predelete
+ @postdelete = postdelete
+ end
+
+ def generate_script
+ super + [
+ init_command,
+ predelete,
+ delete_command,
+ postdelete
+ ].compact.join("\n")
+ end
+
+ def pod_name
+ "uninstall-#{name}"
+ end
+
+ def delete_command
+ ['helm', 'delete', '--purge', name].shelljoin
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes/helm/v2/init_command.rb b/lib/gitlab/kubernetes/helm/v2/init_command.rb
new file mode 100644
index 00000000000..f8b52feb5b6
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/v2/init_command.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Kubernetes
+ module Helm
+ module V2
+ class InitCommand < BaseCommand
+ def generate_script
+ super + [
+ init_helm_command
+ ].join("\n")
+ end
+
+ private
+
+ def init_helm_command
+ command = %w[helm init] + init_command_flags
+
+ command.shelljoin
+ end
+
+ def init_command_flags
+ tls_flags + optional_service_account_flag
+ end
+
+ def tls_flags
+ [
+ '--tiller-tls',
+ '--tiller-tls-verify',
+ '--tls-ca-cert', "#{files_dir}/ca.pem",
+ '--tiller-tls-cert', "#{files_dir}/cert.pem",
+ '--tiller-tls-key', "#{files_dir}/key.pem"
+ ]
+ end
+
+ def optional_service_account_flag
+ return [] unless rbac?
+
+ ['--service-account', service_account_name]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes/helm/v2/install_command.rb b/lib/gitlab/kubernetes/helm/v2/install_command.rb
new file mode 100644
index 00000000000..10e16723e45
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/v2/install_command.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Kubernetes
+ module Helm
+ module V2
+ class InstallCommand < BaseCommand
+ include ClientCommand
+
+ attr_reader :chart, :repository, :preinstall, :postinstall
+ attr_accessor :version
+
+ def initialize(chart:, version: nil, repository: nil, preinstall: nil, postinstall: nil, **args)
+ super(**args)
+ @chart = chart
+ @version = version
+ @repository = repository
+ @preinstall = preinstall
+ @postinstall = postinstall
+ end
+
+ def generate_script
+ super + [
+ init_command,
+ repository_command,
+ repository_update_command,
+ preinstall,
+ install_command,
+ postinstall
+ ].compact.join("\n")
+ end
+
+ private
+
+ # Uses `helm upgrade --install` which means we can use this for both
+ # installation and uprade of applications
+ def install_command
+ command = ['helm', 'upgrade', name, chart] +
+ install_flag +
+ rollback_support_flag +
+ reset_values_flag +
+ optional_version_flag +
+ rbac_create_flag +
+ namespace_flag +
+ value_flag
+
+ command.shelljoin
+ end
+
+ def install_flag
+ ['--install']
+ end
+
+ def reset_values_flag
+ ['--reset-values']
+ end
+
+ def value_flag
+ ['-f', "/data/helm/#{name}/config/values.yaml"]
+ end
+
+ def namespace_flag
+ ['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
+ end
+
+ def rbac_create_flag
+ if rbac?
+ %w[--set rbac.create=true,rbac.enabled=true]
+ else
+ %w[--set rbac.create=false,rbac.enabled=false]
+ end
+ end
+
+ def optional_version_flag
+ return [] unless version
+
+ ['--version', version]
+ end
+
+ def rollback_support_flag
+ ['--atomic', '--cleanup-on-fail']
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes/helm/v2/patch_command.rb b/lib/gitlab/kubernetes/helm/v2/patch_command.rb
new file mode 100644
index 00000000000..2855e6444b1
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/v2/patch_command.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+# PatchCommand is for updating values in installed charts without overwriting
+# existing values.
+module Gitlab
+ module Kubernetes
+ module Helm
+ module V2
+ class PatchCommand < BaseCommand
+ include ClientCommand
+
+ attr_reader :chart, :repository
+ attr_accessor :version
+
+ def initialize(chart:, version:, repository: nil, **args)
+ super(**args)
+
+ # version is mandatory to prevent chart mismatches
+ # we do not want our values interpreted in the context of the wrong version
+ raise ArgumentError, 'version is required' if version.blank?
+
+ @chart = chart
+ @version = version
+ @repository = repository
+ end
+
+ def generate_script
+ super + [
+ init_command,
+ repository_command,
+ repository_update_command,
+ upgrade_command
+ ].compact.join("\n")
+ end
+
+ private
+
+ def upgrade_command
+ command = ['helm', 'upgrade', name, chart] +
+ reuse_values_flag +
+ version_flag +
+ namespace_flag +
+ value_flag
+
+ command.shelljoin
+ end
+
+ def reuse_values_flag
+ ['--reuse-values']
+ end
+
+ def value_flag
+ ['-f', "/data/helm/#{name}/config/values.yaml"]
+ end
+
+ def namespace_flag
+ ['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
+ end
+
+ def version_flag
+ ['--version', version]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes/helm/v2/reset_command.rb b/lib/gitlab/kubernetes/helm/v2/reset_command.rb
new file mode 100644
index 00000000000..172a0884c49
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/v2/reset_command.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Kubernetes
+ module Helm
+ module V2
+ class ResetCommand < BaseCommand
+ include ClientCommand
+
+ def generate_script
+ super + [
+ reset_helm_command,
+ delete_tiller_replicaset,
+ delete_tiller_clusterrolebinding
+ ].join("\n")
+ end
+
+ def pod_name
+ "uninstall-#{name}"
+ end
+
+ private
+
+ # This method can be delete once we upgrade Helm to > 12.13.0
+ # https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/27096#note_159695900
+ #
+ # Tracking this method to be removed here:
+ # https://gitlab.com/gitlab-org/gitlab-foss/issues/52791#note_199374155
+ def delete_tiller_replicaset
+ delete_args = %w[replicaset -n gitlab-managed-apps -l name=tiller]
+
+ Gitlab::Kubernetes::KubectlCmd.delete(*delete_args)
+ end
+
+ def delete_tiller_clusterrolebinding
+ delete_args = %w[clusterrolebinding tiller-admin]
+
+ Gitlab::Kubernetes::KubectlCmd.delete(*delete_args)
+ end
+
+ def reset_helm_command
+ command = %w[helm reset] + optional_tls_flags
+
+ command.shelljoin
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes/helm/v3/base_command.rb b/lib/gitlab/kubernetes/helm/v3/base_command.rb
new file mode 100644
index 00000000000..ca1bf5462f0
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/v3/base_command.rb
@@ -0,0 +1,101 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Kubernetes
+ module Helm
+ module V3
+ class BaseCommand
+ attr_reader :name, :files
+
+ HELM_VERSION = '3.2.4'
+
+ def initialize(rbac:, name:, files:)
+ @rbac = rbac
+ @name = name
+ @files = files
+ end
+
+ def env
+ {}
+ end
+
+ def rbac?
+ @rbac
+ end
+
+ def pod_resource
+ pod_service_account_name = rbac? ? service_account_name : nil
+
+ Gitlab::Kubernetes::Helm::Pod.new(self, namespace, service_account_name: pod_service_account_name).generate
+ end
+
+ def generate_script
+ <<~HEREDOC
+ set -xeo pipefail
+ HEREDOC
+ end
+
+ def pod_name
+ "install-#{name}"
+ end
+
+ def config_map_resource
+ Gitlab::Kubernetes::ConfigMap.new(name, files).generate
+ end
+
+ def service_account_resource
+ return unless rbac?
+
+ Gitlab::Kubernetes::ServiceAccount.new(service_account_name, namespace).generate
+ end
+
+ def cluster_role_binding_resource
+ return unless rbac?
+
+ subjects = [{ kind: 'ServiceAccount', name: service_account_name, namespace: namespace }]
+
+ Gitlab::Kubernetes::ClusterRoleBinding.new(
+ cluster_role_binding_name,
+ cluster_role_name,
+ subjects
+ ).generate
+ end
+
+ def file_names
+ files.keys
+ end
+
+ def repository_command
+ ['helm', 'repo', 'add', name, repository].shelljoin if repository
+ end
+
+ private
+
+ def repository_update_command
+ 'helm repo update'
+ end
+
+ def namespace_flag
+ ['--namespace', Gitlab::Kubernetes::Helm::NAMESPACE]
+ end
+
+ def namespace
+ Gitlab::Kubernetes::Helm::NAMESPACE
+ end
+
+ def service_account_name
+ Gitlab::Kubernetes::Helm::SERVICE_ACCOUNT
+ end
+
+ def cluster_role_binding_name
+ Gitlab::Kubernetes::Helm::CLUSTER_ROLE_BINDING
+ end
+
+ def cluster_role_name
+ Gitlab::Kubernetes::Helm::CLUSTER_ROLE
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes/helm/v3/delete_command.rb b/lib/gitlab/kubernetes/helm/v3/delete_command.rb
new file mode 100644
index 00000000000..f628e852f54
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/v3/delete_command.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Kubernetes
+ module Helm
+ module V3
+ class DeleteCommand < BaseCommand
+ attr_reader :predelete, :postdelete
+
+ def initialize(predelete: nil, postdelete: nil, **args)
+ super(**args)
+ @predelete = predelete
+ @postdelete = postdelete
+ end
+
+ def generate_script
+ super + [
+ predelete,
+ delete_command,
+ postdelete
+ ].compact.join("\n")
+ end
+
+ def pod_name
+ "uninstall-#{name}"
+ end
+
+ def delete_command
+ ['helm', 'uninstall', name, *namespace_flag].shelljoin
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes/helm/v3/install_command.rb b/lib/gitlab/kubernetes/helm/v3/install_command.rb
new file mode 100644
index 00000000000..20d17f49115
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/v3/install_command.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Kubernetes
+ module Helm
+ module V3
+ class InstallCommand < BaseCommand
+ attr_reader :chart, :repository, :preinstall, :postinstall
+ attr_accessor :version
+
+ def initialize(chart:, version: nil, repository: nil, preinstall: nil, postinstall: nil, **args)
+ super(**args)
+ @chart = chart
+ @version = version
+ @repository = repository
+ @preinstall = preinstall
+ @postinstall = postinstall
+ end
+
+ def generate_script
+ super + [
+ repository_command,
+ repository_update_command,
+ preinstall,
+ install_command,
+ postinstall
+ ].compact.join("\n")
+ end
+
+ private
+
+ # Uses `helm upgrade --install` which means we can use this for both
+ # installation and uprade of applications
+ def install_command
+ command = ['helm', 'upgrade', name, chart] +
+ install_flag +
+ rollback_support_flag +
+ reset_values_flag +
+ optional_version_flag +
+ rbac_create_flag +
+ namespace_flag +
+ value_flag
+
+ command.shelljoin
+ end
+
+ def install_flag
+ ['--install']
+ end
+
+ def reset_values_flag
+ ['--reset-values']
+ end
+
+ def value_flag
+ ['-f', "/data/helm/#{name}/config/values.yaml"]
+ end
+
+ def rbac_create_flag
+ if rbac?
+ %w[--set rbac.create=true,rbac.enabled=true]
+ else
+ %w[--set rbac.create=false,rbac.enabled=false]
+ end
+ end
+
+ def optional_version_flag
+ return [] unless version
+
+ ['--version', version]
+ end
+
+ def rollback_support_flag
+ ['--atomic', '--cleanup-on-fail']
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/kubernetes/helm/v3/patch_command.rb b/lib/gitlab/kubernetes/helm/v3/patch_command.rb
new file mode 100644
index 00000000000..00f340591e7
--- /dev/null
+++ b/lib/gitlab/kubernetes/helm/v3/patch_command.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+# PatchCommand is for updating values in installed charts without overwriting
+# existing values.
+module Gitlab
+ module Kubernetes
+ module Helm
+ module V3
+ class PatchCommand < BaseCommand
+ attr_reader :chart, :repository
+ attr_accessor :version
+
+ def initialize(chart:, version:, repository: nil, **args)
+ super(**args)
+
+ # version is mandatory to prevent chart mismatches
+ # we do not want our values interpreted in the context of the wrong version
+ raise ArgumentError, 'version is required' if version.blank?
+
+ @chart = chart
+ @version = version
+ @repository = repository
+ end
+
+ def generate_script
+ super + [
+ repository_command,
+ repository_update_command,
+ upgrade_command
+ ].compact.join("\n")
+ end
+
+ private
+
+ def upgrade_command
+ command = ['helm', 'upgrade', name, chart] +
+ reuse_values_flag +
+ version_flag +
+ namespace_flag +
+ value_flag
+
+ command.shelljoin
+ end
+
+ def reuse_values_flag
+ ['--reuse-values']
+ end
+
+ def value_flag
+ ['-f', "/data/helm/#{name}/config/values.yaml"]
+ end
+
+ def version_flag
+ ['--version', version]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 01886a4edcb..d283d5caf08 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -18511,6 +18511,9 @@ msgstr ""
msgid "Notes|This comment has changed since you started editing, please review the %{open_link}updated comment%{close_link} to ensure information is not lost"
msgstr ""
+msgid "Notes|You're only seeing %{boldStart}other activity%{boldEnd} in the feed. To add a comment, switch to one of the following options."
+msgstr ""
+
msgid "Nothing found…"
msgstr ""
@@ -30920,9 +30923,6 @@ msgstr ""
msgid "You're not allowed to make changes to this project directly. A fork of this project is being created that you can make changes in, so you can submit a merge request."
msgstr ""
-msgid "You're only seeing %{startTag}other activity%{endTag} in the feed. To add a comment, switch to one of the following options."
-msgstr ""
-
msgid "You're receiving this email because of your account on %{host}."
msgstr ""
diff --git a/spec/factories/clusters/applications/helm.rb b/spec/factories/clusters/applications/helm.rb
index 46aa640780b..01df5cc677d 100644
--- a/spec/factories/clusters/applications/helm.rb
+++ b/spec/factories/clusters/applications/helm.rb
@@ -5,7 +5,7 @@ FactoryBot.define do
cluster factory: %i(cluster provided_by_gcp)
before(:create) do
- allow(Gitlab::Kubernetes::Helm::Certificate).to receive(:generate_root)
+ allow(Gitlab::Kubernetes::Helm::V2::Certificate).to receive(:generate_root)
.and_return(
double(
key_string: File.read(Rails.root.join('spec/fixtures/clusters/sample_key.key')),
@@ -15,7 +15,7 @@ FactoryBot.define do
end
after(:create) do
- allow(Gitlab::Kubernetes::Helm::Certificate).to receive(:generate_root).and_call_original
+ allow(Gitlab::Kubernetes::Helm::V2::Certificate).to receive(:generate_root).and_call_original
end
trait :not_installable do
diff --git a/spec/fixtures/api/schemas/public_api/v4/release.json b/spec/fixtures/api/schemas/public_api/v4/release.json
index 02e23d2732d..69ac383b7fd 100644
--- a/spec/fixtures/api/schemas/public_api/v4/release.json
+++ b/spec/fixtures/api/schemas/public_api/v4/release.json
@@ -21,7 +21,6 @@
},
"commit_path": { "type": "string" },
"tag_path": { "type": "string" },
- "name": { "type": "string" },
"evidences": {
"type": "array",
"items": { "$ref": "release/evidence.json" }
@@ -42,11 +41,8 @@
"additionalProperties": false
},
"_links": {
- "required": ["merge_requests_url", "issues_url"],
"properties": {
- "merge_requests_url": { "type": "string" },
- "issues_url": { "type": "string" },
- "edit_url": { "type": "string"}
+ "edit_url": { "type": "string" }
}
}
},
diff --git a/spec/fixtures/api/schemas/public_api/v4/release/release_for_guest.json b/spec/fixtures/api/schemas/public_api/v4/release/release_for_guest.json
index 1a1e92ac778..058b7b4b4ed 100644
--- a/spec/fixtures/api/schemas/public_api/v4/release/release_for_guest.json
+++ b/spec/fixtures/api/schemas/public_api/v4/release/release_for_guest.json
@@ -26,11 +26,7 @@
"additionalProperties": false
},
"_links": {
- "required": ["merge_requests_url", "issues_url"],
- "properties": {
- "merge_requests_url": { "type": "string" },
- "issues_url": { "type": "string" }
- }
+ "properties": {}
}
},
"additionalProperties": false
diff --git a/spec/frontend/notes/components/discussion_filter_note_spec.js b/spec/frontend/notes/components/discussion_filter_note_spec.js
index 4701108d315..d35f8f7c28d 100644
--- a/spec/frontend/notes/components/discussion_filter_note_spec.js
+++ b/spec/frontend/notes/components/discussion_filter_note_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { GlButton, GlSprintf } from '@gitlab/ui';
import DiscussionFilterNote from '~/notes/components/discussion_filter_note.vue';
import eventHub from '~/notes/event_hub';
@@ -6,7 +7,11 @@ describe('DiscussionFilterNote component', () => {
let wrapper;
const createComponent = () => {
- wrapper = shallowMount(DiscussionFilterNote);
+ wrapper = shallowMount(DiscussionFilterNote, {
+ stubs: {
+ GlSprintf,
+ },
+ });
};
beforeEach(() => {
@@ -19,21 +24,27 @@ describe('DiscussionFilterNote component', () => {
});
it('timelineContent renders a string containing instruction for switching feed type', () => {
- expect(wrapper.find({ ref: 'timelineContent' }).html()).toBe(
- "<div>You're only seeing <b>other activity</b> in the feed. To add a comment, switch to one of the following options.</div>",
+ expect(wrapper.find('[data-testid="discussion-filter-timeline-content"]').html()).toBe(
+ '<div data-testid="discussion-filter-timeline-content">You\'re only seeing <b>other activity</b> in the feed. To add a comment, switch to one of the following options.</div>',
);
});
it('emits `dropdownSelect` event with 0 parameter on clicking Show all activity button', () => {
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
- wrapper.find({ ref: 'showAllActivity' }).vm.$emit('click');
+ wrapper
+ .findAll(GlButton)
+ .at(0)
+ .vm.$emit('click');
expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 0);
});
it('emits `dropdownSelect` event with 1 parameter on clicking Show comments only button', () => {
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
- wrapper.find({ ref: 'showComments' }).vm.$emit('click');
+ wrapper
+ .findAll(GlButton)
+ .at(1)
+ .vm.$emit('click');
expect(eventHub.$emit).toHaveBeenCalledWith('dropdownSelect', 1);
});
diff --git a/spec/graphql/types/release_links_type_spec.rb b/spec/graphql/types/release_links_type_spec.rb
index d3494e0e86c..38c38d58baa 100644
--- a/spec/graphql/types/release_links_type_spec.rb
+++ b/spec/graphql/types/release_links_type_spec.rb
@@ -14,8 +14,6 @@ RSpec.describe GitlabSchema.types['ReleaseLinks'] do
openedIssuesUrl
closedIssuesUrl
editUrl
- mergeRequestsUrl
- issuesUrl
]
expect(described_class).to include_graphql_fields(*expected_fields)
diff --git a/spec/lib/gitlab/import_export/importer_spec.rb b/spec/lib/gitlab/import_export/importer_spec.rb
index 7c10011273a..0db038785d3 100644
--- a/spec/lib/gitlab/import_export/importer_spec.rb
+++ b/spec/lib/gitlab/import_export/importer_spec.rb
@@ -65,10 +65,22 @@ RSpec.describe Gitlab::ImportExport::Importer do
end
end
- it 'restores the ProjectTree' do
- expect(Gitlab::ImportExport::Project::TreeRestorer).to receive(:new).and_call_original
+ context 'with sample_data_template' do
+ it 'initializes the Sample::TreeRestorer' do
+ project.create_or_update_import_data(data: { sample_data: true })
- importer.execute
+ expect(Gitlab::ImportExport::Project::Sample::TreeRestorer).to receive(:new).and_call_original
+
+ importer.execute
+ end
+ end
+
+ context 'without sample_data_template' do
+ it 'initializes the ProjectTree' do
+ expect(Gitlab::ImportExport::Project::TreeRestorer).to receive(:new).and_call_original
+
+ importer.execute
+ end
end
it 'removes the import file' do
diff --git a/spec/lib/gitlab/import_export/project/sample/relation_factory_spec.rb b/spec/lib/gitlab/import_export/project/sample/relation_factory_spec.rb
new file mode 100644
index 00000000000..86d5f2402f8
--- /dev/null
+++ b/spec/lib/gitlab/import_export/project/sample/relation_factory_spec.rb
@@ -0,0 +1,168 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::ImportExport::Project::Sample::RelationFactory do
+ let(:group) { create(:group) }
+ let(:project) { create(:project, :repository, group: group) }
+ let(:members_mapper) { double('members_mapper').as_null_object }
+ let(:admin) { create(:admin) }
+ let(:importer_user) { admin }
+ let(:excluded_keys) { [] }
+ let(:date_calculator) { instance_double(Gitlab::ImportExport::Project::Sample::DateCalculator) }
+ let(:original_project_id) { 8 }
+ let(:start_date) { Time.current - 30.days }
+ let(:due_date) { Time.current - 20.days }
+ let(:created_object) do
+ described_class.create( # rubocop:disable Rails/SaveBang
+ relation_sym: relation_sym,
+ relation_hash: relation_hash,
+ object_builder: Gitlab::ImportExport::Project::ObjectBuilder,
+ members_mapper: members_mapper,
+ user: importer_user,
+ importable: project,
+ excluded_keys: excluded_keys,
+ date_calculator: date_calculator
+ )
+ end
+
+ context 'issue object' do
+ let(:relation_sym) { :issues }
+ let(:id) { 999 }
+
+ let(:relation_hash) do
+ {
+ 'id' => id,
+ 'title' => 'Necessitatibus magnam qui at velit consequatur perspiciatis.',
+ 'project_id' => original_project_id,
+ 'created_at' => '2016-08-12T09:41:03.462Z',
+ 'updated_at' => '2016-08-12T09:41:03.462Z',
+ 'description' => 'Molestiae corporis magnam et fugit aliquid nulla quia.',
+ 'state' => 'closed',
+ 'position' => 0,
+ 'confidential' => false,
+ 'due_date' => due_date
+ }
+ end
+
+ before do
+ allow(date_calculator).to receive(:closest_date_to_average) { Time.current - 10.days }
+ allow(date_calculator).to receive(:calculate_by_closest_date_to_average)
+ end
+
+ it 'correctly updated due date', :aggregate_failures do
+ expect(date_calculator).to receive(:calculate_by_closest_date_to_average)
+ .with(relation_hash['due_date']).and_return(due_date - 10.days)
+
+ expect(created_object.due_date).to eq((due_date - 10.days).to_date)
+ end
+ end
+
+ context 'milestone object' do
+ let(:relation_sym) { :milestones }
+ let(:id) { 1001 }
+
+ let(:relation_hash) do
+ {
+ 'id' => id,
+ 'title' => 'v3.0',
+ 'project_id' => original_project_id,
+ 'created_at' => '2016-08-12T09:41:03.462Z',
+ 'updated_at' => '2016-08-12T09:41:03.462Z',
+ 'description' => 'Rerum at autem exercitationem ea voluptates harum quam placeat.',
+ 'state' => 'closed',
+ 'start_date' => start_date,
+ 'due_date' => due_date
+ }
+ end
+
+ before do
+ allow(date_calculator).to receive(:closest_date_to_average).twice { Time.current - 10.days }
+ allow(date_calculator).to receive(:calculate_by_closest_date_to_average).twice
+ end
+
+ it 'correctly updated due date', :aggregate_failures do
+ expect(date_calculator).to receive(:calculate_by_closest_date_to_average)
+ .with(relation_hash['due_date']).and_return(due_date - 10.days)
+
+ expect(created_object.due_date).to eq((due_date - 10.days).to_date)
+ end
+
+ it 'correctly updated start date', :aggregate_failures do
+ expect(date_calculator).to receive(:calculate_by_closest_date_to_average)
+ .with(relation_hash['start_date']).and_return(start_date - 20.days)
+
+ expect(created_object.start_date).to eq((start_date - 20.days).to_date)
+ end
+ end
+
+ context 'milestone object' do
+ let(:relation_sym) { :milestones }
+ let(:id) { 1001 }
+
+ let(:relation_hash) do
+ {
+ 'id' => id,
+ 'title' => 'v3.0',
+ 'project_id' => original_project_id,
+ 'created_at' => '2016-08-12T09:41:03.462Z',
+ 'updated_at' => '2016-08-12T09:41:03.462Z',
+ 'description' => 'Rerum at autem exercitationem ea voluptates harum quam placeat.',
+ 'state' => 'closed',
+ 'start_date' => start_date,
+ 'due_date' => due_date
+ }
+ end
+
+ before do
+ allow(date_calculator).to receive(:closest_date_to_average).twice { Time.current - 10.days }
+ allow(date_calculator).to receive(:calculate_by_closest_date_to_average).twice
+ end
+
+ it 'correctly updated due date', :aggregate_failures do
+ expect(date_calculator).to receive(:calculate_by_closest_date_to_average)
+ .with(relation_hash['due_date']).and_return(due_date - 10.days)
+
+ expect(created_object.due_date).to eq((due_date - 10.days).to_date)
+ end
+
+ it 'correctly updated start date', :aggregate_failures do
+ expect(date_calculator).to receive(:calculate_by_closest_date_to_average)
+ .with(relation_hash['start_date']).and_return(start_date - 20.days)
+
+ expect(created_object.start_date).to eq((start_date - 20.days).to_date)
+ end
+ end
+
+ context 'hook object' do
+ let(:relation_sym) { :hooks }
+ let(:id) { 999 }
+ let(:service_id) { 99 }
+ let(:token) { 'secret' }
+
+ let(:relation_hash) do
+ {
+ 'id' => id,
+ 'url' => 'https://example.json',
+ 'project_id' => original_project_id,
+ 'created_at' => '2016-08-12T09:41:03.462Z',
+ 'updated_at' => '2016-08-12T09:41:03.462Z',
+ 'service_id' => service_id,
+ 'push_events' => true,
+ 'issues_events' => false,
+ 'confidential_issues_events' => false,
+ 'merge_requests_events' => true,
+ 'tag_push_events' => false,
+ 'note_events' => true,
+ 'enable_ssl_verification' => true,
+ 'job_events' => false,
+ 'wiki_page_events' => true,
+ 'token' => token
+ }
+ end
+
+ it 'does not calculate the closest date to average' do
+ expect(date_calculator).not_to receive(:calculate_by_closest_date_to_average)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/project/sample/sample_data_relation_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/sample/relation_tree_restorer_spec.rb
index f173345a4c6..f87f79d4462 100644
--- a/spec/lib/gitlab/import_export/project/sample/sample_data_relation_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project/sample/relation_tree_restorer_spec.rb
@@ -9,7 +9,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::ImportExport::Project::Sample::SampleDataRelationTreeRestorer do
+RSpec.describe Gitlab::ImportExport::Project::Sample::RelationTreeRestorer do
include_context 'relation tree restorer shared context'
let(:sample_data_relation_tree_restorer) do
@@ -74,13 +74,26 @@ RSpec.describe Gitlab::ImportExport::Project::Sample::SampleDataRelationTreeRest
let(:importable_name) { 'project' }
let(:importable_path) { 'project' }
let(:object_builder) { Gitlab::ImportExport::Project::ObjectBuilder }
- let(:relation_factory) { Gitlab::ImportExport::Project::RelationFactory }
+ let(:relation_factory) { Gitlab::ImportExport::Project::Sample::RelationFactory }
let(:reader) { Gitlab::ImportExport::Reader.new(shared: shared) }
+ let(:path) { 'spec/fixtures/lib/gitlab/import_export/sample_data/tree' }
+ let(:relation_reader) { Gitlab::ImportExport::JSON::NdjsonReader.new(path) }
- context 'using ndjson reader' do
- let(:path) { 'spec/fixtures/lib/gitlab/import_export/sample_data/tree' }
- let(:relation_reader) { Gitlab::ImportExport::JSON::NdjsonReader.new(path) }
+ it 'initializes relation_factory with date_calculator as parameter' do
+ expect(Gitlab::ImportExport::Project::Sample::RelationFactory).to receive(:create).with(hash_including(:date_calculator)).at_least(:once).times
+
+ subject
+ end
+
+ context 'when relation tree restorer is initialized' do
+ it 'initializes date calculator with due dates' do
+ expect(Gitlab::ImportExport::Project::Sample::DateCalculator).to receive(:new).with(Array)
+ sample_data_relation_tree_restorer
+ end
+ end
+
+ context 'using ndjson reader' do
it_behaves_like 'import project successfully'
end
end
diff --git a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
index c05968c9a85..f75494aa7c7 100644
--- a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
@@ -1040,41 +1040,6 @@ RSpec.describe Gitlab::ImportExport::Project::TreeRestorer do
it_behaves_like 'project tree restorer work properly', :legacy_reader, true
it_behaves_like 'project tree restorer work properly', :ndjson_reader, true
-
- context 'Sample Data JSON' do
- let(:user) { create(:user) }
- let!(:project) { create(:project, :builds_disabled, :issues_disabled, name: 'project', path: 'project') }
- let(:project_tree_restorer) { described_class.new(user: user, shared: shared, project: project) }
-
- before do
- setup_import_export_config('sample_data')
- setup_reader(:ndjson_reader)
- end
-
- context 'with sample_data_template' do
- before do
- allow(project).to receive_message_chain(:import_data, :data, :dig).with('sample_data') { true }
- end
-
- it 'initialize SampleDataRelationTreeRestorer' do
- expect_next_instance_of(Gitlab::ImportExport::Project::Sample::SampleDataRelationTreeRestorer) do |restorer|
- expect(restorer).to receive(:restore).and_return(true)
- end
-
- expect(project_tree_restorer.restore).to eq(true)
- end
- end
-
- context 'without sample_data_template' do
- it 'initialize RelationTreeRestorer' do
- expect_next_instance_of(Gitlab::ImportExport::RelationTreeRestorer) do |restorer|
- expect(restorer).to receive(:restore).and_return(true)
- end
-
- expect(project_tree_restorer.restore).to eq(true)
- end
- end
- end
end
context 'disable ndjson import' do
diff --git a/spec/lib/gitlab/kubernetes/helm/api_spec.rb b/spec/lib/gitlab/kubernetes/helm/api_spec.rb
index bcc95bdbf2b..e022f5bd912 100644
--- a/spec/lib/gitlab/kubernetes/helm/api_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/api_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe Gitlab::Kubernetes::Helm::API do
let(:files) { {} }
let(:command) do
- Gitlab::Kubernetes::Helm::InstallCommand.new(
+ Gitlab::Kubernetes::Helm::V2::InstallCommand.new(
name: application_name,
chart: 'chart-name',
rbac: rbac,
@@ -142,7 +142,7 @@ RSpec.describe Gitlab::Kubernetes::Helm::API do
end
context 'with a service account' do
- let(:command) { Gitlab::Kubernetes::Helm::InitCommand.new(name: application_name, files: files, rbac: rbac) }
+ let(:command) { Gitlab::Kubernetes::Helm::V2::InitCommand.new(name: application_name, files: files, rbac: rbac) }
context 'rbac-enabled cluster' do
let(:rbac) { true }
diff --git a/spec/lib/gitlab/kubernetes/helm/pod_spec.rb b/spec/lib/gitlab/kubernetes/helm/pod_spec.rb
index 54e3289dd25..6d97790fc8b 100644
--- a/spec/lib/gitlab/kubernetes/helm/pod_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/pod_spec.rb
@@ -4,75 +4,84 @@ require 'spec_helper'
RSpec.describe Gitlab::Kubernetes::Helm::Pod do
describe '#generate' do
- let(:app) { create(:clusters_applications_prometheus) }
- let(:command) { app.install_command }
- let(:namespace) { Gitlab::Kubernetes::Helm::NAMESPACE }
- let(:service_account_name) { nil }
+ using RSpec::Parameterized::TableSyntax
- subject { described_class.new(command, namespace, service_account_name: service_account_name) }
+ where(:helm_major_version, :expected_helm_version, :expected_command_env) do
+ 2 | '2.16.9' | [:TILLER_NAMESPACE]
+ 3 | '3.2.4' | nil
+ end
- context 'with a command' do
- it 'generates a Kubeclient::Resource' do
- expect(subject.generate).to be_a_kind_of(Kubeclient::Resource)
- end
+ with_them do
+ let(:cluster) { create(:cluster, helm_major_version: helm_major_version) }
+ let(:app) { create(:clusters_applications_prometheus, cluster: cluster) }
+ let(:command) { app.install_command }
+ let(:namespace) { Gitlab::Kubernetes::Helm::NAMESPACE }
+ let(:service_account_name) { nil }
- it 'generates the appropriate metadata' do
- metadata = subject.generate.metadata
- expect(metadata.name).to eq("install-#{app.name}")
- expect(metadata.namespace).to eq('gitlab-managed-apps')
- expect(metadata.labels['gitlab.org/action']).to eq('install')
- expect(metadata.labels['gitlab.org/application']).to eq(app.name)
- end
+ subject { described_class.new(command, namespace, service_account_name: service_account_name) }
- it 'generates a container spec' do
- spec = subject.generate.spec
- expect(spec.containers.count).to eq(1)
- end
+ context 'with a command' do
+ it 'generates a Kubeclient::Resource' do
+ expect(subject.generate).to be_a_kind_of(Kubeclient::Resource)
+ end
- it 'generates the appropriate specifications for the container' do
- container = subject.generate.spec.containers.first
- expect(container.name).to eq('helm')
- expect(container.image).to eq('registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/2.16.9-kube-1.13.12')
- expect(container.env.count).to eq(3)
- expect(container.env.map(&:name)).to match_array([:HELM_VERSION, :TILLER_NAMESPACE, :COMMAND_SCRIPT])
- expect(container.command).to match_array(["/bin/sh"])
- expect(container.args).to match_array(["-c", "$(COMMAND_SCRIPT)"])
- end
+ it 'generates the appropriate metadata' do
+ metadata = subject.generate.metadata
+ expect(metadata.name).to eq("install-#{app.name}")
+ expect(metadata.namespace).to eq('gitlab-managed-apps')
+ expect(metadata.labels['gitlab.org/action']).to eq('install')
+ expect(metadata.labels['gitlab.org/application']).to eq(app.name)
+ end
- it 'includes a never restart policy' do
- spec = subject.generate.spec
- expect(spec.restartPolicy).to eq('Never')
- end
+ it 'generates a container spec' do
+ spec = subject.generate.spec
+ expect(spec.containers.count).to eq(1)
+ end
- it 'includes volumes for the container' do
- container = subject.generate.spec.containers.first
- expect(container.volumeMounts.first['name']).to eq('configuration-volume')
- expect(container.volumeMounts.first['mountPath']).to eq("/data/helm/#{app.name}/config")
- end
+ it 'generates the appropriate specifications for the container' do
+ container = subject.generate.spec.containers.first
+ expect(container.name).to eq('helm')
+ expect(container.image).to eq("registry.gitlab.com/gitlab-org/cluster-integration/helm-install-image/releases/#{expected_helm_version}-kube-1.13.12-alpine-3.12")
+ expect(container.env.map(&:name)).to include(:HELM_VERSION, :COMMAND_SCRIPT, *expected_command_env)
+ expect(container.command).to match_array(["/bin/sh"])
+ expect(container.args).to match_array(["-c", "$(COMMAND_SCRIPT)"])
+ end
- it 'includes a volume inside the specification' do
- spec = subject.generate.spec
- expect(spec.volumes.first['name']).to eq('configuration-volume')
- end
+ it 'includes a never restart policy' do
+ spec = subject.generate.spec
+ expect(spec.restartPolicy).to eq('Never')
+ end
- it 'mounts configMap specification in the volume' do
- volume = subject.generate.spec.volumes.first
- expect(volume.configMap['name']).to eq("values-content-configuration-#{app.name}")
- expect(volume.configMap['items'].first['key']).to eq(:'values.yaml')
- expect(volume.configMap['items'].first['path']).to eq(:'values.yaml')
- end
+ it 'includes volumes for the container' do
+ container = subject.generate.spec.containers.first
+ expect(container.volumeMounts.first['name']).to eq('configuration-volume')
+ expect(container.volumeMounts.first['mountPath']).to eq("/data/helm/#{app.name}/config")
+ end
- it 'has no serviceAccountName' do
- spec = subject.generate.spec
- expect(spec.serviceAccountName).to be_nil
- end
+ it 'includes a volume inside the specification' do
+ spec = subject.generate.spec
+ expect(spec.volumes.first['name']).to eq('configuration-volume')
+ end
- context 'with a service_account_name' do
- let(:service_account_name) { 'sa' }
+ it 'mounts configMap specification in the volume' do
+ volume = subject.generate.spec.volumes.first
+ expect(volume.configMap['name']).to eq("values-content-configuration-#{app.name}")
+ expect(volume.configMap['items'].first['key']).to eq(:'values.yaml')
+ expect(volume.configMap['items'].first['path']).to eq(:'values.yaml')
+ end
- it 'uses the serviceAccountName provided' do
+ it 'has no serviceAccountName' do
spec = subject.generate.spec
- expect(spec.serviceAccountName).to eq(service_account_name)
+ expect(spec.serviceAccountName).to be_nil
+ end
+
+ context 'with a service_account_name' do
+ let(:service_account_name) { 'sa' }
+
+ it 'uses the serviceAccountName provided' do
+ spec = subject.generate.spec
+ expect(spec.serviceAccountName).to eq(service_account_name)
+ end
end
end
end
diff --git a/spec/lib/gitlab/kubernetes/helm/v2/base_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/v2/base_command_spec.rb
new file mode 100644
index 00000000000..3d2b36b9094
--- /dev/null
+++ b/spec/lib/gitlab/kubernetes/helm/v2/base_command_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Kubernetes::Helm::V2::BaseCommand do
+ subject(:base_command) do
+ test_class.new(rbac)
+ end
+
+ let(:application) { create(:clusters_applications_helm) }
+ let(:rbac) { false }
+
+ let(:test_class) do
+ Class.new(described_class) do
+ def initialize(rbac)
+ super(
+ name: 'test-class-name',
+ rbac: rbac,
+ files: { some: 'value' }
+ )
+ end
+ end
+ end
+
+ describe 'HELM_VERSION' do
+ subject { described_class::HELM_VERSION }
+
+ it { is_expected.to match /^2\.\d+\.\d+$/ }
+ end
+
+ describe '#env' do
+ subject { base_command.env }
+
+ it { is_expected.to include(TILLER_NAMESPACE: 'gitlab-managed-apps') }
+ end
+
+ it_behaves_like 'helm command generator' do
+ let(:commands) { '' }
+ end
+
+ describe '#pod_name' do
+ subject { base_command.pod_name }
+
+ it { is_expected.to eq('install-test-class-name') }
+ end
+
+ it_behaves_like 'helm command' do
+ let(:command) { base_command }
+ end
+end
diff --git a/spec/lib/gitlab/kubernetes/helm/certificate_spec.rb b/spec/lib/gitlab/kubernetes/helm/v2/certificate_spec.rb
index b446c5e1149..a3f0fd9eb9b 100644
--- a/spec/lib/gitlab/kubernetes/helm/certificate_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/v2/certificate_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe Gitlab::Kubernetes::Helm::Certificate do
+RSpec.describe Gitlab::Kubernetes::Helm::V2::Certificate do
describe '.generate_root' do
subject { described_class.generate_root }
diff --git a/spec/lib/gitlab/kubernetes/helm/delete_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/v2/delete_command_spec.rb
index ff2c2d76f22..4a3a41dba4a 100644
--- a/spec/lib/gitlab/kubernetes/helm/delete_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/v2/delete_command_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Kubernetes::Helm::DeleteCommand do
+RSpec.describe Gitlab::Kubernetes::Helm::V2::DeleteCommand do
subject(:delete_command) { described_class.new(name: app_name, rbac: rbac, files: files) }
let(:app_name) { 'app-name' }
diff --git a/spec/lib/gitlab/kubernetes/helm/init_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/v2/init_command_spec.rb
index d538ed12a07..8ae78ada15c 100644
--- a/spec/lib/gitlab/kubernetes/helm/init_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/v2/init_command_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Kubernetes::Helm::InitCommand do
+RSpec.describe Gitlab::Kubernetes::Helm::V2::InitCommand do
subject(:init_command) { described_class.new(name: application.name, files: files, rbac: rbac) }
let(:application) { create(:clusters_applications_helm) }
diff --git a/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/v2/install_command_spec.rb
index 6ed7323c96f..250d1a82e7a 100644
--- a/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/v2/install_command_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Kubernetes::Helm::InstallCommand do
+RSpec.describe Gitlab::Kubernetes::Helm::V2::InstallCommand do
subject(:install_command) do
described_class.new(
name: 'app-name',
@@ -147,37 +147,6 @@ RSpec.describe Gitlab::Kubernetes::Helm::InstallCommand do
end
end
- context 'when there is no ca.pem file' do
- let(:files) { { 'file.txt': 'some content' } }
-
- it_behaves_like 'helm command generator' do
- let(:commands) do
- <<~EOS
- export HELM_HOST="localhost:44134"
- tiller -listen ${HELM_HOST} -alsologtostderr &
- helm init --client-only
- helm repo add app-name https://repository.example.com
- helm repo update
- #{helm_install_command}
- EOS
- end
-
- let(:helm_install_command) do
- <<~EOS.squish
- helm upgrade app-name chart-name
- --install
- --atomic
- --cleanup-on-fail
- --reset-values
- --version 1.2.3
- --set rbac.create\\=false,rbac.enabled\\=false
- --namespace gitlab-managed-apps
- -f /data/helm/app-name/config/values.yaml
- EOS
- end
- end
- end
-
context 'when there is no version' do
let(:version) { nil }
diff --git a/spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/v2/patch_command_spec.rb
index 487a38f286d..98eb77d397c 100644
--- a/spec/lib/gitlab/kubernetes/helm/patch_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/v2/patch_command_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Kubernetes::Helm::PatchCommand do
+RSpec.describe Gitlab::Kubernetes::Helm::V2::PatchCommand do
let(:files) { { 'ca.pem': 'some file content' } }
let(:repository) { 'https://repository.example.com' }
let(:rbac) { false }
@@ -69,33 +69,6 @@ RSpec.describe Gitlab::Kubernetes::Helm::PatchCommand do
end
end
- context 'when there is no ca.pem file' do
- let(:files) { { 'file.txt': 'some content' } }
-
- it_behaves_like 'helm command generator' do
- let(:commands) do
- <<~EOS
- export HELM_HOST="localhost:44134"
- tiller -listen ${HELM_HOST} -alsologtostderr &
- helm init --client-only
- helm repo add app-name https://repository.example.com
- helm repo update
- #{helm_upgrade_command}
- EOS
- end
-
- let(:helm_upgrade_command) do
- <<~EOS.squish
- helm upgrade app-name chart-name
- --reuse-values
- --version 1.2.3
- --namespace gitlab-managed-apps
- -f /data/helm/app-name/config/values.yaml
- EOS
- end
- end
- end
-
context 'when there is no version' do
let(:version) { nil }
diff --git a/spec/lib/gitlab/kubernetes/helm/reset_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/v2/reset_command_spec.rb
index 5a3ba59b8c0..9e580cea397 100644
--- a/spec/lib/gitlab/kubernetes/helm/reset_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/v2/reset_command_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Kubernetes::Helm::ResetCommand do
+RSpec.describe Gitlab::Kubernetes::Helm::V2::ResetCommand do
subject(:reset_command) { described_class.new(name: name, rbac: rbac, files: files) }
let(:rbac) { true }
diff --git a/spec/lib/gitlab/kubernetes/helm/base_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/v3/base_command_spec.rb
index a7abd6ab1bf..ad5ff13b4c9 100644
--- a/spec/lib/gitlab/kubernetes/helm/base_command_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/v3/base_command_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Kubernetes::Helm::BaseCommand do
+RSpec.describe Gitlab::Kubernetes::Helm::V3::BaseCommand do
subject(:base_command) do
test_class.new(rbac)
end
@@ -11,7 +11,7 @@ RSpec.describe Gitlab::Kubernetes::Helm::BaseCommand do
let(:rbac) { false }
let(:test_class) do
- Class.new(Gitlab::Kubernetes::Helm::BaseCommand) do
+ Class.new(described_class) do
def initialize(rbac)
super(
name: 'test-class-name',
@@ -22,6 +22,12 @@ RSpec.describe Gitlab::Kubernetes::Helm::BaseCommand do
end
end
+ describe 'HELM_VERSION' do
+ subject { described_class::HELM_VERSION }
+
+ it { is_expected.to match /^3\.\d+\.\d+$/ }
+ end
+
it_behaves_like 'helm command generator' do
let(:commands) { '' }
end
diff --git a/spec/lib/gitlab/kubernetes/helm/v3/delete_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/v3/delete_command_spec.rb
new file mode 100644
index 00000000000..63e7a8d2f25
--- /dev/null
+++ b/spec/lib/gitlab/kubernetes/helm/v3/delete_command_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Kubernetes::Helm::V3::DeleteCommand do
+ subject(:delete_command) { described_class.new(name: app_name, rbac: rbac, files: files) }
+
+ let(:app_name) { 'app-name' }
+ let(:rbac) { true }
+ let(:files) { {} }
+
+ it_behaves_like 'helm command generator' do
+ let(:commands) do
+ <<~EOS
+ helm uninstall app-name --namespace gitlab-managed-apps
+ EOS
+ end
+ end
+
+ describe '#pod_name' do
+ subject { delete_command.pod_name }
+
+ it { is_expected.to eq('uninstall-app-name') }
+ end
+
+ it_behaves_like 'helm command' do
+ let(:command) { delete_command }
+ end
+
+ describe '#delete_command' do
+ it 'deletes the release' do
+ expect(subject.delete_command).to eq('helm uninstall app-name --namespace gitlab-managed-apps')
+ end
+ end
+end
diff --git a/spec/lib/gitlab/kubernetes/helm/v3/install_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/v3/install_command_spec.rb
new file mode 100644
index 00000000000..2bf1f713b3f
--- /dev/null
+++ b/spec/lib/gitlab/kubernetes/helm/v3/install_command_spec.rb
@@ -0,0 +1,168 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Kubernetes::Helm::V3::InstallCommand do
+ subject(:install_command) do
+ described_class.new(
+ name: 'app-name',
+ chart: 'chart-name',
+ rbac: rbac,
+ files: files,
+ version: version,
+ repository: repository,
+ preinstall: preinstall,
+ postinstall: postinstall
+ )
+ end
+
+ let(:files) { { 'ca.pem': 'some file content' } }
+ let(:repository) { 'https://repository.example.com' }
+ let(:rbac) { false }
+ let(:version) { '1.2.3' }
+ let(:preinstall) { nil }
+ let(:postinstall) { nil }
+
+ it_behaves_like 'helm command generator' do
+ let(:commands) do
+ <<~EOS
+ helm repo add app-name https://repository.example.com
+ helm repo update
+ #{helm_install_comand}
+ EOS
+ end
+
+ let(:helm_install_comand) do
+ <<~EOS.squish
+ helm upgrade app-name chart-name
+ --install
+ --atomic
+ --cleanup-on-fail
+ --reset-values
+ --version 1.2.3
+ --set rbac.create\\=false,rbac.enabled\\=false
+ --namespace gitlab-managed-apps
+ -f /data/helm/app-name/config/values.yaml
+ EOS
+ end
+ end
+
+ context 'when rbac is true' do
+ let(:rbac) { true }
+
+ it_behaves_like 'helm command generator' do
+ let(:commands) do
+ <<~EOS
+ helm repo add app-name https://repository.example.com
+ helm repo update
+ #{helm_install_command}
+ EOS
+ end
+
+ let(:helm_install_command) do
+ <<~EOS.squish
+ helm upgrade app-name chart-name
+ --install
+ --atomic
+ --cleanup-on-fail
+ --reset-values
+ --version 1.2.3
+ --set rbac.create\\=true,rbac.enabled\\=true
+ --namespace gitlab-managed-apps
+ -f /data/helm/app-name/config/values.yaml
+ EOS
+ end
+ end
+ end
+
+ context 'when there is a pre-install script' do
+ let(:preinstall) { ['/bin/date', '/bin/true'] }
+
+ it_behaves_like 'helm command generator' do
+ let(:commands) do
+ <<~EOS
+ helm repo add app-name https://repository.example.com
+ helm repo update
+ /bin/date
+ /bin/true
+ #{helm_install_command}
+ EOS
+ end
+
+ let(:helm_install_command) do
+ <<~EOS.squish
+ helm upgrade app-name chart-name
+ --install
+ --atomic
+ --cleanup-on-fail
+ --reset-values
+ --version 1.2.3
+ --set rbac.create\\=false,rbac.enabled\\=false
+ --namespace gitlab-managed-apps
+ -f /data/helm/app-name/config/values.yaml
+ EOS
+ end
+ end
+ end
+
+ context 'when there is a post-install script' do
+ let(:postinstall) { ['/bin/date', "/bin/false\n"] }
+
+ it_behaves_like 'helm command generator' do
+ let(:commands) do
+ <<~EOS
+ helm repo add app-name https://repository.example.com
+ helm repo update
+ #{helm_install_command}
+ /bin/date
+ /bin/false
+ EOS
+ end
+
+ let(:helm_install_command) do
+ <<~EOS.squish
+ helm upgrade app-name chart-name
+ --install
+ --atomic
+ --cleanup-on-fail
+ --reset-values
+ --version 1.2.3
+ --set rbac.create\\=false,rbac.enabled\\=false
+ --namespace gitlab-managed-apps
+ -f /data/helm/app-name/config/values.yaml
+ EOS
+ end
+ end
+ end
+
+ context 'when there is no version' do
+ let(:version) { nil }
+
+ it_behaves_like 'helm command generator' do
+ let(:commands) do
+ <<~EOS
+ helm repo add app-name https://repository.example.com
+ helm repo update
+ #{helm_install_command}
+ EOS
+ end
+
+ let(:helm_install_command) do
+ <<~EOS.squish
+ helm upgrade app-name chart-name
+ --install
+ --atomic
+ --cleanup-on-fail
+ --reset-values
+ --set rbac.create\\=false,rbac.enabled\\=false
+ --namespace gitlab-managed-apps
+ -f /data/helm/app-name/config/values.yaml
+ EOS
+ end
+ end
+ end
+
+ it_behaves_like 'helm command' do
+ let(:command) { install_command }
+ end
+end
diff --git a/spec/lib/gitlab/kubernetes/helm/v3/patch_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/v3/patch_command_spec.rb
new file mode 100644
index 00000000000..2f22e0f2e77
--- /dev/null
+++ b/spec/lib/gitlab/kubernetes/helm/v3/patch_command_spec.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Kubernetes::Helm::V3::PatchCommand do
+ let(:files) { { 'ca.pem': 'some file content' } }
+ let(:repository) { 'https://repository.example.com' }
+ let(:rbac) { false }
+ let(:version) { '1.2.3' }
+
+ subject(:patch_command) do
+ described_class.new(
+ name: 'app-name',
+ chart: 'chart-name',
+ rbac: rbac,
+ files: files,
+ version: version,
+ repository: repository
+ )
+ end
+
+ it_behaves_like 'helm command generator' do
+ let(:commands) do
+ <<~EOS
+ helm repo add app-name https://repository.example.com
+ helm repo update
+ #{helm_upgrade_comand}
+ EOS
+ end
+
+ let(:helm_upgrade_comand) do
+ <<~EOS.squish
+ helm upgrade app-name chart-name
+ --reuse-values
+ --version 1.2.3
+ --namespace gitlab-managed-apps
+ -f /data/helm/app-name/config/values.yaml
+ EOS
+ end
+ end
+
+ context 'when rbac is true' do
+ let(:rbac) { true }
+
+ it_behaves_like 'helm command generator' do
+ let(:commands) do
+ <<~EOS
+ helm repo add app-name https://repository.example.com
+ helm repo update
+ #{helm_upgrade_command}
+ EOS
+ end
+
+ let(:helm_upgrade_command) do
+ <<~EOS.squish
+ helm upgrade app-name chart-name
+ --reuse-values
+ --version 1.2.3
+ --namespace gitlab-managed-apps
+ -f /data/helm/app-name/config/values.yaml
+ EOS
+ end
+ end
+ end
+
+ context 'when there is no version' do
+ let(:version) { nil }
+
+ it { expect { patch_command }.to raise_error(ArgumentError, 'version is required') }
+ end
+
+ describe '#pod_name' do
+ subject { patch_command.pod_name }
+
+ it { is_expected.to eq 'install-app-name' }
+ end
+
+ it_behaves_like 'helm command' do
+ let(:command) { patch_command }
+ end
+end
diff --git a/spec/models/clusters/applications/cert_manager_spec.rb b/spec/models/clusters/applications/cert_manager_spec.rb
index 7ca7f533a27..3044260a000 100644
--- a/spec/models/clusters/applications/cert_manager_spec.rb
+++ b/spec/models/clusters/applications/cert_manager_spec.rb
@@ -40,7 +40,7 @@ RSpec.describe Clusters::Applications::CertManager do
subject { cert_manager.install_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
it 'is initialized with cert_manager arguments' do
expect(subject.name).to eq('certmanager')
@@ -90,7 +90,7 @@ RSpec.describe Clusters::Applications::CertManager do
describe '#uninstall_command' do
subject { cert_manager.uninstall_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::DeleteCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand) }
it 'is initialized with cert_manager arguments' do
expect(subject.name).to eq('certmanager')
diff --git a/spec/models/clusters/applications/crossplane_spec.rb b/spec/models/clusters/applications/crossplane_spec.rb
index a41c5f6586b..7082576028b 100644
--- a/spec/models/clusters/applications/crossplane_spec.rb
+++ b/spec/models/clusters/applications/crossplane_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe Clusters::Applications::Crossplane do
subject { crossplane.install_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
it 'is initialized with crossplane arguments' do
expect(subject.name).to eq('crossplane')
diff --git a/spec/models/clusters/applications/elastic_stack_spec.rb b/spec/models/clusters/applications/elastic_stack_spec.rb
index 62123ffa542..74cacd486b0 100644
--- a/spec/models/clusters/applications/elastic_stack_spec.rb
+++ b/spec/models/clusters/applications/elastic_stack_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe Clusters::Applications::ElasticStack do
subject { elastic_stack.install_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
it 'is initialized with elastic stack arguments' do
expect(subject.name).to eq('elastic-stack')
@@ -57,7 +57,7 @@ RSpec.describe Clusters::Applications::ElasticStack do
it 'includes a preinstall script' do
expect(subject.preinstall).not_to be_empty
- expect(subject.preinstall.first).to include("delete")
+ expect(subject.preinstall.first).to include("helm uninstall")
end
end
@@ -69,7 +69,7 @@ RSpec.describe Clusters::Applications::ElasticStack do
it 'includes a preinstall script' do
expect(subject.preinstall).not_to be_empty
- expect(subject.preinstall.first).to include("delete")
+ expect(subject.preinstall.first).to include("helm uninstall")
end
end
@@ -123,7 +123,7 @@ RSpec.describe Clusters::Applications::ElasticStack do
subject { elastic_stack.uninstall_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::DeleteCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand) }
it 'is initialized with elastic stack arguments' do
expect(subject.name).to eq('elastic-stack')
diff --git a/spec/models/clusters/applications/fluentd_spec.rb b/spec/models/clusters/applications/fluentd_spec.rb
index 3bda3e99ec1..ccdf6b0e40d 100644
--- a/spec/models/clusters/applications/fluentd_spec.rb
+++ b/spec/models/clusters/applications/fluentd_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe Clusters::Applications::Fluentd do
describe '#install_command' do
subject { fluentd.install_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
it 'is initialized with fluentd arguments' do
expect(subject.name).to eq('fluentd')
diff --git a/spec/models/clusters/applications/helm_spec.rb b/spec/models/clusters/applications/helm_spec.rb
index 6d2ecaa6d47..ad1ebd4966a 100644
--- a/spec/models/clusters/applications/helm_spec.rb
+++ b/spec/models/clusters/applications/helm_spec.rb
@@ -56,7 +56,7 @@ RSpec.describe Clusters::Applications::Helm do
subject { application.issue_client_cert }
it 'returns a new cert' do
- is_expected.to be_kind_of(Gitlab::Kubernetes::Helm::Certificate)
+ is_expected.to be_kind_of(Gitlab::Kubernetes::Helm::V2::Certificate)
expect(subject.cert_string).not_to eq(application.ca_cert)
expect(subject.key_string).not_to eq(application.ca_key)
end
@@ -67,7 +67,7 @@ RSpec.describe Clusters::Applications::Helm do
subject { helm.install_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InitCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V2::InitCommand) }
it 'is initialized with 1 arguments' do
expect(subject.name).to eq('helm')
@@ -104,7 +104,7 @@ RSpec.describe Clusters::Applications::Helm do
subject { helm.uninstall_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::ResetCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V2::ResetCommand) }
it 'has name' do
expect(subject.name).to eq('helm')
diff --git a/spec/models/clusters/applications/ingress_spec.rb b/spec/models/clusters/applications/ingress_spec.rb
index 196d57aff7b..1bc1a4343aa 100644
--- a/spec/models/clusters/applications/ingress_spec.rb
+++ b/spec/models/clusters/applications/ingress_spec.rb
@@ -131,7 +131,7 @@ RSpec.describe Clusters::Applications::Ingress do
describe '#install_command' do
subject { ingress.install_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
it 'is initialized with ingress arguments' do
expect(subject.name).to eq('ingress')
diff --git a/spec/models/clusters/applications/jupyter_spec.rb b/spec/models/clusters/applications/jupyter_spec.rb
index 3cf24f1a9ef..e7de2d24334 100644
--- a/spec/models/clusters/applications/jupyter_spec.rb
+++ b/spec/models/clusters/applications/jupyter_spec.rb
@@ -52,7 +52,7 @@ RSpec.describe Clusters::Applications::Jupyter do
subject { jupyter.install_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
it 'is initialized with 4 arguments' do
expect(subject.name).to eq('jupyter')
diff --git a/spec/models/clusters/applications/knative_spec.rb b/spec/models/clusters/applications/knative_spec.rb
index b14161ce8e6..41b4ec86233 100644
--- a/spec/models/clusters/applications/knative_spec.rb
+++ b/spec/models/clusters/applications/knative_spec.rb
@@ -119,7 +119,7 @@ RSpec.describe Clusters::Applications::Knative do
shared_examples 'a command' do
it 'is an instance of Helm::InstallCommand' do
- expect(subject).to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand)
+ expect(subject).to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand)
end
it 'is initialized with knative arguments' do
@@ -171,7 +171,7 @@ RSpec.describe Clusters::Applications::Knative do
describe '#uninstall_command' do
subject { knative.uninstall_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::DeleteCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand) }
it "removes knative deployed services before uninstallation" do
2.times do |i|
diff --git a/spec/models/clusters/applications/prometheus_spec.rb b/spec/models/clusters/applications/prometheus_spec.rb
index b450900bee6..032de6aa7c2 100644
--- a/spec/models/clusters/applications/prometheus_spec.rb
+++ b/spec/models/clusters/applications/prometheus_spec.rb
@@ -148,7 +148,7 @@ RSpec.describe Clusters::Applications::Prometheus do
subject { prometheus.install_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
it 'is initialized with 3 arguments' do
expect(subject.name).to eq('prometheus')
@@ -195,7 +195,7 @@ RSpec.describe Clusters::Applications::Prometheus do
subject { prometheus.uninstall_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::DeleteCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand) }
it 'has the application name' do
expect(subject.name).to eq('prometheus')
@@ -236,7 +236,7 @@ RSpec.describe Clusters::Applications::Prometheus do
let(:prometheus) { build(:clusters_applications_prometheus) }
let(:values) { prometheus.values }
- it { is_expected.to be_an_instance_of(::Gitlab::Kubernetes::Helm::PatchCommand) }
+ it { is_expected.to be_an_instance_of(::Gitlab::Kubernetes::Helm::V3::PatchCommand) }
it 'is initialized with 3 arguments' do
expect(patch_command.name).to eq('prometheus')
diff --git a/spec/models/clusters/applications/runner_spec.rb b/spec/models/clusters/applications/runner_spec.rb
index ef916c73e0b..43e2eab3b9d 100644
--- a/spec/models/clusters/applications/runner_spec.rb
+++ b/spec/models/clusters/applications/runner_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe Clusters::Applications::Runner do
subject { gitlab_runner.install_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::InstallCommand) }
it 'is initialized with 4 arguments' do
expect(subject.name).to eq('runner')
diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb
index dd9b96f39ad..ed74a841044 100644
--- a/spec/models/clusters/cluster_spec.rb
+++ b/spec/models/clusters/cluster_spec.rb
@@ -540,6 +540,27 @@ RSpec.describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
end
end
end
+
+ describe 'helm_major_version can only be 2 or 3' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:helm_major_version, :expect_valid) do
+ 2 | true
+ 3 | true
+ 4 | false
+ -1 | false
+ end
+
+ with_them do
+ let(:cluster) { build(:cluster, helm_major_version: helm_major_version) }
+
+ it { is_expected.to eq(expect_valid) }
+ end
+ end
+ end
+
+ it 'has default helm_major_version 3' do
+ expect(create(:cluster).helm_major_version).to eq(3)
end
describe '.ancestor_clusters_for_clusterable' do
diff --git a/spec/requests/api/graphql/project/release_spec.rb b/spec/requests/api/graphql/project/release_spec.rb
index ade7cc177be..57b620dbdf7 100644
--- a/spec/requests/api/graphql/project/release_spec.rb
+++ b/spec/requests/api/graphql/project/release_spec.rb
@@ -189,8 +189,6 @@ RSpec.describe 'Query.project(fullPath).release(tagName)' do
closedMergeRequestsUrl
openedIssuesUrl
closedIssuesUrl
- mergeRequestsUrl
- issuesUrl
})
end
@@ -203,9 +201,7 @@ RSpec.describe 'Query.project(fullPath).release(tagName)' do
'mergedMergeRequestsUrl' => project_merge_requests_url(project, merged_url_params),
'closedMergeRequestsUrl' => project_merge_requests_url(project, closed_url_params),
'openedIssuesUrl' => project_issues_url(project, opened_url_params),
- 'closedIssuesUrl' => project_issues_url(project, closed_url_params),
- 'mergeRequestsUrl' => project_merge_requests_url(project, opened_url_params),
- 'issuesUrl' => project_issues_url(project, opened_url_params)
+ 'closedIssuesUrl' => project_issues_url(project, closed_url_params)
)
end
end
diff --git a/spec/requests/api/graphql/project/releases_spec.rb b/spec/requests/api/graphql/project/releases_spec.rb
index 9288dab3f2e..6e364c7d7b5 100644
--- a/spec/requests/api/graphql/project/releases_spec.rb
+++ b/spec/requests/api/graphql/project/releases_spec.rb
@@ -47,8 +47,6 @@ RSpec.describe 'Query.project(fullPath).releases()' do
closedMergeRequestsUrl
openedIssuesUrl
closedIssuesUrl
- mergeRequestsUrl
- issuesUrl
}
}
}
@@ -115,9 +113,7 @@ RSpec.describe 'Query.project(fullPath).releases()' do
'mergedMergeRequestsUrl' => project_merge_requests_url(project, merged_url_params),
'closedMergeRequestsUrl' => project_merge_requests_url(project, closed_url_params),
'openedIssuesUrl' => project_issues_url(project, opened_url_params),
- 'closedIssuesUrl' => project_issues_url(project, closed_url_params),
- 'mergeRequestsUrl' => project_merge_requests_url(project, opened_url_params),
- 'issuesUrl' => project_issues_url(project, opened_url_params)
+ 'closedIssuesUrl' => project_issues_url(project, closed_url_params)
}
)
end
diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb
index e78d05835f2..f8e4cfbb9e5 100644
--- a/spec/requests/api/releases_spec.rb
+++ b/spec/requests/api/releases_spec.rb
@@ -110,22 +110,6 @@ RSpec.describe API::Releases do
expect(json_response.second['commit_path']).to eq("/#{release_1.project.full_path}/-/commit/#{release_1.commit.id}")
expect(json_response.second['tag_path']).to eq("/#{release_1.project.full_path}/-/tags/#{release_1.tag}")
end
-
- it 'returns the merge requests and issues links, with correct query' do
- get api("/projects/#{project.id}/releases", maintainer)
-
- links = json_response.first['_links']
- release = json_response.first['tag_name']
- expected_query = "release_tag=#{release}&scope=all&state=opened"
- path_base = "/#{project.namespace.path}/#{project.path}"
- mr_uri = URI.parse(links['merge_requests_url'])
- issue_uri = URI.parse(links['issues_url'])
-
- expect(mr_uri.path).to eq("#{path_base}/-/merge_requests")
- expect(issue_uri.path).to eq("#{path_base}/-/issues")
- expect(mr_uri.query).to eq(expected_query)
- expect(issue_uri.query).to eq(expected_query)
- end
end
it 'returns an upcoming_release status for a future release' do
diff --git a/spec/services/clusters/applications/uninstall_service_spec.rb b/spec/services/clusters/applications/uninstall_service_spec.rb
index 50d7e82c47e..bfe38ba670d 100644
--- a/spec/services/clusters/applications/uninstall_service_spec.rb
+++ b/spec/services/clusters/applications/uninstall_service_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Clusters::Applications::UninstallService, '#execute' do
context 'when there are no errors' do
before do
- expect(helm_client).to receive(:uninstall).with(kind_of(Gitlab::Kubernetes::Helm::DeleteCommand))
+ expect(helm_client).to receive(:uninstall).with(kind_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand))
allow(worker_class).to receive(:perform_in).and_return(nil)
end
@@ -36,7 +36,7 @@ RSpec.describe Clusters::Applications::UninstallService, '#execute' do
let(:error) { Kubeclient::HttpError.new(500, 'system failure', nil) }
before do
- expect(helm_client).to receive(:uninstall).with(kind_of(Gitlab::Kubernetes::Helm::DeleteCommand)).and_raise(error)
+ expect(helm_client).to receive(:uninstall).with(kind_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand)).and_raise(error)
end
include_examples 'logs kubernetes errors' do
@@ -58,7 +58,7 @@ RSpec.describe Clusters::Applications::UninstallService, '#execute' do
let(:error) { StandardError.new('something bad happened') }
before do
- expect(helm_client).to receive(:uninstall).with(kind_of(Gitlab::Kubernetes::Helm::DeleteCommand)).and_raise(error)
+ expect(helm_client).to receive(:uninstall).with(kind_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand)).and_raise(error)
end
include_examples 'logs kubernetes errors' do
diff --git a/spec/support/shared_examples/helm_commands_shared_examples.rb b/spec/support/shared_examples/helm_commands_shared_examples.rb
index 0a94c6648cc..64f176c5ae9 100644
--- a/spec/support/shared_examples/helm_commands_shared_examples.rb
+++ b/spec/support/shared_examples/helm_commands_shared_examples.rb
@@ -15,6 +15,18 @@ RSpec.shared_examples 'helm command generator' do
end
RSpec.shared_examples 'helm command' do
+ describe 'HELM_VERSION' do
+ subject { command.class::HELM_VERSION }
+
+ it { is_expected.to match(/\d+\.\d+\.\d+/) }
+ end
+
+ describe '#env' do
+ subject { command.env }
+
+ it { is_expected.to be_a Hash }
+ end
+
describe '#rbac?' do
subject { command.rbac? }
diff --git a/spec/support/shared_examples/models/cluster_application_core_shared_examples.rb b/spec/support/shared_examples/models/cluster_application_core_shared_examples.rb
index 85a7c90ee42..51071ae47c3 100644
--- a/spec/support/shared_examples/models/cluster_application_core_shared_examples.rb
+++ b/spec/support/shared_examples/models/cluster_application_core_shared_examples.rb
@@ -25,4 +25,21 @@ RSpec.shared_examples 'cluster application core specs' do |application_name|
describe '.association_name' do
it { expect(described_class.association_name).to eq(:"application_#{subject.name}") }
end
+
+ describe '#helm_command_module' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:helm_major_version, :expected_helm_command_module) do
+ 2 | Gitlab::Kubernetes::Helm::V2
+ 3 | Gitlab::Kubernetes::Helm::V3
+ end
+
+ with_them do
+ subject { described_class.new(cluster: cluster).helm_command_module }
+
+ let(:cluster) { build(:cluster, helm_major_version: helm_major_version)}
+
+ it { is_expected.to eq(expected_helm_command_module) }
+ end
+ end
end
diff --git a/spec/support/shared_examples/models/cluster_application_helm_cert_shared_examples.rb b/spec/support/shared_examples/models/cluster_application_helm_cert_shared_examples.rb
index ac8022a4726..187a44ec3cd 100644
--- a/spec/support/shared_examples/models/cluster_application_helm_cert_shared_examples.rb
+++ b/spec/support/shared_examples/models/cluster_application_helm_cert_shared_examples.rb
@@ -6,7 +6,7 @@ RSpec.shared_examples 'cluster application helm specs' do |application_name|
describe '#uninstall_command' do
subject { application.uninstall_command }
- it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::DeleteCommand) }
+ it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::V3::DeleteCommand) }
it 'has files' do
expect(subject.files).to eq(application.files)