Fix/add use cases under SMO package
[it/dep.git] / smo-install / test / pythonsdk / src / orantests / network_slicing / preparation / sdc_preparation.py
1 #!/usr/bin/env python3
2 ###
3 # ============LICENSE_START===================================================
4 # ORAN SMO PACKAGE - PYTHONSDK TESTS
5 # ================================================================================
6 #  Copyright (C) 2021 Samsung Electronics
7 #  Copyright (C) 2022 AT&T Intellectual Property. All rights
8 #                             reserved.
9 # ============================================================================
10 # Licensed under the Apache License, Version 2.0 (the "License");
11 # you may not use this file except in compliance with the License.
12 # You may obtain a copy of the License at
13 #
14 #      http://www.apache.org/licenses/LICENSE-2.0
15 #
16 # Unless required by applicable law or agreed to in writing, software
17 # distributed under the License is distributed on an "AS IS" BASIS,
18 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 # See the License for the specific language governing permissions and
20 # limitations under the License.
21 #
22 # SPDX-License-Identifier: Apache-2.0
23 # ============LICENSE_END=====================================================
24 #
25 ###
26 """Create SDC Templates for Network Slicing option2 test."""
27 import logging
28 import logging.config
29 from time import sleep
30 import os
31 from onapsdk.sdc.vfc import Vfc
32 from onapsdk.sdc.vf import Vf
33 import onapsdk.constants as const
34 from onapsdk.configuration import settings
35 from onapsdk.exceptions import ResourceNotFound
36 from onapsdk.sdc.properties import Property, ParameterError
37 from waiting import wait
38 from oransdk.aai.service_design_and_creation import AaiModel
39 from oransdk.sdc.sdc import SdcTemplate
40 from oransdk.sdc.service import OranService
41
42 # Set working dir as python script location
43 abspath = os.path.abspath(__file__)
44 dname = os.path.dirname(abspath)
45 os.chdir(dname)
46
47 logging.config.dictConfig(settings.LOG_CONFIG)
48 logger = logging.getLogger("####################### Start SDC Preparation")
49 service_dict = {}
50 service_list = []
51
52 class SdcPreparation():
53     """Can be used to prepare SDC for Network Slicing usecase option2."""
54
55     def __init__(self, suffix: str = None):
56         """
57         Initialize SDC preparation object.
58
59         Args:
60             suffix (str, optional): the suffix of the SDC template names
61
62         """
63         if suffix is None:
64             self.suffix = ""
65         else:
66             self.suffix = suffix
67
68     def prepare_sdc(self) -> dict:
69         """Create SDC templates."""
70         # Populate AAI needed value
71
72         sdc = SdcTemplate()
73         vendor = sdc.create_vendor('ONAP')
74         sdc.create_vsp('test1', vendor)
75
76         # 0.create custom categories
77         logger.info("####################### create custom categories")
78         sdc.create_service_category(['CST', 'ServiceProfile', 'AN SliceProfile', 'CN SliceProfile', 'TN SliceProfile',
79                                      'NST', 'TN BH NSST', 'TN Network Requirement', 'AN NF NSST', 'CN NSST', 'Allotted Resource'])
80
81
82         vf_tn_bh_ar = self.create_tn_resources(sdc, vendor)
83         vf_embban_nf_ar = self.create_an_resources(sdc, vendor)
84         vf_embbcn_external_ar = self.create_cn_resources(sdc, vendor)
85         self.create_nst(sdc, vf_embbcn_external_ar, vf_embban_nf_ar, vf_tn_bh_ar)
86
87         vf_slice_ar = self.create_slice_ar(sdc, vendor)
88
89         srv_slice_profile_an_o2 = self.create_an_slice_profiles(sdc, vf_slice_ar)
90         srv_slice_profile_tn = self.create_tn_slice_profiles(sdc, vf_slice_ar)
91         srv_slice_profile_cn = self.create_cn_slice_profiles(sdc, vf_slice_ar)
92         srv_profile_o2 = self.create_service_profile(sdc, vf_slice_ar, srv_slice_profile_cn, srv_slice_profile_tn, srv_slice_profile_an_o2)
93         cst = self.create_cst(sdc, srv_profile_o2)
94         wait(lambda: self.verify_distribution(), sleep_seconds=60, timeout_seconds=3600, waiting_for="All services distributed successfully")
95         return [cst.identifier, cst.unique_uuid, srv_profile_o2.identifier]
96
97     def create_tn_resources(self, sdc, vendor) -> dict:
98         """Create TN related resources."""
99         # 1.Create TN_Network_Requirement Service
100         logger.info("####################### create TN_Network_Requirement Service")
101         props = [Property('ConnectionLink', 'string'),
102                  Property('jitter', 'string', value='10'),
103                  Property('latency', 'integer', value=10),
104                  Property('maxBandwith', 'integer', value=1000)]
105
106         srv_tn_network = sdc.create_service(self.updated_name('TN_Network_Requirement'), 'TN Network Requirement', properties=props,
107                                             inputs=[Property('ConnectionLink', 'string')])
108         service_dict[srv_tn_network.identifier] = False
109         service_list.append(srv_tn_network)
110
111         # 2.Create TN_Network_Req_AR
112         logger.info("####################### create TN_Network_Req_AR")
113         vf = sdc.create_vf(self.updated_name('TN_Network_Req_AR'), 'Allotted Resource', 'Allotted Resource', vendor)
114         for c in vf.components:
115             if c.name == 'AllottedResource 0':
116                 c.get_property('providing_service_invariant_uuid').value = srv_tn_network.unique_uuid
117                 c.get_property('providing_service_uuid').value = srv_tn_network.identifier
118                 c.get_property('providing_service_name').value = srv_tn_network.name
119                 break
120         sdc.onboard_vf(vf)
121
122         # 3.Create Tn_ONAP_internal_BH Service
123         logger.info("####################### create Tn_ONAP_internal_BH Service")
124         props = [Property('pLMNIdList', 'string', value='39-00'),
125                  Property('jitter', 'string', value='10'),
126                  Property('latency', 'integer', value=10),
127                  Property('maxBandwith', 'integer', value=1000)]
128
129         srv_tn_bh = sdc.create_service(self.updated_name('Tn_ONAP_internal_BH'), 'TN BH NSST', vnfs=[vf],
130                                        role='ONAP_internal', properties=props)
131         service_dict[srv_tn_bh.identifier] = False
132         service_list.append(srv_tn_bh)
133
134         # 6.Create Tn_BH_AR
135         logger.info("####################### Create Tn_BH_AR")
136         vf_tn_bh_ar = sdc.create_vf(self.updated_name('Tn_BH_AR'), 'Allotted Resource', 'Allotted Resource', vendor)
137         for c in vf_tn_bh_ar.components:
138             if c.name == 'AllottedResource 0':
139                 c.get_property('providing_service_invariant_uuid').value = srv_tn_bh.unique_uuid
140                 c.get_property('providing_service_uuid').value = srv_tn_bh.identifier
141                 c.get_property('providing_service_name').value = srv_tn_bh.name
142                 break
143         sdc.onboard_vf(vf_tn_bh_ar)
144         return vf_tn_bh_ar
145
146     def create_an_resources(self, sdc, vendor) -> dict:
147         """Create AN related resources."""
148         # 4.Create EmbbAn_NF Service Template
149         logger.info("####################### create EmbbAn_NF Service Template")
150         props = [Property('anNSSCap', 'org.openecomp.datatypes.NSSCapabilities')]
151         srv_embban_nf = sdc.create_service(self.updated_name('EmbbAn_NF'), 'AN NF NSST', role='huawei', service_type='embb', properties=props)
152         service_dict[srv_embban_nf.identifier] = False
153         service_list.append(srv_embban_nf)
154
155         # 7.Create EmbbAn_NF_AR
156         logger.info("####################### create EmbbAn_NF_AR")
157         vf_embban_nf_ar = sdc.create_vf(self.updated_name('EmbbAn_NF_AR'), 'Allotted Resource', 'Allotted Resource', vendor)
158         for c in vf_embban_nf_ar.components:
159             if c.name == 'AllottedResource 0':
160                 c.get_property('providing_service_invariant_uuid').value = srv_embban_nf.unique_uuid
161                 c.get_property('providing_service_uuid').value = srv_embban_nf.identifier
162                 c.get_property('providing_service_name').value = srv_embban_nf.name
163                 break
164         sdc.onboard_vf(vf_embban_nf_ar)
165         return vf_embban_nf_ar
166
167     def create_cn_resources(self, sdc, vendor) -> dict:
168         """Create CN related resources."""
169         # 5.Create EmbbCn_External Service Template
170         logger.info("####################### create EmbbCn_External Service Template")
171         srv_embbcn = OranService(name=self.updated_name('EmbbCn_External'),
172                                  category='CN NSST',
173                                  role='huawei',
174                                  service_type='embb',
175                                  properties=[Property('cnCap', 'org.openecomp.datatypes.NSSCapabilities',\
176                                                       value="{\\\"latency\\\":20,\\\"maxNumberofUEs\\\":10000,\
177                                                               \\\"resourceSharingLevel\\\":\\\"Shared\\\",\\\"sST\\\":\\\"eMBB\\\",\
178                                                               \\\"activityFactor\\\":30,\\\"areaTrafficCapDL\\\":800,\
179                                                               \\\"areaTrafficCapUL\\\":800,\\\"expDataRateDL\\\":1000,\
180                                                               \\\"survivalTime\\\":10,\\\"uEMobilityLevel\\\":\\\"stationary\\\",\
181                                                               \\\"expDataRateUL\\\":1000,\\\"pLMNIdList\\\":\\\"39-00\\\"}")])
182
183         srv_embbcn.create()
184
185         if srv_embbcn.status == const.DRAFT:
186             srv_embbcn.add_deployment_artifact(artifact_type="WORKFLOW", artifact_name="eMBB.zip", artifact="../resources/eMBB.zip",
187                                                artifact_label="abc")
188
189         if srv_embbcn.status != const.DISTRIBUTED:
190             done = False
191             retry = 0
192             to = 1
193             while not done:
194                 try:
195                     srv_embbcn.onboard()
196                 except ResourceNotFound as e:
197                     retry += 1
198                     if retry > 5:
199                         raise e
200                     to = 2 * to + 1
201                     sleep(to)
202                 else:
203                     done = True
204         service_dict[srv_embbcn.identifier] = False
205         service_list.append(srv_embbcn)
206
207         # 8.EmbbCn_External_AR
208         logger.info("####################### create EmbbCn_External_AR")
209         vf_embbcn_external_ar = sdc.create_vf(self.updated_name('EmbbCn_External_AR'), 'Allotted Resource', 'Allotted Resource', vendor)
210         for c in vf_embbcn_external_ar.components:
211             if c.name == 'AllottedResource 0':
212                 c.get_property('providing_service_invariant_uuid').value = srv_embbcn.unique_uuid
213                 c.get_property('providing_service_uuid').value = srv_embbcn.identifier
214                 c.get_property('providing_service_name').value = srv_embbcn.name
215                 break
216         sdc.onboard_vf(vf_embbcn_external_ar)
217         return vf_embbcn_external_ar
218
219     def create_nst(self, sdc, vf_embbcn_external_ar, vf_embban_nf_ar, vf_tn_bh_ar) -> None:
220         """Create NST."""
221         # 9.Create EmbbNst_O2 Service Template
222         logger.info("####################### create service EmbbNst_O2")
223         props = [Property('latency', 'integer', value=20),
224                  Property('maxNumberofUEs', 'integer', value=1000),
225                  Property('maxNumberofConns', 'integer', value=100000),
226                  Property('resourceSharingLevel', 'string', value='Shared'),
227                  Property('sST', 'string', value='eMBB'),
228                  Property('activityFactor', 'integer', value=60),
229                  Property('availability', 'float', value=0.6),
230                  Property('dLThptPerSlice', 'integer', value=1000),
231                  Property('uLThptPerSlice', 'integer', value=1000),
232                  Property('jitter', 'integer', value=10),
233                  Property('survivalTime', 'integer', value=10),
234                  Property('uEMobilityLevel', 'string', value='stationary'),
235                  Property('pLMNIdList', 'string', value='39-00'),
236                  Property('reliability', 'string', value='99%')]
237         nst = sdc.create_service(self.updated_name('EmbbNst_O2'),
238                                  'NST',
239                                  role='option2',
240                                  vnfs=[vf_embbcn_external_ar, vf_embban_nf_ar, vf_tn_bh_ar],
241                                  properties=props)
242         service_dict[nst.identifier] = False
243         service_list.append(nst)
244
245     def create_slice_ar(self, sdc, vendor) -> dict:
246         """Create Slice AR."""
247         # 10. create Slice_AR
248         logger.info("####################### create Slice_AR")
249
250         vfc = Vfc('AllottedResource')
251         vf_slice_ar = Vf(name=self.updated_name('Slice_AR'), category='Allotted Resource', subcategory='Allotted Resource', vendor=vendor)
252         vf_slice_ar.create()
253         if vf_slice_ar.status == const.DRAFT:
254             vf_slice_ar.add_resource(vfc)
255
256         for c in vf_slice_ar.components:
257             if c.name == 'AllottedResource 0':
258                 cp = sdc.get_component_property(c, 'providing_service_invariant_uuid')
259                 if cp:
260                     logger.info('declare input for property [%s]', cp)
261                     vf_slice_ar.declare_input(cp)
262                 else:
263                     raise ParameterError('no property providing_service_invariant_uuid found')
264
265                 cp = sdc.get_component_property(c, 'providing_service_uuid')
266                 if cp:
267                     logger.info('declare input for property [%s]', cp)
268                     vf_slice_ar.declare_input(cp)
269                 else:
270                     raise ParameterError('no property providing_service_uuid found')
271
272                 break
273
274         sdc.onboard_vf(vf_slice_ar)
275         # AAI bug workaround: create Slice_ar in AAI DB before SO distribution, otherwise service will not be deployed to AAI succesfully
276         aai = AaiModel(invariant_id=vf_slice_ar.unique_uuid, model_type="resource", resource_version=vf_slice_ar.version)
277         aai.create(vf_slice_ar.name, vf_slice_ar.identifier, aai.invariant_id)
278         return vf_slice_ar
279
280     def create_an_slice_profiles(self, sdc, vf_slice_ar) -> dict:
281         """Create AN Slice profile."""
282         # 11.Create SliceProfile_AN_O2 Service Template
283         logger.info("####################### create SliceProfile_AN_O2 Service Template")
284         an_slice_profile = [Property('ipAddress', 'string'),
285                             Property('logicInterfaceId', 'string'),
286                             Property('nextHopInfo', 'string')]
287         complex_property = Property('anSP', 'org.openecomp.datatypes.SliceProfile')
288         srv_slice_profile_an_o2 = sdc.create_service_1(self.updated_name('SliceProfile_AN_O2'),
289                                                        'AN SliceProfile',
290                                                        properties=an_slice_profile,
291                                                        inputs=an_slice_profile,
292                                                        complex_input=complex_property,
293                                                        vnfs=[vf_slice_ar])
294         service_dict[srv_slice_profile_an_o2.identifier] = False
295         service_list.append(srv_slice_profile_an_o2)
296         return srv_slice_profile_an_o2
297
298     def create_tn_slice_profiles(self, sdc, vf_slice_ar) -> dict:
299         """Create TN Slice profile."""
300         # 12.Create SliceProfile_TN Service Template
301         logger.info('####################### create service SliceProfile_TN')
302         tn_slice_profile = [Property('jitter', 'string'),
303                             Property('latency', 'integer'),
304                             Property('pLMNIdList', 'string'),
305                             Property('sNSSAI', 'string'),
306                             Property('sST', 'integer'),
307                             Property('maxBandwidth', 'integer')]
308
309         srv_slice_profile_tn = sdc.create_service_1(self.updated_name('SliceProfile_TN'),
310                                                     'TN SliceProfile',
311                                                     vnfs=[vf_slice_ar],
312                                                     inputs=tn_slice_profile,
313                                                     properties=tn_slice_profile)
314         service_dict[srv_slice_profile_tn.identifier] = False
315         service_list.append(srv_slice_profile_tn)
316         return srv_slice_profile_tn
317
318     def create_cn_slice_profiles(self, sdc, vf_slice_ar) -> dict:
319         """Create CN Slice profile."""
320         # 13.Create SliceProfile_CN Service Template
321         logger.info('####################### create slice SliceProfile_CN')
322         cn_slice_profile = [Property('ipAddress', 'string'),
323                             Property('logicInterfaceId', 'string'),
324                             Property('nextHopInfo', 'string')]
325         srv_slice_profile_cn = sdc.create_service_1(self.updated_name('SliceProfile_CN'),
326                                                     'CN SliceProfile',
327                                                     vnfs=[vf_slice_ar],
328                                                     inputs=cn_slice_profile,
329                                                     properties=cn_slice_profile)
330         service_dict[srv_slice_profile_cn.identifier] = False
331         service_list.append(srv_slice_profile_cn)
332         return srv_slice_profile_cn
333
334     def create_service_profile(self, sdc, vf_slice_ar, srv_slice_profile_cn, srv_slice_profile_tn, srv_slice_profile_an_o2) -> dict:
335         """Create Slice profile."""
336         # 14.Create ServiceProfile_O2 Service Template
337         logger.info('####################### create service ServiceProfile O2')
338         service_props = Property('spProp', 'org.openecomp.datatypes.ServiceProfile')
339         srv_profile_o2 = sdc.create_service_1(self.updated_name('ServiceProfile_O2'),
340                                               'ServiceProfile',
341                                               properties=[service_props],
342                                               complex_input=service_props,
343                                               vnfs=[vf_slice_ar, srv_slice_profile_cn, srv_slice_profile_tn, srv_slice_profile_an_o2],
344                                               role='option2')
345         service_dict[srv_profile_o2.identifier] = False
346         service_list.append(srv_profile_o2)
347         return srv_profile_o2
348
349     def create_cst(self, sdc, srv_profile_o2) -> dict:
350         """Create CST."""
351         # 15.Create CST_O2 Service Template
352         logger.info('####################### create service CST O2')
353         cs_prop = Property('csProp', 'org.openecomp.datatypes.CSProperties')
354         cst = sdc.create_service_1(self.updated_name('CST_O2'),
355                                    'CST',
356                                    role='option2',
357                                    service_type='embb',
358                                    vnfs=[srv_profile_o2],
359                                    properties=[cs_prop],
360                                    complex_input=cs_prop)
361         service_dict[cst.identifier] = False
362         service_list.append(cst)
363         return cst
364
365     def updated_name(self, name) -> str:
366         """Adding suffix for the name."""
367         return name + self.suffix
368
369     @classmethod
370     def verify_distribution(cls) -> bool:
371         """Verify the distribution of all the services."""
372         for service in service_list:
373             logger.info('####################### verify service:%s', service.name)
374             if service_dict[service.identifier]:
375                 continue
376             so_ready = False
377             aai_ready = False
378             result = service.get_distribution_status()
379             for element in result['distributionStatusList']:
380                 if (element['omfComponentID'] == "SO-COpenSource-Env11" and (element['status'] == "DEPLOY_OK" or element['status'] == const.DOWNLOAD_OK)):
381                     so_ready = True
382                 if (element['omfComponentID'] == "aai-ml" and element['status'] == "DEPLOY_OK"):
383                     aai_ready = True
384             if so_ready and aai_ready:
385                 service_dict[service.identifier] = True
386                 logger.info('####################### service %s distributed successfully to SO and AAI', service.name)
387
388         res = True
389         for value in service_dict.values():
390             res = res and value
391             logger.info('####################### res is:%s, value is:%s', str(res), str(value))
392         return res