CLOUDSTACK-3357: dnsmasq on vpc-routervm

This commit is contained in:
Daan Hoogland 2013-07-08 18:27:20 +02:00 committed by Chip Childers
parent 7f2c659630
commit b903262df5
4 changed files with 223 additions and 15 deletions

View File

@ -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.
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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>