diff --git a/doc/source/command-objects/volume-type.rst b/doc/source/command-objects/volume-type.rst index dfc169cd1..e2a277b04 100644 --- a/doc/source/command-objects/volume-type.rst +++ b/doc/source/command-objects/volume-type.rst @@ -16,6 +16,8 @@ Create new volume type [--description ] [--public | --private] [--property [...] ] + [--project ] + [--project-domain ] .. option:: --description @@ -40,6 +42,20 @@ Create new volume type Set a property on this volume type (repeat option to set multiple properties) +.. option:: --project + + Allow to access private type (name or ID) + (Must be used with :option:`--private` option) + + *Volume version 2 only* + +.. option:: --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: .. describe:: diff --git a/openstackclient/tests/volume/v2/test_type.py b/openstackclient/tests/volume/v2/test_type.py index 174f33f2f..a7db2e49e 100644 --- a/openstackclient/tests/volume/v2/test_type.py +++ b/openstackclient/tests/volume/v2/test_type.py @@ -14,6 +14,7 @@ import copy +from osc_lib import exceptions from osc_lib import utils from openstackclient.tests import fakes @@ -41,6 +42,7 @@ class TestType(volume_fakes.TestVolume): class TestTypeCreate(TestType): + project = identity_fakes.FakeProject.create_one_project() columns = ( 'description', 'id', @@ -58,6 +60,7 @@ class TestTypeCreate(TestType): ) self.types_mock.create.return_value = self.new_volume_type + self.projects_mock.get.return_value = self.project # Get the command object to test self.cmd = volume_type.CreateVolumeType(self.app, None) @@ -89,12 +92,14 @@ class TestTypeCreate(TestType): arglist = [ "--description", self.new_volume_type.description, "--private", + "--project", self.project.id, self.new_volume_type.name, ] verifylist = [ ("description", self.new_volume_type.description), ("public", False), ("private", True), + ("project", self.project.id), ("name", self.new_volume_type.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -109,6 +114,21 @@ class TestTypeCreate(TestType): self.assertEqual(self.columns, columns) 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): diff --git a/openstackclient/volume/v2/volume_type.py b/openstackclient/volume/v2/volume_type.py index 87f4c5472..a1cd8bb5a 100644 --- a/openstackclient/volume/v2/volume_type.py +++ b/openstackclient/volume/v2/volume_type.py @@ -66,12 +66,23 @@ class CreateVolumeType(command.ShowOne): help=_('Set a property on this volume type ' '(repeat option to set multiple properties)'), ) + parser.add_argument( + '--project', + metavar='', + help=_("Allow to access private type (name or ID) " + "(Must be used with --private option)"), + ) + identity_common.add_project_domain_option_to_parser(parser) return parser def take_action(self, parsed_args): - + identity_client = self.app.client_manager.identity 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 = {} if parsed_args.public: kwargs['is_public'] = True @@ -84,6 +95,20 @@ class CreateVolumeType(command.ShowOne): **kwargs ) 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: result = volume_type.set_keys(parsed_args.property) volume_type._info.update({'properties': utils.format_dict(result)}) diff --git a/releasenotes/notes/bug-1602169-2750c9a6896d2825.yaml b/releasenotes/notes/bug-1602169-2750c9a6896d2825.yaml new file mode 100644 index 000000000..1ccd68fda --- /dev/null +++ b/releasenotes/notes/bug-1602169-2750c9a6896d2825.yaml @@ -0,0 +1,5 @@ +--- +features: + - Add ``--project`` and ``--project-domain`` options to ``volume type create`` + command. + [Bug `1602169 `_]