diff --git a/charts/shield/Chart.yaml b/charts/shield/Chart.yaml index 9b315199c..013117c9f 100644 --- a/charts/shield/Chart.yaml +++ b/charts/shield/Chart.yaml @@ -13,5 +13,5 @@ maintainers: - name: mavimo email: marcovito.moscaritolo@sysdig.com type: application -version: 1.21.2 +version: 1.22.0 appVersion: "1.0.0" diff --git a/charts/shield/README.md b/charts/shield/README.md index 0ec3474a9..d47df3601 100644 --- a/charts/shield/README.md +++ b/charts/shield/README.md @@ -219,6 +219,17 @@ The following table lists the configurable parameters of the `shield` chart and | cluster.validatingwebhookconfiguration.create | Create the validatingwebhookconfiguration resources for the cluster shield | true | | cluster.tls_certificates.create | Create the TLS certificates for the cluster shield | true | | cluster.tls_certificates.secret_name | The name of the secret that contains the TLS certificates | | +| cluster.tls_certificates.cert_manager.enabled | Enable cert-manager for certificate management | false | +| cluster.tls_certificates.cert_manager.ca.create | Create the CA certificate using cert-manager | false | +| cluster.tls_certificates.cert_manager.ca.secret_template | The template for the CA certificate secret (if generate is true) will automatically add the annotation `cert-manager.io/allow-direct-injection: "true"` if not present | {} | +| cluster.tls_certificates.cert_manager.ca.secret_name | The name of the existing CA certificate secret (if generate is false) has to be annotated with `cert-manager.io/allow-direct-injection: "true"` | "" | +| cluster.tls_certificates.cert_manager.ca.secret_namespace | The namespace of the existing CA certificate secret (if generate is false) | "" | +| cluster.tls_certificates.cert_manager.issuer.create | Create the Issuer instead of using an existing one | false | +| cluster.tls_certificates.cert_manager.issuer.name | The name of the existing issuer | "" | +| cluster.tls_certificates.cert_manager.issuer.kind | The kind of the existing issuer (Issuer, ClusterIssuer) | Issuer | +| cluster.tls_certificates.cert_manager.issuer.group | The group of the existing issuer | cert-manager.io | +| cluster.tls_certificates.cert_manager.duration | Certificate duration (default: 30 days) | "720h" | +| cluster.tls_certificates.cert_manager.renew_before | How long before expiry to renew (default: 15 days) | "360h" | | cluster.resources.requests.cpu | The CPU request for the cluster shield | 500m | | cluster.resources.requests.memory | The memory request for the cluster shield | 512Mi | | cluster.resources.limits.cpu | The CPU limit for the cluster shield | 1500m | diff --git a/charts/shield/templates/cluster/_tls.tpl b/charts/shield/templates/cluster/_tls.tpl index 4b42ae8fd..bdec4d8ad 100644 --- a/charts/shield/templates/cluster/_tls.tpl +++ b/charts/shield/templates/cluster/_tls.tpl @@ -9,8 +9,10 @@ {{- end }} {{- define "cluster.tls_certificates.secret_name" -}} - {{- if .Values.cluster.tls_certificates.create -}} + {{- if and (.Values.cluster.tls_certificates.create) (not (include "cluster.tls_certificates.use_cert_manager" .)) -}} {{- include "cluster.fullname" . }}-tls-certificates + {{- else if (include "cluster.tls_certificates.use_cert_manager" .) -}} + {{- include "cluster.tls_certificates.cm_certificate_name" . -}} {{- else if .Values.cluster.tls_certificates.secret_name -}} {{- .Values.cluster.tls_certificates.secret_name -}} {{- else -}} @@ -47,3 +49,114 @@ {{- end -}} {{- $dnsNames | toYaml -}} {{- end }} + +{{- define "cluster.tls_certificates.check_conflicts" -}} + {{- if and (not (quote .Values.cluster.tls_certificates.secret_name | empty)) .Values.cluster.tls_certificates.cert_manager.enabled -}} + {{- fail "Cannot specify both tls_certificates.cert_manager.enabled and tls_certificates.secret_name" -}} + {{- end -}} +{{- end }} + +{{- define "cluster.tls_certificates.validate_cert_manager" -}} + {{- if and .Values.cluster.tls_certificates.cert_manager .Values.cluster.tls_certificates.cert_manager.enabled -}} + {{- if and (not .Values.cluster.tls_certificates.cert_manager.ca.create) (not .Values.cluster.tls_certificates.cert_manager.ca.secret_name) -}} + {{- fail "cert_manager.ca.secret_name must be specified when CA generation is disabled" -}} + {{- end -}} + {{- if and (not .Values.cluster.tls_certificates.cert_manager.issuer.create) (not .Values.cluster.tls_certificates.cert_manager.issuer.name) -}} + {{- fail "cert_manager.issuer.name must be specified when Issuer generation is disabled" -}} + {{- end -}} + {{- end -}} +{{- end }} + +{{- define "cluster.tls_certificates.use_cert_manager" -}} + {{- if and .Values.cluster.tls_certificates.cert_manager .Values.cluster.tls_certificates.cert_manager.enabled -}} + {{- true -}} + {{- end -}} +{{- end }} + +{{- define "cluster.tls_certificates.cm_certificate_name" -}} + {{- printf "%s-cm-tls" ((include "cluster.fullname" .) | trimSuffix "-" | trunc 57) -}} +{{- end }} + +{{- define "cluster.tls_certificates.cm_ca_secret_name" -}} + {{- if .Values.cluster.tls_certificates.cert_manager.ca.create -}} + {{- printf "%s-cm-ca" ((include "cluster.fullname" .) | trimSuffix "-" | trunc 58) -}} + {{- else -}} + {{- .Values.cluster.tls_certificates.cert_manager.ca.secret_name -}} + {{- end -}} +{{- end }} + +{{- define "cluster.tls_certificates.cm_generate_ca" -}} + {{- if and (include "cluster.tls_certificates.use_cert_manager" .) (.Values.cluster.tls_certificates.cert_manager.ca.create) -}} + {{- true -}} + {{- end -}} +{{- end }} + +{{- define "cluster.tls_certificates.cm_generate_issuer" -}} + {{- if and (include "cluster.tls_certificates.use_cert_manager" .) (.Values.cluster.tls_certificates.cert_manager.issuer.create) -}} + {{- true -}} + {{- end -}} +{{- end }} + +{{- define "cluster.tls_certificates.cm_issuer_name" -}} + {{- if .Values.cluster.tls_certificates.cert_manager.issuer.create -}} + {{- printf "%s-cm-self-issuer" ((include "cluster.fullname" .) | trimSuffix "-" | trunc 49) -}} + {{- else -}} + {{- .Values.cluster.tls_certificates.cert_manager.issuer.name -}} + {{- end -}} +{{- end }} + +{{- define "cluster.tls_certificates.cm_issuer_namespace" -}} + {{- if .Values.cluster.tls_certificates.cert_manager.issuer.create -}} + {{- if and (not .Values.cluster.tls_certificates.cert_manager.ca.create) (not (empty .Values.cluster.tls_certificates.cert_manager.ca.secret_namespace)) -}} + {{- .Values.cluster.tls_certificates.cert_manager.ca.secret_namespace -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end }} + +{{- define "cluster.tls_certificates.cm_self_ca_cert_name" -}} + {{- printf "%s-cm-self-ca" ((include "cluster.fullname" .) | trimSuffix "-" | trunc 53) -}} +{{- end }} + +{{- define "cluster.tls_certificates.cm_issuer_kind" -}} + {{- if .Values.cluster.tls_certificates.cert_manager.issuer.create -}} + {{- if and (not .Values.cluster.tls_certificates.cert_manager.ca.create) (not (empty .Values.cluster.tls_certificates.cert_manager.ca.secret_namespace)) -}} + {{- "ClusterIssuer" -}} + {{- else -}} + {{- "Issuer" -}} + {{- end -}} + {{- else -}} + {{- .Values.cluster.tls_certificates.cert_manager.issuer.kind -}} + {{- end -}} +{{- end }} + +{{- define "cluster.tls_certificates.cm_issuer_group" -}} + {{- if .Values.cluster.tls_certificates.cert_manager.issuer.create -}} + {{- "cert-manager.io" -}} + {{- else -}} + {{- .Values.cluster.tls_certificates.cert_manager.issuer.group -}} + {{- end -}} +{{- end }} + +{{/* +If we are generating the Issuer we are going to use the CA secret for the inject-ca annotation, +because the Issuer maybe not ready yet. +*/}} +{{- define "cluster.tls_certificates.cm_use_ca_secret" -}} + {{- if (include "cluster.tls_certificates.cm_generate_issuer" .) -}} + {{- true -}} + {{- end -}} +{{- end }} + +{{- define "cluster.tls_certificates.cm_ca_secret_template" -}} + {{- $tmpl := .Values.cluster.tls_certificates.cert_manager.ca.secret_template -}} + {{- $injectAnnotation := "cert-manager.io/allow-direct-injection" -}} + {{- if and (include "cluster.tls_certificates.cm_generate_ca" .) (include "cluster.tls_certificates.cm_generate_issuer" .) -}} + {{- $currentAnnotations := $tmpl.annotations | default (dict) -}} + {{- $_ := set $tmpl "annotations" (merge $currentAnnotations (dict $injectAnnotation "true")) -}} + {{- end -}} + {{- $tmpl | toYaml -}} +{{- end }} diff --git a/charts/shield/templates/cluster/cert-manager-certificate.yaml b/charts/shield/templates/cluster/cert-manager-certificate.yaml new file mode 100644 index 000000000..825dd579d --- /dev/null +++ b/charts/shield/templates/cluster/cert-manager-certificate.yaml @@ -0,0 +1,35 @@ +{{- if (include "cluster.tls_certificates.use_cert_manager" .) }} +{{- include "cluster.tls_certificates.validate_cert_manager" . -}} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "cluster.tls_certificates.cm_certificate_name" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "cluster.labels" . | nindent 4 }} +spec: + secretName: {{ include "cluster.tls_certificates.cm_certificate_name" . }} + privateKey: + algorithm: RSA + encoding: PKCS1 + size: 2048 + issuerRef: + name: {{ include "cluster.tls_certificates.cm_issuer_name" . }} + kind: {{ include "cluster.tls_certificates.cm_issuer_kind" . }} + group: {{ include "cluster.tls_certificates.cm_issuer_group" . }} + duration: {{ .Values.cluster.tls_certificates.cert_manager.duration }} + renewBefore: {{ .Values.cluster.tls_certificates.cert_manager.renew_before }} + subject: + organizations: + - "Sysdig, Inc." + isCA: false + usages: + - server auth + - client auth + commonName: {{ include "cluster.fullname" . }} + dnsNames: + {{- include "cluster.tls_certificates.dns_names" . | nindent 4 }} + ipAddresses: + - "127.0.0.1" +{{- end }} diff --git a/charts/shield/templates/cluster/cert-manager-self-generate.yaml b/charts/shield/templates/cluster/cert-manager-self-generate.yaml new file mode 100644 index 000000000..32d9810ae --- /dev/null +++ b/charts/shield/templates/cluster/cert-manager-self-generate.yaml @@ -0,0 +1,49 @@ +{{- if and (include "cluster.tls_certificates.cm_generate_ca" .) (include "cluster.tls_certificates.cm_generate_issuer" .) }} +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ include "cluster.tls_certificates.cm_self_ca_cert_name" . }} + namespace: {{ include "cluster.tls_certificates.cm_issuer_namespace" . }} + labels: + {{- include "cluster.labels" . | nindent 4 }} +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "cluster.tls_certificates.cm_self_ca_cert_name" . }} + namespace: {{ include "cluster.tls_certificates.cm_issuer_namespace" . }} + labels: + {{- include "cluster.labels" . | nindent 4 }} +spec: + isCA: true + commonName: {{ include "cluster.fullname" . }} + secretName: {{ include "cluster.tls_certificates.cm_ca_secret_name" . }} + secretTemplate: + {{- (include "cluster.tls_certificates.cm_ca_secret_template" .) | nindent 4 }} + privateKey: + algorithm: RSA + size: 2048 + duration: 43800h0m0s # 5 years + renewBefore: 14600h0m0s # 1.6 year, 1/3rd of the duration + issuerRef: + name: {{ include "cluster.tls_certificates.cm_self_ca_cert_name" . }} + kind: Issuer + group: cert-manager.io +{{- end }} +{{- if (include "cluster.tls_certificates.cm_generate_issuer" .) }} +--- +apiVersion: cert-manager.io/v1 +kind: {{ include "cluster.tls_certificates.cm_issuer_kind" . }} +metadata: + name: {{ include "cluster.tls_certificates.cm_issuer_name" . }} + {{- if eq (include "cluster.tls_certificates.cm_issuer_kind" .) "Issuer" }} + namespace: {{ include "cluster.tls_certificates.cm_issuer_namespace" . }} + {{- end }} + labels: + {{- include "cluster.labels" . | nindent 4 }} +spec: + ca: + secretName: {{ include "cluster.tls_certificates.cm_ca_secret_name" . }} +{{- end }} diff --git a/charts/shield/templates/cluster/tls-certificates-admissionregistration.yaml b/charts/shield/templates/cluster/tls-certificates-admissionregistration.yaml index 12331687b..033ff44e3 100644 --- a/charts/shield/templates/cluster/tls-certificates-admissionregistration.yaml +++ b/charts/shield/templates/cluster/tls-certificates-admissionregistration.yaml @@ -1,5 +1,7 @@ {{- if (include "cluster.tls_certificates.required" .) }} +{{- include "cluster.tls_certificates.check_conflicts" . -}} {{- $cert := dict -}} +{{- if not (include "cluster.tls_certificates.use_cert_manager" .) }} {{- $existingTlsCertificatesSecret := lookup "v1" "Secret" .Release.Namespace (include "cluster.tls_certificates.secret_name" .) -}} {{- if $existingTlsCertificatesSecret -}} {{- $_ := set $cert "Cert" (index $existingTlsCertificatesSecret.data (include "cluster.tls_certificates.cert_file_name" .)) -}} @@ -32,6 +34,7 @@ data: {{ include "cluster.tls_certificates.private_key_file_name" . }}: {{ $cert.Key }} {{ include "cluster.tls_certificates.ca_cert_file_name" . }}: {{ $cert.CACert }} {{- end }} +{{- end -}} {{- if and .Values.cluster.validatingwebhookconfiguration.create (include "cluster.audit_enabled" .) }} --- apiVersion: admissionregistration.k8s.io/v1 @@ -40,6 +43,14 @@ metadata: name: {{ include "cluster.audit_webhook_name" . }} labels: {{- include "cluster.labels" . | nindent 4 }} + {{- if (include "cluster.tls_certificates.use_cert_manager" .) }} + annotations: + {{- if (include "cluster.tls_certificates.cm_use_ca_secret" .) }} + cert-manager.io/inject-ca-from-secret: {{ include "cluster.tls_certificates.cm_issuer_namespace" . }}/{{ include "cluster.tls_certificates.cm_ca_secret_name" . }} + {{- else }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "cluster.tls_certificates.cm_certificate_name" . }} + {{- end }} + {{- end }} webhooks: - name: audit.secure.sysdig.com {{ with .Values.features.detections.kubernetes_audit.excluded_namespaces }} @@ -63,7 +74,9 @@ webhooks: name: {{ include "cluster.service_name" . }} path: /k8s-audit port: {{ include "cluster.audit_service_port" . }} + {{- if not (include "cluster.tls_certificates.use_cert_manager" .) }} caBundle: {{ $cert.CACert }} + {{- end }} admissionReviewVersions: ["v1", "v1beta1"] sideEffects: None timeoutSeconds: {{ .Values.features.detections.kubernetes_audit.timeout }} @@ -77,6 +90,14 @@ metadata: name: {{ include "cluster.admission_control_webhook_name" . }} labels: {{- include "cluster.labels" . | nindent 4 }} + {{- if (include "cluster.tls_certificates.use_cert_manager" .) }} + annotations: + {{- if (include "cluster.tls_certificates.cm_use_ca_secret" .) }} + cert-manager.io/inject-ca-from-secret: {{ include "cluster.tls_certificates.cm_issuer_namespace" . }}/{{ include "cluster.tls_certificates.cm_ca_secret_name" . }} + {{- else }} + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "cluster.tls_certificates.cm_certificate_name" . }} + {{- end }} + {{- end }} webhooks: - name: vac.secure.sysdig.com namespaceSelector: @@ -112,7 +133,9 @@ webhooks: name: {{ include "cluster.service_name" . }} path: /validate port: {{ include "cluster.admission_control_service_port" . }} + {{- if not (include "cluster.tls_certificates.use_cert_manager" .) }} caBundle: {{ $cert.CACert }} + {{- end }} admissionReviewVersions: ["v1", "v1beta1"] sideEffects: None timeoutSeconds: {{ .Values.features.admission_control.timeout }} diff --git a/charts/shield/tests/cluster/cert-manager_test.yaml b/charts/shield/tests/cluster/cert-manager_test.yaml new file mode 100644 index 000000000..787c3e52c --- /dev/null +++ b/charts/shield/tests/cluster/cert-manager_test.yaml @@ -0,0 +1,439 @@ +--- +suite: Cluster - Cert Manager Integration +templates: + - templates/cluster/tls-certificates-admissionregistration.yaml + - templates/cluster/cert-manager-certificate.yaml + - templates/cluster/cert-manager-self-generate.yaml +release: + name: shield-release + namespace: shield-namespace +values: + - ../values/base.yaml +kubernetesProvider: + objects: + # Mock CA secret in cert-manager namespace + - apiVersion: v1 + kind: Secret + metadata: + name: external-ca-secret + namespace: cert-manager + data: + tls.crt: Y2EgY2VydGlmaWNhdGU= # "ca certificate" + tls.key: Y2Ega2V5 # "ca key" + # Mock CA secret in same namespace + - apiVersion: v1 + kind: Secret + metadata: + name: external-ca-secret + namespace: shield-namespace + data: + tls.crt: Y2EgY2VydGlmaWNhdGU= # "ca certificate" + tls.key: Y2Ega2V5 # "ca key" + +tests: + - it: Cert Manager disabled by default + set: + features: + detections: + kubernetes_audit: + enabled: true + vulnerability_management: + container_vulnerability_management: + enabled: true + asserts: + - hasDocuments: + count: 0 + templates: + - templates/cluster/cert-manager-certificate.yaml + - templates/cluster/cert-manager-self-generate.yaml + + - it: Cert Manager validation - missing CA secret name when generate is false + set: + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: false + secret_name: "" # Missing secret name + issuer: + create: true + asserts: + - failedTemplate: + errorPattern: "cert_manager.ca.secret_name must be specified" + template: templates/cluster/cert-manager-certificate.yaml + + - it: Cert Manager validation - missing issuer name when generate is false + set: + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: false + secret_name: external-ca-secret + secret_namespace: cert-manager + issuer: + create: false + name: "" # Missing issuer name + asserts: + - failedTemplate: + errorPattern: "cert_manager.issuer.name must be specified" + template: templates/cluster/cert-manager-certificate.yaml + + - it: Cert Manager with custom duration and renew_before + set: + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: false + secret_name: external-ca-secret + secret_namespace: cert-manager + issuer: + create: true + duration: "168h" # 7 days + renew_before: "24h" # 1 day + asserts: + - equal: + path: spec.duration + value: "168h" + - equal: + path: spec.renewBefore + value: "24h" + template: templates/cluster/cert-manager-certificate.yaml + + - it: Cert Manager with CA secret in same namespace (Issuer) + set: + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: false + secret_name: external-ca-secret + secret_namespace: "" # Same namespace + issuer: + create: true + asserts: + - containsDocument: + kind: Issuer + apiVersion: cert-manager.io/v1 + name: shield-release-cluster-cm-self-issuer + namespace: shield-namespace + template: templates/cluster/cert-manager-self-generate.yaml + - containsDocument: + kind: Certificate + apiVersion: cert-manager.io/v1 + name: shield-release-cluster-cm-tls + namespace: shield-namespace + template: templates/cluster/cert-manager-certificate.yaml + - equal: + path: spec.ca.secretName + value: external-ca-secret + documentIndex: 0 + template: templates/cluster/cert-manager-self-generate.yaml + - equal: + path: spec.issuerRef.name + value: shield-release-cluster-cm-self-issuer + template: templates/cluster/cert-manager-certificate.yaml + - equal: + path: spec.issuerRef.kind + value: Issuer + template: templates/cluster/cert-manager-certificate.yaml + + - it: Cert Manager with CA secret in different namespace (ClusterIssuer) + set: + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: false + secret_name: external-ca-secret + secret_namespace: cert-manager # Different namespace + issuer: + create: true + asserts: + - containsDocument: + kind: ClusterIssuer + apiVersion: cert-manager.io/v1 + name: shield-release-cluster-cm-self-issuer + template: templates/cluster/cert-manager-self-generate.yaml + - containsDocument: + kind: Certificate + apiVersion: cert-manager.io/v1 + name: shield-release-cluster-cm-tls + namespace: shield-namespace + template: templates/cluster/cert-manager-certificate.yaml + - equal: + path: spec.ca.secretName + value: external-ca-secret + template: templates/cluster/cert-manager-self-generate.yaml + - equal: + path: spec.issuerRef.name + value: shield-release-cluster-cm-self-issuer + template: templates/cluster/cert-manager-certificate.yaml + - equal: + path: spec.issuerRef.kind + value: ClusterIssuer + template: templates/cluster/cert-manager-certificate.yaml + + - it: Cert Manager with generated CA (same namespace) + set: + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: true + issuer: + create: true + asserts: + - containsDocument: + kind: Issuer + apiVersion: cert-manager.io/v1 + name: shield-release-cluster-cm-self-ca + namespace: shield-namespace + documentIndex: 0 + template: templates/cluster/cert-manager-self-generate.yaml + - containsDocument: + kind: Certificate + apiVersion: cert-manager.io/v1 + name: shield-release-cluster-cm-self-ca + namespace: shield-namespace + documentIndex: 1 + template: templates/cluster/cert-manager-self-generate.yaml + - containsDocument: + kind: Issuer + apiVersion: cert-manager.io/v1 + name: shield-release-cluster-cm-self-issuer + namespace: shield-namespace + documentIndex: 2 + template: templates/cluster/cert-manager-self-generate.yaml + - equal: + path: spec.selfSigned + value: {} + documentIndex: 0 + template: templates/cluster/cert-manager-self-generate.yaml + - equal: + path: spec.isCA + value: true + documentIndex: 1 + template: templates/cluster/cert-manager-self-generate.yaml + - equal: + path: spec.secretName + value: shield-release-cluster-cm-ca + documentIndex: 1 + template: templates/cluster/cert-manager-self-generate.yaml + + - it: Cert Manager with custom CA secret template + set: + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: true + secret_template: + labels: + app.kubernetes.io/name: sysdig-ca + app.kubernetes.io/component: ca + annotations: + sysdig.com/created-by: cert-manager + issuer: + create: true + asserts: + - equal: + path: spec.secretTemplate.labels["app.kubernetes.io/name"] + value: sysdig-ca + documentIndex: 1 + - equal: + path: spec.secretTemplate.labels["app.kubernetes.io/component"] + value: ca + documentIndex: 1 + - equal: + path: spec.secretTemplate.annotations["sysdig.com/created-by"] + value: cert-manager + documentIndex: 1 + template: templates/cluster/cert-manager-self-generate.yaml + + - it: Cert Manager with existing issuer + set: + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: false + secret_name: external-ca-secret + secret_namespace: cert-manager + issuer: + create: false + name: my-existing-issuer + kind: ClusterIssuer + group: cert-manager.io + asserts: + - containsDocument: + kind: Certificate + apiVersion: cert-manager.io/v1 + name: shield-release-cluster-cm-tls + namespace: shield-namespace + template: templates/cluster/cert-manager-certificate.yaml + - equal: + path: spec.issuerRef.name + value: my-existing-issuer + template: templates/cluster/cert-manager-certificate.yaml + - equal: + path: spec.issuerRef.kind + value: ClusterIssuer + template: templates/cluster/cert-manager-certificate.yaml + - equal: + path: spec.issuerRef.group + value: cert-manager.io + template: templates/cluster/cert-manager-certificate.yaml + + - it: Cert Manager with container vulnerability management enabled + set: + features: + vulnerability_management: + container_vulnerability_management: + enabled: true + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: false + secret_name: external-ca-secret + secret_namespace: cert-manager + issuer: + create: true + asserts: + - containsDocument: + kind: ClusterIssuer + apiVersion: cert-manager.io/v1 + name: shield-release-cluster-cm-self-issuer + template: templates/cluster/cert-manager-self-generate.yaml + - containsDocument: + kind: Certificate + apiVersion: cert-manager.io/v1 + name: shield-release-cluster-cm-tls + namespace: shield-namespace + template: templates/cluster/cert-manager-certificate.yaml + - equal: + path: spec.dnsNames + value: + - localhost + - shield-release-cluster + - "*.shield-release-cluster" + - "*.shield-release-cluster.shield-namespace.svc" + - shield-release-cluster.shield-namespace.svc + - "*.shield-release-cluster.shield-namespace.svc.cluster.local" + - shield-release-cluster.shield-namespace.svc.cluster.local + - shield-release-cluster-container-vm + - "*.shield-release-cluster-container-vm" + - "*.shield-release-cluster-container-vm.shield-namespace.svc" + - shield-release-cluster-container-vm.shield-namespace.svc + - "*.shield-release-cluster-container-vm.shield-namespace.svc.cluster.local" + - shield-release-cluster-container-vm.shield-namespace.svc.cluster.local + template: templates/cluster/cert-manager-certificate.yaml + + - it: Auto-injection annotation added when both CA and Issuer generated + set: + features: + detections: + kubernetes_audit: + enabled: true + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: true + issuer: + create: true + asserts: + - equal: + path: spec.secretTemplate.annotations["cert-manager.io/allow-direct-injection"] + value: "true" + documentIndex: 1 + template: templates/cluster/cert-manager-self-generate.yaml + + - it: Custom labels preserved in secret template + set: + features: + detections: + kubernetes_audit: + enabled: true + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: true + secret_template: + labels: + custom.label: test-value + app.kubernetes.io/name: sysdig-ca + issuer: + create: true + asserts: + - equal: + path: spec.secretTemplate.labels["custom.label"] + value: test-value + documentIndex: 1 + template: templates/cluster/cert-manager-self-generate.yaml + - equal: + path: spec.secretTemplate.labels["app.kubernetes.io/name"] + value: sysdig-ca + documentIndex: 1 + template: templates/cluster/cert-manager-self-generate.yaml + + - it: Custom annotations merged with injection annotation + set: + features: + detections: + kubernetes_audit: + enabled: true + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: true + secret_template: + annotations: + custom.annotation: test-value + sysdig.com/created-by: cert-manager + issuer: + create: true + asserts: + - equal: + path: spec.secretTemplate.annotations["custom.annotation"] + value: test-value + documentIndex: 1 + template: templates/cluster/cert-manager-self-generate.yaml + - equal: + path: spec.secretTemplate.annotations["sysdig.com/created-by"] + value: cert-manager + documentIndex: 1 + template: templates/cluster/cert-manager-self-generate.yaml + - equal: + path: spec.secretTemplate.annotations["cert-manager.io/allow-direct-injection"] + value: "true" + documentIndex: 1 + template: templates/cluster/cert-manager-self-generate.yaml diff --git a/charts/shield/tests/cluster/tls-certificates-admissionregistration_test.yaml b/charts/shield/tests/cluster/tls-certificates-admissionregistration_test.yaml index a249bfc4e..b49b9e16f 100644 --- a/charts/shield/tests/cluster/tls-certificates-admissionregistration_test.yaml +++ b/charts/shield/tests/cluster/tls-certificates-admissionregistration_test.yaml @@ -635,3 +635,145 @@ tests: - pods scope: Namespaced documentIndex: 1 + + - it: Cert Manager Integration exclusive with tls secret name + set: + features: + detections: + kubernetes_audit: + enabled: true + cluster: + tls_certificates: + secret_name: foo + cert_manager: + enabled: true + asserts: + - failedTemplate: + errorPattern: "Cannot specify both" + + + - it: Audit webhook with cert-manager annotations (generated issuer) + set: + features: + detections: + kubernetes_audit: + enabled: true + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: false + secret_name: external-ca-secret + secret_namespace: cert-manager + issuer: + create: true + asserts: + - containsDocument: + kind: ValidatingWebhookConfiguration + apiVersion: admissionregistration.k8s.io/v1 + name: shield-release-cluster-audit + template: templates/cluster/tls-certificates-admissionregistration.yaml + - equal: + path: metadata.annotations["cert-manager.io/inject-ca-from-secret"] + value: cert-manager/external-ca-secret + template: templates/cluster/tls-certificates-admissionregistration.yaml + - notExists: + path: .webhooks[0].clientConfig.caBundle + template: templates/cluster/tls-certificates-admissionregistration.yaml + + - it: Audit webhook with cert-manager annotations (existing issuer) + set: + features: + detections: + kubernetes_audit: + enabled: true + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: false + secret_name: external-ca-secret + secret_namespace: cert-manager + issuer: + create: false + name: my-existing-issuer + kind: ClusterIssuer + asserts: + - containsDocument: + kind: ValidatingWebhookConfiguration + apiVersion: admissionregistration.k8s.io/v1 + name: shield-release-cluster-audit + template: templates/cluster/tls-certificates-admissionregistration.yaml + - equal: + path: metadata.annotations["cert-manager.io/inject-ca-from"] + value: shield-namespace/shield-release-cluster-cm-tls + template: templates/cluster/tls-certificates-admissionregistration.yaml + - notExists: + path: .webhooks[0].clientConfig.caBundle + template: templates/cluster/tls-certificates-admissionregistration.yaml + + - it: Admission control webhook with cert-manager annotations (generated issuer) + set: + features: + admission_control: + enabled: true + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: false + secret_name: external-ca-secret + secret_namespace: cert-manager + issuer: + create: true + asserts: + - containsDocument: + kind: ValidatingWebhookConfiguration + apiVersion: admissionregistration.k8s.io/v1 + name: shield-release-cluster-admission-control + template: templates/cluster/tls-certificates-admissionregistration.yaml + - equal: + path: metadata.annotations["cert-manager.io/inject-ca-from-secret"] + value: cert-manager/external-ca-secret + template: templates/cluster/tls-certificates-admissionregistration.yaml + - notExists: + path: .webhooks[0].clientConfig.caBundle + template: templates/cluster/tls-certificates-admissionregistration.yaml + + - it: Admission control webhook with cert-manager annotations (existing issuer) + set: + features: + admission_control: + enabled: true + cluster: + tls_certificates: + create: true + cert_manager: + enabled: true + ca: + create: false + secret_name: external-ca-secret + secret_namespace: cert-manager + issuer: + create: false + name: my-existing-issuer + kind: ClusterIssuer + asserts: + - containsDocument: + kind: ValidatingWebhookConfiguration + apiVersion: admissionregistration.k8s.io/v1 + name: shield-release-cluster-admission-control + template: templates/cluster/tls-certificates-admissionregistration.yaml + - equal: + path: metadata.annotations["cert-manager.io/inject-ca-from"] + value: shield-namespace/shield-release-cluster-cm-tls + template: templates/cluster/tls-certificates-admissionregistration.yaml + - notExists: + path: .webhooks[0].clientConfig.caBundle + template: templates/cluster/tls-certificates-admissionregistration.yaml diff --git a/charts/shield/values.yaml b/charts/shield/values.yaml index 2ce138011..4d5b77464 100644 --- a/charts/shield/values.yaml +++ b/charts/shield/values.yaml @@ -440,6 +440,33 @@ cluster: create: true # The name of the secret that contains the TLS certificates secret_name: + cert_manager: + # Enable cert-manager for certificate management + enabled: false + ca: + # Create the CA certificate using cert-manager + create: false + # The template for the CA certificate secret (if generate is true) + # will automatically add the annotation `cert-manager.io/allow-direct-injection: "true"` if not present + secret_template: {} + # The name of the existing CA certificate secret (if generate is false) + # has to be annotated with `cert-manager.io/allow-direct-injection: "true"` + secret_name: "" + # The namespace of the existing CA certificate secret (if generate is false) + secret_namespace: "" + issuer: + # Create the Issuer instead of using an existing one + create: false + # The name of the existing issuer + name: "" + # The kind of the existing issuer (Issuer, ClusterIssuer) + kind: Issuer + # The group of the existing issuer + group: cert-manager.io + # Certificate duration (default: 30 days) + duration: "720h" + # How long before expiry to renew (default: 15 days) + renew_before: "360h" resources: requests: # The CPU request for the cluster shield