Ejemplo n.º 1
0
 def open_log(self):
     """ Create an AuditLogParser and open the audit file.
     """
     self.log = AuditLogParser(self.options)
     self.log.open_log()
Ejemplo n.º 2
0
class AuditLog(object):
    """ Class to manage and parse the audit log.

    The AuditLog class is used to manage and retrieve information of the
    audit log. It allows the execution of commands to change audit log
    settings, display control variables, copy and parse audit log files.
    """
    def __init__(self, options):
        """Constructor

        options[in]       dictionary of options to include width, verbosity,
                          pedantic, quiet
        """
        self.options = options
        self.log = None

    def open_log(self):
        """ Create an AuditLogParser and open the audit file.
        """
        self.log = AuditLogParser(self.options)
        self.log.open_log()

    def close_log(self):
        """Close the previously opened audit log file.
        """
        self.log.close_log()

    def parse_log(self):
        """ Parse the audit log file (previously opened), applying
        search/filtering criterion.
        """
        self.log.parse_log()

    def output_formatted_log(self):
        """Output the parsed log entries according to the specified format.

        Print the entries resulting from the parsing process to the standard
        output in the specified format. If no entries are found (i.e., none
        match the defined search criterion) a notification message is print.
        """
        log_rows = self.log.retrieve_rows()
        if log_rows:
            out_format = self.options.get("format", "GRID")
            if out_format == 'raw':
                for row in log_rows:
                    sys.stdout.write(row)
            else:
                # Convert the results to the appropriate format
                cols, rows = convert_dictionary_list(log_rows)
                # Note: No need to sort rows, retrieved with the same order
                # as read (i.e., sorted by timestamp)
                print_list(sys.stdout, out_format, cols, rows)
        else:
            # Print message notifying that no entry was found
            no_entry_msg = "#\n# No entry found!\n#"
            print no_entry_msg

    def check_audit_log(self):
        """Verify if the audit log plugin is installed on the server.
        Return the message error if not, or None.
        """
        error = None
        server = Server({'conn_info': self.options.get("server_vals", None)})
        server.connect()
        # Check to see if the plug-in is installed
        if not server.supports_plugin("audit"):
            error = "The audit log plug-in is not installed on this " + \
                    "server or is not enabled."
        server.disconnect()

        return error

    def show_statistics(self):
        """Display statistical information about audit log including:
            - size, date, etc.
            - Audit log entries
        """
        out_format = self.options.get("format", "GRID")
        log_name = self.options.get("log_name", None)
        # Print file statistics:
        print "#\n# Audit Log File Statistics:\n#"
        show_file_statistics(log_name, False, out_format)

        # Print audit log 'AUDIT' entries
        print "\n#\n# Audit Log Startup Entries:\n#\n"
        cols, rows = convert_dictionary_list(self.log.header_rows)
        # Note: No need to sort rows, retrieved with the same order
        # as read (i.e., sorted by timestamp)
        print_list(sys.stdout, out_format, cols, rows)

    def show_options(self):
        """ Show all audit log variables.
        """
        server = Server({'conn_info': self.options.get("server_vals", None)})
        server.connect()
        rows = server.show_server_variable("audit%")
        server.disconnect()
        if rows:
            print "#\n# Audit Log Variables and Options\n#"
            print_list(sys.stdout, "GRID", ['Variable_name', 'Value'], rows)
            print
        else:
            raise UtilError("No audit log variables found.")

    def _copy_log(self):
        """ Copy the audit log to a local destionation or from a remote server.
        """
        # Need to see if this is a local copy or not.
        rlogin = self.options.get("rlogin", None)
        log_name = self.options.get("log_name", None)
        copy_location = self.options.get("copy_location", None)
        if not rlogin:
            copy(log_name, copy_location)
        else:
            user, host = rlogin.split(":", 1)
            remote_copy(log_name, user, host, copy_location,
                        self.options.get("verbosity", 0))

    @staticmethod
    def _rotate_log(server):
        """Rotate the log.

        To rotate the log, first discover the value of rotate_on_size
        then set rotate_on_size to the minimum allowed value (i.e. 4096) and
        force rotation with a manual flush. Note: the rotation will only
        effectively occur if the audit log file size is greater than 4096.
        """

        # Get the current rotation size
        rotate_size = server.show_server_variable(
            "audit_log_rotate_on_size")[0][1]
        min_rotation_size = 4096

        # If needed, set rotation size to the minimum allowed value.
        if int(rotate_size) != min_rotation_size:
            server.exec_query("SET @@GLOBAL.audit_log_rotate_on_size = "
                              "{0}".format(min_rotation_size))

        # If needed, restore the rotation size to what it was initially.
        if int(rotate_size) != min_rotation_size:
            server.exec_query("SET @@GLOBAL.audit_log_rotate_on_size = "
                              "{0}".format(rotate_size))

    @staticmethod
    def _change_policy(server, policy_value):
        """ Change the audit log plugin policy.

        This method changes the audit log policy by setting the appropriate
        variables according to the MySQL server version.

        Note: For recent MySQL server versions (i.e. >= 5.6.20, and >= 5.7.5)
        the audit_log_policy is readonly and cannot be changed at runtime
        (only when starting the server). For those versions, the policy
        results from the combination of the values set for the
        'audit_log_connection_policy' and 'audit_log_statement_policy'
        variables (not available in previous versions).

        server[in]          Instance of the server.
        policy_value[in]    Policy value to set, supported values: 'ALL',
                            'NONE', 'LOGINS', 'QUERIES', 'DEFAULT'.
        """
        # Check server version to set appropriate variables.
        if ((
                server.check_version_compat(5, 6, 20)
                and  # >= 5.6.20 and < 5.7
                not server.check_version_compat(5, 7, 0))
                or server.check_version_compat(5, 7, 5)):  # >= 5.7.5
            # Set the audit_log_connection_policy and
            # audit_log_statement_policy to yield the chosen policy.
            policy = policy_value.upper()
            set_connection_policy = (
                "SET @@GLOBAL.audit_log_connection_policy = {0}")
            set_statement_policy = (
                "SET @@GLOBAL.audit_log_statement_policy = {0}")
            if policy == 'QUERIES':
                server.exec_query(set_connection_policy.format('NONE'))
                server.exec_query(set_statement_policy.format('ALL'))
            elif policy == 'LOGINS':
                server.exec_query(set_connection_policy.format('ALL'))
                server.exec_query(set_statement_policy.format('NONE'))
            else:
                server.exec_query(set_connection_policy.format(policy_value))
                server.exec_query(set_statement_policy.format(policy_value))
        else:
            # Set the audit_log_policy for older server versions.
            server.exec_query("SET @@GLOBAL.audit_log_policy = "
                              "{0}".format(policy_value))

    def do_command(self):
        """ Check and execute the audit log command (previously set by the the
        options of the object constructor).
        """
        # Check for valid command
        command = self.options.get("command", None)
        if command not in VALID_COMMANDS:
            raise UtilError("Invalid command.")

        command_value = self.options.get("value", None)
        # Check for valid value if needed
        if (command_requires_value(command)
                and not check_command_value(command, command_value)):
            raise UtilError("Please provide the correct value for the %s "
                            "command." % command)

        # Copy command does not need the server
        if command == "COPY":
            self._copy_log()
            return True

        # Connect to server
        server = Server({'conn_info': self.options.get("server_vals", None)})
        server.connect()

        # Now execute the command
        print "#\n# Executing %s command.\n#\n" % command
        try:
            if command == "POLICY":
                self._change_policy(server, command_value)
            elif command == "ROTATE":
                self._rotate_log(server)
            else:  # "ROTATE_ON_SIZE":
                server.exec_query(
                    "SET @@GLOBAL.audit_log_rotate_on_size = %s" %
                    command_value)
        finally:
            server.disconnect()

        return True
