From 83bae5fd87bdddd907d3cad0a43bd8e8933ff4b6 Mon Sep 17 00:00:00 2001 From: Yauheni Kaliuta Date: Thu, 9 Nov 2023 17:06:54 +0200 Subject: [PATCH] DSC, DSCI: webhook: implement one instance enforcing The webhook is written with the idea to handle both Create and Update requests (configured in config/webhook/manifests.yaml), but at the moment only duplication check on Create is implemented. Implements the logic which is done now on reconcile time [1] (same for DSCI). It checks for 0 instances, not 1, since when the webhook is running the object has not been created yet. Means if it's 1 then it handles request to create a second one. It could be probably possible to use generics but does not make a lot of sense for such a simple case. Closes: #693 [1] https://github.com/opendatahub-io/opendatahub-operator/blob/incubation/controllers/datasciencecluster/datasciencecluster_controller.go#L98 Signed-off-by: Yauheni Kaliuta --- controllers/webhook/webhook.go | 52 +++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/controllers/webhook/webhook.go b/controllers/webhook/webhook.go index 07b6d63c2ad..08f58635613 100644 --- a/controllers/webhook/webhook.go +++ b/controllers/webhook/webhook.go @@ -59,6 +59,56 @@ func (w *OpenDataHubWebhook) InjectClient(c client.Client) error { return nil } +func (w *OpenDataHubWebhook) checkDupCreation(ctx context.Context, req admission.Request) admission.Response { + var listLen int + var err error + + if req.Operation != admissionv1.Create { + return admission.Allowed(fmt.Sprintf("duplication check: skipping %v request", req.Operation)) + } + + switch req.Kind.Kind { + case "DataScienceCluster": + instances := &dsc.DataScienceClusterList{} + err = w.client.List(ctx, instances) + listLen = len(instances.Items) + + case "DSCInitialization": + instances := &dsci.DSCInitializationList{} + err = w.client.List(ctx, instances) + listLen = len(instances.Items) + + default: + log.Info("Got wrong kind %s", req.Kind.Kind) + return admission.Errored(http.StatusBadRequest, nil) + } + + if err != nil { + return admission.Errored(http.StatusBadRequest, err) + } + + // if listLen == 1 now creation of #2 is being handled + if listLen > 0 { + return admission.Denied(fmt.Sprintf("Only one instance of %s object is allowed", req.Kind.Kind)) + } + + return admission.Allowed(fmt.Sprintf("%s duplication check passed", req.Kind.Kind)) +} + func (w *OpenDataHubWebhook) Handle(ctx context.Context, req admission.Request) admission.Response { - return admission.ValidationResponse(true, "") + var resp admission.Response + + // Handle only Create and Update + if req.Operation == admissionv1.Delete || req.Operation == admissionv1.Connect { + msg := fmt.Sprintf("ODH skipping %v request", req.Operation) + log.Info(msg) + return admission.Allowed(msg) + } + + resp = w.checkDupCreation(ctx, req) + if !resp.Allowed { + return resp + } + + return admission.Allowed(fmt.Sprintf("%s allowed", req.Kind.Kind)) }