Fix: Console endpoint API VM state handling, FR64 Follow-up (#212)
* Remove configkey to use the optional token parameter and improve preconditions
* Improve condition
diff --git a/api/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManager.java b/api/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManager.java
index 80c6b30..c7e7f43 100644
--- a/api/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManager.java
+++ b/api/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManager.java
@@ -18,15 +18,10 @@
import com.cloud.utils.component.Manager;
import org.apache.cloudstack.api.command.user.consoleproxy.ConsoleEndpoint;
-import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
public interface ConsoleAccessManager extends Manager, Configurable {
- ConfigKey<Boolean> ConsoleProxyExtraSecurityValidationEnabled = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Boolean.class,
- "consoleproxy.extra.security.validation.enabled", "false",
- "Enable/disable extra security validation for console proxy using an extra token", true);
-
ConsoleEndpoint generateConsoleEndpoint(Long vmId, String extraSecurityToken, String clientAddress);
boolean isSessionAllowed(String sessionUuid);
diff --git a/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java b/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
index fb70d9d..ce1aa64 100644
--- a/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
+++ b/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
@@ -50,7 +50,6 @@
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.security.keys.KeysManager;
import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
@@ -59,8 +58,10 @@
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -89,6 +90,10 @@
public static final Logger s_logger = Logger.getLogger(ConsoleAccessManagerImpl.class.getName());
+ private static final List<VirtualMachine.State> unsupportedConsoleVMState = Arrays.asList(
+ VirtualMachine.State.Stopped, VirtualMachine.State.Error, VirtualMachine.State.Destroyed
+ );
+
private static Set<String> allowedSessions;
@Override
@@ -129,13 +134,6 @@
return new ConsoleEndpoint(false, null, "Permission denied");
}
- if (BooleanUtils.isTrue(ConsoleAccessManager.ConsoleProxyExtraSecurityValidationEnabled.value()) &&
- StringUtils.isBlank(extraSecurityToken)) {
- String errorMsg = "Extra security validation is enabled but the extra token is missing";
- s_logger.error(errorMsg);
- return new ConsoleEndpoint(false, errorMsg);
- }
-
String sessionUuid = UUID.randomUUID().toString();
return generateAccessEndpoint(vmId, sessionUuid, extraSecurityToken, clientAddress);
} catch (Exception e) {
@@ -202,15 +200,22 @@
throw new CloudRuntimeException(msg);
}
+ String vmUuid = vm.getUuid();
+ if (unsupportedConsoleVMState.contains(vm.getState())) {
+ msg = "VM " + vmUuid + " must be running to connect console, sending blank response for console access request";
+ s_logger.warn(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
if (vm.getHostId() == null) {
- msg = "VM " + vmId + " lost host info, sending blank response for console access request";
+ msg = "VM " + vmUuid + " lost host info, sending blank response for console access request";
s_logger.warn(msg);
throw new CloudRuntimeException(msg);
}
HostVO host = managementServer.getHostBy(vm.getHostId());
if (host == null) {
- msg = "VM " + vmId + "'s host does not exist, sending blank response for console access request";
+ msg = "VM " + vmUuid + "'s host does not exist, sending blank response for console access request";
s_logger.warn(msg);
throw new CloudRuntimeException(msg);
}
@@ -467,6 +472,6 @@
@Override
public ConfigKey<?>[] getConfigKeys() {
- return new ConfigKey[] { ConsoleProxyExtraSecurityValidationEnabled };
+ return new ConfigKey[] {};
}
}
diff --git a/ui/src/components/widgets/Console.vue b/ui/src/components/widgets/Console.vue
index 772d86f..6f4a3e3 100644
--- a/ui/src/components/widgets/Console.vue
+++ b/ui/src/components/widgets/Console.vue
@@ -30,7 +30,6 @@
import { SERVER_MANAGER } from '@/store/mutation-types'
import { api } from '@/api'
import TooltipLabel from '@/components/widgets/TooltipLabel'
-import { uuid } from 'vue-uuid'
export default {
name: 'Console',
@@ -46,8 +45,7 @@
},
data () {
return {
- url: '',
- tokenValidationEnabled: false
+ url: ''
}
},
components: {
@@ -56,20 +54,9 @@
beforeCreate () {
this.form = this.$form.createForm(this)
},
- mounted () {
- this.verifyExtraValidationEnabled()
- },
methods: {
- verifyExtraValidationEnabled () {
- api('listConfigurations', { name: 'consoleproxy.extra.security.validation.enabled' }).then(json => {
- this.tokenValidationEnabled = json.listconfigurationsresponse.configuration !== null && json.listconfigurationsresponse.configuration[0].value === 'true'
- })
- },
consoleUrl () {
const params = {}
- if (this.tokenValidationEnabled) {
- params.token = uuid.v4()
- }
params.virtualmachineid = this.resource.id
api('createConsoleEndpoint', params).then(json => {
this.url = (json && json.createconsoleendpointresponse) ? json.createconsoleendpointresponse.consoleendpoint.url : '#/exception/404'