Revision 432fc8c3 api/images.py

b/api/images.py
3 3
#
4 4

  
5 5
from synnefo.api.common import method_not_allowed
6
from synnefo.api.util import isoformat, isoparse, get_user, get_image, get_request_dict, api_method
6
from synnefo.api.util import *
7 7
from synnefo.db.models import Image, ImageMetadata, VirtualMachine
8 8

  
9 9
from django.conf.urls.defaults import patterns
......
16 16
    (r'^(?:/|.json|.xml)?$', 'demux'),
17 17
    (r'^/detail(?:.json|.xml)?$', 'list_images', {'detail': True}),
18 18
    (r'^/(\d+)(?:.json|.xml)?$', 'image_demux'),
19
    (r'^/(\d+)/meta(?:.json|.xml)?$', 'metadata_demux'),
20
    (r'^/(\d+)/meta/(.+?)(?:.json|.xml)?$', 'metadata_item_demux'),
19 21
)
20 22

  
21 23
def demux(request):
......
34 36
    else:
35 37
        return method_not_allowed(request)
36 38

  
39
def metadata_demux(request, image_id):
40
    if request.method == 'GET':
41
        return list_metadata(request, image_id)
42
    elif request.method == 'POST':
43
        return update_metadata(request, image_id)
44
    else:
45
        return method_not_allowed(request)
46

  
47
def metadata_item_demux(request, image_id, key):
48
    if request.method == 'GET':
49
        return get_metadata_item(request, image_id, key)
50
    elif request.method == 'PUT':
51
        return create_metadata_item(request, image_id, key)
52
    elif request.method == 'DELETE':
53
        return delete_metadata_item(request, image_id, key)
54
    else:
55
        return method_not_allowed(request)
56

  
37 57

  
38 58
def image_to_dict(image, detail=True):
39 59
    d = {'id': image.id, 'name': image.name}
......
55 75
    
56 76
    return d
57 77

  
78
def metadata_to_dict(image):
79
    image_meta = image.imagemetadata_set.all()
80
    return dict((meta.meta_key, meta.meta_value) for meta in image_meta)
81

  
58 82

  
59 83
@api_method('GET')
60 84
def list_images(request, detail=False):
......
99 123
    #                       overLimit (413)
100 124
    
101 125
    req = get_request_dict(request)
102
    owner = get_user()
103 126
    
104 127
    try:
105 128
        d = req['image']
106
        server_id = int(d['serverRef'])
107
        vm = VirtualMachine.objects.get(id=server_id)
108
        image = Image.objects.create(name=d['name'], size=0, owner=owner, sourcevm=vm)
109
        image.save()
110
    except KeyError:
111
        raise BadRequest
112
    except ValueError:
113
        raise BadRequest
114
    except VirtualMachine.DoesNotExist:
115
        raise ItemNotFound
129
        server_id = d['serverRef']
130
        name = d['name']
131
    except (KeyError, ValueError):
132
        raise BadRequest('Malformed request.')
133
    
134
    owner = get_user()
135
    vm = get_vm(server_id)
136
    image = Image.objects.create(name=name, size=0, owner=owner, sourcevm=vm)
137
    image.save()
116 138
    
117 139
    imagedict = image_to_dict(image)
118 140
    if request.serialization == 'xml':
......
156 178
        raise Unauthorized()
157 179
    image.delete()
158 180
    return HttpResponse(status=204)
181

  
182
@api_method('GET')
183
def list_metadata(request, image_id):
184
    # Normal Response Codes: 200, 203
185
    # Error Response Codes: computeFault (400, 500),
186
    #                       serviceUnavailable (503),
187
    #                       unauthorized (401),
188
    #                       badRequest (400),
189
    #                       overLimit (413)
190

  
191
    image = get_image(image_id)
192
    metadata = metadata_to_dict(image)
193
    return render_metadata(request, metadata, use_values=True, status=200)
194

  
195
@api_method('POST')
196
def update_metadata(request, image_id):
197
    # Normal Response Code: 201
198
    # Error Response Codes: computeFault (400, 500),
199
    #                       serviceUnavailable (503),
200
    #                       unauthorized (401),
201
    #                       badRequest (400),
202
    #                       buildInProgress (409),
203
    #                       badMediaType(415),
204
    #                       overLimit (413)
205

  
206
    image = get_image(image_id)
207
    req = get_request_dict(request)
208
    try:
209
        metadata = req['metadata']
210
        assert isinstance(metadata, dict)
211
    except (KeyError, AssertionError):
212
        raise BadRequest('Malformed request.')
213

  
214
    updated = {}
215

  
216
    for key, val in metadata.items():
217
        try:
218
            meta = ImageMetadata.objects.get(meta_key=key, image=image)
219
            meta.meta_value = val
220
            meta.save()
221
            updated[key] = val
222
        except ImageMetadata.DoesNotExist:
223
            pass    # Ignore non-existent metadata
224

  
225
    return render_metadata(request, metadata, status=201)
226

  
227
@api_method('GET')
228
def get_metadata_item(request, image_id, key):
229
    # Normal Response Codes: 200, 203
230
    # Error Response Codes: computeFault (400, 500),
231
    #                       serviceUnavailable (503),
232
    #                       unauthorized (401),
233
    #                       itemNotFound (404),
234
    #                       badRequest (400),
235
    #                       overLimit (413)
236

  
237
    meta = get_image_meta(image_id, key)
238
    return render_meta(request, meta, status=200)
239

  
240
@api_method('PUT')
241
def create_metadata_item(request, image_id, key):
242
    # Normal Response Code: 201
243
    # Error Response Codes: computeFault (400, 500),
244
    #                       serviceUnavailable (503),
245
    #                       unauthorized (401),
246
    #                       itemNotFound (404),
247
    #                       badRequest (400),
248
    #                       buildInProgress (409),
249
    #                       badMediaType(415),
250
    #                       overLimit (413)
251

  
252
    image = get_image(image_id)
253
    req = get_request_dict(request)
254
    try:
255
        metadict = req['meta']
256
        assert isinstance(metadict, dict)
257
        assert len(metadict) == 1
258
        assert key in metadict
259
    except (KeyError, AssertionError):
260
        raise BadRequest('Malformed request.')
261

  
262
    meta, created = ImageMetadata.objects.get_or_create(meta_key=key, image=image)
263
    meta.meta_value = metadict[key]
264
    meta.save()
265
    return render_meta(request, meta, status=201)
266

  
267
@api_method('DELETE')
268
def delete_metadata_item(request, image_id, key):
269
    # Normal Response Code: 204
270
    # Error Response Codes: computeFault (400, 500),
271
    #                       serviceUnavailable (503),
272
    #                       unauthorized (401),
273
    #                       itemNotFound (404),
274
    #                       badRequest (400),
275
    #                       buildInProgress (409),
276
    #                       badMediaType(415),
277
    #                       overLimit (413),
278

  
279
    meta = get_image_meta(image_id, key)
280
    meta.delete()
281
    return HttpResponse(status=204)

Also available in: Unified diff