def load_messages_to_db(msg_list): """ Load list of messages into DB Status_Message table Args: msg_list ([Message]): Message list purge (boolean): Indicates when the fucntion should purge old messages. Returns: success (bool): True if successful, False elsewhere result (str): Error message (if any) """ success = True result = "" try: if msg_list: db.session.begin() for msg in msg_list: db_msg = Status_Message( id=get_bytes_from_uuid(msg.id), level=Status_Message.get_level_integer_from_string( msg.level), type=msg.type, message_role=msg.message_role, action_role=msg.action_role, title=msg.title, description=msg.description, actions=msg.actions, alternative_actions=msg.alternative_actions, source=msg.source) db.session.merge(db_msg) # insert or update # remove those messages that have been dissapeared messsages_ids_str = ','.join( ["'%s'" % msg.id.replace('-', '').upper() for msg in msg_list]) cmd = "delete from status_message where hex(id) not in (%s) and source='monitor'" % ( messsages_ids_str) db.session.connection(mapper=Status_Message).execute(cmd) #cmd = "delete current_status from current_status left join status_message on current_status.message_id=status_message.id where status_message.id is null;" #db.session.connection(mapper=Current_Status).execute(cmd) #success, result = purge_current_status_messages() db.session.commit() except Exception, e: success = False result = "[load_messages_to_db] Error: %s" % str(e) db.session.rollback()
def load_messages_to_db(msg_list): """ Load list of messages into DB Status_Message table Args: msg_list ([Message]): Message list purge (boolean): Indicates when the fucntion should purge old messages. Returns: success (bool): True if successful, False elsewhere result (str): Error message (if any) """ success = True result = "" try: if msg_list: db.session.begin() for msg in msg_list: db_msg = Status_Message(id=get_bytes_from_uuid(msg.id), level=Status_Message.get_level_integer_from_string(msg.level), type=msg.type, message_role=msg.message_role, action_role=msg.action_role, title=msg.title, description=msg.description, actions=msg.actions, alternative_actions=msg.alternative_actions, source=msg.source) db.session.merge(db_msg) # insert or update # remove those messages that have been dissapeared messsages_ids_str = ','.join(["'%s'" % msg.id.replace('-', '').upper() for msg in msg_list]) cmd = "delete from status_message where hex(id) not in (%s) and source='monitor'" % (messsages_ids_str) db.session.connection(mapper=Status_Message).execute(cmd) #cmd = "delete current_status from current_status left join status_message on current_status.message_id=status_message.id where status_message.id is null;" #db.session.connection(mapper=Current_Status).execute(cmd) #success, result = purge_current_status_messages() db.session.commit() except Exception, e: success = False result = "[load_messages_to_db] Error: %s" % str(e) db.session.rollback()
def load_mcserver_messages(message_list): """Adds or updates messages coming from the mcserver Args: message_list[Status_Message] Returns: success (bool): True if successful, False elsewhere result (str): Error message (if any) """ result = "" success = True try: db.session.begin() for msg in message_list: msg_id_str = str(msg['msg_id']) msg_id_binary = get_bytes_from_uuid(msg_id_str) additional_info_json = "" if msg['additional_info'] is not None and msg[ 'additional_info'] != "": try: additional_info_json = json.dumps(msg['additional_info']) except Exception as e: api_log.warning( "Message with an invalid additional_info %s - %s" % (msg_id_str, str(e))) additional_info_json = "" success, status_message = get_status_message_from_id( message_id=msg_id_binary, is_admin=True, serialize=False) if success: #update values: status_message.level = Status_Message.get_level_integer_from_string( str(msg['level'])) status_message.title = msg['title'] status_message.description = msg['description'] status_message.type = msg['type'] success, current_status_message = get_current_status_from_message_id( msg_id_str) if not success or len(current_status_message) != 1: api_log.error( "Invalid external message %s. Current_Status: %s, tuples(%s)" % (msg_id_str, success, len(current_status_message))) continue current_status_message[ 0].additional_info = additional_info_json db.session.merge(current_status_message[0]) db.session.merge(status_message) else: new_msg = Status_Message() new_msg.id = msg_id_binary new_msg.level = Status_Message.get_level_integer_from_string( str(msg['level'])) new_msg.title = msg['title'] new_msg.description = msg['description'] new_msg.type = msg['type'] new_msg.expire = datetime.strptime(msg['valid_to'], "%Y-%m-%dT%H:%M:%S") new_msg.actions = "" new_msg.alternative_actions = "" new_msg.source = "external" current_status_message = Current_Status() current_status_message.id = uuid4().bytes current_status_message.component_type = 'external' current_status_message.creation_time = datetime.strptime( msg['valid_from'], "%Y-%m-%dT%H:%M:%S") current_status_message.message_id = new_msg.id current_status_message.additional_info = "" current_status_message.suppressed = 0 current_status_message.viewed = 0 current_status_message.additional_info = additional_info_json db.session.add(new_msg) db.session.add(current_status_message) db.session.commit() except Exception, e: success = False result = "[load_mcserver_messages(] Error: %s" % str(e) db.session.rollback()
def get_current_status_messages(component_id=None, message_level=None, order_by=None, page=None, page_row=None, order_desc=None, component_type=None, message_id=None, message_type=None, search=None, only_unread=None, login_user=None, is_admin=False): """Returns the list of current_status messages matching the given criteria. Args: component_id(UUID string): Component ID related with the message message_level(list<str>): Message level order_by(str): Current status field by which you want to sort the results. page(int): Page number page_row(int): Number of items per page order_desc(Boolean or None): Specify whether you want to sort the results in descendig order or not. component_type(str): Component Type related with the message message_id(UUID string): The message ID you are looking for message_type(list<str>): Kind of message you want to retrieve. search(str): It's a free text to search for message title only_unread(Boolean or None): If true, retrieve only unread messages login_user (admin): logged user on the system is_admin(bool): Whether the current user is admin or not. Returns: [Current_Status] A list of Current_Status Items """ if login_user is None or login_user == "": return True, {'messages': {}, 'total': 0} query = db.session.query(Current_Status) # message_type and message_level are fields belonging to the related table status_message # We need to deal with this situation when we set the build the order_by clause if order_by is not None: if order_by not in ['message_level', 'message_type', 'message_title']: if order_desc: query = query.order_by(desc(order_by)) else: query = query.order_by(asc(order_by)) else: order_by_field = Status_Message.type if order_by == 'message_level': order_by_field = Status_Message.level if order_by == 'message_title': order_by_field = Status_Message.title if order_desc: query = query.join(Status_Message).order_by( desc(order_by_field)) else: query = query.join(Status_Message).order_by( asc(order_by_field)) if login_user != "admin" and not is_admin: # neither user admin nor is_admin query = query.join( UserPermissions, UserPermissions.component_id == Current_Status.component_id) query = query.filter(and_(UserPermissions.login == login_user)) query = query.order_by(asc(Current_Status.viewed)) if component_id is not None: query = query.filter( and_(Current_Status.component_id == get_bytes_from_uuid( component_id))) if message_id is not None: query = query.filter( and_(Current_Status.message_id == get_bytes_from_uuid(message_id))) if message_level is not None: new_filter = [ Current_Status.message.has( Status_Message.level.like( Status_Message.get_level_integer_from_string(x))) for x in message_level ] query = query.filter(or_(*new_filter)) if message_type is not None: new_filter = [ Current_Status.message.has(Status_Message.type.like(x)) for x in message_type ] query = query.filter(or_(*new_filter)) if component_type is not None: query = query.filter( and_(Current_Status.component_type == component_type)) if search is not None: query = query.filter( or_( Current_Status.message.has( Status_Message.title.like("%" + search + "%")), Current_Status.message.has( Status_Message.description.like("%" + search + "%")))) if only_unread: query = query.filter(and_(Current_Status.viewed == 0)) query = query.filter( or_(Current_Status.suppressed == None, Current_Status.suppressed == 0)) # Always order by creationtime if order_by != "creation_time": query = query.order_by(desc(Current_Status.creation_time)) msgs = {} total = 0 try: if page is None: # return all data = query.all() msgs = [x.serialize for x in data] total = len(data) else: current_page = paginate(query, page, page_row, error_out=False) msgs = [x.serialize for x in current_page['items']] total = current_page['total'] except Exception as err: api_log.error("status: get_status_messages: %s" % format_exc()) return False, "Internal error %s" % str(err) return True, {'messages': msgs, 'total': total}
def load_mcserver_messages(message_list): """Adds or updates messages coming from the mcserver Args: message_list[Status_Message] Returns: success (bool): True if successful, False elsewhere result (str): Error message (if any) """ result = "" success = True try: db.session.begin() for msg in message_list: msg_id_str = str(msg['msg_id']) msg_id_binary = get_bytes_from_uuid(msg_id_str) additional_info_json = "" if msg['additional_info'] is not None and msg['additional_info'] != "": try: additional_info_json = json.dumps(msg['additional_info']) except Exception as e: api_log.warning("Message with an invalid additional_info %s - %s" % (msg_id_str, str(e))) additional_info_json = "" success, status_message = get_status_message_from_id(message_id=msg_id_binary, is_admin=True, serialize=False) if success: #update values: status_message.level = Status_Message.get_level_integer_from_string(str(msg['level'])) status_message.title = msg['title'] status_message.description = msg['description'] status_message.type = msg['type'] success, current_status_message = get_current_status_from_message_id(msg_id_str) if not success or len(current_status_message) != 1: api_log.error("Invalid external message %s. Current_Status: %s, tuples(%s)" % ( msg_id_str, success, len(current_status_message))) continue current_status_message[0].additional_info = additional_info_json db.session.merge(current_status_message[0]) db.session.merge(status_message) else: new_msg = Status_Message() new_msg.id = msg_id_binary new_msg.level = Status_Message.get_level_integer_from_string(str(msg['level'])) new_msg.title = msg['title'] new_msg.description = msg['description'] new_msg.type = msg['type'] new_msg.expire = datetime.strptime(msg['valid_to'], "%Y-%m-%dT%H:%M:%S") new_msg.actions = "" new_msg.alternative_actions = "" new_msg.source = "external" current_status_message = Current_Status() current_status_message.id = uuid4().bytes current_status_message.component_type = 'external' current_status_message.creation_time = datetime.strptime(msg['valid_from'], "%Y-%m-%dT%H:%M:%S") current_status_message.message_id = new_msg.id current_status_message.additional_info = "" current_status_message.suppressed = 0 current_status_message.viewed = 0 current_status_message.additional_info = additional_info_json db.session.add(new_msg) db.session.add(current_status_message) db.session.commit() except Exception, e: success = False result = "[load_mcserver_messages(] Error: %s" % str(e) db.session.rollback()
def get_current_status_messages_stats(search=None, only_unread=False, login_user=None, is_admin=False): """ Returns the list of current status messages stats all messages count unread messages count info level messages count warning level messages count error level messages count update type messages count deployment type messages count information type messages count announcement type messages count is_admin(bool): Whether the current user is admin or not. :return: (bool, {stats}) """ m_levels = ['info', 'warning', 'error'] m_types = ['update', 'deployment', 'information', 'alienvault', 'ticket', 'alarm', 'security'] stats = {} if login_user is None or login_user == '': return {'all': 0, 'unread': 0, 'type': 0} try: query = db.session.query(Current_Status) # db.session.query(func.count(Current_Status.id)).scalar() query = query.filter(or_(Current_Status.suppressed == None, Current_Status.suppressed == 0)) if search is not None: query = query.filter(and_(or_(Current_Status.message.has(Status_Message.title.like("%" + search + "%")), Current_Status.message.has( Status_Message.description.like("%" + search + "%"))))) if login_user != "admin" and not is_admin: # neither user admin nor is_admin query = query.join(UserPermissions, UserPermissions.component_id == Current_Status.component_id) query = query.filter(and_(UserPermissions.login == login_user)) stats['all'] = query.count() query = db.session.query(Current_Status).filter(Current_Status.viewed == 0) query = query.filter(or_(Current_Status.suppressed == None, Current_Status.suppressed == 0)) if search is not None: query = query.filter(and_(or_(Current_Status.message.has(Status_Message.title.like("%" + search + "%")), Current_Status.message.has( Status_Message.description.like("%" + search + "%"))))) if login_user != "admin" and not is_admin: # neither user admin nor is_admin query = query.join(UserPermissions, UserPermissions.component_id == Current_Status.component_id) query = query.filter(and_(UserPermissions.login == login_user)) stats['unread'] = query.count() stats['level'] = {} for m_level in m_levels: query = db.session.query(Current_Status).join(Status_Message).filter( Status_Message.level == Status_Message.get_level_integer_from_string(m_level)) query = query.filter(or_(Current_Status.suppressed == None, Current_Status.suppressed == 0)) if only_unread: query = query.filter(and_(Current_Status.viewed == 0)) if search is not None: query = query.filter(and_(or_(Current_Status.message.has(Status_Message.title.like("%" + search + "%")), Current_Status.message.has( Status_Message.description.like("%" + search + "%"))))) if login_user != "admin" and not is_admin: # neither user admin nor is_admin query = query.join(UserPermissions, UserPermissions.component_id == Current_Status.component_id) query = query.filter(and_(UserPermissions.login == login_user)) stats['level'][m_level] = query.count() stats['type'] = {} for m_type in m_types: query = db.session.query(Current_Status).join(Status_Message).filter(Status_Message.type == m_type) query = query.filter(or_(Current_Status.suppressed == None, Current_Status.suppressed == 0)) if only_unread: query = query.filter(and_(Current_Status.viewed == 0)) if search is not None: query = query.filter(and_(or_(Current_Status.message.has(Status_Message.title.like("%" + search + "%")), Current_Status.message.has( Status_Message.description.like("%" + search + "%"))))) if login_user != "admin" and not is_admin: # neither user admin nor is_admin query = query.join(UserPermissions, UserPermissions.component_id == Current_Status.component_id) query = query.filter(and_(UserPermissions.login == login_user)) stats['type'][m_type] = query.count() except Exception as err: api_log.error('status: get_status_messages_stats: %s' % format_exc()) return False, 'Internal error %s' % str(err) return True, {'stats': stats}
def get_current_status_messages(component_id=None, message_level=None, order_by=None, page=None, page_row=None, order_desc=None, component_type=None, message_id=None, message_type=None, search=None, only_unread=None, login_user=None, is_admin=False): """Returns the list of current_status messages matching the given criteria. Args: component_id(UUID string): Component ID related with the message message_level(list<str>): Message level order_by(str): Current status field by which you want to sort the results. page(int): Page number page_row(int): Number of items per page order_desc(Boolean or None): Specify whether you want to sort the results in descendig order or not. component_type(str): Component Type related with the message message_id(UUID string): The message ID you are looking for message_type(list<str>): Kind of message you want to retrieve. search(str): It's a free text to search for message title only_unread(Boolean or None): If true, retrieve only unread messages login_user (admin): logged user on the system is_admin(bool): Whether the current user is admin or not. Returns: [Current_Status] A list of Current_Status Items """ if login_user is None or login_user == "": return True, {'messages': {}, 'total': 0} query = db.session.query(Current_Status) # message_type and message_level are fields belonging to the related table status_message # We need to deal with this situation when we set the build the order_by clause if order_by is not None: if order_by not in ['message_level', 'message_type', 'message_title']: if order_desc: query = query.order_by(desc(order_by)) else: query = query.order_by(asc(order_by)) else: order_by_field = Status_Message.type if order_by == 'message_level': order_by_field = Status_Message.level if order_by == 'message_title': order_by_field = Status_Message.title if order_desc: query = query.join(Status_Message).order_by(desc(order_by_field)) else: query = query.join(Status_Message).order_by(asc(order_by_field)) if login_user != "admin" and not is_admin: # neither user admin nor is_admin query = query.join(UserPermissions, UserPermissions.component_id == Current_Status.component_id) query = query.filter(and_(UserPermissions.login == login_user)) query = query.order_by(asc(Current_Status.viewed)) if component_id is not None: query = query.filter(and_(Current_Status.component_id == get_bytes_from_uuid(component_id))) if message_id is not None: query = query.filter(and_(Current_Status.message_id == get_bytes_from_uuid(message_id))) if message_level is not None: new_filter = [ Current_Status.message.has(Status_Message.level.like(Status_Message.get_level_integer_from_string(x))) for x in message_level] query = query.filter(or_(*new_filter)) if message_type is not None: new_filter = [Current_Status.message.has(Status_Message.type.like(x)) for x in message_type] query = query.filter(or_(*new_filter)) if component_type is not None: query = query.filter(and_(Current_Status.component_type == component_type)) if search is not None: query = query.filter(or_(Current_Status.message.has(Status_Message.title.like("%" + search + "%")), Current_Status.message.has(Status_Message.description.like("%" + search + "%")))) if only_unread: query = query.filter(and_(Current_Status.viewed == 0)) query = query.filter(or_(Current_Status.suppressed == None, Current_Status.suppressed == 0)) # Always order by creationtime if order_by != "creation_time": query = query.order_by(desc(Current_Status.creation_time)) msgs = {} total = 0 try: if page is None: # return all data = query.all() msgs = [x.serialize for x in data] total = len(data) else: current_page = paginate(query, page, page_row, error_out=False) msgs = [x.serialize for x in current_page['items']] total = current_page['total'] except Exception as err: api_log.error("status: get_status_messages: %s" % format_exc()) return False, "Internal error %s" % str(err) return True, {'messages': msgs, 'total': total}