diff --git a/openstackclient/identity/v2_0/project.py b/openstackclient/identity/v2_0/project.py index 2d0acb8fe0..60a52ad4a6 100644 --- a/openstackclient/identity/v2_0/project.py +++ b/openstackclient/identity/v2_0/project.py @@ -22,6 +22,7 @@ from cliff import command from cliff import lister from cliff import show +from openstackclient.common import parseractions from openstackclient.common import utils @@ -53,6 +54,13 @@ class CreateProject(show.ShowOne): action='store_true', help='Disable project', ) + parser.add_argument( + '--property', + metavar='<key=value>', + action=parseractions.KeyValueAction, + help='Property to add for this project ' + '(repeat option to set multiple properties)', + ) return parser def take_action(self, parsed_args): @@ -62,11 +70,15 @@ class CreateProject(show.ShowOne): enabled = True if parsed_args.disable: enabled = False + kwargs = {} + if parsed_args.property: + kwargs = parsed_args.property.copy() project = identity_client.tenants.create( parsed_args.name, description=parsed_args.description, enabled=enabled, + **kwargs ) info = {} @@ -163,6 +175,13 @@ class SetProject(command.Command): action='store_true', help='Disable project', ) + parser.add_argument( + '--property', + metavar='<key=value>', + action=parseractions.KeyValueAction, + help='Property to add for this project ' + '(repeat option to set multiple properties)', + ) return parser def take_action(self, parsed_args): @@ -172,6 +191,7 @@ class SetProject(command.Command): if (not parsed_args.name and not parsed_args.description and not parsed_args.enable + and not parsed_args.property and not parsed_args.disable): return @@ -189,6 +209,8 @@ class SetProject(command.Command): kwargs['enabled'] = True if parsed_args.disable: kwargs['enabled'] = False + if parsed_args.property: + kwargs.update(parsed_args.property) if 'id' in kwargs: del kwargs['id'] if 'name' in kwargs: diff --git a/openstackclient/identity/v3/project.py b/openstackclient/identity/v3/project.py index f245a88898..ebae733df9 100644 --- a/openstackclient/identity/v3/project.py +++ b/openstackclient/identity/v3/project.py @@ -22,6 +22,7 @@ from cliff import command from cliff import lister from cliff import show +from openstackclient.common import parseractions from openstackclient.common import utils @@ -58,6 +59,13 @@ class CreateProject(show.ShowOne): action='store_true', help='Disable project', ) + parser.add_argument( + '--property', + metavar='<key=value>', + action=parseractions.KeyValueAction, + help='Property to add for this project ' + '(repeat option to set multiple properties)', + ) return parser def take_action(self, parsed_args): @@ -75,12 +83,16 @@ class CreateProject(show.ShowOne): enabled = True if parsed_args.disable: enabled = False + kwargs = {} + if parsed_args.property: + kwargs = parsed_args.property.copy() project = identity_client.projects.create( parsed_args.name, domain, description=parsed_args.description, enabled=enabled, + **kwargs ) info = {} @@ -182,6 +194,13 @@ class SetProject(command.Command): action='store_true', help='Disable project', ) + parser.add_argument( + '--property', + metavar='<key=value>', + action=parseractions.KeyValueAction, + help='Property to add for this project ' + '(repeat option to set multiple properties)', + ) return parser def take_action(self, parsed_args): @@ -192,6 +211,7 @@ class SetProject(command.Command): and not parsed_args.description and not parsed_args.domain and not parsed_args.enable + and not parsed_args.property and not parsed_args.disable): return @@ -214,6 +234,8 @@ class SetProject(command.Command): kwargs['enabled'] = True if parsed_args.disable: kwargs['enabled'] = False + if parsed_args.property: + kwargs.update(parsed_args.property) if 'id' in kwargs: del kwargs['id'] if 'domain_id' in kwargs: diff --git a/openstackclient/tests/identity/v2_0/test_project.py b/openstackclient/tests/identity/v2_0/test_project.py index 30f4278bea..d046cd4796 100644 --- a/openstackclient/tests/identity/v2_0/test_project.py +++ b/openstackclient/tests/identity/v2_0/test_project.py @@ -182,6 +182,43 @@ class TestProjectCreate(TestProject): ) self.assertEqual(data, datalist) + def test_project_create_property(self): + arglist = [ + '--property', 'fee=fi', + '--property', 'fo=fum', + identity_fakes.project_name, + ] + verifylist = [ + ('property', {'fee': 'fi', 'fo': 'fum'}), + ('name', identity_fakes.project_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'description': None, + 'enabled': True, + 'fee': 'fi', + 'fo': 'fum', + } + self.projects_mock.create.assert_called_with( + identity_fakes.project_name, + **kwargs + ) + + collist = ('description', 'enabled', 'id', 'name') + self.assertEqual(columns, collist) + datalist = ( + identity_fakes.project_description, + True, + identity_fakes.project_id, + identity_fakes.project_name, + ) + self.assertEqual(data, datalist) + class TestProjectDelete(TestProject): @@ -412,6 +449,34 @@ class TestProjectSet(TestProject): **kwargs ) + def test_project_set_property(self): + arglist = [ + '--property', 'fee=fi', + '--property', 'fo=fum', + identity_fakes.project_name, + ] + verifylist = [ + ('property', {'fee': 'fi', 'fo': 'fum'}), + ('project', identity_fakes.project_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.run(parsed_args) + self.assertEqual(result, 0) + + # Set expected values + kwargs = { + 'description': identity_fakes.project_description, + 'enabled': True, + 'tenant_name': identity_fakes.project_name, + 'fee': 'fi', + 'fo': 'fum', + } + self.projects_mock.update.assert_called_with( + identity_fakes.project_id, + **kwargs + ) + class TestProjectShow(TestProject): diff --git a/openstackclient/tests/identity/v3/test_project.py b/openstackclient/tests/identity/v3/test_project.py index 02cb41bedb..517c73c594 100644 --- a/openstackclient/tests/identity/v3/test_project.py +++ b/openstackclient/tests/identity/v3/test_project.py @@ -245,6 +245,46 @@ class TestProjectCreate(TestProject): ) self.assertEqual(data, datalist) + def test_project_create_property(self): + arglist = [ + '--property', 'fee=fi', + '--property', 'fo=fum', + identity_fakes.project_name, + ] + verifylist = [ + ('property', {'fee': 'fi', 'fo': 'fum'}), + ('name', identity_fakes.project_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # DisplayCommandBase.take_action() returns two tuples + columns, data = self.cmd.take_action(parsed_args) + + # Set expected values + kwargs = { + 'description': None, + 'enabled': True, + 'fee': 'fi', + 'fo': 'fum', + } + # ProjectManager.create(name, domain, description=, enabled=, **kwargs) + self.projects_mock.create.assert_called_with( + identity_fakes.project_name, + None, + **kwargs + ) + + collist = ('description', 'domain_id', 'enabled', 'id', 'name') + self.assertEqual(columns, collist) + datalist = ( + identity_fakes.project_description, + identity_fakes.domain_id, + True, + identity_fakes.project_id, + identity_fakes.project_name, + ) + self.assertEqual(data, datalist) + class TestProjectDelete(TestProject): @@ -488,6 +528,35 @@ class TestProjectSet(TestProject): **kwargs ) + def test_project_set_property(self): + arglist = [ + '--property', 'fee=fi', + '--property', 'fo=fum', + identity_fakes.project_name, + ] + verifylist = [ + ('property', {'fee': 'fi', 'fo': 'fum'}), + ('project', identity_fakes.project_name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.run(parsed_args) + self.assertEqual(result, 0) + + # Set expected values + kwargs = { + 'description': identity_fakes.project_description, + 'domain': identity_fakes.domain_id, + 'enabled': True, + 'name': identity_fakes.project_name, + 'fee': 'fi', + 'fo': 'fum', + } + self.projects_mock.update.assert_called_with( + identity_fakes.project_id, + **kwargs + ) + class TestProjectShow(TestProject):