# 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 IP reservation feature

    Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/IP+Range+Reservation+within+a+Network+Test+Cases

    Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-2266

    Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/FS+-+IP+Range+Reservation+within+a+Network
"""
from marvin.cloudstackTestCase import cloudstackTestCase
import unittest
from marvin.lib.utils import validateList, cleanup_resources, verifyRouterState
from marvin.lib.base import (Account,
                             Network,
                             VirtualMachine,
                             Router,
                             ServiceOffering,
                             NetworkOffering)
from marvin.lib.common import (get_zone,
                               get_template,
                               get_domain,
                               wait_for_cleanup,
                               createEnabledNetworkOffering,
                               createNetworkRulesForVM,
                               verifyNetworkState)
from marvin.codes import (PASS, FAIL, FAILED, UNKNOWN, FAULT, PRIMARY,
                          NAT_RULE, STATIC_NAT_RULE)
import netaddr

import random
from nose.plugins.attrib import attr
from ddt import ddt, data

def createIsolatedNetwork(self, network_offering_id, gateway=None):
    """Create isolated network with given network offering and gateway if provided
    and return"""
    try:
        isolated_network = Network.create(self.apiclient, self.testData["isolated_network"],
                         networkofferingid=network_offering_id,accountid=self.account.name,
                         domainid=self.domain.id,zoneid=self.zone.id,
                         gateway=gateway, netmask='255.255.255.0' if gateway else None)
    except Exception as e:
        return [FAIL, e]
    return [PASS, isolated_network]

def matchNetworkGuestVmCIDR(self, networkid, guestvmcidr):
    """List networks with given network id and check if the guestvmcidr matches
    with the given cidr"""

    networks = Network.list(self.apiclient, id=networkid, listall=True)
    self.assertEqual(validateList(networks)[0], PASS, "network list validation failed")
    self.assertEqual(str(networks[0].cidr), guestvmcidr, "guestvmcidr of network %s \
                does not match with the given value %s" % (networks[0].cidr, guestvmcidr))

    return

def createVirtualMachine(self, network_id=None, ip_address=None):
    """Create and return virtual machine within network and ipaddress"""
    virtual_machine = VirtualMachine.create(self.apiclient,
                                            self.testData["virtual_machine"],
                                            networkids=network_id,
                                            serviceofferingid=self.service_offering.id,
                                            accountid=self.account.name,
                                            domainid=self.domain.id,
                                            ipaddress=ip_address)
    return virtual_machine

def CreateEnabledNetworkOffering(apiclient, networkServices):
    """Create network offering of given test data and enable it"""

    result = createEnabledNetworkOffering(apiclient, networkServices)
    assert result[0] == PASS, "Network offering creation/enabling failed due to %s" % result[2]
    return result[1]

@ddt
class TestIpReservation(cloudstackTestCase):
    """Test IP Range Reservation with a Network
    """
    @classmethod
    def setUpClass(cls):
        cls.testClient = super(TestIpReservation, cls).getClsTestClient()
        cls.api_client = cls.testClient.getApiClient()

        # Fill services from the external config file
        cls.testData = cls.testClient.getParsedTestDataConfig()

        # 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.testData["ostype"]
                            )
        if cls.template == FAILED:
            assert False, "get_template() failed to return template with description %s" % cls.testData["ostype"]
        cls.testData["domainid"] = cls.domain.id
        cls.testData["zoneid"] = cls.zone.id
        cls.testData["virtual_machine"]["zoneid"] = cls.zone.id
        cls.testData["virtual_machine"]["template"] = cls.template.id
        cls._cleanup = []
        try:
            cls.service_offering = ServiceOffering.create(
                                            cls.api_client,
                                            cls.testData["service_offering"]
                                            )
            cls._cleanup.append(cls.service_offering)
            cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client,
                                            cls.testData["isolated_network_offering"])
            cls._cleanup.append(cls.isolated_network_offering)
            cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client,
                                            cls.testData["nw_off_isolated_persistent"])
            cls._cleanup.append(cls.isolated_persistent_network_offering)
            cls.isolated_network_offering_RVR = CreateEnabledNetworkOffering(cls.api_client,
                                            cls.testData["nw_off_isolated_RVR"])
            cls._cleanup.append(cls.isolated_network_offering_RVR)
        except Exception as e:
            cls.tearDownClass()
            raise unittest.SkipTest("Failure in setUpClass: %s" % e)
        return

    @classmethod
    def tearDownClass(cls):
        try:
            # Cleanup resources used
            cleanup_resources(cls.api_client, cls._cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.cleanup = []
        try:
            self.account = Account.create(self.apiclient, self.testData["account"],
                                      domainid=self.domain.id)
            self.cleanup.append(self.account)
        except Exception as e:
            self.skipTest("Failed to create account: %s" % e)
        return

    def tearDown(self):
        try:
            # Clean up, terminate the resources created
            cleanup_resources(self.apiclient, self.cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    @attr(tags=["advanced"])
    def test_vm_create_after_reservation(self):
        """ Test creating VM in network after IP reservation
        # steps
        # 1. Create vm in isolated network (LB through VR or Netscaler) with ip in guestvmcidr
        # 2. Update guestvmcidr
        # 3. Create another VM
        # validation
        # 1. Guest vm cidr should be successfully updated with correct value
        # 2. Existing guest vm ip should not be changed after reservation
        # 3. Newly created VM should get ip in guestvmcidr"""

        networkOffering = self.isolated_network_offering
        subnet = "10.1."+str(random.randrange(1,254))
        gateway = subnet +".1"
        resultSet = createIsolatedNetwork(self, networkOffering.id, gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_network = resultSet[1]
        guest_vm_cidr = subnet +".0/29"

        try:
            virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id,
                    ip_address = subnet+".3")
        except Exception as e:
            self.fail("VM creation failed: %s" % e)

        isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr)
        matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr)
        vms = VirtualMachine.list(self.apiclient,
                                       id=virtual_machine_1.id)
        self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed")
        self.assertEqual(vms[0].nic[0].ipaddress,
                          virtual_machine_1.ipaddress,
                           "VM IP should not change after reservation")
        try:
            virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id)
            if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr):
                self.fail("Newly created VM doesn't get IP from reserverd CIDR")
        except Exception as e:
            self.fail("VM creation failed, cannot validate the condition: %s" % e)
        return

    @attr(tags=["advanced"])
    def test_vm_create_outside_cidr_after_reservation(self):
        """ Test create VM outside the range of reserved IPs
        # steps
        # 1. update guestvmcidr of persistent isolated network (LB through VR or
        #    Netscaler
        # 2. create another VM with ip outside guestvmcidr
        """
        # validation
        # 1. guest vm cidr should be successfully updated with correct value
        # 2  newly created VM should not be created and result in exception

        networkOffering = self.isolated_persistent_network_offering
        subnet = "10.1."+str(random.randrange(1,254))
        gateway = subnet +".1"
        resultSet = createIsolatedNetwork(self, networkOffering.id, gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_network = resultSet[1]
        guest_vm_cidr = subnet+".0/29"

        isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr)
        matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr)
        try:
            createVirtualMachine(self, network_id=self.isolated_network.id,
                                 ip_address=subnet+".9")
            self.fail("vm should not be created ")
        except Exception as e:
            self.debug("exception as IP is outside of guestvmcidr %s" % e)
        return

    @attr(tags=["advanced"])
    def test_update_cidr_multiple_vms_not_all_inclusive(self):
        """ Test reserve IP range such that one of the VM is not included
        # steps
        # 1. Create two vms in isolated network
        # 2. Update guestvmcidr of network such that only one of the ipaddress of vms
        #    is in the given range
        # validation
        # 1. Network updation with this new range should fail"""

        subnet = "10.1."+str(random.randrange(1,254))
        gateway = subnet +".1"
        resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id,
                                          gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_network = resultSet[1]
        guest_vm_cidr = subnet+".0/29"

        try:
            createVirtualMachine(self, network_id=isolated_network.id,
                    ip_address=subnet+".3")
        except Exception as e:
            self.fail("VM creation failed: %s" % e)

        try:
            createVirtualMachine(self, network_id=isolated_network.id,
                    ip_address=subnet+".9")
        except Exception as e:
            self.fail("VM creation failed: %s" % e)

        with self.assertRaises(Exception):
            isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr)
        return

    @attr(tags=["advanced"])
    def test_update_cidr_single_vm_not_inclusive(self):
        """ Test reserving IP range in network such that existing VM is outside the range
        # steps
        # 1. Create vm in isolated network
        # 2. Update guestvmcidr of network such that ip address of vm
        #    is outside the given range
        #
        # validation
        # 1. Network updation with this new range should fail"""
        subnet = "10.1."+str(random.randrange(1,254))
        gateway = subnet +".1"
        resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id,
                                          gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_network = resultSet[1]
        guest_vm_cidr = subnet+".0/29"

        try:
            createVirtualMachine(self, network_id=isolated_network.id,
                    ip_address=subnet+".9")
        except Exception as e:
            self.fail("VM creation failed: %s" % e)

        with self.assertRaises(Exception):
            isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr)
        return

    @data(NAT_RULE, STATIC_NAT_RULE)
    @attr(tags=["advanced"], required_hardware="true")
    def test_nat_rules(self, value):
        """ Test NAT rules working with IP reservation
        # steps
        # 1. Create vm in persistent isolated network with ip in guestvmcidr
        # 2. Create NAT/static NAT rule for this VM
        # 3. Update guestvmcidr
        # 4. Create another VM and create network rules for this vm too
        #
        # validation
        # 1. Guest vm cidr should be successfully updated with correct value
        # 2. Existing guest vm ip should not be changed after reservation
        # 3. Newly created VM should get ip in guestvmcidr
        # 4. The network rules should be working"""

        subnet = "10.1."+str(random.randrange(1,254))
        gateway = subnet +".1"
        resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id,
                                          gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_network = resultSet[1]
        guest_vm_cidr = subnet+".0/29"

        try:
            virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id,
                    ip_address=subnet+".3")
        except Exception as e:
            self.fail("VM creation failed: %s" % e)

        result = createNetworkRulesForVM(self.apiclient, virtual_machine_1,value,
                                         self.account, self.testData)
        if result[0] == FAIL:
            self.fail("Failed to create network rules for VM: %s" % result[1])
        else:
            ipaddress_1 = result[1]
        virtual_machine_1.get_ssh_client(ipaddress=ipaddress_1.ipaddress.ipaddress)

        isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr)
        matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr)
        vms = VirtualMachine.list(self.apiclient, id=virtual_machine_1.id)
        self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed")
        self.assertEqual(vms[0].nic[0].ipaddress,
                          virtual_machine_1.ipaddress,
                           "VM IP should not change after reservation")
        try:
            virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id)
            if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr):
                self.fail("Newly created VM doesn't get IP from reserverd CIDR")
        except Exception as e:
            self.fail("VM creation failed, cannot validate the condition: %s" % e)

        result = createNetworkRulesForVM(self.apiclient, virtual_machine_2, value,
                                         self.account, self.testData)
        if result[0] == FAIL:
            self.fail("Failed to create network rules for VM: %s" % result[1])
        else:
            ipaddress_2 = result[1]
        virtual_machine_2.get_ssh_client(ipaddress=ipaddress_2.ipaddress.ipaddress)
        return

    @unittest.skip("Skip - WIP")
    @attr(tags=["advanced"])
    def test_RVR_network(self):
        """ Test IP reservation in network with RVR
        # steps
        # 1. create vm in isolated network with RVR and ip in guestvmcidr
        # 2. update guestvmcidr
        # 3. List routers and stop the primary router, wait till backup router comes up
        # 4. create another VM
        #
        # validation
        # 1. Guest vm cidr should be successfully updated with correct value
        # 2. Existing guest vm ip should not be changed after reservation
        # 3. Newly created VM should get ip in guestvmcidr
        # 4. Verify that the network has two routers associated with it
        # 5. Backup router should come up when primary router is stopped"""

        subnet = "10.1."+str(random.randrange(1,254))
        gateway = subnet +".1"
        resultSet = createIsolatedNetwork(self, self.isolated_network_offering_RVR.id,
                                          gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_network_RVR= resultSet[1]
        guest_vm_cidr = subnet+".0/29"

        try:
            virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network_RVR.id,
                    ip_address=subnet+".3")
        except Exception as e:
            self.fail("VM creation failed: %s" % e)

        isolated_network_RVR.update(self.apiclient, guestvmcidr=guest_vm_cidr)
        matchNetworkGuestVmCIDR(self, isolated_network_RVR.id, guest_vm_cidr)
        vms = VirtualMachine.list(self.apiclient,
                                       id=virtual_machine_1.id)
        self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed")
        self.assertEqual(vms[0].nic[0].ipaddress,
                          virtual_machine_1.ipaddress,
                           "VM IP should not change after reservation")

        self.debug("Listing routers for network: %s" % isolated_network_RVR.name)
        routers = Router.list(self.apiclient, networkid=isolated_network_RVR.id, listall=True)
        self.assertEqual(validateList(routers)[0], PASS, "Routers list validation failed")
        self.assertEqual(len(routers), 2, "Length of the list router should be 2 (Backup & primary)")

        if routers[0].redundantstate == PRIMARY:
            primary_router = routers[0]
            backup_router = routers[1]
        else:
            primary_router = routers[1]
            backup_router = routers[0]

        self.debug("Stopping router ID: %s" % primary_router.id)

        try:
            Router.stop(self.apiclient, id=primary_router.id)
        except Exception as e:
            self.fail("Failed to stop primary router due to error %s" % e)

        # wait for VR to update state
        wait_for_cleanup(self.apiclient, ["router.check.interval"])

        result = verifyRouterState(primary_router.id, [UNKNOWN,FAULT])
        if result[0] == FAIL:
            self.fail(result[1])
        result = verifyRouterState(backup_router.id, [PRIMARY])
        if result[0] == FAIL:
            self.fail(result[1])

        try:
            virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network_RVR.id)
            if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr):
                self.fail("Newly created VM doesn't get IP from reserverd CIDR")
        except Exception as e:
            self.fail("VM creation failed, cannot validate the condition: %s" % e)
        return

    @attr(tags=["advanced"])
    def test_ip_reservation_in_multiple_networks_same_account(self):
        """ Test IP reservation in multiple networks created in same account
        # steps
        # 1. Create two isolated networks with user defined cidr in same account
        # Test below conditions for both the networks in the account
        # 2. Create vm in persistent isolated network with ip in guestvmcidr
        # 3. Update guestvmcidr
        # 4. Create another VM
        #
        # validation
        # 1. Guest vm cidr should be successfully updated with correct value
        # 2. Existing guest vm ip should not be changed after reservation
        # 3. Newly created VM should get ip in guestvmcidr"""

        account_1 = Account.create(self.apiclient, self.testData["account"],
                                      domainid=self.domain.id)
        self.cleanup.append(account_1)

        random_subnet = str(random.randrange(1,254))
        gateway = "10.1." + random_subnet +".1"
        isolated_network_1 = Network.create(self.apiclient, self.testData["isolated_network"],
                         networkofferingid=self.isolated_network_offering.id,accountid=account_1.name,
                         domainid=self.domain.id,zoneid=self.zone.id,
                         gateway=gateway, netmask='255.255.255.0')
        guest_vm_cidr = "10.1."+random_subnet+".0/29"

        try:
            virtual_machine_1 = VirtualMachine.create(self.apiclient, self.testData["virtual_machine"],
                                            networkids=isolated_network_1.id, serviceofferingid=self.service_offering.id,
                                            accountid=account_1.name, domainid=self.domain.id,
                                            ipaddress="10.1."+random_subnet+".3")
        except Exception as e:
            self.fail("VM creation failed: %s" % e)

        isolated_network_1.update(self.apiclient, guestvmcidr=guest_vm_cidr)
        matchNetworkGuestVmCIDR(self, isolated_network_1.id, guest_vm_cidr)
        vms = VirtualMachine.list(self.apiclient,
                                       id=virtual_machine_1.id)
        self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed")
        self.assertEqual(vms[0].nic[0].ipaddress,
                          virtual_machine_1.ipaddress,
                           "VM IP should not change after reservation")

        try:
            virtual_machine_2 = VirtualMachine.create(self.apiclient, self.testData["virtual_machine"],
                                            networkids=isolated_network_1.id, serviceofferingid=self.service_offering.id,
                                            accountid=account_1.name, domainid=self.domain.id)
            if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr):
                self.fail("Newly created VM doesn't get IP from reserverd CIDR")
        except Exception as e:
            self.fail("VM creation failed, cannot validate the condition: %s" % e)

        random_subnet = str(random.randrange(1,254))
        gateway = "10.1." + random_subnet +".1"
        isolated_network_2 = Network.create(self.apiclient, self.testData["isolated_network"],
                         networkofferingid=self.isolated_network_offering.id,accountid=account_1.name,
                         domainid=self.domain.id,zoneid=self.zone.id,
                         gateway=gateway, netmask='255.255.255.0')
        guest_vm_cidr = "10.1."+random_subnet+".0/29"

        try:
            virtual_machine_3 = VirtualMachine.create(self.apiclient, self.testData["virtual_machine"],
                                            networkids=isolated_network_2.id, serviceofferingid=self.service_offering.id,
                                            accountid=account_1.name, domainid=self.domain.id,
                                            ipaddress="10.1."+random_subnet+".3")
        except Exception as e:
            self.fail("VM creation failed: %s" % e)

        isolated_network_2.update(self.apiclient, guestvmcidr=guest_vm_cidr)
        matchNetworkGuestVmCIDR(self, isolated_network_2.id, guest_vm_cidr)
        vms = VirtualMachine.list(self.apiclient,
                                       id=virtual_machine_3.id)
        self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed")
        self.assertEqual(vms[0].nic[0].ipaddress,
                          virtual_machine_3.ipaddress,
                           "VM IP should not change after reservation")

        try:
            virtual_machine_4 = VirtualMachine.create(self.apiclient, self.testData["virtual_machine"],
                                            networkids=isolated_network_2.id, serviceofferingid=self.service_offering.id,
                                            accountid=account_1.name, domainid=self.domain.id)
            if netaddr.IPAddress(virtual_machine_4.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr):
                self.fail("Newly created VM doesn't get IP from reserverd CIDR")
        except Exception as e:
            self.fail("VM creation failed, cannot validate the condition: %s" % e)
        return

@ddt
class TestRestartNetwork(cloudstackTestCase):
    """Test Restart Network
    """
    @classmethod
    def setUpClass(cls):
        cls.testClient = super(TestRestartNetwork, cls).getClsTestClient()
        cls.api_client = cls.testClient.getApiClient()

        # Fill services from the external config file
        cls.testData = cls.testClient.getParsedTestDataConfig()

        # 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.testData["ostype"]
                            )
        if cls.template == FAILED:
            assert False, "get_template() failed to return template with description %s" % cls.testData["ostype"]
        cls.testData["domainid"] = cls.domain.id
        cls.testData["zoneid"] = cls.zone.id
        cls.testData["virtual_machine"]["zoneid"] = cls.zone.id
        cls.testData["virtual_machine"]["template"] = cls.template.id
        cls._cleanup = []
        try:
            cls.service_offering = ServiceOffering.create(
                                            cls.api_client,
                                            cls.testData["service_offering"]
                                            )
            cls._cleanup.append(cls.service_offering)
            cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client,
                                                cls.testData["isolated_network_offering"])
            cls._cleanup.append(cls.isolated_network_offering)
            cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client,
                                                        cls.testData["nw_off_isolated_persistent"])
            cls._cleanup.append(cls.isolated_persistent_network_offering)
        except Exception as e:
            cls.tearDownClass()
            raise unittest.SkipTest("Failure in setUpClass: %s" % e)
        return

    @classmethod
    def tearDownClass(cls):
        try:
            # Cleanup resources used
            cleanup_resources(cls.api_client, cls._cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.cleanup = []
        try:
            self.account = Account.create(self.apiclient, self.testData["account"],
                                      domainid=self.domain.id)
            self.cleanup.append(self.account)
        except Exception as e:
            self.skipTest("Failed to create account: %s" % e)
        return

    def tearDown(self):
        try:
            # Clean up, terminate the resources created
            cleanup_resources(self.apiclient, self.cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    @data(True, False)
    @attr(tags=["advanced"])
    def test_restart_network_with_cleanup(self, value):
        """ Test IP reservation rules with network restart operation
        # steps
        # 1. Create vm in isolated network with ip in guestvmcidr
        # 2. Update guestvmcidr
        # 3. Restart network with cleanup True/False
        # 4. Deploy another VM in the network
        #
        # validation
        # 1. Guest vm cidr should be successfully updated with correct value
        # 2. Existing guest vm ip should not be changed after reservation
        # 3. Network should be restarted successfully with and without cleanup
        # 4. Newly created VM should get ip in guestvmcidr"""

        subnet = "10.1."+str(random.randrange(1,254))
        gateway = subnet +".1"
        resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id,
                                          gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_network= resultSet[1]
        guest_vm_cidr = subnet+".0/29"

        try:
            virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id,
                    ip_address=subnet+".3")
        except Exception as e:
            self.fail("VM creation failed: %s" % e)

        isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr)
        matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr)
        vms = VirtualMachine.list(self.apiclient,
                                       id=virtual_machine_1.id)
        self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed")
        self.assertEqual(vms[0].nic[0].ipaddress,
                          virtual_machine_1.ipaddress,
                           "VM IP should not change after reservation")

        #Restart Network
        isolated_network.restart(self.apiclient, cleanup=value)

        try:
            virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id)
            if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr):
                self.fail("Newly created VM doesn't get IP from reserverd CIDR")
        except Exception as e:
            self.fail("VM creation failed, cannot validate the condition: %s" % e)
        return

