From 642987dcca77cdf1ae551d824ab44272f3406f70 Mon Sep 17 00:00:00 2001 From: boucherv Date: Wed, 21 Jun 2017 16:37:56 +0200 Subject: [cloudify_ims] Support Cloudify 4.0 - Delete all shell commands to use cloudify python lib - Cloudify Manager installation with a packaged image - SNAPS integration - Adapt test_vnf unit tests - Initiate test cloudify_ims unit tests (to be completed) JIRA: FUNCTEST-838 Change-Id: Ia4b499d4155e6af5d37d6d5cf4310a5a9693c7ce Signed-off-by: boucherv Signed-off-by: Morgan Richomme --- functest/opnfv_tests/vnf/ims/clearwater.py | 66 --- .../opnfv_tests/vnf/ims/clearwater_ims_base.py | 13 +- functest/opnfv_tests/vnf/ims/cloudify_ims.py | 602 ++++++++++++++------- functest/opnfv_tests/vnf/ims/cloudify_ims.yaml | 59 +- functest/opnfv_tests/vnf/ims/create_venv.sh | 44 -- .../opnfv_tests/vnf/ims/orchestrator_cloudify.py | 232 -------- functest/opnfv_tests/vnf/ims/requirements.pip | 1 - 7 files changed, 455 insertions(+), 562 deletions(-) delete mode 100644 functest/opnfv_tests/vnf/ims/clearwater.py delete mode 100755 functest/opnfv_tests/vnf/ims/create_venv.sh delete mode 100644 functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py delete mode 100644 functest/opnfv_tests/vnf/ims/requirements.pip (limited to 'functest/opnfv_tests/vnf') diff --git a/functest/opnfv_tests/vnf/ims/clearwater.py b/functest/opnfv_tests/vnf/ims/clearwater.py deleted file mode 100644 index 33ed352d..00000000 --- a/functest/opnfv_tests/vnf/ims/clearwater.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python -# coding: utf8 -####################################################################### -# -# Copyright (c) 2015 Orange -# valentin.boucher@orange.com -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -######################################################################## - - -class Clearwater(object): - - def __init__(self, inputs={}, orchestrator=None, logger=None): - self.config = inputs - self.orchestrator = orchestrator - self.logger = logger - self.deploy = False - - def set_orchestrator(self, orchestrator): - self.orchestrator = orchestrator - - def set_flavor_id(self, flavor_id): - self.config['flavor_id'] = flavor_id - - def set_image_id(self, image_id): - self.config['image_id'] = image_id - - def set_agent_user(self, agent_user): - self.config['agent_user'] = agent_user - - def set_external_network_name(self, external_network_name): - self.config['external_network_name'] = external_network_name - - def set_public_domain(self, public_domain): - self.config['public_domain'] = public_domain - - def deploy_vnf(self, blueprint, bp_name='clearwater', - dep_name='clearwater-opnfv'): - if self.orchestrator: - self.dep_name = dep_name - error = self.orchestrator.download_upload_and_deploy_blueprint( - blueprint, self.config, bp_name, dep_name) - if error: - return error - - self.deploy = True - - else: - if self.logger: - self.logger.error("Cloudify manager is down or not provide...") - - def undeploy_vnf(self): - if self.orchestrator: - if self.deploy: - self.deploy = False - self.orchestrator.undeploy_deployment(self.dep_name) - else: - if self.logger: - self.logger.error("Clearwater isn't already deploy...") - else: - if self.logger: - self.logger.error("Cloudify manager is down or not provide...") diff --git a/functest/opnfv_tests/vnf/ims/clearwater_ims_base.py b/functest/opnfv_tests/vnf/ims/clearwater_ims_base.py index c1a35be3..25ddca21 100644 --- a/functest/opnfv_tests/vnf/ims/clearwater_ims_base.py +++ b/functest/opnfv_tests/vnf/ims/clearwater_ims_base.py @@ -11,6 +11,7 @@ import logging import os import pkg_resources import shutil +import time import requests @@ -71,7 +72,17 @@ class ClearwaterOnBoardingBase(vnf.VnfOnBoarding): ellis_ip, params['email']) self.logger.info('Create 1st calling number on Ellis') - number_res = self.create_ellis_number(number_url, cookies) + i = 24 + while rq.status_code != 200 and i > 0: + try: + number_res = self.create_ellis_number(number_url, cookies) + break + except: + if i == 1: + raise Exception("Unable to create a number") + self.logger.warn("Unable to create a number. Retry ..") + time.sleep(25) + i = i - 1 output_dict['number'] = number_res if two_numbers: diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.py b/functest/opnfv_tests/vnf/ims/cloudify_ims.py index 7d7ce33e..2dcce408 100644 --- a/functest/opnfv_tests/vnf/ims/cloudify_ims.py +++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.py @@ -9,33 +9,48 @@ import logging import os -import sys - -import requests +import time import yaml +from scp import SCPClient + +from cloudify_rest_client import CloudifyClient +from cloudify_rest_client.executions import Execution -from functest.opnfv_tests.vnf.ims.clearwater import Clearwater import functest.opnfv_tests.vnf.ims.clearwater_ims_base as clearwater_ims_base -from functest.opnfv_tests.vnf.ims.orchestrator_cloudify import Orchestrator from functest.utils.constants import CONST -import functest.utils.functest_utils as ft_utils import functest.utils.openstack_utils as os_utils +from snaps.openstack.os_credentials import OSCreds +from snaps.openstack.create_network import NetworkSettings, SubnetSettings, \ + OpenStackNetwork +from snaps.openstack.create_security_group import SecurityGroupSettings, \ + SecurityGroupRuleSettings,\ + Direction, Protocol, \ + OpenStackSecurityGroup +from snaps.openstack.create_router import RouterSettings, OpenStackRouter +from snaps.openstack.create_instance import VmInstanceSettings, \ + FloatingIpSettings, \ + OpenStackVmInstance +from snaps.openstack.create_flavor import FlavorSettings, OpenStackFlavor +from snaps.openstack.create_image import ImageSettings, OpenStackImage +from snaps.openstack.create_keypairs import KeypairSettings, OpenStackKeypair +from snaps.openstack.create_network import PortSettings + +from functest.opnfv_tests.openstack.snaps import snaps_utils + + __author__ = "Valentin Boucher " class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase): """Clearwater vIMS deployed with Cloudify Orchestrator Case""" + __logger = logging.getLogger(__name__) + def __init__(self, **kwargs): if "case_name" not in kwargs: kwargs["case_name"] = "cloudify_ims" super(CloudifyIms, self).__init__(**kwargs) - self.logger = logging.getLogger(__name__) - self.neutron_client = '' - self.glance_client = '' - self.keystone_client = '' - self.nova_client = '' # Retrieve the configuration try: @@ -44,200 +59,285 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase): except Exception: raise Exception("VNF config file not found") + self.snaps_creds = '' + self.created_object = [] + config_file = os.path.join(self.case_dir, self.config) self.orchestrator = dict( - requirements=get_config("cloudify.requirements", config_file), - blueprint=get_config("cloudify.blueprint", config_file), - inputs=get_config("cloudify.inputs", config_file) + requirements=get_config("orchestrator.requirements", config_file), ) - self.logger.debug("Orchestrator configuration: %s", self.orchestrator) + self.details['orchestrator'] = dict( + name=get_config("orchestrator.name", config_file), + version=get_config("orchestrator.version", config_file), + status='ERROR', + result='' + ) + self.__logger.debug("Orchestrator configuration %s", self.orchestrator) self.vnf = dict( - blueprint=get_config("clearwater.blueprint", config_file), - deployment_name=get_config("clearwater.deployment_name", - config_file), - inputs=get_config("clearwater.inputs", config_file), - requirements=get_config("clearwater.requirements", config_file) + descriptor=get_config("vnf.descriptor", config_file), + inputs=get_config("vnf.inputs", config_file), + requirements=get_config("vnf.requirements", config_file) + ) + self.details['vnf'] = dict( + descriptor_version=self.vnf['descriptor']['version'], + name=get_config("vnf.name", config_file), + version=get_config("vnf.version", config_file), ) - self.logger.debug("VNF configuration: %s", self.vnf) + self.__logger.debug("VNF configuration: %s", self.vnf) + self.details['test_vnf'] = dict( + name=get_config("vnf_test_suite.name", config_file), + version=get_config("vnf_test_suite.version", config_file) + ) self.images = get_config("tenant_images", config_file) - self.logger.info("Images needed for vIMS: %s", self.images) + self.__logger.info("Images needed for vIMS: %s", self.images) - def deploy_orchestrator(self): + def prepare(self): + super(CloudifyIms, self).prepare() + + self.__logger.info("Additional pre-configuration steps") - self.logger.info("Additional pre-configuration steps") - self.neutron_client = os_utils.get_neutron_client(self.admin_creds) - self.glance_client = os_utils.get_glance_client(self.admin_creds) - self.keystone_client = os_utils.get_keystone_client(self.admin_creds) - self.nova_client = os_utils.get_nova_client(self.admin_creds) + self.snaps_creds = OSCreds( + username=self.creds['username'], + password=self.creds['password'], + auth_url=self.creds['auth_url'], + project_name=self.creds['tenant'], + identity_api_version=int(os_utils.get_keystone_client_version())) # needs some images - self.logger.info("Upload some OS images if it doesn't exist") - temp_dir = os.path.join(self.data_dir, "tmp/") + self.__logger.info("Upload some OS images if it doesn't exist") for image_name, image_url in self.images.iteritems(): - self.logger.info("image: %s, url: %s", image_name, image_url) - try: - image_id = os_utils.get_image_id(self.glance_client, - image_name) - self.logger.debug("image_id: %s", image_id) - except Exception: - self.logger.error("Unexpected error: %s", sys.exc_info()[0]) - - if image_id == '': - self.logger.info("""%s image does not exist on glance repo. - Try downloading this image - and upload on glance !""", - image_name) - image_id = os_utils.download_and_add_image_on_glance( - self.glance_client, - image_name, - image_url, - temp_dir) - # Need to extend quota - self.logger.info("Update security group quota for this tenant") - tenant_id = os_utils.get_tenant_id(self.keystone_client, - self.tenant_name) - self.logger.debug("Tenant id found %s", tenant_id) - if not os_utils.update_sg_quota(self.neutron_client, - tenant_id, 50, 100): - self.logger.error("Failed to update security group quota" - " for tenant " + self.tenant_name) - - self.logger.debug("group quota extended") - - # start the deployment of cloudify + self.__logger.info("image: %s, url: %s", image_name, image_url) + if image_url and image_name: + image_creator = OpenStackImage( + self.snaps_creds, + ImageSettings(name=image_name, + image_user='cloud', + img_format='qcow2', + url=image_url)) + image_creator.create() + # self.created_object.append(image_creator) + + def deploy_orchestrator(self): + """ + Deploy Cloudify Manager + + network, security group, fip, VM creation + """ + # network creation + + start_time = time.time() + self.__logger.info("Creating keypair ...") + kp_file = os.path.join(self.data_dir, "cloudify_ims.pem") + keypair_settings = KeypairSettings(name='cloudify_ims_kp', + private_filepath=kp_file) + keypair_creator = OpenStackKeypair(self.snaps_creds, keypair_settings) + keypair_creator.create() + self.created_object.append(keypair_creator) + + self.__logger.info("Creating full network ...") + subnet_settings = SubnetSettings(name='cloudify_ims_subnet', + cidr='10.67.79.0/24') + network_settings = NetworkSettings(name='cloudify_ims_network', + subnet_settings=[subnet_settings]) + network_creator = OpenStackNetwork(self.snaps_creds, network_settings) + network_creator.create() + self.created_object.append(network_creator) + ext_net_name = snaps_utils.get_ext_net_name(self.snaps_creds) + router_creator = OpenStackRouter( + self.snaps_creds, + RouterSettings( + name='cloudify_ims_router', + external_gateway=ext_net_name, + internal_subnets=[subnet_settings.name])) + router_creator.create() + self.created_object.append(router_creator) + + # security group creation + self.__logger.info("Creating security group for cloudify manager vm") + sg_rules = list() + sg_rules.append( + SecurityGroupRuleSettings(sec_grp_name="sg-cloudify-manager", + direction=Direction.ingress, + protocol=Protocol.tcp, port_range_min=1, + port_range_max=65535)) + sg_rules.append( + SecurityGroupRuleSettings(sec_grp_name="sg-cloudify-manager", + direction=Direction.ingress, + protocol=Protocol.udp, port_range_min=1, + port_range_max=65535)) + + securit_group_creator = OpenStackSecurityGroup( + self.snaps_creds, + SecurityGroupSettings( + name="sg-cloudify-manager", + rule_settings=sg_rules)) + + securit_group_creator.create() + self.created_object.append(securit_group_creator) + + # orchestrator VM flavor + self.__logger.info("Get or create flavor for cloudify manager vm ...") + + flavor_settings = FlavorSettings( + name=self.orchestrator['requirements']['flavor']['name'], + ram=self.orchestrator['requirements']['flavor']['ram_min'], + disk=50, + vcpus=2) + flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings) + flavor_creator.create() + self.created_object.append(flavor_creator) + image_settings = ImageSettings( + name=self.orchestrator['requirements']['os_image'], + image_user='centos', + exists=True) + + port_settings = PortSettings(name='cloudify_manager_port', + network_name=network_settings.name) + + manager_settings = VmInstanceSettings( + name='cloudify_manager', + flavor=flavor_settings.name, + port_settings=[port_settings], + security_group_names=[securit_group_creator.sec_grp_settings.name], + floating_ip_settings=[FloatingIpSettings( + name='cloudify_manager_fip', + port_name=port_settings.name, + router_name=router_creator.router_settings.name)]) + + manager_creator = OpenStackVmInstance(self.snaps_creds, + manager_settings, + image_settings, + keypair_settings) + + self.__logger.info("Creating cloudify manager VM") + manager_creator.create() + self.created_object.append(manager_creator) + public_auth_url = os_utils.get_endpoint('identity') - self.logger.debug("CFY inputs: %s", self.orchestrator['inputs']) - cfy = Orchestrator(self.data_dir, self.orchestrator['inputs']) - self.orchestrator['object'] = cfy - self.logger.debug("Orchestrator object created") + self.__logger.info("Set creds for cloudify manager") + cfy_creds = dict(keystone_username=self.tenant_name, + keystone_password=self.tenant_name, + keystone_tenant_name=self.tenant_name, + keystone_url=public_auth_url) - self.logger.debug("Tenant name: %s", self.tenant_name) + cfy_client = CloudifyClient(host=manager_creator.get_floating_ip().ip, + username='admin', + password='admin', + tenant='default_tenant') - cfy.set_credentials(username=self.tenant_name, - password=self.tenant_name, - tenant_name=self.tenant_name, - auth_url=public_auth_url) - self.logger.info("Credentials set in CFY") + self.orchestrator['object'] = cfy_client - # orchestrator VM flavor - self.logger.info("Check Flavor is available, if not create one") - self.logger.debug("Flavor details %s ", - self.orchestrator['requirements']['ram_min']) - flavor_exist, flavor_id = os_utils.get_or_create_flavor( - "m1.large", - self.orchestrator['requirements']['ram_min'], - '50', - '2', - public=True) - self.logger.debug("Flavor id: %s", flavor_id) - - if not flavor_id: - self.logger.info("Available flavors are: ") - self.logger.info(self.nova_client.flavor.list()) - - cfy.set_flavor_id(flavor_id) - self.logger.debug("Flavor OK") - - # orchestrator VM image - self.logger.debug("Orchestrator image") - if 'os_image' in self.orchestrator['requirements'].keys(): - image_id = os_utils.get_image_id( - self.glance_client, - self.orchestrator['requirements']['os_image']) - self.logger.debug("Orchestrator image id: %s", image_id) - if image_id == '': - self.logger.error("CFY image not found") - - cfy.set_image_id(image_id) - self.logger.debug("Orchestrator image set") - - self.logger.debug("Get External network") - ext_net = os_utils.get_external_net(self.neutron_client) - self.logger.debug("External network: %s", ext_net) - - cfy.set_external_network_name(ext_net) - self.logger.debug("CFY External network set") - - self.logger.debug("get resolvconf") - ns = ft_utils.get_resolvconf_ns() - if ns: - cfy.set_nameservers(ns) - self.logger.debug("Resolvconf set") - - self.logger.info("Prepare virtualenv for cloudify-cli") - venv_scrit_dir = os.path.join(self.case_dir, "create_venv.sh") - cmd = "bash {} {}".format(venv_scrit_dir, self.data_dir) - ft_utils.execute_command(cmd) - - cfy.download_manager_blueprint( - self.orchestrator['blueprint']['url'], - self.orchestrator['blueprint']['branch']) - - error = cfy.deploy_manager() - if error: - self.logger.error(error) - return {'status': 'FAIL', 'result': error} + self.__logger.info("Attemps running status of the Manager") + cfy_status = None + retry = 10 + while str(cfy_status) != 'running' and retry: + try: + cfy_status = cfy_client.manager.get_status()['status'] + except Exception: # pylint: disable=broad-except + self.__logger.warning("Cloudify Manager isn't " + + "up and running. Retrying ...") + retry = retry - 1 + time.sleep(30) + + if str(cfy_status) == 'running': + self.__logger.info("Cloudify Manager is up and running") else: - return {'status': 'PASS', 'result': ''} + raise Exception("Cloudify Manager isn't up and running") + + self.__logger.info("Put OpenStack creds in manager") + secrets_list = cfy_client.secrets.list() + for k, val in cfy_creds.iteritems(): + if not any(d.get('key', None) == k for d in secrets_list): + cfy_client.secrets.create(k, val) + else: + cfy_client.secrets.update(k, val) + + duration = time.time() - start_time + + self.__logger.info("Put private keypair in manager") + if manager_creator.vm_ssh_active(block=True): + ssh = manager_creator.ssh_client() + scp = SCPClient(ssh.get_transport()) + scp.put(kp_file, '~/') + cmd = "sudo cp ~/cloudify_ims.pem /etc/cloudify/" + ssh.exec_command(cmd) + cmd = "sudo chmod 444 /etc/cloudify/cloudify_ims.pem" + ssh.exec_command(cmd) + cmd = "sudo yum install -y gcc python-devel" + ssh.exec_command(cmd) + + self.details['orchestrator'].update(status='PASS', duration=duration) + + self.vnf['inputs'].update(dict( + external_network_name=ext_net_name, + network_name=network_settings.name + )) + return True def deploy_vnf(self): - cw = Clearwater(self.vnf['inputs'], self.orchestrator['object'], - self.logger) - self.vnf['object'] = cw - - self.logger.info("Collect flavor id for all clearwater vm") - flavor_exist, flavor_id = os_utils.get_or_create_flavor( - "m1.small", - self.vnf['requirements']['ram_min'], + """ + Deploy Clearwater IMS + """ + start_time = time.time() + + self.__logger.info("Upload VNFD") + cfy_client = self.orchestrator['object'] + descriptor = self.vnf['descriptor'] + cfy_client.blueprints.publish_archive(descriptor.get('url'), + descriptor.get('name'), + descriptor.get('file_name')) + + self.__logger.info("Get or create flavor for all clearwater vm") + self.exist_obj['flavor2'], flavor_id = os_utils.get_or_create_flavor( + self.vnf['requirements']['flavor']['name'], + self.vnf['requirements']['flavor']['ram_min'], '30', '1', public=True) - self.logger.debug("Flavor id: %s", flavor_id) - if not flavor_id: - self.logger.info("Available flavors are: ") - self.logger.info(self.nova_client.flavor.list()) - - cw.set_flavor_id(flavor_id) - - # VMs image - if 'os_image' in self.vnf['requirements'].keys(): - image_id = os_utils.get_image_id( - self.glance_client, self.vnf['requirements']['os_image']) - - cw.set_image_id(image_id) - ext_net = os_utils.get_external_net(self.neutron_client) - cw.set_external_network_name(ext_net) - - error = cw.deploy_vnf(self.vnf['blueprint']) - if error: - self.logger.error(error) - return {'status': 'FAIL', 'result': error} + + self.vnf['inputs'].update(dict( + flavor_id=flavor_id, + )) + + self.__logger.info("Create VNF Instance") + cfy_client.deployments.create(descriptor.get('name'), + descriptor.get('name'), + self.vnf.get('inputs')) + + wait_for_execution(cfy_client, + _get_deployment_environment_creation_execution( + cfy_client, descriptor.get('name')), + self.__logger, + timeout=600) + + self.__logger.info("Start the VNF Instance deployment") + execution = cfy_client.executions.start(descriptor.get('name'), + 'install') + # Show execution log + execution = wait_for_execution(cfy_client, execution, self.__logger) + + duration = time.time() - start_time + + self.__logger.info(execution) + if execution.status == 'terminated': + self.details['vnf'].update(status='PASS', duration=duration) + return True else: - return {'status': 'PASS', 'result': ''} + self.details['vnf'].update(status='FAIL', duration=duration) + return False def test_vnf(self): - script = "source {0}venv_cloudify/bin/activate; " - script += "cd {0}; " - script += "cfy status | grep -Eo \"([0-9]{{1,3}}\.){{3}}[0-9]{{1,3}}\"" - cmd = "/bin/bash -c '" + script.format(self.data_dir) + "'" + """ + Run test on clearwater ims instance + """ + start_time = time.time() - try: - self.logger.debug("Trying to get clearwater manager IP ... ") - mgr_ip = os.popen(cmd).read() - mgr_ip = mgr_ip.splitlines()[0] - except Exception: - self.logger.exception("Unable to retrieve the IP of the " - "cloudify manager server !") - - self.logger.info('Cloudify Manager: %s', mgr_ip) - api_url = 'http://{0}/api/v2/deployments/{1}/outputs'.format( - mgr_ip, self.vnf['deployment_name']) - dep_outputs = requests.get(api_url) - self.logger.info(api_url) - outputs = dep_outputs.json()['outputs'] - self.logger.info("Deployment outputs: %s", outputs) + cfy_client = self.orchestrator['object'] + + outputs = cfy_client.deployments.outputs.get( + self.vnf['descriptor'].get('name'))['outputs'] dns_ip = outputs['dns_ip'] ellis_ip = outputs['ellis_ip'] self.config_ellis(ellis_ip) @@ -245,15 +345,52 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase): if dns_ip != "": vims_test_result = self.run_clearwater_live_test( dns_ip=dns_ip, - public_domain="") # self.inputs["public_domain"] - if vims_test_result != '': - return {'status': 'PASS', 'result': vims_test_result} - else: - return {'status': 'FAIL', 'result': ''} + public_domain=self.vnf['inputs']["public_domain"]) + duration = time.time() - start_time + short_result = sig_test_format(vims_test_result) + self.__logger.info(short_result) + self.details['test_vnf'].update(status='PASS', + result=short_result, + full_result=vims_test_result, + duration=duration) + return True + else: + return False def clean(self): - self.vnf['object'].undeploy_vnf() - self.orchestrator['object'].undeploy_manager() + try: + cfy_client = self.orchestrator['object'] + dep_name = self.vnf['descriptor'].get('name') + # kill existing execution + self.__logger.info('Deleting the current deployment') + exec_list = cfy_client.executions.list(dep_name) + for execution in exec_list: + if execution['status'] == "started": + try: + cfy_client.executions.cancel(execution['id'], + force=True) + except: + self.__logger.warn("Can't cancel the current exec") + + execution = cfy_client.executions.start( + dep_name, + 'uninstall', + parameters=dict(ignore_failure=True), + force=True) + + wait_for_execution(cfy_client, execution, self.__logger) + cfy_client.deployments.delete(self.vnf['descriptor'].get('name')) + cfy_client.blueprints.delete(self.vnf['descriptor'].get('name')) + except: + self.__logger.warn("Some issue during the undeployment ..") + self.__logger.warn("Tenant clean continue ..") + + self.__logger.info('Remove the cloudify manager OS object ..') + for creator in reversed(self.created_object): + try: + creator.clean() + except Exception as e: + self.logger.error('Unexpected error cleaning - %s', e) super(CloudifyIms, self).clean() @@ -262,15 +399,15 @@ class CloudifyIms(clearwater_ims_base.ClearwaterOnBoardingBase): # YAML UTILS # # ----------------------------------------------------------- -def get_config(parameter, file): +def get_config(parameter, file_path): """ Returns the value of a given parameter in file.yaml parameter must be given in string format with dots Example: general.openstack.image_name """ - with open(file) as f: - file_yaml = yaml.safe_load(f) - f.close() + with open(file_path) as config_file: + file_yaml = yaml.safe_load(config_file) + config_file.close() value = file_yaml for element in parameter.split("."): value = value.get(element) @@ -278,3 +415,90 @@ def get_config(parameter, file): raise ValueError("The parameter %s is not defined in" " reporting.yaml" % parameter) return value + + +def wait_for_execution(client, execution, logger, timeout=2400, ): + """ + Wait for a workflow execution on Cloudify Manager + """ + # if execution already ended - return without waiting + if execution.status in Execution.END_STATES: + return execution + + if timeout is not None: + deadline = time.time() + timeout + + # Poll for execution status and execution logs, until execution ends + # and we receive an event of type in WORKFLOW_END_TYPES + offset = 0 + batch_size = 50 + event_list = [] + execution_ended = False + while True: + event_list = client.events.list( + execution_id=execution.id, + _offset=offset, + _size=batch_size, + include_logs=False, + sort='@timestamp').items + + offset = offset + len(event_list) + for event in event_list: + logger.debug(event.get('message')) + + if timeout is not None: + if time.time() > deadline: + raise RuntimeError( + 'execution of operation {0} for deployment {1} ' + 'timed out'.format(execution.workflow_id, + execution.deployment_id)) + else: + # update the remaining timeout + timeout = deadline - time.time() + + if not execution_ended: + execution = client.executions.get(execution.id) + execution_ended = execution.status in Execution.END_STATES + + if execution_ended: + break + + time.sleep(5) + + return execution + + +def _get_deployment_environment_creation_execution(client, deployment_id): + """ + Get the execution id of a env preparation + + network, security group, fip, VM creation + """ + executions = client.executions.list(deployment_id=deployment_id) + for execution in executions: + if execution.workflow_id == 'create_deployment_environment': + return execution + raise RuntimeError('Failed to get create_deployment_environment ' + 'workflow execution.' + 'Available executions: {0}'.format(executions)) + + +def sig_test_format(sig_test): + """ + Process the signaling result to have a short result + """ + nb_passed = 0 + nb_failures = 0 + nb_skipped = 0 + for data_test in sig_test: + if data_test['result'] == "Passed": + nb_passed += 1 + elif data_test['result'] == "Failed": + nb_failures += 1 + elif data_test['result'] == "Skipped": + nb_skipped += 1 + total_sig_test_result = {} + total_sig_test_result['passed'] = nb_passed + total_sig_test_result['failures'] = nb_failures + total_sig_test_result['skipped'] = nb_skipped + return total_sig_test_result diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml b/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml index 74b9e958..f1028ce7 100644 --- a/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml +++ b/functest/opnfv_tests/vnf/ims/cloudify_ims.yaml @@ -1,39 +1,40 @@ tenant_images: ubuntu_14.04: http://cloud-images.ubuntu.com/trusty/current/trusty-server-cloudimg-amd64-disk1.img - centos_7: http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud-1510.qcow2 -cloudify: - blueprint: - url: https://github.com/boucherv-orange/cloudify-manager-blueprints.git - branch: '3.3.1-build' + cloudify_manager_4.0: http://repository.cloudifysource.org/cloudify/4.0.1/sp-release/cloudify-manager-premium-4.0.1.qcow2 +orchestrator: + name: cloudify + version: '4.0' requirements: - ram_min: 4096 - os_image: centos_7 - inputs: - keystone_username: "" - keystone_password: "" - keystone_tenant_name: "" - keystone_url: "" - manager_public_key_name: 'manager-kp' - agent_public_key_name: 'agent-kp' - image_id: "" - flavor_id: "3" - external_network_name: "" - ssh_user: centos - agents_user: ubuntu -clearwater: - blueprint: + flavor: + name: m1.medium + ram_min: 4096 + os_image: 'cloudify_manager_4.0' +vnf: + name: clearwater + version: '107' + descriptor: file_name: openstack-blueprint.yaml name: clearwater-opnfv - destination_folder: opnfv-cloudify-clearwater - url: https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater.git - branch: stable - deployment_name: clearwater-opnfv + url: https://github.com/Orange-OpenSource/opnfv-cloudify-clearwater/archive/master.zip + version: '122' requirements: - ram_min: 2048 - os_image: ubuntu_14.04 + flavor: + name: m1.medium + ram_min: 2048 inputs: - image_id: '' - flavor_id: '' + image_id: 'ubuntu_14.04' + flavor_id: 'm1.small' agent_user: ubuntu + key_pair_name: cloudify_ims_kp + private_key_path: '/etc/cloudify/cloudify_ims.pem' external_network_name: '' public_domain: clearwater.opnfv + release: repo122 + bono_cluster_size: 1 + sprout_cluster_size: 1 + vellum_cluster_size: 1 + dime_cluster_size: 1 + homer_cluster_size: 1 +vnf_test_suite: + name: clearwater-live-test + version: "1.0" diff --git a/functest/opnfv_tests/vnf/ims/create_venv.sh b/functest/opnfv_tests/vnf/ims/create_venv.sh deleted file mode 100755 index 575fd177..00000000 --- a/functest/opnfv_tests/vnf/ims/create_venv.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -e - -# Script checks that venv exists. If it doesn't it will be created -# It requires python2.7 and virtualenv packages installed -# -# Copyright (c) 2015 Orange -# valentin.boucher@orange.com -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 - -BASEDIR=`dirname $0` -VENV_PATH=$1 -VENV_NAME="venv_cloudify" -function venv_install() { - if command -v virtualenv-2.7; then - virtualenv-2.7 $1 - elif command -v virtualenv2; then - virtualenv2 $1 - elif command -v virtualenv; then - virtualenv $1 - else - echo Cannot find virtualenv command. - return 1 - fi -} - -# exit when something goes wrong during venv install -set -e -if [ ! -d "$VENV_PATH/$VENV_NAME" ]; then - venv_install $VENV_PATH/$VENV_NAME - echo "Virtualenv" + $VENV_NAME + "created." -fi - -if [ ! -f "$VENV_PATH/$VENV_NAME/updated" -o $BASEDIR/requirements.pip -nt $VENV_PATH/$VENV_NAME/updated ]; then - source $VENV_PATH/$VENV_NAME/bin/activate - pip install -r $BASEDIR/requirements.pip - touch $VENV_PATH/$VENV_NAME/updated - echo "Requirements installed." - deactivate -fi -set +e diff --git a/functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py b/functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py deleted file mode 100644 index 0cdfcb3f..00000000 --- a/functest/opnfv_tests/vnf/ims/orchestrator_cloudify.py +++ /dev/null @@ -1,232 +0,0 @@ -#!/usr/bin/env python -# coding: utf8 -####################################################################### -# -# Copyright (c) 2015 Orange -# valentin.boucher@orange.com -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -######################################################################## - -import logging -import os -import shutil -import subprocess32 as subprocess -import yaml - -from git import Repo - - -class Orchestrator(object): - - def __init__(self, testcase_dir, inputs={}): - self.testcase_dir = testcase_dir - self.blueprint_dir = testcase_dir + 'cloudify-manager-blueprint/' - self.input_file = 'inputs.yaml' - self.manager_blueprint = False - self.config = inputs - self.logger = logging.getLogger(__name__) - self.manager_up = False - - def set_credentials(self, username, password, tenant_name, auth_url): - self.config['keystone_username'] = username - self.config['keystone_password'] = password - self.config['keystone_url'] = auth_url - self.config['keystone_tenant_name'] = tenant_name - - def set_flavor_id(self, flavor_id): - self.config['flavor_id'] = flavor_id - - def set_image_id(self, image_id): - self.config['image_id'] = image_id - - def set_external_network_name(self, external_network_name): - self.config['external_network_name'] = external_network_name - - def set_ssh_user(self, ssh_user): - self.config['ssh_user'] = ssh_user - - def set_nova_url(self, nova_url): - self.config['nova_url'] = nova_url - - def set_neutron_url(self, neutron_url): - self.config['neutron_url'] = neutron_url - - def set_nameservers(self, nameservers): - if 0 < len(nameservers): - self.config['dns_subnet_1'] = nameservers[0] - - def download_manager_blueprint(self, manager_blueprint_url, - manager_blueprint_branch): - if self.manager_blueprint: - self.logger.info( - "cloudify manager server blueprint is " - "already downloaded !") - else: - self.logger.info( - "Downloading the cloudify manager server blueprint") - download_result = self._download_blueprints( - manager_blueprint_url, - manager_blueprint_branch, - self.blueprint_dir) - - if not download_result: - self.logger.error("Failed to download manager blueprint") - exit(-1) - else: - self.manager_blueprint = True - - def manager_up(self): - return self.manager_up - - def deploy_manager(self): - if self.manager_blueprint: - self.logger.info("Writing the inputs file") - with open(self.blueprint_dir + "inputs.yaml", "w") as f: - f.write(yaml.dump(self.config, default_style='"')) - f.close() - - # Ensure no ssh key file already exists - key_files = ["/.ssh/cloudify-manager-kp.pem", - "/.ssh/cloudify-agent-kp.pem"] - home = os.path.expanduser("~") - - for key_file in key_files: - if os.path.isfile(home + key_file): - os.remove(home + key_file) - - self.logger.info("Launching the cloudify-manager deployment") - script = "set -e; " - script += ("source " + self.testcase_dir + - "venv_cloudify/bin/activate; ") - script += "cd " + self.testcase_dir + "; " - script += "cfy init -r; " - script += "cd cloudify-manager-blueprint; " - script += ("cfy local create-requirements -o requirements.txt " + - "-p openstack-manager-blueprint.yaml; ") - script += "pip install -r requirements.txt; " - script += ("cfy bootstrap --install-plugins " + - "-p openstack-manager-blueprint.yaml -i inputs.yaml; ") - cmd = "/bin/bash -c '" + script + "'" - error = execute_command(cmd, self.logger) - if error: - self.logger.error("Failed to deploy cloudify-manager") - return error - - self.logger.info("Cloudify-manager server is UP !") - - self.manager_up = True - - def undeploy_manager(self): - self.logger.info("Launching the cloudify-manager undeployment") - - self.manager_up = False - - script = "source " + self.testcase_dir + "venv_cloudify/bin/activate; " - script += "cd " + self.testcase_dir + "; " - script += "cfy teardown -f --ignore-deployments; " - cmd = "/bin/bash -c '" + script + "'" - execute_command(cmd, self.logger) - - self.logger.info( - "Cloudify-manager server has been successfully removed!") - - def download_upload_and_deploy_blueprint(self, blueprint, config, - bp_name, dep_name): - self.logger.info("Downloading the {0} blueprint".format( - blueprint['file_name'])) - destination_folder = os.path.join(self.testcase_dir, - blueprint['destination_folder']) - download_result = self._download_blueprints(blueprint['url'], - blueprint['branch'], - destination_folder) - - if not download_result: - self.logger.error( - "Failed to download blueprint {0}". - format(blueprint['file_name'])) - exit(-1) - - self.logger.info("Writing the inputs file") - - with open(self.testcase_dir + blueprint['destination_folder'] + - "/inputs.yaml", "w") as f: - f.write(yaml.dump(config, default_style='"')) - f.close() - - self.logger.info("Launching the {0} deployment".format(bp_name)) - script = "source " + self.testcase_dir + "venv_cloudify/bin/activate; " - script += ("cd " + self.testcase_dir + - blueprint['destination_folder'] + "; ") - script += ("cfy blueprints upload -b " + - bp_name + " -p openstack-blueprint.yaml; ") - script += ("cfy deployments create -b " + bp_name + - " -d " + dep_name + " --inputs inputs.yaml; ") - script += ("cfy executions start -w install -d " + - dep_name + " --timeout 1800; ") - - cmd = "/bin/bash -c '" + script + "'" - error = execute_command(cmd, self.logger, 2000) - if error: - self.logger.error("Failed to deploy blueprint") - return error - self.logger.info("The deployment of {0} is ended".format(dep_name)) - - def undeploy_deployment(self, dep_name): - self.logger.info("Launching the {0} undeployment".format(dep_name)) - script = "source " + self.testcase_dir + "venv_cloudify/bin/activate; " - script += "cd " + self.testcase_dir + "; " - script += ("cfy executions start -w uninstall -d " + dep_name + - " --timeout 1800 ; ") - script += "cfy deployments delete -d " + dep_name + "; " - - cmd = "/bin/bash -c '" + script + "'" - try: - execute_command(cmd, self.logger) - except: - self.logger.error("Clearwater undeployment failed") - - def _download_blueprints(self, blueprint_url, branch, dest_path): - if os.path.exists(dest_path): - shutil.rmtree(dest_path) - try: - Repo.clone_from(blueprint_url, dest_path, branch=branch) - return True - except: - return False - - -def execute_command(cmd, logger, timeout=1800): - """ - Execute Linux command - """ - if logger: - logger.debug('Executing command : {}'.format(cmd)) - timeout_exception = False - output_file = "output.txt" - f = open(output_file, 'w+') - try: - p = subprocess.call(cmd, shell=True, stdout=f, - stderr=subprocess.STDOUT, timeout=timeout) - except subprocess.TimeoutExpired: - timeout_exception = True - if logger: - logger.error("TIMEOUT when executing command %s" % cmd) - pass - - f.close() - f = open(output_file, 'r') - result = f.read() - if result != "" and logger: - logger.debug(result) - if p == 0: - return False - else: - if logger and not timeout_exception: - logger.error("Error when executing command %s" % cmd) - f = open(output_file, 'r') - lines = f.readlines() - return lines[-5:] diff --git a/functest/opnfv_tests/vnf/ims/requirements.pip b/functest/opnfv_tests/vnf/ims/requirements.pip deleted file mode 100644 index ab26f6e0..00000000 --- a/functest/opnfv_tests/vnf/ims/requirements.pip +++ /dev/null @@ -1 +0,0 @@ -cloudify==3.3.1 \ No newline at end of file -- cgit 1.2.3-korg