This is an automated email from the ASF dual-hosted git repository.

sateesh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git

commit 6535949383c31fc492ff9b1728bd0362bfdd7546
Author: Sowmya Krishnan <sowmya.krish...@accelerite.com>
AuthorDate: Wed Jan 25 17:17:43 2017 +0530

    CLOUDSTACK-8672 : NCC Integration with CloudStack.
    Marvin Integration Tests for Shared and Dedicated Workflow.
---
 .../component/test_ncc_integration_dedicated.py    | 269 +++++++++++++++++
 .../component/test_ncc_integration_shared.py       | 323 +++++++++++++++++++++
 tools/marvin/marvin/config/test_data.py            |  48 +++
 tools/marvin/marvin/lib/base.py                    |  21 ++
 tools/marvin/marvin/lib/ncc.py                     | 317 ++++++++++++++++++++
 5 files changed, 978 insertions(+)

diff --git a/test/integration/component/test_ncc_integration_dedicated.py 
b/test/integration/component/test_ncc_integration_dedicated.py
new file mode 100755
index 0000000..b02d051
--- /dev/null
+++ b/test/integration/component/test_ncc_integration_dedicated.py
@@ -0,0 +1,269 @@
+# 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.
+"""
+BVT tests for NCC integration with cloudstack
+"""
+#Import Local Modules
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.lib.common import get_domain, get_zone, get_template
+from marvin.lib import ncc
+from marvin.lib.base import (Account,
+                             VirtualMachine,
+                             PublicIPAddress,
+                             LoadBalancerRule,
+                             ServiceOffering,
+                             NetworkOffering,
+                             Network,
+                             NATRule,
+                            PhysicalNetwork,
+                            NetworkServiceProvider,
+                               RegisteredServicePackage)
+from marvin.lib.utils import cleanup_resources
+from nose.plugins.attrib import attr
+import logging
+
+
+class TestNccIntegrationDedicated(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.testClient = super(TestNccIntegrationDedicated, 
cls).getClsTestClient()
+        cls.api_client = cls.testClient.getApiClient()
+        cls.services = cls.testClient.getParsedTestDataConfig()
+        cls._cleanup = []
+
+        cls.logger = logging.getLogger('TestNccIntegrationDedicated')
+        cls.stream_handler = logging.StreamHandler()
+        cls.logger.setLevel(logging.DEBUG)
+        cls.logger.addHandler(cls.stream_handler)
+
+        # Get Zone, Domain and templates
+        cls.domain = get_domain(cls.api_client)
+        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
+        cls.services['mode'] = cls.zone.networktype
+        cls.template = get_template(
+            cls.api_client,
+            cls.zone.id,
+            cls.services["ostype"] )
+        ncc_ip = cls.services["NCC"]["NCCIP"]
+        ns_ip = cls.services["NSDedicated"]["NSIP"]
+        cls.debug("NS IP - Dedicated: %s" % ns_ip)
+
+        mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"]
+        #ncc_ip = "10.102.195.215"
+        #ns_ip = "10.102.195.210"
+        cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger)
+        cls.ns.registerCCP(cls.api_client)
+        cls.ns.registerNS()
+        cls.ns.assignNStoCSZone()
+        spname = cls.services["servicepackage_dedicated"]["name"]
+
+        # Create Service package and get device group id, tenant group id and 
service package id
+        # These would be needed later for clean up
+
+        (cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = 
cls.ns.createServicePackages(
+            spname,
+            "NetScalerVPX",
+            ns_ip,
+            isolation_policy="dedicated")
+        cls.debug("Created service package in NCC")
+        cls.debug("dv_group, tnt_group, srv_pkg_id: %s %s %s" 
%(cls.dv_group_id,cls.tnt_group_id, cls.srv_pkg_id))
+
+        srv_pkg_list = RegisteredServicePackage.list(cls.api_client)
+        # Choose the one created
+        cls.srv_pkg_uuid = None
+        for sp in srv_pkg_list:
+            if sp.name == spname:
+                cls.srv_pkg_uuid = sp.id
+        #srv_pkg_id = srv_pkg_list[0].id
+
+        cls.account = Account.create(
+            cls.api_client,
+            cls.services["account"]
+        )
+        cls._cleanup.append(cls.account)
+
+        try:
+            cls.services["nw_off_ncc_DedicatedSP"]["servicepackageuuid"] = 
cls.srv_pkg_uuid
+            
cls.services["nw_off_ncc_DedicatedSP"]["servicepackagedescription"] = "A 
NetScalerVPX is dedicated per network."
+            cls.network_offering = NetworkOffering.create(
+                cls.api_client,
+                cls.services["nw_off_ncc_DedicatedSP"])
+        except Exception as e:
+            raise Exception ("Unable to create network offering with Service 
package % s due to exception % s"
+                             % (cls.srv_pkg_uuid, e))
+
+        # Network offering should be removed so that service package may be 
deleted later
+        cls._cleanup.append(cls.network_offering)
+
+        cls.network_offering.update(cls.api_client, state = "Enabled")
+        cls.service_offering = ServiceOffering.create(
+                cls.api_client,
+                cls.services["service_offering"]
+            )
+        cls.services["small"]["template"] = cls.template.id
+
+        # Enable Netscaler Service Provider
+
+        cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id)
+        if isinstance(cls.phy_nws, list):
+            physical_network = cls.phy_nws[0]
+
+        try:
+            cls.ns_service_provider = 
NetworkServiceProvider.list(cls.api_client,name='Netscaler')
+            if isinstance(cls.ns_service_provider, list):
+                ns_provider = cls.ns_service_provider[0]
+        except:
+            raise Exception ("Netscaler service provider not found!!")
+
+        try:
+            if ns_provider.state != "Enabled":
+                NetworkServiceProvider.update(cls.api_client, 
id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled")
+        except:
+            raise Exception ("Enabling Netscaler Service provider failed. 
Unable to proceed")
+
+        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)
+         cls.ns.cleanup_ncc(cls.dv_group_id, cls.srv_pkg_uuid, cls.srv_pkg_id, 
cls.tnt_group_id)
+         return
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        return
+
+    def tearDown(self):
+        return
+
+
+    @attr(tags=["ncc"], required_hardware="true")
+    def test_01_dedicated_first_network(self):
+        # Create network
+        self.debug("Creating network with network offering: %s" % 
self.network_offering.id)
+        self.network = Network.create(
+            self.apiclient,
+            self.services["network"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkofferingid=self.network_offering.id,
+            zoneid=self.zone.id
+        )
+        self.debug("Created network: %s" % self.network.id)
+
+        self.debug("Trying VM deploy with network created on account: %s" % 
self.account.name)
+
+        self.virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.services["small"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            zoneid=self.zone.id,
+            networkids=self.network.id,
+            serviceofferingid=self.service_offering.id
+        )
+        self.debug("Deployed VM in network: %s" % self.network.id)
+        list_vm_response = VirtualMachine.list(
+            self.apiclient,
+            id=self.virtual_machine.id
+        )
+        self.debug(
+            "Verify listVirtualMachines response for virtual machine: %s"
+            % self.virtual_machine.id
+        )
+
+        self.assertEqual(
+            isinstance(list_vm_response, list),
+            True,
+            "Check list response returns a valid list")
+        vm_response = list_vm_response[0]
+
+        self.assertEqual(
+            vm_response.state,
+            "Running",
+            "VM state should be running after deployment"
+        )
+
+        self.debug("Aquiring public IP for network: %s" % self.network.id)
+
+        ip_with_lb_rule = PublicIPAddress.create(
+            self.apiclient,
+            accountid=self.account.name,
+            zoneid=self.zone.id,
+            domainid=self.account.domainid,
+            networkid=self.network.id)
+
+        self.debug(
+            "Creating LB rule for IP address: %s with round robin algo" %
+            ip_with_lb_rule.ipaddress.ipaddress)
+
+        self.services["lbrule"]["alg"] = 'roundrobin'
+        lb_rule = LoadBalancerRule.create(
+            self.apiclient,
+            self.services["lbrule"],
+            ipaddressid=ip_with_lb_rule.ipaddress.id,
+            accountid=self.account.name,
+            networkid=self.network.id
+        )
+
+        lb_rules = LoadBalancerRule.list(
+            self.apiclient,
+            id=lb_rule.id,
+            listall=True
+        )
+        self.assertEqual(
+            isinstance(lb_rules, list),
+            True,
+            "List LB rules should return a newly created LB rule"
+        )
+        self.debug("Adding %s to the LB rule %s" % (
+            self.virtual_machine.name,
+            lb_rule.name
+        ))
+        lb_rule.assign(self.apiclient, [self.virtual_machine])
+
+    @attr(tags=["ncc"], required_hardware="true")
+    def test_02_dedicated_another_network(self):
+        # Create network
+        self.network = Network.create(
+            self.apiclient,
+            self.services["network"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkofferingid=self.network_offering.id,
+            zoneid=self.zone.id
+        )
+        self.debug("Created network: %s" % self.network.id)
+
+        self.debug("Trying VM deploy with network created on account: %s" % 
self.account.name)
+
+        with self.assertRaises(Exception):
+            self.virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.services["small"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkids=self.network.id,
+            zoneid=self.zone.id,
+            serviceofferingid=self.service_offering.id
+            )
+        return
diff --git a/test/integration/component/test_ncc_integration_shared.py 
b/test/integration/component/test_ncc_integration_shared.py
new file mode 100755
index 0000000..cb5b90c
--- /dev/null
+++ b/test/integration/component/test_ncc_integration_shared.py
@@ -0,0 +1,323 @@
+# 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.
+"""
+BVT tests for NCC integration with cloudstack
+"""
+#Import Local Modules
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.lib.common import get_domain, get_zone, get_template
+from marvin.lib import ncc
+from marvin.lib.base import (Account,
+                             VirtualMachine,
+                             PublicIPAddress,
+                             LoadBalancerRule,
+                             ServiceOffering,
+                             NetworkOffering,
+                             Network,
+                             NATRule,
+                            PhysicalNetwork,
+                            NetworkServiceProvider,
+                               RegisteredServicePackage)
+from marvin.lib.utils import cleanup_resources
+from nose.plugins.attrib import attr
+import logging
+
+
+class TestNccIntegrationShared(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.testClient = super(TestNccIntegrationShared, 
cls).getClsTestClient()
+        cls.api_client = cls.testClient.getApiClient()
+        cls.services = cls.testClient.getParsedTestDataConfig()
+        cls._cleanup = []
+
+        cls.logger = logging.getLogger('TestNccIntegrationShared')
+        cls.stream_handler = logging.StreamHandler()
+        cls.logger.setLevel(logging.DEBUG)
+        cls.logger.addHandler(cls.stream_handler)
+
+        # Get Zone, Domain and templates
+        cls.domain = get_domain(cls.api_client)
+        cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
+        cls.services['mode'] = cls.zone.networktype
+        cls.template = get_template(
+            cls.api_client,
+            cls.zone.id,
+            cls.services["ostype"] )
+        ncc_ip=cls.services["NCC"]["NCCIP"]
+        ns_ip=cls.services["NSShared"]["NSIP"]
+        cls.debug("NS IP: Shared: %s" % ns_ip)
+
+        mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"]
+        #ncc_ip = "10.102.195.215"
+        #ns_ip = "10.102.195.210"
+        cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger)
+        cls.ns.registerCCP(cls.api_client)
+        cls.ns.registerNS()
+        cls.ns.assignNStoCSZone()
+        spname = cls.services["servicepackage_shared"]["name"]
+        cls.debug("SPname (Shared): %s" % spname)
+        #spname="SharedSP9"
+        # Create Service package and get device group id, tenant group id and 
service package id
+        # These would be needed later for clean up
+
+        (cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = 
cls.ns.createServicePackages(
+            spname,
+            "NetScalerVPX",
+            ns_ip)
+        srv_pkg_list = RegisteredServicePackage.list(cls.api_client)
+        # Choose the one created
+        cls.srv_pkg_uuid = None
+        for sp in srv_pkg_list:
+            if sp.name == spname:
+                cls.srv_pkg_uuid = sp.id
+        #srv_pkg_id = srv_pkg_list[0].id
+
+        cls.account = Account.create(
+            cls.api_client,
+            cls.services["account"]
+        )
+        cls._cleanup.append(cls.account)
+
+        try:
+            cls.services["nw_off_ncc_SharedSP"]["servicepackageuuid"] = 
cls.srv_pkg_uuid
+            cls.services["nw_off_ncc_SharedSP"]["servicepackagedescription"] = 
"A NetScalerVPX is shared across all networks."
+            cls.network_offering = NetworkOffering.create(
+                cls.api_client,
+                cls.services["nw_off_ncc_SharedSP"])
+        except Exception as e:
+            raise Exception ("Unable to create network offering with Service 
package % s due to exception % s"
+                             % (cls.srv_pkg_uuid, e))
+
+        # Network offering should be removed so that service package may be 
deleted later
+        cls._cleanup.append(cls.network_offering)
+
+        cls.network_offering.update(cls.api_client, state = "Enabled")
+        cls.service_offering_shared = ServiceOffering.create(
+                cls.api_client,
+                cls.services["service_offering"]
+            )
+        cls.services["small"]["template"] = cls.template.id
+
+        # Enable Netscaler Service Provider
+
+        cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id)
+        if isinstance(cls.phy_nws, list):
+            physical_network = cls.phy_nws[0]
+
+        try:
+            cls.ns_service_provider = 
NetworkServiceProvider.list(cls.api_client,name='Netscaler')
+            if isinstance(cls.ns_service_provider, list):
+                ns_provider = cls.ns_service_provider[0]
+        except:
+            raise Exception ("Netscaler service provider not found!!")
+
+        try:
+            if ns_provider.state != "Enabled":
+                NetworkServiceProvider.update(cls.api_client, 
id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled")
+        except:
+            raise Exception ("Enabling Netscaler Service provider failed. 
Unable to proceed")
+
+        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)
+         cls.ns.cleanup_ncc(cls.dv_group_id, cls.srv_pkg_uuid, cls.srv_pkg_id, 
cls.tnt_group_id)
+         return
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        return
+
+    def tearDown(self):
+        return
+
+    @attr(tags=["ncc"], required_hardware="true")
+    def test_01_shared_first_network(self):
+        # Create network
+        self.debug("Creating network with network offering: %s" % 
self.network_offering.id)
+        self.network = Network.create(
+            self.apiclient,
+            self.services["network"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkofferingid=self.network_offering.id,
+            zoneid=self.zone.id
+        )
+        self.debug("Created network: %s" % self.network.id)
+
+        self.debug("Trying VM deploy with network created on account: %s" % 
self.account.name)
+
+        self.virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.services["small"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            zoneid=self.zone.id,
+            networkids=self.network.id,
+            serviceofferingid=self.service_offering_shared.id)
+        self.debug("Deployed VM in network: %s" % self.network.id)
+        list_vm_response = VirtualMachine.list(
+            self.apiclient,
+            id=self.virtual_machine.id
+        )
+        self.debug(
+            "Verify listVirtualMachines response for virtual machine: %s"
+            % self.virtual_machine.id
+        )
+
+        self.assertEqual(
+            isinstance(list_vm_response, list),
+            True,
+            "Check list response returns a valid list")
+        vm_response = list_vm_response[0]
+
+        self.assertEqual(
+            vm_response.state,
+            "Running",
+            "VM state should be running after deployment"
+        )
+
+        self.debug("Acquiring public IP for network: %s" % self.network.id)
+
+        ip_with_lb_rule = PublicIPAddress.create(
+            self.apiclient,
+            accountid=self.account.name,
+            zoneid=self.zone.id,
+            domainid=self.account.domainid,
+            networkid=self.network.id)
+
+        self.debug(
+            "Creating LB rule for IP address: %s with round robin algo" %
+            ip_with_lb_rule.ipaddress.ipaddress)
+
+        self.services["lbrule"]["alg"] = 'roundrobin'
+        lb_rule = LoadBalancerRule.create(
+            self.apiclient,
+            self.services["lbrule"],
+            ipaddressid=ip_with_lb_rule.ipaddress.id,
+            accountid=self.account.name,
+            networkid=self.network.id
+        )
+
+        lb_rules = LoadBalancerRule.list(
+            self.apiclient,
+            id=lb_rule.id,
+            listall=True
+        )
+        self.assertEqual(
+            isinstance(lb_rules, list),
+            True,
+            "List LB rules should return a newly created LB rule"
+        )
+        self.debug("Adding %s to the LB rule %s" % (
+            self.virtual_machine.name,
+            lb_rule.name
+        ))
+        lb_rule.assign(self.apiclient, [self.virtual_machine])
+
+    @attr(tags=["ncc"], required_hardware="true")
+    def test_02_shared_another_network(self):
+        # Create network
+        self.debug("Creating network with network offering: %s" % 
self.network_offering.id)
+        self.network = Network.create(
+            self.apiclient,
+            self.services["network"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkofferingid=self.network_offering.id,
+            zoneid=self.zone.id
+        )
+        self.debug("Created network: %s" % self.network.id)
+
+        self.debug("Trying VM deploy with network created on account: %s" % 
self.account.name)
+
+        self.virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.services["small"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            networkids=self.network.id,
+            zoneid=self.zone.id,
+            serviceofferingid=self.service_offering_shared.id
+        )
+        self.debug("Deployed VM in network: %s" % self.network.id)
+        list_vm_response = VirtualMachine.list(
+            self.apiclient,
+            id=self.virtual_machine.id
+        )
+        self.debug(
+            "Verify listVirtualMachines response for virtual machine: %s"
+            % self.virtual_machine.id
+        )
+
+        self.assertEqual(
+            isinstance(list_vm_response, list),
+            True,
+            "Check list response returns a valid list")
+        vm_response = list_vm_response[0]
+
+        self.assertEqual(
+            vm_response.state,
+            "Running",
+            "VM state should be running after deployment"
+        )
+
+        self.debug("Aquiring public IP for network: %s" % self.network.id)
+
+        ip_with_lb_rule = PublicIPAddress.create(
+            self.apiclient,
+            accountid=self.account.name,
+            zoneid=self.zone.id,
+            domainid=self.account.domainid,
+            networkid=self.network.id)
+
+        self.debug(
+            "Creating LB rule for IP address: %s with round robin algo" %
+            ip_with_lb_rule.ipaddress.ipaddress)
+
+        self.services["lbrule"]["alg"] = 'roundrobin'
+        lb_rule = LoadBalancerRule.create(
+            self.apiclient,
+            self.services["lbrule"],
+            ipaddressid=ip_with_lb_rule.ipaddress.id,
+            accountid=self.account.name,
+            networkid=self.network.id
+        )
+
+        lb_rules = LoadBalancerRule.list(
+            self.apiclient,
+            id=lb_rule.id,
+            listall=True
+        )
+        self.assertEqual(
+            isinstance(lb_rules, list),
+            True,
+            "List LB rules should return a newly created LB rule"
+        )
+        self.debug("Adding %s to the LB rule %s" % (
+            self.virtual_machine.name,
+            lb_rule.name
+        ))
+        lb_rule.assign(self.apiclient, [self.virtual_machine])
+        return
diff --git a/tools/marvin/marvin/config/test_data.py 
b/tools/marvin/marvin/config/test_data.py
index d1ec1ba..0f67ce8 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -674,6 +674,54 @@ test_data = {
         "cidr": "0.0.0.0/0",
         "protocol": "TCP"
     },
+    "nw_off_ncc_SharedSP": {
+        "name": 'SharedSP',
+        "displaytext": 'SharedSP',
+        "guestiptype": 'Isolated',
+        "supportedservices":
+            'Dhcp,Dns,SourceNat,Lb,StaticNat',
+        "traffictype": 'GUEST',
+        "availability": 'Optional',
+        "serviceProviderList": {
+            "Dhcp": 'VirtualRouter',
+            "Dns": 'VirtualRouter',
+            "SourceNat": 'VirtualRouter',
+            "Lb": 'Netscaler',
+            "StaticNat": 'VirtualRouter'
+        }
+    },
+    "nw_off_ncc_DedicatedSP": {
+        "name": 'DedicatedSP',
+        "displaytext": 'DedicatedSP',
+        "guestiptype": 'Isolated',
+        "supportedservices":
+            'Dhcp,Dns,SourceNat,Lb,StaticNat',
+        "traffictype": 'GUEST',
+        "availability": 'Optional',
+        "serviceProviderList": {
+            "Dhcp": 'VirtualRouter',
+            "Dns": 'VirtualRouter',
+            "SourceNat": 'VirtualRouter',
+            "Lb": 'Netscaler',
+            "StaticNat": 'VirtualRouter'
+        }
+    },
+    "NCC": {
+        "NCCIP": '10.102.195.215',
+    },
+    "NSShared": {
+        "NSIP": '10.102.195.210',
+    },
+    "NSDedicated": {
+        "NSIP": '10.102.195.212'
+    },
+    "servicepackage_shared": {
+        "name": "SharedSP",
+    },
+    "servicepackage_dedicated": {
+        "name": "DedicatedSP",
+    },
+
     "nw_off_isolated_persistent_netscaler": {
         "name": 'Netscaler',
         "displaytext": 'Netscaler',
diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py
index 3283911..6a00c67 100755
--- a/tools/marvin/marvin/lib/base.py
+++ b/tools/marvin/marvin/lib/base.py
@@ -2201,6 +2201,12 @@ class NetworkOffering:
             cmd.ispersistent = services["ispersistent"]
         if "egress_policy" in services:
             cmd.egressdefaultpolicy = services["egress_policy"]
+        cmd.details = [{}]
+        if "servicepackageuuid" in services:
+            cmd.details[0]["servicepackageuuid"] = 
services["servicepackageuuid"]
+        if "servicepackagedescription" in services:
+            cmd.details[0]["servicepackagedescription"] = 
services["servicepackagedescription"]
+
 
         cmd.availability = 'Optional'
 
@@ -5190,3 +5196,18 @@ class StorageNetworkIpRange:
         cmd = listStorageNetworkIpRange.listStorageNetworkIpRangeCmd()
         [setattr(cmd, k, v) for k, v in kwargs.items()]
         return(apiclient.listStorageNetworkIpRange(cmd))
+
+class RegisteredServicePackage:
+    """Manage ServicePackage registered with NCC"""
+
+    def __init__(self, items):
+        self.__dict__.update(items)
+
+    @classmethod
+    def list(cls, apiclient, **kwargs):
+        """Lists service packages published by NCC"""
+
+        cmd = listRegisteredServicePackages.listRegisteredServicePackagesCmd()
+        [setattr(cmd, k, v) for k, v in kwargs.items()]
+        return(apiclient.listRegisteredServicePackages(cmd))
+
diff --git a/tools/marvin/marvin/lib/ncc.py b/tools/marvin/marvin/lib/ncc.py
new file mode 100755
index 0000000..5c0ae32
--- /dev/null
+++ b/tools/marvin/marvin/lib/ncc.py
@@ -0,0 +1,317 @@
+# 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.
+
+"""
+Base class for NCC Orchestration
+"""
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.cloudstackAPI import *
+from marvin.lib.base import Domain, Account
+from marvin.lib.utils import validateList
+from marvin.codes import PASS,FAILED
+from marvin.cloudstackException import (InvalidParameterException,
+                                        GetDetailExceptionInfo)
+from os import system
+from subprocess import call
+import requests, json, urllib
+
+class NCC:
+
+    def __init__(self, nccip, nsip, csip, logger=None):
+        self.nccip = nccip
+        self.nsip = nsip
+        self.csip = csip
+        self.logger = logger
+        self.__lastError = ''
+
+    def registerCCP(self, apiclient):
+        """
+        Register CCP with NCC
+        """
+        auth_keys = self.getAdminKeys(apiclient)
+        url = "http://"+self.nccip+"/cs/cca/v1/cloudstacks";
+        cs_url = "http://"+self.csip+":8080/";
+        payload = {"cloudstack": {
+            "name": "Cloudstack",
+            "apikey": auth_keys[0],
+            "secretkey": auth_keys[1],
+            "driver_username": "admin",
+            "driver_password": "nsroot",
+            "cloudstack_uri": cs_url
+            }
+        }
+        cmd_response = self.sendCmdToNCC(url, payload)
+        if cmd_response == FAILED:
+            raise Exception("Error:  %s" % self.__lastError)
+
+    def registerNS(self):
+        url = "http://"+self.nccip+"/nitro/v1/config/managed_device/";
+        payload = 'object={"params":{"action":"add_device"}, 
"managed_device":{"ip_address":"%s",\
+                  "profile_name":"ns_nsroot_profile", 
"sync_operation":"false"}}' % self.nsip
+        headers = {'Content-Type': 'application/x-www-form-urlencoded'}
+        cmd_response = self.sendCmdToNS(url, payload, header=headers)
+        if cmd_response == FAILED:
+            raise Exception("Error:  %s" % self.__lastError)
+
+    def assignNStoCSZone(self):
+        cs_zone = self.getCSZoneFromNCC()
+        if cs_zone == FAILED:
+            raise Exception("Error:  %s" % self.__lastError)
+        url = "http://"+self.nccip+"/nitro/v1/config/tag/";
+        payload = 'object={"tag": {"entity_type": "managed_device", 
"entity_id": "%s",\
+                  "tag_key": "zone", "tag_value": "%s"}}' % (self.nsip, 
cs_zone)
+        header = {'Content-Type':'application/x-www-form-urlencoded'}
+        cmd_response = self.sendCmdToNS(url, payload, header=header)
+        if cmd_response == FAILED:
+            raise Exception("Error:  %s" % self.__lastError)
+
+    def createServicePackages(self, name, platform_type, device_ip, 
isolation_policy="shared"):
+        tnt_group = self.createTenantGroup(name)
+        if tnt_group.status_code != 201:
+            raise Exception("Error:  %s" % self.__lastError)
+        tnt_group_id = json.loads(tnt_group.content)["tenantgroups"][0]["id"]
+        dv_group = self.createDeviceGroup(name, platform_type)
+        if dv_group.status_code != 201:
+            raise Exception("Error:  %s" % self.__lastError)
+        dv_group_id = json.loads(dv_group.content)["devicegroups"][0]["id"]
+        if isolation_policy.lower() == "shared":
+            srv_pkg = self.createServicePackageShared(name, tnt_group_id, 
dv_group_id, isolation_policy )
+        elif isolation_policy.lower() == "dedicated":
+            srv_pkg = self.createServicePackageDedicated(name, tnt_group_id, 
dv_group_id, isolation_policy )
+        else:
+            raise  Exception("NS device must be either in shared or dedicated 
mode")
+        if srv_pkg.status_code != 201:
+            raise Exception("Error:  %s" % self.__lastError)
+        dev_add_res =self.addDevicetoServicePackage(dv_group_id, device_ip)
+        if dev_add_res == FAILED:
+            raise Exception ("Error:  %s" % self.__lastError)
+        srv_pkg_id = json.loads(srv_pkg.content)["servicepackages"][0]["id"]
+        publish_srv_pkg_res = self.publishServicePackage(srv_pkg_id)
+        if publish_srv_pkg_res == FAILED:
+            raise Exception("Error:  %s" % self.__lastError)
+        return (dv_group_id, tnt_group_id, srv_pkg_id)
+
+    def createTenantGroup(self, name):
+        url = "http://"+self.nccip+"/admin/v1/tenantgroups";
+        payload = {"tenantgroups": [{"name": name}]}
+        res = self.sendCmdToNCC(url, payload)
+        return res
+
+    def createDeviceGroup(self, name, platform_type, device_type="netscaler"):
+        url = "http://"+self.nccip+"/admin/v1/devicegroups";
+        payload = {"devicegroups":[{"name": name,
+                                    "device_type": device_type,
+                                    "platform_type": platform_type
+                                   }]
+        }
+        res = self.sendCmdToNCC(url, payload)
+        return res
+
+    def createServicePackageShared(self, name, tenant_group, device_group, 
allocation, device_type="netscaler"):
+        url = "http://"+self.nccip+"/admin/v1/servicepackages";
+        payload = {"servicepackages":[{"allocationgroups": [{"device_type": 
device_type,
+                                                             
"allocationpolicy":allocation,
+                                                             
"placement_scheme": "ROUNDROBIN",
+                                                             "deviceaffinity": 
"onedevice",
+                                                             
"devicegroup":{"ref": device_group}
+                                                             }],
+                                       "name": name,
+                                       "isdefault": "false",
+                                       "tenantgroup": {"ref": tenant_group}
+                                      }]
+        }
+        res = self.sendCmdToNCC(url, payload)
+        return res
+
+    def createServicePackageDedicated(self, name, tenant_group, device_group, 
allocation, device_type="netscaler"):
+        url = "http://"+self.nccip+"/admin/v1/servicepackages";
+        payload = {"servicepackages":[{"allocationgroups": [{"device_type": 
device_type,
+                                                             
"allocationpolicy":allocation,
+                                                             
#"placement_scheme": "roundrobin or leastentity",
+                                                             
"devicegroup":{"ref": device_group}
+                                                            }],
+                                       "name": name,
+                                       "isdefault": "false",
+                                       "tenantgroup": {"ref": tenant_group}
+                                      }]
+        }
+        res = self.sendCmdToNCC(url, payload)
+        return res
+   
+    def addDevicetoServicePackage(self, devicegroup_id, device_ip):
+        url = 
"http://"+self.nccip+"/admin/v1/devicegroups/"+devicegroup_id+"/devices";
+        payload = {"devices":[{"ref":device_ip }]}
+        res = self.sendCmdToNCC(url, payload, method="PUT")
+        return res
+
+    def removeDevicefromServicePackage(self, devicegroup_id):
+        url = 
"http://"+self.nccip+"/admin/v1/devicegroups/"+devicegroup_id+"/devices";
+        payload = {"devices":[]}
+        res = self.sendCmdToNCC(url, payload, method="PUT")
+        return res
+
+    def publishServicePackage(self, pkg_id):
+        url = "http://"+self.nccip+"/cs/cca/v1/servicepackages";
+        payload = {"servicepackages":[{"servicepackageid":pkg_id}]}
+        res = self.sendCmdToNCC(url, payload)
+        return res
+
+    def getCSZoneFromNCC(self):
+        url = "http://"+self.nccip+"/cs/cca/v1/zones";
+        res = self.sendCmdToNCC(url, method="GET")
+        if res != FAILED:
+            zoneid = json.loads(res.content)["zones"][0]
+            return zoneid
+        else:
+            return FAILED
+
+    def sendCmdToNCC(self, url, payload={}, method="POST", 
header={'content-type': 'application/json'}):
+        try:
+            # self.logger.debug("url :%s" % url)
+            # self.logger.debug("payload: %s" % payload)
+            if method == "POST":
+                #self.logger.debug("====Sending POST Request====")
+                return self.sendPostRequstToNCC(url, payload, header)
+            if method == "GET":
+                #self.logger.debug("====Sending GET Request====")
+                return self.sendGetRequestToNCC(url, payload, header)
+            if method == "PUT":
+                return self.sendPutRequestToNCC(url, payload, header)
+            if method == "DELETE":
+                self.logger.debug("Trying delete")
+                return self.sendDeleteRequestToNCC(url, header)
+        except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendCmdToNCC: Exception:%s" %
+            #                       GetDetailExceptionInfo(e))
+            return FAILED
+
+
+    def sendGetRequestToNCC(self, url, payload, header):
+        try:
+            res = requests.get(url, json=payload, auth=("nsroot", "nsroot"), 
headers=header)
+            return res
+        except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendGetRequestToNCC : Exception Occured: 
%s" %
+            #                       str(self.__lastError))
+            return FAILED
+
+    def sendPostRequstToNCC(self, url, payload, header):
+        try:
+            res = requests.post(url, json=payload, auth=("nsroot", "nsroot"), 
headers=header)
+            return res
+        except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendPostRequstToNCC: Exception Occured: 
%s" %
+            #                       str(self.__lastError))
+            return FAILED
+
+    def sendPutRequestToNCC(self, url, payload, header):
+         try:
+            res = requests.put(url, json=payload, auth=("nsroot", "nsroot"), 
headers=header)
+            return res
+         except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendPostRequstToNCC: Exception Occured: 
%s" %
+            #                       str(self.__lastError))
+            return FAILED
+
+    def sendDeleteRequestToNCC(self, url, header):
+         try:
+            res = requests.delete (url, auth=("nsroot", "nsroot"), 
headers=header)
+            return res
+         except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendPostRequstToNCC: Exception Occured: 
%s" %
+            #                       str(self.__lastError))
+            return FAILED
+
+    def sendCmdToNS(self, url, payload={}, method="POST", 
header={'content-type': 'application/json'}):
+        try:
+            # self.logger.debug("url :%s" % url)
+            # self.logger.debug("payload: %s" % payload)
+            if method == "POST":
+                #self.logger.debug("====Sending POST Request====")
+                return self.sendPostRequstToNS(url, payload, header)
+            if method == "GET":
+                #self.logger.debug("====Sending GET Request====")
+                return self.sendGetRequestToNS(url, payload, header)
+        except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendCmdToNCC: Exception:%s" %
+            #                       GetDetailExceptionInfo(e))
+            return FAILED
+
+    def sendPostRequstToNS(self, url, payload, header):
+        try:
+            res = requests.post(url, data=payload, auth=("nsroot", "nsroot"), 
headers=header)
+            return res
+        except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendPostRequstToNCC: Exception Occured: 
%s" %
+            #                       str(self.__lastError))
+            return FAILED
+
+    def sendGetRequestToNS(self, url, payload, header):
+        try:
+            res = requests.get(url, data=payload, auth=("nsroot", "nsroot"), 
headers=header)
+            return res
+        except Exception as e:
+            self.__lastError = e
+            # self.logger.exception("sendGetRequestToNCC : Exception Occured: 
%s" %
+            #                       str(self.__lastError))
+            return FAILED
+
+    def getAdminKeys(self, apiClient):
+        domains = Domain.list(apiClient, name="ROOT")
+        listuser = listUsers.listUsersCmd()
+        listuser.username = "admin"
+        listuser.domainid = domains[0].id
+        listuser.listall = True
+        listuserRes = apiClient.listUsers(listuser)
+        userId = listuserRes[0].id
+        apiKey = listuserRes[0].apikey
+        securityKey = listuserRes[0].secretkey
+        return [apiKey, securityKey]
+
+    def cleanup_ncc(self, device_gp_id, srv_pkg_uuid, srv_pkg_id, 
tnt_group_id):
+        self.removeDevicefromServicePackage(device_gp_id)
+        # Remove service package reference from Cloudplatform
+        url = "http://"+self.nccip+"/cs/cca/v1/servicepackages/"+srv_pkg_uuid
+        self.logger.debug("Sending DELETE SP uuid: %s " % url)
+        res = self.sendCmdToNCC(url, method="DELETE")
+
+
+        # Remove Service package from NCC
+        url = "http://"+self.nccip+"/admin/v1/servicepackages/"+srv_pkg_id
+        self.logger.debug("Sending DELETE SP : %s " % url)
+        res = self.sendCmdToNCC(url, method="DELETE")
+
+
+        # Remove Device group
+        url = "http://"+self.nccip+"/admin/v1/devicegroups/"+device_gp_id
+        self.logger.debug("Sending DELETE devicegroup: %s " % url)
+        res = self.sendCmdToNCC(url, method="DELETE")
+
+
+        # Remove Tenant group
+        url = "http://"+self.nccip+"/admin/v1/tenantgroups/"+tnt_group_id
+        self.logger.debug("Sending DELETE tenant group: %s " % url)
+        res = self.sendCmdToNCC(url, method="DELETE")
+        self.logger.debug("Result: %s" % res)
+        return res

-- 
To stop receiving notification emails like this one, please contact
"commits@cloudstack.apache.org" <commits@cloudstack.apache.org>.

Reply via email to