region level VPC support

introduce 'RegionLevelVpc' as capability of 'Connectivity' service. Add
support for CreateVPCOffering to take the 'regionlevelvpc' as capability
of service 'connectivity'.

introduces new capability 'StretchedL2Subnet' for 'Connectivity'
service. Also add support to createNetworkOffering api to allow
StretchedL2Subnet capablity for the connectivity service.

adds check to ensure 'Connectivity' service provider supports
'StretchedL2Subnet' and 'RegionLevelVpc' capabilities when specified in
createNetworkOffering and createVpcOffering respectivley

enable ovs plug-in to support both StretchedL2Subnet and RegionLevelVpc
capabilities

make zone id optional parameter in createVpc, zone id can be null only
if vpc offfering supports region level VPC

in region level vpc, let the network/tier to be created in any zone of
the region

keep zoneid as required param for createVpc

skip external guest network guru if 'Connectivy' service is present in
network offering

fix build break in contrail manager

permit VM's to be created in different zone that in which network is
created if the network support streched L2 subnet

add integration tests for region level VPC

rebase to master

Conflicts:
	setup/db/db/schema-430to440.sql

Conflicts:
	api/src/org/apache/cloudstack/api/ApiConstants.java
	engine/schema/src/com/cloud/network/vpc/VpcVO.java
	setup/db/db/schema-430to440.sql
This commit is contained in:
Murali Reddy 2014-01-24 11:15:38 +05:30
parent c838f3abb8
commit d2d54a9463
28 changed files with 876 additions and 131 deletions

View File

@ -57,7 +57,7 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
public static final Service PortForwarding = new Service("PortForwarding");
public static final Service SecurityGroup = new Service("SecurityGroup");
public static final Service NetworkACL = new Service("NetworkACL", Capability.SupportedProtocols);
public static final Service Connectivity = new Service("Connectivity", Capability.DistributedRouter);
public static final Service Connectivity = new Service("Connectivity", Capability.DistributedRouter, Capability.RegionLevelVpc, Capability.StretchedL2Subnet);
private final String name;
private final Capability[] caps;
@ -187,6 +187,8 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
public static final Capability LbSchemes = new Capability("LbSchemes");
public static final Capability DhcpAccrossMultipleSubnets = new Capability("DhcpAccrossMultipleSubnets");
public static final Capability DistributedRouter = new Capability("DistributedRouter");
public static final Capability StretchedL2Subnet = new Capability("StretchedL2Subnet");
public static final Capability RegionLevelVpc = new Capability("RegionLevelVpc");
private final String name;
@ -337,4 +339,6 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
Long getNetworkACLId();
void setNetworkACLId(Long networkACLId);
boolean isStrechedL2Network();
}

View File

@ -55,6 +55,7 @@ public class NetworkProfile implements Network {
private final boolean displayNetwork;
private Long networkAclId;
private final String guruName;
private boolean strechedL2Subnet;
public NetworkProfile(Network network) {
id = network.getId();
@ -87,6 +88,7 @@ public class NetworkProfile implements Network {
displayNetwork = network.getDisplayNetwork();
networkAclId = network.getNetworkACLId();
guruName = network.getGuruName();
strechedL2Subnet = network.isStrechedL2Network();
}
public String getDns1() {
@ -280,4 +282,10 @@ public class NetworkProfile implements Network {
public Class<?> getEntityType() {
return Network.class;
}
@Override
public boolean isStrechedL2Network() {
return false;
}
}

View File

@ -79,4 +79,10 @@ public interface Vpc extends ControlledEntity, Identity, InternalIdentity {
* @return true if VPC is configured to use distributed router to provides one-hop forwarding and hypervisor based ACL
*/
boolean usesDistributedRouter();
/**
*
* @return true if VPC spans multiple zones in the region
*/
boolean isRegionLevelVpc();
}

View File

@ -56,8 +56,12 @@ public interface VpcOffering extends InternalIdentity, Identity {
Long getServiceOfferingId();
/**
*
* @return true if the offering provides a distributed router capable of one-hop forwarding
*/
boolean supportsDistributedRouter();
/**
* @return true if VPC created with the offering can span multiple zones in the region
*/
boolean offersRegionLevelVPC();
}

View File

@ -16,6 +16,7 @@
// under the License.
package com.cloud.network.vpc;
import java.util.List;
import java.util.Map;

View File

@ -129,4 +129,6 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
Integer getConcurrentConnections();
boolean isKeepAliveEnabled();
boolean getSupportsStrechedL2();
}

View File

@ -592,7 +592,9 @@ public class ApiConstants {
public static final String REMAININGCAPACITY = "remainingcapacity";
public static final String DISTRIBUTED_VPC_ROUTER = "distributedvpcrouter";
public static final String READ_ONLY = "readonly";
public static final String SUPPORTS_REGION_LEVEL_VPC = "supportsregionLevelvpc";
public static final String SUPPORTS_STRECHED_L2_SUBNET = "supportsstrechedl2subnet";
public static final String REGION_LEVEL_VPC = "regionlevelvpc";
public enum HostDetails {
all, capacity, events, stats, min;

View File

@ -64,7 +64,7 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd {
private Long projectId;
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class,
required = true, description = "the ID of the availability zone")
required = true, description = "the ID of the availability zone")
private Long zoneId;
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the VPC")

View File

@ -116,6 +116,10 @@ public class NetworkOfferingResponse extends BaseResponse {
@Param(description = "maximum number of concurrents connections to be handled by lb")
private Integer concurrentConnections;
@SerializedName(ApiConstants.SUPPORTS_STRECHED_L2_SUBNET)
@Param(description = "true if network offering supports network that span multiple zones")
private Boolean supportsStrechedL2Subnet;
public void setId(String id) {
this.id = id;
}
@ -200,4 +204,7 @@ public class NetworkOfferingResponse extends BaseResponse {
this.concurrentConnections = concurrentConnections;
}
public void setSupportsStrechedL2Subnet(Boolean supportsStrechedL2Subnet) {
this.supportsStrechedL2Subnet = supportsStrechedL2Subnet;
}
}

View File

@ -63,6 +63,10 @@ public class VpcOfferingResponse extends BaseResponse {
@Param(description = " indicates if the vpc offering supports distributed router for one-hop forwarding")
private Boolean supportsDistributedRouter;
@SerializedName((ApiConstants.SUPPORTS_REGION_LEVEL_VPC))
@Param(description = " indicated if the offering can support region level vpc")
private Boolean supportsRegionLevelVpc;
public void setId(String id) {
this.id = id;
}
@ -94,4 +98,8 @@ public class VpcOfferingResponse extends BaseResponse {
public void setSupportsDistributedRouter(Boolean supportsDistributedRouter) {
this.supportsDistributedRouter = supportsDistributedRouter;
}
public void setSupportsRegionLevelVpc(Boolean supports) {
this.supportsRegionLevelVpc = supports;
}
}

View File

@ -111,11 +111,14 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons
@Param(description = "is vpc for display to the regular user", since = "4.4", authorized = {RoleType.Admin})
private Boolean forDisplay;
@SerializedName(ApiConstants.DISTRIBUTED_VPC_ROUTER)
@Param(description = "is VPC uses distributed router for one hop forwarding and host based network ACL's")
private boolean usesDistributedRouter;
@SerializedName((ApiConstants.REGION_LEVEL_VPC))
@Param(description = "true if VPC is region level")
private Boolean regionLevelVpc;
public void setId(String id) {
this.id = id;
}
@ -205,6 +208,10 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons
this.forDisplay = forDisplay;
}
public void setRegionLevelVpc(Boolean regionLevelVpc) {
this.regionLevelVpc = regionLevelVpc;
}
public void setUsesDistributedRouter(Boolean usesDistributedRouter) {
this.usesDistributedRouter = usesDistributedRouter;
}

View File

@ -166,6 +166,9 @@ public class NetworkVO implements Network {
@Column(name = "network_acl_id")
Long networkACLId;
@Column(name = "streched_l2")
boolean strechedL2Network = false;
public NetworkVO() {
uuid = UUID.randomUUID().toString();
}
@ -588,4 +591,13 @@ public class NetworkVO implements Network {
public Class<?> getEntityType() {
return Network.class;
}
@Override
public boolean isStrechedL2Network() {
return strechedL2Network;
}
public void setStrechedL2Network(boolean strechedL2Network) {
this.strechedL2Network = strechedL2Network;
}
}

View File

@ -70,6 +70,9 @@ public class VpcOfferingVO implements VpcOffering {
@Column(name = "supports_distributed_router")
boolean supportsDistributedRouter=false;
@Column(name = "supports_region_level_vpc")
boolean offersRegionLevelVPC = false;
public VpcOfferingVO() {
this.uuid = UUID.randomUUID().toString();
}
@ -84,10 +87,11 @@ public class VpcOfferingVO implements VpcOffering {
}
public VpcOfferingVO(String name, String displayText, boolean isDefault, Long serviceOfferingId,
boolean supportsDistributedRouter) {
boolean supportsDistributedRouter, boolean offersRegionLevelVPC) {
this(name, displayText, serviceOfferingId);
this.isDefault = isDefault;
this.supportsDistributedRouter = supportsDistributedRouter;
this.offersRegionLevelVPC = offersRegionLevelVPC;
}
@Override
@ -155,4 +159,9 @@ public class VpcOfferingVO implements VpcOffering {
public boolean supportsDistributedRouter() {
return supportsDistributedRouter;
}
@Override
public boolean offersRegionLevelVPC() {
return offersRegionLevelVPC;
}
}

View File

@ -82,12 +82,15 @@ public class VpcVO implements Vpc {
@Column(name="uses_distributed_router")
boolean usesDistributedRouter = false;
@Column(name = "region_level_vpc")
boolean regionLevelVpc = false;
public VpcVO() {
uuid = UUID.randomUUID().toString();
}
public VpcVO(long zoneId, String name, String displayText, long accountId, long domainId, long vpcOffId, String cidr,
String networkDomain, boolean useDistributedRouter) {
String networkDomain, boolean useDistributedRouter, boolean regionLevelVpc) {
this.zoneId = zoneId;
this.name = name;
this.displayText = displayText;
@ -98,7 +101,8 @@ public class VpcVO implements Vpc {
state = State.Enabled;
this.networkDomain = networkDomain;
vpcOfferingId = vpcOffId;
usesDistributedRouter = useDistributedRouter;
this.usesDistributedRouter = useDistributedRouter;
this.regionLevelVpc = regionLevelVpc;
}
@Override
@ -191,6 +195,11 @@ public class VpcVO implements Vpc {
this.uuid = uuid;
}
@Override
public boolean isRegionLevelVpc() {
return regionLevelVpc;
}
public void setDisplay(boolean display) {
this.display = display;

View File

@ -139,6 +139,9 @@ public class NetworkOfferingVO implements NetworkOffering {
@Column(name = "keep_alive_enabled")
boolean keepAliveEnabled = false;
@Column(name="supports_streched_l2")
boolean supportsStrechedL2 = false;
@Override
public String getDisplayText() {
return displayText;
@ -331,7 +334,7 @@ public class NetworkOfferingVO implements NetworkOffering {
public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps,
Integer multicastRateMbps, boolean isDefault, Availability availability, String tags, Network.GuestType guestType, boolean conserveMode, boolean dedicatedLb,
boolean sharedSourceNat, boolean redundantRouter, boolean elasticIp, boolean elasticLb, boolean specifyIpRanges, boolean inline, boolean isPersistent,
boolean associatePublicIP, boolean publicLb, boolean internalLb, boolean egressdefaultpolicy) {
boolean associatePublicIP, boolean publicLb, boolean internalLb, boolean egressdefaultpolicy, boolean supportsStrechedL2) {
this(name,
displayText,
trafficType,
@ -356,6 +359,7 @@ public class NetworkOfferingVO implements NetworkOffering {
this.inline = inline;
this.eipAssociatePublicIp = associatePublicIP;
this.egressdefaultpolicy = egressdefaultpolicy;
this.supportsStrechedL2 = supportsStrechedL2;
}
public NetworkOfferingVO() {
@ -486,4 +490,9 @@ public class NetworkOfferingVO implements NetworkOffering {
public void setPublicLb(boolean publicLb) {
this.publicLb = publicLb;
}
@Override
public boolean getSupportsStrechedL2() {
return supportsStrechedL2;
}
}

View File

@ -261,6 +261,8 @@ StaticNatServiceProvider, IpDeployer {
// L2 Support : SDN provisioning
Map<Capability, String> connectivityCapabilities = new HashMap<Capability, String>();
connectivityCapabilities.put(Capability.DistributedRouter, null);
connectivityCapabilities.put(Capability.StretchedL2Subnet, null);
connectivityCapabilities.put(Capability.RegionLevelVpc, null);
capabilities.put(Service.Connectivity, connectivityCapabilities);

View File

@ -1901,6 +1901,7 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setNetworkRate(ApiDBUtils.getNetworkRate(offering.getId()));
response.setEgressDefaultPolicy(offering.getEgressDefaultPolicy());
response.setConcurrentConnections(offering.getConcurrentConnections());
response.setSupportsStrechedL2Subnet(offering.getSupportsStrechedL2());
Long so = null;
if (offering.getServiceOfferingId() != null) {
so = offering.getServiceOfferingId();
@ -2766,6 +2767,7 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setIsDefault(offering.isDefault());
response.setState(offering.getState().name());
response.setSupportsDistributedRouter(offering.supportsDistributedRouter());
response.setSupportsRegionLevelVpc(offering.offersRegionLevelVPC());
Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listVpcOffServices(offering.getId());
List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();
@ -2809,6 +2811,7 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setNetworkDomain(vpc.getNetworkDomain());
response.setForDisplay(vpc.isDisplay());
response.setUsesDistributedRouter(vpc.usesDistributedRouter());
response.setRegionLevelVpc(vpc.isRegionLevelVpc());
Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listVpcOffServices(vpc.getVpcOfferingId());
List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();

View File

@ -16,6 +16,7 @@
// under the License.
package com.cloud.configuration;
import com.cloud.network.element.NetworkElement;
import java.net.URI;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -3814,10 +3815,21 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
validateStaticNatServiceCapablities(staticNatServiceCapabilityMap);
// validate the 'Connectivity' service capabilities specified in the network offering, if 'Connectivity' service
// is in the supported services of network offering
Map<Capability, String> connectivityServiceCapabilityMap = cmd.getServiceCapabilities(Service.Connectivity);
if (!serviceProviderMap.containsKey(Service.Connectivity) &&
(connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty())) {
throw new InvalidParameterValueException("Capabilities for 'Connectivity' service can be specified " +
"only when Connectivity service is enabled for network offering.");
}
validateConnectivityServiceCapablities(serviceProviderMap.get(Service.Connectivity), connectivityServiceCapabilityMap);
Map<Service, Map<Capability, String>> serviceCapabilityMap = new HashMap<Service, Map<Capability, String>>();
serviceCapabilityMap.put(Service.Lb, lbServiceCapabilityMap);
serviceCapabilityMap.put(Service.SourceNat, sourceNatServiceCapabilityMap);
serviceCapabilityMap.put(Service.StaticNat, staticNatServiceCapabilityMap);
serviceCapabilityMap.put(Service.Connectivity, connectivityServiceCapabilityMap);
// if Firewall service is missing, add Firewall service/provider
// combination
@ -3952,6 +3964,36 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
}
void validateConnectivityServiceCapablities(Set<Provider> providers, Map<Capability, String> connectivityServiceCapabilityMap) {
if (connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty()) {
for (Capability capability: connectivityServiceCapabilityMap.keySet()) {
if (capability == Capability.StretchedL2Subnet) {
String value = connectivityServiceCapabilityMap.get(capability).toLowerCase();
if (!(value.contains("true") ^ value.contains("false"))) {
throw new InvalidParameterValueException("Invalid value (" + value + ") for " + capability +
" should be true/false");
}
} else {
throw new InvalidParameterValueException("Capability " + capability.getName() + " can not be "
+ " specified with connectivity service.");
}
}
}
if (providers != null && !providers.isEmpty()) {
for (Provider provider: providers) {
NetworkElement element = _networkModel.getElementImplementingProvider(provider.getName());
Map<Service, Map<Capability, String>> capabilities = element.getCapabilities();
if (capabilities != null && !capabilities.isEmpty()) {
Map<Capability, String> connectivityCapabilities = capabilities.get(Service.Connectivity);
if (connectivityCapabilities == null || (connectivityCapabilities != null && !connectivityCapabilities.keySet().contains(Capability.StretchedL2Subnet))) {
throw new InvalidParameterValueException("Provider: " + provider.getName() + " does not support "
+ Capability.StretchedL2Subnet.getName());
}
}
}
}
}
@Override
@DB
public NetworkOfferingVO createNetworkOffering(String name, String displayText, TrafficType trafficType, String tags, boolean specifyVlan, Availability availability,
@ -4012,6 +4054,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
boolean inline = false;
boolean publicLb = false;
boolean internalLb = false;
boolean strechedL2Subnet = false;
if (serviceCapabilityMap != null && !serviceCapabilityMap.isEmpty()) {
Map<Capability, String> lbServiceCapabilityMap = serviceCapabilityMap.get(Service.Lb);
@ -4079,6 +4123,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
}
}
Map<Capability, String> connectivityServiceCapabilityMap = serviceCapabilityMap.get(Service.Connectivity);
if (connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty()) {
String value = connectivityServiceCapabilityMap.get(Capability.StretchedL2Subnet);
if ("true".equalsIgnoreCase(value)) {
strechedL2Subnet = true;
}
}
}
if (serviceProviderMap != null && serviceProviderMap.containsKey(Service.Lb) && !internalLb && !publicLb) {
@ -4088,7 +4140,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
final NetworkOfferingVO offeringFinal = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability,
tags, type, conserveMode, dedicatedLb, sharedSourceNat, redundantRouter, elasticIp, elasticLb, specifyIpRanges, inline, isPersistent, associatePublicIp, publicLb,
internalLb, egressDefaultPolicy);
internalLb, egressDefaultPolicy, strechedL2Subnet);
if (serviceOfferingId != null) {
offeringFinal.setServiceOfferingId(serviceOfferingId);

View File

@ -127,6 +127,10 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru {
throws InsufficientVirtualNetworkCapcityException {
assert (config.getState() == State.Implementing) : "Why are we implementing " + config;
if (_networkModel.areServicesSupportedInNetwork(config.getId(), Network.Service.Connectivity)) {
return null;
}
if (!_networkModel.networkIsConfiguredForExternalNetworking(config.getDataCenterId(), config.getId())) {
return super.implement(config, offering, dest, context);
}

View File

@ -16,6 +16,8 @@
// under the License.
package com.cloud.network.vpc;
import com.cloud.network.element.NetworkElement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -221,44 +223,49 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCOfferingName) == null) {
s_logger.debug("Creating default VPC offering " + VpcOffering.defaultVPCOfferingName);
Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
Set<Provider> defaultProviders = new HashSet<Provider>();
defaultProviders.add(Provider.VPCVirtualRouter);
for (Service svc : getSupportedServices()) {
if (svc == Service.Lb) {
Set<Provider> lbProviders = new HashSet<Provider>();
lbProviders.add(Provider.VPCVirtualRouter);
lbProviders.add(Provider.InternalLbVm);
svcProviderMap.put(svc, lbProviders);
} else {
svcProviderMap.put(svc, defaultProviders);
if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCOfferingName) == null) {
s_logger.debug("Creating default VPC offering " + VpcOffering.defaultVPCOfferingName);
Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
Set<Provider> defaultProviders = new HashSet<Provider>();
defaultProviders.add(Provider.VPCVirtualRouter);
for (Service svc : getSupportedServices()) {
if (svc == Service.Lb) {
Set<Provider> lbProviders = new HashSet<Provider>();
lbProviders.add(Provider.VPCVirtualRouter);
lbProviders.add(Provider.InternalLbVm);
svcProviderMap.put(svc, lbProviders);
} else {
svcProviderMap.put(svc, defaultProviders);
}
}
createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName,
svcProviderMap, true, State.Enabled, null, false, false);
}
}
createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, true, State.Enabled, null, false);
}
//configure default vpc offering with Netscaler as LB Provider
//configure default vpc offering with Netscaler as LB Provider
if (_vpcOffDao.findByUniqueName(VpcOffering.defaultVPCNSOfferingName) == null) {
s_logger.debug("Creating default VPC offering with Netscaler as LB Provider" + VpcOffering.defaultVPCNSOfferingName);
Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
Set<Provider> defaultProviders = new HashSet<Provider>();
defaultProviders.add(Provider.VPCVirtualRouter);
for (Service svc : getSupportedServices()) {
if (svc == Service.Lb) {
Set<Provider> lbProviders = new HashSet<Provider>();
lbProviders.add(Provider.Netscaler);
lbProviders.add(Provider.InternalLbVm);
svcProviderMap.put(svc, lbProviders);
} else {
svcProviderMap.put(svc, defaultProviders);
s_logger.debug("Creating default VPC offering with Netscaler as LB Provider" + VpcOffering.defaultVPCNSOfferingName);
Map<Service, Set<Provider>> svcProviderMap = new HashMap<Service, Set<Provider>>();
Set<Provider> defaultProviders = new HashSet<Provider>();
defaultProviders.add(Provider.VPCVirtualRouter);
for (Service svc : getSupportedServices()) {
if (svc == Service.Lb) {
Set<Provider> lbProviders = new HashSet<Provider>();
lbProviders.add(Provider.Netscaler);
lbProviders.add(Provider.InternalLbVm);
svcProviderMap.put(svc, lbProviders);
} else {
svcProviderMap.put(svc, defaultProviders);
}
}
createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName,
svcProviderMap, false, State.Enabled, null, false, false);
}
}
createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, svcProviderMap, false, State.Enabled, null, false);
}
}
});
Map<String, String> configs = _configDao.getConfiguration(params);
@ -383,9 +390,9 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
validateConnectivtyServiceCapablitlies(svcProviderMap.get(Service.Connectivity), serviceCapabilitystList);
boolean supportsDistributedRouter = isVpcOfferingSupportsDistributedRouter(serviceCapabilitystList);
boolean offersRegionLevelVPC = isVpcOfferingForRegionLevelVpc(serviceCapabilitystList);
VpcOffering offering = createVpcOffering(name, displayText, svcProviderMap, false, null,
serviceOfferingId,supportsDistributedRouter);
serviceOfferingId, supportsDistributedRouter, offersRegionLevelVPC);
CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name);
return offering;
@ -395,37 +402,149 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
protected VpcOffering createVpcOffering(final String name, final String displayText,
final Map<Network.Service, Set<Network.Provider>> svcProviderMap,
final boolean isDefault, final State state, final Long serviceOfferingId,
final boolean supportsDistributedRouter) {
final boolean supportsDistributedRouter, final boolean offersRegionLevelVPC) {
return Transaction.execute(new TransactionCallback<VpcOffering>() {
@Override
public VpcOffering doInTransaction(TransactionStatus status) {
// create vpc offering object
VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, serviceOfferingId, supportsDistributedRouter);
VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, serviceOfferingId,
supportsDistributedRouter, offersRegionLevelVPC);
if (state != null) {
offering.setState(state);
}
s_logger.debug("Adding vpc offering " + offering);
offering = _vpcOffDao.persist(offering);
// populate services and providers
if (svcProviderMap != null) {
for (Network.Service service : svcProviderMap.keySet()) {
Set<Provider> providers = svcProviderMap.get(service);
if (providers != null && !providers.isEmpty()) {
for (Network.Provider provider : providers) {
VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider);
_vpcOffSvcMapDao.persist(offService);
s_logger.trace("Added service for the vpc offering: " + offService + " with provider " + provider.getName());
if (state != null) {
offering.setState(state);
}
s_logger.debug("Adding vpc offering " + offering);
offering = _vpcOffDao.persist(offering);
// populate services and providers
if (svcProviderMap != null) {
for (Network.Service service : svcProviderMap.keySet()) {
Set<Provider> providers = svcProviderMap.get(service);
if (providers != null && !providers.isEmpty()) {
for (Network.Provider provider : providers) {
VpcOfferingServiceMapVO offService = new VpcOfferingServiceMapVO(offering.getId(), service, provider);
_vpcOffSvcMapDao.persist(offService);
s_logger.trace("Added service for the vpc offering: " + offService + " with provider " + provider.getName());
}
} else {
throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName());
}
}
}
return offering;
}
});
}
private void validateConnectivtyServiceCapablitlies(Set<Provider> providers, Map serviceCapabilitystList) {
if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
Collection serviceCapabilityCollection = serviceCapabilitystList.values();
Iterator iter = serviceCapabilityCollection.iterator();
Map<Network.Capability, String> capabilityMap = null;
boolean distributedRouterCapabilitySpecified = false;
boolean regionLevelVpcCapabilitySpecified = false;
while (iter.hasNext()) {
HashMap<String, String> svcCapabilityMap = (HashMap<String, String>)iter.next();
Network.Capability capability = null;
String svc = svcCapabilityMap.get("service");
String capabilityName = svcCapabilityMap.get("capabilitytype");
String capabilityValue = svcCapabilityMap.get("capabilityvalue");
if (capabilityName != null) {
capability = Network.Capability.getCapability(capabilityName);
}
if ((capability == null) || (capabilityName == null) || (capabilityValue == null)) {
throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue);
}
if (!svc.equalsIgnoreCase(Service.Connectivity.getName())) {
throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only 'Connectivity'" +
" service capabilities can be specified");
}
if (!capabilityName.equalsIgnoreCase("DistributedRouter") && !capabilityName.equalsIgnoreCase("RegionLevelVpc")) {
throw new InvalidParameterValueException("Invalid Capability:" + capabilityName + " specified." +
" Only 'DistributedRouter'/'RegionLevelVpc' capability can be specified.");
}
if (capabilityName.equalsIgnoreCase("DistributedRouter")) {
distributedRouterCapabilitySpecified = true;
}
if (capabilityName.equalsIgnoreCase("RegionLevelVpc")) {
regionLevelVpcCapabilitySpecified = true;
}
if (!capabilityValue.equalsIgnoreCase("true") && capabilityValue.equalsIgnoreCase("false")) {
throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified.");
}
}
if (providers != null && !providers.isEmpty()) {
for (Provider provider: providers) {
NetworkElement element = _ntwkModel.getElementImplementingProvider(provider.getName());
Map<Service, Map<Network.Capability, String>> capabilities = element.getCapabilities();
if (capabilities != null && !capabilities.isEmpty()) {
Map<Network.Capability, String> connectivityCapabilities = capabilities.get(Service.Connectivity);
if (regionLevelVpcCapabilitySpecified) {
if (connectivityCapabilities == null || (connectivityCapabilities != null &&
!connectivityCapabilities.keySet().contains(Network.Capability.RegionLevelVpc))) {
throw new InvalidParameterValueException("Provider: " + provider.getName() + " does not support "
+ Network.Capability.RegionLevelVpc.getName() + " capability.");
}
}
if (distributedRouterCapabilitySpecified) {
if (connectivityCapabilities == null || (connectivityCapabilities != null &&
!connectivityCapabilities.keySet().contains(Network.Capability.DistributedRouter))) {
throw new InvalidParameterValueException("Provider: " + provider.getName() + " does not support "
+ Network.Capability.DistributedRouter.getName() + " capability.");
}
}
}
} else {
throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName());
}
}
}
return offering;
}
});
private boolean isVpcOfferingForRegionLevelVpc(Map serviceCapabilitystList) {
boolean offersRegionLevelVPC = false;
if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
Collection serviceCapabilityCollection = serviceCapabilitystList.values();
Iterator iter = serviceCapabilityCollection.iterator();
Map<Network.Capability, String> capabilityMap = null;
while (iter.hasNext()) {
HashMap<String, String> svcCapabilityMap = (HashMap<String, String>)iter.next();
Network.Capability capability = null;
String svc = svcCapabilityMap.get("service");
String capabilityName = svcCapabilityMap.get("capabilitytype");
String capabilityValue = svcCapabilityMap.get("capabilityvalue");
if (capabilityName != null) {
capability = Network.Capability.getCapability(capabilityName);
}
if ((capability == null) || (capabilityName == null) || (capabilityValue == null)) {
throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue);
}
if (!svc.equalsIgnoreCase(Service.Connectivity.getName())) {
throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only for 'Connectivity' service capabilities can be specified");
}
if (!capabilityName.equalsIgnoreCase("RegionLevelVpc")) {
continue;
}
if (!capabilityValue.equalsIgnoreCase("true") && capabilityValue.equalsIgnoreCase("false")) {
throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified.");
}
offersRegionLevelVPC = capabilityValue.equalsIgnoreCase("true");
}
}
return offersRegionLevelVPC;
}
private boolean isVpcOfferingSupportsDistributedRouter(Map serviceCapabilitystList) {
@ -454,7 +573,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
}
if (!capabilityName.equalsIgnoreCase("DistributedRouter")) {
throw new InvalidParameterValueException("Invalid Capability:" + capabilityName + " specified. Only 'DistributedRouter' capability can be specified.");
continue;
}
if (!capabilityValue.equalsIgnoreCase("true") && capabilityValue.equalsIgnoreCase("false")) {
@ -466,56 +585,6 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
return supportsDistributedRouter;
}
private void validateConnectivtyServiceCapablitlies(Set<Provider> providers, Map serviceCapabilitystList) {
if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
Collection serviceCapabilityCollection = serviceCapabilitystList.values();
Iterator iter = serviceCapabilityCollection.iterator();
Map<Network.Capability, String> capabilityMap = null;
while (iter.hasNext()) {
HashMap<String, String> svcCapabilityMap = (HashMap<String, String>)iter.next();
Network.Capability capability = null;
String svc = svcCapabilityMap.get("service");
String capabilityName = svcCapabilityMap.get("capabilitytype");
String capabilityValue = svcCapabilityMap.get("capabilityvalue");
if (capabilityName != null) {
capability = Network.Capability.getCapability(capabilityName);
}
if ((capability == null) || (capabilityName == null) || (capabilityValue == null)) {
throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue);
}
if (!svc.equalsIgnoreCase(Service.Connectivity.getName())) {
throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only for 'Connectivity' service capabilities can be specified");
}
if (!capabilityName.equalsIgnoreCase("DistributedRouter")) {
throw new InvalidParameterValueException("Invalid Capability:" + capabilityName + " specified. Only 'DistributedRouter' capability can be specified.");
}
if (!capabilityValue.equalsIgnoreCase("true") && capabilityValue.equalsIgnoreCase("false")) {
throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified.");
}
}
if (providers != null && !providers.isEmpty()) {
for (Provider provider: providers) {
NetworkElement element = _ntwkModel.getElementImplementingProvider(provider.getName());
Map<Service, Map<Network.Capability, String>> capabilities = element.getCapabilities();
if (capabilities != null && !capabilities.isEmpty()) {
Map<Network.Capability, String> connectivityCapabilities = capabilities.get(Service.Connectivity);
if (connectivityCapabilities == null || (connectivityCapabilities != null && !connectivityCapabilities.keySet().contains(Network.Capability.DistributedRouter))) {
throw new InvalidParameterValueException("Provider: " + provider.getName() + " does not support "
+ Network.Capability.DistributedRouter.getName() + " capability.");
}
}
}
}
}
}
@Override
public Vpc getActiveVpc(long vpcId) {
return _vpcDao.getActiveVpcById(vpcId);
@ -710,6 +779,11 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
throw ex;
}
boolean isRegionLevelVpcOff = vpcOff.offersRegionLevelVPC();
if (isRegionLevelVpcOff && networkDomain == null) {
throw new InvalidParameterValueException("Network domain must be specified for region level VPC");
}
//Validate zone
DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
if (zone == null) {
@ -732,13 +806,15 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
networkDomain = "cs" + Long.toHexString(owner.getId()) + NetworkOrchestrationService.GuestDomainSuffix.valueIn(zoneId);
}
}
boolean useDistributedRouter = vpcOff.supportsDistributedRouter();
return createVpc(zoneId, vpcOffId, owner, vpcName, displayText, cidr, networkDomain, displayVpc, useDistributedRouter);
return createVpc(zoneId, vpcOffId, owner, vpcName, displayText, cidr, networkDomain, displayVpc,
useDistributedRouter, isRegionLevelVpcOff);
}
@DB
protected Vpc createVpc(final long zoneId, final long vpcOffId, final Account vpcOwner, final String vpcName, final String displayText, final String cidr,
final String networkDomain, final Boolean displayVpc, final boolean useDistributedRouter) {
final String networkDomain, final Boolean displayVpc, final boolean useDistributedRouter, final boolean regionLevelVpc) {
//Validate CIDR
if (!NetUtils.isValidCIDR(cidr)) {
@ -761,7 +837,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Override
public VpcVO doInTransaction(TransactionStatus status) {
VpcVO vpc = new VpcVO(zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId,
cidr, networkDomain, useDistributedRouter);
cidr, networkDomain, useDistributedRouter, regionLevelVpc);
if (displayVpc != null) {
vpc.setDisplay(displayVpc);
}
@ -2212,7 +2289,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
networkDomain = vpc.getNetworkDomain();
}
if (vpc.getZoneId() != zoneId) {
if (!vpc.isRegionLevelVpc() && vpc.getZoneId() != zoneId) {
throw new InvalidParameterValueException("New network doesn't belong to vpc zone");
}

View File

@ -1153,9 +1153,9 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
// Offering #5
NetworkOfferingVO defaultNetscalerNetworkOffering =
new NetworkOfferingVO(NetworkOffering.DefaultSharedEIPandELBNetworkOffering,
"Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, false, true, null, null, true,
Availability.Optional, null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false, false);
new NetworkOfferingVO(NetworkOffering.DefaultSharedEIPandELBNetworkOffering,
"Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, false, true, null, null, true,
Availability.Optional, null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false, false, false);
defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled);
defaultNetscalerNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetscalerNetworkOffering);

View File

@ -2713,7 +2713,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
boolean securityGroupEnabled = false;
boolean vpcNetwork = false;
for (NetworkVO network : networkList) {
if (network.getDataCenterId() != zone.getId()) {
if ((network.getDataCenterId() != zone.getId()) && !network.isStrechedL2Network()) {
throw new InvalidParameterValueException("Network id=" + network.getId() + " doesn't belong to zone " + zone.getId());
}

View File

@ -103,7 +103,7 @@ public class CreatePrivateNetworkTest {
NetworkOfferingVO ntwkOff =
new NetworkOfferingVO("offer", "fakeOffer", TrafficType.Guest, true, true, null, null, false, null, null, GuestType.Isolated, false, false, false, false,
false, false, false, false, false, false, false, false, false);
false, false, false, false, false, false, false, false, false, false);
when(networkService._networkOfferingDao.findById(anyLong())).thenReturn(ntwkOff);
List<NetworkOfferingVO> netofferlist = new ArrayList<NetworkOfferingVO>();
netofferlist.add(ntwkOff);

View File

@ -606,7 +606,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
@Override
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain,
Account owner, Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6,
String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException,
String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan ) throws ConcurrentOperationException, InsufficientCapacityException,
ResourceAllocationException {
// TODO Auto-generated method stub
return null;

View File

@ -85,7 +85,7 @@ public class VpcApiUnitTest extends TestCase {
public void validateNtwkOffForVpc() {
//validate network offering
//1) correct network offering
VpcVO vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false);
VpcVO vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false, false);
boolean result = false;
try {
_vpcService.validateNtwkOffForNtwkInVpc(2L, 1, "0.0.0.0", "111-", vo, "10.1.1.1", new AccountVO(), null);

View File

@ -98,9 +98,9 @@ public class MockVpcDaoImpl extends GenericDaoBase<VpcVO, Long> implements VpcDa
public VpcVO findById(Long id) {
VpcVO vo = null;
if (id.longValue() == 1) {
vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false);
vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false, false);
} else if (id.longValue() == 2) {
vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false);
vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false, false);
vo.setState(State.Inactive);
}

View File

@ -742,8 +742,10 @@ UPDATE `cloud`.`guest_os` SET `created` = now();
ALTER TABLE `cloud`.`vm_reservation` ADD COLUMN `deployment_planner` varchar(40) DEFAULT NULL COMMENT 'Preferred deployment planner for the vm';
ALTER TABLE `cloud`.`vpc_offerings` ADD COLUMN supports_distributed_router boolean default false;
ALTER TABLE `cloud`.`vpc` ADD COLUMN uses_distributed_router boolean default false;
INSERT INTO `cloud`.`storage_pool_details` (pool_id,name,value,display) SELECT storage_pool.id,data_center_details.name,data_center_details.value,data_center_details.display FROM `cloud`.`storage_pool` JOIN `cloud`.`data_center_details` ON data_center_details.dc_id=storage_pool.data_center_id WHERE data_center_details.name = "storage.overprovisioning.factor";
DELETE FROM `cloud`.`data_center_details` WHERE name="storage.overprovisioning.factor";
ALTER TABLE `cloud`.`load_balancer_vm_map` ADD COLUMN instance_ip VARCHAR(40);
ALTER TABLE `cloud`.`load_balancer_vm_map` DROP KEY `load_balancer_id`, ADD UNIQUE KEY load_balancer_id (`load_balancer_id`, `instance_id`, `instance_ip`);
ALTER TABLE `cloud`.`load_balancer_vm_map` DROP KEY `load_balancer_id`, ADD UNIQUE KEY load_balancer_id (`load_balancer_id`, `instance_id`, `instance_ip`);
ALTER TABLE `cloud`.`vpc_offerings` ADD COLUMN supports_region_level_vpc boolean default false;
ALTER TABLE `cloud`.`network_offerings` ADD COLUMN supports_streched_l2 boolean default false;
ALTER TABLE `cloud`.`vpc` ADD COLUMN region_level_vpc boolean default false;

