diff --git a/api/src/com/cloud/network/element/NetworkElement.java b/api/src/com/cloud/network/element/NetworkElement.java index fb620a7babf..7b6763fbdcd 100644 --- a/api/src/com/cloud/network/element/NetworkElement.java +++ b/api/src/com/cloud/network/element/NetworkElement.java @@ -94,4 +94,5 @@ public interface NetworkElement extends Adapter { * @throws ResourceUnavailableException */ boolean applyRules(Network network, List rules) throws ResourceUnavailableException; + } diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 7036dc4ebde..e7095585d93 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -76,6 +76,7 @@ + diff --git a/server/src/com/cloud/network/element/DhcpElement.java b/server/src/com/cloud/network/element/DhcpElement.java new file mode 100644 index 00000000000..8203b1d1205 --- /dev/null +++ b/server/src/com/cloud/network/element/DhcpElement.java @@ -0,0 +1,151 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.network.element; + +import java.util.List; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.dc.DataCenter; +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientNetworkCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.NetworkManager; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.router.DomainRouterManager; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.service.Providers; +import com.cloud.offering.NetworkOffering; +import com.cloud.offering.NetworkOffering.GuestIpType; +import com.cloud.uservm.UserVm; +import com.cloud.utils.component.AdapterBase; +import com.cloud.utils.component.Inject; +import com.cloud.utils.net.Ip; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.UserVmManager; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.Type; +import com.cloud.vm.VirtualMachineProfile; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.UserVmDao; + + +@Local(value=NetworkElement.class) +public class DhcpElement extends AdapterBase implements NetworkElement { + private static final Logger s_logger = Logger.getLogger(DhcpElement.class); + + @Inject NetworkDao _networkConfigDao; + @Inject NetworkManager _networkMgr; + @Inject DomainRouterManager _routerMgr; + @Inject UserVmManager _userVmMgr; + @Inject UserVmDao _userVmDao; + @Inject DomainRouterDao _routerDao; + + private boolean canHandle(GuestIpType ipType, DeployDestination dest) { + DataCenter dc = dest.getDataCenter(); + String provider = dc.getGatewayProvider(); + if (!dc.getDhcpProvider().equals(Providers.VirtualRouter)) { + return false; + } + return ((ipType == GuestIpType.Virtual && !provider.equals(Providers.VirtualRouter)) || (ipType == GuestIpType.Direct || ipType == GuestIpType.DirectPodBased)); + } + + @Override + public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException { + if (canHandle(offering.getGuestIpType(), dest)) { + DomainRouterVO router = _routerMgr.deployDhcp(guestConfig, dest, context.getAccount()); + if (router == null) { + throw new ResourceUnavailableException("Unable to deploy the router for " + guestConfig); + } + return true; + + } else { + return false; + } + } + + @Override + public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException { + if (canHandle(config.getGuestType(), dest)) { + if (config.getTrafficType() != TrafficType.Guest || vm.getType() != Type.User) { + s_logger.trace("DHCP only cares about guest network and User VMs"); + return false; + } + + if (vm.getType() != VirtualMachine.Type.User) { + return false; + } + + @SuppressWarnings("unchecked") + VirtualMachineProfile uservm = (VirtualMachineProfile)vm; + + return _routerMgr.addVirtualMachineIntoNetwork(config, nic, uservm, dest, context, true) != null; + } else { + return false; + } + } + + @Override + public boolean release(Network config, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) { + if (config.getTrafficType() != TrafficType.Guest || vm.getType() != Type.User) { + s_logger.trace("DHCP only cares about guest network and User VMs"); + return false; + } + return true; + } + + @Override + public boolean shutdown(Network config, ReservationContext context) throws ConcurrentOperationException { + if (config.getTrafficType() != TrafficType.Guest) { + s_logger.trace("DHCP only cares about guet network."); + return false; + } + DomainRouterVO router = _routerDao.findByNetworkConfiguration(config.getId()); + if (router == null) { + return true; + } + return _routerMgr.stopRouter(router.getId(), 1); + } + + protected DhcpElement() { + super(); + } + + @Override + public boolean applyRules(Network config, List rules) throws ResourceUnavailableException { + return true; + } + + @Override + public boolean associate(Network network, Ip ipAddress) throws ResourceUnavailableException { + return true; + } + + @Override + public boolean disassociate(Network network, Ip ipAddress) throws ResourceUnavailableException { + return true; + } +} diff --git a/server/src/com/cloud/network/element/DomainRouterElement.java b/server/src/com/cloud/network/element/DomainRouterElement.java index aa462f6564a..3f632a184f5 100644 --- a/server/src/com/cloud/network/element/DomainRouterElement.java +++ b/server/src/com/cloud/network/element/DomainRouterElement.java @@ -23,6 +23,7 @@ import javax.ejb.Local; import org.apache.log4j.Logger; +import com.cloud.dc.DataCenter; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -34,8 +35,11 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.dao.NetworkDao; import com.cloud.network.router.DomainRouterManager; import com.cloud.network.rules.FirewallRule; +import com.cloud.network.service.Providers; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.GuestIpType; +import com.cloud.offerings.NetworkOfferingVO; +import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.uservm.UserVm; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.Inject; @@ -57,41 +61,52 @@ public class DomainRouterElement extends AdapterBase implements NetworkElement { @Inject NetworkDao _networkConfigDao; @Inject NetworkManager _networkMgr; + @Inject NetworkOfferingDao _networkOfferingDao; @Inject DomainRouterManager _routerMgr; @Inject UserVmManager _userVmMgr; @Inject UserVmDao _userVmDao; @Inject DomainRouterDao _routerDao; + + private boolean canHandle(GuestIpType ipType, DeployDestination dest) { + DataCenter dc = dest.getDataCenter(); + String provider = dc.getGatewayProvider(); + return (ipType == GuestIpType.Virtual && provider.equals(Providers.VirtualRouter)); + } @Override public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException { - if (offering.getGuestIpType() != GuestIpType.Virtual) { - s_logger.trace("Not handling guest ip type = " + offering.getGuestIpType()); + if (canHandle(offering.getGuestIpType(), dest)) { + DomainRouterVO router = _routerMgr.deployVirtualRouter(guestConfig, dest, context.getAccount()); + if (router == null) { + throw new ResourceUnavailableException("Unable to deploy the router for " + guestConfig); + } + + return true; + } else { return false; } - - DomainRouterVO router = _routerMgr.deploy(guestConfig, dest, context.getAccount()); - if (router == null) { - throw new ResourceUnavailableException("Unable to deploy the router for " + guestConfig); - } - - return true; } @Override public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException { - if (config.getTrafficType() != TrafficType.Guest || vm.getType() != Type.User) { - s_logger.trace("Domain Router only cares about guest network and User VMs"); + if (canHandle(config.getGuestType(), dest)) { + if (config.getTrafficType() != TrafficType.Guest || vm.getType() != Type.User) { + s_logger.trace("Domain Router only cares about guest network and User VMs"); + return false; + } + + if (vm.getType() != VirtualMachine.Type.User) { + return false; + } + + @SuppressWarnings("unchecked") + VirtualMachineProfile uservm = (VirtualMachineProfile)vm; + + return _routerMgr.addVirtualMachineIntoNetwork(config, nic, uservm, dest, context, false) != null; + } else { return false; } - - if (vm.getType() != VirtualMachine.Type.User) { - return false; - } - - @SuppressWarnings("unchecked") - VirtualMachineProfile uservm = (VirtualMachineProfile)vm; - - return _routerMgr.addVirtualMachineIntoNetwork(config, nic, uservm, dest, context) != null; + } @Override @@ -100,8 +115,6 @@ public class DomainRouterElement extends AdapterBase implements NetworkElement { s_logger.trace("Domain Router only cares about guest network and User VMs"); return false; } - - return true; } diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java index f604b40bc01..ae8f0556e39 100644 --- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java @@ -169,8 +169,10 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { if (nic == null) { nic = new NicProfile(ReservationStrategy.Start, null, null, null, null); - } else { + } else if (nic.getIp4Address() != null){ nic.setStrategy(ReservationStrategy.Create); + } else { + nic.setStrategy(ReservationStrategy.Start); } if (nic.getMacAddress() == null) { diff --git a/server/src/com/cloud/network/router/DomainRouterManager.java b/server/src/com/cloud/network/router/DomainRouterManager.java index bb0cd05a426..38758f696fb 100644 --- a/server/src/com/cloud/network/router/DomainRouterManager.java +++ b/server/src/com/cloud/network/router/DomainRouterManager.java @@ -147,13 +147,15 @@ public interface DomainRouterManager extends Manager { DomainRouterVO getRouter(long accountId, long zoneId); DomainRouterVO getRouter(String publicIpAddress); - DomainRouterVO deploy(Network guestConfig, DeployDestination dest, Account owner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException; - + DomainRouterVO deployVirtualRouter(Network guestConfig, DeployDestination dest, Account owner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException; + + DomainRouterVO deployDhcp(Network guestConfig, DeployDestination dest, Account owner) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException; + RemoteAccessVpnVO startRemoteAccessVpn(RemoteAccessVpnVO vpnVO) throws ResourceUnavailableException; boolean addRemoveVpnUsers(RemoteAccessVpnVO vpnVO, List addUsers, List removeUsers); boolean deleteRemoteAccessVpn(RemoteAccessVpnVO vpnVO); - DomainRouterVO addVirtualMachineIntoNetwork(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException; + DomainRouterVO addVirtualMachineIntoNetwork(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context, Boolean startDhcp) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException; } diff --git a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java index f10a99ae2b2..34ba73972e7 100644 --- a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java +++ b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java @@ -2069,7 +2069,7 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute } @Override - public DomainRouterVO deploy(Network guestConfig, DeployDestination dest, Account owner) throws InsufficientCapacityException, StorageUnavailableException, ConcurrentOperationException, ResourceUnavailableException { + public DomainRouterVO deployVirtualRouter(Network guestConfig, DeployDestination dest, Account owner) throws InsufficientCapacityException, StorageUnavailableException, ConcurrentOperationException, ResourceUnavailableException { long dcId = dest.getDataCenter().getId(); if (s_logger.isDebugEnabled()) { @@ -2123,6 +2123,49 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute return _itMgr.start(router, null, _accountService.getSystemUser(), _accountService.getSystemAccount()); } + + @Override + public DomainRouterVO deployDhcp(Network guestConfig, DeployDestination dest, Account owner) throws InsufficientCapacityException, StorageUnavailableException, ConcurrentOperationException, ResourceUnavailableException { + long dcId = dest.getDataCenter().getId(); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Starting a dhcp for network configurations: dhcp=" + guestConfig + " in " + dest); + } + assert guestConfig.getState() == Network.State.Implemented || guestConfig.getState() == Network.State.Setup : "Network is not yet fully implemented: " + guestConfig; + assert guestConfig.getTrafficType() == TrafficType.Guest; + + DataCenterDeployment plan = new DataCenterDeployment(dcId); + + guestConfig = _networkConfigurationDao.lockRow(guestConfig.getId(), true); + if (guestConfig == null) { + throw new ConcurrentOperationException("Unable to get the lock on " + guestConfig); + } + + DomainRouterVO router = _routerDao.findByNetworkConfiguration(guestConfig.getId()); + if (router == null) { + long id = _routerDao.getNextInSequence(Long.class, "id"); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating the router " + id); + } + + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmControlNetwork); + NetworkOfferingVO controlOffering = offerings.get(0); + NetworkVO controlConfig = _networkMgr.setupNetworkConfiguration(_systemAcct, controlOffering, plan, null, null, false).get(0); + + List> networks = new ArrayList>(3); + NicProfile gatewayNic = new NicProfile(); + gatewayNic.setDefaultNic(true); + networks.add(new Pair((NetworkVO)guestConfig, gatewayNic)); + networks.add(new Pair(controlConfig, null)); + + router = new DomainRouterVO(id, _offering.getId(), VirtualMachineName.getRouterName(id, _instance), _template.getId(), _template.getGuestOSId(), owner.getDomainId(), owner.getId(), guestConfig.getId(), _offering.getOfferHA()); + router.setRole(Role.DHCP_USERDATA); + router = _itMgr.allocate(router, _template, _offering, networks, plan, owner); + } + + return _itMgr.start(router, null, _accountService.getSystemUser(), _accountService.getSystemAccount()); + } + @Override public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { StringBuilder buf = profile.getBootArgsBuilder(); @@ -2277,10 +2320,15 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute } @Override - public DomainRouterVO addVirtualMachineIntoNetwork(Network config, NicProfile nic, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException { + public DomainRouterVO addVirtualMachineIntoNetwork(Network config, NicProfile nic, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context, Boolean startDhcp) throws ConcurrentOperationException, InsufficientNetworkCapacityException, ResourceUnavailableException { DomainRouterVO router = _routerDao.findByNetworkConfiguration(config.getId()); try { - router = this.deploy(config, dest, profile.getOwner()); + if (startDhcp) { + router = this.deployDhcp(config, dest, profile.getOwner()); + } else { + router = this.deployVirtualRouter(config, dest, profile.getOwner()); + } + } catch (InsufficientNetworkCapacityException e) { throw e; } catch (InsufficientCapacityException e) { diff --git a/vmops.log.2010-12-06.gz b/vmops.log.2010-12-06.gz new file mode 100644 index 00000000000..d3a44dae78e Binary files /dev/null and b/vmops.log.2010-12-06.gz differ