a5363352d6a191e307304754de213012a9f2c2a1
[sfa.git] / sfatables / runtime.py
1 #!/usr/bin/python
2
3 import sys
4 import os
5 import pdb
6 import libxml2
7
8 from optparse import OptionParser
9 from sfatables import commands
10 from sfatables.globals import *
11 from sfatables.commands.List import *
12 from sfatables.xmlrule import *
13
14 class SFATablesRules:
15     def __init__(self, chain_name):
16         self.active_context = {}
17         self.contexts = None # placeholder for rspec_manger
18         self.sorted_rule_list = []
19         self.final_processor = '__sfatables_wrap_up__.xsl'
20         chain_dir_path = os.path.join(sfatables_config,chain_name)
21         rule_list = List().get_rule_list(chain_dir_path)
22         for rule_number in rule_list:
23             self.sorted_rule_list = self.sorted_rule_list + [XMLRule(chain_name, rule_number)]
24         return
25
26     def wrap_up(self, doc):
27         filepath = os.path.join(sfatables_config, 'processors', self.final_processor)
28
29         if not os.path.exists(filepath):
30             raise Exception('Could not find final rule filter')
31
32         styledoc = libxml2.parseFile(filepath)
33         style = libxslt.parseStylesheetDoc(styledoc)
34         result = style.applyStylesheet(doc, None)
35         stylesheet_result = style.saveResultToString(result)
36         style.freeStylesheet()
37         doc.freeDoc()
38         result.freeDoc()
39
40         return stylesheet_result
41
42     def set_context(self, request_context):
43         self.active_context = request_context
44         return
45
46     def create_xml_node(self, name, context_dict):
47         node = libxml2.newNode(name)
48         for k in context_dict.keys():
49             if (type(context_dict[k])==dict):
50                 childNode = self.create_xml_node(k, context_dict[k])
51                 node.addChild(childNode)
52             else:
53                 childNode = libxml2.newNode(k)
54                 childNode.addContent(context_dict[k])
55                 node.addChild(childNode)
56         return node
57                 
58     def add_request_context_to_rspec(self, doc):
59         p = doc.xpathNewContext()
60         context = p.xpathEval("//RSpec")
61         if (not context):
62             raise Exception('Request is not an rspec')
63         else:
64             # Add the request context
65             requestNode = self.create_xml_node('request-context',self.active_context)
66             context[0].addChild(requestNode)
67         p.xpathFreeContext()
68         return doc
69
70     
71     def apply(self, rspec):
72         if (self.sorted_rule_list):
73             doc = libxml2.parseDoc(rspec)
74             doc = self.add_request_context_to_rspec(doc)
75
76             intermediate_rspec = doc
77
78             for rule in self.sorted_rule_list:
79                 (matched,intermediate_rspec) = rule.apply_interpreted(intermediate_rspec)
80                 if (rule.terminal and matched):
81                     break
82
83             final_rspec = self.wrap_up(intermediate_rspec) 
84         else:
85             final_rspec = rspec
86
87         return final_rspec
88
89     def print_rules(self):
90         for rule in self.sorted_rule_list:
91             print rule.processors
92
93 def main():
94     incoming = SFATablesRules('INCOMING')
95     incoming.set_context({'sfa':{'user':{'hrn':'plc.princeton.sapanb'}}})
96
97     outgoing = SFATablesRules('OUTGOING')
98     print "%d rules loaded for INCOMING chain"%len(incoming.sorted_rule_list)
99     incoming.print_rules()
100
101     print "%d rules loaded for OUTGOING chain"%len(outgoing.sorted_rule_list)
102     outgoing.print_rules()
103
104     rspec = open(sys.argv[1]).read()
105     newrspec = incoming.apply(rspec)
106     print newrspec
107     return
108
109 if __name__=="__main__":
110     main()