Add support for setting volume-type-access
OSC does not support to set volume type access to project. This patch will provide support for adding volume type access to existing project. Closes-Bug:#1554889 Implements: bp cinder-command-support Change-Id: Ie36e202bdde7de36eb263a476eb66699d82f7565
This commit is contained in:
parent
9e7f0cf1a5
commit
be2d2a1b8d
doc/source/command-objects
openstackclient
releasenotes/notes
@ -88,6 +88,8 @@ Set volume type properties
|
||||
[--name <name>]
|
||||
[--description <description>]
|
||||
[--property <key=value> [...] ]
|
||||
[--project <project>]
|
||||
[--project-domain <project-domain>]
|
||||
<volume-type>
|
||||
|
||||
.. option:: --name <name>
|
||||
@ -102,6 +104,17 @@ Set volume type properties
|
||||
|
||||
.. versionadded:: 2
|
||||
|
||||
.. option:: --project <project>
|
||||
|
||||
Set volume type access to project (name or ID) (admin only)
|
||||
|
||||
*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.
|
||||
|
||||
.. option:: --property <key=value>
|
||||
|
||||
Set a property on this volume type (repeat option to set multiple properties)
|
||||
|
@ -243,6 +243,8 @@ class FakeVolumeClient(object):
|
||||
self.backups.resource_class = fakes.FakeResource(None, {})
|
||||
self.volume_types = mock.Mock()
|
||||
self.volume_types.resource_class = fakes.FakeResource(None, {})
|
||||
self.volume_type_access = mock.Mock()
|
||||
self.volume_type_access.resource_class = fakes.FakeResource(None, {})
|
||||
self.restores = mock.Mock()
|
||||
self.restores.resource_class = fakes.FakeResource(None, {})
|
||||
self.qos_specs = mock.Mock()
|
||||
|
@ -15,6 +15,8 @@
|
||||
import copy
|
||||
|
||||
from openstackclient.tests import fakes
|
||||
from openstackclient.tests.identity.v3 import fakes as identity_fakes
|
||||
from openstackclient.tests import utils as tests_utils
|
||||
from openstackclient.tests.volume.v2 import fakes as volume_fakes
|
||||
from openstackclient.volume.v2 import volume_type
|
||||
|
||||
@ -41,6 +43,13 @@ class TestType(volume_fakes.TestVolume):
|
||||
self.types_mock = self.app.client_manager.volume.volume_types
|
||||
self.types_mock.reset_mock()
|
||||
|
||||
self.types_access_mock = (
|
||||
self.app.client_manager.volume.volume_type_access)
|
||||
self.types_access_mock.reset_mock()
|
||||
|
||||
self.projects_mock = self.app.client_manager.identity.projects
|
||||
self.projects_mock.reset_mock()
|
||||
|
||||
|
||||
class TestTypeCreate(TestType):
|
||||
|
||||
@ -211,6 +220,13 @@ class TestTypeSet(TestType):
|
||||
loaded=True,
|
||||
)
|
||||
|
||||
# Return a project
|
||||
self.projects_mock.get.return_value = fakes.FakeResource(
|
||||
None,
|
||||
copy.deepcopy(identity_fakes.PROJECT),
|
||||
loaded=True,
|
||||
)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = volume_type.SetVolumeType(self.app, None)
|
||||
|
||||
@ -286,6 +302,56 @@ class TestTypeSet(TestType):
|
||||
self.assertIn('myprop', result)
|
||||
self.assertEqual('myvalue', result['myprop'])
|
||||
|
||||
def test_type_set_not_called_without_project_argument(self):
|
||||
arglist = [
|
||||
'--project', '',
|
||||
volume_fakes.type_id,
|
||||
]
|
||||
verifylist = [
|
||||
('project', ''),
|
||||
('volume_type', volume_fakes.type_id),
|
||||
]
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.assertIsNone(result)
|
||||
|
||||
self.assertFalse(self.types_access_mock.add_project_access.called)
|
||||
|
||||
def test_type_set_failed_with_missing_volume_type_argument(self):
|
||||
arglist = [
|
||||
'--project', 'identity_fakes.project_id',
|
||||
]
|
||||
verifylist = [
|
||||
('project', 'identity_fakes.project_id'),
|
||||
]
|
||||
|
||||
self.assertRaises(tests_utils.ParserException,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
arglist,
|
||||
verifylist)
|
||||
|
||||
def test_type_set_project_access(self):
|
||||
arglist = [
|
||||
'--project', identity_fakes.project_id,
|
||||
volume_fakes.type_id,
|
||||
]
|
||||
verifylist = [
|
||||
('project', identity_fakes.project_id),
|
||||
('volume_type', volume_fakes.type_id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.take_action(parsed_args)
|
||||
self.assertIsNone(result)
|
||||
|
||||
self.types_access_mock.add_project_access.assert_called_with(
|
||||
volume_fakes.type_id,
|
||||
identity_fakes.project_id,
|
||||
)
|
||||
|
||||
|
||||
class TestTypeShow(TestType):
|
||||
|
||||
|
@ -17,8 +17,10 @@
|
||||
import six
|
||||
|
||||
from openstackclient.common import command
|
||||
from openstackclient.common import exceptions
|
||||
from openstackclient.common import parseractions
|
||||
from openstackclient.common import utils
|
||||
from openstackclient.identity import common as identity_common
|
||||
|
||||
|
||||
class CreateVolumeType(command.ShowOne):
|
||||
@ -156,19 +158,30 @@ class SetVolumeType(command.Command):
|
||||
help='Set a property on this volume type '
|
||||
'(repeat option to set multiple properties)',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--project',
|
||||
metavar='<project>',
|
||||
help='Set volume type access to project (name or ID) (admin only)',
|
||||
)
|
||||
identity_common.add_project_domain_option_to_parser(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
volume_client = self.app.client_manager.volume
|
||||
identity_client = self.app.client_manager.identity
|
||||
|
||||
volume_type = utils.find_resource(
|
||||
volume_client.volume_types, parsed_args.volume_type)
|
||||
|
||||
if (not parsed_args.name
|
||||
and not parsed_args.description
|
||||
and not parsed_args.property):
|
||||
and not parsed_args.property
|
||||
and not parsed_args.project):
|
||||
self.app.log.error("No changes requested\n")
|
||||
return
|
||||
|
||||
result = 0
|
||||
kwargs = {}
|
||||
if parsed_args.name:
|
||||
kwargs['name'] = parsed_args.name
|
||||
@ -176,13 +189,42 @@ class SetVolumeType(command.Command):
|
||||
kwargs['description'] = parsed_args.description
|
||||
|
||||
if kwargs:
|
||||
volume_client.volume_types.update(
|
||||
volume_type.id,
|
||||
**kwargs
|
||||
)
|
||||
try:
|
||||
volume_client.volume_types.update(
|
||||
volume_type.id,
|
||||
**kwargs
|
||||
)
|
||||
except Exception as e:
|
||||
self.app.log.error("Failed to update volume type name or"
|
||||
" description: " + str(e))
|
||||
result += 1
|
||||
|
||||
if parsed_args.property:
|
||||
volume_type.set_keys(parsed_args.property)
|
||||
try:
|
||||
volume_type.set_keys(parsed_args.property)
|
||||
except Exception as e:
|
||||
self.app.log.error("Failed to set volume type property: " +
|
||||
str(e))
|
||||
result += 1
|
||||
|
||||
if parsed_args.project:
|
||||
project_info = None
|
||||
try:
|
||||
project_info = identity_common.find_project(
|
||||
identity_client,
|
||||
parsed_args.project,
|
||||
parsed_args.project_domain)
|
||||
|
||||
volume_client.volume_type_access.add_project_access(
|
||||
volume_type.id, project_info.id)
|
||||
except Exception as e:
|
||||
self.app.log.error("Failed to set volume type access to"
|
||||
" project: " + str(e))
|
||||
result += 1
|
||||
|
||||
if result > 0:
|
||||
raise exceptions.CommandError("Command Failed: One or more of the"
|
||||
" operations failed")
|
||||
|
||||
|
||||
class ShowVolumeType(command.ShowOne):
|
||||
|
@ -0,0 +1,18 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added support for setting volume type access to project.
|
||||
|
||||
By default, volumes types are public.
|
||||
To create a private volume type, user needs to set is_public boolean
|
||||
field to false at volume type creation time.
|
||||
To control access to a private volume type, user needs to add access
|
||||
of a private volume type to project.
|
||||
|
||||
So, this feature enables user to add private volume type access to a
|
||||
project using below command
|
||||
|
||||
``volume type set --project <project> <volume_type>``.
|
||||
|
||||
[Bug 1554889 'https://bugs.launchpad.net/python-openstackclient/+bug/1554889'_]
|
||||
|
Loading…
x
Reference in New Issue
Block a user