# 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.

""" Component tests for VPC - Router Operations
"""
import time
from nose.plugins.attrib import attr

# Import Local Modules
from marvin.cloudstackAPI import (
    startRouter,
    stopRouter,
    rebootRouter,
    migrateSystemVm)
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.base import (
    Account,
    Router,
    ServiceOffering,
    VirtualMachine,
    Host,
    PublicIPAddress,
    VPC,
    VpcOffering,
    StaticRoute,
    Network,
    NetworkOffering,
    PrivateGateway,
    NATRule,
    NetworkACL,
    StaticNATRule,
    LoadBalancerRule)
from marvin.lib.common import (
    get_domain,
    get_zone,
    list_routers,
    get_template)
from marvin.lib.utils import cleanup_resources


class Services:
    """Test VPC Router 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,
            },
            "service_offering_new": {
                "name": "Small Instance",
                "displaytext": "Small Instance",
                "cpunumber": 1,
                "cpuspeed": 100,
                "memory": 256,
                "issystem": 'true',
            },

            "network_offering": {
                "name": 'VPC Network offering',
                "displaytext": 'VPC Network off',
                "guestiptype": 'Isolated',
                "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Lb,UserData,StaticNat,NetworkACL',
                "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'
                },
            },
            "network_offering_no_lb": {
                "name": 'VPC Network offering',
                "displaytext": 'VPC Network off',
                "guestiptype": 'Isolated',
                "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,UserData,StaticNat,NetworkACL',
                "traffictype": 'GUEST',
                "availability": 'Optional',
                "useVpc": 'on',
                "serviceProviderList": {
                    "Vpn": 'VpcVirtualRouter',
                    "Dhcp": 'VpcVirtualRouter',
                    "Dns": 'VpcVirtualRouter',
                    "SourceNat": 'VpcVirtualRouter',
                    "PortForwarding": 'VpcVirtualRouter',
                    "UserData": 'VpcVirtualRouter',
                    "StaticNat": 'VpcVirtualRouter',
                    "NetworkACL": 'VpcVirtualRouter'
                },
            },
            "vpc_offering": {
                "name": 'VPC off',
                "displaytext": 'VPC off',
                "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat',
            },
            "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,
                "protocol": "TCP",
                "cidrlist": '0.0.0.0/0',
            },
            "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"
            },
            "http_rule": {
                "startport": 80,
                "endport": 80,
                "cidrlist": '0.0.0.0/0',
                "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,
            "mode": 'advanced'
        }


class TestVPCRoutersBasic(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cls.testClient = super(TestVPCRoutersBasic, cls).getClsTestClient()
        cls.api_client = cls.testClient.getApiClient()
        cls.hypervisor = cls.testClient.getHypervisorInfo()
        cls.vpcSupported = True
        cls._cleanup = []
        if cls.hypervisor.lower() == 'hyperv':
            cls.vpcSupported = False
            return
        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client)
        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
        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.append(cls.service_offering)
        cls.vpc_off = VpcOffering.create(
            cls.api_client,
            cls.services["vpc_offering"]
        )
        cls._cleanup.append(cls.vpc_off)
        cls.vpc_off.update(cls.api_client, state='Enabled')
        cls.account = Account.create(
            cls.api_client,
            cls.services["account"],
            admin=True,
            domainid=cls.domain.id
        )
        cls._cleanup.append(cls.account)
        cls.vpc_off.update(cls.api_client, state='Enabled')

        cls.services["vpc"]["cidr"] = '10.1.1.1/16'
        cls.vpc = VPC.create(
            cls.api_client,
            cls.services["vpc"],
            vpcofferingid=cls.vpc_off.id,
            zoneid=cls.zone.id,
            account=cls.account.name,
            domainid=cls.account.domainid
        )
        cls._cleanup.append(cls.vpc)
        return

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

    def setUp(self):
        self.api_client = self.testClient.getApiClient()
        if not self.vpcSupported:
            self.skipTest("VPC is not supported on %s" % self.hypervisor)
        return

    def tearDown(self):
        super(TestVPCRoutersBasic, self).tearDown()
        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.api_client,
            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.debug(
            "VPC offering is created successfully - %s" %
            vpc_offering.name)
        return

    def validate_vpc_network(self, network, state=None):
        """Validates the VPC network"""

        self.debug("Check if the VPC network is created successfully?")
        vpc_networks = VPC.list(
            self.api_client,
            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"
        )
        if state:
            self.assertEqual(
                vpc_networks[0].state,
                state,
                "VPC state should be '%s'" % state
            )
        self.debug("VPC network validated - %s" % network.name)
        return

    def migrate_router(self, router):
        """ Migrate the router """

        self.debug("Checking if the host is available for migration?")
        hosts = Host.list(self.api_client, zoneid=self.zone.id, type='Routing')

        self.assertEqual(
            isinstance(hosts, list),
            True,
            "List hosts should return a valid list"
        )
        if len(hosts) < 2:
            self.skipTest(
                "No host available for migration. Test requires at least 2 hosts")

        # Remove the host of current VM from the hosts list
        hosts[:] = [host for host in hosts if host.id != router.hostid]
        host = hosts[0]
        self.debug("Validating if the network rules work properly or not?")

        self.debug("Migrating VM-ID: %s from %s to Host: %s" % (
            router.id,
            router.hostid,
            host.id
        ))
        try:

            # Migrate  the router
            cmd = migrateSystemVm.migrateSystemVmCmd()
            cmd.isAsync = "false"
            cmd.hostid = host.id
            cmd.virtualmachineid = router.id
            self.api_client.migrateSystemVm(cmd)

        except Exception as e:
            self.fail("Failed to migrate instance, %s" % e)

        self.debug("Waiting for Router mgiration ....")
        time.sleep(240)

        # List routers to check state of router
        router_response = list_routers(
            self.api_client,
            id=router.id
        )
        self.assertEqual(
            isinstance(router_response, list),
            True,
            "Check list response returns a valid list"
        )

        router.hostid = router_response[0].hostid
        self.assertEqual(
            router.hostid, host.id, "Migration to host %s failed. The router host is"
                                    " still %s" %
                                    (host.id, router.hostid))
        return

    @attr(tags=["advanced", "intervlan"], required_hardware="false")
    def test_01_stop_start_router_after_creating_vpc(self):
        """ Test to stop and start router after creation of VPC
        """

        # Validate following:
        # 1. Create a VPC with cidr - 10.1.1.1/16
        # 2. Stop the VPC Virtual Router which is created as a result of VPC creation.
        # 3. Start the Stopped VPC Virtual Router

        self.validate_vpc_offering(self.vpc_off)
        self.validate_vpc_network(self.vpc)

        # Stop the VPC Router
        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        self.assertEqual(
            isinstance(routers, list),
            True,
            "List Routers should return a valid list"
        )
        router = routers[0]
        self.debug("Stopping the router with ID: %s" % router.id)

        # Stop the router
        cmd = stopRouter.stopRouterCmd()
        cmd.id = router.id
        self.api_client.stopRouter(cmd)

        # List routers to check state of router
        router_response = list_routers(
            self.api_client,
            id=router.id
        )
        self.assertEqual(
            isinstance(router_response, list),
            True,
            "Check list response returns a valid list"
        )
        # List router should have router in stopped state
        self.assertEqual(
            router_response[0].state,
            'Stopped',
            "Check list router response for router state"
        )

        self.debug("Stopped the router with ID: %s" % router.id)

        # Start The Router
        self.debug("Starting the router with ID: %s" % router.id)
        cmd = startRouter.startRouterCmd()
        cmd.id = router.id
        self.api_client.startRouter(cmd)

        # List routers to check state of router
        router_response = list_routers(
            self.api_client,
            id=router.id
        )
        self.assertEqual(
            isinstance(router_response, list),
            True,
            "Check list response returns a valid list"
        )
        # List router should have router in running state
        self.assertEqual(
            router_response[0].state,
            'Running',
            "Check list router response for router state"
        )
        self.debug("Started the router with ID: %s" % router.id)

        return

    @attr(tags=["advanced", "intervlan"], required_hardware="false")
    def test_02_reboot_router_after_creating_vpc(self):
        """ Test to reboot the router after creating a VPC
        """
        # Validate the following
        # 1. Create a VPC with cidr - 10.1.1.1/16
        # 2. Reboot the VPC Virtual Router which is created as a result of VPC creation.
        # Stop the VPC Router

        self.validate_vpc_offering(self.vpc_off)
        self.validate_vpc_network(self.vpc)
        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        self.assertEqual(
            isinstance(routers, list),
            True,
            "List Routers should return a valid list"
        )
        router = routers[0]

        self.debug("Rebooting the router ...")
        # Reboot the router
        cmd = rebootRouter.rebootRouterCmd()
        cmd.id = router.id
        self.api_client.rebootRouter(cmd)

        # List routers to check state of router
        router_response = list_routers(
            self.api_client,
            id=router.id
        )
        self.assertEqual(
            isinstance(router_response, list),
            True,
            "Check list response returns a valid list"
        )
        # List router should have router in running state and same public IP
        self.assertEqual(
            router_response[0].state,
            'Running',
            "Check list router response for router state"
        )
        return

    @attr(tags=["advanced", "intervlan"], required_hardware="true")
    def test_03_migrate_router_after_creating_vpc(self):
        """ Test migration of router to another host after creating VPC """
        self.hypervisor = self.testClient.getHypervisorInfo()
        if self.hypervisor.lower() in ['lxc']:
            self.skipTest(
                "vm migrate is not supported in %s" %
                self.hypervisor)

        self.validate_vpc_offering(self.vpc_off)
        self.validate_vpc_network(self.vpc)

        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        self.assertEqual(
            isinstance(routers, list),
            True,
            "List Routers should return a valid list"
        )
        self.migrate_router(routers[0])
        return

    @attr(tags=["advanced", "intervlan"], required_hardware="false")
    def test_04_change_service_offerring_vpc(self):
        """ Tests to change service offering of the Router after
            creating a vpc
        """

        # Validate the following
        # 1. Create a VPC with cidr - 10.1.1.1/16
        # 2. Change the service offerings of the VPC Virtual Router which is
        # created as a result of VPC creation.

        self.validate_vpc_offering(self.vpc_off)
        self.validate_vpc_network(self.vpc)

        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        self.assertEqual(
            isinstance(routers, list),
            True,
            "List Routers should return a valid list"
        )

        # Stop the router
        router = routers[0]
        self.debug("Stopping the router with ID: %s" % router.id)
        cmd = stopRouter.stopRouterCmd()
        cmd.id = router.id
        self.api_client.stopRouter(cmd)

        service_offering = ServiceOffering.create(
            self.api_client,
            self.services["service_offering_new"]
        )
        self.debug("Changing service offering for the Router %s" % router.id)
        try:
            router = Router.change_service_offering(self.api_client,
                                                    router.id,
                                                    service_offering.id
                                                    )
        except:
            self.fail("Changing service offering failed")

        self.debug("Router %s" % router)
        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        router = routers[0]
        self.assertEqual(
            router.serviceofferingid,
            service_offering.id,
            "Changing service offering failed as id is %s and expected"
            "is %s" % (router.serviceofferingid, service_offering.id)
        )
        return

    @attr(tags=["advanced", "intervlan"], required_hardware="false")
    def test_05_destroy_router_after_creating_vpc(self):
        """ Test to destroy the router after creating a VPC
            """
        # Validate the following
        # 1. Create a VPC with cidr - 10.1.1.1/16
        # 2. Destroy the VPC Virtual Router which is created as a result of VPC
        # creation.
        self.validate_vpc_offering(self.vpc_off)
        self.validate_vpc_network(self.vpc)
        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        self.assertEqual(
            isinstance(routers, list),
            True,
            "List Routers should return a valid list"
        )

        Router.destroy(self.api_client,
                       id=routers[0].id
                       )

        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        self.assertEqual(
            isinstance(routers, list),
            False,
            "List Routers should be empty"
        )
        return


class TestVPCRouterOneNetwork(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cls.testClient = super(TestVPCRouterOneNetwork, cls).getClsTestClient()
        cls.api_client = cls.testClient.getApiClient()
        cls.hypervisor = cls.testClient.getHypervisorInfo()
        cls.vpcSupported = True
        cls._cleanup = []
        if cls.hypervisor.lower() == 'hyperv':
            cls.vpcSupported = False
            return
        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client)
        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
        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.append(cls.service_offering)
        cls.vpc_off = VpcOffering.create(
            cls.api_client,
            cls.services["vpc_offering"]
        )
        cls.vpc_off.update(cls.api_client, state='Enabled')
        cls._cleanup.append(cls.vpc_off)

        cls.account = Account.create(
            cls.api_client,
            cls.services["account"],
            admin=True,
            domainid=cls.domain.id
        )
        cls._cleanup.append(cls.account)

        cls.services["vpc"]["cidr"] = '10.1.1.1/16'
        cls.vpc = VPC.create(
            cls.api_client,
            cls.services["vpc"],
            vpcofferingid=cls.vpc_off.id,
            zoneid=cls.zone.id,
            account=cls.account.name,
            domainid=cls.account.domainid
        )
        cls._cleanup.append(cls.vpc)

        private_gateway = PrivateGateway.create(
            cls.api_client,
            gateway='10.1.3.1',
            ipaddress='10.1.3.100',
            netmask='255.255.255.0',
            vlan=678,
            vpcid=cls.vpc.id
        )
        cls._cleanup.append(private_gateway)
        cls.gateways = PrivateGateway.list(
            cls.api_client,
            id=private_gateway.id,
            listall=True
        )

        static_route = StaticRoute.create(
            cls.api_client,
            cidr='11.1.1.1/24',
            gatewayid=private_gateway.id
        )
        cls.static_routes = StaticRoute.list(
            cls.api_client,
            id=static_route.id,
            listall=True
        )
        cls._cleanup.append(static_route)

        cls.nw_off = NetworkOffering.create(
            cls.api_client,
            cls.services["network_offering"],
            conservemode=False
        )
        # Enable Network offering
        cls.nw_off.update(cls.api_client, state='Enabled')
        cls._cleanup.append(cls.nw_off)

        # Creating network using the network offering created
        cls.network_1 = Network.create(
            cls.api_client,
            cls.services["network"],
            accountid=cls.account.name,
            domainid=cls.account.domainid,
            networkofferingid=cls.nw_off.id,
            zoneid=cls.zone.id,
            gateway='10.1.1.1',
            vpcid=cls.vpc.id
        )
        cls._cleanup.append(cls.network_1)

        # Spawn an instance in that network
        vm_1 = VirtualMachine.create(
            cls.api_client,
            cls.services["virtual_machine"],
            accountid=cls.account.name,
            domainid=cls.account.domainid,
            serviceofferingid=cls.service_offering.id,
            networkids=[str(cls.network_1.id)]
        )
        cls._cleanup.append(vm_1)
        vm_2 = VirtualMachine.create(
            cls.api_client,
            cls.services["virtual_machine"],
            accountid=cls.account.name,
            domainid=cls.account.domainid,
            serviceofferingid=cls.service_offering.id,
            networkids=[str(cls.network_1.id)]
        )
        cls._cleanup.append(vm_2)

        # Spawn an instance in that network
        vm_3 = VirtualMachine.create(
            cls.api_client,
            cls.services["virtual_machine"],
            accountid=cls.account.name,
            domainid=cls.account.domainid,
            serviceofferingid=cls.service_offering.id,
            networkids=[str(cls.network_1.id)]
        )
        cls._cleanup.append(vm_3)

        VirtualMachine.list(
            cls.api_client,
            account=cls.account.name,
            domainid=cls.account.domainid,
            listall=True
        )

        public_ip_1 = PublicIPAddress.create(
            cls.api_client,
            accountid=cls.account.name,
            zoneid=cls.zone.id,
            domainid=cls.account.domainid,
            networkid=cls.network_1.id,
            vpcid=cls.vpc.id
        )
        cls._cleanup.append(public_ip_1)

        NATRule.create(
            cls.api_client,
            vm_1,
            cls.services["natrule"],
            ipaddressid=public_ip_1.ipaddress.id,
            openfirewall=False,
            networkid=cls.network_1.id,
            vpcid=cls.vpc.id
        )

        NetworkACL.create(
            cls.api_client,
            networkid=cls.network_1.id,
            services=cls.services["natrule"],
            traffictype='Ingress'
        )

        public_ip_2 = PublicIPAddress.create(
            cls.api_client,
            accountid=cls.account.name,
            zoneid=cls.zone.id,
            domainid=cls.account.domainid,
            networkid=cls.network_1.id,
            vpcid=cls.vpc.id
        )
        cls._cleanup.append(public_ip_2)

        try:
            StaticNATRule.enable(
                cls.api_client,
                ipaddressid=public_ip_2.ipaddress.id,
                virtualmachineid=vm_2.id,
                networkid=cls.network_1.id
            )
        except Exception as e:
            cls.fail("Failed to enable static NAT on IP: %s - %s" % (
                public_ip_2.ipaddress.ipaddress, e))

        PublicIPAddress.list(
            cls.api_client,
            networkid=cls.network_1.id,
            listall=True,
            isstaticnat=True,
            account=cls.account.name,
            domainid=cls.account.domainid
        )
        public_ip_3 = PublicIPAddress.create(
            cls.api_client,
            accountid=cls.account.name,
            zoneid=cls.zone.id,
            domainid=cls.account.domainid,
            networkid=cls.network_1.id,
            vpcid=cls.vpc.id
        )
        cls._cleanup.append(public_ip_3)

        lb_rule = LoadBalancerRule.create(
            cls.api_client,
            cls.services["lbrule"],
            ipaddressid=public_ip_3.ipaddress.id,
            accountid=cls.account.name,
            networkid=cls.network_1.id,
            vpcid=cls.vpc.id,
            domainid=cls.account.domainid
        )

        lb_rule.assign(cls.api_client, [vm_3])

        NetworkACL.create(
            cls.api_client,
            networkid=cls.network_1.id,
            services=cls.services["lbrule"],
            traffictype='Ingress'
        )

        NetworkACL.create(
            cls.api_client,
            networkid=cls.network_1.id,
            services=cls.services["http_rule"],
            traffictype='Egress'
        )

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

    def setUp(self):
        self.api_client = self.testClient.getApiClient()
        self.cleanup = []
        if not self.vpcSupported:
            self.skipTest("VPC is not supported on %s" % self.hypervisor)
        return

    def tearDown(self):
        super(TestVPCRouterOneNetwork, self).tearDown()
        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.api_client,
            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.debug(
            "VPC offering is created successfully - %s" %
            vpc_offering.name)
        return

    def validate_vpc_network(self, network, state=None):
        """Validates the VPC network"""

        self.debug("Check if the VPC network is created successfully?")
        vpc_networks = VPC.list(
            self.api_client,
            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"
        )
        if state:
            self.assertEqual(
                vpc_networks[0].state,
                state,
                "VPC state should be '%s'" % state
            )
        self.debug("VPC network validated - %s" % network.name)
        return

    def validate_network_rules(self):
        """ Validate network rules
        """
        vms = VirtualMachine.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        public_ips = PublicIPAddress.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        for vm, public_ip in zip(vms, public_ips):
            try:
                ssh_1 = vm.get_ssh_client(
                    ipaddress=public_ip.ipaddress.ipaddress)
                self.debug("SSH into VM is successfully")

                self.debug(
                    "Verifying if we can ping to outside world from VM?")
                # Ping to outsite world
                res = ssh_1.execute("ping -c 1 www.google.com")
                # res = 64 bytes from maa03s17-in-f20.1e100.net (74.125.236.212):
                # icmp_req=1 ttl=57 time=25.9 ms
                # --- www.l.google.com ping statistics ---
                # 1 packets transmitted, 1 received, 0% packet loss, time 0ms
                # rtt min/avg/max/mdev = 25.970/25.970/25.970/0.000 ms
            except Exception as e:
                self.fail("Failed to SSH into VM - %s, %s" %
                          (public_ip.ipaddress.ipaddress, e))

            result = str(res)
            self.assertEqual(
                result.count("1 received"),
                1,
                "Ping to outside world from VM should be successful"
            )

    def migrate_router(self, router):
        """ Migrate the router """

        self.debug("Checking if the host is available for migration?")
        hosts = Host.list(self.api_client, zoneid=self.zone.id, type='Routing')

        self.assertEqual(
            isinstance(hosts, list),
            True,
            "List hosts should return a valid list"
        )
        if len(hosts) < 2:
            self.skipTest(
                "No host available for migration. Test requires at least 2 hosts")

        # Remove the host of current VM from the hosts list
        hosts[:] = [host for host in hosts if host.id != router.hostid]
        host = hosts[0]
        self.debug("Validating if the network rules work properly or not?")

        self.debug("Migrating VM-ID: %s from %s to Host: %s" % (
            router.id,
            router.hostid,
            host.id
        ))
        try:

            # Migrate  the router
            cmd = migrateSystemVm.migrateSystemVmCmd()
            cmd.isAsync = "false"
            cmd.hostid = host.id
            cmd.virtualmachineid = router.id
            self.api_client.migrateSystemVm(cmd)

        except Exception as e:
            self.fail("Failed to migrate instance, %s" % e)

        self.debug("Waiting for Router mgiration ....")
        time.sleep(240)

        # List routers to check state of router
        router_response = list_routers(
            self.api_client,
            id=router.id
        )
        self.assertEqual(
            isinstance(router_response, list),
            True,
            "Check list response returns a valid list"
        )

        router.hostid = router_response[0].hostid
        self.assertEqual(
            router.hostid, host.id, "Migration to host %s failed. The router host is"
                                    "still %s" %
                                    (host.id, router.hostid))
        return

    @attr(tags=["advanced", "intervlan", "provisioining"])
    def test_01_start_stop_router_after_addition_of_one_guest_network(self):
        """ Test start/stop of router after addition of one guest network
            """
        # Validations
        # 1. Create a VPC with cidr - 10.1.1.1/16
        # 2. Add network1(10.1.1.1/24) to this VPC.
        # 3. Deploy vm1,vm2 and vm3 such that they are part of network1.
        # 4. Create a PF /Static Nat/LB rule for vms in network1.
        # 5. Create ingress network ACL for allowing all the above rules from a public ip range on network1.
        # 6. Create egress network ACL for network1 to access google.com.
        # 7. Create a private gateway for this VPC and add a static route to this gateway.
        # 8. Create a VPN gateway for this VPC and add a static route to this gateway.
        # 9. Make sure that all the PF,LB and Static NAT rules work as expected.
        # 10. Make sure that we are able to access google.com from all the user Vms.
        # 11. Make sure that the newly added private gateway's and VPN
        # gateway's static routes work as expected

        self.validate_vpc_offering(self.vpc_off)
        self.validate_vpc_network(self.vpc)
        self.assertEqual(
            isinstance(self.gateways, list),
            True,
            "List private gateways should return a valid response"
        )
        self.assertEqual(
            isinstance(self.static_routes, list),
            True,
            "List static route should return a valid response"
        )

        # Stop the VPC Router
        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        self.assertEqual(
            isinstance(routers, list),
            True,
            "List Routers should return a valid list"
        )
        router = routers[0]
        self.debug("Stopping the router with ID: %s" % router.id)

        # Stop the router
        cmd = stopRouter.stopRouterCmd()
        cmd.id = router.id
        self.api_client.stopRouter(cmd)

        # List routers to check state of router
        router_response = list_routers(
            self.api_client,
            id=router.id
        )
        self.assertEqual(
            isinstance(router_response, list),
            True,
            "Check list response returns a valid list"
        )
        # List router should have router in stopped state
        self.assertEqual(
            router_response[0].state,
            'Stopped',
            "Check list router response for router state"
        )

        self.debug("Stopped the router with ID: %s" % router.id)

        # Start The Router
        self.debug("Starting the router with ID: %s" % router.id)
        cmd = startRouter.startRouterCmd()
        cmd.id = router.id
        self.api_client.startRouter(cmd)

        # List routers to check state of router
        router_response = list_routers(
            self.api_client,
            id=router.id
        )
        self.assertEqual(
            isinstance(router_response, list),
            True,
            "Check list response returns a valid list"
        )
        # List router should have router in running state
        self.assertEqual(
            router_response[0].state,
            'Running',
            "Check list router response for router state"
        )
        self.debug("Started the router with ID: %s" % router.id)

        return

    @attr(tags=["advanced", "intervlan"], required_hardware="false")
    def test_02_reboot_router_after_addition_of_one_guest_network(self):
        """ Test reboot of router after addition of one guest network
            """
        # Validations
        # 1. Create a VPC with cidr - 10.1.1.1/16
        # 2. Add network1(10.1.1.1/24) to this VPC.
        # 3. Deploy vm1,vm2 and vm3 such that they are part of network1.
        # 4. Create a PF /Static Nat/LB rule for vms in network1.
        # 5. Create ingress network ACL for allowing all the above rules from a public ip range on network1.
        # 6. Create egress network ACL for network1 to access google.com.
        # 7. Create a private gateway for this VPC and add a static route to this gateway.
        # 8. Create a VPN gateway for this VPC and add a static route to this gateway.
        # 9. Make sure that all the PF,LB and Static NAT rules work as expected.
        # 10. Make sure that we are able to access google.com from all the user Vms.
        # 11. Make sure that the newly added private gateway's and VPN
        # gateway's static routes work as expected

        self.validate_vpc_offering(self.vpc_off)
        self.validate_vpc_network(self.vpc)
        self.assertEqual(
            isinstance(self.gateways, list),
            True,
            "List private gateways should return a valid response"
        )
        self.assertEqual(
            isinstance(self.static_routes, list),
            True,
            "List static route should return a valid response"
        )

        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        self.assertEqual(
            isinstance(routers, list),
            True,
            "List Routers should return a valid list"
        )
        router = routers[0]

        self.debug("Rebooting the router ...")
        # Reboot the router
        cmd = rebootRouter.rebootRouterCmd()
        cmd.id = router.id
        self.api_client.rebootRouter(cmd)

        # List routers to check state of router
        router_response = list_routers(
            self.api_client,
            id=router.id
        )
        self.assertEqual(
            isinstance(router_response, list),
            True,
            "Check list response returns a valid list"
        )
        # List router should have router in running state and same public IP
        self.assertEqual(
            router_response[0].state,
            'Running',
            "Check list router response for router state"
        )
        return

    @attr(tags=["advanced", "intervlan", "bla"], required_hardware="true")
    def test_03_migrate_router_after_addition_of_one_guest_network(self):
        """ Test migrate of router after addition of one guest network
            """
        # Validations
        # 1. Create a VPC with cidr - 10.1.1.1/16
        # 2. Add network1(10.1.1.1/24) to this VPC.
        # 3. Deploy vm1,vm2 and vm3 such that they are part of network1.
        # 4. Create a PF /Static Nat/LB rule for vms in network1.
        # 5. Create ingress network ACL for allowing all the above rules from a public ip range on network1.
        # 6. Create egress network ACL for network1 to access google.com.
        # 7. Create a private gateway for this VPC and add a static route to this gateway.
        # 8. Create a VPN gateway for this VPC and add a static route to this gateway.
        # 9. Make sure that all the PF,LB and Static NAT rules work as expected.
        # 10. Make sure that we are able to access google.com from all the user Vms.
        # 11. Make sure that the newly added private gateway's and VPN
        # gateway's static routes work as expected

        self.hypervisor = self.testClient.getHypervisorInfo()
        if self.hypervisor.lower() in ['lxc']:
            self.skipTest(
                "vm migrate is not supported in %s" %
                self.hypervisor)
        self.validate_vpc_offering(self.vpc_off)
        self.validate_vpc_network(self.vpc)
        self.assertEqual(
            isinstance(self.gateways, list),
            True,
            "List private gateways should return a valid response"
        )
        self.assertEqual(
            isinstance(self.static_routes, list),
            True,
            "List static route should return a valid response"
        )
        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        self.assertEqual(
            isinstance(routers, list),
            True,
            "List Routers should return a valid list"
        )
        self.migrate_router(routers[0])
        return

    @attr(tags=["advanced", "intervlan"], required_hardware="false")
    def test_04_chg_srv_off_router_after_addition_of_one_guest_network(self):
        """ Test to change service offering of router after addition of one guest network
            """
        # Validations
        # 1. Create a VPC with cidr - 10.1.1.1/16
        # 2. Add network1(10.1.1.1/24) to this VPC.
        # 3. Deploy vm1,vm2 and vm3 such that they are part of network1.
        # 4. Create a PF /Static Nat/LB rule for vms in network1.
        # 5. Create ingress network ACL for allowing all the above rules from a public ip range on network1.
        # 6. Create egress network ACL for network1 to access google.com.
        # 7. Create a private gateway for this VPC and add a static route to this gateway.
        # 8. Create a VPN gateway for this VPC and add a static route to this gateway.
        # 9. Make sure that all the PF,LB and Static NAT rules work as expected.
        # 10. Make sure that we are able to access google.com from all the user Vms.
        # 11. Make sure that the newly added private gateway's and VPN
        # gateway's static routes work as expected

        self.validate_vpc_offering(self.vpc_off)
        self.validate_vpc_network(self.vpc)
        self.assertEqual(
            isinstance(self.gateways, list),
            True,
            "List private gateways should return a valid response"
        )
        self.assertEqual(
            isinstance(self.static_routes, list),
            True,
            "List static route should return a valid response"
        )

        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        self.assertEqual(
            isinstance(routers, list),
            True,
            "List Routers should return a valid list"
        )

        # Stop the router
        router = routers[0]
        self.debug("Stopping the router with ID: %s" % router.id)
        cmd = stopRouter.stopRouterCmd()
        cmd.id = router.id
        self.api_client.stopRouter(cmd)

        service_offering = ServiceOffering.create(
            self.api_client,
            self.services["service_offering_new"]
        )
        self.debug("Changing service offering for the Router %s" % router.id)
        try:
            router = Router.change_service_offering(self.api_client,
                                                    router.id,
                                                    service_offering.id
                                                    )
        except:
            self.fail("Changing service offering failed")

        self.debug("Router %s" % router)
        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        router = routers[0]
        self.assertEqual(
            router.serviceofferingid,
            service_offering.id,
            "Changing service offering failed as id is %s and expected"
            "is %s" % (router.serviceofferingid, service_offering.id)
        )
        return

    @attr(tags=["advanced", "intervlan", "bla"], required_hardware="false")
    def test_05_destroy_router_after_addition_of_one_guest_network(self):
        """ Test destroy of router after addition of one guest network
        """
        # Validations
        # 1. Create a VPC with cidr - 10.1.1.1/16
        # 2. Add network1(10.1.1.1/24) to this VPC.
        # 3. Deploy vm1,vm2 and vm3 such that they are part of network1.
        # 4. Create a PF /Static Nat/LB rule for vms in network1.
        # 5. Create ingress network ACL for allowing all the above rules from a public ip range on network1.
        # 6. Create egress network ACL for network1 to access google.com.
        # 7. Create a private gateway for this VPC and add a static route to this gateway.
        # 8. Create a VPN gateway for this VPC and add a static route to this gateway.
        # 9. Make sure that all the PF,LB and Static NAT rules work as expected.
        # 10. Make sure that we are able to access google.com from all the user Vms.
        # 11. Make sure that the newly added private gateway's and VPN
        # gateway's static routes work as expected

        self.validate_vpc_offering(self.vpc_off)
        self.validate_vpc_network(self.vpc)
        self.assertEqual(
            isinstance(self.gateways, list),
            True,
            "List private gateways should return a valid response"
        )
        self.assertEqual(
            isinstance(self.static_routes, list),
            True,
            "List static route should return a valid response"
        )

        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        self.assertEqual(
            isinstance(routers, list),
            True,
            "List Routers should return a valid list"
        )

        Router.destroy(self.api_client,
                       id=routers[0].id
                       )

        routers = Router.list(
            self.api_client,
            account=self.account.name,
            domainid=self.account.domainid,
            listall=True
        )
        self.assertEqual(
            isinstance(routers, list),
            False,
            "List Routers should be empty"
        )
        return
