Skip to content

Commit 34d06db

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Add share commands to compute"
2 parents 9e7f604 + ce4fcd3 commit 34d06db

5 files changed

Lines changed: 586 additions & 0 deletions

File tree

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
# Copyright 2020, Red Hat Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
15+
"""Compute v2 Server action implementations"""
16+
17+
from openstack import utils as sdk_utils
18+
from osc_lib import exceptions
19+
from osc_lib import utils
20+
21+
from openstackclient import command
22+
from openstackclient.i18n import _
23+
24+
25+
def _get_server_share_columns(item):
26+
# Non admin cannot see uuid and export location, so hide them
27+
if item.uuid is None:
28+
column_map = {
29+
'share_id': 'Share ID',
30+
'status': 'Status',
31+
'tag': 'Tag',
32+
}
33+
hidden_columns = [
34+
'id',
35+
'location',
36+
'name',
37+
'uuid',
38+
'export_location',
39+
'share_proto',
40+
]
41+
else:
42+
column_map = {
43+
'uuid': 'UUID',
44+
'share_id': 'Share ID',
45+
'status': 'Status',
46+
'tag': 'Tag',
47+
'export_location': 'Export Location',
48+
}
49+
hidden_columns = ['id', 'location', 'name', 'share_proto']
50+
51+
return utils.get_osc_show_columns_for_sdk_resource(
52+
item, column_map, hidden_columns
53+
)
54+
55+
56+
class ListServerShare(command.Lister):
57+
"""List all the shares attached to a server.
58+
59+
Requires ``--os-compute-api-version 2.97`` or later.
60+
"""
61+
62+
def get_parser(self, prog_name):
63+
parser = super().get_parser(prog_name)
64+
parser.add_argument(
65+
'server',
66+
metavar='<server>',
67+
help=_('Server to list share mapping for (name or ID)'),
68+
)
69+
return parser
70+
71+
def take_action(self, parsed_args):
72+
compute_client = self.app.client_manager.compute
73+
74+
if not sdk_utils.supports_microversion(compute_client, '2.97'):
75+
msg = _(
76+
'--os-compute-api-version 2.97 or greater is required '
77+
'to support share attachments'
78+
)
79+
raise exceptions.CommandError(msg)
80+
81+
server = compute_client.find_server(
82+
parsed_args.server,
83+
ignore_missing=False,
84+
)
85+
shares = compute_client.share_attachments(server)
86+
87+
columns = (
88+
'share_id',
89+
'status',
90+
'tag',
91+
)
92+
column_headers = (
93+
'Share ID',
94+
'Status',
95+
'Tag',
96+
)
97+
98+
return (
99+
column_headers,
100+
(utils.get_item_properties(s, columns) for s in shares),
101+
)
102+
103+
104+
class ShowServerShare(command.ShowOne):
105+
"""Show detail of a share attachment to a server.
106+
107+
Requires ``--os-compute-api-version 2.97`` or later.
108+
"""
109+
110+
def get_parser(self, prog_name):
111+
parser = super().get_parser(prog_name)
112+
parser.add_argument(
113+
'server',
114+
metavar='<server>',
115+
help=_('Server to show share mapping for (name or ID)'),
116+
)
117+
parser.add_argument(
118+
'share',
119+
metavar='<share>',
120+
help=_('Share to show details for (name or ID)'),
121+
)
122+
return parser
123+
124+
def take_action(self, parsed_args):
125+
compute_client = self.app.client_manager.compute
126+
shared_file_system_client = (
127+
self.app.client_manager.sdk_connection.shared_file_system
128+
)
129+
130+
if not sdk_utils.supports_microversion(compute_client, '2.97'):
131+
msg = _(
132+
'--os-compute-api-version 2.97 or greater is required '
133+
'to support share attachments'
134+
)
135+
raise exceptions.CommandError(msg)
136+
137+
server = compute_client.find_server(
138+
parsed_args.server,
139+
ignore_missing=False,
140+
)
141+
share = shared_file_system_client.find_share(
142+
parsed_args.share,
143+
ignore_missing=False,
144+
)
145+
share_attachment = compute_client.get_share_attachment(
146+
server, share.id
147+
)
148+
149+
display_columns, columns = _get_server_share_columns(
150+
share_attachment,
151+
)
152+
data = utils.get_item_properties(share_attachment, columns)
153+
return display_columns, data
154+
155+
156+
class AddServerShare(command.ShowOne):
157+
"""Add a share to a server.
158+
159+
Requires ``--os-compute-api-version 2.97`` or later.
160+
"""
161+
162+
def get_parser(self, prog_name):
163+
parser = super().get_parser(prog_name)
164+
parser.add_argument(
165+
'server',
166+
metavar='<server>',
167+
help=_('Server to add share to (name or ID)'),
168+
)
169+
parser.add_argument(
170+
'share',
171+
metavar='<share>',
172+
help=_('Share to add (name or ID)'),
173+
)
174+
parser.add_argument(
175+
'--tag',
176+
metavar='<tag>',
177+
help=_(
178+
'Optional tag used to mount the share, '
179+
'if not provided the share uuid is used as tag by default'
180+
),
181+
)
182+
return parser
183+
184+
def take_action(self, parsed_args):
185+
compute_client = self.app.client_manager.compute
186+
shared_file_system_client = (
187+
self.app.client_manager.sdk_connection.shared_file_system
188+
)
189+
190+
if not sdk_utils.supports_microversion(compute_client, '2.97'):
191+
msg = _(
192+
'--os-compute-api-version 2.97 or greater is required '
193+
'to support share attachments'
194+
)
195+
raise exceptions.CommandError(msg)
196+
197+
server = compute_client.find_server(
198+
parsed_args.server,
199+
ignore_missing=False,
200+
)
201+
share = shared_file_system_client.find_share(
202+
parsed_args.share,
203+
ignore_missing=False,
204+
)
205+
206+
kwargs = {}
207+
if parsed_args.tag:
208+
kwargs['tag'] = parsed_args.tag
209+
210+
share_attachment = compute_client.create_share_attachment(
211+
server, share.id, **kwargs
212+
)
213+
214+
display_columns, columns = _get_server_share_columns(
215+
share_attachment,
216+
)
217+
data = utils.get_item_properties(share_attachment, columns)
218+
return display_columns, data
219+
220+
221+
class RemoveServerShare(command.Command):
222+
"""Remove a share from a server.
223+
224+
Requires ``--os-compute-api-version 2.97`` or later.
225+
"""
226+
227+
def get_parser(self, prog_name):
228+
parser = super().get_parser(prog_name)
229+
parser.add_argument(
230+
'server',
231+
metavar='<server>',
232+
help=_('Server to remove share from (name or ID)'),
233+
)
234+
parser.add_argument(
235+
'share',
236+
metavar='<share>',
237+
help=_('Share to remove (name or ID)'),
238+
)
239+
return parser
240+
241+
def take_action(self, parsed_args):
242+
compute_client = self.app.client_manager.compute
243+
shared_file_system_client = (
244+
self.app.client_manager.sdk_connection.shared_file_system
245+
)
246+
247+
if not sdk_utils.supports_microversion(compute_client, '2.97'):
248+
msg = _(
249+
'--os-compute-api-version 2.97 or greater is required '
250+
'to support share attachments'
251+
)
252+
raise exceptions.CommandError(msg)
253+
254+
server = compute_client.find_server(
255+
parsed_args.server,
256+
ignore_missing=False,
257+
)
258+
share = shared_file_system_client.find_share(
259+
parsed_args.share,
260+
ignore_missing=False,
261+
)
262+
compute_client.delete_share_attachment(server, share.id)

