Skip to content

Commit

Permalink
- Initial API server based implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
jjzazuet committed Aug 25, 2024
1 parent 2dfcf66 commit 2c108c5
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 116 deletions.
1 change: 0 additions & 1 deletion bl-k8s-rt/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ val api by configurations
val k8s129 = ":bl-k8s129"

dependencies {
api("io.github.java-diff-utils:java-diff-utils:4.12")
api(project(":bl-codegen"))
compileOnly(project(k8s129))
testImplementation(project(k8s129))
Expand Down
11 changes: 7 additions & 4 deletions bl-k8s-rt/src/main/java/io/vacco/beleth/rt/BlKubeRt.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ public Set<BlResource> buildResourceSet(String packageName) {
for (var manifest : manifests) {
var objCopy = ctx.fromJson(ctx.toJson(manifest), manifest.getClass());
var objCopyMeta = pointerOnObject(objCopy, format("/%s", kMetadata));
var blId = String.format("%s.%s", packageName, Integer.toHexString(ctx.toJson(objCopyMeta).hashCode()));
var blId = format("%s.%s", packageName, Integer.toHexString(ctx.toJson(objCopyMeta).hashCode()));
var blHash = Integer.toHexString(ctx.toJson(objCopy).hashCode());
var kind = requireNonNull(pointerOnObject(manifest, "/kind")).toString().toLowerCase() + "s";
var rType = BlResourceType.of("", kind, false);
injectMeta(objCopy, kBl, Boolean.TRUE.toString());
injectMeta(objCopy, kBlId, blId);
idx.add(resourceOf(blId, objCopy).withType(rType));
injectMeta(objCopy, kBlHash, blHash);
var res = resourceOf(blId, objCopy).withType(rType);
idx.add(res);
}
return idx;
}
Expand All @@ -59,8 +62,8 @@ public void commit(String packageName) {
kubeApi.create(res);
}
for (var res : chg.toUpdate) {
var p = resourcePairOf(res.blId, local, cluster, kubeApi.ctx);
if (!p.patch.getDeltas().isEmpty()) {
var p = resourcePairOf(res.blId, local, cluster);
if (!p.manifest0.blHash.equals(p.manifest1.blHash)) {
kubeApi.update(p.manifest0);
}
}
Expand Down
10 changes: 8 additions & 2 deletions bl-k8s-rt/src/main/java/io/vacco/beleth/rt/impl/BlKubeApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ public String createUrlFor(BlResourceType type, String namespace) {
}
return String.format("%s/%s", type.apiPath, type.name);
} else {
return String.format("%snamespaces/%s/%s", type.apiPath.replace(type.name, ""), namespace, type.name);
return String.format(
"%s/namespaces/%s/%s", type.apiPath.replace(type.name, ""),
namespace != null ? namespace : "default", type.name
).replace("//", "/");
}
}

