def update_object(self,
                      data: (dict, CmdbObject),
                      user: UserModel = None,
                      permission: AccessControlPermission = None) -> str:

        if isinstance(data, dict):
            update_object = CmdbObject(**data)
        elif isinstance(data, CmdbObject):
            update_object = data
        else:
            raise ObjectManagerUpdateError(
                'Wrong CmdbObject init format - expecting CmdbObject or dict')
        update_object.last_edit_time = datetime.utcnow()
        if user:
            update_object.editor_id = user.public_id

        type_ = self._type_manager.get(update_object.type_id)
        verify_access(type_, user, permission)

        ack = self._update(collection=CmdbObject.COLLECTION,
                           public_id=update_object.get_public_id(),
                           data=update_object.__dict__)
        # create cmdb.core.object.updated event
        if self._event_queue and user:
            event = Event(
                "cmdb.core.object.updated", {
                    "id": update_object.get_public_id(),
                    "type_id": update_object.get_type_id(),
                    "user_id": user.get_public_id()
                })
            self._event_queue.put(event)
        return ack.acknowledged
Example #2
0
def delete_job(public_id: int, request_user: UserModel):
    try:
        try:
            job_instance = exportd_manager.get_job(public_id)
            log_params = {
                'job_id': job_instance.get_public_id(),
                'state': True,
                'user_id': request_user.get_public_id(),
                'user_name': request_user.get_display_name(),
                'event': LogAction.DELETE.name,
                'message': '',
            }
            log_manager.insert_log(action=LogAction.DELETE,
                                   log_type=ExportdJobLog.__name__,
                                   **log_params)
        except (ExportdJobManagerGetError, LogManagerInsertError) as err:
            LOGGER.error(err)
            return abort(404)

        ack = exportd_manager.delete_job(public_id=public_id,
                                         request_user=request_user)
    except ExportdJobManagerDeleteError:
        return abort(400)
    except CMDBError:
        return abort(500)
    resp = make_response(ack)
    return resp
Example #3
0
 def update_template(self, data: (dict, DocapiTemplate),
                     request_user: UserModel) -> str:
     """
     Update new DocapiTemplat Object
     Args:
         data: init data
         request_user: current user, to detect who triggered event
     Returns:
         Public ID of the DocapiTemplate in database
     """
     if isinstance(data, dict):
         update_object = DocapiTemplate(**data)
     elif isinstance(data, DocapiTemplate):
         update_object = data
     else:
         raise DocapiTemplateManagerUpdateError(
             f'Could not update template with ID: {data.get_public_id()}')
     update_object.last_execute_date = datetime.utcnow()
     ack = self._update(collection=DocapiTemplate.COLLECTION,
                        public_id=update_object.get_public_id(),
                        data=update_object.to_database())
     if self._event_queue:
         event = Event(
             "cmdb.docapi.updated", {
                 "id": update_object.get_public_id(),
                 "active": update_object.get_active(),
                 "user_id": request_user.get_public_id()
             })
         self._event_queue.put(event)
     return ack.acknowledged
Example #4
0
 def run_job_manual(self, public_id: int, request_user: UserModel) -> bool:
     if self._event_queue:
         event = Event("cmdb.exportd.run_manual", {"id": public_id,
                                                   "user_id": request_user.get_public_id(),
                                                   "event": 'manuel'})
         self._event_queue.put(event)
     return True
Example #5
0
 def delete_object(self,
                   public_id: int,
                   user: UserModel,
                   permission: AccessControlPermission = None):
     type_id = self.get_object(public_id=public_id).type_id
     type_ = self._type_manager.get(type_id)
     if not type_.active:
         raise AccessDeniedError(
             f'Objects cannot be removed because type `{type_.name}` is deactivated.'
         )
     verify_access(type_, user, permission)
     try:
         if self._event_queue:
             event = Event(
                 "cmdb.core.object.deleted", {
                     "id": public_id,
                     "type_id": self.get_object(public_id).get_type_id(),
                     "user_id": user.get_public_id(),
                     "event": 'delete'
                 })
             self._event_queue.put(event)
         ack = self._delete(CmdbObject.COLLECTION, public_id)
         return ack
     except (CMDBError, Exception):
         raise ObjectDeleteError(msg=public_id)
Example #6
0
def update_file(request_user: UserModel):
    """ This method updates a file to the specified section in the document.
        Any existing value that matches the file name and metadata is taken into account.
        Furthermore, it is checked whether the current file name already exists in the directory.
        If this is the case, 'copy_(index)_' is appended as prefix. The method is executed recursively.
        Exception, if the parameter 'attachment' is passed with the value '{reference':true}', the name is not checked.

        Note:
            Create a unique media file element:
             - Folders in the same directory are unique.
             - The folder name can exist in different directories

            Create sub-folders:
             - Selected folder is considered as parent folder

            This also applies to files

        Changes:
            Is stored under 'request.json'

        Raises:
            MediaFileManagerUpdateError: If something went wrong during update.

        Args:
            Args:
            request_user (User): the instance of the started user (last modifier)

        Returns: MediaFile as JSON

        """
    try:
        add_data_dump = json.dumps(request.json)
        new_file_data = json.loads(add_data_dump,
                                   object_hook=json_util.object_hook)
        reference_attachment = json.loads(request.args.get('attachment'))

        data = media_file_manager.get_file(
            metadata={'public_id': new_file_data['public_id']})
        data['public_id'] = new_file_data['public_id']
        data['filename'] = new_file_data['filename']
        data['metadata'] = new_file_data['metadata']
        data['metadata']['author_id'] = new_file_data['metadata'][
            'author_id'] = request_user.get_public_id()

        # Check if file / folder exist in folder
        if not reference_attachment['reference']:
            checker = {
                'filename': new_file_data['filename'],
                'metadata.parent': new_file_data['metadata']['parent']
            }
            copied_name = create_attachment_name(new_file_data['filename'], 0,
                                                 checker, media_file_manager)
            data['filename'] = copied_name

        media_file_manager.updata_file(data)
    except MediaFileManagerUpdateError:
        return abort(500)

    resp = make_response(data)
    return resp
Example #7
0
def worker(job: ExportdJob, request_user: UserModel):
    from flask import make_response as make_res
    from cmdb.exportd.exporter_base import ExportdManagerBase
    from cmdb.event_management.event import Event

    try:
        event = Event(
            "cmdb.exportd.run_manual", {
                "id": job.get_public_id(),
                "user_id": request_user.get_public_id(),
                "event": 'manuel'
            })

        content = ExportdManagerBase(job, object_manager, log_manager,
                                     event).execute(
                                         request_user.public_id,
                                         request_user.get_display_name(),
                                         False)
        response = make_res(content.data, content.status)
        response.headers['Content-Type'] = '%s; charset=%s' % (
            content.mimetype, content.charset)
        return response
    except Exception as err:
        LOGGER.error(err)
        return abort(404)
Example #8
0
 def update_job(self, data: (dict, ExportdJob), request_user: UserModel, event_start=True) -> str:
     """
     Update new ExportdJob Object
     Args:
         data: init data
         request_user: current user, to detect who triggered event
         event_start: Controls whether an event should be started
     Returns:
         Public ID of the ExportdJob in database
     """
     if isinstance(data, dict):
         update_object = ExportdJob(**data)
     elif isinstance(data, ExportdJob):
         update_object = data
     else:
         raise ExportdJobManagerUpdateError(f'Could not update job with ID: {data.get_public_id()}')
     update_object.last_execute_date = datetime.utcnow()
     ack = self._update(
         collection=ExportdJob.COLLECTION,
         public_id=update_object.get_public_id(),
         data=update_object.to_database()
     )
     if self._event_queue and event_start:
         event = Event("cmdb.exportd.updated", {"id": update_object.get_public_id(),
                                                "active": update_object.scheduling["event"]["active"] and update_object.get_active(),
                                                "user_id": request_user.get_public_id()})
         self._event_queue.put(event)
     return ack.acknowledged
 def delete_many_objects(self, filter_query: dict, public_ids, user: UserModel):
     ack = self._delete_many(CmdbObject.COLLECTION, filter_query)
     if self._event_queue:
         event = Event("cmdb.core.objects.deleted", {"ids": public_ids,
                                                     "user_id": user.get_public_id(),
                                                     "event": 'delete'})
         self._event_queue.put(event)
     return ack
Example #10
0
def delete_object(public_id: int, request_user: UserModel):
    try:
        current_object_instance = object_manager.get_object(public_id)
        current_type_instance = object_manager.get_type(
            current_object_instance.get_type_id())
        current_object_render_result = CmdbRender(
            object_instance=current_object_instance,
            object_manager=object_manager,
            type_instance=current_type_instance,
            render_user=request_user).result()
    except ObjectManagerGetError as err:
        LOGGER.error(err)
        return abort(404)
    except RenderError as err:
        LOGGER.error(err)
        return abort(500)

    try:
        ack = object_manager.delete_object(
            public_id=public_id,
            user=request_user,
            permission=AccessControlPermission.DELETE)
    except ObjectManagerGetError as err:
        return abort(400, err.message)
    except AccessDeniedError as err:
        return abort(403, err.message)
    except ObjectDeleteError:
        return abort(400)
    except CMDBError:
        return abort(500)

    try:
        # generate log
        log_data = {
            'object_id':
            public_id,
            'version':
            current_object_render_result.object_information['version'],
            'user_id':
            request_user.get_public_id(),
            'user_name':
            request_user.get_display_name(),
            'comment':
            'Object was deleted',
            'render_state':
            json.dumps(current_object_render_result,
                       default=default).encode('UTF-8')
        }
        log_manager.insert(action=LogAction.DELETE,
                           log_type=CmdbObjectLog.__name__,
                           **log_data)
    except (CMDBError, LogManagerInsertError) as err:
        LOGGER.error(err)

    resp = make_response(ack)
    return resp
Example #11
0
 def delete_template(self, public_id: int, request_user: UserModel) -> bool:
     try:
         ack = self._delete(collection=DocapiTemplate.COLLECTION, public_id=public_id)
         if self._event_queue:
             event = Event("cmdb.docapi.deleted", {"id": public_id, "active": False,
                                                   "user_id": request_user.get_public_id()})
             self._event_queue.put(event)
         return ack
     except Exception:
         raise DocapiTemplateManagerDeleteError(f'Could not delete template with ID: {public_id}')
Example #12
0
 def delete_job(self, public_id: int, request_user: UserModel) -> bool:
     try:
         ack = self._delete(collection=ExportdJob.COLLECTION, public_id=public_id)
         if self._event_queue:
             event = Event("cmdb.exportd.deleted", {"id": public_id, "active": False,
                                                    "user_id": request_user.get_public_id()})
             self._event_queue.put(event)
         return ack
     except Exception:
         raise ExportdJobManagerDeleteError(f'Could not delete job with ID: {public_id}')
def add_job(request_user: UserModel):
    from bson import json_util
    add_data_dump = json.dumps(request.json)
    try:
        new_job_data = json.loads(add_data_dump,
                                  object_hook=json_util.object_hook)
        new_job_data['public_id'] = exportd_manager.get_new_id(
            ExportdJob.COLLECTION)
        new_job_data['last_execute_date'] = datetime.utcnow()
        new_job_data['author_id'] = request_user.get_public_id()
        new_job_data['author_name'] = request_user.get_display_name()
        new_job_data['state'] = ExecuteState.SUCCESSFUL.name
    except TypeError as e:
        LOGGER.warning(e)
        abort(400)
    try:
        job_instance = ExportdJob(**new_job_data)
    except CMDBError as e:
        LOGGER.debug(e)
        return abort(400)
    try:
        ack = exportd_manager.insert_job(job_instance)
    except ExportdJobManagerInsertError:
        return abort(500)

    # Generate new insert log
    try:
        log_params = {
            'job_id': job_instance.get_public_id(),
            'state': True,
            'user_id': request_user.get_public_id(),
            'user_name': request_user.get_display_name(),
            'event': LogAction.CREATE.name,
            'message': '',
        }
        log_manager.insert_log(action=LogAction.CREATE,
                               log_type=ExportdJobLog.__name__,
                               **log_params)
    except LogManagerInsertError as err:
        LOGGER.error(err)

    resp = make_response(ack)
    return resp
 def delete_object(self,
                   public_id: int,
                   user: UserModel,
                   permission: AccessControlPermission = None):
     type_id = self.get_object(public_id=public_id).type_id
     type_ = self._type_manager.get(type_id)
     verify_access(type_, user, permission)
     try:
         if self._event_queue:
             event = Event(
                 "cmdb.core.object.deleted", {
                     "id": public_id,
                     "type_id": self.get_object(public_id).get_type_id(),
                     "user_id": user.get_public_id()
                 })
             self._event_queue.put(event)
         ack = self._delete(CmdbObject.COLLECTION, public_id)
         return ack
     except (CMDBError, Exception):
         raise ObjectDeleteError(msg=public_id)
Example #15
0
def update_job(request_user: UserModel):
    from bson import json_util
    add_data_dump = json.dumps(request.json)
    new_job_data = None
    try:
        new_job_data = json.loads(add_data_dump,
                                  object_hook=json_util.object_hook)
    except TypeError as e:
        LOGGER.warning(e)
        abort(400)
    try:
        state = new_job_data["state"]
        update_job_instance = ExportdJob(**new_job_data)
    except CMDBError:
        return abort(400)
    try:
        exportd_manager.update_job(update_job_instance, request_user, False)
    except ExportdJobManagerUpdateError:
        return abort(500)

    # Generate new insert log
    if state not in ExecuteState.RUNNING.name:
        try:
            log_params = {
                'job_id': update_job_instance.get_public_id(),
                'state': True,
                'user_id': request_user.get_public_id(),
                'user_name': request_user.get_display_name(),
                'event': LogAction.EDIT.name,
                'message': '',
            }
            log_manager.insert_log(action=LogAction.EDIT,
                                   log_type=ExportdJobLog.__name__,
                                   **log_params)
        except LogManagerInsertError as err:
            LOGGER.error(err)

    resp = make_response(update_job_instance)
    return resp
Example #16
0
def add_template(request_user: UserModel):
    from bson import json_util
    add_data_dump = json.dumps(request.json)
    try:
        new_tpl_data = json.loads(add_data_dump,
                                  object_hook=json_util.object_hook)
        new_tpl_data['public_id'] = docapi_tpl_manager.get_new_id()
        new_tpl_data['author_id'] = request_user.get_public_id()
    except TypeError as err:
        LOGGER.warning(err)
        abort(400)
    try:
        template_instance = DocapiTemplate(**new_tpl_data)
    except CMDBError as err:
        LOGGER.debug(err)
        return abort(400)
    try:
        ack = docapi_tpl_manager.insert_template(template_instance)
    except DocapiTemplateManagerInsertError:
        return abort(500)

    resp = make_response(ack)
    return resp
Example #17
0
    def update_object(self,
                      data: (dict, CmdbObject),
                      user: UserModel = None,
                      permission: AccessControlPermission = None) -> str:

        if isinstance(data, dict):
            update_object = CmdbObject(**data)
        elif isinstance(data, CmdbObject):
            update_object = data
        else:
            raise ObjectManagerUpdateError(
                'Wrong CmdbObject init format - expecting CmdbObject or dict')
        update_object.last_edit_time = datetime.now(timezone.utc)
        if user:
            update_object.editor_id = user.public_id

        type_ = self._type_manager.get(update_object.type_id)
        if not type_.active:
            raise AccessDeniedError(
                f'Objects cannot be updated because type `{type_.name}` is deactivated.'
            )
        verify_access(type_, user, permission)

        ack = self._update(collection=CmdbObject.COLLECTION,
                           public_id=update_object.get_public_id(),
                           data=update_object.__dict__)

        if self._event_queue and user:
            event = Event(
                "cmdb.core.object.updated", {
                    "id": update_object.get_public_id(),
                    "type_id": update_object.get_type_id(),
                    "user_id": user.get_public_id(),
                    'event': 'update'
                })
            self._event_queue.put(event)
        return ack.acknowledged
Example #18
0
def update_object_state(public_id: int, request_user: UserModel):
    if isinstance(request.json, bool):
        state = request.json
    else:
        return abort(400)
    try:
        founded_object = object_manager.get_object(public_id=public_id)
    except ObjectManagerGetError as err:
        LOGGER.error(err)
        return abort(404)
    if founded_object.active == state:
        return make_response(False, 204)
    try:
        founded_object.active = state
        update_ack = object_manager.update_object(
            founded_object,
            user=request_user,
            permission=AccessControlPermission.READ)
    except AccessDeniedError as err:
        return abort(403, err.message)
    except ObjectManagerUpdateError as err:
        LOGGER.error(err)
        return abort(500)

        # get current object state
    try:
        current_type_instance = object_manager.get_type(
            founded_object.get_type_id())
        current_object_render_result = CmdbRender(
            object_instance=founded_object,
            object_manager=object_manager,
            type_instance=current_type_instance,
            render_user=request_user).result()
    except ObjectManagerGetError as err:
        LOGGER.error(err)
        return abort(404)
    except RenderError as err:
        LOGGER.error(err)
        return abort(500)
    try:
        # generate log
        change = {'old': not state, 'new': state}
        log_data = {
            'object_id':
            public_id,
            'version':
            founded_object.version,
            'user_id':
            request_user.get_public_id(),
            'user_name':
            request_user.get_display_name(),
            'render_state':
            json.dumps(current_object_render_result,
                       default=default).encode('UTF-8'),
            'comment':
            'Active status has changed',
            'changes':
            change,
        }
        log_manager.insert(action=LogAction.ACTIVE_CHANGE,
                           log_type=CmdbObjectLog.__name__,
                           **log_data)
    except (CMDBError, LogManagerInsertError) as err:
        LOGGER.error(err)

    return make_response(update_ack)
