diff --git a/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/Constants.java b/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/Constants.java index 7a1bd1a..60afd91 100644 --- a/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/Constants.java +++ b/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/Constants.java @@ -18,6 +18,7 @@ package org.jdrupes.vmoperator.common; +// TODO: Auto-generated Javadoc /** * Some constants. */ @@ -30,21 +31,48 @@ public class Constants { /** The Constant VM_OP_NAME. */ public static final String VM_OP_NAME = "vm-operator"; - /** The Constant VM_OP_GROUP. */ - public static final String VM_OP_GROUP = "vmoperator.jdrupes.org"; + /** + * Constants related to the CRD. + */ + @SuppressWarnings("PMD.ShortClassName") + public static class Crd { + /** The Constant GROUP. */ + public static final String GROUP = "vmoperator.jdrupes.org"; - /** The Constant VM_OP_KIND_VM. */ - public static final String VM_OP_KIND_VM = "VirtualMachine"; + /** The Constant KIND_VM. */ + public static final String KIND_VM = "VirtualMachine"; - /** The Constant VM_OP_KIND_VM_POOL. */ - public static final String VM_OP_KIND_VM_POOL = "VmPool"; + /** The Constant KIND_VM_POOL. */ + public static final String KIND_VM_POOL = "VmPool"; + } - /** The Constant COMP_DISPLAY_SECRETS. */ - public static final String COMP_DISPLAY_SECRET = "display-secret"; + /** + * Status related constants. + */ + public static class Status { + /** The Constant LOGGED_IN_USER. */ + public static final String LOGGED_IN_USER = "loggedInUser"; - /** The Constant DATA_DISPLAY_PASSWORD. */ - public static final String DATA_DISPLAY_PASSWORD = "display-password"; + /** The Constant CONSOLE_CLIENT. */ + public static final String CONSOLE_CLIENT = "consoleClient"; - /** The Constant DATA_PASSWORD_EXPIRY. */ - public static final String DATA_PASSWORD_EXPIRY = "password-expiry"; + /** The Constant CONSOLE_USER. */ + public static final String CONSOLE_USER = "consoleUser"; + } + + /** + * DisplaySecret related constants. + */ + public static class DisplaySecret { + + /** The Constant NAME. */ + public static final String NAME = "display-secret"; + + /** The Constant PASSWORD. */ + public static final String PASSWORD = "display-password"; + + /** The Constant EXPIRY. */ + public static final String EXPIRY = "password-expiry"; + + } } diff --git a/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/VmDefinition.java b/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/VmDefinition.java index ec79b80..0eb1428 100644 --- a/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/VmDefinition.java +++ b/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/VmDefinition.java @@ -38,6 +38,7 @@ import java.util.Set; import java.util.function.Function; import java.util.logging.Logger; import java.util.stream.Collectors; +import org.jdrupes.vmoperator.common.Constants.Status; import org.jdrupes.vmoperator.util.DataPath; /** @@ -286,7 +287,7 @@ public class VmDefinition extends K8sDynamicModel { * @return the optional */ public Optional consoleUser() { - return this. fromStatus("consoleUser"); + return this. fromStatus(Status.CONSOLE_USER); } /** diff --git a/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerConfig.ftl.yaml b/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerConfig.ftl.yaml index 9c4b72a..2fbeb94 100644 --- a/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerConfig.ftl.yaml +++ b/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerConfig.ftl.yaml @@ -11,7 +11,7 @@ metadata: vmoperator.jdrupes.org/version: ${ managerVersion } ownerReferences: - apiVersion: ${ cr.apiVersion() } - kind: ${ constants.VM_OP_KIND_VM } + kind: ${ constants.Crd.KIND_VM } name: ${ cr.name() } uid: ${ cr.metadata().getUid() } controller: false diff --git a/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerLoadBalancer.ftl.yaml b/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerLoadBalancer.ftl.yaml index c25d7f4..b7215a5 100644 --- a/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerLoadBalancer.ftl.yaml +++ b/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerLoadBalancer.ftl.yaml @@ -11,7 +11,7 @@ metadata: vmoperator.jdrupes.org/version: ${ managerVersion } ownerReferences: - apiVersion: ${ cr.apiVersion() } - kind: ${ constants.VM_OP_KIND_VM } + kind: ${ constants.Crd.KIND_VM } name: ${ cr.name() } uid: ${ cr.metadata().getUid() } controller: false diff --git a/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerPod.ftl.yaml b/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerPod.ftl.yaml index 917d790..f000c70 100644 --- a/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerPod.ftl.yaml +++ b/org.jdrupes.vmoperator.manager/resources/org/jdrupes/vmoperator/manager/runnerPod.ftl.yaml @@ -15,7 +15,7 @@ metadata: vmoperator.jdrupes.org/version: ${ managerVersion } ownerReferences: - apiVersion: ${ cr.apiVersion() } - kind: ${ constants.VM_OP_KIND_VM } + kind: ${ constants.Crd.KIND_VM } name: ${ cr.name() } uid: ${ cr.metadata().getUid() } blockOwnerDeletion: true diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Controller.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Controller.java index 80ff0f7..f3deefa 100644 --- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Controller.java +++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/Controller.java @@ -29,8 +29,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.time.Instant; import java.util.logging.Level; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_GROUP; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_KIND_VM; +import org.jdrupes.vmoperator.common.Constants.Crd; import org.jdrupes.vmoperator.common.K8sClient; import org.jdrupes.vmoperator.common.K8sDynamicStub; import org.jdrupes.vmoperator.common.VmDefinitionStub; @@ -194,7 +193,7 @@ public class Controller extends Component { private void patchVmDef(K8sClient client, String name, String path, Object value) throws ApiException, IOException { var vmStub = K8sDynamicStub.get(client, - new GroupVersionKind(VM_OP_GROUP, "", VM_OP_KIND_VM), namespace, + new GroupVersionKind(Crd.GROUP, "", Crd.KIND_VM), namespace, name); // Patch running @@ -227,7 +226,7 @@ public class Controller extends Component { try { var vmDef = channel.vmDefinition(); var vmStub = VmDefinitionStub.get(channel.client(), - new GroupVersionKind(VM_OP_GROUP, "", VM_OP_KIND_VM), + new GroupVersionKind(Crd.GROUP, "", Crd.KIND_VM), vmDef.namespace(), vmDef.name()); if (vmStub.updateStatus(vmDef, from -> { JsonObject status = from.statusJson(); diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/DisplaySecretMonitor.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/DisplaySecretMonitor.java index 99c8a11..a254c0e 100644 --- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/DisplaySecretMonitor.java +++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/DisplaySecretMonitor.java @@ -28,11 +28,11 @@ import io.kubernetes.client.util.generic.options.PatchOptions; import java.io.IOException; import java.util.logging.Level; import static org.jdrupes.vmoperator.common.Constants.APP_NAME; +import org.jdrupes.vmoperator.common.Constants.DisplaySecret; import static org.jdrupes.vmoperator.common.Constants.VM_OP_NAME; import org.jdrupes.vmoperator.common.K8sClient; import org.jdrupes.vmoperator.common.K8sV1PodStub; import org.jdrupes.vmoperator.common.K8sV1SecretStub; -import static org.jdrupes.vmoperator.manager.Constants.COMP_DISPLAY_SECRET; import org.jdrupes.vmoperator.manager.events.ChannelDictionary; import org.jdrupes.vmoperator.manager.events.VmChannel; import org.jgrapes.core.Channel; @@ -61,7 +61,7 @@ public class DisplaySecretMonitor context(K8sV1SecretStub.CONTEXT); ListOptions options = new ListOptions(); options.setLabelSelector("app.kubernetes.io/name=" + APP_NAME + "," - + "app.kubernetes.io/component=" + COMP_DISPLAY_SECRET); + + "app.kubernetes.io/component=" + DisplaySecret.NAME); options(options); } diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/DisplaySecretReconciler.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/DisplaySecretReconciler.java index bf8042a..7c5c3ad 100644 --- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/DisplaySecretReconciler.java +++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/DisplaySecretReconciler.java @@ -37,14 +37,12 @@ import java.util.Optional; import java.util.Scanner; import java.util.logging.Logger; import static org.jdrupes.vmoperator.common.Constants.APP_NAME; -import static org.jdrupes.vmoperator.common.Constants.COMP_DISPLAY_SECRET; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_GROUP; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_KIND_VM; +import org.jdrupes.vmoperator.common.Constants.Crd; +import org.jdrupes.vmoperator.common.Constants.DisplaySecret; +import org.jdrupes.vmoperator.common.Constants.Status; import org.jdrupes.vmoperator.common.K8sV1SecretStub; import org.jdrupes.vmoperator.common.VmDefinition; import org.jdrupes.vmoperator.common.VmDefinitionStub; -import static org.jdrupes.vmoperator.manager.Constants.DATA_DISPLAY_PASSWORD; -import static org.jdrupes.vmoperator.manager.Constants.DATA_PASSWORD_EXPIRY; import org.jdrupes.vmoperator.manager.events.PrepareConsole; import org.jdrupes.vmoperator.manager.events.VmChannel; import org.jdrupes.vmoperator.manager.events.VmDefChanged; @@ -143,7 +141,7 @@ public class DisplaySecretReconciler extends Component { var vmDef = event.vmDefinition(); ListOptions options = new ListOptions(); options.setLabelSelector("app.kubernetes.io/name=" + APP_NAME + "," - + "app.kubernetes.io/component=" + COMP_DISPLAY_SECRET + "," + + "app.kubernetes.io/component=" + DisplaySecret.NAME + "," + "app.kubernetes.io/instance=" + vmDef.name()); var stubs = K8sV1SecretStub.list(channel.client(), vmDef.namespace(), options); @@ -154,9 +152,9 @@ public class DisplaySecretReconciler extends Component { // Create secret var secret = new V1Secret(); secret.setMetadata(new V1ObjectMeta().namespace(vmDef.namespace()) - .name(vmDef.name() + "-" + COMP_DISPLAY_SECRET) + .name(vmDef.name() + "-" + DisplaySecret.NAME) .putLabelsItem("app.kubernetes.io/name", APP_NAME) - .putLabelsItem("app.kubernetes.io/component", COMP_DISPLAY_SECRET) + .putLabelsItem("app.kubernetes.io/component", DisplaySecret.NAME) .putLabelsItem("app.kubernetes.io/instance", vmDef.name())); secret.setType("Opaque"); SecureRandom random = null; @@ -169,8 +167,8 @@ public class DisplaySecretReconciler extends Component { byte[] bytes = new byte[16]; random.nextBytes(bytes); var password = Base64.encode(bytes); - secret.setStringData(Map.of(DATA_DISPLAY_PASSWORD, password, - DATA_PASSWORD_EXPIRY, "now")); + secret.setStringData(Map.of(DisplaySecret.PASSWORD, password, + DisplaySecret.EXPIRY, "now")); K8sV1SecretStub.create(channel.client(), secret); } @@ -196,7 +194,7 @@ public class DisplaySecretReconciler extends Component { // Check if access is possible if (event.loginUser() - ? !vmDef. fromStatus("loggedInUser") + ? !vmDef. fromStatus(Status.LOGGED_IN_USER) .map(u -> u.equals(event.user())).orElse(false) : !vmDef.conditionStatus("Running").orElse(false)) { return; @@ -229,11 +227,11 @@ public class DisplaySecretReconciler extends Component { private VmDefinition updateConsoleUser(PrepareConsole event, VmChannel channel) throws ApiException { var vmStub = VmDefinitionStub.get(channel.client(), - new GroupVersionKind(VM_OP_GROUP, "", VM_OP_KIND_VM), + new GroupVersionKind(Crd.GROUP, "", Crd.KIND_VM), event.vmDefinition().namespace(), event.vmDefinition().name()); return vmStub.updateStatus(from -> { JsonObject status = from.statusJson(); - status.addProperty("consoleUser", event.user()); + status.addProperty(Status.CONSOLE_USER, event.user()); return status; }).orElse(null); } @@ -243,7 +241,7 @@ public class DisplaySecretReconciler extends Component { // Look for secret ListOptions options = new ListOptions(); options.setLabelSelector("app.kubernetes.io/name=" + APP_NAME + "," - + "app.kubernetes.io/component=" + COMP_DISPLAY_SECRET + "," + + "app.kubernetes.io/component=" + DisplaySecret.NAME + "," + "app.kubernetes.io/instance=" + vmDef.name()); var stubs = K8sV1SecretStub.list(channel.client(), vmDef.namespace(), options); @@ -257,12 +255,12 @@ public class DisplaySecretReconciler extends Component { private boolean updatePassword(V1Secret secret, PrepareConsole event) { var expiry = Optional.ofNullable(secret.getData() - .get(DATA_PASSWORD_EXPIRY)).map(b -> new String(b)).orElse(null); - if (secret.getData().get(DATA_DISPLAY_PASSWORD) != null + .get(DisplaySecret.EXPIRY)).map(b -> new String(b)).orElse(null); + if (secret.getData().get(DisplaySecret.PASSWORD) != null && stillValid(expiry)) { // Fixed secret, don't touch event.setResult( - new String(secret.getData().get(DATA_DISPLAY_PASSWORD))); + new String(secret.getData().get(DisplaySecret.PASSWORD))); return false; } @@ -277,8 +275,8 @@ public class DisplaySecretReconciler extends Component { byte[] bytes = new byte[16]; random.nextBytes(bytes); var password = Base64.encode(bytes); - secret.setStringData(Map.of(DATA_DISPLAY_PASSWORD, password, - DATA_PASSWORD_EXPIRY, + secret.setStringData(Map.of(DisplaySecret.PASSWORD, password, + DisplaySecret.EXPIRY, Long.toString(Instant.now().getEpochSecond() + passwordValidity))); event.setResult(password); return true; diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/PoolMonitor.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/PoolMonitor.java index 25fb10b..465a9ed 100644 --- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/PoolMonitor.java +++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/PoolMonitor.java @@ -28,8 +28,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_GROUP; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_KIND_VM; +import org.jdrupes.vmoperator.common.Constants.Crd; import org.jdrupes.vmoperator.common.K8s; import org.jdrupes.vmoperator.common.K8sClient; import org.jdrupes.vmoperator.common.K8sDynamicModel; @@ -38,7 +37,6 @@ import org.jdrupes.vmoperator.common.K8sDynamicStub; import org.jdrupes.vmoperator.common.K8sObserver.ResponseType; import org.jdrupes.vmoperator.common.VmDefinitionStub; import org.jdrupes.vmoperator.common.VmPool; -import static org.jdrupes.vmoperator.manager.Constants.VM_OP_KIND_VM_POOL; import org.jdrupes.vmoperator.manager.events.GetPools; import org.jdrupes.vmoperator.manager.events.VmDefChanged; import org.jdrupes.vmoperator.manager.events.VmPoolChanged; @@ -88,7 +86,7 @@ public class PoolMonitor extends client(new K8sClient()); // Get all our API versions - var ctx = K8s.context(client(), VM_OP_GROUP, "", VM_OP_KIND_VM_POOL); + var ctx = K8s.context(client(), Crd.GROUP, "", Crd.KIND_VM_POOL); if (ctx.isEmpty()) { logger.severe(() -> "Cannot get CRD context."); return; @@ -184,7 +182,7 @@ public class PoolMonitor extends return; } var vmStub = VmDefinitionStub.get(client(), - new GroupVersionKind(VM_OP_GROUP, "", VM_OP_KIND_VM), + new GroupVersionKind(Crd.GROUP, "", Crd.KIND_VM), vmDef.namespace(), vmDef.name()); vmStub.updateStatus(from -> { // TODO 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 8011e2c..e5bfaec 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 @@ -22,12 +22,10 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import freemarker.template.AdapterTemplateModel; import freemarker.template.Configuration; -import freemarker.template.DefaultObjectWrapperBuilder; import freemarker.template.SimpleNumber; import freemarker.template.SimpleScalar; import freemarker.template.TemplateException; import freemarker.template.TemplateExceptionHandler; -import freemarker.template.TemplateHashModel; import freemarker.template.TemplateMethodModelEx; import freemarker.template.TemplateModel; import freemarker.template.TemplateModelException; @@ -37,21 +35,23 @@ import io.kubernetes.client.openapi.ApiException; import io.kubernetes.client.openapi.models.V1ObjectMeta; import io.kubernetes.client.util.generic.options.ListOptions; import java.io.IOException; +import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; import java.net.URISyntaxException; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import static org.jdrupes.vmoperator.common.Constants.APP_NAME; +import org.jdrupes.vmoperator.common.Constants.DisplaySecret; import org.jdrupes.vmoperator.common.Convertions; import org.jdrupes.vmoperator.common.K8sClient; import org.jdrupes.vmoperator.common.K8sObserver; import org.jdrupes.vmoperator.common.K8sV1SecretStub; import org.jdrupes.vmoperator.common.VmDefinition; -import static org.jdrupes.vmoperator.manager.Constants.COMP_DISPLAY_SECRET; import org.jdrupes.vmoperator.manager.events.ResetVm; import org.jdrupes.vmoperator.manager.events.VmChannel; import org.jdrupes.vmoperator.manager.events.VmDefChanged; @@ -266,17 +266,14 @@ public class Reconciler extends Component { Optional.ofNullable(Reconciler.class.getPackage() .getImplementationVersion()).orElse("(Unknown)")); model.put("cr", vmDef); - model.put("constants", - (TemplateHashModel) new DefaultObjectWrapperBuilder( - Configuration.VERSION_2_3_32) - .build().getStaticModels() - .get(Constants.class.getName())); + // Freemarker's static models don't handle nested classes. + model.put("constants", constantsMap(Constants.class)); model.put("reconciler", config); // Check if we have a display secret ListOptions options = new ListOptions(); options.setLabelSelector("app.kubernetes.io/name=" + APP_NAME + "," - + "app.kubernetes.io/component=" + COMP_DISPLAY_SECRET + "," + + "app.kubernetes.io/component=" + DisplaySecret.NAME + "," + "app.kubernetes.io/instance=" + vmDef.name()); var dsStub = K8sV1SecretStub .list(client, vmDef.namespace(), options) @@ -297,6 +294,30 @@ public class Reconciler extends Component { return model; } + @SuppressWarnings("PMD.EmptyCatchBlock") + private Map constantsMap(Class clazz) { + @SuppressWarnings("PMD.UseConcurrentHashMap") + Map result = new HashMap<>(); + Arrays.stream(clazz.getFields()).filter(f -> { + var modifiers = f.getModifiers(); + return Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers) + && f.getType() == String.class; + }).forEach(f -> { + try { + result.put(f.getName(), f.get(null)); + } catch (IllegalArgumentException | IllegalAccessException e) { + // Should not happen, ignore + } + }); + Arrays.stream(clazz.getClasses()).filter(c -> { + var modifiers = c.getModifiers(); + return Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers); + }).forEach(c -> { + result.put(c.getSimpleName(), constantsMap(c)); + }); + return result; + } + private final TemplateMethodModelEx parseQuantityModel = new TemplateMethodModelEx() { @Override diff --git a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmMonitor.java b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmMonitor.java index 5c1ae77..4f8ac77 100644 --- a/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmMonitor.java +++ b/org.jdrupes.vmoperator.manager/src/org/jdrupes/vmoperator/manager/VmMonitor.java @@ -31,8 +31,7 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.stream.Collectors; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_GROUP; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_KIND_VM; +import org.jdrupes.vmoperator.common.Constants.Crd; import org.jdrupes.vmoperator.common.K8s; import org.jdrupes.vmoperator.common.K8sClient; import org.jdrupes.vmoperator.common.K8sDynamicStub; @@ -87,7 +86,7 @@ public class VmMonitor extends client(new K8sClient()); // Get all our API versions - var ctx = K8s.context(client(), VM_OP_GROUP, "", VM_OP_KIND_VM); + var ctx = K8s.context(client(), Crd.GROUP, "", Crd.KIND_VM); if (ctx.isEmpty()) { logger.severe(() -> "Cannot get CRD context."); return; diff --git a/org.jdrupes.vmoperator.manager/test/org/jdrupes/vmoperator/manager/BasicTests.java b/org.jdrupes.vmoperator.manager/test/org/jdrupes/vmoperator/manager/BasicTests.java index 4f5d7a3..03db0d2 100644 --- a/org.jdrupes.vmoperator.manager/test/org/jdrupes/vmoperator/manager/BasicTests.java +++ b/org.jdrupes.vmoperator.manager/test/org/jdrupes/vmoperator/manager/BasicTests.java @@ -12,10 +12,10 @@ import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.jdrupes.vmoperator.common.Constants; import static org.jdrupes.vmoperator.common.Constants.APP_NAME; -import static org.jdrupes.vmoperator.common.Constants.COMP_DISPLAY_SECRET; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_GROUP; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_KIND_VM; +import org.jdrupes.vmoperator.common.Constants.Crd; +import org.jdrupes.vmoperator.common.Constants.DisplaySecret; import static org.jdrupes.vmoperator.common.Constants.VM_OP_NAME; import org.jdrupes.vmoperator.common.K8s; import org.jdrupes.vmoperator.common.K8sClient; @@ -60,7 +60,7 @@ class BasicTests { waitForManager(); // Context for working with our CR - var apiRes = K8s.context(client, VM_OP_GROUP, null, VM_OP_KIND_VM); + var apiRes = K8s.context(client, Crd.GROUP, null, Crd.KIND_VM); assertTrue(apiRes.isPresent()); vmsContext = apiRes.get(); @@ -70,7 +70,7 @@ class BasicTests { ListOptions listOpts = new ListOptions(); listOpts.setLabelSelector("app.kubernetes.io/name=" + APP_NAME + "," + "app.kubernetes.io/instance=" + VM_NAME + "," - + "app.kubernetes.io/component=" + COMP_DISPLAY_SECRET); + + "app.kubernetes.io/component=" + DisplaySecret.NAME); var secrets = K8sV1SecretStub.list(client, "vmop-dev", listOpts); for (var secret : secrets) { secret.delete(); @@ -138,12 +138,11 @@ class BasicTests { List.of("name"), VM_NAME, List.of("labels", "app.kubernetes.io/name"), Constants.APP_NAME, List.of("labels", "app.kubernetes.io/instance"), VM_NAME, - List.of("labels", "app.kubernetes.io/managed-by"), - Constants.VM_OP_NAME, + List.of("labels", "app.kubernetes.io/managed-by"), VM_OP_NAME, List.of("annotations", "vmoperator.jdrupes.org/version"), EXISTS, List.of("ownerReferences", 0, "apiVersion"), vmsContext.getGroup() + "/" + vmsContext.getVersions().get(0), - List.of("ownerReferences", 0, "kind"), Constants.VM_OP_KIND_VM, + List.of("ownerReferences", 0, "kind"), Crd.KIND_VM, List.of("ownerReferences", 0, "name"), VM_NAME, List.of("ownerReferences", 0, "uid"), EXISTS); checkProps(config.getMetadata(), toCheck); @@ -189,7 +188,7 @@ class BasicTests { ListOptions listOpts = new ListOptions(); listOpts.setLabelSelector("app.kubernetes.io/name=" + APP_NAME + "," + "app.kubernetes.io/instance=" + VM_NAME + "," - + "app.kubernetes.io/component=" + COMP_DISPLAY_SECRET); + + "app.kubernetes.io/component=" + DisplaySecret.NAME); Collection secrets = null; for (int i = 0; i < 10; i++) { secrets = K8sV1SecretStub.list(client, "vmop-dev", listOpts); @@ -219,8 +218,7 @@ class BasicTests { checkProps(pvc.getMetadata(), Map.of( List.of("labels", "app.kubernetes.io/name"), Constants.APP_NAME, List.of("labels", "app.kubernetes.io/instance"), VM_NAME, - List.of("labels", "app.kubernetes.io/managed-by"), - Constants.VM_OP_NAME)); + List.of("labels", "app.kubernetes.io/managed-by"), VM_OP_NAME)); checkProps(pvc.getSpec(), Map.of( List.of("resources", "requests", "storage"), Quantity.fromString("1Mi"))); @@ -240,8 +238,7 @@ class BasicTests { checkProps(pvc.getMetadata(), Map.of( List.of("labels", "app.kubernetes.io/name"), Constants.APP_NAME, List.of("labels", "app.kubernetes.io/instance"), VM_NAME, - List.of("labels", "app.kubernetes.io/managed-by"), - Constants.VM_OP_NAME, + List.of("labels", "app.kubernetes.io/managed-by"), VM_OP_NAME, List.of("annotations", "use_as"), "system-disk")); checkProps(pvc.getSpec(), Map.of( List.of("resources", "requests", "storage"), @@ -262,8 +259,7 @@ class BasicTests { checkProps(pvc.getMetadata(), Map.of( List.of("labels", "app.kubernetes.io/name"), Constants.APP_NAME, List.of("labels", "app.kubernetes.io/instance"), VM_NAME, - List.of("labels", "app.kubernetes.io/managed-by"), - Constants.VM_OP_NAME)); + List.of("labels", "app.kubernetes.io/managed-by"), VM_OP_NAME)); checkProps(pvc.getSpec(), Map.of( List.of("resources", "requests", "storage"), Quantity.fromString("1Gi"))); @@ -290,13 +286,12 @@ class BasicTests { List.of("labels", "app.kubernetes.io/name"), APP_NAME, List.of("labels", "app.kubernetes.io/instance"), VM_NAME, List.of("labels", "app.kubernetes.io/component"), APP_NAME, - List.of("labels", "app.kubernetes.io/managed-by"), - Constants.VM_OP_NAME, + List.of("labels", "app.kubernetes.io/managed-by"), VM_OP_NAME, List.of("annotations", "vmrunner.jdrupes.org/cmVersion"), EXISTS, List.of("annotations", "vmoperator.jdrupes.org/version"), EXISTS, List.of("ownerReferences", 0, "apiVersion"), vmsContext.getGroup() + "/" + vmsContext.getVersions().get(0), - List.of("ownerReferences", 0, "kind"), Constants.VM_OP_KIND_VM, + List.of("ownerReferences", 0, "kind"), Crd.KIND_VM, List.of("ownerReferences", 0, "name"), VM_NAME, List.of("ownerReferences", 0, "uid"), EXISTS)); checkProps(pod.getSpec(), Map.of( diff --git a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/ConsoleTracker.java b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/ConsoleTracker.java index 7956fa1..ddfc702 100644 --- a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/ConsoleTracker.java +++ b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/ConsoleTracker.java @@ -25,8 +25,8 @@ import io.kubernetes.client.openapi.models.EventsV1Event; import java.io.IOException; import java.util.logging.Level; import static org.jdrupes.vmoperator.common.Constants.APP_NAME; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_GROUP; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_KIND_VM; +import org.jdrupes.vmoperator.common.Constants.Crd; +import org.jdrupes.vmoperator.common.Constants.Status; import org.jdrupes.vmoperator.common.K8s; import org.jdrupes.vmoperator.common.K8sClient; import org.jdrupes.vmoperator.common.VmDefinitionStub; @@ -74,7 +74,7 @@ public class ConsoleTracker extends VmDefUpdater { } try { vmStub = VmDefinitionStub.get(apiClient, - new GroupVersionKind(VM_OP_GROUP, "", VM_OP_KIND_VM), + new GroupVersionKind(Crd.GROUP, "", Crd.KIND_VM), namespace, vmName); } catch (ApiException e) { logger.log(Level.SEVERE, e, @@ -108,13 +108,13 @@ public class ConsoleTracker extends VmDefUpdater { vmStub.updateStatus(from -> { JsonObject status = updateCondition(from, "ConsoleConnected", true, "Connected", "Connection from " + event.clientHost()); - status.addProperty("consoleClient", event.clientHost()); + status.addProperty(Status.CONSOLE_CLIENT, event.clientHost()); return status; }); // Log event var evt = new EventsV1Event() - .reportingController(VM_OP_GROUP + "/" + APP_NAME) + .reportingController(Crd.GROUP + "/" + APP_NAME) .action("ConsoleConnectionUpdate") .reason("Connection from " + event.clientHost()); K8s.createEvent(apiClient, vmStub.model().get(), evt); @@ -142,13 +142,13 @@ public class ConsoleTracker extends VmDefUpdater { vmStub.updateStatus(from -> { JsonObject status = updateCondition(from, "ConsoleConnected", false, "Disconnected", event.clientHost() + " has disconnected"); - status.addProperty("consoleClient", ""); + status.addProperty(Status.CONSOLE_CLIENT, ""); return status; }); // Log event var evt = new EventsV1Event() - .reportingController(VM_OP_GROUP + "/" + APP_NAME) + .reportingController(Crd.GROUP + "/" + APP_NAME) .action("ConsoleConnectionUpdate") .reason("Disconnected from " + event.clientHost()); K8s.createEvent(apiClient, vmStub.model().get(), evt); diff --git a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/DisplayController.java b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/DisplayController.java index 39f71d5..d301aac 100644 --- a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/DisplayController.java +++ b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/DisplayController.java @@ -24,8 +24,7 @@ import java.nio.file.Path; import java.util.Objects; import java.util.Optional; import java.util.logging.Level; -import static org.jdrupes.vmoperator.common.Constants.DATA_DISPLAY_PASSWORD; -import static org.jdrupes.vmoperator.common.Constants.DATA_PASSWORD_EXPIRY; +import org.jdrupes.vmoperator.common.Constants.DisplaySecret; import org.jdrupes.vmoperator.runner.qemu.commands.QmpSetDisplayPassword; import org.jdrupes.vmoperator.runner.qemu.commands.QmpSetPasswordExpiry; import org.jdrupes.vmoperator.runner.qemu.events.ConfigureQemu; @@ -64,7 +63,7 @@ public class DisplayController extends Component { public DisplayController(Channel componentChannel, Path configDir) { super(componentChannel); this.configDir = configDir; - fire(new WatchFile(configDir.resolve(DATA_DISPLAY_PASSWORD))); + fire(new WatchFile(configDir.resolve(DisplaySecret.PASSWORD))); } /** @@ -115,7 +114,7 @@ public class DisplayController extends Component { @Handler @SuppressWarnings("PMD.EmptyCatchBlock") public void onFileChanged(FileChanged event) { - if (event.path().equals(configDir.resolve(DATA_DISPLAY_PASSWORD))) { + if (event.path().equals(configDir.resolve(DisplaySecret.PASSWORD))) { configurePassword(); } } @@ -130,7 +129,7 @@ public class DisplayController extends Component { } private boolean setDisplayPassword() { - return readFromFile(DATA_DISPLAY_PASSWORD).map(password -> { + return readFromFile(DisplaySecret.PASSWORD).map(password -> { if (Objects.equals(this.currentPassword, password)) { return true; } @@ -143,7 +142,7 @@ public class DisplayController extends Component { } private void setPasswordExpiry() { - readFromFile(DATA_PASSWORD_EXPIRY).ifPresent(expiry -> { + readFromFile(DisplaySecret.EXPIRY).ifPresent(expiry -> { logger.fine(() -> "Updating expiry time to " + expiry); fire( new MonitorCommand(new QmpSetPasswordExpiry(protocol, expiry))); diff --git a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Runner.java b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Runner.java index f64af2d..a01618d 100644 --- a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Runner.java +++ b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Runner.java @@ -56,7 +56,7 @@ import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import static org.jdrupes.vmoperator.common.Constants.APP_NAME; -import static org.jdrupes.vmoperator.common.Constants.DATA_DISPLAY_PASSWORD; +import org.jdrupes.vmoperator.common.Constants.DisplaySecret; import org.jdrupes.vmoperator.runner.qemu.commands.QmpCont; import org.jdrupes.vmoperator.runner.qemu.commands.QmpReset; import org.jdrupes.vmoperator.runner.qemu.events.ConfigureQemu; @@ -312,7 +312,7 @@ public class Runner extends Component { // Add some values from other sources to configuration newConf.asOf = Instant.ofEpochSecond(configFile.lastModified()); - Path dsPath = configDir.resolve(DATA_DISPLAY_PASSWORD); + Path dsPath = configDir.resolve(DisplaySecret.PASSWORD); newConf.hasDisplayPassword = dsPath.toFile().canRead(); // Special actions for initial configuration (startup) diff --git a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/StatusUpdater.java b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/StatusUpdater.java index f2437d3..3323a7e 100644 --- a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/StatusUpdater.java +++ b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/StatusUpdater.java @@ -33,8 +33,8 @@ import java.io.IOException; import java.math.BigDecimal; import java.util.logging.Level; import static org.jdrupes.vmoperator.common.Constants.APP_NAME; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_GROUP; -import static org.jdrupes.vmoperator.common.Constants.VM_OP_KIND_VM; +import org.jdrupes.vmoperator.common.Constants.Crd; +import org.jdrupes.vmoperator.common.Constants.Status; import org.jdrupes.vmoperator.common.K8s; import org.jdrupes.vmoperator.common.VmDefinition; import org.jdrupes.vmoperator.common.VmDefinitionStub; @@ -112,7 +112,7 @@ public class StatusUpdater extends VmDefUpdater { } try { vmStub = VmDefinitionStub.get(apiClient, - new GroupVersionKind(VM_OP_GROUP, "", VM_OP_KIND_VM), + new GroupVersionKind(Crd.GROUP, "", Crd.KIND_VM), namespace, vmName); var vmDef = vmStub.model().orElse(null); if (vmDef == null) { @@ -121,7 +121,7 @@ public class StatusUpdater extends VmDefUpdater { observedGeneration = vmDef.getMetadata().getGeneration(); vmStub.updateStatus(from -> { JsonObject status = from.statusJson(); - status.remove("loggedInUser"); + status.remove(Status.LOGGED_IN_USER); return status; }); } catch (ApiException e) { @@ -206,12 +206,12 @@ public class StatusUpdater extends VmDefUpdater { } else if (event.runState() == RunState.STOPPED) { status.addProperty("ram", "0"); status.addProperty("cpus", 0); - status.remove("loggedInUser"); + status.remove(Status.LOGGED_IN_USER); } if (!running) { // In case console connection was still present - status.addProperty("consoleClient", ""); + status.addProperty(Status.CONSOLE_CLIENT, ""); updateCondition(from, "ConsoleConnected", false, "VmStopped", "The VM is not running"); @@ -239,7 +239,7 @@ public class StatusUpdater extends VmDefUpdater { // Log event var evt = new EventsV1Event() - .reportingController(VM_OP_GROUP + "/" + APP_NAME) + .reportingController(Crd.GROUP + "/" + APP_NAME) .action("StatusUpdate").reason(event.reason()) .note(event.message()); K8s.createEvent(apiClient, vmDef, evt); @@ -363,7 +363,8 @@ public class StatusUpdater extends VmDefUpdater { throws ApiException { vmStub.updateStatus(from -> { JsonObject status = from.statusJson(); - status.addProperty("loggedInUser", event.triggering().user()); + status.addProperty(Status.LOGGED_IN_USER, + event.triggering().user()); return status; }); } @@ -378,7 +379,7 @@ public class StatusUpdater extends VmDefUpdater { throws ApiException { vmStub.updateStatus(from -> { JsonObject status = from.statusJson(); - status.remove("loggedInUser"); + status.remove(Status.LOGGED_IN_USER); return status; }); }