diff --git a/Dockerfile.local b/Dockerfile.local index da13878c69f5a2850f4cdfc4188d7f047e5b9a1e..0d2a3d6465e515bb8cb77c86f40d54cb5c631732 100644 --- a/Dockerfile.local +++ b/Dockerfile.local @@ -6,7 +6,7 @@ FROM ubuntu:16.04 WORKDIR /app/NBI/osm_nbi # Copy the current directory contents into the container at /app -ADD . /app/NBI +#ADD . /app RUN apt-get update && apt-get install -y git python3 python3-jsonschema \ python3-pymongo python3-yaml python3-pip python3-keystoneclient \ @@ -80,6 +80,8 @@ ENV OSMNBI_AUTHENTICATION_BACKEND internal #ENV OSMNBI_AUTHENTICATION_SERVICE_PASSWORD nbi #ENV OSMNBI_AUTHENTICATION_SERVICE_PROJECT service +ADD . /app/NBI + # Run app.py when the container launches CMD ["python3", "nbi.py"] diff --git a/osm_nbi/descriptor_topics.py b/osm_nbi/descriptor_topics.py index 9e367c989251440489d4b4cc44fea75c5959a90f..3ace489b0f5d2c90694beb30ad8e3fe21e25a4e5 100644 --- a/osm_nbi/descriptor_topics.py +++ b/osm_nbi/descriptor_topics.py @@ -40,7 +40,7 @@ class DescriptorTopic(BaseTopic): BaseTopic.format_on_new(content, project_id=project_id, make_public=make_public) content["_admin"]["onboardingState"] = "CREATED" content["_admin"]["operationalState"] = "DISABLED" - content["_admin"]["usageSate"] = "NOT_IN_USE" + content["_admin"]["usageState"] = "NOT_IN_USE" def delete(self, session, _id, force=False, dry_run=False): """ @@ -657,16 +657,6 @@ class NstTopic(DescriptorTopic): clean_indata = clean_indata['nst'][0] return clean_indata - def _validate_input_new(self, indata, force=False): - # transform netslice-subnet:nsd-ref to string - if indata.get("netslice-subnet"): - for nsd_ref in indata["netslice-subnet"]: - if "nsd-ref" in nsd_ref: - nsd_ref["nsd-ref"] = str(nsd_ref["nsd-ref"]) - - # TODO validate with pyangbind, serialize - return indata - def _validate_input_edit(self, indata, force=False): # TODO validate with pyangbind, serialize return indata @@ -698,15 +688,21 @@ class NstTopic(DescriptorTopic): Check that there is not any NSIR that uses this NST. Only NSIRs belonging to this project are considered. Note that NST can be public and be used by other projects. :param session: - :param _id: nsd internal id + :param _id: nst internal id :param force: Avoid this checking :return: None or raises EngineException with the conflict """ # TODO: Check this method if force: return + # Get Network Slice Template from Database + _filter = self._get_project_filter(session, write=False, show_all=False) + _filter["_id"] = _id + nst = self.db.get_one("nst", _filter) + + # Search NSIs using NST via nst-ref _filter = self._get_project_filter(session, write=False, show_all=False) - _filter["nst"] = _id + _filter["nst-ref"] = nst["id"] if self.db.get_list("nsis", _filter): raise EngineException("There is some NSIS that depends on this NST", http_code=HTTPStatus.CONFLICT) @@ -725,7 +721,7 @@ class PduTopic(BaseTopic): BaseTopic.format_on_new(content, project_id=None, make_public=make_public) content["_admin"]["onboardingState"] = "CREATED" content["_admin"]["operationalState"] = "DISABLED" - content["_admin"]["usageSate"] = "NOT_IN_USE" + content["_admin"]["usageState"] = "NOT_IN_USE" def check_conflict_on_del(self, session, _id, force=False): if force: diff --git a/osm_nbi/engine.py b/osm_nbi/engine.py index 3de3d156514389e03111bcc3f8844ea1b806ed39..4713b89f698c557273756ecd76766fe211ed832a 100644 --- a/osm_nbi/engine.py +++ b/osm_nbi/engine.py @@ -9,7 +9,7 @@ from http import HTTPStatus from base_topic import EngineException, versiontuple from admin_topics import UserTopic, ProjectTopic, VimAccountTopic, SdnTopic from descriptor_topics import VnfdTopic, NsdTopic, PduTopic, NstTopic -from instance_topics import NsrTopic, VnfrTopic, NsLcmOpTopic, NsiTopic +from instance_topics import NsrTopic, VnfrTopic, NsLcmOpTopic, NsiTopic, NsiLcmOpTopic from base64 import b64encode from os import urandom @@ -31,6 +31,7 @@ class Engine(object): "users": UserTopic, "projects": ProjectTopic, "nsis": NsiTopic, + "nsilcmops": NsiLcmOpTopic # [NEW_TOPIC]: add an entry here } diff --git a/osm_nbi/html_out.py b/osm_nbi/html_out.py index e9237e92528ace0680315184fbcab49c8ff43400..8d3baabfbb176294ba70fee6930945c2234e2f17 100644 --- a/osm_nbi/html_out.py +++ b/osm_nbi/html_out.py @@ -25,6 +25,7 @@ html_start = """ NSDs NSs NSTDs + NSIs USERs PROJECTs TOKENs @@ -102,6 +103,15 @@ html_nslcmop_body = """ """ +html_nsilcmop_body = """ +nsilcm operations +
+""" + def format(data, request, response, session): """ @@ -145,6 +155,10 @@ def format(data, request, response, session): request.path_info.startswith("/nslcm/v1/ns_instances/"): _id = request.path_info[request.path_info.rfind("/")+1:] body += html_nslcmop_body.format(id=_id) + elif request.path_info.startswith("/nsilcm/v1/netslice_instances_content/") or \ + request.path_info.startswith("/nsilcm/v1/netslice_instances/"): + _id = request.path_info[request.path_info.rfind("/")+1:] + body += html_nsilcmop_body.format(id=_id) body += "" + html_escape(yaml.safe_dump(data, explicit_start=True, indent=4, default_flow_style=False)) + \
""
elif data is None:
diff --git a/osm_nbi/instance_topics.py b/osm_nbi/instance_topics.py
index 4228bc5ac41d9482c557abbfe79ffdcf7441e4de..41187dce9f98324e0556b0871cbd55ae2ab345c4 100644
--- a/osm_nbi/instance_topics.py
+++ b/osm_nbi/instance_topics.py
@@ -5,7 +5,7 @@ from uuid import uuid4
from http import HTTPStatus
from time import time
from copy import copy, deepcopy
-from validation import validate_input, ValidationError, ns_instantiate, ns_action, ns_scale
+from validation import validate_input, ValidationError, ns_instantiate, ns_action, ns_scale, nsi_instantiate
from base_topic import BaseTopic, EngineException, get_iterable
from descriptor_topics import DescriptorTopic
@@ -66,7 +66,7 @@ class NsrTopic(BaseTopic):
self.db.del_list("vnfrs", {"nsr-id-ref": _id})
# set all used pdus as free
self.db.set_list("pdus", {"_admin.usage.nsr_id": _id},
- {"_admin.usageSate": "NOT_IN_USE", "_admin.usage": None})
+ {"_admin.usageState": "NOT_IN_USE", "_admin.usage": None})
self._send_msg("deleted", {"_id": _id})
return v
@@ -266,17 +266,6 @@ class NsLcmOpTopic(BaseTopic):
def __init__(self, db, fs, msg):
BaseTopic.__init__(self, db, fs, msg)
- def _validate_input_new(self, input, force=False):
- """
- Validates input user content for a new entry. It uses jsonschema for each type or operation.
- :param input: user input content for the new topic
- :param force: may be used for being more tolerant
- :return: The same input content, or a changed version of it.
- """
- if self.schema_new:
- validate_input(input, self.schema_new)
- return input
-
def _check_ns_operation(self, session, nsr, operation, indata):
"""
Check that user has enter right parameters for the operation
@@ -432,7 +421,7 @@ class NsLcmOpTopic(BaseTopic):
pdu_filter["vim.vim_accounts"] = vim_account
pdu_filter["type"] = pdu_type
pdu_filter["_admin.operationalState"] = "ENABLED"
- pdu_filter["_admin.usageSate"] = "NOT_IN_USE",
+ pdu_filter["_admin.usageState"] = "NOT_IN_USE",
# TODO feature 1417: "shared": True,
available_pdus = self.db.get_list("pdus", pdu_filter)
@@ -462,7 +451,7 @@ class NsLcmOpTopic(BaseTopic):
"_admin.usage.vdur": None,
}
self.db.set_one("pdus", {"_id": pdu["_id"]},
- {"_admin.usageSate": "IN_USE",
+ {"_admin.usageState": "IN_USE",
"_admin.usage.vnfr_id": vnfr["_id"],
"_admin.usage.nsr_id": vnfr["nsr-id-ref"],
"_admin.usage.vdur": vdur["vdu-id-ref"]}
@@ -535,7 +524,8 @@ class NsLcmOpTopic(BaseTopic):
}
return nslcmop
- def new(self, rollback, session, indata=None, kwargs=None, headers=None, force=False, make_public=False):
+ def new(self, rollback, session, indata=None, kwargs=None, headers=None, force=False, make_public=False,
+ slice_object=False):
"""
Performs a new operation over a ns
:param rollback: list to append created items at database in case a rollback must to be done
@@ -580,7 +570,8 @@ class NsLcmOpTopic(BaseTopic):
self.format_on_new(nslcmop_desc, session["project_id"], make_public=make_public)
_id = self.db.create("nslcmops", nslcmop_desc)
rollback.append({"topic": "nslcmops", "_id": _id})
- self.msg.write("ns", operation, nslcmop_desc)
+ if not slice_object:
+ self.msg.write("ns", operation, nslcmop_desc)
return _id
except ValidationError as e:
raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
@@ -608,17 +599,16 @@ class NsiTopic(BaseTopic):
:param descriptor: descriptor to be inserted or edit
:return: None or raises exception
"""
- if not descriptor.get("nstdId"):
+ if not descriptor.get("nst-ref"):
return
- nstd_id = descriptor["nstdId"]
+ nstd_id = descriptor["nst-ref"]
if not self.get_item_list(session, "nsts", {"id": nstd_id}):
- raise EngineException("Descriptor error at nstdId='{}' references a non exist nstd".format(nstd_id),
+ raise EngineException("Descriptor error at nst-ref='{}' references a non exist nstd".format(nstd_id),
http_code=HTTPStatus.CONFLICT)
@staticmethod
def format_on_new(content, project_id=None, make_public=False):
BaseTopic.format_on_new(content, project_id=project_id, make_public=make_public)
- content["_admin"]["nstState"] = "NOT_INSTANTIATED"
def check_conflict_on_del(self, session, _id, force=False):
if force:
@@ -642,17 +632,28 @@ class NsiTopic(BaseTopic):
BaseTopic.delete(self, session, _id, force, dry_run=True)
if dry_run:
return
+
+ # deletes NetSlice instance object
v = self.db.del_one("nsis", {"_id": _id})
- self.db.del_list("nstlcmops", {"nstInstanceId": _id})
- self.db.del_list("vnfrs", {"nsr-id-ref": _id})
- # set all used pdus as free
- self.db.set_list("pdus", {"_admin.usage.nsr_id": _id}, {"_admin.usageSate": "NOT_IN_USE", "_admin.usage": None})
+
+ # makes a temporal list of nsilcmops objects related to the _id given and deletes them from db
+ _filter = {"netsliceInstanceId": _id}
+ self.db.del_list("nsilcmops", _filter)
+
+ _filter = {"operationParams.netsliceInstanceId": _id}
+ nslcmops_list = self.db.get_list("nslcmops", _filter)
+
+ for id_item in nslcmops_list:
+ _filter = {"_id": id_item}
+ nslcmop = self.db.get_one("nslcmops", _filter)
+ nsr_id = nslcmop["operationParams"]["nsr_id"]
+ NsrTopic.delete(self, session, nsr_id, force=False, dry_run=False)
self._send_msg("deleted", {"_id": _id})
return v
def new(self, rollback, session, indata=None, kwargs=None, headers=None, force=False, make_public=False):
"""
- Creates a new nsr into database. It also creates needed vnfrs
+ Creates a new netslice instance record into database. It also creates needed nsrs and vnfrs
:param rollback: list to append the created items at database in case a rollback must be done
:param session: contains the used login username and working project
:param indata: params to be used for the nsir
@@ -671,13 +672,18 @@ class NsiTopic(BaseTopic):
step = ""
# look for nstd
+ self.logger.info(str(slice_request))
step = "getting nstd id='{}' from database".format(slice_request.get("nstdId"))
- _filter = {"_id": slice_request["nstdId"]}
+ _filter = {"id": slice_request["nstdId"]}
_filter.update(BaseTopic._get_project_filter(session, write=False, show_all=True))
nstd = self.db.get_one("nsts", _filter)
+ nstd.pop("_admin", None)
+ nstd.pop("_id", None)
nsi_id = str(uuid4())
- # now = time()
step = "filling nsi_descriptor with input data"
+
+ # "instantiation-parameters.netslice-subnet": []
+ # TODO: Equal as template for now
nsi_descriptor = {
"id": nsi_id,
"nst-ref": nstd["id"],
@@ -685,28 +691,12 @@ class NsiTopic(BaseTopic):
"netslice-subnet": []
},
"network-slice-template": nstd,
- # "nsr-ref-list": [], #TODO: not used for now...
- # "vlr-ref-list": [], #TODO: not used for now...
"_id": nsi_id,
-
- # TODO CHECK: what about the following params?
- # "admin-status": "ENABLED",
- # "description": slice_request.get("nsDescription", ""),
- # "operational-status": "init", # typedef ns-operational-
- # "config-status": "init", # typedef config-states
- # "detailed-status": "scheduled",
- # "orchestration-progress": {},
- # # {"networks": {"active": 0, "total": 0}, "vms": {"active": 0, "total": 0}},
- # "create-time": now,
- # "operational-events": [], # "id", "timestamp", "description", "event",
- # "ssh-authorized-key": slice_request.get("key-pair-ref"),
}
- # nstd["nsi_id"] = nsi_id
- # TODO: ask if we have to develop the VNFR here or we can imply call the NsrTopic() for each service to
- # instantiate.
- # Create netslice-subnet_record
+ # Creating netslice-subnet_record.
needed_nsds = {}
+ services = []
for member_ns in nstd["netslice-subnet"]:
nsd_id = member_ns["nsd-ref"]
step = "getting nstd id='{}' constituent-nsd='{}' from database".format(
@@ -716,20 +706,38 @@ class NsiTopic(BaseTopic):
nsd = DescriptorTopic.get_one_by_id(self.db, session, "nsds", nsd_id)
nsd.pop("_admin")
needed_nsds[nsd_id] = nsd
+ member_ns["_id"] = needed_nsds[nsd_id].get("_id")
+ services.append(member_ns)
else:
nsd = needed_nsds[nsd_id]
-
+ member_ns["_id"] = needed_nsds[nsd_id].get("_id")
+ services.append(member_ns)
+
step = "filling nsir nsd-id='{}' constituent-nsd='{}' from database".format(
member_ns["nsd-ref"], member_ns["id"])
- netslice_subnet_descriptor = {
- "nsName": member_ns["instantiation-parameters"]["name"],
- "nsdId": member_ns["instantiation-parameters"]["nsdId"],
- "vimAccountId": member_ns["instantiation-parameters"]["vimAccountId"]
- }
- nsi_descriptor["instantiation-parameters"]["netslice-subnet"].append(netslice_subnet_descriptor)
step = "creating nsi at database"
self.format_on_new(nsi_descriptor, session["project_id"], make_public=make_public)
+ nsi_descriptor["_admin"]["nsiState"] = "NOT_INSTANTIATED"
+
+ # creates Network Services records (NSRs)
+ step = "creating nsrs at database using NsrTopic.new()"
+ nsrs_list = []
+ for service in services:
+ indata_ns = {}
+ indata_ns["nsdId"] = service["_id"]
+ indata_ns["nsName"] = service["name"]
+ indata_ns["vimAccountId"] = indata.get("vimAccountId")
+ indata_ns["nsDescription"] = service["description"]
+ indata_ns["key-pair-ref"] = None
+ # NsrTopic(rollback, session, indata_ns, kwargs, headers, force)
+ _id_nsr = NsrTopic.new(self, rollback, session, indata_ns, kwargs, headers, force)
+ nsrs_item = {"nsrId": _id_nsr}
+ nsrs_list.append(nsrs_item)
+
+ # Adding the nsrs list to the nsi
+ nsi_descriptor["_admin"]["nsrs-detailed-list"] = nsrs_list
+ # Creating the entry in the database
self.db.create("nsis", nsi_descriptor)
rollback.append({"topic": "nsis", "_id": nsi_id})
return nsi_id
@@ -741,3 +749,141 @@ class NsiTopic(BaseTopic):
def edit(self, session, _id, indata=None, kwargs=None, force=False, content=None):
raise EngineException("Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
+
+
+class NsiLcmOpTopic(BaseTopic):
+ topic = "nsilcmops"
+ topic_msg = "nsi"
+ operation_schema = { # mapping between operation and jsonschema to validate
+ "instantiate": nsi_instantiate,
+ "terminate": None
+ }
+
+ def __init__(self, db, fs, msg):
+ BaseTopic.__init__(self, db, fs, msg)
+
+ def _check_nsi_operation(self, session, nsir, operation, indata):
+ """
+ Check that user has enter right parameters for the operation
+ :param session:
+ :param operation: it can be: instantiate, terminate, action, TODO: update, heal
+ :param indata: descriptor with the parameters of the operation
+ :return: None
+ """
+ nsds = {}
+ nstd = nsir["network-slice-template"]
+
+ def check_valid_netslice_subnet_id(nsId):
+ # TODO change to vnfR (??)
+ for ns in nstd["netslice-subnet"]:
+ if nsId == ns["id"]:
+ nsd_id = ns["nsd-ref"]
+ if nsd_id not in nsds:
+ nsds[nsd_id] = self.db.get_one("nsds", {"id": nsd_id})
+ return nsds[nsd_id]
+ else:
+ raise EngineException("Invalid parameter nsId='{}' is not one of the "
+ "nst:netslice-subnet".format(nsId))
+ if operation == "instantiate":
+ # check the existance of netslice-subnet items
+ for in_nst in get_iterable(indata.get("netslice-subnet")):
+ nstd = check_valid_netslice_subnet_id(in_nst["nsdId"])
+
+ def _create_nsilcmop(self, session, netsliceInstanceId, operation, params):
+ now = time()
+ _id = str(uuid4())
+ nsilcmop = {
+ "id": _id,
+ "_id": _id,
+ "operationState": "PROCESSING", # COMPLETED,PARTIALLY_COMPLETED,FAILED_TEMP,FAILED,ROLLING_BACK,ROLLED_BACK
+ "statusEnteredTime": now,
+ "netsliceInstanceId": netsliceInstanceId,
+ "lcmOperationType": operation,
+ "startTime": now,
+ "isAutomaticInvocation": False,
+ "operationParams": params,
+ "isCancelPending": False,
+ "links": {
+ "self": "/osm/nsilcm/v1/nsi_lcm_op_occs/" + _id,
+ "nsInstance": "/osm/nsilcm/v1/netslice_instances/" + netsliceInstanceId,
+ }
+ }
+ return nsilcmop
+
+ def new(self, rollback, session, indata=None, kwargs=None, headers=None, force=False, make_public=False):
+ """
+ Performs a new operation over a ns
+ :param rollback: list to append created items at database in case a rollback must to be done
+ :param session: contains the used login username and working project
+ :param indata: descriptor with the parameters of the operation. It must contains among others
+ nsiInstanceId: _id of the nsir to perform the operation
+ operation: it can be: instantiate, terminate, action, TODO: update, heal
+ :param kwargs: used to override the indata descriptor
+ :param headers: http request headers
+ :param force: If True avoid some dependence checks
+ :param make_public: Make the created item public to all projects
+ :return: id of the nslcmops
+ """
+ try:
+ # Override descriptor with query string kwargs
+ self._update_input_with_kwargs(indata, kwargs)
+ operation = indata["lcmOperationType"]
+ nsiInstanceId = indata["nsiInstanceId"]
+ validate_input(indata, self.operation_schema[operation])
+
+ # get nsi from nsiInstanceId
+ _filter = BaseTopic._get_project_filter(session, write=True, show_all=False)
+ _filter["_id"] = nsiInstanceId
+ nsir = self.db.get_one("nsis", _filter)
+
+ # initial checking
+ if not nsir["_admin"].get("nsiState") or nsir["_admin"]["nsiState"] == "NOT_INSTANTIATED":
+ if operation == "terminate" and indata.get("autoremove"):
+ # NSIR must be deleted
+ return self.delete(session, nsiInstanceId)
+ if operation != "instantiate":
+ raise EngineException("netslice_instance '{}' cannot be '{}' because it is not instantiated".format(
+ nsiInstanceId, operation), HTTPStatus.CONFLICT)
+ else:
+ if operation == "instantiate" and not indata.get("force"):
+ raise EngineException("netslice_instance '{}' cannot be '{}' because it is already instantiated".
+ format(nsiInstanceId, operation), HTTPStatus.CONFLICT)
+
+ # Creating all the NS_operation (nslcmop)
+ # Get service list from db
+ nsrs_list = nsir["_admin"]["nsrs-detailed-list"]
+ nslcmops = []
+ for nsr_item in nsrs_list:
+ service = self.db.get_one("nsrs", {"_id": nsr_item["nsrId"]})
+ indata_ns = {}
+ indata_ns = service["instantiate_params"]
+ indata_ns["lcmOperationType"] = operation
+ indata_ns["nsInstanceId"] = service["_id"]
+ # Including netslice_id in the ns instantiate Operation
+ indata_ns["netsliceInstanceId"] = nsiInstanceId
+ del indata_ns["key-pair-ref"]
+ nsi_NsLcmOpTopic = NsLcmOpTopic(self.db, self.fs, self.msg)
+ # Creating NS_LCM_OP with the flag slice_object=True to not trigger the service instantiation
+ # message via kafka bus
+ nslcmop = nsi_NsLcmOpTopic.new(rollback, session, indata_ns, kwargs, headers, force, slice_object=True)
+ nslcmops.append(nslcmop)
+
+ # Creates nsilcmop
+ indata["nslcmops_ids"] = nslcmops
+ self._check_nsi_operation(session, nsir, operation, indata)
+ nsilcmop_desc = self._create_nsilcmop(session, nsiInstanceId, operation, indata)
+ self.format_on_new(nsilcmop_desc, session["project_id"], make_public=make_public)
+ _id = self.db.create("nsilcmops", nsilcmop_desc)
+ rollback.append({"topic": "nsilcmops", "_id": _id})
+ self.msg.write("nsi", operation, nsilcmop_desc)
+ return _id
+ except ValidationError as e:
+ raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
+ # except DbException as e:
+ # raise EngineException("Cannot get nsi_instance '{}': {}".format(e), HTTPStatus.NOT_FOUND)
+
+ def delete(self, session, _id, force=False, dry_run=False):
+ raise EngineException("Method delete called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
+
+ def edit(self, session, _id, indata=None, kwargs=None, force=False, content=None):
+ raise EngineException("Method edit called directly", HTTPStatus.INTERNAL_SERVER_ERROR)
diff --git a/osm_nbi/nbi.py b/osm_nbi/nbi.py
index e8f22465d8ed202c3322198704fad48dc4ebf6f3..1354f2cae797c6e7251703841285dc94e8cee4e7 100644
--- a/osm_nbi/nbi.py
+++ b/osm_nbi/nbi.py
@@ -675,9 +675,7 @@ class Server(object):
force = kwargs.pop("FORCE")
else:
force = False
-
self._check_valid_url_method(method, main_topic, version, topic, _id, item, *args)
-
if main_topic == "admin" and topic == "tokens":
return self.token(method, _id, kwargs)
@@ -712,8 +710,7 @@ class Server(object):
engine_topic = "vim_accounts"
if method == "GET":
- if item in ("nsd_content", "package_content", "artifacts", "vnfd", "nsd", "nst", "nst_content",
- "netslice_instances"):
+ if item in ("nsd_content", "package_content", "artifacts", "vnfd", "nsd", "nst", "nst_content"):
if item in ("vnfd", "nsd", "nst"):
path = "$DESCRIPTOR"
elif args:
@@ -759,14 +756,14 @@ class Server(object):
outdata = {"id": _id}
cherrypy.response.status = HTTPStatus.ACCEPTED.value
elif topic == "netslice_instances_content":
- # creates NSI
+ # creates NetSlice_Instance_record (NSIR)
_id = self.engine.new_item(rollback, session, engine_topic, indata, kwargs, force=force)
- # creates nsilcmop
+ self._set_location_header(main_topic, version, topic, _id)
indata["lcmOperationType"] = "instantiate"
indata["nsiInstanceId"] = _id
- self.engine.new_item(rollback, session, "nsilcmops", indata, None)
- self._set_location_header(main_topic, version, topic, _id)
+ self.engine.new_item(rollback, session, "nsilcmops", indata, kwargs)
outdata = {"id": _id}
+
elif topic == "netslice_instances" and item:
indata["lcmOperationType"] = item
indata["nsiInstanceId"] = _id
diff --git a/osm_nbi/tests/cirros_slice/cirros_slice.yaml b/osm_nbi/tests/cirros_slice/cirros_slice.yaml
index 3b5c963c5168f2cc78acb7acb22d1113c0ba978c..6f66c2721aa9079dad79cf95fa2bde9bff15f075 100644
--- a/osm_nbi/tests/cirros_slice/cirros_slice.yaml
+++ b/osm_nbi/tests/cirros_slice/cirros_slice.yaml
@@ -1,21 +1,17 @@
nst:
nst:
- id: cirros_nst
- name: cirros_slice_template
+ name: cirros_netslice_template
SNSSAI-identifier:
- slice-service-type: eMBB
quality-of-service:
- id: 1
netslice-subnet:
- - id: cirros_nsd_nst
- name: cirros_ns
- short-name: cirros_ns
- vendor: OSM
+ - id: cirros_nsd
is-shared-nss: 'false'
- description: Slice for osm-3.0-three 2nd-hackfest nsd2vnfs package
- version: '1.0'
- nsd-ref: cirros_2vnf_nsd
+ description: Slice example for osm-5.0
+ nsd-ref: cirros_nsd
instantiation-parameters:
- - name: cirros_2vnf_nsd
- nsdId: cirros_2vnf_nsd
+ - nsName: cirros_nsd
+ nsdId: cirros_nsd
vimAccountId: openstack_18
\ No newline at end of file
diff --git a/osm_nbi/tests/clear-all.sh b/osm_nbi/tests/clear-all.sh
index 5ba9d4bd51df8bd437270baebd7e09751283b882..c670106bbc1445535a0885120f4e6e357945f24d 100755
--- a/osm_nbi/tests/clear-all.sh
+++ b/osm_nbi/tests/clear-all.sh
@@ -66,7 +66,7 @@ then
done
fi
-for item in vim_accounts sdns nsrs vnfrs nslcmops nsds vnfds projects nsts # vims
+for item in vim_accounts sdns nsrs vnfrs nslcmops nsds vnfds projects nsts nsis nsilcmops # vims
do
curl --insecure ${OSMNBI_URL}/test/db-clear/${item}
echo " ${item}"
diff --git a/osm_nbi/tests/test.py b/osm_nbi/tests/test.py
index bcdfadf0d6ef21c1307325b0be004fae4e0c01b5..2fbc21727ea49610196e457ebdd797f0faaa2a71 100755
--- a/osm_nbi/tests/test.py
+++ b/osm_nbi/tests/test.py
@@ -1343,7 +1343,7 @@ class TestNstTemplates:
def run(self, engine, test_osm, manual_check, test_params=None):
# nst CREATE
engine.get_autorization()
- r = engine.test("NST", "Onboard NST", "POST", "/nst/v1/netslice_templates_content", headers_yaml,
+ r = engine.test("NST1", "Onboard NST", "POST", "/nst/v1/netslice_templates_content", headers_yaml,
self.nst_filenames,
201, {"Location": "/nst/v1/netslice_templates_content", "Content-Type": "application/yaml"},
"yaml")
@@ -1351,13 +1351,13 @@ class TestNstTemplates:
nst_id = location[location.rfind("/")+1:]
# nstd SHOW OSM format
- r = engine.test("NST", "Show NSTD OSM format", "GET",
- "/nst/v1/netslice_templates_content/{}".format(nst_id), headers_json, None,
+ r = engine.test("NST2", "Show NSTD OSM format", "GET",
+ "/nst/v1/netslice_templates/{}".format(nst_id), headers_json, None,
200, r_header_json, "json")
# nstd DELETE
- r = engine.test("NST", "Delete NSTD", "DELETE",
- "/nst/v1/netslice_templates_content/{}".format(nst_id), headers_json, None,
+ r = engine.test("NST3", "Delete NSTD", "DELETE",
+ "/nst/v1/netslice_templates/{}".format(nst_id), headers_json, None,
204, None, 0)
diff --git a/osm_nbi/validation.py b/osm_nbi/validation.py
index da3dd04a361a0de06ea8b89d174ee4b438821abb..62d9d22cf503c7c888b9183dc7e6576720abd61a 100644
--- a/osm_nbi/validation.py
+++ b/osm_nbi/validation.py
@@ -192,6 +192,7 @@ ns_instantiate = {
"properties": {
"lcmOperationType": string_schema,
"nsInstanceId": id_schema,
+ "netsliceInstanceId": id_schema,
"nsName": name_schema,
"nsDescription": {"oneOf": [description_schema, {"type": "null"}]},
"nsdId": id_schema,
@@ -559,6 +560,38 @@ nbi_edit_input_schemas = {
"pdus": pdu_edit_schema,
}
+# NETSLICE SCHEMAS
+nsi_instantiate = {
+ "title": "netslice action instantiate input schema",
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "object",
+ "properties": {
+ "lcmOperationType": string_schema,
+ "nsiInstanceId": id_schema,
+ "nsiName": name_schema,
+ "nsiDescription": {"oneOf": [description_schema, {"type": "null"}]},
+ "nstdId": string_schema,
+ "vimAccountId": id_schema,
+ "ssh_keys": {"type": "string"},
+ "nsi_id": id_schema,
+ "ns": {
+ "type": "array",
+ "minItems": 1,
+ "items": ns_instantiate
+ },
+ },
+ "required": ["nsiName", "nstdId", "vimAccountId"],
+ "additionalProperties": False
+}
+
+nsi_action = {
+
+}
+
+nsi_terminate = {
+
+}
+
class ValidationError(Exception):
pass