Added command for policy engine's simulation functionality

Change-Id: Ic6da21fcbc114383588783c990917f70238e0663
This commit is contained in:
Tim Hinrichs 2014-10-10 09:09:51 -07:00
parent cd65844f5e
commit d46cee8b44
4 changed files with 164 additions and 0 deletions

View File

@ -112,6 +112,63 @@ class ListPolicyRules(command.Command):
return 0
class SimulatePolicy(command.Command):
"""Show the result of simulation."""
log = logging.getLogger(__name__ + '.SimulatePolicy')
def get_parser(self, prog_name):
parser = super(SimulatePolicy, self).get_parser(prog_name)
parser.add_argument(
'policy',
metavar="<policy>",
help="Name of the policy")
parser.add_argument(
'query',
metavar="<query>",
help="String representing query (policy rule or literal)")
parser.add_argument(
'sequence',
metavar="<sequence>",
help="String representing sequence of updates/actions")
parser.add_argument(
'action_policy',
metavar="<action_policy>",
help="Name of the policy with actions",
default=None)
parser.add_argument(
'--delta',
action='store_true',
default=False,
help="Return difference in query caused by update sequence")
parser.add_argument(
'--trace',
action='store_true',
default=False,
help="Include trace describing computation")
return parser
def take_action(self, parsed_args):
self.log.debug('take_action(%s)' % parsed_args)
client = self.app.client_manager.congressclient
args = {}
args['query'] = parsed_args.query
args['sequence'] = parsed_args.sequence
if parsed_args.action_policy is not None:
args['action_policy'] = parsed_args.action_policy
if parsed_args.delta:
args['delta'] = parsed_args.delta
if parsed_args.trace:
args['trace'] = parsed_args.trace
results = client.execute_policy_action(
parsed_args.policy, 'simulate', args)
for result in results['result']:
print(result)
if 'trace' in results:
print (results['trace'])
return 0
class ListPolicyTables(lister.Lister):
"""List policy tables."""

View File

@ -194,3 +194,98 @@ class TestListPolicyRows(common.TestCongressBase):
cmd.take_action(parsed_args)
lister.assert_called_with(policy_name, table_name, True)
class TestSimulatePolicy(common.TestCongressBase):
def test_simulate_policy(self):
policy_name = 'classification'
action_name = 'action'
sequence = 'q(1)'
query = 'error(x)'
arglist = [
policy_name, query, sequence, action_name
]
verifylist = [
('policy', policy_name),
('action_policy', action_name),
('sequence', sequence),
('query', query),
('delta', False)
]
response = {'result': ['error(1)', 'error(2)']}
lister = mock.Mock(return_value=response)
self.app.client_manager.congressclient.execute_policy_action = lister
cmd = policy.SimulatePolicy(self.app, self.namespace)
parsed_args = self.check_parser(cmd, arglist, verifylist)
cmd.take_action(parsed_args)
args = {}
args['action_policy'] = action_name
args['sequence'] = sequence
args['query'] = query
lister.assert_called_with(policy_name, 'simulate', args)
def test_simulate_policy_delta(self):
policy_name = 'classification'
action_name = 'action'
sequence = 'q(1)'
query = 'error(x)'
arglist = [
policy_name, query, sequence, action_name, "--delta"
]
verifylist = [
('policy', policy_name),
('action_policy', action_name),
('sequence', sequence),
('query', query),
('delta', True)
]
response = {'result': ['error(1)', 'error(2)']}
lister = mock.Mock(return_value=response)
self.app.client_manager.congressclient.execute_policy_action = lister
cmd = policy.SimulatePolicy(self.app, self.namespace)
parsed_args = self.check_parser(cmd, arglist, verifylist)
cmd.take_action(parsed_args)
args = {}
args['action_policy'] = action_name
args['sequence'] = sequence
args['query'] = query
args['delta'] = True
lister.assert_called_with(policy_name, 'simulate', args)
def test_simulate_policy_trace(self):
policy_name = 'classification'
action_name = 'action'
sequence = 'q(1)'
query = 'error(x)'
arglist = [
policy_name, query, sequence, action_name, "--trace"
]
verifylist = [
('policy', policy_name),
('action_policy', action_name),
('sequence', sequence),
('query', query),
('trace', True)
]
response = {'result': ['error(1)', 'error(2)'], 'trace': 'Call'}
lister = mock.Mock(return_value=response)
self.app.client_manager.congressclient.execute_policy_action = lister
cmd = policy.SimulatePolicy(self.app, self.namespace)
parsed_args = self.check_parser(cmd, arglist, verifylist)
cmd.take_action(parsed_args)
args = {}
args['action_policy'] = action_name
args['sequence'] = sequence
args['query'] = query
args['trace'] = True
lister.assert_called_with(policy_name, 'simulate', args)

View File

@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import urllib
from keystoneclient import adapter
@ -41,6 +43,7 @@ class Client(object):
policy_rows_trace = '/v1/policies/%s/tables/%s/rows?trace=True'
policy_rules = '/v1/policies/%s/rules'
policies = '/v1/policies'
policy_action = '/v1/policies/%s?%s'
datasources = '/v1/data-sources'
datasource_tables = '/v1/data-sources/%s/tables'
datasource_rows = '/v1/data-sources/%s/tables/%s/rows'
@ -81,6 +84,14 @@ class Client(object):
resp, body = self.httpclient.get(self.policy_tables % (policy_name))
return body
def execute_policy_action(self, policy_name, action, args):
newargs = dict(args) # make a copy; then add action=<action>
newargs['action'] = action
actionurl = urllib.urlencode(newargs)
resp, body = self.httpclient.post(
self.policy_action % (policy_name, actionurl))
return body
def list_datasources(self):
resp, body = self.httpclient.get(self.datasources)
return body

View File

@ -34,6 +34,7 @@ openstack.congressclient.v1 =
congress_policy_list = congressclient.osc.v1.policy:ListPolicy
congress_policy_row_list = congressclient.osc.v1.policy:ListPolicyRows
congress_policy_table_list = congressclient.osc.v1.policy:ListPolicyTables
congress_policy_simulate = congressclient.osc.v1.policy:SimulatePolicy
congress_datasource_list = congressclient.osc.v1.datasource:ListDatasources
congress_datasource_table_list = congressclient.osc.v1.datasource:ListDatasourceTables
congress_datasource_row_list = congressclient.osc.v1.datasource:ListDatasourceRows