def testVal_object_group_network_02(): """Test recursion through a group object""" conf = ['!', 'name 1.1.2.20 loghost01', 'name 1.2.2.20 loghost02', '!', 'object-group network INSIDE_recurse', ' network-object host loghost02', 'object-group network INSIDE_addrs', ' network-object host loghost01', ' network-object host 1.1.2.1', ' network-object 1.1.2.2 255.255.255.255', ' network-object 1.1.2.0 255.255.255.0', ' group-object INSIDE_recurse', '!',] cfg_factory = CiscoConfParse(conf, factory=True, syntax='asa') obj = cfg_factory.find_objects(r'object-group\snetwork')[1] result_correct_01 = [IPv4Obj('1.1.2.20/32'), IPv4Obj('1.1.2.1/32'), IPv4Obj('1.1.2.2/32'), IPv4Obj('1.1.2.0/24'), IPv4Obj('1.2.2.20/32')] result_correct_02 = ['1.1.2.20', '1.1.2.1', '1.1.2.2', '1.1.2.0/255.255.255.0', '1.2.2.20'] # Ensure obj.name is set correctly assert obj.name=="INSIDE_addrs" assert obj.networks==result_correct_01 assert obj.network_strings==result_correct_02 ## Test obj.networks again to test the result_cache assert obj.networks==result_correct_01
def testVal_IOSIntfLine_in_ipv4_subnets(self): cfg = CiscoConfParse(self.c01, factory=True) result_correct = { 'interface Serial 1/0': True, 'interface Serial 1/1': True, 'interface GigabitEthernet4/1': None, 'interface GigabitEthernet4/2': None, 'interface GigabitEthernet4/3': None, 'interface GigabitEthernet4/4': None, 'interface GigabitEthernet4/5': None, 'interface GigabitEthernet4/6': None, 'interface GigabitEthernet4/7': None, 'interface GigabitEthernet4/8.120': True, 'interface ATM5/0/0': None, 'interface ATM5/0/0.32 point-to-point': True, 'interface ATM5/0/1': None, } test_result = dict() ## Parse all interface objects in self.c01 and check in_ipv4_subnets test_network1 = IPv4Obj('1.1.0.0/23', strict=False) test_network2 = IPv4Obj('1.1.2.0/23', strict=False) networks = set([test_network1, test_network2]) for intf_obj in cfg.find_objects('^interface'): test_result[intf_obj.text] = intf_obj.in_ipv4_subnets(networks) self.maxDiff = None self.assertEqual(result_correct, test_result)
def ip_network_object(self): try: return IPv4Obj('%s/%s' % (self.ipv4_addr, self.ipv4_netmask), strict=False).network except AttributeError: return IPv4Obj('%s/%s' % (self.ipv4_addr, self.ipv4_netmask), strict=False).network_address except: return self.default_ipv4_addr_object
def testIPv4Obj_contain(self): ## Test ccp_util.IPv4Obj.__contains__() ## ## Test whether a prefix is or is not contained in another prefix results_correct = [ ('1.0.0.0/8', '0.0.0.0/0', True), # Is 1.0.0.0/8 in 0.0.0.0/0? ('0.0.0.0/0', '1.0.0.0/8', False), # Is 0.0.0.0/0 in 1.0.0.0/8? ('1.1.1.0/27', '1.0.0.0/8', True), # Is 1.1.1.0/27 in 1.0.0.0/8? ('1.1.1.0/27', '9.9.9.9/32', False), # Is 1.1.1.0/27 in 9.9.9.9/32? ('9.9.9.0/27', '9.9.9.9/32', False), # Is 9.9.9.0/27 in 9.9.9.9/32? ] for prefix1, prefix2, result_correct in results_correct: ## 'foo in bar' tests bar.__contains__(foo) test_result = IPv4Obj(prefix1) in IPv4Obj(prefix2) self.assertEqual(test_result, result_correct)
def ipv4_standby_addr_object(self): """Return a ccp_util.IPv4Obj object representing the standby address on this interface; if there is no address, return IPv4Obj('127.0.0.1/32')""" try: return IPv4Obj('%s/%s' % (self.ipv4_standby_addr, self.ipv4_netmask)) except: return self.default_ipv4_addr_object
def testValues_IOSIntfLine_find_objects_factory_02(parse_c01_factory, c01_insert_serial_replace): """test whether find_objects() returns correct IOSIntfLine objects and tests IOSIntfLine methods""" with patch(__name__ + '.' + 'IOSIntfLine') as mockobj: # the mock pretends to be an IOSCfgLine so we can test against it result_correct01 = mockobj result_correct01.linenum = 12 result_correct01.text = 'interface Serial 2/0' result_correct01.classname = 'IOSIntfLine' result_correct01.ipv4_addr_object = IPv4Obj('1.1.1.1/30', strict=False) result_correct02 = c01_insert_serial_replace # Insert a line above the IOSIntfLine object parse_c01_factory.insert_before('interface Serial 1/0', 'default interface Serial 1/0') # Replace text in the IOSIntfLine object parse_c01_factory.replace_lines('interface Serial 1/0', 'interface Serial 2/0', exactmatch=False) test_result01 = parse_c01_factory.find_objects( '^interface Serial 2/0')[0] test_result02 = parse_c01_factory.ioscfg # Check attributes of the IOSIntfLine object assert result_correct01.linenum == test_result01.linenum assert result_correct01.text == test_result01.text assert result_correct01.classname == test_result01.classname assert result_correct01.ipv4_addr_object == test_result01.ipv4_addr_object # Ensure the text configs are exactly what we wanted assert result_correct02 == test_result02
def network_object(self): try: if self.address_family == 'ip': return IPv4Obj('%s/%s' % (self.network, self.netmask), strict=False) elif self.address_family == 'ipv6': return IPv6Network('%s/%s' % (self.network, self.netmask)) except: return None
def networks(self): """Return a list of IPv4Obj objects which represent the address space allowed by This object-group""" retval = list() names = self.confobj.names for obj in self.children: if 'network-object host ' in obj.text: host_str = obj.re_match_typed(_RE_NETHOST, group=1, result_type=str) retval.append(IPv4Obj(names.get(host_str, host_str))) elif 'network-object ' in obj.text: network_str = obj.re_match_typed(_RE_NETWORK1, group=1, result_type=str) netmask_str = obj.re_match_typed(_RE_NETWORK2, group=1, result_type=str) retval.append( IPv4Obj('{0} {1}'.format( names.get(network_str, network_str), netmask_str))) elif 'group-object ' in obj.text: name = obj.re_match_typed(r'^\s*group-object\s+(\S+)', group=1, result_type=str) group_nets = self.confobj.object_group_network.get(name, None) if name == self.name: ## Throw an error when importing self raise ValueError( "FATAL: Cannot recurse through group-object {0} in object-group network {1}" .format(name, self.name)) if (group_nets is None): raise ValueError( "FATAL: Cannot find group-object named {0}".format( name)) else: retval.extend(group_nets.networks) elif 'description ' in obj.text: pass else: raise NotImplementedError("Cannot parse '{0}'".format( obj.text)) return retval
def in_ipv4_subnet(self, ipv4network=IPv4Obj('0.0.0.0/32', strict=False)): """Accept two string arguments for network and netmask, and return a boolean for whether this interface is within the requested subnet. Return None if there is no address on the interface""" if not (str(self.ipv4_addr_object.ip) == "127.0.0.1"): try: # Return a boolean for whether the interface is in that network and mask return self.ipv4_addr_object in ipv4network except: raise ValueError( "FATAL: %s.in_ipv4_subnet(ipv4network={0}) is an invalid arg" .format(ipv4network)) else: return None
def testIPv4Obj_parse(self): ## Ensure that IPv4Obj can correctly parse various inputs test_strings = [ '1.0.0.1/24', '1.0.0.1/32', '1.0.0.1 255.255.255.0', '1.0.0.1 255.255.255.255', '1.0.0.1 255.255.255.0', '1.0.0.1 255.255.255.255', '1.0.0.1/255.255.255.0', '1.0.0.1/255.255.255.255', ] for test_string in test_strings: test_result = IPv4Obj(test_string) self.assertTrue(isinstance(test_result, IPv4Obj))
def testVal_object_group_network(self): conf = [ '!', 'name 1.1.2.20 loghost01', '!', 'object-group network INSIDE_addrs', ' network-object host loghost01', ' network-object host 1.1.2.1', ' network-object 1.1.2.2 255.255.255.255', ' network-object 1.1.2.0 255.255.255.0', '!', ] cfg_factory = CiscoConfParse(conf, factory=True, syntax='asa') obj = cfg_factory.find_objects(r'object-group\snetwork')[0] # Ensure obj.name is set correctly self.assertEqual(obj.name, "INSIDE_addrs") result_correct = [ IPv4Obj('1.1.2.20/32'), IPv4Obj('1.1.2.1/32'), IPv4Obj('1.1.2.2/32'), IPv4Obj('1.1.2.0/24') ] self.assertEqual(obj.networks, result_correct)
def networks(self): """Return a list of IPv4Obj objects which represent the address space allowed by This object-group""" ## FIXME: Implement object caching for other ASAConfigList objects ## Return a cached result if the networks lookup has already been done retval = list() for net_str in self.network_strings: ## Check the ASACfgList cache of network objects if not self.confobj._network_cache.get(net_str, False): net = IPv4Obj(net_str) self.confobj._network_cache[net_str] = net retval.append(net) else: retval.append(self.confobj._network_cache[net_str]) return retval
def testValues_IOSIntfLine_find_objects_factory_01(parse_c01_factory): """test whether find_objects() returns correct IOSIntfLine objects and tests IOSIntfLine methods""" # mockobj pretends to be the IOSIntfLine object with patch(__name__ + '.' + 'IOSIntfLine') as mockobj: # the mock pretends to be an IOSCfgLine so we can test against it result_correct = mockobj result_correct.linenum = 11 result_correct.text = 'interface Serial 1/0' result_correct.classname = 'IOSIntfLine' result_correct.ipv4_addr_object = IPv4Obj('1.1.1.1/30', strict=False) # this test finds the IOSIntfLine instance for 'Serial 1/0' test_result = parse_c01_factory.find_objects( '^interface Serial 1/0')[0] assert result_correct.linenum == test_result.linenum assert result_correct.text == test_result.text assert result_correct.classname == test_result.classname assert result_correct.ipv4_addr_object == test_result.ipv4_addr_object
def testIPv4Obj_attributes(self): ## Ensure that attributes are accessible and pass the smell test test_object = IPv4Obj('1.0.0.1 255.255.255.0') results_correct = [ ('ip', IPv4Address('1.0.0.1')), ('netmask', IPv4Address('255.255.255.0')), ('prefixlen', 24), ('broadcast', IPv4Address('1.0.0.255')), ('network', IPv4Network('1.0.0.0/24')), ('hostmask', IPv4Address('0.0.0.255')), ('numhosts', 256), ('version', 4), ('is_reserved', False), ('is_multicast', False), ('is_private', False), ('as_decimal', 16777217), ('as_hex_tuple', ('01', '00', '00', '01')), ('as_binary_tuple', ('00000001', '00000000', '00000000', '00000001')), ] for attribute, result_correct in results_correct: self.assertEqual(getattr(test_object, attribute), result_correct)
def __init__(self, *args, **kwargs): super(BaseASAIntfLine, self).__init__(*args, **kwargs) self.ifindex = None # Optional, for user use self.default_ipv4_addr_object = IPv4Obj('127.0.0.1/32', strict=False)
def testIPv4Obj_recursive(): """IPv4Obj() should be able to parse itself""" obj = IPv4Obj(IPv4Obj('1.1.1.1/24')) assert str(obj.ip_object) == '1.1.1.1' assert obj.prefixlen == 24
def testVal_IOSIntfLine_ipv4_network_object(self): cfg = CiscoConfParse(self.c01, factory=True) result_correct = { 'interface Serial 1/0': IPv4Obj('1.1.1.0/30', strict=False), 'interface Serial 1/1': IPv4Obj('1.1.1.8/31', strict=False), 'interface GigabitEthernet4/1': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/2': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/3': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/4': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/5': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/6': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/7': IPv4Obj('127.0.0.1/32', strict=False), 'interface GigabitEthernet4/8.120': IPv4Obj('1.1.2.0/24', strict=False), 'interface ATM5/0/0': IPv4Obj('127.0.0.1/32', strict=False), 'interface ATM5/0/0.32 point-to-point': IPv4Obj('1.1.1.4/30', strict=False), 'interface ATM5/0/1': IPv4Obj('127.0.0.1/32', strict=False), } test_result = dict() ## Parse all interface objects in self.c01 and check ipv4_network_object for intf_obj in cfg.find_objects('^interface'): test_result[intf_obj.text] = intf_obj.ipv4_network_object self.assertEqual(result_correct, test_result)