Example #19
0
def delete_many_objects(public_ids, request_user: UserModel):
    try:
        ids = []
        operator_in = {'$in': []}
        filter_public_ids = {'public_id': {}}
        for v in public_ids.split(","):
            try:
                ids.append(int(v))
            except (ValueError, TypeError):
                return abort(400)
        operator_in.update({'$in': ids})
        filter_public_ids.update({'public_id': operator_in})

        ack = []
        objects = object_manager.get_objects_by(**filter_public_ids)

        for current_object_instance in objects:
            try:
                current_type_instance = object_manager.get_type(
                    current_object_instance.get_type_id())
                current_object_render_result = CmdbRender(
                    object_instance=current_object_instance,
                    object_manager=object_manager,
                    type_instance=current_type_instance,
                    render_user=request_user).result()
            except ObjectManagerGetError as err:
                LOGGER.error(err)
                return abort(404)
            except RenderError as err:
                LOGGER.error(err)
                return abort(500)

            try:
                ack.append(
                    object_manager.delete_object(
                        public_id=current_object_instance.get_public_id(),
                        user=request_user,
                        permission=AccessControlPermission.DELETE))
            except ObjectDeleteError:
                return abort(400)
            except AccessDeniedError as err:
                return abort(403, err.message)
            except CMDBError:
                return abort(500)

            try:
                # generate log
                log_data = {
                    'object_id':
                    current_object_instance.get_public_id(),
                    'version':
                    current_object_render_result.object_information['version'],
                    'user_id':
                    request_user.get_public_id(),
                    'user_name':
                    request_user.get_display_name(),
                    'comment':
                    'Object was deleted',
                    'render_state':
                    json.dumps(current_object_render_result,
                               default=default).encode('UTF-8')
                }
                log_manager.insert(action=LogAction.DELETE,
                                   log_type=CmdbObjectLog.__name__,
                                   **log_data)
            except (CMDBError, LogManagerInsertError) as err:
                LOGGER.error(err)

        resp = make_response({'successfully': ack})
        return resp

    except ObjectDeleteError as e:
        return jsonify(message='Delete Error', error=e.message)
    except CMDBError:
        return abort(500)
