# 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.cloudstackException import cloudstackAPIException
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.integration.lib.base import (
                                        Account,
                                        ServiceOffering,
                                        VirtualMachine,
                                        PublicIPAddress,
                                        Vpn,
                                        VpnUser,
                                        Configurations,
                                        NATRule
                                        )
from marvin.integration.lib.common import (get_domain,
                                        get_zone,
                                        get_template
                                        )
from marvin.integration.lib.utils import cleanup_resources


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": 'KVM',
                                    "privateport": 22,
                                    "publicport": 22,
                                    "protocol": 'TCP',
                                },
                         "vpn_user": {
                                   "username": "test",
                                   "password": "test",
                                },
                         "natrule": {
                                   "privateport": 1701,
                                   "publicport": 1701,
                                   "protocol": "UDP"
                                },
                        "ostype": 'CentOS 5.5 (64-bit)',
                        "sleep": 60,
                        "timeout": 10,
                        # Networking mode: Advanced, Basic
                    }


class TestVPNUsers(cloudstackTestCase):
    @classmethod
    def setUpClass(cls):
        cls.api_client = super(TestVPNUsers,
            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.services["mode"] = cls.zone.networktype

        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):
        try:
            self.apiclient = self.testClient.getApiClient()
            self.dbclient = self.testClient.getDbConnection()
            self.account = Account.create(
                                self.apiclient,
                                self.services["account"],
                                domainid=self.domain.id
                                )
            self.cleanup = [
                            self.account,
                            ]
            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.public_ip = PublicIPAddress.create(
                                               self.apiclient,
                                               accountid=self.virtual_machine.account,
                                               zoneid=self.virtual_machine.zoneid,
                                               domainid=self.virtual_machine.domainid,
                                               services=self.services["virtual_machine"]
                                               )
            return
        except cloudstackAPIException as e:
                self.tearDown()
                raise e

    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

    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 create_VPN_Users(self, rand_name=True, api_client=None):
        """Creates VPN users for the network"""

        self.debug("Creating VPN users for account: %s" %
                                                    self.account.name)
        if api_client is None:
            api_client = self.apiclient
        try:
            vpnuser = VpnUser.create(
                                 api_client,
                                 self.services["vpn_user"]["username"],
                                 self.services["vpn_user"]["password"],
                                 account=self.account.name,
                                 domainid=self.account.domainid,
                                 rand_name=rand_name
                                 )

            self.debug("Verifying the remote VPN access")
            vpn_users = VpnUser.list(self.apiclient,
                                     id=vpnuser.id,
                                     listall=True)
            self.assertEqual(
                         isinstance(vpn_users, list),
                         True,
                         "List VPNs shall return a valid response"
                         )
            return vpnuser
        except Exception as e:
            self.fail("Failed to create remote VPN users: %s" % e)

    @attr(tags=["advanced", "advancedns"])
    @attr(configuration='remote.access.vpn.user.limit')
    def test_01_VPN_user_limit(self):
        """VPN remote access user limit tests"""

        # Validate the following
        # prerequisite: change management configuration setting of
        #    remote.access.vpn.user.limit
        # 1. provision more users than is set in the limit
        #    Provisioning of users after the limit should failProvisioning of
        #    users after the limit should fail

        self.debug("Fetching the limit for remote access VPN users")
        configs = Configurations.list(
                                     self.apiclient,
                                     name='remote.access.vpn.user.limit',
                                     listall=True)
        self.assertEqual(isinstance(configs, list),
                         True,
                         "List configs should return a valid response")

        limit = int(configs[0].value)

        self.debug("Enabling the VPN access for IP: %s" %
                                            self.public_ip.ipaddress)

        self.create_VPN(self.public_ip)
        self.debug("Creating %s VPN users" % limit)
        for x in range(limit):
            self.create_VPN_Users()

        self.debug("Adding another user exceeding limit for remote VPN users")
        with self.assertRaises(Exception):
            self.create_VPN_Users()
        self.debug("Limit exceeded exception raised!")
        return

    @attr(tags=["advanced", "advancedns"])
    def test_02_use_vpn_port(self):
        """Test create VPN when L2TP port in use"""

        # Validate the following
        # 1. set a port forward for UDP: 1701 and enable VPN
        # 2. set port forward rule for the udp port 1701 over which L2TP works
        # 3. port forward should prevent VPN from being enabled

        self.debug("Creating a port forwarding rule on port 1701")
        # Create NAT rule
        nat_rule = NATRule.create(
                        self.apiclient,
                        self.virtual_machine,
                        self.services["natrule"],
                        self.public_ip.ipaddress.id)

        self.debug("Verifying the NAT rule created")
        nat_rules = NATRule.list(self.apiclient, id=nat_rule.id, listall=True)

        self.assertEqual(isinstance(nat_rules, list),
                         True,
                         "List NAT rules should return a valid response")

        self.debug("Enabling the VPN connection for IP: %s" %
                                            self.public_ip.ipaddress)
        with self.assertRaises(Exception):
            self.create_VPN(self.public_ip)
        self.debug("Create VPN connection failed! Test successful!")
        return

    @attr(tags=["advanced", "advancedns"])
    def test_03_enable_vpn_use_port(self):
        """Test create NAT rule when VPN when L2TP enabled"""

        # Validate the following
        # 1. Enable a VPN connection on source NAT
        # 2. Add a VPN user
        # 3. add a port forward rule for UDP port 1701.  Should result in error
        #    saying that VPN is enabled over port 1701

        self.debug("Enabling the VPN connection for IP: %s" %
                                            self.public_ip.ipaddress)
        self.create_VPN(self.public_ip)

        self.debug("Creating a port forwarding rule on port 1701")
        # Create NAT rule
        with self.assertRaises(Exception):
            NATRule.create(
                        self.apiclient,
                        self.virtual_machine,
                        self.services["natrule"],
                        self.public_ip.ipaddress.id)

        self.debug("Create NAT rule failed! Test successful!")
        return

    @attr(tags=["advanced", "advancedns"])
    def test_04_add_new_users(self):
        """Test add new users to existing VPN"""

        # Validate the following
        # 1. Enable a VPN connection on source NAT
        # 2. Add new user to VPN when there are already existing users.
        # 3. We should be able to successfully establish a VPN connection using
        #    the newly added user credential.

        self.debug("Enabling the VPN connection for IP: %s" %
                                            self.public_ip.ipaddress)
        self.create_VPN(self.public_ip)

        try:
            self.debug("Adding new VPN user to account: %s" %
                                                    self.account.name)
            self.create_VPN_Users()

            # TODO: Verify the VPN connection
            self.debug("Adding another user to account")
            self.create_VPN_Users()

            # TODO: Verify the VPN connection with new user
        except Exception as e:
            self.fail("Failed to create new VPN user: %s" % e)
        return

    @attr(tags=["advanced", "advancedns"])
    def test_05_add_duplicate_user(self):
        """Test add duplicate user to existing VPN"""

        # Validate the following
        # 1. Enable a VPN connection on source NAT
        # 2. Add a VPN user say "abc"  that already an added user to the VPN.
        # 3. Adding this VPN user should fail.

        self.debug("Enabling the VPN connection for IP: %s" %
                                            self.public_ip.ipaddress)
        self.create_VPN(self.public_ip)

        self.debug("Adding new VPN user to account: %s" %
                                                    self.account.name)
        self.create_VPN_Users(rand_name=False)

        # TODO: Verify the VPN connection
        self.debug("Adding another user to account with same username")
        with self.assertRaises(Exception):
            self.create_VPN_Users(rand_name=False)
        return

    @attr(tags=["advanced", "advancedns"])
    def test_06_add_VPN_user_global_admin(self):
        """Test as global admin, add a new VPN user to an existing VPN entry
            that was created by another account."""

        # Steps for verification
        # 1. Create a new user and deploy few Vms.
        # 2. Enable VPN access. Add few VPN users.
        # 3. Make sure that VPN access works as expected.
        # 4. As global Admin , add VPN user to this user's existing VPN entry.
        #  Validate the following
        # 1. The newly added VPN user should get configured to the router of
        #    user account.
        # 2. We should be able to use this newly created user credential to
        #   establish VPN connection that will give access all VMs of this user

        self.debug("Enabling VPN connection to account: %s" %
                                                    self.account.name)
        self.create_VPN(self.public_ip)
        self.debug("Creating VPN user for the account: %s" %
                                                    self.account.name)
        self.create_VPN_Users()

        self.debug("Creating a global admin account")
        admin = Account.create(self.apiclient,
                               self.services["account"],
                               admin=True,
                               domainid=self.account.domainid)
        self.cleanup.append(admin)
        self.debug("Creating API client for newly created user")
        api_client = self.testClient.createUserApiClient(
                                    UserName=self.account.name,
                                    DomainName=self.account.domain)

        self.debug("Adding new user to VPN as a global admin: %s" %
                                                            admin.name)
        try:
            self.create_VPN_Users(api_client=api_client)
        except Exception as e:
            self.fail("Global admin should be allowed to create VPN user: %s" %
                                                                            e)
        return

    @attr(tags=["advanced", "advancedns"])
    def test_07_add_VPN_user_domain_admin(self):
        """Test as domain admin, add a new VPN user to an existing VPN entry
            that was created by another account."""

        # Steps for verification
        # 1. Create a new user and deploy few Vms.
        # 2. Enable VPN access. Add few VPN users.
        # 3. Make sure that VPN access works as expected.
        # 4. As domain Admin , add VPN user to this user's existing VPN entry.
        #  Validate the following
        # 1. The newly added VPN user should get configured to the router of
        #    user account.
        # 2. We should be able to use this newly created user credential to
        #   establish VPN connection that will give access all VMs of this user

        self.debug("Enabling VPN connection to account: %s" %
                                                    self.account.name)
        self.create_VPN(self.public_ip)
        self.debug("Creating VPN user for the account: %s" %
                                                    self.account.name)
        self.create_VPN_Users()

        self.debug("Creating a domain admin account")
        admin = Account.create(self.apiclient,
                               self.services["account"],
                               domainid=self.account.domainid)
        self.cleanup.append(admin)
        self.debug("Creating API client for newly created user")
        api_client = self.testClient.createUserApiClient(
                                    UserName=self.account.name,
                                    DomainName=self.account.domain)

        self.debug("Adding new user to VPN as a domain admin: %s" %
                                                            admin.name)
        try:
            self.create_VPN_Users(api_client=api_client)
        except Exception as e:
            self.fail("Domain admin should be allowed to create VPN user: %s" %
                                                                            e)
        return
