コード例 #1
0
 def _validate_input_new(self, indata, storage_params, force=False):
     indata = self.pyangbind_validation("nsds", indata, force)
     # Cross references validation in the descriptor
     # TODO validata that if contains cloud-init-file or charms, have artifacts _admin.storage."pkg-dir" is not none
     for vld in get_iterable(indata.get("vld")):
         for vnfd_cp in get_iterable(vld.get("vnfd-connection-point-ref")):
             for constituent_vnfd in get_iterable(
                     indata.get("constituent-vnfd")):
                 if vnfd_cp["member-vnf-index-ref"] == constituent_vnfd[
                         "member-vnf-index"]:
                     if vnfd_cp.get("vnfd-id-ref") and vnfd_cp[
                             "vnfd-id-ref"] != constituent_vnfd[
                                 "vnfd-id-ref"]:
                         raise EngineException(
                             "Error at vld[id='{}']:vnfd-connection-point-ref[vnfd-id-ref='{}'] "
                             "does not match constituent-vnfd[member-vnf-index='{}']:vnfd-id-ref"
                             " '{}'".format(
                                 vld["id"], vnfd_cp["vnfd-id-ref"],
                                 constituent_vnfd["member-vnf-index"],
                                 constituent_vnfd["vnfd-id-ref"]),
                             http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
                     break
             else:
                 raise EngineException(
                     "Error at vld[id='{}']:vnfd-connection-point-ref[member-vnf-index-ref='{}'] "
                     "does not match any constituent-vnfd:member-vnf-index".
                     format(vld["id"], vnfd_cp["member-vnf-index-ref"]),
                     http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
     return indata
コード例 #2
0
    def check_conflict_on_del(self, session, _id, force=False):
        """
        Check that there is not any NSD that uses this VNFD. Only NSDs belonging to this project are considered. Note
        that VNFD can be public and be used by NSD of other projects. Also check there are not deployments, or vnfr
        that uses this vnfd
        :param session:
        :param _id: vnfd inernal id
        :param force: Avoid this checking
        :return: None or raises EngineException with the conflict
        """
        if force:
            return
        descriptor = self.db.get_one("vnfds", {"_id": _id})
        descriptor_id = descriptor.get("id")
        if not descriptor_id:  # empty vnfd not uploaded
            return

        _filter = self._get_project_filter(session,
                                           write=False,
                                           show_all=False)
        # check vnfrs using this vnfd
        _filter["vnfd-id"] = _id
        if self.db.get_list("vnfrs", _filter):
            raise EngineException(
                "There is some VNFR that depends on this VNFD",
                http_code=HTTPStatus.CONFLICT)
        del _filter["vnfd-id"]
        # check NSD using this VNFD
        _filter["constituent-vnfd.ANYINDEX.vnfd-id-ref"] = descriptor_id
        if self.db.get_list("nsds", _filter):
            raise EngineException(
                "There is soame NSD that depends on this VNFD",
                http_code=HTTPStatus.CONFLICT)
コード例 #3
0
    def _check_descriptor_dependencies(self, session, descriptor, force=False):
        """
        Check that the dependent descriptors exist on a new descriptor or edition. Also checks references to vnfd
        connection points are ok
        :param session: client session information
        :param descriptor: descriptor to be inserted or edit
        :param force: if true skip dependencies checking
        :return: None or raises exception
        """
        if force:
            return
        member_vnfd_index = {}
        if descriptor.get("constituent-vnfd") and not force:
            for vnf in descriptor["constituent-vnfd"]:
                vnfd_id = vnf["vnfd-id-ref"]
                filter_q = self._get_project_filter(session,
                                                    write=False,
                                                    show_all=True)
                filter_q["id"] = vnfd_id
                vnf_list = self.db.get_list("vnfds", filter_q)
                if not vnf_list:
                    raise EngineException(
                        "Descriptor error at 'constituent-vnfd':'vnfd-id-ref'='{}' references a non "
                        "existing vnfd".format(vnfd_id),
                        http_code=HTTPStatus.CONFLICT)
                # elif len(vnf_list) > 1:
                #     raise EngineException("More than one vnfd found for id='{}'".format(vnfd_id),
                #                           http_code=HTTPStatus.CONFLICT)
                member_vnfd_index[vnf["member-vnf-index"]] = vnf_list[0]

        # Cross references validation in the descriptor and vnfd connection point validation
        for vld in get_iterable(descriptor.get("vld")):
            for referenced_vnfd_cp in get_iterable(
                    vld.get("vnfd-connection-point-ref")):
                # look if this vnfd contains this connection point
                vnfd = member_vnfd_index.get(
                    referenced_vnfd_cp["member-vnf-index-ref"])
                if not vnfd:
                    raise EngineException(
                        "Error at vld[id='{}']:vnfd-connection-point-ref[member-vnf-index-ref='{}'] "
                        "does not match any constituent-vnfd:member-vnf-index".
                        format(vld["id"],
                               referenced_vnfd_cp["member-vnf-index-ref"]),
                        http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
                for vnfd_cp in get_iterable(vnfd.get("connection-point")):
                    if referenced_vnfd_cp.get(
                            "vnfd-connection-point-ref") == vnfd_cp["name"]:
                        break
                else:
                    raise EngineException(
                        "Error at vld[id='{}']:vnfd-connection-point-ref[member-vnf-index-ref='{}']:vnfd-"
                        "connection-point-ref='{}' references a non existing conection-point:name inside vnfd '{}'"
                        .format(
                            vld["id"],
                            referenced_vnfd_cp["member-vnf-index-ref"],
                            referenced_vnfd_cp["vnfd-connection-point-ref"],
                            vnfd["id"]),
                        http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
コード例 #4
0
 def check_conflict_on_new(self, session, indata, force=False):
     if not indata.get("name"):
         raise EngineException("missing 'name'")
     # check name not exists
     if self.db.get_one(self.topic, {"name": indata.get("name")},
                        fail_on_empty=False,
                        fail_on_more=False):
         raise EngineException("name '{}' exists".format(indata["name"]),
                               HTTPStatus.CONFLICT)
コード例 #5
0
 def check_conflict_on_del(self, session, _id, force=False):
     if _id == session["project_id"]:
         raise EngineException("You cannot delete your own project",
                               http_code=HTTPStatus.CONFLICT)
     if force:
         return
     _filter = {"projects": _id}
     if self.db.get_list("users", _filter):
         raise EngineException(
             "There is some USER that contains this project",
             http_code=HTTPStatus.CONFLICT)
コード例 #6
0
    def start(self, config):
        """
        Connect to database, filesystem storage, and messaging
        :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
        :return: None
        """
        self.config = config
        # check right version of common
        if versiontuple(common_version) < versiontuple(min_common_version):
            raise EngineException(
                "Not compatible osm/common version '{}'. Needed '{}' or higher"
                .format(common_version, min_common_version))

        try:
            if not self.db:
                if config["database"]["driver"] == "mongo":
                    self.db = dbmongo.DbMongo()
                    self.db.db_connect(config["database"])
                elif config["database"]["driver"] == "memory":
                    self.db = dbmemory.DbMemory()
                    self.db.db_connect(config["database"])
                else:
                    raise EngineException(
                        "Invalid configuration param '{}' at '[database]':'driver'"
                        .format(config["database"]["driver"]))
            if not self.fs:
                if config["storage"]["driver"] == "local":
                    self.fs = fslocal.FsLocal()
                    self.fs.fs_connect(config["storage"])
                else:
                    raise EngineException(
                        "Invalid configuration param '{}' at '[storage]':'driver'"
                        .format(config["storage"]["driver"]))
            if not self.msg:
                if config["message"]["driver"] == "local":
                    self.msg = msglocal.MsgLocal()
                    self.msg.connect(config["message"])
                elif config["message"]["driver"] == "kafka":
                    self.msg = msgkafka.MsgKafka()
                    self.msg.connect(config["message"])
                else:
                    raise EngineException(
                        "Invalid configuration param '{}' at '[message]':'driver'"
                        .format(config["message"]["driver"]))

            self.write_lock = Lock()
            # create one class per topic
            for topic, topic_class in self.map_from_topic_to_class.items():
                self.map_topic[topic] = topic_class(self.db, self.fs, self.msg)
        except (DbException, FsException, MsgException) as e:
            raise EngineException(str(e), http_code=e.http_code)
コード例 #7
0
 def new_item(self,
              rollback,
              session,
              topic,
              indata=None,
              kwargs=None,
              headers=None,
              force=False):
     """
     Creates a new entry into database. For nsds and vnfds it creates an almost empty DISABLED  entry,
     that must be completed with a call to method upload_content
     :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 topic: it can be: users, projects, vim_accounts, sdns, nsrs, nsds, vnfds
     :param indata: data to be inserted
     :param kwargs: used to override the indata descriptor
     :param headers: http request headers
     :param force: If True avoid some dependence checks
     :return: _id: identity of the inserted data.
     """
     if topic not in self.map_topic:
         raise EngineException("Unknown topic {}!!!".format(topic),
                               HTTPStatus.INTERNAL_SERVER_ERROR)
     with self.write_lock:
         return self.map_topic[topic].new(rollback, session, indata, kwargs,
                                          headers, force)
コード例 #8
0
    def check_conflict_on_del(self, session, _id, force=False):
        """
        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: 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("nsts", _filter)

        # Search NSIs using NST via nst-ref
        _filter = self._get_project_filter(session,
                                           write=False,
                                           show_all=False)
        _filter["nst-ref"] = nst["id"]
        nsis_list = self.db.get_list("nsis", _filter)
        for nsi_item in nsis_list:
            if nsi_item["_admin"].get("nsiState") != "TERMINATED":
                raise EngineException(
                    "There is some NSIS that depends on this NST",
                    http_code=HTTPStatus.CONFLICT)
コード例 #9
0
 def upload_content(self,
                    session,
                    topic,
                    _id,
                    indata,
                    kwargs,
                    headers,
                    force=False):
     """
     Upload content for an already created entry (_id)
     :param session: contains the used login username and working project
     :param topic: it can be: users, projects, vnfds, nsds,
     :param _id: server id of the item
     :param indata: data to be inserted
     :param kwargs: used to override the indata descriptor
     :param headers: http request headers
     :param force: If True avoid some dependence checks
     :return: _id: identity of the inserted data.
     """
     if topic not in self.map_topic:
         raise EngineException("Unknown topic {}!!!".format(topic),
                               HTTPStatus.INTERNAL_SERVER_ERROR)
     with self.write_lock:
         return self.map_topic[topic].upload_content(
             session, _id, indata, kwargs, headers, force)
コード例 #10
0
    def upgrade_db(self, current_version, target_version):
        if not target_version or current_version == target_version:
            return
        if target_version == '1.0':
            if not current_version:
                # create database version
                serial = urandom(32)
                version_data = {
                    "_id": 'version',  # Always 'version'
                    "version_int": 1000,  # version number
                    "version": '1.0',  # version text
                    "date": "2018-10-25",  # version date
                    "description": "added serial",  # changes in this version
                    'status':
                    'ENABLED',  # ENABLED, DISABLED (migration in process), ERROR,
                    'serial': b64encode(serial)
                }
                self.db.create("admin", version_data)
                self.db.set_secret_key(serial)
                return
            # TODO add future migrations here

        raise EngineException("Wrong database version '{}'. Expected '{}'"
                              ". It cannot be up/down-grade".format(
                                  current_version, target_version),
                              http_code=HTTPStatus.INTERNAL_SERVER_ERROR)
コード例 #11
0
    def init_db(self, target_version='1.0'):
        """
        Init database if empty. If not empty it checks that database version and migrates if needed
        If empty, it creates a new user admin/admin at 'users' and a new entry at 'version'
        :param target_version: check desired database version. Migrate to it if possible or raises exception
        :return: None if ok, exception if error or if the version is different.
        """

        version_data = self.db.get_one("admin", {"_id": "version"},
                                       fail_on_empty=False,
                                       fail_on_more=True)
        # check database status is ok
        if version_data and version_data.get("status") != 'ENABLED':
            raise EngineException(
                "Wrong database status '{}'".format(version_data["status"]),
                HTTPStatus.INTERNAL_SERVER_ERROR)

        # check version
        db_version = None if not version_data else version_data.get("version")
        if db_version != target_version:
            self.upgrade_db(db_version, target_version)

        # create user admin if not exist
        self.create_admin()
        return
コード例 #12
0
    def pyangbind_validation(self, item, data, force=False):
        try:
            if item == "vnfds":
                myvnfd = vnfd_im()
                pybindJSONDecoder.load_ietf_json(
                    {'vnfd:vnfd-catalog': {
                        'vnfd': [data]
                    }},
                    None,
                    None,
                    obj=myvnfd,
                    path_helper=True,
                    skip_unknown=force)
                out = pybindJSON.dumps(myvnfd, mode="ietf")
            elif item == "nsds":
                mynsd = nsd_im()
                pybindJSONDecoder.load_ietf_json(
                    {'nsd:nsd-catalog': {
                        'nsd': [data]
                    }},
                    None,
                    None,
                    obj=mynsd,
                    path_helper=True,
                    skip_unknown=force)
                out = pybindJSON.dumps(mynsd, mode="ietf")
            elif item == "nsts":
                mynst = nst_im()
                pybindJSONDecoder.load_ietf_json({'nst': [data]},
                                                 None,
                                                 None,
                                                 obj=mynst,
                                                 path_helper=True,
                                                 skip_unknown=force)
                out = pybindJSON.dumps(mynst, mode="ietf")
            else:
                raise EngineException(
                    "Not possible to validate '{}' item".format(item),
                    http_code=HTTPStatus.INTERNAL_SERVER_ERROR)

            desc_out = self._remove_envelop(yaml.safe_load(out))
            return desc_out

        except Exception as e:
            raise EngineException("Error in pyangbind validation: {}".format(
                str(e)),
                                  http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
コード例 #13
0
    def _remove_envelop(indata=None):
        if not indata:
            return {}
        clean_indata = indata

        if clean_indata.get('nst'):
            if not isinstance(clean_indata['nst'],
                              list) or len(clean_indata['nst']) != 1:
                raise EngineException("'nst' must be a list only one element")
            clean_indata = clean_indata['nst'][0]
        elif clean_indata.get('nst:nst'):
            if not isinstance(clean_indata['nst:nst'],
                              list) or len(clean_indata['nst:nst']) != 1:
                raise EngineException(
                    "'nst:nst' must be a list only one element")
            clean_indata = clean_indata['nst:nst'][0]
        return clean_indata
コード例 #14
0
 def check_conflict_on_del(self, session, _id, force=False):
     if force:
         return
     # TODO Is it needed to check descriptors _admin.project_read/project_write??
     _filter = {"vdur.pdu-id": _id}
     if self.db.get_list("vnfrs", _filter):
         raise EngineException("There is some NSR that uses this PDU",
                               http_code=HTTPStatus.CONFLICT)
コード例 #15
0
 def check_conflict_on_new(self, session, indata, force=False):
     # check username not exists
     if self.db.get_one(self.topic, {"username": indata.get("username")},
                        fail_on_empty=False,
                        fail_on_more=False):
         raise EngineException(
             "username '{}' exists".format(indata["username"]),
             HTTPStatus.CONFLICT)
     # check projects
     if not force:
         for p in indata["projects"]:
             if p == "admin":
                 continue
             if not self.db.get_one("projects", {"_id": p},
                                    fail_on_empty=False,
                                    fail_on_more=False):
                 raise EngineException(
                     "project '{}' does not exists".format(p),
                     HTTPStatus.CONFLICT)
コード例 #16
0
 def stop(self):
     try:
         if self.db:
             self.db.db_disconnect()
         if self.fs:
             self.fs.fs_disconnect()
         if self.msg:
             self.msg.disconnect()
         self.write_lock = None
     except (DbException, FsException, MsgException) as e:
         raise EngineException(str(e), http_code=e.http_code)
コード例 #17
0
 def _remove_envelop(indata=None):
     if not indata:
         return {}
     clean_indata = indata
     if clean_indata.get('vnfd:vnfd-catalog'):
         clean_indata = clean_indata['vnfd:vnfd-catalog']
     elif clean_indata.get('vnfd-catalog'):
         clean_indata = clean_indata['vnfd-catalog']
     if clean_indata.get('vnfd'):
         if not isinstance(clean_indata['vnfd'],
                           list) or len(clean_indata['vnfd']) != 1:
             raise EngineException(
                 "'vnfd' must be a list of only one element")
         clean_indata = clean_indata['vnfd'][0]
     elif clean_indata.get('vnfd:vnfd'):
         if not isinstance(clean_indata['vnfd:vnfd'],
                           list) or len(clean_indata['vnfd:vnfd']) != 1:
             raise EngineException(
                 "'vnfd:vnfd' must be a list of only one element")
         clean_indata = clean_indata['vnfd:vnfd'][0]
     return clean_indata
コード例 #18
0
 def get_item_list(self, session, topic, filter_q=None):
     """
     Get a list of items
     :param session: contains the used login username and working project
     :param topic: it can be: users, projects, vnfds, nsds, ...
     :param filter_q: filter of data to be applied
     :return: The list, it can be empty if no one match the filter_q.
     """
     if topic not in self.map_topic:
         raise EngineException("Unknown topic {}!!!".format(topic),
                               HTTPStatus.INTERNAL_SERVER_ERROR)
     return self.map_topic[topic].list(session, filter_q)
コード例 #19
0
 def get_item(self, session, topic, _id):
     """
     Get complete information on an item
     :param session: contains the used login username and working project
     :param topic: it can be: users, projects, vnfds, nsds,
     :param _id: server id of the item
     :return: dictionary, raise exception if not found.
     """
     if topic not in self.map_topic:
         raise EngineException("Unknown topic {}!!!".format(topic),
                               HTTPStatus.INTERNAL_SERVER_ERROR)
     return self.map_topic[topic].show(session, _id)
コード例 #20
0
 def del_item_list(self, session, topic, _filter=None):
     """
     Delete a list of items
     :param session: contains the used login username and working project
     :param topic: it can be: users, projects, vnfds, nsds, ...
     :param _filter: filter of data to be applied
     :return: The deleted list, it can be empty if no one match the _filter.
     """
     if topic not in self.map_topic:
         raise EngineException("Unknown topic {}!!!".format(topic),
                               HTTPStatus.INTERNAL_SERVER_ERROR)
     with self.write_lock:
         return self.map_topic[topic].delete_list(session, _filter)
コード例 #21
0
 def del_item(self, session, topic, _id, force=False):
     """
     Delete item by its internal id
     :param session: contains the used login username and working project
     :param topic: it can be: users, projects, vnfds, nsds, ...
     :param _id: server id of the item
     :param force: indicates if deletion must be forced in case of conflict
     :return: dictionary with deleted item _id. It raises exception if not found.
     """
     if topic not in self.map_topic:
         raise EngineException("Unknown topic {}!!!".format(topic),
                               HTTPStatus.INTERNAL_SERVER_ERROR)
     with self.write_lock:
         return self.map_topic[topic].delete(session, _id, force)
コード例 #22
0
 def get_file(self, session, topic, _id, path=None, accept_header=None):
     """
     Get descriptor package or artifact file content
     :param session: contains the used login username and working project
     :param topic: it can be: users, projects, vnfds, nsds,
     :param _id: server id of the item
     :param path: artifact path or "$DESCRIPTOR" or None
     :param accept_header: Content of Accept header. Must contain applition/zip or/and text/plain
     :return: opened file plus Accept format or raises an exception
     """
     if topic not in self.map_topic:
         raise EngineException("Unknown topic {}!!!".format(topic),
                               HTTPStatus.INTERNAL_SERVER_ERROR)
     return self.map_topic[topic].get_file(session, _id, path,
                                           accept_header)
コード例 #23
0
 def edit(self,
          session,
          _id,
          indata=None,
          kwargs=None,
          force=False,
          content=None):
     if not session["admin"]:
         raise EngineException("needed admin privileges",
                               http_code=HTTPStatus.UNAUTHORIZED)
     return BaseTopic.edit(self,
                           session,
                           _id,
                           indata=indata,
                           kwargs=kwargs,
                           force=force,
                           content=content)
コード例 #24
0
 def check_conflict_on_del(self, session, _id, force=False):
     """
     Check that there is not any NSR that uses this NSD. Only NSRs belonging to this project are considered. Note
     that NSD can be public and be used by other projects.
     :param session:
     :param _id: vnfd inernal id
     :param force: Avoid this checking
     :return: None or raises EngineException with the conflict
     """
     if force:
         return
     _filter = self._get_project_filter(session,
                                        write=False,
                                        show_all=False)
     _filter["nsdId"] = _id
     if self.db.get_list("nsrs", _filter):
         raise EngineException("There is some NSR that depends on this NSD",
                               http_code=HTTPStatus.CONFLICT)
コード例 #25
0
    def new(self,
            rollback,
            session,
            indata=None,
            kwargs=None,
            headers=None,
            force=False,
            make_public=False):
        """
        Creates a new almost empty DISABLED  entry into database. Due to SOL005, it does not follow normal procedure.
        Creating a VNFD or NSD is done in two steps: 1. Creates an empty descriptor (this step) and 2) upload content
        (self.upload_content)
        :param rollback: list to append created items at database in case a rollback may to be done
        :param session: contains the used login username and working project
        :param indata: data to be inserted
        :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 descriptor public to all projects
        :return: _id: identity of the inserted data.
        """

        try:
            # _remove_envelop
            if indata:
                if "userDefinedData" in indata:
                    indata = indata['userDefinedData']

            # Override descriptor with query string kwargs
            self._update_input_with_kwargs(indata, kwargs)
            # uncomment when this method is implemented.
            # Avoid override in this case as the target is userDefinedData, but not vnfd,nsd descriptors
            # indata = DescriptorTopic._validate_input_new(self, indata, force=force)

            content = {"_admin": {"userDefinedData": indata}}
            self.format_on_new(content,
                               session["project_id"],
                               make_public=make_public)
            _id = self.db.create(self.topic, content)
            rollback.append({"topic": self.topic, "_id": _id})
            return _id
        except ValidationError as e:
            raise EngineException(e, HTTPStatus.UNPROCESSABLE_ENTITY)
コード例 #26
0
 def new(self,
         rollback,
         session,
         indata=None,
         kwargs=None,
         headers=None,
         force=False,
         make_public=False):
     if not session["admin"]:
         raise EngineException("needed admin privileges",
                               http_code=HTTPStatus.UNAUTHORIZED)
     return BaseTopic.new(self,
                          rollback,
                          session,
                          indata=indata,
                          kwargs=kwargs,
                          headers=headers,
                          force=force,
                          make_public=make_public)
コード例 #27
0
 def _check_descriptor_dependencies(self, session, descriptor):
     """
     Check that the dependent descriptors exist on a new descriptor or edition
     :param session: client session information
     :param descriptor: descriptor to be inserted or edit
     :return: None or raises exception
     """
     if not descriptor.get("netslice-subnet"):
         return
     for nsd in descriptor["netslice-subnet"]:
         nsd_id = nsd["nsd-ref"]
         filter_q = self._get_project_filter(session,
                                             write=False,
                                             show_all=True)
         filter_q["id"] = nsd_id
         if not self.db.get_list("nsds", filter_q):
             raise EngineException(
                 "Descriptor error at 'netslice-subnet':'nsd-ref'='{}' references a non "
                 "existing nsd".format(nsd_id),
                 http_code=HTTPStatus.CONFLICT)
コード例 #28
0
 def edit_item(self,
               session,
               topic,
               _id,
               indata=None,
               kwargs=None,
               force=False):
     """
     Update an existing entry at database
     :param session: contains the used login username and working project
     :param topic: it can be: users, projects, vnfds, nsds, ...
     :param _id: identifier to be updated
     :param indata: data to be inserted
     :param kwargs: used to override the indata descriptor
     :param force: If True avoid some dependence checks
     :return: dictionary, raise exception if not found.
     """
     if topic not in self.map_topic:
         raise EngineException("Unknown topic {}!!!".format(topic),
                               HTTPStatus.INTERNAL_SERVER_ERROR)
     with self.write_lock:
         return self.map_topic[topic].edit(session, _id, indata, kwargs,
                                           force)
コード例 #29
0
    def check_conflict_on_edit(self,
                               session,
                               final_content,
                               edit_content,
                               _id,
                               force=False):
        # 1. validate again with pyangbind
        # 1.1. remove internal keys
        internal_keys = {}
        for k in ("_id", "_admin"):
            if k in final_content:
                internal_keys[k] = final_content.pop(k)
        storage_params = internal_keys["_admin"].get("storage")
        serialized = self._validate_input_new(final_content, storage_params,
                                              force)
        # 1.2. modify final_content with a serialized version
        final_content.clear()
        final_content.update(serialized)
        # 1.3. restore internal keys
        for k, v in internal_keys.items():
            final_content[k] = v

        if force:
            return
        # 2. check that this id is not present
        if "id" in edit_content:
            _filter = self._get_project_filter(session,
                                               write=False,
                                               show_all=False)
            _filter["id"] = final_content["id"]
            _filter["_id.neq"] = _id
            if self.db.get_one(self.topic, _filter, fail_on_empty=False):
                raise EngineException(
                    "{} with id '{}' already exists for this project".format(
                        self.topic[:-1], final_content["id"]),
                    HTTPStatus.CONFLICT)
コード例 #30
0
    def _validate_input_new(self, indata, storage_params, force=False):
        indata = self.pyangbind_validation("vnfds", indata, force)
        # Cross references validation in the descriptor
        if indata.get("vdu"):
            if not indata.get("mgmt-interface"):
                raise EngineException(
                    "'mgmt-interface' is a mandatory field and it is not defined",
                    http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
            if indata["mgmt-interface"].get("cp"):
                for cp in get_iterable(indata.get("connection-point")):
                    if cp["name"] == indata["mgmt-interface"]["cp"]:
                        break
                else:
                    raise EngineException(
                        "mgmt-interface:cp='{}' must match an existing connection-point"
                        .format(indata["mgmt-interface"]["cp"]),
                        http_code=HTTPStatus.UNPROCESSABLE_ENTITY)

        for vdu in get_iterable(indata.get("vdu")):
            for interface in get_iterable(vdu.get("interface")):
                if interface.get("external-connection-point-ref"):
                    for cp in get_iterable(indata.get("connection-point")):
                        if cp["name"] == interface[
                                "external-connection-point-ref"]:
                            break
                    else:
                        raise EngineException(
                            "vdu[id='{}']:interface[name='{}']:external-connection-point-ref='{}' "
                            "must match an existing connection-point".format(
                                vdu["id"], interface["name"],
                                interface["external-connection-point-ref"]),
                            http_code=HTTPStatus.UNPROCESSABLE_ENTITY)

                elif interface.get("internal-connection-point-ref"):
                    for internal_cp in get_iterable(
                            vdu.get("internal-connection-point")):
                        if interface[
                                "internal-connection-point-ref"] == internal_cp.get(
                                    "id"):
                            break
                    else:
                        raise EngineException(
                            "vdu[id='{}']:interface[name='{}']:internal-connection-point-ref='{}' "
                            "must match an existing vdu:internal-connection-point"
                            .format(
                                vdu["id"], interface["name"],
                                interface["internal-connection-point-ref"]),
                            http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
            # Validate that if descriptor contains charms, artifacts _admin.storage."pkg-dir" is not none
            if vdu.get("vdu-configuration"):
                if vdu["vdu-configuration"].get("juju"):
                    if not self._validate_package_folders(
                            storage_params, 'charms'):
                        raise EngineException(
                            "Charm defined in vnf[id={}]:vdu[id={}] but not present in "
                            "package".format(indata["id"], vdu["id"]))
            # Validate that if descriptor contains cloud-init, artifacts _admin.storage."pkg-dir" is not none
            if vdu.get("cloud-init-file"):
                if not self._validate_package_folders(
                        storage_params, 'cloud_init', vdu["cloud-init-file"]):
                    raise EngineException(
                        "Cloud-init defined in vnf[id={}]:vdu[id={}] but not present in "
                        "package".format(indata["id"], vdu["id"]))
        # Validate that if descriptor contains charms, artifacts _admin.storage."pkg-dir" is not none
        if indata.get("vnf-configuration"):
            if indata["vnf-configuration"].get("juju"):
                if not self._validate_package_folders(storage_params,
                                                      'charms'):
                    raise EngineException(
                        "Charm defined in vnf[id={}] but not present in "
                        "package".format(indata["id"]))
        for ivld in get_iterable(indata.get("internal-vld")):
            for icp in get_iterable(ivld.get("internal-connection-point")):
                icp_mark = False
                for vdu in get_iterable(indata.get("vdu")):
                    for internal_cp in get_iterable(
                            vdu.get("internal-connection-point")):
                        if icp["id-ref"] == internal_cp["id"]:
                            icp_mark = True
                            break
                    if icp_mark:
                        break
                else:
                    raise EngineException(
                        "internal-vld[id='{}']:internal-connection-point='{}' must match an existing "
                        "vdu:internal-connection-point".format(
                            ivld["id"], icp["id-ref"]),
                        http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
            if ivld.get("ip-profile-ref"):
                for ip_prof in get_iterable(indata.get("ip-profiles")):
                    if ip_prof["name"] == get_iterable(
                            ivld.get("ip-profile-ref")):
                        break
                else:
                    raise EngineException(
                        "internal-vld[id='{}']:ip-profile-ref='{}' does not exist"
                        .format(ivld["id"], ivld["ip-profile-ref"]),
                        http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
        for mp in get_iterable(indata.get("monitoring-param")):
            if mp.get("vdu-monitoring-param"):
                mp_vmp_mark = False
                for vdu in get_iterable(indata.get("vdu")):
                    for vmp in get_iterable(vdu.get("monitoring-param")):
                        if vmp["id"] == mp["vdu-monitoring-param"].get("vdu-monitoring-param-ref") and vdu["id"] ==\
                                mp["vdu-monitoring-param"]["vdu-ref"]:
                            mp_vmp_mark = True
                            break
                    if mp_vmp_mark:
                        break
                else:
                    raise EngineException(
                        "monitoring-param:vdu-monitoring-param:vdu-monitoring-param-ref='{}' not "
                        "defined at vdu[id='{}'] or vdu does not exist".format(
                            mp["vdu-monitoring-param"]
                            ["vdu-monitoring-param-ref"],
                            mp["vdu-monitoring-param"]["vdu-ref"]),
                        http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
            elif mp.get("vdu-metric"):
                mp_vm_mark = False
                for vdu in get_iterable(indata.get("vdu")):
                    if vdu.get("vdu-configuration"):
                        for metric in get_iterable(
                                vdu["vdu-configuration"].get("metrics")):
                            if metric["name"] == mp["vdu-metric"]["vdu-metric-name-ref"] and vdu["id"] == \
                                    mp["vdu-metric"]["vdu-ref"]:
                                mp_vm_mark = True
                                break
                        if mp_vm_mark:
                            break
                else:
                    raise EngineException(
                        "monitoring-param:vdu-metric:vdu-metric-name-ref='{}' not defined at "
                        "vdu[id='{}'] or vdu does not exist".format(
                            mp["vdu-metric"]["vdu-metric-name-ref"],
                            mp["vdu-metric"]["vdu-ref"]),
                        http_code=HTTPStatus.UNPROCESSABLE_ENTITY)

        for sgd in get_iterable(indata.get("scaling-group-descriptor")):
            for sp in get_iterable(sgd.get("scaling-policy")):
                for sc in get_iterable(sp.get("scaling-criteria")):
                    for mp in get_iterable(indata.get("monitoring-param")):
                        if mp["id"] == get_iterable(
                                sc.get("vnf-monitoring-param-ref")):
                            break
                    else:
                        raise EngineException(
                            "scaling-group-descriptor[name='{}']:scaling-criteria[name='{}']:"
                            "vnf-monitoring-param-ref='{}' not defined in any monitoring-param"
                            .format(sgd["name"], sc["name"],
                                    sc["vnf-monitoring-param-ref"]),
                            http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
            for sgd_vdu in get_iterable(sgd.get("vdu")):
                sgd_vdu_mark = False
                for vdu in get_iterable(indata.get("vdu")):
                    if vdu["id"] == sgd_vdu["vdu-id-ref"]:
                        sgd_vdu_mark = True
                        break
                if sgd_vdu_mark:
                    break
            else:
                raise EngineException(
                    "scaling-group-descriptor[name='{}']:vdu-id-ref={} does not match any vdu"
                    .format(sgd["name"], sgd_vdu["vdu-id-ref"]),
                    http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
            for sca in get_iterable(sgd.get("scaling-config-action")):
                if not indata.get("vnf-configuration"):
                    raise EngineException(
                        "'vnf-configuration' not defined in the descriptor but it is referenced by "
                        "scaling-group-descriptor[name='{}']:scaling-config-action"
                        .format(sgd["name"]),
                        http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
                for primitive in get_iterable(
                        indata["vnf-configuration"].get("config-primitive")):
                    if primitive["name"] == sca[
                            "vnf-config-primitive-name-ref"]:
                        break
                else:
                    raise EngineException(
                        "scaling-group-descriptor[name='{}']:scaling-config-action:vnf-config-"
                        "primitive-name-ref='{}' does not match any "
                        "vnf-configuration:config-primitive:name".format(
                            sgd["name"], sca["vnf-config-primitive-name-ref"]),
                        http_code=HTTPStatus.UNPROCESSABLE_ENTITY)
        return indata