def testNegateWithNetwork(self): expected_result = """\ # $Id:$ # $Date:$ # $Revision:$ netdestination good-term-negate_src network 100.0.0.0 255.0.0.0 ! ip access-list session test-filter no alias good-term-negate_src any any deny ! """ self.naming.GetNetAddr.return_value = [nacaddr.IP('100.0.0.0/8')] aru = aruba.Aruba( policy.ParsePolicy(GOOD_HEADER_V4 + GOOD_TERM_NEGATE_1, self.naming), EXP_INFO) self.assertEqual(textwrap.dedent(expected_result), str(aru))
def testRemark(self): self.naming.GetNetAddr.return_value = [nacaddr.IP('10.1.1.1/32')] # Extended ACLs should have extended remark style. acl = cisco.Cisco( policy.ParsePolicy(GOOD_EXTENDED_NUMBERED_HEADER + GOOD_TERM_1, self.naming), EXP_INFO) self.failUnless('ip access-list extended 150' in str(acl), str(acl)) self.failUnless(' remark numbered extended' in str(acl), str(acl)) self.failIf('150 remark' in str(acl), str(acl)) # Extended ACLs should have extended remark style. acl = cisco.Cisco( policy.ParsePolicy( GOOD_STANDARD_NUMBERED_HEADER + GOOD_STANDARD_TERM_1, self.naming), EXP_INFO) self.failUnless('access-list 50 remark' in str(acl), str(acl)) self.naming.GetNetAddr.assert_called_once_with('SOME_HOST')
def testMaxRuleLimitEnforcement(self): test_1001_ips_list = [] for _ in range(1001): random_ip_octets = [] for _ in range(4): random_ip_octets.append(str(int(random.randint(1, 255)))) rand_ip = '.'.join(random_ip_octets) test_1001_ips_list.append(nacaddr.IP(rand_ip + '/32')) self.naming.GetNetAddr.return_value = test_1001_ips_list self.assertRaisesRegex( cloudarmor.ExceededMaxTermsError, 'Exceeded maximum number of rules in a single policy | MAX = 200', cloudarmor.CloudArmor, policy.ParsePolicy(GOOD_HEADER + GOOD_TERM_ALLOW, self.naming), EXP_INFO)
def testStateless(self): ip = nacaddr.IP('10.0.0.0/8') ip.parent_token = 'PROD_NETWORK' self.naming.GetNetAddr.return_value = [ip] self.naming.GetServiceByProto.return_value = ['25'] acl = packetfilter.PacketFilter(policy.ParsePolicy( GOOD_HEADER_STATELESS + GOOD_TERM_TCP, self.naming), EXP_INFO) result = str(acl) self.failUnless('# term good-term-tcp' in result, 'did not find comment for good-term-tcp') self.failUnless( 'pass quick proto { tcp } from { any } to { <PROD_NETWORK> } port ' '{ 25 } no state' in result, 'did not find actual term for good-term-tcp') self.naming.GetNetAddr.assert_called_once_with('PROD_NETWORK') self.naming.GetServiceByProto.assert_called_once_with('SMTP', 'tcp')
def testDirectional(self): ip = nacaddr.IP('10.0.0.0/8') ip.parent_token = 'PROD_NETWORK' self.naming.GetNetAddr.return_value = [ip] self.naming.GetServiceByProto.return_value = ['25'] acl = packetfilter.PacketFilter( policy.ParsePolicy(GOOD_HEADER_DIRECTIONAL + GOOD_TERM_TCP, self.naming), EXP_INFO) result = str(acl) self.assertIn('# term good-term-tcp', result, 'did not find comment for good-term-tcp') self.assertIn( 'pass out quick proto { tcp } from { any } to { <PROD_NETWORK> } port ' '{ 25 }', result, 'did not find actual term for good-term-tcp') self.naming.GetNetAddr.assert_called_once_with('PROD_NETWORK') self.naming.GetServiceByProto.assert_called_once_with('SMTP', 'tcp')
def testStandardTermHostIPv6(self): self.naming.GetNetAddr.return_value = [nacaddr.IP('2001::3/128')] self.naming.GetServiceByProto.return_value = ['80'] pol = policy.ParsePolicy(GOOD_HEADER_2 + GOOD_TERM_2 + GOOD_TERM_4, self.naming) acl = ciscoxr.CiscoXR(pol, EXP_INFO) expected = 'ipv6 access-list ipv6-test-filter' self.failUnless(expected in str(acl), '[%s]' % str(acl)) expected = ' permit tcp any eq 80 host 2001::3' self.failUnless(expected in str(acl), str(acl)) expected = ' permit ipv6 host 2001::3 any' self.failUnless(expected in str(acl), str(acl)) self.naming.GetNetAddr.assert_has_calls( [mock.call('SOME_HOST2'), mock.call('SOME_HOST2')]) self.naming.GetServiceByProto.assert_called_once_with('HTTP', 'tcp')
def testTranslatePolicyMixedFilterInetOnly(self): """Test for Nsxv.test_TranslatePolicy. Testing Mixed filter with inet.""" self.naming.GetNetAddr.return_value = [nacaddr.IP('10.0.0.0/8')] self.naming.GetServiceByProto.return_value = ['25'] pol = policy.ParsePolicy(MIXED_FILTER_INET_ONLY, self.naming, False) translate_pol = nsxv.Nsxv(pol, EXP_INFO) nsxv_policies = translate_pol.nsxv_policies for (_, filter_name, filter_list, terms) in nsxv_policies: self.assertEqual(filter_name, 'mixed') self.assertEqual(filter_list, ['mixed']) self.assertEqual(len(terms), 1) self.assertIn('10.0.0.0/8', str(terms[0])) self.naming.GetNetAddr.assert_has_calls( [mock.call('MAIL_SERVERS')]) self.naming.GetServiceByProto.assert_has_calls( [mock.call('MAIL_SERVICES', 'tcp')] * 1)
def GetNet(self, query): """Expand a network token into a list of nacaddr.IPv4 or nacaddr.IPv6 objects. Args: query: Network definition token which may include comment text Raises: BadNetmaskTypeError: Results when an unknown netmask_type is specified. Acceptable values are 'cidr', 'netmask', and 'hostmask'. Returns: List of nacaddr.IPv4 or nacaddr.IPv6 objects Raises: UndefinedAddressError: for an undefined token value """ returnlist = [] data = [] token = '' data = query.split('#') # Get the token keyword and remove any comment token = data[0].split()[0] # Remove whitespace and cast from list to string if token not in self.networks: raise UndefinedAddressError('%s %s' % ('\nUNDEFINED:', str(token))) for i in self.networks[token].items: comment = '' if i.find('#') > -1: (net, comment) = i.split('#', 1) else: net = i try: net = net.strip() # TODO(robankeny): Fix using error to continue processing. addr = nacaddr.IP(net, strict=False) addr.text = comment.lstrip() addr.token = token returnlist.append(addr) except ValueError: # if net was something like 'FOO', or the name of another token which # needs to be dereferenced, nacaddr.IP() will return a ValueError returnlist.extend(self.GetNet(net)) for i in returnlist: i.parent_token = token return returnlist
def testSrcFsMixed(self): self.naming.GetNetAddr.side_effect = [ [ nacaddr.IP("8.8.4.0/24"), nacaddr.IP("8.8.8.0/24"), nacaddr.IP("2001:4860:4860::/64"), nacaddr.IP("2001:4860:4860::/64"), nacaddr.IP("2001:4860:4861::/64") ], [ nacaddr.IP("2001:4860:4860::8844"), nacaddr.IP("2001:4860:4861::8888"), nacaddr.IP("8.8.4.4"), nacaddr.IP("8.8.8.8"), ], ] atp = arista_tp.AristaTrafficPolicy( policy.ParsePolicy(GOOD_HEADER + SRC_FIELD_SET_MIXED, self.naming), EXP_INFO) output = str(atp) self.assertIn("field-set ipv4 prefix src-FS_MIXED", output, output) self.assertIn("field-set ipv6 prefix src-ipv6-FS_MIXED", output, output) self.assertIn("source prefix field-set src-FS_MIXED", output, output) self.assertIn("source prefix field-set src-ipv6-FS_MIXED", output, output)
def testTcp(self): self.naming.GetNetAddr.return_value = [nacaddr.IP('10.0.0.0/8')] self.naming.GetServiceByProto.return_value = ['25'] acl = windows_ipsec.WindowsIPSec( policy.ParsePolicy(GOOD_HEADER + GOOD_TERM_TCP, self.naming), EXP_INFO) result = str(acl) self.assertTrue([ 'filteraction name=t_good-term-tcp-action action=permit', 'filter filterlist=t_good-term-tcp-list mirrored=yes srcaddr=any ' ' dstaddr=10.0.0.0 dstmask=8 dstport=25', 'rule name=t_good-term-tcp-rule policy=test-filter' ' filterlist=t_good-term-tcp-list' ' filteraction=t_good-term-tcp-action' ], result, 'good-term-tcp') self.naming.GetNetAddr.assert_called_once_with('PROD_NET') self.naming.GetServiceByProto.assert_called_once_with('SMTP', 'tcp')
def testProtocolIsContiguousRange(self): expected_result = """\ # $Id:$ # $Date:$ # $Revision:$ netdestination good-term-destination-is-user_src network 100.0.0.0 255.0.0.0 ! ip access-list session test-filter alias good-term-destination-is-user_src user tcp 53 55 permit ! """ self.naming.GetNetAddr.return_value = [nacaddr.IP('100.0.0.0/8')] self.naming.GetServiceByProto.return_value = ['53-55', '54'] aru = aruba.Aruba( policy.ParsePolicy(GOOD_HEADER_V4 + GOOD_TERM_DESTINATION_IS_USER, self.naming), EXP_INFO) self.assertEqual(textwrap.dedent(expected_result), str(aru))
def testSingleNetdestinationIPv6(self): expected_result = """\ # $Id:$ # $Date:$ # $Revision:$ netdestination6 gt-one-netd_src host 2001:: ! ip access-list session test-filter ipv6 alias gt-one-netd_src any 1 permit ! """ self.naming.GetNetAddr.return_value = [nacaddr.IP('2001::/128')] aru = aruba.Aruba( policy.ParsePolicy( GOOD_HEADER_V6 + GOOD_TERM_SINGLE_NETDESTINATION, self.naming), EXP_INFO) self.assertEqual(textwrap.dedent(expected_result), str(aru))
def testSourceIsUser(self): expected_result = """\ # $Id:$ # $Date:$ # $Revision:$ netdestination good-term-source-is-user_dst network 100.0.0.0 255.0.0.0 ! ip access-list session test-filter user alias good-term-source-is-user_dst tcp 53 permit ! """ self.naming.GetNetAddr.return_value = [nacaddr.IP('100.0.0.0/8')] self.naming.GetServiceByProto.return_value = ['53'] aru = aruba.Aruba( policy.ParsePolicy(GOOD_HEADER_V4 + GOOD_TERM_SOURCE_IS_USER, self.naming), EXP_INFO) self.assertEqual(textwrap.dedent(expected_result), str(aru))
def testMultipleCallsSingleNetdestinationsBlock(self): expected_result = textwrap.dedent("""\ # $Id:$ # $Date:$ # $Revision:$ netdestination gt-one-netd_src host 10.1.1.1 ! ip access-list session test-filter alias gt-one-netd_src any 1 permit ! """) self.naming.GetNetAddr.return_value = [nacaddr.IP('10.1.1.1/32')] aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V4 + GOOD_TERM_SINGLE_NETDESTINATION, self.naming), EXP_INFO) self.assertEqual(expected_result, str(aru)) self.assertEqual(expected_result, str(aru))
def testNakedExclude(self): SMALL = [nacaddr.IP('10.0.0.0/24', 'SMALL', 'SMALL')] self.naming.GetNetAddr.side_effect = [SMALL] pol = policy.ParsePolicy(GOOD_HEADER + GOOD_TERM_18, self.naming) output = str(junipersrx.JuniperSRX(pol, EXP_INFO)) self.failUnless( 'address GOOD_TERM_18_SRC_EXCLUDE_2 10.0.1.0/24;' in output, output) self.failUnless( 'address GOOD_TERM_18_SRC_EXCLUDE_3 10.0.2.0/23;' in output, output) self.failUnless( 'address GOOD_TERM_18_SRC_EXCLUDE_4 10.0.4.0/22;' in output, output) self.failUnless( 'address GOOD_TERM_18_SRC_EXCLUDE_5 10.0.8.0/21;' in output, output) self.assertFalse('10.0.0.0' in output)
def testMixedToMixed(self): self.naming.GetNetAddr.side_effect = [ [ nacaddr.IP('8.8.4.4'), nacaddr.IP('8.8.8.8'), nacaddr.IP('2001:4860:4860::8844'), nacaddr.IP('2001:4860:4860::8888') ], [ nacaddr.IP('8.8.4.4'), nacaddr.IP('8.8.8.8'), nacaddr.IP('2001:4860:4860::8844'), nacaddr.IP('2001:4860:4860::8888') ] ] source_addr, dest_addr = self.get_source_dest_addresses(MIXED_HEADER + MIXED_TO_MIXED) self.verify_mixed_address_types(source_addr) self.verify_mixed_address_types(dest_addr) self.naming.GetNetAddr.assert_has_calls([mock.call('GOOGLE_DNS')] * 2)
def testStandardTermHost(self): self.naming.GetNetAddr.return_value = [nacaddr.IP('10.1.1.0/24')] self.naming.GetServiceByProto.return_value = ['22', '6537'] pol = policy.ParsePolicy(GOOD_HEADER_2 + GOOD_TERM_2 + GOOD_TERM_3, self.naming) acl = arista.Arista(pol, EXP_INFO) expected = 'ip access-list test-filter' self.assertIn(expected, str(acl), '[%s]' % str(acl)) expected = ' permit tcp 10.1.1.0/24 any eq ssh' self.assertIn(expected, str(acl), str(acl)) expected = ' permit tcp 10.1.1.0/24 any eq 6537' self.assertIn(expected, str(acl), str(acl)) self.naming.GetNetAddr.assert_has_calls( [mock.call('SOME_HOST'), mock.call('SOME_HOST2')]) self.naming.GetServiceByProto.assert_has_calls( [mock.call('SSH', 'tcp'), mock.call('GOPENFLOW', 'tcp')])
def testTableNameShortened(self): prod_network = nacaddr.IP('10.0.0.0/8') prod_network.parent_token = 'PROD_NETWORK_EXTREAMLY_LONG_VERY_NO_GOOD_NAME' self.naming.GetNetAddr.return_value = [prod_network] self.naming.GetServiceByProto.return_value = ['53'] acl = packetfilter.PacketFilter( policy.ParsePolicy(GOOD_HEADER_DIRECTIONAL + LONG_NAME_TERM_DNS_TCP, self.naming), EXP_INFO) result = str(acl) self.assertIn( 'table <PROD_NETWORK_EXTREAMLY_LONG_VER> {10.0.0.0/8}', result, 'did not find shortened name in header.') self.assertIn( 'pass out quick proto { tcp } from { any } to ' '{ <PROD_NETWORK_EXTREAMLY_LONG_VER> } ' 'port { 53 } flags S/SA keep state', result, 'did not find actual term for multiple-name') self.naming.GetNetAddr.assert_called_once_with( 'PROD_NETWORK_EXTREAMLY_LONG_VERY_NO_GOOD_NAME') self.naming.GetServiceByProto.assert_called_once_with('DNS', 'tcp')
def testTwoNetdestinationsIPv4(self): expected_result = """\ # $Id:$ # $Date:$ # $Revision:$ netdestination gt-two-netd_src host 10.1.1.1 ! netdestination gt-two-netd_dst host 10.1.1.1 ! ip access-list session test-filter alias gt-two-netd_src alias gt-two-netd_dst 1 permit ! """ self.naming.GetNetAddr.return_value = [nacaddr.IP('10.1.1.1/32')] aru = aruba.Aruba( policy.ParsePolicy(GOOD_HEADER_V4 + GOOD_TERM_TWO_NETDESTINATIONS, self.naming), EXP_INFO) self.assertEqual(textwrap.dedent(expected_result), str(aru))
def testTwoNetworkNetdestinationsIPv6(self): expected_result = """\ # $Id:$ # $Date:$ # $Revision:$ netdestination6 gt-mix-netd_src network 2001::/64 ! netdestination6 gt-mix-netd_dst network 2001::/64 ! ip access-list session test-filter ipv6 alias gt-mix-netd_src alias gt-mix-netd_dst 1 permit ! """ self.naming.GetNetAddr.return_value = [nacaddr.IP('2001::/64')] aru = aruba.Aruba(policy.ParsePolicy(GOOD_HEADER_V6 + GOOD_TERM_TWO_NETWORK_NETDESTINATIONS, self.naming), EXP_INFO) self.assertEqual(textwrap.dedent(expected_result), str(aru))
def testMixedToV4(self): self.naming.GetNetAddr.side_effect = [[ nacaddr.IP('8.8.4.4'), nacaddr.IP('8.8.8.8'), nacaddr.IP('2001:4860:4860::8844'), nacaddr.IP('2001:4860:4860::8888') ], [ nacaddr.IP('10.0.0.0/8'), nacaddr.IP('172.16.0.0/12'), nacaddr.IP('192.168.0.0/16') ]] source_addr, dest_addr = self.get_source_dest_addresses(MIXED_HEADER + MIXED_TO_V4) self.verify_address_type(source_addr, 'Ipv4Address') self.verify_address_type(dest_addr, 'Ipv4Address') self.naming.GetNetAddr.assert_has_calls( [mock.call('GOOGLE_DNS'), mock.call('INTERNAL')])
def testMixedInet(self): self.naming.GetNetAddr.side_effect = [[ nacaddr.IP("8.8.4.4"), nacaddr.IP("8.8.8.8"), nacaddr.IP("2001:4860:4860::8844"), nacaddr.IP("2001:4860:4860::8888") ], [ nacaddr.IP("10.0.0.0/8"), nacaddr.IP("172.16.0.0/12"), nacaddr.IP("192.168.0.0/16") ]] pol = policy.ParsePolicy(GOOD_HEADER + MIXED_INET, self.naming) atp = arista_tp.AristaTrafficPolicy(pol, EXP_INFO) output = str(atp) self.assertIn("match MIXED_INET ipv4", output, output) self.assertIn("source prefix 8.8.4.4/32", output, output) self.assertIn("destination prefix 10.0.0.0/8", output, output) self.assertNotIn("match ipv6-MIXED_INET ipv6", output, output) self.assertNotIn("source prefix 2001:4860:4860::8844/128", output, output)
def testRemark(self): self.naming.GetNetAddr.return_value = [nacaddr.IP('10.1.1.1/32')] # Extended ACLs should have extended remark style. acl = cisco.Cisco(policy.ParsePolicy( GOOD_EXTENDED_NUMBERED_HEADER + GOOD_TERM_1, self.naming), EXP_INFO) self.assertIn('ip access-list extended 150', str(acl), str(acl)) self.assertIn(' remark numbered extended', str(acl), str(acl)) self.assertNotIn('150 remark', str(acl), str(acl)) # Standard ACLs should have standard remark style. acl = cisco.Cisco(policy.ParsePolicy( GOOD_STANDARD_NUMBERED_HEADER + GOOD_STANDARD_TERM_1, self.naming), EXP_INFO) self.assertIn('access-list 50 remark numbered standard', str(acl), str(acl)) self.assertIn('access-list 50 remark standard-term-1', str(acl), str(acl)) self.assertIn('access-list 50 remark %sId:%s' % ('$', '$'), str(acl), str(acl)) self.assertNotIn('access-list 50 remark %sRevision:%s' % ('$', '$'), str(acl), str(acl)) self.naming.GetNetAddr.assert_called_once_with('SOME_HOST')
def get_nets_and_highest_prefix(ip, net_group, db): """Find the highest prefix length in all networks given it contains the IP. Args: ip: the IP address contained in net_group net_group: the name of the network object we'll be looking through db: network and service definitions Returns: highest_prefix_length, networks as tuple highest_prefix_length : the longest prefix length found, networks : network objects """ highest_prefix_length = 0 networks = [] ip = nacaddr.IP(ip) # loop through all the networks in the net_group for net in get_nets([net_group], db)[0][1]: # find the highest prefix length for the networks that contain the IP if ip in net: networks.append(str(net)) if net.prefixlen > highest_prefix_length: highest_prefix_length = net.prefixlen return highest_prefix_length, networks
def testDuplicateTermNames(self): self.naming.GetNetAddr.return_value = [nacaddr.IP('10.0.0.0/24')] pol = policy.ParsePolicy(GOOD_STANDARD_HEADER_1 + GOOD_STANDARD_TERM_1 + GOOD_STANDARD_TERM_1, self.naming) self.assertRaises(cisco.CiscoDuplicateTermError, cisco.Cisco, pol, EXP_INFO)
def _TranslatePolicy(self, pol, exp_info): self.gce_policies = [] max_attribute_count = 0 total_attribute_count = 0 total_rule_count = 0 current_date = datetime.datetime.utcnow().date() exp_info_date = current_date + datetime.timedelta(weeks=exp_info) for header, terms in pol.filters: if self._PLATFORM not in header.platforms: continue filter_options = header.FilterOptions(self._PLATFORM) filter_name = header.FilterName(self._PLATFORM) network = '' direction = 'INGRESS' if filter_options: for i in self._GOOD_DIRECTION: if i in filter_options: direction = i filter_options.remove(i) for opt in filter_options: try: max_attribute_count = int(opt) logging.info( 'Checking policy for max attribute count %d', max_attribute_count) filter_options.remove(opt) break except ValueError: continue if filter_options: network = filter_options[0] else: logging.warning('GCE filter does not specify a network.') term_names = set() if IsDefaultDeny(terms[-1]): terms[-1].protocol = ['all'] terms[-1].priority = 65534 if direction == 'EGRESS': terms[-1].destination_address = [nacaddr.IP('0.0.0.0/0'), nacaddr.IP('::/0')] else: terms[-1].source_address = [ nacaddr.IP('0.0.0.0/0'), nacaddr.IP('::/0') ] for term in terms: if term.stateless_reply: logging.warning('WARNING: Term %s in policy %s is a stateless reply ' 'term and will not be rendered.', term.name, filter_name) continue term.network = network if not term.comment: term.comment = header.comment if direction == 'EGRESS': term.name += '-e' term.name = self.FixTermLength(term.name) if term.name in term_names: raise GceFirewallError('Duplicate term name') term_names.add(term.name) term.direction = direction if term.expiration: if term.expiration <= exp_info_date: logging.info('INFO: Term %s in policy %s expires ' 'in less than two weeks.', term.name, filter_name) if term.expiration <= current_date: logging.warning('WARNING: Term %s in policy %s is expired and ' 'will not be rendered.', term.name, filter_name) continue if term.option: raise GceFirewallError( 'GCE firewall does not support term options.') for rules in Term(term).ConvertToDict(): logging.debug('Attribute count of rule %s is: %d', term.name, GetAttributeCount(rules)) total_attribute_count += GetAttributeCount(rules) total_rule_count += 1 if max_attribute_count and total_attribute_count > max_attribute_count: # Stop processing rules as soon as the attribute count is over the # limit. raise ExceededAttributeCountError( 'Attribute count (%d) for %s exceeded the maximum (%d)' % ( total_attribute_count, filter_name, max_attribute_count)) self.gce_policies.append(rules) logging.info('Total rule count of policy %s is: %d', filter_name, total_rule_count) logging.info('Total attribute count of policy %s is: %d', filter_name, total_attribute_count)
'priority', 'protocol', 'source_address', 'source_address_exclude', 'source_port', 'source_tag', 'translated', } SUPPORTED_SUB_TOKENS = {'action': {'accept', 'deny'}} # Print a info message when a term is set to expire in that many weeks. # This is normally passed from command line. EXP_INFO = 2 TEST_IPS = [nacaddr.IP('10.2.3.4/32'), nacaddr.IP('2001:4860:8000::5/128')] TEST_INCLUDE_IPS = [nacaddr.IP('10.2.3.4/32'), nacaddr.IP('10.4.3.2/32')] TEST_EXCLUDE_IPS = [nacaddr.IP('10.4.3.2/32')] TEST_INCLUDE_RANGE = [nacaddr.IP('10.128.0.0/9')] TEST_EXCLUDE_RANGE = [nacaddr.IP('10.240.0.0/16')] class GCETest(unittest.TestCase): def setUp(self):
class HierarchicalFirewall(gcp.GCP): """A GCP Hierarchical Firewall policy.""" SUFFIX = '.gchf' _ANY = [nacaddr.IP('0.0.0.0/0')] _PLATFORM = 'gcp_hf' _SUPPORTED_AF = frozenset(['inet']) _DEFAULT_MAXIMUM_COST = 100 def _BuildTokens(self): """Build supported tokens for platform. Returns: Tuple containing both supported tokens and sub tokens. """ supported_tokens, _ = super(HierarchicalFirewall, self)._BuildTokens() supported_tokens |= {'destination_tag', 'expiration', 'source_tag', 'translated', 'target_resources', 'logging'} supported_tokens -= {'destination_address_exclude', 'expiration', 'icmp_type', 'platform', 'platform_exclude', 'source_address_exclude', 'verbatim'} supported_sub_tokens = {'action': {'accept', 'deny', 'next'}} return supported_tokens, supported_sub_tokens def _TranslatePolicy(self, pol, exp_info): """Translates a Capirca policy into a HF-specific data structure. Takes in a POL file, parses each term and populates the policy dict. Each term in this list is a dictionary formatted according to HF's rule API specification. Additionally, checks for its quota. Args: pol: A Policy() object representing a given POL file. exp_info: An int that specifies number of weeks until policy expiry. Raises: ExceededCostError: Raised when the cost of a policy exceeds the default maximum cost. HeaderError: Raised when the header cannot be parsed or a header option is invalid. """ self.policies = [] for header, terms in pol.filters: counter = 1 total_cost = 0 policy = { 'rules': [] } if self._PLATFORM not in header.platforms: continue filter_options = header.FilterOptions(self._PLATFORM) # Get the policy name. filter_name = header.FilterName(self._PLATFORM) filter_options.remove(filter_name) policy['display_name'] = filter_name # Get term direction if set. direction = 'INGRESS' for i in self._GOOD_DIRECTION: if i in filter_options: direction = i filter_options.remove(i) # Get the address family if set. address_family = 'inet' for i in self._SUPPORTED_AF: if i in filter_options: address_family = i filter_options.remove(i) # Find the default maximum cost of a policy, an integer, if specified. max_cost = self._DEFAULT_MAXIMUM_COST for opt in filter_options: try: max_cost = int(opt) filter_options.remove(opt) break except ValueError: continue if max_cost > 65536: raise gcp.HeaderError( 'Default maximum cost cannot be higher than 65536') # If there are remaining options, they are unknown/unsupported options. if filter_options: raise gcp.HeaderError( 'Unsupported or unknown filter options %s in policy %s ' % (str(filter_options), filter_name)) for term in terms: if term.stateless_reply: continue total_cost += GetCost(term) if total_cost > max_cost: raise ExceededCostError('Policy cost (%d) reached the maximum (%d)' % (total_cost, max_cost)) if gcp.IsDefaultDeny(term): if direction == 'EGRESS': term.destination_address = self._ANY else: term.source_address = self._ANY term.name = self.FixTermLength(term.name) term.direction = direction dict_term = Term(term, address_family=address_family).ConvertToDict( priority_index=counter) counter += 1 policy['rules'].append(dict_term) self.policies.append(policy)
def testStrForinet(self): """Test for Term._str_.""" self.naming.GetNetAddr.side_effect = [[ nacaddr.IP('10.0.0.1'), nacaddr.IP('10.0.0.2') ], [ nacaddr.IP('10.0.0.0/8'), nacaddr.IP('172.16.0.0/12'), nacaddr.IP('192.168.0.0/16') ]] self.naming.GetServiceByProto.return_value = ['123'] pol = policy.ParsePolicy(INET_FILTER, self.naming, False) af = 4 for _, terms in pol.filters: nsxv_term = nsxv.Term(terms[0], af) rule_str = nsxv.Term.__str__(nsxv_term) # parse xml rule and check if the values are correct root = ET.fromstring(rule_str) # check name and action self.assertEqual(root.find('name').text, 'allow-ntp-request') self.assertEqual(root.find('action').text, 'allow') # check source address exp_sourceaddr = ['10.0.0.1', '10.0.0.2'] source_address = root.findall('./sources/source') self.assertNotEqual(len(source_address), 0) for source in source_address: self.assertEqual((source.find('type').text), 'Ipv4Address') value = (source.find('value').text) if value not in exp_sourceaddr: self.fail( 'IPv4Address source address not found in test_str_forinet()' ) # check destination address exp_destaddr = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'] destination_address = root.findall('./destinations/destination') self.assertNotEqual(len(destination_address), 0) for destination in destination_address: self.assertEqual((destination.find('type').text), 'Ipv4Address') value = (destination.find('value').text) if value not in exp_destaddr: self.fail( 'IPv4Address destination not found in test_str_forinet()') # check protocol protocol = int(root.find('./services/service/protocol').text) self.assertEqual(protocol, 17) # check source port source_port = root.find('./services/service/sourcePort').text self.assertEqual(source_port, '123') # check destination port destination_port = root.find('./services/service/destinationPort').text self.assertEqual(destination_port, '123') # check notes notes = root.find('notes').text self.assertEqual(notes, 'Allow ntp request') self.naming.GetNetAddr.assert_has_calls( [mock.call('NTP_SERVERS'), mock.call('INTERNAL')]) self.naming.GetServiceByProto.assert_has_calls( [mock.call('NTP', 'udp')] * 2)
def testNsxvStr(self): """Test for Nsxv._str_.""" self.naming.GetNetAddr.side_effect = [[ nacaddr.IP('8.8.4.4'), nacaddr.IP('8.8.8.8'), nacaddr.IP('2001:4860:4860::8844'), nacaddr.IP('2001:4860:4860::8888') ]] self.naming.GetServiceByProto.return_value = ['53'] pol = policy.ParsePolicy(MIXED_FILTER, self.naming, False) target = nsxv.Nsxv(pol, EXP_INFO) # parse the output and seperate sections and comment section_tokens = str(target).split('<section') sections = [] for sec in section_tokens: section = sec.replace('name=', '<section name=') sections.append(section) # parse the xml # Checking comment tag comment = sections[0] if 'Id' not in comment: self.fail('Id missing in xml comment in test_nsxv_str()') if 'Date' not in comment: self.fail('Date missing in xml comment in test_nsxv_str()') if 'Revision' not in comment: self.fail('Revision missing in xml comment in test_nsxv_str()') root = ET.fromstring(sections[1]) # check section name section_name = {'name': 'MIXED_FILTER_NAME'} self.assertEqual(root.attrib, section_name) # check name and action self.assertEqual(root.find('./rule/name').text, 'accept-to-honestdns') self.assertEqual(root.find('./rule/action').text, 'allow') # check IPV4 and IPV6 destinations exp_ipv4dest = ['8.8.4.4', '8.8.8.8'] exp_ipv6dest = ['2001:4860:4860::8844', '2001:4860:4860::8888'] destination_address = root.findall('./rule/destinations/destination') self.assertNotEqual(len(destination_address), 0) for destination in destination_address: addr_type = destination.find('type').text value = (destination.find('value').text) if 'Ipv4Address' in addr_type: if value not in exp_ipv4dest: self.fail('IPv4Address not found in test_nsxv_str()') else: if value not in exp_ipv6dest: self.fail('IPv6Address not found in test_nsxv_str()') # check protocol protocol = int(root.find('./rule/services/service/protocol').text) self.assertEqual(protocol, 17) # check destination port destination_port = root.find( './rule/services/service/destinationPort').text self.assertEqual(destination_port, '53') # check notes notes = root.find('./rule/notes').text self.assertEqual(notes, 'Allow name resolution using honestdns.') self.naming.GetNetAddr.assert_called_once_with('GOOGLE_DNS') self.naming.GetServiceByProto.assert_called_once_with('DNS', 'udp')