@ddt
class TestUpdateIPReservation(cloudstackTestCase):
    """Test Updating IP reservation multiple times
    """
    @classmethod
    def setUpClass(cls):
        cls.testClient = super(TestUpdateIPReservation, cls).getClsTestClient()
        cls.api_client = cls.testClient.getApiClient()

        # Fill services from the external config file
        cls.testData = cls.testClient.getParsedTestDataConfig()

        # 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.testData["ostype"]
                            )
        if cls.template == FAILED:
            assert False, "get_template() failed to return template with description %s" % cls.testData["ostype"]
        cls.testData["domainid"] = cls.domain.id
        cls.testData["zoneid"] = cls.zone.id
        cls.testData["virtual_machine"]["zoneid"] = cls.zone.id
        cls.testData["virtual_machine"]["template"] = cls.template.id
        cls._cleanup = []
        try:
            cls.service_offering = ServiceOffering.create(
                                            cls.api_client,
                                            cls.testData["service_offering"]
                                            )
            cls._cleanup.append(cls.service_offering)
            cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client,
                                            cls.testData["isolated_network_offering"])
            cls._cleanup.append(cls.isolated_network_offering)
            cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client,
                                                        cls.testData["nw_off_isolated_persistent"])
            cls._cleanup.append(cls.isolated_persistent_network_offering)
        except Exception as e:
            cls.tearDownClass()
            raise unittest.SkipTest("Failure in setUpClass: %s" % e)
        return

    @classmethod
    def tearDownClass(cls):
        try:
            # Cleanup resources used
            cleanup_resources(cls.api_client, cls._cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.cleanup = []
        try:
            self.account = Account.create(self.apiclient, self.testData["account"],
                                      domainid=self.domain.id)
            self.cleanup.append(self.account)
        except Exception as e:
            self.skipTest("Failed to create account: %s" % e)
        return

    def tearDown(self):
        try:
            # Clean up, terminate the resources created
            cleanup_resources(self.apiclient, self.cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    @data("existingVmInclusive", "existingVmExclusive")
    @attr(tags=["advanced"])
    def test_update_network_guestvmcidr(self, value):
        """ Test updating guest vm cidr of the network after
        VMs are already deployed in previous guest VM cidr

        # steps
        # 1. Create isolated network with user defined cidr
        # 2. Deploy VM in the network
        # 3. Try to update the guestvmcidr of the network with VM ip in the guestvmcidr and
        #    deploy another VM
        # 4. Try to update the guestvmcidr of the network with VM ip outside the guestvmcidr
        #
        # validation
        # 1. When vm IP is in the guestvmcidr, updation should be successful and
        #    new VM should get IP from this range
        # 2. When VM IP is outside the guestvmcidr, updation should be unsuccessful"""

        random_subnet = str(random.randrange(1,254))
        gateway = "10.1." + random_subnet +".1"
        resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id,
                                          gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_network= resultSet[1]
        guest_vm_cidr = "10.1."+random_subnet+".0/29"

        try:
            virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id,
                    ip_address="10.1."+random_subnet+".3")
        except Exception as e:
            self.fail("VM creation failed: %s" % e)

        isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr)
        matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr)
        vms = VirtualMachine.list(self.apiclient,
                                       id=virtual_machine_1.id)
        self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed")
        self.assertEqual(vms[0].nic[0].ipaddress,
                          virtual_machine_1.ipaddress,
                           "VM IP should not change after reservation")

        try:
            virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id)
            if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr):
                self.fail("Newly created VM doesn't get IP from reserverd CIDR")
        except Exception as e:
            self.fail("VM creation failed, cannot validate the condition: %s" % e)

        # Update guest vm cidr of network again
        if value == "existingVmExclusive":
            guest_vm_cidr = "10.1."+random_subnet+".10/29"

            try:
                isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr)
                self.fail("Network updation should fail")
            except Exception as e:
                self.debug("Failed to update guest VM cidr of network: %s" % e)
        elif value == "existingVmInclusive":
            guest_vm_cidr = "10.1."+random_subnet+".0/28"

            try:
                isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr)
            except Exception as e:
                self.fail("Failed to update guest VM cidr of network: %s" % e)

            matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr)

            try:
                virtual_machine_3 = createVirtualMachine(self, network_id=isolated_network.id)
                if netaddr.IPAddress(virtual_machine_3.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr):
                    self.fail("Newly created VM doesn't get IP from reserverd CIDR")
            except Exception as e:
                self.fail("VM creation failed, cannot validate the condition: %s" % e)
        return

