Skip to content

Commit

Permalink
webhook: implement one instance enforcing
Browse files Browse the repository at this point in the history
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: opendatahub-io#693

[1] https://github.com/opendatahub-io/opendatahub-operator/blob/incubation/controllers/datasciencecluster/datasciencecluster_controller.go#L98

Signed-off-by: Yauheni Kaliuta <ykaliuta@redhat.com>
  • Loading branch information
ykaliuta committed Feb 16, 2024
1 parent 09f4d7a commit f8eeeec
Showing 1 changed file with 51 additions and 4 deletions.
55 changes: 51 additions & 4 deletions controllers/webhook/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@ import (
"net/http"

admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

dsc "github.com/opendatahub-io/opendatahub-operator/v2/apis/datasciencecluster/v1"
dsci "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/v1"
)

var log = ctrl.Log.WithName("odh-controller-webhook")
Expand Down Expand Up @@ -59,6 +58,54 @@ func (w *OpenDataHubWebhook) InjectClient(c client.Client) error {
return nil
}

func (w *OpenDataHubWebhook) checkDupCreation(ctx context.Context, req admission.Request) admission.Response {
if req.Operation != admissionv1.Create {
return admission.Allowed(fmt.Sprintf("duplication check: skipping %v request", req.Operation))
}

switch req.Kind.Kind {
case "DataScienceCluster":
case "DSCInitialization":
default:
log.Info("Got wrong kind", "kind", req.Kind.Kind)
return admission.Errored(http.StatusBadRequest, nil)
}

gvk := schema.GroupVersionKind{
Group: req.Kind.Group,
Version: req.Kind.Version,
Kind: req.Kind.Kind,
}

list := &unstructured.UnstructuredList{}
list.SetGroupVersionKind(gvk)

if err := w.client.List(ctx, list); err != nil {
return admission.Errored(http.StatusBadRequest, err)
}

// if len == 1 now creation of #2 is being handled
if len(list.Items) > 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))
}

0 comments on commit f8eeeec

Please sign in to comment.