Example #20
0
def update_object(public_id: int, request_user: UserModel):
    object_ids = request.args.getlist('objectIDs')

    if len(object_ids) > 0:
        object_ids = list(map(int, object_ids))
    else:
        object_ids = [public_id]

    update_ack = None

    for obj_id in object_ids:
        # get current object state
        try:
            current_object_instance = object_manager.get_object(obj_id)
            current_type_instance = object_manager.get_type(
                current_object_instance.get_type_id())
            current_object_render_result = CmdbRender(
                object_instance=current_object_instance,
                type_instance=current_type_instance,
                render_user=request_user,
                object_manager=object_manager,
                ref_render=True).result()
        except ObjectManagerGetError as err:
            LOGGER.error(err)
            return abort(404)
        except RenderError as err:
            LOGGER.error(err)
            return abort(500)

        update_comment = ''
        # load put data
        try:
            # get data as str
            add_data_dump = json.dumps(request.json)

            # convert into python dict
            put_data = json.loads(add_data_dump, object_hook=object_hook)
            # check for comment
            try:
                put_data['public_id'] = obj_id
                put_data[
                    'creation_time'] = current_object_instance.creation_time
                put_data['author_id'] = current_object_instance.author_id

                old_fields = list(
                    map(
                        lambda x:
                        {k: v
                         for k, v in x.items() if k in ['name', 'value']},
                        current_type_instance.get_fields()))
                new_fields = put_data['fields']
                for item in new_fields:
                    for old in old_fields:
                        if item['name'] == old['name']:
                            old['value'] = item['value']
                put_data['fields'] = old_fields

                if 'active' not in put_data:
                    put_data['active'] = current_object_instance.active
                if 'version' not in put_data:
                    put_data['version'] = current_object_instance.version

                update_comment = put_data['comment']
                del put_data['comment']
            except (KeyError, IndexError, ValueError):
                update_comment = ''
        except TypeError as e:
            LOGGER.warning(e)
            return abort(400)

        # update edit time
        put_data['last_edit_time'] = datetime.now(timezone.utc)

        try:
            update_object_instance = CmdbObject(**put_data)
        except ObjectManagerUpdateError as err:
            LOGGER.error(err)
            return abort(400)

        # calc version

        changes = current_object_instance / update_object_instance

        if len(changes['new']) == 1:
            update_object_instance.update_version(
                update_object_instance.VERSIONING_PATCH)
        elif len(changes['new']) == len(update_object_instance.fields):
            update_object_instance.update_version(
                update_object_instance.VERSIONING_MAJOR)
        elif len(changes['new']) > (len(update_object_instance.fields) / 2):
            update_object_instance.update_version(
                update_object_instance.VERSIONING_MINOR)
        else:
            update_object_instance.update_version(
                update_object_instance.VERSIONING_PATCH)

        # insert object
        try:
            update_ack = object_manager.update_object(
                update_object_instance, request_user,
                AccessControlPermission.UPDATE)

        except ManagerGetError as err:
            return abort(404, err.message)
        except AccessDeniedError as err:
            return abort(403, err.message)
        except CMDBError as e:
            LOGGER.warning(e)
            return abort(500)

        try:
            # generate log
            log_data = {
                'object_id':
                obj_id,
                'version':
                current_object_render_result.object_information['version'],
                'user_id':
                request_user.get_public_id(),
                'user_name':
                request_user.get_display_name(),
                'comment':
                update_comment,
                'changes':
                changes,
                'render_state':
                json.dumps(current_object_render_result,
                           default=default).encode('UTF-8')
            }
            log_manager.insert(action=LogAction.EDIT,
                               log_type=CmdbObjectLog.__name__,
                               **log_data)
        except (CMDBError, LogManagerInsertError) as err:
            LOGGER.error(err)

    return make_response(update_ack)
Example #21
0
def insert_object(request_user: UserModel):
    from bson import json_util
    add_data_dump = json.dumps(request.json)

    try:
        new_object_data = json.loads(add_data_dump,
                                     object_hook=json_util.object_hook)
        if not 'public_id' in new_object_data:
            new_object_data['public_id'] = object_manager.get_new_id(
                CmdbObject.COLLECTION)
        if not 'active' in new_object_data:
            new_object_data['active'] = True
        new_object_data['creation_time'] = datetime.now(timezone.utc)
        new_object_data['views'] = 0
        new_object_data['version'] = '1.0.0'  # default init version
    except TypeError as e:
        LOGGER.warning(e)
        abort(400)

    try:
        new_object_id = object_manager.insert_object(
            new_object_data,
            user=request_user,
            permission=AccessControlPermission.CREATE)
    except ManagerGetError as err:
        return abort(404, err.message)
    except AccessDeniedError as err:
        return abort(403, err.message)
    except ObjectInsertError as err:
        LOGGER.error(err)
        return abort(400, str(err))

    # get current object state
    try:
        current_type_instance = object_manager.get_type(
            new_object_data['type_id'])
        current_object = object_manager.get_object(new_object_id)
        current_object_render_result = CmdbRender(
            object_instance=current_object,
            object_manager=object_manager,
            type_instance=current_type_instance,
            render_user=request_user).result()
    except ObjectManagerGetError as err:
        LOGGER.error(err)
        return abort(404)
    except RenderError as err:
        LOGGER.error(err)
        return abort(500)

    # Generate new insert log
    try:
        log_params = {
            'object_id':
            new_object_id,
            'user_id':
            request_user.get_public_id(),
            'user_name':
            request_user.get_display_name(),
            'comment':
            'Object was created',
            'render_state':
            json.dumps(current_object_render_result,
                       default=default).encode('UTF-8'),
            'version':
            current_object.version
        }
        log_ack = log_manager.insert(action=LogAction.CREATE,
                                     log_type=CmdbObjectLog.__name__,
                                     **log_params)
    except LogManagerInsertError as err:
        LOGGER.error(err)

    resp = make_response(new_object_id)
    return resp
Example #22
0
def import_objects(request_user: UserModel):
    # Check if file exists
    if not request.files:
        return abort(400, 'No import file was provided')
    request_file: FileStorage = get_file_in_request('file', request.files)

    filename = secure_filename(request_file.filename)
    working_file = f'/tmp/{filename}'
    request_file.save(working_file)

    # Load file format
    file_format = request.form.get('file_format', None)

    # Load parser config
    parser_config: dict = get_element_from_data_request('parser_config', request) or {}
    if parser_config == {}:
        LOGGER.info('No parser config was provided - using default parser config')

    # Check for importer config
    importer_config_request: dict = get_element_from_data_request('importer_config', request) or None
    if not importer_config_request:
        return abort(400, 'No import config was provided')

    # Check if type exists
    try:
        type_manager = TypeManager(database_manager=current_app.database_manager)
        type_ = type_manager.get(importer_config_request.get('type_id'))
        if not type_.active:
            raise AccessDeniedError(f'Objects cannot be created because type `{type_.name}` is deactivated.')
        verify_import_access(user=request_user,
                             _type=type_,
                             _manager=type_manager)
    except ObjectManagerGetError as err:
        return abort(404, err.message)
    except AccessDeniedError as err:
        return abort(403, err.message)

    # Load parser
    try:
        parser_class = load_parser_class('object', file_format)
    except ParserLoadError as ple:
        return abort(406, ple.message)
    parser = parser_class(parser_config)

    LOGGER.info(f'Parser {parser_class} was loaded')

    # Load importer config
    try:
        importer_config_class = load_importer_config_class('object', file_format)
    except ImporterLoadError as ile:
        return abort(406, ile.message)
    importer_config = importer_config_class(**importer_config_request)
    LOGGER.debug(importer_config_request)
    # Load importer
    try:
        importer_class = load_importer_class('object', file_format)
    except ImporterLoadError as ile:
        return abort(406, ile.message)
    importer = importer_class(working_file, importer_config, parser, object_manager, request_user)
    LOGGER.info(f'Importer {importer_class} was loaded')

    try:
        import_response: ImporterObjectResponse = importer.start_import()
    except ImportRuntimeError as ire:
        LOGGER.error(f'Error while importing objects: {ire.message}')
        return abort(500, ire.message)
    except AccessDeniedError as err:
        return abort(403, err.message)

    # close request file
    request_file.close()

    # log all successful imports
    for message in import_response.success_imports:
        try:

            # get object state of every imported object
            current_type_instance = object_manager.get_type(importer_config_request.get('type_id'))
            current_object = object_manager.get_object(message.public_id)
            current_object_render_result = CmdbRender(object_instance=current_object,
                                                      type_instance=current_type_instance,
                                                      render_user=request_user,
                                                      object_manager=object_manager).result()

            # insert object create log
            log_params = {
                'object_id': message.public_id,
                'user_id': request_user.get_public_id(),
                'user_name': request_user.get_display_name(),
                'comment': 'Object was imported',
                'render_state': json.dumps(current_object_render_result, default=default).encode('UTF-8'),
                'version': current_object.version
            }
            log_manager.insert(action=LogAction.CREATE, log_type=CmdbObjectLog.__name__, **log_params)

        except ObjectManagerGetError as err:
            LOGGER.error(err)
            return abort(404)
        except RenderError as err:
            LOGGER.error(err)
            return abort(500)
        except LogManagerInsertError as err:
            LOGGER.error(err)

    return make_response(import_response)
