Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / util.py @ 6dd70a5c

History | View | Annotate | Download (11.9 kB)

1 6ef51e9f Giorgos Verigakis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 d1387ed7 Christodoulos Psaltis
#
3 adee02b8 Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
4 adee02b8 Giorgos Verigakis
# without modification, are permitted provided that the following
5 adee02b8 Giorgos Verigakis
# conditions are met:
6 d1387ed7 Christodoulos Psaltis
#
7 adee02b8 Giorgos Verigakis
#   1. Redistributions of source code must retain the above
8 adee02b8 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
9 adee02b8 Giorgos Verigakis
#      disclaimer.
10 d1387ed7 Christodoulos Psaltis
#
11 adee02b8 Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
12 adee02b8 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
13 adee02b8 Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
14 adee02b8 Giorgos Verigakis
#      provided with the distribution.
15 d1387ed7 Christodoulos Psaltis
#
16 adee02b8 Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 adee02b8 Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 adee02b8 Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 adee02b8 Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 adee02b8 Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 adee02b8 Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 adee02b8 Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 adee02b8 Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 adee02b8 Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 adee02b8 Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 adee02b8 Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 adee02b8 Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
28 d1387ed7 Christodoulos Psaltis
#
29 adee02b8 Giorgos Verigakis
# The views and conclusions contained in the software and
30 adee02b8 Giorgos Verigakis
# documentation are those of the authors and should not be
31 adee02b8 Giorgos Verigakis
# interpreted as representing official policies, either expressed
32 adee02b8 Giorgos Verigakis
# or implied, of GRNET S.A.
33 7e2f9d4b Giorgos Verigakis
34 c738c935 Giorgos Verigakis
import datetime
35 c738c935 Giorgos Verigakis
36 c738c935 Giorgos Verigakis
from base64 import b64encode
37 d8e50a39 Giorgos Verigakis
from datetime import timedelta, tzinfo
38 d8e50a39 Giorgos Verigakis
from functools import wraps
39 c738c935 Giorgos Verigakis
from hashlib import sha256
40 2035039b Giorgos Verigakis
from logging import getLogger
41 d8e50a39 Giorgos Verigakis
from random import choice
42 dca2a31f Giorgos Verigakis
from string import digits, lowercase, uppercase
43 8b01f7f3 Giorgos Verigakis
from time import time
44 d8e50a39 Giorgos Verigakis
from traceback import format_exc
45 8b01f7f3 Giorgos Verigakis
from wsgiref.handlers import format_date_time
46 7e2f9d4b Giorgos Verigakis
47 2035039b Giorgos Verigakis
import dateutil.parser
48 2035039b Giorgos Verigakis
49 c738c935 Giorgos Verigakis
from Crypto.Cipher import AES
50 529178b1 Giorgos Verigakis
51 d8e50a39 Giorgos Verigakis
from django.conf import settings
52 7e2f9d4b Giorgos Verigakis
from django.http import HttpResponse
53 7e2f9d4b Giorgos Verigakis
from django.template.loader import render_to_string
54 29a59bc1 Giorgos Verigakis
from django.utils import simplejson as json
55 b75555e5 Giorgos Verigakis
from django.utils.cache import add_never_cache_headers
56 7e2f9d4b Giorgos Verigakis
57 b36f78fa Giorgos Verigakis
from synnefo.api.faults import (Fault, BadRequest, BuildInProgress,
58 6dd70a5c Christos Stavrakakis
                                ItemNotFound, ServiceUnavailable, Unauthorized,
59 6dd70a5c Christos Stavrakakis
                                BadMediaType, OverLimit)
60 6ef51e9f Giorgos Verigakis
from synnefo.db.models import (Flavor, VirtualMachine, VirtualMachineMetadata,
61 6dd70a5c Christos Stavrakakis
                               Network, NetworkInterface, BridgePool,
62 6dd70a5c Christos Stavrakakis
                               MacPrefixPool, Pool)
