def get_object(public_id, request_user: UserModel): try: object_instance = object_manager.get_object( public_id, user=request_user, permission=AccessControlPermission.READ) except (ObjectManagerGetError, ManagerGetError) as err: return abort(404, err.message) except AccessDeniedError as err: return abort(403, err.message) try: type_instance = TypeManager( database_manager=current_app.database_manager).get( object_instance.get_type_id()) except ObjectManagerGetError as err: LOGGER.error(err.message) return abort(404, err.message) try: render = CmdbRender(object_instance=object_instance, type_instance=type_instance, render_user=request_user, object_manager=object_manager, ref_render=True) render_result = render.result() except RenderError as err: LOGGER.error(err) return abort(500) resp = make_response(render_result) return resp
def __get_objectdata(self, cmdb_object, iteration): data = {} data["id"] = cmdb_object.object_information['object_id'] data["fields"] = {} for field in cmdb_object.fields: try: field_name = field["name"] if field["type"] == "ref" and field["value"] and iteration > 0: # resolve type current_object = self.__object_manager.get_object( field["value"]) type_instance = self.__object_manager.get_type( current_object.get_type_id()) cmdb_render_object = CmdbRender( object_instance=current_object, type_instance=type_instance, render_user=None, object_manager=self.__object_manager) data["fields"][field_name] = self.__get_objectdata( cmdb_render_object.result(), iteration - 1) elif field['type'] == 'ref-section-field': data['fields'][field_name] = {'fields': {}} for section_ref_field in field['references']['fields']: data['fields'][field_name]['fields'][section_ref_field[ 'name']] = section_ref_field['value'] else: data["fields"][field_name] = field["value"] except ObjectManagerGetError: continue except Exception as err: LOGGER.error(err) return data
def get_object(public_id, request_user: User): try: object_instance = object_manager.get_object(public_id) except ObjectManagerGetError as err: LOGGER.error(err) return abort(404) try: type_instance = object_manager.get_type(object_instance.get_type_id()) except ObjectManagerGetError as err: LOGGER.error(err) return abort(404) try: render = CmdbRender(object_instance=object_instance, type_instance=type_instance, render_user=request_user, user_list=user_manager.get_users()) render_result = render.result() except RenderError as err: LOGGER.error(err) return abort(500) resp = make_response(render_result) return resp
def __get_objectdata(self, cmdb_object, iteration): data = {} data["id"] = cmdb_object.object_information['object_id'] data["fields"] = {} for field in cmdb_object.fields: try: field_name = field["name"] if field["type"] == "ref" and field["value"] and iteration > 0: # resolve type iteration = iteration - 1 current_object = self.__object_manager.get_object( field["value"]) type_instance = self.__object_manager.get_type( current_object.get_type_id()) cmdb_render_object = CmdbRender( object_instance=current_object, type_instance=type_instance, render_user=None) data["fields"][field_name] = self.__get_objectdata( cmdb_render_object.result(), iteration) else: data["fields"][field_name] = field["value"] except Exception as err: LOGGER.error(err) return data
def render_object_template(self, doctpl_id: int, object_id: int): template = self.__template_manager.get_template(doctpl_id) cmdb_object = self.__obm.get_object(object_id) type_instance = self.__obm.get_type(cmdb_object.get_type_id()) cmdb_render_object = CmdbRender(object_instance=cmdb_object, type_instance=type_instance, render_user=None) generator = ObjectDocumentGenerator(template, self.__obm, cmdb_render_object.result(), PdfDocumentType()) return generator.generate_doc()
def delete_many_objects(public_ids, request_user: User): 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, type_instance=current_type_instance, render_user=request_user, user_list=user_manager.get_users()).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(), request_user=request_user)) except ObjectDeleteError: return abort(400) 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_name(), 'comment': 'Object was deleted', 'render_state': json.dumps(current_object_render_result, default=default).encode('UTF-8') } log_manager.insert_log(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)
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
def insert_object(request_user: User): from bson import json_util from datetime import datetime 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.utcnow() 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) except ObjectInsertError as oie: LOGGER.error(oie) return abort(500) # 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, type_instance=current_type_instance, render_user=request_user, user_list=user_manager.get_users()).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_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_log(action=LogAction.CREATE, log_type=CmdbObjectLog.__name__, **log_params) except LogManagerInsertError as err: LOGGER.error(err) resp = make_response(new_object_id) return resp
def update_object_state(public_id: int, request_user: User): 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, request_user) 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, type_instance=current_type_instance, render_user=request_user, user_list=user_manager.get_users()).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_name(), 'render_state': json.dumps(current_object_render_result, default=default).encode('UTF-8'), 'comment': 'Active status has changed', 'changes': change, } log_manager.insert_log(action=LogAction.ACTIVE_CHANGE, log_type=CmdbObjectLog.__name__, **log_data) except (CMDBError, LogManagerInsertError) as err: LOGGER.error(err) return make_response(update_ack)
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)
def update_object_state(public_id: int, request_user: UserModel): if isinstance(request.json, bool): state = request.json else: return abort(400) try: manager = ObjectManager(database_manager=current_app.database_manager, event_queue=current_app.event_queue) founded_object = manager.get(public_id=public_id, user=request_user, permission=AccessControlPermission.READ) except ObjectManagerGetError as err: LOGGER.error(err) return abort(404, err.message) if founded_object.active == state: return make_response(False, 204) try: founded_object.active = state manager.update(public_id, founded_object, user=request_user, permission=AccessControlPermission.UPDATE) except AccessDeniedError as err: return abort(403, err.message) except ObjectManagerUpdateError as err: LOGGER.error(err) return abort(500, err.message) # get current object state try: current_type_instance = type_manager.get(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) api_response = UpdateSingleResponse(result=founded_object.__dict__, url=request.url, model=CmdbObject.MODEL) return api_response.make_response()
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()
def insert_object(request_user: UserModel): add_data_dump = json.dumps(request.json) try: new_object_data = json.loads(add_data_dump, object_hook=json_util.object_hook) if 'public_id' not in new_object_data: new_object_data['public_id'] = object_manager.get_new_id( CmdbObject.COLLECTION) else: try: object_manager.get_object( public_id=new_object_data['public_id']) except ObjectManagerGetError: pass else: return abort( 400, f'Type with PublicID {new_object_data["public_id"]} already exists.' ) if 'active' not 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 new_object_id = object_manager.insert_object( new_object_data, user=request_user, permission=AccessControlPermission.CREATE) # get current object state 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() # 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_manager.insert(action=LogAction.CREATE, log_type=CmdbObjectLog.__name__, **log_params) except LogManagerInsertError as err: LOGGER.error(err) except (TypeError, ObjectInsertError) as err: LOGGER.error(err) return abort(400, str(err)) except (ManagerGetError, ObjectManagerGetError) as err: LOGGER.error(err) return abort(404, err.message) except AccessDeniedError as err: return abort(403, err.message) except RenderError as err: LOGGER.error(err) return abort(500) resp = make_response(new_object_id) return resp
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)