Skip to content

Commit

Permalink
feat(webhook): queue events for instrumentation success
Browse files Browse the repository at this point in the history
  • Loading branch information
basti1302 committed May 16, 2024
1 parent ed19fbc commit bd67886
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 42 deletions.
4 changes: 2 additions & 2 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ func startOperatorManager(
setupLog.Info("Dash0 reconciler has been set up.")

if os.Getenv("ENABLE_WEBHOOKS") != "false" {
if err = (&dash0webhook.WebhookHandler{
EventRecorder: mgr.GetEventRecorderFor("dash0-webhook"),
if err = (&dash0webhook.Handler{
Recorder: mgr.GetEventRecorderFor("dash0-webhook"),
}).SetupWebhookWithManager(mgr); err != nil {
return fmt.Errorf("unable to create the Dash0 webhook: %w", err)
}
Expand Down
4 changes: 2 additions & 2 deletions internal/controller/dash0_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,10 @@ func (r *Dash0Reconciler) modifyExistingResources(ctx context.Context, dash0Cust
}, &logger)

if err != nil {
queueFailedInstrumentationEvent(r.Recorder, &deployment, "controller", err)
QueueFailedInstrumentationEvent(r.Recorder, &deployment, "controller", err)
return fmt.Errorf("Error when modifying deployment %s/%s: %w", deployment.GetNamespace(), deployment.GetName(), err)
} else {
queueSuccessfulInstrumentationEvent(r.Recorder, &deployment, "controller")
QueueSuccessfulInstrumentationEvent(r.Recorder, &deployment, "controller")
logger.Info("Added instrumentation to deployment", "name", deployment.Name)
}
}
Expand Down
16 changes: 1 addition & 15 deletions internal/controller/dash0_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ var _ = Describe("Dash0 Controller", func() {
NodeOptionsEnvVarIdx: 0,
}},
})
verifySuccessEvent(ctx, namespace, deploymentName)
VerifySuccessEvent(ctx, clientset, namespace, deploymentName, "controller")
})
})
})
Expand All @@ -155,17 +155,3 @@ func verifyStatusConditions(ctx context.Context, typeNamespacedName types.Namesp
})
return available
}

