Centralize evaluation of console accessibility.
This commit is contained in:
parent
7437a17c9f
commit
2524172c12
5 changed files with 85 additions and 66 deletions
|
|
@ -39,6 +39,8 @@ import java.util.function.Function;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.jdrupes.vmoperator.common.Constants.Status;
|
import org.jdrupes.vmoperator.common.Constants.Status;
|
||||||
|
import org.jdrupes.vmoperator.common.Constants.Status.Condition;
|
||||||
|
import org.jdrupes.vmoperator.common.Constants.Status.Condition.Reason;
|
||||||
import org.jdrupes.vmoperator.util.DataPath;
|
import org.jdrupes.vmoperator.util.DataPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -363,9 +365,17 @@ public class VmDefinition extends K8sDynamicModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the console is accessible. Returns true if the console is
|
* Check if the console is accessible. Always returns `true` if
|
||||||
* currently unused, used by the given user or if the permissions
|
* the VM is running and the permissions allow taking over the
|
||||||
* allow taking over the console.
|
* console. Else, returns `true` if
|
||||||
|
*
|
||||||
|
* * the permissions allow access to the console and
|
||||||
|
*
|
||||||
|
* * the VM is running and
|
||||||
|
*
|
||||||
|
* * the console is currently unused or used by the given user and
|
||||||
|
*
|
||||||
|
* * if user login is requested, the given user is logged in.
|
||||||
*
|
*
|
||||||
* @param user the user
|
* @param user the user
|
||||||
* @param permissions the permissions
|
* @param permissions the permissions
|
||||||
|
|
@ -373,34 +383,31 @@ public class VmDefinition extends K8sDynamicModel {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("PMD.SimplifyBooleanReturns")
|
@SuppressWarnings("PMD.SimplifyBooleanReturns")
|
||||||
public boolean consoleAccessible(String user, Set<Permission> permissions) {
|
public boolean consoleAccessible(String user, Set<Permission> permissions) {
|
||||||
// If user has takeConsole permission, console is always accessible
|
// Basic checks
|
||||||
if (permissions.contains(VmDefinition.Permission.TAKE_CONSOLE)) {
|
if (!conditionStatus(Condition.RUNNING).orElse(false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (permissions.contains(Permission.TAKE_CONSOLE)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (!permissions.contains(Permission.ACCESS_CONSOLE)) {
|
||||||
// Check if an automatic login is requested. If so, allow access only
|
|
||||||
// if the log in has been established
|
|
||||||
var wantedLogIn = DataPath.<String> get(spec(), "vm", "display",
|
|
||||||
"loggedInUser").orElse(null);
|
|
||||||
if (wantedLogIn != null
|
|
||||||
&& !wantedLogIn.equals(status().get(Status.LOGGED_IN_USER))) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the console is not in use, allow access
|
// If the console is in use by another user, deny access
|
||||||
if (!conditionStatus("ConsoleConnected").orElse(true)) {
|
if (conditionStatus(Condition.CONSOLE_CONNECTED).orElse(false)
|
||||||
return true;
|
&& !consoleUser().map(cu -> cu.equals(user)).orElse(false)) {
|
||||||
}
|
|
||||||
|
|
||||||
// If the console is in use by the user, allow access
|
|
||||||
if (consoleUser().map(cu -> cu.equals(user)).orElse(true)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Else deny access
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no login is requested, allow access, else check if user matches
|
||||||
|
if (condition(Condition.USER_LOGGED_IN).map(V1Condition::getReason)
|
||||||
|
.map(r -> Reason.NOT_REQUESTED.equals(r)).orElse(false)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return user.equals(status().get(Status.LOGGED_IN_USER));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the display password serial.
|
* Get the display password serial.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -524,6 +524,13 @@ public class VmAccess extends FreeMarkerConlet<VmAccess.ResourceModel> {
|
||||||
.assignedTo(user)).get().stream().findFirst();
|
.assignedTo(user)).get().stream().findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the permissions from the VM definition.
|
||||||
|
*
|
||||||
|
* @param vmDef the VM definition
|
||||||
|
* @param session the session
|
||||||
|
* @return the sets the
|
||||||
|
*/
|
||||||
private Set<Permission> permissions(VmDefinition vmDef, Session session) {
|
private Set<Permission> permissions(VmDefinition vmDef, Session session) {
|
||||||
var user = WebConsoleUtils.userFromSession(session)
|
var user = WebConsoleUtils.userFromSession(session)
|
||||||
.map(ConsoleUser::getName).orElse(null);
|
.map(ConsoleUser::getName).orElse(null);
|
||||||
|
|
@ -532,6 +539,13 @@ public class VmAccess extends FreeMarkerConlet<VmAccess.ResourceModel> {
|
||||||
return vmDef.permissionsFor(user, roles);
|
return vmDef.permissionsFor(user, roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the permissions from the pool.
|
||||||
|
*
|
||||||
|
* @param pool the pool
|
||||||
|
* @param session the session
|
||||||
|
* @return the sets the
|
||||||
|
*/
|
||||||
private Set<Permission> permissions(VmPool pool, Session session) {
|
private Set<Permission> permissions(VmPool pool, Session session) {
|
||||||
var user = WebConsoleUtils.userFromSession(session)
|
var user = WebConsoleUtils.userFromSession(session)
|
||||||
.map(ConsoleUser::getName).orElse(null);
|
.map(ConsoleUser::getName).orElse(null);
|
||||||
|
|
@ -540,23 +554,33 @@ public class VmAccess extends FreeMarkerConlet<VmAccess.ResourceModel> {
|
||||||
return pool.permissionsFor(user, roles);
|
return pool.permissionsFor(user, roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Permission> permissions(ResourceModel model, Session session,
|
/**
|
||||||
VmPool pool, VmDefinition vmDef) throws InterruptedException {
|
* Returns the permissions from the VM definition or the pool depending
|
||||||
|
* on the state of the model.
|
||||||
|
*
|
||||||
|
* @param session the session
|
||||||
|
* @param model the model
|
||||||
|
* @param vmDef the vm def
|
||||||
|
* @return the sets the
|
||||||
|
* @throws InterruptedException the interrupted exception
|
||||||
|
*/
|
||||||
|
private Set<Permission> permissions(Session session, ResourceModel model,
|
||||||
|
VmDefinition vmDef) throws InterruptedException {
|
||||||
var user = WebConsoleUtils.userFromSession(session)
|
var user = WebConsoleUtils.userFromSession(session)
|
||||||
.map(ConsoleUser::getName).orElse(null);
|
.map(ConsoleUser::getName).orElse(null);
|
||||||
var roles = WebConsoleUtils.rolesFromSession(session)
|
var roles = WebConsoleUtils.rolesFromSession(session)
|
||||||
.stream().map(ConsoleRole::getName).toList();
|
.stream().map(ConsoleRole::getName).toList();
|
||||||
if (model.mode() == ResourceModel.Mode.POOL) {
|
if (model.mode() == ResourceModel.Mode.POOL) {
|
||||||
if (pool == null) {
|
// Use permissions from pool
|
||||||
pool = appPipeline.fire(new GetPools()
|
var pool = appPipeline.fire(new GetPools().withName(model.name()))
|
||||||
.withName(model.name())).get().stream().findFirst()
|
.get().stream().findFirst().orElse(null);
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
if (pool == null) {
|
if (pool == null) {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
return pool.permissionsFor(user, roles);
|
return pool.permissionsFor(user, roles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use permissions from VM
|
||||||
if (vmDef == null) {
|
if (vmDef == null) {
|
||||||
vmDef = appPipeline.fire(new GetVms().assignedFrom(model.name())
|
vmDef = appPipeline.fire(new GetVms().assignedFrom(model.name())
|
||||||
.assignedTo(user)).get().stream().map(VmData::definition)
|
.assignedTo(user)).get().stream().map(VmData::definition)
|
||||||
|
|
@ -578,7 +602,7 @@ public class VmAccess extends FreeMarkerConlet<VmAccess.ResourceModel> {
|
||||||
VmDefinition vmDef) throws InterruptedException {
|
VmDefinition vmDef) throws InterruptedException {
|
||||||
channel.respond(new NotifyConletView(type(),
|
channel.respond(new NotifyConletView(type(),
|
||||||
model.getConletId(), "updateConfig", model.mode(), model.name(),
|
model.getConletId(), "updateConfig", model.mode(), model.name(),
|
||||||
permissions(model, channel.session(), null, vmDef).stream()
|
permissions(channel.session(), model, vmDef).stream()
|
||||||
.map(VmDefinition.Permission::toString).toList()));
|
.map(VmDefinition.Permission::toString).toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -589,12 +613,17 @@ public class VmAccess extends FreeMarkerConlet<VmAccess.ResourceModel> {
|
||||||
model.setAssignedVm(null);
|
model.setAssignedVm(null);
|
||||||
} else {
|
} else {
|
||||||
model.setAssignedVm(vmDef.name());
|
model.setAssignedVm(vmDef.name());
|
||||||
|
var session = channel.session();
|
||||||
|
var user = WebConsoleUtils.userFromSession(session)
|
||||||
|
.map(ConsoleUser::getName).orElse(null);
|
||||||
|
var perms = permissions(session, model, vmDef);
|
||||||
try {
|
try {
|
||||||
data = Map.of("metadata",
|
data = Map.of(
|
||||||
Map.of("namespace", vmDef.namespace(),
|
"metadata", Map.of("namespace", vmDef.namespace(),
|
||||||
"name", vmDef.name()),
|
"name", vmDef.name()),
|
||||||
"spec", vmDef.spec(),
|
"spec", vmDef.spec(),
|
||||||
"status", vmDef.status());
|
"status", vmDef.status(),
|
||||||
|
"consoleAccessible", vmDef.consoleAccessible(user, perms));
|
||||||
} catch (JsonSyntaxException e) {
|
} catch (JsonSyntaxException e) {
|
||||||
logger.log(Level.SEVERE, e,
|
logger.log(Level.SEVERE, e,
|
||||||
() -> "Failed to serialize VM definition");
|
() -> "Failed to serialize VM definition");
|
||||||
|
|
@ -635,6 +664,8 @@ public class VmAccess extends FreeMarkerConlet<VmAccess.ResourceModel> {
|
||||||
// Update known conlets
|
// Update known conlets
|
||||||
for (var entry : conletIdsByConsoleConnection().entrySet()) {
|
for (var entry : conletIdsByConsoleConnection().entrySet()) {
|
||||||
var connection = entry.getKey();
|
var connection = entry.getKey();
|
||||||
|
var user = WebConsoleUtils.userFromSession(connection.session())
|
||||||
|
.map(ConsoleUser::getName).orElse(null);
|
||||||
for (var conletId : entry.getValue()) {
|
for (var conletId : entry.getValue()) {
|
||||||
var model = stateFromSession(connection.session(), conletId);
|
var model = stateFromSession(connection.session(), conletId);
|
||||||
if (model.isEmpty()
|
if (model.isEmpty()
|
||||||
|
|
@ -655,9 +686,6 @@ public class VmAccess extends FreeMarkerConlet<VmAccess.ResourceModel> {
|
||||||
} else {
|
} else {
|
||||||
// Check if VM is used by pool conlet or to be assigned to
|
// Check if VM is used by pool conlet or to be assigned to
|
||||||
// it
|
// it
|
||||||
var user
|
|
||||||
= WebConsoleUtils.userFromSession(connection.session())
|
|
||||||
.map(ConsoleUser::getName).orElse(null);
|
|
||||||
var toBeUsedByConlet = vmDef.assignment()
|
var toBeUsedByConlet = vmDef.assignment()
|
||||||
.map(Assignment::pool)
|
.map(Assignment::pool)
|
||||||
.map(p -> p.equals(model.get().name())).orElse(false)
|
.map(p -> p.equals(model.get().name())).orElse(false)
|
||||||
|
|
@ -752,7 +780,7 @@ public class VmAccess extends FreeMarkerConlet<VmAccess.ResourceModel> {
|
||||||
var vmChannel = vmData.get().channel();
|
var vmChannel = vmData.get().channel();
|
||||||
var vmDef = vmData.get().definition();
|
var vmDef = vmData.get().definition();
|
||||||
var vmName = vmDef.metadata().getName();
|
var vmName = vmDef.metadata().getName();
|
||||||
var perms = permissions(model, channel.session(), null, vmDef);
|
var perms = permissions(channel.session(), model, vmDef);
|
||||||
var resourceBundle = resourceBundle(channel.locale());
|
var resourceBundle = resourceBundle(channel.locale());
|
||||||
switch (event.method()) {
|
switch (event.method()) {
|
||||||
case "start":
|
case "start":
|
||||||
|
|
@ -776,9 +804,7 @@ public class VmAccess extends FreeMarkerConlet<VmAccess.ResourceModel> {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "openConsole":
|
case "openConsole":
|
||||||
if (perms.contains(VmDefinition.Permission.ACCESS_CONSOLE)) {
|
|
||||||
openConsole(channel, model, vmChannel, vmDef, perms);
|
openConsole(channel, model, vmChannel, vmDef, perms);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:// ignore
|
default:// ignore
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* VM-Operator
|
* VM-Operator
|
||||||
* Copyright (C) 2024 Michael N. Lipp
|
* Copyright (C) 2024,2025 Michael N. Lipp
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
|
@ -71,12 +71,10 @@ window.orgJDrupesVmOperatorVmAccess.initPreview = (previewDom: HTMLElement,
|
||||||
const poolName = computed(() => previewApi.poolName);
|
const poolName = computed(() => previewApi.poolName);
|
||||||
const vmName = computed(() => previewApi.vmDefinition.name);
|
const vmName = computed(() => previewApi.vmDefinition.name);
|
||||||
const configured = computed(() => previewApi.vmDefinition.spec);
|
const configured = computed(() => previewApi.vmDefinition.spec);
|
||||||
|
const accessible = computed(() => previewApi.vmDefinition.consoleAccessible);
|
||||||
const busy = computed(() => previewApi.vmDefinition.spec
|
const busy = computed(() => previewApi.vmDefinition.spec
|
||||||
&& (previewApi.vmDefinition.spec.vm.state === 'Running'
|
&& (previewApi.vmDefinition.spec.vm.state === 'Running'
|
||||||
&& ((previewApi.poolName
|
&& (!previewApi.vmDefinition.consoleAccessible)
|
||||||
&& previewApi.vmDefinition.userLoginRequested)
|
|
||||||
? !previewApi.vmDefinition.userLoggedIn
|
|
||||||
: !previewApi.vmDefinition.running)
|
|
||||||
|| previewApi.vmDefinition.spec.vm.state === 'Stopped'
|
|| previewApi.vmDefinition.spec.vm.state === 'Stopped'
|
||||||
&& previewApi.vmDefinition.running));
|
&& previewApi.vmDefinition.running));
|
||||||
const startable = computed(() => previewApi.vmDefinition.spec
|
const startable = computed(() => previewApi.vmDefinition.spec
|
||||||
|
|
@ -88,8 +86,6 @@ window.orgJDrupesVmOperatorVmAccess.initPreview = (previewDom: HTMLElement,
|
||||||
previewApi.vmDefinition.spec.vm.state !== 'Stopped'
|
previewApi.vmDefinition.spec.vm.state !== 'Stopped'
|
||||||
&& previewApi.vmDefinition.running);
|
&& previewApi.vmDefinition.running);
|
||||||
const running = computed(() => previewApi.vmDefinition.running);
|
const running = computed(() => previewApi.vmDefinition.running);
|
||||||
const userLoginRequested = computed(() => previewApi.vmDefinition.userLoginRequested);
|
|
||||||
const userLoggedIn = computed(() => previewApi.vmDefinition.userLoggedIn);
|
|
||||||
const inUse = computed(() => previewApi.vmDefinition.usedBy != '');
|
const inUse = computed(() => previewApi.vmDefinition.usedBy != '');
|
||||||
const permissions = computed(() => previewApi.permissions);
|
const permissions = computed(() => previewApi.permissions);
|
||||||
const osicon = computed(() => {
|
const osicon = computed(() => {
|
||||||
|
|
@ -125,8 +121,8 @@ window.orgJDrupesVmOperatorVmAccess.initPreview = (previewDom: HTMLElement,
|
||||||
};
|
};
|
||||||
|
|
||||||
return { localize, resourceBase, vmAction, poolName, vmName,
|
return { localize, resourceBase, vmAction, poolName, vmName,
|
||||||
configured, busy, startable, stoppable, running, userLoggedIn,
|
configured, accessible, busy, startable, stoppable, running,
|
||||||
userLoginRequested, inUse, permissions, osicon };
|
inUse, permissions, osicon };
|
||||||
},
|
},
|
||||||
template: `
|
template: `
|
||||||
<table>
|
<table>
|
||||||
|
|
@ -134,10 +130,7 @@ window.orgJDrupesVmOperatorVmAccess.initPreview = (previewDom: HTMLElement,
|
||||||
<tr>
|
<tr>
|
||||||
<td rowspan="2" style="position: relative"><span
|
<td rowspan="2" style="position: relative"><span
|
||||||
style="position: absolute;" :class="{ busy: busy }"
|
style="position: absolute;" :class="{ busy: busy }"
|
||||||
><img role=button :aria-disabled="
|
><img role=button :aria-disabled="!accessible"
|
||||||
((poolName && userLoginRequested)
|
|
||||||
? !userLoggedIn : !running)
|
|
||||||
|| !permissions.includes('accessConsole')"
|
|
||||||
v-on:click="vmAction('openConsole')"
|
v-on:click="vmAction('openConsole')"
|
||||||
:src="resourceBase + (running
|
:src="resourceBase + (running
|
||||||
? (inUse ? 'computer-in-use.svg' : 'computer.svg')
|
? (inUse ? 'computer-in-use.svg' : 'computer.svg')
|
||||||
|
|
@ -214,16 +207,11 @@ JGConsole.registerConletFunction("org.jdrupes.vmoperator.vmaccess.VmAccess",
|
||||||
vmDefinition.currentRam = Number(vmDefinition.status.ram);
|
vmDefinition.currentRam = Number(vmDefinition.status.ram);
|
||||||
vmDefinition.usedBy = vmDefinition.status.consoleClient || "";
|
vmDefinition.usedBy = vmDefinition.status.consoleClient || "";
|
||||||
// safety fallbacks
|
// safety fallbacks
|
||||||
vmDefinition.userLoginRequested = true;
|
|
||||||
vmDefinition.userLoggedIn = false;
|
|
||||||
vmDefinition.status.conditions.forEach((condition: any) => {
|
vmDefinition.status.conditions.forEach((condition: any) => {
|
||||||
if (condition.type === "Running") {
|
if (condition.type === "Running") {
|
||||||
vmDefinition.running = condition.status === "True";
|
vmDefinition.running = condition.status === "True";
|
||||||
vmDefinition.runningConditionSince
|
vmDefinition.runningConditionSince
|
||||||
= new Date(condition.lastTransitionTime);
|
= new Date(condition.lastTransitionTime);
|
||||||
} else if (condition.type === "UserLoggedIn") {
|
|
||||||
vmDefinition.userLoggedIn = condition.status === "True";
|
|
||||||
vmDefinition.userLoginRequested = condition.reason !== "NotRequested";
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -60,21 +60,21 @@
|
||||||
<td class="jdrupes-vmoperator-vmmgmt-view-action-list">
|
<td class="jdrupes-vmoperator-vmmgmt-view-action-list">
|
||||||
<span role="button"
|
<span role="button"
|
||||||
v-if="entry.spec.vm.state != 'Running' && !entry['running']
|
v-if="entry.spec.vm.state != 'Running' && !entry['running']
|
||||||
&& entry.permissions.includes('start')"
|
&& entry.permissions.includes('START')"
|
||||||
tabindex="0" class="fa fa-play" :title="localize('Start VM')"
|
tabindex="0" class="fa fa-play" :title="localize('Start VM')"
|
||||||
v-on:click="vmAction(entry.name, 'start')"></span>
|
v-on:click="vmAction(entry.name, 'start')"></span>
|
||||||
<span role="button" v-else class="fa fa-play"
|
<span role="button" v-else class="fa fa-play"
|
||||||
aria-disabled="true" :title="localize('Start VM')"></span>
|
aria-disabled="true" :title="localize('Start VM')"></span>
|
||||||
<span role="button"
|
<span role="button"
|
||||||
v-if="entry.spec.vm.state != 'Stopped' && entry['running']
|
v-if="entry.spec.vm.state != 'Stopped' && entry['running']
|
||||||
&& entry.permissions.includes('stop')"
|
&& entry.permissions.includes('STOP')"
|
||||||
tabindex="0" class="fa fa-stop" :title="localize('Stop VM')"
|
tabindex="0" class="fa fa-stop" :title="localize('Stop VM')"
|
||||||
v-on:click="vmAction(entry.name, 'stop')"></span>
|
v-on:click="vmAction(entry.name, 'stop')"></span>
|
||||||
<span role="button" v-else class="fa fa-stop"
|
<span role="button" v-else class="fa fa-stop"
|
||||||
aria-disabled="true" :title="localize('Stop VM')"></span>
|
aria-disabled="true" :title="localize('Stop VM')"></span>
|
||||||
<span role="button"
|
<span role="button"
|
||||||
:aria-disabled="!entry['running']
|
:aria-disabled="!entry['running']
|
||||||
|| !entry.permissions.includes('reset')"
|
|| !entry.permissions.includes('RESET')"
|
||||||
tabindex="0" class="svg-icon" :title="localize('Reset VM')"
|
tabindex="0" class="svg-icon" :title="localize('Reset VM')"
|
||||||
v-on:click="vmAction(entry.name, 'reset')">
|
v-on:click="vmAction(entry.name, 'reset')">
|
||||||
<svg viewBox="0 0 1541.33 1535.5083">
|
<svg viewBox="0 0 1541.33 1535.5083">
|
||||||
|
|
@ -86,8 +86,7 @@
|
||||||
? 'computer-off.svg' : (entry.usedFrom
|
? 'computer-off.svg' : (entry.usedFrom
|
||||||
? 'computer-in-use.svg' : 'computer.svg'))"
|
? 'computer-in-use.svg' : 'computer.svg'))"
|
||||||
:title="localize('Open console')"
|
:title="localize('Open console')"
|
||||||
:aria-disabled="!entry['running']
|
:aria-disabled="!entry.consoleAccessible"
|
||||||
|| !(entry.permissions.includes('accessConsole'))"
|
|
||||||
v-on:click="vmAction(entry.name, 'openConsole')">
|
v-on:click="vmAction(entry.name, 'openConsole')">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
|
|
@ -249,14 +249,15 @@ public class VmMgmt extends FreeMarkerConlet<VmMgmt.VmsModel> {
|
||||||
.toBigInteger());
|
.toBigInteger());
|
||||||
|
|
||||||
// Build result
|
// Build result
|
||||||
|
var perms = vmDef.permissionsFor(user, roles);
|
||||||
return Map.of("metadata",
|
return Map.of("metadata",
|
||||||
Map.of("namespace", vmDef.namespace(),
|
Map.of("namespace", vmDef.namespace(),
|
||||||
"name", vmDef.name()),
|
"name", vmDef.name()),
|
||||||
"spec", spec,
|
"spec", spec,
|
||||||
"status", status,
|
"status", status,
|
||||||
"nodeName", vmDef.extra().map(VmExtraData::nodeName).orElse(""),
|
"nodeName", vmDef.extra().map(VmExtraData::nodeName).orElse(""),
|
||||||
"permissions", vmDef.permissionsFor(user, roles).stream()
|
"consoleAccessible", vmDef.consoleAccessible(user, perms),
|
||||||
.map(VmDefinition.Permission::toString).toList());
|
"permissions", perms);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -438,9 +439,7 @@ public class VmMgmt extends FreeMarkerConlet<VmMgmt.VmsModel> {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "openConsole":
|
case "openConsole":
|
||||||
if (perms.contains(VmDefinition.Permission.ACCESS_CONSOLE)) {
|
|
||||||
openConsole(channel, model, vmChannel, vmDef, user, perms);
|
openConsole(channel, model, vmChannel, vmDef, user, perms);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case "cpus":
|
case "cpus":
|
||||||
fire(new ModifyVm(vmName, "currentCpus",
|
fire(new ModifyVm(vmName, "currentCpus",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue