diff --git a/api/src/com/cloud/network/Site2SiteVpnConnection.java b/api/src/com/cloud/network/Site2SiteVpnConnection.java index 810f9992d93..984b0519ddc 100644 --- a/api/src/com/cloud/network/Site2SiteVpnConnection.java +++ b/api/src/com/cloud/network/Site2SiteVpnConnection.java @@ -35,4 +35,5 @@ public interface Site2SiteVpnConnection extends ControlledEntity, InternalIdenti public State getState(); public Date getCreated(); public Date getRemoved(); + public boolean isPassive(); } diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index e56fdbc8715..b1bfcfbf6f5 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -524,6 +524,7 @@ public class ApiConstants { public static final String RESOURCE_DETAILS = "resourcedetails"; public static final String EXPUNGE = "expunge"; public static final String FOR_DISPLAY = "fordisplay"; + public static final String PASSIVE = "passive"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnConnectionCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnConnectionCmd.java index a8c6dc2f0be..b5cebf36afe 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnConnectionCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnConnectionCmd.java @@ -53,6 +53,9 @@ public class CreateVpnConnectionCmd extends BaseAsyncCreateCmd { required=true, description="id of the customer gateway") private Long customerGatewayId; + @Parameter(name=ApiConstants.PASSIVE, type=CommandType.BOOLEAN, required=false, description="connection is passive or not") + private Boolean passive; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -65,6 +68,13 @@ public class CreateVpnConnectionCmd extends BaseAsyncCreateCmd { public Long getCustomerGatewayId() { return customerGatewayId; } + + public boolean isPassive() { + if (passive == null) { + return false; + } + return passive; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java b/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java index 99075b5f213..b4cf5e7d113 100644 --- a/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java +++ b/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java @@ -68,6 +68,9 @@ public class Site2SiteVpnConnectionResponse extends BaseResponse implements Cont @SerializedName(ApiConstants.STATE) @Param(description="State of vpn connection") private String state; + @SerializedName(ApiConstants.PASSIVE) @Param(description="State of vpn connection") + private boolean passive; + @SerializedName(ApiConstants.ACCOUNT) @Param(description="the owner") private String accountName; @@ -141,6 +144,10 @@ public class Site2SiteVpnConnectionResponse extends BaseResponse implements Cont this.state = state; } + public void setPassive(boolean passive) { + this.passive = passive; + } + public void setCreated(Date created) { this.created = created; } diff --git a/core/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java b/core/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java index 83163039f51..d54c29c9c86 100644 --- a/core/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java +++ b/core/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java @@ -30,6 +30,7 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand { private long ikeLifetime; private long espLifetime; private boolean dpd; + private boolean passive; @Override public boolean executeInSequence() { @@ -41,7 +42,7 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand { } public Site2SiteVpnCfgCommand (boolean create, String localPublicIp, String localPublicGateway, String localGuestCidr, String peerGatewayIp, - String peerGuestCidrList, String ikePolicy, String espPolicy, String ipsecPsk, Long ikeLifetime, Long espLifetime, Boolean dpd) { + String peerGuestCidrList, String ikePolicy, String espPolicy, String ipsecPsk, Long ikeLifetime, Long espLifetime, Boolean dpd, boolean passive) { this.create = create; this.setLocalPublicIp(localPublicIp); this.setLocalPublicGateway(localPublicGateway); @@ -54,6 +55,7 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand { this.ikeLifetime = ikeLifetime; this.espLifetime = espLifetime; this.dpd = dpd; + this.passive = passive; } public boolean isCreate() { @@ -151,4 +153,12 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand { public void setPeerGuestCidrList(String peerGuestCidrList) { this.peerGuestCidrList = peerGuestCidrList; } + + public boolean isPassive() { + return passive; + } + + public void setPassive(boolean passive) { + this.passive = passive; + } } diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 874146c6258..4c2ee505117 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -761,6 +761,9 @@ public class VirtualRoutingResource implements Manager { } else { args += "0"; } + if (cmd.isPassive()) { + args += " -p "; + } } else { args = "-D"; args += " -r "; diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java b/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java index f8eeb8a9912..d99823f2e0a 100644 --- a/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java +++ b/engine/schema/src/com/cloud/network/dao/Site2SiteVpnConnectionVO.java @@ -66,15 +66,19 @@ public class Site2SiteVpnConnectionVO implements Site2SiteVpnConnection, Interna @Column(name=GenericDao.REMOVED_COLUMN) private Date removed; + @Column(name="passive") + private boolean passive; + public Site2SiteVpnConnectionVO() { } - public Site2SiteVpnConnectionVO(long accountId, long domainId, long vpnGatewayId, long customerGatewayId) { + public Site2SiteVpnConnectionVO(long accountId, long domainId, long vpnGatewayId, long customerGatewayId, boolean passive) { this.uuid = UUID.randomUUID().toString(); this.setVpnGatewayId(vpnGatewayId); this.setCustomerGatewayId(customerGatewayId); this.setState(State.Pending); this.accountId = accountId; this.domainId = domainId; + this.passive = passive; } @Override @@ -140,4 +144,12 @@ public class Site2SiteVpnConnectionVO implements Site2SiteVpnConnection, Interna public long getAccountId() { return accountId; } + + public boolean isPassive() { + return passive; + } + + public void setPassive(boolean passive) { + this.passive = passive; + } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 423abe67a47..6d3d34a27e0 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1559,6 +1559,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } else { args += "0"; } + if (cmd.isPassive()) { + args += " -p "; + } } else { args += " -D"; args += " -r "; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 3323a15ba9d..3df28ed0c7e 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -8519,6 +8519,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } else { args += "0"; } + if (cmd.isPassive()) { + args += " -p "; + } } else { args += " -D"; args += " -r "; diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index de4cc66c365..769d34562c3 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -3195,6 +3195,7 @@ public class ApiResponseHelper implements ResponseGenerator { public Site2SiteVpnConnectionResponse createSite2SiteVpnConnectionResponse(Site2SiteVpnConnection result) { Site2SiteVpnConnectionResponse response = new Site2SiteVpnConnectionResponse(); response.setId(result.getUuid()); + response.setPassive(result.isPassive()); Long vpnGatewayId = result.getVpnGatewayId(); if (vpnGatewayId != null) { diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index 63eb75b672e..ecfce575fd0 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -1122,7 +1122,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian Boolean dpd = gw.getDpd(); Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(isCreate, localPublicIp, localPublicGateway, localGuestCidr, - peerGatewayIp, peerGuestCidrList, ikePolicy, espPolicy, ipsecPsk, ikeLifetime, espLifetime, dpd); + peerGatewayIp, peerGuestCidrList, ikePolicy, espPolicy, ipsecPsk, ikeLifetime, espLifetime, dpd, conn.isPassive()); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index f29a8c87054..94d2dc3e223 100644 --- a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -290,7 +290,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn } } - Site2SiteVpnConnectionVO conn = new Site2SiteVpnConnectionVO(owner.getAccountId(), owner.getDomainId(), vpnGatewayId, customerGatewayId); + Site2SiteVpnConnectionVO conn = new Site2SiteVpnConnectionVO(owner.getAccountId(), owner.getDomainId(), vpnGatewayId, customerGatewayId, cmd.isPassive()); conn.setState(State.Pending); _vpnConnectionDao.persist(conn); return conn; @@ -317,7 +317,11 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn } if (result) { - conn.setState(State.Connected); + if (conn.isPassive()) { + conn.setState(State.Disconnected); + } else { + conn.setState(State.Connected); + } _vpnConnectionDao.persist(conn); return conn; } diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index 803f1d965f1..0de9dfd9a74 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -119,6 +119,8 @@ UPDATE `cloud`.`vm_template` SET `removed`=NULL; ALTER TABLE `cloud`.`remote_access_vpn` MODIFY COLUMN `network_id` bigint unsigned; ALTER TABLE `cloud`.`remote_access_vpn` ADD COLUMN `vpc_id` bigint unsigned default NULL; +ALTER TABLE `cloud`.`s2s_vpn_connection` ADD COLUMN `passive` int(1) unsigned NOT NULL DEFAULT 0; + DROP VIEW IF EXISTS `cloud`.`disk_offering_view`; CREATE VIEW `cloud`.`disk_offering_view` AS select diff --git a/systemvm/patches/debian/config/opt/cloud/bin/ipsectunnel.sh b/systemvm/patches/debian/config/opt/cloud/bin/ipsectunnel.sh index e511a3d966a..e20c10f9e6d 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/ipsectunnel.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/ipsectunnel.sh @@ -30,7 +30,7 @@ vpnoutmark="0x525" vpninmark="0x524" usage() { - printf "Usage: %s: (-A|-D) -l -n -g -r -N -e -i -t -T -s -d \n" $(basename $0) >&2 + printf "Usage: %s: (-A|-D) -l -n -g -r -N -e -i -t -T -s -d [ -p ]\n" $(basename $0) >&2 } #set -x @@ -173,29 +173,35 @@ ipsec_tunnel_add() { sudo ipsec auto --rereadall sudo ipsec auto --add vpn-$rightpeer - sudo ipsec auto --up vpn-$rightpeer logger -t cloud "$(basename $0): done ipsec tunnel entry for right peer=$rightpeer right networks=$rightnets" - #5 seconds for checking if it's ready - for i in {1..5} - do - logger -t cloud "$(basename $0): checking connection status..." - /opt/cloud/bin/checks2svpn.sh $rightpeer - result=$? + result=0 + + if [ $passive -eq 0 ] + then + sudo ipsec auto --up vpn-$rightpeer + + #5 seconds for checking if it's ready + for i in {1..5} + do + logger -t cloud "$(basename $0): checking connection status..." + /opt/cloud/bin/checks2svpn.sh $rightpeer + result=$? + if [ $result -eq 0 ] + then + break + fi + sleep 1 + done if [ $result -eq 0 ] then - break + logger -t cloud "$(basename $0): connect to remote successful" + else + logger -t cloud "$(basename $0): fail to connect to remote, status code: $result" + logger -t cloud "$(basename $0): would stop site-to-site VPN connection" + ipsec_tunnel_del fi - sleep 1 - done - if [ $result -eq 0 ] - then - logger -t cloud "$(basename $0): connect to remote successful" - else - logger -t cloud "$(basename $0): fail to connect to remote, status code: $result" - logger -t cloud "$(basename $0): would stop site-to-site VPN connection" - ipsec_tunnel_del fi return $result } @@ -208,9 +214,10 @@ lflag= iflag= Iflag= sflag= +passive=0 op="" -while getopts 'ADl:n:g:r:N:e:i:t:T:s:d:' OPTION +while getopts 'ADpl:n:g:r:N:e:i:t:T:s:d:' OPTION do case $OPTION in A) opflag=1 @@ -252,6 +259,8 @@ do d) dflag=1 dpd="$OPTARG" ;; + p) passive=1 + ;; ?) usage unlock_exit 2 $lock $locked ;; diff --git a/test/integration/smoke/test_vpc_vpn.py b/test/integration/smoke/test_vpc_vpn.py index c360884ce4c..5e97c79065f 100644 --- a/test/integration/smoke/test_vpc_vpn.py +++ b/test/integration/smoke/test_vpc_vpn.py @@ -24,6 +24,8 @@ from marvin.integration.lib.base import * from marvin.integration.lib.common import * from nose.plugins.attrib import attr +import time + class Services: def __init__(self): self.services = { @@ -77,15 +79,37 @@ class Services: "vpn_user": { "username": "test", "password": "password", + }, + "vpc": { + "name": "vpc_vpn", + "displaytext": "vpc-vpn", + "cidr": "10.1.1.0/24" + }, + "ntwk": { + "name": "tier1", + "displaytext": "vpc-tier1", + "gateway" : "10.1.1.1", + "netmask" : "255.255.255.192" + }, + "vpc2": { + "name": "vpc2_vpn", + "displaytext": "vpc2-vpn", + "cidr": "10.2.1.0/24" + }, + "ntwk2": { + "name": "tier2", + "displaytext": "vpc-tier2", + "gateway" : "10.2.1.1", + "netmask" : "255.255.255.192" } } -class TestVpcVpn(cloudstackTestCase): +class TestVpcRemoteAccessVpn(cloudstackTestCase): @classmethod def setUpClass(cls): - cls.apiclient = super(TestVpcVpn, cls).getClsTestClient().getApiClient() + cls.apiclient = super(TestVpcRemoteAccessVpn, cls).getClsTestClient().getApiClient() cls.services = Services().services cls.zone = get_zone(cls.apiclient, cls.services) cls.domain = get_domain(cls.apiclient) @@ -102,7 +126,7 @@ class TestVpcVpn(cloudstackTestCase): cls.cleanup = [cls.account] @attr(tags=["advanced"]) - def test_vpc_vpn(self): + def test_vpc_remote_access_vpn(self): """Test VPN in VPC""" # 0) Get the default network offering for VPC @@ -112,10 +136,6 @@ class TestVpcVpn(cloudstackTestCase): # 1) Create VPC vpcOffering = VpcOffering.list(self.apiclient,isdefault=True) self.assert_(vpcOffering is not None and len(vpcOffering)>0, "No VPC offerings found") - self.services["vpc"] = {} - self.services["vpc"]["name"] = "vpc-vpn" - self.services["vpc"]["displaytext"] = "vpc-vpn" - self.services["vpc"]["cidr"] = "10.1.1.0/24" vpc = VPC.create( apiclient=self.apiclient, services=self.services["vpc"], @@ -126,33 +146,29 @@ class TestVpcVpn(cloudstackTestCase): domainid=self.domain.id ) self.assert_(vpc is not None, "VPC creation failed") + self.debug("VPC %s created" %(vpc.id)) # 2) Create network in VPC - self.services["vpcnetwork"] = {} - self.services["vpcnetwork"]["name"] = "vpcntwk" - self.services["vpcnetwork"]["displaytext"] = "vpcntwk" ntwk = Network.create( apiclient=self.apiclient, - services=self.services["vpcnetwork"], + services=self.services["ntwk"], accountid=self.account.name, domainid=self.domain.id, networkofferingid=networkOffering[0].id, zoneid=self.zone.id, - vpcid=vpc.id, - gateway="10.1.1.1", - netmask="255.255.255.192" + vpcid=vpc.id ) self.assertIsNotNone(ntwk, "Network failed to create") self.debug("Network %s created in VPC %s" %(ntwk.id, vpc.id)) # 3) Deploy a vm - self.services["virtual_machine"]["networkids"] = ntwk.id vm = VirtualMachine.create(self.apiclient, services=self.services["virtual_machine"], templateid=self.template.id, zoneid=self.zone.id, accountid=self.account.name, domainid= self.domain.id, serviceofferingid=self.service_offering.id, + networkids=ntwk.id ) self.assert_(vm is not None, "VM failed to deploy") self.assert_(vm.state == 'Running', "VM is not running") @@ -190,3 +206,186 @@ class TestVpcVpn(cloudstackTestCase): cleanup_resources(cls.apiclient, cls.cleanup) except Exception, e: raise Exception("Cleanup failed with %s" % e) + +class TestVpcSite2SiteVpn(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.apiclient = super(TestVpcSite2SiteVpn, cls).getClsTestClient().getApiClient() + cls.services = Services().services + cls.zone = get_zone(cls.apiclient, cls.services) + cls.domain = get_domain(cls.apiclient) + cls.service_offering = ServiceOffering.create( + cls.apiclient, + cls.services["service_offering"] + ) + cls.account = Account.create(cls.apiclient, services=cls.services["account"]) + cls.template = get_template( + cls.apiclient, + cls.zone.id, + cls.services["ostype"] + ) + cls.cleanup = [cls.account] + + @attr(tags=["advanced"]) + def test_vpc_site2site_vpn(self): + """Test VPN in VPC""" + + # 0) Get the default network offering for VPC + networkOffering = NetworkOffering.list(self.apiclient, name="DefaultIsolatedNetworkOfferingForVpcNetworks") + self.assert_(networkOffering is not None and len(networkOffering) > 0, "No VPC based network offering") + + # 1) Create VPC + vpcOffering = VpcOffering.list(self.apiclient,isdefault=True) + self.assert_(vpcOffering is not None and len(vpcOffering)>0, "No VPC offerings found") + + vpc1 = VPC.create( + apiclient=self.apiclient, + services=self.services["vpc"], + networkDomain="vpc1.vpn", + vpcofferingid=vpcOffering[0].id, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.domain.id + ) + self.assert_(vpc1 is not None, "VPC creation failed") + self.debug("VPC1 %s created" %(vpc1.id)) + + vpc2 = VPC.create( + apiclient=self.apiclient, + services=self.services["vpc2"], + networkDomain="vpc2.vpn", + vpcofferingid=vpcOffering[0].id, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.domain.id + ) + self.assert_(vpc2 is not None, "VPC2 creation failed") + self.debug("VPC2 %s created" %(vpc1.id)) + + # 2) Create network in VPC + ntwk1 = Network.create( + apiclient=self.apiclient, + services=self.services["ntwk"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=networkOffering[0].id, + zoneid=self.zone.id, + vpcid=vpc1.id + ) + self.assertIsNotNone(ntwk1, "Network failed to create") + self.debug("Network %s created in VPC %s" %(ntwk1.id, vpc1.id)) + + ntwk2 = Network.create( + apiclient=self.apiclient, + services=self.services["ntwk2"], + accountid=self.account.name, + domainid=self.domain.id, + networkofferingid=networkOffering[0].id, + zoneid=self.zone.id, + vpcid=vpc2.id + ) + self.assertIsNotNone(ntwk2, "Network failed to create") + self.debug("Network %s created in VPC %s" %(ntwk2.id, vpc2.id)) + + # 3) Deploy a vm + vm1 = VirtualMachine.create(self.apiclient, services=self.services["virtual_machine"], + templateid=self.template.id, + zoneid=self.zone.id, + accountid=self.account.name, + domainid= self.domain.id, + serviceofferingid=self.service_offering.id, + networkids=ntwk1.id + ) + self.assert_(vm1 is not None, "VM failed to deploy") + self.assert_(vm1.state == 'Running', "VM is not running") + self.debug("VM %s deployed in VPC %s" %(vm1.id, vpc1.id)) + + vm2 = VirtualMachine.create(self.apiclient, services=self.services["virtual_machine"], + templateid=self.template.id, + zoneid=self.zone.id, + accountid=self.account.name, + domainid= self.domain.id, + serviceofferingid=self.service_offering.id, + networkids=ntwk2.id + ) + self.assert_(vm2 is not None, "VM failed to deploy") + self.assert_(vm2.state == 'Running', "VM is not running") + self.debug("VM %s deployed in VPC %s" %(vm2.id, vpc2.id)) + + # 4) Enable Site-to-Site VPN for VPC + cmd=createVpnGateway.createVpnGatewayCmd() + cmd.vpcid=vpc1.id + vpn1_response = self.apiclient.createVpnGateway(cmd) + + self.debug("VPN gateway for VPC %s enabled" % (vpc1.id)) + + cmd=createVpnGateway.createVpnGatewayCmd() + cmd.vpcid=vpc2.id + vpn2_response = self.apiclient.createVpnGateway(cmd) + + self.debug("VPN gateway for VPC %s enabled" %(vpc2.id)) + + # 5) Add VPN Customer gateway info + + src_nat_list = PublicIPAddress.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + listall=True, + issourcenat=True, + vpcid=vpc1.id + ) + ip1 = src_nat_list[0] + + src_nat_list = PublicIPAddress.list( + self.apiclient, + account=self.account.name, + domainid=self.account.domainid, + listall=True, + issourcenat=True, + vpcid=vpc2.id + ) + ip2 = src_nat_list[0] + + cmd=createVpnCustomerGateway.createVpnCustomerGatewayCmd() + cmd.esppolicy="3des-md5;modp1536" + cmd.ikepolicy="3des-md5;modp1536" + cmd.domainid=self.account.domainid + cmd.account=self.account.name + cmd.ipsecpsk="ipsecpsk" + + cmd.name="Peer VPC1" + cmd.gateway=ip1.ipaddress + cmd.cidrlist=vpc1.cidr + customer1_response = self.apiclient.createVpnCustomerGateway(cmd) + self.debug("VPN customer gateway added for VPC %s enabled" %(vpc1.id)) + + cmd.name="Peer VPC2" + cmd.gateway=ip2.ipaddress + cmd.cidrlist=vpc2.cidr + customer2_response = self.apiclient.createVpnCustomerGateway(cmd) + self.debug("VPN customer gateway added for VPC %s enabled" %(vpc2.id)) + + # 6) Connect two VPCs + cmd = createVpnConnection.createVpnConnectionCmd() + cmd.s2svpngatewayid = vpn2_response.id + cmd.s2scustomergatewayid = customer1_response.id + cmd.passive="true" + vpnconn1_response = self.apiclient.createVpnConnection(cmd) + self.debug("VPN passive connection created for VPC %s" %(vpc2.id)) + + cmd = createVpnConnection.createVpnConnectionCmd() + cmd.s2svpngatewayid = vpn1_response.id + cmd.s2scustomergatewayid = customer2_response.id + vpnconn2_response = self.apiclient.createVpnConnection(cmd) + self.debug("VPN connection created for VPC %s" %(vpc1.id)) + + self.assertEqual(vpnconn2_response.state, "Connected", "Failed to connect between VPCs!") + + @classmethod + def tearDownClass(cls): + try: + cleanup_resources(cls.apiclient, cls.cleanup) + except Exception, e: + raise Exception("Cleanup failed with %s" % e)