Add support of export location metadata feature
Add support of new Manila APIs for listing share and share instance export locations. CLI looks like following: $ manila share-export-location-list %share_id% $ manila share-export-location-show %share_id% %el_uuid% $ manila share-instance-export-location-list %si_id% $ manila share-instance-export-location-show %si_id% %el_uuid% Change-Id: I6ae57cb1fc1551e4d87658a16550f052d14641a0 Depends-On: I36d1aa8d9302e097ffb08d239cf7a81101d2c1cb
This commit is contained in:
parent
8726bf5dda
commit
17f9908ce2
@ -31,7 +31,7 @@ if not LOG.handlers:
|
||||
LOG.addHandler(logging.StreamHandler())
|
||||
|
||||
|
||||
MAX_VERSION = '2.8'
|
||||
MAX_VERSION = '2.9'
|
||||
MIN_VERSION = '2.0'
|
||||
DEPRECATED_VERSION = '1.0'
|
||||
_VERSIONED_METHOD_MAP = {}
|
||||
|
@ -571,6 +571,19 @@ class ManilaCLIClient(base.CLIClient):
|
||||
shares = utils.listing(shares_raw)
|
||||
return shares
|
||||
|
||||
def list_share_instances(self, share_id=None, microversion=None):
|
||||
"""List share instances.
|
||||
|
||||
:param share_id: ID of a share to filter by.
|
||||
:param microversion: API microversion to be used for request.
|
||||
"""
|
||||
cmd = 'share-instance-list '
|
||||
if share_id:
|
||||
cmd += '--share-id %s' % share_id
|
||||
share_instances_raw = self.manila(cmd, microversion=microversion)
|
||||
share_instances = utils.listing(share_instances_raw)
|
||||
return share_instances
|
||||
|
||||
def is_share_deleted(self, share, microversion=None):
|
||||
"""Says whether share is deleted or not.
|
||||
|
||||
@ -836,3 +849,77 @@ class ManilaCLIClient(base.CLIClient):
|
||||
if password is not None:
|
||||
data += '--password %s ' % password
|
||||
return data
|
||||
|
||||
@not_found_wrapper
|
||||
def list_share_export_locations(self, share, columns=None,
|
||||
microversion=None):
|
||||
"""List share export locations.
|
||||
|
||||
:param share: str -- Name or ID of a share.
|
||||
:param columns: str -- comma separated string of columns.
|
||||
Example, "--columns uuid,path".
|
||||
:param microversion: API microversion to be used for request.
|
||||
"""
|
||||
cmd = "share-export-location-list %s" % share
|
||||
if columns is not None:
|
||||
cmd += " --columns " + columns
|
||||
export_locations_raw = self.manila(cmd, microversion=microversion)
|
||||
export_locations = utils.listing(export_locations_raw)
|
||||
return export_locations
|
||||
|
||||
@not_found_wrapper
|
||||
def get_share_export_location(self, share, export_location_uuid,
|
||||
microversion=None):
|
||||
"""Returns an export location by share and its UUID.
|
||||
|
||||
:param share: str -- Name or ID of a share.
|
||||
:param export_location_uuid: str -- UUID of an export location.
|
||||
:param microversion: API microversion to be used for request.
|
||||
"""
|
||||
share_raw = self.manila(
|
||||
'share-export-location-show %(share)s %(el_uuid)s' % {
|
||||
'share': share,
|
||||
'el_uuid': export_location_uuid,
|
||||
},
|
||||
microversion=microversion)
|
||||
share = output_parser.details(share_raw)
|
||||
return share
|
||||
|
||||
@not_found_wrapper
|
||||
@forbidden_wrapper
|
||||
def list_share_instance_export_locations(self, share_instance,
|
||||
columns=None, microversion=None):
|
||||
"""List share instance export locations.
|
||||
|
||||
:param share_instance: str -- Name or ID of a share instance.
|
||||
:param columns: str -- comma separated string of columns.
|
||||
Example, "--columns uuid,path".
|
||||
:param microversion: API microversion to be used for request.
|
||||
"""
|
||||
cmd = "share-instance-export-location-list %s" % share_instance
|
||||
if columns is not None:
|
||||
cmd += " --columns " + columns
|
||||
export_locations_raw = self.manila(cmd, microversion=microversion)
|
||||
export_locations = utils.listing(export_locations_raw)
|
||||
return export_locations
|
||||
|
||||
@not_found_wrapper
|
||||
@forbidden_wrapper
|
||||
def get_share_instance_export_location(self, share_instance,
|
||||
export_location_uuid,
|
||||
microversion=None):
|
||||
"""Returns an export location by share instance and its UUID.
|
||||
|
||||
:param share_instance: str -- Name or ID of a share instance.
|
||||
:param export_location_uuid: str -- UUID of an export location.
|
||||
:param microversion: API microversion to be used for request.
|
||||
"""
|
||||
share_raw = self.manila(
|
||||
'share-instance-export-location-show '
|
||||
'%(share_instance)s %(el_uuid)s' % {
|
||||
'share_instance': share_instance,
|
||||
'el_uuid': export_location_uuid,
|
||||
},
|
||||
microversion=microversion)
|
||||
share = output_parser.details(share_raw)
|
||||
return share
|
||||
|
158
manilaclient/tests/functional/test_export_locations.py
Normal file
158
manilaclient/tests/functional/test_export_locations.py
Normal file
@ -0,0 +1,158 @@
|
||||
# Copyright 2015 Mirantis Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 ddt
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from manilaclient.tests.functional import base
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ExportLocationReadWriteTest(base.BaseTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(ExportLocationReadWriteTest, cls).setUpClass()
|
||||
cls.share = cls.create_share(
|
||||
client=cls.get_user_client(),
|
||||
cleanup_in_class=True)
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
def test_list_share_export_locations(self, role):
|
||||
client = self.admin_client if role == 'admin' else self.user_client
|
||||
export_locations = client.list_share_export_locations(
|
||||
self.share['id'])
|
||||
|
||||
self.assertTrue(len(export_locations) > 0)
|
||||
expected_keys = (
|
||||
'Path', 'Updated At', 'Created At', 'UUID',
|
||||
)
|
||||
for el in export_locations:
|
||||
for key in expected_keys:
|
||||
self.assertIn(key, el)
|
||||
self.assertTrue(uuidutils.is_uuid_like(el['UUID']))
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
def test_list_share_export_locations_with_columns(self, role):
|
||||
client = self.admin_client if role == 'admin' else self.user_client
|
||||
export_locations = client.list_share_export_locations(
|
||||
self.share['id'], columns='uuid,path')
|
||||
|
||||
self.assertTrue(len(export_locations) > 0)
|
||||
expected_keys = ('Uuid', 'Path')
|
||||
unexpected_keys = ('Updated At', 'Created At')
|
||||
for el in export_locations:
|
||||
for key in expected_keys:
|
||||
self.assertIn(key, el)
|
||||
for key in unexpected_keys:
|
||||
self.assertNotIn(key, el)
|
||||
self.assertTrue(uuidutils.is_uuid_like(el['Uuid']))
|
||||
|
||||
@ddt.data('admin', 'user')
|
||||
def test_get_share_export_location(self, role):
|
||||
client = self.admin_client if role == 'admin' else self.user_client
|
||||
export_locations = client.list_share_export_locations(
|
||||
self.share['id'])
|
||||
|
||||
el = client.get_share_export_location(
|
||||
self.share['id'], export_locations[0]['UUID'])
|
||||
|
||||
expected_keys = [
|
||||
'path', 'updated_at', 'created_at', 'uuid',
|
||||
]
|
||||
if role == 'admin':
|
||||
expected_keys.extend(['is_admin_only', 'share_instance_id'])
|
||||
for key in expected_keys:
|
||||
self.assertIn(key, el)
|
||||
if role == 'admin':
|
||||
self.assertTrue(uuidutils.is_uuid_like(el['share_instance_id']))
|
||||
self.assertIn(el['is_admin_only'], ('True', 'False'))
|
||||
self.assertTrue(uuidutils.is_uuid_like(el['uuid']))
|
||||
for list_k, get_k in (
|
||||
('UUID', 'uuid'), ('Created At', 'created_at'),
|
||||
('Path', 'path'), ('Updated At', 'updated_at')):
|
||||
self.assertEqual(
|
||||
export_locations[0][list_k], el[get_k])
|
||||
|
||||
def test_list_share_instance_export_locations(self):
|
||||
client = self.admin_client
|
||||
share_instances = client.list_share_instances(self.share['id'])
|
||||
self.assertTrue(len(share_instances) > 0)
|
||||
self.assertIn('ID', share_instances[0])
|
||||
self.assertTrue(uuidutils.is_uuid_like(share_instances[0]['ID']))
|
||||
share_instance_id = share_instances[0]['ID']
|
||||
|
||||
export_locations = client.list_share_instance_export_locations(
|
||||
share_instance_id)
|
||||
|
||||
self.assertTrue(len(export_locations) > 0)
|
||||
expected_keys = (
|
||||
'Path', 'Updated At', 'Created At', 'UUID', 'Is Admin only',
|
||||
)
|
||||
for el in export_locations:
|
||||
for key in expected_keys:
|
||||
self.assertIn(key, el)
|
||||
self.assertTrue(uuidutils.is_uuid_like(el['UUID']))
|
||||
|
||||
def test_list_share_instance_export_locations_with_columns(self):
|
||||
client = self.admin_client
|
||||
share_instances = client.list_share_instances(self.share['id'])
|
||||
self.assertTrue(len(share_instances) > 0)
|
||||
self.assertIn('ID', share_instances[0])
|
||||
self.assertTrue(uuidutils.is_uuid_like(share_instances[0]['ID']))
|
||||
share_instance_id = share_instances[0]['ID']
|
||||
|
||||
export_locations = client.list_share_instance_export_locations(
|
||||
share_instance_id, columns='uuid,path')
|
||||
|
||||
self.assertTrue(len(export_locations) > 0)
|
||||
expected_keys = ('Uuid', 'Path')
|
||||
unexpected_keys = (
|
||||
'Updated At', 'Created At', 'Is Admin only',
|
||||
)
|
||||
for el in export_locations:
|
||||
for key in expected_keys:
|
||||
self.assertIn(key, el)
|
||||
for key in unexpected_keys:
|
||||
self.assertNotIn(key, el)
|
||||
self.assertTrue(uuidutils.is_uuid_like(el['Uuid']))
|
||||
|
||||
def test_get_share_instance_export_location(self):
|
||||
client = self.admin_client
|
||||
share_instances = client.list_share_instances(self.share['id'])
|
||||
self.assertTrue(len(share_instances) > 0)
|
||||
self.assertIn('ID', share_instances[0])
|
||||
self.assertTrue(uuidutils.is_uuid_like(share_instances[0]['ID']))
|
||||
share_instance_id = share_instances[0]['ID']
|
||||
|
||||
export_locations = client.list_share_instance_export_locations(
|
||||
share_instance_id)
|
||||
|
||||
el = client.get_share_instance_export_location(
|
||||
share_instance_id, export_locations[0]['UUID'])
|
||||
|
||||
expected_keys = (
|
||||
'path', 'updated_at', 'created_at', 'uuid',
|
||||
'is_admin_only', 'share_instance_id',
|
||||
)
|
||||
for key in expected_keys:
|
||||
self.assertIn(key, el)
|
||||
self.assertIn(el['is_admin_only'], ('True', 'False'))
|
||||
self.assertTrue(uuidutils.is_uuid_like(el['uuid']))
|
||||
for list_k, get_k in (
|
||||
('UUID', 'uuid'), ('Created At', 'created_at'),
|
||||
('Path', 'path'), ('Updated At', 'updated_at')):
|
||||
self.assertEqual(
|
||||
export_locations[0][list_k], el[get_k])
|
@ -42,6 +42,17 @@ fake_share_instance = {
|
||||
}
|
||||
|
||||
|
||||
def get_fake_export_location():
|
||||
return {
|
||||
'uuid': 'foo_el_uuid',
|
||||
'path': '/foo/el/path',
|
||||
'share_instance_id': 'foo_share_instance_id',
|
||||
'is_admin_only': False,
|
||||
'created_at': '2015-12-17T13:14:15Z',
|
||||
'updated_at': '2015-12-17T14:15:16Z',
|
||||
}
|
||||
|
||||
|
||||
class FakeHTTPClient(fakes.FakeHTTPClient):
|
||||
|
||||
def get_(self, **kw):
|
||||
@ -222,6 +233,24 @@ class FakeHTTPClient(fakes.FakeHTTPClient):
|
||||
def get_share_instances(self, **kw):
|
||||
return self._share_instances()
|
||||
|
||||
def get_share_instances_1234_export_locations(self, **kw):
|
||||
export_locations = {
|
||||
'export_locations': [
|
||||
get_fake_export_location(),
|
||||
]
|
||||
}
|
||||
return (200, {}, export_locations)
|
||||
|
||||
get_shares_1234_export_locations = (
|
||||
get_share_instances_1234_export_locations)
|
||||
|
||||
def get_share_instances_1234_export_locations_fake_el_uuid(self, **kw):
|
||||
export_location = {'export_location': get_fake_export_location()}
|
||||
return (200, {}, export_location)
|
||||
|
||||
get_shares_1234_export_locations_fake_el_uuid = (
|
||||
get_share_instances_1234_export_locations_fake_el_uuid)
|
||||
|
||||
def get_shares_fake_instances(self, **kw):
|
||||
return self._share_instances()
|
||||
|
||||
|
57
manilaclient/tests/unit/v2/test_share_export_locations.py
Normal file
57
manilaclient/tests/unit/v2/test_share_export_locations.py
Normal file
@ -0,0 +1,57 @@
|
||||
# Copyright 2015 Mirantis inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 ddt
|
||||
import mock
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import extension
|
||||
from manilaclient.tests.unit import utils
|
||||
from manilaclient.tests.unit.v2 import fakes
|
||||
from manilaclient.v2 import share_export_locations
|
||||
|
||||
|
||||
extensions = [
|
||||
extension.Extension('share_export_locations', share_export_locations),
|
||||
]
|
||||
cs = fakes.FakeClient(extensions=extensions)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ShareExportLocationsTest(utils.TestCase):
|
||||
|
||||
def _get_manager(self, microversion):
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
return (
|
||||
share_export_locations.ShareExportLocationManager(
|
||||
api=mock_microversion)
|
||||
)
|
||||
|
||||
def test_list_of_export_locations(self):
|
||||
share_id = '1234'
|
||||
cs.share_export_locations.list(share_id)
|
||||
cs.assert_called(
|
||||
'GET', '/shares/%s/export_locations' % share_id)
|
||||
|
||||
def test_get_single_export_location(self):
|
||||
share_id = '1234'
|
||||
el_uuid = 'fake_el_uuid'
|
||||
cs.share_export_locations.get(share_id, el_uuid)
|
||||
cs.assert_called(
|
||||
'GET',
|
||||
('/shares/%(share_id)s/export_locations/'
|
||||
'%(el_uuid)s') % {
|
||||
'share_id': share_id, 'el_uuid': el_uuid})
|
@ -0,0 +1,58 @@
|
||||
# Copyright 2015 Mirantis inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 ddt
|
||||
import mock
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import extension
|
||||
from manilaclient.tests.unit import utils
|
||||
from manilaclient.tests.unit.v2 import fakes
|
||||
from manilaclient.v2 import share_instance_export_locations
|
||||
|
||||
|
||||
extensions = [
|
||||
extension.Extension('share_instance_export_locations',
|
||||
share_instance_export_locations),
|
||||
]
|
||||
cs = fakes.FakeClient(extensions=extensions)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ShareInstanceExportLocationsTest(utils.TestCase):
|
||||
|
||||
def _get_manager(self, microversion):
|
||||
version = api_versions.APIVersion(microversion)
|
||||
mock_microversion = mock.Mock(api_version=version)
|
||||
return (
|
||||
share_instance_export_locations.ShareInstanceExportLocationManager(
|
||||
api=mock_microversion)
|
||||
)
|
||||
|
||||
def test_list_of_export_locations(self):
|
||||
share_instance_id = '1234'
|
||||
cs.share_instance_export_locations.list(share_instance_id)
|
||||
cs.assert_called(
|
||||
'GET', '/share_instances/%s/export_locations' % share_instance_id)
|
||||
|
||||
def test_get_single_export_location(self):
|
||||
share_instance_id = '1234'
|
||||
el_uuid = 'fake_el_uuid'
|
||||
cs.share_instance_export_locations.get(share_instance_id, el_uuid)
|
||||
cs.assert_called(
|
||||
'GET',
|
||||
('/share_instances/%(share_instance_id)s/export_locations/'
|
||||
'%(el_uuid)s') % {
|
||||
'share_instance_id': share_instance_id, 'el_uuid': el_uuid})
|
@ -335,7 +335,28 @@ class ShellTest(test_utils.TestCase):
|
||||
|
||||
def test_share_instance_show(self):
|
||||
self.run_command('share-instance-show 1234')
|
||||
self.assert_called('GET', '/share_instances/1234')
|
||||
self.assert_called_anytime('GET', '/share_instances/1234')
|
||||
|
||||
def test_share_instance_export_location_list(self):
|
||||
self.run_command('share-instance-export-location-list 1234')
|
||||
|
||||
self.assert_called_anytime(
|
||||
'GET', '/share_instances/1234/export_locations')
|
||||
|
||||
@mock.patch.object(cliutils, 'print_list', mock.Mock())
|
||||
def test_share_instance_export_location_list_with_columns(self):
|
||||
self.run_command(
|
||||
'share-instance-export-location-list 1234 --columns uuid,path')
|
||||
|
||||
self.assert_called_anytime(
|
||||
'GET', '/share_instances/1234/export_locations')
|
||||
cliutils.print_list.assert_called_once_with(mock.ANY, ['Uuid', 'Path'])
|
||||
|
||||
def test_share_instance_export_location_show(self):
|
||||
self.run_command(
|
||||
'share-instance-export-location-show 1234 fake_el_uuid')
|
||||
self.assert_called_anytime(
|
||||
'GET', '/share_instances/1234/export_locations/fake_el_uuid')
|
||||
|
||||
def test_share_instance_reset_state(self):
|
||||
self.run_command('share-instance-reset-state 1234')
|
||||
@ -439,7 +460,25 @@ class ShellTest(test_utils.TestCase):
|
||||
|
||||
def test_show(self):
|
||||
self.run_command('show 1234')
|
||||
self.assert_called('GET', '/shares/1234')
|
||||
self.assert_called_anytime('GET', '/shares/1234')
|
||||
|
||||
def test_share_export_location_list(self):
|
||||
self.run_command('share-export-location-list 1234')
|
||||
self.assert_called_anytime(
|
||||
'GET', '/shares/1234/export_locations')
|
||||
|
||||
@mock.patch.object(cliutils, 'print_list', mock.Mock())
|
||||
def test_share_export_location_list_with_columns(self):
|
||||
self.run_command('share-export-location-list 1234 --columns uuid,path')
|
||||
|
||||
self.assert_called_anytime(
|
||||
'GET', '/shares/1234/export_locations')
|
||||
cliutils.print_list.assert_called_once_with(mock.ANY, ['Uuid', 'Path'])
|
||||
|
||||
def test_share_export_location_show(self):
|
||||
self.run_command('share-export-location-show 1234 fake_el_uuid')
|
||||
self.assert_called_anytime(
|
||||
'GET', '/shares/1234/export_locations/fake_el_uuid')
|
||||
|
||||
@ddt.data({'cmd_args': '--driver_options opt1=opt1 opt2=opt2'
|
||||
' --share_type fake_share_type',
|
||||
|
@ -30,6 +30,8 @@ from manilaclient.v2 import quotas
|
||||
from manilaclient.v2 import scheduler_stats
|
||||
from manilaclient.v2 import security_services
|
||||
from manilaclient.v2 import services
|
||||
from manilaclient.v2 import share_export_locations
|
||||
from manilaclient.v2 import share_instance_export_locations
|
||||
from manilaclient.v2 import share_instances
|
||||
from manilaclient.v2 import share_networks
|
||||
from manilaclient.v2 import share_servers
|
||||
@ -210,7 +212,12 @@ class Client(object):
|
||||
self.quotas = quotas.QuotaSetManager(self)
|
||||
|
||||
self.shares = shares.ShareManager(self)
|
||||
self.share_export_locations = (
|
||||
share_export_locations.ShareExportLocationManager(self))
|
||||
self.share_instances = share_instances.ShareInstanceManager(self)
|
||||
self.share_instance_export_locations = (
|
||||
share_instance_export_locations.ShareInstanceExportLocationManager(
|
||||
self))
|
||||
self.share_snapshots = share_snapshots.ShareSnapshotManager(self)
|
||||
|
||||
self.share_types = share_types.ShareTypeManager(self)
|
||||
|
50
manilaclient/v2/share_export_locations.py
Normal file
50
manilaclient/v2/share_export_locations.py
Normal file
@ -0,0 +1,50 @@
|
||||
# Copyright 2015 Mirantis inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import base
|
||||
from manilaclient.openstack.common.apiclient import base as common_base
|
||||
|
||||
|
||||
class ShareExportLocation(common_base.Resource):
|
||||
"""Resource class for a share export location."""
|
||||
|
||||
def __repr__(self):
|
||||
return "<ShareExportLocation: %s>" % self.id
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._info[key]
|
||||
|
||||
|
||||
class ShareExportLocationManager(base.ManagerWithFind):
|
||||
"""Manage :class:`ShareExportLocation` resources."""
|
||||
resource_class = ShareExportLocation
|
||||
|
||||
@api_versions.wraps("2.9")
|
||||
def list(self, share):
|
||||
"""List all share export locations."""
|
||||
share_id = common_base.getid(share)
|
||||
return self._list("/shares/%s/export_locations" % share_id,
|
||||
"export_locations")
|
||||
|
||||
@api_versions.wraps("2.9")
|
||||
def get(self, share, export_location):
|
||||
"""Get a share export location."""
|
||||
share_id = common_base.getid(share)
|
||||
export_location_id = common_base.getid(export_location)
|
||||
return self._get(
|
||||
"/shares/%(share_id)s/export_locations/%(export_location_id)s" % {
|
||||
"share_id": share_id,
|
||||
"export_location_id": export_location_id}, "export_location")
|
54
manilaclient/v2/share_instance_export_locations.py
Normal file
54
manilaclient/v2/share_instance_export_locations.py
Normal file
@ -0,0 +1,54 @@
|
||||
# Copyright 2015 Mirantis inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from manilaclient import api_versions
|
||||
from manilaclient import base
|
||||
from manilaclient.openstack.common.apiclient import base as common_base
|
||||
|
||||
|
||||
class ShareInstanceExportLocation(common_base.Resource):
|
||||
"""Resource class for a share export location."""
|
||||
|
||||
def __repr__(self):
|
||||
return "<ShareInstanceExportLocation: %s>" % self.id
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._info[key]
|
||||
|
||||
|
||||
class ShareInstanceExportLocationManager(base.ManagerWithFind):
|
||||
"""Manage :class:`ShareInstanceExportLocation` resources."""
|
||||
resource_class = ShareInstanceExportLocation
|
||||
|
||||
@api_versions.wraps("2.9")
|
||||
def list(self, share_instance):
|
||||
"""List all share export locations."""
|
||||
share_instance_id = common_base.getid(share_instance)
|
||||
return self._list(
|
||||
"/share_instances/%s/export_locations" % share_instance_id,
|
||||
"export_locations")
|
||||
|
||||
@api_versions.wraps("2.9")
|
||||
def get(self, share_instance, export_location):
|
||||
"""Get a share export location."""
|
||||
share_instance_id = common_base.getid(share_instance)
|
||||
export_location_id = common_base.getid(export_location)
|
||||
return self._get(
|
||||
("/share_instances/%(share_instance_id)s/export_locations/"
|
||||
"%(export_location_id)s") % {
|
||||
"share_instance_id": share_instance_id,
|
||||
"export_location_id": export_location_id,
|
||||
},
|
||||
"export_location")
|
@ -66,6 +66,20 @@ def _find_share(cs, share):
|
||||
return apiclient_utils.find_resource(cs.shares, share)
|
||||
|
||||
|
||||
def _transform_export_locations_to_string_view(export_locations):
|
||||
export_locations_string_view = ''
|
||||
for el in export_locations:
|
||||
if hasattr(el, '_info'):
|
||||
export_locations_dict = el._info
|
||||
else:
|
||||
export_locations_dict = el
|
||||
for k, v in export_locations_dict.items():
|
||||
export_locations_string_view += '\n%(k)s = %(v)s' % {
|
||||
'k': k, 'v': v}
|
||||
return export_locations_string_view
|
||||
|
||||
|
||||
@api_versions.wraps("1.0", "2.8")
|
||||
def _print_share(cs, share):
|
||||
info = share._info.copy()
|
||||
info.pop('links', None)
|
||||
@ -96,17 +110,65 @@ def _print_share(cs, share):
|
||||
cliutils.print_dict(info)
|
||||
|
||||
|
||||
@api_versions.wraps("2.9") # noqa
|
||||
def _print_share(cs, share):
|
||||
info = share._info.copy()
|
||||
info.pop('links', None)
|
||||
|
||||
# NOTE(vponomaryov): remove deprecated single field 'export_location' and
|
||||
# leave only list field 'export_locations'. Also, transform the latter to
|
||||
# text with new line separators to make it pretty in CLI.
|
||||
# It will look like following:
|
||||
# +-------------------+--------------------------------------------+
|
||||
# | Property | Value |
|
||||
# +-------------------+--------------------------------------------+
|
||||
# | status | available |
|
||||
# | export_locations | |
|
||||
# | | uuid = FOO-UUID |
|
||||
# | | path = 5.6.7.8:/foo/export/location/path |
|
||||
# | | |
|
||||
# | | uuid = BAR-UUID |
|
||||
# | | path = 5.6.7.8:/bar/export/location/path |
|
||||
# | | |
|
||||
# | id | d778d2ee-b6bb-4c5f-9f5d-6f3057d549b1 |
|
||||
# | size | 1 |
|
||||
# | share_proto | NFS |
|
||||
# +-------------------+--------------------------------------------+
|
||||
if info.get('export_locations'):
|
||||
info['export_locations'] = (
|
||||
_transform_export_locations_to_string_view(
|
||||
info['export_locations']))
|
||||
|
||||
# No need to print both volume_type and share_type to CLI
|
||||
if 'volume_type' in info and 'share_type' in info:
|
||||
info.pop('volume_type', None)
|
||||
|
||||
cliutils.print_dict(info)
|
||||
|
||||
|
||||
def _find_share_instance(cs, instance):
|
||||
"""Get a share instance by ID."""
|
||||
return apiclient_utils.find_resource(cs.share_instances, instance)
|
||||
|
||||
|
||||
@api_versions.wraps("1.0", "2.8")
|
||||
def _print_share_instance(cs, instance):
|
||||
info = instance._info.copy()
|
||||
info.pop('links', None)
|
||||
cliutils.print_dict(info)
|
||||
|
||||
|
||||
@api_versions.wraps("2.9") # noqa
|
||||
def _print_share_instance(cs, instance):
|
||||
info = instance._info.copy()
|
||||
info.pop('links', None)
|
||||
if info.get('export_locations'):
|
||||
info['export_locations'] = (
|
||||
_transform_export_locations_to_string_view(
|
||||
info['export_locations']))
|
||||
cliutils.print_dict(info)
|
||||
|
||||
|
||||
@api_versions.experimental_api
|
||||
@api_versions.wraps("2.4")
|
||||
def _find_consistency_group(cs, consistency_group):
|
||||
@ -609,6 +671,52 @@ def do_metadata_update_all(cs, args):
|
||||
cliutils.print_dict(metadata, 'Property')
|
||||
|
||||
|
||||
@api_versions.wraps("2.9")
|
||||
@cliutils.arg(
|
||||
'share',
|
||||
metavar='<share>',
|
||||
help='Name or ID of the share.')
|
||||
@cliutils.arg(
|
||||
'--columns',
|
||||
metavar='<columns>',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Comma separated list of columns to be displayed '
|
||||
'e.g. --columns "id,host,status"')
|
||||
def do_share_export_location_list(cs, args):
|
||||
"""List export locations of a given share."""
|
||||
if args.columns is not None:
|
||||
list_of_keys = _split_columns(columns=args.columns)
|
||||
else:
|
||||
list_of_keys = [
|
||||
'UUID',
|
||||
'Created At',
|
||||
'Updated At',
|
||||
'Path',
|
||||
]
|
||||
share = _find_share(cs, args.share)
|
||||
export_locations = cs.share_export_locations.list(share)
|
||||
cliutils.print_list(export_locations, list_of_keys)
|
||||
|
||||
|
||||
@api_versions.wraps("2.9")
|
||||
@cliutils.arg(
|
||||
'share',
|
||||
metavar='<share>',
|
||||
help='Name or ID of the share.')
|
||||
@cliutils.arg(
|
||||
'export_location',
|
||||
metavar='<export_location>',
|
||||
help='ID of the share export location.')
|
||||
def do_share_export_location_show(cs, args):
|
||||
"""Show export location of the share."""
|
||||
share = _find_share(cs, args.share)
|
||||
export_location = cs.share_export_locations.get(
|
||||
share, args.export_location)
|
||||
view_data = export_location._info.copy()
|
||||
cliutils.print_dict(view_data)
|
||||
|
||||
|
||||
@cliutils.arg(
|
||||
'service_host',
|
||||
metavar='<service_host>',
|
||||
@ -738,6 +846,7 @@ def do_force_delete(cs, args):
|
||||
"specified shares.")
|
||||
|
||||
|
||||
@api_versions.wraps("1.0", "2.8")
|
||||
@cliutils.arg(
|
||||
'share',
|
||||
metavar='<share>',
|
||||
@ -748,6 +857,19 @@ def do_show(cs, args):
|
||||
_print_share(cs, share)
|
||||
|
||||
|
||||
@api_versions.wraps("2.9") # noqa
|
||||
@cliutils.arg(
|
||||
'share',
|
||||
metavar='<share>',
|
||||
help='Name or ID of the NAS share.')
|
||||
def do_show(cs, args):
|
||||
"""Show details about a NAS share."""
|
||||
share = _find_share(cs, args.share)
|
||||
export_locations = cs.share_export_locations.list(share)
|
||||
share._info['export_locations'] = export_locations
|
||||
_print_share(cs, share)
|
||||
|
||||
|
||||
@cliutils.arg(
|
||||
'share',
|
||||
metavar='<share>',
|
||||
@ -962,8 +1084,9 @@ def do_list(cs, args):
|
||||
'Share Type Name', 'Host', 'Availability Zone'
|
||||
]
|
||||
|
||||
if args.columns is not None:
|
||||
list_of_keys = _split_columns(columns=args.columns)
|
||||
columns = args.columns
|
||||
if columns is not None:
|
||||
list_of_keys = _split_columns(columns=columns)
|
||||
|
||||
all_tenants = int(os.environ.get("ALL_TENANTS", args.all_tenants))
|
||||
empty_obj = type('Empty', (object,), {'id': None})
|
||||
@ -1005,6 +1128,17 @@ def do_list(cs, args):
|
||||
sort_key=args.sort_key,
|
||||
sort_dir=args.sort_dir,
|
||||
)
|
||||
# NOTE(vponomaryov): usage of 'export_location' and
|
||||
# 'export_locations' columns may cause scaling issue using API 2.9+ and
|
||||
# when lots of shares are returned.
|
||||
if (shares and columns is not None and 'export_location' in columns and
|
||||
not hasattr(shares[0], 'export_location')):
|
||||
# NOTE(vponomaryov): we will get here only using API 2.9+
|
||||
for share in shares:
|
||||
els_objs = cs.share_export_locations.list(share)
|
||||
els = [el.to_dict()['path'] for el in els_objs]
|
||||
setattr(share, 'export_locations', els)
|
||||
setattr(share, 'export_location', els[0] if els else None)
|
||||
cliutils.print_list(shares, list_of_keys)
|
||||
|
||||
|
||||
@ -1043,17 +1177,30 @@ def do_share_instance_list(cs, args):
|
||||
cliutils.print_list(instances, list_of_keys)
|
||||
|
||||
|
||||
@api_versions.wraps("2.3", "2.8")
|
||||
@cliutils.arg(
|
||||
'instance',
|
||||
metavar='<instance>',
|
||||
help='Name or ID of the share instance.')
|
||||
@api_versions.wraps("2.3")
|
||||
def do_share_instance_show(cs, args):
|
||||
"""Show details about a share instance."""
|
||||
instance = _find_share_instance(cs, args.instance)
|
||||
_print_share_instance(cs, instance)
|
||||
|
||||
|
||||
@api_versions.wraps("2.9") # noqa
|
||||
@cliutils.arg(
|
||||
'instance',
|
||||
metavar='<instance>',
|
||||
help='Name or ID of the share instance.')
|
||||
def do_share_instance_show(cs, args):
|
||||
"""Show details about a share instance."""
|
||||
instance = _find_share_instance(cs, args.instance)
|
||||
export_locations = cs.share_instance_export_locations.list(instance)
|
||||
instance._info['export_locations'] = export_locations
|
||||
_print_share_instance(cs, instance)
|
||||
|
||||
|
||||
@cliutils.arg(
|
||||
'instance',
|
||||
metavar='<instance>',
|
||||
@ -1093,6 +1240,53 @@ def do_share_instance_reset_state(cs, args):
|
||||
instance.reset_state(args.state)
|
||||
|
||||
|
||||
@api_versions.wraps("2.9")
|
||||
@cliutils.arg(
|
||||
'instance',
|
||||
metavar='<instance>',
|
||||
help='Name or ID of the share instance.')
|
||||
@cliutils.arg(
|
||||
'--columns',
|
||||
metavar='<columns>',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Comma separated list of columns to be displayed '
|
||||
'e.g. --columns "id,host,status"')
|
||||
def do_share_instance_export_location_list(cs, args):
|
||||
"""List export locations of a given share instance."""
|
||||
if args.columns is not None:
|
||||
list_of_keys = _split_columns(columns=args.columns)
|
||||
else:
|
||||
list_of_keys = [
|
||||
'UUID',
|
||||
'Created At',
|
||||
'Updated At',
|
||||
'Path',
|
||||
'Is Admin only',
|
||||
]
|
||||
instance = _find_share_instance(cs, args.instance)
|
||||
export_locations = cs.share_instance_export_locations.list(instance)
|
||||
cliutils.print_list(export_locations, list_of_keys)
|
||||
|
||||
|
||||
@api_versions.wraps("2.9")
|
||||
@cliutils.arg(
|
||||
'instance',
|
||||
metavar='<instance>',
|
||||
help='Name or ID of the share instance.')
|
||||
@cliutils.arg(
|
||||
'export_location',
|
||||
metavar='<export_location>',
|
||||
help='ID of the share instance export location.')
|
||||
def do_share_instance_export_location_show(cs, args):
|
||||
"""Show export location for the share instance."""
|
||||
instance = _find_share_instance(cs, args.instance)
|
||||
export_location = cs.share_instance_export_locations.get(
|
||||
instance, args.export_location)
|
||||
view_data = export_location._info.copy()
|
||||
cliutils.print_dict(view_data)
|
||||
|
||||
|
||||
@cliutils.arg(
|
||||
'--all-tenants',
|
||||
dest='all_tenants',
|
||||
|
Loading…
x
Reference in New Issue
Block a user