# 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.
""" Tests for VPN in VPC
"""
# Import Local Modules
from marvin.codes import PASS, FAILED
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.utils import (validateList,
                              wait_until)

from marvin.lib.base import (Account,
                             VPC,
                             VpcOffering,
                             ServiceOffering,
                             NetworkOffering,
                             Network,
                             PublicIPAddress,
                             NATRule,
                             NetworkACLList,
                             VirtualMachine,
                             Vpn,
                             VpnCustomerGateway,
                             VpnUser
                             )

from marvin.sshClient import SshClient


from marvin.lib.common import (get_zone,
                               get_domain,
                               get_test_template)

from nose.plugins.attrib import attr

import logging
import time


class Services:

    """Test VPC VPN Services.
    """

    def __init__(self):
        self.services = {
            "account": {
                "email": "test@test.com",
                "firstname": "Test",
                "lastname": "User",
                "username": "test",
                "password": "password",
            },
            "host1": None,
            "host2": None,
            "compute_offering": {
                "name": "Tiny Instance",
                "displaytext": "Tiny Instance",
                "cpunumber": 1,
                "cpuspeed": 100,
                "memory": 128,
            },
            "network_offering": {
                "name": 'VPC Network offering',
                "displaytext": 'VPC Network',
                "guestiptype": 'Isolated',
                "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,Lb,PortForwarding,UserData,StaticNat,NetworkACL',
                "traffictype": 'GUEST',
                "availability": 'Optional',
                "useVpc": 'on',
                "serviceProviderList": {
                    "Vpn": 'VpcVirtualRouter',
                    "Dhcp": 'VpcVirtualRouter',
                    "Dns": 'VpcVirtualRouter',
                    "SourceNat": 'VpcVirtualRouter',
                    "Lb": 'VpcVirtualRouter',
                    "PortForwarding": 'VpcVirtualRouter',
                    "UserData": 'VpcVirtualRouter',
                    "StaticNat": 'VpcVirtualRouter',
                    "NetworkACL": 'VpcVirtualRouter'
                },
            },
            "network_offering_internal_lb": {
                "name": 'VPC Network Internal Lb offering',
                "displaytext": 'VPC Network internal lb',
                "guestiptype": 'Isolated',
                "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,UserData,StaticNat,NetworkACL,Lb',
                "traffictype": 'GUEST',
                "availability": 'Optional',
                "useVpc": 'on',
                "serviceCapabilityList": {
                    "Lb": {
                        "SupportedLbIsolation": 'dedicated',
                        "lbSchemes": 'internal'
                    }
                },
                "serviceProviderList": {
                    "Dhcp": 'VpcVirtualRouter',
                    "Dns": 'VpcVirtualRouter',
                    "SourceNat": 'VpcVirtualRouter',
                    "PortForwarding": 'VpcVirtualRouter',
                    "UserData": 'VpcVirtualRouter',
                    "StaticNat": 'VpcVirtualRouter',
                    "NetworkACL": 'VpcVirtualRouter',
                    "Lb": 'InternalLbVm'
                },
                "egress_policy": "true",
            },
            "vpc_offering": {
                "name": 'VPC off',
                "displaytext": 'VPC off',
                "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat',
            },
            "redundant_vpc_offering": {
                "name": 'Redundant VPC off',
                "displaytext": 'Redundant VPC off',
                "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat',
                "serviceProviderList": {
                    "Vpn": 'VpcVirtualRouter',
                    "Dhcp": 'VpcVirtualRouter',
                    "Dns": 'VpcVirtualRouter',
                    "SourceNat": 'VpcVirtualRouter',
                    "PortForwarding": 'VpcVirtualRouter',
                    "Lb": 'VpcVirtualRouter',
                    "UserData": 'VpcVirtualRouter',
                    "StaticNat": 'VpcVirtualRouter',
                    "NetworkACL": 'VpcVirtualRouter'
                },
                "serviceCapabilityList": {
                    "SourceNat": {
                        "RedundantRouter": 'true'
                    }
                },
            },
            "vpc": {
                "name": "TestVPC",
                "displaytext": "TestVPC",
                "cidr": '10.1.0.0/16'
            },
            "vpc1": {
                "name": "TestVPC",
                "displaytext": "VPC1",
                "cidr": '10.1.0.0/16'
            },
            "vpc2": {
                "name": "TestVPC",
                "displaytext": "VPC2",
                "cidr": '10.3.0.0/16'
            },
            "network_1": {
                "name": "Test Network",
                "displaytext": "Test Network",
                "netmask": '255.255.255.0',
                "gateway": "10.1.1.1"
            },
            "network_2": {
                "name": "Test Network",
                "displaytext": "Test Network",
                "netmask": '255.255.255.0',
                "gateway": "10.3.1.1"
            },
            "vpn": {
                "vpn_user": "root",
                "vpn_pass": "Md1sdc",
                "vpn_pass_fail": "abc!123",  # too short
                "iprange": "10.3.2.1-10.3.2.10",
                "fordisplay": "true"
            },
            "vpncustomergateway": {
                "esppolicy": "3des-md5;modp1536",
                "ikepolicy": "3des-md5;modp1536",
                "ipsecpsk": "ipsecpsk"
            },
            "natrule": {
                "protocol": "TCP",
                "cidrlist": '0.0.0.0/0',
            },
            "http_rule": {
                "privateport": 80,
                "publicport": 80,
                "startport": 80,
                "endport": 80,
                "cidrlist": '0.0.0.0/0',
                "protocol": "TCP"
            },
            "virtual_machine": {
                "displayname": "Test VM",
                "username": "root",
                "password": "password",
                "ssh_port": 22,
                "privateport": 22,
                "publicport": 22,
                "protocol": 'TCP',
            }
        }


