Continuation - adding request and rule contexts to rspecs currently being processed.
[sfa.git] / sfatables / runtime.py
index e2b5787..1aac773 100644 (file)
@@ -13,7 +13,7 @@ from sfatables.xmlrule import *
 
 class SFATablesRules:
     def __init__(self, chain_name):
-        self.active_context = None
+        self.active_context = {}
         self.contexts = None # placeholder for rspec_manger
         self.sorted_rule_list = []
         chain_dir_path = os.path.join(sfatables_config,chain_name)
@@ -27,8 +27,55 @@ class SFATablesRules:
         self.active_context = request_context
         return
 
+    def create_xml_node(self, name, context_dict):
+        node = libxml2.newNode(name)
+        for k in context_dict.keys():
+            if (type(context_dict[k])==dict):
+                childNode = self.create_xml_node(k, context_dict[k])
+                node.addChild(childNode)
+            else:
+                node.addContent(context_dict[k])
+        return node
+                
+    def add_request_context_to_rspec(self, doc):
+        p = doc.xpathNewContext()
+        context = p.xpathEval("//rspec")
+        if (not context):
+            raise Exception('Request is not an rspec')
+        else:
+            # Add the request context
+            requestNode = self.create_xml_node('request-context',self.active_context)
+            context[0].addChild(requestNode)
+        p.xpathFreeContext()
+        return doc
+
+    def add_rule_context_to_rspec(self,arguments, doc):
+        p = doc.xpathNewContext()
+        context = p.xpathEval("//rspec")
+        if (not context):
+            raise Exception('Request is not an rspec')
+        else:
+            # Add the request context
+            ruleNode = libxml2.newNode('rule-context')
+            ac = self.active_context
+            for k in ac:
+                argumentNode = libxml2.newNode('argument')
+                nameNode = libxml2.newNode('name')
+                nameNode.addContent(k)
+                valueNode = libxml2.newNode('value')
+                valueNode.addContent(ac[k])
+                argumentNode.addChild(nameNode)
+                argumentNode.addChild(valueNode)
+                ruleNode.addChild(argumentNode)
+                context[0].addChild(ruleNode)
+        p.xpathFreeContext()
+
+        return doc
+
     def apply(self, rspec):
         doc = libxml2.parseDoc(rspec)
+        doc = self.add_request_context_to_rspec(doc)
+
         intermediate_rspec = doc
 
         for rule in self.sorted_rule_list:
@@ -41,6 +88,7 @@ class SFATablesRules:
 
 def main():
     incoming = SFATablesRules('INCOMING')
+    incoming.set_context({'sfa':{'user':{'hrn':'plc.princeton.sapanb'}}})
 
     outgoing = SFATablesRules('OUTGOING')
     print "%d rules loaded for INCOMING chain"%len(incoming.sorted_rule_list)