Skip to content

Commit

Permalink
feat(webhooks): add validation webhook for operator configuration
Browse files Browse the repository at this point in the history
Reject operator configuration resources with self-telemetry enabled that
have no export configuration.
  • Loading branch information
basti1302 committed Sep 15, 2024
1 parent fb3ec75 commit ff7f74c
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 0 deletions.
5 changes: 5 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,11 @@ func startDash0Controllers(
return fmt.Errorf("unable to create the instrumentation webhook: %w", err)
}

if err := (&webhooks.OperatorConfigurationValidationWebhookHandler{
Client: k8sClient,
}).SetupWebhookWithManager(mgr); err != nil {
return fmt.Errorf("unable to create the operator configuration validation webhook: %w", err)
}
if err := (&webhooks.MonitoringValidationWebhookHandler{
Client: k8sClient,
}).SetupWebhookWithManager(mgr); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,38 @@ webhooks:
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: {{ template "dash0-operator.chartName" . }}-operator-configuration-validator
labels:
app.kubernetes.io/name: dash0-operator
app.kubernetes.io/component: validator
app.kubernetes.io/instance: operator-configuration-validator-webhook
{{- include "dash0-operator.labels" . | nindent 4 }}
webhooks:
- name: validate-operator-configuration.dash0.com
clientConfig:
caBundle: {{ default "" ( $ca.Cert | b64enc ) }}
service:
name: {{ template "dash0-operator.chartName" . }}-webhook-service
namespace: {{ .Release.Namespace }}
path: /v1alpha1/validate/operator-configuration
admissionReviewVersions:
- v1
rules:
- apiGroups:
- operator.dash0.com
apiVersions:
- v1alpha1
operations:
- CREATE
- UPDATE
resources:
- dash0operatorconfigurations
sideEffects: None
timeoutSeconds: 5
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: {{ template "dash0-operator.chartName" . }}-monitoring-validator
labels:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,25 @@ tests:
- isNotNullOrEmpty:
path: webhooks[0].clientConfig.caBundle

- it: validating webhook for operator configuration resource should have caBundle set
documentSelector:
path: metadata.name
value: dash0-operator-operator-configuration-validator
asserts:
- isNotNullOrEmpty:
path: webhooks[0].clientConfig.caBundle

- it: validating webhook for operator configuration resource should have caBundle set also with custom settings
documentSelector:
path: metadata.name
value: dash0-operator-operator-configuration-validator
set:
operator:
webhookPort: 554
asserts:
- isNotNullOrEmpty:
path: webhooks[0].clientConfig.caBundle

- it: validating webhook for monitoring resource should have caBundle set
documentSelector:
path: metadata.name
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc.
// SPDX-License-Identifier: Apache-2.0

package webhooks

import (
"context"
"net/http"

ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

dash0v1alpha1 "github.com/dash0hq/dash0-operator/api/dash0monitoring/v1alpha1"
)

type OperatorConfigurationValidationWebhookHandler struct {
Client client.Client
}

func (h *OperatorConfigurationValidationWebhookHandler) SetupWebhookWithManager(mgr ctrl.Manager) error {
webhook := &admission.Webhook{
Handler: h,
}

handler, err := admission.StandaloneWebhook(webhook, admission.StandaloneOptions{})
if err != nil {
return err
}
mgr.GetWebhookServer().Register("/v1alpha1/validate/operator-configuration", handler)

return nil
}

func (h *OperatorConfigurationValidationWebhookHandler) Handle(_ context.Context, request admission.Request) admission.Response {
operatorConfigurationResource := &dash0v1alpha1.Dash0OperatorConfiguration{}
if _, _, err := decoder.Decode(request.Object.Raw, nil, operatorConfigurationResource); err != nil {
return admission.Errored(http.StatusBadRequest, err)
}

if operatorConfigurationResource.Spec.SelfMonitoring.Enabled && operatorConfigurationResource.Spec.Export == nil {
return admission.Denied(
"The provided Dash0 operator configuration resource has self-monitoring enabled, but it does not have an " +
"export configuration. Either disable self-monitoring or provide an export configuration for self-" +
"monitoring telemetry.")

}
return admission.Allowed("")
}

0 comments on commit ff7f74c

Please sign in to comment.