63 6dd70a5c Christos Stavrakakis
64 4b3b8688 Giorgos Verigakis
from synnefo.lib.astakos import get_user
65 3a9b3cde Giorgos Verigakis
from synnefo.plankton.backend import ImageBackend
66 9e98ba3c Giorgos Verigakis
67 9e98ba3c Giorgos Verigakis
68 9e98ba3c Giorgos Verigakis
log = getLogger('synnefo.api')
69 9e98ba3c Giorgos Verigakis
70 7e2f9d4b Giorgos Verigakis
71 d8e50a39 Giorgos Verigakis
class UTC(tzinfo):
72 d8e50a39 Giorgos Verigakis
    def utcoffset(self, dt):
73 d8e50a39 Giorgos Verigakis
        return timedelta(0)
74 aa197ee4 Vangelis Koukis
75 d8e50a39 Giorgos Verigakis
    def tzname(self, dt):
76 d8e50a39 Giorgos Verigakis
        return 'UTC'
77 aa197ee4 Vangelis Koukis
78 d8e50a39 Giorgos Verigakis
    def dst(self, dt):
79 d8e50a39 Giorgos Verigakis
        return timedelta(0)
80 7e2f9d4b Giorgos Verigakis
81 7e2f9d4b Giorgos Verigakis
82 d8e50a39 Giorgos Verigakis
def isoformat(d):
83 529178b1 Giorgos Verigakis
    """Return an ISO8601 date string that includes a timezone."""
84 aa197ee4 Vangelis Koukis
85 d8e50a39 Giorgos Verigakis
    return d.replace(tzinfo=UTC()).isoformat()
86 d8e50a39 Giorgos Verigakis
87 a08e4270 Vangelis Koukis
88 d8e50a39 Giorgos Verigakis
def isoparse(s):
89 d8e50a39 Giorgos Verigakis
    """Parse an ISO8601 date string into a datetime object."""
90 aa197ee4 Vangelis Koukis
91 d8e50a39 Giorgos Verigakis
    if not s:
92 d8e50a39 Giorgos Verigakis
        return None
93 aa197ee4 Vangelis Koukis
94 d8e50a39 Giorgos Verigakis
    try:
95 d8e50a39 Giorgos Verigakis
        since = dateutil.parser.parse(s)
96 e87d30f3 Giorgos Verigakis
        utc_since = since.astimezone(UTC()).replace(tzinfo=None)
97 d8e50a39 Giorgos Verigakis
    except ValueError:
98 d8e50a39 Giorgos Verigakis
        raise BadRequest('Invalid changes-since parameter.')
99 aa197ee4 Vangelis Koukis
100 e87d30f3 Giorgos Verigakis
    now = datetime.datetime.now()
101 e87d30f3 Giorgos Verigakis
    if utc_since > now:
102 d8e50a39 Giorgos Verigakis
        raise BadRequest('changes-since value set in the future.')
103 aa197ee4 Vangelis Koukis
104 e87d30f3 Giorgos Verigakis
    if now - utc_since > timedelta(seconds=settings.POLL_LIMIT):
105 d8e50a39 Giorgos Verigakis
        raise BadRequest('Too old changes-since value.')
106 aa197ee4 Vangelis Koukis
107 0140e54b Vangelis Koukis
    return utc_since
108 aa197ee4 Vangelis Koukis
109 dca2a31f Giorgos Verigakis
110 dca2a31f Giorgos Verigakis
def random_password():
111 dca2a31f Giorgos Verigakis
    """Generates a random password
112 ce55f211 Kostas Papadimitriou

113 62eac5a6 Giorgos Verigakis
    We generate a windows compliant password: it must contain at least
114 dca2a31f Giorgos Verigakis
    one charachter from each of the groups: upper case, lower case, digits.
115 dca2a31f Giorgos Verigakis
    """
116 ce55f211 Kostas Papadimitriou
117 dca2a31f Giorgos Verigakis
    pool = lowercase + uppercase + digits
118 dca2a31f Giorgos Verigakis
    lowerset = set(lowercase)
119 dca2a31f Giorgos Verigakis
    upperset = set(uppercase)
120 dca2a31f Giorgos Verigakis
    digitset = set(digits)
121 dca2a31f Giorgos Verigakis
    length = 10
