From d2f92f1c768041b1d41c3733fb23dc5bcc52fb4a Mon Sep 17 00:00:00 2001 From: alena Date: Tue, 15 Mar 2011 14:35:28 -0700 Subject: [PATCH] bug 8973: Create Virtual Guest network as a part of deployVm if corresponding networkOffering has availability=Required and no networkIds are specified status 8973: resolved fixed --- api/src/com/cloud/network/NetworkService.java | 1 - .../src/com/cloud/network/NetworkManager.java | 4 +- .../com/cloud/network/NetworkManagerImpl.java | 18 +++++ .../offerings/dao/NetworkOfferingDao.java | 4 ++ .../offerings/dao/NetworkOfferingDaoImpl.java | 19 ++++++ .../src/com/cloud/vm/UserVmManagerImpl.java | 68 +++++++++++++++---- 6 files changed, 99 insertions(+), 15 deletions(-) diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index d6c86f61c0f..1af0bb60529 100644 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -70,5 +70,4 @@ public interface NetworkService { Map> getZoneCapabilities(long zoneId); Map> getNetworkCapabilities(long networkId); - } diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index a83217c05e3..3de177d0a42 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -29,6 +29,7 @@ import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network.Capability; +import com.cloud.network.Network.GuestIpType; import com.cloud.network.Network.Service; import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; @@ -42,7 +43,6 @@ import com.cloud.user.AccountVO; import com.cloud.utils.Pair; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; -import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; @@ -185,4 +185,6 @@ public interface NetworkManager extends NetworkService { boolean startNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; String getIpOfNetworkElementInVirtualNetwork(long accountId, long dataCenterId); + + List listNetworksForAccount(long accountId, long zoneId, GuestIpType guestType, Boolean isDefault); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 4dcd008c656..02ad16eb5bd 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -2642,4 +2642,22 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return null; } } + + @Override + public List listNetworksForAccount(long accountId, long zoneId, GuestIpType guestType, Boolean isDefault) { + List accountNetworks = new ArrayList(); + List zoneNetworks = _networksDao.listByZone(zoneId); + + for (NetworkVO network : zoneNetworks) { + NetworkOfferingVO no = _networkOfferingDao.findById(network.getNetworkOfferingId()); + if (!no.isSystemOnly()) { + if (network.isShared() || !_networksDao.listBy(accountId, network.getId()).isEmpty()) { + if ((guestType == null || guestType == network.getGuestType()) && (isDefault == null || isDefault == network.isDefault)) { + accountNetworks.add(network); + } + } + } + } + return accountNetworks; + } } diff --git a/server/src/com/cloud/offerings/dao/NetworkOfferingDao.java b/server/src/com/cloud/offerings/dao/NetworkOfferingDao.java index 9195c621c59..2c42412db5b 100644 --- a/server/src/com/cloud/offerings/dao/NetworkOfferingDao.java +++ b/server/src/com/cloud/offerings/dao/NetworkOfferingDao.java @@ -5,6 +5,8 @@ package com.cloud.offerings.dao; import java.util.List; +import com.cloud.network.Network.GuestIpType; +import com.cloud.network.Networks.TrafficType; import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.utils.db.GenericDao; @@ -38,4 +40,6 @@ public interface NetworkOfferingDao extends GenericDao List listByAvailability(Availability availability, boolean isSystem); + List listByTrafficTypeAndGuestType(boolean isSystem, TrafficType trafficType, GuestIpType guestType); + } diff --git a/server/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java b/server/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java index fe62f233ea1..cabdd662247 100644 --- a/server/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java +++ b/server/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java @@ -11,6 +11,8 @@ import javax.persistence.EntityExistsException; import org.apache.log4j.Logger; +import com.cloud.network.Network.GuestIpType; +import com.cloud.network.Networks.TrafficType; import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.utils.db.DB; @@ -26,6 +28,7 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase NameSearch; final SearchBuilder SystemOfferingSearch; final SearchBuilder AvailabilitySearch; + final SearchBuilder TrafficTypeGuestTypeSearch; protected NetworkOfferingDaoImpl() { super(); @@ -42,6 +45,12 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase listByTrafficTypeAndGuestType(boolean isSystem, TrafficType trafficType, GuestIpType guestType) { + SearchCriteria sc = TrafficTypeGuestTypeSearch.create(); + sc.setParameters("trafficType", trafficType); + sc.setParameters("guestType", guestType); + sc.setParameters("isSystem", isSystem); + return listBy(sc, null); + } + } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 38e8ba20920..31441c467a5 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -123,10 +123,12 @@ import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.rules.RulesManager; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.vpn.PasswordResetElement; +import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offering.ServiceOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.org.Cluster; import com.cloud.server.Criteria; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; @@ -199,7 +201,6 @@ import com.cloud.vm.dao.InstanceGroupVMMapDao; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.UserVmDetailsDao; -import com.cloud.org.Cluster; @Local(value={UserVmManager.class, UserVmService.class}) public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager { @@ -1992,22 +1993,57 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager //Verify that caller can perform actions in behalf of vm owner _accountMgr.checkAccess(caller, owner); - //if no network is passed in, find Account specific Guest Virtual network if (networkIdList == null || networkIdList.isEmpty()) { - List networks = _networkDao.listByOwner(owner.getId()); - NetworkVO guestVirtualNetwork = null; - for (NetworkVO network : networks) { - if (!network.isShared() && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == GuestIpType.Virtual) { - guestVirtualNetwork = network; - break; + NetworkVO defaultNetwork = null; + + //if no network is passed in + //1) Check if default virtual network offering has Availability=Required. If it's true, search for corresponding network + // * if network is found, use it. If more than 1 virtual network is found, throw an error + // * if network is not found, create a new one and use it + //2) If Availability=Optional, search for default networks for the account. If it's more than 1, throw an error. + // If it's 0, and there are no default direct networks, create default Guest Virtual network + + List defaultVirtualOffering = _networkOfferingDao.listByTrafficTypeAndGuestType(false, TrafficType.Guest, GuestIpType.Virtual); + + if (defaultVirtualOffering.get(0).getAvailability() == Availability.Required) { + //get Virtual netowrks + List virtualNetworks = _networkMgr.listNetworksForAccount(owner.getId(), zone.getId(), GuestIpType.Virtual, true); + + if (virtualNetworks.isEmpty()) { + s_logger.debug("Creating default Virtual network for account " + owner + " as a part of deployVM process"); + Network newNetwork = _networkMgr.createNetwork(defaultVirtualOffering.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", false, null, zone.getId(), null, null, null, null, owner, false); + defaultNetwork = _networkDao.findById(newNetwork.getId()); + } else if (virtualNetworks.size() > 1) { + throw new InvalidParameterValueException("More than 1 default Virtaul networks are found for account " + owner + "; please specify networkIds"); + } else { + defaultNetwork = virtualNetworks.get(0); + } + } else { + List defaultNetworks = _networkMgr.listNetworksForAccount(owner.getId(), zone.getId(), null, true); + if (defaultNetworks.isEmpty()) { + if (defaultVirtualOffering.get(0).getAvailability() == Availability.Optional) { + s_logger.debug("Creating default Virtual network for account " + owner + " as a part of deployVM process"); + Network newNetwork = _networkMgr.createNetwork(defaultVirtualOffering.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network", false, null, zone.getId(), null, null, null, null, owner, false); + defaultNetwork = _networkDao.findById(newNetwork.getId()); + } else { + throw new InvalidParameterValueException("Unable to find default networks for account " + owner); + } + + } else if (defaultNetworks.size() > 1) { + throw new InvalidParameterValueException("More than 1 default network is found for accoun " + owner); + } else { + defaultNetwork = defaultNetworks.get(0); } } - if (guestVirtualNetwork == null) { - throw new InvalidParameterValueException("Unable to find Guest Virtual network for account id=" + owner.getId() + "; please specify networkId(s)"); + //Check that network offering doesn't have Availability=Unavailable + NetworkOffering networkOffering = _configMgr.getNetworkOffering(defaultNetwork.getNetworkOfferingId()); + + if (networkOffering.getAvailability() == Availability.Unavailable) { + throw new InvalidParameterValueException("Unable to find default network; please specify networkOfferingIds"); } - networkList.add(guestVirtualNetwork); + networkList.add(defaultNetwork); } else { @@ -2034,6 +2070,13 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } } + //check that corresponding offering is available + NetworkOffering networkOffering = _configMgr.getNetworkOffering(network.getNetworkOfferingId()); + + if (networkOffering.getAvailability() == Availability.Unavailable) { + throw new InvalidParameterValueException("Network id=" + network.getId() + " can't be used; corresponding network offering is " + Availability.Unavailable); + } + if (requiredOfferingId != null && network.getNetworkOfferingId() == requiredOfferingId.longValue()) { requiredNetworkOfferingIsPresent = true; } @@ -2045,8 +2088,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (requiredOfferingId != null && !requiredNetworkOfferingIsPresent) { throw new InvalidParameterValueException("Network created from the network offering id=" + requiredOfferingId + " is required; change network offering availability to be Optional to relax this requirement"); } - - } return createVirtualMachine(zone, serviceOffering, template, hostName, displayName, owner, diskOfferingId, @@ -2902,4 +2943,5 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager UserVmVO migratedVm = _itMgr.migrate((UserVmVO)vm, srcHostId, dest); return migratedVm; } + }