class CloudifyVrouter(cloudify.Cloudify): # pylint: disable=too-many-instance-attributes """vrouter testcase deployed with Cloudify Orchestrator.""" __logger = logging.getLogger(__name__) filename_alt = '/home/opnfv/functest/images/vyos-1.1.8-amd64.qcow2' flavor_alt_ram = 1024 flavor_alt_vcpus = 1 flavor_alt_disk = 3 cop_yaml = ("https://github.com/cloudify-cosmo/cloudify-openstack-plugin/" "releases/download/2.14.7/plugin.yaml") cop_wgn = ("https://github.com/cloudify-cosmo/cloudify-openstack-plugin/" "releases/download/2.14.7/cloudify_openstack_plugin-2.14.7-py27" "-none-linux_x86_64-centos-Core.wgn") def __init__(self, **kwargs): if "case_name" not in kwargs: kwargs["case_name"] = "vyos_vrouter" super(CloudifyVrouter, self).__init__(**kwargs) # Retrieve the configuration try: self.config = getattr( config.CONF, 'vnf_{}_config'.format(self.case_name)) except Exception: raise Exception("VNF config file not found") self.case_dir = pkg_resources.resource_filename( 'functest', 'opnfv_tests/vnf/router') config_file = os.path.join(self.case_dir, self.config) self.orchestrator = dict( requirements=functest_utils.get_parameter_from_yaml( "orchestrator.requirements", config_file), ) self.details['orchestrator'] = dict( name=functest_utils.get_parameter_from_yaml( "orchestrator.name", config_file), version=functest_utils.get_parameter_from_yaml( "orchestrator.version", config_file), status='ERROR', result='' ) self.__logger.debug("Orchestrator configuration %s", self.orchestrator) self.__logger.debug("name = %s", __name__) self.vnf = dict( descriptor=functest_utils.get_parameter_from_yaml( "vnf.descriptor", config_file), inputs=functest_utils.get_parameter_from_yaml( "vnf.inputs", config_file), requirements=functest_utils.get_parameter_from_yaml( "vnf.requirements", config_file) ) self.details['vnf'] = dict( descriptor_version=self.vnf['descriptor']['version'], name=functest_utils.get_parameter_from_yaml( "vnf.name", config_file), version=functest_utils.get_parameter_from_yaml( "vnf.version", config_file), ) self.__logger.debug("VNF configuration: %s", self.vnf) self.util = Utilvnf() self.util.set_credentials(self.cloud) credentials = {"cloud": self.cloud} self.util_info = {"credentials": credentials, "vnf_data_dir": self.util.vnf_data_dir} self.details['test_vnf'] = dict( name=functest_utils.get_parameter_from_yaml( "vnf_test_suite.name", config_file), version=functest_utils.get_parameter_from_yaml( "vnf_test_suite.version", config_file) ) self.images = functest_utils.get_parameter_from_yaml( "tenant_images", config_file) self.__logger.info("Images needed for vrouter: %s", self.images) self.image_alt = None self.flavor_alt = None def execute(self): # pylint: disable=too-many-locals,too-many-statements """ Deploy Cloudify Manager. network, security group, fip, VM creation """ # network creation super(CloudifyVrouter, self).execute() start_time = time.time() self.__logger.info("Put private keypair in manager") scpc = scp.SCPClient(self.ssh.get_transport()) scpc.put(self.key_filename, remote_path='~/cloudify_ims.pem') (_, stdout, stderr) = self.ssh.exec_command( "sudo docker exec cfy_manager_local " "cfy plugins upload -y {} {} && " "sudo docker cp ~/cloudify_ims.pem " "cfy_manager_local:/etc/cloudify/ && " "sudo docker exec cfy_manager_local " "chmod 444 /etc/cloudify/cloudify_ims.pem && " "sudo docker exec cfy_manager_local cfy status".format( self.cop_yaml, self.cop_wgn)) self.__logger.info("output:\n%s", stdout.read()) self.__logger.info("error:\n%s", stderr.read()) self.image_alt = self.publish_image_alt() self.flavor_alt = self.create_flavor_alt() duration = time.time() - start_time self.details['orchestrator'].update(status='PASS', duration=duration) self.vnf['inputs'].update(dict( external_network_name=self.ext_net.name)) self.vnf['inputs'].update(dict( target_vnf_image_id=self.image_alt.id)) self.vnf['inputs'].update(dict( reference_vnf_image_id=self.image_alt.id)) self.vnf['inputs'].update(dict( target_vnf_flavor_id=self.flavor_alt.id)) self.vnf['inputs'].update(dict( reference_vnf_flavor_id=self.flavor_alt.id)) self.vnf['inputs'].update(dict( keystone_username=self.project.user.name)) self.vnf['inputs'].update(dict( keystone_password=self.project.password)) self.vnf['inputs'].update(dict( keystone_tenant_name=self.project.project.name)) self.vnf['inputs'].update(dict( keystone_user_domain_name=os.environ.get( 'OS_USER_DOMAIN_NAME', 'Default'))) self.vnf['inputs'].update(dict( keystone_project_domain_name=os.environ.get( 'OS_PROJECT_DOMAIN_NAME', 'Default'))) self.vnf['inputs'].update(dict( region=os.environ.get('OS_REGION_NAME', 'RegionOne'))) self.vnf['inputs'].update(dict( keystone_url=self.get_public_auth_url(self.orig_cloud))) if self.deploy_vnf() and self.test_vnf(): self.result = 100 return 0 self.result = 1/3 * 100 return 1 def deploy_vnf(self): start_time = time.time() self.__logger.info("Upload VNFD") descriptor = self.vnf['descriptor'] self.util_info["cfy"] = self.cfy_client self.util_info["cfy_manager_ip"] = self.fip.floating_ip_address self.util_info["deployment_name"] = descriptor.get('name') self.cfy_client.blueprints.upload( descriptor.get('file_name'), descriptor.get('name')) self.__logger.info("Create VNF Instance") self.cfy_client.deployments.create( descriptor.get('name'), descriptor.get('name'), self.vnf.get('inputs')) cloudify.wait_for_execution( self.cfy_client, cloudify.get_execution_id( self.cfy_client, descriptor.get('name')), self.__logger, timeout=7200) self.__logger.info("Start the VNF Instance deployment") execution = self.cfy_client.executions.start( descriptor.get('name'), 'install') # Show execution log execution = cloudify.wait_for_execution( self.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) result = True else: self.details['vnf'].update(status='FAIL', duration=duration) result = False return result def test_vnf(self): start_time = time.time() testing = vrouter_base.VrouterOnBoardingBase(self.util, self.util_info) result, test_result_data = testing.test_vnf() duration = time.time() - start_time if result: self.details['test_vnf'].update( status='PASS', result='OK', full_result=test_result_data, duration=duration) else: self.details['test_vnf'].update( status='FAIL', result='NG', full_result=test_result_data, duration=duration) return True def clean(self): try: dep_name = self.vnf['descriptor'].get('name') # kill existing execution self.__logger.info('Deleting the current deployment') exec_list = self.cfy_client.executions.list() for execution in exec_list: if execution['status'] == "started": try: self.cfy_client.executions.cancel( execution['id'], force=True) except Exception: # pylint: disable=broad-except self.__logger.warn("Can't cancel the current exec") execution = self.cfy_client.executions.start( dep_name, 'uninstall', parameters=dict(ignore_failure=True)) cloudify.wait_for_execution( self.cfy_client, execution, self.__logger) self.cfy_client.deployments.delete( self.vnf['descriptor'].get('name')) time.sleep(10) self.cfy_client.blueprints.delete( self.vnf['descriptor'].get('name')) except Exception: # pylint: disable=broad-except self.__logger.exception("Some issue during the undeployment ..") if self.image_alt: self.cloud.delete_image(self.image_alt) if self.flavor_alt: self.orig_cloud.delete_flavor(self.flavor_alt.id) super(CloudifyVrouter, self).clean()
class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase): """vrouter testcase deployed with Cloudify Orchestrator.""" __logger = logging.getLogger(__name__) name = __name__ def __init__(self, **kwargs): if "case_name" not in kwargs: kwargs["case_name"] = "vyos_vrouter" super(CloudifyVrouter, self).__init__(**kwargs) # Retrieve the configuration try: self.config = CONST.__getattribute__('vnf_{}_config'.format( self.case_name)) except Exception: raise Exception("VNF config file not found") self.snaps_creds = '' self.created_object = [] self.cfy_manager_ip = '' self.util_info = {} self.deployment_name = '' config_file = os.path.join(self.case_dir, self.config) self.orchestrator = dict(requirements=get_config( "orchestrator.requirements", config_file), ) 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.__logger.debug("name = %s", self.name) self.vnf = dict(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.util = Utilvnf() 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 vrouter: %s", self.images) def prepare(self): super(CloudifyVrouter, self).prepare() self.__logger.info("Additional pre-configuration steps") 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())) self.util.set_credentials(self.creds["username"], self.creds["password"], self.creds["auth_url"], self.creds["tenant"]) # needs some images self.__logger.info("Upload some OS images if it doesn't exist") for image_name, image_file in self.images.iteritems(): self.__logger.info("image: %s, file: %s", image_name, image_file) if image_file and image_name: image_creator = OpenStackImage( self.snaps_creds, ImageSettings(name=image_name, image_user='******', img_format='qcow2', image_file=image_file)) 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_vrouter.pem") keypair_settings = KeypairSettings(name='cloudify_vrouter_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_vrouter_subnet', cidr='10.67.79.0/24') network_settings = NetworkSettings(name='cloudify_vrouter_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_vrouter_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)) security_group_creator = OpenStackSecurityGroup( self.snaps_creds, SecurityGroupSettings(name="sg-cloudify-manager", rule_settings=sg_rules)) security_group_creator.create() self.created_object.append(security_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='******', 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=[ security_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.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) cfy_client = CloudifyClient(host=manager_creator.get_floating_ip().ip, username='******', password='******', tenant='default_tenant') self.orchestrator['object'] = cfy_client self.cfy_manager_ip = manager_creator.get_floating_ip().ip 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'] self.__logger.debug("The current manager status is %s", cfy_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: 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(), socket_timeout=15.0) scp.put(kp_file, '~/') cmd = "sudo cp ~/cloudify_vrouter.pem /etc/cloudify/" run_blocking_ssh_command(ssh, cmd) cmd = "sudo chmod 444 /etc/cloudify/cloudify_vrouter.pem" run_blocking_ssh_command(ssh, cmd) cmd = "sudo yum install -y gcc python-devel" run_blocking_ssh_command(ssh, cmd, "Unable to install packages on manager") self.details['orchestrator'].update(status='PASS', duration=duration) self.vnf['inputs'].update(dict(external_network_name=ext_net_name)) return True def deploy_vnf(self): start_time = time.time() self.__logger.info("Upload VNFD") cfy_client = self.orchestrator['object'] descriptor = self.vnf['descriptor'] self.deployment_name = descriptor.get('name') vrouter_blueprint_dir = os.path.join(self.data_dir, self.util.blueprint_dir) if not os.path.exists(vrouter_blueprint_dir): Repo.clone_from(descriptor.get('url'), vrouter_blueprint_dir, branch=descriptor.get('version')) cfy_client.blueprints.upload( vrouter_blueprint_dir + self.util.blueprint_file_name, descriptor.get('name')) self.__logger.info("Get or create flavor for vrouter") flavor_settings = FlavorSettings( name=self.vnf['requirements']['flavor']['name'], ram=self.vnf['requirements']['flavor']['ram_min'], disk=25, vcpus=1) flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings) flavor = flavor_creator.create() self.created_object.append(flavor_creator) # set image name glance = glance_utils.glance_client(self.snaps_creds) image = glance_utils.get_image(glance, "vyos1.1.7") self.vnf['inputs'].update(dict(target_vnf_image_id=image.id)) self.vnf['inputs'].update(dict(reference_vnf_image_id=image.id)) # set flavor id self.vnf['inputs'].update(dict(target_vnf_flavor_id=flavor.id)) self.vnf['inputs'].update(dict(reference_vnf_flavor_id=flavor.id)) self.vnf['inputs'].update(dict(keystone_username=self.tenant_name)) self.vnf['inputs'].update(dict(keystone_password=self.tenant_name)) self.vnf['inputs'].update(dict(keystone_tenant_name=self.tenant_name)) self.vnf['inputs'].update( dict(keystone_url=os_utils.get_endpoint('identity'))) 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_execution_id(cfy_client, descriptor.get('name')), self.__logger, timeout=7200) 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) result = True else: self.details['vnf'].update(status='FAIL', duration=duration) result = False return result def test_vnf(self): cfy_client = self.orchestrator['object'] credentials = { "username": self.creds["username"], "password": self.creds["password"], "auth_url": self.creds["auth_url"], "tenant_name": self.creds["tenant"], "region_name": os.environ['OS_REGION_NAME'] } self.util_info = { "credentials": credentials, "cfy": cfy_client, "vnf_data_dir": self.util.vnf_data_dir } start_time = time.time() result, test_result_data = super(CloudifyVrouter, self).test_vnf() duration = time.time() - start_time if result: self.details['test_vnf'].update(status='PASS', result='OK', full_result=test_result_data, duration=duration) else: self.details['test_vnf'].update(status='FAIL', result='NG', full_result=test_result_data, duration=duration) return True def clean(self): 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: # pylint: disable=broad-except self.__logger.warn("Can't cancel the current exec") execution = cfy_client.executions.start( dep_name, 'uninstall', parameters=dict(ignore_failure=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: # pylint: disable=broad-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 exc: self.logger.error('Unexpected error cleaning - %s', exc) super(CloudifyVrouter, self).clean() def run(self, **kwargs): """Execute CloudifyVrouter test case.""" return super(CloudifyVrouter, self).run(**kwargs) def get_vnf_info_list(self, target_vnf_name): return self.util.get_vnf_info_list(self.cfy_manager_ip, self.deployment_name, target_vnf_name)
class VmController(object): """vm controll class""" logger = logging.getLogger(__name__) def __init__(self, util_info): self.logger.debug("initialize vm controller") self.command_gen = CommandGenerator() credentials = util_info["credentials"] self.util = Utilvnf() self.util.set_credentials(credentials["snaps_creds"]) with open(self.util.test_env_config_yaml) as file_fd: test_env_config_yaml = yaml.safe_load(file_fd) file_fd.close() self.reboot_wait = test_env_config_yaml.get("general").get( "reboot_wait") self.command_wait = test_env_config_yaml.get("general").get( "command_wait") self.ssh_connect_timeout = test_env_config_yaml.get("general").get( "ssh_connect_timeout") self.ssh_connect_retry_count = test_env_config_yaml.get("general").get( "ssh_connect_retry_count") def command_gen_from_template(self, command_file_path, cmd_input_param): (command_file_dir, command_file_name) = os.path.split( command_file_path) template = self.command_gen.load_template(command_file_dir, command_file_name) return self.command_gen.command_create(template, cmd_input_param) def config_vm(self, vm_info, test_cmd_file_path, cmd_input_param, prompt_file_path): ssh = self.connect_ssh_and_config_vm(vm_info, test_cmd_file_path, cmd_input_param, prompt_file_path) if ssh is None: return False ssh.close() return True def connect_ssh_and_config_vm(self, vm_info, test_cmd_file_path, cmd_input_param, prompt_file_path): key_filename = None if "key_path" in vm_info: key_filename = vm_info["key_path"] ssh = SshClient(ip_address=vm_info["floating_ip"], user=vm_info["user"], password=vm_info["pass"], key_filename=key_filename) result = ssh.connect(self.ssh_connect_timeout, self.ssh_connect_retry_count) if not result: self.logger.debug("try to vm reboot.") self.util.reboot_vm(vm_info["vnf_name"]) time.sleep(self.reboot_wait) result = ssh.connect(self.ssh_connect_timeout, self.ssh_connect_retry_count) if not result: return None (result, _) = self.command_create_and_execute( ssh, test_cmd_file_path, cmd_input_param, prompt_file_path) if not result: ssh.close() return None return ssh def command_create_and_execute(self, ssh, test_cmd_file_path, cmd_input_param, prompt_file_path): prompt_file = open(prompt_file_path, 'r') prompt = yaml.safe_load(prompt_file) prompt_file.close() config_mode_prompt = prompt["config_mode"] commands = self.command_gen_from_template(test_cmd_file_path, cmd_input_param) return self.command_list_execute(ssh, commands, config_mode_prompt) def command_list_execute(self, ssh, command_list, prompt): res_data_list = [] for command in command_list: self.logger.debug("Command : " + command) (res, res_data) = self.command_execute(ssh, command, prompt) self.logger.debug("Response : " + res_data) res_data_list.append(res_data) if not res: return res, res_data_list time.sleep(self.command_wait) return True, res_data_list def command_execute(self, ssh, command, prompt): res_data = ssh.send(command, prompt) if res_data is None: self.logger.info("retry send command : " + command) res_data = ssh.send(command, prompt) if not ssh.error_check(res_data): return False, res_data return True, res_data
class FunctionTestExec(object): """vrouter function test execution class""" logger = logging.getLogger(__name__) def __init__(self, util_info): self.logger.debug("init test exec") self.util = Utilvnf() credentials = util_info["credentials"] self.vnf_ctrl = VnfController(util_info) test_cmd_map_file = open(self.util.vnf_data_dir + self.util.opnfv_vnf_data_dir + self.util.command_template_dir + self.util.test_cmd_map_yaml_file, 'r') self.test_cmd_map_yaml = yaml.safe_load(test_cmd_map_file) test_cmd_map_file.close() self.util.set_credentials(credentials["snaps_creds"]) with open(self.util.test_env_config_yaml) as file_fd: test_env_config_yaml = yaml.safe_load(file_fd) file_fd.close() self.protocol_stable_wait = test_env_config_yaml.get("general").get( "protocol_stable_wait") def config_target_vnf(self, target_vnf, reference_vnf, test_kind): self.logger.debug("Configuration to target vnf") test_info = self.test_cmd_map_yaml[target_vnf["os_type"]] test_cmd_file_path = test_info[test_kind]["pre_command_target"] target_parameter_file_path = test_info[test_kind]["parameter_target"] prompt_file_path = test_info["prompt"] return self.vnf_ctrl.config_vnf(target_vnf, reference_vnf, test_cmd_file_path, target_parameter_file_path, prompt_file_path) def config_reference_vnf(self, target_vnf, reference_vnf, test_kind): self.logger.debug("Configuration to reference vnf") test_info = self.test_cmd_map_yaml[reference_vnf["os_type"]] test_cmd_file_path = test_info[test_kind]["pre_command_reference"] reference_parameter_file_path = test_info[test_kind][ "parameter_reference"] prompt_file_path = test_info["prompt"] return self.vnf_ctrl.config_vnf(reference_vnf, target_vnf, test_cmd_file_path, reference_parameter_file_path, prompt_file_path) def result_check(self, target_vnf, reference_vnf, test_kind, test_list): test_info = self.test_cmd_map_yaml[target_vnf["os_type"]] target_parameter_file_path = test_info[test_kind]["parameter_target"] prompt_file_path = test_info["prompt"] check_rule_file_path_list = [] for test in test_list: check_rule_file_path_list.append(test_info[test_kind][test]) return self.vnf_ctrl.result_check(target_vnf, reference_vnf, check_rule_file_path_list, target_parameter_file_path, prompt_file_path) def run(self, target_vnf, reference_vnf_list, test_info, test_list): test_result_data = {} test_kind = test_info["protocol"] for reference_vnf in reference_vnf_list: self.logger.debug("Start config command " + target_vnf["vnf_name"] + " and " + reference_vnf["vnf_name"]) result = self.config_target_vnf(target_vnf, reference_vnf, test_kind) if not result: return False, test_result_data result = self.config_reference_vnf(target_vnf, reference_vnf, test_kind) if not result: return False, test_result_data self.logger.debug("Finish config command.") self.logger.debug("Waiting for protocol stable.") time.sleep(self.protocol_stable_wait) self.logger.debug("Start check method") (result, res_dict_data_list) = self.result_check(target_vnf, reference_vnf, test_kind, test_list) test_result_data = {"test_kind": test_info["test_kind"], "protocol": test_info["protocol"], "result": res_dict_data_list} if not result: self.logger.debug("Error check method.") return False, test_result_data self.logger.debug("Finish check method.") return True, test_result_data
class CloudifyVrouter(vrouter_base.VrouterOnBoardingBase): # pylint: disable=too-many-instance-attributes """vrouter testcase deployed with Cloudify Orchestrator.""" __logger = logging.getLogger(__name__) name = __name__ def __init__(self, **kwargs): if "case_name" not in kwargs: kwargs["case_name"] = "vyos_vrouter" super(CloudifyVrouter, self).__init__(**kwargs) # Retrieve the configuration try: self.config = getattr(config.CONF, 'vnf_{}_config'.format(self.case_name)) except Exception: raise Exception("VNF config file not found") self.cfy_manager_ip = '' self.deployment_name = '' config_file = os.path.join(self.case_dir, self.config) self.orchestrator = dict( requirements=functest_utils.get_parameter_from_yaml( "orchestrator.requirements", config_file), ) self.details['orchestrator'] = dict( name=functest_utils.get_parameter_from_yaml( "orchestrator.name", config_file), version=functest_utils.get_parameter_from_yaml( "orchestrator.version", config_file), status='ERROR', result='') self.__logger.debug("Orchestrator configuration %s", self.orchestrator) self.__logger.debug("name = %s", self.name) self.vnf = dict(descriptor=functest_utils.get_parameter_from_yaml( "vnf.descriptor", config_file), inputs=functest_utils.get_parameter_from_yaml( "vnf.inputs", config_file), requirements=functest_utils.get_parameter_from_yaml( "vnf.requirements", config_file)) self.details['vnf'] = dict( descriptor_version=self.vnf['descriptor']['version'], name=functest_utils.get_parameter_from_yaml( "vnf.name", config_file), version=functest_utils.get_parameter_from_yaml( "vnf.version", config_file), ) self.__logger.debug("VNF configuration: %s", self.vnf) self.util = Utilvnf() self.details['test_vnf'] = dict( name=functest_utils.get_parameter_from_yaml( "vnf_test_suite.name", config_file), version=functest_utils.get_parameter_from_yaml( "vnf_test_suite.version", config_file)) self.images = functest_utils.get_parameter_from_yaml( "tenant_images", config_file) self.__logger.info("Images needed for vrouter: %s", self.images) @staticmethod def run_blocking_ssh_command(ssh, cmd, error_msg="Unable to run this command"): """Command to run ssh command with the exit status.""" (_, stdout, stderr) = ssh.exec_command(cmd) CloudifyVrouter.__logger.debug("SSH %s stdout: %s", cmd, stdout.read()) if stdout.channel.recv_exit_status() != 0: CloudifyVrouter.__logger.error("SSH %s stderr: %s", cmd, stderr.read()) raise Exception(error_msg) def prepare(self): super(CloudifyVrouter, self).prepare() self.__logger.info("Additional pre-configuration steps") self.util.set_credentials(self.snaps_creds) self.__logger.info("Upload some OS images if it doesn't exist") for image_name, image_file in self.images.iteritems(): self.__logger.info("image: %s, file: %s", image_name, image_file) if image_file and image_name: image_creator = OpenStackImage( self.snaps_creds, ImageConfig(name=image_name, image_user='******', img_format='qcow2', image_file=image_file)) image_creator.create() self.created_object.append(image_creator) def deploy_orchestrator(self): # pylint: disable=too-many-locals,too-many-statements """ 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_vrouter.pem") keypair_settings = KeypairConfig(name='cloudify_vrouter_kp-{}'.format( self.uuid), 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 = SubnetConfig( name='cloudify_vrouter_subnet-{}'.format(self.uuid), cidr='10.67.79.0/24', dns_nameservers=[env.get('NAMESERVER')]) network_settings = NetworkConfig( name='cloudify_vrouter_network-{}'.format(self.uuid), 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, RouterConfig(name='cloudify_vrouter_router-{}'.format(self.uuid), 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( SecurityGroupRuleConfig( sec_grp_name="sg-cloudify-manager-{}".format(self.uuid), direction=Direction.ingress, protocol=Protocol.tcp, port_range_min=1, port_range_max=65535)) sg_rules.append( SecurityGroupRuleConfig( sec_grp_name="sg-cloudify-manager-{}".format(self.uuid), direction=Direction.ingress, protocol=Protocol.udp, port_range_min=1, port_range_max=65535)) security_group_creator = OpenStackSecurityGroup( self.snaps_creds, SecurityGroupConfig(name="sg-cloudify-manager-{}".format( self.uuid), rule_settings=sg_rules)) security_group_creator.create() self.created_object.append(security_group_creator) # orchestrator VM flavor self.__logger.info("Get or create flavor for cloudify manager vm ...") flavor_settings = FlavorConfig( 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 = ImageConfig( name=self.orchestrator['requirements']['os_image'], image_user='******', exists=True) port_settings = PortConfig(name='cloudify_manager_port-{}'.format( self.uuid), network_name=network_settings.name) manager_settings = VmInstanceConfig( name='cloudify_manager-{}'.format(self.uuid), flavor=flavor_settings.name, port_settings=[port_settings], security_group_names=[ security_group_creator.sec_grp_settings.name ], floating_ip_settings=[ FloatingIpConfig( name='cloudify_manager_fip-{}'.format(self.uuid), 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) cfy_client = CloudifyClient(host=manager_creator.get_floating_ip().ip, username='******', password='******', tenant='default_tenant') self.orchestrator['object'] = cfy_client self.cfy_manager_ip = manager_creator.get_floating_ip().ip 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'] self.__logger.info("The current manager status is %s", cfy_status) except Exception: # pylint: disable=broad-except self.__logger.info( "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: raise Exception("Cloudify Manager isn't up and running") 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(), socket_timeout=15.0) scp.put(kp_file, '~/') cmd = "sudo cp ~/cloudify_vrouter.pem /etc/cloudify/" self.run_blocking_ssh_command(ssh, cmd) cmd = "sudo chmod 444 /etc/cloudify/cloudify_vrouter.pem" self.run_blocking_ssh_command(ssh, cmd) cmd = "sudo yum install -y gcc python-devel" self.run_blocking_ssh_command( ssh, cmd, "Unable to install packages on manager") self.details['orchestrator'].update(status='PASS', duration=duration) self.vnf['inputs'].update(dict(external_network_name=ext_net_name)) return True def deploy_vnf(self): start_time = time.time() self.__logger.info("Upload VNFD") cfy_client = self.orchestrator['object'] descriptor = self.vnf['descriptor'] self.deployment_name = descriptor.get('name') cfy_client.blueprints.upload(descriptor.get('file_name'), descriptor.get('name')) self.__logger.info("Get or create flavor for vrouter") flavor_settings = FlavorConfig( name=self.vnf['requirements']['flavor']['name'], ram=self.vnf['requirements']['flavor']['ram_min'], disk=25, vcpus=1) flavor_creator = OpenStackFlavor(self.snaps_creds, flavor_settings) flavor = flavor_creator.create() self.created_object.append(flavor_creator) # set image name glance = glance_utils.glance_client(self.snaps_creds) image = glance_utils.get_image(glance, "vyos1.1.7") user_creator = OpenStackUser( self.snaps_creds, UserConfig(name='cloudify_network_bug-{}'.format(self.uuid), password=str(uuid.uuid4()), project_name=self.tenant_name, domain=self.snaps_creds.user_domain_name, roles={'_member_': self.tenant_name})) user_creator.create() self.created_object.append(user_creator) snaps_creds = user_creator.get_os_creds(self.snaps_creds.project_name) self.__logger.debug("snaps creds: %s", snaps_creds) self.vnf['inputs'].update(dict(target_vnf_image_id=image.id)) self.vnf['inputs'].update(dict(reference_vnf_image_id=image.id)) self.vnf['inputs'].update(dict(target_vnf_flavor_id=flavor.id)) self.vnf['inputs'].update(dict(reference_vnf_flavor_id=flavor.id)) self.vnf['inputs'].update(dict(keystone_username=snaps_creds.username)) self.vnf['inputs'].update(dict(keystone_password=snaps_creds.password)) self.vnf['inputs'].update( dict(keystone_tenant_name=snaps_creds.project_name)) self.vnf['inputs'].update( dict(keystone_user_domain_name=snaps_creds.user_domain_name)) self.vnf['inputs'].update( dict(keystone_project_domain_name=snaps_creds.project_domain_name)) self.vnf['inputs'].update(dict(region=snaps_creds.region_name)) self.vnf['inputs'].update( dict(keystone_url=keystone_utils.get_endpoint( snaps_creds, 'identity'))) 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_execution_id(cfy_client, descriptor.get('name')), self.__logger, timeout=7200) 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) result = True else: self.details['vnf'].update(status='FAIL', duration=duration) result = False return result def test_vnf(self): cfy_client = self.orchestrator['object'] credentials = {"snaps_creds": self.snaps_creds} self.util_info = { "credentials": credentials, "cfy": cfy_client, "vnf_data_dir": self.util.vnf_data_dir } start_time = time.time() result, test_result_data = super(CloudifyVrouter, self).test_vnf() duration = time.time() - start_time if result: self.details['test_vnf'].update(status='PASS', result='OK', full_result=test_result_data, duration=duration) else: self.details['test_vnf'].update(status='FAIL', result='NG', full_result=test_result_data, duration=duration) return True def clean(self): 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 Exception: # pylint: disable=broad-except self.__logger.warn("Can't cancel the current exec") execution = cfy_client.executions.start( dep_name, 'uninstall', parameters=dict(ignore_failure=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 Exception: # pylint: disable=broad-except self.__logger.exception("Some issue during the undeployment ..") super(CloudifyVrouter, self).clean() def get_vnf_info_list(self, target_vnf_name): return self.util.get_vnf_info_list(self.cfy_manager_ip, self.deployment_name, target_vnf_name)
class CloudifyVrouter(cloudify.Cloudify): # pylint: disable=too-many-instance-attributes """vrouter testcase deployed with Cloudify Orchestrator.""" __logger = logging.getLogger(__name__) filename_alt = '/home/opnfv/functest/images/vyos-1.1.8-amd64.qcow2' flavor_alt_ram = 1024 flavor_alt_vcpus = 1 flavor_alt_disk = 3 check_console_loop = 12 cop_yaml = ("https://github.com/cloudify-cosmo/cloudify-openstack-plugin/" "releases/download/2.14.7/plugin.yaml") cop_wgn = ("https://github.com/cloudify-cosmo/cloudify-openstack-plugin/" "releases/download/2.14.7/cloudify_openstack_plugin-2.14.7-py27" "-none-linux_x86_64-centos-Core.wgn") def __init__(self, **kwargs): if "case_name" not in kwargs: kwargs["case_name"] = "vyos_vrouter" super(CloudifyVrouter, self).__init__(**kwargs) # Retrieve the configuration try: self.config = getattr( config.CONF, 'vnf_{}_config'.format(self.case_name)) except Exception: raise Exception("VNF config file not found") self.case_dir = pkg_resources.resource_filename( 'functest', 'opnfv_tests/vnf/router') config_file = os.path.join(self.case_dir, self.config) self.orchestrator = dict( requirements=functest_utils.get_parameter_from_yaml( "orchestrator.requirements", config_file), ) self.details['orchestrator'] = dict( name=functest_utils.get_parameter_from_yaml( "orchestrator.name", config_file), version=functest_utils.get_parameter_from_yaml( "orchestrator.version", config_file), status='ERROR', result='' ) self.__logger.debug("Orchestrator configuration %s", self.orchestrator) self.__logger.debug("name = %s", __name__) self.vnf = dict( descriptor=functest_utils.get_parameter_from_yaml( "vnf.descriptor", config_file), inputs=functest_utils.get_parameter_from_yaml( "vnf.inputs", config_file), requirements=functest_utils.get_parameter_from_yaml( "vnf.requirements", config_file) ) self.details['vnf'] = dict( descriptor_version=self.vnf['descriptor']['version'], name=functest_utils.get_parameter_from_yaml( "vnf.name", config_file), version=functest_utils.get_parameter_from_yaml( "vnf.version", config_file), ) self.__logger.debug("VNF configuration: %s", self.vnf) self.util = Utilvnf() self.util.set_credentials(self.cloud) credentials = {"cloud": self.cloud} self.util_info = {"credentials": credentials, "vnf_data_dir": self.util.vnf_data_dir} self.details['test_vnf'] = dict( name=functest_utils.get_parameter_from_yaml( "vnf_test_suite.name", config_file), version=functest_utils.get_parameter_from_yaml( "vnf_test_suite.version", config_file) ) self.images = functest_utils.get_parameter_from_yaml( "tenant_images", config_file) self.__logger.info("Images needed for vrouter: %s", self.images) self.image_alt = None self.flavor_alt = None def check_requirements(self): if env.get('NEW_USER_ROLE').lower() == "admin": self.__logger.warning( "Defining NEW_USER_ROLE=admin will easily break the testcase " "because Cloudify doesn't manage tenancy (e.g. subnet " "overlapping)") def execute(self): # pylint: disable=too-many-locals,too-many-statements """ Deploy Cloudify Manager. network, security group, fip, VM creation """ # network creation super(CloudifyVrouter, self).execute() start_time = time.time() self.put_private_key() self.upload_cfy_plugins(self.cop_yaml, self.cop_wgn) self.image_alt = self.publish_image_alt() self.flavor_alt = self.create_flavor_alt() duration = time.time() - start_time self.details['orchestrator'].update(status='PASS', duration=duration) self.vnf['inputs'].update(dict( external_network_name=self.ext_net.name)) self.vnf['inputs'].update(dict( target_vnf_image_id=self.image_alt.id)) self.vnf['inputs'].update(dict( reference_vnf_image_id=self.image_alt.id)) self.vnf['inputs'].update(dict( target_vnf_flavor_id=self.flavor_alt.id)) self.vnf['inputs'].update(dict( reference_vnf_flavor_id=self.flavor_alt.id)) self.vnf['inputs'].update(dict( keystone_username=self.project.user.name)) self.vnf['inputs'].update(dict( keystone_password=self.project.password)) self.vnf['inputs'].update(dict( keystone_tenant_name=self.project.project.name)) self.vnf['inputs'].update(dict( keystone_user_domain_name=os.environ.get( 'OS_USER_DOMAIN_NAME', 'Default'))) self.vnf['inputs'].update(dict( keystone_project_domain_name=os.environ.get( 'OS_PROJECT_DOMAIN_NAME', 'Default'))) self.vnf['inputs'].update(dict( region=os.environ.get('OS_REGION_NAME', 'RegionOne'))) self.vnf['inputs'].update(dict( keystone_url=self.get_public_auth_url(self.orig_cloud))) if self.deploy_vnf() and self.test_vnf(): self.result = 100 return 0 self.result = 1/3 * 100 return 1 def deploy_vnf(self): start_time = time.time() self.__logger.info("Upload VNFD") descriptor = self.vnf['descriptor'] self.util_info["cfy"] = self.cfy_client self.util_info["cfy_manager_ip"] = self.fip.floating_ip_address self.util_info["deployment_name"] = descriptor.get('name') self.cfy_client.blueprints.upload( descriptor.get('file_name'), descriptor.get('name')) self.__logger.info("Create VNF Instance") self.cfy_client.deployments.create( descriptor.get('name'), descriptor.get('name'), self.vnf.get('inputs')) cloudify.wait_for_execution( self.cfy_client, cloudify.get_execution_id( self.cfy_client, descriptor.get('name')), self.__logger, timeout=7200) self.__logger.info("Start the VNF Instance deployment") execution = self.cfy_client.executions.start( descriptor.get('name'), 'install') # Show execution log execution = cloudify.wait_for_execution( self.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) result = True else: self.details['vnf'].update(status='FAIL', duration=duration) result = False return result def test_vnf(self): start_time = time.time() testing = vrouter_base.VrouterOnBoardingBase(self.util, self.util_info) result, test_result_data = testing.test_vnf() duration = time.time() - start_time if result: self.details['test_vnf'].update( status='PASS', result='OK', full_result=test_result_data, duration=duration) else: self.details['test_vnf'].update( status='FAIL', result='NG', full_result=test_result_data, duration=duration) return True def clean(self): self.kill_existing_execution(self.vnf['descriptor'].get('name')) if self.image_alt: self.cloud.delete_image(self.image_alt) if self.flavor_alt: self.orig_cloud.delete_flavor(self.flavor_alt.id) super(CloudifyVrouter, self).clean()