CORD-1568: Support sharing policies by letting one policy invoke another
Change-Id: I87fdb80a65d86b61364abd3ec35961668924c8f5
diff --git a/lib/xos-genx/xosgenx/jinja2_extensions/fol2.py b/lib/xos-genx/xosgenx/jinja2_extensions/fol2.py
index ca39b17..f7af1dc 100644
--- a/lib/xos-genx/xosgenx/jinja2_extensions/fol2.py
+++ b/lib/xos-genx/xosgenx/jinja2_extensions/fol2.py
@@ -126,7 +126,7 @@
k = 'term'
v = fol
- if k == 'python':
+ if k in ['python', 'policy'] :
# Tainted, don't optimize
if var:
return {'hoist': []}
@@ -202,8 +202,8 @@
if not tag:
tag = gen_random_string()
- policy_function_name = 'policy_%(policy_name)s_%(random_string)s' % {
- 'policy_name': policy_name, 'random_string': tag}
+ policy_function_name_template = 'policy_%s_' + '%(random_string)s' % {'random_string': tag}
+ policy_function_name = policy_function_name_template % policy_name
self.verdict_next()
function_str = """
def %(fn_name)s(obj, ctx):
@@ -211,7 +211,7 @@
""" % {'fn_name': policy_function_name, 'vvar': self.verdict_variable, 'message': message}
function_ast = self.str_to_ast(function_str)
- policy_code = self.gen_test(fol, self.verdict_variable)
+ policy_code = self.gen_test(policy_function_name_template, fol, self.verdict_variable)
function_ast.body = [policy_code] + function_ast.body
@@ -222,8 +222,9 @@
if not tag:
tag = gen_random_string()
- policy_function_name = 'policy_%(policy_name)s_%(random_string)s' % {
- 'policy_name': policy_name, 'random_string': tag}
+ policy_function_name_template = 'policy_%s_' + '%(random_string)s' % {'random_string': tag}
+ policy_function_name = policy_function_name_template % policy_name
+
self.verdict_next()
function_str = """
def %(fn_name)s(obj, ctx):
@@ -231,18 +232,28 @@
""" % {'fn_name': policy_function_name, 'vvar': self.verdict_variable}
function_ast = self.str_to_ast(function_str)
- policy_code = self.gen_test(fol, self.verdict_variable)
+ policy_code = self.gen_test(policy_function_name_template, fol, self.verdict_variable)
function_ast.body = [policy_code] + function_ast.body
return function_ast
- def gen_test(self, fol, verdict_var, bindings=None):
+ def gen_test(self, fn_template, fol, verdict_var, bindings=None):
if isinstance(fol, str):
return self.str_to_ast('%(verdict_var)s = %(constant)s' % {'verdict_var': verdict_var, 'constant': fol})
(k, v), = fol.items()
+ if k == 'policy':
+ policy_name, object_name = v
+
+ policy_fn = fn_template % policy_name
+ call_str = """
+%(verdict_var)s = %(policy_fn)s(obj.%(object_name)s, ctx)
+ """ % {'verdict_var': self.verdict_variable, 'policy_fn': policy_fn, 'object_name': object_name}
+
+ call_ast = self.str_to_ast(call_str)
+ return call_ast
if k == 'python':
try:
expr_ast = self.str_to_ast(v)
@@ -263,7 +274,7 @@
top_vvar = self.verdict_variable
self.verdict_next()
sub_vvar = self.verdict_variable
- block = self.gen_test(v, sub_vvar)
+ block = self.gen_test(fn_template, v, sub_vvar)
assignment_str = """
%(verdict_var)s = not (%(subvar)s)
""" % {'verdict_var': top_vvar, 'subvar': sub_vvar}
@@ -333,8 +344,8 @@
self.verdict_next()
rvar = self.verdict_variable
- lblock = self.gen_test(lhs, lvar)
- rblock = self.gen_test(rhs, rvar)
+ lblock = self.gen_test(fn_template, lhs, lvar)
+ rblock = self.gen_test(fn_template, rhs, rvar)
invert = ''
if k == '&':
diff --git a/lib/xos-genx/xosgenx/xos2jinja.py b/lib/xos-genx/xosgenx/xos2jinja.py
index edd80ef..efcb995 100644
--- a/lib/xos-genx/xosgenx/xos2jinja.py
+++ b/lib/xos-genx/xosgenx/xos2jinja.py
@@ -7,7 +7,23 @@
import jinja2
import os
import copy
+import pdb
+class MissingPolicyException(Exception):
+ pass
+
+def find_missing_policy_calls(name, policies, policy):
+ if isinstance(policy, dict):
+ (k, lst), = policy.items()
+ if k=='policy':
+ policy_name = lst[0]
+ if policy_name not in policies: raise MissingPolicyException("Policy %s invoked missing policy %s"%(name, policy_name))
+ else:
+ for p in lst:
+ find_missing_policy_calls(name, policies, p)
+ elif isinstance(policy, list):
+ for p in lst:
+ find_missing_policy_calls(name, policies, p)
def dotname_to_fqn(dotname):
b_names = [part.pval for part in dotname]
@@ -121,16 +137,7 @@
pname = obj.name.value.pval
self.policies[pname] = obj.body
-
- return True
-
- def visit_PolicyDefinition(self, obj):
- if self.package:
- pname = '.'.join([self.package, obj.name.value.pval])
- else:
- pname = obj.name.value.pval
-
- self.policies[pname] = obj.body
+ find_missing_policy_calls(pname, self.policies, obj.body)
return True