Updated Branches: refs/heads/master 7f2c65963 -> b903262df
CLOUDSTACK-3357: dnsmasq on vpc-routervm Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/b903262d Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/b903262d Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/b903262d Branch: refs/heads/master Commit: b903262df5e2ff5d174859ce28abae75c4689f0c Parents: 7f2c659 Author: Daan Hoogland <dhoogl...@schubergphilis.com> Authored: Mon Jul 8 18:27:20 2013 +0200 Committer: Chip Childers <chip.child...@gmail.com> Committed: Thu Jul 11 14:33:20 2013 +0100 ---------------------------------------------------------------------- .../VirtualNetworkApplianceManagerImpl.java | 27 ++++- .../VpcVirtualNetworkApplianceManagerImpl.java | 70 +++++++++++-- ...cVirtualNetworkApplianceManagerImplTest.java | 100 +++++++++++++++++++ server/test/resources/VpcVirtNetAppContext.xml | 41 ++++++++ 4 files changed, 223 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b903262d/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 index 8d73941..ed10369 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1322,7 +1322,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } } - + protected class CheckRouterTask implements Runnable { public CheckRouterTask() { @@ -1588,6 +1588,12 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException { + if(s_logger.isTraceEnabled()) { + s_logger.trace("deployRouter(" + owner.getAccountName() + ", " + dest.getHost() + ", " + plan.toString() + ", " + params.toString() + + ", " + isRedundant + ", " + vrProvider.getUuid() + ", " + svcOffId + ", " + vpcId + + ", list_of_" + networks.size() + "networks, " + startRouter + ", " + supportedHypervisors + ")"); + } + ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(svcOffId); // Router is the network element, we don't know the hypervisor type yet. @@ -1863,7 +1869,11 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V private DomainRouterVO startVirtualRouter(DomainRouterVO router, User user, Account caller, Map<Param, Object> params) throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { - + + if(s_logger.isTraceEnabled()) { + s_logger.trace("startVirtualRouter(" + router.getHostName() + ", " + user.getUsername() + ", " + caller.getAccountName() + ", " + params.toString() + ")"); + } + if (router.getRole() != Role.VIRTUAL_ROUTER || !router.getIsRedundantRouter()) { return this.start(router, user, caller, params, null); } @@ -2493,7 +2503,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V activeIpAliasTOs.add(new IpAliasTO(aliasVO.getIp4Address(), aliasVO.getNetmask(), aliasVO.getAliasCount().toString())); } if (revokedIpAliasTOs.size() != 0 || activeIpAliasTOs.size() != 0){ - createDeleteIpAliasCommand(router, revokedIpAliasTOs, activeIpAliasTOs, guestNetworkId, cmds); + createDeleteIpAliasCommand(router, revokedIpAliasTOs, activeIpAliasTOs, guestNetworkId, cmds); configDnsMasq(router, _networkDao.findById(guestNetworkId), cmds); } @@ -2888,6 +2898,9 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V public boolean applyDhcpEntry(Network network, final NicProfile nic, VirtualMachineProfile<UserVm> profile, DeployDestination dest, List<DomainRouterVO> routers) throws ResourceUnavailableException { + if(s_logger.isTraceEnabled()) { + s_logger.trace("applyDhcpEntry(" + network.getCidr() + ", " + nic.getMacAddress() + ", " + profile.getUuid() + ", " + dest.getHost() + ", " + routers + ")"); + } _userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine()); final VirtualMachineProfile<UserVm> updatedProfile = profile; @@ -3429,6 +3442,9 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } private void configDnsMasq(VirtualRouter router, Network network, Commands cmds) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("configDnsMasq(" + router.getHostName() + ", " + network.getNetworkDomain() + ", " + cmds + ")"); + } DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); List<NicIpAliasVO> ipAliasVOList = _nicIpAliasDao.listByNetworkIdAndState(network.getId(), NicIpAlias.state.active); List<DnsmasqTO> ipList = new ArrayList<DnsmasqTO>(); @@ -3443,6 +3459,9 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V ipList.add(new DnsmasqTO(router_guest_nic.getIp4Address(),router_guest_nic.getGateway(),router_guest_nic.getNetmask(), startIpOfSubnet)); for (NicIpAliasVO ipAliasVO : ipAliasVOList) { DnsmasqTO dnsmasqTO = new DnsmasqTO(ipAliasVO.getIp4Address(), ipAliasVO.getGateway(), ipAliasVO.getNetmask(), ipAliasVO.getStartIpOfSubnet()); + if (s_logger.isTraceEnabled()) { + s_logger.trace("configDnsMasq : adding ip {" + dnsmasqTO.getGateway() + ", " + dnsmasqTO.getNetmask() + ", " + dnsmasqTO.getRouterIp() + ", " + dnsmasqTO.getStartIpOfSubnet() + "}"); + } ipList.add(dnsmasqTO); ipAliasVO.setVmId(router.getId()); } @@ -3453,7 +3472,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(network.getId(), router.getId())); dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); - cmds.addCommand("dhcpConfig" ,dnsMasqConfigCmd); + cmds.addCommand("dnsMasqConfig" ,dnsMasqConfigCmd); //To change body of created methods use File | Settings | File Templates. } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b903262d/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index 7115499..51c072c 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -40,12 +40,14 @@ import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.UnPlugNicAnswer; import com.cloud.agent.api.UnPlugNicCommand; +import com.cloud.agent.api.routing.DnsMasqConfigCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.SetNetworkACLCommand; import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.routing.SetStaticRouteCommand; import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; +import com.cloud.agent.api.to.DnsmasqTO; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.NetworkACLTO; import com.cloud.agent.api.to.NicTO; @@ -170,6 +172,9 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian public List<DomainRouterVO> deployVirtualRouterInVpc(Vpc vpc, DeployDestination dest, Account owner, Map<Param, Object> params) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { + if(s_logger.isTraceEnabled()) { + s_logger.trace("deployVirtualRouterInVpc(" + vpc.getName() +", "+dest.getHost()+", "+owner.getAccountName()+", "+params.toString()+")"); + } List<DomainRouterVO> routers = findOrDeployVirtualRouterInVpc(vpc, dest, owner, params); @@ -247,7 +252,9 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian @Override public boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { - + if (s_logger.isTraceEnabled()) { + s_logger.trace("addVpcRouterToGuestNetwork(" + router.getUuid() + ", " + network.getCidr() + ", " + isRedundant + ")"); + } if (network.getTrafficType() != TrafficType.Guest) { s_logger.warn("Network " + network + " is not of type " + TrafficType.Guest); return false; @@ -319,7 +326,10 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian Long vpcId, PublicIp sourceNatIp) throws ConcurrentOperationException, InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException { - + if(s_logger.isTraceEnabled()) { + s_logger.trace("deployVpcRouter(" + owner.getAccountName() + ", " + dest.getHost() + ", " + plan.toString() + ", " + params.toString() + + ", " + isRedundant + ", " + vrProvider.getUuid() + ", " + svcOffId + ", " + vpcId + ", " + sourceNatIp + ")"); + } List<Pair<NetworkVO, NicProfile>> networks = createVpcRouterNetworks(owner, isRedundant, plan, new Pair<Boolean, PublicIp>(true, sourceNatIp), vpcId); DomainRouterVO router = @@ -769,12 +779,15 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian @Override public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile<DomainRouterVO> profile) { DomainRouterVO router = profile.getVirtualMachine(); + if(s_logger.isTraceEnabled()) { + s_logger.trace("finalizeCommandsOnStart(" + cmds + ", " + profile.getHostName() + ")"); + } boolean isVpc = (router.getVpcId() != null); if (!isVpc) { return super.finalizeCommandsOnStart(cmds, profile); } - + //1) FORM SSH CHECK COMMAND NicProfile controlNic = getControlNic(profile); if (controlNic == null) { @@ -783,7 +796,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian } finalizeSshAndVersionAndNetworkUsageOnStart(cmds, profile, router, controlNic); - + //2) FORM PLUG NIC COMMANDS List<Pair<Nic, Network>> guestNics = new ArrayList<Pair<Nic, Network>>(); List<Pair<Nic, Network>> publicNics = new ArrayList<Pair<Nic, Network>>(); @@ -936,16 +949,44 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian //Add network usage commands cmds.addCommands(usageCmds); - + configDnsMasq(router, cmds); + return true; } - - + + protected void configDnsMasq(VirtualRouter router, Commands cmds) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("configDnsMasq(" + router.getHostName() + ", " + cmds + ")"); + } + VpcVO vpc = _vpcDao.findById(router.getVpcId()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); + List<DnsmasqTO> ipList = new ArrayList<DnsmasqTO>(); + + String cidr = vpc.getCidr(); + String[] cidrPair = cidr.split("\\/"); + String cidrAddress = cidrPair[0]; + long cidrSize = Long.parseLong(cidrPair[1]); + String startIpOfSubnet = NetUtils.getIpRangeStartIpFromCidr(cidrAddress, cidrSize); + DnsmasqTO dnsmasqTO = new DnsmasqTO(router.getPrivateIpAddress(), router.getPublicIpAddress(), NetUtils.getCidrNetmask(cidrSize), startIpOfSubnet); + ipList.add(dnsmasqTO); + + DnsMasqConfigCommand dnsMasqConfigCmd = new DnsMasqConfigCommand(vpc.getNetworkDomain(),ipList, dcVo.getDns1(), dcVo.getDns2(), dcVo.getInternalDns1(), dcVo.getInternalDns2()); + dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); + dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getPublicIpAddress()); + dnsMasqConfigCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand("dnsMasqConfig" ,dnsMasqConfigCmd); + //To change body of created methods use File | Settings | File Templates. + } + + @Override protected void finalizeNetworkRulesForNetwork(Commands cmds, DomainRouterVO router, Provider provider, Long guestNetworkId) { - + if(s_logger.isTraceEnabled()) { + s_logger.trace("finalizing network config for "+ router.getHostName()); + } super.finalizeNetworkRulesForNetwork(cmds, router, provider, guestNetworkId); - if (router.getVpcId() != null) { if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.NetworkACL, Provider.VPCVirtualRouter)) { List<NetworkACLItemVO> networkACLs = _networkACLMgr.listNetworkACLItems(guestNetworkId); @@ -955,6 +996,10 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian createNetworkACLsCommands(networkACLs, router, cmds, guestNetworkId, false); } } + + if(s_logger.isDebugEnabled()) { + s_logger.debug("setup the vpc domain on router " + router.getHostName()); + } } } @@ -999,7 +1044,10 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian */ protected boolean setupVpcPrivateNetwork(VirtualRouter router, boolean add, NicProfile privateNic) throws ResourceUnavailableException { - + if(s_logger.isTraceEnabled()) { + s_logger.trace("deployVpcRouter(" + router.getHostName() + ", " + add + ", " + privateNic.getMacAddress() + ")"); + } + if (router.getState() == State.Running) { PrivateIpVO ipVO = _privateIpDao.findByIpAndSourceNetworkId(privateNic.getNetworkId(), privateNic.getIp4Address()); Network network = _networkDao.findById(privateNic.getNetworkId()); @@ -1011,7 +1059,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian privateIps.add(ip); Commands cmds = new Commands(OnError.Stop); createVpcAssociatePrivateIPCommands(router, privateIps, cmds, add); - + if (sendCommandsToRouter(router, cmds)) { s_logger.debug("Successfully applied ip association for ip " + ip + " in vpc network " + network); return true; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b903262d/server/test/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImplTest.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImplTest.java b/server/test/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImplTest.java new file mode 100644 index 0000000..04a3601 --- /dev/null +++ b/server/test/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImplTest.java @@ -0,0 +1,100 @@ +// 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 static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; + +import org.apache.log4j.Logger; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.cloud.agent.AgentManager.OnError; +import com.cloud.agent.api.routing.DnsMasqConfigCommand; +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.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.NetworkManager; +import com.cloud.network.router.VirtualRouter.RedundantState; +import com.cloud.network.vpc.VpcVO; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.NicVO; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations="classpath:/VpcVirtNetAppContext.xml") +public class VpcVirtualNetworkApplianceManagerImplTest { + private static final Logger s_logger = Logger.getLogger(VpcVirtualNetworkApplianceManagerImplTest.class); + + @Mock DataCenterDao _dcDao; + @Mock VpcDao _vpcDao; + @Mock VirtualRouter router; + @Mock NicDao _nicDao; + @Mock DomainRouterDao _routerDao; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + } + + @Test + public void testConfigDnsMasq() { + VpcVirtualNetworkApplianceManagerImpl vpcVirtNetAppMgr = new VpcVirtualNetworkApplianceManagerImpl(); + vpcVirtNetAppMgr._vpcDao = _vpcDao; + vpcVirtNetAppMgr._dcDao = _dcDao; + vpcVirtNetAppMgr._nicDao = _nicDao; + vpcVirtNetAppMgr._routerDao = _routerDao; + when(router.getId()).thenReturn(1L); + when(router.getVpcId()).thenReturn(1L); + when(router.getDataCenterId()).thenReturn(1L); + VpcVO vpc = new VpcVO(1L,"bla","bla",1L,1L,1L,"10.0.0.0/8","blieb.net"); + when( _vpcDao.findById(1L)).thenReturn(vpc); + DataCenterVO dcVo = new DataCenterVO(1L,"dc","dc","8.8.8.8",null,null,null,"10.0.0.0/8","bla.net",new Long(1L),NetworkType.Advanced,null,".net"); + when( _dcDao.findById(1L) ).thenReturn(dcVo); + DomainRouterVO routerVo = new DomainRouterVO(1L,1L,1L,"brr",1L,HypervisorType.Any,1L,1L,1L,false,0,false,RedundantState.MASTER,false,false,1L); + when( _routerDao.findById(1L)).thenReturn(routerVo); +// when( vpcVirtNetAppMgr.getRouterControlIp(1L)).thenReturn("10.0.0.1"); + when( router.getInstanceName()).thenReturn("r-vm-1"); + when( router.getPublicIpAddress()).thenReturn("11.11.11.11"); + when( _nicDao.listByVmId(1L)).thenReturn(new ArrayList<NicVO>()); + NetworkManager netMgr = mock(NetworkManager.class); + vpcVirtNetAppMgr._networkMgr = netMgr; + + Commands cmds = new Commands(OnError.Stop); + + vpcVirtNetAppMgr.configDnsMasq(router, cmds); + Assert.assertEquals("expected one command",1,cmds.size()); + + DnsMasqConfigCommand cmd = cmds.getCommand(DnsMasqConfigCommand.class); + } + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b903262d/server/test/resources/VpcVirtNetAppContext.xml ---------------------------------------------------------------------- diff --git a/server/test/resources/VpcVirtNetAppContext.xml b/server/test/resources/VpcVirtNetAppContext.xml new file mode 100644 index 0000000..f8a8aa4 --- /dev/null +++ b/server/test/resources/VpcVirtNetAppContext.xml @@ -0,0 +1,41 @@ +<!-- 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. --> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" + xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/tx + http://www.springframework.org/schema/tx/spring-tx-3.0.xsd + http://www.springframework.org/schema/aop + http://www.springframework.org/schema/aop/spring-aop-3.0.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context-3.0.xsd"> + + <context:annotation-config /> + + <!-- @DB support --> +<!-- + <bean id="vpcVirtualNetworkApplianceManager" class="com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl" /> + <bean id="vpcDao" class="com.cloud.network.vpc.dao.VpcDaoImpl" /> + <bean id="nicDao" class="com.cloud.vm.dao.NicDaoImpl" /> + <bean id="dcDao" class="com.cloud.dc.dao.DataCenterDaoImpl" /> + --> + <bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" /> + <bean id="instantiatePostProcessor" class="com.cloud.utils.component.ComponentInstantiationPostProcessor"> + <property name="Interceptors"> + <list> + <ref bean="transactionContextBuilder" /> + </list> + </property> + </bean> + + </beans>