Add ability to set key value pairs in projects

Add supporto of extra key value pairs for projects (aka tenants)
* Added option --property key=value to create and set commands
* Support for versions v2 and v3

Change-Id: I84064b8b308579d1b66c83b1ed3d1a37614ec087
Closes-Bug: #1220280
This commit is contained in:
Terry Howe 2014-03-06 12:50:37 -07:00
parent 808fa65210
commit 70e6333e7d
4 changed files with 178 additions and 0 deletions

View File

@ -22,6 +22,7 @@ from cliff import command
from cliff import lister from cliff import lister
from cliff import show from cliff import show
from openstackclient.common import parseractions
from openstackclient.common import utils from openstackclient.common import utils
@ -53,6 +54,13 @@ class CreateProject(show.ShowOne):
action='store_true', action='store_true',
help='Disable project', 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 return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
@ -62,11 +70,15 @@ class CreateProject(show.ShowOne):
enabled = True enabled = True
if parsed_args.disable: if parsed_args.disable:
enabled = False enabled = False
kwargs = {}
if parsed_args.property:
kwargs = parsed_args.property.copy()
project = identity_client.tenants.create( project = identity_client.tenants.create(
parsed_args.name, parsed_args.name,
description=parsed_args.description, description=parsed_args.description,
enabled=enabled, enabled=enabled,
**kwargs
) )
info = {} info = {}
@ -163,6 +175,13 @@ class SetProject(command.Command):
action='store_true', action='store_true',
help='Disable project', 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 return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
@ -172,6 +191,7 @@ class SetProject(command.Command):
if (not parsed_args.name if (not parsed_args.name
and not parsed_args.description and not parsed_args.description
and not parsed_args.enable and not parsed_args.enable
and not parsed_args.property
and not parsed_args.disable): and not parsed_args.disable):
return return
@ -189,6 +209,8 @@ class SetProject(command.Command):
kwargs['enabled'] = True kwargs['enabled'] = True
if parsed_args.disable: if parsed_args.disable:
kwargs['enabled'] = False kwargs['enabled'] = False
if parsed_args.property:
kwargs.update(parsed_args.property)
if 'id' in kwargs: if 'id' in kwargs:
del kwargs['id'] del kwargs['id']
if 'name' in kwargs: if 'name' in kwargs:

View File

@ -22,6 +22,7 @@ from cliff import command
from cliff import lister from cliff import lister
from cliff import show from cliff import show
from openstackclient.common import parseractions
from openstackclient.common import utils from openstackclient.common import utils
@ -58,6 +59,13 @@ class CreateProject(show.ShowOne):
action='store_true', action='store_true',
help='Disable project', 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 return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
@ -75,12 +83,16 @@ class CreateProject(show.ShowOne):
enabled = True enabled = True
if parsed_args.disable: if parsed_args.disable:
enabled = False enabled = False
kwargs = {}
if parsed_args.property:
kwargs = parsed_args.property.copy()
project = identity_client.projects.create( project = identity_client.projects.create(
parsed_args.name, parsed_args.name,
domain, domain,
description=parsed_args.description, description=parsed_args.description,
enabled=enabled, enabled=enabled,
**kwargs
) )
info = {} info = {}
@ -182,6 +194,13 @@ class SetProject(command.Command):
action='store_true', action='store_true',
help='Disable project', 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 return parser
def take_action(self, parsed_args): def take_action(self, parsed_args):
@ -192,6 +211,7 @@ class SetProject(command.Command):
and not parsed_args.description and not parsed_args.description
and not parsed_args.domain and not parsed_args.domain
and not parsed_args.enable and not parsed_args.enable
and not parsed_args.property
and not parsed_args.disable): and not parsed_args.disable):
return return
@ -214,6 +234,8 @@ class SetProject(command.Command):
kwargs['enabled'] = True kwargs['enabled'] = True
if parsed_args.disable: if parsed_args.disable:
kwargs['enabled'] = False kwargs['enabled'] = False
if parsed_args.property:
kwargs.update(parsed_args.property)
if 'id' in kwargs: if 'id' in kwargs:
del kwargs['id'] del kwargs['id']
if 'domain_id' in kwargs: if 'domain_id' in kwargs:

View File

@ -182,6 +182,43 @@ class TestProjectCreate(TestProject):
) )
self.assertEqual(data, datalist) 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): class TestProjectDelete(TestProject):
@ -412,6 +449,34 @@ class TestProjectSet(TestProject):
**kwargs **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): class TestProjectShow(TestProject):

View File

@ -245,6 +245,46 @@ class TestProjectCreate(TestProject):
) )
self.assertEqual(data, datalist) 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): class TestProjectDelete(TestProject):
@ -488,6 +528,35 @@ class TestProjectSet(TestProject):
**kwargs **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): class TestProjectShow(TestProject):