View File

@ -0,0 +1,517 @@
# 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.
import unittest
""" Component tests for region level VPC functionality
"""
#Import Local Modules
import marvin
from nose.plugins.attrib import attr
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
from marvin.integration.lib.utils import *
from marvin.integration.lib.base import *
from marvin.integration.lib.common import *
from marvin.sshClient import SshClient
import datetime
class Services:
"""Test inter VLAN services
"""
def __init__(self):
self.services = {
"account": {
"email": "test@test.com",
"firstname": "Test",
"lastname": "User",
"username": "test",
# Random characters are appended for unique
# username
"password": "password",
},
"service_offering": {
"name": "Tiny Instance",
"displaytext": "Tiny Instance",
"cpunumber": 1,
"cpuspeed": 100,
"memory": 128,
},
"network_offering": {
"name": 'VPC Network offering',
"displaytext": 'VPC Network off',
"guestiptype": 'Isolated',
"supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Lb,UserData,StaticNat,NetworkACL, Connectivity',
"traffictype": 'GUEST',
"availability": 'Optional',
"useVpc": 'on',
"serviceProviderList": {
"Vpn": 'VpcVirtualRouter',
"Dhcp": 'VpcVirtualRouter',
"Dns": 'VpcVirtualRouter',
"SourceNat": 'VpcVirtualRouter',
"PortForwarding": 'VpcVirtualRouter',
"Lb": 'VpcVirtualRouter',
"UserData": 'VpcVirtualRouter',
"StaticNat": 'VpcVirtualRouter',
"NetworkACL": 'VpcVirtualRouter',
"Connectivity": 'Ovs'
},
"serviceCapabilityList": {
"Connectivity": {
"StretchedL2Subnet": "true"
},
},
},
"vpc_offering": {
"name": 'VPC off',
"displaytext": 'VPC off',
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,Connectivity',
"serviceProviderList": {
"Vpn": 'VpcVirtualRouter',
"Dhcp": 'VpcVirtualRouter',
"Dns": 'VpcVirtualRouter',
"SourceNat": 'VpcVirtualRouter',
"PortForwarding": 'VpcVirtualRouter',
"Lb": 'VpcVirtualRouter',
"UserData": 'VpcVirtualRouter',
"StaticNat": 'VpcVirtualRouter',
"Connectivity": 'Ovs'
},
"serviceCapabilityList": {
"Connectivity": {
"RegionLevelVpc": "true"
},
},
},
"vpc": {
"name": "TestVPC",
"displaytext": "TestVPC",
"cidr": '10.0.0.1/24'
},
"network": {
"name": "Test Network",
"displaytext": "Test Network",
"netmask": '255.255.255.0'
},
"lbrule": {
"name": "SSH",
"alg": "leastconn",
# Algorithm used for load balancing
"privateport": 22,
"publicport": 2222,
"openfirewall": False,
"startport": 2222,
"endport": 2222,
"cidrlist": '0.0.0.0/0',
"protocol": 'TCP'
},
"natrule": {
"privateport": 22,
"publicport": 22,
"startport": 22,
"endport": 22,
"protocol": "TCP",
"cidrlist": '0.0.0.0/0',
},
"fw_rule": {
"startport": 1,
"endport": 6000,
"cidr": '0.0.0.0/0',
# Any network (For creating FW rule)
"protocol": "TCP"
},
"virtual_machine": {
"displayname": "Test VM",
"username": "root",
"password": "password",
"ssh_port": 22,
"hypervisor": 'XenServer',
# Hypervisor type should be same as
# hypervisor type of cluster
"privateport": 22,
"publicport": 22,
"protocol": 'TCP',
},
"ostype": 'CentOS 5.3 (64-bit)',
# Cent OS 5.3 (64 bit)
"sleep": 60,
"timeout": 10,
}
class TestRegionVpcOffering(cloudstackTestCase):
@classmethod
def setUpClass(cls):
cls.api_client = super(
TestRegionVpcOffering,
cls
).getClsTestClient().getApiClient()
cls.services = Services().services
# Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client, cls.services)
cls.zone = get_zone(cls.api_client, cls.services)
cls.template = get_template(
cls.api_client,
cls.zone.id,
cls.services["ostype"]
)
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
cls.services["virtual_machine"]["template"] = cls.template.id
cls.service_offering = ServiceOffering.create(
cls.api_client,
cls.services["service_offering"]
)
cls._cleanup = [
cls.service_offering,
]
return
@classmethod
def tearDownClass(cls):
try:
#Cleanup resources used
cleanup_resources(cls.api_client, cls._cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.dbclient = self.testClient.getDbConnection()
self.account = Account.create(
self.apiclient,
self.services["account"],
admin=True,
domainid=self.domain.id
)
self.cleanup = []
self.cleanup.insert(0, self.account)
return
def tearDown(self):
try:
cleanup_resources(self.apiclient, self.cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
return
def validate_vpc_offering(self, vpc_offering):
"""Validates the VPC offering"""
self.debug("Check if the VPC offering is created successfully?")
vpc_offs = VpcOffering.list(
self.apiclient,
id=vpc_offering.id
)
self.assertEqual(
isinstance(vpc_offs, list),
True,
"List VPC offerings should return a valid list"
)
self.assertEqual(
vpc_offering.name,
vpc_offs[0].name,
"Name of the VPC offering should match with listVPCOff data"
)
self.assertEqual(
vpc_offering.name,
vpc_offs[0].name,
"Name of the VPC offering should match with listVPCOff data"
)
self.assertEqual(
vpc_offs[0].regionlevelvpc,True,
"VPC offering is not set up for region level VPC"
)
self.debug(
"VPC offering is created successfully - %s" %
vpc_offering.name)
return
def validate_vpc_network(self, network):
"""Validates the VPC network"""
self.debug("Check if the VPC network is created successfully?")
vpc_networks = VPC.list(
self.apiclient,
id=network.id
)
self.assertEqual(
isinstance(vpc_networks, list),
True,
"List VPC network should return a valid list"
)
self.assertEqual(
network.name,
vpc_networks[0].name,
"Name of the VPC network should match with listVPC data"
)
self.debug("VPC network created successfully - %s" % network.name)
return
@attr(tags=["advanced", "intervlan"])
def test_01_create_vpc_offering_with_regionlevelvpc_service_capability(self):
""" Test create VPC offering
"""
# Steps for validation
# 1. Create VPC Offering by specifying all supported Services
# 2. VPC offering should be created successfully.
self.debug("Creating inter VPC offering")
vpc_off = VpcOffering.create(
self.apiclient,
self.services["vpc_offering"]
)
self.debug("Check if the VPC offering is created successfully?")
self.cleanup.append(vpc_off)
self.validate_vpc_offering(vpc_off)
return
@attr(tags=["advanced", "intervlan"])
def test_02_create_vpc_from_offering_with_regionlevelvpc_service_capability(self):
""" Test create VPC offering
"""
# Steps for validation
# 1. Create VPC Offering by specifying all supported Services
# 2. VPC offering should be created successfully.
self.debug("Creating inter VPC offering")
vpc_off = VpcOffering.create(
self.apiclient,
self.services["vpc_offering"]
)
vpc_off.update(self.apiclient, state='Enabled')
vpc = VPC.create(
self.apiclient,
self.services["vpc"],
vpcofferingid=vpc_off.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.account.domainid
)
self.assertEqual(vpc.distributedvpcrouter, True, "VPC created should have 'distributedvpcrouter' set to True")
try:
vpc.delete(self.apiclient)
except Exception as e:
self.fail("Failed to delete VPC network - %s" % e)
return
@attr(tags=["advanced", "intervlan"])
def test_03_deploy_vms_in_vpc_with_regionlevelvpc(self):
"""Test deploy virtual machines in VPC networks"""
# 1. Create VPC Offering by specifying all supported Services
# (Vpn,dhcpdns,UserData, SourceNat,Static NAT and PF,LB,NetworkAcl)
# 2. Create a VPC using the above VPC offering
# 3. Create a network as part of this VPC.
# 4. Deploy few Vms.
# 5. Create a LB rule for this VM.
# 6. Create a PF rule for this VM.
# 7. Create a Static Nat rule for this VM.
# 8. Create Ingress rules on the network to open the above created
# LB PF and Static Nat rule
# 9. Create Egress Network ACL for this network to access google.com.
# 10. Enable VPN services
self.debug("Creating a VPC offering..")
vpc_off = VpcOffering.create(
self.apiclient,
self.services["vpc_offering"]
)
vpc_off.update(self.apiclient, state='Enabled')
self.debug("creating a VPC network in the account: %s" %
self.account.name)
vpc = VPC.create(
self.apiclient,
self.services["vpc"],
vpcofferingid=vpc_off.id,
zoneid=self.zone.id,
account=self.account.name,
domainid=self.account.domainid
)
self.validate_vpc_network(vpc)
self.network_offering = NetworkOffering.create(
self.apiclient,
self.services["network_offering"],
conservemode=False
)
# Enable Network offering
self.network_offering.update(self.apiclient, state='Enabled')
gateway = vpc.cidr.split('/')[0]
# Split the cidr to retrieve gateway
# for eg. cidr = 10.0.0.1/24
# Gateway = 10.0.0.1
# Creating network using the network offering created
self.debug("Creating network with network offering: %s" %
self.network_offering.id)
network = Network.create(
self.apiclient,
self.services["network"],
accountid=self.account.name,
domainid=self.account.domainid,
networkofferingid=self.network_offering.id,
zoneid=self.zone.id,
gateway=gateway,
vpcid=vpc.id
)
self.debug("Created network with ID: %s" % network.id)
# Spawn an instance in that network
virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
accountid=self.account.name,
domainid=self.account.domainid,
serviceofferingid=self.service_offering.id,
networkids=[str(network.id)]
)
self.debug("Deployed VM in network: %s" % network.id)
self.debug("Associating public IP for network: %s" % network.name)
public_ip = PublicIPAddress.create(
self.apiclient,
accountid=self.account.name,
zoneid=self.zone.id,
domainid=self.account.domainid,
networkid=network.id,
vpcid=vpc.id
)
self.debug("Associated %s with network %s" % (
public_ip.ipaddress.ipaddress,
network.id
))
self.debug("Creating LB rule for IP address: %s" %
public_ip.ipaddress.ipaddress)
lb_rule = LoadBalancerRule.create(
self.apiclient,
self.services["lbrule"],
ipaddressid=public_ip.ipaddress.id,
accountid=self.account.name,
networkid=network.id,
vpcid=vpc.id,
domainid=self.account.domainid
)
self.debug("Associating public IP for network: %s" % vpc.name)
public_ip_2 = PublicIPAddress.create(
self.apiclient,
accountid=self.account.name,
zoneid=self.zone.id,
domainid=self.account.domainid,
networkid=network.id,
vpcid=vpc.id
)
self.debug("Associated %s with network %s" % (
public_ip_2.ipaddress.ipaddress,
network.id
))
nat_rule = NATRule.create(
self.apiclient,
virtual_machine,
self.services["natrule"],
ipaddressid=public_ip_2.ipaddress.id,
openfirewall=False,
networkid=network.id,
vpcid=vpc.id
)
self.debug("Adding NetwrokACl rules to make PF and LB accessible")
networkacl_1 = NetworkACL.create(
self.apiclient,
networkid=network.id,
services=self.services["natrule"],
traffictype='Ingress'
)
networkacl_2 = NetworkACL.create(
self.apiclient,
networkid=network.id,
services=self.services["lbrule"],
traffictype='Ingress'
)
self.debug("Checking if we can SSH into VM?")
try:
virtual_machine.get_ssh_client(
ipaddress=public_ip_2.ipaddress.ipaddress,
)
self.debug("SSH into VM is successfully")
except Exception as e:
self.fail("Failed to SSH into VM - %s, %s" %
(public_ip_2.ipaddress.ipaddress, e))
self.debug("Associating public IP for network: %s" % network.name)
public_ip_3 = PublicIPAddress.create(
self.apiclient,
accountid=self.account.name,
zoneid=self.zone.id,
domainid=self.account.domainid,
networkid=network.id,
vpcid=vpc.id
)
self.debug("Associated %s with network %s" % (
public_ip_3.ipaddress.ipaddress,
network.id
))
self.debug("Enabling static NAT for IP: %s" %
public_ip_3.ipaddress.ipaddress)
try:
StaticNATRule.enable(
self.apiclient,
ipaddressid=public_ip_3.ipaddress.id,
virtualmachineid=virtual_machine.id,
networkid=network.id
)
self.debug("Static NAT enabled for IP: %s" %
public_ip_3.ipaddress.ipaddress)
except Exception as e:
self.fail("Failed to enable static NAT on IP: %s - %s" % (
public_ip_3.ipaddress.ipaddress, e))
public_ips = PublicIPAddress.list(
self.apiclient,
networkid=network.id,
listall=True,
isstaticnat=True,
account=self.account.name,
domainid=self.account.domainid
)
self.assertEqual(
isinstance(public_ips, list),
True,
"List public Ip for network should list the Ip addr"
)
self.assertEqual(
public_ips[0].ipaddress,
public_ip_3.ipaddress.ipaddress,
"List public Ip for network should list the Ip addr"
)
# TODO: Remote Access VPN is not yet supported in VPC
return