122 ce55f211 Kostas Papadimitriou
123 62eac5a6 Giorgos Verigakis
    password = ''.join(choice(pool) for i in range(length - 2))
124 ce55f211 Kostas Papadimitriou
125 62eac5a6 Giorgos Verigakis
    # Make sure the password is compliant
126 62eac5a6 Giorgos Verigakis
    chars = set(password)
127 62eac5a6 Giorgos Verigakis
    if not chars & lowerset:
128 62eac5a6 Giorgos Verigakis
        password += choice(lowercase)
129 62eac5a6 Giorgos Verigakis
    if not chars & upperset:
130 62eac5a6 Giorgos Verigakis
        password += choice(uppercase)
131 62eac5a6 Giorgos Verigakis
    if not chars & digitset:
132 62eac5a6 Giorgos Verigakis
        password += choice(digits)
133 ce55f211 Kostas Papadimitriou
134 62eac5a6 Giorgos Verigakis
    # Pad if necessary to reach required length
135 62eac5a6 Giorgos Verigakis
    password += ''.join(choice(pool) for i in range(length - len(password)))
136 ce55f211 Kostas Papadimitriou
137 dca2a31f Giorgos Verigakis
    return password
138 dca2a31f Giorgos Verigakis
139 d8e50a39 Giorgos Verigakis
140 c738c935 Giorgos Verigakis
def zeropad(s):
141 c738c935 Giorgos Verigakis
    """Add zeros at the end of a string in order to make its length
142 c738c935 Giorgos Verigakis
       a multiple of 16."""
143 d1387ed7 Christodoulos Psaltis
144 c738c935 Giorgos Verigakis
    npad = 16 - len(s) % 16
145 c738c935 Giorgos Verigakis
    return s + '\x00' * npad
146 c738c935 Giorgos Verigakis
147 a08e4270 Vangelis Koukis
148 c738c935 Giorgos Verigakis
def encrypt(plaintext):
149 c738c935 Giorgos Verigakis
    # Make sure key is 32 bytes long
150 c738c935 Giorgos Verigakis
    key = sha256(settings.SECRET_KEY).digest()
151 d1387ed7 Christodoulos Psaltis
152 c738c935 Giorgos Verigakis
    aes = AES.new(key)
153 c738c935 Giorgos Verigakis
    enc = aes.encrypt(zeropad(plaintext))
154 c738c935 Giorgos Verigakis
    return b64encode(enc)
155 c738c935 Giorgos Verigakis
156 7e2f9d4b Giorgos Verigakis
157 6ef51e9f Giorgos Verigakis
def get_vm(server_id, user_id):
158 d8e50a39 Giorgos Verigakis
    """Return a VirtualMachine instance or raise ItemNotFound."""
159 aa197ee4 Vangelis Koukis
160 d8e50a39 Giorgos Verigakis
    try:
161 d8e50a39 Giorgos Verigakis
        server_id = int(server_id)
162 6ef51e9f Giorgos Verigakis
        return VirtualMachine.objects.get(id=server_id, userid=user_id)
163 d8e50a39 Giorgos Verigakis
    except ValueError:
164 d8e50a39 Giorgos Verigakis
        raise BadRequest('Invalid server ID.')
165 d8e50a39 Giorgos Verigakis
    except VirtualMachine.DoesNotExist:
166 d8e50a39 Giorgos Verigakis
        raise ItemNotFound('Server not found.')
167 d8e50a39 Giorgos Verigakis
168 a08e4270 Vangelis Koukis
169 40777cc8 Giorgos Verigakis
def get_vm_meta(vm, key):
170 d8e50a39 Giorgos Verigakis
    """Return a VirtualMachineMetadata instance or raise ItemNotFound."""
171 aa197ee4 Vangelis Koukis
172 d8e50a39 Giorgos Verigakis
    try:
173 40777cc8 Giorgos Verigakis
        return VirtualMachineMetadata.objects.get(meta_key=key, vm=vm)
174 d8e50a39 Giorgos Verigakis
    except VirtualMachineMetadata.DoesNotExist:
