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>.