# 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.
""" P1 tests for Resource creation
"""
#Import Local Modules
import marvin
from nose.plugins.attrib import attr
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
from marvin.integration.lib.utils import *
from marvin.integration.lib.base import *
from marvin.integration.lib.common import *
from marvin.remoteSSHClient import remoteSSHClient
import datetime


class Services:
    """Test Resource creation Services
    """

    def __init__(self):
        self.services = {
                        "domain": {
                                   "name": "Domain",
                        },
                        "project": {
                                    "name": "Project",
                                    "displaytext": "Test project",
                        },
                        "account": {
                                    "email": "administrator@clogeny.com",
                                    "firstname": "Test",
                                    "lastname": "User",
                                    "username": "test",
                                    # Random characters are appended for unique
                                    # username
                                    "password": "password",
                         },
                         "user": {
                                    "email": "administrator@clogeny.com",
                                    "firstname": "User",
                                    "lastname": "User",
                                    "username": "User",
                                    # Random characters are appended for unique
                                    # username
                                    "password": "password",
                         },
                         "service_offering": {
                                    "name": "Tiny Instance",
                                    "displaytext": "Tiny Instance",
                                    "cpunumber": 1,
                                    "cpuspeed": 100,    # in MHz
                                    "memory": 128,       # In MBs
                        },
                        "disk_offering": {
                                    "displaytext": "Tiny Disk Offering",
                                    "name": "Tiny Disk Offering",
                                    "disksize": 1
                        },
                        "volume": {
                                   "diskname": "Test Volume",
                        },
                        "server": {
                                    "displayname": "TestVM",
                                    "username": "root",
                                    "password": "password",
                                    "ssh_port": 22,
                                    "hypervisor": 'XenServer',
                                    "privateport": 22,
                                    "publicport": 22,
                                    "protocol": 'TCP',
                        },
                        "template": {
                                    "displaytext": "Cent OS Template",
                                    "name": "Cent OS Template",
                                    "ostype": 'CentOS 5.3 (64-bit)',
                                    "templatefilter": 'self',
                                    "ispublic": False,
                        },
                        "network": {
                                    "name": "Test Network",
                                    "displaytext": "Test Network",
                        },
                        "domain_network": {
                                    "name": "Domainwide Network",
                                    "displaytext": "Domainwide Network",
                                    "gateway": '192.168.100.1',
                                    "netmask": '255.255.255.0',
                                    "startip": '192.168.100.200',
                                    "endip": '192.168.100.201',
                                    "vlan": 4001,
                                    "acltype": 'domain'
                        },
                        "natrule": {
                                    "privateport": 22,
                                    "publicport": 22,
                                    "protocol": "TCP"
                        },
                        "lbrule": {
                                    "name": "SSH",
                                    "alg": "roundrobin",
                                    # Algorithm used for load balancing
                                    "privateport": 22,
                                    "publicport": 2222,
                        },
                        "fw_rule": {
                                    "startport": 1,
                                    "endport": 6000,
                                    "cidr": '55.55.0.0/11',
                                    # Any network (For creating FW rule)
                        },
                        "security_group": {
                                    "name": 'SSH',
                                    "protocol": 'TCP',
                                    "startport": 22,
                                    "endport": 22,
                                    "cidrlist": '0.0.0.0/0',
                        },
                        "ostype": 'CentOS 5.3 (64-bit)',
                        # Cent OS 5.3 (64 bit)
                        "sleep": 60,
                        "timeout": 10,
                    }


