diff options
26 files changed, 315 insertions, 11 deletions
diff --git a/app/assets/images/cluster_app_logos/cert_manager.png b/app/assets/images/cluster_app_logos/cert_manager.png Binary files differnew file mode 100644 index 00000000000..bbc867858da --- /dev/null +++ b/app/assets/images/cluster_app_logos/cert_manager.png diff --git a/app/assets/javascripts/clusters/clusters_bundle.js b/app/assets/javascripts/clusters/clusters_bundle.js index 71fc2ac7d80..cf70a48f076 100644 --- a/app/assets/javascripts/clusters/clusters_bundle.js +++ b/app/assets/javascripts/clusters/clusters_bundle.js @@ -26,6 +26,7 @@ export default class Clusters { statusPath, installHelmPath, installIngressPath, + installCertManagerPath, installRunnerPath, installJupyterPath, installKnativePath, @@ -48,6 +49,7 @@ export default class Clusters { endpoint: statusPath, installHelmEndpoint: installHelmPath, installIngressEndpoint: installIngressPath, + installCertManagerEndpoint: installCertManagerPath, installRunnerEndpoint: installRunnerPath, installPrometheusEndpoint: installPrometheusPath, installJupyterEndpoint: installJupyterPath, diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue index 0d2e7c3e356..fcdbffbc8b8 100644 --- a/app/assets/javascripts/clusters/components/applications.vue +++ b/app/assets/javascripts/clusters/components/applications.vue @@ -7,6 +7,7 @@ import helmLogo from 'images/cluster_app_logos/helm.png'; import jeagerLogo from 'images/cluster_app_logos/jeager.png'; import jupyterhubLogo from 'images/cluster_app_logos/jupyterhub.png'; import kubernetesLogo from 'images/cluster_app_logos/kubernetes.png'; +import certManagerLogo from 'images/cluster_app_logos/cert_manager.png'; import knativeLogo from 'images/cluster_app_logos/knative.png'; import meltanoLogo from 'images/cluster_app_logos/meltano.png'; import prometheusLogo from 'images/cluster_app_logos/prometheus.png'; @@ -59,6 +60,7 @@ export default { jeagerLogo, jupyterhubLogo, kubernetesLogo, + certManagerLogo, knativeLogo, meltanoLogo, prometheusLogo, @@ -124,6 +126,23 @@ export default { </p> `; }, + certManagerDescription() { + return sprintf( + _.escape( + s__( + `ClusterIntegration|cert-manager is a native Kubernetes certificate management controller that helps with issuing certificates. + Installing cert-manager on your cluster will issue a certificate by %{letsEncrypt} and ensure that certificates + are valid and up to date.`, + ), + ), + { + letsEncrypt: `<a href="https://letsencrypt.org/" + target="_blank" rel="noopener noreferrer"> + ${_.escape(s__("ClusterIntegration|Let's Encrypt"))}</a>`, + }, + false, + ); + }, prometheusDescription() { return sprintf( _.escape( @@ -266,6 +285,24 @@ export default { </div> </application-row> <application-row + id="cert_manager" + :logo-url="certManagerLogo" + :title="applications.cert_manager.title" + :status="applications.cert_manager.status" + :status-reason="applications.cert_manager.statusReason" + :request-status="applications.cert_manager.requestStatus" + :request-reason="applications.cert_manager.requestReason" + :disabled="!helmInstalled" + class="hide-bottom-border rounded-bottom" + title-link="https://cert-manager.readthedocs.io/en/latest/#" + > + <div + slot="description" + v-html="certManagerDescription" + > + </div> + </application-row> + <application-row v-if="isProjectCluster" id="prometheus" :logo-url="prometheusLogo" diff --git a/app/assets/javascripts/clusters/services/clusters_service.js b/app/assets/javascripts/clusters/services/clusters_service.js index da562b09ee5..89dda4b7902 100644 --- a/app/assets/javascripts/clusters/services/clusters_service.js +++ b/app/assets/javascripts/clusters/services/clusters_service.js @@ -6,6 +6,7 @@ export default class ClusterService { this.appInstallEndpointMap = { helm: this.options.installHelmEndpoint, ingress: this.options.installIngressEndpoint, + cert_manager: this.options.installCertManagerEndpoint, runner: this.options.installRunnerEndpoint, prometheus: this.options.installPrometheusEndpoint, jupyter: this.options.installJupyterEndpoint, diff --git a/app/assets/javascripts/clusters/stores/clusters_store.js b/app/assets/javascripts/clusters/stores/clusters_store.js index e45da967392..3678be59d24 100644 --- a/app/assets/javascripts/clusters/stores/clusters_store.js +++ b/app/assets/javascripts/clusters/stores/clusters_store.js @@ -24,6 +24,13 @@ export default class ClusterStore { requestReason: null, externalIp: null, }, + cert_manager: { + title: s__('ClusterIntegration|Cert-Manager'), + status: null, + statusReason: null, + requestStatus: null, + requestReason: null, + }, runner: { title: s__('ClusterIntegration|GitLab Runner'), status: null, diff --git a/app/models/clusters/applications/cert_manager.rb b/app/models/clusters/applications/cert_manager.rb new file mode 100644 index 00000000000..077e2bda143 --- /dev/null +++ b/app/models/clusters/applications/cert_manager.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module Clusters + module Applications + class CertManager < ActiveRecord::Base + VERSION = 'v0.5.0'.freeze + + self.table_name = 'clusters_applications_cert_managers' + + include ::Clusters::Concerns::ApplicationCore + include ::Clusters::Concerns::ApplicationStatus + include ::Clusters::Concerns::ApplicationVersion + include ::Clusters::Concerns::ApplicationData + + default_value_for :version, VERSION + + validates :email, presence: true + + def chart + 'stable/cert-manager' + end + + def install_command + Gitlab::Kubernetes::Helm::InstallCommand.new( + name: 'certmanager', + version: VERSION, + rbac: cluster.platform_kubernetes_rbac?, + chart: chart, + files: files.merge(cluster_issuer_file), + postinstall: post_install_script + ) + end + + private + + def post_install_script + ["/usr/bin/kubectl create -f /data/helm/certmanager/config/cluster_issuer.yaml"] + end + + def cluster_issuer_file + { + 'cluster_issuer.yaml': cluster_issuer_yaml_content + } + end + + def cluster_issuer_yaml_content + YAML.dump(cluster_issuer_content.deep_merge(cluster_issue_overlay)) + end + + def cluster_issuer_content + YAML.safe_load(File.read(cluster_issuer_file_path)) + end + + def cluster_issue_overlay + { "spec" => { "acme" => { "email" => self.email } } } + end + + def cluster_issuer_file_path + Rails.root.join('vendor', 'cert_manager', 'cluster_issuer.yaml') + end + end + end +end diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb index 0ba056e57d4..13906c903b9 100644 --- a/app/models/clusters/cluster.rb +++ b/app/models/clusters/cluster.rb @@ -10,6 +10,7 @@ module Clusters APPLICATIONS = { Applications::Helm.application_name => Applications::Helm, Applications::Ingress.application_name => Applications::Ingress, + Applications::CertManager.application_name => Applications::CertManager, Applications::Prometheus.application_name => Applications::Prometheus, Applications::Runner.application_name => Applications::Runner, Applications::Jupyter.application_name => Applications::Jupyter, @@ -33,6 +34,7 @@ module Clusters has_one :application_helm, class_name: 'Clusters::Applications::Helm' has_one :application_ingress, class_name: 'Clusters::Applications::Ingress' + has_one :application_cert_manager, class_name: 'Clusters::Applications::CertManager' has_one :application_prometheus, class_name: 'Clusters::Applications::Prometheus' has_one :application_runner, class_name: 'Clusters::Applications::Runner' has_one :application_jupyter, class_name: 'Clusters::Applications::Jupyter' @@ -100,6 +102,7 @@ module Clusters [ application_helm || build_application_helm, application_ingress || build_application_ingress, + application_cert_manager || build_application_cert_manager, application_prometheus || build_application_prometheus, application_runner || build_application_runner, application_jupyter || build_application_jupyter, diff --git a/app/services/clusters/applications/create_service.rb b/app/services/clusters/applications/create_service.rb index 844807c2581..a89772e82dc 100644 --- a/app/services/clusters/applications/create_service.rb +++ b/app/services/clusters/applications/create_service.rb @@ -19,6 +19,10 @@ module Clusters application.hostname = params[:hostname] end + if application.has_attribute?(:email) + application.email = current_user.email + end + if application.respond_to?(:oauth_application) application.oauth_application = create_oauth_application(application, request) end @@ -42,7 +46,8 @@ module Clusters def builders { "helm" => -> (cluster) { cluster.application_helm || cluster.build_application_helm }, - "ingress" => -> (cluster) { cluster.application_ingress || cluster.build_application_ingress } + "ingress" => -> (cluster) { cluster.application_ingress || cluster.build_application_ingress }, + "cert_manager" => -> (cluster) { cluster.application_cert_manager || cluster.build_application_cert_manager } }.tap do |hash| hash.merge!(project_builders) if cluster.project_type? end diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml index 8a7f7a5c978..b1aa8e5d477 100644 --- a/app/views/clusters/clusters/show.html.haml +++ b/app/views/clusters/clusters/show.html.haml @@ -10,6 +10,7 @@ .edit-cluster-form.js-edit-cluster-form{ data: { status_path: status_path, install_helm_path: clusterable.install_applications_cluster_path(@cluster, :helm), install_ingress_path: clusterable.install_applications_cluster_path(@cluster, :ingress), + install_cert_manager_path: clusterable.install_applications_cluster_path(@cluster, :cert_manager), install_prometheus_path: clusterable.install_applications_cluster_path(@cluster, :prometheus), install_runner_path: clusterable.install_applications_cluster_path(@cluster, :runner), install_jupyter_path: clusterable.install_applications_cluster_path(@cluster, :jupyter), diff --git a/changelogs/unreleased/certmanager-temp.yml b/changelogs/unreleased/certmanager-temp.yml new file mode 100644 index 00000000000..3f908d01c9f --- /dev/null +++ b/changelogs/unreleased/certmanager-temp.yml @@ -0,0 +1,5 @@ +--- +title: "#40635: Adds support for cert-manager" +merge_request: 23036 +author: Amit Rathi +type: added diff --git a/db/migrate/20181101191341_create_clusters_applications_cert_manager.rb b/db/migrate/20181101191341_create_clusters_applications_cert_manager.rb new file mode 100644 index 00000000000..4966b89964a --- /dev/null +++ b/db/migrate/20181101191341_create_clusters_applications_cert_manager.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class CreateClustersApplicationsCertManager < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + create_table :clusters_applications_cert_managers do |t| + t.references :cluster, null: false, index: false, foreign_key: { on_delete: :cascade } + t.integer :status, null: false + t.string :version, null: false + t.string :email, null: false + t.timestamps_with_timezone null: false + t.text :status_reason + t.index :cluster_id, unique: true + end + end +end diff --git a/db/schema.rb b/db/schema.rb index cc47368c530..1fdc417b639 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -640,6 +640,17 @@ ActiveRecord::Schema.define(version: 20181112103239) do t.index ["user_id"], name: "index_clusters_on_user_id", using: :btree end + create_table "clusters_applications_cert_managers", force: :cascade do |t| + t.integer "cluster_id", null: false + t.integer "status", null: false + t.string "version", null: false + t.string "email", null: false + t.datetime_with_timezone "created_at", null: false + t.datetime_with_timezone "updated_at", null: false + t.text "status_reason" + t.index ["cluster_id"], name: "index_clusters_applications_cert_managers_on_cluster_id", unique: true, using: :btree + end + create_table "clusters_applications_helm", force: :cascade do |t| t.integer "cluster_id", null: false t.datetime_with_timezone "created_at", null: false @@ -2288,6 +2299,7 @@ ActiveRecord::Schema.define(version: 20181112103239) do add_foreign_key "cluster_projects", "projects", on_delete: :cascade add_foreign_key "cluster_providers_gcp", "clusters", on_delete: :cascade add_foreign_key "clusters", "users", on_delete: :nullify + add_foreign_key "clusters_applications_cert_managers", "clusters", on_delete: :cascade add_foreign_key "clusters_applications_helm", "clusters", on_delete: :cascade add_foreign_key "clusters_applications_ingress", "clusters", name: "fk_753a7b41c1", on_delete: :cascade add_foreign_key "clusters_applications_jupyter", "clusters", on_delete: :cascade diff --git a/doc/user/project/clusters/index.md b/doc/user/project/clusters/index.md index ca262e4b76e..6735710e2bb 100644 --- a/doc/user/project/clusters/index.md +++ b/doc/user/project/clusters/index.md @@ -225,6 +225,7 @@ twice, which can lead to confusion during deployments. | ----------- | :------------: | ----------- | --------------- | | [Helm Tiller](https://docs.helm.sh/) | 10.2+ | Helm is a package manager for Kubernetes and is required to install all the other applications. It is installed in its own pod inside the cluster which can run the `helm` CLI in a safe environment. | n/a | | [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) | 10.2+ | Ingress can provide load balancing, SSL termination, and name-based virtual hosting. It acts as a web proxy for your applications and is useful if you want to use [Auto DevOps] or deploy your own web apps. | [stable/nginx-ingress](https://github.com/helm/charts/tree/master/stable/nginx-ingress) | +| [Cert Manager](http://docs.cert-manager.io/en/latest/) | 11.6+ | Cert Manager is a native Kubernetes certificate management controller that helps with issuing certificates. Installing Cert Manager on your cluster will issue a certificate by [Let's Encrypt](https://letsencrypt.org/) and ensure that certificates are valid and up to date. The email address used by Let's Encrypt registration will be taken from the GitLab user that installed Cert Manager on the cluster. | [stable/cert-manager](https://github.com/helm/charts/tree/master/stable/cert-manager) | | [Prometheus](https://prometheus.io/docs/introduction/overview/) | 10.4+ | Prometheus is an open-source monitoring and alerting system useful to supervise your deployed applications. | [stable/prometheus](https://github.com/helm/charts/tree/master/stable/prometheus) | | [GitLab Runner](https://docs.gitlab.com/runner/) | 10.6+ | GitLab Runner is the open source project that is used to run your jobs and send the results back to GitLab. It is used in conjunction with [GitLab CI/CD](https://about.gitlab.com/features/gitlab-ci-cd/), the open-source continuous integration service included with GitLab that coordinates the jobs. When installing the GitLab Runner via the applications, it will run in **privileged mode** by default. Make sure you read the [security implications](#security-implications) before doing so. | [runner/gitlab-runner](https://gitlab.com/charts/gitlab-runner) | | [JupyterHub](http://jupyter.org/) | 11.0+ | [JupyterHub](https://jupyterhub.readthedocs.io/en/stable/) is a multi-user service for managing notebooks across a team. [Jupyter Notebooks](https://jupyter-notebook.readthedocs.io/en/latest/) provide a web-based interactive programming environment used for data analysis, visualization, and machine learning. We use [this](https://gitlab.com/gitlab-org/jupyterhub-user-image/blob/master/Dockerfile) custom Jupyter image that installs additional useful packages on top of the base Jupyter. You will also see ready-to-use DevOps Runbooks built with Nurtch's [Rubix library](https://github.com/amit1rrr/rubix). More information on creating executable runbooks can be found at [Nurtch Documentation](http://docs.nurtch.com/en/latest). **Note**: Authentication will be enabled for any user of the GitLab server via OAuth2. HTTPS will be supported in a future release. | [jupyter/jupyterhub](https://jupyterhub.github.io/helm-chart/) | diff --git a/lib/gitlab/kubernetes/helm/install_command.rb b/lib/gitlab/kubernetes/helm/install_command.rb index 961485005f7..a1ab5e048ac 100644 --- a/lib/gitlab/kubernetes/helm/install_command.rb +++ b/lib/gitlab/kubernetes/helm/install_command.rb @@ -64,17 +64,17 @@ module Gitlab name_flag + optional_tls_flags + optional_version_flag + - optional_rbac_create_flag + + rbac_create_flag + namespace_flag + value_flag end - def optional_rbac_create_flag - return [] unless rbac? - - # jupyterhub helm chart is using rbac.enabled - # https://github.com/jupyterhub/zero-to-jupyterhub-k8s/tree/master/jupyterhub - %w[--set rbac.create=true,rbac.enabled=true] + 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 diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb index 069cd1f802a..9bceec749fc 100644 --- a/lib/gitlab/usage_data.rb +++ b/lib/gitlab/usage_data.rb @@ -60,6 +60,7 @@ module Gitlab clusters_platforms_user: count(::Clusters::Cluster.user_provided.enabled), clusters_applications_helm: count(::Clusters::Applications::Helm.installed), clusters_applications_ingress: count(::Clusters::Applications::Ingress.installed), + clusters_applications_cert_managers: count(::Clusters::Applications::CertManager.installed), clusters_applications_prometheus: count(::Clusters::Applications::Prometheus.installed), clusters_applications_runner: count(::Clusters::Applications::Runner.installed), clusters_applications_knative: count(::Clusters::Applications::Knative.installed), diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 64c01a7cdc4..3a8716b04e7 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -1415,6 +1415,9 @@ msgstr "" msgid "ClusterIntegration|CA Certificate" msgstr "" +msgid "ClusterIntegration|Cert-Manager" +msgstr "" + msgid "ClusterIntegration|Certificate Authority bundle (PEM format)" msgstr "" @@ -1574,6 +1577,9 @@ msgstr "" msgid "ClusterIntegration|Learn more about group Kubernetes clusters" msgstr "" +msgid "ClusterIntegration|Let's Encrypt" +msgstr "" + msgid "ClusterIntegration|Machine type" msgstr "" @@ -1736,6 +1742,9 @@ msgstr "" msgid "ClusterIntegration|access to Google Kubernetes Engine" msgstr "" +msgid "ClusterIntegration|cert-manager is a native Kubernetes certificate management controller that helps with issuing certificates. Installing cert-manager on your cluster will issue a certificate by %{letsEncrypt} and ensure that certificates are valid and up to date." +msgstr "" + msgid "ClusterIntegration|check the pricing here" msgstr "" diff --git a/spec/factories/clusters/applications/helm.rb b/spec/factories/clusters/applications/helm.rb index ff65c76cf26..7fc3d16e864 100644 --- a/spec/factories/clusters/applications/helm.rb +++ b/spec/factories/clusters/applications/helm.rb @@ -49,6 +49,11 @@ FactoryBot.define do cluster factory: %i(cluster with_installed_helm provided_by_gcp) end + factory :clusters_applications_cert_managers, class: Clusters::Applications::CertManager do + email 'admin@example.com' + cluster factory: %i(cluster with_installed_helm provided_by_gcp) + end + factory :clusters_applications_prometheus, class: Clusters::Applications::Prometheus do cluster factory: %i(cluster with_installed_helm provided_by_gcp) end diff --git a/spec/javascripts/clusters/components/applications_spec.js b/spec/javascripts/clusters/components/applications_spec.js index 0e2cc13fa52..928bf70f3a2 100644 --- a/spec/javascripts/clusters/components/applications_spec.js +++ b/spec/javascripts/clusters/components/applications_spec.js @@ -20,6 +20,7 @@ describe('Applications', () => { applications: { helm: { title: 'Helm Tiller' }, ingress: { title: 'Ingress' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub' }, @@ -36,6 +37,10 @@ describe('Applications', () => { expect(vm.$el.querySelector('.js-cluster-application-row-ingress')).toBeDefined(); }); + it('renders a row for Cert-Manager', () => { + expect(vm.$el.querySelector('.js-cluster-application-row-cert_manager')).toBeDefined(); + }); + it('renders a row for Prometheus', () => { expect(vm.$el.querySelector('.js-cluster-application-row-prometheus')).toBeDefined(); }); @@ -65,6 +70,7 @@ describe('Applications', () => { externalIp: '0.0.0.0', }, helm: { title: 'Helm Tiller' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', hostname: '' }, @@ -89,6 +95,7 @@ describe('Applications', () => { status: 'installed', }, helm: { title: 'Helm Tiller' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', hostname: '' }, @@ -109,6 +116,7 @@ describe('Applications', () => { applications: { helm: { title: 'Helm Tiller' }, ingress: { title: 'Ingress' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', hostname: '' }, @@ -128,6 +136,7 @@ describe('Applications', () => { applications: { helm: { title: 'Helm Tiller', status: 'installed' }, ingress: { title: 'Ingress', status: 'installed', externalIp: '1.1.1.1' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', hostname: '', status: 'installable' }, @@ -145,6 +154,7 @@ describe('Applications', () => { applications: { helm: { title: 'Helm Tiller', status: 'installed' }, ingress: { title: 'Ingress', status: 'installed' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', hostname: '', status: 'installable' }, @@ -162,6 +172,7 @@ describe('Applications', () => { applications: { helm: { title: 'Helm Tiller', status: 'installed' }, ingress: { title: 'Ingress', status: 'installed', externalIp: '1.1.1.1' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', status: 'installed', hostname: '' }, @@ -179,6 +190,7 @@ describe('Applications', () => { applications: { helm: { title: 'Helm Tiller' }, ingress: { title: 'Ingress' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', status: 'not_installable' }, diff --git a/spec/javascripts/clusters/services/mock_data.js b/spec/javascripts/clusters/services/mock_data.js index 73abf6504c0..540d7f30858 100644 --- a/spec/javascripts/clusters/services/mock_data.js +++ b/spec/javascripts/clusters/services/mock_data.js @@ -38,6 +38,11 @@ const CLUSTERS_MOCK_DATA = { status: APPLICATION_STATUS.INSTALLING, status_reason: 'Cannot connect', }, + { + name: 'cert_manager', + status: APPLICATION_STATUS.ERROR, + status_reason: 'Cannot connect', + }, ], }, }, @@ -77,6 +82,11 @@ const CLUSTERS_MOCK_DATA = { status: APPLICATION_STATUS.INSTALLABLE, status_reason: 'Cannot connect', }, + { + name: 'cert_manager', + status: APPLICATION_STATUS.ERROR, + status_reason: 'Cannot connect', + }, ], }, }, @@ -84,6 +94,7 @@ const CLUSTERS_MOCK_DATA = { POST: { '/gitlab-org/gitlab-shell/clusters/1/applications/helm': {}, '/gitlab-org/gitlab-shell/clusters/1/applications/ingress': {}, + '/gitlab-org/gitlab-shell/clusters/1/applications/cert_manager': {}, '/gitlab-org/gitlab-shell/clusters/1/applications/runner': {}, '/gitlab-org/gitlab-shell/clusters/1/applications/prometheus': {}, '/gitlab-org/gitlab-shell/clusters/1/applications/jupyter': {}, diff --git a/spec/javascripts/clusters/stores/clusters_store_spec.js b/spec/javascripts/clusters/stores/clusters_store_spec.js index 34ed36afa5b..6a08d08f33e 100644 --- a/spec/javascripts/clusters/stores/clusters_store_spec.js +++ b/spec/javascripts/clusters/stores/clusters_store_spec.js @@ -108,6 +108,13 @@ describe('Clusters Store', () => { requestReason: null, hostname: null, }, + cert_manager: { + title: 'Cert-Manager', + status: mockResponseData.applications[6].status, + statusReason: mockResponseData.applications[6].status_reason, + requestStatus: null, + requestReason: null, + }, }, }); }); diff --git a/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb index 39852b7fe29..82ed4d47857 100644 --- a/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb +++ b/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb @@ -43,6 +43,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem --version 1.2.3 + --set rbac.create\\=false,rbac.enabled\\=false --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml EOS @@ -101,6 +102,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem --version 1.2.3 + --set rbac.create\\=false,rbac.enabled\\=false --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml EOS @@ -126,7 +128,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do <<~EOS.strip /bin/date /bin/true - helm install chart-name --name app-name --tls --tls-ca-cert /data/helm/app-name/config/ca.pem --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem --version 1.2.3 --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml + helm install chart-name --name app-name --tls --tls-ca-cert /data/helm/app-name/config/ca.pem --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem --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 @@ -148,7 +150,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do let(:helm_install_command) do <<~EOS.strip - helm install chart-name --name app-name --tls --tls-ca-cert /data/helm/app-name/config/ca.pem --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem --version 1.2.3 --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml + helm install chart-name --name app-name --tls --tls-ca-cert /data/helm/app-name/config/ca.pem --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem --version 1.2.3 --set rbac.create\\=false,rbac.enabled\\=false --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml /bin/date /bin/false EOS @@ -175,6 +177,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do helm install chart-name --name app-name --version 1.2.3 + --set rbac.create\\=false,rbac.enabled\\=false --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml EOS @@ -204,6 +207,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do --tls-ca-cert /data/helm/app-name/config/ca.pem --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem + --set rbac.create\\=false,rbac.enabled\\=false --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml EOS diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index b212d2b05f2..5390f237073 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -19,6 +19,7 @@ describe Gitlab::UsageData do create(:cluster, :provided_by_user, :disabled) create(:clusters_applications_helm, :installed, cluster: gcp_cluster) create(:clusters_applications_ingress, :installed, cluster: gcp_cluster) + create(:clusters_applications_cert_managers, :installed, cluster: gcp_cluster) create(:clusters_applications_prometheus, :installed, cluster: gcp_cluster) create(:clusters_applications_runner, :installed, cluster: gcp_cluster) create(:clusters_applications_knative, :installed, cluster: gcp_cluster) @@ -81,6 +82,7 @@ describe Gitlab::UsageData do clusters_platforms_user clusters_applications_helm clusters_applications_ingress + clusters_applications_cert_managers clusters_applications_prometheus clusters_applications_runner clusters_applications_knative @@ -131,6 +133,7 @@ describe Gitlab::UsageData do expect(count_data[:clusters_platforms_user]).to eq(1) expect(count_data[:clusters_applications_helm]).to eq(1) expect(count_data[:clusters_applications_ingress]).to eq(1) + expect(count_data[:clusters_applications_cert_managers]).to eq(1) expect(count_data[:clusters_applications_prometheus]).to eq(1) expect(count_data[:clusters_applications_runner]).to eq(1) expect(count_data[:clusters_applications_knative]).to eq(1) diff --git a/spec/models/clusters/applications/cert_manager_spec.rb b/spec/models/clusters/applications/cert_manager_spec.rb new file mode 100644 index 00000000000..170c6001eaf --- /dev/null +++ b/spec/models/clusters/applications/cert_manager_spec.rb @@ -0,0 +1,79 @@ +require 'rails_helper' + +describe Clusters::Applications::CertManager do + let(:cert_manager) { create(:clusters_applications_cert_managers) } + + include_examples 'cluster application core specs', :clusters_applications_cert_managers + + describe '#make_installing!' do + before do + application.make_installing! + end + + context 'application install previously errored with older version' do + let(:application) { create(:clusters_applications_cert_managers, :scheduled, version: 'v0.4.0') } + + it 'updates the application version' do + expect(application.reload.version).to eq('v0.5.0') + end + end + end + + describe '#install_command' do + let(:cluster_issuer_file) { { "cluster_issuer.yaml": "---\napiVersion: certmanager.k8s.io/v1alpha1\nkind: ClusterIssuer\nmetadata:\n name: letsencrypt-prod\nspec:\n acme:\n server: https://acme-v02.api.letsencrypt.org/directory\n email: admin@example.com\n privateKeySecretRef:\n name: letsencrypt-prod\n http01: {}\n" } } + subject { cert_manager.install_command } + + it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) } + + it 'should be initialized with cert_manager arguments' do + expect(subject.name).to eq('certmanager') + expect(subject.chart).to eq('stable/cert-manager') + expect(subject.version).to eq('v0.5.0') + expect(subject).not_to be_rbac + expect(subject.files).to eq(cert_manager.files.merge(cluster_issuer_file)) + expect(subject.postinstall).to eq(['/usr/bin/kubectl create -f /data/helm/certmanager/config/cluster_issuer.yaml']) + end + + context 'for a specific user' do + before do + cert_manager.email = 'abc@xyz.com' + cluster_issuer_file[:'cluster_issuer.yaml'].gsub! 'admin@example.com', 'abc@xyz.com' + end + + it 'should use his/her email to register issuer with certificate provider' do + expect(subject.files).to eq(cert_manager.files.merge(cluster_issuer_file)) + end + end + + context 'on a rbac enabled cluster' do + before do + cert_manager.cluster.platform_kubernetes.rbac! + end + + it { is_expected.to be_rbac } + end + + context 'application failed to install previously' do + let(:cert_manager) { create(:clusters_applications_cert_managers, :errored, version: '0.0.1') } + + it 'should be initialized with the locked version' do + expect(subject.version).to eq('v0.5.0') + end + end + end + + describe '#files' do + let(:application) { cert_manager } + let(:values) { subject[:'values.yaml'] } + + subject { application.files } + + it 'should include cert_manager specific keys in the values.yaml file' do + expect(values).to include('ingressShim') + end + end + + describe 'validations' do + it { is_expected.to validate_presence_of(:email) } + end +end diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb index 98d7e799d67..eb68ebccdcb 100644 --- a/spec/models/clusters/cluster_spec.rb +++ b/spec/models/clusters/cluster_spec.rb @@ -311,13 +311,14 @@ describe Clusters::Cluster do context 'when applications are created' do let!(:helm) { create(:clusters_applications_helm, cluster: cluster) } let!(:ingress) { create(:clusters_applications_ingress, cluster: cluster) } + let!(:cert_manager) { create(:clusters_applications_cert_managers, cluster: cluster) } let!(:prometheus) { create(:clusters_applications_prometheus, cluster: cluster) } let!(:runner) { create(:clusters_applications_runner, cluster: cluster) } let!(:jupyter) { create(:clusters_applications_jupyter, cluster: cluster) } let!(:knative) { create(:clusters_applications_knative, cluster: cluster) } it 'returns a list of created applications' do - is_expected.to contain_exactly(helm, ingress, prometheus, runner, jupyter, knative) + is_expected.to contain_exactly(helm, ingress, cert_manager, prometheus, runner, jupyter, knative) end end end diff --git a/vendor/cert_manager/cluster_issuer.yaml b/vendor/cert_manager/cluster_issuer.yaml new file mode 100644 index 00000000000..23fa6eff4b2 --- /dev/null +++ b/vendor/cert_manager/cluster_issuer.yaml @@ -0,0 +1,11 @@ +apiVersion: certmanager.k8s.io/v1alpha1 +kind: ClusterIssuer +metadata: + name: letsencrypt-prod +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + email: my-email@example.com + privateKeySecretRef: + name: letsencrypt-prod + http01: {} diff --git a/vendor/cert_manager/values.yaml b/vendor/cert_manager/values.yaml new file mode 100644 index 00000000000..4515e3e39c7 --- /dev/null +++ b/vendor/cert_manager/values.yaml @@ -0,0 +1,5 @@ +# These options provide fully automated TLS. +# See https://github.com/jetstack/cert-manager/blob/master/docs/reference/ingress-shim.rst#configuration +ingressShim: + defaultIssuerKind: "ClusterIssuer" + defaultIssuerName: "letsencrypt-prod" |