diff --git a/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerService.ftl.yaml b/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerService.ftl.yaml new file mode 100644 index 0000000..ee0d88d --- /dev/null +++ b/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerService.ftl.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + namespace: ${ cr.metadata.namespace.asString } + name: ${ cr.metadata.name.asString } + labels: + app.kubernetes.io/name: ${ constants.APP_NAME } + app.kubernetes.io/instance: ${ cr.metadata.name.asString } + app.kubernetes.io/managed-by: ${ constants.VM_OP_NAME } +spec: + ports: + - name: spice + port: ${ cr.spec.vm.display.spice.port.asInt?c } + clusterIP: None + selector: + app.kubernetes.io/name: ${ cr.metadata.name.asString } + app.kubernetes.io/instance: ${ cr.metadata.name.asString } 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 e0c18a9..1e32a0d 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 @@ -53,6 +53,7 @@ public class Reconciler extends Component { private final Configuration fmConfig; private final CmReconciler cmReconciler; private final StsReconciler stsReconciler; + private final ServiceReconciler serviceReconciler; /** * Instantiates a new reconciler. @@ -74,6 +75,7 @@ public class Reconciler extends Component { cmReconciler = new CmReconciler(fmConfig); stsReconciler = new StsReconciler(fmConfig); + serviceReconciler = new ServiceReconciler(fmConfig); } /** @@ -121,7 +123,9 @@ public class Reconciler extends Component { var configMap = cmReconciler.reconcile(event, model, channel); model.put("cm", configMap.getRaw()); stsReconciler.reconcile(event, model, channel); + serviceReconciler.reconcile(event, model, channel); } else { + serviceReconciler.reconcile(event, model, channel); stsReconciler.reconcile(event, model, channel); cmReconciler.reconcile(event, model, channel); } diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/ServiceReconciler.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/ServiceReconciler.java new file mode 100644 index 0000000..aef4898 --- /dev/null +++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/ServiceReconciler.java @@ -0,0 +1,88 @@ +/* + * 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 freemarker.template.Configuration; +import freemarker.template.TemplateException; +import io.kubernetes.client.openapi.ApiException; +import io.kubernetes.client.util.generic.dynamic.DynamicKubernetesApi; +import io.kubernetes.client.util.generic.dynamic.Dynamics; +import java.io.IOException; +import java.io.StringWriter; +import java.util.Map; +import java.util.logging.Logger; +import org.jdrupes.vmoperator.manager.VmDefChanged.Type; + +/** + * Delegee for reconciling the service + */ +@SuppressWarnings("PMD.DataflowAnomalyAnalysis") +/* default */ class ServiceReconciler { + + protected final Logger logger = Logger.getLogger(getClass().getName()); + private final Configuration fmConfig; + + /** + * Instantiates a new service reconciler. + * + * @param fmConfig the fm config + */ + public ServiceReconciler(Configuration fmConfig) { + this.fmConfig = fmConfig; + } + + /** + * Reconcile. + * + * @param event the event + * @param model the model + * @param channel the channel + * @throws IOException Signals that an I/O exception has occurred. + * @throws TemplateException the template exception + * @throws ApiException the api exception + */ + public void reconcile(VmDefChanged event, + Map model, VmChannel channel) + throws IOException, TemplateException, ApiException { + // Get API and check if exists + DynamicKubernetesApi svcApi = new DynamicKubernetesApi("", "v1", + "services", channel.client()); + var existing = K8s.get(svcApi, event.object().getMetadata()); + + // If deleted, delete + if (event.type() == Type.DELETED) { + if (existing.isPresent()) { + K8s.delete(svcApi, existing.get()); + } + return; + } + + // Combine template and data and parse result + var fmTemplate = fmConfig.getTemplate("runnerService.ftl.yaml"); + StringWriter out = new StringWriter(); + fmTemplate.process(model, out); + // Avoid Yaml.load due to + // https://github.com/kubernetes-client/java/issues/2741 + var mapDef = Dynamics.newFromYaml(out.toString()); + + // Apply + K8s.apply(svcApi, mapDef, out.toString()); + } + +}