Source code for roster_core.helpers_lib

#!/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 is a library of static helper functions for Roster."""

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


import inspect
import IPy
import math

import constants
import copy
import errors


[docs]def GetFunctionNameAndArgs(): """Grabs the current frame and adjacent frames then finds the calling function name and arguments and returns them. Outputs: tuple: function name and current args ex: ('MakeUser', {'replay_args': [u'ahoward', 64], 'audit_args': {'access_level': 64, 'user_name': u'ahoward'}} """ current_frame = inspect.currentframe() try: outer_frames = inspect.getouterframes(current_frame) try: function_name = unicode(outer_frames[1][3]) calling_frame = outer_frames[1][0] try: arg_values = inspect.getargvalues(calling_frame) finally: del calling_frame finally: del outer_frames finally: del current_frame replay_args = [] audit_args = {} for arg in arg_values[0]: if( arg == 'self' ): continue audit_args[arg] = arg_values[3][arg] replay_args.append(arg_values[3][arg]) current_args = {'audit_args': audit_args, 'replay_args': replay_args} return (function_name, current_args)
[docs]def GetValidTables(): """Returns all of the tables in the database that are enumerated in this modules. Outputs: list: list of valid tables. example: ['acls', 'records', 'etc'] """ return constants.TABLES.keys()
[docs]def GetRowDict(table_name): """Returns a specific dictionary keyed off of table name. Inputs: table_name: string of table name from db Outputs: dictionary: dict of row that was requested (see constants above) """ row_dict = {} if( table_name in constants.TABLES.keys() ): row_dict = copy.copy(constants.TABLES[table_name]) return row_dict
[docs]def ReverseIP(ip_address): """Reverse an IP address Inputs: ip_address: either an ipv4 or ipv6 string Raises: InvalidInputError: Not a valid IP address. Outputs: string: reverse ip address """ try: ip_object = IPy.IP(ip_address) except ValueError: raise errors.InvalidInputError('%s is not a valid IP address' % ip_address) reverse_ip_string = ip_object.reverseName() if( ip_object.version() == 4 ): ip_parts = reverse_ip_string.split('.') if( '-' in ip_parts[0] ): ip_range = ip_parts.pop(0).split('-') num_ips = int(ip_range[1]) - int(ip_range[0]) + 1 netmask = int(32 - (math.log(num_ips) / math.log(2))) last_octet = ip_parts.pop(0) reverse_ip_string = '.'.join(ip_parts) reverse_ip_string = '%s/%s.%s' % (last_octet, netmask, reverse_ip_string) return unicode(reverse_ip_string)
[docs]def UnReverseIP(ip_address): """Un-Reverses reversed IP addresses Inputs: ip_address: either an ipv4 or ipv6 string (reversed) Outputs: string: forward ip address """ mask = 0 ip_address = ip_address.lower() cidr_parts = ip_address.split('/') if( len(cidr_parts) == 2 ): mask = cidr_parts[1].split('.')[0] ip_address = ip_address.replace('/%s' % mask, '') if( ip_address.endswith('in-addr.arpa.') ): octets = 0 ip_array = ip_address.split('.') ip_parts = [] while len(ip_array): ip_part = ip_array.pop() if( ip_part.isdigit() ): ip_parts.append(ip_part) octets += 1 new_ip = '.'.join(ip_parts) if( mask ): new_ip = '%s/%s' % (new_ip, mask) elif( octets < 4 ): new_ip = '%s/%s' % (new_ip, octets * 8) elif( ip_address.endswith('ip6.arpa.') ): if( len(ip_address.split('.')[:-3]) == 32 ): ip_array = ip_address.split('.')[:-3] ip_parts = [] while len(ip_array): ip_parts.append('%s%s%s%s' % (ip_array.pop(), ip_array.pop(), ip_array.pop(), ip_array.pop())) new_ip = ':'.join(ip_parts) else: ip_array = ip_address.split('.')[:-3] ip_parts = [] while( len(ip_array) > 3 ): ip_parts.append('%s%s%s%s' % (ip_array.pop(), ip_array.pop(), ip_array.pop(), ip_array.pop())) if( len(ip_array) > 0 ): ip_parts.append('%s' % (''.join(ip_array[::-1]))) new_ip = ':'.join(ip_parts) new_ip = '%s::/%s' % (new_ip, len(ip_address.split('.')[:-3] * 4)) else: new_ip = ip_address return new_ip
[docs]def CIDRExpand(cidr_block, begin=None, end=None): """Expands a cidr block to a list of ip addreses from begin (integer) to end (integer). Inputs: cidr_block: string of cidr_block begin: integer of ip address to start end: integer of ip address to end Raises: InvalidInputError: Not a valid CIDR block. Outputs: list: list of ip addresses in strings """ try: cidr_block = IPy.IP(cidr_block) except ValueError: raise errors.InvalidInputError('%s is not a valid cidr block' % cidr_block) ip_address_list = [] end_count = -1 length = cidr_block.len() count = 0 start_ip = cidr_block.int() if( begin ): start_ip = cidr_block.int() + begin if( begin and end ): end_count = end - begin elif( end ): end_count = end while( count != end_count and count != length and IPy.IP(start_ip + count) in cidr_block ): ip_address_list.append(unicode(IPy.IP(start_ip + count).strFullsize())) count += 1 return ip_address_list
[docs]def ExpandIPV6(ip_address): """Expands a shorthand ipv6 address to a full ipv6 address Inputs: ip_address: string of ipv6 address Raises: InvalidInputError: Not a valid IP address. InvalidInputError: Not a valid IPV6 address. Outputs: string: string of long ipv6 address """ try: ipv6_address = IPy.IP(ip_address) except ValueError: raise errors.InvalidInputError('%s is not a valid IP address' % ip_address) if( ipv6_address.version() != 6 ): raise errors.InvalidInputError('"%s" is not a valid IPV6 address.' % ipv6_address) return ipv6_address.strFullsize()
[docs]def GetRecordsFromRecordRowsAndArgumentRows(record_data, record_args_dict): """Takes data from joined records and record_arguments_record_assignments and creates record rows that are combined. Inputs: record_data: List of rows from ListRow with records and records_arguments_record_assignments joined. Outputs: list of record dictionaries Each dictionary can have different args depending on record type. All of them will include record_type, target, zone_name, ttl, and view_name regardless of record type. Below is an example of an mx record search. example: [{'record_type': 'mx', 'target': 'university.edu.', 'zone_name': 'university.edu', ttl: 3600, 'view_name': 'external', 'priority': 10, 'mail_server': 'smtp-01.university.edu.', 'last_user': 'sharrell}, {'record_type': 'mx', 'target': 'university.edu.', 'zone_name': 'university.edu', ttl: 3600, 'view_name': 'external', 'priority': 20, 'mail_server': 'smtp-02.university.edu.'}, 'last_user': 'sharrell}] """ full_record_dicts = {} del_id_list = [] for record in record_data: if( record['record_arguments_records_assignments_argument_name'] in record_args_dict and record_args_dict[record[ 'record_arguments_records_assignments_argument_name']] is not None and unicode(record_args_dict[record[ 'record_arguments_records_assignments_argument_name']]) != record['argument_value'] ): del_id_list.append(record['records_id']) if( not record['record_arguments_records_assignments_record_id'] in full_record_dicts ): full_record_dicts[ record['record_arguments_records_assignments_record_id']] = {} full_record_dicts[ record['record_arguments_records_assignments_record_id']][ 'record_type'] = record['record_type'] full_record_dicts[ record['record_arguments_records_assignments_record_id']][ 'zone_name'] = record['record_zone_name'] if( record['record_view_dependency'].endswith('_dep') ): record['record_view_dependency'] = record[ 'record_view_dependency'][:-4:] full_record_dicts[ record['record_arguments_records_assignments_record_id']][ 'view_name'] = record['record_view_dependency'] full_record_dicts[ record['record_arguments_records_assignments_record_id']][ 'target'] = record['record_target'] full_record_dicts[ record['record_arguments_records_assignments_record_id']][ 'ttl'] = record['record_ttl'] full_record_dicts[ record['record_arguments_records_assignments_record_id']][ 'last_user'] = record['record_last_user'] if( record['argument_value'].isdigit() ): record['argument_value'] = int(record['argument_value']) full_record_dicts[ record['record_arguments_records_assignments_record_id']][record[ 'record_arguments_records_assignments_argument_name']] = record[ 'argument_value'] for record_id in set(del_id_list): del full_record_dicts[record_id] return full_record_dicts.values()
[docs]def UnicodeString(string): """Returns unicode string if object is a string Inputs: string: string to unicode Outputs: unicode string: if input is a string """ if( type(string) == str ): return unicode(string) return string # vi: set ai aw sw=2: