Move console proxy related global settings to Zone level (#11415)

This commit is contained in:
Pearl Dsilva 2025-09-17 08:06:00 -04:00 committed by GitHub
parent 273ae03274
commit e7015cbc4c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 168 additions and 238 deletions

View File

@ -25,7 +25,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
import org.apache.cloudstack.framework.config.ConfigKey;
import com.cloud.agent.AgentManager;
import com.cloud.consoleproxy.ConsoleProxyManager;
import com.cloud.ha.HighAvailabilityManager;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
@ -404,96 +403,6 @@ public enum Config {
"service monitoring in router enable/disable option, default false", null),
// Console Proxy
ConsoleProxyCapacityStandby(
"Console Proxy",
AgentManager.class,
String.class,
"consoleproxy.capacity.standby",
"10",
"The minimal number of console proxy viewer sessions that system is able to serve immediately(standby capacity)",
null),
ConsoleProxyCapacityScanInterval(
"Console Proxy",
AgentManager.class,
String.class,
"consoleproxy.capacityscan.interval",
"30000",
"The time interval(in millisecond) to scan whether or not system needs more console proxy to ensure minimal standby capacity",
null),
ConsoleProxyCmdPort(
"Console Proxy",
AgentManager.class,
Integer.class,
"consoleproxy.cmd.port",
"8001",
"Console proxy command port that is used to communicate with management server",
null),
ConsoleProxyRestart(
"Console Proxy",
AgentManager.class,
Boolean.class,
"consoleproxy.restart",
"true",
"Console proxy restart flag, defaulted to true",
null),
ConsoleProxyUrlDomain(
"Console Proxy",
AgentManager.class,
String.class,
"consoleproxy.url.domain",
"",
"Console proxy url domain",
"domainName,privateip"),
ConsoleProxySessionMax(
"Console Proxy",
AgentManager.class,
Integer.class,
"consoleproxy.session.max",
String.valueOf(ConsoleProxyManager.DEFAULT_PROXY_CAPACITY),
"The max number of viewer sessions console proxy is configured to serve for",
null),
ConsoleProxySessionTimeout(
"Console Proxy",
AgentManager.class,
Integer.class,
"consoleproxy.session.timeout",
"300000",
"Timeout(in milliseconds) that console proxy tries to maintain a viewer session before it times out the session for no activity",
null),
ConsoleProxyDisableRpFilter(
"Console Proxy",
AgentManager.class,
Boolean.class,
"consoleproxy.disable.rpfilter",
"true",
"disable rp_filter on console proxy VM public interface",
null),
ConsoleProxyLaunchMax(
"Console Proxy",
AgentManager.class,
Integer.class,
"consoleproxy.launch.max",
"10",
"maximum number of console proxy instances per zone can be launched",
null),
ConsoleProxyManagementState(
"Console Proxy",
AgentManager.class,
String.class,
"consoleproxy.management.state",
com.cloud.consoleproxy.ConsoleProxyManagementState.Auto.toString(),
"console proxy service management state",
null),
ConsoleProxyManagementLastState(
"Console Proxy",
AgentManager.class,
String.class,
"consoleproxy.management.state.last",
com.cloud.consoleproxy.ConsoleProxyManagementState.Auto.toString(),
"last console proxy service management state",
null),
// Snapshots
SnapshotPollInterval(
@ -1587,14 +1496,6 @@ public enum Config {
"false",
"Should be set to true, if there will be multiple NetScaler devices providing EIP service in a zone",
null),
ConsoleProxyServiceOffering(
"Advanced",
ManagementServer.class,
String.class,
"consoleproxy.service.offering",
null,
"Uuid of the service offering used by console proxy; if NULL - system offering will be used",
null),
SecondaryStorageServiceOffering(
"Advanced",
ManagementServer.class,
@ -1799,6 +1700,7 @@ public enum Config {
SSVMPSK("Hidden", ManagementServer.class, String.class, "upload.post.secret.key", "", "PSK with SSVM", null);
private final String _category;
private final Class<?> _componentClass;
private final Class<?> _type;

View File

@ -49,6 +49,7 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.consoleproxy.ConsoleProxyManager;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.affinity.AffinityGroup;
@ -573,7 +574,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
configValuesForValidation.add("event.purge.interval");
configValuesForValidation.add("account.cleanup.interval");
configValuesForValidation.add("alert.wait");
configValuesForValidation.add("consoleproxy.capacityscan.interval");
configValuesForValidation.add(ConsoleProxyManager.ConsoleProxyCapacityScanInterval.key());
configValuesForValidation.add("expunge.interval");
configValuesForValidation.add("host.stats.interval");
configValuesForValidation.add("network.gc.interval");

View File

@ -120,12 +120,12 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
_consoleProxyPort = NumbersUtil.parseInt(value, ConsoleProxyManager.DEFAULT_PROXY_VNC_PORT);
}
value = configs.get(ConsoleProxySslEnabled.key());
if (value != null && value.equalsIgnoreCase("true")) {
Boolean sslEnabled = ConsoleProxySslEnabled.value();
if (Boolean.TRUE.equals(sslEnabled)) {
_sslEnabled = true;
}
_consoleProxyUrlDomain = configs.get("consoleproxy.url.domain");
_consoleProxyUrlDomain = ConsoleProxyUrlDomain.value();
_listener = new ConsoleProxyListener(new AgentBasedAgentHook(_instanceDao, _hostDao, _configDao, _ksMgr,
_agentMgr, _keysMgr, consoleAccessManager));
@ -166,6 +166,8 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
urlPort = host.getProxyPort().intValue();
}
_sslEnabled = ConsoleProxySslEnabled.valueIn(dataCenterId);
_consoleProxyUrlDomain = ConsoleProxyUrlDomain.valueIn(dataCenterId);
return new ConsoleProxyInfo(_sslEnabled, publicIp, _consoleProxyPort, urlPort, _consoleProxyUrlDomain);
} else {
logger.warn("Host that VM is running is no longer available, console access to VM {} will be temporarily unavailable.", userVm);
@ -189,7 +191,7 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol
}
@Override
public int getVncPort() {
public int getVncPort(Long dataCenterId) {
return _consoleProxyPort;
}

View File

@ -20,6 +20,7 @@ package com.cloud.consoleproxy;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Date;
import java.util.Objects;
import org.apache.cloudstack.consoleproxy.ConsoleAccessManager;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@ -41,7 +42,6 @@ import com.cloud.agent.api.GetVncPortCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupProxyCommand;
import com.cloud.agent.api.proxy.StartConsoleProxyAgentHttpHandlerCommand;
import com.cloud.configuration.Config;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.host.Host;
@ -213,10 +213,16 @@ public abstract class AgentHookBase implements AgentHook {
byte[] ksBits = null;
String consoleProxyUrlDomain = _configDao.getValue(Config.ConsoleProxyUrlDomain.key());
String consoleProxySslEnabled = _configDao.getValue(ConsoleProxyManager.ConsoleProxySslEnabled.key());
if (!StringUtils.isEmpty(consoleProxyUrlDomain) && !StringUtils.isEmpty(consoleProxySslEnabled)
&& consoleProxySslEnabled.equalsIgnoreCase("true")) {
HostVO consoleProxyHost = findConsoleProxyHost(startupCmd);
if (Objects.isNull(consoleProxyHost)) {
throw new IllegalStateException("Console proxy host is null");
}
Long datacenterId = consoleProxyHost.getDataCenterId();
String consoleProxyUrlDomain = ConsoleProxyManager.ConsoleProxyUrlDomain.valueIn(datacenterId);
Boolean consoleProxySslEnabled = ConsoleProxyManager.ConsoleProxySslEnabled.valueIn(datacenterId);
if (!StringUtils.isEmpty(consoleProxyUrlDomain) && Boolean.TRUE.equals(consoleProxySslEnabled)) {
ksBits = _ksMgr.getKeystoreBits(ConsoleProxyManager.CERTIFICATE_NAME, ConsoleProxyManager.CERTIFICATE_NAME, storePassword);
//ks manager raises exception if ksBits are null, hence no need to explicltly handle the condition
} else {
@ -227,9 +233,6 @@ public abstract class AgentHookBase implements AgentHook {
cmd.setEncryptorPassword(getEncryptorPassword());
cmd.setIsSourceIpCheckEnabled(Boolean.parseBoolean(_configDao.getValue(ConsoleProxyManager.NoVncConsoleSourceIpCheckEnabled.key())));
HostVO consoleProxyHost = findConsoleProxyHost(startupCmd);
assert (consoleProxyHost != null);
if (consoleProxyHost != null) {
Answer answer = _agentMgr.send(consoleProxyHost.getId(), cmd);
if (answer == null || !answer.getResult()) {

View File

@ -16,7 +16,9 @@
// under the License.
package com.cloud.consoleproxy;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.cloudstack.framework.config.ConfigKey;
@ -45,15 +47,52 @@ public interface ConsoleProxyManager extends Manager, ConsoleProxyService {
String ALERT_SUBJECT = "proxy-alert";
String CERTIFICATE_NAME = "CPVMCertificate";
ConfigKey<Boolean> ConsoleProxySslEnabled = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Boolean.class, "consoleproxy.sslEnabled", "false",
"Enable SSL for console proxy", false);
ConfigKey<Boolean> ConsoleProxySslEnabled = new ConfigKey<>(Boolean.class, "consoleproxy.sslEnabled", ConfigKey.CATEGORY_ADVANCED, "false",
"Enable SSL for console proxy", false, ConfigKey.Scope.Zone, null);
ConfigKey<Boolean> NoVncConsoleDefault = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Boolean.class, "novnc.console.default", "true",
"If true, noVNC console will be default console for virtual machines", true);
ConfigKey<Boolean> NoVncConsoleDefault = new ConfigKey<>(Boolean.class, "novnc.console.default", ConfigKey.CATEGORY_ADVANCED, "true",
"If true, noVNC console will be default console for virtual machines", false, ConfigKey.Scope.Zone, null);
ConfigKey<Boolean> NoVncConsoleSourceIpCheckEnabled = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Boolean.class, "novnc.console.sourceip.check.enabled", "false",
"If true, The source IP to access novnc console must be same as the IP in request to management server for console URL. Needs to reconnect CPVM to management server when this changes (via restart CPVM, or management server, or cloud service in CPVM)", false);
ConfigKey<String> ConsoleProxyServiceOffering = new ConfigKey<>(String.class, "consoleproxy.service.offering", "Console Proxy", null,
"Uuid of the service offering used by console proxy; if NULL - system offering will be used", true, ConfigKey.Scope.Zone, null);
ConfigKey<String> ConsoleProxyCapacityStandby = new ConfigKey<>(String.class, "consoleproxy.capacity.standby", "Console Proxy", String.valueOf(DEFAULT_STANDBY_CAPACITY),
"The minimal number of console proxy viewer sessions that system is able to serve immediately(standby capacity)", false, ConfigKey.Scope.Zone, null);
ConfigKey<String> ConsoleProxyCapacityScanInterval = new ConfigKey<>(String.class, "consoleproxy.capacityscan.interval", "Console Proxy", "30000",
"The time interval(in millisecond) to scan whether or not system needs more console proxy to ensure minimal standby capacity", false, null);
ConfigKey<Integer> ConsoleProxyCmdPort = new ConfigKey<>(Integer.class, "consoleproxy.cmd.port", "Console Proxy", String.valueOf(DEFAULT_PROXY_CMD_PORT),
"Console proxy command port that is used to communicate with management server", false, ConfigKey.Scope.Zone, null);
ConfigKey<Boolean> ConsoleProxyRestart = new ConfigKey<>(Boolean.class, "consoleproxy.restart", "Console Proxy", "true",
"Console proxy restart flag, defaults to true", true, ConfigKey.Scope.Zone, null);
ConfigKey<String> ConsoleProxyUrlDomain = new ConfigKey<>(String.class, "consoleproxy.url.domain", "Console Proxy", "",
"Console proxy url domain - domainName,privateip", false, ConfigKey.Scope.Zone, null);
ConfigKey<Integer> ConsoleProxySessionMax = new ConfigKey<>(Integer.class, "consoleproxy.session.max", "Console Proxy", String.valueOf(DEFAULT_PROXY_CAPACITY),
"The max number of viewer sessions console proxy is configured to serve for", true, ConfigKey.Scope.Zone, null);
ConfigKey<Integer> ConsoleProxySessionTimeout = new ConfigKey<>(Integer.class, "consoleproxy.session.timeout", "Console Proxy", String.valueOf(DEFAULT_PROXY_SESSION_TIMEOUT),
"Timeout(in milliseconds) that console proxy tries to maintain a viewer session before it times out the session for no activity", true, ConfigKey.Scope.Zone, null);
ConfigKey<Boolean> ConsoleProxyDisableRpFilter = new ConfigKey<>(Boolean.class, "consoleproxy.disable.rpfilter", "Console Proxy", "true",
"disable rp_filter on console proxy VM public interface", true, ConfigKey.Scope.Zone, null);
ConfigKey<Integer> ConsoleProxyLaunchMax = new ConfigKey<>(Integer.class, "consoleproxy.launch.max", "Console Proxy", "10",
"maximum number of console proxy instances per zone can be launched", false, ConfigKey.Scope.Zone, null);
String consoleProxyManagementStates = Arrays.stream(com.cloud.consoleproxy.ConsoleProxyManagementState.values()).map(Enum::name).collect(Collectors.joining(","));
ConfigKey<String> ConsoleProxyServiceManagementState = new ConfigKey<String>(ConfigKey.CATEGORY_ADVANCED, String.class, "consoleproxy.management.state", com.cloud.consoleproxy.ConsoleProxyManagementState.Auto.toString(),
"console proxy service management state", false, ConfigKey.Kind.Select, consoleProxyManagementStates);
ConfigKey<String> ConsoleProxyManagementLastState = new ConfigKey<String>(ConfigKey.CATEGORY_ADVANCED, String.class, "consoleproxy.management.state.last", com.cloud.consoleproxy.ConsoleProxyManagementState.Auto.toString(),
"last console proxy service management state", false, ConfigKey.Kind.Select, consoleProxyManagementStates);
void setManagementState(ConsoleProxyManagementState state);
ConsoleProxyManagementState getManagementState();
@ -72,6 +111,6 @@ public interface ConsoleProxyManager extends Manager, ConsoleProxyService {
boolean destroyProxy(long proxyVmId);
int getVncPort();
int getVncPort(Long dataCenterId);
}

View File

@ -230,20 +230,11 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
private ConsoleProxyListener consoleProxyListener;
private ServiceOfferingVO serviceOfferingVO;
private long capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL_IN_MILLISECONDS;
private int capacityPerProxy = ConsoleProxyManager.DEFAULT_PROXY_CAPACITY;
private int standbyCapacity = ConsoleProxyManager.DEFAULT_STANDBY_CAPACITY;
private boolean useStorageVm;
private boolean disableRpFilter = false;
private String instance;
private int proxySessionTimeoutValue = DEFAULT_PROXY_SESSION_TIMEOUT;
private boolean sslEnabled = false;
private String consoleProxyUrlDomain;
private SystemVmLoadScanner<Long> loadScanner;
private Map<Long, ZoneHostInfo> zoneHostInfoMap;
private Map<Long, ConsoleProxyLoadInfo> zoneProxyCountMap;
@ -342,6 +333,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
logger.warn(String.format("SSL is enabled for console proxy [%s] but no server certificate found in database.", proxy.toString()));
}
String consoleProxyUrlDomain = ConsoleProxyUrlDomain.valueIn(dataCenterId);
ConsoleProxyInfo info;
if (staticPublicIp == null) {
info = new ConsoleProxyInfo(proxy.isSslEnabled(), proxy.getPublicIpAddress(), consoleProxyPort, proxy.getPort(), consoleProxyUrlDomain);
@ -374,6 +366,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
}
proxy = null;
} else {
long capacityPerProxy = ConsoleProxySessionMax.valueIn(dataCenterId);
if (consoleProxyDao.getProxyActiveLoad(proxy.getId()) < capacityPerProxy || hasPreviousSession(proxy, vm)) {
if (logger.isDebugEnabled()) {
logger.debug("Assign previous allocated console proxy for user vm: {}", vm);
@ -408,7 +401,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
if (vm.getProxyId() == null || vm.getProxyId() != proxy.getId()) {
vmInstanceDao.updateProxyId(vm.getId(), proxy.getId(), DateUtil.currentGMTTime());
}
boolean sslEnabled = isSslEnabled(dataCenterId);
proxy.setSslEnabled(sslEnabled);
if (sslEnabled) {
proxy.setPort(443);
@ -451,6 +444,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
}
}
Integer proxySessionTimeoutValue = ConsoleProxySessionTimeout.valueIn(proxy.getDataCenterId());
return DateUtil.currentGMTTime().getTime() - vm.getProxyAssignTime().getTime() < proxySessionTimeoutValue;
} else {
logger.warn(String.format("Unable to retrieve load info from proxy [%s] on an overloaded proxy.", proxy.toString()));
@ -466,8 +460,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
return proxy;
}
String restart = configurationDao.getValue(Config.ConsoleProxyRestart.key());
if (!ignoreRestartSetting && restart != null && restart.equalsIgnoreCase("false")) {
Boolean restart = ConsoleProxyRestart.valueIn(proxy.getDataCenterId());
if (!ignoreRestartSetting && Boolean.FALSE.equals(restart)) {
return null;
}
@ -500,6 +494,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
logger.debug("Assign console proxy from running pool for request from data center: {}", zone);
}
long capacityPerProxy = ConsoleProxySessionMax.valueIn(dataCenterId);
ConsoleProxyAllocator allocator = getCurrentAllocator();
assert (allocator != null);
List<ConsoleProxyVO> runningList = consoleProxyDao.getProxyListInStates(dataCenterId, State.Running);
@ -559,15 +555,16 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
return null;
}
public ConsoleProxyVO startNew(long dataCenterId) throws ConcurrentOperationException {
public ConsoleProxyVO startNew(long dataCenterId) throws ConcurrentOperationException, ConfigurationException {
if (logger.isDebugEnabled()) {
logger.debug("Assign console proxy from a newly started instance for request from data center : " + dataCenterId);
}
if (!allowToLaunchNew(dataCenterId)) {
String configKey = Config.ConsoleProxyLaunchMax.key();
logger.warn(String.format("The number of launched console proxys on zone [%s] has reached the limit [%s]. Limit set in [%s].", dataCenterId, configurationDao.getValue(configKey), configKey));
String configKey = ConsoleProxyLaunchMax.key();
Integer configValue = ConsoleProxyLaunchMax.valueIn(dataCenterId);
logger.warn(String.format("The number of launched console proxys on zone [%s] has reached the limit [%s]. Limit set in [%s].", dataCenterId, configValue, configKey));
return null;
}
@ -690,7 +687,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
return proxy;
}
protected Map<String, Object> createProxyInstance(long dataCenterId, List<VMTemplateVO> templates) throws ConcurrentOperationException {
protected Map<String, Object> createProxyInstance(long dataCenterId, List<VMTemplateVO> templates) throws ConcurrentOperationException, ConfigurationException {
long id = consoleProxyDao.getNextInSequence(Long.class, "id");
String name = VirtualMachineName.getConsoleProxyName(id, instance);
@ -715,7 +712,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
networks.put(networkOrchestrationService.setupNetwork(systemAcct, offering, plan, null, null, false).get(0), new ArrayList<>());
}
ServiceOfferingVO serviceOffering = serviceOfferingVO;
ServiceOfferingVO serviceOffering = getConsoleProxyServiceOffering(dataCenterId);
if (serviceOffering == null) {
serviceOffering = serviceOfferingDao.findDefaultSystemOffering(ServiceOffering.consoleProxyDefaultOffUniqueName, ConfigurationManagerImpl.SystemVMUseLocalStorage.valueIn(dataCenterId));
}
@ -814,13 +811,13 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
consoleProxyDao.getProxyListInStates(dcId, State.Starting, State.Running, State.Stopping,
State.Stopped, State.Migrating, State.Shutdown, State.Unknown);
String value = configurationDao.getValue(Config.ConsoleProxyLaunchMax.key());
int launchLimit = NumbersUtil.parseInt(value, 10);
int launchLimit = ConsoleProxyLaunchMax.valueIn(dcId);
return l.size() < launchLimit;
}
private boolean checkCapacity(ConsoleProxyLoadInfo proxyCountInfo, ConsoleProxyLoadInfo vmCountInfo) {
return proxyCountInfo.getCount() * capacityPerProxy - vmCountInfo.getCount() > standbyCapacity;
private boolean checkCapacity(ConsoleProxyLoadInfo proxyCountInfo, ConsoleProxyLoadInfo vmCountInfo, long dataCenterId) {
long capacityPerProxy = ConsoleProxySessionMax.valueIn(dataCenterId);
return proxyCountInfo.getCount() * capacityPerProxy - vmCountInfo.getCount() > getStandbyCapacity(dataCenterId);
}
private void allocCapacity(long dataCenterId) {
@ -842,7 +839,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
if (allocProxyLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_SYNC_IN_SECONDS)) {
try {
proxy = startNew(dataCenterId);
} catch (ConcurrentOperationException e) {
} catch (ConcurrentOperationException | ConfigurationException e) {
logger.warn("Unable to start new console proxy on zone [{}] due to [{}].", zone, e.getMessage(), e);
} finally {
allocProxyLock.unlock();
@ -997,8 +994,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
configurationDao.update(Config.ConsoleProxyManagementLastState.key(), Config.ConsoleProxyManagementLastState.getCategory(), lastState.toString());
configurationDao.update(Config.ConsoleProxyManagementState.key(), Config.ConsoleProxyManagementState.getCategory(), state.toString());
configurationDao.update(ConsoleProxyManagementLastState.key(), ConsoleProxyManagementLastState.category(), lastState.toString());
configurationDao.update(ConsoleProxyServiceManagementState.key(), ConsoleProxyServiceManagementState.category(), state.toString());
}
});
}
@ -1009,8 +1006,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
@Override
public ConsoleProxyManagementState getManagementState() {
String configKey = Config.ConsoleProxyManagementState.key();
String value = configurationDao.getValue(configKey);
String configKey = ConsoleProxyServiceManagementState.key();
String value = ConsoleProxyServiceManagementState.value();
if (value != null) {
ConsoleProxyManagementState state = ConsoleProxyManagementState.valueOf(value);
@ -1035,7 +1032,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
}
if (lastState != state) {
configurationDao.update(Config.ConsoleProxyManagementState.key(), Config.ConsoleProxyManagementState.getCategory(), lastState.toString());
configurationDao.update(ConsoleProxyServiceManagementState.key(), ConsoleProxyServiceManagementState.category(), lastState.toString());
}
} catch (Exception e) {
logger.error(String.format("Unable to resume last management state due to [%s].", e.getMessage()), e);
@ -1043,8 +1040,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
}
private ConsoleProxyManagementState getLastManagementState() {
String configKey = Config.ConsoleProxyManagementLastState.key();
String value = configurationDao.getValue(configKey);
String configKey = ConsoleProxyManagementLastState.key();
String value = ConsoleProxyManagementLastState.value();
if (value != null) {
ConsoleProxyManagementState state = ConsoleProxyManagementState.valueOf(value);
@ -1117,8 +1114,8 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
}
@Override
public int getVncPort() {
return sslEnabled && _ksDao.findByName(ConsoleProxyManager.CERTIFICATE_NAME) != null ? 8443 : 8080;
public int getVncPort(Long dataCenterId) {
return isSslEnabled(dataCenterId) && _ksDao.findByName(ConsoleProxyManager.CERTIFICATE_NAME) != null ? 8443 : 8080;
}
private String getAllocProxyLockName() {
@ -1133,44 +1130,19 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
Map<String, String> configs = configurationDao.getConfiguration("management-server", params);
String value = configs.get(ConsoleProxySslEnabled.key());
if (value != null && value.equalsIgnoreCase("true")) {
sslEnabled = true;
}
consoleProxyUrlDomain = configs.get(Config.ConsoleProxyUrlDomain.key());
if( sslEnabled && (consoleProxyUrlDomain == null || consoleProxyUrlDomain.isEmpty())) {
logger.warn("Empty console proxy domain, explicitly disabling SSL");
sslEnabled = false;
}
value = configs.get(Config.ConsoleProxyCapacityScanInterval.key());
String value = ConsoleProxyCapacityScanInterval.value();
capacityScanInterval = NumbersUtil.parseLong(value, DEFAULT_CAPACITY_SCAN_INTERVAL_IN_MILLISECONDS);
capacityPerProxy = NumbersUtil.parseInt(configs.get("consoleproxy.session.max"), DEFAULT_PROXY_CAPACITY);
standbyCapacity = NumbersUtil.parseInt(configs.get("consoleproxy.capacity.standby"), DEFAULT_STANDBY_CAPACITY);
proxySessionTimeoutValue = NumbersUtil.parseInt(configs.get("consoleproxy.session.timeout"), DEFAULT_PROXY_SESSION_TIMEOUT);
value = configs.get("consoleproxy.port");
if (value != null) {
consoleProxyPort = NumbersUtil.parseInt(value, ConsoleProxyManager.DEFAULT_PROXY_VNC_PORT);
}
value = configs.get(Config.ConsoleProxyDisableRpFilter.key());
if (value != null && value.equalsIgnoreCase("true")) {
disableRpFilter = true;
}
value = configs.get("secondary.storage.vm");
if (value != null && value.equalsIgnoreCase("true")) {
useStorageVm = true;
}
if (logger.isInfoEnabled()) {
logger.info("Console proxy max session soft limit : " + capacityPerProxy);
logger.info("Console proxy standby capacity : " + standbyCapacity);
}
instance = configs.get("instance.name");
if (instance == null) {
instance = "DEFAULT";
@ -1187,37 +1159,6 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
virtualMachineManager.registerGuru(VirtualMachine.Type.ConsoleProxy, this);
String configKey = Config.ConsoleProxyServiceOffering.key();
String cpvmSrvcOffIdStr = configs.get(configKey);
if (cpvmSrvcOffIdStr != null) {
serviceOfferingVO = serviceOfferingDao.findByUuid(cpvmSrvcOffIdStr);
if (serviceOfferingVO == null) {
try {
logger.debug(String.format("Unable to find a service offering by the UUID for console proxy VM with the value [%s] set in the configuration [%s]. Trying to find by the ID.", cpvmSrvcOffIdStr, configKey));
serviceOfferingVO = serviceOfferingDao.findById(Long.parseLong(cpvmSrvcOffIdStr));
} catch (NumberFormatException ex) {
logger.warn(String.format("Unable to find a service offering by the ID for console proxy VM with the value [%s] set in the configuration [%s]. The value is not a valid integer number. Error: [%s].", cpvmSrvcOffIdStr, configKey, ex.getMessage()), ex);
}
}
if (serviceOfferingVO == null) {
logger.warn(String.format("Unable to find a service offering by the UUID or ID for console proxy VM with the value [%s] set in the configuration [%s]", cpvmSrvcOffIdStr, configKey));
}
}
if (serviceOfferingVO == null || !serviceOfferingVO.isSystemUse()) {
int ramSize = NumbersUtil.parseInt(configurationDao.getValue("console.ram.size"), DEFAULT_PROXY_VM_RAMSIZE);
int cpuFreq = NumbersUtil.parseInt(configurationDao.getValue("console.cpu.mhz"), DEFAULT_PROXY_VM_CPUMHZ);
List<ServiceOfferingVO> offerings = serviceOfferingDao.createSystemServiceOfferings("System Offering For Console Proxy",
ServiceOffering.consoleProxyDefaultOffUniqueName, 1, ramSize, cpuFreq, 0, 0, false, null,
Storage.ProvisioningType.THIN, true, null, true, VirtualMachine.Type.ConsoleProxy, true);
if (offerings == null || offerings.size() < 2) {
String msg = "Data integrity problem : System Offering For Console Proxy has been removed?";
logger.error(msg);
throw new ConfigurationException(msg);
}
}
loadScanner = new SystemVmLoadScanner<>(this);
loadScanner.initScan(STARTUP_DELAY_IN_MILLISECONDS, capacityScanInterval);
resourceManager.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
@ -1252,14 +1193,16 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
buf.append(" host=").append(StringUtils.toCSVList(indirectAgentLB.getManagementServerList(dest.getHost().getId(), dest.getDataCenter().getId(), null)));
buf.append(" port=").append(managementPort);
buf.append(" name=").append(profile.getVirtualMachine().getHostName());
if (sslEnabled) {
if (isSslEnabled(dest.getDataCenter().getId())) {
buf.append(" premium=true");
}
buf.append(" zone=").append(dest.getDataCenter().getId());
Long datacenterId = dest.getDataCenter().getId();
buf.append(" zone=").append(datacenterId);
buf.append(" pod=").append(dest.getPod().getId());
buf.append(" guid=Proxy.").append(profile.getId());
buf.append(" proxy_vm=").append(profile.getId());
if (disableRpFilter) {
Boolean disableRpFilter = ConsoleProxyDisableRpFilter.valueIn(datacenterId);
if (Boolean.TRUE.equals(disableRpFilter)) {
buf.append(" disable_rp_filter=true");
}
@ -1319,7 +1262,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
buf.append(" dns2=").append(dc.getDns2());
}
if (VirtualMachine.Type.ConsoleProxy == profile.getVirtualMachine().getType()) {
buf.append(" vncport=").append(getVncPort());
buf.append(" vncport=").append(getVncPort(datacenterId));
}
buf.append(" keystore_password=").append(VirtualMachineGuru.getEncodedString(PasswordGenerator.generateRandomPassword(16)));
String bootArgs = buf.toString();
@ -1552,7 +1495,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
vmInfo = new ConsoleProxyLoadInfo();
}
if (!checkCapacity(proxyInfo, vmInfo)) {
if (!checkCapacity(proxyInfo, vmInfo, dataCenterId)) {
if (logger.isDebugEnabled()) {
logger.debug("Expand console proxy standby capacity for zone " + proxyInfo.getName());
}
@ -1627,7 +1570,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
@Override
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] { ConsoleProxySslEnabled, NoVncConsoleDefault, NoVncConsoleSourceIpCheckEnabled };
return new ConfigKey<?>[] { ConsoleProxySslEnabled, NoVncConsoleDefault, NoVncConsoleSourceIpCheckEnabled, ConsoleProxyServiceOffering,
ConsoleProxyCapacityStandby, ConsoleProxyCapacityScanInterval, ConsoleProxyCmdPort, ConsoleProxyRestart, ConsoleProxyUrlDomain, ConsoleProxySessionMax, ConsoleProxySessionTimeout, ConsoleProxyDisableRpFilter, ConsoleProxyLaunchMax,
ConsoleProxyManagementLastState, ConsoleProxyServiceManagementState };
}
protected ConsoleProxyStatus parseJsonToConsoleProxyStatus(String json) throws JsonParseException {
@ -1661,4 +1606,65 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
consoleProxyDao.update(proxyVmId, count, DateUtil.currentGMTTime(), details);
}
private boolean isSslEnabled(Long dataCenterId) {
boolean sslEnabled = ConsoleProxySslEnabled.valueIn(dataCenterId);
String consoleProxyUrlDomain = ConsoleProxyUrlDomain.valueIn(dataCenterId);
if( sslEnabled && (consoleProxyUrlDomain == null || consoleProxyUrlDomain.isEmpty())) {
logger.warn("Empty console proxy domain, explicitly disabling SSL");
sslEnabled = false;
}
return sslEnabled;
}
private Integer getStandbyCapacity(Long datacenterId) {
return Integer.parseInt(ConsoleProxyCapacityStandby.valueIn(datacenterId));
}
private ServiceOfferingVO getConsoleProxyServiceOffering(Long datacenterId) throws ConfigurationException {
String configKey = ConsoleProxyServiceOffering.key();
String cpvmSrvcOffIdStr = ConsoleProxyServiceOffering.valueIn(datacenterId);
String warningMessage = String.format("Unable to find a service offering by the UUID or ID for console proxy VM with the value [%s] set in the configuration [%s]", cpvmSrvcOffIdStr, configKey);
ServiceOfferingVO serviceOfferingVO = null;
if (cpvmSrvcOffIdStr != null) {
serviceOfferingVO = getServiceOfferingByUuidOrId(cpvmSrvcOffIdStr, warningMessage, configKey);
}
if (serviceOfferingVO == null || !serviceOfferingVO.isSystemUse()) {
logger.debug("Service offering for console proxy VM is not set or not a system service offering. Creating a default service offering.");
createServiceOfferingForConsoleProxy();
}
return serviceOfferingVO;
}
private ServiceOfferingVO getServiceOfferingByUuidOrId(String cpvmSrvcOffIdStr, String warningMessage, String configKey) {
ServiceOfferingVO serviceOfferingVO = serviceOfferingDao.findByUuid(cpvmSrvcOffIdStr);
if (serviceOfferingVO == null) {
try {
logger.debug(warningMessage);
serviceOfferingVO = serviceOfferingDao.findById(Long.parseLong(cpvmSrvcOffIdStr));
} catch (NumberFormatException ex) {
logger.warn(String.format("Unable to find a service offering by the ID for console proxy VM with the value [%s] set in the configuration [%s]. The value is not a valid integer number. Error: [%s].", cpvmSrvcOffIdStr, configKey, ex.getMessage()), ex);
}
}
if (serviceOfferingVO == null) {
logger.warn(warningMessage);
}
return serviceOfferingVO;
}
private void createServiceOfferingForConsoleProxy() throws ConfigurationException {
int ramSize = NumbersUtil.parseInt(configurationDao.getValue("console.ram.size"), DEFAULT_PROXY_VM_RAMSIZE);
int cpuFreq = NumbersUtil.parseInt(configurationDao.getValue("console.cpu.mhz"), DEFAULT_PROXY_VM_CPUMHZ);
List<ServiceOfferingVO> offerings = serviceOfferingDao.createSystemServiceOfferings("System Offering For Console Proxy",
ServiceOffering.consoleProxyDefaultOffUniqueName, 1, ramSize, cpuFreq, 0, 0, false, null,
Storage.ProvisioningType.THIN, true, null, true, VirtualMachine.Type.ConsoleProxy, true);
if (offerings == null || offerings.size() < 2) {
String msg = "Data integrity problem : System Offering For Console Proxy has been removed?";
logger.error(msg);
throw new ConfigurationException(msg);
}
}
}

View File

@ -476,7 +476,7 @@ public class ConsoleAccessManagerImpl extends ManagerBase implements ConsoleAcce
ConsoleProxyClientParam param = generateConsoleProxyClientParam(parsedHostInfo, port, sid, tag, ticket,
sessionUuid, addr, extraSecurityToken, vm, hostVo, details, portInfo, host, displayName);
String token = encryptor.encryptObject(ConsoleProxyClientParam.class, param);
int vncPort = consoleProxyManager.getVncPort();
int vncPort = consoleProxyManager.getVncPort(vm.getDataCenterId());
String url = generateConsoleAccessUrl(rootUrl, param, token, vncPort, vm, hostVo, details);

View File

@ -850,30 +850,6 @@ public class ConfigurationManagerImplTest {
Assert.assertEquals(expectedResult, result);
}
@Test
public void shouldValidateConfigRangeTestValueIsNullReturnFalse() {
boolean result = configurationManagerImplSpy.shouldValidateConfigRange(Config.ConsoleProxyUrlDomain.name(), null, Config.ConsoleProxyUrlDomain);
Assert.assertFalse(result);
}
@Test
public void shouldValidateConfigRangeTestConfigIsNullReturnFalse() {
boolean result = configurationManagerImplSpy.shouldValidateConfigRange("", "test", null);
Assert.assertFalse(result);
}
@Test
public void shouldValidateConfigRangeTestConfigDoesNotHaveARangeReturnFalse() {
boolean result = configurationManagerImplSpy.shouldValidateConfigRange(Config.ConsoleProxySessionMax.name(), "test", Config.ConsoleProxySessionMax);
Assert.assertFalse(result);
}
@Test
public void shouldValidateConfigRangeTestValueIsNotNullAndConfigHasRangeReturnTrue() {
boolean result = configurationManagerImplSpy.shouldValidateConfigRange(Config.ConsoleProxySessionMax.name(), "test", Config.ConsoleProxyUrlDomain);
Assert.assertTrue(result);
}
@Test
public void testResetConfigurations() {
Long poolId = 1L;

View File

@ -28,6 +28,7 @@ import javax.naming.ConfigurationException;
import com.cloud.agent.api.Command;
import com.cloud.configuration.Config;
import com.cloud.consoleproxy.ConsoleProxyManager;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.Status;
@ -121,8 +122,8 @@ public class PremiumSecondaryStorageManagerImpl extends SecondaryStorageManagerI
boolean suspendAutoLoading = !reserveStandbyCapacity();
if (!suspendAutoLoading) {
// this is a hacking, has nothing to do with console proxy, it is just a flag that primary storage is being under maintenance mode
String restart = _configDao.getValue("consoleproxy.restart");
if (restart != null && restart.equalsIgnoreCase("false")) {
Boolean restart = ConsoleProxyManager.ConsoleProxyRestart.valueIn(dataCenterId);
if (Boolean.FALSE.equals(restart)) {
logger.debug("Capacity scan disabled purposefully, consoleproxy.restart = false. This happens when the primarystorage is in maintenance mode");
suspendAutoLoading = true;
}