diff --git a/capirca/aclgen.py b/capirca/aclgen.py index c2a0610a..3a4b2f41 100644 --- a/capirca/aclgen.py +++ b/capirca/aclgen.py @@ -40,6 +40,7 @@ from capirca.lib import cloudarmor from capirca.lib import gce from capirca.lib import gcp_hf +from capirca.lib import fortigate from capirca.lib import ipset from capirca.lib import iptables from capirca.lib import juniper @@ -199,6 +200,7 @@ def RenderFile(base_directory, input_file, output_directory, definitions, win_afw = False xacl = False paloalto = False + fcl = False try: with open(input_file) as f: @@ -268,6 +270,8 @@ def RenderFile(base_directory, input_file, output_directory, definitions, paloalto = copy.deepcopy(pol) if 'cloudarmor' in platforms: gca = copy.deepcopy(pol) + if 'fortigate' in platforms: + fcl = copy.deepcopy(pol) if not output_directory.endswith('/'): output_directory += '/' @@ -366,11 +370,17 @@ def RenderFile(base_directory, input_file, output_directory, definitions, acl_obj = cloudarmor.CloudArmor(gca, exp_info) RenderACL(str(acl_obj), acl_obj.SUFFIX, output_directory, input_file, write_files) + + if fcl: + acl_obj = fortigate.Fortigate(fcl, exp_info) + RenderACL(str(acl_obj), acl_obj.SUFFIX, output_directory, + input_file, write_files) + # TODO(robankeny) add additional errors. except (juniper.Error, junipermsmpc.Error, junipersrx.Error, cisco.Error, ipset.Error, iptables.Error, speedway.Error, pcap.Error, aclgenerator.Error, aruba.Error, nftables.Error, gce.Error, - cloudarmor.Error) as e: + cloudarmor.Error, fortigate.Error) as e: raise ACLGeneratorError( 'Error generating target ACL for %s:\n%s' % (input_file, e)) diff --git a/capirca/lib/cloudarmor.py b/capirca/lib/cloudarmor.py index 8d9213b1..0b744849 100644 --- a/capirca/lib/cloudarmor.py +++ b/capirca/lib/cloudarmor.py @@ -105,39 +105,43 @@ def ConvertToDict(self, priority_index): 'srcIpRanges': saddrs, } } - # If scrIpRanges within a single term exceed _MAX_IP_RANGES_PER_TERM, # split into multiple terms source_addr_chunks = [ saddrs[x:x+self._MAX_IP_RANGES_PER_TERM] for x in range( 0, len(saddrs), self._MAX_IP_RANGES_PER_TERM)] - split_rule_count = len(source_addr_chunks) - - for i, chunk in enumerate(source_addr_chunks): + if not source_addr_chunks: rule = copy.deepcopy(term_dict) - if split_rule_count > 1: - term_position_suffix = ' [%d/%d]' % (i+1, split_rule_count) - desc_limit = self._MAX_TERM_COMMENT_LENGTH - len(term_position_suffix) - rule['description'] = (rule.get('description', '')[:desc_limit] - + term_position_suffix) - - rule['priority'] = priority_index + i - rule['match'] = { - 'versionedExpr': 'SRC_IPS_V1', - 'config': { - 'srcIpRanges': [str(saddr) for saddr in chunk], - } - } + rule['priority'] = priority_index + rule['match']['config']['srcIpRanges'] = ['*'] rules.append(rule) + else: + split_rule_count = len(source_addr_chunks) + for i, chunk in enumerate(source_addr_chunks): + rule = copy.deepcopy(term_dict) + if split_rule_count > 1: + term_position_suffix = ' [%d/%d]' % (i+1, split_rule_count) + desc_limit = self._MAX_TERM_COMMENT_LENGTH - len(term_position_suffix) + rule['description'] = (rule.get('description', '')[:desc_limit] + + term_position_suffix) + + rule['priority'] = priority_index + i + rule['match'] = { + 'versionedExpr': 'SRC_IPS_V1', + 'config': { + 'srcIpRanges': [str(saddr) for saddr in chunk], + } + } + rules.append(rule) + # TODO(robankeny@): Review this log entry to make it cleaner/more useful. # Right now, it prints the entire term which might be huge if len(source_addr_chunks) > 1: logging.debug('Current term [%s] was split into %d sub-terms since ' '_MAX_IP_RANGES_PER_TERM was exceeded', str(term_dict), len(source_addr_chunks)) - return rules diff --git a/capirca/lib/fortigate.py b/capirca/lib/fortigate.py new file mode 100644 index 00000000..61a07c16 --- /dev/null +++ b/capirca/lib/fortigate.py @@ -0,0 +1,971 @@ +# Copyright 2019 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Version 1.1.14 + +"""Fortigate generator.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals + +import datetime +from absl import logging +import six + +from capirca.lib import aclgenerator +from capirca.lib import nacaddr + +_ACTION_TABLE = { + 'accept': 'accept', + 'deny': 'deny', + 'next': 'next', + 'reject': 'reject', + 'reject-with-tcp-rst': 'reject', # set deny-tcp-with-icmp enable +} +_SP = ' ' +_DEFAULT_COMMENT = 'Generated by Capirca' +_SUPPORT_VERBATIM_TERM = False +_COMMENT_MAX_LENGTH = 1024 + + +class Error(Exception): + """Generic error class.""" + + +class FilterError(Error): + """Generic pol Filter class.""" + + +class FortiGateValueError(Error): + """Raised when invalid values provided.""" + + +class FortiGateFindServiceError(Error): + """Raised when unable to get the service name.""" + + +class FortiGateDuplicateTermError(Error): + """Raised when duplicate term found.""" + + +class FortiGatePortDoesNotExistError(Error): + """Raised when port is not found in ports list.""" + + +class FortiGateScheduleDateError(Error): + """Raised expiration date is invalid.""" + + +class FortigatePortMap(object): + """Map port numbers to service names.""" + _PORTS_TCP = { + '179': 'BGP', + '53': 'DNS', + '7': 'PING', + '79': 'FINGER', + '21': 'FTP', + '70': 'GOPHER', + '443': 'HTTPS', + '194': 'IRC', + '2049': 'NFS', + '119': 'NNTP', + '110': 'POP3', + '1723': 'PPTP', + '25': 'SMTP', + '22': 'SSH', + '517': 'TALK', + '23': 'TELNET', + '540': 'UUCP', + '80': 'HTTP', + '993': 'IMAPS', + '3389': 'RDP', + '3306': 'MYSQL', + '1433': 'MS-SQL', + '1812': 'RADIUS', + '995': 'POP3S', + '465': 'SMTPS', + '389': 'LDAP', + '69': 'TFTP', + 'all': 'ALL_TCP' + } + _PORTS_UDP = { + '53': 'DNS', + '7': 'PING', + '500': 'IKE', + '2049': 'NFS', + '123': 'NTP', + '520': 'RIP', + '161': 'SNMP', + '162': 'snmptrap', + '514': 'SYSLOG', + '517': 'TALK', + '69': 'TFTP', + '37': 'TIMESTAMP', + '1812': 'RADIUS', + '67': 'DHCP', + 'all': 'ALL_UDP' + } + _PORTS_SCTP = { + #'53': 'DNS', + #'7': 'PING', + 'all': 'ALL_SCTP' + } + _PROTO_MAP = { + 'icmp': 'ALL_ICMP', + 'icmpv6': 'ALL_ICMP6', + #'gre': 'GRE', + #'ip': 'ALL', + 'tcp': _PORTS_TCP, + 'udp': _PORTS_UDP, + 'sctp': _PORTS_SCTP + } + + @staticmethod + def get_protocol(protocol, port=None): + """Converts a port number to a service name. + + Args: + protocol: string representing protocol (tcp, udp, etc) + port: integer representing the port number + + Returns: + string + + Raises: + FortiGateValueError: When unsupported protocol is used. + FortiGatePortDoesNotExistError: if the port does not exist. + FortiGateFindServiceError: when unable to find the requested service. + """ + f_proto = FortigatePortMap._PROTO_MAP.get(protocol, None) + if f_proto is None: + raise FortiGateValueError( + '%r protocol is unsupported, supported protocols = %r' % ( + protocol, FortigatePortMap._PROTO_MAP.keys())) + + if isinstance(f_proto, six.string_types): + return f_proto + elif port: + try: + return f_proto[port] + except KeyError: + raise FortiGatePortDoesNotExistError + else: + raise FortiGateFindServiceError( + 'service not found from %r protocol and %r port' % + (protocol, port)) + + +class ObjectsContainer(object): + """A Container that holds service and network objects.""" + + def __init__(self): + self.verbose = True + self._sys_settings = set() + self._dict_addresses = set() + self._dict_addrgrps = {} + self._dict_services = {} + self._dict_svcgrps = {} + self._dict_schedules = {} + + def get_sys_settings(self): + """Returns the collected addresses. + + """ + settings = [] + for setting in self._sys_settings: + settings += [_SP + setting] + + return settings + + def get_fw_addresses(self, ip_v=4): + """ + Returns the collected firewall addresses. + + Args: + ip_v: an integer. version 4 or 6. + + Returns: a list. contains address objects. + + """ + addresses = [] + addresses_v = [] + for addr in self._dict_addresses: + if ip_v == 4 and not isinstance(addr, nacaddr.IPv6): + addresses_v += [addr] + if ip_v == 6 and isinstance(addr, nacaddr.IPv6): + addresses_v += [addr] + + for addr in sorted(addresses_v): + addresses.extend(self.get_fw_address_obj(addr, self.verbose)) + + return addresses + + def get_fw_address_obj(self, addr, verbose=True): + """Gets firewall address objects. + + """ + addr_name = addr.with_prefixlen + address = [] + address += [_SP + 'edit "%s"' % addr_name] + if verbose: + addr_comment = _DEFAULT_COMMENT + if len(addr.text): + addr_comment += " (" + addr.text + ")" + address += [_SP * 2 + 'set comment "%s"' % self.FixCommentLength(addr_comment)] + if not isinstance(addr, nacaddr.IPv6): + address += [_SP * 2 + 'set subnet %s' % addr_name] + if isinstance(addr, nacaddr.IPv6): + address += [_SP * 2 + 'set ip6 %s' % addr_name] + address += [_SP + 'next'] + + return address + + def get_fw_addrgrps(self, ip_v=4): + """Returns the collected address groups.""" + addrgrps = [] + for addrgrp_name, addrgrp_item in self._dict_addrgrps.items(): + if addrgrp_item[0] == ip_v: + address = addrgrp_item[1] + exclude_address = addrgrp_item[2] + addrgrps += [_SP + 'edit "%s"' % addrgrp_name] + if self.verbose: + addrgrps += [_SP * 2 + 'set comment "%s"' % _DEFAULT_COMMENT] + if address: + addrgrps += [_SP * 2 + 'set member %s' % + ' '.join(('"' + v + '"') for v in address)] + else: + addrgrps += [_SP * 2 + 'set member "all"'] + if exclude_address: + addrgrps += [_SP * 2 + 'set exclude enable'] + addrgrps += [_SP * 2 + 'set exclude-member %s' % + ' '.join(('"' + v + '"') for v in exclude_address)] + addrgrps += [_SP + 'next'] + + return addrgrps + + def get_port_range(self, port): + port_range = '' + if len(port) == 1: + port_range = str(port[0]) + elif len(port) > 1: + port_range = str(port[0]) + if port[0] != port[1]: + port_range = str(min(port[0], port[1])) + '-' + \ + str(max(port[0], port[1])) + + return port_range + + def get_fw_services(self): + """Returns the collected services.""" + fw_services = [] + for service_name in sorted(self._dict_services.keys()): + fw_services += [_SP + 'edit ' + service_name] + if self.verbose: + fw_services += [_SP * 2 + 'set comment "%s"' % _DEFAULT_COMMENT] + for service_item in self._dict_services[service_name]: + fw_services += [_SP * 2 + service_item] + fw_services += [_SP + 'next'] + + return fw_services + + def get_fw_svcgrps(self): + """Returns the collected service groups.""" + svcgrps = [] + for svcgrp, value in self._dict_svcgrps.items(): + svcgrps += [_SP + 'edit %s' % svcgrp] + if self.verbose: + svcgrps += [_SP * 2 + 'set comment "%s"' % _DEFAULT_COMMENT] + svcgrps += [_SP * 2 + value] + svcgrps += [_SP + 'next'] + + return svcgrps + + def get_fw_schedules(self): + """Returns the collected schedules.""" + schedules = [] + for schedule_name, schedule_date in self._dict_schedules.items(): + schedules.extend([_SP + 'edit %s' % schedule_name, + _SP * 2 + 'set end %s' % schedule_date, + _SP + 'next']) + return schedules + + def process_action_setting(self, action): + """Process reject action.""" + found_action = _ACTION_TABLE.get(action) + if found_action == 'reject': + self._sys_settings.add('set deny-tcp-with-icmp enable') + + return action + + def add_address_to_fw_addrgrps( + self, + addrgrp_name, + address, + address_exclude): + """Add address and exclude to address group store.""" + address_v4 = [x.with_prefixlen for x in address if + not isinstance(x, nacaddr.IPv6)] + address_v6 = [x.with_prefixlen for x in address if + isinstance(x, nacaddr.IPv6)] + address_exclude_v4 = [x.with_prefixlen for x in address_exclude if + not isinstance(x, nacaddr.IPv6)] + address_exclude_v6 = [x.with_prefixlen for x in address_exclude if + isinstance(x, nacaddr.IPv6)] + + if address_exclude_v6: + raise FortiGateValueError( + 'Exclude IPv6 address is unsupported: %r' % + ' '.join([x.with_prefixlen for x in address_exclude_v6])) + + addr_names = [] + if address_v4 or address_exclude_v4: + addr_name = self.generate_address_or_addrgrp( + addrgrp_name, address_v4, address_exclude_v4, 4) + addr_names += [(4, addr_name)] + + if address_v6: + addr_name6 = self.generate_address_or_addrgrp( + addrgrp_name + '6', address_v6, None, 6) + addr_names += [(6, addr_name6)] + + return addr_names or 'all' + + def generate_address_or_addrgrp( + self, + addrgrp_name, + address, + address_exclude, + ip_v): + """ + Generates an address or address group. + + Args: + addrgrp_name: a string. name of address group + address: a string. ipv4 or ipv6 address + address_exclude: a string. ipv4 or ipv6 address + ip_v: an integer. 4 or 6 for ipVersion + + Returns: string + + """ + if not address and not address_exclude: + return 'all' + + if not address_exclude: + if len(address) == 1: + return address[0] + + if addrgrp_name not in self._dict_addrgrps: + self._dict_addrgrps[addrgrp_name] = [ + ip_v, address, address_exclude] + + return addrgrp_name + + def get_defined_service(self, protocol, port): + """return service if find service in defined map.""" + try: + service = FortigatePortMap.get_protocol(protocol, port) + return service + except FortiGatePortDoesNotExistError: + pass + + return None + + def add_service_to_fw_services(self, term_name, protocol_ports): + """Add service to services store.""" + protocols = set() + portranges = set() + for protocol, portrange in protocol_ports.items(): + protocols.add(protocol) + for range1 in portrange: + portranges.add(str(range1)) + + service_name = term_name + "-svc" + if service_name not in self._dict_services: + protocol_set = set() + for protocol, port_ranges in protocol_ports.items(): + portrange_str = ' '.join(str(v) for v in sorted(port_ranges)) + protocol_set.add( + 'set %s-portrange %s' % + (protocol.lower(), portrange_str)) + + self._dict_services[service_name] = sorted(protocol_set) + + return service_name + + def add_icmp_to_fw_services( + self, + protocol, + icmp_type, + normalized_icmptype, + icmp_code): + """ + Processes ICMP Additions to Firewall Services. + + """ + # icmp-types + if not normalized_icmptype and not icmp_code: + return 'ALL_ICMP6' if protocol == 'icmpv6' else 'ALL_ICMP' + + icmp_service_name = protocol + '-type-' + icmp_type + \ + (('-' + str(icmp_code)) if icmp_code else '') + if icmp_service_name not in self._dict_services: + protocol_set = [] + protocol_set += ['set protocol %s' % + ('ICMP6' if protocol == 'icmpv6' else 'ICMP')] + if normalized_icmptype: + protocol_set += ['set icmptype %s' % normalized_icmptype] + if icmp_code: + protocol_set += ['set icmpcode %s' % str(icmp_code)] + + self._dict_services[icmp_service_name] = protocol_set + + return icmp_service_name + + def add_icmp_service_grp(self, term_name, icmp_service_grp): + icmp_service_grp_name = term_name + "-svcgrp" + if icmp_service_grp_name not in self._dict_svcgrps: + icmp_members = 'set member ' + (' ').join(sorted(icmp_service_grp)) + for key, value in self._dict_svcgrps.items(): + if icmp_members == value: + return key + self._dict_svcgrps[icmp_service_grp_name] = icmp_members + + return icmp_service_grp_name + + def add_expiration_to_fw_schedules(self, expiration): + """Add expiry date to schedule store.""" + schedule_name = expiration[-10:] + '_' + expiration[:5] + if schedule_name not in self._dict_schedules: + self._dict_schedules[schedule_name] = expiration + return schedule_name + + def FixCommentLength(self, comment): + """Return a comment which is equal or shorter than _COMMENT_MAX_LENGTH. + _COMMENT_MAX_LENGTH truncated as necessary. + """ + return comment[:_COMMENT_MAX_LENGTH] + + +class Term(aclgenerator.Term): + """Single Firewall Policy.""" + + _PLATFORM = 'fortigate' + _NGFW_MODE = 'profile-based' + CURRENT_ID = 0 + + def __init__(self, term, object_container, verbose=True): + super(Term, self).__init__(term) + self._term = term + self._obj_container = object_container + self._term.verbose = verbose + + self.id_ = type(self).CURRENT_ID + if type(self).CURRENT_ID > 0: + type(self).CURRENT_ID += 1 + + def _get_services_name(self, protocols, destination_ports, source_ports): + """Get the service name, if not exist create it. + + Args: + protocols: list of protocols + destination_ports: list of destination ports + source_ports: list of source ports + + Returns: + string (all services separated by spaces). + """ + #if not protocols: + # raise FortiGateFindServiceError('protocol not found') + + ports = set() + # fortigate does not allow empty destination_ports + if not len(destination_ports) and len(source_ports): + # source ports only, to set destination ports = 1-65535 + destination_ports.append((1, 65535)) + + if len(destination_ports): + for destination_port in destination_ports: + dest_port_range = self._obj_container.get_port_range(destination_port) + if source_ports: + for source_port in source_ports: + src_port_range = self._obj_container.get_port_range(source_port) + ports.add(dest_port_range + ':' + src_port_range) + else: + ports.add(dest_port_range) + + if not len(ports): + ports.add('all') + + ports = sorted(ports) + + services = set() + portranges = {} + for protocol in protocols: + if FortigatePortMap._PROTO_MAP.get(protocol, None) is None: + raise FortiGateValueError( + 'fortigate does not support %r protocol' % protocol) + + if protocol == 'icmp' or protocol == 'icmpv6': + ip_v = 4 if protocol == 'icmp' else 6 + icmp_type_dict = {} + for icmp_type in self._term.icmp_type: + normalized_icmptype = self.NormalizeIcmpTypes( + [icmp_type], protocols, ip_v) + if normalized_icmptype: + icmp_type_dict[icmp_type] = normalized_icmptype[0] + + icmp_service_grp = set() + icmp_service_name = '' + for icmp_type in sorted( + icmp_type_dict, key=icmp_type_dict.get): + if self._term.icmp_code: + for each_code in sorted(self._term.icmp_code): + icmp_service_name = self._obj_container.add_icmp_to_fw_services( + protocol, icmp_type, icmp_type_dict[icmp_type], each_code) + icmp_service_grp.add(icmp_service_name) + else: + icmp_service_name = self._obj_container.add_icmp_to_fw_services( + protocol, + icmp_type, + icmp_type_dict[icmp_type], + self._term.icmp_code) + icmp_service_grp.add(icmp_service_name) + + if len(icmp_service_grp) > 1: + service = self._obj_container.add_icmp_service_grp( + self._term.name, icmp_service_grp) + else: + service = icmp_service_name + services.add(service) + else: + for port in ports: + service = self._obj_container.get_defined_service(protocol, port) + if service: + if service == 'ALL_SCTP': + if protocol not in portranges: + portranges[protocol] = set() + portranges[protocol].add('1-65535') + else: + services.add(service) + else: + if protocol not in portranges: + portranges[protocol] = set() + portranges[protocol].add(port) + + if portranges: + service = self._obj_container.add_service_to_fw_services( + self._term.name, portranges) + services.add(service) + + return ' '.join(sorted(services)) or 'ALL' + + def _generate_address_names(self, *addresses): + """Generate the addresses names (object-network names).""" + for group in addresses: + for addr in group: + if addr: + self._obj_container._dict_addresses.add(addr) + + def _process_verbatim_term(self): + """Process verbatim term output""" + # If Term includes verbatim token only + # Warning and skip this term + if not _SUPPORT_VERBATIM_TERM: + logging.warning( + 'WARNING: Term %s is a verbatim term. ' + 'term will not be rendered.', + self.term.name) + return '' + # output verbatim term and warning + else: + output = [] + for verbatim_line in self.term.verbatim: + platform, contents = verbatim_line + if platform == self._PLATFORM: + output += [str(contents)] + logging.warning( + 'WARNING: Term %s is a verbatim term. ' + 'to ensure the term output is' + 'valid FortiGate items.', self.term.name) + return (_SP * 2 + ('\n' + _SP * 2).join(output)) if output else '' + + def _process_verbatim_item(self): + """Process verbatim output""" + # Term verbatim output + output = [] + if self.term.verbatim: + for verbatim_line in self.term.verbatim: + platform, contents = verbatim_line + if platform == self._PLATFORM: + output += [_SP * 2 + str(contents)] + + return output + + def _convert_date(self, expiration): + """Covert date format yyyy-mm-dd hh:mi to hh:mi yyyy/mm/dd.""" + try: + schedule_date = expiration.strftime('%H:%M %Y/%m/%d') + return schedule_date + except ValueError as e: + raise FortiGateScheduleDateError( + 'Expiration is invalid datetime format.') + + def __str__(self): + lines = [] + + # process verbatim term + if self.term.verbatim and ( + not self.term.protocol or not self.term.action): + return self._process_verbatim_term() + + # Not support next action, skip this term + action = self._obj_container.process_action_setting( + self._term.action[0]) + if action == 'next': + """ unknow next action, skip this term """ + return '' + + self._generate_address_names( + self._term.destination_address, + self._term.source_address, + self._term.destination_address_exclude, + self._term.source_address_exclude) + + dest_addresses = self._obj_container.add_address_to_fw_addrgrps( + self._term.name + '-dstgrp', + self._term.destination_address, + self._term.destination_address_exclude) + src_addresses = self._obj_container.add_address_to_fw_addrgrps( + self._term.name + '-srcgrp', + self._term.source_address, + self._term.source_address_exclude) + + services = self._get_services_name( + sorted( + self._term.protocol), + self._term.destination_port, + self._term.source_port) + + schedule_name = None + if self._term.expiration: + schedule_date = self._convert_date(self._term.expiration) + schedule_name = self._obj_container.add_expiration_to_fw_schedules( + schedule_date) + + lines += [_SP * 2 + 'set name "%s"' % self._term.name] + # Owner (implement as comment) + if not self._term.comment: + self._term.comment = [_DEFAULT_COMMENT] + if self._term.owner: + self._term.comment += ['Owner: %s' % self._term.owner] + if self._term.comment and self._term.verbose: + lines += [_SP * 2 + 'set comments "%s"' % + self._obj_container.FixCommentLength((' ').join(self._term.comment))] + lines += [_SP * 2 + 'set srcintf %s' % + (self._term.source_interface or 'any')] + lines += [_SP * 2 + 'set dstintf %s' % + (self._term.destination_interface or 'any')] + exist_src6 = False + exist_dst6 = False + if isinstance(dest_addresses, list): + for (ip_v, addr_name) in dest_addresses: + lines += [_SP * 2 + 'set %s "%s"' % + (('dstaddr' if ip_v == 4 else 'dstaddr6'), + addr_name)] + if ip_v == 6: + exist_dst6 = True + else: + lines += [_SP * 2 + 'set dstaddr "%s"' % dest_addresses] + if isinstance(src_addresses, list): + for (ip_v, addr_name) in src_addresses: + lines += [_SP * 2 + 'set %s "%s"' % + (('srcaddr' if ip_v == 4 else 'srcaddr6'), + addr_name)] + if ip_v == 6: + exist_src6 = True + else: + lines += [_SP * 2 + 'set srcaddr "%s"' % src_addresses] + if exist_src6 and not exist_dst6: + lines += [_SP * 2 + 'set dstaddr6 "all"'] + elif not exist_src6 and exist_dst6: + lines += [_SP * 2 + 'set srcaddr6 "all"'] + + # if self._term.destination_address_exclude + # and not self._term.destination_address: + # lines += [_SP*2 + 'set dstaddr-negate enable'] + # if self._term.source_address_exclude + # and not self._term.source_address: + # lines += [_SP*2 + 'set srcaddr-negate enable'] + + # process verbatim items + # if self._term.verbatim: + # lines.extend(self._process_verbatim_item()) + + lines += [_SP * 2 + 'set action %s' % + (action if action == 'accept' else 'deny')] + if action == 'reject': + lines += [_SP * 2 + 'set send-deny-packet enable'] + + if services: + if self._NGFW_MODE == 'policy-based': + lines += [_SP * 2 + 'set enforce-default-app-port disable'] + lines += [_SP * 2 + 'set service %s' % services] + else: + if self._NGFW_MODE == 'policy-based': + lines += [_SP * 2 + 'set enforce-default-app-port enable'] + + """ + if self._NGFW_MODE == 'profile-based': + if self._term.av_profile or self._term.webfilter_profile or + self._term.ssl_ssh_profile or self._term.dnsfilter_profile or + self._term.ips_sensor: + lines += [_SP*2 + 'set utm-status enable'] + """ + if self._NGFW_MODE == 'policy-based' and self._term.application_id: + lines += [_SP * 2 + + 'set application %s' % + ' '.join(str(v) + for v in sorted(self._term.application_id))] + + lines += [_SP * 2 + 'set schedule %s' % (schedule_name or 'always')] + + # opts = [str(x) for x in self._term.option] + # if ('tcp-established' in opts or 'established' in opts): + # lines += [_SP*2 + 'set something'] + + if self._term.logging: + if self._term.logging == 'log-both': + lines += [_SP * 2 + 'set logtraffic all'] + lines += [_SP * 2 + 'set logtraffic-start enable'] + elif self._term.logging == 'disable': + lines += [_SP * 2 + 'set logtraffic disable'] + else: + lines += [_SP * 2 + 'set logtraffic all'] + + return '\n'.join(lines) + + +class Fortigate(aclgenerator.ACLGenerator): + """A Fortigate policy object.""" + + _PLATFORM = 'fortigate' + _NGFW_MODE = 'profile-based' + _DEFAULT_PROTOCOL = 'ALL' + SUFFIX = '.fcl' + + def __init__(self, *args, **kwargs): + self._obj_container = ObjectsContainer() + super(Fortigate, self).__init__(*args, **kwargs) + + def _BuildTokens(self): + """Build supported tokens for platform. + + Returns: + tuple containing both supported tokens and sub tokens. + """ + supported_tokens, supported_sub_tokens = super( + Fortigate, self)._BuildTokens() + supported_tokens |= {'source_interface', + 'destination_interface', + 'source_address_exclude', + 'destination_address_exclude', + 'icmp_type', + 'icmp_code', + 'application_id'} + + supported_sub_tokens.update({'option': {'tcp-established'}, + # Warning, some of these are mapped + # differently. See _ACTION_TABLE + 'action': {'accept', 'deny', + 'next', 'reject', + 'reject-with-tcp-rst'}}) + + return supported_tokens, supported_sub_tokens + + def _TranslatePolicy(self, pol, exp_info): + """Translate Capirca pol to fortigate pol.""" + self.fortigate_policies = [] + current_date = datetime.datetime.utcnow().date() + exp_info_date = current_date + datetime.timedelta(weeks=exp_info) + + term_dup_check = set() + + for header, terms in pol.filters: + if self._PLATFORM not in header.platforms: + continue + + # fortigate option format: + # target:: fortigate from-id n + # target:: fortigate from-id n ngfw-mode profile-based | + # policy-based + filter_options = header.FilterOptions(self._PLATFORM) + + verbose = True + if 'noverbose' in filter_options: + filter_options.remove('noverbose') + verbose = False + + self._obj_container.verbose = verbose + + my_filter = {} + if len(filter_options) == 1: + my_filter[filter_options[0]] = '' + if len(filter_options) > 1: + my_filter[filter_options[0]] = filter_options[1] + if len(filter_options) > 3: + if filter_options[2] in my_filter.keys(): + raise FilterError( + 'Fortigate filter arguments are duplicated: ' + + filter_options[2]) + else: + my_filter[filter_options[2]] = filter_options[3] + + # default from-id is 0 + Term.CURRENT_ID = 0 + # default ngfw_mode = profile-based + self._NGFW_MODE = 'profile-based' + for filter_key, filter_val in my_filter.items(): + if filter_key == 'from-id': + from_id = int(filter_val) + if from_id < 1: + raise FilterError( + 'FortiGate from-id must be more than zero') + Term.CURRENT_ID = int(from_id) + elif filter_key == 'ngfw-mode': + if filter_val != 'profile-based' and \ + filter_val != 'policy-based': + raise FilterError( + 'FortiGate ngfw-mode only supports ' + 'profile-based or policy-based') + self._NGFW_MODE = filter_val + else: + raise FilterError( + 'FortiGate only support from-id and ngfw-mode filter') + + Term._NGFW_MODE = self._NGFW_MODE + + for term in terms: + term.name = self.FixTermLength(term.name) + + filter_name = header.FilterName(self._PLATFORM) + if term.stateless_reply: + logging.warning( + 'WARNING: Term %s in policy %s is a stateless reply ' + 'term and will not be rendered. FortiGates are stateful', + term.name, + filter_name) + continue + 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.name in term_dup_check: + raise FortiGateDuplicateTermError( + 'You have a duplicate term: %s' % term.name) + term_dup_check.add(term.name) + + new_term = Term(term, self._obj_container, verbose) + + self.fortigate_policies += [(header, term.name, new_term)] + + def _get_fw_policies(self): + target_policies = [] + for (_, _, term) in self.fortigate_policies: + term_str = str(term) + if term_str != '': + target_policies += [_SP + 'edit %s' % term.id_] + target_policies += [term_str] + target_policies += [_SP + 'next'] + + return target_policies + + def __str__(self): + fw_policies = self._get_fw_policies() + + start_sys_settings = ['config sys setting'] + start_addresses_v4 = ['config firewall address'] + start_addresses_v6 = ['config firewall address6'] + start_addrgrps_v4 = ['config firewall addrgrp'] + start_addrgrps_v6 = ['config firewall addrgrp6'] + start_services = ['config firewall service custom'] + start_svcgrps = ['config firewall service group'] + start_schedules = ['config firewall schedule onetime'] + start_policies = [] + if self._NGFW_MODE == 'profile-based': + start_policies = ['config firewall policy'] + else: + start_policies = ['config firewall security-policy'] + end = ['end'] + + sys_settings = [] + if self._obj_container.get_sys_settings(): + sys_settings = start_sys_settings + \ + self._obj_container.get_sys_settings() + \ + end + [''] + + fw_addresses = [] + if self._obj_container.get_fw_addresses(4): + fw_addresses += start_addresses_v4 + \ + self._obj_container.get_fw_addresses(4) + \ + end + [''] + if self._obj_container.get_fw_addresses(6): + fw_addresses += start_addresses_v6 + \ + self._obj_container.get_fw_addresses(6) + \ + end + [''] + + fw_addr_grps = [] + if self._obj_container.get_fw_addrgrps(4): + fw_addr_grps += start_addrgrps_v4 + \ + self._obj_container.get_fw_addrgrps(4) + \ + end + [''] + if self._obj_container.get_fw_addrgrps(6): + fw_addr_grps += start_addrgrps_v6 + \ + self._obj_container.get_fw_addrgrps(6) + \ + end + [''] + + fw_services = [] + if self._obj_container.get_fw_services(): + fw_services = start_services + \ + self._obj_container.get_fw_services() + \ + end + [''] + + fw_svc_grps = [] + if self._obj_container.get_fw_svcgrps(): + fw_svc_grps = start_svcgrps + \ + self._obj_container.get_fw_svcgrps() + \ + end + [''] + + fw_schedules = [] + if self._obj_container.get_fw_schedules(): + fw_schedules = start_schedules + \ + self._obj_container.get_fw_schedules() + \ + end + [''] + + fw_policies = start_policies + fw_policies + end + + target = sys_settings + fw_addresses + fw_addr_grps + \ + fw_services + fw_svc_grps + fw_schedules + fw_policies + + return '\n'.join(target) diff --git a/capirca/lib/gce.py b/capirca/lib/gce.py index b37cee76..27b0f7c8 100644 --- a/capirca/lib/gce.py +++ b/capirca/lib/gce.py @@ -32,6 +32,8 @@ import logging import re +from typing import Dict, Text, Any + from capirca.lib import aclgenerator from capirca.lib import nacaddr import six @@ -46,6 +48,10 @@ class GceFirewallError(Error): """Raised with problems in formatting for GCE firewall.""" +class ExceededAttributeCountError(Error): + """Raised when the total attribute count of a policy is above the maximum.""" + + def IsDefaultDeny(term): """Returns true if a term is a default deny without IPs, ports, etc.""" skip_attrs = ['flattened', 'flattened_addr', 'flattened_saddr', @@ -303,6 +309,9 @@ def _BuildTokens(self): 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) @@ -322,6 +331,16 @@ def _TranslatePolicy(self, pol, exp_info): 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: @@ -369,7 +388,22 @@ def _TranslatePolicy(self, pol, exp_info): raise GceFirewallError( 'GCE firewall does not support term options.') + for tmp_term in Term(term).ConvertToDict(): + logging.debug('Attribute count of rule %s is: %d', term.name, + GetAttributeCount(tmp_term)) + total_attribute_count += GetAttributeCount(tmp_term) + 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(Term(term)) + 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) def __str__(self): target = [] @@ -383,3 +417,40 @@ def __str__(self): sort_keys=True)) return out + + +def GetAttributeCount(dict_term: Dict[Text, Any]) -> int: + """Calculate the attribute count of a term in its dictionary form. + + The attribute count of a rule is the sum of the number of ports, protocols, IP + ranges, tags and target service account. + + Note: The goal of this function is not to determine if a term is valid, but + to calculate its attribute count regardless of correctness. + + Args: + dict_term: A dict object. + + Returns: + int: The attribute count of the term. + """ + addresses = (len(dict_term.get('destinationRanges', [])) + or len(dict_term.get('sourceRanges', []))) + + proto_ports = 0 + for allowed in dict_term.get('allowed', []): + proto_ports += len(allowed.get('ports', [])) + 1 # 1 for ipProtocol + for denied in dict_term.get('denied', []): + proto_ports += len(denied.get('ports', [])) + 1 # 1 for ipProtocol + + tags = 0 + for _ in dict_term.get('sourceTags', []): + tags += 1 + for _ in dict_term.get('targetTags', []): + tags += 1 + + service_accounts = 0 + for _ in dict_term.get('targetServiceAccount', []): + service_accounts += 1 + + return addresses + proto_ports + tags + service_accounts diff --git a/capirca/lib/policy.py b/capirca/lib/policy.py index ba2132c6..4f21b466 100644 --- a/capirca/lib/policy.py +++ b/capirca/lib/policy.py @@ -337,6 +337,7 @@ class Term(object): policer: VarType.POLICER priority: VarType.PRIORITY vpn: VarType.VPN + application-id: VarType.APPLICATION_ID """ ICMP_TYPE = {4: {'echo-reply': 0, 'unreachable': 3, @@ -476,6 +477,8 @@ def __init__(self, obj): self.flattened_saddr = None self.flattened_daddr = None self.stateless_reply = False + # fortigate specific + self.application_id = [] # AddObject touches variables which might not have been initialized # further up so this has to be at the end. @@ -783,6 +786,8 @@ def __str__(self): (vpn_name, pair_policy)) else: ret_str.append(' vpn: name = %s' % vpn_name) + if self.application_id: + ret_str.append(' application_id: %s' % self.application_id) return '\n'.join(ret_str) @@ -883,6 +888,8 @@ def __eq__(self, other): return False if sorted(self.traffic_type) != sorted(other.traffic_type): return False + if sorted(self.application_id) != sorted(other.application_id): + return False # vpn if self.vpn != other.vpn: @@ -1115,6 +1122,8 @@ def AddObject(self, obj): self.target_resources.append(x.value) elif x.var_type is VarType.TARGET_SERVICE_ACCOUNTS: self.target_service_accounts.append(x.value) + elif x.var_type is VarType.APPLICATION_ID: + self.application_id.append(x.value) else: raise TermObjectTypeError( '%s isn\'t a type I know how to deal with (contains \'%s\')' % ( @@ -1196,6 +1205,8 @@ def AddObject(self, obj): self.target_resources.append(obj.value) elif obj.var_type is VarType.TARGET_SERVICE_ACCOUNTS: self.target_service_accounts.append(obj.value) + elif obj.var_type is VarType.APPLICATION_ID: + self.application_id.append(obj.value) else: raise TermObjectTypeError( '%s isn\'t a type I know how to deal with' % (type(obj))) @@ -1500,6 +1511,7 @@ class VarType(object): TARGET_RESOURCES = 59 TARGET_SERVICE_ACCOUNTS = 60 ENCAPSULATE = 61 + APPLICATION_ID = 62 def __init__(self, var_type, value): self.var_type = var_type @@ -1729,6 +1741,7 @@ def __ne__(self, other): 'TTL', 'VERBATIM', 'VPN', + 'APPLICATION_ID', ) literals = r':{},-/' @@ -1804,6 +1817,7 @@ def __ne__(self, other): 'ttl': 'TTL', 'verbatim': 'VERBATIM', 'vpn': 'VPN', + 'application-id': 'APPLICATION_ID', } # disable linting warnings for lexx/yacc code @@ -1972,6 +1986,7 @@ def p_term_spec(p): | term_spec traffic_type_spec | term_spec verbatim_spec | term_spec vpn_spec + | term_spec application_id_spec | """ if len(p) > 1: if type(p[1]) == Term: @@ -2332,6 +2347,13 @@ def p_pan_application_spec(p): p[0].append(VarType(VarType.PAN_APPLICATION, apps)) +def p_application_id_spec(p): + """ application_id_spec : APPLICATION_ID ':' ':' one_or_more_ints """ + p[0] = [] + for apps in p[4]: + p[0].append(VarType(VarType.APPLICATION_ID, apps)) + + def p_interface_spec(p): """ interface_spec : SINTERFACE ':' ':' STRING | DINTERFACE ':' ':' STRING """ diff --git a/capirca/lib/policy_simple.py b/capirca/lib/policy_simple.py index 61aed382..f5e3bb1b 100644 --- a/capirca/lib/policy_simple.py +++ b/capirca/lib/policy_simple.py @@ -324,6 +324,10 @@ class Vpn(Field): """A vpn field.""" +class ApplicationID(Field): + """A application id field.""" + + destination_address_fields = (DestinationAddress, DestinationExclude, DestinationPrefix) @@ -378,6 +382,7 @@ class Vpn(Field): 'verbatim': Verbatim, 'vpn': Vpn, 'encapsulate': Encapsulate, + 'application-id': ApplicationID, } diff --git a/doc/generator_patterns.md b/doc/generator_patterns.md new file mode 100644 index 00000000..4681f87a --- /dev/null +++ b/doc/generator_patterns.md @@ -0,0 +1,367 @@ +# Common Patterns For Generators + + + +## Objective + +The purpose of this document is to describe common patterns for new Capirca +Generators. + +## Security based requirements: + +### Inet_version ‘Mixed’ Platform Support + +#### When the platform does not support “mixed” in a single access-list + +##### Problem + +When the inet_version is set to ‘mixed’ it implies that the resultant policy +should contain addresses from both families. Some platforms do not support both +address families to exist in the same filter therefore leading to Capirca +generators needing to handle the output differently for those platforms. Cisco +is an example platform that does not support a mixed filter being generated, and +therefore it requires two separate *access-list* filters. + +Platforms that support mixed family filters will simply generate filters that +contain both address families. + +##### Desired Approach + +**The desired approach will be to have Capirca output two filters, one for each +address family, for platforms that do not support ‘mixed’.** This currently +occurs already with +[cisco.py](https://github.com/google/capirca/blob/master/capirca/lib/cisco.py) +which outputs two access-lists one that contains IPv4 and another that contains +IPv6 addresses. This solves a problem of having to potentially maintain two +different .pol so that in cases where vendor syntax of filter name is derived +from .pol a syncing between v4 and v6 .pol do not need to be maintained. + +This may be misleading at first because when using Capirca the user expects that +the output will be a single policy, but it is actually their lack of +understanding about the vendor syntax that causes this belief. + +If the user does not want this output, then the user can simply issue two +headers to Capirca one for IPv4 and one for IPv6. + +#### When the platform does supports “mixed” in a single access-list + +This will require the policy to be generated correctly for the +[following permutations](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/tests/lib/nsxv_test.py#L236-L322) +of address family, and when “mixed” is supported, and with valid tests: + +1. [MIXED_TO_V4](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/tests/lib/nsxv_test.py#L236) +1. [V4_TO_MIXED](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/tests/lib/nsxv_test.py#L245) +1. [MIXED_TO_V6](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/tests/lib/nsxv_test.py#L254) +1. [V6_TO_MIXED](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/tests/lib/nsxv_test.py#L262) +1. [MIXED_TO_MIXED](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/tests/lib/nsxv_test.py#L270) +1. [MIXED_TO_ANY](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/tests/lib/nsxv_test.py#L278) +1. [ANY_TO_MIXED](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/tests/lib/nsxv_test.py#L285) +1. [V4_TO_V4](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/tests/lib/nsxv_test.py#L92) +1. [V6_TO_V6](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/tests/lib/nsxv_test.py#L300) +1. [V4_TO_V6](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/tests/lib/nsxv_test.py#L308) +1. [V6_TO_V4](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/tests/lib/nsxv_test.py#L316) + +### noverbose option is supported correctly + +noverberse must be supported if it makes sense for the platform. Noverbose +removes all comments from the ACE terms, policies, etc. For example see the +logic implemented in +[juniper.py](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/capirca/lib/juniper.py#L219). + +### Sample.pol file is present + +A sample pol file should exist for that generator. Some examples are +[here](https://github.com/google/capirca/tree/master/policies/pol). The +sample.pol file for the new generator should have examples for all the filter +option types used, with all supported IP types, along with any custom fields for +that generator. + +### Perform truncating of names for term name or comment based on max length + +This is to ensure that truncation of terms and comments that exceed a max_width, +is supported by the generator. Not all platforms have length limitations, if the +generator’s platform has none, then this requirement can be skipped. This +applies only when the term name and comments are being incorporated into the +policy. If they are actual # comments (which are not applied to the policy), +then this requirement does not apply. This could be done using the existing +[WrapWords()](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/capirca/lib/aclgenerator.py#L549) +or it may be done by a truncate function within the generator using a custom +function such as in +[juniper.py](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/capirca/lib/juniper.py#L715). +This wrapping should also be present for the term name, and should be using +Capirca’s +[FixTermLength()](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/capirca/lib/aclgenerator.py#L463). + +### Logging is supported correctly for different types of logging + +There are different values of logging already created in +[policy.py](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/capirca/lib/policy.py#L49). +Not all are supported by every platform. + +* LOG_BOTH is for logging session-init as well as session-close, which is + currently supported by JuniperSRX. + +* DISABLE is a negative logging action. + +* Every other option are considered positive actions. + +General rules: + +* The generator should support all the types of logging it can. + +* For all unsupported positive logging actions, the generator should enable + logging. + +* For DISABLE, if the platform can turn off logging, it must; if the platform + does not support it, then it does nothing. Key part is DISABLE must not + enable logging. + +### DSMO Support + +DSMO is Discontinuous Subnet Masks and is used to save on TCAM space. This is +supported by certain platforms such as Cisco, but is not supported by most +platforms. If DSMO is not supported by a platform, this requirement can be +safely ignored. If DSMO is supported by a platform it must be fully implemented +and carefully unit tested. + +### The usage of good and meta Unified Direction names + +Good unified direction names for the ACE terms, that are meta and not specific +to that platform, are preferred. This is only for platforms that require +direction. The meta directions +[supported by Capirca](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/capirca/lib/packetfilter.py#L77) +are “in”, “out” and “”, but these should not be used as is. Different platforms +use “ingress”, “egress” or “both” such as GCE. Do not rely on platform specific +names for directions. “ingress” and “egress” are the preferred directions to be +used, which can then be converted to the platform’s required specific names for +directions. + +### Term Expirations are handled correctly + +Term expirations need to be handled correctly in code. An +[example from Juniper](https://github.com/google/capirca/blob/master/capirca/lib/juniper.py#L968-L974) +is that when the term is close to +[expiration](https://github.com/google/capirca/blob/c0ca9d9a3a34d3dab0b41510571448f5d82c033d/capirca/utils/config.py#L17), +an INFO message is logged; and when it is expired, a WARNING message is logged +and the term is not generated. This is also done similarly across other +platforms such as Cisco/GCE. + +### ICMP and ICMPv6 handling + +The generator needs to handle ICMP and ICMPv6 correctly. This is a broad +requirement, but ICMP and ICMPv6 requires careful handling to **avoid rendering +icmp terms under inet6, and icmpv6 under inet**. One commit that implements this +for gcp_hf is +[here](https://github.com/google/capirca/commit/b4af15a36b70593b7bbf043559405558e82c81bc). +Some generators do not support icmp and icmp6 when the address family is mixed, +such as +[nftables.py](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/capirca/lib/nftables.py#L103-L111). +The expected correct behavior is that when “mixed” is specified in the +inet_version, the rule for ICMP should only contain IPv4 addresses, and the rule +for ICMPv6 should contain only IPv6 addresses. Tests must ensure that types and +codes used are valid for the given address family. + +In the future, we hope to refactor the code to allow for general ICMP support, +but for now this functionality is implemented per-platform in each generator. + +### Makes an explicit determination about statefulness + +The generator author should check for “Am I stateful?”. It should clearly state +in generator the result of this as a comment somewhere If it is, it should make +sure that it is doing the right thing for terms. For example, for Juniper SRX, +it is +[possible to skip TCP-established](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/capirca/lib/junipersrx.py#L450-L453) +because it is stateful. You would also want to do the stateful check probably +early in the code rather than later, since this may impact efficiency by being +able to skip further code/ checks. A pro of checking early would be being able +to skip any processing of terms not necessary for a stateful firewall such as +skipping TCP-established. In contrast, in iptables.py, the check is made later, +while formatting the terms to modify the term to +[allow established and related terms](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/capirca/lib/iptables.py#L474-L485). + +### Syntax of the config from the generator and on-device should match when cryptographically verified + +The ACL that is generated from the generator, and the ACL that is obtained from +the device when a show configuration command is used, should match bit-by-bit, +such that it should be possible to run a hashing function (such as SHA-1) and +obtain the same hash for both the ACL configurations. Another variant of this +requirement is that the `diff` between these two policies should be empty. + +There can be certain exceptions, such as if there is a policy header comment +that cannot be handled by Cisco devices and is thus not present in the Cisco +ACL. This can be handled by checking the diff between them and skipping over the +known mismatches that are acceptable because of the device’s incapability. +Another example of an exception is the Juniper +[control sequence such as ‘replace’,](https://github.com/google/capirca/blob/b3e605a54f12efa1e6b0b1cfd179ee6078313c9d/capirca/lib/juniper.py#L993) +which indicates the device to replace, rather than merge the contents of the +ACL, which does not show up on the device ACL. + +If there is a mismatch in the syntax of the 2 ACLs that cannot be fixed, then +these mismatches and the technical reasoning behind the lack of a workaround or +a fix should be listed in the associated Github issue for this generator. + +### Apply priority as described in .pol files + +If a priority or order exists for the platform, and an input pol file doesn't +set priority for ACEs, then autogenerate priorities in top down order based on +the ACE order in the .pol file. + +### Protocol support + +#### Call out support + +Make explicit which protocols the platform supports, and support them in the +generator. If protocols are not supported by the platform, ensure that the +generator explicitly does not support them, and gracefully handles these errors. + +#### Names vs numbers + +Names or numbers can be used to represent protocols within a generator. +Throughout a given generators use only names or numbers, not a mix of both. The +choice should be made based on the default representation for the device +platform. (I.e. if the policy once applied to the device will show names in a +"show config" command output, then use names within the generator. If the output +contains numbers, use numbers within the generator.) + +#### Port support + +The following is a list of which IP protocols support ports. When supporting a +protocol, make sure that the handling of port or lack thereof is correct. + +* HOPOPT = No + +* ICMP = No + +* IGMP = No + +* GGP = No + +* IPIP = No + +* TCP = Yes + +* EGP = No + +* IGP = No + +* UDP = *Yes* + +* RDP = *Yes (Uses different port ranges though, check RFC)* + +* IPV6 = No + +* IPV6_ROUTE = No + +* FRAGMENT = No + +* RSVP = No + +* GRE = No + +* ESP = No + +* AH = No + +* ICMPV6 = No + +* IPV6_NONXT = No + +* IPV6_OPTS = No + +* OSPF = No + +* PIM = No + +* VRRP = No + +* L2TP = No. (only uses UDP 1701) + +* SCTP = *Yes* + +* UDPLITE = *Yes* + +Note: DCCP also uses ports, but this is not currently supported. Source: +https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml + +### Zone based firewall support + +Zone based firewalls should be implemented if supported by the platform. When +implementing zone based firewalls, all combinations of zone types must be tested +fully. Test for invalid and reserved zone names and illegal combinations of +policies (i.e. any-> specific, or any->any). + +### Address book support + +Address books should be implemented if they are present in a platform. The +generator should explicitly state whether it is implementing a global or zone +based address book. If both are available for the platform, both must be +implemented, and an option must be added to choose between the two. When +implementing address books, always filter for address family before building the +book. Tests should ensure that address books are filtered by address family +properly along with their relevant rules. + +## Coding Style Requirements: + +### Use builtin libraries + +Use only Python standard builtin libraries wherever possible. External +dependencies are discouraged and must be justified. + +### Structure generators for inheritance + +See Cisco and Juniper generators for examples. Wherever possible, use base +classes, inheritance, etc to allow for common functions between generators in a +"family". + +### Reuse common functions + +Use functions from aclgenerator.py, policy.py, nacaddr.py, etc wherever possible +instead of implementing your own. + +### If output will be in a common exchange format, use a standard library for rendering + +This applies to common standards such as JSON, XML, YAML, protocol buffers, etc. +Instead of building up such serialized output using string ops, use a standard +library to produce the rendered output instead. (For example, to render JSON, +use [json.dumps](https://docs.python.org/3/library/json.html#json.dumps). For +XML, use some combination of the +[standard libraries](https://docs.python.org/3/library/xml.html), such as +xml.etree and xml.dom.) This should allow most generator code to interact with +objects only, and serialize to a buffer at the end. Unit tests should operate on +the object structures. Additional small unit tests should sanity check that the +rendering library is producing valid output as expected. If a (JSON, XML, etc.) +schema is available this should also be used to validate output in a test. + +### Check various limits when rendering output + +Make sure that line, identifier, full output, etc. limits are applied when +rendering final output. Some of these may be specific to a given platform. These +should always include but are not limited to: + +* Maximum value of addresses and ports allowed in single rule. Generator must + support automatically splitting into new rule when exceeded. +* Maximum values allowed across entire policy for rule count, address, ports +* Maximum length for comments, and support splitting across lines the correct + way when over. Also check for max per-rule limit if one exists and truncate + using the common Capirca functions if needed. +* Max term length supported must be 24 or greater, in order to allow for + meaningful term names. + +### Test coverage + +#### General coverage + +Aim for as close to 100% test coverage as you can. Tests should cover a wide +span of the vendor syntax, not just a single keyword. + +#### Custom exceptions + +All custom exceptions types added must be unit tested. + + diff --git a/policies/pol/sample_fortigate.pol b/policies/pol/sample_fortigate.pol new file mode 100644 index 00000000..396489a2 --- /dev/null +++ b/policies/pol/sample_fortigate.pol @@ -0,0 +1,50 @@ +# Header Option: from-id -- Tells Capirca to number firewall +# policies starting at the provided integer. +# Header Option: ngfw-mode -- Default is profile. +# If Fortigate is using policy-based NGFW mode add 'ngfw-mode policy' + +header { + target:: fortigate +} + +term allow-web-outbound{ + source-address:: INTERNAL + destination-port:: HTTP HTTPS + source-port:: HTTP + protocol:: tcp udp + expiration:: 2020-12-20 + logging:: syslog + action:: accept +} + +term customers-policy { + destination-address:: INTERNAL + destination-exclude:: NTP_SERVERS + destination-port:: DNS HTTPS + source-exclude:: NTP_SERVERS + protocol:: tcp udp + action:: reject +} + +term customers-policy2 { + source-interface:: port2 + destination-interface:: port1 + source-address:: INTERNAL + source-port:: SMTP + destination-address:: MAIL_SERVERS + destination-port:: SMTP + protocol:: tcp udp + comment:: "this a test policy" + owner:: foo@google.com + action:: accept +} + +term ipv6-outbound{ + source-address:: LINKLOCAL + destination-address:: SITELOCAL LINKLOCAL + destination-port:: HTTP HTTPS + source-port:: HTTP + protocol:: tcp + expiration:: 2020-12-20 + action:: accept +} diff --git a/policies/pol/sample_multitarget.pol b/policies/pol/sample_multitarget.pol index 3664b70f..3a07b059 100644 --- a/policies/pol/sample_multitarget.pol +++ b/policies/pol/sample_multitarget.pol @@ -16,6 +16,7 @@ header { target:: arista edge-inbound target:: brocade edge-inbound target:: ciscoxr edge-inbound + target:: fortigate } #include 'includes/untrusted-networks-blocking.inc' @@ -59,6 +60,7 @@ header { target:: cisco edge-outbound mixed target:: speedway OUTPUT target:: ciscoasa asa_out + target:: fortigate } term deny-to-bad-destinations { diff --git a/tests/lib/cloudarmor_test.py b/tests/lib/cloudarmor_test.py index 8ea61dde..c9befd24 100644 --- a/tests/lib/cloudarmor_test.py +++ b/tests/lib/cloudarmor_test.py @@ -88,6 +88,14 @@ } """ +GOOD_TERM_DEFAULT_DENY = """ +term good-term-defaultdeny { + comment:: "Default Deny term" + action:: deny +} + +""" + GOOD_TERM_LARGE_COMMENT = """ term good-term-allow { comment:: "This is an unnecessarily long term comment that's going to be truncated" @@ -577,6 +585,150 @@ ] """ +EXPECTED_DEFAULT_DENY_JSON = """ +[ + { + "action": "deny(404)", + "description": "Default Deny term", + "match": { + "config": { + "srcIpRanges": [ + "*" + ] + }, + "versionedExpr": "SRC_IPS_V1" + }, + "preview": false, + "priority": 1 + } +] +""" + +EXPECTED_DEFAULT_DENY_SPLIT_JSON = """ +[ + { + "action": "allow", + "description": "Sample CloudArmor Allow Rule [1/3]", + "match": { + "config": { + "srcIpRanges": [ + "5.2.3.2/32", + "10.2.3.4/32", + "23.2.3.3/32", + "54.2.3.4/32", + "76.2.3.5/32" + ] + }, + "versionedExpr": "SRC_IPS_V1" + }, + "preview": false, + "priority": 1 + }, + { + "action": "allow", + "description": "Sample CloudArmor Allow Rule [2/3]", + "match": { + "config": { + "srcIpRanges": [ + "132.2.3.6/32", + "197.2.3.7/32", + "2001:4860:8000::5/128", + "24da:3ed8:32a0::7/128", + "3051:abd2:5400::9/128" + ] + }, + "versionedExpr": "SRC_IPS_V1" + }, + "preview": false, + "priority": 2 + }, + { + "action": "allow", + "description": "Sample CloudArmor Allow Rule [3/3]", + "match": { + "config": { + "srcIpRanges": [ + "577e:5400:3051::6/128", + "6f5d:abd2:1403::1/128", + "aee2:37ba:3cc0::3/128", + "af22:32d2:3f00::2/128" + ] + }, + "versionedExpr": "SRC_IPS_V1" + }, + "preview": false, + "priority": 3 + }, + { + "action": "deny(404)", + "description": "Sample Deny Rule [1/3]", + "match": { + "config": { + "srcIpRanges": [ + "5.2.3.2/32", + "10.2.3.4/32", + "23.2.3.3/32", + "54.2.3.4/32", + "76.2.3.5/32" + ] + }, + "versionedExpr": "SRC_IPS_V1" + }, + "preview": false, + "priority": 4 + }, + { + "action": "deny(404)", + "description": "Sample Deny Rule [2/3]", + "match": { + "config": { + "srcIpRanges": [ + "132.2.3.6/32", + "197.2.3.7/32", + "2001:4860:8000::5/128", + "24da:3ed8:32a0::7/128", + "3051:abd2:5400::9/128" + ] + }, + "versionedExpr": "SRC_IPS_V1" + }, + "preview": false, + "priority": 5 + }, + { + "action": "deny(404)", + "description": "Sample Deny Rule [3/3]", + "match": { + "config": { + "srcIpRanges": [ + "577e:5400:3051::6/128", + "6f5d:abd2:1403::1/128", + "aee2:37ba:3cc0::3/128", + "af22:32d2:3f00::2/128" + ] + }, + "versionedExpr": "SRC_IPS_V1" + }, + "preview": false, + "priority": 6 + }, + { + "action": "deny(404)", + "description": "Default Deny term", + "match": { + "config": { + "srcIpRanges": [ + "*" + ] + }, + "versionedExpr": "SRC_IPS_V1" + }, + "preview": false, + "priority": 7 + } +] +""" + TEST_IPS_NOSPLIT = [nacaddr.IP('10.2.3.4/32'), nacaddr.IP('2001:4860:8000::5/128')] @@ -747,6 +899,24 @@ def testNoVerbose(self): self.naming), EXP_INFO) self.assertNotIn('description', str(acl)) + def testDefaultDenyStandalone(self): + self.naming.GetNetAddr.return_value = TEST_IPS_NOSPLIT + + acl = cloudarmor.CloudArmor( + policy.ParsePolicy(GOOD_HEADER + GOOD_TERM_DEFAULT_DENY, + self.naming), EXP_INFO) + expected = json.loads(EXPECTED_DEFAULT_DENY_JSON) + self.assertEqual(expected, json.loads(self._StripAclHeaders(str(acl)))) + + def testDefaultDenyWithSplit(self): + self.naming.GetNetAddr.return_value = TEST_IPS_SPLIT + + acl = cloudarmor.CloudArmor( + policy.ParsePolicy(GOOD_HEADER_MIXED + GOOD_TERM_ALLOW + + GOOD_TERM_DENY + GOOD_TERM_DEFAULT_DENY, + self.naming), EXP_INFO) + expected = json.loads(EXPECTED_DEFAULT_DENY_SPLIT_JSON) + self.assertEqual(expected, json.loads(self._StripAclHeaders(str(acl)))) if __name__ == '__main__': unittest.main() diff --git a/tests/lib/fortigate_test.py b/tests/lib/fortigate_test.py new file mode 100644 index 00000000..b80cc95f --- /dev/null +++ b/tests/lib/fortigate_test.py @@ -0,0 +1,496 @@ +# Copyright 2019 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Unittest for fortigate policy rendering module.""" + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals + +import re +import string +import unittest +import mock + +from capirca.lib import fortigate +from capirca.lib import nacaddr +from capirca.lib import naming +from capirca.lib import policy + + +GOOD_HEADER = """ +header { + comment:: "this is a test acl" + target:: fortigate from-id 2 +} +""" + +GOOD_HEADER_1 = """ +header { + comment:: "this is a test acl" + target:: fortigate ngfw-mode policy-based +} +""" + +BAD_HEADER = """ +header { + comment:: "this is a test acl" + target:: fortigate edge-filter +} +""" + +TERM_TEMPLATE = """ +term good-term-2 {{ + source-interface:: {src_interface} + destination-interface:: {dest_interface} + protocol:: {protocol} + destination-address:: {dest_addr} + destination-port:: {dest_port} + source-address:: {src_addr} + source-port:: {src_port} + action:: {action} + logging:: {logging} +}} +""" + +_SP = ' ' + +EXP_INFO = 2 + + +class CustomFormatter(string.Formatter): + """ + Checks the custom formatter for fortigate output. + + """ + DEFAULT_VALUES = { + 'src_interface': 'wan1', + 'dest_interface': 'wan2', + 'protocol': 'tcp', + 'src_addr': 'SOME_HOST', + 'dest_addr': 'SOME_HOST', + 'src_port': 'HTTP', + 'dest_port': 'HTTP', + 'action': 'accept', + 'logging': 'true' + } + + def format(*args, **kwargs): + if 'remove_fields' in kwargs or 'add_fields' in kwargs: + args = list(args) + + if 'remove_fields' in kwargs: + for field in kwargs['remove_fields']: + remove_regex = '.*' + field + '.*' + args[1] = re.sub(remove_regex, '', args[1]) + + if 'add_fields' in kwargs: + add_fields_string = "" + for field, value in kwargs['add_fields'].items(): + add_fields_string += " " + field + ":: " + value + "\n" + args[1] = args[1][:-3] + add_fields_string + args[1][-3:] + + return string.Formatter.format(*args, **kwargs) + + def get_value(self, key, args, kwds): + try: + return kwds[key] + except KeyError: + return self.DEFAULT_VALUES[key] + + +class FortigateTest(unittest.TestCase): + """ + Fortigate test class. + + """ + def setUp(self): + self.naming = mock.create_autospec(naming.Naming) + + def get_addr_side_eff(host): + hosts = { + 'SOME_HOST': [nacaddr.IP('10.0.0.0/8')], + 'SOME_HOST2': [nacaddr.IP('20.0.0.0/8')], + 'SOME_HOST6': [nacaddr.IP('fec0::/10')] + } + return hosts[host] + + def get_port_side_eff(*args): + hosts = { + 'HTTP': ['80'], + 'HTTPS': ['443'], + 'SSH': ['22'], + 'WHOIS': ['43'] + } + return hosts[args[0]] + + self.naming.GetNetAddr.side_effect = get_addr_side_eff + self.naming.GetServiceByProto.side_effect = get_port_side_eff + self.fmt = CustomFormatter() + + def testGoodHeader(self): + """ + Tests a good header value. + + """ + term = self.fmt.format(TERM_TEMPLATE) + acl = fortigate.Fortigate(policy.ParsePolicy(GOOD_HEADER + term, + self.naming), EXP_INFO) + + expected_sig = 'edit 2' + + get_net_calls = [mock.call('SOME_HOST')] * 2 + get_server_by_proto_calls = [mock.call('HTTP', 'tcp')] * 2 + + self.assertIn(expected_sig, str(acl), '[%s]' % str(acl)) + self.naming.GetNetAddr.assert_has_calls(get_net_calls) + self.naming.GetServiceByProto.assert_has_calls(get_server_by_proto_calls) + + def testBadHeader(self): + """ + Tests a bad header value. + + """ + term = self.fmt.format(TERM_TEMPLATE) + parsed_p = policy.ParsePolicy(BAD_HEADER + term, + self.naming) + + self.assertRaises(fortigate.FilterError, + fortigate.Fortigate, + parsed_p, + EXP_INFO) + + def testAction(self): + """ + Tests the action detection. + + """ + accept_term = self.fmt.format(TERM_TEMPLATE, action='accept') + deny_term = self.fmt.format(TERM_TEMPLATE, action='deny') + reject_term = self.fmt.format(TERM_TEMPLATE, action='reject') + + accept_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + accept_term, + self.naming), EXP_INFO) + deny_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + deny_term, + self.naming), EXP_INFO) + reject_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + reject_term, + self.naming), EXP_INFO) + + accept_sig = 'set action accept' + deny_sig = 'set action deny' + reject_sig = 'set send-deny-packet enable' + reject_sys_sig = ('config sys setting\n' + + _SP + 'set deny-tcp-with-icmp enable\n' + + 'end\n') + + self.assertIn( + accept_sig, str(accept_acl), '[%s]' % str(accept_acl)) + self.assertIn( + deny_sig, str(deny_sig), '[%s]' % str(deny_acl)) + self.assertIn( + reject_sys_sig, str(reject_acl), '[%s]' % str(reject_acl)) + self.assertTrue( + deny_sig in str(reject_acl) and reject_sig in str(reject_acl), + '[%s]' % str(reject_acl)) + + def testAddresses(self): + """ + Tests an address object. + + """ + diff_addr_term = self.fmt.format(TERM_TEMPLATE, + src_addr='SOME_HOST', + dest_addr='SOME_HOST2') + same_addr_term = self.fmt.format(TERM_TEMPLATE, + src_addr='SOME_HOST2', + dest_addr='SOME_HOST2') + any_src_term = self.fmt.format(TERM_TEMPLATE, + remove_fields=('src_addr',)) + any_dest_term = self.fmt.format(TERM_TEMPLATE, + remove_fields=('dest_addr',)) + # testing for IPv6 + same_addr6_term = self.fmt.format(TERM_TEMPLATE, + src_addr='SOME_HOST6', + dest_addr='SOME_HOST6') + + diff_addr_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + diff_addr_term, + self.naming), EXP_INFO) + + same_addr_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + same_addr_term, + self.naming), EXP_INFO) + + any_src_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + any_src_term, + self.naming), EXP_INFO) + + any_dest_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + any_dest_term, + self.naming), EXP_INFO) + + same_addr6_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + same_addr6_term, + self.naming), EXP_INFO) + + src_sig = 'set srcaddr "10.0.0.0/8"' + dest_sig = 'set dstaddr "20.0.0.0/8"' + any_dest_sig = 'set dstaddr "all"' + any_src_sig = 'set srcaddr "all"' + src_sig_v6 = 'set srcaddr6 "fec0::/10"' + dest_sig_v6 = 'set dstaddr6 "fec0::/10"' + + self.assertTrue( + src_sig in str(diff_addr_acl) and dest_sig in str(diff_addr_acl), + '[%s]' % str(diff_addr_acl)) + # [] check acl generate one 'set subnet' for dup addresses + self.assertEqual( + str(same_addr_acl).count('set subnet'), 1) + self.assertIn( + any_src_sig, str(any_src_acl), '[%s]' % str(any_src_acl)) + self.assertIn( + any_dest_sig, str(any_dest_acl), '[%s]' % str(any_dest_acl)) + self.assertTrue( + src_sig_v6 in str(same_addr6_acl) + and dest_sig_v6 in str(same_addr6_acl), + '[%s]' % str(same_addr6_acl)) + + def testServices(self): + """ + Tests services objects. + + """ + dest_only_term = self.fmt.format(TERM_TEMPLATE, + dest_port='HTTP', + remove_fields=('src_port',)) + diff_port_term = self.fmt.format(TERM_TEMPLATE, + dest_port='HTTP HTTPS', + remove_fields=('src_port',)) + dup_port_term = self.fmt.format(TERM_TEMPLATE, + src_port='HTTP', + dest_port='HTTP') + icmp_term = self.fmt.format(TERM_TEMPLATE, + protocol='icmp', + add_fields={'icmp-type': 'echo-request'}, + remove_fields=('src_addr', 'dest_addr', + 'dest_port', 'src_port')) + ip_term = self.fmt.format(TERM_TEMPLATE, + remove_fields=('dest_port', 'src_port')) + custom_port_term = self.fmt.format(TERM_TEMPLATE, src_port='WHOIS') + #print("\icmp_term=========\n", icmp_term) + + dest_only_acl = fortigate.Fortigate(policy.ParsePolicy( + GOOD_HEADER + dest_only_term, + self.naming), EXP_INFO) + diff_acl = fortigate.Fortigate(policy.ParsePolicy( + GOOD_HEADER + diff_port_term, + self.naming), EXP_INFO) + dup_acl = fortigate.Fortigate(policy.ParsePolicy( + GOOD_HEADER + dup_port_term, + self.naming), EXP_INFO) + icmp_acl = fortigate.Fortigate(policy.ParsePolicy( + GOOD_HEADER + icmp_term, + self.naming), EXP_INFO) + ip_acl = fortigate.Fortigate(policy.ParsePolicy( + GOOD_HEADER + ip_term, + self.naming), EXP_INFO) + custom_port_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + custom_port_term, + self.naming), EXP_INFO) + #print("\ncustom_port_acl=========\n", custom_port_acl) + + dest_only_sig = 'set service HTTP\n' + diff_sig = 'set service HTTP HTTPS\n' + dup_sig = 'set service good-term-2-svc\n' + icmp_sig = 'set service icmp-type-echo-request\n' + ip_sig = 'set service ALL_TCP\n' + custom_port_sig = ('config firewall service custom\n' + + _SP + 'edit good-term-2-svc\n' + + _SP*2 + 'set comment "Generated by Capirca"\n' + + _SP*2 + 'set tcp-portrange 80:43\n' + + _SP + 'next\n') + + self.assertIn( + dest_only_sig, str(dest_only_acl), '[%s]' % str(dest_only_acl)) + self.assertIn( + diff_sig, str(diff_acl), '[%s]' % str(diff_acl)) + self.assertIn( + dup_sig, str(dup_acl), '[%s]' % str(dup_acl)) + self.assertIn( + icmp_sig, str(icmp_acl), '[%s]' % str(icmp_acl)) + self.assertIn( + ip_sig, str(ip_acl), '[%s]' % str(ip_acl)) + self.assertIn( + custom_port_sig, str(custom_port_acl), '[%s]' % str(custom_port_acl)) + + def testInterfaces(self): + """ + Tests interfaces. + + """ + no_interfaces_term = self.fmt.format(TERM_TEMPLATE, + remove_fields=('src_interface', + 'dest_interface')) + #print("no_interfaces_term=", no_interfaces_term) + src_only_int_term = self.fmt.format(TERM_TEMPLATE, + src_interface='wan1', + remove_fields=('dest_interface',)) + dest_only_int_term = self.fmt.format(TERM_TEMPLATE, + dest_interface='wan2', + remove_fields=('src_interface',)) + both_interfaces_term = self.fmt.format(TERM_TEMPLATE, + src_interface='wan1', + dest_interface='wan2',) + + no_interfaces_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + no_interfaces_term, + self.naming), EXP_INFO) + src_only_int_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + src_only_int_term, + self.naming), EXP_INFO) + dest_only_int_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + dest_only_int_term, + self.naming), EXP_INFO) + both_interfaces_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + both_interfaces_term, + self.naming), EXP_INFO) + + no_interfaces_sig = 'set srcintf any\n' + _SP*2 + 'set dstintf any' + src_int_only_sig = 'set srcintf wan1\n' + _SP*2 + 'set dstintf any' + dest_int_only_sig = 'set srcintf any\n' + _SP*2 + 'set dstintf wan2' + both_interfaces_sig = 'set srcintf wan1\n' + _SP*2 + 'set dstintf wan2' + + self.assertIn( + no_interfaces_sig, str(no_interfaces_acl), + '[%s]' % str(no_interfaces_acl)) + self.assertIn( + src_int_only_sig, str(src_only_int_acl), + '[%s]' % str(src_only_int_acl)) + self.assertIn( + dest_int_only_sig, str(dest_only_int_acl), + '[%s]' % str(dest_only_int_acl)) + self.assertIn( + both_interfaces_sig, str(both_interfaces_acl), + '[%s]' % str(both_interfaces_acl)) + + def testExpiration(self): + """ + Tests expiration / schedule object. + + """ + no_expiration_term = self.fmt.format(TERM_TEMPLATE) + expiration_term = self.fmt.format(TERM_TEMPLATE, + add_fields={'expiration': + '2022-12-31', + 'comment': + '"test expiration"'}) + + no_expiration_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + no_expiration_term, + self.naming), EXP_INFO) + expiration_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + expiration_term, + self.naming), EXP_INFO) + + no_expiration_sig = 'set schedule always' + expiration_sig = 'set schedule 2022/12/31_00:00' + expiration_config_sig = ('config firewall schedule onetime\n' + + _SP + 'edit 2022/12/31_00:00\n' + + _SP*2 + 'set end 00:00 2022/12/31\n' + + _SP + 'next\n' + + 'end\n') + + self.assertIn( + no_expiration_sig, str(no_expiration_acl), + '[%s]' % str(no_expiration_acl)) + self.assertTrue( + expiration_config_sig in str(expiration_acl) + and expiration_sig in str(expiration_acl), + '[%s]' % str(expiration_acl)) + + def testApplication_ID(self): + """ + Tests an application ID being used. + + """ + application_term = self.fmt.format(TERM_TEMPLATE, + add_fields={'application-id': '15816'}, + remove_fields=('src_addr', 'src_port')) + + application_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER_1 + application_term, + self.naming), EXP_INFO) + + application_sig = 'set application 15816' + + self.assertIn( + application_sig, str(application_acl), + '[%s]' % str(application_acl)) + + def testLogging(self): + """ + Tests logger input. + + """ + log_term = self.fmt.format(TERM_TEMPLATE, + logging='true') + no_log_term = self.fmt.format(TERM_TEMPLATE, + remove_fields=('logging',)) + + log_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + log_term, + self.naming), EXP_INFO) + no_log_acl = fortigate.Fortigate( + policy.ParsePolicy(GOOD_HEADER + no_log_term, + self.naming), EXP_INFO) + + log_sig = 'set logtraffic all' + + self.assertIn( + log_sig, str(log_acl), '[%s]' % str(log_acl)) + self.assertNotIn( + log_sig, str(no_log_term), '[%s]' % str(no_log_acl)) + + def testDuplicateTermError(self): + """ + Tests for duplicate term detection. + + """ + term = self.fmt.format(TERM_TEMPLATE, logging='true') + duplicate_terms = term + term + parsed_p = policy.ParsePolicy(GOOD_HEADER + duplicate_terms, + self.naming) + + self.assertRaises(fortigate.FortiGateDuplicateTermError, + fortigate.Fortigate, + parsed_p, + EXP_INFO) + + def testPortMap(self): + """ + Tests port map object. + + """ + port_map = fortigate.FortigatePortMap() + self.assertEqual('SSH', port_map.get_protocol('tcp', '22')) + self.assertRaises(fortigate.FortiGatePortDoesNotExistError, + port_map.get_protocol, + 'tcp', 5000) + self.assertRaises(fortigate.FortiGateValueError, + port_map.get_protocol, + 'bad_proto', 22) diff --git a/tests/lib/gce_test.py b/tests/lib/gce_test.py index 491ed0dc..0a66233b 100644 --- a/tests/lib/gce_test.py +++ b/tests/lib/gce_test.py @@ -22,6 +22,8 @@ import json import unittest +from absl.testing import parameterized + from capirca.lib import aclgenerator from capirca.lib import gce from capirca.lib import nacaddr @@ -57,6 +59,13 @@ } """ +GOOD_HEADER_MAX_ATTRIBUTE_COUNT = """ +header { + comment:: "The general policy comment." + target:: gce INGRESS global/networks/default 2 +} +""" + GOOD_TERM = """ term good-term-1 { comment:: "DNS access from corp." @@ -114,6 +123,14 @@ action:: accept } """ +GOOD_TERM_5 = """ +term good-term-5 { + comment:: "ICMP from IP." + source-address:: CORP_EXTERNAL + protocol:: icmp + action:: accept +} +""" GOOD_TERM_EGRESS = """ term good-term-1 { @@ -479,7 +496,7 @@ TEST_EXCLUDE_RANGE = [nacaddr.IP('10.240.0.0/16')] -class GCETest(unittest.TestCase): +class GCETest(parameterized.TestCase): def setUp(self): super(GCETest, self).setUp() @@ -881,5 +898,131 @@ def testValidTermNames(self): acl = gce.GCE(pol, EXP_INFO) self.assertIsNotNone(str(acl)) + def testMaxAttributeExceeded(self): + self.naming.GetNetAddr.return_value = TEST_IPS + self.naming.GetServiceByProto.side_effect = [['53'], ['53']] + self.assertRaises( + gce.ExceededAttributeCountError, + gce.GCE, + policy.ParsePolicy( + GOOD_HEADER_MAX_ATTRIBUTE_COUNT + GOOD_TERM + DEFAULT_DENY, + self.naming), + EXP_INFO) + + def testMaxAttribute(self): + self.naming.GetNetAddr.return_value = [nacaddr.IP('10.2.3.4/32')] + pol = policy.ParsePolicy(GOOD_HEADER_MAX_ATTRIBUTE_COUNT + GOOD_TERM_5, self.naming) + acl = gce.GCE(pol, EXP_INFO) + self.assertIsNotNone(str(acl)) + + @parameterized.named_parameters( + ('1 ip, 2 ports', + { + 'sourceRanges': ['10.128.0.0/10'], + 'allowed': [ + { + 'ports': ['22'], + 'IPProtocol': 'tcp' + }, + { + 'ports': ['53'], + 'IPProtocol': 'udp' + } + ], + }, 5), + ('1 ip, 2 ports, 1 target tag', + { + 'sourceRanges': ['10.128.0.0/10'], + 'allowed': [ + { + 'ports': ['22'], + 'IPProtocol': 'tcp' + }, + { + 'ports': ['53'], + 'IPProtocol': 'udp' + } + ], + 'targetTags': ['dns-servers'], + }, 6), + ('2 ips, 2 ports, 1 target tag', + { + 'sourceRanges': ['10.128.0.0/10', '192.168.1.1/24'], + 'allowed': [ + { + 'ports': ['22'], + 'IPProtocol': 'tcp' + }, + { + 'ports': ['53'], + 'IPProtocol': 'udp' + } + ], + 'targetTags': ['dns-servers'], + }, 7), + ('2 ips, 2 ports', + { + 'sourceRanges': ['10.128.0.0/10', '192.168.1.1/24'], + 'allowed': [ + { + 'ports': ['22'], + 'IPProtocol': 'tcp' + }, + { + 'ports': ['53'], + 'IPProtocol': 'udp' + } + ], + }, 6), + ('2 ips, 2 protocols', + { + 'sourceRanges': ['10.128.0.0/10', '192.168.1.1/24'], + 'allowed': [ + { + 'IPProtocol': 'tcp' + }, + { + 'IPProtocol': 'udp' + } + ], + }, 4), + ('1 ip, 2 protocols, 1 source tag', + { + 'sourceRanges': ['10.128.0.0/10'], + 'allowed': [ + { + 'IPProtocol': 'tcp' + }, + { + 'IPProtocol': 'udp' + } + ], + 'sourceTags': ['dns-servers'], + }, 4), + ('2 ips, 1 protocol', + { + 'sourceRanges': ['10.128.0.0/10', '192.168.1.1/24'], + 'allowed': [ + { + 'IPProtocol': 'icmp' + } + ], + }, 3), + ('1 ip, 2 protocols, 1 service account', + { + 'sourceRanges': ['10.128.0.0/10'], + 'allowed': [ + { + 'IPProtocol': 'tcp' + }, + { + 'IPProtocol': 'udp' + } + ], + 'targetServiceAccount': ['test@system.gserviceaccount.com'], + }, 4)) + def testGetAttributeCount(self, dict_term, expected): + self.assertEqual(gce.GetAttributeCount(dict_term), expected) + if __name__ == '__main__': unittest.main() diff --git a/tools/current_lint_errors.txt b/tools/current_lint_errors.txt deleted file mode 100644 index 684bd590..00000000 --- a/tools/current_lint_errors.txt +++ /dev/null @@ -1,1033 +0,0 @@ -************* Module aclcheck_cmdline -C0103: 30 main: Invalid variable name "_parser"[invalid-name] -C0103: 45 main: Invalid variable name "FLAGS"[invalid-name] -************* Module aclgen -W0212: 124 : Access to a protected member _deepcopy_dispatch of a client class[protected-access] -R0204: 246 RenderFile: Redefinition of acl_obj type from lib.juniper.Juniper to lib.junipersrx.JuniperSRX[redefined-variable-type] -C0103: 122 _deepcopy_method: Invalid function name "_deepcopy_method"[invalid-name] -C0411: 54 : standard import "import logging" comes before "from lib import aclgenerator"[wrong-import-order] -************* Module cgrep -C0325: 135 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 142 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 145 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 149 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 155 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 159 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 164 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 170 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 171 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 173 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 174 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 177 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 179 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 182 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 184 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 192 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 194 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 204 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 208 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 214 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 221 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 277 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 280 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 283 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0325: 286 : Unnecessary parens after 'print' keyword[superfluous-parens] -C0111: 1 : Missing module docstring[missing-docstring] -************* Module definate -C0111: 1 : Missing module docstring[missing-docstring] -************* Module definate.yaml_validator -C0123: 47 YamlValidator.CheckConfigurationItem: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 71 YamlValidator.CheckConfiguration: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 74 YamlValidator.CheckConfiguration: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 78 YamlValidator.CheckConfiguration: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 80 YamlValidator.CheckConfiguration: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -************* Module lib.aclcheck -C0123: 112 AclCheck.__init__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -W0622: 181 AclCheck.ActionMatch: Redefining built-in 'next'[redefined-builtin] -W0622: 195 AclCheck.DescribeMatches: Redefining built-in 'next'[redefined-builtin] -W0622: 203 AclCheck.__str__: Redefining built-in 'next'[redefined-builtin] -W0622: 251 AclCheck._AddrInside: Redefining built-in 'next'[redefined-builtin] -************* Module lib.aclgenerator -C0200: 428 WrapWords: Consider using enumerate instead of iterating with range and len[consider-using-enumerate] -************* Module lib.ciscoasa -C0305: 459 : Trailing newlines[trailing-newlines] -W1401: 392 : Anomalous backslash in string: '\s'. String constant might be missing an r prefix.[anomalous-backslash-in-string] -W0231: 62 Term.__init__: __init__ method from base class 'Term' is not called[super-init-not-called] -W0622: 100 Term.__str__: Redefining built-in 'next'[redefined-builtin] -C0123: 178 Term.__str__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 179 Term.__str__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -R0101: 169 Term.__str__: Too many nested blocks (8/5)[too-many-nested-blocks] -C0123: 182 Term.__str__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 183 Term.__str__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -R0101: 169 Term.__str__: Too many nested blocks (8/5)[too-many-nested-blocks] -C0103: 199 Term._TermPortToProtocol: Invalid argument name "portNumber"[invalid-name] -C0111: 199 Term._TermPortToProtocol: Missing method docstring[missing-docstring] -C0103: 200 Term._TermPortToProtocol: Invalid variable name "_ASA_PORTS_TCP"[invalid-name] -C0103: 248 Term._TermPortToProtocol: Invalid variable name "_ASA_PORTS_UDP"[invalid-name] -C0103: 281 Term._TermPortToProtocol: Invalid variable name "_ASA_TYPES_ICMP"[invalid-name] -C0123: 332 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 332 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 337 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 337 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 343 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 343 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 348 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 348 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -W0612: 417 CiscoASA._TranslatePolicy: Unused variable 'filter_options'[unused-variable] -W0612: 437 CiscoASA.__str__: Unused variable 'target_header'[unused-variable] -************* Module lib.cisco -C0123: 122 TermStandard.__str__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -R0101: 228 ObjectGroup.__str__: Too many nested blocks (6/5)[too-many-nested-blocks] -E0602: 513 Term.__str__: Undefined variable 'ExtendedAclTermError'[undefined-variable] -C0123: 563 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 563 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 568 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 568 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 574 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 574 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 579 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 579 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 585 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 587 Term._TermletToStr: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0411: 29 : standard import "import logging" comes before "from lib import aclgenerator"[wrong-import-order] -************* Module lib.demo -W0231: 42 Term.__init__: __init__ method from base class 'Term' is not called[super-init-not-called] -C0111: 137 Term._Group: Missing method docstring[missing-docstring] -************* Module lib.iptables -R0204: 103 Term.__init__: Redefinition of self._all_ips type from lib.nacaddr.IPv6 to lib.nacaddr.IPv4[redefined-variable-type] -R0101: 672 Iptables._TranslatePolicy: Too many nested blocks (6/5)[too-many-nested-blocks] -C0411: 26 : standard import "import logging" comes before "from lib import aclgenerator"[wrong-import-order] -************* Module lib.juniper -C0111: 639 Term._Comment: Missing method docstring[missing-docstring] -C0411: 27 : standard import "import logging" comes before "from lib import aclgenerator"[wrong-import-order] -************* Module lib.junipersrx -R0204: 136 Term.__str__: Redefinition of daddr_check type from list to set[redefined-variable-type] -R0101: 626 JuniperSRX._GenerateAddressBook: Too many nested blocks (6/5)[too-many-nested-blocks] -R0204: 651 JuniperSRX._GenerateAddressBook: Redefinition of address_book_groups_dict type from dict to collections.OrderedDict[redefined-variable-type] -C0111: 696 JuniperSRX._GenerateApplications: Missing method docstring[missing-docstring] -R0101: 701 JuniperSRX._GenerateApplications: Too many nested blocks (8/5)[too-many-nested-blocks] -R0101: 701 JuniperSRX._GenerateApplications: Too many nested blocks (7/5)[too-many-nested-blocks] -C0411: 28 : standard import "import logging" comes before "from lib import aclgenerator"[wrong-import-order] -************* Module lib.nacaddr -W0212: 212 CollapseAddrList: Access to a protected member _get_networks_key of a client class[protected-access] -W0212: 212 CollapseAddrList: Access to a protected member _BaseNet of a client class[protected-access] -W0212: 217 SortAddrList: Access to a protected member _get_networks_key of a client class[protected-access] -W0212: 217 SortAddrList: Access to a protected member _BaseNet of a client class[protected-access] -C0103: 268 : Invalid constant name "ExcludeAddrs"[invalid-name] -************* Module lib.naming -C0123: 159 Naming.GetIpParents: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 159 Naming.GetIpParents: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 163 Naming.GetIpParents: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 163 Naming.GetIpParents: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -W0622: 413 Naming.GetNet: Redefining built-in 'next'[redefined-builtin] -R0101: 560 Naming._ParseLine: Too many nested blocks (6/5)[too-many-nested-blocks] -************* Module lib.nftables -R0204: 70 Term.__init__: Redefinition of self.all_ips type from lib.nacaddr.IPv6 to lib.nacaddr.IPv4[redefined-variable-type] -C0111: 186 Term._FormatMatch: Missing method docstring[missing-docstring] -C0411: 32 : standard import "import logging" comes before "from lib import aclgenerator"[wrong-import-order] -************* Module lib.nsxv -W0231: 105 Term.__init__: __init__ method from base class 'Term' is not called[super-init-not-called] -C0123: 258 Term.__str__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 269 Term.__str__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 285 Term.__str__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 296 Term.__str__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0411: 23 : standard import "import logging" comes before "from lib import aclgenerator"[wrong-import-order] -************* Module lib.packetfilter -R0204: 177 Term.__str__: Redefinition of source_port type from list to str[redefined-variable-type] -R0204: 179 Term.__str__: Redefinition of destination_port type from list to str[redefined-variable-type] -C0111: 326 Term._GenerateProtoStatement: Missing method docstring[missing-docstring] -C0111: 340 Term._GenerateAddrStatement: Missing method docstring[missing-docstring] -C0411: 25 : standard import "import logging" comes before "from lib import aclgenerator"[wrong-import-order] -************* Module lib.pcap -C0111: 239 Term._GenerateAddrStatement: Missing method docstring[missing-docstring] -C0111: 265 Term._GeneratePortStatement: Missing method docstring[missing-docstring] -C0111: 278 Term._GenerateTcpOptions: Missing method docstring[missing-docstring] -C0411: 34 : standard import "import logging" comes before "from lib import aclgenerator"[wrong-import-order] -************* Module lib.policy -W0110: 860 Term.GetAddressOfVersion: map/filter on lambda could be replaced by comprehension[deprecated-lambda] -C0123: 876 Term.AddObject: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123:1333 Header.AddObject: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -W0110:1349 Header.platforms: map/filter on lambda could be replaced by comprehension[deprecated-lambda] -C0123:1630 p_target: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123:1649 p_header_spec: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123:1669 p_terms: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123:1714 p_term_spec: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123:1786 p_one_or_more_dscps: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123:2018 p_one_or_more_strings: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123:2030 p_one_or_more_ints: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123:2044 p_strings_or_ints: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -R0204:2196 : Redefinition of ret type from int to bool[redefined-variable-type] -C0103: 106 TranslatePorts: Invalid function name "TranslatePorts"[invalid-name] -C0103:2072 _ReadFile: Invalid function name "_ReadFile"[invalid-name] -C0103:2096 _Preprocess: Invalid function name "_Preprocess"[invalid-name] -C0103:2131 ParseFile: Invalid function name "ParseFile"[invalid-name] -C0103:2153 ParsePolicy: Invalid function name "ParsePolicy"[invalid-name] -C0411: 31 : standard import "import logging" comes before "from lib import nacaddr"[wrong-import-order] -************* Module lib.policyreader -W0622: 202 Policy.Matches: Redefining built-in 'next'[redefined-builtin] -************* Module lib.policy_simple -C0123: 44 Field.__eq__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 391 Block.__eq__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 523 BlankLine.__eq__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 539 CommentLine.__eq__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -C0123: 557 Include.__eq__: Using type() instead of isinstance() for a typecheck.[unidiomatic-typecheck] -************* Module lib.port -C0325: 100 : Unnecessary parens after 'return' keyword[superfluous-parens] -W0702: 108 PPP.__lt__: No exception type(s) specified[bare-except] -W0702: 117 PPP.__gt__: No exception type(s) specified[bare-except] -W0702: 126 PPP.__le__: No exception type(s) specified[bare-except] -W0702: 135 PPP.__ge__: No exception type(s) specified[bare-except] -W0702: 147 PPP.__eq__: No exception type(s) specified[bare-except] -************* Module lib.setup -C0111: 1 : Missing module docstring[missing-docstring] -E0602: 25 : Undefined variable 'ipaddr'[undefined-variable] -W0611: 20 : Unused import capirca[unused-import] -************* Module lib.windows_advfirewall -C0200: 73 Term._HandleIcmpTypes: Consider using enumerate instead of iterating with range and len[consider-using-enumerate] -C0122: 102 Term._ComposeRule: Comparison should be self.filter.lower() == 'in'[misplaced-comparison-constant] -C0411: 22 : standard import "import logging" comes before "from lib import windows"[wrong-import-order] -************* Module lib.windows_ipsec -C0411: 21 : standard import "import logging" comes before "from lib import aclgenerator"[wrong-import-order] -************* Module lib.windows -R0204: 60 Term.__init__: Redefinition of self._all_ips type from lib.nacaddr.IPv6 to lib.nacaddr.IPv4[redefined-variable-type] -R0101: 254 WindowsGenerator._TranslatePolicy: Too many nested blocks (6/5)[too-many-nested-blocks] -C0411: 22 : standard import "import logging" comes before "from lib import aclgenerator"[wrong-import-order] -************* Module setup -C0330: 49 : Wrong hanging indentation (add 2 spaces). - 'python-gflags', 'ply', 'ipaddr', 'mock'] - ^ |[bad-continuation] -C0111: 1 : Missing module docstring[missing-docstring] -************* Module tests.cgrep_test -C0330: 266 : Wrong continued indentation (add 1 space). - ('GOOGLE_DNS -> GOOGLE_PUBLIC_DNS_ANYCAST', - ^|[bad-continuation] -C0111: 214 CgrepTest: Missing class docstring[missing-docstring] -C0111: 332 CgrepTest.test_compare_same_token: Missing method docstring[missing-docstring] -C0111: 384 CgrepTest.test_group_diff: Missing method docstring[missing-docstring] -C0111: 397 CgrepTest.test_group_diff_identical: Missing method docstring[missing-docstring] -C0111: 414 CgrepTest.test_token_to_ips: Missing method docstring[missing-docstring] -C0111: 434 CgrepTest.test_token_to_ip_fail: Missing method docstring[missing-docstring] -C0111: 456 CgrepTest.test_svc_to_port: Missing method docstring[missing-docstring] -C0111: 472 CgrepTest.test_svc_to_port_fail: Missing method docstring[missing-docstring] -************* Module tests.integration.aclgen_test -C0111: 1 : Missing module docstring[missing-docstring] -C0111: 52 TestAclGenDemo.test_smoke_test_generates_successfully: Missing method docstring[missing-docstring] -C0111: 87 TestAclGenDemo.test_generate_single_policy: Missing method docstring[missing-docstring] -C0111: 140 AclGenArgumentsTests.test_missing_defs_folder_raises_error: Missing method docstring[missing-docstring] -C0111: 160 AclGenCharacterizationTests.test_characterization: Missing method docstring[missing-docstring] -************* Module tests.lib.aclcheck_test -C0111: 63 AclCheckTest: Missing class docstring[missing-docstring] -C0103: 77 AclCheckTest.testExactMatches: Invalid method name "testExactMatches"[invalid-name] -C0103: 83 AclCheckTest.testAclCheck: Invalid method name "testAclCheck"[invalid-name] -C0111: 83 AclCheckTest.testAclCheck: Missing method docstring[missing-docstring] -C0103: 115 AclCheckTest.testExceptions: Invalid method name "testExceptions"[invalid-name] -C0111: 115 AclCheckTest.testExceptions: Missing method docstring[missing-docstring] -************* Module tests.lib.aclgenerator_test -C0111: 90 ACLGeneratorTest: Missing class docstring[missing-docstring] -C0103: 95 ACLGeneratorTest.testEstablishedNostate: Invalid method name "testEstablishedNostate"[invalid-name] -C0103: 105 ACLGeneratorTest.testSupportedAF: Invalid method name "testSupportedAF"[invalid-name] -C0103: 114 ACLGeneratorTest.testTermNameBelowLimit: Invalid method name "testTermNameBelowLimit"[invalid-name] -C0103: 130 ACLGeneratorTest.testLongTermAbbreviation: Invalid method name "testLongTermAbbreviation"[invalid-name] -C0103: 141 ACLGeneratorTest.testTermNameTruncation: Invalid method name "testTermNameTruncation"[invalid-name] -C0103: 151 ACLGeneratorTest.testLongTermName: Invalid method name "testLongTermName"[invalid-name] -C0103: 161 ACLGeneratorTest.testAddRepositoryTags: Invalid method name "testAddRepositoryTags"[invalid-name] -C0111: 161 ACLGeneratorTest.testAddRepositoryTags: Missing method docstring[missing-docstring] -************* Module tests.lib.arista_test -C0103: 51 AristaTest.testExtendedEosSyntax: Invalid method name "testExtendedEosSyntax"[invalid-name] -************* Module tests.lib.aruba_test -C0111: 72 ArubaTest: Missing class docstring[missing-docstring] -C0103: 77 ArubaTest.testNetdestination: Invalid method name "testNetdestination"[invalid-name] -C0103: 88 ArubaTest.testNetdestination6: Invalid method name "testNetdestination6"[invalid-name] -C0103: 99 ArubaTest.testActionUnsupported: Invalid method name "testActionUnsupported"[invalid-name] -C0111: 99 ArubaTest.testActionUnsupported: Missing method docstring[missing-docstring] -************* Module tests.lib.brocade_test -C0111: 43 BrocadeTest: Missing class docstring[missing-docstring] -C0103: 48 BrocadeTest.testTcpEstablished: Invalid method name "testTcpEstablished"[invalid-name] -C0103: 54 BrocadeTest.testNoTermRemark: Invalid method name "testNoTermRemark"[invalid-name] -************* Module tests.lib.cisco_test -C0330: 313 : Wrong hanging indentation (remove 4 spaces). - 'CONSECUTIVE_PORTS', 'tcp') - | ^[bad-continuation] -C0111: 270 CiscoTest: Missing class docstring[missing-docstring] -C0103: 275 CiscoTest.testIPVersion: Invalid method name "testIPVersion"[invalid-name] -C0103: 286 CiscoTest.testOptions: Invalid method name "testOptions"[invalid-name] -C0111: 286 CiscoTest.testOptions: Missing method docstring[missing-docstring] -C0103: 300 CiscoTest.testExpandingConsequtivePorts: Invalid method name "testExpandingConsequtivePorts"[invalid-name] -C0111: 300 CiscoTest.testExpandingConsequtivePorts: Missing method docstring[missing-docstring] -C0103: 315 CiscoTest.testDSCP: Invalid method name "testDSCP"[invalid-name] -C0103: 321 CiscoTest.testTermAndFilterName: Invalid method name "testTermAndFilterName"[invalid-name] -C0103: 327 CiscoTest.testRemark: Invalid method name "testRemark"[invalid-name] -C0111: 327 CiscoTest.testRemark: Missing method docstring[missing-docstring] -C0103: 344 CiscoTest.testTcpEstablished: Invalid method name "testTcpEstablished"[invalid-name] -C0103: 350 CiscoTest.testLogging: Invalid method name "testLogging"[invalid-name] -C0103: 356 CiscoTest.testVerbatimTerm: Invalid method name "testVerbatimTerm"[invalid-name] -C0103: 364 CiscoTest.testBadStandardTerm: Invalid method name "testBadStandardTerm"[invalid-name] -C0103: 373 CiscoTest.testStandardTermHost: Invalid method name "testStandardTermHost"[invalid-name] -C0103: 384 CiscoTest.testStandardTermNet: Invalid method name "testStandardTermNet"[invalid-name] -C0103: 395 CiscoTest.testNamedStandard: Invalid method name "testNamedStandard"[invalid-name] -C0103: 406 CiscoTest.testNoIPv6InOutput: Invalid method name "testNoIPv6InOutput"[invalid-name] -C0103: 416 CiscoTest.testStandardFilterName: Invalid method name "testStandardFilterName"[invalid-name] -C0103: 426 CiscoTest.testStandardFilterRange: Invalid method name "testStandardFilterRange"[invalid-name] -C0103: 436 CiscoTest.testActionsSupport: Invalid method name "testActionsSupport"[invalid-name] -W0212: 437 CiscoTest.testActionsSupport: Access to a protected member _ACTION_TABLE of a client class[protected-access] -C0103: 440 CiscoTest.testObjectGroup: Invalid method name "testObjectGroup"[invalid-name] -C0111: 440 CiscoTest.testObjectGroup: Missing method docstring[missing-docstring] -C0103: 477 CiscoTest.testInet6: Invalid method name "testInet6"[invalid-name] -C0111: 477 CiscoTest.testInet6: Missing method docstring[missing-docstring] -C0103: 493 CiscoTest.testMixed: Invalid method name "testMixed"[invalid-name] -C0111: 493 CiscoTest.testMixed: Missing method docstring[missing-docstring] -C0103: 515 CiscoTest.testDsmo: Invalid method name "testDsmo"[invalid-name] -C0111: 515 CiscoTest.testDsmo: Missing method docstring[missing-docstring] -C0103: 528 CiscoTest.testUdpEstablished: Invalid method name "testUdpEstablished"[invalid-name] -C0103: 534 CiscoTest.testIcmpTypes: Invalid method name "testIcmpTypes"[invalid-name] -C0111: 534 CiscoTest.testIcmpTypes: Missing method docstring[missing-docstring] -C0103: 547 CiscoTest.testIpv6IcmpTypes: Invalid method name "testIpv6IcmpTypes"[invalid-name] -C0111: 547 CiscoTest.testIpv6IcmpTypes: Missing method docstring[missing-docstring] -C0103: 561 CiscoTest.testIcmpv6InetMismatch: Invalid method name "testIcmpv6InetMismatch"[invalid-name] -C0103: 573 CiscoTest.testIcmpInet6Mismatch: Invalid method name "testIcmpInet6Mismatch"[invalid-name] -C0103: 584 CiscoTest.testUnsupportedKeywordsError: Invalid method name "testUnsupportedKeywordsError"[invalid-name] -C0103: 594 CiscoTest.testDefaultInet6Protocol: Invalid method name "testDefaultInet6Protocol"[invalid-name] -C0103: 600 CiscoTest.testExpiredTerm: Invalid method name "testExpiredTerm"[invalid-name] -C0103: 609 CiscoTest.testExpiringTerm: Invalid method name "testExpiringTerm"[invalid-name] -C0103: 619 CiscoTest.testTermHopByHop: Invalid method name "testTermHopByHop"[invalid-name] -C0103: 624 CiscoTest.testOwnerTerm: Invalid method name "testOwnerTerm"[invalid-name] -C0103: 630 CiscoTest.testRemoveTrailingCommentWhitespace: Invalid method name "testRemoveTrailingCommentWhitespace"[invalid-name] -W0612: 632 CiscoTest.testRemoveTrailingCommentWhitespace: Unused variable 'acl'[unused-variable] -************* Module tests.lib.ciscoxr_test -C0111: 66 CiscoXRTest: Missing class docstring[missing-docstring] -C0103: 71 CiscoXRTest.testStandardTermHost: Invalid method name "testStandardTermHost"[invalid-name] -C0103: 82 CiscoXRTest.testStandardTermHostIPv6: Invalid method name "testStandardTermHostIPv6"[invalid-name] -C0111: 82 CiscoXRTest.testStandardTermHostIPv6: Missing method docstring[missing-docstring] -************* Module tests.lib.gce_test -C0111: 297 GCETest: Missing class docstring[missing-docstring] -C0103: 306 GCETest.testGenericTerm: Invalid method name "testGenericTerm"[invalid-name] -C0111: 306 GCETest.testGenericTerm: Missing method docstring[missing-docstring] -C0103: 320 GCETest.testGenericTermWithoutNetwork: Invalid method name "testGenericTermWithoutNetwork"[invalid-name] -C0111: 320 GCETest.testGenericTermWithoutNetwork: Missing method docstring[missing-docstring] -C0103: 334 GCETest.testGenericTermWithExclude: Invalid method name "testGenericTermWithExclude"[invalid-name] -C0111: 334 GCETest.testGenericTermWithExclude: Missing method docstring[missing-docstring] -C0103: 350 GCETest.testGenericTermWithExcludeRange: Invalid method name "testGenericTermWithExcludeRange"[invalid-name] -C0111: 350 GCETest.testGenericTermWithExcludeRange: Missing method docstring[missing-docstring] -C0103: 367 GCETest.testExpiredTerm: Invalid method name "testExpiredTerm"[invalid-name] -C0103: 378 GCETest.testSourceNetworkSplit: Invalid method name "testSourceNetworkSplit"[invalid-name] -C0111: 378 GCETest.testSourceNetworkSplit: Missing method docstring[missing-docstring] -C0103: 398 GCETest.testRaisesWithUnsupportedAction: Invalid method name "testRaisesWithUnsupportedAction"[invalid-name] -C0111: 398 GCETest.testRaisesWithUnsupportedAction: Missing method docstring[missing-docstring] -C0103: 413 GCETest.testRaisesWithoutSource: Invalid method name "testRaisesWithoutSource"[invalid-name] -C0111: 413 GCETest.testRaisesWithoutSource: Missing method docstring[missing-docstring] -C0103: 426 GCETest.testRaisesWithOnlySourceExclusion: Invalid method name "testRaisesWithOnlySourceExclusion"[invalid-name] -C0111: 426 GCETest.testRaisesWithOnlySourceExclusion: Missing method docstring[missing-docstring] -C0103: 442 GCETest.testRaisesNoSourceAfterExclude: Invalid method name "testRaisesNoSourceAfterExclude"[invalid-name] -C0111: 442 GCETest.testRaisesNoSourceAfterExclude: Missing method docstring[missing-docstring] -C0103: 462 GCETest.testRaisesWithSourcePort: Invalid method name "testRaisesWithSourcePort"[invalid-name] -C0111: 462 GCETest.testRaisesWithSourcePort: Missing method docstring[missing-docstring] -C0103: 477 GCETest.testRaisesWithLongTermName: Invalid method name "testRaisesWithLongTermName"[invalid-name] -C0111: 477 GCETest.testRaisesWithLongTermName: Missing method docstring[missing-docstring] -C0103: 491 GCETest.testRaisesWithIcmpAndDestinationPort: Invalid method name "testRaisesWithIcmpAndDestinationPort"[invalid-name] -C0111: 491 GCETest.testRaisesWithIcmpAndDestinationPort: Missing method docstring[missing-docstring] -************* Module tests.lib.ipset_test -C0305: 193 : Trailing newlines[trailing-newlines] -C0111: 60 IpsetTest: Missing class docstring[missing-docstring] -C0103: 65 IpsetTest.testMarkers: Invalid method name "testMarkers"[invalid-name] -C0103: 76 IpsetTest.testGenerateSetName: Invalid method name "testGenerateSetName"[invalid-name] -C0111: 76 IpsetTest.testGenerateSetName: Missing method docstring[missing-docstring] -W0212: 83 IpsetTest.testGenerateSetName: Access to a protected member _GenerateSetName of a client class[protected-access] -W0212: 85 IpsetTest.testGenerateSetName: Access to a protected member _GenerateSetName of a client class[protected-access] -W0212: 89 IpsetTest.testGenerateSetName: Access to a protected member _GenerateSetName of a client class[protected-access] -W0212: 91 IpsetTest.testGenerateSetName: Access to a protected member _GenerateSetName of a client class[protected-access] -C0103: 95 IpsetTest.testOneSourceAddress: Invalid method name "testOneSourceAddress"[invalid-name] -C0103: 106 IpsetTest.testOneDestinationAddress: Invalid method name "testOneDestinationAddress"[invalid-name] -C0103: 117 IpsetTest.testOneSourceAndDestinationAddress: Invalid method name "testOneSourceAndDestinationAddress"[invalid-name] -C0111: 117 IpsetTest.testOneSourceAndDestinationAddress: Missing method docstring[missing-docstring] -C0103: 134 IpsetTest.testManySourceAddresses: Invalid method name "testManySourceAddresses"[invalid-name] -C0111: 134 IpsetTest.testManySourceAddresses: Missing method docstring[missing-docstring] -C0103: 150 IpsetTest.testManyDestinationAddresses: Invalid method name "testManyDestinationAddresses"[invalid-name] -C0111: 150 IpsetTest.testManyDestinationAddresses: Missing method docstring[missing-docstring] -C0103: 166 IpsetTest.testManySourceAndDestinationAddresses: Invalid method name "testManySourceAndDestinationAddresses"[invalid-name] -C0111: 166 IpsetTest.testManySourceAndDestinationAddresses: Missing method docstring[missing-docstring] -************* Module tests.lib.iptables_test -C0330: 831 : Wrong hanging indentation (remove 4 spaces). - 'FOURTEEN_PORTS', 'tcp') - | ^[bad-continuation] -C0330: 845 : Wrong hanging indentation (remove 4 spaces). - 'FIFTEEN_PORTS_WITH_RANGES', 'tcp') - | ^[bad-continuation] -C0111: 412 AclCheckTest: Missing class docstring[missing-docstring] -C0103: 418 AclCheckTest.testChainFilter: Invalid method name "testChainFilter"[invalid-name] -C0111: 418 AclCheckTest.testChainFilter: Missing method docstring[missing-docstring] -C0103: 434 AclCheckTest.testUnsupportedTargetOption: Invalid method name "testUnsupportedTargetOption"[invalid-name] -C0103: 439 AclCheckTest.testGoodPolicy: Invalid method name "testGoodPolicy"[invalid-name] -C0103: 451 AclCheckTest.testCustomChain: Invalid method name "testCustomChain"[invalid-name] -C0103: 458 AclCheckTest.testChainNoTarget: Invalid method name "testChainNoTarget"[invalid-name] -C0103: 470 AclCheckTest.testCustomChainNoTarget: Invalid method name "testCustomChainNoTarget"[invalid-name] -C0103: 481 AclCheckTest.testExcludeReturnsPolicy: Invalid method name "testExcludeReturnsPolicy"[invalid-name] -C0111: 481 AclCheckTest.testExcludeReturnsPolicy: Missing method docstring[missing-docstring] -C0103: 507 AclCheckTest.testExcludeAddressesPolicy: Invalid method name "testExcludeAddressesPolicy"[invalid-name] -C0111: 507 AclCheckTest.testExcludeAddressesPolicy: Missing method docstring[missing-docstring] -C0103: 528 AclCheckTest.testAddExcludeSourceForLengthPolicy: Invalid method name "testAddExcludeSourceForLengthPolicy"[invalid-name] -C0111: 528 AclCheckTest.testAddExcludeSourceForLengthPolicy: Missing method docstring[missing-docstring] -C0103: 570 AclCheckTest.testAddExcludeDestForLengthPolicy: Invalid method name "testAddExcludeDestForLengthPolicy"[invalid-name] -C0111: 570 AclCheckTest.testAddExcludeDestForLengthPolicy: Missing method docstring[missing-docstring] -C0103: 612 AclCheckTest.testOptions: Invalid method name "testOptions"[invalid-name] -C0111: 612 AclCheckTest.testOptions: Missing method docstring[missing-docstring] -C0103: 628 AclCheckTest.testRejectReset: Invalid method name "testRejectReset"[invalid-name] -C0103: 635 AclCheckTest.testReject: Invalid method name "testReject"[invalid-name] -C0103: 642 AclCheckTest.testRejectIpv6: Invalid method name "testRejectIpv6"[invalid-name] -C0103: 650 AclCheckTest.testIPv6Headers: Invalid method name "testIPv6Headers"[invalid-name] -C0103: 659 AclCheckTest.testNextTerm: Invalid method name "testNextTerm"[invalid-name] -C0103: 666 AclCheckTest.testProtocols: Invalid method name "testProtocols"[invalid-name] -C0111: 666 AclCheckTest.testProtocols: Missing method docstring[missing-docstring] -C0103: 678 AclCheckTest.testVerbatimTerm: Invalid method name "testVerbatimTerm"[invalid-name] -C0103: 690 AclCheckTest.testCommentReflowing: Invalid method name "testCommentReflowing"[invalid-name] -C0103: 701 AclCheckTest.testLongTermName: Invalid method name "testLongTermName"[invalid-name] -C0103: 706 AclCheckTest.testLongTermAbbreviation: Invalid method name "testLongTermAbbreviation"[invalid-name] -C0103: 713 AclCheckTest.testLongTermTruncation: Invalid method name "testLongTermTruncation"[invalid-name] -C0103: 722 AclCheckTest.testFragmentOptions: Invalid method name "testFragmentOptions"[invalid-name] -C0103: 733 AclCheckTest.testIcmpMatching: Invalid method name "testIcmpMatching"[invalid-name] -C0111: 733 AclCheckTest.testIcmpMatching: Missing method docstring[missing-docstring] -C0103: 746 AclCheckTest.testConntrackUDP: Invalid method name "testConntrackUDP"[invalid-name] -C0103: 757 AclCheckTest.testConntrackAll: Invalid method name "testConntrackAll"[invalid-name] -C0103: 766 AclCheckTest.testTcpEstablishedNostate: Invalid method name "testTcpEstablishedNostate"[invalid-name] -C0111: 766 AclCheckTest.testTcpEstablishedNostate: Missing method docstring[missing-docstring] -C0103: 779 AclCheckTest.testUdpEstablishedNostate: Invalid method name "testUdpEstablishedNostate"[invalid-name] -C0103: 788 AclCheckTest.testEstablishedNostate: Invalid method name "testEstablishedNostate"[invalid-name] -C0103: 795 AclCheckTest.testUnsupportedFilter: Invalid method name "testUnsupportedFilter"[invalid-name] -C0103: 800 AclCheckTest.testUnknownTermKeyword: Invalid method name "testUnknownTermKeyword"[invalid-name] -C0103: 807 AclCheckTest.testProtocolExceptUnsupported: Invalid method name "testProtocolExceptUnsupported"[invalid-name] -C0103: 812 AclCheckTest.testTermNameConflict: Invalid method name "testTermNameConflict"[invalid-name] -C0103: 818 AclCheckTest.testMultiPort: Invalid method name "testMultiPort"[invalid-name] -C0111: 818 AclCheckTest.testMultiPort: Missing method docstring[missing-docstring] -C0103: 833 AclCheckTest.testMultiPortWithRanges: Invalid method name "testMultiPortWithRanges"[invalid-name] -C0111: 833 AclCheckTest.testMultiPortWithRanges: Missing method docstring[missing-docstring] -C0103: 847 AclCheckTest.testMultiportSwap: Invalid method name "testMultiportSwap"[invalid-name] -C0103: 861 AclCheckTest.testMultiportLargePortCount: Invalid method name "testMultiportLargePortCount"[invalid-name] -C0111: 861 AclCheckTest.testMultiportLargePortCount: Missing method docstring[missing-docstring] -C0103: 874 AclCheckTest.testMultiportDualLargePortCount: Invalid method name "testMultiportDualLargePortCount"[invalid-name] -C0111: 874 AclCheckTest.testMultiportDualLargePortCount: Missing method docstring[missing-docstring] -C0103: 897 AclCheckTest.testGeneratePortBadArguments: Invalid method name "testGeneratePortBadArguments"[invalid-name] -W0212: 901 AclCheckTest.testGeneratePortBadArguments: Access to a protected member _GeneratePortStatement of a client class[protected-access] -C0103: 904 AclCheckTest.testGeneratePortNotImplemented: Invalid method name "testGeneratePortNotImplemented"[invalid-name] -W0212: 908 AclCheckTest.testGeneratePortNotImplemented: Access to a protected member _GeneratePortStatement of a client class[protected-access] -C0103: 911 AclCheckTest.testLogging: Invalid method name "testLogging"[invalid-name] -C0103: 920 AclCheckTest.testSourceInterface: Invalid method name "testSourceInterface"[invalid-name] -C0103: 927 AclCheckTest.testDestinationInterface: Invalid method name "testDestinationInterface"[invalid-name] -C0103: 936 AclCheckTest.testExpired: Invalid method name "testExpired"[invalid-name] -C0103: 945 AclCheckTest.testExpiringTerm: Invalid method name "testExpiringTerm"[invalid-name] -C0103: 955 AclCheckTest.testIPv6Icmp: Invalid method name "testIPv6Icmp"[invalid-name] -C0103: 966 AclCheckTest.testIPv6IcmpOrder: Invalid method name "testIPv6IcmpOrder"[invalid-name] -C0111: 966 AclCheckTest.testIPv6IcmpOrder: Missing method docstring[missing-docstring] -C0103: 980 AclCheckTest.testIcmpv6InetMismatch: Invalid method name "testIcmpv6InetMismatch"[invalid-name] -C0103: 992 AclCheckTest.testIcmpInet6Mismatch: Invalid method name "testIcmpInet6Mismatch"[invalid-name] -C0103:1004 AclCheckTest.testOwner: Invalid method name "testOwner"[invalid-name] -C0103:1012 AclCheckTest.testSetTarget: Invalid method name "testSetTarget"[invalid-name] -C0103:1020 AclCheckTest.testSetCustomTarget: Invalid method name "testSetCustomTarget"[invalid-name] -************* Module tests.lib.junipersrx_test -C0330: 739 : Wrong hanging indentation (remove 4 spaces). - [mock.call('SOME_HOST')] * 2) - | ^[bad-continuation] -C0330: 741 : Wrong hanging indentation (remove 4 spaces). - [mock.call('SMTP', 'tcp')] * 2) - | ^[bad-continuation] -C0330: 757 : Wrong hanging indentation (remove 4 spaces). - [mock.call('SOME_HOST')] * 2) - | ^[bad-continuation] -C0330: 759 : Wrong hanging indentation (remove 4 spaces). - [mock.call('SMTP', 'tcp')] * 2) - | ^[bad-continuation] -C0111: 313 JuniperSRXTest: Missing class docstring[missing-docstring] -C0103: 318 JuniperSRXTest.testHeaderComment: Invalid method name "testHeaderComment"[invalid-name] -C0103: 323 JuniperSRXTest.testHeaderApplyGroups: Invalid method name "testHeaderApplyGroups"[invalid-name] -C0103: 329 JuniperSRXTest.testHeaderApplyGroupsExcept: Invalid method name "testHeaderApplyGroupsExcept"[invalid-name] -C0103: 335 JuniperSRXTest.testLongComment: Invalid method name "testLongComment"[invalid-name] -C0111: 335 JuniperSRXTest.testLongComment: Missing method docstring[missing-docstring] -C0103: 352 JuniperSRXTest.testTermAndFilterName: Invalid method name "testTermAndFilterName"[invalid-name] -C0111: 352 JuniperSRXTest.testTermAndFilterName: Missing method docstring[missing-docstring] -C0103: 364 JuniperSRXTest.testVpnWithoutPolicy: Invalid method name "testVpnWithoutPolicy"[invalid-name] -C0103: 374 JuniperSRXTest.testVpnWithPolicy: Invalid method name "testVpnWithPolicy"[invalid-name] -C0103: 385 JuniperSRXTest.testVpnWithDrop: Invalid method name "testVpnWithDrop"[invalid-name] -C0103: 396 JuniperSRXTest.testDefaultDeny: Invalid method name "testDefaultDeny"[invalid-name] -C0103: 402 JuniperSRXTest.testIcmpTypes: Invalid method name "testIcmpTypes"[invalid-name] -C0103: 412 JuniperSRXTest.testLoggingBoth: Invalid method name "testLoggingBoth"[invalid-name] -C0103: 419 JuniperSRXTest.testOwnerTerm: Invalid method name "testOwnerTerm"[invalid-name] -C0103: 426 JuniperSRXTest.testBadICMP: Invalid method name "testBadICMP"[invalid-name] -C0103: 431 JuniperSRXTest.testICMPProtocolOnly: Invalid method name "testICMPProtocolOnly"[invalid-name] -C0103: 436 JuniperSRXTest.testMultipleProtocolGrouping: Invalid method name "testMultipleProtocolGrouping"[invalid-name] -C0111: 436 JuniperSRXTest.testMultipleProtocolGrouping: Missing method docstring[missing-docstring] -C0103: 450 JuniperSRXTest.testGlobalPolicyHeader: Invalid method name "testGlobalPolicyHeader"[invalid-name] -C0103: 457 JuniperSRXTest.testBadGlobalPolicyHeaderZoneBook: Invalid method name "testBadGlobalPolicyHeaderZoneBook"[invalid-name] -C0103: 463 JuniperSRXTest.testBadGlobalPolicyHeaderNameAll: Invalid method name "testBadGlobalPolicyHeaderNameAll"[invalid-name] -C0103: 469 JuniperSRXTest.testBadHeaderType: Invalid method name "testBadHeaderType"[invalid-name] -C0103: 480 JuniperSRXTest.testBadHeaderMultiAF: Invalid method name "testBadHeaderMultiAF"[invalid-name] -C0111: 480 JuniperSRXTest.testBadHeaderMultiAF: Missing method docstring[missing-docstring] -C0103: 493 JuniperSRXTest.testBadHeaderMultiAB: Invalid method name "testBadHeaderMultiAB"[invalid-name] -C0111: 493 JuniperSRXTest.testBadHeaderMultiAB: Missing method docstring[missing-docstring] -C0103: 507 JuniperSRXTest.testExpiredTerm: Invalid method name "testExpiredTerm"[invalid-name] -C0103: 516 JuniperSRXTest.testExpiringTerm: Invalid method name "testExpiringTerm"[invalid-name] -C0103: 527 JuniperSRXTest.testTimeout: Invalid method name "testTimeout"[invalid-name] -C0103: 532 JuniperSRXTest.testIcmpV6: Invalid method name "testIcmpV6"[invalid-name] -C0103: 537 JuniperSRXTest.testReplaceStatement: Invalid method name "testReplaceStatement"[invalid-name] -C0111: 537 JuniperSRXTest.testReplaceStatement: Missing method docstring[missing-docstring] -C0103: 550 JuniperSRXTest.testAdressBookBothAFs: Invalid method name "testAdressBookBothAFs"[invalid-name] -C0111: 550 JuniperSRXTest.testAdressBookBothAFs: Missing method docstring[missing-docstring] -C0103: 564 JuniperSRXTest.testAdressBookIPv4: Invalid method name "testAdressBookIPv4"[invalid-name] -C0111: 564 JuniperSRXTest.testAdressBookIPv4: Missing method docstring[missing-docstring] -C0103: 578 JuniperSRXTest.testAdressBookIPv6: Invalid method name "testAdressBookIPv6"[invalid-name] -C0111: 578 JuniperSRXTest.testAdressBookIPv6: Missing method docstring[missing-docstring] -C0103: 592 JuniperSRXTest.testAddressBookContainsSmallerPrefix: Invalid method name "testAddressBookContainsSmallerPrefix"[invalid-name] -C0111: 592 JuniperSRXTest.testAddressBookContainsSmallerPrefix: Missing method docstring[missing-docstring] -C0103: 610 JuniperSRXTest.testAddressBookContainsLargerPrefix: Invalid method name "testAddressBookContainsLargerPrefix"[invalid-name] -C0111: 610 JuniperSRXTest.testAddressBookContainsLargerPrefix: Missing method docstring[missing-docstring] -C0103: 628 JuniperSRXTest.testZoneAdressBookBothAFs: Invalid method name "testZoneAdressBookBothAFs"[invalid-name] -C0111: 628 JuniperSRXTest.testZoneAdressBookBothAFs: Missing method docstring[missing-docstring] -C0103: 642 JuniperSRXTest.testZoneAdressBookIPv4: Invalid method name "testZoneAdressBookIPv4"[invalid-name] -C0111: 642 JuniperSRXTest.testZoneAdressBookIPv4: Missing method docstring[missing-docstring] -C0103: 656 JuniperSRXTest.testZoneAdressBookIPv6: Invalid method name "testZoneAdressBookIPv6"[invalid-name] -C0111: 656 JuniperSRXTest.testZoneAdressBookIPv6: Missing method docstring[missing-docstring] -C0103: 688 JuniperSRXTest.testAddressBookOrderingSuccess: Invalid method name "testAddressBookOrderingSuccess"[invalid-name] -C0111: 688 JuniperSRXTest.testAddressBookOrderingSuccess: Missing method docstring[missing-docstring] -W0212: 695 JuniperSRXTest.testAddressBookOrderingSuccess: Access to a protected member _GenerateAddressBook of a client class[protected-access] -C0103: 700 JuniperSRXTest.testAddressBookOrderingAlreadyOrdered: Invalid method name "testAddressBookOrderingAlreadyOrdered"[invalid-name] -C0111: 700 JuniperSRXTest.testAddressBookOrderingAlreadyOrdered: Missing method docstring[missing-docstring] -W0212: 708 JuniperSRXTest.testAddressBookOrderingAlreadyOrdered: Access to a protected member _GenerateAddressBook of a client class[protected-access] -C0103: 725 JuniperSRXTest.testApplicationsOrderingSuccess: Invalid method name "testApplicationsOrderingSuccess"[invalid-name] -C0111: 725 JuniperSRXTest.testApplicationsOrderingSuccess: Missing method docstring[missing-docstring] -W0212: 732 JuniperSRXTest.testApplicationsOrderingSuccess: Access to a protected member _GenerateApplications of a client class[protected-access] -C0103: 743 JuniperSRXTest.testApplicationsOrderingAlreadyOrdered: Invalid method name "testApplicationsOrderingAlreadyOrdered"[invalid-name] -C0111: 743 JuniperSRXTest.testApplicationsOrderingAlreadyOrdered: Missing method docstring[missing-docstring] -W0212: 750 JuniperSRXTest.testApplicationsOrderingAlreadyOrdered: Access to a protected member _GenerateApplications of a client class[protected-access] -C0103: 761 JuniperSRXTest.testDscpWithByte: Invalid method name "testDscpWithByte"[invalid-name] -C0103: 770 JuniperSRXTest.testDscpWithClass: Invalid method name "testDscpWithClass"[invalid-name] -C0111: 770 JuniperSRXTest.testDscpWithClass: Missing method docstring[missing-docstring] -C0103: 782 JuniperSRXTest.testLargeTermSplitting: Invalid method name "testLargeTermSplitting"[invalid-name] -C0111: 782 JuniperSRXTest.testLargeTermSplitting: Missing method docstring[missing-docstring] -C0103: 811 JuniperSRXTest.testLargeTermSplittingV6: Invalid method name "testLargeTermSplittingV6"[invalid-name] -C0111: 811 JuniperSRXTest.testLargeTermSplittingV6: Missing method docstring[missing-docstring] -C0103: 842 JuniperSRXTest.testDuplicateTermsInDifferentZones: Invalid method name "testDuplicateTermsInDifferentZones"[invalid-name] -C0111: 842 JuniperSRXTest.testDuplicateTermsInDifferentZones: Missing method docstring[missing-docstring] -************* Module tests.lib.juniper_test -C0330: 437 : Wrong hanging indentation (remove 4 spaces). - [nacaddr.IPv4('10.0.0.0/8', comment=long_comment)]) - | ^[bad-continuation] -C0330: 681 : Wrong hanging indentation (remove 4 spaces). - nacaddr.IPv4('127.0.0.1'), nacaddr.IPv6('::1/128')] - | ^[bad-continuation] -C0330: 803 : Wrong hanging indentation (remove 4 spaces). - 'Term icmptype-mismatch will not be rendered,' - | ^[bad-continuation] -W1401: 533 : Anomalous backslash in string: '\W'. String constant might be missing an r prefix.[anomalous-backslash-in-string] -W1401: 533 : Anomalous backslash in string: '\W'. String constant might be missing an r prefix.[anomalous-backslash-in-string] -W1401: 535 : Anomalous backslash in string: '\W'. String constant might be missing an r prefix.[anomalous-backslash-in-string] -W1401: 535 : Anomalous backslash in string: '\W'. String constant might be missing an r prefix.[anomalous-backslash-in-string] -W1401: 535 : Anomalous backslash in string: '\W'. String constant might be missing an r prefix.[anomalous-backslash-in-string] -C0111: 372 JuniperTest: Missing class docstring[missing-docstring] -C0103: 377 JuniperTest.testOptions: Invalid method name "testOptions"[invalid-name] -C0111: 377 JuniperTest.testOptions: Missing method docstring[missing-docstring] -C0103: 392 JuniperTest.testTermAndFilterName: Invalid method name "testTermAndFilterName"[invalid-name] -C0111: 392 JuniperTest.testTermAndFilterName: Missing method docstring[missing-docstring] -C0103: 405 JuniperTest.testBadFilterType: Invalid method name "testBadFilterType"[invalid-name] -C0103: 416 JuniperTest.testBridgeFilterType: Invalid method name "testBridgeFilterType"[invalid-name] -C0111: 416 JuniperTest.testBridgeFilterType: Missing method docstring[missing-docstring] -C0103: 429 JuniperTest.testCommentShrinking: Invalid method name "testCommentShrinking"[invalid-name] -C0111: 429 JuniperTest.testCommentShrinking: Missing method docstring[missing-docstring] -C0103: 448 JuniperTest.testDefaultDeny: Invalid method name "testDefaultDeny"[invalid-name] -C0103: 454 JuniperTest.testIcmpType: Invalid method name "testIcmpType"[invalid-name] -C0111: 454 JuniperTest.testIcmpType: Missing method docstring[missing-docstring] -C0103: 467 JuniperTest.testInet6: Invalid method name "testInet6"[invalid-name] -C0111: 467 JuniperTest.testInet6: Missing method docstring[missing-docstring] -C0103: 480 JuniperTest.testNotInterfaceSpecificHeader: Invalid method name "testNotInterfaceSpecificHeader"[invalid-name] -C0111: 480 JuniperTest.testNotInterfaceSpecificHeader: Missing method docstring[missing-docstring] -C0103: 493 JuniperTest.testInterfaceSpecificHeader: Invalid method name "testInterfaceSpecificHeader"[invalid-name] -C0111: 493 JuniperTest.testInterfaceSpecificHeader: Missing method docstring[missing-docstring] -C0103: 505 JuniperTest.testHopLimit: Invalid method name "testHopLimit"[invalid-name] -C0103: 512 JuniperTest.testProtocolExcept: Invalid method name "testProtocolExcept"[invalid-name] -C0103: 518 JuniperTest.testIcmpv6Except: Invalid method name "testIcmpv6Except"[invalid-name] -C0103: 524 JuniperTest.testProtocolCase: Invalid method name "testProtocolCase"[invalid-name] -C0103: 530 JuniperTest.testPrefixList: Invalid method name "testPrefixList"[invalid-name] -C0103: 540 JuniperTest.testEtherType: Invalid method name "testEtherType"[invalid-name] -C0103: 546 JuniperTest.testTrafficType: Invalid method name "testTrafficType"[invalid-name] -C0103: 552 JuniperTest.testVerbatimTerm: Invalid method name "testVerbatimTerm"[invalid-name] -C0103: 561 JuniperTest.testDscpByte: Invalid method name "testDscpByte"[invalid-name] -C0103: 572 JuniperTest.testDscpClass: Invalid method name "testDscpClass"[invalid-name] -C0111: 572 JuniperTest.testDscpClass: Missing method docstring[missing-docstring] -C0103: 585 JuniperTest.testDscpIPv6: Invalid method name "testDscpIPv6"[invalid-name] -C0111: 585 JuniperTest.testDscpIPv6: Missing method docstring[missing-docstring] -C0103: 599 JuniperTest.testSimplifiedThenStatement: Invalid method name "testSimplifiedThenStatement"[invalid-name] -C0111: 599 JuniperTest.testSimplifiedThenStatement: Missing method docstring[missing-docstring] -C0103: 611 JuniperTest.testSimplifiedThenStatementWithSingleAction: Invalid method name "testSimplifiedThenStatementWithSingleAction"[invalid-name] -C0103: 622 JuniperTest.testSimplifiedThenStatementWithSingleActionDiscardIPv4: Invalid method name "testSimplifiedThenStatementWithSingleActionDiscardIPv4"[invalid-name] -C0111: 622 JuniperTest.testSimplifiedThenStatementWithSingleActionDiscardIPv4: Missing method docstring[missing-docstring] -C0103: 634 JuniperTest.testSimplifiedThenStatementWithSingleActionDiscardIPv6: Invalid method name "testSimplifiedThenStatementWithSingleActionDiscardIPv6"[invalid-name] -C0103: 645 JuniperTest.testSimplifiedThenStatementWithSingleActionRejectIPv6: Invalid method name "testSimplifiedThenStatementWithSingleActionRejectIPv6"[invalid-name] -C0111: 645 JuniperTest.testSimplifiedThenStatementWithSingleActionRejectIPv6: Missing method docstring[missing-docstring] -C0103: 657 JuniperTest.testTcpEstablished: Invalid method name "testTcpEstablished"[invalid-name] -C0103: 668 JuniperTest.testNonTcpWithTcpEstablished: Invalid method name "testNonTcpWithTcpEstablished"[invalid-name] -C0103: 679 JuniperTest.testBridgeFilterInetType: Invalid method name "testBridgeFilterInetType"[invalid-name] -C0103: 690 JuniperTest.testDsmo: Invalid method name "testDsmo"[invalid-name] -C0111: 690 JuniperTest.testDsmo: Missing method docstring[missing-docstring] -C0103: 705 JuniperTest.testDsmoJuniperFriendly: Invalid method name "testDsmoJuniperFriendly"[invalid-name] -C0111: 705 JuniperTest.testDsmoJuniperFriendly: Missing method docstring[missing-docstring] -C0103: 717 JuniperTest.testDsmoExclude: Invalid method name "testDsmoExclude"[invalid-name] -C0111: 717 JuniperTest.testDsmoExclude: Missing method docstring[missing-docstring] -C0103: 735 JuniperTest.testTermTypeIndexKeys: Invalid method name "testTermTypeIndexKeys"[invalid-name] -W0212: 737 JuniperTest.testTermTypeIndexKeys: Access to a protected member _TERM_TYPE of a client class[protected-access] -C0103: 740 JuniperTest.testRoutingInstance: Invalid method name "testRoutingInstance"[invalid-name] -C0103: 746 JuniperTest.testLossPriority: Invalid method name "testLossPriority"[invalid-name] -C0103: 752 JuniperTest.testPrecedence: Invalid method name "testPrecedence"[invalid-name] -C0103: 762 JuniperTest.testMultiplePrecedence: Invalid method name "testMultiplePrecedence"[invalid-name] -C0103: 772 JuniperTest.testArbitraryOptions: Invalid method name "testArbitraryOptions"[invalid-name] -C0103: 783 JuniperTest.testIcmpv6InetMismatch: Invalid method name "testIcmpv6InetMismatch"[invalid-name] -C0103: 795 JuniperTest.testIcmpInet6Mismatch: Invalid method name "testIcmpInet6Mismatch"[invalid-name] -C0103: 808 JuniperTest.testExpiredTerm: Invalid method name "testExpiredTerm"[invalid-name] -C0103: 817 JuniperTest.testExpiringTerm: Invalid method name "testExpiringTerm"[invalid-name] -C0103: 827 JuniperTest.testOwnerTerm: Invalid method name "testOwnerTerm"[invalid-name] -C0103: 835 JuniperTest.testAddressExclude: Invalid method name "testAddressExclude"[invalid-name] -C0111: 835 JuniperTest.testAddressExclude: Missing method docstring[missing-docstring] -C0103: 857 JuniperTest.testMinimizePrefixes: Invalid method name "testMinimizePrefixes"[invalid-name] -C0111: 857 JuniperTest.testMinimizePrefixes: Missing method docstring[missing-docstring] -C0103: 885 JuniperTest.testConfigHelper: Invalid method name "testConfigHelper"[invalid-name] -C0111: 885 JuniperTest.testConfigHelper: Missing method docstring[missing-docstring] -C0103: 911 JuniperTest.testForwardingClass: Invalid method name "testForwardingClass"[invalid-name] -C0103: 918 JuniperTest.testLongPolicer: Invalid method name "testLongPolicer"[invalid-name] -C0103: 932 JuniperTest.testNextIp: Invalid method name "testNextIp"[invalid-name] -C0103: 943 JuniperTest.testNextIpFormat: Invalid method name "testNextIpFormat"[invalid-name] -C0111: 943 JuniperTest.testNextIpFormat: Missing method docstring[missing-docstring] -C0103: 956 JuniperTest.testNextIpv6: Invalid method name "testNextIpv6"[invalid-name] -C0103: 967 JuniperTest.testFailNextIpMultipleIP: Invalid method name "testFailNextIpMultipleIP"[invalid-name] -C0103: 976 JuniperTest.testFailNextIpNetworkIP: Invalid method name "testFailNextIpNetworkIP"[invalid-name] -C0411: 29 : standard import "import logging" comes before "from lib import aclgenerator"[wrong-import-order] -************* Module tests.lib.nacaddr_test -C0103: 36 NacaddrUnitTest.testCollapsing: Invalid method name "testCollapsing"[invalid-name] -C0111: 36 NacaddrUnitTest.testCollapsing: Missing method docstring[missing-docstring] -R0204: 67 NacaddrUnitTest.testCollapsing: Redefinition of ip2 type from lib.nacaddr.IPv4 to lib.nacaddr.IPv6[redefined-variable-type] -R0204: 68 NacaddrUnitTest.testCollapsing: Redefinition of ip3 type from lib.nacaddr.IPv4 to lib.nacaddr.IPv6[redefined-variable-type] -R0204: 66 NacaddrUnitTest.testCollapsing: Redefinition of ip1 type from lib.nacaddr.IPv4 to lib.nacaddr.IPv6[redefined-variable-type] -C0103: 73 NacaddrUnitTest.testNacaddrV4Comment: Invalid method name "testNacaddrV4Comment"[invalid-name] -C0103: 76 NacaddrUnitTest.testNacaddrV6Comment: Invalid method name "testNacaddrV6Comment"[invalid-name] -C0103: 79 NacaddrUnitTest.testSupernetting: Invalid method name "testSupernetting"[invalid-name] -C0111: 79 NacaddrUnitTest.testSupernetting: Missing method docstring[missing-docstring] -C0103: 96 NacaddrUnitTest.testAddressListExclusion: Invalid method name "testAddressListExclusion"[invalid-name] -C0111: 96 NacaddrUnitTest.testAddressListExclusion: Missing method docstring[missing-docstring] -C0103: 119 NacaddrUnitTest.testComplexAddressListExcludesion: Invalid method name "testComplexAddressListExcludesion"[invalid-name] -C0111: 119 NacaddrUnitTest.testComplexAddressListExcludesion: Missing method docstring[missing-docstring] -C0103: 155 NacaddrUnitTest.testAddressListExcludeCaseOne: Invalid method name "testAddressListExcludeCaseOne"[invalid-name] -C0103: 165 NacaddrUnitTest.testAddressListExcludeCaseTwo: Invalid method name "testAddressListExcludeCaseTwo"[invalid-name] -C0103: 178 NacaddrUnitTest.testAddressListExcludeCaseThree: Invalid method name "testAddressListExcludeCaseThree"[invalid-name] -C0103: 191 NacaddrUnitTest.testAddressListExcludeCaseFour: Invalid method name "testAddressListExcludeCaseFour"[invalid-name] -C0103: 199 NacaddrUnitTest.testAddressListExcludeCaseFive: Invalid method name "testAddressListExcludeCaseFive"[invalid-name] -C0103: 207 NacaddrUnitTest.testAddressListExcludeCaseSix: Invalid method name "testAddressListExcludeCaseSix"[invalid-name] -************* Module tests.lib.naming_test -C0103: 61 NamingUnitTest.testCommentedServices: Invalid method name "testCommentedServices"[invalid-name] -C0103: 66 NamingUnitTest.testBadGetRequest: Invalid method name "testBadGetRequest"[invalid-name] -C0103: 72 NamingUnitTest.testGetServiceRecursion: Invalid method name "testGetServiceRecursion"[invalid-name] -C0103: 77 NamingUnitTest.testGetService: Invalid method name "testGetService"[invalid-name] -C0103: 82 NamingUnitTest.testBadProtocol: Invalid method name "testBadProtocol"[invalid-name] -C0103: 86 NamingUnitTest.testGetServiceByProto: Invalid method name "testGetServiceByProto"[invalid-name] -C0103: 90 NamingUnitTest.testGetServiceByProtoWithoutProtocols: Invalid method name "testGetServiceByProtoWithoutProtocols"[invalid-name] -C0103: 94 NamingUnitTest.testNetworkComment: Invalid method name "testNetworkComment"[invalid-name] -C0103: 97 NamingUnitTest.testNestedNetworkComment: Invalid method name "testNestedNetworkComment"[invalid-name] -C0103: 100 NamingUnitTest.testUndefinedAddress: Invalid method name "testUndefinedAddress"[invalid-name] -C0103: 103 NamingUnitTest.testNamespaceCollisionError: Invalid method name "testNamespaceCollisionError"[invalid-name] -C0103: 111 NamingUnitTest.testNetworkAddress: Invalid method name "testNetworkAddress"[invalid-name] -C0103: 115 NamingUnitTest.testInet6Address: Invalid method name "testInet6Address"[invalid-name] -C0103: 120 NamingUnitTest.testMixedAddresses: Invalid method name "testMixedAddresses"[invalid-name] -C0103: 129 NamingUnitTest.testNestedServices: Invalid method name "testNestedServices"[invalid-name] -C0103: 133 NamingUnitTest.testServiceParents: Invalid method name "testServiceParents"[invalid-name] -C0103: 138 NamingUnitTest.testNetParents: Invalid method name "testNetParents"[invalid-name] -C0103: 144 NamingUnitTest.testGetIpParents: Invalid method name "testGetIpParents"[invalid-name] -C0103: 149 NamingUnitTest.testUndefinedTokenNesting: Invalid method name "testUndefinedTokenNesting"[invalid-name] -W0212: 156 NamingUnitTest.testUndefinedTokenNesting: Access to a protected member _CheckUnseen of a client class[protected-access] -W0212: 158 NamingUnitTest.testUndefinedTokenNesting: Access to a protected member _CheckUnseen of a client class[protected-access] -C0103: 160 NamingUnitTest.testParseNetFile: Invalid method name "testParseNetFile"[invalid-name] -W0212: 163 NamingUnitTest.testParseNetFile: Access to a protected member _ParseFile of a client class[protected-access] -C0103: 166 NamingUnitTest.testParseServiceFile: Invalid method name "testParseServiceFile"[invalid-name] -W0212: 169 NamingUnitTest.testParseServiceFile: Access to a protected member _ParseFile of a client class[protected-access] -************* Module tests.lib.nftables_test -C0111: 174 NftablesTest: Missing class docstring[missing-docstring] -C0103: 179 NftablesTest.testBadHeader: Invalid method name "testBadHeader"[invalid-name] -C0103: 198 NftablesTest.testGoodHeader: Invalid method name "testGoodHeader"[invalid-name] -C0111: 198 NftablesTest.testGoodHeader: Missing method docstring[missing-docstring] -C0103: 216 NftablesTest.testExpired: Invalid method name "testExpired"[invalid-name] -C0103: 224 NftablesTest.testExpiring: Invalid method name "testExpiring"[invalid-name] -C0103: 235 NftablesTest.testIcmpv6InetMismatch: Invalid method name "testIcmpv6InetMismatch"[invalid-name] -C0103: 244 NftablesTest.testSingleSourceDestIp: Invalid method name "testSingleSourceDestIp"[invalid-name] -C0103: 253 NftablesTest.testMultipleSourceDestIp: Invalid method name "testMultipleSourceDestIp"[invalid-name] -C0103: 265 NftablesTest.testSingleProtocol: Invalid method name "testSingleProtocol"[invalid-name] -C0103: 270 NftablesTest.testMultiProtocol: Invalid method name "testMultiProtocol"[invalid-name] -C0103: 275 NftablesTest.testSingleDport: Invalid method name "testSingleDport"[invalid-name] -C0103: 282 NftablesTest.testMultiDport: Invalid method name "testMultiDport"[invalid-name] -C0103: 289 NftablesTest.testSingleSport: Invalid method name "testSingleSport"[invalid-name] -C0103: 296 NftablesTest.testMultiSport: Invalid method name "testMultiSport"[invalid-name] -C0103: 303 NftablesTest.testIcmpType: Invalid method name "testIcmpType"[invalid-name] -C0103: 308 NftablesTest.testAction: Invalid method name "testAction"[invalid-name] -C0103: 322 NftablesTest.testCommentOwner: Invalid method name "testCommentOwner"[invalid-name] -C0103: 328 NftablesTest.testVerbatimTerm: Invalid method name "testVerbatimTerm"[invalid-name] -C0103: 336 NftablesTest.testSourceDestExclude: Invalid method name "testSourceDestExclude"[invalid-name] -C0111: 336 NftablesTest.testSourceDestExclude: Missing method docstring[missing-docstring] -C0103: 352 NftablesTest.testSourceDestExcludeFromAllIps: Invalid method name "testSourceDestExcludeFromAllIps"[invalid-name] -C0111: 352 NftablesTest.testSourceDestExcludeFromAllIps: Missing method docstring[missing-docstring] -C0411: 26 : standard import "import logging" comes before "from lib import nacaddr"[wrong-import-order] -************* Module tests.lib.nsxv_functtest -C0301: 33 : Line too long (87/80)[line-too-long] -C0330: 41 : Wrong continued indentation (add 1 space). - help='definitions directory', default='../def') - ^|[bad-continuation] -C0326: 77 : Exactly one space required after assignment - protocol = int(root.find('./rule/services/service/protocol').text) - ^[bad-whitespace] -C0326: 100 : Exactly one space required after assignment - protocol = int(root.find('./rule/services/service/protocol').text) - ^[bad-whitespace] -C0301: 113 : Line too long (84/80)[line-too-long] -C0301: 117 : Line too long (84/80)[line-too-long] -C0103: 39 NsxvFunctionalTest.setUp: Invalid variable name "_parser"[invalid-name] -C0103: 42 NsxvFunctionalTest.setUp: Invalid variable name "FLAGS"[invalid-name] -W0612: 42 NsxvFunctionalTest.setUp: Unused variable 'args'[unused-variable] -C0103: 48 NsxvFunctionalTest.runTest: Invalid method name "runTest"[invalid-name] -C0111: 51 NsxvFunctionalTest.test_nsxv_policy: Missing method docstring[missing-docstring] -C0111: 84 NsxvFunctionalTest.test_nsxv_nosectiondid: Missing method docstring[missing-docstring] -W0612: 108 NsxvFunctionalTest.test_nsxv_nofiltertype.test_nofiltertype: Unused variable 'fw'[unused-variable] -W0612: 116 NsxvFunctionalTest.test_nsxv_incorrectfiltertype.test_incorrectfiltertype: Unused variable 'fw'[unused-variable] -W0612: 125 NsxvFunctionalTest.test_nsxv_optionkywd.test_optionkywd: Unused variable 'output'[unused-variable] -************* Module tests.lib.nsxv_mocktest -C0326: 18 : Exactly one space required around assignment -INET_TERM="""\ - ^[bad-whitespace] -C0326: 27 : Exactly one space required around assignment -INET6_TERM="""\ - ^[bad-whitespace] -C0326: 35 : Exactly one space required before assignment -INET_FILTER= """\ - ^[bad-whitespace] -C0326: 52 : Exactly one space required before assignment -INET6_FILTER= """\ - ^[bad-whitespace] -C0326: 66 : Exactly one space required before assignment -MIXED_FILTER= """\ - ^[bad-whitespace] -C0326: 81 : Exactly one space required before assignment -POLICY= """\ - ^[bad-whitespace] -C0326: 95 : Exactly one space required before assignment -POLICY_NO_SECTION_ID= """\ - ^[bad-whitespace] -C0326: 106 : Exactly one space required before assignment -POLICY_NO_FILTERTYPE= """\ - ^[bad-whitespace] -C0326: 117 : Exactly one space required before assignment -POLICY_INCORRECT_FILTERTYPE= """\ - ^[bad-whitespace] -C0326: 128 : Exactly one space required before assignment -POLICY_OPTION_KYWD= """\ - ^[bad-whitespace] -************* Module tests.lib.nsxv_test -C0330: 197 : Wrong hanging indentation (remove 4 spaces). - [mock.call('NTP', 'udp')] * 2) - | ^[bad-continuation] -C0330: 244 : Wrong hanging indentation (remove 4 spaces). - [mock.call('NTP', 'udp')] * 2) - | ^[bad-continuation] -C0111: 114 TermTest: Missing class docstring[missing-docstring] -C0103: 119 TermTest.testInitForinet: Invalid method name "testInitForinet"[invalid-name] -C0103: 125 TermTest.testInitForinet6: Invalid method name "testInitForinet6"[invalid-name] -C0103: 131 TermTest.testServiceToStr: Invalid method name "testServiceToStr"[invalid-name] -W0212: 139 TermTest.testServiceToStr: Access to a protected member _ServiceToString of a client class[protected-access] -C0103: 144 TermTest.testStrForinet: Invalid method name "testStrForinet"[invalid-name] -C0103: 199 TermTest.testStrForinet6: Invalid method name "testStrForinet6"[invalid-name] -C0103: 224 TermTest.testTranslatePolicy: Invalid method name "testTranslatePolicy"[invalid-name] -C0103: 246 TermTest.testNsxvStr: Invalid method name "testNsxvStr"[invalid-name] -************* Module tests.lib.nsxv_unittest -C0330: 33 : Wrong continued indentation (add 1 space). - help='definitions directory', default='../def') - ^|[bad-continuation] -C0301: 66 : Line too long (148/80)[line-too-long] -C0326: 71 : Exactly one space required around assignment - af=4 - ^[bad-whitespace] -W0311: 73 : Bad indentation. Found 7 spaces, expected 6[bad-indentation] -C0326: 73 : Exactly one space required before assignment - nsxv_term= nsxv.Term(terms[0], af) - ^[bad-whitespace] -W0311: 74 : Bad indentation. Found 7 spaces, expected 6[bad-indentation] -C0326: 82 : Exactly one space required after comma - exp_sourceaddr = ['10.0.0.1','10.0.0.2'] - ^[bad-whitespace] -C0326: 90 : Exactly one space required after comma - exp_destaddr = ['10.0.0.0/8','172.16.0.0/12','192.168.0.0/16'] - ^[bad-whitespace] -C0326: 90 : Exactly one space required after comma - exp_destaddr = ['10.0.0.0/8','172.16.0.0/12','192.168.0.0/16'] - ^[bad-whitespace] -C0326: 98 : Exactly one space required after assignment - protocol = int(root.find('./services/service/protocol').text) - ^[bad-whitespace] -C0326: 110 : Exactly one space required after assignment - notes = root.find('notes').text - ^[bad-whitespace] -C0326: 116 : Exactly one space required around assignment - af=6 - ^[bad-whitespace] -W0311: 119 : Bad indentation. Found 7 spaces, expected 6[bad-indentation] -C0326: 119 : Exactly one space required before assignment - nsxv_term= nsxv.Term(terms[0], filter_type, af) - ^[bad-whitespace] -W0311: 120 : Bad indentation. Found 7 spaces, expected 6[bad-indentation] -C0326: 149 : No space allowed before comma - self.assertEqual(len(terms) , 1) - ^[bad-whitespace] -C0326: 168 : Exactly one space required after comma - exp_ipv4dest = ['8.8.4.4','8.8.8.8'] - ^[bad-whitespace] -C0326: 169 : Exactly one space required after comma - exp_ipv6dest = ['2001:4860:4860::8844','2001:4860:4860::8888'] - ^[bad-whitespace] -C0326: 183 : Exactly one space required after assignment - protocol = int(root.find('./rule/services/service/protocol').text) - ^[bad-whitespace] -C0326: 191 : Exactly one space required after assignment - notes = root.find('./rule/notes').text - ^[bad-whitespace] -C0111: 27 TermTest: Missing class docstring[missing-docstring] -C0103: 31 TermTest.setUp: Invalid variable name "_parser"[invalid-name] -E0602: 31 TermTest.setUp: Undefined variable 'OptionParser'[undefined-variable] -C0103: 34 TermTest.setUp: Invalid variable name "FLAGS"[invalid-name] -W0612: 34 TermTest.setUp: Unused variable 'args'[unused-variable] -C0103: 40 TermTest.runTest: Invalid method name "runTest"[invalid-name] -C0103: 57 TermTest.test_ServiceToStr: Invalid method name "test_ServiceToStr"[invalid-name] -W0212: 65 TermTest.test_ServiceToStr: Access to a protected member _ServiceToString of a client class[protected-access] -W0612: 72 TermTest.test_str_forinet: Unused variable 'header'[unused-variable] -W0612: 118 TermTest.test_str_forinet6: Unused variable 'header'[unused-variable] -C0103: 138 TermTest.test_TranslatePolicy: Invalid method name "test_TranslatePolicy"[invalid-name] -W0612: 145 TermTest.test_TranslatePolicy: Unused variable 'header'[unused-variable] -W0622: 172 TermTest.test_nsxv_str: Redefining built-in 'type'[redefined-builtin] -************* Module tests.lib.packetfilter_test -C0301: 680 : Line too long (81/80)[line-too-long] -C0301: 725 : Line too long (82/80)[line-too-long] -C0111: 295 PacketFilterTest: Missing class docstring[missing-docstring] -C0103: 300 PacketFilterTest.testTcp: Invalid method name "testTcp"[invalid-name] -C0111: 300 PacketFilterTest.testTcp: Missing method docstring[missing-docstring] -C0103: 319 PacketFilterTest.testLog: Invalid method name "testLog"[invalid-name] -C0103: 331 PacketFilterTest.testIcmp: Invalid method name "testIcmp"[invalid-name] -C0103: 342 PacketFilterTest.testIcmpTypes: Invalid method name "testIcmpTypes"[invalid-name] -C0103: 353 PacketFilterTest.testIcmpv6: Invalid method name "testIcmpv6"[invalid-name] -C0103: 364 PacketFilterTest.testBadIcmp: Invalid method name "testBadIcmp"[invalid-name] -C0103: 370 PacketFilterTest.testExpiredTerm: Invalid method name "testExpiredTerm"[invalid-name] -C0103: 380 PacketFilterTest.testExpiredTerm2: Invalid method name "testExpiredTerm2"[invalid-name] -C0103: 390 PacketFilterTest.testExpiringTerm: Invalid method name "testExpiringTerm"[invalid-name] -C0103: 401 PacketFilterTest.testBadAction: Invalid method name "testBadAction"[invalid-name] -C0103: 406 PacketFilterTest.testMultiprotocol: Invalid method name "testMultiprotocol"[invalid-name] -C0103: 417 PacketFilterTest.testNextTerm: Invalid method name "testNextTerm"[invalid-name] -C0103: 427 PacketFilterTest.testNextLogTerm: Invalid method name "testNextLogTerm"[invalid-name] -C0103: 437 PacketFilterTest.testPortRange: Invalid method name "testPortRange"[invalid-name] -C0111: 437 PacketFilterTest.testPortRange: Missing method docstring[missing-docstring] -C0103: 453 PacketFilterTest.testFlags: Invalid method name "testFlags"[invalid-name] -C0103: 464 PacketFilterTest.testInvalidFlags: Invalid method name "testInvalidFlags"[invalid-name] -C0103: 469 PacketFilterTest.testMultilineComment: Invalid method name "testMultilineComment"[invalid-name] -C0103: 478 PacketFilterTest.testStateless: Invalid method name "testStateless"[invalid-name] -C0111: 478 PacketFilterTest.testStateless: Missing method docstring[missing-docstring] -C0103: 497 PacketFilterTest.testInet4: Invalid method name "testInet4"[invalid-name] -C0103: 509 PacketFilterTest.testInet6: Invalid method name "testInet6"[invalid-name] -C0103: 521 PacketFilterTest.testDirectional: Invalid method name "testDirectional"[invalid-name] -C0111: 521 PacketFilterTest.testDirectional: Missing method docstring[missing-docstring] -C0103: 540 PacketFilterTest.testMultipleHeader: Invalid method name "testMultipleHeader"[invalid-name] -C0111: 540 PacketFilterTest.testMultipleHeader: Missing method docstring[missing-docstring] -C0103: 555 PacketFilterTest.testDirectionalStateless: Invalid method name "testDirectionalStateless"[invalid-name] -C0111: 555 PacketFilterTest.testDirectionalStateless: Missing method docstring[missing-docstring] -C0103: 575 PacketFilterTest.testStatelessEstablished: Invalid method name "testStatelessEstablished"[invalid-name] -C0103: 587 PacketFilterTest.testBadFlags: Invalid method name "testBadFlags"[invalid-name] -C0103: 604 PacketFilterTest.testUdpStatelessEstablished: Invalid method name "testUdpStatelessEstablished"[invalid-name] -C0103: 616 PacketFilterTest.testStatefulBlock: Invalid method name "testStatefulBlock"[invalid-name] -C0103: 627 PacketFilterTest.testTcpEstablished: Invalid method name "testTcpEstablished"[invalid-name] -C0103: 639 PacketFilterTest.testTableCreation: Invalid method name "testTableCreation"[invalid-name] -C0111: 639 PacketFilterTest.testTableCreation: Missing method docstring[missing-docstring] -C0103: 673 PacketFilterTest.testTableNameShortened: Invalid method name "testTableNameShortened"[invalid-name] -C0111: 673 PacketFilterTest.testTableNameShortened: Missing method docstring[missing-docstring] -C0103: 696 PacketFilterTest.testTableDuplicateShortNameError: Invalid method name "testTableDuplicateShortNameError"[invalid-name] -C0111: 696 PacketFilterTest.testTableDuplicateShortNameError: Missing method docstring[missing-docstring] -C0103: 718 PacketFilterTest.testTableSameLongNameSameFilter: Invalid method name "testTableSameLongNameSameFilter"[invalid-name] -C0111: 718 PacketFilterTest.testTableSameLongNameSameFilter: Missing method docstring[missing-docstring] -C0103: 751 PacketFilterTest.testTableSameLongNameDiffFilter: Invalid method name "testTableSameLongNameDiffFilter"[invalid-name] -C0111: 751 PacketFilterTest.testTableSameLongNameDiffFilter: Missing method docstring[missing-docstring] -C0103: 785 PacketFilterTest.testTableDiffObjectsShortenedAndNonShortened: Invalid method name "testTableDiffObjectsShortenedAndNonShortened"[invalid-name] -C0111: 785 PacketFilterTest.testTableDiffObjectsShortenedAndNonShortened: Missing method docstring[missing-docstring] -C0103: 810 PacketFilterTest.testTableDuplicateShortNameErrorDiffFilter: Invalid method name "testTableDuplicateShortNameErrorDiffFilter"[invalid-name] -C0111: 810 PacketFilterTest.testTableDuplicateShortNameErrorDiffFilter: Missing method docstring[missing-docstring] -C0103: 835 PacketFilterTest.testTermNameConflict: Invalid method name "testTermNameConflict"[invalid-name] -C0103: 845 PacketFilterTest.testBadProtoError: Invalid method name "testBadProtoError"[invalid-name] -************* Module tests.lib.pcap_test -C0111: 171 PcapFilter: Missing class docstring[missing-docstring] -C0103: 176 PcapFilter.testTcp: Invalid method name "testTcp"[invalid-name] -C0111: 176 PcapFilter.testTcp: Missing method docstring[missing-docstring] -C0103: 190 PcapFilter.testLog: Invalid method name "testLog"[invalid-name] -C0103: 198 PcapFilter.testIcmp: Invalid method name "testIcmp"[invalid-name] -C0103: 206 PcapFilter.testIcmpTypes: Invalid method name "testIcmpTypes"[invalid-name] -C0103: 215 PcapFilter.testIcmpv6: Invalid method name "testIcmpv6"[invalid-name] -C0103: 223 PcapFilter.testBadIcmp: Invalid method name "testBadIcmp"[invalid-name] -C0103: 230 PcapFilter.testExpiredTerm: Invalid method name "testExpiredTerm"[invalid-name] -C0103: 239 PcapFilter.testExpiringTerm: Invalid method name "testExpiringTerm"[invalid-name] -C0103: 249 PcapFilter.testMultiprotocol: Invalid method name "testMultiprotocol"[invalid-name] -C0103: 257 PcapFilter.testNextTerm: Invalid method name "testNextTerm"[invalid-name] -C0103: 264 PcapFilter.testTcpOptions: Invalid method name "testTcpOptions"[invalid-name] -C0103: 272 PcapFilter.testVrrpTerm: Invalid method name "testVrrpTerm"[invalid-name] -C0103: 280 PcapFilter.testMultiHeader: Invalid method name "testMultiHeader"[invalid-name] -C0103: 289 PcapFilter.testDirectional: Invalid method name "testDirectional"[invalid-name] -C0103: 299 PcapFilter.testUnicastIPv6: Invalid method name "testUnicastIPv6"[invalid-name] -C0111: 299 PcapFilter.testUnicastIPv6: Missing method docstring[missing-docstring] -C0103: 311 PcapFilter.testHbh: Invalid method name "testHbh"[invalid-name] -************* Module tests.lib.policy_simple_test -C0111: 1 : Missing module docstring[missing-docstring] -C0111: 21 FieldTest: Missing class docstring[missing-docstring] -C0103: 26 FieldTest.testAppendAppends: Invalid method name "testAppendAppends"[invalid-name] -C0103: 31 FieldTest.testStr: Invalid method name "testStr"[invalid-name] -C0103: 35 FieldTest.testStrIndents: Invalid method name "testStrIndents"[invalid-name] -C0103: 39 FieldTest.testIntegerField: Invalid method name "testIntegerField"[invalid-name] -C0103: 46 FieldTest.testNamingFieldRejectsBad: Invalid method name "testNamingFieldRejectsBad"[invalid-name] -C0103: 55 FieldTest.testNamingFieldAcceptsGood: Invalid method name "testNamingFieldAcceptsGood"[invalid-name] -C0103: 68 FieldTest.testNamingFieldAppendRejectsBad: Invalid method name "testNamingFieldAppendRejectsBad"[invalid-name] -C0103: 78 FieldTest.testNamingFieldAppendAcceptsGood: Invalid method name "testNamingFieldAppendAcceptsGood"[invalid-name] -C0103: 92 FieldTest.testNamingFieldDedupes: Invalid method name "testNamingFieldDedupes"[invalid-name] -C0103: 98 FieldTest.testNamingFieldStr: Invalid method name "testNamingFieldStr"[invalid-name] -C0111: 105 BlockTest: Missing class docstring[missing-docstring] -C0103: 110 BlockTest.testRejectsNonField: Invalid method name "testRejectsNonField"[invalid-name] -C0103: 116 BlockTest.testFieldsWithType: Invalid method name "testFieldsWithType"[invalid-name] -C0111: 116 BlockTest.testFieldsWithType: Missing method docstring[missing-docstring] -C0103: 128 BlockTest.testIter: Invalid method name "testIter"[invalid-name] -C0111: 138 PolicyTest: Missing class docstring[missing-docstring] -C0103: 143 PolicyTest.testAddMember: Invalid method name "testAddMember"[invalid-name] -C0111: 143 PolicyTest.testAddMember: Missing method docstring[missing-docstring] -C0103: 160 PolicyTest.testIter: Invalid method name "testIter"[invalid-name] -C0111: 170 PolicyParserTest: Missing class docstring[missing-docstring] -C0103: 178 PolicyParserTest.testParseCommentLine: Invalid method name "testParseCommentLine"[invalid-name] -C0103: 185 PolicyParserTest.testParseBlankLine: Invalid method name "testParseBlankLine"[invalid-name] -C0103: 192 PolicyParserTest.testParseInclude: Invalid method name "testParseInclude"[invalid-name] -C0103: 199 PolicyParserTest.testParseHeader: Invalid method name "testParseHeader"[invalid-name] -C0103: 207 PolicyParserTest.testParseTerm: Invalid method name "testParseTerm"[invalid-name] -C0103: 215 PolicyParserTest.testParseTermBadField: Invalid method name "testParseTermBadField"[invalid-name] -C0103: 219 PolicyParserTest.testUnfinishedBlock: Invalid method name "testUnfinishedBlock"[invalid-name] -C0411: 18 : standard import "import logging" comes before "from lib import policy_simple"[wrong-import-order] -************* Module tests.lib.policy_test -C0111: 449 PolicyTest: Missing class docstring[missing-docstring] -C0103: 455 PolicyTest.testIncludes: Invalid method name "testIncludes"[invalid-name] -C0103: 476 PolicyTest.testGoodPol: Invalid method name "testGoodPol"[invalid-name] -C0111: 476 PolicyTest.testGoodPol: Missing method docstring[missing-docstring] -C0103: 495 PolicyTest.testBadPol: Invalid method name "testBadPol"[invalid-name] -C0103: 499 PolicyTest.testMissingHeader: Invalid method name "testMissingHeader"[invalid-name] -C0103: 503 PolicyTest.testService: Invalid method name "testService"[invalid-name] -C0111: 503 PolicyTest.testService: Missing method docstring[missing-docstring] -C0103: 518 PolicyTest.testInvalidKeyword: Invalid method name "testInvalidKeyword"[invalid-name] -C0103: 522 PolicyTest.testNumericProtocol: Invalid method name "testNumericProtocol"[invalid-name] -C0103: 529 PolicyTest.testHopLimitSingle: Invalid method name "testHopLimitSingle"[invalid-name] -C0103: 536 PolicyTest.testHopLimitRange: Invalid method name "testHopLimitRange"[invalid-name] -C0103: 543 PolicyTest.testBadPortProtocols: Invalid method name "testBadPortProtocols"[invalid-name] -C0103: 549 PolicyTest.testBadPortProtocols2: Invalid method name "testBadPortProtocols2"[invalid-name] -C0103: 554 PolicyTest.testMinimumTerm: Invalid method name "testMinimumTerm"[invalid-name] -C0103: 562 PolicyTest.testPortCollapsing: Invalid method name "testPortCollapsing"[invalid-name] -C0111: 562 PolicyTest.testPortCollapsing: Missing method docstring[missing-docstring] -C0103: 576 PolicyTest.testPortCollapsing2: Invalid method name "testPortCollapsing2"[invalid-name] -C0103: 589 PolicyTest.testMinimumTerm2: Invalid method name "testMinimumTerm2"[invalid-name] -C0103: 597 PolicyTest.testTermEquality: Invalid method name "testTermEquality"[invalid-name] -C0111: 597 PolicyTest.testTermEquality: Missing method docstring[missing-docstring] -C0103: 637 PolicyTest.testIpAndPortContains: Invalid method name "testIpAndPortContains"[invalid-name] -C0111: 637 PolicyTest.testIpAndPortContains: Missing method docstring[missing-docstring] -C0103: 660 PolicyTest.testEmptyIpContains: Invalid method name "testEmptyIpContains"[invalid-name] -C0111: 660 PolicyTest.testEmptyIpContains: Missing method docstring[missing-docstring] -C0103: 683 PolicyTest.testIpExcludeContains: Invalid method name "testIpExcludeContains"[invalid-name] -C0111: 683 PolicyTest.testIpExcludeContains: Missing method docstring[missing-docstring] -C0103: 705 PolicyTest.testIpDualExcludeContains: Invalid method name "testIpDualExcludeContains"[invalid-name] -C0111: 705 PolicyTest.testIpDualExcludeContains: Missing method docstring[missing-docstring] -C0103: 729 PolicyTest.testOptionsContains: Invalid method name "testOptionsContains"[invalid-name] -C0111: 729 PolicyTest.testOptionsContains: Missing method docstring[missing-docstring] -C0103: 749 PolicyTest.testPrecedenceContains: Invalid method name "testPrecedenceContains"[invalid-name] -C0103: 761 PolicyTest.testProtocolExceptContains: Invalid method name "testProtocolExceptContains"[invalid-name] -C0103: 770 PolicyTest.testGoodDestAddrExcludes: Invalid method name "testGoodDestAddrExcludes"[invalid-name] -C0111: 770 PolicyTest.testGoodDestAddrExcludes: Missing method docstring[missing-docstring] -C0103: 785 PolicyTest.testGoodSrcAddrExcludes: Invalid method name "testGoodSrcAddrExcludes"[invalid-name] -C0111: 785 PolicyTest.testGoodSrcAddrExcludes: Missing method docstring[missing-docstring] -C0103: 800 PolicyTest.testGoodAddrExcludes: Invalid method name "testGoodAddrExcludes"[invalid-name] -C0111: 800 PolicyTest.testGoodAddrExcludes: Missing method docstring[missing-docstring] -C0103: 815 PolicyTest.testGoodAddrExcludesFlatten: Invalid method name "testGoodAddrExcludesFlatten"[invalid-name] -C0111: 815 PolicyTest.testGoodAddrExcludesFlatten: Missing method docstring[missing-docstring] -C0103: 842 PolicyTest.testGoodAddrExcludesFlattenMultiple: Invalid method name "testGoodAddrExcludesFlattenMultiple"[invalid-name] -C0111: 842 PolicyTest.testGoodAddrExcludesFlattenMultiple: Missing method docstring[missing-docstring] -C0103: 862 PolicyTest.testGoodAddrExcludesFlattenAll: Invalid method name "testGoodAddrExcludesFlattenAll"[invalid-name] -C0111: 862 PolicyTest.testGoodAddrExcludesFlattenAll: Missing method docstring[missing-docstring] -C0103: 879 PolicyTest.testLogging: Invalid method name "testLogging"[invalid-name] -C0103: 886 PolicyTest.testBadLogging: Invalid method name "testBadLogging"[invalid-name] -C0103: 891 PolicyTest.testBadAction: Invalid method name "testBadAction"[invalid-name] -C0103: 896 PolicyTest.testMultifilter: Invalid method name "testMultifilter"[invalid-name] -C0103: 901 PolicyTest.testBadMultifilter: Invalid method name "testBadMultifilter"[invalid-name] -C0103: 906 PolicyTest.testICMPTypes: Invalid method name "testICMPTypes"[invalid-name] -C0103: 913 PolicyTest.testBadICMPTypes: Invalid method name "testBadICMPTypes"[invalid-name] -C0103: 918 PolicyTest.testReservedWordTermName: Invalid method name "testReservedWordTermName"[invalid-name] -C0103: 926 PolicyTest.testMultiPortLines: Invalid method name "testMultiPortLines"[invalid-name] -C0103: 939 PolicyTest.testErrorLineNumber: Invalid method name "testErrorLineNumber"[invalid-name] -C0103: 945 PolicyTest.testPrefixList: Invalid method name "testPrefixList"[invalid-name] -C0111: 945 PolicyTest.testPrefixList: Missing method docstring[missing-docstring] -C0103: 962 PolicyTest.testEtherTypes: Invalid method name "testEtherTypes"[invalid-name] -C0103: 971 PolicyTest.testTrafficTypes: Invalid method name "testTrafficTypes"[invalid-name] -C0103: 980 PolicyTest.testBadProtocolEtherTypes: Invalid method name "testBadProtocolEtherTypes"[invalid-name] -C0103: 985 PolicyTest.testVerbatimTerm: Invalid method name "testVerbatimTerm"[invalid-name] -C0103: 993 PolicyTest.testVerbatimMixed: Invalid method name "testVerbatimMixed"[invalid-name] -C0103: 997 PolicyTest.testIntegerFilterName: Invalid method name "testIntegerFilterName"[invalid-name] -C0103:1002 PolicyTest.testPrecedence: Invalid method name "testPrecedence"[invalid-name] -C0103:1009 PolicyTest.testLossPriority: Invalid method name "testLossPriority"[invalid-name] -C0103:1019 PolicyTest.testRoutingInstance: Invalid method name "testRoutingInstance"[invalid-name] -C0103:1029 PolicyTest.testSourceInterface: Invalid method name "testSourceInterface"[invalid-name] -C0103:1040 PolicyTest.testShadingDetection: Invalid method name "testShadingDetection"[invalid-name] -C0111:1040 PolicyTest.testShadingDetection: Missing method docstring[missing-docstring] -C0103:1055 PolicyTest.testVpnConfigWithoutPairPolicy: Invalid method name "testVpnConfigWithoutPairPolicy"[invalid-name] -C0103:1061 PolicyTest.testVpnConfigWithPairPolicy: Invalid method name "testVpnConfigWithPairPolicy"[invalid-name] -C0103:1067 PolicyTest.testForwardingClassPolicy: Invalid method name "testForwardingClassPolicy"[invalid-name] -C0103:1071 PolicyTest.testForwardingClassEqual: Invalid method name "testForwardingClassEqual"[invalid-name] -C0103:1079 PolicyTest.testTagSupportAndNetworkHeaderParsing: Invalid method name "testTagSupportAndNetworkHeaderParsing"[invalid-name] -C0103:1088 PolicyTest.testEq: Invalid method name "testEq"[invalid-name] -C0103:1097 PolicyTest.testNextIP: Invalid method name "testNextIP"[invalid-name] -C0103:1110 PolicyTest.testStr: Invalid method name "testStr"[invalid-name] -C0411: 25 : standard import "import logging" comes before "from lib import nacaddr"[wrong-import-order] -************* Module tests.lib.speedway_test -C0305: 70 : Trailing newlines[trailing-newlines] -C0103: 49 SpeedwayTest.testSpeedwayOutputFormat: Invalid method name "testSpeedwayOutputFormat"[invalid-name] -C0111: 49 SpeedwayTest.testSpeedwayOutputFormat: Missing method docstring[missing-docstring] -C0122: 54 SpeedwayTest.testSpeedwayOutputFormat: Comparison should be result[0] == '*filter'[misplaced-comparison-constant] -C0122: 64 SpeedwayTest.testSpeedwayOutputFormat: Comparison should be result[(len(result)) - (2)] == 'COMMIT'[misplaced-comparison-constant] -************* Module tests.lib.srxlo_test -C0111: 50 SRXloTest: Missing class docstring[missing-docstring] -C0103: 55 SRXloTest.testIcmpv6: Invalid method name "testIcmpv6"[invalid-name] -C0103: 61 SRXloTest.testIcmpv6Type: Invalid method name "testIcmpv6Type"[invalid-name] -************* Module tests.lib.summarizer_test -C0305: 151 : Trailing newlines[trailing-newlines] -C0111: 30 SummarizerTest: Missing class docstring[missing-docstring] -C0103: 43 SummarizerTest.testToDottedQuad: Invalid method name "testToDottedQuad"[invalid-name] -C0111: 43 SummarizerTest.testToDottedQuad: Missing method docstring[missing-docstring] -C0103: 67 SummarizerTest.testInt32ToDottedQuad: Invalid method name "testInt32ToDottedQuad"[invalid-name] -W0212: 68 SummarizerTest.testInt32ToDottedQuad: Access to a protected member _Int32ToDottedQuad of a client class[protected-access] -C0103: 71 SummarizerTest.testSummarizeEmptyList: Invalid method name "testSummarizeEmptyList"[invalid-name] -C0103: 76 SummarizerTest.testSummarizeNoNetworks: Invalid method name "testSummarizeNoNetworks"[invalid-name] -C0103: 86 SummarizerTest.testSummarizeSomeNetworks: Invalid method name "testSummarizeSomeNetworks"[invalid-name] -C0111: 86 SummarizerTest.testSummarizeSomeNetworks: Missing method docstring[missing-docstring] -C0103: 107 SummarizerTest.testSummarizeAllNetworks: Invalid method name "testSummarizeAllNetworks"[invalid-name] -C0103: 117 SummarizerTest.testSummarizeToAllSpace: Invalid method name "testSummarizeToAllSpace"[invalid-name] -C0103: 126 SummarizerTest.testIpaddrToTuple: Invalid method name "testIpaddrToTuple"[invalid-name] -W0212: 128 SummarizerTest.testIpaddrToTuple: Access to a protected member _IpaddrToTuple of a client class[protected-access] -C0103: 130 SummarizerTest.testToPrettyBinaryFormat: Invalid method name "testToPrettyBinaryFormat"[invalid-name] -C0111: 130 SummarizerTest.testToPrettyBinaryFormat: Missing method docstring[missing-docstring] -W0212: 132 SummarizerTest.testToPrettyBinaryFormat: Access to a protected member _ToPrettyBinaryFormat of a client class[protected-access] -W0212: 135 SummarizerTest.testToPrettyBinaryFormat: Access to a protected member _ToPrettyBinaryFormat of a client class[protected-access] -W0212: 138 SummarizerTest.testToPrettyBinaryFormat: Access to a protected member _ToPrettyBinaryFormat of a client class[protected-access] -W0212: 142 SummarizerTest.testToPrettyBinaryFormat: Access to a protected member _ToPrettyBinaryFormat of a client class[protected-access] -C0411: 27 : standard import "import logging" comes before "from lib import summarizer"[wrong-import-order] -************* Module tests.lib.windows_advfirewall_test -C0111: 156 WindowsAdvFirewallTest: Missing class docstring[missing-docstring] -C0103: 168 WindowsAdvFirewallTest.testTcp: Invalid method name "testTcp"[invalid-name] -C0111: 168 WindowsAdvFirewallTest.testTcp: Missing method docstring[missing-docstring] -C0103: 184 WindowsAdvFirewallTest.testIcmp: Invalid method name "testIcmp"[invalid-name] -C0103: 194 WindowsAdvFirewallTest.testIcmpTypes: Invalid method name "testIcmpTypes"[invalid-name] -C0103: 208 WindowsAdvFirewallTest.testBadIcmp: Invalid method name "testBadIcmp"[invalid-name] -C0103: 215 WindowsAdvFirewallTest.testExpiredTerm: Invalid method name "testExpiredTerm"[invalid-name] -C0103: 225 WindowsAdvFirewallTest.testExpiringTerm: Invalid method name "testExpiringTerm"[invalid-name] -C0103: 236 WindowsAdvFirewallTest.testMultiprotocol: Invalid method name "testMultiprotocol"[invalid-name] -C0103: 250 WindowsAdvFirewallTest.testDirectionIn: Invalid method name "testDirectionIn"[invalid-name] -C0111: 250 WindowsAdvFirewallTest.testDirectionIn: Missing method docstring[missing-docstring] -************* Module tests.lib.windows_ipsec_test -C0111: 84 WindowsIPSecTest: Missing class docstring[missing-docstring] -C0111: 97 WindowsIPSecTest.testPolicy: Missing method docstring[missing-docstring] -C0111: 112 WindowsIPSecTest.testTcp: Missing method docstring[missing-docstring]