Skip to content

Commit 6dc94e1

Browse files
committed
volume: Add 'volume attachment *' commands
These mirror the 'cinder attachment-*' commands, with arguments copied across essentially verbatim. The only significant departure is the replacement of "tenant" terminology with "project". volume attachment create volume attachment delete volume attachment list volume attachment complete volume attachment set volume attachment show Full support for filtering is deferred for now since that's a more complicated change that requires additional commands be added first. TODOs are included to this effect. Change-Id: If47c2b56fe65ee2cee07c000d6ae3688d5ef3b42 Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
1 parent 0f28588 commit 6dc94e1

8 files changed

Lines changed: 1259 additions & 9 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
=================
2+
volume attachment
3+
=================
4+
5+
Block Storage v3
6+
7+
.. autoprogram-cliff:: openstack.volume.v3
8+
:command: volume attachment *

doc/source/cli/commands.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,12 @@ referring to both Compute and Volume quotas.
153153
* ``user``: (**Identity**) individual cloud resources users
154154
* ``user role``: (**Identity**) roles assigned to a user
155155
* ``volume``: (**Volume**) block volumes
156+
* ``volume attachment``: (**Volume**) an attachment of a volumes to a server
156157
* ``volume backup``: (**Volume**) backup for volumes
157-
* ``volume backend capability``: (**volume**) volume backend storage capabilities
158-
* ``volume backend pool``: (**volume**) volume backend storage pools
158+
* ``volume backend capability``: (**Volume**) volume backend storage capabilities
159+
* ``volume backend pool``: (**Volume**) volume backend storage pools
159160
* ``volume backup record``: (**Volume**) volume record that can be imported or exported
160-
* ``volume backend``: (**volume**) volume backend storage
161+
* ``volume backend``: (**Volume**) volume backend storage
161162
* ``volume host``: (**Volume**) the physical computer for volumes
162163
* ``volume qos``: (**Volume**) quality-of-service (QoS) specification for volumes
163164
* ``volume snapshot``: (**Volume**) a point-in-time copy of a volume

