diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Constants.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Constants.java
new file mode 100644
index 0000000..0d03ea6
--- /dev/null
+++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Constants.java
@@ -0,0 +1,30 @@
+/*
+ * VM-Operator
+ * Copyright (C) 2023 Michael N. Lipp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.jdrupes.vmoperator.manager;
+
+/**
+ * Some constants.
+ */
+public class Constants {
+
+ static final String VM_OP_GROUP = "vmoperator.jdrupes.org";
+ static final String VM_OP_VERSION = "v1";
+ static final String VM_OP_KIND_VM = "VirtualMachine";
+
+}
diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Manager.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Manager.java
index 0a62134..675c11a 100644
--- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Manager.java
+++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Manager.java
@@ -47,7 +47,7 @@ public class Manager extends Component {
public Manager() throws IOException {
// Prepare component tree
attach(new NioDispatcher());
- attach(new VmDefinitionWatcher(channel()));
+ attach(new VmWatcher(channel()));
attach(new Reconciler(channel()));
}
diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Reconciler.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Reconciler.java
index 67abd9f..2cbf29d 100644
--- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Reconciler.java
+++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Reconciler.java
@@ -1,18 +1,80 @@
+/*
+ * VM-Operator
+ * Copyright (C) 2023 Michael N. Lipp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
package org.jdrupes.vmoperator.manager;
+import io.kubernetes.client.openapi.ApiException;
+import io.kubernetes.client.util.generic.dynamic.DynamicKubernetesApi;
+import static org.jdrupes.vmoperator.manager.Constants.VM_OP_GROUP;
+import static org.jdrupes.vmoperator.manager.Constants.VM_OP_VERSION;
import org.jgrapes.core.Channel;
import org.jgrapes.core.Component;
import org.jgrapes.core.annotation.Handler;
+/**
+ * Adapts Kubenetes resources to changes in VM definitions (CRs).
+ */
public class Reconciler extends Component {
+ /**
+ * Instantiates a new reconciler.
+ *
+ * @param componentChannel the component channel
+ */
public Reconciler(Channel componentChannel) {
super(componentChannel);
}
+ /**
+ * Handles the change event.
+ *
+ * @param event the event
+ * @param channel the channel
+ * @throws ApiException the api exception
+ */
@Handler
- public void onVmChanged(VmChangedEvent event, WatchChannel channel) {
+ public void onVmDefChanged(VmDefChanged event, WatchChannel channel)
+ throws ApiException {
+ DynamicKubernetesApi vmDefApi = new DynamicKubernetesApi(VM_OP_GROUP,
+ VM_OP_VERSION, event.crd().getName(), channel.client());
+ var defMeta = event.metadata();
+ var vmDef = vmDefApi.get(defMeta.getNamespace(), defMeta.getName());
+
+// DynamicKubernetesApi cmApi = new DynamicKubernetesApi("", "v1",
+// "configmaps", channel.client());
+// var cm = new DynamicKubernetesObject();
+// cm.setApiVersion("v1");
+// cm.setKind("ConfigMap");
+// V1ObjectMeta metadata = new V1ObjectMeta();
+// metadata.setNamespace("default");
+// metadata.setName("test");
+// cm.setMetadata(metadata);
+// JsonObject data = new JsonObject();
+// data.addProperty("test", "value");
+// cm.getRaw().add("data", data);
+//
+// var response = cmApi.create("default", cm, new CreateOptions())
+// .throwsApiException();
+
+// var obj = channel.coa().getNamespacedCustomObject(VM_OP_GROUP, VM_OP_VERSION,
+// md.getNamespace(), event.crd().getName(), md.getName());
event = null;
+
}
}
diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmChangedEvent.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmDefChanged.java
similarity index 84%
rename from org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmChangedEvent.java
rename to org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmDefChanged.java
index 424c09b..d3e6f34 100644
--- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmChangedEvent.java
+++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmDefChanged.java
@@ -18,8 +18,8 @@
package org.jdrupes.vmoperator.manager;
+import io.kubernetes.client.openapi.models.V1APIResource;
import io.kubernetes.client.openapi.models.V1ObjectMeta;
-
import org.jgrapes.core.Channel;
import org.jgrapes.core.Components;
import org.jgrapes.core.Event;
@@ -27,7 +27,7 @@ import org.jgrapes.core.Event;
/**
* Indicates a change in a VM definition.
*/
-public class VmChangedEvent extends Event {
+public class VmDefChanged extends Event {
/**
* The type of change.
@@ -37,6 +37,7 @@ public class VmChangedEvent extends Event {
}
private final Type type;
+ private final V1APIResource crd;
private final V1ObjectMeta metadata;
/**
@@ -45,8 +46,9 @@ public class VmChangedEvent extends Event {
* @param type the type
* @param metadata the metadata
*/
- public VmChangedEvent(Type type, V1ObjectMeta metadata) {
+ public VmDefChanged(Type type, V1APIResource crd, V1ObjectMeta metadata) {
this.type = type;
+ this.crd = crd;
this.metadata = metadata;
}
@@ -59,6 +61,15 @@ public class VmChangedEvent extends Event {
return type;
}
+ /**
+ * Returns the Crd.
+ *
+ * @return the v 1 API resource
+ */
+ public V1APIResource crd() {
+ return crd;
+ }
+
/**
* Returns the metadata.
*
diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmDefinitionWatcher.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmWatcher.java
similarity index 72%
rename from org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmDefinitionWatcher.java
rename to org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmWatcher.java
index 8a32769..fc9933f 100644
--- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmDefinitionWatcher.java
+++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmWatcher.java
@@ -22,7 +22,6 @@ import com.google.gson.reflect.TypeToken;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.Configuration;
-import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.apis.CustomObjectsApi;
import io.kubernetes.client.openapi.models.V1APIResource;
import io.kubernetes.client.openapi.models.V1Namespace;
@@ -34,7 +33,9 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import okhttp3.Call;
-import org.jdrupes.vmoperator.manager.VmChangedEvent.Type;
+import static org.jdrupes.vmoperator.manager.Constants.VM_OP_GROUP;
+import static org.jdrupes.vmoperator.manager.Constants.VM_OP_VERSION;
+import org.jdrupes.vmoperator.manager.VmDefChanged.Type;
import org.jgrapes.core.Channel;
import org.jgrapes.core.Component;
import org.jgrapes.core.annotation.Handler;
@@ -45,13 +46,9 @@ import org.jgrapes.core.events.Stop;
* Watches for changes of VM definitions.
*/
@SuppressWarnings("PMD.DataflowAnomalyAnalysis")
-public class VmDefinitionWatcher extends Component {
+public class VmWatcher extends Component {
- private static final String CR_GROUP = "vmoperator.jdrupes.org";
- private static final String CR_VERSION = "v1";
- private static final String CR_KIND = "VirtualMachine";
- private CoreV1Api api;
- private CustomObjectsApi coa;
+ private ApiClient client;
private V1APIResource vmsCrd;
private String managedNamespace = "default";
private final Map channels
@@ -62,7 +59,7 @@ public class VmDefinitionWatcher extends Component {
*
* @param componentChannel the component channel
*/
- public VmDefinitionWatcher(Channel componentChannel) {
+ public VmWatcher(Channel componentChannel) {
super(componentChannel);
}
@@ -75,44 +72,44 @@ public class VmDefinitionWatcher extends Component {
*/
@Handler
public void onStart(Start event) throws IOException, ApiException {
- ApiClient client = Config.defaultClient();
+ client = Config.defaultClient();
Configuration.setDefaultApiClient(client);
- // Get access to APIs
- api = new CoreV1Api();
- coa = new CustomObjectsApi();
+ // Get access to API
+ var coa = new CustomObjectsApi(client);
// Derive all information from the CRD
- var resources = coa.getAPIResources(CR_GROUP, CR_VERSION);
+ var resources
+ = coa.getAPIResources(VM_OP_GROUP, VM_OP_VERSION);
vmsCrd = resources.getResources().stream()
- .filter(r -> CR_KIND.equals(r.getKind())).findFirst().get();
+ .filter(r -> Constants.VM_OP_KIND_VM.equals(r.getKind()))
+ .findFirst().get();
// Watch the resources (vm definitions)
Call call = coa.listNamespacedCustomObjectCall(
- CR_GROUP, CR_VERSION, managedNamespace, vmsCrd.getName(), null,
- false, null, null, null, null, null, null, null, true, null);
+ VM_OP_GROUP, VM_OP_VERSION, managedNamespace, vmsCrd.getName(),
+ null, false, null, null, null, null, null, null, null, true, null);
new Thread(() -> {
- try (Watch watch = Watch.createWatch(client,
- call, new TypeToken>() {
+ try (Watch watch = Watch.createWatch(client, call,
+ new TypeToken>() {
}.getType())) {
for (Watch.Response item : watch) {
- handleCrEvent(item);
+ handleVmDefinitionEvent(item);
}
} catch (IOException | ApiException e) {
logger.log(Level.FINE, e, () -> "Probem while watching: "
+ e.getMessage());
}
fire(new Stop());
-
}).start();
}
- private void handleCrEvent(Watch.Response item) {
+ private void handleVmDefinitionEvent(Watch.Response item) {
V1ObjectMeta metadata = item.object.getMetadata();
WatchChannel channel = channels.computeIfAbsent(metadata.getName(),
- k -> new WatchChannel(channel(), newEventPipeline(), api, coa));
- channel.pipeline().fire(new VmChangedEvent(
- VmChangedEvent.Type.valueOf(item.type), metadata), channel);
+ k -> new WatchChannel(channel(), newEventPipeline(), client));
+ channel.pipeline().fire(new VmDefChanged(
+ VmDefChanged.Type.valueOf(item.type), vmsCrd, metadata), channel);
}
/**
@@ -122,7 +119,7 @@ public class VmDefinitionWatcher extends Component {
* @param channel the channel
*/
@Handler(priority = -10_000)
- public void onVmChanged(VmChangedEvent event, WatchChannel channel) {
+ public void onVmDefChanged(VmDefChanged event, WatchChannel channel) {
if (event.type() == Type.DELETED) {
channels.remove(event.metadata().getName());
}
diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/WatchChannel.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/WatchChannel.java
index 17ae66f..ab5e2c5 100644
--- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/WatchChannel.java
+++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/WatchChannel.java
@@ -18,8 +18,8 @@
package org.jdrupes.vmoperator.manager;
-import io.kubernetes.client.openapi.apis.CoreV1Api;
-import io.kubernetes.client.openapi.apis.CustomObjectsApi;
+import io.kubernetes.client.openapi.ApiClient;
+
import org.jgrapes.core.Channel;
import org.jgrapes.core.EventPipeline;
import org.jgrapes.core.Subchannel.DefaultSubchannel;
@@ -31,21 +31,20 @@ import org.jgrapes.core.Subchannel.DefaultSubchannel;
public class WatchChannel extends DefaultSubchannel {
private final EventPipeline pipeline;
- private final CoreV1Api api;
- private final CustomObjectsApi coa;
+ private final ApiClient client;
/**
* Instantiates a new watch channel.
*
* @param mainChannel the main channel
* @param pipeline the pipeline
+ * @param client
*/
public WatchChannel(Channel mainChannel, EventPipeline pipeline,
- CoreV1Api api, CustomObjectsApi coa) {
+ ApiClient client) {
super(mainChannel);
this.pipeline = pipeline;
- this.api = api;
- this.coa = coa;
+ this.client = client;
}
/**
@@ -58,21 +57,11 @@ public class WatchChannel extends DefaultSubchannel {
}
/**
- * Returns the API object for invoking kubernetes functions.
+ * Returns the API client.
*
- * @return the API object
+ * @return the API client
*/
- public CoreV1Api api() {
- return api;
- }
-
- /**
- * Returns the API object for invoking kubernetes custom object
- * functions.
- *
- * @return the API object
- */
- public CustomObjectsApi coa() {
- return coa;
+ public ApiClient client() {
+ return client;
}
}