Add "--project" option to "volume type create" command
Add "--project" and "--project-domain" options to "volume type create" command. We can use these options to add the type access to a given project when we create the volume type. Change-Id: I483a6b61dae137682c3d1f7527531b40e508ba92 Closes-Bug: #1602169
This commit is contained in:
parent
5a21eb2555
commit
e310682235
@ -16,6 +16,8 @@ Create new volume type
|
|||||||
[--description <description>]
|
[--description <description>]
|
||||||
[--public | --private]
|
[--public | --private]
|
||||||
[--property <key=value> [...] ]
|
[--property <key=value> [...] ]
|
||||||
|
[--project <project>]
|
||||||
|
[--project-domain <project-domain>]
|
||||||
<name>
|
<name>
|
||||||
|
|
||||||
.. option:: --description <description>
|
.. option:: --description <description>
|
||||||
@ -40,6 +42,20 @@ Create new volume type
|
|||||||
|
|
||||||
Set a property on this volume type (repeat option to set multiple properties)
|
Set a property on this volume type (repeat option to set multiple properties)
|
||||||
|
|
||||||
|
.. option:: --project <project>
|
||||||
|
|
||||||
|
Allow <project> to access private type (name or ID)
|
||||||
|
(Must be used with :option:`--private` option)
|
||||||
|
|
||||||
|
*Volume version 2 only*
|
||||||
|
|
||||||
|
.. option:: --project-domain <project-domain>
|
||||||
|
|
||||||
|
Domain the project belongs to (name or ID).
|
||||||
|
This can be used in case collisions between project names exist.
|
||||||
|
|
||||||
|
*Volume version 2 only*
|
||||||
|
|
||||||
.. _volume_type_create-name:
|
.. _volume_type_create-name:
|
||||||
.. describe:: <name>
|
.. describe:: <name>
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
from osc_lib import exceptions
|
||||||
from osc_lib import utils
|
from osc_lib import utils
|
||||||
|
|
||||||
from openstackclient.tests import fakes
|
from openstackclient.tests import fakes
|
||||||
@ -41,6 +42,7 @@ class TestType(volume_fakes.TestVolume):
|
|||||||
|
|
||||||
class TestTypeCreate(TestType):
|
class TestTypeCreate(TestType):
|
||||||
|
|
||||||
|
project = identity_fakes.FakeProject.create_one_project()
|
||||||
columns = (
|
columns = (
|
||||||
'description',
|
'description',
|
||||||
'id',
|
'id',
|
||||||
@ -58,6 +60,7 @@ class TestTypeCreate(TestType):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.types_mock.create.return_value = self.new_volume_type
|
self.types_mock.create.return_value = self.new_volume_type
|
||||||
|
self.projects_mock.get.return_value = self.project
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = volume_type.CreateVolumeType(self.app, None)
|
self.cmd = volume_type.CreateVolumeType(self.app, None)
|
||||||
|
|
||||||
@ -89,12 +92,14 @@ class TestTypeCreate(TestType):
|
|||||||
arglist = [
|
arglist = [
|
||||||
"--description", self.new_volume_type.description,
|
"--description", self.new_volume_type.description,
|
||||||
"--private",
|
"--private",
|
||||||
|
"--project", self.project.id,
|
||||||
self.new_volume_type.name,
|
self.new_volume_type.name,
|
||||||
]
|
]
|
||||||
verifylist = [
|
verifylist = [
|
||||||
("description", self.new_volume_type.description),
|
("description", self.new_volume_type.description),
|
||||||
("public", False),
|
("public", False),
|
||||||
("private", True),
|
("private", True),
|
||||||
|
("project", self.project.id),
|
||||||
("name", self.new_volume_type.name),
|
("name", self.new_volume_type.name),
|
||||||
]
|
]
|
||||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
@ -109,6 +114,21 @@ class TestTypeCreate(TestType):
|
|||||||
self.assertEqual(self.columns, columns)
|
self.assertEqual(self.columns, columns)
|
||||||
self.assertEqual(self.data, data)
|
self.assertEqual(self.data, data)
|
||||||
|
|
||||||
|
def test_public_type_create_with_project(self):
|
||||||
|
arglist = [
|
||||||
|
'--project', self.project.id,
|
||||||
|
self.new_volume_type.name,
|
||||||
|
]
|
||||||
|
verifylist = [
|
||||||
|
('project', self.project.id),
|
||||||
|
('name', self.new_volume_type.name),
|
||||||
|
]
|
||||||
|
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||||
|
|
||||||
|
self.assertRaises(exceptions.CommandError,
|
||||||
|
self.cmd.take_action,
|
||||||
|
parsed_args)
|
||||||
|
|
||||||
|
|
||||||
class TestTypeDelete(TestType):
|
class TestTypeDelete(TestType):
|
||||||
|
|
||||||
|
@ -66,12 +66,23 @@ class CreateVolumeType(command.ShowOne):
|
|||||||
help=_('Set a property on this volume type '
|
help=_('Set a property on this volume type '
|
||||||
'(repeat option to set multiple properties)'),
|
'(repeat option to set multiple properties)'),
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--project',
|
||||||
|
metavar='<project>',
|
||||||
|
help=_("Allow <project> to access private type (name or ID) "
|
||||||
|
"(Must be used with --private option)"),
|
||||||
|
)
|
||||||
|
identity_common.add_project_domain_option_to_parser(parser)
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
|
identity_client = self.app.client_manager.identity
|
||||||
volume_client = self.app.client_manager.volume
|
volume_client = self.app.client_manager.volume
|
||||||
|
|
||||||
|
if parsed_args.project and not parsed_args.private:
|
||||||
|
msg = _("--project is only allowed with --private")
|
||||||
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if parsed_args.public:
|
if parsed_args.public:
|
||||||
kwargs['is_public'] = True
|
kwargs['is_public'] = True
|
||||||
@ -84,6 +95,20 @@ class CreateVolumeType(command.ShowOne):
|
|||||||
**kwargs
|
**kwargs
|
||||||
)
|
)
|
||||||
volume_type._info.pop('extra_specs')
|
volume_type._info.pop('extra_specs')
|
||||||
|
|
||||||
|
if parsed_args.project:
|
||||||
|
try:
|
||||||
|
project_id = identity_common.find_project(
|
||||||
|
identity_client,
|
||||||
|
parsed_args.project,
|
||||||
|
parsed_args.project_domain,
|
||||||
|
).id
|
||||||
|
volume_client.volume_type_access.add_project_access(
|
||||||
|
volume_type.id, project_id)
|
||||||
|
except Exception as e:
|
||||||
|
msg = _("Failed to add project %(project)s access to "
|
||||||
|
"type: %(e)s")
|
||||||
|
LOG.error(msg % {'project': parsed_args.project, 'e': e})
|
||||||
if parsed_args.property:
|
if parsed_args.property:
|
||||||
result = volume_type.set_keys(parsed_args.property)
|
result = volume_type.set_keys(parsed_args.property)
|
||||||
volume_type._info.update({'properties': utils.format_dict(result)})
|
volume_type._info.update({'properties': utils.format_dict(result)})
|
||||||
|
5
releasenotes/notes/bug-1602169-2750c9a6896d2825.yaml
Normal file
5
releasenotes/notes/bug-1602169-2750c9a6896d2825.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Add ``--project`` and ``--project-domain`` options to ``volume type create``
|
||||||
|
command.
|
||||||
|
[Bug `1602169 <https://bugs.launchpad.net/bugs/1602169>`_]
|
Loading…
Reference in New Issue
Block a user