class TestVpcRemoteAccessVpn(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):

        cls.logger = logging.getLogger('TestVPCRemoteAccessVPN')
        cls.stream_handler = logging.StreamHandler()
        cls.logger.setLevel(logging.DEBUG)
        cls.logger.addHandler(cls.stream_handler)

        testClient = super(TestVpcRemoteAccessVpn, cls).getClsTestClient()
        cls.apiclient = testClient.getApiClient()
        cls.services = Services().services

        cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
        cls.domain = get_domain(cls.apiclient)

        cls._cleanup = []

        cls.compute_offering = ServiceOffering.create(
            cls.apiclient,
            cls.services["compute_offering"]
        )
        cls._cleanup.append(cls.compute_offering)
        cls.account = Account.create(
            cls.apiclient, services=cls.services["account"])
        cls._cleanup.append(cls.account)

        cls.hypervisor = testClient.getHypervisorInfo()

        cls.template = get_test_template(cls.apiclient, cls.zone.id, cls.hypervisor)
        if cls.template == FAILED:
            assert False, "get_test_template() failed to return template"

        cls.logger.debug("Successfully created account: %s, id: \
                   %s" % (cls.account.name,
                          cls.account.id))

        return

    @attr(tags=["advanced"], required_hardware="true")
    def test_01_vpc_remote_access_vpn(self):
        """Test Remote Access VPN in VPC"""

        self.logger.debug("Starting test: test_01_vpc_remote_access_vpn")

        # 0) Get the default network offering for VPC
        self.logger.debug("Retrieving default VPC offering")
        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, name="Default VPC offering")
        self.assert_(vpcOffering is not None and len(
            vpcOffering) > 0, "No VPC offerings found")

        vpc = None
        try:
            vpc = VPC.create(
                apiclient=self.apiclient,
                services=self.services["vpc"],
                networkDomain="vpc.vpn",
                vpcofferingid=vpcOffering[0].id,
                zoneid=self.zone.id,
                account=self.account.name,
                domainid=self.domain.id
            )
            self.cleanup.append(vpc)
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vpc is not None, "VPC creation failed")
            self.logger.debug("VPC %s created" % (vpc.id))

        try:
            # 2) Create network in VPC
            ntwk = Network.create(
                apiclient=self.apiclient,
                services=self.services["network_1"],
                accountid=self.account.name,
                domainid=self.domain.id,
                networkofferingid=networkOffering[0].id,
                zoneid=self.zone.id,
                vpcid=vpc.id
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assertIsNotNone(ntwk, "Network failed to create")
            self.cleanup.append(ntwk)
            self.logger.debug(
                "Network %s created in VPC %s" % (ntwk.id, vpc.id))

        try:
            # 3) Deploy a vm
            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.compute_offering.id,
                                       networkids=ntwk.id,
                                       hypervisor=self.hypervisor
                                       )
            self.assert_(vm is not None, "VM failed to deploy")
            self.cleanup.append(vm)
            self.assert_(vm.state == 'Running', "VM is not running")
            self.debug("VM %s deployed in VPC %s" % (vm.id, vpc.id))
        except Exception as e:
            self.fail(e)
        finally:
            self.logger.debug("Deployed virtual machine: OK")

        try:
            # 4) Enable VPN for VPC
            src_nat_list = PublicIPAddress.list(
                self.apiclient,
                account=self.account.name,
                domainid=self.account.domainid,
                listall=True,
                issourcenat=True,
                vpcid=vpc.id
            )
            ip = src_nat_list[0]
        except Exception as e:
            self.fail(e)
        finally:
            self.logger.debug("Acquired public ip address: OK")

        vpn = None
        try:
            vpn = Vpn.create(self.apiclient,
                             publicipid=ip.id,
                             account=self.account.name,
                             domainid=self.account.domainid,
                             iprange=self.services["vpn"]["iprange"],
                             fordisplay=self.services["vpn"]["fordisplay"]
                             )
        except Exception as e:
            self.fail(e)
        finally:
            self.assertIsNotNone(vpn, "Failed to create Remote Access VPN")
            self.logger.debug("Created Remote Access VPN: OK")

        vpnUser = None
        # 5) Add VPN user for VPC
        try:
            vpnUser = VpnUser.create(self.apiclient,
                                     account=self.account.name,
                                     domainid=self.account.domainid,
                                     username=self.services["vpn"]["vpn_user"],
                                     password=self.services["vpn"]["vpn_pass"]
                                     )
        except Exception as e:
            self.fail(e)
        finally:
            self.assertIsNotNone(
                vpnUser, "Failed to create Remote Access VPN User")
            self.logger.debug("Created VPN User: OK")

        # TODO: Add an actual remote vpn connection test from a remote vpc

        try:
            # 9) Disable VPN for VPC
            vpn.delete(self.apiclient)
        except Exception as e:
            self.fail(e)
        finally:
            self.logger.debug("Deleted the Remote Access VPN: OK")

    @classmethod
    def tearDownClass(cls):
        super(TestVpcRemoteAccessVpn, cls).tearDownClass()

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.hypervisor = self.testClient.getHypervisorInfo()
        self.cleanup = []

    def tearDown(self):
        super(TestVpcRemoteAccessVpn, self).tearDown()


class TestVpcSite2SiteVpn(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cls.logger = logging.getLogger('TestVPCSite2SiteVPN')
        cls.stream_handler = logging.StreamHandler()
        cls.logger.setLevel(logging.DEBUG)
        cls.logger.addHandler(cls.stream_handler)

        testClient = super(TestVpcSite2SiteVpn, cls).getClsTestClient()
        cls.apiclient = testClient.getApiClient()
        cls.services = Services().services

        cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
        cls.domain = get_domain(cls.apiclient)

        cls._cleanup = []

        cls.compute_offering = ServiceOffering.create(
            cls.apiclient,
            cls.services["compute_offering"]
        )
        cls._cleanup.append(cls.compute_offering)

        cls.account = Account.create(
            cls.apiclient, services=cls.services["account"])
        cls._cleanup.append(cls.account)

        cls.hypervisor = testClient.getHypervisorInfo()

        cls.template = get_test_template(cls.apiclient, cls.zone.id, cls.hypervisor)
        if cls.template == FAILED:
            assert False, "get_test_template() failed to return template"

        cls.logger.debug("Successfully created account: %s, id: \
                   %s" % (cls.account.name,
                          cls.account.id))
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.hypervisor = self.testClient.getHypervisorInfo()
        self.cleanup = []

    def _get_ssh_client(self, virtual_machine, services, retries):
        """ Setup ssh client connection and return connection
        vm requires attributes public_ip, public_port, username, password """

        try:
            ssh_client = SshClient(
                virtual_machine.public_ip,
                services["virtual_machine"]["ssh_port"],
                services["virtual_machine"]["username"],
                services["virtual_machine"]["password"],
                retries)

        except Exception as e:
            self.fail("Unable to create ssh connection: " % e)

        self.assertIsNotNone(
            ssh_client, "Failed to setup ssh connection to vm=%s on public_ip=%s" % (virtual_machine.name, virtual_machine.public_ip))

        return ssh_client

    def _create_natrule(self, vpc, vm, public_port, private_port, public_ip, network, services=None):
        self.logger.debug("Creating NAT rule in network for vm with public IP")
        if not services:
            self.services["natrule"]["privateport"] = private_port
            self.services["natrule"]["publicport"] = public_port
            self.services["natrule"]["startport"] = public_port
            self.services["natrule"]["endport"] = public_port
            services = self.services["natrule"]

        nat_rule = NATRule.create(
            apiclient=self.apiclient,
            services=services,
            ipaddressid=public_ip.ipaddress.id,
            virtual_machine=vm,
            networkid=network.id
        )
        self.assertIsNotNone(
            nat_rule, "Failed to create NAT Rule for %s" % public_ip.ipaddress.ipaddress)
        self.logger.debug(
            "Adding NetworkACL rules to make NAT rule accessible")

        vm.ssh_ip = nat_rule.ipaddress
        vm.public_ip = nat_rule.ipaddress
        vm.public_port = int(public_port)
        return nat_rule

    def _validate_vpc_offering(self, vpc_offering):

        self.logger.debug("Check if the VPC offering is created successfully?")
        vpc_offs = VpcOffering.list(
            self.apiclient,
            id=vpc_offering.id
        )
        offering_list = validateList(vpc_offs)
        self.assertEqual(offering_list[0],
                         PASS,
                         "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.logger.debug(
            "VPC offering is created successfully - %s" %
            vpc_offering.name)
        return

    def _create_vpc_offering(self, offering_name):

        vpc_off = None
        if offering_name is not None:

            self.logger.debug("Creating VPC offering: %s", offering_name)
            vpc_off = VpcOffering.create(
                self.apiclient,
                self.services[offering_name]
            )

            self._validate_vpc_offering(vpc_off)
            self.cleanup.append(vpc_off)

        return vpc_off

    @attr(tags=["advanced"], required_hardware="true")
    def test_01_vpc_site2site_vpn(self):
        """Test Site 2 Site VPN Across VPCs"""
        self.logger.debug("Starting test: test_01_vpc_site2site_vpn")
        # 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")

        # Create and Enable VPC offering
        vpc_offering = self._create_vpc_offering('vpc_offering')
        self.assert_(vpc_offering is not None, "Failed to create VPC Offering")
        vpc_offering.update(self.apiclient, state='Enabled')

        vpc1 = None
        # Create VPC 1
        try:
            vpc1 = VPC.create(
                apiclient=self.apiclient,
                services=self.services["vpc"],
                networkDomain="vpc1.vpn",
                vpcofferingid=vpc_offering.id,
                zoneid=self.zone.id,
                account=self.account.name,
                domainid=self.domain.id
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vpc1 is not None, "VPC1 creation failed")
        self.cleanup.append(vpc1)
        self.logger.debug("VPC1 %s created" % vpc1.id)

        vpc2 = None
        # Create VPC 2
        try:
            vpc2 = VPC.create(
                apiclient=self.apiclient,
                services=self.services["vpc2"],
                networkDomain="vpc2.vpn",
                vpcofferingid=vpc_offering.id,
                zoneid=self.zone.id,
                account=self.account.name,
                domainid=self.account.domainid
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vpc2 is not None, "VPC2 creation failed")
        self.cleanup.append(vpc2)
        self.logger.debug("VPC2 %s created" % vpc2.id)

        default_acl = NetworkACLList.list(
            self.apiclient, name="default_allow")[0]

        ntwk1 = None
        # Create network in VPC 1
        try:
            ntwk1 = Network.create(
                apiclient=self.apiclient,
                services=self.services["network_1"],
                accountid=self.account.name,
                domainid=self.account.domainid,
                networkofferingid=networkOffering[0].id,
                zoneid=self.zone.id,
                vpcid=vpc1.id,
                aclid=default_acl.id
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assertIsNotNone(ntwk1, "Network failed to create")
        self.cleanup.append(ntwk1)
        self.logger.debug("Network %s created in VPC %s" % (ntwk1.id, vpc1.id))

        ntwk2 = None
        # Create network in VPC 2
        try:
            ntwk2 = Network.create(
                apiclient=self.apiclient,
                services=self.services["network_2"],
                accountid=self.account.name,
                domainid=self.account.domainid,
                networkofferingid=networkOffering[0].id,
                zoneid=self.zone.id,
                vpcid=vpc2.id,
                aclid=default_acl.id
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assertIsNotNone(ntwk2, "Network failed to create")
        self.cleanup.append(ntwk2)
        self.logger.debug("Network %s created in VPC %s" % (ntwk2.id, vpc2.id))

        vm1 = None
        # Deploy a vm in network 2
        try:
            vm1 = VirtualMachine.create(self.apiclient, services=self.services["virtual_machine"],
                                        templateid=self.template.id,
                                        zoneid=self.zone.id,
                                        accountid=self.account.name,
                                        domainid=self.account.domainid,
                                        serviceofferingid=self.compute_offering.id,
                                        networkids=ntwk1.id,
                                        hypervisor=self.hypervisor
                                        )
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vm1 is not None, "VM failed to deploy")
            self.assert_(vm1.state == 'Running', "VM is not running")
        self.cleanup.append(vm1)
        self.logger.debug("VM %s deployed in VPC %s" % (vm1.id, vpc1.id))

        vm2 = None
        # Deploy a vm in network 2
        try:
            vm2 = VirtualMachine.create(self.apiclient, services=self.services["virtual_machine"],
                                        templateid=self.template.id,
                                        zoneid=self.zone.id,
                                        accountid=self.account.name,
                                        domainid=self.account.domainid,
                                        serviceofferingid=self.compute_offering.id,
                                        networkids=ntwk2.id,
                                        hypervisor=self.hypervisor
                                        )
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vm2 is not None, "VM failed to deploy")
            self.assert_(vm2.state == 'Running', "VM is not running")
        self.cleanup.append(vm2)
        self.debug("VM %s deployed in VPC %s" % (vm2.id, vpc2.id))

        # 4) Enable Site-to-Site VPN for VPC
        vpn1_response = Vpn.createVpnGateway(self.apiclient, vpc1.id)
        self.assert_(
            vpn1_response is not None, "Failed to enable VPN Gateway 1")
        self.logger.debug("VPN gateway for VPC %s enabled" % vpc1.id)

        vpn2_response = Vpn.createVpnGateway(self.apiclient, vpc2.id)
        self.assert_(
            vpn2_response is not None, "Failed to enable VPN Gateway 2")
        self.logger.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]

        services = self.services["vpncustomergateway"]
        customer1_response = VpnCustomerGateway.create(
            self.apiclient, services, "Peer VPC1", ip1.ipaddress, vpc1.cidr, self.account.name, self.domain.id)
        self.debug("VPN customer gateway added for VPC %s enabled" % vpc1.id)
        self.logger.debug(vars(customer1_response))

        customer2_response = VpnCustomerGateway.create(
            self.apiclient, services, "Peer VPC2", ip2.ipaddress, vpc2.cidr, self.account.name, self.domain.id)
        self.debug("VPN customer gateway added for VPC %s enabled" % vpc2.id)
        self.logger.debug(vars(customer2_response))

        # 6) Connect two VPCs
        vpnconn1_response = Vpn.createVpnConnection(
            self.apiclient, customer1_response.id, vpn2_response['id'], True)
        self.debug("VPN passive connection created for VPC %s" % vpc2.id)

        vpnconn2_response = Vpn.createVpnConnection(
            self.apiclient, customer2_response.id, vpn1_response['id'])
        self.debug("VPN connection created for VPC %s" % vpc1.id)

        def checkVpnConnected():
            connections = Vpn.listVpnConnection(
                self.apiclient,
                listall='true',
                vpcid=vpc2.id)
            if isinstance(connections, list):
                return connections[0].state == 'Connected', None
            return False, None

        # Wait up to 60 seconds for passive connection to show up as Connected
        res, _ = wait_until(2, 30, checkVpnConnected)
        if not res:
            self.fail("Failed to connect between VPCs, see VPN state as Connected")

        # acquire an extra ip address to use to ssh into vm2
        try:
            vm2.public_ip = PublicIPAddress.create(
                apiclient=self.apiclient,
                accountid=self.account.name,
                zoneid=self.zone.id,
                domainid=self.account.domainid,
                services=self.services,
                networkid=ntwk2.id,
                vpcid=vpc2.id)
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(
                vm2.public_ip is not None, "Failed to aqcuire public ip for vm2")

        natrule = None
        # Create port forward to be able to ssh into vm2
        try:
            natrule = self._create_natrule(
                vpc2, vm2, 22, 22, vm2.public_ip, ntwk2)
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(
                natrule is not None, "Failed to create portforward for vm2")
            time.sleep(20)

        # setup ssh connection to vm2
        ssh_client = self._get_ssh_client(vm2, self.services, 10)

        if ssh_client:
            # run ping test
            packet_loss = ssh_client.execute("/bin/ping -c 3 -t 10 " + vm1.nic[0].ipaddress + " | grep packet | sed 's/.*received, //g' | sed 's/[% ]*packet.*//g'")[0]
            # during startup, some packets may not reply due to link/ipsec-route setup
            self.assert_(int(packet_loss) < 50, "Ping did not succeed")
        else:
            self.fail("Failed to setup ssh connection to %s" % vm2.public_ip)

    @classmethod
    def tearDownClass(cls):
        super(TestVpcSite2SiteVpn, cls).tearDownClass()

    def tearDown(self):
        super(TestVpcSite2SiteVpn, self).tearDown()


class TestRVPCSite2SiteVpn(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cls.logger = logging.getLogger('TestRVPCSite2SiteVPN')
        cls.stream_handler = logging.StreamHandler()
        cls.logger.setLevel(logging.DEBUG)
        cls.logger.addHandler(cls.stream_handler)

        testClient = super(TestRVPCSite2SiteVpn, cls).getClsTestClient()
        cls.apiclient = testClient.getApiClient()
        cls.services = Services().services

        cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
        cls.domain = get_domain(cls.apiclient)
        cls._cleanup = []

        cls.compute_offering = ServiceOffering.create(
            cls.apiclient,
            cls.services["compute_offering"]
        )
        cls._cleanup.append(cls.compute_offering)

        cls.account = Account.create(
            cls.apiclient, services=cls.services["account"])
        cls._cleanup.append(cls.account)

        cls.hypervisor = testClient.getHypervisorInfo()

        cls.template = get_test_template(cls.apiclient, cls.zone.id, cls.hypervisor)
        if cls.template == FAILED:
            assert False, "get_test_template() failed to return template"

        cls.logger.debug("Successfully created account: %s, id: \
                   %s" % (cls.account.name,
                          cls.account.id))
        return

    def _validate_vpc_offering(self, vpc_offering):

        self.logger.debug("Check if the VPC offering is created successfully?")
        vpc_offs = VpcOffering.list(
            self.apiclient,
            id=vpc_offering.id
        )
        offering_list = validateList(vpc_offs)
        self.assertEqual(offering_list[0],
                         PASS,
                         "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.logger.debug(
            "VPC offering is created successfully - %s" %
            vpc_offering.name)
        return

    def _create_vpc_offering(self, offering_name):

        vpc_off = None
        if offering_name is not None:

            self.logger.debug("Creating VPC offering: %s", offering_name)
            vpc_off = VpcOffering.create(
                self.apiclient,
                self.services[offering_name]
            )

            self._validate_vpc_offering(vpc_off)
            self.cleanup.append(vpc_off)

        return vpc_off

    def _get_ssh_client(self, virtual_machine, services, retries):
        """ Setup ssh client connection and return connection
        vm requires attributes public_ip, public_port, username, password """

        try:
            ssh_client = SshClient(
                virtual_machine.public_ip,
                services["virtual_machine"]["ssh_port"],
                services["virtual_machine"]["username"],
                services["virtual_machine"]["password"],
                retries)

        except Exception as e:
            self.fail("Unable to create ssh connection: %s" % e)

        self.assertIsNotNone(
            ssh_client, "Failed to setup ssh connection to vm=%s on public_ip=%s" % (virtual_machine.name, virtual_machine.public_ip))

        return ssh_client

    def _create_natrule(self, vpc, vm, public_port, private_port, public_ip, network, services=None):
        self.logger.debug("Creating NAT rule in network for vm with public IP")
        if not services:
            self.services["natrule"]["privateport"] = private_port
            self.services["natrule"]["publicport"] = public_port
            self.services["natrule"]["startport"] = public_port
            self.services["natrule"]["endport"] = public_port
            services = self.services["natrule"]

        nat_rule = NATRule.create(
            apiclient=self.apiclient,
            services=services,
            ipaddressid=public_ip.ipaddress.id,
            virtual_machine=vm,
            networkid=network.id
        )
        self.assertIsNotNone(
            nat_rule, "Failed to create NAT Rule for %s" % public_ip.ipaddress.ipaddress)
        self.logger.debug(
            "Adding NetworkACL rules to make NAT rule accessible")

        vm.ssh_ip = nat_rule.ipaddress
        vm.public_ip = nat_rule.ipaddress
        vm.public_port = int(public_port)
        return nat_rule

    @attr(tags=["advanced"], required_hardware="true")
    def test_01_redundant_vpc_site2site_vpn(self):
        """Test Site 2 Site VPN Across redundant VPCs"""
        self.logger.debug("Starting test: test_02_redundant_vpc_site2site_vpn")

        # 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")

        # Create and enable redundant VPC offering
        redundant_vpc_offering = self._create_vpc_offering(
            'redundant_vpc_offering')
        self.assert_(redundant_vpc_offering is not None,
                     "Failed to create redundant VPC Offering")
        redundant_vpc_offering.update(self.apiclient, state='Enabled')

        # Create VPC 1
        vpc1 = None
        try:
            vpc1 = VPC.create(
                apiclient=self.apiclient,
                services=self.services["vpc"],
                networkDomain="vpc1.vpn",
                vpcofferingid=redundant_vpc_offering.id,
                zoneid=self.zone.id,
                account=self.account.name,
                domainid=self.domain.id
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vpc1 is not None, "VPC1 creation failed")
        self.cleanup.append(vpc1)
        self.logger.debug("VPC1 %s created" % vpc1.id)

        # Create VPC 2
        vpc2 = None
        try:
            vpc2 = VPC.create(
                apiclient=self.apiclient,
                services=self.services["vpc2"],
                networkDomain="vpc2.vpn",
                vpcofferingid=redundant_vpc_offering.id,
                zoneid=self.zone.id,
                account=self.account.name,
                domainid=self.account.domainid
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vpc2 is not None, "VPC2 creation failed")
        self.cleanup.append(vpc2)
        self.logger.debug("VPC2 %s created" % vpc2.id)

        default_acl = NetworkACLList.list(
            self.apiclient, name="default_allow")[0]

        # Create network in VPC 1
        ntwk1 = None
        try:
            ntwk1 = Network.create(
                apiclient=self.apiclient,
                services=self.services["network_1"],
                accountid=self.account.name,
                domainid=self.account.domainid,
                networkofferingid=networkOffering[0].id,
                zoneid=self.zone.id,
                vpcid=vpc1.id,
                aclid=default_acl.id
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assertIsNotNone(ntwk1, "Network failed to create")
        self.cleanup.append(ntwk1)
        self.logger.debug("Network %s created in VPC %s" % (ntwk1.id, vpc1.id))

        # Create network in VPC 2
        ntwk2 = None
        try:
            ntwk2 = Network.create(
                apiclient=self.apiclient,
                services=self.services["network_2"],
                accountid=self.account.name,
                domainid=self.account.domainid,
                networkofferingid=networkOffering[0].id,
                zoneid=self.zone.id,
                vpcid=vpc2.id,
                aclid=default_acl.id
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assertIsNotNone(ntwk2, "Network failed to create")
        self.cleanup.append(ntwk2)
        self.logger.debug("Network %s created in VPC %s" % (ntwk2.id, vpc2.id))

        # Deploy a vm in network 2
        vm1 = None
        try:
            vm1 = VirtualMachine.create(self.apiclient, services=self.services["virtual_machine"],
                                        templateid=self.template.id,
                                        zoneid=self.zone.id,
                                        accountid=self.account.name,
                                        domainid=self.account.domainid,
                                        serviceofferingid=self.compute_offering.id,
                                        networkids=ntwk1.id,
                                        hypervisor=self.hypervisor
                                        )
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vm1 is not None, "VM failed to deploy")
            self.assert_(vm1.state == 'Running', "VM is not running")
        self.cleanup.append(vm1)
        self.logger.debug("VM %s deployed in VPC %s" % (vm1.id, vpc1.id))

        # Deploy a vm in network 2
        vm2 = None
        try:
            vm2 = VirtualMachine.create(self.apiclient, services=self.services["virtual_machine"],
                                        templateid=self.template.id,
                                        zoneid=self.zone.id,
                                        accountid=self.account.name,
                                        domainid=self.account.domainid,
                                        serviceofferingid=self.compute_offering.id,
                                        networkids=ntwk2.id,
                                        hypervisor=self.hypervisor
                                        )
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vm2 is not None, "VM failed to deploy")
            self.assert_(vm2.state == 'Running', "VM is not running")
        self.cleanup.append(vm2)
        self.debug("VM %s deployed in VPC %s" % (vm2.id, vpc2.id))

        # 4) Enable Site-to-Site VPN for VPC
        vpn1_response = Vpn.createVpnGateway(self.apiclient, vpc1.id)
        self.assert_(
            vpn1_response is not None, "Failed to enable VPN Gateway 1")
        self.logger.debug("VPN gateway for VPC %s enabled" % vpc1.id)

        vpn2_response = Vpn.createVpnGateway(self.apiclient, vpc2.id)
        self.assert_(
            vpn2_response is not None, "Failed to enable VPN Gateway 2")
        self.logger.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]

        services = self.services["vpncustomergateway"]
        customer1_response = VpnCustomerGateway.create(
            self.apiclient, services, "Peer VPC1", ip1.ipaddress, vpc1.cidr, self.account.name, self.domain.id)
        self.debug("VPN customer gateway added for VPC %s enabled" % vpc1.id)
        self.logger.debug(vars(customer1_response))

        customer2_response = VpnCustomerGateway.create(
            self.apiclient, services, "Peer VPC2", ip2.ipaddress, vpc2.cidr, self.account.name, self.domain.id)
        self.debug("VPN customer gateway added for VPC %s enabled" % vpc2.id)
        self.logger.debug(vars(customer2_response))

        # 6) Connect two VPCs
        vpnconn1_response = Vpn.createVpnConnection(
            self.apiclient, customer1_response.id, vpn2_response['id'], True)
        self.debug("VPN passive connection created for VPC %s" % vpc2.id)

        vpnconn2_response = Vpn.createVpnConnection(
            self.apiclient, customer2_response.id, vpn1_response['id'])
        self.debug("VPN connection created for VPC %s" % vpc1.id)

        def checkVpnConnected():
            connections = Vpn.listVpnConnection(
                self.apiclient,
                listall='true',
                vpcid=vpc2.id)
            if isinstance(connections, list):
                return connections[0].state == 'Connected', None
            return False, None

        # Wait up to 60 seconds for passive connection to show up as Connected
        res, _ = wait_until(2, 30, checkVpnConnected)
        if not res:
            self.fail("Failed to connect between VPCs, see VPN state as Connected")

        # acquire an extra ip address to use to ssh into vm2
        try:
            vm2.public_ip = PublicIPAddress.create(
                apiclient=self.apiclient,
                accountid=self.account.name,
                zoneid=self.zone.id,
                domainid=self.account.domainid,
                services=self.services,
                networkid=ntwk2.id,
                vpcid=vpc2.id)
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(
                vm2.public_ip is not None, "Failed to aqcuire public ip for vm2")

        # Create port forward to be able to ssh into vm2
        natrule = None
        try:
            natrule = self._create_natrule(
                vpc2, vm2, 22, 22, vm2.public_ip, ntwk2)
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(
                natrule is not None, "Failed to create portforward for vm2")
            time.sleep(20)

        # setup ssh connection to vm2
        ssh_client = self._get_ssh_client(vm2, self.services, 10)

        if ssh_client:
            # run ping test
            packet_loss = ssh_client.execute("/bin/ping -c 3 -t 10 " + vm1.nic[0].ipaddress + " | grep packet | sed 's/.*received, //g' | sed 's/[% ]*packet.*//g'")[0]
            self.assert_(int(packet_loss) < 50, "Ping did not succeed")
        else:
            self.fail("Failed to setup ssh connection to %s" % vm2.public_ip)

    @classmethod
    def tearDownClass(cls):
        super(TestRVPCSite2SiteVpn, cls).tearDownClass()

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.hypervisor = self.testClient.getHypervisorInfo()
        self.cleanup = []

    def tearDown(self):
        super(TestRVPCSite2SiteVpn, self).tearDown()

class TestVPCSite2SiteVPNMultipleOptions(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cls.logger = logging.getLogger('TestVPCSite2SiteVPNMultipleOptions')
        cls.stream_handler = logging.StreamHandler()
        cls.logger.setLevel(logging.DEBUG)
        cls.logger.addHandler(cls.stream_handler)

        testClient = super(TestVPCSite2SiteVPNMultipleOptions, cls).getClsTestClient()
        cls.apiclient = testClient.getApiClient()
        cls.services = Services().services

        cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
        cls.domain = get_domain(cls.apiclient)

        cls._cleanup = []

        cls.compute_offering = ServiceOffering.create(
            cls.apiclient,
            cls.services["compute_offering"]
        )
        cls._cleanup.append(cls.compute_offering)

        cls.account = Account.create(
            cls.apiclient, services=cls.services["account"])
        cls._cleanup.append(cls.account)

        cls.hypervisor = testClient.getHypervisorInfo()

        cls.template = get_test_template(cls.apiclient, cls.zone.id, cls.hypervisor)
        if cls.template == FAILED:
            assert False, "get_test_template() failed to return template"

        cls.logger.debug("Successfully created account: %s, id: \
                   %s" % (cls.account.name,
                          cls.account.id))
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.hypervisor = self.testClient.getHypervisorInfo()
        self.cleanup = []

    def _get_ssh_client(self, virtual_machine, services, retries):
        """ Setup ssh client connection and return connection
        vm requires attributes public_ip, public_port, username, password """

        try:
            ssh_client = SshClient(
                virtual_machine.public_ip,
                services["virtual_machine"]["ssh_port"],
                services["virtual_machine"]["username"],
                services["virtual_machine"]["password"],
                retries)

        except Exception as e:
            self.fail("Unable to create ssh connection: " % e)

        self.assertIsNotNone(
            ssh_client, "Failed to setup ssh connection to vm=%s on public_ip=%s" % (virtual_machine.name, virtual_machine.public_ip))

        return ssh_client

    def _create_natrule(self, vpc, vm, public_port, private_port, public_ip, network, services=None):
        self.logger.debug("Creating NAT rule in network for vm with public IP")
        if not services:
            self.services["natrule"]["privateport"] = private_port
            self.services["natrule"]["publicport"] = public_port
            self.services["natrule"]["startport"] = public_port
            self.services["natrule"]["endport"] = public_port
            services = self.services["natrule"]

        nat_rule = NATRule.create(
            apiclient=self.apiclient,
            services=services,
            ipaddressid=public_ip.ipaddress.id,
            virtual_machine=vm,
            networkid=network.id
        )
        self.assertIsNotNone(
            nat_rule, "Failed to create NAT Rule for %s" % public_ip.ipaddress.ipaddress)
        self.logger.debug(
            "Adding NetworkACL rules to make NAT rule accessible")

        vm.ssh_ip = nat_rule.ipaddress
        vm.public_ip = nat_rule.ipaddress
        vm.public_port = int(public_port)
        return nat_rule

    def _validate_vpc_offering(self, vpc_offering):

        self.logger.debug("Check if the VPC offering is created successfully?")
        vpc_offs = VpcOffering.list(
            self.apiclient,
            id=vpc_offering.id
        )
        offering_list = validateList(vpc_offs)
        self.assertEqual(offering_list[0],
                         PASS,
                         "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.logger.debug(
            "VPC offering is created successfully - %s" %
            vpc_offering.name)
        return

    def _create_vpc_offering(self, offering_name):

        vpc_off = None
        if offering_name is not None:

            self.logger.debug("Creating VPC offering: %s", offering_name)
            vpc_off = VpcOffering.create(
                self.apiclient,
                self.services[offering_name]
            )

            self._validate_vpc_offering(vpc_off)
            self.cleanup.append(vpc_off)

        return vpc_off

    @attr(tags=["advanced"], required_hardware="true")
    def test_01_vpc_site2site_vpn_multiple_options(self):
        """Test Site 2 Site VPN Across VPCs"""
        self.logger.debug("Starting test: test_01_vpc_site2site_vpn_multiple_options")
        # 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")

        # Create and Enable VPC offering
        vpc_offering = self._create_vpc_offering('vpc_offering')
        self.assert_(vpc_offering is not None, "Failed to create VPC Offering")
        vpc_offering.update(self.apiclient, state='Enabled')

        vpc1 = None
        # Create VPC 1
        try:
            vpc1 = VPC.create(
                apiclient=self.apiclient,
                services=self.services["vpc"],
                networkDomain="vpc1.vpn",
                vpcofferingid=vpc_offering.id,
                zoneid=self.zone.id,
                account=self.account.name,
                domainid=self.domain.id
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vpc1 is not None, "VPC1 creation failed")
        self.cleanup.append(vpc1)
        self.logger.debug("VPC1 %s created" % vpc1.id)

        vpc2 = None
        # Create VPC 2
        try:
            vpc2 = VPC.create(
                apiclient=self.apiclient,
                services=self.services["vpc2"],
                networkDomain="vpc2.vpn",
                vpcofferingid=vpc_offering.id,
                zoneid=self.zone.id,
                account=self.account.name,
                domainid=self.domain.id
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vpc2 is not None, "VPC2 creation failed")
        self.cleanup.append(vpc2)
        self.logger.debug("VPC2 %s created" % vpc2.id)

        default_acl = NetworkACLList.list(
            self.apiclient, name="default_allow")[0]

        ntwk1 = None
        # Create network in VPC 1
        try:
            ntwk1 = Network.create(
                apiclient=self.apiclient,
                services=self.services["network_1"],
                accountid=self.account.name,
                domainid=self.account.domainid,
                networkofferingid=networkOffering[0].id,
                zoneid=self.zone.id,
                vpcid=vpc1.id,
                aclid=default_acl.id
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assertIsNotNone(ntwk1, "Network failed to create")
        self.cleanup.append(ntwk1)
        self.logger.debug("Network %s created in VPC %s" % (ntwk1.id, vpc1.id))

        ntwk2 = None
        # Create network in VPC 2
        try:
            ntwk2 = Network.create(
                apiclient=self.apiclient,
                services=self.services["network_2"],
                accountid=self.account.name,
                domainid=self.account.domainid,
                networkofferingid=networkOffering[0].id,
                zoneid=self.zone.id,
                vpcid=vpc2.id,
                aclid=default_acl.id
            )
        except Exception as e:
            self.fail(e)
        finally:
            self.assertIsNotNone(ntwk2, "Network failed to create")
        self.cleanup.append(ntwk2)
        self.logger.debug("Network %s created in VPC %s" % (ntwk2.id, vpc2.id))

        vm1 = None
        # Deploy a vm in network 2
        try:
            vm1 = VirtualMachine.create(self.apiclient, services=self.services["virtual_machine"],
                                        templateid=self.template.id,
                                        zoneid=self.zone.id,
                                        accountid=self.account.name,
                                        domainid=self.account.domainid,
                                        serviceofferingid=self.compute_offering.id,
                                        networkids=ntwk1.id,
                                        hypervisor=self.hypervisor
                                        )
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vm1 is not None, "VM failed to deploy")
            self.assert_(vm1.state == 'Running', "VM is not running")
        self.cleanup.append(vm1)
        self.logger.debug("VM %s deployed in VPC %s" % (vm1.id, vpc1.id))

        vm2 = None
        # Deploy a vm in network 2
        try:
            vm2 = VirtualMachine.create(self.apiclient, services=self.services["virtual_machine"],
                                        templateid=self.template.id,
                                        zoneid=self.zone.id,
                                        accountid=self.account.name,
                                        domainid=self.account.domainid,
                                        serviceofferingid=self.compute_offering.id,
                                        networkids=ntwk2.id,
                                        hypervisor=self.hypervisor
                                        )
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(vm2 is not None, "VM failed to deploy")
            self.assert_(vm2.state == 'Running', "VM is not running")
        self.cleanup.append(vm2)
        self.debug("VM %s deployed in VPC %s" % (vm2.id, vpc2.id))

        # default config
        config = {
            'ike_enc'       :'aes128',
            'ike_hash'      :'sha1',
            'ike_dh'        :'modp1536',
            'esp_enc'       :'aes128',
            'esp_hash'      :'sha1',
            'esp_pfs'       :'modp1536',
            'psk'           :'secreatKey',
            'ike_life'      :86400,
            'esp_life'      :3600,
            'dpd'           :True,
            'force_encap'   :False,
            'passive_1'     :False,
            'passive_2'     :False
        }
        test_confs = [
            {}, # default
            {'force_encap': True},
            {'ike_life': ''},
            {'esp_life': ''},
            {'ike_life': '', 'esp_life': ''},
            {'passive_1': True, 'passive_2': True},
            {'passive_1': False, 'passive_2': True},
            {'passive_1': True, 'passive_2': False},
            {'passive_1': False, 'passive_2': False, 'dpd': False},
            {'passive_1': True, 'passive_2': True, 'dpd': False},
            {'passive_1': True, 'passive_2': False, 'dpd': False},
            {'passive_1': False, 'passive_2': True, 'dpd': False},
            {'passive_1': True, 'passive_2': False, 'esp_pfs': ''},
            {'ike_dh': 'modp3072', 'ike_hash': 'sha256', 'esp_pfs': 'modp2048', 'esp_hash':'sha384'},
            {'ike_dh': 'modp4096', 'ike_hash': 'sha384', 'esp_pfs': 'modp6144', 'esp_hash':'sha512'},
            {'ike_dh': 'modp8192', 'ike_hash': 'sha512', 'esp_pfs': 'modp8192', 'esp_hash':'sha384'}
        ]

        # 4) Enable Site-to-Site VPN for VPC
        vpn1_response = Vpn.createVpnGateway(self.apiclient, vpc1.id)
        self.assert_(
            vpn1_response is not None, "Failed to enable VPN Gateway 1")
        self.logger.debug("VPN gateway for VPC %s enabled" % vpc1.id)

        vpn2_response = Vpn.createVpnGateway(self.apiclient, vpc2.id)
        self.assert_(
            vpn2_response is not None, "Failed to enable VPN Gateway 2")
        self.logger.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]

        # acquire an extra ip address to use to ssh into vm2
        try:
            vm2.public_ip = PublicIPAddress.create(
                apiclient=self.apiclient,
                accountid=self.account.name,
                zoneid=self.zone.id,
                domainid=self.account.domainid,
                services=self.services,
                networkid=ntwk2.id,
                vpcid=vpc2.id)
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(
                vm2.public_ip is not None, "Failed to aqcuire public ip for vm2")

        natrule = None
        # Create port forward to be able to ssh into vm2
        try:
            natrule = self._create_natrule(
                vpc2, vm2, 22, 22, vm2.public_ip, ntwk2)
        except Exception as e:
            self.fail(e)
        finally:
            self.assert_(
                natrule is not None, "Failed to create portforward for vm2")
            time.sleep(20)

        # setup ssh connection to vm2
        ssh_client = self._get_ssh_client(vm2, self.services, 10)
        if not ssh_client:
            self.fail("Failed to setup ssh connection to %s" % vm2.public_ip)

        for test_c in test_confs:
            c = config.copy()
            c.update(test_c)
            services = self._get_vpn_config(c)
            self.logger.debug(services)
            customer1_response = VpnCustomerGateway.create(
                self.apiclient,
                services,
                "Peer VPC1",
                ip1.ipaddress,
                vpc1.cidr,
                account=self.account.name,
                domainid=self.account.domainid)
            self.logger.debug("VPN customer gateway added for VPC %s enabled" % vpc1.id)

            customer2_response = VpnCustomerGateway.create(
                self.apiclient,
                services,
                "Peer VPC2",
                ip2.ipaddress,
                vpc2.cidr,
                account=self.account.name,
                domainid=self.account.domainid)
            self.logger.debug("VPN customer gateway added for VPC %s enabled" % vpc2.id)

            # 6) Connect two VPCs
            vpnconn1_response = Vpn.createVpnConnection(
                self.apiclient, customer1_response.id, vpn2_response['id'], c['passive_1'])
            self.logger.debug("VPN connection created for VPC %s" % vpc2.id)
            time.sleep(5)
            vpnconn2_response = Vpn.createVpnConnection(
                self.apiclient, customer2_response.id, vpn1_response['id'], c['passive_2'])
            self.logger.debug("VPN connection created for VPC %s" % vpc1.id)

            def checkVpnConnected():
                connections = Vpn.listVpnConnection(
                    self.apiclient,
                    listall='true',
                    vpcid=vpc2.id)
                if isinstance(connections, list):
                    return connections[0].state == 'Connected', None
                return False, None

            # Wait up to 60 seconds for passive connection to show up as Connected
            res, _ = wait_until(2, 30, checkVpnConnected)
            if not res:
                self.logger.debug("Failed to see VPN state as Connected, we'll attempt ssh+pinging")

            # run ping test
            packet_loss = ssh_client.execute("/bin/ping -c 3 -t 10 " + vm1.nic[0].ipaddress + " | grep packet | sed 's/.*received, //g' | sed 's/[% ]*packet.*//g'")[0]
            self.logger.debug("Packet loss %s" % packet_loss)
            self.assert_(int(packet_loss) < 50, "Ping did not succeed")

            # Cleanup
            Vpn.deleteVpnConnection(self.apiclient, vpnconn1_response['id'])
            Vpn.deleteVpnConnection(self.apiclient, vpnconn2_response['id'])
            customer1_response.delete(self.apiclient)
            customer2_response.delete(self.apiclient)

    def _get_vpn_config(self, c):
        ike_policy = '%s-%s;%s' % (c['ike_enc'], c['ike_hash'], c['ike_dh']) if c['ike_dh'] else '%s-%s' % (c['ike_enc'], c['ike_hash'])
        esp_policy = '%s-%s;%s' % (c['esp_enc'], c['esp_hash'], c['esp_pfs']) if c['esp_pfs'] else '%s-%s' % (c['esp_enc'], c['esp_hash'])
        out =  {
            'ipsecpsk': c['psk'],
            'ikepolicy':ike_policy,
            'esppolicy':esp_policy,
            'dpd':c['dpd'],
            'forceencap':c['force_encap']
        }
        if c['ike_life']:
            out['ikelifetime'] = c['ike_life']
        if c['esp_life']:
            out['esplifetime'] = c['esp_life']
        return out

    @classmethod
    def tearDownClass(cls):
        super(TestVPCSite2SiteVPNMultipleOptions, cls).tearDownClass()
