diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 5528f792759..0d812a27df4 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1351,7 +1351,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian new Pair(publicNetwork, sourceNatIp)); //don't start the router as we are holding the network lock that needs to be released at the end of router allocation DomainRouterVO router = deployRouter(owner, dest, plan, params, isRedundant, vrProvider, offeringId, - null, networks, false); + null, networks, false, null); _routerDao.addRouterToGuestNetwork(router, guestNetwork); routers.add(router); @@ -1369,7 +1369,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian protected DomainRouterVO deployRouter(Account owner, DeployDestination dest, DeploymentPlan plan, Map params, boolean isRedundant, VirtualRouterProvider vrProvider, long svcOffId, - Long vpcId, List> networks, boolean startRouter) throws ConcurrentOperationException, + Long vpcId, List> networks, boolean startRouter, List supportedHypervisors) throws ConcurrentOperationException, InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException { @@ -1382,12 +1382,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian // Router is the network element, we don't know the hypervisor type yet. // Try to allocate the domR twice using diff hypervisors, and when failed both times, throw the exception up - List supportedHypervisors = getSupportedHypervisors(dest, plan); + List hypervisors = getHypervisors(dest, plan, supportedHypervisors); int allocateRetry = 0; int startRetry = 0; DomainRouterVO router = null; - for (Iterator iter = supportedHypervisors.iterator();iter.hasNext();) { + for (Iterator iter = hypervisors.iterator(); iter.hasNext();) { HypervisorType hType = iter.next(); try { s_logger.debug("Allocating the domR with the hypervisor type " + hType); @@ -1446,33 +1446,44 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } - protected List getSupportedHypervisors(DeployDestination dest, DeploymentPlan plan) throws InsufficientServerCapacityException { - List supportedHypervisors = new ArrayList(); + protected List getHypervisors(DeployDestination dest, DeploymentPlan plan, + List supportedHypervisors) throws InsufficientServerCapacityException { + List hypervisors = new ArrayList(); HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId()); if (defaults != HypervisorType.None) { - supportedHypervisors.add(defaults); + hypervisors.add(defaults); } if (dest.getCluster() != null) { if (dest.getCluster().getHypervisorType() == HypervisorType.Ovm) { - supportedHypervisors.add(getClusterToStartDomainRouterForOvm(dest.getCluster().getPodId())); + hypervisors.add(getClusterToStartDomainRouterForOvm(dest.getCluster().getPodId())); } else { - supportedHypervisors.add(dest.getCluster().getHypervisorType()); + hypervisors.add(dest.getCluster().getHypervisorType()); } } else { - supportedHypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, + hypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, plan.getPodId()); } - if (supportedHypervisors.isEmpty()) { + //keep only elements defined in supported hypervisors + StringBuilder hTypesStr = new StringBuilder(); + if (supportedHypervisors != null && !supportedHypervisors.isEmpty()) { + hypervisors.retainAll(supportedHypervisors); + for (HypervisorType hType : supportedHypervisors) { + hTypesStr.append(hType).append(" "); + } + } + + if (hypervisors.isEmpty()) { + String errMsg = (hTypesStr.capacity() > 0) ? "supporting hypervisors " + hTypesStr.toString() : ""; if (plan.getPodId() != null) { throw new InsufficientServerCapacityException("Unable to create virtual router, " + - "there are no clusters in the pod ", Pod.class, plan.getPodId()); + "there are no clusters in the pod " + errMsg, Pod.class, plan.getPodId()); } throw new InsufficientServerCapacityException("Unable to create virtual router, " + - "there are no clusters in the zone ", DataCenter.class, dest.getDataCenter().getId()); + "there are no clusters in the zone " + errMsg, DataCenter.class, dest.getDataCenter().getId()); } - return supportedHypervisors; + return hypervisors; } protected List> createRouterNetworks(Account owner, boolean isRedundant, diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index 98613b86a06..2d4d0bfb8b7 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -318,7 +318,8 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian List> networks = createVpcRouterNetworks(owner, isRedundant, plan, new Pair(true, sourceNatIp), vpcId); DomainRouterVO router = - super.deployRouter(owner, dest, plan, params, isRedundant, vrProvider, svcOffId, vpcId, networks, true); + super.deployRouter(owner, dest, plan, params, isRedundant, vrProvider, svcOffId, vpcId, networks, true, + _vpcMgr.getSupportedVpcHypervisors()); return router; } diff --git a/server/src/com/cloud/network/vpc/VpcManager.java b/server/src/com/cloud/network/vpc/VpcManager.java index 553891ceb41..14fdbe933af 100644 --- a/server/src/com/cloud/network/vpc/VpcManager.java +++ b/server/src/com/cloud/network/vpc/VpcManager.java @@ -24,6 +24,7 @@ import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.IpAddress; import com.cloud.network.Network; import com.cloud.network.Network.Service; @@ -136,4 +137,10 @@ public interface VpcManager extends VpcService{ */ void validateNtwkOffForVpc(NetworkOffering guestNtwkOff, List supportedSvcs); + + /** + * @return + */ + List getSupportedVpcHypervisors(); + } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index e06c843f8d6..f4c47ed9c49 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -54,6 +54,7 @@ import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.UnsupportedServiceException; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.IPAddressVO; import com.cloud.network.IpAddress; import com.cloud.network.Network; @@ -1954,5 +1955,13 @@ public class VpcManagerImpl implements VpcManager, Manager{ return _ntwkMgr.updateGuestNetwork(networkId, name, displayText, callerAccount, callerUser, domainSuffix, ntwkOffId, changeCidr); - } + } + + @Override + public List getSupportedVpcHypervisors() { + List hTypes = new ArrayList(); + hTypes.add(HypervisorType.XenServer); + hTypes.add(HypervisorType.VMware); + return hTypes; + } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 051791fc112..f1f32c37a92 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -33,6 +33,7 @@ import javax.naming.ConfigurationException; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; +import org.apache.tools.ant.taskdefs.Length.When; import com.cloud.acl.ControlledEntity.ACLType; import com.cloud.agent.AgentManager; @@ -128,6 +129,7 @@ import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerVMMapDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkServiceMapDao; +import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.rules.FirewallManager; @@ -139,6 +141,7 @@ import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupManager; import com.cloud.network.security.dao.SecurityGroupDao; import com.cloud.network.security.dao.SecurityGroupVMMapDao; +import com.cloud.network.vpc.VpcManager; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offering.ServiceOffering; @@ -352,7 +355,10 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager protected VolumeHostDao _volumeHostDao; @Inject ResourceTagDao _resourceTagDao; - + @Inject + PhysicalNetworkDao _physicalNetworkDao; + @Inject + VpcManager _vpcMgr; protected ScheduledExecutorService _executor = null; protected int _expungeInterval; @@ -2185,6 +2191,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager // Verify that caller can perform actions in behalf of vm owner _accountMgr.checkAccess(caller, null, true, owner); + List vpcSupportedHTypes = _vpcMgr.getSupportedVpcHypervisors(); if (networkIdList == null || networkIdList.isEmpty()) { NetworkVO defaultNetwork = null; @@ -2227,7 +2234,15 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (network == null) { throw new InvalidParameterValueException("Unable to find network by id " + networkIdList.get(0).longValue()); } + if (network.getVpcId() != null) { + //Only XenServer and VmWare hypervisors are supported for vpc networks + if (!vpcSupportedHTypes.contains(template.getHypervisorType())) { + throw new InvalidParameterValueException("Can't create vm from template with hypervisor " + + template.getHypervisorType() + " in vpc network " + network); + } + } + _networkMgr.checkNetworkPermissions(owner, network); //don't allow to use system networks