Replacing the old [Vpc}VirtualNetworkApplianceManager by the new ones; Implement the missing commands related to DHCP PV Lan and DHCP SubNet
Conflicts: server/src/com/cloud/network/element/VirtualRouterElement.java server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java server/src/com/cloud/network/rules/DhcpRules.java server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java server/src/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java server/src/org/apache/cloudstack/network/topology/BasicNetworkVisitor.java server/src/org/apache/cloudstack/network/topology/NetworkTopologyVisitor.java Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/12b0d188 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/12b0d188 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/12b0d188 Branch: refs/heads/master Commit: 12b0d188cbaa5af52337b9ac80267ca9d6a53d41 Parents: a83f579 Author: Wilder Rodrigues <wrodrig...@schubergphilis.com> Authored: Mon Aug 18 17:01:54 2014 +0200 Committer: wilderrodrigues <wrodrig...@schubergphilis.com> Committed: Tue Oct 14 15:01:16 2014 +0200 ---------------------------------------------------------------------- .../spring-server-core-managers-context.xml | 3 - .../network/element/VirtualRouterElement.java | 49 ++- .../NEWVirtualNetworkApplianceManagerImpl.java | 301 ---------------- .../router/VirtualNetworkApplianceManager.java | 18 +- .../VirtualNetworkApplianceManagerImpl.java | 350 ++----------------- .../src/com/cloud/network/rules/DhcpRules.java | 41 +-- .../cloud/network/rules/DhcpSubNetRules.java | 181 +++++++++- .../com/cloud/network/rules/RuleApplier.java | 21 +- .../rules/VirtualNetworkApplianceFactory.java | 50 +++ .../topology/AdvancedNetworkTopology.java | 62 +++- .../topology/AdvancedNetworkVisitor.java | 38 +- .../network/topology/BasicNetworkTopology.java | 8 +- .../network/topology/BasicNetworkVisitor.java | 10 +- .../network/topology/NetworkTopology.java | 13 +- .../topology/NetworkTopologyVisitor.java | 4 +- .../MockVpcVirtualNetworkApplianceManager.java | 40 +-- 16 files changed, 444 insertions(+), 745 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b0d188/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml ---------------------------------------------------------------------- diff --git a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml index 37004d2..5cfc802 100644 --- a/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml +++ b/server/resources/META-INF/cloudstack/core/spring-server-core-managers-context.xml @@ -186,9 +186,6 @@ <bean id="vpcVirtualNetworkApplianceManagerImpl" class="com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl" /> - <bean id="newVirtualNetworkApplianceManagerImpl" - class="com.cloud.network.router.NEWVirtualNetworkApplianceManagerImpl" /> - <bean id="virtualNetworkApplianceFactory" class="com.cloud.network.rules.VirtualNetworkApplianceFactory" /> http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b0d188/server/src/com/cloud/network/element/VirtualRouterElement.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 4481a20..0fd22bd 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -42,6 +42,7 @@ import com.cloud.configuration.ConfigurationManager; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; 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; @@ -154,6 +155,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl OvsProviderDao _ovsProviderDao; @Inject IPAddressDao _ipAddressDao; + @Inject + DataCenterDao _dcDao; @Inject NetworkTopologyContext networkTopologyContext; @@ -291,7 +294,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (endChar != null) { boolean matchedEndChar = false; if (str.length() < 2) { - return false; // atleast one numeric and one char. example: + return false; // at least one numeric and one char. example: } // 3h char strEnd = str.toCharArray()[str.length() - 1]; @@ -712,7 +715,6 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return true; } - @SuppressWarnings("unchecked") VirtualMachineProfile uservm = vm; // If any router is running then send save password command otherwise @@ -750,7 +752,6 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return true; } - @SuppressWarnings("unchecked") VirtualMachineProfile uservm = vm; DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); @@ -770,7 +771,6 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return true; } - @SuppressWarnings("unchecked") VirtualMachineProfile uservm = vm; DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); @@ -913,7 +913,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (vm.getType() != VirtualMachine.Type.User) { return false; } - @SuppressWarnings("unchecked") + VirtualMachineProfile uservm = vm; List<DomainRouterVO> routers = getRouters(network, dest); @@ -922,7 +922,10 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId()); } - return _routerMgr.configDhcpForSubnet(network, nic, uservm, dest, routers); + DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); + NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO); + + return networkTopology.configDhcpForSubnet(network, nic, uservm, dest, routers); } return false; } @@ -951,7 +954,6 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return false; } - @SuppressWarnings("unchecked") VirtualMachineProfile uservm = vm; List<DomainRouterVO> routers = getRouters(network, dest); @@ -963,7 +965,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO); - return _routerMgr.applyDhcpEntry(network, nic, uservm, dest, routers); + return networkTopology.applyDhcpEntry(network, nic, uservm, dest, routers); } return false; } @@ -981,7 +983,6 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return true; } - @SuppressWarnings("unchecked") VirtualMachineProfile uservm = vm; List<DomainRouterVO> routers = getRouters(network, dest); @@ -1122,7 +1123,15 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (vm.getType() == VirtualMachine.Type.DomainRouter) { assert vm instanceof DomainRouterVO; DomainRouterVO router = (DomainRouterVO) vm.getVirtualMachine(); - _routerMgr.setupDhcpForPvlan(false, router, router.getHostId(), nic); + + DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); + NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO); + + try { + networkTopology.setupDhcpForPvlan(false, router, router.getHostId(), nic); + } catch (ResourceUnavailableException e) { + s_logger.warn("Timed Out", e); + } } else if (vm.getType() == VirtualMachine.Type.User) { assert vm instanceof UserVmVO; UserVmVO userVm = (UserVmVO) vm.getVirtualMachine(); @@ -1139,7 +1148,15 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (vm.getType() == VirtualMachine.Type.DomainRouter) { assert vm instanceof DomainRouterVO; DomainRouterVO router = (DomainRouterVO) vm.getVirtualMachine(); - _routerMgr.setupDhcpForPvlan(true, router, router.getHostId(), nic); + + DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); + NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO); + + try { + networkTopology.setupDhcpForPvlan(true, router, router.getHostId(), nic); + } catch (ResourceUnavailableException e) { + s_logger.warn("Timed Out", e); + } } else if (vm.getType() == VirtualMachine.Type.User) { assert vm instanceof UserVmVO; UserVmVO userVm = (UserVmVO) vm.getVirtualMachine(); @@ -1155,7 +1172,15 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (vm.getType() == VirtualMachine.Type.DomainRouter) { assert vm instanceof DomainRouterVO; DomainRouterVO router = (DomainRouterVO) vm.getVirtualMachine(); - _routerMgr.setupDhcpForPvlan(true, router, router.getHostId(), nic); + + DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); + NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO); + + try { + networkTopology.setupDhcpForPvlan(true, router, router.getHostId(), nic); + } catch (ResourceUnavailableException e) { + s_logger.warn("Timed Out", e); + } } else if (vm.getType() == VirtualMachine.Type.User) { assert vm instanceof UserVmVO; UserVmVO userVm = (UserVmVO) vm.getVirtualMachine(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b0d188/server/src/com/cloud/network/router/NEWVirtualNetworkApplianceManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/router/NEWVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/NEWVirtualNetworkApplianceManagerImpl.java deleted file mode 100644 index 7e416ab..0000000 --- a/server/src/com/cloud/network/router/NEWVirtualNetworkApplianceManagerImpl.java +++ /dev/null @@ -1,301 +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.router; - -import java.util.List; -import java.util.Map; - -import javax.ejb.Local; -import javax.inject.Inject; -import javax.naming.ConfigurationException; - -import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd; -import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd; -import org.apache.cloudstack.framework.config.ConfigKey; -import org.apache.log4j.Logger; - -import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.manager.Commands; -import com.cloud.deploy.DeployDestination; -import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.maint.Version; -import com.cloud.network.Network; -import com.cloud.network.RemoteAccessVpn; -import com.cloud.network.VirtualNetworkApplianceService; -import com.cloud.user.Account; -import com.cloud.user.User; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.VirtualMachineProfile.Param; - - -/** - * NetworkManager manages the network for the different end users. - * - */ -@Local(value = { NEWVirtualNetworkApplianceManager.class, VirtualNetworkApplianceService.class }) -public class NEWVirtualNetworkApplianceManagerImpl implements NEWVirtualNetworkApplianceManager { - - private static final Logger s_logger = Logger.getLogger(NEWVirtualNetworkApplianceManagerImpl.class); - - static final ConfigKey<Boolean> routerVersionCheckEnabled = new ConfigKey<Boolean>("Advanced", Boolean.class, "router.version.check", "true", - "If true, router minimum required version is checked before sending command", false); - - @Inject - private AgentManager _agentMgr; - - @Override - public String getName() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setName(final String name) { - // TODO Auto-generated method stub - - } - - @Override - public void setConfigParams(final Map<String, Object> params) { - // TODO Auto-generated method stub - - } - - @Override - public Map<String, Object> getConfigParams() { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getRunLevel() { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void setRunLevel(final int level) { - // TODO Auto-generated method stub - - } - - @Override - public boolean configure(final String name, final Map<String, Object> params) - throws ConfigurationException { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean start() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean stop() { - // TODO Auto-generated method stub - return false; - } - - @Override - public VirtualRouter startRouter(final long routerId, final boolean reprogramNetwork) - throws ConcurrentOperationException, ResourceUnavailableException, - InsufficientCapacityException { - // TODO Auto-generated method stub - return null; - } - - @Override - public VirtualRouter rebootRouter(final long routerId, final boolean reprogramNetwork) - throws ConcurrentOperationException, ResourceUnavailableException, - InsufficientCapacityException { - // TODO Auto-generated method stub - return null; - } - - @Override - public VirtualRouter upgradeRouter(final UpgradeRouterCmd cmd) { - // TODO Auto-generated method stub - return null; - } - - @Override - public VirtualRouter stopRouter(final long routerId, final boolean forced) - throws ResourceUnavailableException, ConcurrentOperationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public VirtualRouter startRouter(final long id) - throws ResourceUnavailableException, InsufficientCapacityException, - ConcurrentOperationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public VirtualRouter destroyRouter(final long routerId, final Account caller, - final Long callerUserId) throws ResourceUnavailableException, - ConcurrentOperationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public VirtualRouter findRouter(final long routerId) { - // TODO Auto-generated method stub - return null; - } - - @Override - public List<Long> upgradeRouterTemplate(final UpgradeRouterTemplateCmd cmd) { - // TODO Auto-generated method stub - return null; - } - - @Override - public List<DomainRouterVO> deployVirtualRouterInGuestNetwork( - final Network guestNetwork, final DeployDestination dest, final Account owner, - final Map<Param, Object> params, final boolean isRedundant) - throws InsufficientCapacityException, ResourceUnavailableException, - ConcurrentOperationException { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean startRemoteAccessVpn(final Network network, final RemoteAccessVpn vpn, - final List<? extends VirtualRouter> routers) - throws ResourceUnavailableException { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean deleteRemoteAccessVpn(final Network network, final RemoteAccessVpn vpn, - final List<? extends VirtualRouter> routers) - throws ResourceUnavailableException { - // TODO Auto-generated method stub - return false; - } - - @Override - public List<VirtualRouter> getRoutersForNetwork(final long networkId) { - // TODO Auto-generated method stub - return null; - } - - @Override - public VirtualRouter stop(final VirtualRouter router, final boolean forced, - final User callingUser, final Account callingAccount) - throws ConcurrentOperationException, ResourceUnavailableException { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getDnsBasicZoneUpdate() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean removeDhcpSupportForSubnet(final Network network, - final List<DomainRouterVO> routers) throws ResourceUnavailableException { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean prepareAggregatedExecution(final Network network, - final List<DomainRouterVO> routers) throws AgentUnavailableException { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean completeAggregatedExecution(final Network network, - final List<DomainRouterVO> routers) throws AgentUnavailableException { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean cleanupAggregatedExecution(final Network network, - final List<DomainRouterVO> routers) throws AgentUnavailableException { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean sendCommandsToRouter(final VirtualRouter router, final Commands cmds) throws AgentUnavailableException { - if(!checkRouterVersion(router)){ - s_logger.debug("Router requires upgrade. Unable to send command to router:" + router.getId() + ", router template version : " + router.getTemplateVersion() - + ", minimal required version : " + MinVRVersion); - throw new CloudRuntimeException("Unable to send command. Upgrade in progress. Please contact administrator."); - } - Answer[] answers = null; - try { - answers = _agentMgr.send(router.getHostId(), cmds); - } catch (final OperationTimedoutException e) { - s_logger.warn("Timed Out", e); - throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e); - } - - if (answers == null) { - return false; - } - - if (answers.length != cmds.size()) { - return false; - } - - // FIXME: Have to return state for individual command in the future - boolean result = true; - if (answers.length > 0) { - for (final Answer answer : answers) { - if (!answer.getResult()) { - result = false; - break; - } - } - } - return result; - } - - // Checks if the router is at the required version - // Compares MS version and router version - protected boolean checkRouterVersion(final VirtualRouter router) { - if(!routerVersionCheckEnabled.value()){ - //Router version check is disabled. - return true; - } - if(router.getTemplateVersion() == null){ - return false; - } - final String trimmedVersion = Version.trimRouterVersion(router.getTemplateVersion()); - return (Version.compare(trimmedVersion, MinVRVersion) >= 0); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b0d188/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index 857cfe9..f5b5096 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -20,26 +20,22 @@ import java.util.List; import org.apache.cloudstack.framework.config.ConfigKey; -import com.cloud.deploy.DeployDestination; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.RemoteAccessVpn; import com.cloud.network.VirtualNetworkApplianceService; -import com.cloud.network.VpnUser; import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.utils.component.Manager; import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.NicProfile; -import com.cloud.vm.VirtualMachineProfile; /** * NetworkManager manages the network for the different end users. - * */ 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"; @@ -75,8 +71,11 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA * @param hostId * @param pubKey * @param prvKey + * + * NOT USED IN THE VIRTUAL NET APPLIANCE + * */ - boolean sendSshKeysToHost(Long hostId, String pubKey, String prvKey); + //boolean sendSshKeysToHost(Long hostId, String pubKey, String prvKey): boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List<? extends VirtualRouter> routers) throws ResourceUnavailableException; @@ -84,19 +83,12 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA List<VirtualRouter> getRoutersForNetwork(long networkId); - String[] applyVpnUsers(Network network, List<? extends VpnUser> users, List<DomainRouterVO> routers) throws ResourceUnavailableException; - VirtualRouter stop(VirtualRouter router, boolean forced, User callingUser, Account callingAccount) throws ConcurrentOperationException, ResourceUnavailableException; String getDnsBasicZoneUpdate(); - boolean configDhcpForSubnet(Network network, NicProfile nic, VirtualMachineProfile uservm, DeployDestination dest, List<DomainRouterVO> routers) - throws ResourceUnavailableException; - boolean removeDhcpSupportForSubnet(Network network, List<DomainRouterVO> routers) throws ResourceUnavailableException; - boolean setupDhcpForPvlan(boolean add, DomainRouterVO router, Long hostId, NicProfile nic); - public boolean prepareAggregatedExecution(Network network, List<DomainRouterVO> routers) throws AgentUnavailableException; public boolean completeAggregatedExecution(Network network, List<DomainRouterVO> routers) throws AgentUnavailableException; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b0d188/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java old mode 100755 new mode 100644 index 8b70fa0..cc97e5d --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -56,6 +56,8 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.framework.jobs.AsyncJobManager; import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO; import org.apache.cloudstack.managed.context.ManagedContextRunnable; +import org.apache.cloudstack.network.topology.NetworkTopology; +import org.apache.cloudstack.network.topology.NetworkTopologyContext; import org.apache.cloudstack.utils.identity.ManagementServerNode; import org.apache.log4j.Logger; import org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder; @@ -74,10 +76,8 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.GetDomRVersionAnswer; import com.cloud.agent.api.GetDomRVersionCmd; import com.cloud.agent.api.GetRouterAlertsAnswer; -import com.cloud.agent.api.ModifySshKeysCommand; import com.cloud.agent.api.NetworkUsageAnswer; import com.cloud.agent.api.NetworkUsageCommand; -import com.cloud.agent.api.PvlanSetupCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.routing.AggregationControlCommand; @@ -92,7 +92,6 @@ import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; -import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetFirewallRulesCommand; import com.cloud.agent.api.routing.SetMonitorServiceCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; @@ -120,9 +119,6 @@ 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.Pod; -import com.cloud.dc.Vlan; -import com.cloud.dc.VlanVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; @@ -133,7 +129,6 @@ import com.cloud.event.EventTypes; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConnectionException; -import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapacityException; import com.cloud.exception.InvalidParameterValueException; @@ -228,7 +223,6 @@ import com.cloud.user.dao.UserStatisticsDao; import com.cloud.user.dao.UserStatsLogDao; import com.cloud.uservm.UserVm; import com.cloud.utils.NumbersUtil; -import com.cloud.utils.PasswordGenerator; import com.cloud.utils.StringUtils; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.component.ManagerBase; @@ -391,6 +385,9 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { OpRouterMonitorServiceDao _opRouterMonitorServiceDao; @Inject + NetworkTopologyContext networkTopologyContext; + + @Inject protected NetworkGeneralHelper nwHelper; @Inject protected RouterDeploymentDefinitionBuilder routerDeploymentManagerBuilder; @@ -427,18 +424,6 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { BlockingQueue<Long> _vrUpdateQueue = null; @Override - public boolean sendSshKeysToHost(final Long hostId, final String pubKey, final String prvKey) { - final ModifySshKeysCommand cmd = new ModifySshKeysCommand(pubKey, prvKey); - final Answer answer = _agentMgr.easySend(hostId, cmd); - - if (answer != null) { - return true; - } else { - return false; - } - } - - @Override public VirtualRouter destroyRouter(final long routerId, final Account caller, final Long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException { return nwHelper.destroyRouter(routerId, caller, callerUserId); } @@ -1714,37 +1699,6 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { } @Override - public boolean setupDhcpForPvlan(final boolean add, final DomainRouterVO router, final Long hostId, final NicProfile nic) { - if (!nic.getBroadCastUri().getScheme().equals("pvlan")) { - return false; - } - String op = "add"; - if (!add) { - op = "delete"; - } - final Network network = _networkDao.findById(nic.getNetworkId()); - final String networkTag = _networkModel.getNetworkTag(router.getHypervisorType(), network); - final PvlanSetupCommand cmd = PvlanSetupCommand.createDhcpSetup(op, nic.getBroadCastUri(), networkTag, router.getInstanceName(), nic.getMacAddress(), nic.getIp4Address()); - // In fact we send command to the host of router, we're not programming - // router but the host - Answer answer = null; - try { - answer = _agentMgr.send(hostId, cmd); - } catch (final OperationTimedoutException e) { - s_logger.warn("Timed Out", e); - return false; - } catch (final AgentUnavailableException e) { - s_logger.warn("Agent Unavailable ", e); - return false; - } - - if (answer == null || !answer.getResult()) { - return false; - } - return true; - } - - @Override public boolean finalizeDeployment(final Commands cmds, final VirtualMachineProfile profile, final DeployDestination dest, final ReservationContext context) throws ResourceUnavailableException { final DomainRouterVO router = _routerDao.findById(profile.getId()); @@ -2160,11 +2114,20 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { final List<? extends Nic> 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) { guestNetworks.add(network); if (nic.getBroadcastUri().getScheme().equals("pvlan")) { final NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(), 0, false, "pvlan-nic"); - result = setupDhcpForPvlan(true, router, router.getHostId(), nicProfile); + + final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO); + try { + result = networkTopology.setupDhcpForPvlan(true, router, router.getHostId(), nicProfile); + } catch (final ResourceUnavailableException e) { + s_logger.debug("ERROR in finalizeStart: ", e); + } } } } @@ -2187,9 +2150,17 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { final List<? extends Nic> 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"); - setupDhcpForPvlan(false, domR, domR.getHostId(), nicProfile); + + 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); + } } } @@ -2279,96 +2250,6 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { } @Override - public boolean configDhcpForSubnet(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, - final List<DomainRouterVO> routers) throws ResourceUnavailableException { - final UserVmVO vm = _userVmDao.findById(profile.getId()); - _userVmDao.loadDetails(vm); - - // Asuming we have only one router per network For Now. - final DomainRouterVO router = routers.get(0); - if (router.getState() != State.Running) { - s_logger.warn("Failed to configure dhcp: router not in running state"); - throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState(), DataCenter.class, network.getDataCenterId()); - } - // check if this is not the primary subnet. - final NicVO domr_guest_nic = _nicDao.findByInstanceIdAndIpAddressAndVmtype(router.getId(), _nicDao.getIpAddress(nic.getNetworkId(), router.getId()), - VirtualMachine.Type.DomainRouter); - // check if the router ip address and the vm ip address belong to same - // subnet. - // if they do not belong to same netwoek check for the alias ips. if not - // create one. - // This should happen only in case of Basic and Advanced SG enabled - // networks. - if (!NetUtils.sameSubnet(domr_guest_nic.getIp4Address(), nic.getIp4Address(), nic.getNetmask())) { - final List<NicIpAliasVO> aliasIps = _nicIpAliasDao.listByNetworkIdAndState(domr_guest_nic.getNetworkId(), NicIpAlias.state.active); - boolean ipInVmsubnet = false; - for (final NicIpAliasVO alias : aliasIps) { - // check if any of the alias ips belongs to the Vm's subnet. - if (NetUtils.sameSubnet(alias.getIp4Address(), nic.getIp4Address(), nic.getNetmask())) { - ipInVmsubnet = true; - break; - } - } - PublicIp routerPublicIP = null; - String routerAliasIp = null; - final DataCenter dc = _dcDao.findById(router.getDataCenterId()); - if (ipInVmsubnet == false) { - try { - if (network.getTrafficType() == TrafficType.Guest && network.getGuestType() == GuestType.Shared) { - _podDao.findById(vm.getPodIdToDeployIn()); - final Account caller = CallContext.current().getCallingAccount(); - final List<VlanVO> vlanList = _vlanDao.listVlansByNetworkIdAndGateway(network.getId(), nic.getGateway()); - final List<Long> vlanDbIdList = new ArrayList<Long>(); - for (final VlanVO vlan : vlanList) { - vlanDbIdList.add(vlan.getId()); - } - if (dc.getNetworkType() == NetworkType.Basic) { - routerPublicIP = _ipAddrMgr.assignPublicIpAddressFromVlans(router.getDataCenterId(), vm.getPodIdToDeployIn(), caller, Vlan.VlanType.DirectAttached, - vlanDbIdList, nic.getNetworkId(), null, false); - } else { - routerPublicIP = _ipAddrMgr.assignPublicIpAddressFromVlans(router.getDataCenterId(), null, caller, Vlan.VlanType.DirectAttached, vlanDbIdList, - nic.getNetworkId(), null, false); - } - - routerAliasIp = routerPublicIP.getAddress().addr(); - } - } catch (final InsufficientAddressCapacityException e) { - s_logger.info(e.getMessage()); - s_logger.info("unable to configure dhcp for this VM."); - return false; - } - // this means we did not create a ip alis on the router. - final NicIpAliasVO alias = new NicIpAliasVO(domr_guest_nic.getId(), routerAliasIp, router.getId(), CallContext.current().getCallingAccountId(), - network.getDomainId(), nic.getNetworkId(), nic.getGateway(), nic.getNetmask()); - alias.setAliasCount(routerPublicIP.getIpMacAddress()); - _nicIpAliasDao.persist(alias); - final List<IpAliasTO> ipaliasTo = new ArrayList<IpAliasTO>(); - ipaliasTo.add(new IpAliasTO(routerAliasIp, alias.getNetmask(), alias.getAliasCount().toString())); - final Commands cmds = new Commands(Command.OnError.Stop); - createIpAlias(router, ipaliasTo, alias.getNetworkId(), cmds); - // also add the required configuration to the dnsmasq for - // supporting dhcp and dns on the new ip. - configDnsMasq(router, network, cmds); - final boolean result = sendCommandsToRouter(router, cmds); - if (result == false) { - final NicIpAliasVO ipAliasVO = _nicIpAliasDao.findByInstanceIdAndNetworkId(network.getId(), router.getId()); - final PublicIp routerPublicIPFinal = routerPublicIP; - Transaction.execute(new TransactionCallbackNoReturn() { - @Override - public void doInTransactionWithoutResult(final TransactionStatus status) { - _nicIpAliasDao.expunge(ipAliasVO.getId()); - _ipAddressDao.unassignIpAddress(routerPublicIPFinal.getId()); - } - }); - throw new CloudRuntimeException("failed to configure ip alias on the router as a part of dhcp config"); - } - } - return true; - } - return true; - } - - @Override public boolean removeDhcpSupportForSubnet(final Network network, final List<DomainRouterVO> routers) throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Failed to add/remove VPN users: no router found for account and zone"); @@ -2479,45 +2360,6 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { } @Override - // FIXME add partial success and STOP state support - public String[] applyVpnUsers(final Network network, final List<? extends VpnUser> users, final List<DomainRouterVO> routers) throws ResourceUnavailableException { - if (routers == null || routers.isEmpty()) { - s_logger.warn("Failed to add/remove VPN users: no router found for account and zone"); - throw new ResourceUnavailableException("Unable to assign ip addresses, domR doesn't exist for network " + network.getId(), DataCenter.class, network.getDataCenterId()); - } - - boolean agentResults = true; - - for (final DomainRouterVO router : routers) { - if (router.getState() != State.Running) { - s_logger.warn("Failed to add/remove VPN users: router not in running state"); - throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState(), DataCenter.class, - network.getDataCenterId()); - } - - final Commands cmds = new Commands(Command.OnError.Continue); - createApplyVpnUsersCommand(users, router, cmds); - - // Currently we receive just one answer from the agent. In the - // future we have to parse individual answers and set - // results accordingly - final boolean agentResult = sendCommandsToRouter(router, cmds); - agentResults = agentResults && agentResult; - } - - final String[] result = new String[users.size()]; - for (int i = 0; i < result.length; i++) { - if (agentResults) { - result[i] = null; - } else { - result[i] = String.valueOf(agentResults); - } - } - - return result; - } - - @Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_START, eventDescription = "starting router Vm", async = true) public VirtualRouter startRouter(final long id) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException { return startRouter(id, true); @@ -2814,25 +2656,6 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { cmds.addCommand("startVpn", startVpnCmd); } - private void createPasswordCommand(final VirtualRouter router, final VirtualMachineProfile profile, final NicVO nic, final Commands cmds) { - final String password = (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword); - final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); - - // password should be set only on default network element - if (password != null && nic.isDefaultNic()) { - final String encodedPassword = PasswordGenerator.rot13(password); - final SavePasswordCommand cmd = new SavePasswordCommand(encodedPassword, nic.getIp4Address(), profile.getVirtualMachine().getHostName(), - _networkModel.getExecuteInSeqNtwkElmtCmd()); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(nic.getNetworkId(), router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); - cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - - cmds.addCommand("password", cmd); - } - - } - private void createVmDataCommand(final VirtualRouter router, final UserVm vm, final NicVO nic, final String publicKey, final Commands cmds) { final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText(); final String zoneName = _dcDao.findById(router.getDataCenterId()).getName(); @@ -2954,7 +2777,8 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { } } - protected boolean sendCommandsToRouter(final VirtualRouter router, final Commands cmds) throws AgentUnavailableException { + @Override + public boolean sendCommandsToRouter(final VirtualRouter router, final Commands cmds) throws AgentUnavailableException { if (!nwHelper.checkRouterVersion(router)) { s_logger.debug("Router requires upgrade. Unable to send command to router:" + router.getId() + ", router template version : " + router.getTemplateVersion() + ", minimal required version : " + MinVRVersion); @@ -3039,24 +2863,6 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { } } - protected boolean sendLBRules(final VirtualRouter router, final List<LoadBalancingRule> rules, final long guestNetworkId) throws ResourceUnavailableException { - final Commands cmds = new Commands(Command.OnError.Continue); - createApplyLoadBalancingRulesCommands(rules, router, cmds, guestNetworkId); - return sendCommandsToRouter(router, cmds); - } - - protected boolean sendPortForwardingRules(final VirtualRouter router, final List<PortForwardingRule> rules, final long guestNetworkId) throws ResourceUnavailableException { - final Commands cmds = new Commands(Command.OnError.Continue); - createApplyPortForwardingRulesCommands(rules, router, cmds, guestNetworkId); - return sendCommandsToRouter(router, cmds); - } - - protected boolean sendStaticNatRules(final VirtualRouter router, final List<StaticNatRule> rules, final long guestNetworkId) throws ResourceUnavailableException { - final Commands cmds = new Commands(Command.OnError.Continue); - createApplyStaticNatRulesCommands(rules, router, cmds, guestNetworkId); - return sendCommandsToRouter(router, cmds); - } - @Override public List<VirtualRouter> getRoutersForNetwork(final long networkId) { final List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId); @@ -3110,110 +2916,11 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { cmds.addCommand(cmd); } - protected boolean sendFirewallRules(final VirtualRouter router, final List<FirewallRule> rules, final long guestNetworkId) throws ResourceUnavailableException { - final Commands cmds = new Commands(Command.OnError.Continue); - createFirewallRulesCommands(rules, router, cmds, guestNetworkId); - return sendCommandsToRouter(router, cmds); - } - @Override public String getDnsBasicZoneUpdate() { return _dnsBasicZoneUpdates; } - protected interface RuleApplier { - boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException; - } - - protected boolean applyRules(final Network network, final List<? extends VirtualRouter> routers, final String typeString, final boolean isPodLevelException, final Long podId, - final boolean failWhenDisconnect, final RuleApplier applier) throws ResourceUnavailableException { - if (routers == null || routers.isEmpty()) { - s_logger.warn("Unable to apply " + typeString + ", virtual router doesn't exist in the network " + network.getId()); - throw new ResourceUnavailableException("Unable to apply " + typeString, DataCenter.class, network.getDataCenterId()); - } - - final DataCenter dc = _dcDao.findById(network.getDataCenterId()); - final boolean isZoneBasic = dc.getNetworkType() == NetworkType.Basic; - - // isPodLevelException and podId is only used for basic zone - assert !(!isZoneBasic && isPodLevelException || isZoneBasic && isPodLevelException && podId == null); - - final List<VirtualRouter> connectedRouters = new ArrayList<VirtualRouter>(); - final List<VirtualRouter> disconnectedRouters = new ArrayList<VirtualRouter>(); - boolean result = true; - final String msg = "Unable to apply " + typeString + " on disconnected router "; - for (final VirtualRouter router : routers) { - if (router.getState() == State.Running) { - s_logger.debug("Applying " + typeString + " in network " + network); - - if (router.isStopPending()) { - if (_hostDao.findById(router.getHostId()).getState() == Status.Up) { - throw new ResourceUnavailableException("Unable to process due to the stop pending router " + router.getInstanceName() - + " haven't been stopped after it's host coming back!", DataCenter.class, router.getDataCenterId()); - } - s_logger.debug("Router " + router.getInstanceName() + " is stop pending, so not sending apply " + typeString + " commands to the backend"); - continue; - } - - try { - result = applier.execute(network, router); - connectedRouters.add(router); - } catch (final AgentUnavailableException e) { - s_logger.warn(msg + router.getInstanceName(), e); - disconnectedRouters.add(router); - } - - // If rules fail to apply on one domR and not due to - // disconnection, no need to proceed with the rest - if (!result) { - if (isZoneBasic && isPodLevelException) { - throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", Pod.class, podId); - } - throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", DataCenter.class, router.getDataCenterId()); - } - - } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) { - s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + ", so not sending apply " + typeString + " commands to the backend"); - } else { - s_logger.warn("Unable to apply " + typeString + ", virtual router is not in the right state " + router.getState()); - if (isZoneBasic && isPodLevelException) { - throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", Pod.class, podId); - } - throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", DataCenter.class, router.getDataCenterId()); - } - } - - if (!connectedRouters.isEmpty()) { - if (!isZoneBasic && !disconnectedRouters.isEmpty() && disconnectedRouters.get(0).getIsRedundantRouter()) { - // These disconnected redundant virtual routers are out of sync - // now, stop them for synchronization - handleSingleWorkingRedundantRouter(connectedRouters, disconnectedRouters, msg); - } - } else if (!disconnectedRouters.isEmpty()) { - for (final VirtualRouter router : disconnectedRouters) { - if (s_logger.isDebugEnabled()) { - s_logger.debug(msg + router.getInstanceName() + "(" + router.getId() + ")"); - } - } - if (isZoneBasic && isPodLevelException) { - throw new ResourceUnavailableException(msg, Pod.class, podId); - } - throw new ResourceUnavailableException(msg, DataCenter.class, disconnectedRouters.get(0).getDataCenterId()); - } - - result = true; - if (failWhenDisconnect) { - result = !connectedRouters.isEmpty(); - } - return result; - } - - protected boolean applyStaticNat(final VirtualRouter router, final List<? extends StaticNat> rules, final long guestNetworkId) throws ResourceUnavailableException { - final Commands cmds = new Commands(Command.OnError.Continue); - createApplyStaticNatCommands(rules, router, cmds, guestNetworkId); - return sendCommandsToRouter(router, cmds); - } - private void createApplyStaticNatCommands(final List<? extends StaticNat> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) { final List<StaticNatRuleTO> rulesTO = new ArrayList<StaticNatRuleTO>(); if (rules != null) { @@ -3578,4 +3285,9 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { public boolean completeAggregatedExecution(final Network network, final List<DomainRouterVO> routers) throws AgentUnavailableException { return aggregationExecution(Action.Finish, network, routers); } + + @Override + public boolean cleanupAggregatedExecution(final Network network, final List<DomainRouterVO> routers) throws AgentUnavailableException { + return aggregationExecution(Action.Cleanup, network, routers); + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b0d188/server/src/com/cloud/network/rules/DhcpRules.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/rules/DhcpRules.java b/server/src/com/cloud/network/rules/DhcpRules.java index 172c198..0ff2462 100644 --- a/server/src/com/cloud/network/rules/DhcpRules.java +++ b/server/src/com/cloud/network/rules/DhcpRules.java @@ -19,43 +19,44 @@ package com.cloud.network.rules; import org.apache.cloudstack.network.topology.NetworkTopologyVisitor; -import com.cloud.deploy.DeployDestination; +import com.cloud.agent.api.PvlanSetupCommand; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.router.VirtualRouter; import com.cloud.vm.NicProfile; -import com.cloud.vm.VirtualMachineProfile; public class DhcpRules extends RuleApplier { - private final NicProfile nic; - private final VirtualMachineProfile profile; - private final DeployDestination destination; + private final boolean _isAddPvlan; + private final NicProfile _nic; - public DhcpRules(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination destination) { - super(network); + private PvlanSetupCommand _setupCommand; - this.nic = nic; - this.profile = profile; - this.destination = destination; + public DhcpPvlanRules(final boolean isAddPvlan, final NicProfile nic) { + super(null); + + _isAddPvlan = isAddPvlan; + _nic = nic; } @Override public boolean accept(final NetworkTopologyVisitor visitor, final VirtualRouter router) throws ResourceUnavailableException { - this._router = router; + _router = router; - return visitor.visit(this); - } + String op = "add"; + if (!_isAddPvlan) { + op = "delete"; + } - public NicProfile getNic() { - return nic; - } + final Network network = _networkDao.findById(_nic.getNetworkId()); + final String networkTag = _networkModel.getNetworkTag(router.getHypervisorType(), network); + + _setupCommand = PvlanSetupCommand.createDhcpSetup(op, _nic.getBroadCastUri(), networkTag, router.getInstanceName(), _nic.getMacAddress(), _nic.getIp4Address()); - public VirtualMachineProfile getProfile() { - return profile; + return visitor.visit(this); } - public DeployDestination getDestination() { - return destination; + public PvlanSetupCommand getSetupCommand() { + return _setupCommand; } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b0d188/server/src/com/cloud/network/rules/DhcpSubNetRules.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/rules/DhcpSubNetRules.java b/server/src/com/cloud/network/rules/DhcpSubNetRules.java index b3374ba..e10a92a 100644 --- a/server/src/com/cloud/network/rules/DhcpSubNetRules.java +++ b/server/src/com/cloud/network/rules/DhcpSubNetRules.java @@ -17,45 +17,196 @@ package com.cloud.network.rules; +import java.util.ArrayList; +import java.util.List; + +import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.network.topology.NetworkTopologyVisitor; +import org.apache.log4j.Logger; -import com.cloud.deploy.DeployDestination; +import com.cloud.agent.api.routing.CreateIpAliasCommand; +import com.cloud.agent.api.routing.DnsMasqConfigCommand; +import com.cloud.agent.api.routing.IpAliasTO; +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.to.DhcpTO; +import com.cloud.agent.manager.Commands; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.Vlan; +import com.cloud.dc.VlanVO; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; +import com.cloud.network.Network.GuestType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.addr.PublicIp; import com.cloud.network.router.VirtualRouter; +import com.cloud.user.Account; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.TransactionCallbackNoReturn; +import com.cloud.utils.db.TransactionStatus; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.NicIpAlias; import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.NicIpAliasVO; public class DhcpSubNetRules extends RuleApplier { - private final NicProfile nic; - private final VirtualMachineProfile profile; - private final DeployDestination destination; + private static final Logger s_logger = Logger.getLogger(DhcpSubNetRules.class); + + private final NicProfile _nic; + private final VirtualMachineProfile _profile; - public DhcpSubNetRules(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination destination) { + private NicIpAliasVO _nicAlias; + private String _routerAliasIp; + + public DhcpSubNetRules(final Network network, final NicProfile nic, final VirtualMachineProfile profile) { super(network); - this.nic = nic; - this.profile = profile; - this.destination = destination; + _nic = nic; + _profile = profile; } @Override public boolean accept(final NetworkTopologyVisitor visitor, final VirtualRouter router) throws ResourceUnavailableException { - this._router = router; + _router = router; + + final UserVmVO vm = _userVmDao.findById(_profile.getId()); + _userVmDao.loadDetails(vm); + + //check if this is not the primary subnet. + final NicVO domr_guest_nic = + _nicDao.findByInstanceIdAndIpAddressAndVmtype(router.getId(), _nicDao.getIpAddress(_nic.getNetworkId(), router.getId()), VirtualMachine.Type.DomainRouter); + //check if the router ip address and the vm ip address belong to same subnet. + //if they do not belong to same netwoek check for the alias ips. if not create one. + // This should happen only in case of Basic and Advanced SG enabled networks. + if (!NetUtils.sameSubnet(domr_guest_nic.getIp4Address(), _nic.getIp4Address(), _nic.getNetmask())) { + final List<NicIpAliasVO> aliasIps = _nicIpAliasDao.listByNetworkIdAndState(domr_guest_nic.getNetworkId(), NicIpAlias.state.active); + boolean ipInVmsubnet = false; + for (final NicIpAliasVO alias : aliasIps) { + //check if any of the alias ips belongs to the Vm's subnet. + if (NetUtils.sameSubnet(alias.getIp4Address(), _nic.getIp4Address(), _nic.getNetmask())) { + ipInVmsubnet = true; + break; + } + } + + PublicIp routerPublicIP = null; + final DataCenter dc = _dcDao.findById(router.getDataCenterId()); + if (ipInVmsubnet == false) { + try { + if (_network.getTrafficType() == TrafficType.Guest && _network.getGuestType() == GuestType.Shared) { + _podDao.findById(vm.getPodIdToDeployIn()); + final Account caller = CallContext.current().getCallingAccount(); + final List<VlanVO> vlanList = _vlanDao.listVlansByNetworkIdAndGateway(_network.getId(), _nic.getGateway()); + final List<Long> vlanDbIdList = new ArrayList<Long>(); + for (final VlanVO vlan : vlanList) { + vlanDbIdList.add(vlan.getId()); + } + if (dc.getNetworkType() == NetworkType.Basic) { + routerPublicIP = + _ipAddrMgr.assignPublicIpAddressFromVlans(router.getDataCenterId(), vm.getPodIdToDeployIn(), caller, Vlan.VlanType.DirectAttached, + vlanDbIdList, _nic.getNetworkId(), null, false); + } else { + routerPublicIP = + _ipAddrMgr.assignPublicIpAddressFromVlans(router.getDataCenterId(), null, caller, Vlan.VlanType.DirectAttached, vlanDbIdList, + _nic.getNetworkId(), null, false); + } + + _routerAliasIp = routerPublicIP.getAddress().addr(); + } + } catch (final InsufficientAddressCapacityException e) { + s_logger.info(e.getMessage()); + s_logger.info("unable to configure dhcp for this VM."); + return false; + } + //this means we did not create an IP alias on the router. + _nicAlias = new NicIpAliasVO(domr_guest_nic.getId(), _routerAliasIp, router.getId(), CallContext.current().getCallingAccountId(), _network.getDomainId(), + _nic.getNetworkId(), _nic.getGateway(), _nic.getNetmask()); + _nicAlias.setAliasCount((routerPublicIP.getIpMacAddress())); + _nicIpAliasDao.persist(_nicAlias); + + final boolean result = visitor.visit(this); + + // Clean the routerAliasIp just to make sure it will keep an older value. + // The rules classes area created every time a command is issued, but I want to make 100% sure + // that the routerAliasIp won't float around. + _routerAliasIp = null; + + if (result == false) { + final NicIpAliasVO ipAliasVO = _nicIpAliasDao.findByInstanceIdAndNetworkId(_network.getId(), router.getId()); + final PublicIp routerPublicIPFinal = routerPublicIP; + Transaction.execute(new TransactionCallbackNoReturn() { + @Override + public void doInTransactionWithoutResult(final TransactionStatus status) { + _nicIpAliasDao.expunge(ipAliasVO.getId()); + _ipAddressDao.unassignIpAddress(routerPublicIPFinal.getId()); + } + }); + throw new CloudRuntimeException("failed to configure ip alias on the router as a part of dhcp config"); + } + } + return true; + } return visitor.visit(this); } - public NicProfile getNic() { - return nic; + public NicIpAliasVO getNicAlias() { + return _nicAlias; + } + + public String getRouterAliasIp() { + return _routerAliasIp; } - public VirtualMachineProfile getProfile() { - return profile; + public void createIpAlias(final VirtualRouter router, final List<IpAliasTO> ipAliasTOs, final Long networkid, final Commands cmds) { + + final String routerip = _routerControlHelper.getRouterIpInNetwork(networkid, router.getId()); + final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); + final CreateIpAliasCommand ipaliasCmd = new CreateIpAliasCommand(routerip, ipAliasTOs); + ipaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId())); + ipaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + ipaliasCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, routerip); + ipaliasCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand("ipalias", ipaliasCmd); } - public DeployDestination getDestination() { - return destination; + public void configDnsMasq(final VirtualRouter router, final Network network, final Commands cmds) { + final DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); + final List<NicIpAliasVO> ipAliasVOList = _nicIpAliasDao.listByNetworkIdAndState(network.getId(), NicIpAlias.state.active); + final List<DhcpTO> ipList = new ArrayList<DhcpTO>(); + + final NicVO router_guest_nic = _nicDao.findByNtwkIdAndInstanceId(network.getId(), router.getId()); + final String cidr = NetUtils.getCidrFromGatewayAndNetmask(router_guest_nic.getGateway(), router_guest_nic.getNetmask()); + final String[] cidrPair = cidr.split("\\/"); + final String cidrAddress = cidrPair[0]; + final long cidrSize = Long.parseLong(cidrPair[1]); + final String startIpOfSubnet = NetUtils.getIpRangeStartIpFromCidr(cidrAddress, cidrSize); + + ipList.add(new DhcpTO(router_guest_nic.getIp4Address(), router_guest_nic.getGateway(), router_guest_nic.getNetmask(), startIpOfSubnet)); + for (final NicIpAliasVO ipAliasVO : ipAliasVOList) { + final DhcpTO DhcpTO = new DhcpTO(ipAliasVO.getIp4Address(), ipAliasVO.getGateway(), ipAliasVO.getNetmask(), ipAliasVO.getStartIpOfSubnet()); + if (s_logger.isTraceEnabled()) { + s_logger.trace("configDnsMasq : adding ip {" + DhcpTO.getGateway() + ", " + DhcpTO.getNetmask() + ", " + DhcpTO.getRouterIp() + ", " + + DhcpTO.getStartIpOfSubnet() + "}"); + } + ipList.add(DhcpTO); + ipAliasVO.setVmId(router.getId()); + } + _dcDao.findById(router.getDataCenterId()); + final DnsMasqConfigCommand dnsMasqConfigCmd = new DnsMasqConfigCommand(ipList); + dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId())); + dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(network.getId(), router.getId())); + dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand("dnsMasqConfig", dnsMasqConfigCmd); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b0d188/server/src/com/cloud/network/rules/RuleApplier.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/rules/RuleApplier.java b/server/src/com/cloud/network/rules/RuleApplier.java index cc29461..110d5da 100644 --- a/server/src/com/cloud/network/rules/RuleApplier.java +++ b/server/src/com/cloud/network/rules/RuleApplier.java @@ -26,16 +26,20 @@ import com.cloud.agent.manager.Commands; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.VlanDao; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.IpAddressManager; import com.cloud.network.Network; import com.cloud.network.NetworkModel; import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.lb.LoadBalancingRulesManager; -import com.cloud.network.router.NEWVirtualNetworkApplianceManager; import com.cloud.network.router.NetworkGeneralHelper; import com.cloud.network.router.RouterControlHelper; +import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.router.VirtualRouter; import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpc.dao.VpcDao; @@ -49,11 +53,12 @@ import com.cloud.vm.NicVO; import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.NicIpAliasDao; import com.cloud.vm.dao.UserVmDao; public abstract class RuleApplier { - protected NEWVirtualNetworkApplianceManager _applianceManager; + protected VirtualNetworkApplianceManager _applianceManager; protected NetworkModel _networkModel; @@ -85,10 +90,20 @@ public abstract class RuleApplier { protected VpcDao _vpcDao; + protected NicIpAliasDao _nicIpAliasDao; + + protected HostPodDao _podDao; + + protected VlanDao _vlanDao; + + protected IPAddressDao _ipAddressDao; + protected VpcManager _vpcMgr; protected VirtualMachineManager _itMgr; + protected IpAddressManager _ipAddrMgr; + protected Network _network; protected VirtualRouter _router; @@ -111,7 +126,7 @@ public abstract class RuleApplier { return _router; } - public NEWVirtualNetworkApplianceManager getApplianceManager() { + public VirtualNetworkApplianceManager getApplianceManager() { return _applianceManager; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b0d188/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java b/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java index 356f3bb..44c4a9f 100644 --- a/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java +++ b/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java @@ -23,18 +23,23 @@ import javax.inject.Inject; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; +import com.cloud.network.IpAddressManager; import com.cloud.network.Network; import com.cloud.network.NetworkModel; import com.cloud.network.PublicIpAddress; import com.cloud.network.VpnUser; import com.cloud.network.dao.FirewallRulesDao; +import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.router.NetworkGeneralHelper; import com.cloud.network.router.RouterControlHelper; +import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.vpc.NetworkACLItem; import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpc.dao.VpcDao; @@ -47,6 +52,7 @@ import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.NicIpAliasDao; import com.cloud.vm.dao.UserVmDao; public class VirtualNetworkApplianceFactory { @@ -103,9 +109,27 @@ public class VirtualNetworkApplianceFactory { protected FirewallRulesDao _rulesDao; @Inject + protected NicIpAliasDao _nicIpAliasDao; + + @Inject + protected HostPodDao _podDao; + + @Inject + protected VlanDao _vlanDao; + + @Inject + protected IPAddressDao _ipAddressDao; + + @Inject protected RouterControlHelper _routerControlHelper; @Inject + protected VirtualNetworkApplianceManager _applianceManager; + + @Inject + protected IpAddressManager _ipAddrMgr; + + @Inject protected NetworkGeneralHelper _networkHelper; public LoadBalancingRules createLoadBalancingRules(final Network network, final List<LoadBalancingRule> rules) { @@ -254,4 +278,30 @@ public class VirtualNetworkApplianceFactory { return networkAclsRules; } + + public DhcpSubNetRules createDhcpSubNetRules(final Network network, final NicProfile nic, final VirtualMachineProfile profile) { + DhcpSubNetRules subNetRules = new DhcpSubNetRules(network, nic, profile); + + initBeans(subNetRules); + + subNetRules._vpcDao = _vpcDao; + subNetRules._userVmDao = _userVmDao; + subNetRules._podDao = _podDao; + subNetRules._vlanDao = _vlanDao; + subNetRules._nicIpAliasDao = _nicIpAliasDao; + subNetRules._ipAddrMgr = _ipAddrMgr; + subNetRules._ipAddressDao = _ipAddressDao; + + return subNetRules; + } + + public DhcpPvlanRules createDhcpPvlanRules(final boolean isAddPvlan, final NicProfile nic) { + DhcpPvlanRules pvlanRules = new DhcpPvlanRules(isAddPvlan, nic); + + initBeans(pvlanRules); + + pvlanRules._networkDao = _networkDao; + + return pvlanRules; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b0d188/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java ---------------------------------------------------------------------- diff --git a/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java b/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java index a39fed6..8b2b55c 100644 --- a/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java +++ b/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkTopology.java @@ -36,6 +36,7 @@ import com.cloud.network.Network; import com.cloud.network.PublicIpAddress; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.DhcpEntryRules; +import com.cloud.network.rules.DhcpSubNetRules; import com.cloud.network.rules.NetworkAclsRules; import com.cloud.network.rules.NicPlugInOutRules; import com.cloud.network.rules.RuleApplier; @@ -58,6 +59,36 @@ public class AdvancedNetworkTopology extends BasicNetworkTopology { protected AdvancedNetworkVisitor _advancedVisitor; @Override + public boolean setupDhcpForPvlan(final boolean isAddPvlan, final DomainRouterVO router, final Long hostId, final NicProfile nic) throws ResourceUnavailableException { + + if (!nic.getBroadCastUri().getScheme().equals("pvlan")) { + return false; + } + + DhcpPvlanRules pvlanRules = _virtualNetworkApplianceFactory.createDhcpPvlanRules(isAddPvlan, nic); + + return pvlanRules.accept(_advancedVisitor, router); + } + + @Override + public boolean configDhcpForSubnet(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, + final List<DomainRouterVO> routers) throws ResourceUnavailableException { + + s_logger.debug("CONFIG DHCP FOR SUBNETS RULES"); + + // Asuming we have only one router per network For Now. + final DomainRouterVO router = routers.get(0); + if (router.getState() != State.Running) { + s_logger.warn("Failed to configure dhcp: router not in running state"); + throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState(), DataCenter.class, network.getDataCenterId()); + } + + DhcpSubNetRules subNetRules = _virtualNetworkApplianceFactory.createDhcpSubNetRules(network, nic, profile); + + return subNetRules.accept(_advancedVisitor, router); + } + + @Override public boolean applyUserData(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final List<DomainRouterVO> routers) throws ResourceUnavailableException { @@ -92,12 +123,13 @@ public class AdvancedNetworkTopology extends BasicNetworkTopology { @Override public boolean associatePublicIP(final Network network, final List<? extends PublicIpAddress> ipAddresses, final List<? extends VirtualRouter> routers) throws ResourceUnavailableException { + if (ipAddresses == null || ipAddresses.isEmpty()) { s_logger.debug("No ip association rules to be applied for network " + network.getId()); return true; } - //only one router is supported in VPC now + // only one router is supported in VPC now VirtualRouter router = routers.get(0); if (router.getVpcId() == null) { @@ -127,6 +159,7 @@ public class AdvancedNetworkTopology extends BasicNetworkTopology { @Override public boolean applyNetworkACLs(final Network network, final List<? extends NetworkACLItem> rules, final List<? extends VirtualRouter> routers, final boolean isPrivateGateway) throws ResourceUnavailableException { + if (rules == null || rules.isEmpty()) { s_logger.debug("No network ACLs to be applied for network " + network.getId()); return true; @@ -145,22 +178,21 @@ public class AdvancedNetworkTopology extends BasicNetworkTopology { } @Override - public boolean applyRules(final Network network, final List<? extends VirtualRouter> routers, final String typeString, final boolean isPodLevelException, final Long podId, final boolean failWhenDisconnect, - final RuleApplierWrapper<RuleApplier> ruleApplierWrapper) - throws ResourceUnavailableException { + public boolean applyRules(final Network network, final List<? extends VirtualRouter> routers, final String typeString, final boolean isPodLevelException, final Long podId, + final boolean failWhenDisconnect, final RuleApplierWrapper<RuleApplier> ruleApplierWrapper) throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Unable to apply " + typeString + ", virtual router doesn't exist in the network " + network.getId()); throw new ResourceUnavailableException("Unable to apply " + typeString, DataCenter.class, network.getDataCenterId()); } - RuleApplier ruleApplier = ruleApplierWrapper.getRuleType(); + RuleApplier ruleApplier = ruleApplierWrapper.getRuleType(); final DataCenter dc = _dcDao.findById(network.getDataCenterId()); - final boolean isZoneBasic = (dc.getNetworkType() == NetworkType.Basic); + final boolean isZoneBasic = dc.getNetworkType() == NetworkType.Basic; // isPodLevelException and podId is only used for basic zone - assert !((!isZoneBasic && isPodLevelException) || (isZoneBasic && isPodLevelException && podId == null)); + assert !(!isZoneBasic && isPodLevelException || isZoneBasic && isPodLevelException && podId == null); final List<VirtualRouter> connectedRouters = new ArrayList<VirtualRouter>(); final List<VirtualRouter> disconnectedRouters = new ArrayList<VirtualRouter>(); @@ -172,8 +204,8 @@ public class AdvancedNetworkTopology extends BasicNetworkTopology { if (router.isStopPending()) { if (_hostDao.findById(router.getHostId()).getState() == Status.Up) { - throw new ResourceUnavailableException("Unable to process due to the stop pending router " + router.getInstanceName() + - " haven't been stopped after it's host coming back!", DataCenter.class, router.getDataCenterId()); + throw new ResourceUnavailableException("Unable to process due to the stop pending router " + router.getInstanceName() + + " haven't been stopped after it's host coming back!", DataCenter.class, router.getDataCenterId()); } s_logger.debug("Router " + router.getInstanceName() + " is stop pending, so not sending apply " + typeString + " commands to the backend"); continue; @@ -188,7 +220,8 @@ public class AdvancedNetworkTopology extends BasicNetworkTopology { disconnectedRouters.add(router); } - //If rules fail to apply on one domR and not due to disconnection, no need to proceed with the rest + // If rules fail to apply on one domR and not due to + // disconnection, no need to proceed with the rest if (!result) { if (isZoneBasic && isPodLevelException) { throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", Pod.class, podId); @@ -203,15 +236,16 @@ public class AdvancedNetworkTopology extends BasicNetworkTopology { if (isZoneBasic && isPodLevelException) { throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", Pod.class, podId); } - throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", DataCenter.class, - router.getDataCenterId()); + throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", DataCenter.class, router.getDataCenterId()); } } if (!connectedRouters.isEmpty()) { if (!isZoneBasic && !disconnectedRouters.isEmpty() && disconnectedRouters.get(0).getIsRedundantRouter()) { - // These disconnected redundant virtual routers are out of sync now, stop them for synchronization - //[FIXME] handleSingleWorkingRedundantRouter(connectedRouters, disconnectedRouters, msg); + // These disconnected redundant virtual routers are out of sync + // now, stop them for synchronization + // [FIXME] handleSingleWorkingRedundantRouter(connectedRouters, + // disconnectedRouters, msg); } } else if (!disconnectedRouters.isEmpty()) { for (final VirtualRouter router : disconnectedRouters) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b0d188/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java ---------------------------------------------------------------------- diff --git a/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java b/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java index cdd9ba0..1b6b20d 100644 --- a/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java +++ b/server/src/org/apache/cloudstack/network/topology/AdvancedNetworkVisitor.java @@ -17,12 +17,16 @@ package org.apache.cloudstack.network.topology; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.agent.api.Command; +import com.cloud.agent.api.PvlanSetupCommand; +import com.cloud.agent.api.routing.IpAliasTO; import com.cloud.agent.manager.Commands; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; @@ -39,10 +43,13 @@ import com.cloud.network.vpc.NetworkACLItem; import com.cloud.vm.NicVO; import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.NicIpAliasVO; @Component public class AdvancedNetworkVisitor extends BasicNetworkVisitor { + private static final Logger s_logger = Logger.getLogger(AdvancedNetworkVisitor.class); + @Override public boolean visit(final UserdataPwdRules userdata) throws ResourceUnavailableException { final VirtualRouter router = userdata.getRouter(); @@ -119,11 +126,38 @@ public class AdvancedNetworkVisitor extends BasicNetworkVisitor { @Override public boolean visit(final DhcpPvlanRules dhcp) throws ResourceUnavailableException { - return false; + final VirtualRouter router = dhcp.getRouter(); + final PvlanSetupCommand setupCommand = dhcp.getSetupCommand(); + + // In fact we send command to the host of router, we're not programming router but the host + Commands cmds = new Commands(Command.OnError.Stop); + cmds.addCommand(setupCommand); + + try { + return _applianceManager.sendCommandsToRouter(router, cmds); + } catch (final ResourceUnavailableException e) { + s_logger.warn("Timed Out", e); + return false; + } } @Override public boolean visit(final DhcpSubNetRules subnet) throws ResourceUnavailableException { - return false; + final VirtualRouter router = subnet.getRouter(); + final Network network = subnet.getNetwork(); + final NicIpAliasVO nicAlias = subnet.getNicAlias(); + final String routerAliasIp = subnet.getRouterAliasIp(); + + final Commands cmds = new Commands(Command.OnError.Stop); + + final List<IpAliasTO> ipaliasTo = new ArrayList<IpAliasTO>(); + ipaliasTo.add(new IpAliasTO(routerAliasIp, nicAlias.getNetmask(), nicAlias.getAliasCount().toString())); + + subnet.createIpAlias(router, ipaliasTo, nicAlias.getNetworkId(), cmds); + + //also add the required configuration to the dnsmasq for supporting dhcp and dns on the new ip. + subnet.configDnsMasq(router, network, cmds); + + return _applianceManager.sendCommandsToRouter(router, cmds); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/12b0d188/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java ---------------------------------------------------------------------- diff --git a/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java b/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java index 318f7e2..1d0c9b3 100644 --- a/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java +++ b/server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java @@ -110,9 +110,15 @@ public class BasicNetworkTopology implements NetworkTopology { } @Override + public boolean setupDhcpForPvlan(final boolean add, final DomainRouterVO router, final Long hostId, final NicProfile nic) throws ResourceUnavailableException { + throw new CloudRuntimeException("setupDhcpForPvlan not implemented in Basic Network Topology."); + } + + @Override public boolean configDhcpForSubnet(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final List<DomainRouterVO> routers) throws ResourceUnavailableException { - return false; + + throw new CloudRuntimeException("configDhcpForSubnet not implemented in Basic Network Topology."); } @Override