Skip to content

Commit df6f5c3

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "api: Add response body schemas for volume attachments APIs"
2 parents c5ebda4 + 0dbc190 commit df6f5c3

2 files changed

Lines changed: 148 additions & 0 deletions

File tree

nova/api/openstack/compute/schemas/volume_attachments.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,135 @@
100100
'properties': {},
101101
'additionalProperties': True,
102102
}
103+
104+
_volume_attachment_response = {
105+
'type': 'object',
106+
'properties': {
107+
'id': parameter_types.volume_id,
108+
'device': {
109+
'type': ['string', 'null'],
110+
# NOTE: The validation pattern from match_device() in
111+
# nova/block_device.py.
112+
'pattern': '(^/dev/x{0,1}[a-z]{0,1}d{0,1})([a-z]+)[0-9]*$'
113+
},
114+
'serverId': parameter_types.server_id,
115+
'volumeId': parameter_types.volume_id,
116+
},
117+
'required': ['id', 'serverId', 'volumeId'],
118+
'additionalProperties': False,
119+
}
120+
121+
_volume_attachment_response_v270 = copy.deepcopy(_volume_attachment_response)
122+
_volume_attachment_response_v270['properties'].update({
123+
'tag': {
124+
'oneOf': [
125+
parameter_types.tag,
126+
{'type': 'null'},
127+
],
128+
},
129+
})
130+
_volume_attachment_response_v270['required'].append('tag')
131+
132+
_volume_attachment_response_v279 = copy.deepcopy(
133+
_volume_attachment_response_v270
134+
)
135+
_volume_attachment_response_v279['properties'].update({
136+
'delete_on_termination': parameter_types.boolean,
137+
})
138+
_volume_attachment_response_v279['required'].append('delete_on_termination')
139+
140+
_volume_attachment_response_v289 = copy.deepcopy(
141+
_volume_attachment_response_v279
142+
)
143+
del _volume_attachment_response_v289['properties']['id']
144+
_volume_attachment_response_v289['properties'].update({
145+
'attachment_id': parameter_types.attachment_id,
146+
'bdm_uuid': {'type': 'string', 'format': 'uuid'},
147+
})
148+
_volume_attachment_response_v289['required'].pop(
149+
_volume_attachment_response_v289['required'].index('id')
150+
)
151+
_volume_attachment_response_v289['required'].extend(
152+
['attachment_id', 'bdm_uuid']
153+
)
154+
155+
index_response = {
156+
'type': 'object',
157+
'properties': {
158+
'volumeAttachments': {
159+
'type': 'array',
160+
'items': _volume_attachment_response,
161+
},
162+
},
163+
'required': ['volumeAttachments'],
164+
'additionalProperties': False,
165+
}
166+
167+
index_response_v270 = copy.deepcopy(index_response)
168+
index_response_v270['properties']['volumeAttachments']['items'] = (
169+
_volume_attachment_response_v270
170+
)
171+
172+
index_response_v279 = copy.deepcopy(index_response_v270)
173+
index_response_v279['properties']['volumeAttachments']['items'] = (
174+
_volume_attachment_response_v279
175+
)
176+
177+
index_response_v289 = copy.deepcopy(index_response_v279)
178+
index_response_v289['properties']['volumeAttachments']['items'] = (
179+
_volume_attachment_response_v289
180+
)
181+
182+
show_response = {
183+
'type': 'object',
184+
'properties': {
185+
'volumeAttachment': _volume_attachment_response,
186+
},
187+
'required': ['volumeAttachment'],
188+
'additionalProperties': False,
189+
}
190+
191+
show_response_v270 = copy.deepcopy(show_response)
192+
show_response_v270['properties']['volumeAttachment'] = (
193+
_volume_attachment_response_v270
194+
)
195+
196+
show_response_v279 = copy.deepcopy(show_response_v270)
197+
show_response_v279['properties']['volumeAttachment'] = (
198+
_volume_attachment_response_v279
199+
)
200+
201+
show_response_v289 = copy.deepcopy(show_response_v279)
202+
show_response_v289['properties']['volumeAttachment'] = (
203+
_volume_attachment_response_v289
204+
)
205+
206+
create_response = {
207+
'type': 'object',
208+
'properties': {
209+
'volumeAttachment': _volume_attachment_response,
210+
},
211+
'required': ['volumeAttachment'],
212+
'additionalProperties': False,
213+
}
214+
215+
create_response_v270 = copy.deepcopy(create_response)
216+
create_response_v270['properties']['volumeAttachment'] = copy.deepcopy(
217+
_volume_attachment_response_v270
218+
)
219+
# device is always shown in create responses, even if null
220+
create_response_v270['properties']['volumeAttachment'][
221+
'required'
222+
].append('device')
223+
224+
create_response_v279 = copy.deepcopy(create_response_v270)
225+
create_response_v279['properties']['volumeAttachment'] = copy.deepcopy(
226+
_volume_attachment_response_v279
227+
)
228+
create_response_v279['properties']['volumeAttachment'][
229+
'required'
230+
].append('device')
231+
232+
update_response = {'type': 'null'}
233+
234+
delete_response = {'type': 'null'}