@ddt
class TestRouterOperations(cloudstackTestCase):
    """Test Router operations of network with IP reservation
    """
    @classmethod
    def setUpClass(cls):
        cls.testClient = super(TestRouterOperations, cls).getClsTestClient()
        cls.api_client = cls.testClient.getApiClient()

        # Fill services from the external config file
        cls.testData = cls.testClient.getParsedTestDataConfig()

        # 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.testData["ostype"]
                            )
        if cls.template == FAILED:
            assert False, "get_template() failed to return template with description %s" % cls.testData["ostype"]
        cls.testData["domainid"] = cls.domain.id
        cls.testData["zoneid"] = cls.zone.id
        cls.testData["virtual_machine"]["zoneid"] = cls.zone.id
        cls.testData["virtual_machine"]["template"] = cls.template.id
        cls._cleanup = []
        try:
            cls.service_offering = ServiceOffering.create(
                                            cls.api_client,
                                            cls.testData["service_offering"]
                                            )
            cls._cleanup.append(cls.service_offering)
            cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client,
                                                cls.testData["isolated_network_offering"])
            cls._cleanup.append(cls.isolated_network_offering)
            cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client,
                                                        cls.testData["nw_off_isolated_persistent"])
            cls._cleanup.append(cls.isolated_persistent_network_offering)
        except Exception as e:
            cls.tearDownClass()
            raise unittest.SkipTest("Failure in setUpClass: %s" % e)
        return

    @classmethod
    def tearDownClass(cls):
        try:
            # Cleanup resources used
            cleanup_resources(cls.api_client, cls._cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.cleanup = []
        try:
            self.account = Account.create(self.apiclient, self.testData["account"],
                                      domainid=self.domain.id)
            self.cleanup.append(self.account)
        except Exception as e:
            self.skipTest("Failed to create account: %s" % e)
        return

    def tearDown(self):
        try:
            # Clean up, terminate the resources created
            cleanup_resources(self.apiclient, self.cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    @attr(tags=["advanced"])
    def test_reservation_after_router_restart(self):
        """ Test IP reservation working before and after router is restarted
        # steps
        # 1. Update guestvmcidr of persistent isolated network
        # 2. Reboot router
        #
        # validation
        # 1. Guest vm cidr should be successfully updated with correct value
        # 2. Network cidr should remain same after router restart"""
        subnet = "10.1."+str(random.randrange(1,254))
        gateway = subnet +".1"
        resultSet = createIsolatedNetwork(self, self.isolated_persistent_network_offering.id,
                                          gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_network= resultSet[1]
        guest_vm_cidr = subnet+".0/29"

        isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr)
        matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr)

        routers = Router.list(self.apiclient,
                             networkid=isolated_network.id,
                             listall=True)
        self.assertEqual(validateList(routers)[0], PASS, "routers list validation failed")
        if not routers:
            self.fail("Router list should not be empty")

        Router.reboot(self.apiclient, routers[0].id)
        networks = Network.list(self.apiclient, id=isolated_network.id)
        self.assertEqual(validateList(networks)[0], PASS, "networks list validation failed")
        self.assertEqual(networks[0].cidr, guest_vm_cidr, "guestvmcidr should match after router reboot")
        return

    @attr(tags=["advanced"])
    def test_destroy_recreate_router(self):
        """ Test IP reservation working after destroying and recreating router
        # steps
        # 1. Create isolated network and deploy VM in it and update network with
        #    guestvmcidr
        # 2. List the router associated with network and destroy the router
        # 3. Restart the network
        # 3. Deploy another VM in the network
        #
        # validation
        # 1. Guest vm cidr should be successfully updated with correct value
        # 2. existing guest vm ip should not be changed after reservation
        # 3. Router should be destroyed and recreated when network is restarted
        # 4. New VM should be deployed in the guestvmcidr"""

        subnet = "10.1."+str(random.randrange(1,254))
        gateway = subnet +".1"
        resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id,
                                          gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_network= resultSet[1]
        guest_vm_cidr = subnet+".0/29"

        try:
            virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id,
                    ip_address=subnet+".3")
        except Exception as e:
            self.fail("VM creation failed: %s" % e)

        isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr)
        matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr)
        vms = VirtualMachine.list(self.apiclient,
                                       id=virtual_machine_1.id)
        self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed")
        self.assertEqual(vms[0].nic[0].ipaddress,
                          virtual_machine_1.ipaddress,
                           "VM IP should not change after reservation")

        # List router and destroy it
        routers = Router.list(self.apiclient, networkid=isolated_network.id, listall=True)
        self.assertEqual(validateList(routers)[0], PASS, "Routers list validation failed")

        # Destroy Router
        Router.destroy(self.apiclient, id=routers[0].id)

        #Restart Network
        isolated_network.restart(self.apiclient)

        try:
            virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id)
            if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr):
                self.fail("Newly created VM doesn't get IP from reserverd CIDR")
        except Exception as e:
            self.fail("VM creation failed, cannot validate the condition: %s" % e)
        return

