X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=examples%2Fping_pong_ns%2Frift%2Fmano%2Fexamples%2Fping_pong_nsd.py;h=ba1c759c88bef3699c4e502208d173474077bd22;hb=8743c4a738dadcf431d4aef3b01d24d398b9f78a;hp=ef2dd90e507fcf624ef084c11d6b418dcf6f5779;hpb=6364d016e7f819903ff29a2ce160cb4cea61bf8f;p=osm%2FSO.git diff --git a/examples/ping_pong_ns/rift/mano/examples/ping_pong_nsd.py b/examples/ping_pong_ns/rift/mano/examples/ping_pong_nsd.py index ef2dd90e..ba1c759c 100755 --- a/examples/ping_pong_ns/rift/mano/examples/ping_pong_nsd.py +++ b/examples/ping_pong_ns/rift/mano/examples/ping_pong_nsd.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -# Copyright 2016 RIFT.IO Inc +# Copyright 2016-2017 RIFT.IO Inc # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,24 +18,27 @@ import argparse +import simplejson import os +import yaml import shutil import sys import uuid +import random + +from xml.dom.minidom import parseString import gi gi.require_version('RwYang', '1.0') gi.require_version('RwVnfdYang', '1.0') gi.require_version('VnfdYang', '1.0') gi.require_version('RwNsdYang', '1.0') -gi.require_version('NsdYang', '1.0') - from gi.repository import ( - RwNsdYang, - NsdYang, - RwVnfdYang, - VnfdYang, + RwNsdYang as RwNsdYang, + NsdYang as NsdYang, + RwVnfdYang as RwVnfdYang, + VnfdYang as VnfdYang, RwYang, ) @@ -91,7 +94,7 @@ class ManoDescriptor(object): self.descriptor = None def write_to_file(self, module_list, outdir, output_format): - model = RwYang.Model.create_libncx() + model = RwYang.Model.create_libyang() for module in module_list: model.load_module(module) @@ -107,28 +110,532 @@ class ManoDescriptor(object): else: raise Exception("Invalid output format for the descriptor") - def get_json(self, module_list): - model = RwYang.Model.create_libncx() - for module in module_list: - model.load_module(module) - print(self.descriptor.to_json(model)) - class VirtualNetworkFunction(ManoDescriptor): def __init__(self, name, instance_count=1): self.vnfd_catalog = None self.vnfd = None + self.mano_ut = False + self.use_ns_init_conf = False + self.use_vca_conf = False + self.use_charm = False self.instance_count = instance_count self._placement_groups = [] + self.config_files = [] self.use_vnf_init_conf = False super(VirtualNetworkFunction, self).__init__(name) def add_placement_group(self, group): self._placement_groups.append(group) - def compose(self, image_name, cloud_init="", cloud_init_file="", endpoint=None, mon_params=[], - mon_port=8888, mgmt_port=8888, num_vlr_count=1, num_ivlr_count=1, - num_vms=1, image_md5sum=None, mano_ut=False): + def add_vnf_conf_param_charm(self): + vnfd = self.descriptor.vnfd[0] + confparam = vnfd.config_parameter + + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "mgmt_ip", + "description": "Management IP address", + "attribute": "../../../mgmt-interface, ip-address", + "parameter" : [{ + "config_primitive_name_ref": "config", + "config_primitive_parameter_ref": "ssh-hostname" + }] + }) + confparam.config_parameter_source.append(src) + + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "username", + "description": "SSH username", + "value": "fedora", + "parameter" : [{ + "config_primitive_name_ref": "config", + "config_primitive_parameter_ref": "ssh-username" + }] + }) + confparam.config_parameter_source.append(src) + + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "ssh_key", + "description": "SSH private key file", + "attribute": "../../../mgmt-interface/ssh-key, private-key-file", + "parameter" : [{ + "config_primitive_name_ref": "config", + "config_primitive_parameter_ref": "ssh-private-key" + }] + }) + confparam.config_parameter_source.append(src) + + # Check if pong + if 'pong_' in self.name: + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "service_ip", + "description": "IP on which Pong service is listening", + "attribute": "../../../connection-point[name='pong_vnfd/cp0'], ip-address", + "parameter" : [ + { + "config_primitive_name_ref": "set-server", + "config_primitive_parameter_ref": "server-ip" + }, + ] + }) + confparam.config_parameter_source.append(src) + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "service_port", + "description": "Port on which server listens for incoming data packets", + "value": "5555", + "parameter" : [ + { + "config_primitive_name_ref": "set-server", + "config_primitive_parameter_ref": "server-port" + }, + ] + }) + confparam.config_parameter_source.append(src) + + else: + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "rate", + "description": "Rate of packet generation", + "value": "5", + "parameter" : [ + { + "config_primitive_name_ref": "set-rate", + "config_primitive_parameter_ref": "rate" + }, + ] + }) + confparam.config_parameter_source.append(src) + + req = confparam.create_config_parameter_request() + req.from_dict({ + "name": "pong_ip", + "description": "IP on which Pong service is listening", + "parameter" : [ + { + "config_primitive_name_ref": "set-server", + "config_primitive_parameter_ref": "server-ip" + }, + ] + }) + confparam.config_parameter_request.append(req) + req = confparam.create_config_parameter_request() + req.from_dict({ + "name": "pong_port", + "description": "Port on which Pong service is listening", + "parameter" : [ + { + "config_primitive_name_ref": "set-server", + "config_primitive_parameter_ref": "server-port" + }, + ] + }) + confparam.config_parameter_request.append(req) + + def add_vnf_conf_param(self): + vnfd = self.descriptor.vnfd[0] + confparam = vnfd.config_parameter + + def get_params(param): + # Check if pong + if 'pong_' in self.name: + params = [ + { + "config_primitive_name_ref": "config", + "config_primitive_parameter_ref": param + }, + { + "config_primitive_name_ref": "start-stop", + "config_primitive_parameter_ref": param + }, + ] + else: + params = [ + { + "config_primitive_name_ref": "config", + "config_primitive_parameter_ref": param + }, + { + "config_primitive_name_ref": "set-rate", + "config_primitive_parameter_ref": param + }, + { + "config_primitive_name_ref": "start-stop", + "config_primitive_parameter_ref": param + }, + ] + return params + + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "mgmt_ip", + "description": "Management address", + "attribute": "../../../mgmt-interface, ip-address", + "parameter" : get_params("mgmt_ip") + }) + confparam.config_parameter_source.append(src) + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "mgmt_port", + "description": "Management port", + "descriptor": "../../../mgmt-interface/port", + "parameter" : get_params("mgmt_port") + }) + confparam.config_parameter_source.append(src) + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "username", + "description": "Management username", + "value": "admin", + "parameter" : get_params("username") + }) + confparam.config_parameter_source.append(src) + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "password", + "description": "Management password", + "value": "admin", + "parameter" : get_params("password") + }) + confparam.config_parameter_source.append(src) + + # Check if pong + if 'pong_' in self.name: + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "service_ip", + "description": "IP on which Pong service is listening", + "attribute": "../../../connection-point[name='pong_vnfd/cp0'], ip-address", + "parameter" : [ + { + "config_primitive_name_ref": "config", + "config_primitive_parameter_ref": "service_ip" + }, + ] + }) + confparam.config_parameter_source.append(src) + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "service_port", + "description": "Port on which server listens for incoming data packets", + "value": "5555", + "parameter" : [ + { + "config_primitive_name_ref": "config", + "config_primitive_parameter_ref": "service_port" + }, + ] + }) + confparam.config_parameter_source.append(src) + + else: + src = confparam.create_config_parameter_source() + src.from_dict({ + "name": "rate", + "description": "Rate of packet generation", + "value": "5", + "parameter" : [ + { + "config_primitive_name_ref": "set-rate", + "config_primitive_parameter_ref": "rate" + }, + ] + }) + confparam.config_parameter_source.append(src) + + req = confparam.create_config_parameter_request() + req.from_dict({ + "name": "pong_ip", + "description": "IP on which Pong service is listening", + "parameter" : [ + { + "config_primitive_name_ref": "config", + "config_primitive_parameter_ref": "pong_ip" + }, + ] + }) + confparam.config_parameter_request.append(req) + req = confparam.create_config_parameter_request() + req.from_dict({ + "name": "pong_port", + "description": "Port on which Pong service is listening", + "parameter" : [ + { + "config_primitive_name_ref": "config", + "config_primitive_parameter_ref": "pong_port" + }, + ] + }) + confparam.config_parameter_request.append(req) + + def add_ping_vca_config(self): + vnfd = self.descriptor.vnfd[0] + # Add vnf configuration + vnf_config = vnfd.vnf_configuration + + # vnf_config.config_attributes.config_delay = 10 + + # Select "script" configuration + vnf_config.script.script_type = 'rift' + + # Add config primitive + prim = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "config", + "parameter": [ + {"name": "mgmt_ip", "data_type": "STRING", "read_only": "true"}, + {"name": "mgmt_port", "data_type": "INTEGER", "read_only": "true"}, + {"name": "username", "data_type": "STRING", "read_only": "true"}, + {"name": "password", "data_type": "STRING", "read_only": "true"}, + {"name": "pong_ip", "data_type": "STRING", "read_only": "true"}, + {"name": "pong_port", "data_type": "INTEGER","read_only": "true", + "default_value": "5555"}, + ], + "user_defined_script": "ping_setup.py", + }) + vnf_config.config_primitive.append(prim) + + prim = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "set-rate", + "parameter": [ + {"name": "mgmt_ip", "data_type": "STRING", "read_only": "true"}, + {"name": "mgmt_port", "data_type": "INTEGER", "read_only": "true"}, + {"name": "username", "data_type": "STRING", "read_only": "true"}, + {"name": "password", "data_type": "STRING", "read_only": "true"}, + {"name": "rate", "data_type": "INTEGER", + "default_value": "5"}, + ], + "user_defined_script": "ping_rate.py", + }) + vnf_config.config_primitive.append(prim) + + prim = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "start-stop", + "parameter": [ + {"name": "mgmt_ip", "data_type": "STRING", "read_only": "true"}, + {"name": "mgmt_port", "data_type": "INTEGER", "read_only": "true"}, + {"name": "username", "data_type": "STRING", "read_only": "true"}, + {"name": "password", "data_type": "STRING", "read_only": "true"}, + {"name": "start", "data_type": "BOOLEAN", + "default_value": "true"} + ], + "user_defined_script": "ping_start_stop.py", + }) + vnf_config.config_primitive.append(prim) + + # Add initial config primitive + init_config = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive.from_dict( + { + "seq": 1, + "config_primitive_ref": "config", + } + ) + vnf_config.initial_config_primitive.append(init_config) + + init_config = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive.from_dict( + { + "seq": 2, + "config_primitive_ref": "set-rate", + }, + ) + vnf_config.initial_config_primitive.append(init_config) + + if self.use_ns_init_conf is False: + init_config = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive.from_dict( + { + "seq": 3, + "config_primitive_ref": "start-stop", + }, + ) + vnf_config.initial_config_primitive.append(init_config) + + def add_pong_vca_config(self): + vnfd = self.descriptor.vnfd[0] + # Add vnf configuration + vnf_config = vnfd.vnf_configuration + + # Select "script" configuration + vnf_config.script.script_type = 'rift' + + # Add config primitive + prim = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "config", + "parameter": [ + {"name": "mgmt_ip", "data_type": "STRING", "read_only": "true"}, + {"name": "mgmt_port", "data_type": "INTEGER", "read_only": "true"}, + {"name": "username", "data_type": "STRING", "read_only": "true"}, + {"name": "password", "data_type": "STRING", "read_only": "true"}, + {"name": "service_ip", "data_type": "STRING", "read_only": "true"}, + {"name": "service_port", "data_type": "INTEGER", "read_only": "true"}, + ], + "user_defined_script": "pong_setup.py", + }) + vnf_config.config_primitive.append(prim) + + prim = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "start-stop", + "parameter": [ + {"name": "mgmt_ip", "data_type": "STRING", "read_only": "true"}, + {"name": "mgmt_port", "data_type": "INTEGER", "read_only": "true"}, + {"name": "username", "data_type": "STRING", "read_only": "true"}, + {"name": "password", "data_type": "STRING", "read_only": "true"}, + {"name": "start", "data_type": "BOOLEAN", + "default_value": "true"} + ], + "user_defined_script": "pong_start_stop.py", + }) + vnf_config.config_primitive.append(prim) + + # Add initial config primitive + init_config = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive.from_dict( + { + "seq": 1, + "config_primitive_ref": "config", + } + ) + vnf_config.initial_config_primitive.append(init_config) + + if self.use_ns_init_conf is False: + init_config = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive.from_dict( + { + "seq": 2, + "config_primitive_ref": "start-stop", + }, + ) + vnf_config.initial_config_primitive.append(init_config) + + def add_charm_config(self): + vnfd = self.descriptor.vnfd[0] + # Add vnf configuration + vnf_config = vnfd.vnf_configuration + + if 'pong_' in self.name: + mode = "pong" + else: + mode = "ping" + + # Select "script" configuration + vnf_config.juju.charm = 'pingpong' + + # Add config primitive + vnf_config.create_config_primitive() + prim = VnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "start", + }) + vnf_config.config_primitive.append(prim) + + prim = VnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "stop", + }) + vnf_config.config_primitive.append(prim) + + prim = VnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "restart", + }) + vnf_config.config_primitive.append(prim) + + prim = VnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "config", + "parameter": [ + {"name": "ssh-hostname", "data_type": "STRING"}, + {"name": "ssh-username", "data_type": "STRING"}, + {"name": "ssh-private-key", "data_type": "STRING"}, + {"name": "mode", "data_type": "STRING", + "default_value": "{}".format(mode), + "read_only": "true"}, + ], + }) + vnf_config.config_primitive.append(prim) + + prim = VnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "set-server", + "parameter": [ + {"name": "server-ip", "data_type": "STRING"}, + {"name": "server-port", "data_type": "INTEGER"}, + ], + }) + vnf_config.config_primitive.append(prim) + + if mode == 'ping': + prim = VnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "set-rate", + "parameter": [ + {"name": "rate", "data_type": "INTEGER", + "default_value": "5"}, + ], + }) + vnf_config.config_primitive.append(prim) + + prim = VnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "start-traffic", + }) + vnf_config.config_primitive.append(prim) + + prim = VnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive.from_dict({ + "name": "stop-traffic", + }) + vnf_config.config_primitive.append(prim) + + # Add initial config primitive + vnf_config.create_initial_config_primitive() + init_config = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive.from_dict( + { + "seq": 1, + "config_primitive_ref": "config", + } + ) + vnf_config.initial_config_primitive.append(init_config) + + init_config = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive.from_dict( + { + "seq": 2, + "config_primitive_ref": "start", + } + ) + vnf_config.initial_config_primitive.append(init_config) + + init_config = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive.from_dict( + { + "seq": 3, + "config_primitive_ref": "set-server", + }, + ) + vnf_config.initial_config_primitive.append(init_config) + + if mode == 'ping': + init_config = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive.from_dict( + { + "seq": 4, + "config_primitive_ref": "set-rate", + }, + ) + vnf_config.initial_config_primitive.append(init_config) + + if self.use_ns_init_conf is False: + init_config = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive.from_dict( + { + "seq": 5, + "config_primitive_ref": "start-traffic", + }, + ) + vnf_config.initial_config_primitive.append(init_config) + + def compose(self, image_name, vnf_descriptor_message, cloud_init="", cloud_init_file="", + endpoint=None, mon_params=[], mon_port=8888, mgmt_port=8888, num_vlr_count=1, + num_ivlr_count=1, num_vms=1, image_md5sum=None, mano_ut=False, + use_ns_init_conf=False, use_vca_conf=False, use_charm=False, use_static_ip=False, + multidisk=None, port_security=None, metadata_vdud=None, use_ipv6=False, + use_virtual_ip=False, vnfd_input_params=None, script_input_params=None, explicit_port_seq=False, mgmt_net=True): + + self.mano_ut = mano_ut + self.use_ns_init_conf = use_ns_init_conf + self.use_vca_conf = use_vca_conf + self.use_charm = use_charm + self.descriptor = RwVnfdYang.YangData_Vnfd_VnfdCatalog() self.id = str(uuid.uuid1()) vnfd = self.descriptor.vnfd.add() @@ -137,12 +644,18 @@ class VirtualNetworkFunction(ManoDescriptor): vnfd.short_name = self.name vnfd.vendor = 'RIFT.io' vnfd.logo = 'rift_logo.png' - vnfd.description = 'This is an example RIFT.ware VNF' + vnfd.description = vnf_descriptor_message vnfd.version = '1.0' self.vnfd = vnfd - if mano_ut is True: + if explicit_port_seq: + # ping and pong vnfds will have 2 and 5 internal interfaces respectively + num_ivlr_count = 2 + if 'pong' in vnfd.name: + num_ivlr_count = 5 + + if mano_ut or use_virtual_ip or explicit_port_seq: internal_vlds = [] for i in range(num_ivlr_count): internal_vld = vnfd.internal_vld.add() @@ -154,12 +667,20 @@ class VirtualNetworkFunction(ManoDescriptor): internal_vlds.append(internal_vld) for i in range(num_vlr_count): + index = i+1 if mgmt_net else i cp = vnfd.connection_point.add() cp.type_yang = 'VPORT' - cp.name = '%s/cp%d' % (self.name, i) - + cp.name = '%s/cp%d' % (self.name, index) + if port_security is not None: + cp.port_security_enabled = port_security + + if mgmt_net: + cp = vnfd.connection_point.add() + cp.type_yang = 'VPORT' + cp.name = '%s/cp0' % (self.name) + if endpoint is not None: - endp = VnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_HttpEndpoint( + endp = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_HttpEndpoint( path=endpoint, port=mon_port, polling_interval_secs=2 ) vnfd.http_endpoint.append(endp) @@ -170,7 +691,6 @@ class VirtualNetworkFunction(ManoDescriptor): monp.http_endpoint_ref = endpoint vnfd.monitoring_param.append(monp) - for i in range(num_vms): # VDU Specification vdu = vnfd.vdu.add() @@ -196,12 +716,16 @@ class VirtualNetworkFunction(ManoDescriptor): mgmt_intf.dashboard_params.path = endpoint mgmt_intf.dashboard_params.port = mgmt_port - if cloud_init_file and len(cloud_init_file): - vdu.cloud_init_file = cloud_init_file - else: - vdu.cloud_init = cloud_init - if aws: - vdu.cloud_init += " - [ systemctl, restart, --no-block, elastic-network-interfaces.service ]\n" + if use_charm: + mgmt_intf.ssh_key = True + + if not self.use_charm: + if cloud_init_file and len(cloud_init_file): + vdu.cloud_init_file = cloud_init_file + else: + vdu.cloud_init = cloud_init + if aws: + vdu.cloud_init += " - [ systemctl, restart, --no-block, elastic-network-interfaces.service ]\n" # sepcify the guest EPA if use_epa: @@ -246,40 +770,167 @@ class VirtualNetworkFunction(ManoDescriptor): if aws: vdu.image = 'rift-ping-pong' + elif multidisk: + ping_test_data, pong_test_data = multidisk + test_data = ping_test_data + if 'pong' in vnfd.name: + test_data = pong_test_data + for vol_name, vol_attrs in test_data.items(): + vol = vdu.volumes.add() + vol.name = vol_name + vol.device_type = vol_attrs[0] + vol.device_bus = vol_attrs[1] + vol.size = vol_attrs[2] + if vol_attrs[3]: + vol.image = vol_attrs[3] + # Bug RIFT-15165. Will comment out later once the bug is fixed + #else: + # vol.ephemeral = True + + if vol_attrs[4] is not None: + vol.boot_priority = vol_attrs[4] else: vdu.image = image_name if image_md5sum is not None: vdu.image_checksum = image_md5sum - if mano_ut is True: + if explicit_port_seq: + # pong vnfd will have 3 ordered interfaces out of 7 and all interfaces of ping vnfd are ordered + ordered_interfaces_count = num_vlr_count + num_ivlr_count + if 'pong' in vnfd.name: + ordered_interfaces_count = 3 + interface_positions_list = random.sample(range(1, 2**32-1), ordered_interfaces_count-1) + random.shuffle(interface_positions_list) + + if mano_ut or use_virtual_ip or explicit_port_seq: + vip_internal_intf_pool_start = 51 for i in range(num_ivlr_count): internal_cp = vdu.internal_connection_point.add() if vnfd.name.find("ping") >= 0: - cp_name = "ping" + cp_name = "ping_vnfd" else: - cp_name = "pong" + cp_name = "pong_vnfd" internal_cp.name = cp_name + "/icp{}".format(i) internal_cp.id = cp_name + "/icp{}".format(i) internal_cp.type_yang = 'VPORT' - ivld_cp = internal_vlds[i].internal_connection_point_ref.add() + ivld_cp = internal_vlds[i].internal_connection_point.add() ivld_cp.id_ref = internal_cp.id - - internal_interface = vdu.internal_interface.add() + if use_virtual_ip: + vcp = internal_vlds[i].virtual_connection_points.add() + if 'ping' in vnfd.name: + vcp.name = 'ivcp-0' + else: + vcp.name = 'ivcp-1' + vcp.type_yang = 'VPORT' + vcp.associated_cps.append(internal_cp.id) + int_interface_positon_set = False + internal_interface = vdu.interface.add() internal_interface.name = 'fab%d' % i - internal_interface.vdu_internal_connection_point_ref = internal_cp.id + internal_interface.type_yang = 'INTERNAL' + internal_interface.internal_connection_point_ref = internal_cp.id internal_interface.virtual_interface.type_yang = 'VIRTIO' - + if explicit_port_seq and interface_positions_list: + internal_interface.position = interface_positions_list.pop() + int_interface_positon_set = True # internal_interface.virtual_interface.vpci = '0000:00:1%d.0'%i - + if use_virtual_ip and int_interface_positon_set is False: + internal_interface.position = vip_internal_intf_pool_start + vip_internal_intf_pool_start += 1 + + if mgmt_net: + #adding a vlr for management network + num_vlr_count = num_vlr_count + 1 + + vip_external_intf_pool_start = 1 for i in range(num_vlr_count): - external_interface = vdu.external_interface.add() - external_interface.name = 'eth%d' % i - external_interface.vnfd_connection_point_ref = '%s/cp%d' % (self.name, i) - if use_epa: - external_interface.virtual_interface.type_yang = 'VIRTIO' - else: - external_interface.virtual_interface.type_yang = 'VIRTIO' + ext_interface_positon_set = False + external_interface = vdu.interface.add() + external_interface.name = 'eth%d' % (i) + external_interface.type_yang = 'EXTERNAL' + external_interface.external_connection_point_ref = '%s/cp%d' % (self.name, i) + # The first external interface need to be set as the packets use this + # and we bring up only the eth0 (mgmt interface) and eth1 in the ping and + # pong VMs + if explicit_port_seq and (i == 0): + external_interface.position = 1 + elif explicit_port_seq and interface_positions_list: + external_interface.position = interface_positions_list.pop() + ext_interface_positon_set = True + + external_interface.virtual_interface.type_yang = 'VIRTIO' # external_interface.virtual_interface.vpci = '0000:00:2%d.0'%i + if use_virtual_ip and ext_interface_positon_set is False: + external_interface.position = vip_external_intf_pool_start + vip_external_intf_pool_start += 1 + + if use_static_ip and not(mgmt_net and i == 0): + if 'pong_' in self.name: + external_interface.static_ip_address = '31.31.31.31' + if use_ipv6: + external_interface.static_ip_address = '3fee:1111:1111::1234' + else: + external_interface.static_ip_address = '31.31.31.32' + if use_ipv6: + external_interface.static_ip_address = '3fee:1111:1111::1235' + + + if metadata_vdud: + # Metadata for VDU + # Add config files, custom-meta-data for both ping, pong VNFs. Enable 'boot data drive' only for ping VNF + meta_data = {'EMS_IP':'10.1.2.3', 'Licenseserver_IP':'192.168.1.1'} + for i in range(2): + self.config_files.append('test_cfg_file_{}.txt'.format(random.randint(1,1000))) + + supplemental_boot_data = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_Vdu_SupplementalBootData() + + # Add config files + for cfg_file in self.config_files: + config_file = supplemental_boot_data.config_file.add() + config_file.source = cfg_file + config_file.dest = os.path.join('/tmp',cfg_file) + + # enable 'boot data drive' only for ping VNF + if 'ping_' in vnfd.name: + supplemental_boot_data.boot_data_drive = True + # Add custom metadata + for name, value in meta_data.items(): + custom_meta_data = supplemental_boot_data.custom_meta_data.add() + custom_meta_data.name = name + custom_meta_data.value = value + + vdu.supplemental_boot_data = supplemental_boot_data + + if vnfd_input_params: + # Input parameters for vnfd + supplemental_boot_data = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_Vdu_SupplementalBootData() + + if 'ping_' in vnfd.name or 'pong_' in vnfd.name: + cloud_init_data = supplemental_boot_data.custom_meta_data.add() + cloud_init_data.destination = 'CLOUD_INIT' + cloud_init_data.name = 'custom_cloud_init_data' + cloud_init_data.value = 'cc_init_data' + cloud_init_data.data_type = 'STRING' + + cloud_meta_data = supplemental_boot_data.custom_meta_data.add() + cloud_meta_data.destination = 'CLOUD_METADATA' + cloud_meta_data.name = 'custom_cloud_meta_data' + cloud_meta_data.value = 'cc_meta_data' + cloud_meta_data.data_type = 'STRING' + + vdu.supplemental_boot_data = supplemental_boot_data + + if script_input_params: + # Input parameters for vnfd + supplemental_boot_data = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_Vdu_SupplementalBootData() + + if 'ping_' in vnfd.name or 'pong_' in vnfd.name: + cloud_init_data = supplemental_boot_data.custom_meta_data.add() + cloud_init_data.destination = 'CLOUD_METADATA' + cloud_init_data.name = 'CI-script-init-data' + cloud_init_data.value = 'default_script_init_data' + cloud_init_data.data_type = 'STRING' + + vdu.supplemental_boot_data = supplemental_boot_data for group in self._placement_groups: placement_group = vnfd.placement_groups.add() @@ -297,6 +948,54 @@ class VirtualNetworkFunction(ManoDescriptor): member_vdu = placement_group.member_vdus.add() member_vdu.member_vdu_ref = vdu.id + # Add VNF access point + if use_vca_conf: + if use_charm: + self.add_vnf_conf_param_charm() + self.add_charm_config() + else: + self.add_vnf_conf_param() + if 'pong_' in self.name: + self.add_pong_vca_config() + else: + self.add_ping_vca_config() + else: + if 'pong_' in self.name: + self.add_pong_config() + else: + self.add_ping_config() + + def add_ping_config(self): + vnfd = self.descriptor.vnfd[0] + # Add vnf configuration + vnf_config = vnfd.vnf_configuration + vnf_config.script.script_type = 'rift' + + # Add initial config primitive + init_config = RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive.from_dict( + { + "seq": 1, + "name": "Ping config", + "user_defined_script": "ping_initial_config.py", + } + ) + vnf_config.initial_config_primitive.append(init_config) + + def add_pong_config(self): + vnfd = self.descriptor.vnfd[0] + # Add vnf configuration + vnf_config = vnfd.vnf_configuration + vnf_config.script.script_type = 'rift' + + # Add initial config primitive + init_config =RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive.from_dict( + { + "seq": 1, + "name": "Pong config", + "user_defined_script": "pong_initial_config.py", + } + ) + vnf_config.initial_config_primitive.append(init_config) def write_to_file(self, outdir, output_format): dirpath = "%s/%s" % (outdir, self.name) @@ -307,7 +1006,7 @@ class VirtualNetworkFunction(ManoDescriptor): output_format) self.add_scripts(outdir) - def add_scripts(self, outdir): + def add_cloud_init(self, outdir): script_dir = os.path.join(outdir, self.name, 'cloud_init') try: os.makedirs(script_dir) @@ -315,7 +1014,7 @@ class VirtualNetworkFunction(ManoDescriptor): if not os.path.isdir(script_dir): raise - if 'ping' in self.name: + if 'ping_' in self.name: script_file = os.path.join(script_dir, 'ping_cloud_init.cfg') cfg = PING_USERDATA_FILE else: @@ -325,19 +1024,68 @@ class VirtualNetworkFunction(ManoDescriptor): with open(script_file, "w") as f: f.write("{}".format(cfg)) - # Copy the vnf_init_config script - if self.use_vnf_init_conf and ('ping' in self.name): - script_name = 'ping_set_rate.py' + # Create the config files in script_dir + for cfg_file in self.config_files: + with open(os.path.join(script_dir, cfg_file), 'w') as f: + f.write('metadata-vdud test') + + def add_scripts(self, outdir): + if not self.use_charm: + self.add_cloud_init(outdir) + + if not self.use_charm: + if self.use_vca_conf: + self.add_vca_scripts(outdir) + else: + self.add_config_scripts(outdir) + + def add_config_scripts(self, outdir): + dest_path = os.path.join(outdir, self.name, 'scripts') + try: + os.makedirs(dest_path) + except OSError: + if not os.path.isdir(dest_path): + raise - src_path = os.path.dirname(os.path.abspath(os.path.realpath(__file__))) + if 'pong_' in self.name: + scripts = ['pong_initial_config.py'] + else: + scripts = ['ping_initial_config.py'] + + for script_name in scripts: + src_path = os.path.dirname(os.path.abspath( + os.path.realpath(__file__))) script_src = os.path.join(src_path, script_name) if not os.path.exists(script_src): src_path = os.path.join(os.environ['RIFT_ROOT'], - 'modules/core/mano/examples/ping_pong_ns/rift/mano/examples') + 'modules/core/mano/examples/' + 'ping_pong_ns/rift/mano/examples') script_src = os.path.join(src_path, script_name) - dest_path = os.path.join(outdir, self.name, 'scripts') - os.makedirs(dest_path, exist_ok=True) + shutil.copy2(script_src, dest_path) + + def add_vca_scripts(self, outdir): + dest_path = os.path.join(outdir, self.name, 'scripts') + try: + os.makedirs(dest_path) + except OSError: + if not os.path.isdir(dest_path): + raise + + if 'pong_' in self.name: + scripts = ['pong_setup.py', 'pong_start_stop.py'] + else: + scripts = ['ping_setup.py', 'ping_rate.py', 'ping_start_stop.py'] + + for script_name in scripts: + src_path = os.path.dirname(os.path.abspath( + os.path.realpath(__file__))) + script_src = os.path.join(src_path, script_name) + if not os.path.exists(script_src): + src_path = os.path.join(os.environ['RIFT_ROOT'], + 'modules/core/mano/examples/' + 'ping_pong_ns/rift/mano/examples') + script_src = os.path.join(src_path, script_name) shutil.copy2(script_src, dest_path) @@ -349,255 +1097,16 @@ class NetworkService(ManoDescriptor): self.vnfd_config = {} self._placement_groups = [] - def ping_config(self, mano_ut, use_ns_init_conf, use_vnf_init_conf): - suffix = '' - if mano_ut: - ping_cfg = r''' -#!/bin/bash - -echo "!!!!!!!! Executed ping Configuration !!!!!!!!!" - ''' - else: - ping_cfg = r''' -#!/bin/bash - -# Rest API config -ping_mgmt_ip='' -ping_mgmt_port=18888 - -# VNF specific configuration -pong_server_ip='' -ping_rate=5 -server_port=5555 - -# Make rest API calls to configure VNF -curl -D /dev/stdout \ - -H "Accept: application/vnd.yang.data+xml" \ - -H "Content-Type: application/vnd.yang.data+json" \ - -X POST \ - -d "{\"ip\":\"$pong_server_ip\", \"port\":$server_port}" \ - http://${ping_mgmt_ip}:${ping_mgmt_port}/api/v1/ping/server -rc=$? -if [ $rc -ne 0 ] -then - echo "Failed to set server info for ping!" - exit $rc -fi -''' % suffix - - if use_vnf_init_conf is False: - ping_cfg +=''' -curl -D /dev/stdout \ - -H "Accept: application/vnd.yang.data+xml" \ - -H "Content-Type: application/vnd.yang.data+json" \ - -X POST \ - -d "{\"rate\":$ping_rate}" \ - http://${ping_mgmt_ip}:${ping_mgmt_port}/api/v1/ping/rate -rc=$? -if [ $rc -ne 0 ] -then - echo "Failed to set ping rate!" - exit $rc -fi - -''' - if use_ns_init_conf: - ping_cfg += "exit 0\n" - else: - ping_cfg +=''' -output=$(curl -D /dev/stdout \ - -H "Accept: application/vnd.yang.data+xml" \ - -H "Content-Type: application/vnd.yang.data+json" \ - -X POST \ - -d "{\"enable\":true}" \ - http://${ping_mgmt_ip}:${ping_mgmt_port}/api/v1/ping/adminstatus/state) -if [[ $output == *"Internal Server Error"* ]] -then - echo $output - exit 3 -else - echo $output -fi - -exit 0 -''' - return ping_cfg + def default_config(self, constituent_vnfd, vnfd, mano_ut, use_ns_init_conf, use_vnf_init_conf): + vnf_config = vnfd.vnfd.vnf_configuration - def pong_config(self, mano_ut, use_ns_init_conf): - suffix = '' - if mano_ut: - pong_cfg = r''' -#!/bin/bash - -echo "!!!!!!!! Executed pong Configuration !!!!!!!!!" - ''' - else: - pong_cfg = r''' -#!/bin/bash - -# Rest API configuration -pong_mgmt_ip='' -pong_mgmt_port=18889 -# username= -# password= - -# VNF specific configuration -pong_server_ip='' -server_port=5555 - -# Make Rest API calls to configure VNF -curl -D /dev/stdout \ - -H "Accept: application/vnd.yang.data+xml" \ - -H "Content-Type: application/vnd.yang.data+json" \ - -X POST \ - -d "{\"ip\":\"$pong_server_ip\", \"port\":$server_port}" \ - http://${pong_mgmt_ip}:${pong_mgmt_port}/api/v1/pong/server -rc=$? -if [ $rc -ne 0 ] -then - echo "Failed to set server(own) info for pong!" - exit $rc -fi - -''' % suffix - - if use_ns_init_conf: - pong_cfg += "exit 0\n" - else: - pong_cfg +=''' -curl -D /dev/stdout \ - -H "Accept: application/vnd.yang.data+xml" \ - -H "Content-Type: application/vnd.yang.data+json" \ - -X POST \ - -d "{\"enable\":true}" \ - http://${pong_mgmt_ip}:${pong_mgmt_port}/api/v1/pong/adminstatus/state -rc=$? -if [ $rc -ne 0 ] -then - echo "Failed to enable pong service!" - exit $rc -fi - -exit 0 -''' - return pong_cfg - - def pong_fake_juju_config(self, vnf_config): - - if vnf_config: - # Select "script" configuration - vnf_config.juju.charm = 'clearwater-aio-proxy' - - # Set the initital-config - vnf_config.create_initial_config_primitive() - init_config = VnfdYang.InitialConfigPrimitive.from_dict({ - "seq": 1, - "name": "config", - "parameter": [ - {"name": "proxied_ip", "value": ""}, - ] - }) - vnf_config.initial_config_primitive.append(init_config) - - init_config_action = VnfdYang.InitialConfigPrimitive.from_dict({ - "seq": 2, - "name": "action1", - "parameter": [ - {"name": "Pong Connection Point", "value": "pong_vnfd/cp0"}, - ] - }) - vnf_config.initial_config_primitive.append(init_config_action) - init_config_action = VnfdYang.InitialConfigPrimitive.from_dict({ - "seq": 3, - "name": "action2", - "parameter": [ - {"name": "Ping Connection Point", "value": "ping_vnfd/cp0"}, - ] - }) - vnf_config.initial_config_primitive.append(init_config_action) - - # Config parameters can be taken from config.yaml and - # actions from actions.yaml in the charm - # Config to set the home domain - vnf_config.create_service_primitive() - config = VnfdYang.ServicePrimitive.from_dict({ - "name": "config", - "parameter": [ - {"name": "home_domain", "data_type": "STRING"}, - {"name": "base_number", "data_type": "STRING"}, - {"name": "number_count", "data_type": "INTEGER"}, - {"name": "password", "data_type": "STRING"}, - ] - }) - vnf_config.service_primitive.append(config) - - config = VnfdYang.ServicePrimitive.from_dict({ - "name": "create-update-user", - # "user-defined-script":"/tmp/test.py", - "parameter": [ - {"name": "number", "data_type": "STRING", "mandatory": True}, - {"name": "password", "data_type": "STRING", "mandatory": True}, - ] - }) - vnf_config.service_primitive.append(config) - - config = VnfdYang.ServicePrimitive.from_dict({ - "name": "delete-user", - "parameter": [ - {"name": "number", "data_type": "STRING", "mandatory": True}, - ] - }) - vnf_config.service_primitive.append(config) - - def default_config(self, const_vnfd, vnfd, mano_ut, - use_ns_init_conf, - use_vnf_init_conf): - vnf_config = vnfd.vnfd.vnf_configuration - - vnf_config.config_attributes.config_priority = 0 - vnf_config.config_attributes.config_delay = 0 - - # Select "script" configuration - vnf_config.script.script_type = 'bash' - - if vnfd.name == 'pong_vnfd' or vnfd.name == 'pong_vnfd_with_epa' or vnfd.name == 'pong_vnfd_aws': - vnf_config.config_attributes.config_priority = 1 - vnf_config.config_template = self.pong_config(mano_ut, use_ns_init_conf) - # First priority config delay will delay the entire NS config delay - if mano_ut is False: - vnf_config.config_attributes.config_delay = 60 - else: - # This is PONG and inside mano_ut - # This is test only - vnf_config.config_attributes.config_delay = 10 - # vnf_config.config_template = self.pong_config(vnf_config, use_ns_init_conf) - - if vnfd.name == 'ping_vnfd' or vnfd.name == 'ping_vnfd_with_epa' or vnfd.name == 'ping_vnfd_aws': - vnf_config.config_attributes.config_priority = 2 - vnf_config.config_template = self.ping_config(mano_ut, - use_ns_init_conf, - use_vnf_init_conf) - if use_vnf_init_conf: - vnf_config.initial_config_primitive.add().from_dict( - { - "seq": 1, - "name": "set ping rate", - "user_defined_script": "ping_set_rate.py", - "parameter": [ - { - 'name': 'rate', - 'value': '5', - }, - ], - } - ) def ns_config(self, nsd, vnfd_list, mano_ut): # Used by scale group if mano_ut: nsd.service_primitive.add().from_dict( { - "name": "ping config", + "name": "ping scale", "user_defined_script": "{}".format(os.path.join( os.environ['RIFT_ROOT'], 'modules/core/mano', @@ -607,12 +1116,21 @@ exit 0 else: nsd.service_primitive.add().from_dict( { - "name": "ping config", - "user_defined_script": "ping_config.py" + "name": "ping scale", + "user_defined_script": "ping_scale.py" }) + def ns_xconfig(self, nsd): + """Used for a testcase.""" + nsd.service_primitive.add().from_dict( + { + "name": "primitive_test", + "user_defined_script": "primitive_test.py" + } + ) + def ns_initial_config(self, nsd): - nsd.initial_config_primitive.add().from_dict( + nsd.initial_service_primitive.add().from_dict( { "seq": 1, "name": "start traffic", @@ -625,6 +1143,19 @@ exit 0 ], } ) + nsd.terminate_service_primitive.add().from_dict( + { + "seq": 1, + "name": "stop traffic", + "user_defined_script": "stop_traffic.py", + "parameter": [ + { + 'name': 'userid', + 'value': 'rift', + }, + ], + } + ) def add_scale_group(self, scale_group): self._scale_groups.append(scale_group) @@ -644,18 +1175,56 @@ exit 0 'value_type': mon_param.value_type, 'vnfd_monitoring_param': [ {'vnfd_id_ref': vnfd_obj.vnfd.id, - 'vnfd_monitoring_param_ref': mon_param.id}] + 'vnfd_monitoring_param_ref': mon_param.id, + 'member_vnf_index_ref': self.get_member_vnf_index(vnfd_obj.vnfd.id)}], }) self.nsd.monitoring_param.append(nsd_monp) param_id += 1 - - + def get_vnfd_id(self, index): + for cv in self.nsd.constituent_vnfd: + if cv.member_vnf_index == index: + return cv.vnfd_id_ref + + def get_member_vnf_index(self, vnfd_id): + for cv in self.nsd.constituent_vnfd: + if cv.vnfd_id_ref == vnfd_id: + return cv.member_vnf_index + + def add_conf_param_map(self): + nsd = self.nsd + + confparam_map = nsd.config_parameter_map.add() + confparam_map.id = '1' + confparam_map.config_parameter_source.member_vnf_index_ref = 2 + confparam_map.config_parameter_source.vnfd_id_ref = self.get_vnfd_id(2) + confparam_map.config_parameter_source.config_parameter_source_ref = 'service_ip' + confparam_map.config_parameter_request.member_vnf_index_ref = 1 + confparam_map.config_parameter_request.vnfd_id_ref = self.get_vnfd_id(1) + confparam_map.config_parameter_request.config_parameter_request_ref = 'pong_ip' + + confparam_map = nsd.config_parameter_map.add() + confparam_map.id = '2' + confparam_map.config_parameter_source.member_vnf_index_ref = 2 + confparam_map.config_parameter_source.vnfd_id_ref = self.get_vnfd_id(2) + confparam_map.config_parameter_source.config_parameter_source_ref = 'service_port' + confparam_map.config_parameter_request.member_vnf_index_ref = 1 + confparam_map.config_parameter_request.vnfd_id_ref = self.get_vnfd_id(1) + confparam_map.config_parameter_request.config_parameter_request_ref = 'pong_port' def compose(self, vnfd_list, cpgroup_list, mano_ut, + ns_descriptor_message, use_ns_init_conf=True, - use_vnf_init_conf=True,): + use_vnf_init_conf=True, + use_vca_conf=False, + use_ipv6=False, + port_security = None, + use_virtual_ip=False, + primitive_test=False, + vnfd_input_params=False, + script_input_params=False, + mgmt_net=True): if mano_ut: # Disable NS initial config primitive @@ -671,20 +1240,31 @@ exit 0 nsd.short_name = self.name nsd.vendor = 'RIFT.io' nsd.logo = 'rift_logo.png' - nsd.description = 'Toy NS' + nsd.description = ns_descriptor_message nsd.version = '1.0' nsd.input_parameter_xpath.append( NsdYang.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath( - xpath="/nsd:nsd-catalog/nsd:nsd/nsd:vendor", + xpath="/nsd-catalog/nsd/vendor", ) ) + if vnfd_input_params: + nsd.input_parameter_xpath.append( + NsdYang.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath( + xpath="/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vendor", + ) + ) + ip_profile = nsd.ip_profiles.add() ip_profile.name = "InterVNFLink" ip_profile.description = "Inter VNF Link" ip_profile.ip_profile_params.ip_version = "ipv4" ip_profile.ip_profile_params.subnet_address = "31.31.31.0/24" ip_profile.ip_profile_params.gateway_address = "31.31.31.210" + if use_ipv6: + ip_profile.ip_profile_params.ip_version = "ipv6" + ip_profile.ip_profile_params.subnet_address = "3fee:1111:1111::/64" + ip_profile.ip_profile_params.gateway_address = "3fee:1111:1111::1" vld_id = 1 for cpgroup in cpgroup_list: @@ -698,12 +1278,19 @@ exit 0 vld.version = '1.0' vld.type_yang = 'ELAN' vld.ip_profile_ref = 'InterVNFLink' - for cp in cpgroup: + for i, cp in enumerate(cpgroup): cpref = vld.vnfd_connection_point_ref.add() cpref.member_vnf_index_ref = cp[0] cpref.vnfd_id_ref = cp[1] cpref.vnfd_connection_point_ref = cp[2] - + if use_virtual_ip: + vcp = vld.virtual_connection_points.add() + vcp.name = 'vcp-{}'.format(i) + vcp.type_yang = 'VPORT' + if port_security is not None: + vcp.port_security_enabled = port_security + vcp.associated_cps.append(cpref.vnfd_connection_point_ref) + vnfd_index_map = {} member_vnf_index = 1 for vnfd in vnfd_list: @@ -719,10 +1306,78 @@ exit 0 constituent_vnfd.start_by_default = False constituent_vnfd.vnfd_id_ref = vnfd.descriptor.vnfd[0].id - self.default_config(constituent_vnfd, vnfd, mano_ut, - use_ns_init_conf, use_vnf_init_conf) + if use_vca_conf is False: + self.default_config(constituent_vnfd, vnfd, mano_ut, + use_ns_init_conf, use_vnf_init_conf) member_vnf_index += 1 + if vnfd_input_params: + nsd.input_parameter_xpath.append( + NsdYang.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath( + xpath="/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id='%s']/vnfd:vendor" % (constituent_vnfd.vnfd_id_ref), + ) + ) + nsd.input_parameter_xpath.append( + NsdYang.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath( + xpath=( + "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu" + "/vnfd:supplemental-boot-data/vnfd:custom-meta-data[vnfd:name='custom_cloud_init_data']/vnfd:value" + ) + ) + ) + nsd.input_parameter_xpath.append( + NsdYang.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath( + xpath=( + "/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id='%s']/vnfd:vdu[vnfd:id='%s']" + "/vnfd:supplemental-boot-data/vnfd:custom-meta-data[vnfd:name='custom_cloud_init_data']/vnfd:value" + ) % (constituent_vnfd.vnfd_id_ref, vnfd.descriptor.vnfd[0].vdu[0].id) + ) + ) + nsd.input_parameter_xpath.append( + NsdYang.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath( + xpath=( + "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu" + "/vnfd:supplemental-boot-data/vnfd:custom-meta-data[vnfd:name='custom_cloud_meta_data']/vnfd:value" + ) + ) + ) + nsd.input_parameter_xpath.append( + NsdYang.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath( + xpath=( + "/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id='%s']/vnfd:vdu[vnfd:id='%s']" + "/vnfd:supplemental-boot-data/vnfd:custom-meta-data[vnfd:name='custom_cloud_meta_data']/vnfd:value" + ) % (constituent_vnfd.vnfd_id_ref, vnfd.descriptor.vnfd[0].vdu[0].id) + ) + ) + + if script_input_params: + nsd.input_parameter_xpath.append( + NsdYang.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath( + xpath=( + "/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id='%s']/vnfd:vdu[vnfd:id='%s']" + "/vnfd:supplemental-boot-data/vnfd:custom-meta-data[vnfd:name='CI-script-init-data']/vnfd:value" + ) % (constituent_vnfd.vnfd_id_ref, vnfd.descriptor.vnfd[0].vdu[0].id) + ) + ) + + if mgmt_net: + vld = nsd.vld.add() + vld.id = 'mgmt_vld' + vld.name = 'mgmt_vld' + vld.type_yang = 'ELAN' + vld.mgmt_network = "true" + vld.vim_network_name = "private" + + ping_cpref = vld.vnfd_connection_point_ref.add() + ping_cpref.member_vnf_index_ref = 1 + ping_cpref.vnfd_id_ref = nsd.constituent_vnfd[0].vnfd_id_ref + ping_cpref.vnfd_connection_point_ref = 'ping_vnfd/cp0' + + pong_cpref = vld.vnfd_connection_point_ref.add() + pong_cpref.member_vnf_index_ref = 2 + pong_cpref.vnfd_id_ref = nsd.constituent_vnfd[1].vnfd_id_ref + pong_cpref.vnfd_connection_point_ref = 'pong_vnfd/cp0' + # Enable config primitives if either mano_ut or # scale groups are enabled if mano_ut or len(self._scale_groups): @@ -732,6 +1387,9 @@ exit 0 if use_ns_init_conf: self.ns_initial_config(nsd) + if primitive_test: + self.ns_xconfig(nsd) + for scale_group in self._scale_groups: group_desc = nsd.scaling_group_descriptor.add() group_desc.name = scale_group.name @@ -746,7 +1404,7 @@ exit 0 config_action = group_desc.scaling_config_action.add() config_action.trigger = trigger config = scale_group.config_action[trigger] - config_action.ns_config_primitive_name_ref = config['ns-config-primitive-name-ref'] + config_action.ns_service_primitive_name_ref = config['ns-service-primitive-name-ref'] for placement_group in self._placement_groups: group = nsd.placement_groups.add() @@ -758,7 +1416,9 @@ exit 0 member.vnfd_id_ref = member_vnfd.descriptor.vnfd[0].id member.member_vnf_index_ref = vnfd_index_map[member_vnfd] - # self.create_mon_params(vnfd_list) + self.create_mon_params(vnfd_list) + if use_vca_conf: + self.add_conf_param_map() def write_config(self, outdir, vnfds): @@ -781,9 +1441,7 @@ exit 0 with open('%s/%s__%s.yaml' % (vnf_config_dir, vnfd.id, i), "w") as fh: fh.write(yaml_data) - def write_initial_config_script(self, outdir): - script_name = 'start_traffic.py' - + def write_config_scripts(self, outdir, script_name): src_path = os.path.dirname(os.path.abspath(os.path.realpath(__file__))) script_src = os.path.join(src_path, script_name) if not os.path.exists(script_src): @@ -805,8 +1463,13 @@ exit 0 dirpath, output_format) - # Write the initial config script - self.write_initial_config_script(dirpath) + # Write the config scripts + self.write_config_scripts(dirpath, 'start_traffic.py') + self.write_config_scripts(dirpath, 'stop_traffic.py') + self.write_config_scripts(dirpath, 'primitive_test.py') + + if len(self._scale_groups): + self.write_config_scripts(dirpath, 'ping_scale.py') def get_ping_mon_params(path): @@ -877,8 +1540,8 @@ class ScaleGroup(object): self.vnfd_count_map[vnfd] = vnfd_count def add_config(self): - self.config_action['post_scale_out']= {'ns-config-primitive-name-ref': - 'ping config'} + self.config_action['post_scale_out']= {'ns-service-primitive-name-ref': + 'ping scale'} class PlacementGroup(object): def __init__(self, name): @@ -909,8 +1572,31 @@ class VnfdPlacementGroup(PlacementGroup): def add_member(self, vdu): self.vdu_list.append(vdu) - - +def generate_vnf_and_ns_description_message(descriptor_type, + aws=False, + epa=False, + charm=False, + vca=False, + vip=False): + # Helper Function to generate a description message for + # VNFD/NSD based on type + + suffix_list = [] + if aws: + suffix_list.append(" for AWS ") + else: + suffix_list.append(' ') + + if epa: + suffix_list.append("EPA") + if charm: + suffix_list.append("Charm") + if vca: + suffix_list.append("VCA Conf") + if vip: + suffix_list.append("VIP") + message = "Toy Rift.ware " + descriptor_type + 'with '.join(filter(None, [suffix_list[0], ', '.join(suffix_list[1:])])) + return message def generate_ping_pong_descriptors(fmt="json", write_to_file=False, @@ -934,14 +1620,38 @@ def generate_ping_pong_descriptors(fmt="json", use_placement_group=True, use_ns_init_conf=True, use_vnf_init_conf=True, - ): + use_vca_conf=False, + use_charm=False, + use_static_ip=False, + port_security=None, + metadata_vdud=None, + vnfd_input_params=None, + script_input_params=None, + multidisk=None, + explicit_port_seq=False, + use_ipv6=False, + primitive_test=False, + use_virtual_ip=False, + mgmt_net=True, + nsd_name=None): + # List of connection point groups # Each connection point group refers to a virtual link # the CP group consists of tuples of connection points + if explicit_port_seq: + # ping and pong each will have two external interfaces. + external_vlr_count = 2 cpgroup_list = [] for i in range(external_vlr_count): cpgroup_list.append([]) + if use_charm: + use_vca_conf = True + + if use_vca_conf: + use_ns_init_conf = True + use_vnf_init_conf = False + suffix = '' ping = VirtualNetworkFunction("ping_vnfd%s" % (suffix), pingcount) ping.use_vnf_init_conf = use_vnf_init_conf @@ -965,9 +1675,16 @@ def generate_ping_pong_descriptors(fmt="json", ping_userdata=ping_userdata, ex_ping_userdata=ex_ping_userdata ) + ns_descriptor_message = generate_vnf_and_ns_description_message("NS", aws, use_epa, + use_charm, use_vca_conf, + use_virtual_ip) + vnf_descriptor_message = generate_vnf_and_ns_description_message("VNF", aws, use_epa, + use_charm, use_vca_conf, + use_virtual_ip) ping.compose( "Fedora-x86_64-20-20131211.1-sda-ping.qcow2", + vnf_descriptor_message, ping_userdata, use_ping_cloud_init_file, "api/v1/ping/stats", @@ -979,7 +1696,19 @@ def generate_ping_pong_descriptors(fmt="json", num_vms=num_vnf_vms, image_md5sum=ping_md5sum, mano_ut=mano_ut, - ) + use_ns_init_conf=use_ns_init_conf, + use_vca_conf=use_vca_conf, + use_charm=use_charm, + use_static_ip=use_static_ip, + port_security=port_security, + metadata_vdud=metadata_vdud, + vnfd_input_params=vnfd_input_params, + script_input_params=script_input_params, + multidisk=multidisk, + explicit_port_seq=explicit_port_seq, + use_ipv6=use_ipv6, + use_virtual_ip=use_virtual_ip, + mgmt_net=mgmt_net) pong = VirtualNetworkFunction("pong_vnfd%s" % (suffix)) @@ -1008,6 +1737,7 @@ def generate_ping_pong_descriptors(fmt="json", pong.compose( "Fedora-x86_64-20-20131211.1-sda-pong.qcow2", + vnf_descriptor_message, pong_userdata, use_pong_cloud_init_file, "api/v1/pong/stats", @@ -1019,15 +1749,29 @@ def generate_ping_pong_descriptors(fmt="json", num_vms=num_vnf_vms, image_md5sum=pong_md5sum, mano_ut=mano_ut, - ) + use_ns_init_conf=use_ns_init_conf, + use_vca_conf=use_vca_conf, + use_charm=use_charm, + use_static_ip=use_static_ip, + port_security=False if port_security else port_security, + metadata_vdud=metadata_vdud, + vnfd_input_params=vnfd_input_params, + script_input_params=script_input_params, + multidisk=multidisk, + explicit_port_seq=explicit_port_seq, + use_ipv6=use_ipv6, + use_virtual_ip=use_virtual_ip, + mgmt_net=mgmt_net) # Initialize the member VNF index member_vnf_index = 1 # define the connection point groups for index, cp_group in enumerate(cpgroup_list): + if explicit_port_seq: + member_vnf_index = 1 desc_id = ping.descriptor.vnfd[0].id - filename = 'ping_vnfd{}/cp{}'.format(suffix, index) + filename = 'ping_vnfd{}/cp{}'.format(suffix, index+1) for idx in range(pingcount): cp_group.append(( @@ -1039,7 +1783,7 @@ def generate_ping_pong_descriptors(fmt="json", member_vnf_index += 1 desc_id = pong.descriptor.vnfd[0].id - filename = 'pong_vnfd{}/cp{}'.format(suffix, index) + filename = 'pong_vnfd{}/cp{}'.format(suffix, index+1) cp_group.append(( member_vnf_index, @@ -1051,7 +1795,10 @@ def generate_ping_pong_descriptors(fmt="json", vnfd_list = [ping, pong] - nsd_catalog = NetworkService("ping_pong_nsd%s" % (suffix)) + if nsd_name is None: + nsd_name = "ping_pong_nsd%s" % (suffix) + + nsd_catalog = NetworkService(nsd_name) if use_scale_group: group = ScaleGroup("ping_group", max_count=10) @@ -1084,15 +1831,22 @@ def generate_ping_pong_descriptors(fmt="json", nsd_catalog.compose(vnfd_list, cpgroup_list, mano_ut, + ns_descriptor_message, use_ns_init_conf=use_ns_init_conf, - use_vnf_init_conf=use_vnf_init_conf,) + use_vnf_init_conf=use_vnf_init_conf, + use_vca_conf=use_vca_conf, + use_ipv6=use_ipv6, + port_security=port_security, + use_virtual_ip=use_virtual_ip, + primitive_test=primitive_test, + vnfd_input_params=vnfd_input_params, + script_input_params=script_input_params) if write_to_file: ping.write_to_file(out_dir, ping_fmt if ping_fmt is not None else fmt) pong.write_to_file(out_dir, pong_fmt if ping_fmt is not None else fmt) nsd_catalog.write_config(out_dir, vnfd_list) nsd_catalog.write_to_file(out_dir, ping_fmt if nsd_fmt is not None else fmt) - return (ping, pong, nsd_catalog) @@ -1103,24 +1857,41 @@ def main(argv=sys.argv[1:]): parser.add_argument('-f', '--format', default='json') parser.add_argument('-e', '--epa', action="store_true", default=False) parser.add_argument('-a', '--aws', action="store_true", default=False) + parser.add_argument('--vnf-input-parameter', action="store_true", default=False) parser.add_argument('-n', '--pingcount', default=NUM_PING_INSTANCES) parser.add_argument('--ping-image-md5') parser.add_argument('--pong-image-md5') parser.add_argument('--ping-cloud-init', default=None) parser.add_argument('--pong-cloud-init', default=None) + parser.add_argument('--charm', action="store_true", default=False) + parser.add_argument('-v', '--vca_conf', action="store_true", default=False) + parser.add_argument('--virtual-ip', action="store_true", default=False) + parser.add_argument('--static-ip', action="store_true", default=False) + parser.add_argument('--scale', action="store_true", default=False) + parser.add_argument('--primitive-test', action="store_true", default=False) + args = parser.parse_args() outdir = args.outdir output_format = args.format use_epa = args.epa + use_vnf_input_params = args.vnf_input_parameter aws = args.aws - pingcount = args.pingcount + pingcount = int(args.pingcount) use_ping_cloud_init_file = args.ping_cloud_init use_pong_cloud_init_file = args.pong_cloud_init generate_ping_pong_descriptors(args.format, True, args.outdir, pingcount, - ping_md5sum=args.ping_image_md5, pong_md5sum=args.pong_image_md5, + ping_md5sum=args.ping_image_md5, + pong_md5sum=args.pong_image_md5, mano_ut=False, - use_scale_group=False,) + use_scale_group=args.scale, + use_charm=args.charm, + use_vca_conf=args.vca_conf, + use_virtual_ip=args.virtual_ip, + use_static_ip=args.static_ip, + primitive_test=args.primitive_test, + vnfd_input_params=use_vnf_input_params + ) if __name__ == "__main__": main()