Expand All @@ -141,7 +144,10 @@ public String updateUrlFor(BlResourceType type, String namespace, String resourc
}
return String.format("%s/%s/%s", type.apiPath, type.name, resourceName);
} else {
return String.format("%snamespaces/%s/%s/%s", type.apiPath.replace(type.name, ""), namespace, type.name, resourceName);
return String.format(
"%s/namespaces/%s/%s/%s", type.apiPath.replace(type.name, ""),
namespace != null ? namespace : "default", type.name, resourceName
).replace("//", "/");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
public class BlResource implements Comparable<BlResource> {

public Object manifest;
public String blId, name, nameSpace;
public String blId, blHash, name, nameSpace;
public BlResourceType type;

public BlResource withType(BlResourceType type) {
Expand All @@ -19,17 +19,17 @@ public BlResource withType(BlResourceType type) {

@Override public boolean equals(Object obj) {
return obj instanceof BlResource
&& ((BlResource) obj).blId.equals(this.blId);
&& ((BlResource) obj).blHash.equals(this.blHash);
}

@Override public int hashCode() {
return this.blId.hashCode();
return this.blHash.hashCode();
}

@Override public String toString() {
return String.format(
"[%s, %s, %s, %s, %s]",
blId,
"[%s, %s, %s, %s, %s, %s]",
blId, blHash,
manifest != null ? manifest.getClass().getSimpleName() : "?",
type != null ? type.name : "?",
name,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
package io.vacco.beleth.rt.schema;

import com.github.difflib.patch.Patch;
import java.util.List;
import java.util.Objects;

public class BlResourcePair {

public BlResource manifest0, manifest1;
public List<String> diff0, diff1;
public Patch<String> patch;

public static BlResourcePair of(BlResource manifest0, BlResource manifest1,
List<String> diff0, List<String> diff1,
Patch<String> patch) {
public static BlResourcePair of(BlResource manifest0, BlResource manifest1) {
var p = new BlResourcePair();
p.manifest0 = Objects.requireNonNull(manifest0);
p.manifest1 = Objects.requireNonNull(manifest1);
p.diff0 = Objects.requireNonNull(diff0);
p.diff1 = Objects.requireNonNull(diff1);
p.patch = Objects.requireNonNull(patch);
return p;
}

Expand Down
65 changes: 0 additions & 65 deletions bl-k8s-rt/src/main/java/io/vacco/beleth/rt/util/BlIo.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.vacco.beleth.rt.util;

import com.google.gson.JsonElement;
import java.net.*;
import javax.net.ssl.*;
import java.net.http.*;
Expand Down Expand Up @@ -104,45 +103,6 @@ public static Object pointerOnMap(Map root, String pointer) {
}
}

@SuppressWarnings("rawtypes")
public static boolean deleteFromMap(Map root, String pointer) {
var tokens = pointer.split("/");
Object current = root;
try {
for (int i = 0; i < tokens.length; i++) {
var token = tokens[i];
if (token.isEmpty()) continue;
if (current instanceof Map) {
@SuppressWarnings("unchecked")
var currentMap = (Map<String, Object>) current;
if (i == tokens.length - 1) {
currentMap.remove(token);
return true; // Deletion successful
} else {
current = currentMap.get(token);
}
} else if (current instanceof List) {
int index = Integer.parseInt(token);
var currentList = (List<?>) current;
if (i == tokens.length - 1) {
currentList.remove(index);
return true; // Deletion successful
} else {
current = currentList.get(index);
}
} else {
return false; // Path does not lead to a valid Map or List
}
if (current == null) {
return false; // Path doesn't exist
}
}
} catch (Exception e) {
return false;
}
return false; // deletion did not happen
}

public static Object pointerOnObject(Object root, String pointer) {
var tokens = pointer.split("/");
Object current = root;
Expand All @@ -162,29 +122,4 @@ public static Object pointerOnObject(Object root, String pointer) {
}
}

private static void extractPathsTail(JsonElement element, String currentPath, Set<String> paths) {
if (element.isJsonObject()) {
var obj = element.getAsJsonObject();
for (var key : obj.keySet()) {
extractPathsTail(obj.get(key), currentPath.isEmpty() ? key : currentPath + "." + key, paths);
}
} else if (element.isJsonArray()) {
var arr = element.getAsJsonArray();
for (int i = 0; i < arr.size(); i++) {
extractPathsTail(arr.get(i), currentPath + "[" + i + "]", paths);
}
} else if (element.isJsonPrimitive()) {
var prim = element.getAsJsonPrimitive();
paths.add(currentPath + " = " + prim.toString());
} else if (element.isJsonNull()) {
paths.add(currentPath + " = null");
}
}

public static List<String> extractPaths(JsonElement root) {
var paths = new TreeSet<String>();
extractPathsTail(root, "", paths);
return new ArrayList<>(paths);
}

}
41 changes: 12 additions & 29 deletions bl-k8s-rt/src/main/java/io/vacco/beleth/rt/util/BlResources.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package io.vacco.beleth.rt.util;

import com.github.difflib.DiffUtils;
import io.k8s.apimachinery.pkg.apis.meta.v1.objectmeta.Labels;
import io.vacco.beleth.rt.schema.BlResource;
import io.vacco.beleth.rt.schema.BlResourcePair;
import io.vacco.beleth.xform.BlDocumentContext;
import java.util.*;

import static java.lang.String.format;
Expand All @@ -17,7 +15,8 @@ public class BlResources {
kMetadata = "metadata",
kLabels = "labels",
kBl = "beleth.io",
kBlId = "beleth.io/id";
kBlId = "beleth.io.id",
kBlHash = "beleth.io.hash";

@SuppressWarnings({"rawtypes"})
public static String idOf(Map m) {
Expand Down Expand Up @@ -80,22 +79,25 @@ public static boolean isValidPackageName(String packageName) {
return true;
}

@SuppressWarnings("rawtypes")
public static BlResource resourceOf(String blId, Object manifest) {
var r = new BlResource();
r.blId = Objects.requireNonNull(blId);
r.manifest = Objects.requireNonNull(manifest);

if (manifest instanceof Map) {
@SuppressWarnings("rawtypes")
var m = (Map) manifest;
var ns = pointerOnMap(m, "metadata/namespace");
r.name = requireNonNull(pointerOnMap(m, "metadata/name")).toString();
r.blHash = requireNonNull(pointerOnMap(m, format("/metadata/labels/%s", kBlHash))).toString();
r.name = requireNonNull(pointerOnMap(m, "/metadata/name")).toString();
if (ns != null) {
r.nameSpace = ns.toString();
}
} else {
var ns = pointerOnObject(manifest, "metadata/namespace");
r.name = requireNonNull(pointerOnObject(manifest, "metadata/name")).toString();
var ns = pointerOnObject(manifest, "/metadata/namespace");
var labels = (Map) requireNonNull(pointerOnObject(manifest, "/metadata/labels"));
r.blHash = labels.get(kBlHash).toString();
r.name = requireNonNull(pointerOnObject(manifest, "/metadata/name")).toString();
if (ns != null) {
r.nameSpace = ns.toString();
}
Expand All @@ -104,30 +106,11 @@ public static BlResource resourceOf(String blId, Object manifest) {
return r;
}

public static BlResourcePair resourcePairOf(String blId, Set<BlResource> local, Set<BlResource> cluster,
BlDocumentContext ctx) {
@SuppressWarnings("rawtypes")
public static BlResourcePair resourcePairOf(String blId, Set<BlResource> local, Set<BlResource> cluster) {
var r0 = local.stream().filter(r -> r.blId.equals(blId)).findFirst().orElseThrow();
var r1 = cluster.stream().filter(r -> r.blId.equals(blId)).findFirst().orElseThrow();

@SuppressWarnings("rawtypes")
var m1 = (Map) r1.manifest;
deleteFromMap(m1, "/metadata/uid");
deleteFromMap(m1, "/metadata/resourceVersion");
deleteFromMap(m1, "/metadata/creationTimestamp");
deleteFromMap(m1, "/metadata/managedFields");
deleteFromMap(m1, "/spec/finalizers");
deleteFromMap(m1, "/status");

var d0 = extractPaths(ctx.toJsonElement(r0.manifest));
var d1 = extractPaths(ctx.toJsonElement(r1.manifest));

d1.add(0, d0.get(1)); // kind
d1.add(0, d0.get(0)); // apiVersion
d1.stream()
.filter(t -> t.startsWith("metadata.labels.kubernetes.io/metadata.name"))
.findFirst().ifPresent(d1::remove);

return BlResourcePair.of(r0, r1, d0, d1, DiffUtils.diff(d0, d1));
return BlResourcePair.of(r0, r1);
}

}

0 comments on commit 2c108c5

Please sign in to comment.