func verifySuccessEvent(ctx context.Context, namespace string, resourceName string) {
allEvents, err := clientset.CoreV1().Events(namespace).List(ctx, metav1.ListOptions{})
Expect(err).NotTo(HaveOccurred())
Expect(allEvents.Items).To(HaveLen(1))
Expect(allEvents.Items).To(
ContainElement(
MatchEvent(
namespace,
resourceName,
operatorv1alpha1.ReasonSuccessfulInstrumentation,
"Dash0 instrumentation by controller has been successful.",
)))
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2024 Dash0 Inc.
// SPDX-License-Identifier: Apache-2.0

package controller
package util

import (
"fmt"
Expand All @@ -13,7 +13,7 @@ import (
operatorv1alpha1 "github.com/dash0hq/dash0-operator/api/v1alpha1"
)

func queueSuccessfulInstrumentationEvent(eventRecorder record.EventRecorder, resource runtime.Object, eventSource string) {
func QueueSuccessfulInstrumentationEvent(eventRecorder record.EventRecorder, resource runtime.Object, eventSource string) {
eventRecorder.Event(
resource,
corev1.EventTypeNormal,
Expand All @@ -22,7 +22,7 @@ func queueSuccessfulInstrumentationEvent(eventRecorder record.EventRecorder, res
)
}

func queueFailedInstrumentationEvent(eventRecorder record.EventRecorder, resource runtime.Object, eventSource string, err error) {
func QueueFailedInstrumentationEvent(eventRecorder record.EventRecorder, resource runtime.Object, eventSource string, err error) {
eventRecorder.Event(
resource,
corev1.EventTypeWarning,
Expand Down
29 changes: 10 additions & 19 deletions internal/webhook/dash0_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,28 @@ import (
"net/http"

"github.com/dash0hq/dash0-operator/internal/k8sresources"
. "github.com/dash0hq/dash0-operator/internal/util"

appsv1 "k8s.io/api/apps/v1"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/record"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)


var (
log = logf.Log.WithName("dash0-webhook")
decoder = scheme.Codecs.UniversalDecoder()
)

type WebhookHandler struct {
client.Client
*admission.Decoder
record.EventRecorder
type Handler struct {
Recorder record.EventRecorder
}

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

handler, err := admission.StandaloneWebhook(webhook, admission.StandaloneOptions{})
Expand All @@ -45,7 +43,7 @@ func (wh *WebhookHandler) SetupWebhookWithManager(mgr ctrl.Manager) error {
return nil
}

func (wh *WebhookHandler) Handle(ctx context.Context, request admission.Request) admission.Response {
func (h *Handler) Handle(ctx context.Context, request admission.Request) admission.Response {
logger := log.WithValues("gvk", request.Kind, "namespace", request.Namespace, "name", request.Name)
logger.Info("incoming admission request")

Expand All @@ -71,19 +69,12 @@ func (wh *WebhookHandler) Handle(ctx context.Context, request admission.Request)
return admission.Allowed(fmt.Errorf("error when marshalling modfied resource to JSON: %w", err).Error())
}

if hasBeenModified {
QueueSuccessfulInstrumentationEvent(h.Recorder, deployment, "webhook")
}
return admission.PatchResponseFromRaw(request.Object.Raw, marshalled)
} else {
logger.Info("resource type not supported", "group", group, "version", version, "kind", kind)
return admission.Allowed("unknown resource type")
}
}

func (wh *WebhookHandler) InjectClient(c client.Client) error {
wh.Client = c
return nil
}

func (wh *WebhookHandler) InjectDecoder(d *admission.Decoder) error {
wh.Decoder = d
return nil
}
1 change: 1 addition & 0 deletions internal/webhook/dash0_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ var _ = Describe("Dash0 Webhook", func() {
},
},
})
VerifySuccessEvent(ctx, clientset, TestNamespaceName, DeploymentName, "webhook")
})

It("should update existing Dash artifacts in a new deployment", func() {
Expand Down
10 changes: 9 additions & 1 deletion internal/webhook/webhook_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
operatorv1alpha1 "github.com/dash0hq/dash0-operator/api/v1alpha1"
admissionv1 "k8s.io/api/admission/v1"
apimachineryruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
ctrl "sigs.k8s.io/controller-runtime"
Expand All @@ -35,6 +36,7 @@ import (
var (
cfg *rest.Config
k8sClient client.Client
clientset *kubernetes.Clientset
testEnv *envtest.Environment
ctx context.Context
cancel context.CancelFunc
Expand Down Expand Up @@ -90,6 +92,10 @@ var _ = BeforeSuite(func() {
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient).NotTo(BeNil())

clientset, err = kubernetes.NewForConfig(cfg)
Expect(err).NotTo(HaveOccurred())
Expect(clientset).NotTo(BeNil())

By("setting up resources")
setupTestResources()

Expand All @@ -107,7 +113,9 @@ var _ = BeforeSuite(func() {
})
Expect(err).NotTo(HaveOccurred())

err = (&WebhookHandler{}).SetupWebhookWithManager(mgr)
err = (&Handler{
Recorder: mgr.GetEventRecorderFor("dash0-webhook"),
}).SetupWebhookWithManager(mgr)
Expect(err).NotTo(HaveOccurred())

//+kubebuilder:scaffold:webhook
Expand Down
25 changes: 25 additions & 0 deletions test/util/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@
package util

import (
"context"
"fmt"
"os"
"os/exec"
"strings"

"github.com/dash0hq/dash0-operator/api/v1alpha1"
. "github.com/onsi/ginkgo/v2" //nolint:golint,revive
"github.com/onsi/gomega"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)

const (
Expand Down Expand Up @@ -125,3 +130,23 @@ func GetProjectDir() (string, error) {
wd = strings.Replace(wd, "/test/e2e", "", -1)
return wd, nil
}

func VerifySuccessEvent(
ctx context.Context,
clientset *kubernetes.Clientset,
namespace string,
resourceName string,
eventSource string,
) {
allEvents, err := clientset.CoreV1().Events(namespace).List(ctx, v1.ListOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(allEvents.Items).To(gomega.HaveLen(1))
gomega.Expect(allEvents.Items).To(
gomega.ContainElement(
MatchEvent(
namespace,
resourceName,
v1alpha1.ReasonSuccessfulInstrumentation,
fmt.Sprintf("Dash0 instrumentation by %s has been successful.", eventSource),
)))
}

0 comments on commit bd67886

Please sign in to comment.