diff --git a/app/assets/images/cluster_app_logos/cert_manager.png b/app/assets/images/cluster_app_logos/cert_manager.png new file mode 100644 index 0000000000000000000000000000000000000000..bbc867858daa7cb5556eb21854e3cab56541ef35 Binary files /dev/null and b/app/assets/images/cluster_app_logos/cert_manager.png differ diff --git a/app/assets/javascripts/clusters/clusters_bundle.js b/app/assets/javascripts/clusters/clusters_bundle.js index 71fc2ac7d801c7c95e4f3b98cf2e55ae315d09df..cf70a48f076aab4ab412401652e1d4e6fed5cf1c 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 0d2e7c3e356d83371c8dedb1087766e5ac16ba36..fcdbffbc8b86b4e6fc1d9b94cd14ecf95c6622bc 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 {

`; }, + 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: ` + ${_.escape(s__("ClusterIntegration|Let's Encrypt"))}`, + }, + false, + ); + }, prometheusDescription() { return sprintf( _.escape( @@ -265,6 +284,24 @@ export default {
+ +
+
+
{ "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 0ba056e57d466af3c7505b33bcbddb730785f223..13906c903b9f03c57a7536f2410ef5d712eab58b 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 844807c25813691fef5d8cd2762acac3db2cd495..a89772e82dc99a427d3abd94560a21b7adf51e58 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 8a7f7a5c9788167a09f8fa52afb718d09d1cae38..b1aa8e5d477ca5b9d6d64ffb1b30c3723166707a 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 0000000000000000000000000000000000000000..3f908d01c9f4968809e51739a84d31b3fbca6c17 --- /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 0000000000000000000000000000000000000000..4966b89964a61d24b71d198200737f3994ad6b1f --- /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 cc47368c53080ca0e0f0dae81a3e77feb142c0f2..1fdc417b63995e5b056f104317ecc4ed9d2186f5 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 ca262e4b76ee3d765f6dfff701f2ac6ad62774b4..6735710e2bb24b6566194f361cee268d51606a57 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 961485005f74b4d22f7f0dff2f767cfe3d3e5791..a1ab5e048acc3fbb3f3f34fff079a3d40d79aebb 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 069cd1f802aee5920e14a26b91e4fc8b92d380f8..9bceec749fc2228a9c47b124ec3f915fe53a59a7 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 64c01a7cdc409f18a70d53eaddf656d50c7d952d..3a8716b04e7e795524ea52db8c33bbaba23706d8 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 ff65c76cf26294d9d46ff710254075c3f11f60c3..7fc3d16e864f6793d9c5c1d911982aa25c2a2033 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 0e2cc13fa5244ace947f5f0201922f8a83c7083b..928bf70f3a2e1fb227e2345cac89bb15142033c7 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 73abf6504c0a5ab9f57617dba56d3955844629cd..540d7f30858438fbce42357693c8fe6f7f172a5e 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 34ed36afa5b377da8e398a8c7cdc805c55ee3423..6a08d08f33ebe7bfba1c3112a5c3dd0eff22d635 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 39852b7fe2980ccbc82b7ce851cce4061f976216..82ed4d47857afc2e1edec48d7d91ff41f636ed8d 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 b212d2b05f2357593369cb784ab8969eeb92fc26..5390f2370733f9f1be9c01fb381b486062331d26 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 0000000000000000000000000000000000000000..170c6001eaff658c495b9353180a92bad6666e68 --- /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 98d7e799d67fb735eca29b8648d60e63b097c274..eb68ebccdcbe8c7f4b52458928be319041aaabb3 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 0000000000000000000000000000000000000000..23fa6eff4b2bf63483b4ea62424b4d605f2404fd --- /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 0000000000000000000000000000000000000000..4515e3e39c775519e3d51b61bad73410711b9baf --- /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"