Skip to content

Commit ec6cf86

Browse files
committed
feat(chart): remove AllowlistSynchronizer automatically
This requires the workload allowlists in version 1.0.1, as they provide an allowlist for this new job.
1 parent e7e0f2d commit ec6cf86

File tree

9 files changed

+620
-6
lines changed

9 files changed

+620
-6
lines changed

helm-chart/dash0-operator/README.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,12 +2157,6 @@ clusters:
21572157
disabled, collecting these requires access to the `/pod` endpoint of the kubelet API which is not available in GKE
21582158
autopilot due to the lack of the `nodes/proxy` permission
21592159

2160-
**Note:** The `AllowlistSynchronizer` resource is not removed automatically with `helm uninstall dash0-operator`.
2161-
If you decide to remove the Dash0 operator Helm release from the cluster, you might want to delete the
2162-
`AllowlistSynchronizer` manually afterward, for example by executing
2163-
`kubectl delete AllowlistSynchronizer dash0-allowlist-synchronizer`.
2164-
Deleting the `AllowlistSynchronizer` will also delete all associated `WorkloadAllowlist` resources.
2165-
21662160
Refer to <https://cloud.google.com/kubernetes-engine/docs/how-to/run-autopilot-partner-workloads> for more information
21672161
on `AllowlistSynchronizer`, `WorkloadAllowlist`, and related concepts.
21682162

@@ -2192,6 +2186,7 @@ spec:
21922186
- Dash0/operator/v1.0.1/dash0-opentelemetry-cluster-metrics-collector-v1.0.1.yaml
21932187
- Dash0/operator/v1.0.1/dash0-opentelemetry-collector-agent-v1.0.1.yaml
21942188
- Dash0/operator/v1.0.1/dash0-operator-manager-v1.0.1.yaml
2189+
- Dash0/operator/v1.0.1/dash0-post-delete-remove-allowlist-synchronizer-v1.0.1.yaml
21952190
- Dash0/operator/v1.0.1/dash0-post-install-v1.0.1.yaml
21962191
- Dash0/operator/v1.0.1/dash0-pre-delete-v1.0.1.yaml
21972192
- Dash0/operator/v1.0.1/dash0-target-allocator-v1.0.1.yaml

helm-chart/dash0-operator/templates/_helpers.tpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ helm.sh/chart: {{ include "dash0-operator.chartNameWithVersion" . }}
4242
{{- default (printf "%s-controller" (include "dash0-operator.chartName" .)) .Values.operator.serviceAccount.name }}
4343
{{- end }}
4444

45+
{{- define "dash0-operator.postDeleteHookServiceAccountName" -}}
46+
{{- printf "%s-post-delete" (include "dash0-operator.chartName" .) }}
47+
{{- end }}
48+
4549
{{/* otelcol resources config map name */}}
4650
{{- define "dash0-operator.extraConfigMapName" -}}
4751
{{ include "dash0-operator.chartName" . }}-extra-config