Ejemplo n.º 3
0
class AuditLog(object):
    """ Class to manage and parse the audit log.

    The AuditLog class is used to manage and retrieve information of the
    audit log. It allows the execution of commands to change audit log
    settings, display control variables, copy and parse audit log files.
    """

    def __init__(self, options):
        """Constructor

        options[in]       dictionary of options to include width, verbosity,
                          pedantic, quiet
        """
        self.options = options
        self.log = None

    def open_log(self):
        """ Create an AuditLogParser and open the audit file.
        """
        self.log = AuditLogParser(self.options)
        self.log.open_log()

    def close_log(self):
        """Close the previously opened audit log file.
        """
        self.log.close_log()

    def parse_log(self):
        """ Parse the audit log file (previously opened), applying
        search/filtering criterion.
        """
        self.log.parse_log()

    def output_formatted_log(self):
        """Output the parsed log entries according to the specified format.

        Print the entries resulting from the parsing process to the standard
        output in the specified format. If no entries are found (i.e., none
        match the defined search criterion) a notification message is print.
        """
        log_rows = self.log.retrieve_rows()
        if log_rows:
            out_format = self.options.get("format", "GRID")
            if out_format == 'raw':
                for row in log_rows:
                    sys.stdout.write(row)
            else:
                # Convert the results to the appropriate format
                cols, rows = convert_dictionary_list(log_rows)
                # Note: No need to sort rows, retrieved with the same order
                # as read (i.e., sorted by timestamp)
                print_list(sys.stdout, out_format, cols, rows)
        else:
            # Print message notifying that no entry was found
            no_entry_msg = "#\n# No entry found!\n#"
            print no_entry_msg

    def check_audit_log(self):
        """Verify if the audit log plugin is installed on the server.
        Return the message error if not, or None.
        """
        error = None
        server = Server({'conn_info': self.options.get("server_vals", None)})
        server.connect()
        # Check to see if the plug-in is installed
        if not server.supports_plugin("audit"):
            error = "The audit log plug-in is not installed on this " + \
                    "server or is not enabled."
        server.disconnect()

        return error

    def show_statistics(self):
        """Display statistical information about audit log including:
            - size, date, etc.
            - Audit log entries
        """
        out_format = self.options.get("format", "GRID")
        log_name = self.options.get("log_name", None)
        # Print file statistics:
        print "#\n# Audit Log File Statistics:\n#"
        show_file_statistics(log_name, False, out_format)

        # Print audit log 'AUDIT' entries
        print "\n#\n# Audit Log Startup Entries:\n#\n"
        cols, rows = convert_dictionary_list(self.log.header_rows)
        # Note: No need to sort rows, retrieved with the same order
        # as read (i.e., sorted by timestamp)
        print_list(sys.stdout, out_format, cols, rows)

    def show_options(self):
        """ Show all audit log variables.
        """
        server = Server({'conn_info': self.options.get("server_vals", None)})
        server.connect()
        rows = server.show_server_variable("audit%")
        server.disconnect()
        if rows:
            print "#\n# Audit Log Variables and Options\n#"
            print_list(sys.stdout, "GRID", ['Variable_name', 'Value'],
                       rows)
            print
        else:
            raise UtilError("No audit log variables found.")

    def _copy_log(self):
        """ Copy the audit log to a local destionation or from a remote server.
        """
        # Need to see if this is a local copy or not.
        rlogin = self.options.get("rlogin", None)
        log_name = self.options.get("log_name", None)
        copy_location = self.options.get("copy_location", None)
        if not rlogin:
            copy(log_name, copy_location)
        else:
            user, host = rlogin.split(":", 1)
            remote_copy(log_name, user, host, copy_location,
                        self.options.get("verbosity", 0))

    @staticmethod
    def _rotate_log(server):
        """Rotate the log.

        To rotate the log, first discover the value of rotate_on_size
        then set rotate_on_size to the minimum allowed value (i.e. 4096) and
        force rotation with a manual flush. Note: the rotation will only
        effectively occur if the audit log file size is greater than 4096.
        """

        # Get the current rotation size
        rotate_size = server.show_server_variable(
            "audit_log_rotate_on_size"
        )[0][1]
        min_rotation_size = 4096

        # If needed, set rotation size to the minimum allowed value.
        if int(rotate_size) != min_rotation_size:
            server.exec_query(
                "SET @@GLOBAL.audit_log_rotate_on_size = "
                "{0}".format(min_rotation_size)
            )

        # If needed, restore the rotation size to what it was initially.
        if int(rotate_size) != min_rotation_size:
            server.exec_query(
                "SET @@GLOBAL.audit_log_rotate_on_size = "
                "{0}".format(rotate_size)
            )

    @staticmethod
    def _change_policy(server, policy_value):
        """ Change the audit log plugin policy.

        This method changes the audit log policy by setting the appropriate
        variables according to the MySQL server version.

        Note: For recent MySQL server versions (i.e. >= 5.6.20, and >= 5.7.5)
        the audit_log_policy is readonly and cannot be changed at runtime
        (only when starting the server). For those versions, the policy
        results from the combination of the values set for the
        'audit_log_connection_policy' and 'audit_log_statement_policy'
        variables (not available in previous versions).

        server[in]          Instance of the server.
        policy_value[in]    Policy value to set, supported values: 'ALL',
                            'NONE', 'LOGINS', 'QUERIES', 'DEFAULT'.
        """
        # Check server version to set appropriate variables.
        if ((server.check_version_compat(5, 6, 20) and  # >= 5.6.20 and < 5.7
             not server.check_version_compat(5, 7, 0)) or
                server.check_version_compat(5, 7, 5)):  # >= 5.7.5
            # Set the audit_log_connection_policy and
            # audit_log_statement_policy to yield the chosen policy.
            policy = policy_value.upper()
            set_connection_policy = (
                "SET @@GLOBAL.audit_log_connection_policy = {0}"
            )
            set_statement_policy = (
                "SET @@GLOBAL.audit_log_statement_policy = {0}"
            )
            if policy == 'QUERIES':
                server.exec_query(set_connection_policy.format('NONE'))
                server.exec_query(set_statement_policy.format('ALL'))
            elif policy == 'LOGINS':
                server.exec_query(set_connection_policy.format('ALL'))
                server.exec_query(set_statement_policy.format('NONE'))
            else:
                server.exec_query(set_connection_policy.format(policy_value))
                server.exec_query(set_statement_policy.format(policy_value))
        else:
            # Set the audit_log_policy for older server versions.
            server.exec_query("SET @@GLOBAL.audit_log_policy = "
                              "{0}".format(policy_value))

    def do_command(self):
        """ Check and execute the audit log command (previously set by the the
        options of the object constructor).
        """
        # Check for valid command
        command = self.options.get("command", None)
        if command not in VALID_COMMANDS:
            raise UtilError("Invalid command.")

        command_value = self.options.get("value", None)
        # Check for valid value if needed
        if (command_requires_value(command)
           and not check_command_value(command, command_value)):
            raise UtilError("Please provide the correct value for the %s "
                            "command." % command)

        # Copy command does not need the server
        if command == "COPY":
            self._copy_log()
            return True

        # Connect to server
        server = Server({'conn_info': self.options.get("server_vals", None)})
        server.connect()

        # Now execute the command
        print "#\n# Executing %s command.\n#\n" % command
        try:
            if command == "POLICY":
                self._change_policy(server, command_value)
            elif command == "ROTATE":
                self._rotate_log(server)
            else:  # "ROTATE_ON_SIZE":
                server.exec_query("SET @@GLOBAL.audit_log_rotate_on_size = %s"
                                  % command_value)
        finally:
            server.disconnect()

        return True