175 d8e50a39 Giorgos Verigakis
        raise ItemNotFound('Metadata key not found.')
176 d8e50a39 Giorgos Verigakis
177 a08e4270 Vangelis Koukis
178 6ef51e9f Giorgos Verigakis
def get_image(image_id, user_id):
179 d8e50a39 Giorgos Verigakis
    """Return an Image instance or raise ItemNotFound."""
180 aa197ee4 Vangelis Koukis
181 6ef51e9f Giorgos Verigakis
    backend = ImageBackend(user_id)
182 d8e50a39 Giorgos Verigakis
    try:
183 6ef51e9f Giorgos Verigakis
        image = backend.get_image(image_id)
184 3a9b3cde Giorgos Verigakis
        if not image:
185 3a9b3cde Giorgos Verigakis
            raise ItemNotFound('Image not found.')
186 3a9b3cde Giorgos Verigakis
        return image
187 3a9b3cde Giorgos Verigakis
    finally:
188 3a9b3cde Giorgos Verigakis
        backend.close()
189 3a9b3cde Giorgos Verigakis
190 a08e4270 Vangelis Koukis
191 529178b1 Giorgos Verigakis
def get_flavor(flavor_id):
192 529178b1 Giorgos Verigakis
    """Return a Flavor instance or raise ItemNotFound."""
193 aa197ee4 Vangelis Koukis
194 529178b1 Giorgos Verigakis
    try:
195 529178b1 Giorgos Verigakis
        flavor_id = int(flavor_id)
196 529178b1 Giorgos Verigakis
        return Flavor.objects.get(id=flavor_id)
197 6ef51e9f Giorgos Verigakis
    except (ValueError, Flavor.DoesNotExist):
198 529178b1 Giorgos Verigakis
        raise ItemNotFound('Flavor not found.')
199 d8e50a39 Giorgos Verigakis
200 a08e4270 Vangelis Koukis
201 6ef51e9f Giorgos Verigakis
def get_network(network_id, user_id):
202 e2ee7808 Giorgos Verigakis
    """Return a Network instance or raise ItemNotFound."""
203 aa197ee4 Vangelis Koukis
204 e2ee7808 Giorgos Verigakis
    try:
205 d44c236b Giorgos Verigakis
        if network_id == 'public':
206 207b70d5 Giorgos Verigakis
            return Network.objects.get(public=True)
207 207b70d5 Giorgos Verigakis
        else:
208 207b70d5 Giorgos Verigakis
            network_id = int(network_id)
209 6ef51e9f Giorgos Verigakis
            return Network.objects.get(id=network_id, userid=user_id)
210 6ef51e9f Giorgos Verigakis
    except (ValueError, Network.DoesNotExist):
211 e2ee7808 Giorgos Verigakis
        raise ItemNotFound('Network not found.')
212 e2ee7808 Giorgos Verigakis
213 a08e4270 Vangelis Koukis
214 d44c236b Giorgos Verigakis
def get_nic(machine, network):
215 d44c236b Giorgos Verigakis
    try:
216 d44c236b Giorgos Verigakis
        return NetworkInterface.objects.get(machine=machine, network=network)
217 d44c236b Giorgos Verigakis
    except NetworkInterface.DoesNotExist:
218 d44c236b Giorgos Verigakis
        raise ItemNotFound('Server not connected to this network.')
219 d44c236b Giorgos Verigakis
220 08b079e2 Stavros Sachtouris
def get_nic_from_index(vm, nic_index):
221 08b079e2 Stavros Sachtouris
    """Returns the nic_index-th nic of a vm
222 08b079e2 Stavros Sachtouris
       Error Response Codes: itemNotFound (404), badMediaType (415)
223 08b079e2 Stavros Sachtouris
    """
224 08b079e2 Stavros Sachtouris
    matching_nics = vm.nics.filter(index=nic_index)
225 08b079e2 Stavros Sachtouris
    matching_nics_len = len(matching_nics)
226 08b079e2 Stavros Sachtouris
    if matching_nics_len < 1:
227 08b079e2 Stavros Sachtouris
        raise  ItemNotFound('NIC not found on VM')
