From 701194799fab3c4338221471b13a5a9b68e0a4b8 Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Mon, 3 Mar 2025 21:19:34 +0100 Subject: [PATCH] Reduce to secret query. --- ...pareConsole.java => GetDisplaySecret.java} | 50 +++++------------- .../manager/DisplaySecretReconciler.java | 52 ++++++++----------- .../jdrupes/vmoperator/vmaccess/VmAccess.java | 11 ++-- .../org/jdrupes/vmoperator/vmmgmt/VmMgmt.java | 10 ++-- 4 files changed, 43 insertions(+), 80 deletions(-) rename org.jdrupes.vmoperator.manager.events/src/org/jdrupes/vmoperator/manager/events/{PrepareConsole.java => GetDisplaySecret.java} (64%) diff --git a/org.jdrupes.vmoperator.manager.events/src/org/jdrupes/vmoperator/manager/events/PrepareConsole.java b/org.jdrupes.vmoperator.manager.events/src/org/jdrupes/vmoperator/manager/events/GetDisplaySecret.java similarity index 64% rename from org.jdrupes.vmoperator.manager.events/src/org/jdrupes/vmoperator/manager/events/PrepareConsole.java rename to org.jdrupes.vmoperator.manager.events/src/org/jdrupes/vmoperator/manager/events/GetDisplaySecret.java index ad8f9ce..2f7dbd6 100644 --- a/org.jdrupes.vmoperator.manager.events/src/org/jdrupes/vmoperator/manager/events/PrepareConsole.java +++ b/org.jdrupes.vmoperator.manager.events/src/org/jdrupes/vmoperator/manager/events/GetDisplaySecret.java @@ -25,46 +25,29 @@ import org.jgrapes.core.Event; * Gets the current display secret and optionally updates it. */ @SuppressWarnings("PMD.DataClass") -public class PrepareConsole extends Event { +public class GetDisplaySecret extends Event { private final VmDefinition vmDef; private final String user; - private final boolean loginUser; /** * Instantiates a new request for the display secret. * After handling the event, a result of `null` means that - * no password is needed. No result means that the console - * is not accessible. - * - * @param vmDef the vm name - * @param user the requesting user - * @param loginUser login the user - */ - public PrepareConsole(VmDefinition vmDef, String user, - boolean loginUser) { - this.vmDef = vmDef; - this.user = user; - this.loginUser = loginUser; - } - - /** - * Instantiates a new request for the display secret. - * After handling the event, a result of `null` means that - * no password is needed. No result means that the console + * no secret is needed. No result means that the console * is not accessible. * * @param vmDef the vm name * @param user the requesting user */ - public PrepareConsole(VmDefinition vmDef, String user) { - this(vmDef, user, false); + public GetDisplaySecret(VmDefinition vmDef, String user) { + this.vmDef = vmDef; + this.user = user; } /** - * Gets the vm definition. + * Gets the VM definition. * - * @return the vm definition + * @return the VM definition */ public VmDefinition vmDefinition() { return vmDef; @@ -79,24 +62,15 @@ public class PrepareConsole extends Event { return user; } - /** - * Checks if the user should be logged in before allowing access. - * - * @return the loginUser - */ - public boolean loginUser() { - return loginUser; - } - /** * Returns `true` if a password is available. May only be called * when the event is completed. Note that the password returned - * by {@link #password()} may be `null`, indicating that no password + * by {@link #secret()} may be `null`, indicating that no password * is needed. * * @return true, if successful */ - public boolean passwordAvailable() { + public boolean secretAvailable() { if (!isDone()) { throw new IllegalStateException("Event is not done."); } @@ -104,13 +78,13 @@ public class PrepareConsole extends Event { } /** - * Return the password. May only be called when the event has been - * completed with a valid result (see {@link #passwordAvailable()}). + * Return the secret. May only be called when the event has been + * completed with a valid result (see {@link #secretAvailable()}). * * @return the password. A value of `null` means that no password * is required. */ - public String password() { + public String secret() { if (!isDone() || currentResults().isEmpty()) { throw new IllegalStateException("Event is not done."); } 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 7c5c3ad..dabffb6 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 @@ -43,7 +43,7 @@ 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 org.jdrupes.vmoperator.manager.events.PrepareConsole; +import org.jdrupes.vmoperator.manager.events.GetDisplaySecret; import org.jdrupes.vmoperator.manager.events.VmChannel; import org.jdrupes.vmoperator.manager.events.VmDefChanged; import org.jdrupes.vmoperator.util.DataPath; @@ -71,7 +71,7 @@ public class DisplaySecretReconciler extends Component { protected final Logger logger = Logger.getLogger(getClass().getName()); private int passwordValidity = 10; - private final List pendingPrepares + private final List pendingPrepares = Collections.synchronizedList(new LinkedList<>()); /** @@ -184,21 +184,23 @@ public class DisplaySecretReconciler extends Component { */ @Handler @SuppressWarnings("PMD.StringInstantiation") - public void onPrepareConsole(PrepareConsole event, VmChannel channel) + public void onGetDisplaySecret(GetDisplaySecret event, VmChannel channel) throws ApiException { - // Update console user in status - var vmDef = updateConsoleUser(event, channel); - if (vmDef == null) { + // Get VM definition and check if running + var vmStub = VmDefinitionStub.get(channel.client(), + new GroupVersionKind(Crd.GROUP, "", Crd.KIND_VM), + event.vmDefinition().namespace(), event.vmDefinition().name()); + var vmDef = vmStub.model().orElse(null); + if (vmDef == null || !vmDef.conditionStatus("Running").orElse(false)) { return; } - // Check if access is possible - if (event.loginUser() - ? !vmDef. fromStatus(Status.LOGGED_IN_USER) - .map(u -> u.equals(event.user())).orElse(false) - : !vmDef.conditionStatus("Running").orElse(false)) { - return; - } + // Update console user in status + vmDef = vmStub.updateStatus(from -> { + JsonObject status = from.statusJson(); + status.addProperty(Status.CONSOLE_USER, event.user()); + return status; + }).get(); // Get secret and update password in secret var stub = getSecretStub(event, channel, vmDef); @@ -212,7 +214,7 @@ public class DisplaySecretReconciler extends Component { // Register wait for confirmation (by VM status change, // after secret update) - var pending = new PendingPrepare(event, + var pending = new PendingRequest(event, event.vmDefinition().displayPasswordSerial().orElse(0L) + 1, new CompletionLock(event, 1500)); pendingPrepares.add(pending); @@ -224,19 +226,7 @@ public class DisplaySecretReconciler extends Component { stub.update(secret).getObject(); } - private VmDefinition updateConsoleUser(PrepareConsole event, - VmChannel channel) throws ApiException { - var vmStub = VmDefinitionStub.get(channel.client(), - new GroupVersionKind(Crd.GROUP, "", Crd.KIND_VM), - event.vmDefinition().namespace(), event.vmDefinition().name()); - return vmStub.updateStatus(from -> { - JsonObject status = from.statusJson(); - status.addProperty(Status.CONSOLE_USER, event.user()); - return status; - }).orElse(null); - } - - private K8sV1SecretStub getSecretStub(PrepareConsole event, + private K8sV1SecretStub getSecretStub(GetDisplaySecret event, VmChannel channel, VmDefinition vmDef) throws ApiException { // Look for secret ListOptions options = new ListOptions(); @@ -253,7 +243,7 @@ public class DisplaySecretReconciler extends Component { return stubs.iterator().next(); } - private boolean updatePassword(V1Secret secret, PrepareConsole event) { + private boolean updatePassword(V1Secret secret, GetDisplaySecret event) { var expiry = Optional.ofNullable(secret.getData() .get(DisplaySecret.EXPIRY)).map(b -> new String(b)).orElse(null); if (secret.getData().get(DisplaySecret.PASSWORD) != null @@ -323,8 +313,8 @@ public class DisplaySecretReconciler extends Component { * The Class PendingGet. */ @SuppressWarnings("PMD.DataClass") - private static class PendingPrepare { - public final PrepareConsole event; + private static class PendingRequest { + public final GetDisplaySecret event; public final long expectedSerial; public final CompletionLock lock; @@ -334,7 +324,7 @@ public class DisplaySecretReconciler extends Component { * @param event the event * @param expectedSerial the expected serial */ - public PendingPrepare(PrepareConsole event, long expectedSerial, + public PendingRequest(GetDisplaySecret event, long expectedSerial, CompletionLock lock) { super(); this.event = event; diff --git a/org.jdrupes.vmoperator.vmaccess/src/org/jdrupes/vmoperator/vmaccess/VmAccess.java b/org.jdrupes.vmoperator.vmaccess/src/org/jdrupes/vmoperator/vmaccess/VmAccess.java index ad4ec63..74a9f76 100644 --- a/org.jdrupes.vmoperator.vmaccess/src/org/jdrupes/vmoperator/vmaccess/VmAccess.java +++ b/org.jdrupes.vmoperator.vmaccess/src/org/jdrupes/vmoperator/vmaccess/VmAccess.java @@ -49,11 +49,11 @@ import org.jdrupes.vmoperator.common.VmDefinition; import org.jdrupes.vmoperator.common.VmDefinition.Permission; import org.jdrupes.vmoperator.common.VmPool; import org.jdrupes.vmoperator.manager.events.AssignVm; +import org.jdrupes.vmoperator.manager.events.GetDisplaySecret; import org.jdrupes.vmoperator.manager.events.GetPools; import org.jdrupes.vmoperator.manager.events.GetVms; import org.jdrupes.vmoperator.manager.events.GetVms.VmData; import org.jdrupes.vmoperator.manager.events.ModifyVm; -import org.jdrupes.vmoperator.manager.events.PrepareConsole; import org.jdrupes.vmoperator.manager.events.ResetVm; import org.jdrupes.vmoperator.manager.events.VmChannel; import org.jdrupes.vmoperator.manager.events.VmDefChanged; @@ -808,18 +808,17 @@ public class VmAccess extends FreeMarkerConlet { Map.of("autoClose", 5_000, "type", "Warning"))); return; } - var pwQuery = Event.onCompletion(new PrepareConsole(vmDef, user, - model.mode() == ResourceModel.Mode.POOL), + var pwQuery = Event.onCompletion(new GetDisplaySecret(vmDef, user), e -> gotPassword(channel, model, vmDef, e)); fire(pwQuery, vmChannel); } private void gotPassword(ConsoleConnection channel, ResourceModel model, - VmDefinition vmDef, PrepareConsole event) { - if (!event.passwordAvailable()) { + VmDefinition vmDef, GetDisplaySecret event) { + if (!event.secretAvailable()) { return; } - vmDef.extra().map(xtra -> xtra.connectionFile(event.password(), + vmDef.extra().map(xtra -> xtra.connectionFile(event.secret(), preferredIpVersion, deleteConnectionFile)) .ifPresent(cf -> channel.respond(new NotifyConletView(type(), model.getConletId(), "openConsole", cf))); diff --git a/org.jdrupes.vmoperator.vmmgmt/src/org/jdrupes/vmoperator/vmmgmt/VmMgmt.java b/org.jdrupes.vmoperator.vmmgmt/src/org/jdrupes/vmoperator/vmmgmt/VmMgmt.java index 6d3891d..ac16803 100644 --- a/org.jdrupes.vmoperator.vmmgmt/src/org/jdrupes/vmoperator/vmmgmt/VmMgmt.java +++ b/org.jdrupes.vmoperator.vmmgmt/src/org/jdrupes/vmoperator/vmmgmt/VmMgmt.java @@ -44,8 +44,8 @@ import org.jdrupes.vmoperator.common.VmDefinition; import org.jdrupes.vmoperator.common.VmDefinition.Permission; import org.jdrupes.vmoperator.common.VmExtraData; import org.jdrupes.vmoperator.manager.events.ChannelTracker; +import org.jdrupes.vmoperator.manager.events.GetDisplaySecret; import org.jdrupes.vmoperator.manager.events.ModifyVm; -import org.jdrupes.vmoperator.manager.events.PrepareConsole; import org.jdrupes.vmoperator.manager.events.ResetVm; import org.jdrupes.vmoperator.manager.events.VmChannel; import org.jdrupes.vmoperator.manager.events.VmDefChanged; @@ -484,17 +484,17 @@ public class VmMgmt extends FreeMarkerConlet { Map.of("autoClose", 5_000, "type", "Warning"))); return; } - var pwQuery = Event.onCompletion(new PrepareConsole(vmDef, user), + var pwQuery = Event.onCompletion(new GetDisplaySecret(vmDef, user), e -> gotPassword(channel, model, vmDef, e)); fire(pwQuery, vmChannel); } private void gotPassword(ConsoleConnection channel, VmsModel model, - VmDefinition vmDef, PrepareConsole event) { - if (!event.passwordAvailable()) { + VmDefinition vmDef, GetDisplaySecret event) { + if (!event.secretAvailable()) { return; } - vmDef.extra().map(xtra -> xtra.connectionFile(event.password(), + vmDef.extra().map(xtra -> xtra.connectionFile(event.secret(), preferredIpVersion, deleteConnectionFile)).ifPresent( cf -> channel.respond(new NotifyConletView(type(), model.getConletId(), "openConsole", cf)));