class TestOfferings(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cls.api_client = super(
                               TestOfferings,
                               cls
                               ).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone and template
        cls.zone = get_zone(cls.api_client, cls.services)
        cls.services['mode'] = cls.zone.networktype
        cls.template = get_template(
                            cls.api_client,
                            cls.zone.id,
                            cls.services["ostype"]
                            )
        cls.services["server"]["zoneid"] = cls.zone.id

        # Create domains, account etc.
        cls.domain = Domain.create(
                                   cls.api_client,
                                   cls.services["domain"]
                                   )

        cls.account = Account.create(
                            cls.api_client,
                            cls.services["account"],
                            admin=True,
                            domainid=cls.domain.id
                            )
        cls.service_offering = ServiceOffering.create(
                                            cls.api_client,
                                            cls.services["service_offering"],
                                            domainid=cls.domain.id
                                            )
        cls.disk_offering = DiskOffering.create(
                                    cls.api_client,
                                    cls.services["disk_offering"]
                                    )
        cls._cleanup = [
                        cls.account,
                        cls.service_offering,
                        cls.disk_offering
                        ]
        return

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

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.cleanup = []
        return

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

    @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"])
    def test_01_service_offerings(self):
        """ Test service offerings in a project
        """
        # Validate the following
        # 1. Create a project.
        # 2. List service offerings for the project. All SO available in the
        #    domain can be used for project resource creation.

        # Create project as a domain admin
        project = Project.create(
                                 self.apiclient,
                                 self.services["project"],
                                 account=self.account.name,
                                 domainid=self.account.domainid
                                 )
        # Cleanup created project at end of test
        self.cleanup.append(project)
        self.debug("Created project with domain admin with ID: %s" %
                                                                project.id)

        self.debug(
            "Deploying VM instance for project: %s & service offering: %s" % (
                                                    project.id,
                                                    self.service_offering.id
                                                    ))
        virtual_machine = VirtualMachine.create(
                                self.apiclient,
                                self.services["server"],
                                templateid=self.template.id,
                                serviceofferingid=self.service_offering.id,
                                projectid=project.id
                                )
        # Verify VM state
        self.assertEqual(
                            virtual_machine.state,
                            'Running',
                            "Check VM state is Running or not"
                        )

        return

    @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"])
    def test_02_project_disk_offerings(self):
        """ Test project disk offerings
        """

        # Validate the following
        # 1. Create a project.
        # 2. List service offerings for the project. All disk offerings
        #    available in the domain can be used for project resource creation

        # Create project as a domain admin
        project = Project.create(
                                 self.apiclient,
                                 self.services["project"],
                                 account=self.account.name,
                                 domainid=self.account.domainid
                                 )
        # Cleanup created project at end of test
        self.cleanup.append(project)
        self.debug("Created project with domain admin with ID: %s" %
                                                                project.id)

        list_projects_reponse = Project.list(
                                             self.apiclient,
                                             id=project.id,
                                             listall=True
                                             )

        self.assertEqual(
                            isinstance(list_projects_reponse, list),
                            True,
                            "Check for a valid list projects response"
                            )
        list_project = list_projects_reponse[0]

        self.assertNotEqual(
                    len(list_projects_reponse),
                    0,
                    "Check list project response returns a valid project"
                    )

        self.assertEqual(
                            project.name,
                            list_project.name,
                            "Check project name from list response"
                            )
        self.debug(
            "Create a data volume for project: %s" % project.id)
        # Create a volume for project
        volume = Volume.create(
                               self.apiclient,
                               self.services["volume"],
                               zoneid=self.zone.id,
                               diskofferingid=self.disk_offering.id,
                               projectid=project.id
                               )
        self.cleanup.append(volume)
        # Verify Volume state
        self.assertEqual(
                            volume.state in [
                                                 'Allocated',
                                                 'Ready'
                                                 ],
                            True,
                            "Check Volume state is Ready or not"
                        )
        return


class TestNetwork(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cls.api_client = super(
                               TestNetwork,
                               cls
                               ).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone and template
        cls.zone = get_zone(cls.api_client, cls.services)
        cls.services['mode'] = cls.zone.networktype
        cls.template = get_template(
                            cls.api_client,
                            cls.zone.id,
                            cls.services["ostype"]
                            )
        cls.services["server"]["zoneid"] = cls.zone.id

        # Create domains, account etc.
        cls.domain = Domain.create(
                                   cls.api_client,
                                   cls.services["domain"]
                                   )

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

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

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.cleanup = []
        return

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

    @attr(tags = ["advanced", "advancedns", "simulator"])
    def test_03_network_create(self):
        """ Test create network in project
        """
        # Validate the following
        # 1. Create a project.
        # 2. Add virtual/direct network resource to the project. User shared
        #    network resource for the project
        # 3. Verify any number of Project level Virtual/Direct networks can be
        #    created and used for vm deployment within the project.
        # 4. Verify shared networks (zone and domain wide) from outside the
        #    project can also be used in a project.

        # Create project as a domain admin
        project = Project.create(
                                 self.apiclient,
                                 self.services["project"],
                                 account=self.account.name,
                                 domainid=self.account.domainid
                                 )
        # Cleanup created project at end of test
        self.cleanup.append(project)
        self.debug("Created project with domain admin with ID: %s" %
                                                                project.id)

        network_offerings = list_network_offerings(
                                                self.apiclient,
                                                projectid=project.id,
                                                supportedServices='SourceNat',
                                                type='isolated',
                                                state='Enabled'
                                                )
        self.assertEqual(
                         isinstance(network_offerings, list),
                         True,
                         "Check for the valid network offerings"
                         )
        network_offering = network_offerings[0]

        self.debug("creating a network with network offering ID: %s" %
                                                        network_offering.id)
        self.services["network"]["zoneid"] = self.zone.id
        network = Network.create(
                                 self.apiclient,
                                 self.services["network"],
                                 networkofferingid=network_offering.id,
                                 projectid=project.id
                                 )
        self.debug("Created network with ID: %s" % network.id)
        networks = Network.list(
                               self.apiclient,
                               projectid=project.id,
                               listall=True
                               )
        self.assertEqual(
                         isinstance(networks, list),
                         True,
                         "Check for the valid network list response"
                         )
        network_response = networks[0]

        self.debug("Deploying VM with network: %s" % network.id)

        virtual_machine = VirtualMachine.create(
                                self.apiclient,
                                self.services["server"],
                                templateid=self.template.id,
                                networkids=[str(network.id)],
                                serviceofferingid=self.service_offering.id,
                                projectid=project.id
                                )
        self.debug("Deployed VM with ID: %s" % virtual_machine.id)
        # Verify VM state
        self.assertEqual(
                            virtual_machine.state,
                            'Running',
                            "Check VM state is Running or not"
                        )

        network_offerings = list_network_offerings(
                                        self.apiclient,
                                        state='Enabled',
                                        guestiptype='Shared',
                                        name='DefaultSharedNetworkOffering',
                                        displaytext='Offering for Shared networks'
                                        )
        self.assertEqual(
                         isinstance(network_offerings, list),
                         True,
                         "Check for the valid network offerings"
                         )
        network_offering = network_offerings[0]

        self.debug("creating a shared network in domain: %s" %
                                                        self.domain.id)
        domain_network = Network.create(
                                 self.apiclient,
                                 self.services["domain_network"],
                                 domainid=self.domain.id,
                                 networkofferingid=network_offering.id,
                                 zoneid=self.zone.id
                                 )
        self._cleanup.append(domain_network)
        self.debug("Created network with ID: %s" % domain_network.id)

        virtual_machine = VirtualMachine.create(
                                self.apiclient,
                                self.services["server"],
                                templateid=self.template.id,
                                networkids=[str(domain_network.id)],
                                serviceofferingid=self.service_offering.id,
                                projectid=project.id
                                )
        self.debug("Deployed VM with ID: %s" % virtual_machine.id)
        # Verify VM state
        self.assertEqual(
                            virtual_machine.state,
                            'Running',
                            "Check VM state is Running or not"
                        )
        return


class TestTemplates(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cls.api_client = super(
                               TestTemplates,
                               cls
                               ).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.zone = get_zone(cls.api_client, cls.services)
        cls.services['mode'] = cls.zone.networktype

        cls.template = get_template(
                            cls.api_client,
                            cls.zone.id,
                            cls.services["ostype"]
                            )
        cls.services["server"]["zoneid"] = cls.zone.id

        # Create Domains, Account etc
        cls.domain = Domain.create(
                                   cls.api_client,
                                   cls.services["domain"]
                                   )

        cls.account = Account.create(
                            cls.api_client,
                            cls.services["account"],
                            domainid=cls.domain.id
                            )
        cls.user = Account.create(
                            cls.api_client,
                            cls.services["account"],
                            domainid=cls.domain.id
                            )
        # Create project as a domain admin
        cls.project = Project.create(
                                 cls.api_client,
                                 cls.services["project"],
                                 account=cls.account.name,
                                 domainid=cls.account.domainid
                                 )
        cls.services["account"] = cls.account.name

        # Create Service offering and disk offerings etc
        cls.service_offering = ServiceOffering.create(
                                            cls.api_client,
                                            cls.services["service_offering"]
                                            )
        cls._cleanup = [
                        cls.project,
                        cls.service_offering,
                        cls.account,
                        cls.user,
                        cls.domain
                        ]
        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 = []
        return

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

    @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns"])
    def test_04_public_template_use_in_project(self):
        """Test Templates creation in projects
        """
        # 1. Create a project
        # 2. Verify Public templates can be used without any restriction
        # 3. Verify that template created in project can be used in project
        #    without any restrictions

        self.debug("Deploying VM for with public template: %s" %
                                                        self.template.id)
        virtual_machine_1 = VirtualMachine.create(
                                self.apiclient,
                                self.services["server"],
                                templateid=self.template.id,
                                serviceofferingid=self.service_offering.id,
                                projectid=self.project.id
                                )
        self.cleanup.append(virtual_machine_1)
        # Verify VM state
        self.assertEqual(
                            virtual_machine_1.state,
                            'Running',
                            "Check VM state is Running or not"
                        )
        virtual_machine_1.stop(self.apiclient)
        # Get the Root disk of VM
        volumes = list_volumes(
                            self.apiclient,
                            projectid=self.project.id,
                            type='ROOT',
                            listall=True
                            )
        self.assertEqual(
                        isinstance(volumes, list),
                        True,
                        "Check for list volume response return valid data"
                        )
        volume = volumes[0]

        self.debug("Creating template from volume: %s" % volume.id)
        # Create a template from the ROOTDISK
        template_1 = Template.create(
                            self.apiclient,
                            self.services["template"],
                            volumeid=volume.id,
                            projectid=self.project.id
                            )

        self.cleanup.append(template_1)
        # Verify Template state
        self.assertEqual(
                            template_1.isready,
                            True,
                            "Check Template is in ready state or not"
                        )
        return

    @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns"])
    def test_05_use_private_template_in_project(self):
        """Test use of private template in a project
        """
        # 1. Create a project
        # 2. Verify that in order to use somebody's Private template for vm
        #    creation in the project, permission to use the template has to
        #    be granted to the Project (use API 'updateTemplatePermissions'
        #    with project id to achieve that).

        self.debug("Deploying VM for with public template: %s" %
                                                        self.template.id)
        virtual_machine_1 = VirtualMachine.create(
                                self.apiclient,
                                self.services["server"],
                                templateid=self.template.id,
                                serviceofferingid=self.service_offering.id,
                                projectid=self.project.id
                                )
        self.cleanup.append(virtual_machine_1)
        # Verify VM state
        self.assertEqual(
                            virtual_machine_1.state,
                            'Running',
                            "Check VM state is Running or not"
                        )
        self.debug("Stopping the VM: %s" % virtual_machine_1.id)
        virtual_machine_1.stop(self.apiclient)
        # Get the Root disk of VM
        volumes = list_volumes(
                            self.apiclient,
                            projectid=self.project.id,
                            type='ROOT',
                            listall=True
                            )
        self.assertEqual(
                        isinstance(volumes, list),
                        True,
                        "Check for list volume response return valid data"
                        )
        volume = volumes[0]

        self.debug("Creating template from volume: %s" % volume.id)
        # Create a template from the ROOTDISK
        template_1 = Template.create(
                            self.apiclient,
                            self.services["template"],
                            volumeid=volume.id,
                            projectid=self.project.id
                            )

        self.cleanup.append(template_1)
        # Verify Template state
        self.assertEqual(
                            template_1.isready,
                            True,
                            "Check Template is in ready state or not"
                        )

        # Update template permissions to grant permission to project
        self.debug(
          "Updating template permissions:%s to grant access to project: %s" % (
                                                            template_1.id,
                                                            self.project.id
                                                        ))

        template_1.updatePermissions(
                                     self.apiclient,
                                     op='add',
                                     projectids=self.project.id
                                     )
        self.debug("Deploying VM for with privileged template: %s" %
                                                        self.template.id)
        virtual_machine_2 = VirtualMachine.create(
                                self.apiclient,
                                self.services["server"],
                                templateid=template_1.id,
                                serviceofferingid=self.service_offering.id,
                                projectid=self.project.id
                                )
        self.cleanup.append(virtual_machine_2)
        # Verify VM state
        self.assertEqual(
                            virtual_machine_2.state,
                            'Running',
                            "Check VM state is Running or not"
                        )
        return


class TestSnapshots(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cls.api_client = super(
                               TestSnapshots,
                               cls
                               ).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.zone = get_zone(cls.api_client, cls.services)
        cls.services['mode'] = cls.zone.networktype

        cls.template = get_template(
                            cls.api_client,
                            cls.zone.id,
                            cls.services["ostype"]
                            )
        cls.services["server"]["zoneid"] = cls.zone.id

        # Create Domains, Account etc
        cls.domain = Domain.create(
                                   cls.api_client,
                                   cls.services["domain"]
                                   )

        cls.account = Account.create(
                            cls.api_client,
                            cls.services["account"],
                            domainid=cls.domain.id
                            )
        # Create project as a domain admin
        cls.project = Project.create(
                                 cls.api_client,
                                 cls.services["project"],
                                 account=cls.account.name,
                                 domainid=cls.account.domainid
                                 )
        cls.services["account"] = cls.account.name

        # Create Service offering and disk offerings etc
        cls.service_offering = ServiceOffering.create(
                                            cls.api_client,
                                            cls.services["service_offering"]
                                            )
        cls._cleanup = [
                        cls.project,
                        cls.service_offering,
                        cls.account,
                        cls.domain
                        ]
        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 = []
        return

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

    @attr(speed = "slow")
    @attr(tags = ["advanced", "basic", "sg", "eip", "advancedns", "simulator"])
    def test_06_create_snapshots_in_project(self):
        """Test create snapshots in project
        """
        # Validate the following
        # 1. Create a project
        # 2. Add some snapshots to the project
        # 3. Verify snapshot created inside project can only be used in inside
        #    the project

        self.debug("Deploying VM for Project: %s" % self.project.id)
        virtual_machine_1 = VirtualMachine.create(
                                self.apiclient,
                                self.services["server"],
                                templateid=self.template.id,
                                serviceofferingid=self.service_offering.id,
                                projectid=self.project.id
                                )
        self.cleanup.append(virtual_machine_1)
        # Verify VM state
        self.assertEqual(
                            virtual_machine_1.state,
                            'Running',
                            "Check VM state is Running or not"
                        )

        # Get the Root disk of VM
        volumes = list_volumes(
                            self.apiclient,
                            projectid=self.project.id,
                            type='ROOT',
                            listall=True
                            )
        self.assertEqual(
                        isinstance(volumes, list),
                        True,
                        "Check for list volume response return valid data"
                        )
        volume = volumes[0]

        self.debug("Creating snapshot from volume: %s" % volumes[0].id)
        # Create a snapshot from the ROOTDISK
        snapshot = Snapshot.create(self.apiclient,
                            volumes[0].id,
                            projectid=self.project.id
                            )
        self.cleanup.append(snapshot)
        # Verify Snapshot state
        self.assertEqual(
                            snapshot.state in [
                                                 'BackedUp',
                                                 'CreatedOnPrimary'
                                                 ],
                            True,
                            "Check Snapshot state is Running or not"
                        )

        snapshots = Snapshot.list(
                                  self.apiclient,
                                  account=self.account.name,
                                  domainid=self.account.domainid
                                  )
        self.assertEqual(
                    snapshots,
                    None,
                    "Snapshots should not be available outside the project"
                    )
        return


class TestPublicIpAddress(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cls.api_client = super(
                               TestPublicIpAddress,
                               cls
                               ).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.zone = get_zone(cls.api_client, cls.services)
        cls.services['mode'] = cls.zone.networktype

        cls.template = get_template(
                            cls.api_client,
                            cls.zone.id,
                            cls.services["ostype"]
                            )
        cls.services["server"]["zoneid"] = cls.zone.id

        # Create Domains, Account etc
        cls.domain = Domain.create(
                                   cls.api_client,
                                   cls.services["domain"]
                                   )

        cls.account = Account.create(
                            cls.api_client,
                            cls.services["account"],
                            domainid=cls.domain.id
                            )
        # Create project as a domain admin
        cls.project = Project.create(
                                 cls.api_client,
                                 cls.services["project"],
                                 account=cls.account.name,
                                 domainid=cls.account.domainid
                                 )
        cls.services["account"] = cls.account.name

        # Create Service offering and disk offerings etc
        cls.service_offering = ServiceOffering.create(
                                            cls.api_client,
                                            cls.services["service_offering"]
                                            )
        cls.virtual_machine = VirtualMachine.create(
                                    cls.api_client,
                                    cls.services["server"],
                                    templateid=cls.template.id,
                                    serviceofferingid=cls.service_offering.id,
                                    projectid=cls.project.id
                                )

        cls._cleanup = [
                        cls.project,
                        cls.service_offering,
                        cls.account,
                        cls.domain
                        ]
        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 = []
        return

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

    @attr(tags = ["advanced", "advancedns"])
    def test_07_associate_public_ip(self):
        """Test associate public IP within the project
        """
        # Validate the following
        # 1. Create a project
        # 2. Add some public Ips to the project
        # 3. Verify public IP assigned can only used to create PF/LB rules
        #    inside project

        networks = Network.list(
                                self.apiclient,
                                projectid=self.project.id,
                                listall=True
                                )
        self.assertEqual(
                    isinstance(networks, list),
                    True,
                    "Check list networks response returns a valid response"
                    )
        self.assertNotEqual(
                    len(networks),
                    0,
                    "Check list networks response returns a valid network"
                    )
        network = networks[0]
        self.debug("Associating public IP for project: %s" % self.project.id)
        public_ip = PublicIPAddress.create(
                                           self.apiclient,
                                           zoneid=self.virtual_machine.zoneid,
                                           services=self.services["server"],
                                           networkid=network.id,
                                           projectid=self.project.id
                                           )
        self.cleanup.append(public_ip)

        #Create NAT rule
        self.debug(
                "Creating a NAT rule within project, VM ID: %s" %
                                                    self.virtual_machine.id)
        nat_rule = NATRule.create(
                                  self.apiclient,
                                  self.virtual_machine,
                                  self.services["natrule"],
                                  public_ip.ipaddress.id,
                                  projectid=self.project.id
                                  )
        self.debug("created a NAT rule with ID: %s" % nat_rule.id)
        nat_rule_response = NATRule.list(
                                            self.apiclient,
                                            id=nat_rule.id
                                        )
        self.assertEqual(
                            isinstance(nat_rule_response, list),
                            True,
                            "Check list response returns a valid list"
                        )
        self.assertNotEqual(
                            len(nat_rule_response),
                            0,
                            "Check Port Forwarding Rule is created"
                            )
        self.assertEqual(
                            nat_rule_response[0].id,
                            nat_rule.id,
                            "Check Correct Port forwarding Rule is returned"
                        )

        #Create Load Balancer rule and assign VMs to rule
        self.debug("Created LB rule for public IP: %s" %
                                        public_ip.ipaddress)
        lb_rule = LoadBalancerRule.create(
                                          self.apiclient,
                                          self.services["lbrule"],
                                          public_ip.ipaddress.id,
                                          projectid=self.project.id
                                          )
        self.cleanup.append(lb_rule)
        self.debug("Assigning VM: %s to LB rule: %s" % (
                                                    self.virtual_machine.name,
                                                    lb_rule.id
                                                    ))
        lb_rule.assign(self.apiclient, [self.virtual_machine])

        lb_rules = list_lb_rules(
                                 self.apiclient,
                                 id=lb_rule.id
                                 )
        self.assertEqual(
                            isinstance(lb_rules, list),
                            True,
                            "Check list response returns a valid list"
                        )
        #verify listLoadBalancerRules lists the added load balancing rule
        self.assertNotEqual(
                            len(lb_rules),
                            0,
                            "Check Load Balancer Rule in its List"
                        )
        self.assertEqual(
                            lb_rules[0].id,
                            lb_rule.id,
                            "Check List Load Balancer Rules returns valid Rule"
                        )

        #Create Firewall rule with configurations from settings file
        fw_rule = FireWallRule.create(
                            self.apiclient,
                            ipaddressid=public_ip.ipaddress.id,
                            protocol='TCP',
                            cidrlist=[self.services["fw_rule"]["cidr"]],
                            startport=self.services["fw_rule"]["startport"],
                            endport=self.services["fw_rule"]["endport"],
                            projectid=self.project.id
                            )
        self.debug("Created firewall rule: %s" % fw_rule.id)

        # After Router start, FW rule should be in Active state
        fw_rules = FireWallRule.list(
                                     self.apiclient,
                                     id=fw_rule.id,
                                     )
        self.assertEqual(
                        isinstance(fw_rules, list),
                        True,
                        "Check for list FW rules response return valid data"
                        )

        self.assertEqual(
                    fw_rules[0].state,
                    'Active',
                    "Check list load balancing rules"
                    )
        self.assertEqual(
                    fw_rules[0].startport,
                    str(self.services["fw_rule"]["startport"]),
                    "Check start port of firewall rule"
                    )

        self.assertEqual(
                    fw_rules[0].endport,
                    str(self.services["fw_rule"]["endport"]),
                    "Check end port of firewall rule"
                    )

        self.debug("Deploying VM for account: %s" % self.account.name)
        virtual_machine_1 = VirtualMachine.create(
                                self.apiclient,
                                self.services["server"],
                                templateid=self.template.id,
                                accountid=self.account.name,
                                domainid=self.account.domainid,
                                serviceofferingid=self.service_offering.id,
                                )
        self.cleanup.append(virtual_machine_1)

        self.debug("VM state after deploy: %s" % virtual_machine_1.state)
        # Verify VM state
        self.assertEqual(
                            virtual_machine_1.state,
                            'Running',
                            "Check VM state is Running or not"
                        )

        self.debug("Creating NAT rule for VM (ID: %s) outside project" %
                                                    virtual_machine_1.id)
        with self.assertRaises(Exception):
            NATRule.create(
                                  self.apiclient,
                                  virtual_machine_1,
                                  self.services["natrule"],
                                  public_ip.ipaddress.id,
                                  )

        self.debug("Creating LB rule for public IP: %s outside project" %
                                                public_ip.ipaddress)
        with self.assertRaises(Exception):
            LoadBalancerRule.create(
                                          self.apiclient,
                                          self.services["lbrule"],
                                          public_ip.ipaddress.id,
                                          accountid=self.account.name
                                          )
        self.debug(
                "Creating firewall rule for public IP: %s outside project" %
                                                public_ip.ipaddress)
        with self.assertRaises(Exception):
            FireWallRule.create(
                            self.apiclient,
                            ipaddressid=public_ip.ipaddress.id,
                            protocol='TCP',
                            cidrlist=[self.services["fw_rule"]["cidr"]],
                            startport=self.services["fw_rule"]["startport"],
                            endport=self.services["fw_rule"]["endport"],
                            )
        return


class TestSecurityGroup(cloudstackTestCase):

    def setUp(self):

        self.apiclient = self.testClient.getApiClient()
        self.dbclient = self.testClient.getDbConnection()
        self.cleanup = []
        return

    def tearDown(self):
        try:
            #Clean up, terminate the created templates
            cleanup_resources(self.apiclient, self.cleanup)

        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    @classmethod
    def setUpClass(cls):
        cls.services = Services().services
        cls.api_client = super(
                               TestSecurityGroup,
                               cls
                               ).getClsTestClient().getApiClient()

        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client, cls.services)
        cls.zone = get_zone(cls.api_client, cls.services)
        cls.services['mode'] = cls.zone.networktype

        template = get_template(
                            cls.api_client,
                            cls.zone.id,
                            cls.services["ostype"]
                            )
        cls.services["domainid"] = cls.domain.id
        cls.services["server"]["zoneid"] = cls.zone.id
        cls.services["server"]["template"] = template.id

        cls.service_offering = ServiceOffering.create(
                                            cls.api_client,
                                            cls.services["service_offering"]
                                            )
        cls.account = Account.create(
                            cls.api_client,
                            cls.services["account"],
                            admin=True,
                            domainid=cls.domain.id
                            )
        # Create project as a domain admin
        cls.project = Project.create(
                                 cls.api_client,
                                 cls.services["project"],
                                 account=cls.account.name,
                                 domainid=cls.account.domainid
                                 )
        cls.services["account"] = cls.account.name

        cls._cleanup = [
                        cls.project,
                        cls.account,
                        cls.service_offering
                        ]
        return

    @classmethod
    def tearDownClass(cls):
        try:
            cls.api_client = super(TestSecurityGroup, cls).getClsTestClient().getApiClient()
            #Cleanup resources used
            cleanup_resources(cls.api_client, cls._cleanup)

        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

        return

    @attr(tags = ["sg", "eip"])
    def test_08_security_group(self):
        """Test security groups in project
        """
        # Validate the following:
        # 1. Create a project
        # 2. Assign some security groups to that project
        # 3. Verify the security groups can only be assigned to VM belonging
        #    to that project.

        security_group = SecurityGroup.create(
                                              self.apiclient,
                                              self.services["security_group"],
                                              projectid=self.project.id
                                              )
        self.debug("Created security group with ID: %s" % security_group.id)
        # Default Security group should not have any ingress rule
        sercurity_groups = SecurityGroup.list(
                                              self.apiclient,
                                              projectid=self.project.id
                                              )
        self.assertEqual(
                         isinstance(sercurity_groups, list),
                         True,
                         "Check for list security groups response"
                         )

        self.assertNotEqual(
                            len(sercurity_groups),
                            0,
                            "Check List Security groups response"
                            )
        # Authorize Security group to SSH to VM
        ingress_rule = security_group.authorize(
                                self.apiclient,
                                self.services["security_group"],
                                projectid=self.project.id
                                )
        self.assertEqual(
                          isinstance(ingress_rule, dict),
                          True,
                          "Check ingress rule created properly"
                    )

        self.debug(
            "Authorizing ingress rule for sec group ID: %s for ssh access"
                                                        % security_group.id)
        self.virtual_machine = VirtualMachine.create(
                                    self.apiclient,
                                    self.services["server"],
                                    serviceofferingid=self.service_offering.id,
                                    securitygroupids=[security_group.id],
                                    projectid=self.project.id
                                )
        self.debug("Deployed VM (ID: %s) in project: %s" % (
                                                    self.virtual_machine.id,
                                                    self.project.id
                                                    ))
        self.assertEqual(
                         self.virtual_machine.state,
                         'Running',
                         "VM state should be running after deployment"
                         )
        # Deploy another VM with same security group outside the project
        self.debug(
            "Deploying VM with security group: %s outside project:%s" % (
                                                            security_group.id,
                                                            self.project.id
                                                            ))
        with self.assertRaises(Exception):
            VirtualMachine.create(
                                    self.apiclient,
                                    self.services["server"],
                                    serviceofferingid=self.service_offering.id,
                                    accountid=self.account.name,
                                    domainid=self.account.domainid,
                                    securitygroupids=[security_group.id],
                                )
        return