doc/source/cli/data/cinder.csv

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
absolute-limits,limits show --absolute,Lists absolute limits for a user.
22
api-version,WONTFIX,Display the server API version information.
33
availability-zone-list,availability zone list --volume,Lists all availability zones.
4-
attachment-complete,,Complete an attachment for a cinder volume. (Supported by API versions 3.44 - 3.latest)
5-
attachment-create,,Create an attachment for a cinder volume. (Supported by API versions 3.27 - 3.latest)
6-
attachment-delete,,Delete an attachment for a cinder volume. (Supported by API versions 3.27 - 3.latest)
7-
attachment-list,,Lists all attachments. (Supported by API versions 3.27 - 3.latest)
8-
attachment-show,,Show detailed information for attachment. (Supported by API versions 3.27 - 3.latest)
9-
attachment-update,,Update an attachment for a cinder volume. (Supported by API versions 3.27 - 3.latest)
4+
attachment-complete,volume attachment complete,Complete an attachment for a cinder volume. (Supported by API versions 3.44 - 3.latest)
5+
attachment-create,volume attachment create,Create an attachment for a cinder volume. (Supported by API versions 3.27 - 3.latest)
6+
attachment-delete,volume attachment delete,Delete an attachment for a cinder volume. (Supported by API versions 3.27 - 3.latest)
7+
attachment-list,volume attachment list,Lists all attachments. (Supported by API versions 3.27 - 3.latest)
8+
attachment-show,volume attachment show,Show detailed information for attachment. (Supported by API versions 3.27 - 3.latest)
9+
attachment-update,volume attachment update,Update an attachment for a cinder volume. (Supported by API versions 3.27 - 3.latest)
1010
backup-create,volume backup create,Creates a volume backup.
1111
backup-delete,volume backup delete,Removes a backup.
1212
backup-export,volume backup record export,Export backup metadata record.
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
import random
14+
from unittest import mock
15+
import uuid
16+
17+
from cinderclient import api_versions
18+
19+
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
20+
from openstackclient.tests.unit import fakes
21+
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
22+
from openstackclient.tests.unit import utils
23+
from openstackclient.tests.unit.volume.v2 import fakes as volume_v2_fakes
24+
25+
26+
class FakeVolumeClient(object):
27+
28+
def __init__(self, **kwargs):
29+
self.auth_token = kwargs['token']
30+
self.management_url = kwargs['endpoint']
31+
self.api_version = api_versions.APIVersion('3.0')
32+
33+
self.attachments = mock.Mock()
34+
self.attachments.resource_class = fakes.FakeResource(None, {})
35+
self.volumes = mock.Mock()
36+
self.volumes.resource_class = fakes.FakeResource(None, {})
37+
38+
39+
class TestVolume(utils.TestCommand):
40+
41+
def setUp(self):
42+
super().setUp()
43+
44+
self.app.client_manager.volume = FakeVolumeClient(
45+
endpoint=fakes.AUTH_URL,
46+
token=fakes.AUTH_TOKEN
47+
)
48+
self.app.client_manager.identity = identity_fakes.FakeIdentityv3Client(
49+
endpoint=fakes.AUTH_URL,
50+
token=fakes.AUTH_TOKEN
51+
)
52+
self.app.client_manager.compute = compute_fakes.FakeComputev2Client(
53+
endpoint=fakes.AUTH_URL,
54+
token=fakes.AUTH_TOKEN,
55+
)
56+
57+
58+
# TODO(stephenfin): Check if the responses are actually the same
59+
FakeVolume = volume_v2_fakes.FakeVolume
60+
61+
62+
class FakeVolumeAttachment:
63+
"""Fake one or more volume attachments."""
64+
65+
@staticmethod
66+
def create_one_volume_attachment(attrs=None):
67+
"""Create a fake volume attachment.
68+
69+
:param attrs: A dictionary with all attributes of volume attachment
70+
:return: A FakeResource object with id, status, etc.
71+
"""
72+
attrs = attrs or {}
73+
74+
attachment_id = uuid.uuid4().hex
75+
volume_id = attrs.pop('volume_id', None) or uuid.uuid4().hex
76+
server_id = attrs.pop('instance', None) or uuid.uuid4().hex
77+
78+
# Set default attribute
79+
attachment_info = {
80+
'id': attachment_id,
81+
'volume_id': volume_id,
82+
'instance': server_id,
83+
'status': random.choice([
84+
'attached',
85+
'attaching',
86+
'detached',
87+
'reserved',
88+
'error_attaching',
89+
'error_detaching',
90+
'deleted',
91+
]),
92+
'attach_mode': random.choice(['ro', 'rw']),
93+
'attached_at': '2015-09-16T09:28:52.000000',
94+
'detached_at': None,
95+
'connection_info': {
96+
'access_mode': 'rw',
97+
'attachment_id': attachment_id,
98+
'auth_method': 'CHAP',
99+
'auth_password': 'AcUZ8PpxLHwzypMC',
100+
'auth_username': '7j3EZQWT3rbE6pcSGKvK',
101+
'cacheable': False,
102+
'driver_volume_type': 'iscsi',
103+
'encrypted': False,
104+
'qos_specs': None,
105+
'target_discovered': False,
106+
'target_iqn':
107+
f'iqn.2010-10.org.openstack:volume-{attachment_id}',
108+
'target_lun': '1',
109+
'target_portal': '192.168.122.170:3260',
110+
'volume_id': volume_id,
111+
},
112+
}
113+
114+
# Overwrite default attributes if there are some attributes set
115+
attachment_info.update(attrs)
116+
117+
attachment = fakes.FakeResource(
118+
None,
119+
attachment_info,
120+
loaded=True)
121+
return attachment
122+
123+
@staticmethod
124+
def create_volume_attachments(attrs=None, count=2):
125+
"""Create multiple fake volume attachments.
126+
127+
:param attrs: A dictionary with all attributes of volume attachment
128+
:param count: The number of volume attachments to be faked
129+
:return: A list of FakeResource objects
130+
"""
131+
attachments = []
132+
133+
for n in range(0, count):
134+
attachments.append(
135+
FakeVolumeAttachment.create_one_volume_attachment(attrs))
136+
137+
return attachments
138+
139+
@staticmethod
140+
def get_volume_attachments(attachments=None, count=2):
141+
"""Get an iterable MagicMock object with a list of faked volumes.
142+
143+
If attachments list is provided, then initialize the Mock object with
144+
the list. Otherwise create one.
145+
146+
:param attachments: A list of FakeResource objects faking volume
147+
attachments
148+
:param count: The number of volume attachments to be faked
149+
:return An iterable Mock object with side_effect set to a list of faked
150+
volume attachments
151+
"""
152+
if attachments is None:
153+
attachments = FakeVolumeAttachment.create_volume_attachments(count)
154+
155+
return mock.Mock(side_effect=attachments)

0 commit comments

Comments
 (0)