Skip to content

Commit

Permalink
feat(model): use Object instead of KubernetesResource for raw types
Browse files Browse the repository at this point in the history
Signed-off-by: Marc Nuri <[email protected]>
  • Loading branch information
manusa committed Sep 5, 2024
1 parent eec18ee commit dc2dcde
Show file tree
Hide file tree
Showing 60 changed files with 1,872 additions and 1,433 deletions.
4 changes: 0 additions & 4 deletions junit/kube-api-test/core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,6 @@
<artifactId>bcprov-jdk18on</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.javaoperatorsdk</groupId>
<artifactId>kubernetes-webhooks-framework-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@
import io.fabric8.kubeapitest.cert.CertManager;
import io.fabric8.kubeapitest.junit.EnableKubeAPIServer;
import io.fabric8.kubeapitest.junit.KubeConfig;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.admission.v1.AdmissionRequest;
import io.fabric8.kubernetes.api.model.admission.v1.AdmissionReview;
import io.fabric8.kubernetes.api.model.admission.v1.AdmissionReviewBuilder;
import io.fabric8.kubernetes.api.model.admissionregistration.v1.MutatingWebhookConfiguration;
import io.fabric8.kubernetes.api.model.networking.v1.*;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.javaoperatorsdk.webhook.admission.AdmissionController;
import io.fabric8.zjsonpatch.JsonDiff;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.bouncycastle.asn1.x509.GeneralName;
Expand Down Expand Up @@ -57,7 +60,8 @@
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.HashMap;
import java.util.Collections;
import java.util.Objects;

import static org.assertj.core.api.Assertions.assertThat;

Expand All @@ -76,31 +80,19 @@ class KubernetesMutationHookHandlingTest {
private static final Logger log = LoggerFactory.getLogger(KubernetesMutationHookHandlingTest.class);

public static final String PASSWORD = "secret";
public static final String TEST_LABEL_KEY = "test-label";
public static final String TEST_LABEL_VALUE = "mutation-test";

static File certFile = new File("target", "mutation.crt");
// server that handles mutation hooks
static Server server = new Server();

// using https://github.com/java-operator-sdk/kubernetes-webooks-framework framework to implement
// the response
static AdmissionController<Ingress> mutationController = new AdmissionController<>((resource, operation) -> {
if (resource.getMetadata().getLabels() == null) {
resource.getMetadata().setLabels(new HashMap<>());
}
resource.getMetadata().getLabels().putIfAbsent(TEST_LABEL_KEY, TEST_LABEL_VALUE);
return resource;
});

@Test
void handleMutatingWebhook() {
var client = new KubernetesClientBuilder().withConfig(Config.fromKubeconfig(kubeConfig)).build();
applyConfig(client);

var ingress = client.resource(testIngress()).create();

assertThat(ingress.getMetadata().getLabels()).containsEntry(TEST_LABEL_KEY, TEST_LABEL_VALUE);
assertThat(ingress.getMetadata().getLabels()).containsEntry("test", "mutation");
}

@BeforeAll
Expand All @@ -112,15 +104,33 @@ public void handle(String s, Request request, HttpServletRequest httpServletRequ
HttpServletResponse httpServletResponse) {
try {
request.setHandled(true);
AdmissionReview admissionReview = Serialization.unmarshal(httpServletRequest.getInputStream());

var response = mutationController.handle(admissionReview);

var out = httpServletResponse.getWriter();
httpServletResponse.setContentType("application/json");
httpServletResponse.setCharacterEncoding(StandardCharsets.UTF_8.toString());
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
out.println(Serialization.asJson(response));
final AdmissionReview requestedAdmissionReview = Serialization.unmarshal(httpServletRequest.getInputStream());
final AdmissionRequest admissionRequest = requestedAdmissionReview.getRequest();
var originalResource = Objects.equals("DELETE", admissionRequest.getOperation())
? admissionRequest.getOldObject()
: admissionRequest.getObject();
if (originalResource instanceof HasMetadata) {
var originalResourceJson = Serialization.jsonMapper().valueToTree(originalResource);
(((HasMetadata) originalResource)).getMetadata().setLabels(Collections.singletonMap("test", "mutation"));
var editedResourceJson = Serialization.jsonMapper().valueToTree(originalResource);
final AdmissionReview responseAdmissionReview = new AdmissionReviewBuilder()
.withNewResponse()
.withAllowed()
.withPatchType("JSONPatch")
.withPatch(Base64.getEncoder().encodeToString(
JsonDiff.asJson(originalResourceJson, editedResourceJson).toString().getBytes(StandardCharsets.UTF_8)))
.withUid(admissionRequest.getUid())
.endResponse()
.build();

var out = httpServletResponse.getWriter();
httpServletResponse.setContentType("application/json");
httpServletResponse.setCharacterEncoding(StandardCharsets.UTF_8.toString());
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
out.println(Serialization.asJson(responseAdmissionReview));
} else {
httpServletResponse.setStatus(422);
}
} catch (Exception e) {
log.error("Error in webhook", e);
throw new RuntimeException(e);
Expand Down
Loading

0 comments on commit dc2dcde

Please sign in to comment.