From a0e592e945e44e67a379a77982e5011b36db3e3c Mon Sep 17 00:00:00 2001 From: dahn Date: Fri, 16 Feb 2024 14:33:22 +0100 Subject: [PATCH] prevent nic removal on out of bounds router stop (#8371) Co-authored-by: Vishesh Co-authored-by: Wei Zhou --- .../main/java/com/cloud/vm/NicProfile.java | 2 +- .../java/com/cloud/serializer/GsonHelper.java | 2 + .../orchestration/NetworkOrchestrator.java | 11 ++- .../src/main/java/com/cloud/vm/NicVO.java | 13 +-- .../network/guru/ControlNetworkGuru.java | 13 ++- .../network/guru/PodBasedNetworkGuru.java | 2 +- .../VirtualNetworkApplianceManager.java | 93 +++++++++---------- .../VirtualNetworkApplianceManagerImpl.java | 82 +++++++--------- 8 files changed, 99 insertions(+), 119 deletions(-) diff --git a/api/src/main/java/com/cloud/vm/NicProfile.java b/api/src/main/java/com/cloud/vm/NicProfile.java index 3f37331b1e4..d3c1daa1f5d 100644 --- a/api/src/main/java/com/cloud/vm/NicProfile.java +++ b/api/src/main/java/com/cloud/vm/NicProfile.java @@ -442,6 +442,6 @@ public class NicProfile implements InternalIdentity, Serializable { @Override public String toString() { - return String.format("NicProfile %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "vmId", "reservationId", "iPv4Address", "broadcastUri")); + return String.format("NicProfile %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "vmId", "deviceId", "broadcastUri", "reservationId", "iPv4Address")); } } diff --git a/core/src/main/java/com/cloud/serializer/GsonHelper.java b/core/src/main/java/com/cloud/serializer/GsonHelper.java index 7ac85d39317..7c33ef0e5d5 100644 --- a/core/src/main/java/com/cloud/serializer/GsonHelper.java +++ b/core/src/main/java/com/cloud/serializer/GsonHelper.java @@ -51,6 +51,8 @@ public class GsonHelper { GsonBuilder loggerBuilder = new GsonBuilder(); loggerBuilder.disableHtmlEscaping(); loggerBuilder.setExclusionStrategies(new LoggingExclusionStrategy(s_logger)); + loggerBuilder.serializeSpecialFloatingPointValues(); + // maybe add loggerBuilder.serializeNulls(); as well? s_gogger = setDefaultGsonConfig(loggerBuilder); s_logger.info("Default Builder inited."); } diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 6c10a02abba..57f6f99bf2a 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -2310,12 +2310,12 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra @DB protected void releaseNic(final VirtualMachineProfile vmProfile, final long nicId) throws ConcurrentOperationException, ResourceUnavailableException { - final Pair networkToRelease = Transaction.execute(new TransactionCallback>() { + final Pair networkToRelease = Transaction.execute(new TransactionCallback<>() { @Override public Pair doInTransaction(final TransactionStatus status) { final NicVO nic = _nicDao.lockRow(nicId, true); if (nic == null) { - throw new ConcurrentOperationException("Unable to acquire lock on nic " + nic); + throw new ConcurrentOperationException(String.format("Unable to acquire lock on nic id=%d", nicId)); } final Nic.State originalState = nic.getState(); @@ -2329,6 +2329,9 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra final NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), null, _networkModel .isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network)); if (guru.release(profile, vmProfile, nic.getReservationId())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug(String.format("The nic %s on %s was released according to %s by guru %s, now updating record.", nic, profile, vmProfile, guru)); + } applyProfileToNicForRelease(nic, profile); nic.setState(Nic.State.Allocated); if (originalState == Nic.State.Reserved) { @@ -2338,7 +2341,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } } // Perform release on network elements - return new Pair(network, profile); + return new Pair<>(network, profile); } else { nic.setState(Nic.State.Allocated); updateNic(nic, network.getId(), -1); @@ -2435,7 +2438,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra for (final NetworkElement element : networkElements) { if (providersToImplement.contains(element.getProvider())) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Asking " + element.getName() + " to release " + nic); + s_logger.debug(String.format("Asking %s to release %s, according to the reservation strategy %s", element.getName(), nic, nic.getReservationStrategy())); } try { element.release(network, profile, vm, null); diff --git a/engine/schema/src/main/java/com/cloud/vm/NicVO.java b/engine/schema/src/main/java/com/cloud/vm/NicVO.java index a32a943ea58..936efd112b7 100644 --- a/engine/schema/src/main/java/com/cloud/vm/NicVO.java +++ b/engine/schema/src/main/java/com/cloud/vm/NicVO.java @@ -30,6 +30,7 @@ import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; +import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; @@ -329,17 +330,7 @@ public class NicVO implements Nic { @Override public String toString() { - return new StringBuilder("Nic[").append(id) - .append("-") - .append(instanceId) - .append("-") - .append(deviceId) - .append("-") - .append(reservationId) - .append("-") - .append(iPv4Address) - .append("]") - .toString(); + return String.format("Nic %s", ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "id", "instanceId", "deviceId", "broadcastUri", "reservationId", "iPv4Address")); } @Override diff --git a/server/src/main/java/com/cloud/network/guru/ControlNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/ControlNetworkGuru.java index ce62c7b4e3f..ce59b50f3c3 100644 --- a/server/src/main/java/com/cloud/network/guru/ControlNetworkGuru.java +++ b/server/src/main/java/com/cloud/network/guru/ControlNetworkGuru.java @@ -21,6 +21,7 @@ import java.util.Map; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.network.router.VirtualNetworkApplianceManager; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.log4j.Logger; @@ -166,18 +167,24 @@ public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGu assert nic.getTrafficType() == TrafficType.Control; HypervisorType hType = vm.getHypervisorType(); if ( ( (hType == HypervisorType.VMware) || (hType == HypervisorType.Hyperv) )&& isRouterVm(vm)) { + if (!VirtualNetworkApplianceManager.RemoveControlIpOnStop.valueIn(vm.getVirtualMachine().getDataCenterId())) { + if (s_logger.isDebugEnabled()) { + s_logger.debug(String.format("not releasing %s from %s with reservationId %s, as systemvm.release.control.ip.on.stop is set to false for the data center.", nic, vm, reservationId)); + } + return true; + } long dcId = vm.getVirtualMachine().getDataCenterId(); DataCenterVO dcVo = _dcDao.findById(dcId); if (dcVo.getNetworkType() != NetworkType.Basic) { super.release(nic, vm, reservationId); if (s_logger.isDebugEnabled()) { - s_logger.debug("Released nic: " + nic); + s_logger.debug(String.format("Released nic: %s for vm %s", nic, vm)); } return true; } else { nic.deallocate(); if (s_logger.isDebugEnabled()) { - s_logger.debug("Released nic: " + nic); + s_logger.debug(String.format("Released nic: %s for vm %s", nic, vm)); } return true; } @@ -187,7 +194,7 @@ public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGu nic.deallocate(); if (s_logger.isDebugEnabled()) { - s_logger.debug("Released nic: " + nic); + s_logger.debug(String.format("Released nic: %s for vm %s", nic, vm)); } return true; diff --git a/server/src/main/java/com/cloud/network/guru/PodBasedNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/PodBasedNetworkGuru.java index 9f9771e7cfb..44d349a861e 100644 --- a/server/src/main/java/com/cloud/network/guru/PodBasedNetworkGuru.java +++ b/server/src/main/java/com/cloud/network/guru/PodBasedNetworkGuru.java @@ -159,7 +159,7 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru { nic.deallocate(); if (s_logger.isDebugEnabled()) { - s_logger.debug("Released nic: " + nic); + s_logger.debug(String.format("Released nic: %s for vm %s", nic, vm)); } return true; diff --git a/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManager.java index 8b2fd81bb48..387e50519e9 100644 --- a/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -36,82 +36,83 @@ import com.cloud.vm.DomainRouterVO; */ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkApplianceService { - static final String RouterTemplateXenCK = "router.template.xenserver"; - static final String RouterTemplateKvmCK = "router.template.kvm"; - static final String RouterTemplateVmwareCK = "router.template.vmware"; - static final String RouterTemplateHyperVCK = "router.template.hyperv"; - static final String RouterTemplateLxcCK = "router.template.lxc"; - static final String RouterTemplateOvm3CK = "router.template.ovm3"; - static final String SetServiceMonitorCK = "network.router.EnableServiceMonitoring"; - static final String RouterAlertsCheckIntervalCK = "router.alerts.check.interval"; - static final String VirtualRouterServiceOfferingCK = "router.service.offering"; + String RouterTemplateXenCK = "router.template.xenserver"; + String RouterTemplateKvmCK = "router.template.kvm"; + String RouterTemplateVmwareCK = "router.template.vmware"; + String RouterTemplateHyperVCK = "router.template.hyperv"; + String RouterTemplateLxcCK = "router.template.lxc"; + String RouterTemplateOvm3CK = "router.template.ovm3"; + String SetServiceMonitorCK = "network.router.EnableServiceMonitoring"; + String RouterAlertsCheckIntervalCK = "router.alerts.check.interval"; + String VirtualRouterServiceOfferingCK = "router.service.offering"; - static final String RouterHealthChecksConfigRefreshIntervalCK = "router.health.checks.config.refresh.interval"; - static final String RouterHealthChecksResultFetchIntervalCK = "router.health.checks.results.fetch.interval"; - static final String RouterHealthChecksFailuresToRecreateVrCK = "router.health.checks.failures.to.recreate.vr"; + String RouterHealthChecksConfigRefreshIntervalCK = "router.health.checks.config.refresh.interval"; + String RouterHealthChecksResultFetchIntervalCK = "router.health.checks.results.fetch.interval"; + String RouterHealthChecksFailuresToRecreateVrCK = "router.health.checks.failures.to.recreate.vr"; + String RemoveControlIpOnStopCK = "systemvm.release.control.ip.on.stop"; - static final ConfigKey RouterTemplateXen = new ConfigKey(String.class, RouterTemplateXenCK, "Advanced", "SystemVM Template (XenServer)", + ConfigKey RouterTemplateXen = new ConfigKey<>(String.class, RouterTemplateXenCK, "Advanced", "SystemVM Template (XenServer)", "Name of the default router template on Xenserver.", true, ConfigKey.Scope.Zone, null); - static final ConfigKey RouterTemplateKvm = new ConfigKey(String.class, RouterTemplateKvmCK, "Advanced", "SystemVM Template (KVM)", + ConfigKey RouterTemplateKvm = new ConfigKey<>(String.class, RouterTemplateKvmCK, "Advanced", "SystemVM Template (KVM)", "Name of the default router template on KVM.", true, ConfigKey.Scope.Zone, null); - static final ConfigKey RouterTemplateVmware = new ConfigKey(String.class, RouterTemplateVmwareCK, "Advanced", "SystemVM Template (vSphere)", + ConfigKey RouterTemplateVmware = new ConfigKey<>(String.class, RouterTemplateVmwareCK, "Advanced", "SystemVM Template (vSphere)", "Name of the default router template on Vmware.", true, ConfigKey.Scope.Zone, null); - static final ConfigKey RouterTemplateHyperV = new ConfigKey(String.class, RouterTemplateHyperVCK, "Advanced", "SystemVM Template (HyperV)", + ConfigKey RouterTemplateHyperV = new ConfigKey<>(String.class, RouterTemplateHyperVCK, "Advanced", "SystemVM Template (HyperV)", "Name of the default router template on Hyperv.", true, ConfigKey.Scope.Zone, null); - static final ConfigKey RouterTemplateLxc = new ConfigKey(String.class, RouterTemplateLxcCK, "Advanced", "SystemVM Template (LXC)", + ConfigKey RouterTemplateLxc = new ConfigKey<>(String.class, RouterTemplateLxcCK, "Advanced", "SystemVM Template (LXC)", "Name of the default router template on LXC.", true, ConfigKey.Scope.Zone, null); - static final ConfigKey RouterTemplateOvm3 = new ConfigKey(String.class, RouterTemplateOvm3CK, "Advanced", "SystemVM Template (Ovm3)", + ConfigKey RouterTemplateOvm3 = new ConfigKey<>(String.class, RouterTemplateOvm3CK, "Advanced", "SystemVM Template (Ovm3)", "Name of the default router template on Ovm3.", true, ConfigKey.Scope.Zone, null); - static final ConfigKey SetServiceMonitor = new ConfigKey(Boolean.class, SetServiceMonitorCK, "Advanced", "true", + ConfigKey SetServiceMonitor = new ConfigKey<>(Boolean.class, SetServiceMonitorCK, "Advanced", "true", "service monitoring in router enable/disable option, default true", true, ConfigKey.Scope.Zone, null); - static final ConfigKey RouterAlertsCheckInterval = new ConfigKey(Integer.class, RouterAlertsCheckIntervalCK, "Advanced", "1800", + ConfigKey RouterAlertsCheckInterval = new ConfigKey<>(Integer.class, RouterAlertsCheckIntervalCK, "Advanced", "1800", "Interval (in seconds) to check for alerts in Virtual Router.", false, ConfigKey.Scope.Global, null); - static final ConfigKey RouterVersionCheckEnabled = new ConfigKey("Advanced", Boolean.class, "router.version.check", "true", + ConfigKey RouterVersionCheckEnabled = new ConfigKey<>("Advanced", Boolean.class, "router.version.check", "true", "If true, router minimum required version is checked before sending command", false); - static final ConfigKey UseExternalDnsServers = new ConfigKey(Boolean.class, "use.external.dns", "Advanced", "false", + ConfigKey UseExternalDnsServers = new ConfigKey<>(Boolean.class, "use.external.dns", "Advanced", "false", "Bypass internal dns, use external dns1 and dns2", true, ConfigKey.Scope.Zone, null); - static final ConfigKey ExposeDnsAndBootpServer = new ConfigKey(Boolean.class, "expose.dns.externally", "Advanced", "true", + ConfigKey ExposeDnsAndBootpServer = new ConfigKey<>(Boolean.class, "expose.dns.externally", "Advanced", "true", "open dns, dhcp and bootp on the public interface", true, ConfigKey.Scope.Zone, null); - static final ConfigKey VirtualRouterServiceOffering = new ConfigKey(String.class, VirtualRouterServiceOfferingCK, "Advanced", "", + ConfigKey VirtualRouterServiceOffering = new ConfigKey<>(String.class, VirtualRouterServiceOfferingCK, "Advanced", "", "Uuid of the service offering used by virtual routers; if NULL - system offering will be used", true, ConfigKey.Scope.Account, null); // Health checks - static final ConfigKey RouterHealthChecksEnabled = new ConfigKey(Boolean.class, "router.health.checks.enabled", "Advanced", "true", + ConfigKey RouterHealthChecksEnabled = new ConfigKey<>(Boolean.class, "router.health.checks.enabled", "Advanced", "true", "If true, router health checks are allowed to be executed and read. If false, all scheduled checks and API calls for on demand checks are disabled.", true, ConfigKey.Scope.Global, null); - static final ConfigKey RouterHealthChecksBasicInterval = new ConfigKey(Integer.class, "router.health.checks.basic.interval", "Advanced", "3", + ConfigKey RouterHealthChecksBasicInterval = new ConfigKey<>(Integer.class, "router.health.checks.basic.interval", "Advanced", "3", "Interval in minutes at which basic router health checks are performed. If set to 0, no tests are scheduled.", true, ConfigKey.Scope.Global, null, RouterHealthChecksEnabled.key()); - static final ConfigKey RouterHealthChecksAdvancedInterval = new ConfigKey(Integer.class, "router.health.checks.advanced.interval", "Advanced", "10", + ConfigKey RouterHealthChecksAdvancedInterval = new ConfigKey<>(Integer.class, "router.health.checks.advanced.interval", "Advanced", "10", "Interval in minutes at which advanced router health checks are performed. If set to 0, no tests are scheduled.", true, ConfigKey.Scope.Global, null, RouterHealthChecksEnabled.key()); - static final ConfigKey RouterHealthChecksConfigRefreshInterval = new ConfigKey(Integer.class, RouterHealthChecksConfigRefreshIntervalCK, "Advanced", "10", + ConfigKey RouterHealthChecksConfigRefreshInterval = new ConfigKey<>(Integer.class, RouterHealthChecksConfigRefreshIntervalCK, "Advanced", "10", "Interval in minutes at which router health checks config - such as scheduling intervals, excluded checks, etc is updated on virtual routers by the management server. This value should" + " be sufficiently high (like 2x) from the router.health.checks.basic.interval and router.health.checks.advanced.interval so that there is time between new results generation and results generation for passed data.", false, ConfigKey.Scope.Global, null, RouterHealthChecksEnabled.key()); - static final ConfigKey RouterHealthChecksResultFetchInterval = new ConfigKey(Integer.class, RouterHealthChecksResultFetchIntervalCK, "Advanced", "10", + ConfigKey RouterHealthChecksResultFetchInterval = new ConfigKey<>(Integer.class, RouterHealthChecksResultFetchIntervalCK, "Advanced", "10", "Interval in minutes at which router health checks results are fetched by management server. On each result fetch, management server evaluates need to recreate VR as per configuration of " + RouterHealthChecksFailuresToRecreateVrCK + "This value should be sufficiently high (like 2x) from the router.health.checks.basic.interval and router.health.checks.advanced.interval so that there is time between new results generation and fetch.", false, ConfigKey.Scope.Global, null, RouterHealthChecksEnabled.key()); - static final ConfigKey RouterHealthChecksFailuresToRecreateVr = new ConfigKey(String.class, RouterHealthChecksFailuresToRecreateVrCK, "Advanced", "", + ConfigKey RouterHealthChecksFailuresToRecreateVr = new ConfigKey<>(String.class, RouterHealthChecksFailuresToRecreateVrCK, "Advanced", "", "Health checks failures defined by this config are the checks that should cause router recreation. If empty the recreate is not attempted for any health check failure. Possible values are comma separated script names " + "from systemvm’s /root/health_scripts/ (namely - cpu_usage_check.py, dhcp_check.py, disk_space_check.py, dns_check.py, gateways_check.py, haproxy_check.py, iptables_check.py, memory_usage_check.py, router_version_check.py), connectivity.test, filesystem.writable.test " + " or services (namely - loadbalancing.service, webserver.service, dhcp.service) ", true, ConfigKey.Scope.Zone, null, null, RouterHealthChecksEnabled.key(), null, null, ConfigKey.Kind.CSV, null); - static final ConfigKey RouterHealthChecksToExclude = new ConfigKey(String.class, "router.health.checks.to.exclude", "Advanced", "", + ConfigKey RouterHealthChecksToExclude = new ConfigKey<>(String.class, "router.health.checks.to.exclude", "Advanced", "", "Health checks that should be excluded when executing scheduled checks on the router. This can be a comma separated list of script names placed in the '/root/health_checks/' folder. Currently the following scripts are " + "placed in default systemvm template - cpu_usage_check.py, disk_space_check.py, gateways_check.py, iptables_check.py, router_version_check.py, dhcp_check.py, dns_check.py, haproxy_check.py, memory_usage_check.py.", true, ConfigKey.Scope.Zone, null, null, RouterHealthChecksEnabled.key(), null, null, ConfigKey.Kind.CSV, null); - static final ConfigKey RouterHealthChecksFreeDiskSpaceThreshold = new ConfigKey(Double.class, "router.health.checks.free.disk.space.threshold", + ConfigKey RouterHealthChecksFreeDiskSpaceThreshold = new ConfigKey<>(Double.class, "router.health.checks.free.disk.space.threshold", "Advanced", "100", "Free disk space threshold (in MB) on VR below which the check is considered a failure.", true, ConfigKey.Scope.Zone, null, RouterHealthChecksEnabled.key()); - static final ConfigKey RouterHealthChecksMaxCpuUsageThreshold = new ConfigKey(Double.class, "router.health.checks.max.cpu.usage.threshold", + ConfigKey RouterHealthChecksMaxCpuUsageThreshold = new ConfigKey<>(Double.class, "router.health.checks.max.cpu.usage.threshold", "Advanced", "100", " Max CPU Usage threshold as % above which check is considered a failure.", true, ConfigKey.Scope.Zone, null, RouterHealthChecksEnabled.key()); - static final ConfigKey RouterHealthChecksMaxMemoryUsageThreshold = new ConfigKey(Double.class, "router.health.checks.max.memory.usage.threshold", + ConfigKey RouterHealthChecksMaxMemoryUsageThreshold = new ConfigKey<>(Double.class, "router.health.checks.max.memory.usage.threshold", "Advanced", "100", "Max Memory Usage threshold as % above which check is considered a failure.", true, ConfigKey.Scope.Zone, null, RouterHealthChecksEnabled.key()); ConfigKey RouterLogrotateFrequency = new ConfigKey<>(String.class, "router.logrotate.frequency", "Advanced", "*:00:00", @@ -121,23 +122,15 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA "reach the minimum size.", true, ConfigKey.Scope.Zone, null); - public static final int DEFAULT_ROUTER_VM_RAMSIZE = 256; // 256M - public static final int DEFAULT_ROUTER_CPU_MHZ = 500; // 500 MHz - public static final boolean USE_POD_VLAN = false; - public static final int DEFAULT_PRIORITY = 100; - public static final int DEFAULT_DELTA = 2; + ConfigKey RemoveControlIpOnStop = new ConfigKey<>(Boolean.class, RemoveControlIpOnStopCK, "Advanced", "true", + "on stopping routers and system VMs the IP will be released to preserve IPv4 space.", true, ConfigKey.Scope.Zone, null); + + int DEFAULT_ROUTER_VM_RAMSIZE = 256; // 256M + int DEFAULT_ROUTER_CPU_MHZ = 500; // 500 MHz + boolean USE_POD_VLAN = false; + int DEFAULT_PRIORITY = 100; + int DEFAULT_DELTA = 2; - /** - /* - * Send ssh public/private key pair to specified host - * @param hostId - * @param pubKey - * @param prvKey - * - * NOT USED IN THE VIRTUAL NET APPLIANCE - * - */ - //boolean sendSshKeysToHost(Long hostId, String pubKey, String prvKey): boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException; diff --git a/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index d49322bde60..ebce0492ce3 100644 --- a/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -57,7 +57,6 @@ import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd; import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; -import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.framework.config.Configurable; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; @@ -66,7 +65,6 @@ import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO; import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; -import org.apache.cloudstack.network.router.deployment.RouterDeploymentDefinitionBuilder; import org.apache.cloudstack.network.topology.NetworkTopology; import org.apache.cloudstack.network.topology.NetworkTopologyContext; import org.apache.cloudstack.utils.CloudStackVersion; @@ -116,13 +114,11 @@ import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.cluster.ManagementServerHostVO; import com.cloud.cluster.dao.ManagementServerHostDao; import com.cloud.configuration.Config; -import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.ZoneConfig; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; -import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.VlanDao; @@ -144,7 +140,6 @@ import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.IpAddress; -import com.cloud.network.IpAddressManager; import com.cloud.network.MonitoringService; import com.cloud.network.Network; import com.cloud.network.Network.GuestType; @@ -178,17 +173,13 @@ import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.OpRouterMonitorServiceDao; import com.cloud.network.dao.OpRouterMonitorServiceVO; -import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.RemoteAccessVpnDao; import com.cloud.network.dao.RouterHealthCheckResultDao; import com.cloud.network.dao.RouterHealthCheckResultVO; import com.cloud.network.dao.Site2SiteCustomerGatewayDao; import com.cloud.network.dao.Site2SiteVpnConnectionDao; import com.cloud.network.dao.Site2SiteVpnConnectionVO; -import com.cloud.network.dao.Site2SiteVpnGatewayDao; -import com.cloud.network.dao.UserIpv6AddressDao; import com.cloud.network.dao.VirtualRouterProviderDao; -import com.cloud.network.dao.VpnUserDao; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy; @@ -217,16 +208,11 @@ import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; -import com.cloud.resource.ResourceManager; import com.cloud.serializer.GsonHelper; -import com.cloud.server.ConfigurationServer; import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.Storage.ProvisioningType; -import com.cloud.storage.dao.GuestOSDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.User; @@ -273,9 +259,7 @@ import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.NicIpAliasDao; import com.cloud.vm.dao.NicIpAliasVO; -import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.UserVmDetailsDao; -import com.cloud.vm.dao.VMInstanceDao; import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; @@ -302,7 +286,6 @@ Configurable, StateListener routerNics = _nicDao.listByVmId(profile.getId()); - for (final Nic nic : routerNics) { - final Network network = _networkModel.getNetwork(nic.getNetworkId()); - final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); - - if (network.getTrafficType() == TrafficType.Guest && nic.getBroadcastUri() != null && nic.getBroadcastUri().getScheme().equals("pvlan")) { - final NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic"); - - final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO); - try { - networkTopology.setupDhcpForPvlan(false, domR, domR.getHostId(), nicProfile); - } catch (final ResourceUnavailableException e) { - s_logger.debug("ERROR in finalizeStop: ", e); - } - } + if (Boolean.TRUE.equals(RemoveControlIpOnStop.valueIn(profile.getVirtualMachine().getDataCenterId()))) { + removeNics(vm, domR); } - } } @Override public void finalizeExpunge(final VirtualMachine vm) { + if (Boolean.FALSE.equals(RemoveControlIpOnStop.valueIn(vm.getDataCenterId()))) { + final DomainRouterVO domR = _routerDao.findById(vm.getId()); + s_logger.info(String.format("removing nics for VR [%s]", vm)); + removeNics(vm, domR); + } + } + + private void removeNics(VirtualMachine vm, DomainRouterVO domR) { + final List routerNics = _nicDao.listByVmId(vm.getId()); + final DataCenterVO dcVO = _dcDao.findById(vm.getDataCenterId()); + + for (final Nic nic : routerNics) { + final Network network = _networkModel.getNetwork(nic.getNetworkId()); + + removeDhcpRulesForPvLan(domR, nic, network, dcVO); + } + } + + private void removeDhcpRulesForPvLan(DomainRouterVO domR, Nic nic, Network network, DataCenterVO dcVO) { + if (network.getTrafficType() == TrafficType.Guest && nic.getBroadcastUri() != null && nic.getBroadcastUri().getScheme().equals("pvlan")) { + final NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic"); + + final NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO); + try { + networkTopology.setupDhcpForPvlan(false, domR, domR.getHostId(), nicProfile); + } catch (final ResourceUnavailableException e) { + s_logger.debug("ERROR in finalizeStop: ", e); + } + } } @Override @@ -3341,7 +3324,8 @@ Configurable, StateListener