Set loggedInUser via Reconciler.
This commit is contained in:
parent
28b1903acc
commit
bfe4c2bb32
10 changed files with 111 additions and 74 deletions
|
|
@ -141,6 +141,16 @@ public class VmDefinition extends K8sDynamicModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The assignment information.
|
||||||
|
*
|
||||||
|
* @param pool the pool
|
||||||
|
* @param user the user
|
||||||
|
* @param lastUsed the last used
|
||||||
|
*/
|
||||||
|
public record Assignment(String pool, String user, Instant lastUsed) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new vm definition.
|
* Instantiates a new vm definition.
|
||||||
*
|
*
|
||||||
|
|
@ -215,31 +225,15 @@ public class VmDefinition extends K8sDynamicModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The pool that the VM was taken from.
|
* The assignment information.
|
||||||
*
|
*
|
||||||
* @return the optional
|
* @return the optional
|
||||||
*/
|
*/
|
||||||
public Optional<String> assignedFrom() {
|
public Optional<Assignment> assignment() {
|
||||||
return fromStatus(Status.ASSIGNMENT, "pool");
|
return this.<Map<String, Object>> fromStatus(Status.ASSIGNMENT)
|
||||||
}
|
.filter(m -> !m.isEmpty()).map(a -> new Assignment(
|
||||||
|
a.get("pool").toString(), a.get("user").toString(),
|
||||||
/**
|
Instant.parse(a.get("lastUsed").toString())));
|
||||||
* The user that the VM was assigned to.
|
|
||||||
*
|
|
||||||
* @return the optional
|
|
||||||
*/
|
|
||||||
public Optional<String> assignedTo() {
|
|
||||||
return fromStatus(Status.ASSIGNMENT, "user");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Last usage of assigned VM.
|
|
||||||
*
|
|
||||||
* @return the optional
|
|
||||||
*/
|
|
||||||
public Optional<Instant> assignmentLastUsed() {
|
|
||||||
return this.<String> fromStatus(Status.ASSIGNMENT, "lastUsed")
|
|
||||||
.map(Instant::parse);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import org.jdrupes.vmoperator.common.VmDefinition.Assignment;
|
||||||
import org.jdrupes.vmoperator.common.VmDefinition.Grant;
|
import org.jdrupes.vmoperator.common.VmDefinition.Grant;
|
||||||
import org.jdrupes.vmoperator.common.VmDefinition.Permission;
|
import org.jdrupes.vmoperator.common.VmDefinition.Permission;
|
||||||
import org.jdrupes.vmoperator.util.DataPath;
|
import org.jdrupes.vmoperator.util.DataPath;
|
||||||
|
|
@ -165,13 +166,12 @@ public class VmPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not assigned, it's usable
|
// If not assigned, it's usable
|
||||||
if (vmDef.assignedTo().isEmpty()) {
|
if (vmDef.assignment().isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if it is to be retained
|
// Check if it is to be retained
|
||||||
if (vmDef.assignmentLastUsed()
|
if (vmDef.assignment().map(Assignment::lastUsed).map(this::retainUntil)
|
||||||
.map(this::retainUntil)
|
|
||||||
.map(ru -> Instant.now().isBefore(ru)).orElse(false)) {
|
.map(ru -> Instant.now().isBefore(ru)).orElse(false)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
package org.jdrupes.vmoperator.manager.events;
|
package org.jdrupes.vmoperator.manager.events;
|
||||||
|
|
||||||
|
import org.jdrupes.vmoperator.common.VmPool;
|
||||||
import org.jgrapes.core.Event;
|
import org.jgrapes.core.Event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -26,31 +27,31 @@ import org.jgrapes.core.Event;
|
||||||
@SuppressWarnings("PMD.DataClass")
|
@SuppressWarnings("PMD.DataClass")
|
||||||
public class UpdateAssignment extends Event<Boolean> {
|
public class UpdateAssignment extends Event<Boolean> {
|
||||||
|
|
||||||
private final String usedPool;
|
private final VmPool fromPool;
|
||||||
private final String toUser;
|
private final String toUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new event.
|
* Instantiates a new event.
|
||||||
*
|
*
|
||||||
* @param usedPool the used pool
|
* @param fromPool the pool from which the VM was assigned
|
||||||
* @param toUser the to user
|
* @param toUser the to user
|
||||||
*/
|
*/
|
||||||
public UpdateAssignment(String usedPool, String toUser) {
|
public UpdateAssignment(VmPool fromPool, String toUser) {
|
||||||
this.usedPool = usedPool;
|
this.fromPool = fromPool;
|
||||||
this.toUser = toUser;
|
this.toUser = toUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the pool to assign from.
|
* Gets the pool from which the VM was assigned.
|
||||||
*
|
*
|
||||||
* @return the pool
|
* @return the pool
|
||||||
*/
|
*/
|
||||||
public String usedPool() {
|
public VmPool fromPool() {
|
||||||
return usedPool;
|
return fromPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the user to assign to.
|
* Gets the user to whom the VM was assigned.
|
||||||
*
|
*
|
||||||
* @return the to user
|
* @return the to user
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -201,8 +201,8 @@ data:
|
||||||
<#if spec.vm.display.outputs?? >
|
<#if spec.vm.display.outputs?? >
|
||||||
outputs: ${ spec.vm.display.outputs?c }
|
outputs: ${ spec.vm.display.outputs?c }
|
||||||
</#if>
|
</#if>
|
||||||
<#if spec.vm.display.loggedInUser?? >
|
<#if loginRequestedFor?? >
|
||||||
loggedInUser: "${ spec.vm.display.loggedInUser }"
|
loggedInUser: "${ loginRequestedFor }"
|
||||||
</#if>
|
</#if>
|
||||||
<#if spec.vm.display.spice??>
|
<#if spec.vm.display.spice??>
|
||||||
spice:
|
spice:
|
||||||
|
|
|
||||||
|
|
@ -232,7 +232,7 @@ public class Controller extends Component {
|
||||||
if (vmStub.updateStatus(vmDef, from -> {
|
if (vmStub.updateStatus(vmDef, from -> {
|
||||||
JsonObject status = from.statusJson();
|
JsonObject status = from.statusJson();
|
||||||
var assignment = GsonPtr.to(status).to(Status.ASSIGNMENT);
|
var assignment = GsonPtr.to(status).to(Status.ASSIGNMENT);
|
||||||
assignment.set("pool", event.usedPool());
|
assignment.set("pool", event.fromPool().name());
|
||||||
assignment.set("user", event.toUser());
|
assignment.set("user", event.toUser());
|
||||||
assignment.set("lastUsed", Instant.now().toString());
|
assignment.set("lastUsed", Instant.now().toString());
|
||||||
return status;
|
return status;
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ import org.jdrupes.vmoperator.common.K8sDynamicModel;
|
||||||
import org.jdrupes.vmoperator.common.K8sDynamicModels;
|
import org.jdrupes.vmoperator.common.K8sDynamicModels;
|
||||||
import org.jdrupes.vmoperator.common.K8sDynamicStub;
|
import org.jdrupes.vmoperator.common.K8sDynamicStub;
|
||||||
import org.jdrupes.vmoperator.common.K8sObserver.ResponseType;
|
import org.jdrupes.vmoperator.common.K8sObserver.ResponseType;
|
||||||
|
import org.jdrupes.vmoperator.common.VmDefinition.Assignment;
|
||||||
import org.jdrupes.vmoperator.common.VmDefinitionStub;
|
import org.jdrupes.vmoperator.common.VmDefinitionStub;
|
||||||
import org.jdrupes.vmoperator.common.VmPool;
|
import org.jdrupes.vmoperator.common.VmPool;
|
||||||
import org.jdrupes.vmoperator.manager.events.GetPools;
|
import org.jdrupes.vmoperator.manager.events.GetPools;
|
||||||
|
|
@ -165,7 +166,7 @@ public class PoolMonitor extends
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync last usage to console state change if user matches
|
// Sync last usage to console state change if user matches
|
||||||
if (vmDef.assignedTo()
|
if (vmDef.assignment().map(Assignment::user)
|
||||||
.map(at -> at.equals(vmDef.consoleUser().orElse(null)))
|
.map(at -> at.equals(vmDef.consoleUser().orElse(null)))
|
||||||
.orElse(true)) {
|
.orElse(true)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -174,8 +175,8 @@ public class PoolMonitor extends
|
||||||
var ccChange = vmDef.condition("ConsoleConnected")
|
var ccChange = vmDef.condition("ConsoleConnected")
|
||||||
.map(cc -> cc.getLastTransitionTime().toInstant());
|
.map(cc -> cc.getLastTransitionTime().toInstant());
|
||||||
if (ccChange
|
if (ccChange
|
||||||
.map(tt -> vmDef.assignmentLastUsed().map(alu -> alu.isAfter(tt))
|
.map(tt -> vmDef.assignment().map(Assignment::lastUsed)
|
||||||
.orElse(true))
|
.map(alu -> alu.isAfter(tt)).orElse(true))
|
||||||
.orElse(true)) {
|
.orElse(true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.logging.Level;
|
||||||
import static org.jdrupes.vmoperator.common.Constants.APP_NAME;
|
import static org.jdrupes.vmoperator.common.Constants.APP_NAME;
|
||||||
import org.jdrupes.vmoperator.common.Constants.DisplaySecret;
|
import org.jdrupes.vmoperator.common.Constants.DisplaySecret;
|
||||||
import org.jdrupes.vmoperator.common.Convertions;
|
import org.jdrupes.vmoperator.common.Convertions;
|
||||||
|
|
@ -52,6 +53,9 @@ import org.jdrupes.vmoperator.common.K8sClient;
|
||||||
import org.jdrupes.vmoperator.common.K8sObserver;
|
import org.jdrupes.vmoperator.common.K8sObserver;
|
||||||
import org.jdrupes.vmoperator.common.K8sV1SecretStub;
|
import org.jdrupes.vmoperator.common.K8sV1SecretStub;
|
||||||
import org.jdrupes.vmoperator.common.VmDefinition;
|
import org.jdrupes.vmoperator.common.VmDefinition;
|
||||||
|
import org.jdrupes.vmoperator.common.VmDefinition.Assignment;
|
||||||
|
import org.jdrupes.vmoperator.common.VmPool;
|
||||||
|
import org.jdrupes.vmoperator.manager.events.GetPools;
|
||||||
import org.jdrupes.vmoperator.manager.events.ResetVm;
|
import org.jdrupes.vmoperator.manager.events.ResetVm;
|
||||||
import org.jdrupes.vmoperator.manager.events.VmChannel;
|
import org.jdrupes.vmoperator.manager.events.VmChannel;
|
||||||
import org.jdrupes.vmoperator.manager.events.VmDefChanged;
|
import org.jdrupes.vmoperator.manager.events.VmDefChanged;
|
||||||
|
|
@ -212,11 +216,6 @@ public class Reconciler extends Component {
|
||||||
@SuppressWarnings("PMD.ConfusingTernary")
|
@SuppressWarnings("PMD.ConfusingTernary")
|
||||||
public void onVmDefChanged(VmDefChanged event, VmChannel channel)
|
public void onVmDefChanged(VmDefChanged event, VmChannel channel)
|
||||||
throws ApiException, TemplateException, IOException {
|
throws ApiException, TemplateException, IOException {
|
||||||
// We're only interested in "spec" changes.
|
|
||||||
if (!event.specChanged()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ownership relationships takes care of deletions
|
// Ownership relationships takes care of deletions
|
||||||
if (event.type() == K8sObserver.ResponseType.DELETED) {
|
if (event.type() == K8sObserver.ResponseType.DELETED) {
|
||||||
logger.fine(
|
logger.fine(
|
||||||
|
|
@ -228,6 +227,11 @@ public class Reconciler extends Component {
|
||||||
Map<String, Object> model
|
Map<String, Object> model
|
||||||
= prepareModel(channel.client(), event.vmDefinition());
|
= prepareModel(channel.client(), event.vmDefinition());
|
||||||
var configMap = cmReconciler.reconcile(model, channel);
|
var configMap = cmReconciler.reconcile(model, channel);
|
||||||
|
|
||||||
|
// The remaining reconcilers depend only on changes of the spec part.
|
||||||
|
if (!event.specChanged()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
model.put("cm", configMap);
|
model.put("cm", configMap);
|
||||||
dsReconciler.reconcile(event, model, channel);
|
dsReconciler.reconcile(event, model, channel);
|
||||||
// Manage (eventual) removal of stateful set.
|
// Manage (eventual) removal of stateful set.
|
||||||
|
|
@ -266,24 +270,10 @@ public class Reconciler extends Component {
|
||||||
Optional.ofNullable(Reconciler.class.getPackage()
|
Optional.ofNullable(Reconciler.class.getPackage()
|
||||||
.getImplementationVersion()).orElse("(Unknown)"));
|
.getImplementationVersion()).orElse("(Unknown)"));
|
||||||
model.put("cr", vmDef);
|
model.put("cr", vmDef);
|
||||||
// Freemarker's static models don't handle nested classes.
|
|
||||||
model.put("constants", constantsMap(Constants.class));
|
|
||||||
model.put("reconciler", config);
|
model.put("reconciler", config);
|
||||||
|
model.put("constants", constantsMap(Constants.class));
|
||||||
// Check if we have a display secret
|
addLoginRequestedFor(model, vmDef);
|
||||||
ListOptions options = new ListOptions();
|
addDisplaySecret(client, model, vmDef);
|
||||||
options.setLabelSelector("app.kubernetes.io/name=" + APP_NAME + ","
|
|
||||||
+ "app.kubernetes.io/component=" + DisplaySecret.NAME + ","
|
|
||||||
+ "app.kubernetes.io/instance=" + vmDef.name());
|
|
||||||
var dsStub = K8sV1SecretStub
|
|
||||||
.list(client, vmDef.namespace(), options)
|
|
||||||
.stream()
|
|
||||||
.findFirst();
|
|
||||||
if (dsStub.isPresent()) {
|
|
||||||
dsStub.get().model().ifPresent(m -> {
|
|
||||||
model.put("displaySecret", m.getMetadata().getName());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
model.put("parseQuantity", parseQuantityModel);
|
model.put("parseQuantity", parseQuantityModel);
|
||||||
|
|
@ -294,6 +284,13 @@ public class Reconciler extends Component {
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a map with constants. Needed because freemarker doesn't support
|
||||||
|
* nested classes with its static models.
|
||||||
|
*
|
||||||
|
* @param clazz the clazz
|
||||||
|
* @return the map
|
||||||
|
*/
|
||||||
@SuppressWarnings("PMD.EmptyCatchBlock")
|
@SuppressWarnings("PMD.EmptyCatchBlock")
|
||||||
private Map<String, Object> constantsMap(Class<?> clazz) {
|
private Map<String, Object> constantsMap(Class<?> clazz) {
|
||||||
@SuppressWarnings("PMD.UseConcurrentHashMap")
|
@SuppressWarnings("PMD.UseConcurrentHashMap")
|
||||||
|
|
@ -318,6 +315,38 @@ public class Reconciler extends Component {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addLoginRequestedFor(Map<String, Object> model,
|
||||||
|
VmDefinition vmDef) {
|
||||||
|
vmDef.assignment().filter(a -> {
|
||||||
|
try {
|
||||||
|
return newEventPipeline()
|
||||||
|
.fire(new GetPools().withName(a.pool())).get()
|
||||||
|
.stream().findFirst().map(VmPool::loginOnAssignment)
|
||||||
|
.orElse(false);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.log(Level.WARNING, e, e::getMessage);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}).map(Assignment::user)
|
||||||
|
.or(() -> vmDef.fromSpec("vm", "display", "loggedInUser"))
|
||||||
|
.ifPresent(u -> model.put("loginRequestedFor", u));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addDisplaySecret(K8sClient client, Map<String, Object> model,
|
||||||
|
VmDefinition vmDef) throws ApiException {
|
||||||
|
ListOptions options = new ListOptions();
|
||||||
|
options.setLabelSelector("app.kubernetes.io/name=" + APP_NAME + ","
|
||||||
|
+ "app.kubernetes.io/component=" + DisplaySecret.NAME + ","
|
||||||
|
+ "app.kubernetes.io/instance=" + vmDef.name());
|
||||||
|
var dsStub = K8sV1SecretStub
|
||||||
|
.list(client, vmDef.namespace(), options).stream().findFirst();
|
||||||
|
if (dsStub.isPresent()) {
|
||||||
|
dsStub.get().model().ifPresent(m -> {
|
||||||
|
model.put("displaySecret", m.getMetadata().getName());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final TemplateMethodModelEx parseQuantityModel
|
private final TemplateMethodModelEx parseQuantityModel
|
||||||
= new TemplateMethodModelEx() {
|
= new TemplateMethodModelEx() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ import org.jdrupes.vmoperator.common.K8sV1ConfigMapStub;
|
||||||
import org.jdrupes.vmoperator.common.K8sV1PodStub;
|
import org.jdrupes.vmoperator.common.K8sV1PodStub;
|
||||||
import org.jdrupes.vmoperator.common.K8sV1StatefulSetStub;
|
import org.jdrupes.vmoperator.common.K8sV1StatefulSetStub;
|
||||||
import org.jdrupes.vmoperator.common.VmDefinition;
|
import org.jdrupes.vmoperator.common.VmDefinition;
|
||||||
|
import org.jdrupes.vmoperator.common.VmDefinition.Assignment;
|
||||||
import org.jdrupes.vmoperator.common.VmDefinitionStub;
|
import org.jdrupes.vmoperator.common.VmDefinitionStub;
|
||||||
import org.jdrupes.vmoperator.common.VmDefinitions;
|
import org.jdrupes.vmoperator.common.VmDefinitions;
|
||||||
import org.jdrupes.vmoperator.common.VmExtraData;
|
import org.jdrupes.vmoperator.common.VmExtraData;
|
||||||
|
|
@ -234,10 +235,10 @@ public class VmMonitor extends
|
||||||
|| !c.vmDefinition().permissionsFor(event.user().orElse(null),
|
|| !c.vmDefinition().permissionsFor(event.user().orElse(null),
|
||||||
event.roles()).isEmpty())
|
event.roles()).isEmpty())
|
||||||
.filter(c -> event.fromPool().isEmpty()
|
.filter(c -> event.fromPool().isEmpty()
|
||||||
|| c.vmDefinition().assignedFrom()
|
|| c.vmDefinition().assignment().map(Assignment::pool)
|
||||||
.map(p -> p.equals(event.fromPool().get())).orElse(false))
|
.map(p -> p.equals(event.fromPool().get())).orElse(false))
|
||||||
.filter(c -> event.toUser().isEmpty()
|
.filter(c -> event.toUser().isEmpty()
|
||||||
|| c.vmDefinition().assignedTo()
|
|| c.vmDefinition().assignment().map(Assignment::user)
|
||||||
.map(u -> u.equals(event.toUser().get())).orElse(false))
|
.map(u -> u.equals(event.toUser().get())).orElse(false))
|
||||||
.map(c -> new VmData(c.vmDefinition(), c))
|
.map(c -> new VmData(c.vmDefinition(), c))
|
||||||
.toList());
|
.toList());
|
||||||
|
|
@ -257,9 +258,9 @@ public class VmMonitor extends
|
||||||
while (true) {
|
while (true) {
|
||||||
// Search for existing assignment.
|
// Search for existing assignment.
|
||||||
var vmQuery = channelManager.channels().stream()
|
var vmQuery = channelManager.channels().stream()
|
||||||
.filter(c -> c.vmDefinition().assignedFrom()
|
.filter(c -> c.vmDefinition().assignment().map(Assignment::pool)
|
||||||
.map(p -> p.equals(event.fromPool())).orElse(false))
|
.map(p -> p.equals(event.fromPool())).orElse(false))
|
||||||
.filter(c -> c.vmDefinition().assignedTo()
|
.filter(c -> c.vmDefinition().assignment().map(Assignment::user)
|
||||||
.map(u -> u.equals(event.toUser())).orElse(false))
|
.map(u -> u.equals(event.toUser())).orElse(false))
|
||||||
.findFirst();
|
.findFirst();
|
||||||
if (vmQuery.isPresent()) {
|
if (vmQuery.isPresent()) {
|
||||||
|
|
@ -280,7 +281,8 @@ public class VmMonitor extends
|
||||||
vmQuery = channelManager.channels().stream()
|
vmQuery = channelManager.channels().stream()
|
||||||
.filter(c -> vmPool.isAssignable(c.vmDefinition()))
|
.filter(c -> vmPool.isAssignable(c.vmDefinition()))
|
||||||
.sorted(Comparator.comparing((VmChannel c) -> c.vmDefinition()
|
.sorted(Comparator.comparing((VmChannel c) -> c.vmDefinition()
|
||||||
.assignmentLastUsed().orElse(Instant.ofEpochSecond(0)))
|
.assignment().map(Assignment::lastUsed)
|
||||||
|
.orElse(Instant.ofEpochSecond(0)))
|
||||||
.thenComparing(preferRunning))
|
.thenComparing(preferRunning))
|
||||||
.findFirst();
|
.findFirst();
|
||||||
|
|
||||||
|
|
@ -293,7 +295,7 @@ public class VmMonitor extends
|
||||||
var chosenVm = vmQuery.get();
|
var chosenVm = vmQuery.get();
|
||||||
var vmPipeline = chosenVm.pipeline();
|
var vmPipeline = chosenVm.pipeline();
|
||||||
if (Optional.ofNullable(vmPipeline.fire(new UpdateAssignment(
|
if (Optional.ofNullable(vmPipeline.fire(new UpdateAssignment(
|
||||||
vmPool.name(), event.toUser()), chosenVm).get())
|
vmPool, event.toUser()), chosenVm).get())
|
||||||
.orElse(false)) {
|
.orElse(false)) {
|
||||||
var vmDef = chosenVm.vmDefinition();
|
var vmDef = chosenVm.vmDefinition();
|
||||||
event.setResult(new VmData(vmDef, chosenVm));
|
event.setResult(new VmData(vmDef, chosenVm));
|
||||||
|
|
@ -301,10 +303,6 @@ public class VmMonitor extends
|
||||||
// Make sure that a newly assigned VM is running.
|
// Make sure that a newly assigned VM is running.
|
||||||
chosenVm.pipeline().fire(new ModifyVm(vmDef.name(),
|
chosenVm.pipeline().fire(new ModifyVm(vmDef.name(),
|
||||||
"state", "Running", chosenVm));
|
"state", "Running", chosenVm));
|
||||||
if (vmPool.loginOnAssignment()) {
|
|
||||||
chosenVm.pipeline().fire(new ModifyVm(vmDef.name(),
|
|
||||||
"display/loggedInUser", event.toUser(), chosenVm));
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -327,6 +327,18 @@ public class GsonPtr {
|
||||||
return set(selector, new JsonPrimitive(value));
|
return set(selector, new JsonPrimitive(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Short for `set(selector, new JsonPrimitive(value))`.
|
||||||
|
*
|
||||||
|
* @param selector the selector
|
||||||
|
* @param value the value
|
||||||
|
* @return the gson ptr
|
||||||
|
* @see #set(Object, JsonElement)
|
||||||
|
*/
|
||||||
|
public GsonPtr set(Object selector, Boolean value) {
|
||||||
|
return set(selector, new JsonPrimitive(value));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as {@link #set(Object, JsonElement)}, but sets the value
|
* Same as {@link #set(Object, JsonElement)}, but sets the value
|
||||||
* only if it doesn't exist yet, else returns the existing value.
|
* only if it doesn't exist yet, else returns the existing value.
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ import java.util.stream.Collectors;
|
||||||
import org.bouncycastle.util.Objects;
|
import org.bouncycastle.util.Objects;
|
||||||
import org.jdrupes.vmoperator.common.K8sObserver;
|
import org.jdrupes.vmoperator.common.K8sObserver;
|
||||||
import org.jdrupes.vmoperator.common.VmDefinition;
|
import org.jdrupes.vmoperator.common.VmDefinition;
|
||||||
|
import org.jdrupes.vmoperator.common.VmDefinition.Assignment;
|
||||||
import org.jdrupes.vmoperator.common.VmDefinition.Permission;
|
import org.jdrupes.vmoperator.common.VmDefinition.Permission;
|
||||||
import org.jdrupes.vmoperator.common.VmPool;
|
import org.jdrupes.vmoperator.common.VmPool;
|
||||||
import org.jdrupes.vmoperator.manager.events.AssignVm;
|
import org.jdrupes.vmoperator.manager.events.AssignVm;
|
||||||
|
|
@ -657,10 +658,11 @@ public class VmAccess extends FreeMarkerConlet<VmAccess.ResourceModel> {
|
||||||
var user
|
var user
|
||||||
= WebConsoleUtils.userFromSession(connection.session())
|
= WebConsoleUtils.userFromSession(connection.session())
|
||||||
.map(ConsoleUser::getName).orElse(null);
|
.map(ConsoleUser::getName).orElse(null);
|
||||||
var toBeUsedByConlet = vmDef.assignedFrom()
|
var toBeUsedByConlet = vmDef.assignment()
|
||||||
|
.map(Assignment::pool)
|
||||||
.map(p -> p.equals(model.get().name())).orElse(false)
|
.map(p -> p.equals(model.get().name())).orElse(false)
|
||||||
&& vmDef.assignedTo().map(u -> u.equals(user))
|
&& vmDef.assignment().map(Assignment::user)
|
||||||
.orElse(false);
|
.map(u -> u.equals(user)).orElse(false);
|
||||||
if (!Objects.areEqual(model.get().assignedVm(),
|
if (!Objects.areEqual(model.get().assignedVm(),
|
||||||
vmDef.name()) && !toBeUsedByConlet) {
|
vmDef.name()) && !toBeUsedByConlet) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue