def _TranslatePolicy(self, pol, exp_info): self.pcap_policies = [] current_date = datetime.datetime.utcnow().date() exp_info_date = current_date + datetime.timedelta(weeks=exp_info) good_afs = ['inet', 'inet6', 'mixed'] good_options = ['in', 'out'] direction = '' for header, terms in pol.filters: filter_type = None if self._PLATFORM not in header.platforms: continue filter_options = header.FilterOptions(self._PLATFORM)[1:] filter_name = header.FilterName(self._PLATFORM) # ensure all options after the filter name are expected for opt in filter_options: if opt not in good_afs + good_options: raise UnsupportedTargetOptionError( '%s %s %s %s' % ('\nUnsupported option found in', self._PLATFORM, 'target definition:', opt)) if 'in' in filter_options: direction = 'in' elif 'out' in filter_options: direction = 'out' # Check for matching af for address_family in good_afs: if address_family in filter_options: # should not specify more than one AF in options if filter_type is not None: raise aclgenerator.UnsupportedFilterError( '%s %s %s %s' % ('\nMay only specify one of', good_afs, 'in filter options:', filter_options)) filter_type = address_family if filter_type is None: filter_type = 'mixed' # add the terms accept_terms = [] deny_terms = [] term_names = set() for term in terms: if term.name in term_names: raise aclgenerator.DuplicateTermError( 'You have a duplicate term: %s' % term.name) 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 not term: continue if term.action[0] == 'accept': accept_terms.append( self._TERM(term, filter_name, filter_type, direction)) elif term.action[0] == 'deny' or term.action[0] == 'reject': deny_terms.append( self._TERM(term, filter_name, filter_type, direction)) self.pcap_policies.append( (header, filter_name, filter_type, accept_terms, deny_terms))
def _TranslatePolicy(self, pol, exp_info): """Translate a policy from objects into strings.""" current_date = datetime.datetime.utcnow().date() exp_info_date = current_date + datetime.timedelta(weeks=exp_info) default_action = None good_default_actions = ['ACCEPT', 'DROP'] good_afs = ['inet', 'inet6'] all_protocols_stateful = True self.verbose = True for header, terms in pol.filters: filter_type = None if self._PLATFORM not in header.platforms: continue self.filter_options = header.FilterOptions(self._PLATFORM)[1:] filter_name = header.FilterName(self._PLATFORM) self._WarnIfCustomTarget(filter_name) # ensure all options after the filter name are expected for opt in self.filter_options: if opt not in good_default_actions + good_afs + self._GOOD_OPTIONS: raise UnsupportedTargetOptionError( '%s %s %s %s' % ('\nUnsupported option found in', self._PLATFORM, 'target definition:', opt)) # disable stateful? if 'nostate' in self.filter_options: all_protocols_stateful = False if 'noverbose' in self.filter_options: self.verbose = False # Check for matching af for address_family in good_afs: if address_family in self.filter_options: # should not specify more than one AF in options if filter_type is not None: raise UnsupportedFilterError( '%s %s %s %s' % ('\nMay only specify one of', good_afs, 'in filter options:', self.filter_options)) filter_type = address_family if filter_type is None: filter_type = 'inet' if self._PLATFORM == 'iptables' and filter_name == 'FORWARD': default_action = 'DROP' # does this policy override the default filter actions? for next_target in header.target: if next_target.platform == self._PLATFORM: if len(next_target.options) > 1: for arg in next_target.options: if arg in good_default_actions: default_action = arg if default_action and default_action not in good_default_actions: raise UnsupportedDefaultActionError( '%s %s %s %s %s' % ('\nOnly', ', '.join(good_default_actions), 'default filter action allowed;', default_action, 'used.')) # add the terms new_terms = [] term_names = set() for term in terms: term.name = self.FixTermLength( term.name, 'abbreviateterms' in self.filter_options, 'truncateterms' in self.filter_options) if term.name in term_names: raise aclgenerator.DuplicateTermError( 'You have a duplicate term: %s' % term.name) term_names.add(term.name) if not term.logging and term.log_limit: raise LimitButNoLogError( 'Term %s: Cannoy use log-limit without logging' % term.name) term = self.FixHighPorts( term, af=filter_type, all_protocols_stateful=all_protocols_stateful) if not term: 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 new_terms.append( self._TERM(term, filter_name, all_protocols_stateful, default_action, filter_type, self.verbose)) self.iptables_policies.append( (header, filter_name, filter_type, default_action, new_terms))
def _TranslatePolicy(self, pol, exp_info): self.arista_traffic_policies = [] _AF_MAP_TXT = {"inet": "ipv4", "inet6": "ipv6"} current_date = datetime.datetime.utcnow().date() exp_info_date = current_date + datetime.timedelta(weeks=exp_info) for header, terms in pol.filters: if self._PLATFORM not in header.platforms: continue filter_options = header.FilterOptions(self._PLATFORM) filter_name = header.FilterName(self._PLATFORM) noverbose = "noverbose" in filter_options[1:] term_names = set() new_terms = [] # list of generated terms policy_field_sets = [] # list of generated field-sets policy_counters = set() # set of the counters in the policy # default to mixed policies filter_type = "mixed" if len(filter_options) > 1: filter_type = filter_options[1] # if the filter_type is mixed, we need to iterate through the # supported address families. treat the incoming policy term # (pol_term) as a template for the term and override the necessary # elements of the term for the inet6 evaluation. # # only make a copy of the pol_term if filter_type = "mixed" ftypes = [] if filter_type == "mixed": ftypes = ["inet", "inet6"] else: ftypes = [filter_type] for pol_term in terms: for ft in ftypes: if filter_type == "mixed": term = copy.deepcopy(pol_term) else: term = pol_term # if the term name is default-* we will render this into the # appropriate default term name to be used in this filter. default_term = re.match(r"^default\-.*", term.name, re.IGNORECASE) # TODO(sulrich): if term names become unique to address # families, this can be removed. if (filter_type == "mixed" and ft == "inet6"): term.name = _AF_MAP_TXT[ft] + '-' + term.name if default_term: term.name = _AF_MAP_TXT[ft] + "-default-all" if term.name in term_names: raise aclgenerator.DuplicateTermError( "multiple terms named: %s" % term.name) term_names.add(term.name) term = self.FixHighPorts(term, af=ft) if not term: 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 # emit warnings for unsupported options / terms if term.option: unsupported_opts = [] for opt in [str(x) for x in term.option]: if opt.startswith("sample") or \ opt.startswith("first-fragment"): unsupported_opts.append(opt) # unsupported options are in use and should be skipped if len(unsupported_opts) > 0: logging.warning( "WARNING: term %s in policy %s uses an " "unsupported option (%s) and will not be " "rendered.", term.name, filter_name, " ".join(unsupported_opts), ) continue has_unsupported_match_criteria = ( term.dscp_except or term.dscp_match or term.ether_type or term.flexible_match_range or term.forwarding_class or term.forwarding_class_except or term.next_ip or term.port or term.traffic_type) if has_unsupported_match_criteria: logging.warning( "WARNING: term %s in policy %s uses an " "unsupported match criteria and will not " "be rendered.", term.name, filter_name, ) continue if (("is-fragment" in term.option or "fragment" in term.option) and filter_type == "inet6"): raise AristaTpFragmentInV6Error( "the term %s uses is-fragment but " "is a v6 policy." % term.name) # this should error out more gracefully in mixed configs if (("is-fragment" in term.option or "fragment" in term.option) and ft == "inet6"): logging.warning( "WARNING: term %s in mixed policy %s uses " "fragment the ipv6 version of the term will not be " "rendered.", term.name, filter_name, ) continue # check for traffic-policy specific feature interactions if (("is-fragment" in term.option or "fragment" in term.option) and (term.source_port or term.destination_port)): logging.warning( "WARNING: term %s uses fragment as well as src/dst " "port matches. traffic-policies currently do not " "support this match combination. the term will not " "be rendered", term.name, ) continue # check for common unsupported actions (e.g.: next) if term.action == ["next"]: logging.warning( "WARNING: term %s uses an unsupported action " "(%s) and will not be rendered", term.name, " ".join(term.action), ) continue # generate the prefix sets when there are inline addres # exclusions in a term. these will be referenced within the # term if term.source_address_exclude: src_addr = term.GetAddressOfVersion( "source_address", self._AF_MAP[ft]) src_addr_ex = term.GetAddressOfVersion( "source_address_exclude", self._AF_MAP[ft]) src_addr, src_addr_ex = self._MinimizePrefixes( src_addr, src_addr_ex) if src_addr_ex: fs = self._GenPrefixFieldset( "src", "%s" % term.name, src_addr, src_addr_ex, _AF_MAP_TXT[ft]) policy_field_sets.append(fs) if term.destination_address_exclude: dst_addr = term.GetAddressOfVersion( "destination_address", self._AF_MAP[ft]) dst_addr_ex = term.GetAddressOfVersion( "destination_address_exclude", self._AF_MAP[ft]) dst_addr, dst_addr_ex = self._MinimizePrefixes( dst_addr, dst_addr_ex) if dst_addr_ex: fs = self._GenPrefixFieldset( "dst", "%s" % term.name, term.destination_address, term.destination_address_exclude, _AF_MAP_TXT[ft]) policy_field_sets.append(fs) # generate the unique list of named counters if term.counter: # we can't have '.' in counter names term.counter = re.sub(r"\.", "-", str(term.counter)) policy_counters.add(term.counter) new_terms.append(self._TERM(term, ft, noverbose)) self.arista_traffic_policies.append( (header, filter_name, filter_type, new_terms, policy_counters, policy_field_sets))
def _TranslatePolicy(self, pol, exp_info): """Translate a policy from objects into strings.""" self.windows_policies = [] current_date = datetime.datetime.utcnow().date() exp_info_date = current_date + datetime.timedelta(weeks=exp_info) default_action = None good_default_actions = ['permit', 'block'] good_options = [] for header, terms in pol.filters: filter_type = None if self._PLATFORM not in header.platforms: continue filter_options = header.FilterOptions(self._PLATFORM)[1:] filter_name = header.FilterName(self._PLATFORM) # ensure all options after the filter name are expected for opt in filter_options: if opt not in good_default_actions + self._GOOD_AFS + good_options: raise aclgenerator.UnsupportedTargetOptionError( '%s %s %s %s' % ('\nUnsupported option found in', self._PLATFORM, 'target definition:', opt)) # Check for matching af for address_family in self._GOOD_AFS: if address_family in filter_options: # should not specify more than one AF in options if filter_type is not None: raise aclgenerator.UnsupportedFilterError( '%s %s %s %s' % ('\nMay only specify one of', self._GOOD_AFS, 'in filter options:', filter_options)) filter_type = address_family if filter_type is None: filter_type = 'inet' # does this policy override the default filter actions? for next_target in header.target: if next_target.platform == self._PLATFORM: if len(next_target.options) > 1: for arg in next_target.options: if arg in good_default_actions: default_action = arg if default_action and default_action not in good_default_actions: raise aclgenerator.UnsupportedTargetOptionError( '%s %s %s %s %s' % ('\nOnly', ', '.join(good_default_actions), 'default filter action allowed;', default_action, 'used.')) # add the terms new_terms = [] term_names = set() for term in terms: if term.name in term_names: raise aclgenerator.DuplicateTermError( 'You have a duplicate term: %s' % term.name) term_names.add(term.name) 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 'established' in term.option or 'tcp-established' in term.option: continue new_terms.append( self._TERM(term, filter_name, default_action, filter_type)) self.windows_policies.append( (header, filter_name, filter_type, default_action, new_terms))