#!/usr/bin/python # # Copyright 2015 NORDUnet A/S 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. # """HTML generator for capirca.""" __author__ = 'lundberg@nordu.net (Johan Lundberg)' import datetime import logging from lib import aclgenerator class Term(aclgenerator.Term): """Used to create an individual term. The __str__ method must be implemented. Args: term policy.Term object """ _ACTIONS = {'accept': 'allow', 'deny': 'discard', 'reject': 'say go away to', 'next': 'pass it onto the next term', 'reject-with-tcp-rst': 'reset' } def __init__ (self, term, term_type): self.term = term self.term_type = term_type def __str__(self): # Verify platform specific terms. Skip whole term if platform does not # match. if self.term.platform: if 'html' not in self.term.platform: return '' if self.term.platform_exclude: if 'html' in self.term.platform_exclude: return '' ret_str = [] #NAME ret_str.append(' ' * 4 + 'Term: '+self.term.name+'{') #COMMENTS if self.term.comment: ret_str.append(' ') ret_str.append(' ' * 8 + '#COMMENTS') for comment in self.term.comment: for line in comment.split('\n'): ret_str.append(' ' * 8 + '#'+line) #SOURCE ADDRESS source_address = self.term.GetAddressOfVersion( 'source_address', self.AF_MAP.get(self.term_type)) source_address_exclude = self.term.GetAddressOfVersion( 'source_address_exclude', self.AF_MAP.get(self.term_type)) if source_address: ret_str.append(' ') ret_str.append(' ' * 8 + 'Source IP\'s') for saddr in source_address: ret_str.append(' ' * 8 + str(saddr)) #SOURCE ADDRESS EXCLUDE if source_address_exclude: ret_str.append(' ') ret_str.append(' ' * 8 + 'Excluded Source IP\'s') for ex in source_address: ret_str.append(' ' * 8 + str(ex)) #SOURCE PORT if self.term.source_port: ret_str.append(' ') ret_str.append(' ' * 8 + 'Source ports') ret_str.append(' ' * 8 + self._Group(self.term.source_port)) #DESTINATION destination_address = self.term.GetAddressOfVersion( 'destination_address', self.AF_MAP.get(self.term_type)) destination_address_exclude = self.term.GetAddressOfVersion( 'destination_address_exclude', self.AF_MAP.get(self.term_type)) if destination_address: ret_str.append(' ') ret_str.append(' ' * 8 + 'Destination IP\'s') for daddr in destination_address: ret_str.append(' ' * 8 + str(daddr)) #DESINATION ADDRESS EXCLUDE if destination_address_exclude: ret_str.append(' ') ret_str.append(' ' * 8 + 'Excluded Destination IP\'s') for ex in destination_address_exclude: ret_str.append(' ' * 8 + str(ex)) #DESTINATION PORT if self.term.destination_port: ret_str.append(' ') ret_str.append(' ' * 8 + 'Destination Ports') ret_str.append(' ' * 8 + self._Group(self.term.destination_port)) #PROTOCOL if self.term.protocol: ret_str.append(' ') ret_str.append(' ' * 8 + 'Protocol') ret_str.append(' ' * 8 + self._Group(self.term.protocol)) #OPTION if self.term.option: ret_str.append(' ') ret_str.append(' ' * 8 + 'Options') for option in self.term.option: ret_str.append(' ' * 8 + option) #ACTION for action in self.term.action: ret_str.append(' ') ret_str.append(' ' * 8 + 'Action: ' + self._ACTIONS.get(str(action))+' all traffic') return '\n '.join(ret_str) def _Group(self, group): def _FormattedGroup(el): if isinstance(el, str): return el.lower() elif isinstance(el, int): return str(el) elif el[0] == el[1]: return '%d' % el[0] else: return '%d-%d' % (el[0], el[1]) if len(group) > 1: rval = '' for item in group: rval = rval + str(item[0])+' ' else: rval = _FormattedGroup(group[0]) return rval class HTML(aclgenerator.ACLGenerator): """HTML rendering class. This class takes a policy object and renders output into a syntax which is not useable by routers. This class should only be used for visualizing or documenting policies. Args: pol: policy.Policy object Steps to implement this library 1) Import library in aclgen.py 2) Create a 3 letter entry in the table in the render_filters function for the HTML library and set it to False 3) In the for header in policy.headers: use the previous entry to add an if statement to create a deep copy of the policy object 4) Create an if statement that will be used if that specific policy object is present will pass the policy file onto the HTML Class. 5) The returned object can be then printed to a file using the do_output_filter function 6) Create a policy file with a target set to use HTML """ _PLATFORM = 'html' _SUFFIX = '.html' _OPTIONAL_SUPPORTED_KEYWORDS = set(['expiration',]) def _TranslatePolicy(self, pol, exp_info): current_date = datetime.date.today() exp_info_date = current_date + datetime.timedelta(weeks=exp_info) self.html_policies = [] for header, terms in pol.filters: if not self._PLATFORM in header.platforms: continue filter_options = header.FilterOptions('html') filter_name = filter_options[0] if len(filter_options) > 1: interface_specific = filter_options[1] else: interface_specific = 'none' filter_type = 'inet' term_names = set() new_terms = [] for term in terms: if term.name in term_names: raise HTMLFilterError('Duplicate term name') term_names.add(term.name) new_terms.append(Term(term, filter_type)) self.html_policies.append((header, filter_name, filter_type, interface_specific, new_terms)) def __str__(self): target = [] for (header, filter_name, filter_type, interface_specific, terms) in self.html_policies: target.append('Header {') target.append(' ' * 4 + 'Name: %s {' % filter_name) target.append(' ' * 8 + 'Type: %s ' % filter_type) for comment in header.comment: for line in comment.split('\n'): target.append(' ' * 8 + 'Comment: %s'%line) target.append(' ' * 8 + 'Family type: %s'%interface_specific) target.append(' ' * 4 +'}') for term in terms: target.append(str(term)) target.append(' ' * 4 +'}') target.append(' ') target.append('}') return '\n'.join(target) class Error(Exception): pass class HTMLFilterError(Error): pass