Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CP-26005: add annotations to init-cert, add better logic for updating certificates #167

Merged
merged 12 commits into from
Feb 17, 2025
16 changes: 14 additions & 2 deletions charts/cloudzero-agent/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ Create the name of the ClusterRoleBinding to use for the init-cert Job
{{ .Values.initCertJob.rbac.clusterRoleBinding | default $defaultName }}
{{- end -}}

{{/*
init-cert Job annotations
*/}}
{{- define "cloudzero-agent.initCertJob.annotations" -}}
{{- if .Values.initCertJob.annotations -}}
annotations:
{{ toYaml .Values.initCertJob.annotations }}
{{- end -}}
{{- end -}}


{{/*
Create a fully qualified Prometheus server name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
Expand Down Expand Up @@ -400,8 +411,9 @@ Name for the backfill job resource
Name for the certificate init job resource. Should be a new name each installation/upgrade.
*/}}
{{- define "cloudzero-agent.initCertJobName" -}}
{{- $name := (printf "%s-init-cert" (include "cloudzero-agent.insightsController.server.webhookFullname" .) | trunc 60) -}}
{{- $name -}}-{{ .Release.Revision | default (randAlpha 5) }}
{{ $version := .Chart.Version | replace "." "-" }}
{{- $name := (printf "%s-init-cert-%s" (include "cloudzero-agent.insightsController.server.webhookFullname" .) $version | trunc 60) -}}
{{- $name -}}-{{ .Release.Revision }}
{{- end }}

{{/*
Expand Down
42 changes: 32 additions & 10 deletions charts/cloudzero-agent/templates/init-job.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ metadata:
labels:
{{- include "cloudzero-agent.insightsController.labels" . | nindent 4 }}
spec:
ttlSecondsAfterFinished: 60
ttlSecondsAfterFinished: {{ $backFillValues.ttlSecondsAfterFinished }}
template:
metadata:
name: {{ include "cloudzero-agent.initBackfillJobName" . }}
Expand Down Expand Up @@ -85,10 +85,11 @@ kind: Job
metadata:
name: {{ include "cloudzero-agent.initCertJobName" . }}
namespace: {{ .Release.Namespace }}
{{- include "cloudzero-agent.initCertJob.annotations" . | nindent 2 }}
labels:
{{- include "cloudzero-agent.insightsController.labels" . | nindent 4 }}
spec:
ttlSecondsAfterFinished: 3600
ttlSecondsAfterFinished: {{ .Values.initCertJob.ttlSecondsAfterFinished }}
template:
metadata:
name: {{ include "cloudzero-agent.initCertJobName" . }}
Expand All @@ -109,27 +110,48 @@ spec:
set -e

{{- if not .Values.insightsController.tls.useCertManager }}
# Determine if the ValidatingWebhookConfiguration resources already have caBundle information
MISSING_CA_BUNDLE=false
GENERATE_CERTIFICATE=false

# Check if the caBundle in the ValidatingWebhookConfiguration is the same for all webhooks
caBundles=()
{{- range $configType, $configs := .Values.insightsController.webhooks.configurations }}
{{- $webhookName := printf "%s-%s" (include "cloudzero-agent.validatingWebhookConfigName" $) $configType }}
{{- if or (index $.Values.insightsController.labels.resources $configType) (index $.Values.insightsController.annotations.resources $configType) }}
CA_BUNDLE=$(kubectl get validatingwebhookconfiguration {{ $webhookName }} -o jsonpath='{.webhooks[0].clientConfig.caBundle}')
if [[ -z "$CA_BUNDLE" ]]; then
MISSING_CA_BUNDLE=true
fi
caBundles+=($(kubectl get validatingwebhookconfiguration {{ $webhookName }} -o jsonpath='{.webhooks[0].clientConfig.caBundle}'))
{{- end }}
{{- end }}

CA_BUNDLE=${caBundles[0]}
for caBundle in "${caBundles[@]}"; do
if [[ "$caBundle" != "$CA_BUNDLE" ]]; then
echo "Mismatch found between ValidatingWebhookConfiguration caBundle values."
GENERATE_CERTIFICATE=true
fi
done

SECRET_NAME={{ include "cloudzero-agent.tlsSecretName" . }}
NAMESPACE={{ .Release.Namespace }}

EXISTING_TLS_CRT=$(kubectl get secret $SECRET_NAME -n $NAMESPACE -o jsonpath='{.data.tls\.crt}')
EXISTING_TLS_KEY=$(kubectl get secret $SECRET_NAME -n $NAMESPACE -o jsonpath='{.data.tls\.key}')

if [[ -n "$EXISTING_TLS_CRT" ]]; then
# Check if the SANs in the certificate match the service name
SAN=$(echo "$EXISTING_TLS_CRT" | base64 -d | openssl x509 -text -noout | grep DNS | sed 's/.*DNS://')
if [[ "$SAN" != "{{ include "cloudzero-agent.serviceName" . }}.{{ .Release.Namespace }}.svc" ]]; then
echo "The SANs in the certificate do not match the service name."
GENERATE_CERTIFICATE=true
fi
# Check that caBundle and tls.crt are the same
if [[ "$CA_BUNDLE" != $EXISTING_TLS_CRT ]]; then
echo "The caBundle in the ValidatingWebhookConfiguration does not match the tls.crt in the TLS Secret."
GENERATE_CERTIFICATE=true
fi
fi

# Check if the TLS Secret already has certificate information
if [[ -z "$EXISTING_TLS_CRT" ]] || [[ -z "$EXISTING_TLS_KEY" ]] || [[ $MISSING_CA_BUNDLE == "true" ]] ; then
echo "The TLS Secret and/or at least one webhook configuration contains empty certificate information, or forceInit is enabled. Creating a new certificate..."
if [[ -z "$EXISTING_TLS_CRT" ]] || [[ -z "$EXISTING_TLS_KEY" ]] || [[ $GENERATE_CERTIFICATE == "true" ]] ; then
echo "The TLS Secret and/or at least one webhook configuration contains empty certificate information, or the certificate is invalid/expired. Creating a new certificate..."
else
echo "The TLS Secret and all webhook configurations contain non-empty certificate information. Will not create a new certificate and will not patch resources."
exit 0
Expand Down
2 changes: 2 additions & 0 deletions charts/cloudzero-agent/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ initBackfillJob:
# tag: 0.1.1
# pullPolicy: Always
enabled: true
ttlSecondsAfterFinished: 180

# -- This is a deprecated field that is replaced by initBackfillJob. However, the fields are identical, and initScrapeJob can still be used to configure the backFill/scrape Job.
# initScrapeJob:
Expand All @@ -181,6 +182,7 @@ initCertJob:
serviceAccountName: ""
clusterRoleName: ""
clusterRoleBindingName: ""
ttlSecondsAfterFinished: 180

kubeStateMetrics:
enabled: true
Expand Down