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.
For more detailed documentation check the docs.
Add dependency to you project:
<dependency>
<groupId>io.javaoperatorsdk</groupId>
<artifactId>kubernetes-webhooks-framework-core</artifactId>
<version>${josdk.webhooks.version}</version>
</dependency>
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 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);
}