diff --git a/NEWS b/NEWS index e2fca71..ab52a03 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,10 @@ - Add new CLI for viewing schemas - openstack congress datasource table schema show Show schema for datasource table. - openstack congress datasource schema show Show schema for datasource. + - Add CLI for creating/deleting policies + - openstack congress policy create + - openstack congress policy delete + 1.0.0 - 2014-09-29 diff --git a/congressclient/osc/v1/policy.py b/congressclient/osc/v1/policy.py index 5917e54..a237778 100644 --- a/congressclient/osc/v1/policy.py +++ b/congressclient/osc/v1/policy.py @@ -105,7 +105,7 @@ class ListPolicyRules(command.Command): results = client.list_policy_rules(parsed_args.policy_name)['results'] for result in results: print("// ID: %s" % str(result['id'])) - if result['comment'] != "None": + if result['comment'] != "None" and result['comment']: print("// %s" % str(result['comment'])) print(result['rule']) print('') @@ -206,7 +206,7 @@ class ListPolicy(lister.Lister): def take_action(self, parsed_args): client = self.app.client_manager.congressclient data = client.list_policy()['results'] - columns = ['id', 'owner_id'] + columns = ['id', 'name', 'owner_id', 'kind', 'description'] formatters = {'Policies': utils.format_list} return (columns, (utils.get_dict_properties(s, columns, @@ -214,6 +214,64 @@ class ListPolicy(lister.Lister): for s in data)) +class CreatePolicy(show.ShowOne): + """Create a policy.""" + + log = logging.getLogger(__name__ + '.CreatePolicy') + + def get_parser(self, prog_name): + parser = super(CreatePolicy, self).get_parser(prog_name) + parser.add_argument( + 'policy_name', + metavar="", + help="Name of the policy") + parser.add_argument( + '--description', + metavar="", + help="Policy description") + parser.add_argument( + '--abbreviation', + metavar="", + help="Policy abbreviation (used in traces)") + parser.add_argument( + '--kind', + metavar="", + choices=['nonrecursive', 'database', 'action', 'materialized'], + help="Kind of policy: " + "{nonrecursive, database, action, materialized}") + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)' % parsed_args) + client = self.app.client_manager.congressclient + body = {'name': parsed_args.policy_name, + 'description': parsed_args.description, + 'abbreviation': parsed_args.abbreviation, + 'kind': parsed_args.kind} + data = client.create_policy(body) + return zip(*sorted(six.iteritems(data))) + + +class DeletePolicy(command.Command): + """Delete a policy.""" + + log = logging.getLogger(__name__ + '.DeletePolicy') + + def get_parser(self, prog_name): + parser = super(DeletePolicy, self).get_parser(prog_name) + parser.add_argument( + 'policy', + metavar="", + help="ID or name of the policy to delete") + return parser + + def take_action(self, parsed_args): + self.log.debug('take_action(%s)' % parsed_args) + client = self.app.client_manager.congressclient + + client.delete_policy(parsed_args.policy) + + class ListPolicyRows(lister.Lister): """List policy rows.""" diff --git a/congressclient/tests/v1/test_policy.py b/congressclient/tests/v1/test_policy.py index 47fd7a9..7cfc620 100644 --- a/congressclient/tests/v1/test_policy.py +++ b/congressclient/tests/v1/test_policy.py @@ -17,6 +17,55 @@ from congressclient.osc.v1 import policy from congressclient.tests import common +class TestCreatePolicy(common.TestCongressBase): + + def test_create_policy(self): + policy_name = 'test1' + policy_id = "e531f2b3-3d97-42c0-b3b5-b7b6ab532018" + response = {"description": "", + "id": policy_id, + "name": policy_name, + "kind": "nonrecursive", + "owner": "system", + "abbreviation": "test1"} + + arglist = [policy_name] + verifylist = [ + ('policy_name', policy_name), + ] + + mocker = mock.Mock(return_value=response) + self.app.client_manager.congressclient.create_policy = mocker + cmd = policy.CreatePolicy(self.app, self.namespace) + parsed_args = self.check_parser(cmd, arglist, verifylist) + result = list(cmd.take_action(parsed_args)) + filtered = [('abbreviation', 'description', 'id', 'kind', 'name', + 'owner'), + (policy_name, '', policy_id, 'nonrecursive', + policy_name, 'system')] + self.assertEqual(filtered, result) + + +class TestDeletePolicy(common.TestCongressBase): + def test_delete_policy(self): + policy_id = 'e531f2b3-3d97-42c0-b3b5-b7b6ab532018' + arglist = [ + policy_id + ] + verifylist = [ + ('policy', policy_id) + ] + mocker = mock.Mock(return_value=None) + self.app.client_manager.congressclient.delete_policy = mocker + cmd = policy.DeletePolicy(self.app, self.namespace) + + parsed_args = self.check_parser(cmd, arglist, verifylist) + result = cmd.take_action(parsed_args) + + mocker.assert_called_with(policy_id) + self.assertEqual(None, result) + + class TestCreatePolicyRule(common.TestCongressBase): def test_create_policy_rule(self): @@ -93,13 +142,17 @@ class TestListPolicyRules(common.TestCongressBase): class TestListPolicy(common.TestCongressBase): def test_list_policy_rules(self): policy_name = 'classification' + policy_id = 'e531f2b3-3d97-42c0-b3b5-b7b6ab532018' arglist = [ ] verifylist = [ ] response = { - "results": [{"id": policy_name, - "owner": "system" + "results": [{"id": policy_id, + "owner_id": "system", + "name": policy_name, + "kind": "nonrecursive", + "description": "my description" }]} lister = mock.Mock(return_value=response) self.app.client_manager.congressclient.list_policy = lister @@ -109,7 +162,8 @@ class TestListPolicy(common.TestCongressBase): result = cmd.take_action(parsed_args) lister.assert_called_with() - self.assertEqual(['id', 'owner_id'], result[0]) + self.assertEqual(['id', 'name', 'owner_id', 'kind', 'description'], + result[0]) class TestListPolicyTables(common.TestCongressBase): diff --git a/congressclient/v1/client.py b/congressclient/v1/client.py index b040cde..ff30ff6 100644 --- a/congressclient/v1/client.py +++ b/congressclient/v1/client.py @@ -36,6 +36,8 @@ class Client(object): """ + policy = '/v1/policies' + policy_path = '/v1/policies/%s' policy_rules = '/v1/policies/%s/rules' policy_rules_path = '/v1/policies/%s/rules/%s' policy_tables = '/v1/policies/%s/tables' @@ -57,6 +59,21 @@ class Client(object): kwargs.setdefault('user_agent', 'python-congressclient') self.httpclient = adapter.LegacyJsonAdapter(**kwargs) + def create_policy(self, body): + resp, body = self.httpclient.post( + self.policy, body=body) + return body + + def delete_policy(self, policy): + resp, body = self.httpclient.delete( + self.policy_path % policy) + return body + + def show_policy(self, policy): + resp, body = self.httpclient.get( + self.policy_path % policy) + return body + def create_policy_rule(self, policy_name, body=None): resp, body = self.httpclient.post( self.policy_rules % policy_name, body=body) diff --git a/setup.cfg b/setup.cfg index 5f60dd9..20e5fc6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -28,6 +28,8 @@ openstack.cli.extension = congressclient = congressclient.osc.osc_plugin openstack.congressclient.v1 = + congress_policy_create = congressclient.osc.v1.policy:CreatePolicy + congress_policy_delete = congressclient.osc.v1.policy:DeletePolicy congress_policy_rule_create = congressclient.osc.v1.policy:CreatePolicyRule congress_policy_rule_delete = congressclient.osc.v1.policy:DeletePolicyRule congress_policy_rule_show = congressclient.osc.v1.policy:ShowPolicyRule