Ejemplo n.º 4
0
 def open_log(self):
     """ Create an AuditLogParser and open the audit file.
     """
     self.log = AuditLogParser(self.options)
     self.log.open_log()
Ejemplo n.º 5
0
class AuditLog(object):
    """ Class to manage and parse the audit log.

    The AuditLog class is used to manage and retrieve information of the
    audit log. It allows the execution of commands to change audit log
    settings, display control variables, copy and parse audit log files.
    """

    def __init__(self, options):
        """Constructor

        options[in]       dictionary of options to include width, verbosity,
                          pedantic, quiet
        """
        self.options = options
        self.log = None

    def open_log(self):
        """ Create an AuditLogParser and open the audit file.
        """
        self.log = AuditLogParser(self.options)
        self.log.open_log()

    def close_log(self):
        """Close the previously opened audit log file.
        """
        self.log.close_log()

    def parse_log(self):
        """ Parse the audit log file (previously opened), applying
        search/filtering criterion.
        """
        self.log.parse_log()

    def output_formatted_log(self):
        """Output the parsed log entries according to the specified format.

        Print the entries resulting from the parsing process to the standard
        output in the specified format. If no entries are found (i.e., none
        match the defined search criterion) a notification message is print.
        """
        log_rows = self.log.retrieve_rows()
        if log_rows:
            out_format = self.options.get("format", "GRID")
            if out_format == 'raw':
                for row in log_rows:
                    sys.stdout.write(row)
            else:
                #Convert the results to the appropriate format
                cols, rows = convert_dictionary_list(log_rows)
                # Note: No need to sort rows, retrieved with the same order
                # as read (i.e., sorted by timestamp)
                print_list(sys.stdout, out_format, cols, rows)
        else:
            #Print message notifying that no entry was found
            no_entry_msg = "#\n# No entry found!\n#"
            print no_entry_msg

    def check_audit_log(self):
        """Verify if the audit log plugin is installed on the server.
        Return the message error if not, or None.
        """
        error = None
        server = Server({'conn_info': self.options.get("server_vals", None)})
        server.connect()
        # Check to see if the plug-in is installed
        if not server.supports_plugin("audit"):
            error = "The audit log plug-in is not installed on this " + \
                    "server or is not enabled."
        server.disconnect()

        return error

    def show_statistics(self):
        """Display statistical information about audit log including:
            - size, date, etc.
            - Audit log entries
        """
        out_format = self.options.get("format", "GRID")
        log_name = self.options.get("log_name", None)
        # Print file statistics:
        print "#\n# Audit Log File Statistics:\n#"
        from mysql.utilities.common.tools import show_file_statistics
        show_file_statistics(log_name, False, out_format)

        # Print audit log 'AUDIT' entries
        print "\n#\n# Audit Log Startup Entries:\n#\n"
        cols, rows = convert_dictionary_list(self.log.header_rows)
        # Note: No need to sort rows, retrieved with the same order
        # as read (i.e., sorted by timestamp)
        print_list(sys.stdout, out_format, cols, rows)

    def show_options(self):
        """ Show all audit log variables.
        """
        server = Server({'conn_info': self.options.get("server_vals", None)})
        server.connect()
        rows = server.show_server_variable("audit%")
        server.disconnect()
        if rows:
            print "#\n# Audit Log Variables and Options\n#"
            print_list(sys.stdout, "GRID", ['Variable_name', 'Value'],
                       rows)
            print
        else:
            raise UtilError("No audit log variables found.")

    def _copy_log(self):
        """ Copy the audit log to a local destionation or from a remote server.
        """
        # Need to see if this is a local copy or not.
        rlogin = self.options.get("rlogin", None)
        log_name = self.options.get("log_name", None)
        copy_location = self.options.get("copy_location", None)
        if not rlogin:
            from shutil import copy
            copy(log_name, copy_location)
        else:
            from mysql.utilities.common.tools import remote_copy
            user, host = rlogin.split(":", 1)
            remote_copy(log_name, user, host, copy_location,
                        self.options.get("verbosity", 0))

    def _rotate_log(self, server):
        """Rotate the log.

        To rotate the log, first discover the value of rotate_on_size
        then set rotate_on_size to the minimum allowed value (i.e. 4096) and
        force rotation with a manual flush. Note: the rotation will only
        effectively occur if the audit log file size is greater than 4096.
        """

        # Get the current rotation size
        rotate_size = server.show_server_variable(
                                            "audit_log_rotate_on_size")[0][1]
        min_rotation_size = 4096

        # If needed, set rotation size to the minimum allowed value.
        if int(rotate_size) != min_rotation_size:
            #
            server.exec_query("SET @@GLOBAL.audit_log_rotate_on_size = %d" % \
                              min_rotation_size)

        # Flush the audit_log forcing the rotation if the file size is greater
        # than the minimum (i.e. 4096).
        server.exec_query("SET @@GLOBAL.audit_log_flush = ON")

        # If needed, restore the rotation size to what it was initially.
        if int(rotate_size) != min_rotation_size:
            server.exec_query("SET @@GLOBAL.audit_log_rotate_on_size = %s" %
                          rotate_size)

    def do_command(self):
        """ Check and execute the audit log command (previously set by the the
        options of the object constructor).
        """
        # Check for valid command
        command = self.options.get("command", None)
        if not command in VALID_COMMANDS:
            raise UtilError("Invalid command.")

        command_value = self.options.get("value", None)
        # Check for valid value if needed
        if (command_requires_value(command)
            and not check_command_value(command, command_value)):
            raise UtilError("Please provide the correct value for the %s "
                             "command." % command)

        # Copy command does not need the server
        if command == "COPY":
            self._copy_log()
            return True

        # Connect to server
        server = Server({'conn_info': self.options.get("server_vals", None)})
        server.connect()

        # Now execute the command
        print "#\n# Executing %s command.\n#\n" % command
        try:
            if command == "POLICY":
                server.exec_query("SET @@GLOBAL.audit_log_policy = %s" %
                                  command_value)
            elif command == "ROTATE":
                self._rotate_log(server)
            else:  # "ROTATE_ON_SIZE":
                server.exec_query("SET @@GLOBAL.audit_log_rotate_on_size = %s"
                                  % command_value)
        finally:
            server.disconnect()

        return True