helm-chart/dash0-operator/templates/operator/gke-autopilot-allowlist-synchronizer.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ spec:
2424
- Dash0/operator/v1.0.1/dash0-opentelemetry-cluster-metrics-collector-v1.0.1.yaml
2525
- Dash0/operator/v1.0.1/dash0-opentelemetry-collector-agent-v1.0.1.yaml
2626
- Dash0/operator/v1.0.1/dash0-operator-manager-v1.0.1.yaml
27+
- Dash0/operator/v1.0.1/dash0-post-delete-remove-allowlist-synchronizer-v1.0.1.yaml
2728
- Dash0/operator/v1.0.1/dash0-post-install-v1.0.1.yaml
2829
- Dash0/operator/v1.0.1/dash0-pre-delete-v1.0.1.yaml
2930
- Dash0/operator/v1.0.1/dash0-target-allocator-v1.0.1.yaml
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
{{- if (and .Values.operator.gke.autopilot.enabled .Values.operator.gke.autopilot.deployAllowlistSynchronizer) }}
2+
{{/*
3+
This job needs its own separate ClusterRole, ClusterRoleBinding and ServiceAccount because all resources from the main
4+
Helm chart have already been deleted by the time this runs.
5+
*/}}
6+
apiVersion: v1
7+
kind: ServiceAccount
8+
metadata:
9+
name: {{ template "dash0-operator.postDeleteHookServiceAccountName" . }}
10+
annotations:
11+
"helm.sh/hook": post-delete
12+
"helm.sh/hook-weight": "-10"
13+
"helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded,hook-failed"
14+
---
15+
apiVersion: rbac.authorization.k8s.io/v1
16+
kind: ClusterRole
17+
metadata:
18+
name: {{ template "dash0-operator.chartName" . }}-post-delete-role
19+
annotations:
20+
"helm.sh/hook": post-delete
21+
"helm.sh/hook-weight": "-5"
22+
"helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded,hook-failed"
23+
rules:
24+
- apiGroups:
25+
- apiextensions.k8s.io
26+
resources:
27+
- customresourcedefinitions
28+
verbs:
29+
- get
30+
- apiGroups:
31+
- auto.gke.io
32+
resources:
33+
- allowlistsynchronizers
34+
verbs:
35+
- delete
36+
---
37+
apiVersion: rbac.authorization.k8s.io/v1
38+
kind: ClusterRoleBinding
39+
metadata:
40+
name: {{ template "dash0-operator.chartName" . }}-post-delete-role-binding
41+
annotations:
42+
"helm.sh/hook": post-delete
43+
"helm.sh/hook-weight": "-4"
44+
"helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded,hook-failed"
45+
roleRef:
46+
apiGroup: rbac.authorization.k8s.io
47+
kind: ClusterRole
48+
name: {{ template "dash0-operator.chartName" . }}-post-delete-role
49+
subjects:
50+
- kind: ServiceAccount
51+
name: {{ template "dash0-operator.postDeleteHookServiceAccountName" . }}
52+
namespace: {{ .Release.Namespace }}
53+
---
54+
apiVersion: batch/v1
55+
kind: Job
56+
metadata:
57+
name: {{ include "dash0-operator.chartName" . }}-post-delete-remove-allowlist-synchronizer
58+
namespace: {{ .Release.Namespace }}
59+
labels:
60+
app.kubernetes.io/name: dash0-operator
61+
app.kubernetes.io/component: remove-allowlist-synchronizer
62+
{{- include "dash0-operator.labels" . | nindent 4 }}
63+
dash0.com/enable: "false"
64+
annotations:
65+
helm.sh/hook: post-delete
66+
helm.sh/hook-weight: "0"
67+
helm.sh/hook-delete-policy: "hook-succeeded"
68+
spec:
69+
template:
70+
metadata:
71+
name: {{ .Release.Name }}-post-delete-job-remove-allowlist-synchronizer
72+
labels:
73+
app.kubernetes.io/name: dash0-operator
74+
app.kubernetes.io/component: remove-allowlist-synchronizer
75+
app.kubernetes.io/instance: post-delete-hook
76+
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
77+
helm.sh/chart: {{ include "dash0-operator.chartNameWithVersion" . }}
78+
cloud.google.com/matching-allowlist: dash0-post-delete-remove-allowlist-synchronizer-v1.0.1
79+
spec:
80+
restartPolicy: OnFailure
81+
affinity:
82+
nodeAffinity:
83+
requiredDuringSchedulingIgnoredDuringExecution:
84+
nodeSelectorTerms:
85+
- matchExpressions:
86+
- key: "dash0.com/enable"
87+
operator: "NotIn"
88+
values: ["false"]
89+
- key: "kubernetes.io/os"
90+
operator: "In"
91+
values: ["linux"]
92+
{{- if .Values.operator.tolerations }}
93+
tolerations:
94+
{{- toYaml .Values.operator.tolerations | nindent 8 }}
95+
{{- end }}
96+
{{- if .Values.operator.managerPriorityClassName }}
97+
priorityClassName: {{ .Values.operator.managerPriorityClassName }}
98+
{{- end }}
99+
containers:
100+
- name: remove-allowlist-synchronizer-job
101+
image: {{ include "dash0-operator.image" . | quote }}
102+
imagePullPolicy: {{ .Values.operator.image.pullPolicy }}
103+
command:
104+
- /manager
105+
args:
106+
- "--delete-allowlist-synchronizer"
107+
{{ include "dash0-operator.restrictiveContainerSecurityContext" dict | nindent 10 }}
108+
env:
109+
- name: GOMEMLIMIT
110+
value: {{ .Values.operator.managerContainerResources.gomemlimit }}
111+
resources:
112+
{{- unset (.Values.operator.managerContainerResources | mustDeepCopy) "gomemlimit" | toYaml | nindent 12 }}
113+
{{- with .Values.operator.imagePullSecrets }}
114+
imagePullSecrets:
115+
{{- toYaml . | nindent 8 }}
116+
{{- end }}
117+
securityContext:
118+
runAsNonRoot: true
119+
serviceAccountName: {{ template "dash0-operator.postDeleteHookServiceAccountName" . }}
120+
automountServiceAccountToken: true
121+
backoffLimit: 2
122+
{{- end }}

helm-chart/dash0-operator/tests/operator/__snapshot__/gke-autopilot-allowlist-synchronizer_test.yaml.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ should install the GKE Autopilot AllowlistSynchronizer if operator.gke.autopilot
1212
- Dash0/operator/v1.0.1/dash0-opentelemetry-cluster-metrics-collector-v1.0.1.yaml
1313
- Dash0/operator/v1.0.1/dash0-opentelemetry-collector-agent-v1.0.1.yaml
1414
- Dash0/operator/v1.0.1/dash0-operator-manager-v1.0.1.yaml
15+
- Dash0/operator/v1.0.1/dash0-post-delete-remove-allowlist-synchronizer-v1.0.1.yaml
1516
- Dash0/operator/v1.0.1/dash0-post-install-v1.0.1.yaml
1617
- Dash0/operator/v1.0.1/dash0-pre-delete-v1.0.1.yaml
1718
- Dash0/operator/v1.0.1/dash0-target-allocator-v1.0.1.yaml
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// SPDX-FileCopyrightText: Copyright 2026 Dash0 Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package postdelete
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"strings"
10+
"time"
11+
12+
"github.com/go-logr/logr"
13+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
14+
apierrors "k8s.io/apimachinery/pkg/api/errors"
15+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
16+
"k8s.io/apimachinery/pkg/runtime"
17+
"k8s.io/apimachinery/pkg/runtime/schema"
18+
"k8s.io/client-go/rest"
19+
ctrl "sigs.k8s.io/controller-runtime"
20+
"sigs.k8s.io/controller-runtime/pkg/client"
21+
22+
dash0v1alpha1 "github.com/dash0hq/dash0-operator/api/operator/v1alpha1"
23+
dash0v1beta1 "github.com/dash0hq/dash0-operator/api/operator/v1beta1"
24+
)
25+
26+
const (
27+
defaultTimeout = 2 * time.Minute
28+
29+
gkeAutopilotAllowlistSynchronizerGroup = "auto.gke.io"
30+
gkeAutopilotAllowlistSynchronizerKind = "AllowlistSynchronizer"
31+
gkeAutopilotAllowlistSynchronizerVersion = "v1"
32+
dash0AllowlistSynchronizerName = "dash0-allowlist-synchronizer"
33+
)
34+
35+
var (
36+
// "allowlistsynchronizers"
37+
gkeAutopilotAllowlistSynchronizerPlural = fmt.Sprintf("%ss", strings.ToLower(gkeAutopilotAllowlistSynchronizerKind))
38+
39+
// "allowlistsynchronizers.auto.gke.io"
40+
gkeAutopilotAllowlistSynchronizerCrdName = fmt.Sprintf(
41+
"%s.%s",
42+
gkeAutopilotAllowlistSynchronizerPlural,
43+
gkeAutopilotAllowlistSynchronizerGroup,
44+
)
45+
)
46+
47+
type OperatorPostDeleteHandler struct {
48+
client client.WithWatch
49+
logger *logr.Logger
50+
timeout time.Duration
51+
}
52+
53+
func NewOperatorPostDeleteHandler() (*OperatorPostDeleteHandler, error) {
54+
config := ctrl.GetConfigOrDie()
55+
return NewOperatorPostDeleteHandlerFromConfig(config)
56+
}
57+
58+
func NewOperatorPostDeleteHandlerFromConfig(config *rest.Config) (*OperatorPostDeleteHandler, error) {
59+
logger := ctrl.Log.WithName("dash0-remove-allowlist-synchronizer")
60+
s := runtime.NewScheme()
61+
if err := dash0v1alpha1.AddToScheme(s); err != nil {
62+
return nil, err
63+
}
64+
if err := dash0v1beta1.AddToScheme(s); err != nil {
65+
return nil, err
66+
}
67+
if err := apiextensionsv1.AddToScheme(s); err != nil {
68+
return nil, err
69+
}
70+
k8sClient, err := client.NewWithWatch(config, client.Options{
71+
Scheme: s,
72+
})
73+
if err != nil {
74+
return nil, fmt.Errorf("failed to create the dynamic client: %w", err)
75+
}
76+
77+
return &OperatorPostDeleteHandler{
78+
client: k8sClient,
79+
logger: &logger,
80+
timeout: defaultTimeout,
81+
}, nil
82+
}
83+
84+
func (h *OperatorPostDeleteHandler) setTimeout(timeout time.Duration) {
85+
h.timeout = timeout
86+
}
87+
88+
func (h *OperatorPostDeleteHandler) DeleteGkeAutopilotAllowlistSynchronizer(ctx context.Context, logger *logr.Logger) error {
89+
if err := h.client.Get(ctx, client.ObjectKey{
90+
Name: gkeAutopilotAllowlistSynchronizerCrdName,
91+
}, &apiextensionsv1.CustomResourceDefinition{}); err != nil {
92+
if !apierrors.IsNotFound(err) {
93+
logger.Error(
94+
err,
95+
fmt.Sprintf(
96+
"error when checking for the existence of the GKE Autopilot AllowlistSynchronizer CRD (client.Get(\"%s\") failed)",
97+
gkeAutopilotAllowlistSynchronizerCrdName,
98+
))
99+
}
100+
101+
// The AllowlistSynchronizer CRD does not exist, hence we can be sure that the Dash0 AllowlistSynchronizer also
102+
// does not exist. Abort the attempt to delete the AllowlistSynchronizer and terminate with exit code 0.
103+
return nil
104+
}
105+
106+
dash0AllowlistSynchronizer := &unstructured.Unstructured{}
107+
dash0AllowlistSynchronizer.SetGroupVersionKind(schema.GroupVersionKind{
108+
Group: gkeAutopilotAllowlistSynchronizerGroup,
109+
Kind: gkeAutopilotAllowlistSynchronizerKind,
110+
Version: gkeAutopilotAllowlistSynchronizerVersion,
111+
})
112+
dash0AllowlistSynchronizer.SetName(dash0AllowlistSynchronizerName)
113+
114+
if err := h.client.Delete(ctx, dash0AllowlistSynchronizer); err != nil {
115+
if apierrors.IsNotFound(err) {
116+
// The dash0-allowlist-synchronizer resource does not exist, nothing to do.
117+
return nil
118+
} else {
119+
logger.Error(
120+
err,
121+
fmt.Sprintf(
122+
"error when attempting to delete the Dash0 AllowlistSynchronizer (%s: %s)",
123+
dash0AllowlistSynchronizerName,
124+
gkeAutopilotAllowlistSynchronizerCrdName,
125+
))
126+
return err
127+
}
128+
}
129+
return nil
130+
}

0 commit comments

Comments
 (0)