nova/api/openstack/compute/volume_attachments.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ def _check_request_version(req, min_version, method, server_id, server_state):
8888
exc_inv, method, server_id)
8989

9090

91+
@validation.validated
9192
class VolumeAttachmentController(wsgi.Controller):
9293
"""The volume attachment API controller for the OpenStack API.
9394
@@ -104,6 +105,10 @@ def __init__(self):
104105
@wsgi.expected_errors(404)
105106
@validation.query_schema(schema.index_query, '2.0', '2.74')
106107
@validation.query_schema(schema.index_query_v275, '2.75')
108+
@validation.response_body_schema(schema.index_response, '2.0', '2.69')
109+
@validation.response_body_schema(schema.index_response_v270, '2.70', '2.78') # noqa: E501
110+
@validation.response_body_schema(schema.index_response_v279, '2.79', '2.88') # noqa: E501
111+
@validation.response_body_schema(schema.index_response_v289, '2.89')
107112
def index(self, req, server_id):
108113
"""Returns the list of volume attachments for a given instance."""
109114
context = req.environ['nova.context']
@@ -136,6 +141,10 @@ def index(self, req, server_id):
136141

137142
@wsgi.expected_errors(404)
138143
@validation.query_schema(schema.show_query)
144+
@validation.response_body_schema(schema.show_response, '2.0', '2.69')
145+
@validation.response_body_schema(schema.show_response_v270, '2.70', '2.78') # noqa: E501
146+
@validation.response_body_schema(schema.show_response_v279, '2.79', '2.88') # noqa: E501
147+
@validation.response_body_schema(schema.show_response_v289, '2.89')
139148
def show(self, req, server_id, id):
140149
"""Return data about the given volume attachment."""
141150
context = req.environ['nova.context']
@@ -175,6 +184,9 @@ def show(self, req, server_id, id):
175184
@validation.schema(schema.create, '2.0', '2.48')
176185
@validation.schema(schema.create_v249, '2.49', '2.78')
177186
@validation.schema(schema.create_v279, '2.79')
187+
@validation.response_body_schema(schema.create_response, '2.0', '2.69')
188+
@validation.response_body_schema(schema.create_response_v270, '2.70', '2.78') # noqa: E501
189+
@validation.response_body_schema(schema.create_response_v279, '2.79')
178190
def create(self, req, server_id, body):
179191
"""Attach a volume to an instance."""
180192
context = req.environ['nova.context']
@@ -234,6 +246,8 @@ def create(self, req, server_id, body):
234246
attachment['tag'] = tag
235247
if api_version_request.is_supported(req, '2.79'):
236248
attachment['delete_on_termination'] = delete_on_termination
249+
# TODO(stephenfin): We forgot to apply 2.89 here. We should return
250+
# 'bdm_uuid' and 'attachment_id' and stop returning 'id'
237251
return {'volumeAttachment': attachment}
238252

239253
def _update_volume_swap(self, req, instance, id, body):
@@ -318,6 +332,7 @@ def _update_volume_regular(self, req, instance, id, body):
318332
@wsgi.expected_errors((400, 404, 409))
319333
@validation.schema(schema.update, '2.0', '2.84')
320334
@validation.schema(schema.update_v285, '2.85')
335+
@validation.response_body_schema(schema.update_response)
321336
def update(self, req, server_id, id, body):
322337
context = req.environ['nova.context']
323338
instance = common.get_instance(self.compute_api, context, server_id)
@@ -348,6 +363,7 @@ def update(self, req, server_id, id, body):
348363

349364
@wsgi.response(202)
350365
@wsgi.expected_errors((400, 403, 404, 409))
366+
@validation.response_body_schema(schema.delete_response)
351367
def delete(self, req, server_id, id):
352368
"""Detach a volume from an instance."""
353369
context = req.environ['nova.context']

0 commit comments

Comments
 (0)