Statistics
| Branch: | Tag: | Revision:

root / api / images.py @ d8e50a39

History | View | Annotate | Download (5.1 kB)

1
#
2
# Copyright (c) 2010 Greek Research and Technology Network
3
#
4

    
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
7
from synnefo.db.models import Image, ImageMetadata, VirtualMachine
8

    
9
from django.conf.urls.defaults import patterns
10
from django.http import HttpResponse
11
from django.template.loader import render_to_string
12
from django.utils import simplejson as json
13

    
14

    
15
urlpatterns = patterns('synnefo.api.images',
16
    (r'^(?:/|.json|.xml)?$', 'demux'),
17
    (r'^/detail(?:.json|.xml)?$', 'list_images', {'detail': True}),
18
    (r'^/(\d+)(?:.json|.xml)?$', 'image_demux'),
19
)
20

    
21
def demux(request):
22
    if request.method == 'GET':
23
        return list_images(request)
24
    elif request.method == 'POST':
25
        return create_image(request)
26
    else:
27
        return method_not_allowed(request)
28

    
29
def image_demux(request, image_id):
30
    if request.method == 'GET':
31
        return get_image_details(request, image_id)
32
    elif request.method == 'DELETE':
33
        return delete_image(request, image_id)
34
    else:
35
        return method_not_allowed(request)
36

    
37

    
38
def image_to_dict(image, detail=True):
39
    d = {'id': image.id, 'name': image.name}
40
    if detail:
41
        d['updated'] = isoformat(image.updated)
42
        d['created'] = isoformat(image.created)
43
        d['status'] = image.state
44
        d['progress'] = 100 if image.state == 'ACTIVE' else 0
45
        d['description'] = image.description
46
        if image.sourcevm:
47
            d['serverRef'] = image.sourcevm.id
48
        
49
        metadata = {}
50
        for meta in ImageMetadata.objects.filter(image=image):
51
            metadata[meta.meta_key] = meta.meta_value
52
        
53
        if metadata:
54
            d['metadata'] = {'values': metadata}
55
    
56
    return d
57

    
58

    
59
@api_method('GET')
60
def list_images(request, detail=False):
61
    # Normal Response Codes: 200, 203
62
    # Error Response Codes: computeFault (400, 500),
63
    #                       serviceUnavailable (503),
64
    #                       unauthorized (401),
65
    #                       badRequest (400),
66
    #                       overLimit (413)
67
    
68
    since = isoparse(request.GET.get('changes-since'))
69
    
70
    if since:
71
        avail_images = Image.objects.filter(updated__gt=since)
72
        if not avail_images:
73
            return HttpResponse(status=304)
74
    else:
75
        avail_images = Image.objects.all()
76
    
77
    images = [image_to_dict(image, detail) for image in avail_images]
78
    
79
    if request.serialization == 'xml':
80
        data = render_to_string('list_images.xml', {'images': images, 'detail': detail})
81
    else:
82
        data = json.dumps({'images': {'values': images}})
83
    
84
    return HttpResponse(data, status=200)
85

    
86
@api_method('POST')
87
def create_image(request):
88
    # Normal Response Code: 202
89
    # Error Response Codes: computeFault (400, 500),
90
    #                       serviceUnavailable (503),
91
    #                       unauthorized (401),
92
    #                       badMediaType(415),
93
    #                       itemNotFound (404),
94
    #                       badRequest (400),
95
    #                       serverCapacityUnavailable (503),
96
    #                       buildInProgress (409),
97
    #                       resizeNotAllowed (403),
98
    #                       backupOrResizeInProgress (409),
99
    #                       overLimit (413)
100
    
101
    req = get_request_dict(request)
102
    owner = get_user()
103
    
104
    try:
105
        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
116
    
117
    imagedict = image_to_dict(image)
118
    if request.serialization == 'xml':
119
        data = render_to_string('image.xml', {'image': imagedict})
120
    else:
121
        data = json.dumps({'image': imagedict})
122
    
123
    return HttpResponse(data, status=202)
124

    
125
@api_method('GET')
126
def get_image_details(request, image_id):
127
    # Normal Response Codes: 200, 203
128
    # Error Response Codes: computeFault (400, 500),
129
    #                       serviceUnavailable (503),
130
    #                       unauthorized (401),
131
    #                       badRequest (400),
132
    #                       itemNotFound (404),
133
    #                       overLimit (413)
134
    
135
    image = get_image(image_id)
136
    imagedict = image_to_dict(image)
137
    
138
    if request.serialization == 'xml':
139
        data = render_to_string('image.xml', {'image': imagedict})
140
    else:
141
        data = json.dumps({'image': imagedict})
142
    
143
    return HttpResponse(data, status=200)
144

    
145
@api_method('DELETE')
146
def delete_image(request, image_id):
147
    # Normal Response Code: 204
148
    # Error Response Codes: computeFault (400, 500),
149
    #                       serviceUnavailable (503),
150
    #                       unauthorized (401),
151
    #                       itemNotFound (404),
152
    #                       overLimit (413)
153
    
154
    image = get_image(image_id)
155
    if image.owner != get_user():
156
        raise Unauthorized()
157
    image.delete()
158
    return HttpResponse(status=204)