@ddt
class TestFailureScnarios(cloudstackTestCase):
    """Test failure scenarios related to IP reservation in network
    """
    @classmethod
    def setUpClass(cls):
        cls.testClient = super(TestFailureScnarios, cls).getClsTestClient()
        cls.api_client = cls.testClient.getApiClient()

        # Fill services from the external config file
        cls.testData = cls.testClient.getParsedTestDataConfig()

        # 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.testData["ostype"]
                            )
        if cls.template == FAILED:
            assert False, "get_template() failed to return template with description %s" % cls.testData["ostype"]
        cls.testData["domainid"] = cls.domain.id
        cls.testData["zoneid"] = cls.zone.id
        cls.testData["virtual_machine"]["zoneid"] = cls.zone.id
        cls.testData["virtual_machine"]["template"] = cls.template.id
        cls._cleanup = []
        try:
            cls.service_offering = ServiceOffering.create(
                                            cls.api_client,
                                            cls.testData["service_offering"]
                                            )
            cls._cleanup.append(cls.service_offering)
            cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client,
                                            cls.testData["isolated_network_offering"])
            cls._cleanup.append(cls.isolated_network_offering)
            cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client,
                                                        cls.testData["nw_off_isolated_persistent"])
            cls._cleanup.append(cls.isolated_persistent_network_offering)

            cls.testData["shared_network_offering"]["specifyVlan"] = "True"
            cls.testData["shared_network_offering"]["specifyIpRanges"] = "True"

            #Create Network Offering
            cls.shared_network_offering = NetworkOffering.create(cls.api_client,
                                        cls.testData["shared_network_offering"],
                                        conservemode=False)
            cls._cleanup.append(cls.shared_network_offering)

            #Update network offering state from disabled to enabled.
            NetworkOffering.update(cls.shared_network_offering,cls.api_client,state="enabled")
        except Exception as e:
            cls.tearDownClass()
            raise unittest.SkipTest("Failure in setUpClass: %s" % e)
        return

    @classmethod
    def tearDownClass(cls):
        try:
            # Cleanup resources used
            cleanup_resources(cls.api_client, cls._cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.cleanup = []
        try:
            self.account = Account.create(self.apiclient, self.testData["account"],
                                      domainid=self.domain.id)
            self.cleanup.append(self.account)
        except Exception as e:
            self.skipTest("Failed to create account: %s" % e)
        return

    def tearDown(self):
        try:
            # Clean up, terminate the resources created
            cleanup_resources(self.apiclient, self.cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    @attr(tags=["advanced"], required_hardware="false")
    def test_network_not_implemented(self):
        # steps
        # 1. update guestvmcidr of isolated network (non persistent)
        #
        # validation
        # should succeed although network is not in implemented state

        networkOffering = self.isolated_network_offering
        resultSet = createIsolatedNetwork(self, networkOffering.id)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_network = resultSet[1]

        isolated_network.update(self.apiclient, guestvmcidr="10.1.1.0/26")

    @attr(tags=["advanced"], required_hardware="false")
    def test_vm_create_after_reservation(self):
        # steps
        # 1. create vm in persistent isolated network with ip in guestvmcidr
        # 2. update guestvmcidr
        # 3. create another VM
        #
        # validation
        # 1. guest vm cidr should be successfully updated with correct value
        # 2. existing guest vm ip should not be changed after reservation
        # 3. newly created VM should get ip in guestvmcidr

        networkOffering = self.isolated_persistent_network_offering
        subnet = "10.1."+str(random.randrange(1,254))
        gateway = subnet + ".1"
        isolated_persistent_network = None
        resultSet = createIsolatedNetwork(self, networkOffering.id, gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_persistent_network = resultSet[1]
        guest_vm_cidr = subnet +".0/29"
        virtual_machine_1 = None
        try:
            virtual_machine_1 = VirtualMachine.create(self.apiclient,
                                                          self.testData["virtual_machine"],
                                                          networkids=isolated_persistent_network.id,
                                                          serviceofferingid=self.service_offering.id,
                                                          accountid=self.account.name,
                                                          domainid=self.domain.id,
                                                          ipaddress=subnet+".3"
                                                          )
        except Exception as e:
            self.fail("VM creation fails in network: %s" % e)

        update_response = Network.update(isolated_persistent_network, self.apiclient, id=isolated_persistent_network.id, guestvmcidr=guest_vm_cidr)
        self.assertEqual(guest_vm_cidr, update_response.cidr, "cidr in response is not as expected")
        vm_list = VirtualMachine.list(self.apiclient,
                                       id=virtual_machine_1.id)
        self.assertEqual(isinstance(vm_list, list),
                         True,
                         "VM list response in not a valid list")
        self.assertEqual(vm_list[0].nic[0].ipaddress,
                          virtual_machine_1.ipaddress,
                           "VM IP should not change after reservation")
        try:
            virtual_machine_2 = VirtualMachine.create(self.apiclient,
                                                          self.testData["virtual_machine"],
                                                          networkids=isolated_persistent_network.id,
                                                          serviceofferingid=self.service_offering.id,
                                                          accountid=self.account.name,
                                                          domainid=self.domain.id
                                                          )
            if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr):
                self.fail("Newly created VM doesn't get IP from reserverd CIDR")
        except Exception as e:
            self.skipTest("VM creation fails, cannot validate the condition: %s" % e)
        return

    @attr(tags=["advanced"], required_hardware="false")
    def test_reservation_after_router_restart(self):
        # steps
        # 1. update guestvmcidr of persistent isolated network
        # 2. reboot router
        #
        # validation
        # 1. guest vm cidr should be successfully updated with correct value
        # 2. network cidr should remain same after router restart
        networkOffering = self.isolated_persistent_network_offering
        subnet = "10.1."+str(random.randrange(1,254))
        gateway = subnet + ".1"
        isolated_persistent_network = None
        resultSet = createIsolatedNetwork(self, networkOffering.id, gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_persistent_network = resultSet[1]

        response = verifyNetworkState(self.apiclient, isolated_persistent_network.id,\
                        "implemented")
        exceptionOccurred = response[0]
        isNetworkInDesiredState = response[1]
        exceptionMessage = response[2]

        if (exceptionOccurred or (not isNetworkInDesiredState)):
            self.fail(exceptionMessage)
        guest_vm_cidr = subnet +".0/29"

        update_response = Network.update(isolated_persistent_network, self.apiclient, id=isolated_persistent_network.id, guestvmcidr=guest_vm_cidr)
        self.assertEqual(guest_vm_cidr, update_response.cidr, "cidr in response is not as expected")

        routers = Router.list(self.apiclient,
                             networkid=isolated_persistent_network.id,
                             listall=True)
        self.assertEqual(
                    isinstance(routers, list),
                    True,
                    "list router should return valid response"
                    )
        if not routers:
            self.skipTest("Router list should not be empty, skipping test")

        Router.reboot(self.apiclient, routers[0].id)
        networks = Network.list(self.apiclient, id=isolated_persistent_network.id)
        self.assertEqual(
                    isinstance(networks, list),
                    True,
                    "list Networks should return valid response"
                    )
        self.assertEqual(networks[0].cidr, guest_vm_cidr, "guestvmcidr should match after router reboot")
        return

    @attr(tags=["advanced"], required_hardware="false")
    def test_vm_create_outside_cidr_after_reservation(self):
        # steps
        # 1. update guestvmcidr of persistent isolated network
        # 2. create another VM with ip outside guestvmcidr
        #
        # validation
        # 1. guest vm cidr should be successfully updated with correct value
        # 2  newly created VM should not be created and result in exception
        networkOffering = self.isolated_persistent_network_offering
        subnet = "10.1."+str(random.randrange(1,254))
        gateway = subnet + ".1"
        isolated_persistent_network = None
        resultSet = createIsolatedNetwork(self, networkOffering.id, gateway=gateway)
        if resultSet[0] == FAIL:
            self.fail("Failed to create isolated network")
        else:
            isolated_persistent_network = resultSet[1]
        guest_vm_cidr = subnet +".0/29"
        update_response = Network.update(isolated_persistent_network, self.apiclient, id=isolated_persistent_network.id, guestvmcidr=guest_vm_cidr)
        self.assertEqual(guest_vm_cidr, update_response.cidr, "cidr in response is not as expected")
        with self.assertRaises(Exception):
            VirtualMachine.create(self.apiclient,
                                  self.testData["virtual_machine"],
                                  networkids=isolated_persistent_network.id,
                                  serviceofferingid=self.service_offering.id,
                                  accountid=self.account.name,
                                  domainid=self.domain.id,
                                  ipaddress="10.1.1.9"
                                  )
        return
