Source code for roster_core.audit_log

#!/usr/bin/python

# Copyright (c) 2009, Purdue University
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution.
# 
# Neither the name of the Purdue University nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""This module is used to create an audit log of activities executed on the
dnsManagement core and user libs.
"""

__copyright__ = 'Copyright (C) 2009, Purdue University'
__license__ = 'BSD'
__version__ = "#TRUNK#"


import cPickle
import datetime
import syslog
import unicodedata


[docs]class AuditLog(object): def __init__(self, log_to_syslog=False, log_to_db=False, db_instance=None, log_to_file=False, log_file_name=None): """Sets where log messages get sent. Inputs: log_to_syslog: bool of if syslog is used log_to_db: bool of if db is used db_instance: instance of DbAccess class log_to_file: bool of if file is used log_file: string of file name to log to """ self.log_to_syslog = log_to_syslog self.log_to_db = log_to_db self.db_instance = db_instance self.log_to_file = log_to_file self.log_file_name = log_file_name
[docs] def LogAction(self, user, action, data, success, current_transaction=False): """Logs action to places specified in initalizer. Inputs: user: string of user name action: string of function name that is being logged data: dictionary of arguments ex: {'replay_args': [u'test_acl', u'192.168.0/24', 1], 'audit_args': {'cidr_block': u'192.168.0/24', 'range_allowed': 1, 'acl_name': u'test_acl'}} success: bool of success of action current_transaction: boolean for if a transaction is already started """ current_datetime = datetime.datetime.now() current_timestamp = current_datetime.strftime('%Y-%m-%d %H:%M:%S') pretty_print_log_string = self._PrettyPrintLogString(user, action, data, success, current_timestamp) if( self.log_to_db ): audit_log_id = self._LogToDatabase(user, action, data, success, current_datetime, current_transaction) if( self.log_to_syslog ): self._LogToSyslog(pretty_print_log_string) if( self.log_to_file ): self._LogToFile(pretty_print_log_string) if( self.log_to_db ): return audit_log_id
def _LogToSyslog(self, log_string): """Writes log string to syslog. Inputs: log_string: string of message to write to syslog """ syslog.openlog('dnsManagement') # Convert the unicode strings to ascii if needed if( isinstance(log_string, unicode) ): log_string = unicodedata.normalize('NFKD', log_string).encode( 'ASCII', 'replace') try: syslog.syslog(log_string) finally: syslog.closelog() def _LogToDatabase(self, user, action, data, success, current_timestamp, current_transaction): """Writes log data to db. Inputs: user: string of user name action: string of action data: string of data success: bool of success of action current_timestamp: string of mysql formated time stamp current_transaction: boolean for if a transaction is already started """ if( success ): success = 1 else: success = 0 data = cPickle.dumps(data) log_dict = {'audit_log_id': None, 'audit_log_user_name': user, 'action': action, 'data': data, 'success': success, 'audit_log_timestamp': current_timestamp} if( not current_transaction ): self.db_instance.StartTransaction() try: audit_log_id = self.db_instance.MakeRow('audit_log', log_dict) except: self.db_instance.EndTransaction(rollback=True) raise if( not current_transaction ): self.db_instance.EndTransaction() return audit_log_id def _LogToFile(self, log_string): """Writes log string to file. Inputs: log_string: string of message to write to file """ log_file = open(self.log_file_name, 'a') try: log_file.write('%s\n' % log_string) finally: log_file.flush() log_file.close() def _PrettyPrintLogString(self, user, action, data, success, current_timestamp): """Formats data into human readable string. Inputs: user: string of user name action: string of action data: string of data success: bool of success of action current_timestamp: string of mysql formated time stamp Outputs: string of log message example: User sharrell SUCCEEDED while executing MakeUser with data user_name: ahoward access_level: 64 at 2009-04-22 16:20:18 """ if( success ): success_string = 'SUCCEEDED' else: success_string = 'FAILED' return 'User %s %s while executing %s with data %s at %s' % ( user, success_string, action, data['audit_args'], current_timestamp) # vi: set ai aw sw=2: