From 7e63c1e4997998e43effd02aab2f574e79b0e388 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Tue, 6 Sep 2022 09:10:04 -0600 Subject: [PATCH 1/4] Allow option of exposing VM domain info via instance metadata Signed-off-by: Marcus Sorensen --- .../java/com/cloud/network/NetworkModel.java | 17 +- .../com/cloud/vm/VirtualMachineManager.java | 3 + .../cloud/vm/VirtualMachineManagerImpl.java | 4 +- .../com/cloud/network/NetworkModelImpl.java | 14 + .../element/CloudZonesNetworkElement.java | 270 ------------------ .../network/router/CommandSetupHelper.java | 21 +- .../ConfigDriveNetworkElementTest.java | 8 + systemvm/debian/var/www/html/latest/.htaccess | 2 + .../integration/component/test_configdrive.py | 42 +++ 9 files changed, 99 insertions(+), 282 deletions(-) delete mode 100644 server/src/main/java/com/cloud/network/element/CloudZonesNetworkElement.java diff --git a/api/src/main/java/com/cloud/network/NetworkModel.java b/api/src/main/java/com/cloud/network/NetworkModel.java index 971bb308b1da..99bc75af9fb2 100644 --- a/api/src/main/java/com/cloud/network/NetworkModel.java +++ b/api/src/main/java/com/cloud/network/NetworkModel.java @@ -68,15 +68,20 @@ public interface NetworkModel { String PUBLIC_KEYS_FILE = "public-keys"; String CLOUD_IDENTIFIER_FILE = "cloud-identifier"; String HYPERVISOR_HOST_NAME_FILE = "hypervisor-host-name"; + String CLOUD_DOMAIN_FILE = "cloud-domain"; + String CLOUD_DOMAIN_ID_FILE = "cloud-domain-id"; int CONFIGDATA_DIR = 0; int CONFIGDATA_FILE = 1; int CONFIGDATA_CONTENT = 2; - ImmutableMap openStackFileMapping = ImmutableMap.of( - AVAILABILITY_ZONE_FILE, "availability_zone", - LOCAL_HOSTNAME_FILE, "hostname", - VM_ID_FILE, "uuid", - PUBLIC_HOSTNAME_FILE, "name" - ); + ImmutableMap openStackFileMapping = ImmutableMap.builder() + .put(AVAILABILITY_ZONE_FILE, "availability_zone") + .put(LOCAL_HOSTNAME_FILE, "hostname") + .put(VM_ID_FILE, "uuid") + .put(PUBLIC_HOSTNAME_FILE, "name") + .put(CLOUD_DOMAIN_FILE, CLOUD_DOMAIN_FILE) + .put(CLOUD_DOMAIN_ID_FILE, CLOUD_DOMAIN_ID_FILE) + .put(HYPERVISOR_HOST_NAME_FILE, HYPERVISOR_HOST_NAME_FILE) + .build(); static final ConfigKey MACIdentifier = new ConfigKey("Advanced",Integer.class, "mac.identifier", "0", "This value will be used while generating the mac addresses for isolated and shared networks. The hexadecimal equivalent value will be present at the 2nd octet of the mac address. Default value is null which means this feature is disabled.Its scope is global.", true, ConfigKey.Scope.Global); diff --git a/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java index 9ee2c2aa7ab6..443dc5062caf 100644 --- a/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java @@ -79,6 +79,9 @@ public interface VirtualMachineManager extends Manager { ConfigKey AllowExposeHypervisorHostname = new ConfigKey("Advanced", Boolean.class, "global.allow.expose.host.hostname", "false", "If set to true, it allows the hypervisor host name on which the VM is spawned on to be exposed to the VM", true, ConfigKey.Scope.Global); + ConfigKey AllowExposeDomainInMetadata = new ConfigKey("Advanced", Boolean.class, "metadata.allow.expose.domain", + "false", "If set to true, it allows the VM's domain to be seen in metadata", true, ConfigKey.Scope.Domain); + interface Topics { String VM_POWER_STATE = "vm.powerstate"; } diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index a1831a5cacdb..84cc1bab42dd 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -4611,7 +4611,9 @@ public ConfigKey[] getConfigKeys() { return new ConfigKey[] { ClusterDeltaSyncInterval, StartRetry, VmDestroyForcestop, VmOpCancelInterval, VmOpCleanupInterval, VmOpCleanupWait, VmOpLockStateRetry, VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel, VmConfigDriveOnPrimaryPool, VmConfigDriveForceHostCacheUse, VmConfigDriveUseHostCacheOnUnsupportedPool, - HaVmRestartHostUp, ResourceCountRunningVMsonly, AllowExposeHypervisorHostname, AllowExposeHypervisorHostnameAccountLevel, SystemVmRootDiskSize }; + HaVmRestartHostUp, ResourceCountRunningVMsonly, AllowExposeHypervisorHostname, AllowExposeHypervisorHostnameAccountLevel, SystemVmRootDiskSize, + AllowExposeDomainInMetadata + }; } public List getStoragePoolAllocators() { diff --git a/server/src/main/java/com/cloud/network/NetworkModelImpl.java b/server/src/main/java/com/cloud/network/NetworkModelImpl.java index c601c13e6ad5..20c8b3b47482 100644 --- a/server/src/main/java/com/cloud/network/NetworkModelImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkModelImpl.java @@ -34,6 +34,8 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.domain.Domain; +import com.cloud.vm.VirtualMachineManager; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -2551,6 +2553,10 @@ public List generateVmData(String userData, String serviceOffering, lo final String zoneName = dcVo.getName(); IPAddressVO publicIp = _ipAddressDao.findByAssociatedVmId(vmId); + VirtualMachine vm = _vmDao.findById(vmId); + if (vm == null) { + throw new CloudRuntimeException("Cannot generate VM instance data, no VM exists by given ID"); + } final List vmData = new ArrayList(); @@ -2619,6 +2625,14 @@ public List generateVmData(String userData, String serviceOffering, lo vmData.add(new String[]{PASSWORD_DIR, PASSWORD_FILE, password}); } vmData.add(new String[]{METATDATA_DIR, HYPERVISOR_HOST_NAME_FILE, hostname}); + + Domain domain = _domainDao.findById(vm.getDomainId()); + if (domain != null && VirtualMachineManager.AllowExposeDomainInMetadata.valueIn(domain.getId())) { + s_logger.debug("Adding domain info to cloud metadata"); + vmData.add(new String[]{METATDATA_DIR, CLOUD_DOMAIN_FILE, domain.getName()}); + vmData.add(new String[]{METATDATA_DIR, CLOUD_DOMAIN_ID_FILE, domain.getUuid()}); + } + return vmData; } diff --git a/server/src/main/java/com/cloud/network/element/CloudZonesNetworkElement.java b/server/src/main/java/com/cloud/network/element/CloudZonesNetworkElement.java deleted file mode 100644 index 848340b1a24c..000000000000 --- a/server/src/main/java/com/cloud/network/element/CloudZonesNetworkElement.java +++ /dev/null @@ -1,270 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.network.element; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import javax.inject.Inject; - -import org.apache.log4j.Logger; - -import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.routing.SavePasswordCommand; -import com.cloud.agent.api.routing.VmDataCommand; -import com.cloud.agent.manager.Commands; -import com.cloud.configuration.ConfigurationManager; -import com.cloud.configuration.ZoneConfig; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.deploy.DeployDestination; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.Network; -import com.cloud.network.Network.Capability; -import com.cloud.network.Network.Provider; -import com.cloud.network.Network.Service; -import com.cloud.network.NetworkModel; -import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.dao.NetworkDao; -import com.cloud.offering.NetworkOffering; -import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.utils.component.AdapterBase; -import com.cloud.vm.NicProfile; -import com.cloud.vm.ReservationContext; -import com.cloud.vm.UserVmManager; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.VirtualMachineManager; -import com.cloud.vm.VirtualMachineProfile; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.UserVmDao; - -public class CloudZonesNetworkElement extends AdapterBase implements NetworkElement, UserDataServiceProvider { - private static final Logger s_logger = Logger.getLogger(CloudZonesNetworkElement.class); - - private static final Map> capabilities = setCapabilities(); - - @Inject - NetworkDao _networkConfigDao; - @Inject - NetworkModel _networkMgr; - @Inject - UserVmManager _userVmMgr; - @Inject - UserVmDao _userVmDao; - @Inject - DomainRouterDao _routerDao; - @Inject - ConfigurationManager _configMgr; - @Inject - DataCenterDao _dcDao; - @Inject - AgentManager _agentManager; - @Inject - ServiceOfferingDao _serviceOfferingDao; - - private boolean canHandle(DeployDestination dest, TrafficType trafficType) { - DataCenterVO dc = (DataCenterVO)dest.getDataCenter(); - - if (dc.getDhcpProvider().equalsIgnoreCase(Provider.ExternalDhcpServer.getName())) { - _dcDao.loadDetails(dc); - String dhcpStrategy = dc.getDetail(ZoneConfig.DhcpStrategy.key()); - if ("external".equalsIgnoreCase(dhcpStrategy)) { - return true; - } - } - - return false; - } - - @Override - public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, - ConcurrentOperationException, InsufficientCapacityException { - if (!canHandle(dest, offering.getTrafficType())) { - return false; - } - - return true; - } - - @Override - public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { - return true; - } - - @Override - public boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) { - return true; - } - - @Override - public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException { - return false; // assume that the agent will remove userdata etc - } - - @Override - public boolean destroy(Network config, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { - return false; // assume that the agent will remove userdata etc - } - - @Override - public Provider getProvider() { - return Provider.ExternalDhcpServer; - } - - @Override - public Map> getCapabilities() { - return capabilities; - } - - private static Map> setCapabilities() { - Map> capabilities = new HashMap>(); - - capabilities.put(Service.UserData, null); - - return capabilities; - } - - private VmDataCommand generateVmDataCommand(String vmPrivateIpAddress, String userData, String serviceOffering, String zoneName, String guestIpAddress, - String vmName, String vmInstanceName, long vmId, String vmUuid, String publicKey, String hostname) { - VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName, _networkMgr.getExecuteInSeqNtwkElmtCmd()); - // if you add new metadata files, also edit systemvm/patches/debian/config/var/www/html/latest/.htaccess - cmd.addVmData("userdata", "user-data", userData); - cmd.addVmData("metadata", "service-offering", serviceOffering); - cmd.addVmData("metadata", "availability-zone", zoneName); - cmd.addVmData("metadata", "local-ipv4", guestIpAddress); - cmd.addVmData("metadata", "local-hostname", vmName); - cmd.addVmData("metadata", "public-ipv4", guestIpAddress); - cmd.addVmData("metadata", "public-hostname", guestIpAddress); - if (vmUuid == null) { - setVmInstanceId(vmInstanceName, vmId, cmd); - } else { - setVmInstanceId(vmUuid, cmd); - } - cmd.addVmData("metadata", "public-keys", publicKey); - cmd.addVmData("metadata", "hypervisor-host-name", hostname); - return cmd; - } - - private void setVmInstanceId(String vmUuid, VmDataCommand cmd) { - cmd.addVmData("metadata", "instance-id", vmUuid); - cmd.addVmData("metadata", "vm-id", vmUuid); - } - - private void setVmInstanceId(String vmInstanceName, long vmId, VmDataCommand cmd) { - cmd.addVmData("metadata", "instance-id", vmInstanceName); - cmd.addVmData("metadata", "vm-id", String.valueOf(vmId)); - } - - @Override - public boolean isReady(PhysicalNetworkServiceProvider provider) { - // TODO Auto-generated method stub - return true; - } - - @Override - public boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, - ResourceUnavailableException { - // TODO Auto-generated method stub - return true; - } - - @Override - public boolean canEnableIndividualServices() { - return false; - } - - @Override - public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { - if (canHandle(dest, network.getTrafficType())) { - - if (vm.getType() != VirtualMachine.Type.User) { - return false; - } - @SuppressWarnings("unchecked") - UserVmVO uservm = _userVmDao.findById(vm.getId()); - _userVmDao.loadDetails(uservm); - String password = (String)vm.getParameter(VirtualMachineProfile.Param.VmPassword); - String userData = uservm.getUserData(); - String sshPublicKey = uservm.getDetail("SSH.PublicKey"); - - Commands cmds = new Commands(Command.OnError.Continue); - if (password != null && nic.isDefaultNic()) { - SavePasswordCommand cmd = new SavePasswordCommand(password, nic.getIPv4Address(), uservm.getHostName(), _networkMgr.getExecuteInSeqNtwkElmtCmd()); - cmds.addCommand("password", cmd); - } - String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(uservm.getServiceOfferingId()).getDisplayText(); - String zoneName = _dcDao.findById(network.getDataCenterId()).getName(); - String destHostname = VirtualMachineManager.getHypervisorHostname(dest.getHost() != null ? dest.getHost().getName() : ""); - cmds.addCommand( - "vmdata", - generateVmDataCommand(nic.getIPv4Address(), userData, serviceOffering, zoneName, nic.getIPv4Address(), uservm.getHostName(), uservm.getInstanceName(), - uservm.getId(), uservm.getUuid(), sshPublicKey, destHostname)); - try { - _agentManager.send(dest.getHost().getId(), cmds); - } catch (OperationTimedoutException e) { - s_logger.debug("Unable to send vm data command to host " + dest.getHost()); - return false; - } - Answer dataAnswer = cmds.getAnswer("vmdata"); - if (dataAnswer != null && dataAnswer.getResult()) { - s_logger.info("Sent vm data successfully to vm " + uservm.getInstanceName()); - return true; - } - s_logger.info("Failed to send vm data to vm " + uservm.getInstanceName()); - return false; - } - return false; - } - - @Override - public boolean savePassword(Network network, NicProfile nic, VirtualMachineProfile vm) throws ResourceUnavailableException { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean saveSSHKey(Network network, NicProfile nic, VirtualMachineProfile vm, String sshPublicKey) throws ResourceUnavailableException { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean saveHypervisorHostname(NicProfile profile, Network network, VirtualMachineProfile vm, DeployDestination dest) throws ResourceUnavailableException { - return true; - } - - @Override - public boolean saveUserData(Network network, NicProfile nic, VirtualMachineProfile vm) throws ResourceUnavailableException { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean verifyServicesCombination(Set services) { - return true; - } -} diff --git a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java index 6839a6ae135b..3d1e0f4f0b06 100644 --- a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java +++ b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java @@ -26,6 +26,8 @@ import javax.inject.Inject; +import com.cloud.domain.Domain; +import com.cloud.domain.dao.DomainDao; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; @@ -149,6 +151,8 @@ public class CommandSetupHelper { @Inject private EntityManager _entityMgr; + @Inject + private DomainDao _domainDao; @Inject private NicDao _nicDao; @Inject @@ -210,11 +214,18 @@ public void createVmDataCommand(final VirtualRouter router, final UserVm vm, fin Host host = _hostDao.findById(vm.getHostId()); String destHostname = VirtualMachineManager.getHypervisorHostname(host != null ? host.getName() : ""); - cmds.addCommand( - "vmdata", - generateVmDataCommand(router, nic.getIPv4Address(), vm.getUserData(), serviceOffering, zoneName, - staticNatIp == null || staticNatIp.getState() != IpAddress.State.Allocated ? null : staticNatIp.getAddress().addr(), vm.getHostName(), vm.getInstanceName(), - vm.getId(), vm.getUuid(), publicKey, nic.getNetworkId(), destHostname)); + VmDataCommand vmDataCommand = generateVmDataCommand(router, nic.getIPv4Address(), vm.getUserData(), serviceOffering, zoneName, + staticNatIp == null || staticNatIp.getState() != IpAddress.State.Allocated ? null : staticNatIp.getAddress().addr(), vm.getHostName(), vm.getInstanceName(), + vm.getId(), vm.getUuid(), publicKey, nic.getNetworkId(), destHostname); + + Domain domain = _domainDao.findById(vm.getDomainId()); + if (domain != null && VirtualMachineManager.AllowExposeDomainInMetadata.valueIn(domain.getId())) { + s_logger.debug("Adding domain info to cloud metadata"); + vmDataCommand.addVmData(NetworkModel.METATDATA_DIR, NetworkModel.CLOUD_DOMAIN_FILE, domain.getName()); + vmDataCommand.addVmData(NetworkModel.METATDATA_DIR, NetworkModel.CLOUD_DOMAIN_ID_FILE, domain.getUuid()); + } + + cmds.addCommand("vmdata", vmDataCommand); } } diff --git a/server/src/test/java/com/cloud/network/element/ConfigDriveNetworkElementTest.java b/server/src/test/java/com/cloud/network/element/ConfigDriveNetworkElementTest.java index ab3489f36b83..06ec0b019b7f 100644 --- a/server/src/test/java/com/cloud/network/element/ConfigDriveNetworkElementTest.java +++ b/server/src/test/java/com/cloud/network/element/ConfigDriveNetworkElementTest.java @@ -36,6 +36,8 @@ import java.util.List; import java.util.Map; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; @@ -119,6 +121,7 @@ public class ConfigDriveNetworkElementTest { private final String VMUSERDATA = "H4sIABCvw1oAAystTi1KSSxJ5AIAUPllwQkAAAA="; private final long SOID = 31L; private final long HOSTID = NETWORK_ID; + private final long DOMAINID = 1L; @Mock private DataCenter dataCenter; @Mock private ConfigurationDao _configDao; @@ -134,6 +137,7 @@ public class ConfigDriveNetworkElementTest { @Mock private NetworkDao _networkDao; @Mock private NetworkServiceMapDao _ntwkSrvcDao; @Mock private IPAddressDao _ipAddressDao; + @Mock private DomainDao _domainDao; @Mock private DataCenterVO dataCenterVO; @Mock private DataStore dataStore; @@ -151,6 +155,7 @@ public class ConfigDriveNetworkElementTest { @Mock private IPAddressVO publicIp; @Mock private AgentManager agentManager; @Mock private CallContext callContextMock; + @Mock private DomainVO domainVO; @InjectMocks private final ConfigDriveNetworkElement _configDrivesNetworkElement = new ConfigDriveNetworkElement(); @InjectMocks @Spy private NetworkModelImpl _networkModel = new NetworkModelImpl(); @@ -164,8 +169,10 @@ public void setUp() throws NoSuchFieldException, IllegalAccessException { when(_dataStoreMgr.getImageStoreWithFreeCapacity(DATACENTERID)).thenReturn(dataStore); when(_ep.select(dataStore)).thenReturn(endpoint); when(_vmDao.findById(VMID)).thenReturn(virtualMachine); + when(_vmInstanceDao.findById(VMID)).thenReturn(virtualMachine); when(_dcDao.findById(DATACENTERID)).thenReturn(dataCenterVO); when(_hostDao.findById(HOSTID)).thenReturn(hostVO); + when(_domainDao.findById(DOMAINID)).thenReturn(domainVO); doReturn(nic).when(_networkModel).getDefaultNic(VMID); when(_serviceOfferingDao.findByIdIncludingRemoved(VMID, SOID)).thenReturn(serviceOfferingVO); when(_guestOSDao.findById(anyLong())).thenReturn(guestOSVO); @@ -185,6 +192,7 @@ public void setUp() throws NoSuchFieldException, IllegalAccessException { when(virtualMachine.getInstanceName()).thenReturn(VMINSTANCENAME); when(virtualMachine.getUserData()).thenReturn(VMUSERDATA); when(virtualMachine.getHostName()).thenReturn(VMHOSTNAME); + when(virtualMachine.getDomainId()).thenReturn(DOMAINID); when(dataCenter.getId()).thenReturn(DATACENTERID); when(deployDestination.getHost()).thenReturn(hostVO); when(deployDestination.getDataCenter()).thenReturn(dataCenter); diff --git a/systemvm/debian/var/www/html/latest/.htaccess b/systemvm/debian/var/www/html/latest/.htaccess index 725e7e112a6b..ebbed4afb851 100644 --- a/systemvm/debian/var/www/html/latest/.htaccess +++ b/systemvm/debian/var/www/html/latest/.htaccess @@ -21,3 +21,5 @@ RewriteRule ^public-ipv4/?$ ../metadata/%{REMOTE_ADDR}/public-ipv4 [L,NC,QSA] RewriteRule ^public-keys/?$ ../metadata/%{REMOTE_ADDR}/public-keys [L,NC,QSA] RewriteRule ^service-offering/?$ ../metadata/%{REMOTE_ADDR}/service-offering [L,NC,QSA] RewriteRule ^vm-id/?$ ../metadata/%{REMOTE_ADDR}/vm-id [L,NC,QSA] +RewriteRule ^cloud-domain/?$ ../metadata/%{REMOTE_ADDR}/vm-id [L,NC,QSA] +RewriteRule ^cloud-domain-id/?$ ../metadata/%{REMOTE_ADDR}/vm-id [L,NC,QSA] diff --git a/test/integration/component/test_configdrive.py b/test/integration/component/test_configdrive.py index 3df175f672ff..b8ce4bdde5b8 100644 --- a/test/integration/component/test_configdrive.py +++ b/test/integration/component/test_configdrive.py @@ -552,6 +552,18 @@ def _verify_metadata(self, vm, ssh, mount_path): if exposeHypevisorHostnameGS == 'true' and exposeHypevisorHostnameAcc == 'true': vm_files.append("hypervisor-host-name.txt") + configs = Configurations.list( + self.api_client, + name="metadata.allow.expose.domain", + listall=True + ) + + exposeDomain = configs[0].value + + if exposeDomain == 'true': + vm_files.append("cloud-domain.txt") + vm_files.append("cloud-domain-id.txt") + def get_name(vm_file): return "{} metadata".format( vm_file.split('.'[-1].replace('-', ' ')) @@ -604,6 +616,18 @@ def get_name(vm_file): "on which the VM is spawned" ) + if exposeDomain == 'true': + self.assertEqual( + str(metadata["cloud-domain-id.txt"]), + self.domain.id, + "Domain name in the metadata file does not match expected" + ) + self.assertEqual( + str(metadata["cloud-domain.txt"]), + self.domain.name, + "Domain name in the metadata file does not match expected" + ) + return def _verify_openstack_metadata(self, ssh, mount_path): @@ -2441,6 +2465,12 @@ def test_configdrive_vpc_network_verify_metadata(self): value="true" ) + # Enable domain in metadata + Configurations.update(self.api_client, + name="metadata.allow.expose.domain", + value="true" + ) + # Verify that the above mentioned settings are set to true before proceeding if not is_config_suitable( apiclient=self.api_client, @@ -2454,6 +2484,12 @@ def test_configdrive_vpc_network_verify_metadata(self): value='true'): self.skipTest('Account level setting account.allow.expose.host.hostname should be true. skipping') + if not is_config_suitable( + apiclient=self.api_client, + name='metadata.allow.expose.domain', + value='true'): + self.skipTest('metadata.allow.expose.domain should be true. skipping') + # ===================================================================== self.debug("+++ Scenario: " "Deploy VM in the Tier 1 with user data") @@ -2513,5 +2549,11 @@ def test_configdrive_vpc_network_verify_metadata(self): value="false" ) + # Disable domain in metadata + Configurations.update(self.api_client, + name="metadata.allow.expose.domain", + value="false" + ) + self.delete(vm, expunge=True) self.delete(network1) From 63bde348c533075762ab5e34e701f76bcff62a63 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Tue, 6 Sep 2022 10:40:51 -0600 Subject: [PATCH 2/4] Address Sonar results --- .../api/src/main/java/com/cloud/vm/VirtualMachineManager.java | 2 +- .../java/com/cloud/network/router/CommandSetupHelper.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java index 443dc5062caf..a8056829c318 100644 --- a/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java @@ -79,7 +79,7 @@ public interface VirtualMachineManager extends Manager { ConfigKey AllowExposeHypervisorHostname = new ConfigKey("Advanced", Boolean.class, "global.allow.expose.host.hostname", "false", "If set to true, it allows the hypervisor host name on which the VM is spawned on to be exposed to the VM", true, ConfigKey.Scope.Global); - ConfigKey AllowExposeDomainInMetadata = new ConfigKey("Advanced", Boolean.class, "metadata.allow.expose.domain", + ConfigKey AllowExposeDomainInMetadata = new ConfigKey<>("Advanced", Boolean.class, "metadata.allow.expose.domain", "false", "If set to true, it allows the VM's domain to be seen in metadata", true, ConfigKey.Scope.Domain); interface Topics { diff --git a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java index 3d1e0f4f0b06..a81515a2b84b 100644 --- a/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java +++ b/server/src/main/java/com/cloud/network/router/CommandSetupHelper.java @@ -152,7 +152,7 @@ public class CommandSetupHelper { private EntityManager _entityMgr; @Inject - private DomainDao _domainDao; + private DomainDao domainDao; @Inject private NicDao _nicDao; @Inject @@ -218,7 +218,7 @@ public void createVmDataCommand(final VirtualRouter router, final UserVm vm, fin staticNatIp == null || staticNatIp.getState() != IpAddress.State.Allocated ? null : staticNatIp.getAddress().addr(), vm.getHostName(), vm.getInstanceName(), vm.getId(), vm.getUuid(), publicKey, nic.getNetworkId(), destHostname); - Domain domain = _domainDao.findById(vm.getDomainId()); + Domain domain = domainDao.findById(vm.getDomainId()); if (domain != null && VirtualMachineManager.AllowExposeDomainInMetadata.valueIn(domain.getId())) { s_logger.debug("Adding domain info to cloud metadata"); vmDataCommand.addVmData(NetworkModel.METATDATA_DIR, NetworkModel.CLOUD_DOMAIN_FILE, domain.getName()); From 6fa39fa811a8addd1c7689fc953daae2524c277a Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Mon, 12 Sep 2022 10:35:05 -0600 Subject: [PATCH 3/4] Update server/src/main/java/com/cloud/network/NetworkModelImpl.java Co-authored-by: dahn --- server/src/main/java/com/cloud/network/NetworkModelImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/network/NetworkModelImpl.java b/server/src/main/java/com/cloud/network/NetworkModelImpl.java index 20c8b3b47482..88b9cba25164 100644 --- a/server/src/main/java/com/cloud/network/NetworkModelImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkModelImpl.java @@ -2555,7 +2555,7 @@ public List generateVmData(String userData, String serviceOffering, lo IPAddressVO publicIp = _ipAddressDao.findByAssociatedVmId(vmId); VirtualMachine vm = _vmDao.findById(vmId); if (vm == null) { - throw new CloudRuntimeException("Cannot generate VM instance data, no VM exists by given ID"); + throw new CloudRuntimeException(String.format("Cannot generate VM instance data, no VM exists by ID: %d", vmId)); } final List vmData = new ArrayList(); From 6c6e78c3392ff171c717f163d50112de067e4879 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Mon, 12 Sep 2022 10:35:25 -0600 Subject: [PATCH 4/4] Update engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java Co-authored-by: Daniel Augusto Veronezi Salvador <38945620+GutoVeronezi@users.noreply.github.com> --- .../api/src/main/java/com/cloud/vm/VirtualMachineManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java index a8056829c318..7b8ae5790a19 100644 --- a/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/main/java/com/cloud/vm/VirtualMachineManager.java @@ -80,7 +80,7 @@ public interface VirtualMachineManager extends Manager { "false", "If set to true, it allows the hypervisor host name on which the VM is spawned on to be exposed to the VM", true, ConfigKey.Scope.Global); ConfigKey AllowExposeDomainInMetadata = new ConfigKey<>("Advanced", Boolean.class, "metadata.allow.expose.domain", - "false", "If set to true, it allows the VM's domain to be seen in metadata", true, ConfigKey.Scope.Domain); + "false", "If set to true, it allows the VM's domain to be seen in metadata.", true, ConfigKey.Scope.Domain); interface Topics { String VM_POWER_STATE = "vm.powerstate";