# Copyright 2021 K Sai Kiran (Tata Elxsi) # # 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. __author__ = "K Sai Kiran , Selvi Jayaraman " __date__ = "$12-June-2021 8:30:59$" from copy import deepcopy from osm_nbi.descriptor_topics import NsdTopic from .base_methods import BaseMethod from osm_nbi.instance_topics import NsrTopic, VnfrTopic class VnfInstances2NsInstances: def __init__(self, db, fs, msg, auth): """ Constructor of Vnf Instances to Ns Instances """ self.new_vnf_instance = NewVnfInstance(db, fs, msg, auth) self.list_vnf_instance = ListVnfInstance(db, fs, msg, auth) self.show_vnf_instance = ShowVnfInstance(db, fs, msg, auth) self.delete_vnf_instance = DeleteVnfInstance(db, fs, msg, auth) def new(self, rollback, session, indata=None, kwargs=None, headers=None): """ Creates a new entry into database. :param rollback: list to append created items at database in case a rollback may have to be done :param session: contains "username", "admin", "force", "public", "project_id", "set_project" :param indata: data to be inserted :param kwargs: used to override the indata descriptor :param headers: http request headers :return: _id, op_id: _id: identity of the inserted data. op_id: operation id if this is asynchronous, None otherwise """ return self.new_vnf_instance.action(rollback, session, indata, kwargs, headers) def list(self, session, filter_q=None, api_req=False): """ Get a list of the Vnfs that match a filter :param session: contains the used login username and working project :param filter_q: filter of data to be applied :param api_req: True if this call is serving an external API request. False if serving internal request. :return: The list, it can be empty if no one match the filter. """ return self.list_vnf_instance.action(session, filter_q, api_req) def show(self, session, _id, api_req=False): """ Get complete information on an Vnf :param session: contains "username", "admin", "force", "public", "project_id", "set_project" :param _id: server internal id :param api_req: True if this call is serving an external API request. False if serving internal request. :return: dictionary, raise exception if not found. """ return self.show_vnf_instance.action(session, _id, api_req) def delete(self, session, _id, dry_run=False, not_send_msg=None): """ Delete item by its internal _id :param session: contains "username", "admin", "force", "public", "project_id", "set_project" :param _id: server internal id :param dry_run: make checking but do not delete :param not_send_msg: To not send message (False) or store content (list) instead :return: operation id (None if there is not operation), raise exception if error or not found, conflict, ... """ return self.delete_vnf_instance.action(session, _id, dry_run, not_send_msg) class NewVnfInstance(BaseMethod): # sample ns descriptor sample_nsd = { "nsd": { "nsd": [ { "df": [ { "id": "default-df", "vnf-profile": [ { "id": 1, "virtual-link-connectivity": [ { "constituent-cpd-id": [ { "constituent-base-element-id": 1, "constituent-cpd-id": "eth0-ext", } ], "virtual-link-profile-id": "mgmtnet", } ], "vnfd-id": "cirros_vnfd", } ], } ], "vnfd-id": ["cirros_vnfd"], "description": "Generated by OSM pacakage generator", "id": "cirros_2vnf_nsd", "name": "cirros_2vnf_ns", "short-name": "cirros_2vnf_ns", "vendor": "OSM", "version": "1.0", } ] } } @staticmethod def __get_formatted_indata(indata, nsd_id): """ Create indata for nsd_id :param indata: Contains unformatted data for new vnf instance :param nsd_id: Id of nsd :return: formatted indata for nsd_id """ formatted_indata = deepcopy(indata) formatted_indata["nsdId"] = nsd_id formatted_indata["nsName"] = indata["vnfInstanceName"] + "-ns" for invalid_key in ( "vnfdId", "vnfInstanceName", "vnfInstanceDescription", "additionalParams", ): formatted_indata.pop(invalid_key) return formatted_indata def __init__(self, db, fs, msg, auth): """ Constructor for new vnf instance """ super().__init__() self.msg = msg self.nsdtopic = NsdTopic(db, fs, msg, auth) self.nsrtopic = NsrTopic(db, fs, msg, auth) def __get_vnfd(self): # get vnfd from nfvo pass def __onboard_vnfd(self): self.__get_vnfd() pass def __create_nsd(self, rollback, session, indata=None, kwargs=None, headers=None): """ Creates new ns descriptor from a vnfd. :param rollback: list to append the created items at database in case a rollback must be done :param session: contains "username", "admin", "force", "public", "project_id", "set_project" :param indata: params to be used for the nsr :param kwargs: used to override the indata :param headers: http request headers :return: id of new nsd created """ _id, *others = self.nsdtopic.new(rollback, session, {}, None, headers) new_nsd = deepcopy(NewVnfInstance.sample_nsd) vnf_content = { "id": "default-df", "vnf-profile": [ { "id": "1", "virtual-link-connectivity": [ { "constituent-cpd-id": [ { "constituent-base-element-id": "1", "constituent-cpd-id": indata["additionalParams"][ "constituent-cpd-id" ], } ], "virtual-link-profile-id": indata["additionalParams"][ "virtual-link-profile-id" ], } ], "vnfd-id": indata["vnfdId"], } ], } vnf_profile = vnf_content["vnf-profile"][0] virtual_link_connectivity = vnf_profile["virtual-link-connectivity"][0] constituent_cpd_id = virtual_link_connectivity["constituent-cpd-id"][0] if "ip-address" in indata["additionalParams"]: constituent_cpd_id["ip-address"] = indata["additionalParams"]["ip-address"] new_nsd["nsd"]["nsd"][0] = { "description": indata["vnfInstanceDescription"], "designer": "OSM", "id": indata["vnfdId"] + "-ns", "name": indata["vnfdId"] + "-ns", "version": "1.0", "df": [ vnf_content, ], "virtual-link-desc": indata["additionalParams"]["virtual-link-desc"], "vnfd-id": [indata["vnfdId"]], } return _id, new_nsd def __create_nsr(self, rollback, session, indata=None, kwargs=None, headers=None): """ Creates an new ns record in database :param rollback: list to append the created items at database in case a rollback must be done :param session: contains "username", "admin", "force", "public", "project_id", "set_project" :param indata: params to be used for the nsr :param kwargs: used to override the indata :param headers: http request headers :return: id of new nsr """ return self.nsrtopic.new(rollback, session, indata, kwargs, headers) def __action_pre_processing( self, rollback, session, indata=None, kwargs=None, headers=None ): """ Pre process for creating new vnf instance :param rollback: list to append the created items at database in case a rollback must be done :param session: contains "username", "admin", "force", "public", "project_id", "set_project" :param indata: params to be used for the nsr :param kwargs: used to override the indata :param headers: http request headers :return: id nsr """ self.__onboard_vnfd() nsd_id, nsd = self.__create_nsd(rollback, session, indata, kwargs, headers) self.nsdtopic.upload_content(session, nsd_id, nsd, kwargs, headers) formatted_indata = NewVnfInstance.__get_formatted_indata(indata, nsd_id) nsr_id, _ = self.__create_nsr( rollback, session, formatted_indata, kwargs, headers ) nsr = self.nsrtopic.show(session, nsr_id) vnfr_id = nsr["constituent-vnfr-ref"][0] if vnfr_id: links = {"vnfInstance": "/osm/vnflcm/v1/vnf_instances/" + vnfr_id} indata["vnfInstanceId"] = vnfr_id indata["_links"] = links self.msg.write("vnf", "create", indata) return vnfr_id, None def action(self, rollback, session, indata=None, kwargs=None, headers=None): """ Creates an new vnf instance :param rollback: list to append the created items at database in case a rollback must be done :param session: contains "username", "admin", "force", "public", "project_id", "set_project" :param indata: params to be used for the nsr :param kwargs: used to override the indata :param headers: http request headers :return: id of new vnf instance """ return self.__action_pre_processing(rollback, session, indata, kwargs, headers) class ListVnfInstance(BaseMethod): def __init__(self, db, fs, msg, auth): """ Constructor call for listing vnfs """ super().__init__() self.vnfrtopic = VnfrTopic(db, fs, msg, auth) def action(self, session, filter_q=None, api_req=False): """ To get list of vnfs that matches a filter :param session: contains the used login username and working project :param filter_q: filter of data to be applied :param api_req: True if this call is serving an external API request. False if serving internal request. :return: The list, it can be empty if no one match the filter. """ return self.vnfrtopic.list(session, filter_q, api_req) class ShowVnfInstance(BaseMethod): def __init__(self, db, fs, msg, auth): """ Constructor call for showing vnf lcm operation """ super().__init__() self.vnfrtopic = VnfrTopic(db, fs, msg, auth) def action(self, session, _id, api_req=False): """ Get complete information on an Vnf Lcm Operation. :param session: contains "username", "admin", "force", "public", "project_id", "set_project" :param _id: Vnf Lcm operation id :param api_req: True if this call is serving an external API request. False if serving internal request. :return: dictionary, raise exception if not found. """ return self.vnfrtopic.show(session, _id, api_req) class DeleteVnfInstance(BaseMethod): def __init__(self, db, fs, msg, auth): """ Constructor call for deleting vnf """ super().__init__() self.msg = msg self.nsrtopic = NsrTopic(db, fs, msg, auth) self.nsdtopic = NsdTopic(db, fs, msg, auth) self.vnfrtopic = VnfrTopic(db, fs, msg, auth) def action(self, session, _id, dry_run=False, not_send_msg=None): """ Delete vnf instance by its internal _id :param session: contains "username", "admin", "force", "public", "project_id", "set_project" :param _id: server internal id :param dry_run: make checking but do not delete :param not_send_msg: To not send message (False) or store content (list) instead :return: operation id (None if there is not operation), raise exception if error or not found, conflict, ... """ vnfInstanceId = _id vnfr = self.vnfrtopic.show(session, vnfInstanceId) ns_id = vnfr.get("nsr-id-ref") nsr = self.nsrtopic.show(session, ns_id) nsd_to_del = nsr["nsd"]["_id"] links = {"vnfInstance": "/osm/vnflcm/v1/vnf_instances/" + _id} params = {"vnfdId": vnfr["vnfd-ref"], "vnfInstanceId": _id, "_links": links} self.msg.write("vnf", "delete", params) self.nsrtopic.delete(session, ns_id, dry_run, not_send_msg) return self.nsdtopic.delete(session, nsd_to_del, dry_run, not_send_msg)