cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From muralire...@apache.org
Subject [1/2] git commit: updated refs/heads/4.4 to c1085ed
Date Fri, 14 Mar 2014 16:27:51 GMT
Repository: cloudstack
Updated Branches:
  refs/heads/4.4 5c37249bf -> c1085ed94


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


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/7a929d1a
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/7a929d1a
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/7a929d1a

Branch: refs/heads/4.4
Commit: 7a929d1a0e0a32cdd2fb9a871617b291f04b46f5
Parents: 5c37249
Author: Murali Reddy <muralimmreddy@gmail.com>
Authored: Fri Jan 24 11:15:38 2014 +0530
Committer: Murali Reddy <muralimmreddy@gmail.com>
Committed: Fri Mar 14 21:54:47 2014 +0530

----------------------------------------------------------------------
 api/src/com/cloud/network/Network.java          |   6 +-
 api/src/com/cloud/network/NetworkProfile.java   |   8 +
 api/src/com/cloud/network/vpc/Vpc.java          |   6 +
 api/src/com/cloud/network/vpc/VpcOffering.java  |   6 +-
 .../network/vpc/VpcProvisioningService.java     |   1 +
 api/src/com/cloud/offering/NetworkOffering.java |   2 +
 .../org/apache/cloudstack/api/ApiConstants.java |   4 +-
 .../api/command/user/vpc/CreateVPCCmd.java      |   2 +-
 .../api/response/NetworkOfferingResponse.java   |   7 +
 .../api/response/VpcOfferingResponse.java       |   8 +
 .../cloudstack/api/response/VpcResponse.java    |   9 +-
 .../src/com/cloud/network/dao/NetworkVO.java    |  12 +
 .../com/cloud/network/vpc/VpcOfferingVO.java    |  11 +-
 .../schema/src/com/cloud/network/vpc/VpcVO.java |  11 +-
 .../com/cloud/offerings/NetworkOfferingVO.java  |  11 +-
 .../com/cloud/network/element/OvsElement.java   |   2 +
 server/src/com/cloud/api/ApiResponseHelper.java |   3 +
 .../configuration/ConfigurationManagerImpl.java |  54 +-
 .../network/guru/ExternalGuestNetworkGuru.java  |   4 +
 .../com/cloud/network/vpc/VpcManagerImpl.java   | 244 ++++++---
 .../cloud/server/ConfigurationServerImpl.java   |   6 +-
 server/src/com/cloud/vm/UserVmManagerImpl.java  |   2 +-
 .../cloud/network/CreatePrivateNetworkTest.java |   2 +-
 .../com/cloud/vpc/MockNetworkManagerImpl.java   |   2 +-
 server/test/com/cloud/vpc/VpcApiUnitTest.java   |   2 +-
 .../test/com/cloud/vpc/dao/MockVpcDaoImpl.java  |   4 +-
 setup/db/db/schema-430to440.sql                 |   4 +-
 test/integration/component/test_region_vpc.py   | 517 +++++++++++++++++++
 28 files changed, 847 insertions(+), 103 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/api/src/com/cloud/network/Network.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java
index 3283a55..ef3bcdf 100644
--- a/api/src/com/cloud/network/Network.java
+++ b/api/src/com/cloud/network/Network.java
@@ -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();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/api/src/com/cloud/network/NetworkProfile.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/NetworkProfile.java b/api/src/com/cloud/network/NetworkProfile.java
index 3f57694..390ec25 100644
--- a/api/src/com/cloud/network/NetworkProfile.java
+++ b/api/src/com/cloud/network/NetworkProfile.java
@@ -57,6 +57,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();
@@ -89,6 +90,7 @@ public class NetworkProfile implements Network {
         displayNetwork = network.getDisplayNetwork();
         networkAclId = network.getNetworkACLId();
         guruName = network.getGuruName();
+        strechedL2Subnet = network.isStrechedL2Network();
     }
 
     public String getDns1() {
@@ -282,4 +284,10 @@ public class NetworkProfile implements Network {
     public IAMEntityType getEntityType() {
         return IAMEntityType.Network;
     }
+
+    @Override
+    public boolean isStrechedL2Network() {
+        return false;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/api/src/com/cloud/network/vpc/Vpc.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/vpc/Vpc.java b/api/src/com/cloud/network/vpc/Vpc.java
index 4bc8c98..2338878 100644
--- a/api/src/com/cloud/network/vpc/Vpc.java
+++ b/api/src/com/cloud/network/vpc/Vpc.java
@@ -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();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/api/src/com/cloud/network/vpc/VpcOffering.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/vpc/VpcOffering.java b/api/src/com/cloud/network/vpc/VpcOffering.java
index a0a1b15..660c79d 100644
--- a/api/src/com/cloud/network/vpc/VpcOffering.java
+++ b/api/src/com/cloud/network/vpc/VpcOffering.java
@@ -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();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/api/src/com/cloud/network/vpc/VpcProvisioningService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/vpc/VpcProvisioningService.java b/api/src/com/cloud/network/vpc/VpcProvisioningService.java
index e545275..82a7baa 100644
--- a/api/src/com/cloud/network/vpc/VpcProvisioningService.java
+++ b/api/src/com/cloud/network/vpc/VpcProvisioningService.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.network.vpc;
 
+
 import java.util.List;
 import java.util.Map;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/api/src/com/cloud/offering/NetworkOffering.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java
index b4f3863..f1ef69c 100644
--- a/api/src/com/cloud/offering/NetworkOffering.java
+++ b/api/src/com/cloud/offering/NetworkOffering.java
@@ -129,4 +129,6 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity,
     Integer getConcurrentConnections();
 
     boolean isKeepAliveEnabled();
+
+    boolean getSupportsStrechedL2();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 32107ed..0dbc1b8 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -589,7 +589,9 @@ public class ApiConstants {
     public static final String VGPUTYPE = "vgputype";
     public static final String REMAININGCAPACITY = "remainingcapacity";
     public static final String DISTRIBUTED_VPC_ROUTER = "distributedvpcrouter";
-
+    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;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
index c179ec8..4bf79da 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
@@ -65,7 +65,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")

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
index 8219147..55ca2ce 100644
--- a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
@@ -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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
index 89697f0..de5adef 100644
--- a/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
@@ -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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/api/src/org/apache/cloudstack/api/response/VpcResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/VpcResponse.java b/api/src/org/apache/cloudstack/api/response/VpcResponse.java
index e3b44f2..d860454 100644
--- a/api/src/org/apache/cloudstack/api/response/VpcResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/VpcResponse.java
@@ -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;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/engine/schema/src/com/cloud/network/dao/NetworkVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkVO.java b/engine/schema/src/com/cloud/network/dao/NetworkVO.java
index 13e8dbf..dc9d60a 100644
--- a/engine/schema/src/com/cloud/network/dao/NetworkVO.java
+++ b/engine/schema/src/com/cloud/network/dao/NetworkVO.java
@@ -167,6 +167,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();
     }
@@ -589,4 +592,13 @@ public class NetworkVO implements Network {
     public IAMEntityType getEntityType() {
         return IAMEntityType.Network;
     }
+
+    @Override
+    public boolean isStrechedL2Network() {
+        return strechedL2Network;
+    }
+
+    public void setStrechedL2Network(boolean strechedL2Network) {
+        this.strechedL2Network = strechedL2Network;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java b/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
index 53f6f60..a7d61b3 100644
--- a/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
+++ b/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
@@ -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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/engine/schema/src/com/cloud/network/vpc/VpcVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/vpc/VpcVO.java b/engine/schema/src/com/cloud/network/vpc/VpcVO.java
index dea8c31..8d0f6a2 100644
--- a/engine/schema/src/com/cloud/network/vpc/VpcVO.java
+++ b/engine/schema/src/com/cloud/network/vpc/VpcVO.java
@@ -84,12 +84,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;
@@ -101,6 +104,7 @@ public class VpcVO implements Vpc {
         this.networkDomain = networkDomain;
         this.vpcOfferingId = vpcOffId;
         this.usesDistributedRouter = useDistributedRouter;
+        this.regionLevelVpc = regionLevelVpc;
     }
 
     @Override
@@ -193,6 +197,11 @@ public class VpcVO implements Vpc {
         this.uuid = uuid;
     }
 
+    @Override
+    public boolean isRegionLevelVpc() {
+        return regionLevelVpc;
+    }
+
 
     public void setDisplay(boolean display) {
         this.display = display;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java
index bf07807..c3d849d 100755
--- a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java
+++ b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java
@@ -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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
index 036c319..d767834 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
@@ -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);
 
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index a37bf7b..bc496a3 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -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>();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 9b9bd13..bdceed7 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -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);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
index 13246a7..ddf1f9c 100644
--- a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
+++ b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
@@ -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);
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index 2e63639..ad212b0 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -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;
@@ -65,7 +67,6 @@ import com.cloud.exception.PermissionDeniedException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.element.NetworkElement;
 import com.cloud.network.IpAddress;
 import com.cloud.network.IpAddressManager;
 import com.cloud.network.Network;
@@ -220,44 +221,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);
@@ -381,9 +387,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;
@@ -393,45 +399,49 @@ 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());
+                        }
                     }
-                } else {
-                    throw new InvalidParameterValueException("Provider is missing for the VPC offering service " + service.getName());
                 }
-            }
-        }
 
-        return offering;
-    }
+                return offering;
+            }
         });
     }
 
-    private boolean isVpcOfferingSupportsDistributedRouter(Map serviceCapabilitystList) {
-        boolean supportsDistributedRouter = false;
+    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();
@@ -448,24 +458,56 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
                 }
 
                 if (!svc.equalsIgnoreCase(Service.Connectivity.getName())) {
-                    throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only for 'Connectivity' service capabilities can be specified");
+                    throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only 'Connectivity'" +
+                            " service capabilities can be specified");
                 }
 
-                if (!capabilityName.equalsIgnoreCase("DistributedRouter")) {
-                    throw new InvalidParameterValueException("Invalid Capability:" + capabilityName + " specified. Only 'DistributedRouter' capability 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.");
                 }
-                supportsDistributedRouter = capabilityValue.equalsIgnoreCase("true");
+            }
+
+            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.");
+                            }
+                        }
+                    }
+                }
             }
         }
-        return supportsDistributedRouter;
     }
 
-    private void validateConnectivtyServiceCapablitlies(Set<Provider> providers, Map serviceCapabilitystList) {
-
+    private boolean isVpcOfferingForRegionLevelVpc(Map serviceCapabilitystList) {
+        boolean offersRegionLevelVPC = false;
         if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
             Collection serviceCapabilityCollection = serviceCapabilitystList.values();
             Iterator iter = serviceCapabilityCollection.iterator();
@@ -489,29 +531,55 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
                     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 (!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;
+    }
 
-            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.");
-                        }
-                    }
+    private boolean isVpcOfferingSupportsDistributedRouter(Map serviceCapabilitystList) {
+        boolean supportsDistributedRouter = 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("DistributedRouter")) {
+                    continue;
+                }
+
+                if (!capabilityValue.equalsIgnoreCase("true") && capabilityValue.equalsIgnoreCase("false")) {
+                    throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified.");
+                }
+                supportsDistributedRouter = capabilityValue.equalsIgnoreCase("true");
             }
         }
+        return supportsDistributedRouter;
     }
 
     @Override
@@ -708,6 +776,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) {
@@ -730,13 +803,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)) {
@@ -759,7 +834,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);
                 }
@@ -2210,7 +2286,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");
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/server/src/com/cloud/server/ConfigurationServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java
index b8da4c8..4781010 100755
--- a/server/src/com/cloud/server/ConfigurationServerImpl.java
+++ b/server/src/com/cloud/server/ConfigurationServerImpl.java
@@ -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);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 393613a..6a7345c 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -2642,7 +2642,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());
             }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/server/test/com/cloud/network/CreatePrivateNetworkTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/network/CreatePrivateNetworkTest.java b/server/test/com/cloud/network/CreatePrivateNetworkTest.java
index dc979d0..b124b20 100644
--- a/server/test/com/cloud/network/CreatePrivateNetworkTest.java
+++ b/server/test/com/cloud/network/CreatePrivateNetworkTest.java
@@ -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);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
index ac303dd..387a710 100644
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -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;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/server/test/com/cloud/vpc/VpcApiUnitTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/VpcApiUnitTest.java b/server/test/com/cloud/vpc/VpcApiUnitTest.java
index 5e28374..dee9afe 100644
--- a/server/test/com/cloud/vpc/VpcApiUnitTest.java
+++ b/server/test/com/cloud/vpc/VpcApiUnitTest.java
@@ -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);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java b/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
index e1a6ac2..7492598 100644
--- a/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
+++ b/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
@@ -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);
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/setup/db/db/schema-430to440.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql
index 1d511c4..b71ce85 100644
--- a/setup/db/db/schema-430to440.sql
+++ b/setup/db/db/schema-430to440.sql
@@ -742,6 +742,8 @@ 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`.`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;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a929d1a/test/integration/component/test_region_vpc.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_region_vpc.py b/test/integration/component/test_region_vpc.py
new file mode 100644
index 0000000..2cd9de9
--- /dev/null
+++ b/test/integration/component/test_region_vpc.py
@@ -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
\ No newline at end of file


Mime
View raw message