Example #23
0
def update_object(public_id: int, data: dict, request_user: UserModel):
    object_ids = request.args.getlist('objectIDs')

    if len(object_ids) > 0:
        object_ids = list(map(int, object_ids))
    else:
        object_ids = [public_id]

    manager = ObjectManager(database_manager=current_app.database_manager,
                            event_queue=current_app.event_queue)
    results: [dict] = []
    failed = []

    for obj_id in object_ids:
        # deep copy
        active_state = request.get_json().get('active', None)
        new_data = copy.deepcopy(data)
        try:
            current_object_instance = manager.get(
                obj_id,
                user=request_user,
                permission=AccessControlPermission.READ)
            current_type_instance = type_manager.get(
                current_object_instance.get_type_id())
            current_object_render_result = CmdbRender(
                object_instance=current_object_instance,
                object_manager=object_manager,
                type_instance=current_type_instance,
                render_user=request_user).result()
            update_comment = ''
            try:
                # check for comment
                new_data['public_id'] = obj_id
                new_data[
                    'creation_time'] = current_object_instance.creation_time
                new_data['author_id'] = current_object_instance.author_id
                new_data[
                    'active'] = active_state if active_state else current_object_instance.active

                if 'version' not in data:
                    new_data['version'] = current_object_instance.version

                old_fields = list(
                    map(
                        lambda x:
                        {k: v
                         for k, v in x.items() if k in ['name', 'value']},
                        current_object_render_result.fields))
                new_fields = data['fields']
                for item in new_fields:
                    for old in old_fields:
                        if item['name'] == old['name']:
                            old['value'] = item['value']
                new_data['fields'] = old_fields

                update_comment = data['comment']
                del new_data['comment']

            except (KeyError, IndexError, ValueError):
                update_comment = ''
            except TypeError as err:
                LOGGER.error(
                    f'Error: {str(err.args)} Object: {json.dumps(new_data, default=default)}'
                )
                failed.append(
                    ResponseFailedMessage(error_message=str(err.args),
                                          status=400,
                                          public_id=obj_id,
                                          obj=new_data).to_dict())
                continue

            # update edit time
            new_data['last_edit_time'] = datetime.now(timezone.utc)
            new_data['editor_id'] = request_user.public_id

            update_object_instance = CmdbObject(
                **json.loads(json.dumps(new_data, default=json_util.default),
                             object_hook=object_hook))

            # calc version
            changes = current_object_instance / update_object_instance

            if len(changes['new']) == 1:
                new_data['version'] = update_object_instance.update_version(
                    update_object_instance.VERSIONING_PATCH)
            elif len(changes['new']) == len(update_object_instance.fields):
                new_data['version'] = update_object_instance.update_version(
                    update_object_instance.VERSIONING_MAJOR)
            elif len(
                    changes['new']) > (len(update_object_instance.fields) / 2):
                new_data['version'] = update_object_instance.update_version(
                    update_object_instance.VERSIONING_MINOR)
            else:
                new_data['version'] = update_object_instance.update_version(
                    update_object_instance.VERSIONING_PATCH)

            manager.update(obj_id, new_data, request_user,
                           AccessControlPermission.UPDATE)
            results.append(new_data)

            # Generate log entry
            try:
                log_data = {
                    'object_id':
                    obj_id,
                    'version':
                    update_object_instance.get_version(),
                    'user_id':
                    request_user.get_public_id(),
                    'user_name':
                    request_user.get_display_name(),
                    'comment':
                    update_comment,
                    'changes':
                    changes,
                    'render_state':
                    json.dumps(update_object_instance,
                               default=default).encode('UTF-8')
                }
                log_manager.insert(action=LogAction.EDIT,
                                   log_type=CmdbObjectLog.__name__,
                                   **log_data)
            except (CMDBError, LogManagerInsertError) as err:
                LOGGER.error(err)

        except AccessDeniedError as err:
            LOGGER.error(err)
            return abort(403)
        except ObjectManagerGetError as err:
            LOGGER.error(err)
            failed.append(
                ResponseFailedMessage(error_message=err.message,
                                      status=400,
                                      public_id=obj_id,
                                      obj=new_data).to_dict())
            continue
        except (ManagerGetError, ObjectManagerUpdateError) as err:
            LOGGER.error(err)
            failed.append(
                ResponseFailedMessage(error_message=err.message,
                                      status=404,
                                      public_id=obj_id,
                                      obj=new_data).to_dict())
            continue
        except (CMDBError, RenderError) as e:
            LOGGER.warning(e)
            failed.append(
                ResponseFailedMessage(error_message=str(e.__repr__),
                                      status=500,
                                      public_id=obj_id,
                                      obj=new_data).to_dict())
            continue

    api_response = UpdateMultiResponse(results=results,
                                       failed=failed,
                                       url=request.url,
                                       model=CmdbObject.MODEL)
    return api_response.make_response()