Skip to content

operator-framework/josdk-webhooks

Repository files navigation

kubernetes-webhooks-framework

Framework and tooling to support implementing dynamic admission controllers and conversion hooks for Kubernetes in Java. Supports both quarkus and spring boot. Both sync and async programing models.

Documentation

For more detailed documentation check the docs.

Sample Usage

Add dependency to you project:

<dependency>
  <groupId>io.javaoperatorsdk</groupId>
  <artifactId>kubernetes-webhooks-framework-core</artifactId>
  <version>${josdk.webhooks.version}</version>
</dependency>

Dynamic Admission Controllers

Defining a mutation or validation controller is as simple as:

  @Singleton
  @Named(MUTATING_CONTROLLER)
  public AdmissionController<Ingress> mutatingController() {
    return new AdmissionController<>((resource, operation) -> {
      if (resource.getMetadata().getLabels() == null) {
        resource.getMetadata().setLabels(new HashMap<>());
      }
      resource.getMetadata().getLabels().putIfAbsent(APP_NAME_LABEL_KEY, "mutation-test");
      return resource;
    });
  }
  
  @Singleton
  @Named(VALIDATING_CONTROLLER)
  public AdmissionController<Ingress> validatingController() {
    return new AdmissionController<>((resource, operation) -> {
      if (resource.getMetadata().getLabels() == null
              || resource.getMetadata().getLabels().get(APP_NAME_LABEL_KEY) == null) {
        throw new NotAllowedException("Missing label: " + APP_NAME_LABEL_KEY);
      }
    });
  }

What can be simply used in an endpoint:

  @POST
  @Path(MUTATE_PATH)
  @Consumes(MediaType.APPLICATION_JSON)
  @Produces(MediaType.APPLICATION_JSON)
  public AdmissionReview mutate(AdmissionReview admissionReview) {
    return mutationController.handle(admissionReview);
  }

  @POST
  @Path(VALIDATE_PATH)
  @Consumes(MediaType.APPLICATION_JSON)
  @Produces(MediaType.APPLICATION_JSON)
  public AdmissionReview validate(AdmissionReview admissionReview) {
    return validationController.handle(admissionReview);
  }

See samples also for details.

Conversion Hooks

Conversion hooks follows the same patter described in Kuberbuilder, thus first converts the custom resource from actual version to a hub, and as next step from the hub to the target resource version.

To create the controller register mappers :

  @Singleton
  public ConversionController conversionController() {
    var controller = new ConversionController();
    controller.registerMapper(new V1Mapper());
    controller.registerMapper(new V2Mapper());
    return controller;
  }

and use the controllers in the endpoint:

  @PostMapping(CONVERSION_PATH)
  @ResponseBody
  public ConversionReview convert(@RequestBody ConversionReview conversionReview) {
    return conversionController.handle(conversionReview);
  }