228 08b079e2 Stavros Sachtouris
    elif matching_nics_len > 1:
229 08b079e2 Stavros Sachtouris
        raise BadMediaType('NIC index conflict on VM')
230 08b079e2 Stavros Sachtouris
    nic = matching_nics[0]
231 08b079e2 Stavros Sachtouris
    return nic
232 e2ee7808 Giorgos Verigakis
233 7e2f9d4b Giorgos Verigakis
def get_request_dict(request):
234 d8e50a39 Giorgos Verigakis
    """Returns data sent by the client as a python dict."""
235 aa197ee4 Vangelis Koukis
236 7e2f9d4b Giorgos Verigakis
    data = request.raw_post_data
237 7e45ddef Dimitris Moraitis
    if request.META.get('CONTENT_TYPE').startswith('application/json'):
238 7e2f9d4b Giorgos Verigakis
        try:
239 7e2f9d4b Giorgos Verigakis
            return json.loads(data)
240 7e2f9d4b Giorgos Verigakis
        except ValueError:
241 d8e50a39 Giorgos Verigakis
            raise BadRequest('Invalid JSON data.')
242 d8e50a39 Giorgos Verigakis
    else:
243 d8e50a39 Giorgos Verigakis
        raise BadRequest('Unsupported Content-Type.')
244 7e2f9d4b Giorgos Verigakis
245 a08e4270 Vangelis Koukis
246 8b01f7f3 Giorgos Verigakis
def update_response_headers(request, response):
247 8b01f7f3 Giorgos Verigakis
    if request.serialization == 'xml':
248 8b01f7f3 Giorgos Verigakis
        response['Content-Type'] = 'application/xml'
249 8b01f7f3 Giorgos Verigakis
    elif request.serialization == 'atom':
250 8b01f7f3 Giorgos Verigakis
        response['Content-Type'] = 'application/atom+xml'
251 8b01f7f3 Giorgos Verigakis
    else:
252 8b01f7f3 Giorgos Verigakis
        response['Content-Type'] = 'application/json'
253 aa197ee4 Vangelis Koukis
254 4cf8adf8 Vangelis Koukis
    if settings.TEST:
255 cdb65551 Giorgos Verigakis
        response['Date'] = format_date_time(time())
256 ce55f211 Kostas Papadimitriou
257 b75555e5 Giorgos Verigakis
    add_never_cache_headers(response)
258 b75555e5 Giorgos Verigakis
259 8b01f7f3 Giorgos Verigakis
260 432fc8c3 Giorgos Verigakis
def render_metadata(request, metadata, use_values=False, status=200):
261 432fc8c3 Giorgos Verigakis
    if request.serialization == 'xml':
262 432fc8c3 Giorgos Verigakis
        data = render_to_string('metadata.xml', {'metadata': metadata})
263 432fc8c3 Giorgos Verigakis
    else:
264 b36f78fa Giorgos Verigakis
        if use_values:
265 b36f78fa Giorgos Verigakis
            d = {'metadata': {'values': metadata}}
266 b36f78fa Giorgos Verigakis
        else:
267 b36f78fa Giorgos Verigakis
            d = {'metadata': metadata}
268 432fc8c3 Giorgos Verigakis
        data = json.dumps(d)
269 432fc8c3 Giorgos Verigakis
    return HttpResponse(data, status=status)
270 432fc8c3 Giorgos Verigakis
271 a08e4270 Vangelis Koukis
272 432fc8c3 Giorgos Verigakis
def render_meta(request, meta, status=200):
273 432fc8c3 Giorgos Verigakis
    if request.serialization == 'xml':
274 6ef51e9f Giorgos Verigakis
        data = render_to_string('meta.xml', dict(key=key, val=val))
275 432fc8c3 Giorgos Verigakis
    else:
276 6ef51e9f Giorgos Verigakis
        data = json.dumps(dict(meta=meta))
277 432fc8c3 Giorgos Verigakis
    return HttpResponse(data, status=status)
