X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=it%2Fdep.git;a=blobdiff_plain;f=smo-install%2Ftest%2Fpythonsdk%2Fsrc%2Forantests%2Fnetwork_slicing%2Fpreparation%2Fsdc_preparation.py;fp=smo-install%2Ftest%2Fpythonsdk%2Fsrc%2Forantests%2Fnetwork_slicing%2Fpreparation%2Fsdc_preparation.py;h=08493e3d2a0f1ec3ea33441e74cb183b2aefb4b6;hp=0000000000000000000000000000000000000000;hb=bc6231f7d4d44ab5f269683c42eb90c2ce4ec9a6;hpb=f97b292fa01903c18b71ec8a549824c7ec3bea93 diff --git a/smo-install/test/pythonsdk/src/orantests/network_slicing/preparation/sdc_preparation.py b/smo-install/test/pythonsdk/src/orantests/network_slicing/preparation/sdc_preparation.py new file mode 100644 index 00000000..08493e3d --- /dev/null +++ b/smo-install/test/pythonsdk/src/orantests/network_slicing/preparation/sdc_preparation.py @@ -0,0 +1,392 @@ +#!/usr/bin/env python3 +### +# ============LICENSE_START=================================================== +# ORAN SMO PACKAGE - PYTHONSDK TESTS +# ================================================================================ +# Copyright (C) 2021 Samsung Electronics +# Copyright (C) 2022 AT&T Intellectual Property. All rights +# reserved. +# ============================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# ============LICENSE_END===================================================== +# +### +"""Create SDC Templates for Network Slicing option2 test.""" +import logging +import logging.config +from time import sleep +import os +from onapsdk.sdc.vfc import Vfc +from onapsdk.sdc.vf import Vf +import onapsdk.constants as const +from onapsdk.configuration import settings +from onapsdk.exceptions import ResourceNotFound +from onapsdk.sdc.properties import Property, ParameterError +from waiting import wait +from oransdk.aai.service_design_and_creation import AaiModel +from oransdk.sdc.sdc import SdcTemplate +from oransdk.sdc.service import OranService + +# Set working dir as python script location +abspath = os.path.abspath(__file__) +dname = os.path.dirname(abspath) +os.chdir(dname) + +logging.config.dictConfig(settings.LOG_CONFIG) +logger = logging.getLogger("####################### Start SDC Preparation") +service_dict = {} +service_list = [] + +class SdcPreparation(): + """Can be used to prepare SDC for Network Slicing usecase option2.""" + + def __init__(self, suffix: str = None): + """ + Initialize SDC preparation object. + + Args: + suffix (str, optional): the suffix of the SDC template names + + """ + if suffix is None: + self.suffix = "" + else: + self.suffix = suffix + + def prepare_sdc(self) -> dict: + """Create SDC templates.""" + # Populate AAI needed value + + sdc = SdcTemplate() + vendor = sdc.create_vendor('ONAP') + sdc.create_vsp('test1', vendor) + + # 0.create custom categories + logger.info("####################### create custom categories") + sdc.create_service_category(['CST', 'ServiceProfile', 'AN SliceProfile', 'CN SliceProfile', 'TN SliceProfile', + 'NST', 'TN BH NSST', 'TN Network Requirement', 'AN NF NSST', 'CN NSST', 'Allotted Resource']) + + + vf_tn_bh_ar = self.create_tn_resources(sdc, vendor) + vf_embban_nf_ar = self.create_an_resources(sdc, vendor) + vf_embbcn_external_ar = self.create_cn_resources(sdc, vendor) + self.create_nst(sdc, vf_embbcn_external_ar, vf_embban_nf_ar, vf_tn_bh_ar) + + vf_slice_ar = self.create_slice_ar(sdc, vendor) + + srv_slice_profile_an_o2 = self.create_an_slice_profiles(sdc, vf_slice_ar) + srv_slice_profile_tn = self.create_tn_slice_profiles(sdc, vf_slice_ar) + srv_slice_profile_cn = self.create_cn_slice_profiles(sdc, vf_slice_ar) + srv_profile_o2 = self.create_service_profile(sdc, vf_slice_ar, srv_slice_profile_cn, srv_slice_profile_tn, srv_slice_profile_an_o2) + cst = self.create_cst(sdc, srv_profile_o2) + wait(lambda: self.verify_distribution(), sleep_seconds=60, timeout_seconds=3600, waiting_for="All services distributed successfully") + return [cst.identifier, cst.unique_uuid, srv_profile_o2.identifier] + + def create_tn_resources(self, sdc, vendor) -> dict: + """Create TN related resources.""" + # 1.Create TN_Network_Requirement Service + logger.info("####################### create TN_Network_Requirement Service") + props = [Property('ConnectionLink', 'string'), + Property('jitter', 'string', value='10'), + Property('latency', 'integer', value=10), + Property('maxBandwith', 'integer', value=1000)] + + srv_tn_network = sdc.create_service(self.updated_name('TN_Network_Requirement'), 'TN Network Requirement', properties=props, + inputs=[Property('ConnectionLink', 'string')]) + service_dict[srv_tn_network.identifier] = False + service_list.append(srv_tn_network) + + # 2.Create TN_Network_Req_AR + logger.info("####################### create TN_Network_Req_AR") + vf = sdc.create_vf(self.updated_name('TN_Network_Req_AR'), 'Allotted Resource', 'Allotted Resource', vendor) + for c in vf.components: + if c.name == 'AllottedResource 0': + c.get_property('providing_service_invariant_uuid').value = srv_tn_network.unique_uuid + c.get_property('providing_service_uuid').value = srv_tn_network.identifier + c.get_property('providing_service_name').value = srv_tn_network.name + break + sdc.onboard_vf(vf) + + # 3.Create Tn_ONAP_internal_BH Service + logger.info("####################### create Tn_ONAP_internal_BH Service") + props = [Property('pLMNIdList', 'string', value='39-00'), + Property('jitter', 'string', value='10'), + Property('latency', 'integer', value=10), + Property('maxBandwith', 'integer', value=1000)] + + srv_tn_bh = sdc.create_service(self.updated_name('Tn_ONAP_internal_BH'), 'TN BH NSST', vnfs=[vf], + role='ONAP_internal', properties=props) + service_dict[srv_tn_bh.identifier] = False + service_list.append(srv_tn_bh) + + # 6.Create Tn_BH_AR + logger.info("####################### Create Tn_BH_AR") + vf_tn_bh_ar = sdc.create_vf(self.updated_name('Tn_BH_AR'), 'Allotted Resource', 'Allotted Resource', vendor) + for c in vf_tn_bh_ar.components: + if c.name == 'AllottedResource 0': + c.get_property('providing_service_invariant_uuid').value = srv_tn_bh.unique_uuid + c.get_property('providing_service_uuid').value = srv_tn_bh.identifier + c.get_property('providing_service_name').value = srv_tn_bh.name + break + sdc.onboard_vf(vf_tn_bh_ar) + return vf_tn_bh_ar + + def create_an_resources(self, sdc, vendor) -> dict: + """Create AN related resources.""" + # 4.Create EmbbAn_NF Service Template + logger.info("####################### create EmbbAn_NF Service Template") + props = [Property('anNSSCap', 'org.openecomp.datatypes.NSSCapabilities')] + srv_embban_nf = sdc.create_service(self.updated_name('EmbbAn_NF'), 'AN NF NSST', role='huawei', service_type='embb', properties=props) + service_dict[srv_embban_nf.identifier] = False + service_list.append(srv_embban_nf) + + # 7.Create EmbbAn_NF_AR + logger.info("####################### create EmbbAn_NF_AR") + vf_embban_nf_ar = sdc.create_vf(self.updated_name('EmbbAn_NF_AR'), 'Allotted Resource', 'Allotted Resource', vendor) + for c in vf_embban_nf_ar.components: + if c.name == 'AllottedResource 0': + c.get_property('providing_service_invariant_uuid').value = srv_embban_nf.unique_uuid + c.get_property('providing_service_uuid').value = srv_embban_nf.identifier + c.get_property('providing_service_name').value = srv_embban_nf.name + break + sdc.onboard_vf(vf_embban_nf_ar) + return vf_embban_nf_ar + + def create_cn_resources(self, sdc, vendor) -> dict: + """Create CN related resources.""" + # 5.Create EmbbCn_External Service Template + logger.info("####################### create EmbbCn_External Service Template") + srv_embbcn = OranService(name=self.updated_name('EmbbCn_External'), + category='CN NSST', + role='huawei', + service_type='embb', + properties=[Property('cnCap', 'org.openecomp.datatypes.NSSCapabilities',\ + value="{\\\"latency\\\":20,\\\"maxNumberofUEs\\\":10000,\ + \\\"resourceSharingLevel\\\":\\\"Shared\\\",\\\"sST\\\":\\\"eMBB\\\",\ + \\\"activityFactor\\\":30,\\\"areaTrafficCapDL\\\":800,\ + \\\"areaTrafficCapUL\\\":800,\\\"expDataRateDL\\\":1000,\ + \\\"survivalTime\\\":10,\\\"uEMobilityLevel\\\":\\\"stationary\\\",\ + \\\"expDataRateUL\\\":1000,\\\"pLMNIdList\\\":\\\"39-00\\\"}")]) + + srv_embbcn.create() + + if srv_embbcn.status == const.DRAFT: + srv_embbcn.add_deployment_artifact(artifact_type="WORKFLOW", artifact_name="eMBB.zip", artifact="../resources/eMBB.zip", + artifact_label="abc") + + if srv_embbcn.status != const.DISTRIBUTED: + done = False + retry = 0 + to = 1 + while not done: + try: + srv_embbcn.onboard() + except ResourceNotFound as e: + retry += 1 + if retry > 5: + raise e + to = 2 * to + 1 + sleep(to) + else: + done = True + service_dict[srv_embbcn.identifier] = False + service_list.append(srv_embbcn) + + # 8.EmbbCn_External_AR + logger.info("####################### create EmbbCn_External_AR") + vf_embbcn_external_ar = sdc.create_vf(self.updated_name('EmbbCn_External_AR'), 'Allotted Resource', 'Allotted Resource', vendor) + for c in vf_embbcn_external_ar.components: + if c.name == 'AllottedResource 0': + c.get_property('providing_service_invariant_uuid').value = srv_embbcn.unique_uuid + c.get_property('providing_service_uuid').value = srv_embbcn.identifier + c.get_property('providing_service_name').value = srv_embbcn.name + break + sdc.onboard_vf(vf_embbcn_external_ar) + return vf_embbcn_external_ar + + def create_nst(self, sdc, vf_embbcn_external_ar, vf_embban_nf_ar, vf_tn_bh_ar) -> None: + """Create NST.""" + # 9.Create EmbbNst_O2 Service Template + logger.info("####################### create service EmbbNst_O2") + props = [Property('latency', 'integer', value=20), + Property('maxNumberofUEs', 'integer', value=1000), + Property('maxNumberofConns', 'integer', value=100000), + Property('resourceSharingLevel', 'string', value='Shared'), + Property('sST', 'string', value='eMBB'), + Property('activityFactor', 'integer', value=60), + Property('availability', 'float', value=0.6), + Property('dLThptPerSlice', 'integer', value=1000), + Property('uLThptPerSlice', 'integer', value=1000), + Property('jitter', 'integer', value=10), + Property('survivalTime', 'integer', value=10), + Property('uEMobilityLevel', 'string', value='stationary'), + Property('pLMNIdList', 'string', value='39-00'), + Property('reliability', 'string', value='99%')] + nst = sdc.create_service(self.updated_name('EmbbNst_O2'), + 'NST', + role='option2', + vnfs=[vf_embbcn_external_ar, vf_embban_nf_ar, vf_tn_bh_ar], + properties=props) + service_dict[nst.identifier] = False + service_list.append(nst) + + def create_slice_ar(self, sdc, vendor) -> dict: + """Create Slice AR.""" + # 10. create Slice_AR + logger.info("####################### create Slice_AR") + + vfc = Vfc('AllottedResource') + vf_slice_ar = Vf(name=self.updated_name('Slice_AR'), category='Allotted Resource', subcategory='Allotted Resource', vendor=vendor) + vf_slice_ar.create() + if vf_slice_ar.status == const.DRAFT: + vf_slice_ar.add_resource(vfc) + + for c in vf_slice_ar.components: + if c.name == 'AllottedResource 0': + cp = sdc.get_component_property(c, 'providing_service_invariant_uuid') + if cp: + logger.info('declare input for property [%s]', cp) + vf_slice_ar.declare_input(cp) + else: + raise ParameterError('no property providing_service_invariant_uuid found') + + cp = sdc.get_component_property(c, 'providing_service_uuid') + if cp: + logger.info('declare input for property [%s]', cp) + vf_slice_ar.declare_input(cp) + else: + raise ParameterError('no property providing_service_uuid found') + + break + + sdc.onboard_vf(vf_slice_ar) + # AAI bug workaround: create Slice_ar in AAI DB before SO distribution, otherwise service will not be deployed to AAI succesfully + aai = AaiModel(invariant_id=vf_slice_ar.unique_uuid, model_type="resource", resource_version=vf_slice_ar.version) + aai.create(vf_slice_ar.name, vf_slice_ar.identifier, aai.invariant_id) + return vf_slice_ar + + def create_an_slice_profiles(self, sdc, vf_slice_ar) -> dict: + """Create AN Slice profile.""" + # 11.Create SliceProfile_AN_O2 Service Template + logger.info("####################### create SliceProfile_AN_O2 Service Template") + an_slice_profile = [Property('ipAddress', 'string'), + Property('logicInterfaceId', 'string'), + Property('nextHopInfo', 'string')] + complex_property = Property('anSP', 'org.openecomp.datatypes.SliceProfile') + srv_slice_profile_an_o2 = sdc.create_service_1(self.updated_name('SliceProfile_AN_O2'), + 'AN SliceProfile', + properties=an_slice_profile, + inputs=an_slice_profile, + complex_input=complex_property, + vnfs=[vf_slice_ar]) + service_dict[srv_slice_profile_an_o2.identifier] = False + service_list.append(srv_slice_profile_an_o2) + return srv_slice_profile_an_o2 + + def create_tn_slice_profiles(self, sdc, vf_slice_ar) -> dict: + """Create TN Slice profile.""" + # 12.Create SliceProfile_TN Service Template + logger.info('####################### create service SliceProfile_TN') + tn_slice_profile = [Property('jitter', 'string'), + Property('latency', 'integer'), + Property('pLMNIdList', 'string'), + Property('sNSSAI', 'string'), + Property('sST', 'integer'), + Property('maxBandwidth', 'integer')] + + srv_slice_profile_tn = sdc.create_service_1(self.updated_name('SliceProfile_TN'), + 'TN SliceProfile', + vnfs=[vf_slice_ar], + inputs=tn_slice_profile, + properties=tn_slice_profile) + service_dict[srv_slice_profile_tn.identifier] = False + service_list.append(srv_slice_profile_tn) + return srv_slice_profile_tn + + def create_cn_slice_profiles(self, sdc, vf_slice_ar) -> dict: + """Create CN Slice profile.""" + # 13.Create SliceProfile_CN Service Template + logger.info('####################### create slice SliceProfile_CN') + cn_slice_profile = [Property('ipAddress', 'string'), + Property('logicInterfaceId', 'string'), + Property('nextHopInfo', 'string')] + srv_slice_profile_cn = sdc.create_service_1(self.updated_name('SliceProfile_CN'), + 'CN SliceProfile', + vnfs=[vf_slice_ar], + inputs=cn_slice_profile, + properties=cn_slice_profile) + service_dict[srv_slice_profile_cn.identifier] = False + service_list.append(srv_slice_profile_cn) + return srv_slice_profile_cn + + def create_service_profile(self, sdc, vf_slice_ar, srv_slice_profile_cn, srv_slice_profile_tn, srv_slice_profile_an_o2) -> dict: + """Create Slice profile.""" + # 14.Create ServiceProfile_O2 Service Template + logger.info('####################### create service ServiceProfile O2') + service_props = Property('spProp', 'org.openecomp.datatypes.ServiceProfile') + srv_profile_o2 = sdc.create_service_1(self.updated_name('ServiceProfile_O2'), + 'ServiceProfile', + properties=[service_props], + complex_input=service_props, + vnfs=[vf_slice_ar, srv_slice_profile_cn, srv_slice_profile_tn, srv_slice_profile_an_o2], + role='option2') + service_dict[srv_profile_o2.identifier] = False + service_list.append(srv_profile_o2) + return srv_profile_o2 + + def create_cst(self, sdc, srv_profile_o2) -> dict: + """Create CST.""" + # 15.Create CST_O2 Service Template + logger.info('####################### create service CST O2') + cs_prop = Property('csProp', 'org.openecomp.datatypes.CSProperties') + cst = sdc.create_service_1(self.updated_name('CST_O2'), + 'CST', + role='option2', + service_type='embb', + vnfs=[srv_profile_o2], + properties=[cs_prop], + complex_input=cs_prop) + service_dict[cst.identifier] = False + service_list.append(cst) + return cst + + def updated_name(self, name) -> str: + """Adding suffix for the name.""" + return name + self.suffix + + @classmethod + def verify_distribution(cls) -> bool: + """Verify the distribution of all the services.""" + for service in service_list: + logger.info('####################### verify service:%s', service.name) + if service_dict[service.identifier]: + continue + so_ready = False + aai_ready = False + result = service.get_distribution_status() + for element in result['distributionStatusList']: + if (element['omfComponentID'] == "SO-COpenSource-Env11" and (element['status'] == "DEPLOY_OK" or element['status'] == const.DOWNLOAD_OK)): + so_ready = True + if (element['omfComponentID'] == "aai-ml" and element['status'] == "DEPLOY_OK"): + aai_ready = True + if so_ready and aai_ready: + service_dict[service.identifier] = True + logger.info('####################### service %s distributed successfully to SO and AAI', service.name) + + res = True + for value in service_dict.values(): + res = res and value + logger.info('####################### res is:%s, value is:%s', str(res), str(value)) + return res