add keystone v3 region object
Co-Authored-By: Steve Martinelli <stevemar@ca.ibm.com> Change-Id: Ia6f607630dbf507681733c3ab3b9b7c55de30f49 Closes-Bug: #1387932
This commit is contained in:
parent
631ed3c802
commit
6edc9b89ed
205
openstackclient/identity/v3/region.py
Normal file
205
openstackclient/identity/v3/region.py
Normal file
@ -0,0 +1,205 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
"""Identity v3 Region action implementations"""
|
||||
|
||||
import logging
|
||||
import six
|
||||
|
||||
from cliff import command
|
||||
from cliff import lister
|
||||
from cliff import show
|
||||
|
||||
from openstackclient.common import utils
|
||||
from openstackclient.i18n import _ # noqa
|
||||
|
||||
|
||||
class CreateRegion(show.ShowOne):
|
||||
"""Create new region"""
|
||||
|
||||
log = logging.getLogger(__name__ + '.CreateRegion')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(CreateRegion, self).get_parser(prog_name)
|
||||
# NOTE(stevemar): The API supports an optional region ID, but that
|
||||
# seems like poor UX, we will only support user-defined IDs.
|
||||
parser.add_argument(
|
||||
'region',
|
||||
metavar='<region>',
|
||||
help=_('New region'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--parent-region',
|
||||
metavar='<parent-region>',
|
||||
help=_('The parent region of new region'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar='<region-description>',
|
||||
help=_('New region description'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--url',
|
||||
metavar='<region-url>',
|
||||
help=_('New region url'),
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug('take_action(%s)', parsed_args)
|
||||
identity_client = self.app.client_manager.identity
|
||||
|
||||
region = identity_client.regions.create(
|
||||
id=parsed_args.region,
|
||||
url=parsed_args.url,
|
||||
parent_region=parsed_args.parent_region,
|
||||
description=parsed_args.description,
|
||||
)
|
||||
|
||||
region._info['region'] = region._info.pop('id')
|
||||
region._info['parent_region'] = region._info.pop('parent_region_id')
|
||||
region._info.pop('links', None)
|
||||
return zip(*sorted(six.iteritems(region._info)))
|
||||
|
||||
|
||||
class DeleteRegion(command.Command):
|
||||
"""Delete region"""
|
||||
|
||||
log = logging.getLogger(__name__ + '.DeleteRegion')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteRegion, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'region',
|
||||
metavar='<region>',
|
||||
help=_('Region to delete'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug('take_action(%s)', parsed_args)
|
||||
identity_client = self.app.client_manager.identity
|
||||
|
||||
identity_client.regions.delete(parsed_args.region)
|
||||
return
|
||||
|
||||
|
||||
class ListRegion(lister.Lister):
|
||||
"""List regions"""
|
||||
|
||||
log = logging.getLogger(__name__ + '.ListRegion')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListRegion, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--parent-region',
|
||||
metavar='<parent-region>',
|
||||
help=_('Filter by parent region'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug('take_action(%s)', parsed_args)
|
||||
identity_client = self.app.client_manager.identity
|
||||
|
||||
kwargs = {}
|
||||
if parsed_args.parent_region:
|
||||
kwargs['parent_region_id'] = parsed_args.parent_region
|
||||
|
||||
columns_headers = ('Region', 'Parent Region', 'Description', 'URL')
|
||||
columns = ('ID', 'Parent Region Id', 'Description', 'URL')
|
||||
|
||||
data = identity_client.regions.list(**kwargs)
|
||||
return (columns_headers,
|
||||
(utils.get_item_properties(
|
||||
s, columns,
|
||||
formatters={},
|
||||
) for s in data))
|
||||
|
||||
|
||||
class SetRegion(command.Command):
|
||||
"""Set region properties"""
|
||||
|
||||
log = logging.getLogger(__name__ + '.SetRegion')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(SetRegion, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'region',
|
||||
metavar='<region>',
|
||||
help=_('Region to change'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--parent-region',
|
||||
metavar='<parent-region>',
|
||||
help=_('New parent region of the region'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
metavar='<region-description>',
|
||||
help=_('New region description'),
|
||||
)
|
||||
parser.add_argument(
|
||||
'--url',
|
||||
metavar='<region-url>',
|
||||
help=_('New region url'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug('take_action(%s)', parsed_args)
|
||||
identity_client = self.app.client_manager.identity
|
||||
|
||||
if (not parsed_args.url
|
||||
and not parsed_args.parent_region
|
||||
and not parsed_args.description):
|
||||
return
|
||||
|
||||
kwargs = {}
|
||||
if parsed_args.url:
|
||||
kwargs['url'] = parsed_args.url
|
||||
if parsed_args.description:
|
||||
kwargs['description'] = parsed_args.description
|
||||
if parsed_args.parent_region:
|
||||
kwargs['parent_region'] = parsed_args.parent_region
|
||||
|
||||
identity_client.regions.update(parsed_args.region, **kwargs)
|
||||
return
|
||||
|
||||
|
||||
class ShowRegion(show.ShowOne):
|
||||
"""Show region"""
|
||||
|
||||
log = logging.getLogger(__name__ + '.ShowRegion')
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowRegion, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'region',
|
||||
metavar='<region>',
|
||||
help=_('Region to display'),
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
self.log.debug('take_action(%s)', parsed_args)
|
||||
identity_client = self.app.client_manager.identity
|
||||
|
||||
region = utils.find_resource(identity_client.regions,
|
||||
parsed_args.region)
|
||||
|
||||
region._info['region'] = region._info.pop('id')
|
||||
region._info['parent_region'] = region._info.pop('parent_region_id')
|
||||
region._info.pop('links', None)
|
||||
return zip(*sorted(six.iteritems(region._info)))
|
@ -122,6 +122,19 @@ PROJECT_2 = {
|
||||
'links': base_url + 'projects/' + project_id,
|
||||
}
|
||||
|
||||
region_id = 'region_one'
|
||||
region_url = 'http://localhost:1111'
|
||||
region_parent_region_id = 'region_two'
|
||||
region_description = 'region one'
|
||||
|
||||
REGION = {
|
||||
'id': region_id,
|
||||
'url': region_url,
|
||||
'description': region_description,
|
||||
'parent_region_id': region_parent_region_id,
|
||||
'links': base_url + 'regions/' + region_id,
|
||||
}
|
||||
|
||||
role_id = 'r1'
|
||||
role_name = 'roller'
|
||||
|
||||
@ -310,6 +323,8 @@ class FakeIdentityv3Client(object):
|
||||
self.oauth1.resource_class = fakes.FakeResource(None, {})
|
||||
self.projects = mock.Mock()
|
||||
self.projects.resource_class = fakes.FakeResource(None, {})
|
||||
self.regions = mock.Mock()
|
||||
self.regions.resource_class = fakes.FakeResource(None, {})
|
||||
self.roles = mock.Mock()
|
||||
self.roles.resource_class = fakes.FakeResource(None, {})
|
||||
self.services = mock.Mock()
|
||||
|
406
openstackclient/tests/identity/v3/test_region.py
Normal file
406
openstackclient/tests/identity/v3/test_region.py
Normal file
@ -0,0 +1,406 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
import copy
|
||||
|
||||
from openstackclient.identity.v3 import region
|
||||
from openstackclient.tests import fakes
|
||||
from openstackclient.tests.identity.v3 import fakes as identity_fakes
|
||||
|
||||
|
||||
class TestRegion(identity_fakes.TestIdentityv3):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRegion, self).setUp()
|
||||
|
||||
# Get a shortcut to the RegionManager Mock
|
||||
self.regions_mock = self.app.client_manager.identity.regions
|
||||
self.regions_mock.reset_mock()
|
||||
|
||||
|
||||
class TestRegionCreate(TestRegion):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRegionCreate, self).setUp()
|
||||
|
||||
self.regions_mock.create.return_value = fakes.FakeResource(
|
||||
None,
|
||||
copy.deepcopy(identity_fakes.REGION),
|
||||
loaded=True,
|
||||
)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = region.CreateRegion(self.app, None)
|
||||
|
||||
def test_region_create_description(self):
|
||||
arglist = [
|
||||
identity_fakes.region_id,
|
||||
'--description', identity_fakes.region_description,
|
||||
]
|
||||
verifylist = [
|
||||
('region', identity_fakes.region_id),
|
||||
('description', identity_fakes.region_description)
|
||||
]
|
||||
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': identity_fakes.region_description,
|
||||
'id': identity_fakes.region_id,
|
||||
'parent_region': None,
|
||||
'url': None,
|
||||
}
|
||||
self.regions_mock.create.assert_called_with(
|
||||
**kwargs
|
||||
)
|
||||
|
||||
collist = ('description', 'parent_region', 'region', 'url')
|
||||
self.assertEqual(collist, columns)
|
||||
datalist = (
|
||||
identity_fakes.region_description,
|
||||
identity_fakes.region_parent_region_id,
|
||||
identity_fakes.region_id,
|
||||
identity_fakes.region_url,
|
||||
)
|
||||
self.assertEqual(datalist, data)
|
||||
|
||||
def test_region_create_no_options(self):
|
||||
arglist = [
|
||||
identity_fakes.region_id,
|
||||
]
|
||||
verifylist = [
|
||||
('region', identity_fakes.region_id),
|
||||
]
|
||||
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,
|
||||
'id': identity_fakes.region_id,
|
||||
'parent_region': None,
|
||||
'url': None,
|
||||
}
|
||||
self.regions_mock.create.assert_called_with(
|
||||
**kwargs
|
||||
)
|
||||
|
||||
collist = ('description', 'parent_region', 'region', 'url')
|
||||
self.assertEqual(collist, columns)
|
||||
datalist = (
|
||||
identity_fakes.region_description,
|
||||
identity_fakes.region_parent_region_id,
|
||||
identity_fakes.region_id,
|
||||
identity_fakes.region_url,
|
||||
)
|
||||
self.assertEqual(datalist, data)
|
||||
|
||||
def test_region_create_parent_region_id(self):
|
||||
arglist = [
|
||||
identity_fakes.region_id,
|
||||
'--parent-region', identity_fakes.region_parent_region_id,
|
||||
]
|
||||
verifylist = [
|
||||
('region', identity_fakes.region_id),
|
||||
('parent_region', identity_fakes.region_parent_region_id),
|
||||
]
|
||||
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,
|
||||
'id': identity_fakes.region_id,
|
||||
'parent_region': identity_fakes.region_parent_region_id,
|
||||
'url': None,
|
||||
}
|
||||
self.regions_mock.create.assert_called_with(
|
||||
**kwargs
|
||||
)
|
||||
|
||||
collist = ('description', 'parent_region', 'region', 'url')
|
||||
self.assertEqual(collist, columns)
|
||||
datalist = (
|
||||
identity_fakes.region_description,
|
||||
identity_fakes.region_parent_region_id,
|
||||
identity_fakes.region_id,
|
||||
identity_fakes.region_url,
|
||||
)
|
||||
self.assertEqual(datalist, data)
|
||||
|
||||
def test_region_create_url(self):
|
||||
arglist = [
|
||||
identity_fakes.region_id,
|
||||
'--url', identity_fakes.region_url,
|
||||
]
|
||||
verifylist = [
|
||||
('region', identity_fakes.region_id),
|
||||
('url', identity_fakes.region_url),
|
||||
]
|
||||
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,
|
||||
'id': identity_fakes.region_id,
|
||||
'parent_region': None,
|
||||
'url': identity_fakes.region_url,
|
||||
}
|
||||
self.regions_mock.create.assert_called_with(
|
||||
**kwargs
|
||||
)
|
||||
|
||||
collist = ('description', 'parent_region', 'region', 'url')
|
||||
self.assertEqual(collist, columns)
|
||||
datalist = (
|
||||
identity_fakes.region_description,
|
||||
identity_fakes.region_parent_region_id,
|
||||
identity_fakes.region_id,
|
||||
identity_fakes.region_url,
|
||||
)
|
||||
self.assertEqual(datalist, data)
|
||||
|
||||
|
||||
class TestRegionDelete(TestRegion):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRegionDelete, self).setUp()
|
||||
|
||||
self.regions_mock.delete.return_value = None
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = region.DeleteRegion(self.app, None)
|
||||
|
||||
def test_region_delete_no_options(self):
|
||||
arglist = [
|
||||
identity_fakes.region_id,
|
||||
]
|
||||
verifylist = [
|
||||
('region', identity_fakes.region_id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.run(parsed_args)
|
||||
self.assertEqual(0, result)
|
||||
|
||||
self.regions_mock.delete.assert_called_with(
|
||||
identity_fakes.region_id,
|
||||
)
|
||||
|
||||
|
||||
class TestRegionList(TestRegion):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRegionList, self).setUp()
|
||||
|
||||
self.regions_mock.list.return_value = [
|
||||
fakes.FakeResource(
|
||||
None,
|
||||
copy.deepcopy(identity_fakes.REGION),
|
||||
loaded=True,
|
||||
),
|
||||
]
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = region.ListRegion(self.app, None)
|
||||
|
||||
def test_region_list_no_options(self):
|
||||
arglist = []
|
||||
verifylist = []
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
# DisplayCommandBase.take_action() returns two tuples
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.regions_mock.list.assert_called_with()
|
||||
|
||||
collist = ('Region', 'Parent Region', 'Description', 'URL')
|
||||
self.assertEqual(collist, columns)
|
||||
datalist = ((
|
||||
identity_fakes.region_id,
|
||||
identity_fakes.region_parent_region_id,
|
||||
identity_fakes.region_description,
|
||||
identity_fakes.region_url,
|
||||
), )
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
|
||||
def test_region_list_parent_region_id(self):
|
||||
arglist = [
|
||||
'--parent-region', identity_fakes.region_parent_region_id,
|
||||
]
|
||||
verifylist = [
|
||||
('parent_region', identity_fakes.region_parent_region_id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
# DisplayCommandBase.take_action() returns two tuples
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.regions_mock.list.assert_called_with(
|
||||
parent_region_id=identity_fakes.region_parent_region_id)
|
||||
|
||||
collist = ('Region', 'Parent Region', 'Description', 'URL')
|
||||
self.assertEqual(collist, columns)
|
||||
datalist = ((
|
||||
identity_fakes.region_id,
|
||||
identity_fakes.region_parent_region_id,
|
||||
identity_fakes.region_description,
|
||||
identity_fakes.region_url,
|
||||
), )
|
||||
self.assertEqual(datalist, tuple(data))
|
||||
|
||||
|
||||
class TestRegionSet(TestRegion):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRegionSet, self).setUp()
|
||||
|
||||
self.regions_mock.update.return_value = fakes.FakeResource(
|
||||
None,
|
||||
copy.deepcopy(identity_fakes.REGION),
|
||||
loaded=True,
|
||||
)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = region.SetRegion(self.app, None)
|
||||
|
||||
def test_region_set_no_options(self):
|
||||
arglist = [
|
||||
identity_fakes.region_id,
|
||||
]
|
||||
verifylist = [
|
||||
('region', identity_fakes.region_id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.run(parsed_args)
|
||||
self.assertEqual(0, result)
|
||||
|
||||
self.assertNotCalled(self.regions_mock.update)
|
||||
|
||||
def test_region_set_description(self):
|
||||
arglist = [
|
||||
'--description', 'qwerty',
|
||||
identity_fakes.region_id,
|
||||
]
|
||||
verifylist = [
|
||||
('description', 'qwerty'),
|
||||
('region', identity_fakes.region_id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.run(parsed_args)
|
||||
self.assertEqual(0, result)
|
||||
|
||||
# Set expected values
|
||||
kwargs = {
|
||||
'description': 'qwerty',
|
||||
}
|
||||
self.regions_mock.update.assert_called_with(
|
||||
identity_fakes.region_id,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def test_region_set_url(self):
|
||||
arglist = [
|
||||
'--url', 'new url',
|
||||
identity_fakes.region_id,
|
||||
]
|
||||
verifylist = [
|
||||
('url', 'new url'),
|
||||
('region', identity_fakes.region_id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.run(parsed_args)
|
||||
self.assertEqual(0, result)
|
||||
|
||||
# Set expected values
|
||||
kwargs = {
|
||||
'url': 'new url',
|
||||
}
|
||||
self.regions_mock.update.assert_called_with(
|
||||
identity_fakes.region_id,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def test_region_set_parent_region_id(self):
|
||||
arglist = [
|
||||
'--parent-region', 'new_parent',
|
||||
identity_fakes.region_id,
|
||||
]
|
||||
verifylist = [
|
||||
('parent_region', 'new_parent'),
|
||||
('region', identity_fakes.region_id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
result = self.cmd.run(parsed_args)
|
||||
self.assertEqual(0, result)
|
||||
|
||||
# Set expected values
|
||||
kwargs = {
|
||||
'parent_region': 'new_parent',
|
||||
}
|
||||
self.regions_mock.update.assert_called_with(
|
||||
identity_fakes.region_id,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
|
||||
class TestRegionShow(TestRegion):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRegionShow, self).setUp()
|
||||
|
||||
self.regions_mock.get.return_value = fakes.FakeResource(
|
||||
None,
|
||||
copy.deepcopy(identity_fakes.REGION),
|
||||
loaded=True,
|
||||
)
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = region.ShowRegion(self.app, None)
|
||||
|
||||
def test_region_show(self):
|
||||
arglist = [
|
||||
identity_fakes.region_id,
|
||||
]
|
||||
verifylist = [
|
||||
('region', identity_fakes.region_id),
|
||||
]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
# DisplayCommandBase.take_action() returns two tuples
|
||||
columns, data = self.cmd.take_action(parsed_args)
|
||||
self.regions_mock.get.assert_called_with(
|
||||
identity_fakes.region_id,
|
||||
)
|
||||
|
||||
collist = ('description', 'parent_region', 'region', 'url')
|
||||
self.assertEqual(collist, columns)
|
||||
datalist = (
|
||||
identity_fakes.region_description,
|
||||
identity_fakes.region_parent_region_id,
|
||||
identity_fakes.region_id,
|
||||
identity_fakes.region_url,
|
||||
)
|
||||
self.assertEqual(datalist, data)
|
@ -243,6 +243,12 @@ openstack.identity.v3 =
|
||||
federation_domain_list = openstackclient.identity.v3.unscoped_saml:ListAccessibleDomains
|
||||
federation_project_list = openstackclient.identity.v3.unscoped_saml:ListAccessibleProjects
|
||||
|
||||
region_create = openstackclient.identity.v3.region:CreateRegion
|
||||
region_delete = openstackclient.identity.v3.region:DeleteRegion
|
||||
region_list = openstackclient.identity.v3.region:ListRegion
|
||||
region_set = openstackclient.identity.v3.region:SetRegion
|
||||
region_show = openstackclient.identity.v3.region:ShowRegion
|
||||
|
||||
request_token_authorize = openstackclient.identity.v3.token:AuthorizeRequestToken
|
||||
request_token_create = openstackclient.identity.v3.token:CreateRequestToken
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user