278 432fc8c3 Giorgos Verigakis
279 a08e4270 Vangelis Koukis
280 c36934a7 Giorgos Verigakis
def render_fault(request, fault):
281 4cf8adf8 Vangelis Koukis
    if settings.DEBUG or settings.TEST:
282 7e2f9d4b Giorgos Verigakis
        fault.details = format_exc(fault)
283 aa197ee4 Vangelis Koukis
284 d8e50a39 Giorgos Verigakis
    if request.serialization == 'xml':
285 d8e50a39 Giorgos Verigakis
        data = render_to_string('fault.xml', {'fault': fault})
286 7e2f9d4b Giorgos Verigakis
    else:
287 b36f78fa Giorgos Verigakis
        d = {fault.name: {
288 b36f78fa Giorgos Verigakis
                'code': fault.code,
289 b36f78fa Giorgos Verigakis
                'message': fault.message,
290 b36f78fa Giorgos Verigakis
                'details': fault.details}}
291 7e2f9d4b Giorgos Verigakis
        data = json.dumps(d)
292 aa197ee4 Vangelis Koukis
293 f0656db1 Giorgos Verigakis
    resp = HttpResponse(data, status=fault.code)
294 8b01f7f3 Giorgos Verigakis
    update_response_headers(request, resp)
295 f0656db1 Giorgos Verigakis
    return resp
296 d8e50a39 Giorgos Verigakis
297 432fc8c3 Giorgos Verigakis
298 d8e50a39 Giorgos Verigakis
def request_serialization(request, atom_allowed=False):
299 d8e50a39 Giorgos Verigakis
    """Return the serialization format requested.
300 aa197ee4 Vangelis Koukis

301 529178b1 Giorgos Verigakis
    Valid formats are 'json', 'xml' and 'atom' if `atom_allowed` is True.
302 d8e50a39 Giorgos Verigakis
    """
303 aa197ee4 Vangelis Koukis
304 d8e50a39 Giorgos Verigakis
    path = request.path
305 aa197ee4 Vangelis Koukis
306 d8e50a39 Giorgos Verigakis
    if path.endswith('.json'):
307 d8e50a39 Giorgos Verigakis
        return 'json'
308 d8e50a39 Giorgos Verigakis
    elif path.endswith('.xml'):
309 d8e50a39 Giorgos Verigakis
        return 'xml'
310 d8e50a39 Giorgos Verigakis
    elif atom_allowed and path.endswith('.atom'):
311 d8e50a39 Giorgos Verigakis
        return 'atom'
312 aa197ee4 Vangelis Koukis
313 d8e50a39 Giorgos Verigakis
    for item in request.META.get('HTTP_ACCEPT', '').split(','):
314 d8e50a39 Giorgos Verigakis
        accept, sep, rest = item.strip().partition(';')
315 d8e50a39 Giorgos Verigakis
        if accept == 'application/json':
316 d8e50a39 Giorgos Verigakis
            return 'json'
317 d8e50a39 Giorgos Verigakis
        elif accept == 'application/xml':
318 d8e50a39 Giorgos Verigakis
            return 'xml'
319 d8e50a39 Giorgos Verigakis
        elif atom_allowed and accept == 'application/atom+xml':
320 d8e50a39 Giorgos Verigakis
            return 'atom'
321 aa197ee4 Vangelis Koukis
322 d8e50a39 Giorgos Verigakis
    return 'json'
323 7e2f9d4b Giorgos Verigakis
324 a08e4270 Vangelis Koukis
325 d8e50a39 Giorgos Verigakis
def api_method(http_method=None, atom_allowed=False):
326 d8e50a39 Giorgos Verigakis
    """Decorator function for views that implement an API method."""
327 aa197ee4 Vangelis Koukis
328 c36934a7 Giorgos Verigakis
    def decorator(func):
329 c36934a7 Giorgos Verigakis
        @wraps(func)
330 c36934a7 Giorgos Verigakis
        def wrapper(request, *args, **kwargs):
331 c36934a7 Giorgos Verigakis
            try:
332 6ef51e9f Giorgos Verigakis
                request.serialization = request_serialization(request,
333 6ef51e9f Giorgos Verigakis
                                                              atom_allowed)