openstackclient/tests/unit/compute/v2/fakes.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
from openstack.compute.v2 import server_action as _server_action
3030
from openstack.compute.v2 import server_interface as _server_interface
3131
from openstack.compute.v2 import server_migration as _server_migration
32+
from openstack.compute.v2 import server_share as _server_share
3233
from openstack.compute.v2 import volume_attachment as _volume_attachment
34+
from openstack.test import fakes as sdk_fakes
3335

3436
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
3537
from openstackclient.tests.unit.image.v2 import fakes as image_fakes
@@ -788,6 +790,29 @@ def create_volume_attachments(attrs=None, count=2):
788790
return volume_attachments
789791

790792

793+
def create_one_share(attrs=None):
794+
"""Create a fake share attachment.
795+
796+
:param dict attrs: A dictionary with all attributes
797+
:return: A fake openstack.compute.v2.server_share.ShareMapping
798+
object
799+
"""
800+
return sdk_fakes.generate_fake_resource(
801+
_server_share.ShareMapping, **(attrs or {})
802+
)
803+
804+
805+
def create_shares(attrs=None, count=2):
806+
"""Create multiple fake share attachments.
807+
808+
:param dict attrs: A dictionary with all attributes
809+
:param int count: The number of share attachments to fake
810+
:return: A list of fake
811+
openstack.compute.v2.server_share.ShareMapping objects
812+
"""
813+
return [create_one_share(attrs) for _ in range(count)]
814+
815+
791816
def create_one_server_interface(attrs=None):
792817
"""Create a fake ServerInterface.
793818

0 commit comments

Comments
 (0)