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 get_object_references(public_id: int, params: CollectionParameters, request_user: UserModel): from cmdb.framework.managers.object_manager import ObjectManager manager = ObjectManager(database_manager=current_app.database_manager) view = params.optional.get('view', 'native') if _fetch_only_active_objs(): if isinstance(params.filter, dict): params.filter.update({'$match': {'active': {"$eq": True}}}) elif isinstance(params.filter, list): params.filter.append({'$match': {'active': {"$eq": True}}}) else: if isinstance(params.filter, dict): params.filter.update({'$match': {}}) elif isinstance(params.filter, list): params.filter.append({'$match': {}}) try: referenced_object: CmdbObject = manager.get( public_id, user=request_user, permission=AccessControlPermission.READ) except ManagerGetError as err: return abort(404, err.message) except AccessDeniedError as err: return abort(403, err.message) try: iteration_result: IterationResult[CmdbObject] = manager.references( object_=referenced_object, filter=params.filter, limit=params.limit, skip=params.skip, sort=params.sort, order=params.order, user=request_user, permission=AccessControlPermission.READ) if view == 'native': object_list: List[dict] = [ object_.__dict__ for object_ in iteration_result.results ] api_response = GetMultiResponse(object_list, total=iteration_result.total, params=params, url=request.url, model=CmdbObject.MODEL, body=request.method == 'HEAD') elif view == 'render': rendered_list = RenderList( object_list=iteration_result.results, request_user=request_user, database_manager=current_app.database_manager, object_manager=object_manager, ref_render=True).render_result_list(raw=True) api_response = GetMultiResponse(rendered_list, total=iteration_result.total, params=params, url=request.url, model=Model('RenderResult'), body=request.method == 'HEAD') else: return abort(401, 'No possible view parameter') except ManagerIterationError as err: return abort(400, err.message) 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()