334 4b3b8688 Giorgos Verigakis
                get_user(request, settings.ASTAKOS_URL)
335 4b3b8688 Giorgos Verigakis
                if not request.user_uniq:
336 40777cc8 Giorgos Verigakis
                    raise Unauthorized('No user found.')
337 d8e50a39 Giorgos Verigakis
                if http_method and request.method != http_method:
338 d8e50a39 Giorgos Verigakis
                    raise BadRequest('Method not allowed.')
339 08b079e2 Stavros Sachtouris
                
340 c36934a7 Giorgos Verigakis
                resp = func(request, *args, **kwargs)
341 8b01f7f3 Giorgos Verigakis
                update_response_headers(request, resp)
342 c36934a7 Giorgos Verigakis
                return resp
343 5231a38a Giorgos Verigakis
            except VirtualMachine.DeletedError:
344 5231a38a Giorgos Verigakis
                fault = BadRequest('Server has been deleted.')
345 5231a38a Giorgos Verigakis
                return render_fault(request, fault)
346 5231a38a Giorgos Verigakis
            except VirtualMachine.BuildingError:
347 5231a38a Giorgos Verigakis
                fault = BuildInProgress('Server is being built.')
348 5231a38a Giorgos Verigakis
                return render_fault(request, fault)
349 c36934a7 Giorgos Verigakis
            except Fault, fault:
350 c36934a7 Giorgos Verigakis
                return render_fault(request, fault)
351 a62a4d20 Giorgos Verigakis
            except BaseException, e:
352 9e98ba3c Giorgos Verigakis
                log.exception('Unexpected error')
353 529178b1 Giorgos Verigakis
                fault = ServiceUnavailable('Unexpected error.')
354 c36934a7 Giorgos Verigakis
                return render_fault(request, fault)
355 c36934a7 Giorgos Verigakis
        return wrapper
356 c36934a7 Giorgos Verigakis
    return decorator
357 08b079e2 Stavros Sachtouris
358 08b079e2 Stavros Sachtouris
def construct_nic_id(nic):
359 08b079e2 Stavros Sachtouris
    return "-".join(["nic", unicode(nic.machine.id), unicode(nic.index)])
360 6dd70a5c Christos Stavrakakis
361 6dd70a5c Christos Stavrakakis
362 6dd70a5c Christos Stavrakakis
def network_specs_from_type(network_type):
363 6dd70a5c Christos Stavrakakis
    mac_prefix = None
364 6dd70a5c Christos Stavrakakis
    try:
365 6dd70a5c Christos Stavrakakis
        if network_type == 'PRIVATE_MAC_FILTERED':
366 6dd70a5c Christos Stavrakakis
            link = settings.PRIVATE_MAC_FILTERED_BRIDGE
367 6dd70a5c Christos Stavrakakis
            mac_prefix = MacPrefixPool.get_available().value
368 6dd70a5c Christos Stavrakakis
        elif network_type == 'PRIVATE_PHYSICAL_VLAN':
369 6dd70a5c Christos Stavrakakis
            link = BridgePool.get_available().value
370 6dd70a5c Christos Stavrakakis
        elif network_type == 'CUSTOM_ROUTED':
371 6dd70a5c Christos Stavrakakis
            link = settings.CUSTOM_ROUTED_ROUTING_TABLE
372 6dd70a5c Christos Stavrakakis
        elif network_type == 'CUSTOM_BRIDGED':
373 6dd70a5c Christos Stavrakakis
            link = settings.CUSTOM_BRIDGED_BRIDGE
374 6dd70a5c Christos Stavrakakis
        else:
375 6dd70a5c Christos Stavrakakis
            raise BadRequest('Unknown network network_type')
376 6dd70a5c Christos Stavrakakis
    except Pool.PoolExhausted:
377 6dd70a5c Christos Stavrakakis
        raise OverLimit('Network count limit exceeded.')
378 6dd70a5c Christos Stavrakakis
379 6dd70a5c Christos Stavrakakis
    return link, mac_prefix