# 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 VPN users
"""
# Import Local Modules
from nose.plugins.attrib import attr
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.integration.lib.base import (
                                        Account,
                                        ServiceOffering,
                                        VirtualMachine,
                                        PublicIPAddress,
                                        Network,
                                        LoadBalancerRule,
                                        Alert,
                                        Router,
                                        Vpn,
                                        NATRule
                                        )
from marvin.integration.lib.common import (get_domain,
                                        get_zone,
                                        get_template
                                        )
from marvin.integration.lib.utils import (cleanup_resources,
                                          random_gen)
from marvin.cloudstackAPI import createLBStickinessPolicy
from marvin.sshClient import SshClient


class Services:
    """Test VPN users Services
    """

    def __init__(self):
        self.services = {
                        "account": {
                                    "email": "test@test.com",
                                    "firstname": "Test",
                                    "lastname": "User",
                                    "username": "test",
                                    # Random characters are appended for unique
                                    # username
                                    "password": "password",
                         },
                         "service_offering": {
                                    "name": "Tiny Instance",
                                    "displaytext": "Tiny Instance",
                                    "cpunumber": 1,
                                    "cpuspeed": 100,    # in MHz
                                    "memory": 128,    # In MBs
                        },
                        "disk_offering": {
                                    "displaytext": "Small Disk Offering",
                                    "name": "Small Disk Offering",
                                    "disksize": 1
                        },
                        "virtual_machine": {
                                    "displayname": "TestVM",
                                    "username": "root",
                                    "password": "password",
                                    "ssh_port": 22,
                                    "hypervisor": 'XenServer',
                                    "privateport": 22,
                                    "publicport": 22,
                                    "protocol": 'TCP',
                                },
                         "vpn_user": {
                                   "username": "test",
                                   "password": "test",
                                },
                         "natrule": {
                                   "privateport": 22,
                                   "publicport": 22,
                                   "protocol": "TCP",
                                   "username":"root",
                                   "password": "password"
                                },
                         "network": {
                                "name": "Test Network",
                                "displaytext": "Test Network",
                                "netmask": '255.255.255.0'
                                },
                         "lbrule": {
                                    "name": "SSH",
                                    "alg": "roundrobin",
                                    # Algorithm used for load balancing
                                    "privateport": 22,
                                    "publicport": 2222,
                                    "openfirewall": False,
                                    "startport": 22,
                                    "endport": 2222,
                                    "protocol": "TCP",
                                    "cidrlist": '0.0.0.0/0',
                                },
                        "ostype": 'CentOS 5.3 (64-bit)',
                        "sleep": 60,
                        "timeout": 10,
                        "mode": 'advanced',
                        # Networking mode: Advanced, Basic
                    }


class TestHAProxyStickyness(cloudstackTestCase):

    @classmethod
    def setUpClass(cls):
        cls.api_client = super(TestHAProxyStickyness,
                               cls).getClsTestClient().getApiClient()
        cls.services = Services().services
        # Get Zone, Domain and templates
        cls.domain = get_domain(cls.api_client, cls.services)
        cls.zone = get_zone(cls.api_client, cls.services)

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

        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
        cls.service_offering = ServiceOffering.create(
                                            cls.api_client,
                                            cls.services["service_offering"]
                                            )

        cls._cleanup = [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.account = Account.create(
                            self.apiclient,
                            self.services["account"],
                            domainid=self.domain.id
                            )
        self.virtual_machine = VirtualMachine.create(
                                self.apiclient,
                                self.services["virtual_machine"],
                                templateid=self.template.id,
                                accountid=self.account.name,
                                domainid=self.account.domainid,
                                serviceofferingid=self.service_offering.id
                                )

        self.virtual_machine_2 = VirtualMachine.create(
                                self.apiclient,
                                self.services["virtual_machine"],
                                templateid=self.template.id,
                                accountid=self.account.name,
                                domainid=self.account.domainid,
                                serviceofferingid=self.service_offering.id
                                )
        self.public_ip = PublicIPAddress.create(
                                           self.apiclient,
                                           self.virtual_machine.account,
                                           self.virtual_machine.zoneid,
                                           self.virtual_machine.domainid,
                                           self.services["virtual_machine"]
                                           )

        NATRule.create(
                        self.apiclient,
                        self.virtual_machine,
                        self.services["natrule"],
                        ipaddressid=self.public_ip.ipaddress.id
                        )

        self.cleanup = [self.account, ]
        return

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

    def get_Network(self, account):
        """Returns a network for account"""

        networks = Network.list(
                                self.apiclient,
                                account=account.name,
                                domainid=account.domainid,
                                listall=True
                                )
        self.assertIsInstance(networks,
                              list,
                              "List networks should return a valid response")
        return networks[0]

    def create_LB_Rule(self, public_ip, network, vmarray, services=None):
        """Create and validate the load balancing rule"""

        self.debug("Creating LB rule for IP address: %s" %
                                        public_ip.ipaddress.ipaddress)
        objservices = None
        if services:
            objservices = services
        else:
            objservices = self.services["lbrule"]

        lb_rule = LoadBalancerRule.create(
                                    self.apiclient,
                                    objservices,
                                    ipaddressid=public_ip.ipaddress.id,
                                    accountid=self.account.name,
                                    networkid=network.id,
                                    domainid=self.account.domainid
                                )
        self.debug("Adding virtual machines %s to LB rule" % str(vmarray))
        lb_rule.assign(self.apiclient, vmarray)
        return lb_rule

    def configure_Stickiness_Policy(self, lb_rule, method, paramDict=None):
        """Configure the stickiness policy on lb rule"""
        try:
            result = lb_rule.createSticky(
                             self.apiclient,
                             methodname=method,
                             name="-".join([method, random_gen()]),
                             param=paramDict
                             )
            self.debug("Response: %s" % result)
            return result
        except Exception as e:
            self.fail("Configure sticky policy failed with exception: %s" % e)

    def validate_Stickiness_Policy(self, lb_rule, method, publicip):
        """Validates the stickiness policy"""

        sticky_policies = lb_rule.listStickyPolicies(self.apiclient,
                                                     lbruleid=lb_rule.id,
                                                     listall=True)
        self.assertIsInstance(sticky_policies,
                            list,
                            "List sticky policies should return a valid list")
        sticky_policy = sticky_policies[0]

        self.debug("Stickiness policy method: %s" %
                                sticky_policy.stickinesspolicy[0].methodname)
        self.assertEqual(sticky_policy.stickinesspolicy[0].methodname,
                    method,
                    "Stickiness policy should have method as - %s" % method)

        hostnames = []

        hostnames = self.try_ssh(publicip, hostnames)
        hostnames = self.try_ssh(publicip, hostnames)

        self.debug("hostnames: %s" % hostnames)
        self.debug("set(hostnames): %s" % set(hostnames))

        #For each ssh, host should be the same, else stickiness policy is not working properly
        if len(hostnames) == len(set(hostnames)):
            raise Exception("Stickyness policy: %s not working properly, got hostnames %s"
                            % (method, hostnames))
        return

    def delete_Stickiness_policy(self, policy, lb_rule):
        """Deletes the stickiness policy"""

        try:
            lb_rule.deleteSticky(self.apiclient, id=policy.id)
        except Exception as e:
            self.fail("Failed to delete the stickiness policy: %s" % e)

        sticky_policies = lb_rule.listStickyPolicies(self.apiclient,
                                                     lbruleid=lb_rule.id,
                                                     listall=True)
        self.assertIsInstance(sticky_policies, list,
                "List stickiness policies shall return a valid response")

        policy = sticky_policies[0]

        self.assertEqual(len(policy.stickinesspolicy),
                         0,
                         "List stickiness policy should return nothing")
        return

    def check_stickiness_supported_methods(self, supportedMethods, value):

        for i, dic in enumerate(supportedMethods):
            if dic["methodname"] == value:
                return True
        return False

    def acquire_Public_Ip(self):
        """Acquires the public IP"""

        try:
            self.debug("Acquiring public IP for account: %s" %
                                                    self.account.name)
            public_ip = PublicIPAddress.create(
                                           self.apiclient,
                                           self.virtual_machine.account,
                                           self.virtual_machine.zoneid,
                                           self.virtual_machine.domainid,
                                           self.services["virtual_machine"]
                                           )
            self.debug("Acquired public IP: %s" %
                                                public_ip.ipaddress.ipaddress)

            self.debug("Configuring NAT rule for the acquired public ip")

            NATRule.create(
                        self.apiclient,
                        self.virtual_machine,
                        self.services["natrule"],
                        ipaddressid=public_ip.ipaddress.id
                        )

            return public_ip
        except Exception as e:
            self.fail("Failed to acquire new public IP: %s" % e)

    def get_router(self, account):
        """Returns a default router for account"""

        routers = Router.list(self.apiclient,
                              account=self.account.name,
                              domainid=self.account.domainid,
                              listall=True)
        self.assertIsInstance(routers, list,
                              "List routers should return a valid repsonse")
        return routers[0]

    def create_VPN(self, public_ip):
        """Creates VPN for the network"""

        self.debug("Creating VPN with public IP: %s" % public_ip.ipaddress.id)
        try:
            # Assign VPN to Public IP
            vpn = Vpn.create(self.apiclient,
                         self.public_ip.ipaddress.id,
                         account=self.account.name,
                         domainid=self.account.domainid)

            self.debug("Verifying the remote VPN access")
            vpns = Vpn.list(self.apiclient,
                        publicipid=public_ip.ipaddress.id,
                        listall=True)
            self.assertEqual(
                         isinstance(vpns, list),
                         True,
                         "List VPNs shall return a valid response"
                         )
            return vpn
        except Exception as e:
            self.fail("Failed to create remote VPN access: %s" % e)

    def try_ssh(self, ip_addr, hostnames):
        try:
            self.debug(
                "SSH into NAT Rule (Public IP: %s)" % ip_addr)

            # If Round Robin Algorithm is chosen,
            # each ssh command should alternate between VMs

            ssh_1  = SshClient(
                                    ip_addr,
                                    22,
                                    self.services["natrule"]["username"],
                                    self.services["natrule"]["password"]
                                    )
            hostnames.append(ssh_1.execute("hostname")[0])
            self.debug(hostnames)
        except Exception as e:
            self.fail("%s: SSH failed for VM with IP Address: %s" %
                                    (e, ip_addr))
        return hostnames

    @attr(tags=["advanced", "advancedns"])
    @attr(speed="slow")
    def test_01_create_sticky_policy_default_values(self):
        """Test Configure stickiness policies with default values"""

        # Validate the following
        # 1. Create a LB rule with round robin. listLoadBalancerRules should
        #    show newly created load balancer rule.
        # 2. Configure the Source based, app cookie and lb cookie based policy
        #   listLBStickinessPolicies should show newly created stickiness

        self.debug("Creating a load balancing rule on IP: %s" %
                                        self.public_ip.ipaddress.ipaddress)

        lb_rule = self.create_LB_Rule(self.public_ip,
                            network=self.get_Network(self.account),
                            vmarray=[self.virtual_machine, self.virtual_machine_2])

        methods = ["SourceBased", "AppCookie", "LBCookie"]
        for method in methods:
            self.debug("Creating stickiness policy for the LB rule: %s" %
                                                                lb_rule.id)
            policies = self.configure_Stickiness_Policy(lb_rule, method=method)

            policy = policies.stickinesspolicy[0]

            self.debug("Policy: %s" % str(policy))
            self.debug("Validating the stickiness policy")
            self.validate_Stickiness_Policy(lb_rule, method, self.public_ip.ipaddress.ipaddress)
            self.debug("Deleting the stickiness policy for lb rule: %s" %
                                                                lb_rule.name)
            self.delete_Stickiness_policy(policy, lb_rule)
        return

    @attr(tags=["advanced", "advancedns"])
    @attr(speed="slow")
    def test_02_create_sticky_policy_custom_values(self):
        """Test Configure stickiness policies with custom values"""

        # Validate the following
        # 1. Create a LB rule with roundrobin, leastconn and source.
        #    listLoadBalancerRules should show newly created load balancer rule
        # 2. Configure the Source based, app cookie and lb cookie based policy
        #    with custom parameters
        #   listLBStickinessPolicies should show newly created stickiness

        lb_methods = ["roundrobin", "leastconn", "source"]

        configs = {"SourceBased": {"tablesize": '100k'},
                   "AppCookie": {"request-learn": "true"},
                   "LBCookie": {"nocache": "true"}}

        for lb_method in lb_methods:
            self.debug("Creating a load balancing rule on IP %s and algo %s" %
                            (self.public_ip.ipaddress.ipaddress, lb_method))

            services = self.services["lbrule"]
            services["alg"] = lb_method

            lb_rule = self.create_LB_Rule(self.public_ip,
                            network=self.get_Network(self.account),
                            vmarray=[self.virtual_machine, self.virtual_machine_2],
                            services=services)

            for method, params in configs.items():
                self.debug("Creating stickiness policy for the LB rule: %s" %
                                                                lb_rule.id)
                policies = self.configure_Stickiness_Policy(lb_rule,
                                                          method=method,
                                                          paramDict=params)

                policy = policies.stickinesspolicy[0]
                self.debug("Policy: %s" % str(policy))

                self.debug("Validating the stickiness policy")
                self.validate_Stickiness_Policy(lb_rule, method, self.public_ip.ipaddress.ipaddress)
                self.debug("Deleting the stickiness policy for lb rule: %s" %
                                                                lb_rule.name)
                self.delete_Stickiness_policy(policy, lb_rule)
            self.debug("Deleting the LB rule: %s" % lb_rule.name)
            lb_rule.delete(self.apiclient)
        return

    @attr(tags=["advanced", "advancedns"])
    @attr(speed="slow")
    def test_03_supported_policies_by_network(self):
        """Test listnetworks response to check supported stickiness policies"""

        # Validate the following
        # 1. List networks for the account in advance network mode
        # 2. List of supported sticky methods should be present under
        #    SupportedStickinessMethods tag

        self.debug("List networks for account: %s" % self.account.name)
        networks = Network.list(self.apiclient,
                                account=self.account.name,
                                domainid=self.account.domainid,
                                listall=True)

        self.assertIsInstance(networks,
                              list,
                              "List network should return a valid response")
        network = networks[0]
        self.debug("Network: %s" % network)
        self.assertEqual(hasattr(network, "SupportedStickinessMethods"),
                        True,
                        "Network should have SupportedStickinessMethods param")

        self.assertEqual(hasattr(network, "LbCookie"),
                        True,
                        "Network should have LbCookie LB method param")

        self.assertEqual(hasattr(network, "AppCookie"),
                        True,
                        "Network should have AppCookie LB method param")

        self.assertEqual(hasattr(network, "SourceBased"),
                        True,
                        "Network should have SourceBased LB method param")

        return

    @attr(tags=["advanced", "advancedns"])
    @attr(speed="slow")
    def test_04_delete_lb_rule(self):
        """Test LB rule before/after stickiness policy creation"""

        # Validate the following
        # 1. Create a LB rule with roundrobin, leastconn and source.
        #    listLoadBalancerRules should show newly created load balancer rule
        # 2. Delete the loadbalancer rule. Delete loadbalancer rule should be
        #    successful
        # 3. Configure the Source based, app cookie and lb cookie based policy
        #    with custom parameters listLBStickinessPolicies should show newly
        #    created stickiness
        # 4. Delete load balancer rule. Delete should be successful

        lb_methods = ["roundrobin", "leastconn", "source"]

        configs = {"SourceBased": {"tablesize": '100k'},
                   "AppCookie": {"request-learn": "true"},
                   "LBCookie": {"nocache": "true"}}
        for lb_method in lb_methods:
            for method, params in configs.items():
                self.debug("Creating load balancing rule on IP %s & algo %s" %
                            (self.public_ip.ipaddress.ipaddress, lb_method))

                services = self.services["lbrule"]
                services["alg"] = lb_method

                lb_rule = self.create_LB_Rule(self.public_ip,
                            network=self.get_Network(self.account),
                            vmarray=[self.virtual_machine, self.virtual_machine_2],
                            services=services)
                self.debug(
                    "Deleting the LB rule before stickiness policy creation")
                lb_rule.delete(self.apiclient)

                with self.assertRaises(Exception):
                    LoadBalancerRule.list(self.apiclient,
                                        id=lb_rule.id,
                                        listall=True)

                lb_rule = self.create_LB_Rule(self.public_ip,
                            network=self.get_Network(self.account),
                            vmarray=[self.virtual_machine, self.virtual_machine_2],
                            services=services)
                self.debug("Creating stickiness policy for the LB rule: %s" %
                                                                lb_rule.id)
                policies = self.configure_Stickiness_Policy(lb_rule,
                                                          method=method,
                                                          paramDict=params)

                policy = policies.stickinesspolicy[0]

                self.debug("Policy: %s" % str(policy))
                self.debug("Validating the stickiness policy")
                self.validate_Stickiness_Policy(lb_rule, method, self.public_ip.ipaddress.ipaddress)

                self.debug("Deleting the LB rule: %s" % lb_rule.name)
                lb_rule.delete(self.apiclient)
                with self.assertRaises(Exception):
                    LoadBalancerRule.list(self.apiclient, id=lb_rule.id)
        return

    @attr(tags=["advanced", "advancedns"])
    @attr(speed="slow")
    def test_05_error_alerts_after_create(self):
        """Test error/alerts after creating stickiness policy"""

        # Validate the following
        # 1. Create a LB rule with round Robin/Least connections/Source
        #    listLoadBalancerRules should show newly created load balancer rule
        # 2. Configure the Stickiness policy to above created LB rule.
        #    listLBStickinessPolicies Api should show newly created stickiness
        # 3. update & delete stickiness policy see error related to stickiness
        # 4. No errors should be shown in the logs and alerts

        lb_methods = ["roundrobin", "leastconn", "source"]
        configs = {"SourceBased": {"tablesize": '100k'},
                   "AppCookie": {"request-learn": "true"},
                   "LBCookie": {"nocache": "true"}}
        for lb_method in lb_methods:
            for method, params in configs.items():
                self.debug("Creating load balancing rule on IP %s & algo %s" %
                            (self.public_ip.ipaddress.ipaddress, lb_method))

                services = self.services["lbrule"]
                services["alg"] = lb_method

                lb_rule = self.create_LB_Rule(self.public_ip,
                            network=self.get_Network(self.account),
                            vmarray=[self.virtual_machine, self.virtual_machine_2],
                            services=services)

                self.debug("Creating stickiness policy for the LB rule: %s" %
                                                                lb_rule.id)
                policies = self.configure_Stickiness_Policy(lb_rule,
                                                          method=method,
                                                          paramDict=params)

                policy = policies.stickinesspolicy[0]

                self.debug("Policy: %s" % str(policy))
                self.debug("Validating the stickiness policy")
                self.validate_Stickiness_Policy(lb_rule, method, self.public_ip.ipaddress.ipaddress)

                self.debug("Deleting the LB rule: %s" % lb_rule.name)
                lb_rule.delete(self.apiclient)

                with self.assertRaises(Exception):
                    LoadBalancerRule.list(self.apiclient,
                                        id=lb_rule.id,
                                        listall=True)
                alerts = Alert.list(self.apiclient, keyword="stickiness",
                                listall=True)
                self.debug(
                    "Create/update/delete should not produce any alert/error")
                self.assertEqual(alerts, None,
                    "Create/update/delete should not produce any alert/error")
        return

    @attr(tags=["advanced", "advancedns"])
    @attr(speed="slow")
    def test_06_release_ip(self):
        """Test release public IP with stickiness policy"""

        # 1. Configure load balancing rule. Listloadbalancerrule should list
        #    valid list
        # 2. Create stickiness policy. liststickinesspolicy should return valid
        #    response
        # 3. Release public Ip. liststickiness policy should return a valid
        #    response

        lb_methods = ["roundrobin", "leastconn", "source"]

        configs = {"SourceBased": {"tablesize": '100k'},
                   "AppCookie": {"request-learn": "true"},
                   "LBCookie": {"nocache": "true"}}

        for lb_method in lb_methods:
            for method, params in configs.items():
                self.debug("Setting up environment - acquire public IP")
                public_ip = self.acquire_Public_Ip()

                self.debug(
                    "Creating a load balancing rule on IP %s and algo %s" %
                                (public_ip.ipaddress.ipaddress, lb_method))

                services = self.services["lbrule"]
                services["alg"] = lb_method

                lb_rule = self.create_LB_Rule(public_ip,
                            network=self.get_Network(self.account),
                            vmarray=[self.virtual_machine, self.virtual_machine_2],
                            services=services)

                policies = self.configure_Stickiness_Policy(lb_rule,
                                                          method=method,
                                                          paramDict=params)
                policy = policies.stickinesspolicy[0]

                self.debug("Policy: %s" % str(policy))
                self.debug("Validating the stickiness policy")
                self.validate_Stickiness_Policy(lb_rule, method, public_ip.ipaddress.ipaddress)

                self.debug("Releasing public Ip: %s" %
                                            public_ip.ipaddress.ipaddress)
                public_ip.delete(self.apiclient)

                self.debug("Checking the response of liststickiness policies")

                with self.assertRaises(Exception):
                    lb_rule.listStickyPolicies(self.apiclient,
                                                     lbruleid=lb_rule.id,
                                                     listall=True)
        return

    @attr(tags=["advanced", "advancedns"])
    def test_07_delete_account(self):
        """Test Delete account  and check the router and its rules"""

        # Validate the following
        # 1. create an account
        # 2. using that account,create an instances
        # 3. select the Source NAT IP  and configure the stikiness policy
        # 4. Delete account
        # 5. The corresponding stikiness policy should be removed
        # listLBStickinessPolicies Api shouldnot show deleted stikiness policy

        self.debug("Creating LB rule for account: %s" %
                                                self.account.name)
        lb_rule = self.create_LB_Rule(self.public_ip,
                                      network=self.get_Network(self.account),
                                      vmarray=[self.virtual_machine, self.virtual_machine_2])

        policies = self.configure_Stickiness_Policy(lb_rule, method="LbCookie")
        policy = policies.stickinesspolicy[0]

        self.debug("Policy: %s" % str(policy))
        self.debug("Validating the stickiness policy")
        self.validate_Stickiness_Policy(lb_rule, "LbCookie", self.public_ip.ipaddress.ipaddress)

        # removing account from cleanup list as we're deleting account
        self.cleanup.pop()
        self.debug("Deleting account: %s" % self.account.name)

        try:
            self.account.delete(self.apiclient)
        except Exception as e:
            self.fail("Failed to delete account: %s" % e)
        self.debug("Checking the response of liststickiness policies")

        with self.assertRaises(Exception):
            lb_rule.listStickyPolicies(self.apiclient,
                                       lbruleid=lb_rule.id,
                                       listall=True)
        return

    @attr(tags=["advanced", "advancedns"])
    def test_08_create_policy_router_stopped(self):
        """Test verify create stickiness policy when router is stopped state"""

        # Validate the following
        # 1. stop the router
        # 2. create stikiness policy from UI
        # 3. start the router. listLBStickinessPolicies Api should show created
        #    stikiness policy

        self.debug("Creating LB rule for account: %s" % self.account.name)
        lb_rule = self.create_LB_Rule(self.public_ip,
                                      network=self.get_Network(self.account),
                                      vmarray=[self.virtual_machine, self.virtual_machine_2])

        self.debug("Fetching routers for the account: %s" %
                                                    self.account.name)
        router = self.get_router(self.account)

        self.debug("Stopping the router: %s" % router.name)
        Router.stop(self.apiclient, id=router.id)

        policies = self.configure_Stickiness_Policy(lb_rule, method="LbCookie")
        policy = policies.stickinesspolicy[0]

        self.debug("Starting the router: %s" % router.name)
        Router.start(self.apiclient, id=router.id)

        self.debug("Policy: %s" % str(policy))
        self.debug("Validating the stickiness policy")
        self.validate_Stickiness_Policy(lb_rule, "LbCookie", self.public_ip.ipaddress.ipaddress)
        return

    @attr(tags=["advanced", "advancedns"])
    def test_09_create_policy_router_destroy(self):
        """Test check the stickiness policy rules after destroying router"""

        # Validate the following
        # 1. create an account
        # 2. using that account,create an instances
        # 3. select the Source NAT IP  and configure the stikiness policy
        # 4. destroy the router.

        self.debug("Creating LB rule for account: %s" % self.account.name)
        lb_rule = self.create_LB_Rule(self.public_ip,
                                      network=self.get_Network(self.account),
                                      vmarray=[self.virtual_machine, self.virtual_machine_2])

        self.debug("Fetching routers for the account: %s" %
                                                    self.account.name)
        router = self.get_router(self.account)

        policies = self.configure_Stickiness_Policy(lb_rule, method="LbCookie")
        policy = policies.stickinesspolicy[0]

        self.debug("Policy: %s" % str(policy))
        self.debug("Validating the stickiness policy")
        self.validate_Stickiness_Policy(lb_rule, "LbCookie", self.public_ip.ipaddress.ipaddress)

        self.debug("Destroying the router: %s" % router.name)
        Router.destroy(self.apiclient, id=router.id)

        return

    @attr(tags=["advanced", "advancedns"])
    def test_10_create_policy_enable_disable_vpn(self):
        """Test enable/disable the VPN after applying sticky policy rules"""

        # Validate the following
        # 1. create an account
        # 2. using that account,create an instances
        # 3. select the Source NAT IP  and configure the stikiness policy
        # 4. enable /disable the VPN. It should not impact the ceated rules
        #    listLBStickinessPolicies Api should show created stikiness policy

        self.debug("Creating LB rule for account: %s" % self.account.name)
        lb_rule = self.create_LB_Rule(self.public_ip,
                                      network=self.get_Network(self.account),
                                      vmarray=[self.virtual_machine, self.virtual_machine_2])

        policies = self.configure_Stickiness_Policy(lb_rule, method="LbCookie")
        policy = policies.stickinesspolicy[0]

        self.debug("Policy: %s" % str(policy))
        self.debug("Validating the stickiness policy")
        self.validate_Stickiness_Policy(lb_rule, "LbCookie", self.public_ip.ipaddress.ipaddress)

        self.debug("Enabling VPN on Public Ip: %s" %
                                        self.public_ip.ipaddress.ipaddress)
        self.create_VPN(self.public_ip)

        self.debug("Validating the stickiness policy after enabling VPN")
        self.validate_Stickiness_Policy(lb_rule, "LbCookie", self.public_ip.ipaddress.ipaddress)
        return

    @attr(tags=["advanced", "advancedns"])
    def test_11_invalid_params(self):
        """Test verfify functionality syncronous and asyncronous validations"""

        # Validate the following
        #  verify the validation  while creating or attaching stikiness policy
        #    by doing the following scenaios
        # * by passing the Invlaid parameter
        # * Invalid method name
        # * required parameter not present
        # * passing invalid values to valid paramters.

        self.debug("Creating LB rule for account: %s" % self.account.name)
        lb_rule = self.create_LB_Rule(self.public_ip,
                                      network=self.get_Network(self.account),
                                      vmarray=[self.virtual_machine, self.virtual_machine_2])

        self.debug("Creating stickiness policy with invalid method")
        with self.assertRaises(Exception):
            self.configure_Stickiness_Policy(lb_rule, method="InvalidMethod")

        self.debug("Creating stickiness policy with invalid params")
        with self.assertRaises(Exception):
            self.configure_Stickiness_Policy(lb_rule, method="LbCookie",
                                             params={"Test": 10})

        self.debug("Passing invalid parameter")
        with self.assertRaises(Exception):
            cmd = createLBStickinessPolicy.createLBStickinessPolicyCmd()
            cmd.lbruleid = lb_rule.id
            cmd.method = "LbCookie"
            cmd.name = "LbCookie"
            self.apiclient.createLBStickinessPolicy(cmd)

        self.debug("Creating stickiness policy not passing required param")
        with self.assertRaises(Exception):
            cmd = createLBStickinessPolicy.createLBStickinessPolicyCmd()
            cmd.lbruleid = lb_rule.id
            cmd.name = "LbCookie"
            self.apiclient.createLBStickinessPolicy(cmd)

        return
