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 f153f89 commit 537140a
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.vacco.beleth.xform;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import jakarta.json.*;
import org.slf4j.*;
import org.yaml.snakeyaml.*;
Expand Down Expand Up @@ -42,6 +43,10 @@ public String toJson(Object o) {
return g.toJson(o);
}

public JsonElement toJsonElement(Object o) {
return g.toJsonTree(o);
}

public JsonObject loadTreeFromJson(URL json) {
try {
try (var jrd = Json.createReader(new InputStreamReader(json.openStream()))) {
Expand Down
30 changes: 15 additions & 15 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 @@ -7,8 +7,8 @@

import static java.util.Objects.requireNonNull;
import static io.vacco.beleth.rt.impl.BlKubeIo.pointerOnObject;
import static io.vacco.beleth.rt.schema.BlKubeResources.*;
import static io.vacco.beleth.rt.schema.BlKubeResourceTypes.*;
import static io.vacco.beleth.rt.schema.BlResources.*;
import static io.vacco.beleth.rt.schema.BlResourceTypes.*;

public class BlKubeRt {

Expand All @@ -22,16 +22,16 @@ public BlKubeRt(String apiServerUrl, String apiToken) {
this.kubeApi = new BlKubeApi(apiServerUrl, apiToken, ApiServerTimeoutMs);
}

public Set<BlKubeResource> buildResourceSet(String packageName) {
public Set<BlResource> buildResourceSet(String packageName) {
if (!isValidPackageName(packageName)) {
throw new IllegalArgumentException("Invalid package name: " + packageName);
}
var idx = new LinkedHashSet<BlKubeResource>();
var idx = new LinkedHashSet<BlResource>();
for (var manifest : manifests) {
var objCopy = ctx.fromJson(ctx.toJson(manifest), manifest.getClass());
var blId = String.format("%s.%s", packageName, Integer.toHexString(ctx.toJson(objCopy).hashCode()));
var kind = requireNonNull(pointerOnObject(manifest, "/kind")).toString().toLowerCase() + "s";
var rType = BlKubeResourceType.of("", kind, false);
var rType = BlResourceType.of("", kind, false);
injectMeta(objCopy, kBl, Boolean.TRUE.toString());
injectMeta(objCopy, kBlId, blId);
idx.add(resourceOf(blId, objCopy).withType(rType));
Expand All @@ -45,22 +45,22 @@ public BlKubeRt add(Object manifest) {
}

public void commit(String packageName) {
var diff = new BlResourceDiff().update(
buildResourceSet(packageName),
this.kubeApi.resourceSet(packageName)
);
var local = buildResourceSet(packageName);
var cluster = this.kubeApi.resourceSet(packageName);
var chg = new BlChangeSet().update(local, cluster);

diff.toAdd.sort(Comparator.comparingInt(r -> priorityOf(r.type)));
diff.toUpdate.sort(Comparator.comparingInt(r -> priorityOf(r.type)));
diff.toDelete.sort(Comparator.comparingInt(r -> -priorityOf(r.type)));
chg.toAdd.sort(Comparator.comparingInt(r -> priorityOf(r.type)));
chg.toUpdate.sort(Comparator.comparingInt(r -> priorityOf(r.type)));
chg.toDelete.sort(Comparator.comparingInt(r -> -priorityOf(r.type)));

for (var res : diff.toAdd) {
for (var res : chg.toAdd) {
kubeApi.create(res);
}
for (var res : diff.toUpdate) {
for (var res : chg.toUpdate) {
var p = resourcePairOf(res.blId, local, cluster, kubeApi.ctx);
System.out.println("lol?");
}
for (var res : diff.toDelete) {
for (var res : chg.toDelete) {
kubeApi.delete(res);
}
}
Expand Down
28 changes: 14 additions & 14 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 @@ -13,8 +13,8 @@
import static java.util.Objects.requireNonNull;
import static com.google.gson.JsonParser.parseString;
import static io.vacco.beleth.rt.impl.BlKubeIo.*;
import static io.vacco.beleth.rt.schema.BlKubeResources.*;
import static io.vacco.beleth.rt.schema.BlKubeResourceTypes.internalTypes;
import static io.vacco.beleth.rt.schema.BlResources.*;
import static io.vacco.beleth.rt.schema.BlResourceTypes.internalTypes;

public class BlKubeApi {

Expand All @@ -27,7 +27,7 @@ public class BlKubeApi {
private final String apiToken;

private final URI apiServerUri;
private final Set<BlKubeResourceType> clusterResourceTypes = new HashSet<>();
private final Set<BlResourceType> clusterResourceTypes = new HashSet<>();

public BlKubeApi(String apiServerUri, String apiToken, int timeoutMs) {
this.timeoutMs = timeoutMs;
Expand All @@ -49,7 +49,7 @@ private void addResource(String apiPath, JsonElement resourceElement) {
var nameSpaced = resource.get("namespaced").getAsBoolean();
var name = resource.get("name").getAsString();
if (!name.contains("/") && !internalTypes.contains(name)) {
this.clusterResourceTypes.add(BlKubeResourceType.of(apiPath, name, nameSpaced));
this.clusterResourceTypes.add(BlResourceType.of(apiPath, name, nameSpaced));
}
}

Expand Down Expand Up @@ -95,7 +95,7 @@ public void loadResourceTypes() {
}

@SuppressWarnings("rawtypes")
private List<BlKubeResource> extractResourcesFrom(String resourceListJson, BlKubeResourceType type) {
private List<BlResource> extractResourcesFrom(String resourceListJson, BlResourceType type) {
var idx = ctx.fromJson(resourceListJson, Map.class);
if (idx != null) {
var items = (List<?>) idx.get("items");
Expand All @@ -109,7 +109,7 @@ private List<BlKubeResource> extractResourcesFrom(String resourceListJson, BlKub
return new ArrayList<>();
}

public String queryUrlFor(BlKubeResourceType type) {
public String queryUrlFor(BlResourceType type) {
return String.format(
"%s/%s?labelSelector=%s%s",
type.apiPath,
Expand All @@ -118,7 +118,7 @@ public String queryUrlFor(BlKubeResourceType type) {
);
}

public String createUrlFor(BlKubeResourceType type, String namespace) {
public String createUrlFor(BlResourceType type, String namespace) {
if (!type.nameSpaced) {
if (type.apiPath.contains(type.name)) {
return type.apiPath;
Expand All @@ -129,7 +129,7 @@ public String createUrlFor(BlKubeResourceType type, String namespace) {
}
}

public String deleteUrlFor(BlKubeResourceType type, String namespace, String resourceName) {
public String deleteUrlFor(BlResourceType type, String namespace, String resourceName) {
if (!type.nameSpaced) {
if (type.apiPath.contains(type.name)) {
return format("%s/%s", type.apiPath, resourceName);
Expand All @@ -140,9 +140,9 @@ public String deleteUrlFor(BlKubeResourceType type, String namespace, String res
}
}

public Map<String, List<BlKubeResource>> resourceTypeIndex() {
public Map<String, List<BlResource>> resourceTypeIndex() {
this.loadResourceTypes();
var idx = new LinkedHashMap<String, List<BlKubeResource>>();
var idx = new LinkedHashMap<String, List<BlResource>>();
for (var rType : clusterResourceTypes) {
var queryUrl = queryUrlFor(rType);
try {
Expand All @@ -158,22 +158,22 @@ public Map<String, List<BlKubeResource>> resourceTypeIndex() {
return idx;
}

public Set<BlKubeResource> resourceSet(String packageName) {
public Set<BlResource> resourceSet(String packageName) {
var rtIdx = this.resourceTypeIndex();
return rtIdx.values().stream()
.flatMap(Collection::stream)
.filter(res -> res.blId.contains(packageName))
.collect(toSet());
}

private BlKubeResourceType resourceTypeOf(BlKubeResource res) {
private BlResourceType resourceTypeOf(BlResource res) {
return this.clusterResourceTypes.stream()
.filter(rt -> rt.name.equals(res.type.name))
.findFirst()
.orElseThrow();
}

public void create(BlKubeResource res) {
public void create(BlResource res) {
var url = createUrlFor(resourceTypeOf(res), res.nameSpace);
var body = ctx.toJson(res.manifest);
var result = doRequest(uri(apiServerUri, url), client, apiToken, POST, body, timeoutMs);
Expand All @@ -182,7 +182,7 @@ public void create(BlKubeResource res) {
}
}

public void delete(BlKubeResource res) {
public void delete(BlResource res) {
var url = deleteUrlFor(resourceTypeOf(res), res.nameSpace, res.name);
var body = ctx.toJson(res.manifest);
var result = doRequest(uri(apiServerUri, url), client, apiToken, DELETE, body, timeoutMs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
import java.util.List;
import java.util.Set;

public class BlResourceDiff {
public class BlChangeSet {

public List<BlKubeResource> toAdd;
public List<BlKubeResource> toUpdate;
public List<BlKubeResource> toDelete;
public List<BlResource> toAdd;
public List<BlResource> toUpdate;
public List<BlResource> toDelete;

public BlResourceDiff update(Set<BlKubeResource> localResourceSet, Set<BlKubeResource> clusterSet) {
public BlChangeSet update(Set<BlResource> localResourceSet, Set<BlResource> clusterSet) {
toAdd = new ArrayList<>(localResourceSet);
toAdd.removeAll(clusterSet);
toDelete = new ArrayList<>(clusterSet);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@

import java.util.Objects;

public class BlKubeResource implements Comparable<BlKubeResource> {
public class BlResource implements Comparable<BlResource> {

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

public BlKubeResource withType(BlKubeResourceType type) {
public BlResource withType(BlResourceType type) {
this.type = Objects.requireNonNull(type);
return this;
}

@Override public int compareTo(BlKubeResource o) {
@Override public int compareTo(BlResource o) {
return this.blId.compareTo(o.blId);
}

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

@Override public int hashCode() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
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) {
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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import java.util.Objects;

public class BlKubeResourceType implements Comparable<BlKubeResourceType> {
public class BlResourceType implements Comparable<BlResourceType> {

public String apiPath, name;
public boolean nameSpaced;
Expand All @@ -11,15 +11,15 @@ public String id() {
return String.format("%s|%s|%s", apiPath, name, nameSpaced);
}

@Override public int compareTo(BlKubeResourceType o) {
@Override public int compareTo(BlResourceType o) {
return this.id().compareTo(o.id());
}

@Override public boolean equals(Object obj) {
if (!(obj instanceof BlKubeResourceType)) {
if (!(obj instanceof BlResourceType)) {
return false;
}
return this.id().equals(((BlKubeResourceType) obj).id());
return this.id().equals(((BlResourceType) obj).id());
}

@Override public int hashCode() {
Expand All @@ -30,8 +30,8 @@ public String id() {
return this.id();
}

public static BlKubeResourceType of(String apiPath, String name, boolean nameSpaced) {
var rt = new BlKubeResourceType();
public static BlResourceType of(String apiPath, String name, boolean nameSpaced) {
var rt = new BlResourceType();
rt.apiPath = Objects.requireNonNull(apiPath);
rt.name = Objects.requireNonNull(name);
rt.nameSpaced = nameSpaced;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.Set;
import java.util.TreeSet;

public class BlKubeResourceTypes {
public class BlResourceTypes {

public static final Set<String> internalTypes = new TreeSet<>();

Expand Down Expand Up @@ -70,7 +70,7 @@ public class BlKubeResourceTypes {
priorityMap.put("events", 660); // Events provide a record of state changes in the cluster
}

public static int priorityOf(BlKubeResourceType type) {
public static int priorityOf(BlResourceType type) {
return priorityMap.getOrDefault(type.name, 100); // if the resource type is unknown.
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package io.vacco.beleth.rt.schema;

import com.github.difflib.DiffUtils;
import io.k8s.apimachinery.pkg.apis.meta.v1.objectmeta.Labels;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import io.vacco.beleth.xform.BlDocumentContext;
import java.util.*;

import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static io.vacco.beleth.rt.impl.BlKubeIo.*;

public class BlKubeResources {
public class BlResources {

public static final String
kMetadata = "metadata",
Expand Down Expand Up @@ -78,8 +78,8 @@ public static boolean isValidPackageName(String packageName) {
return true;
}

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

Expand All @@ -102,4 +102,13 @@ public static BlKubeResource resourceOf(String blId, Object manifest) {
return r;
}

public static BlResourcePair resourcePairOf(String blId, Set<BlResource> local, Set<BlResource> cluster,
BlDocumentContext ctx) {
var r0 = local.stream().filter(r -> r.blId.equals(blId)).findFirst().orElseThrow();
var r1 = cluster.stream().filter(r -> r.blId.equals(blId)).findFirst().orElseThrow();
var d0 = extractPaths(ctx.toJsonElement(r0.manifest));
var d1 = extractPaths(ctx.toJsonElement(r1.manifest));
return BlResourcePair.of(r0, r1, d0, d1, DiffUtils.diff(d0, d1));
}

}

0 comments on commit 537140a

Please sign in to comment.