Revision e440e835

b/snf-cyclades-app/synnefo/api/actions.py
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
# 
1
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
5 5
# conditions are met:
6
# 
6
#
7 7
#   1. Redistributions of source code must retain the above
8 8
#      copyright notice, this list of conditions and the following
9 9
#      disclaimer.
10
# 
10
#
11 11
#   2. Redistributions in binary form must reproduce the above
12 12
#      copyright notice, this list of conditions and the following
13 13
#      disclaimer in the documentation and/or other materials
14 14
#      provided with the distribution.
15
# 
15
#
16 16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
......
25 25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
28
#
29 29
# The views and conclusions contained in the software and
30 30
# documentation are those of the authors and should not be
31 31
# interpreted as representing official policies, either expressed
......
41 41
from django.utils import simplejson as json
42 42

  
43 43
from synnefo.api.faults import (BadRequest, ServiceUnavailable,
44
                                ItemNotFound, BuildInProgress,
45
                                OverLimit)
44
                                BuildInProgress, OverLimit)
46 45
from synnefo.api.util import (random_password, get_vm, get_nic_from_index,
47 46
                              get_network_free_address)
48
from synnefo.db.models import NetworkInterface, Network
47
from synnefo.db.models import NetworkInterface
49 48
from synnefo.db.pools import EmptyPool
50 49
from synnefo.logic import backend
51 50
from synnefo.logic.utils import get_rsapi_state
b/snf-cyclades-app/synnefo/api/common.py
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
# 
1
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
5 5
# conditions are met:
6
# 
6
#
7 7
#   1. Redistributions of source code must retain the above
8 8
#      copyright notice, this list of conditions and the following
9 9
#      disclaimer.
10
# 
10
#
11 11
#   2. Redistributions in binary form must reproduce the above
12 12
#      copyright notice, this list of conditions and the following
13 13
#      disclaimer in the documentation and/or other materials
14 14
#      provided with the distribution.
15
# 
15
#
16 16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
......
25 25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
28
#
29 29
# The views and conclusions contained in the software and
30 30
# documentation are those of the authors and should not be
31 31
# interpreted as representing official policies, either expressed
......
39 39
def not_found(request):
40 40
    raise BadRequest('Not found.')
41 41

  
42

  
42 43
@api_method()
43 44
def method_not_allowed(request):
44 45
    raise BadRequest('Method not allowed')
b/snf-cyclades-app/synnefo/api/delegate.py
1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
1
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
2 2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
......
34 34
import logging
35 35

  
36 36
from urlparse import urlparse
37
import urllib
38
import urllib2
39

  
40
from django.http import (
41
    HttpResponseNotFound, HttpResponseRedirect, HttpResponseBadRequest,
42
    HttpResponse)
43
from django.utils.http import urlencode
37
from django.http import HttpResponse
44 38
from django.views.decorators.csrf import csrf_exempt
45 39

  
46 40
from django.conf import settings
......
74 68
    finally:
75 69
        conn.close()
76 70

  
71

  
77 72
@csrf_exempt
78 73
def delegate_to_feedback_service(request):
79 74
    token = request.META.get('HTTP_X_AUTH_TOKEN')
80 75
    headers = {'X-Auth-Token': token}
81
    return proxy(
82
        request, USER_FEEDBACK_URL, headers=headers, body=request.raw_post_data)
76
    return proxy(request, USER_FEEDBACK_URL, headers=headers,
77
                 body=request.raw_post_data)
78

  
83 79

  
84 80
@csrf_exempt
85 81
def delegate_to_user_catalogs_service(request):
86 82
    token = request.META.get('HTTP_X_AUTH_TOKEN')
87 83
    headers = {'X-Auth-Token': token, 'content-type': 'application/json'}
88
    return proxy(
89
        request, USER_CATALOG_URL, headers=headers, body=request.raw_post_data)
90

  
84
    return proxy(request, USER_CATALOG_URL, headers=headers,
85
                 body=request.raw_post_data)
b/snf-cyclades-app/synnefo/api/faults.py
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
# 
1
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
5 5
# conditions are met:
6
# 
6
#
7 7
#   1. Redistributions of source code must retain the above
8 8
#      copyright notice, this list of conditions and the following
9 9
#      disclaimer.
10
# 
10
#
11 11
#   2. Redistributions in binary form must reproduce the above
12 12
#      copyright notice, this list of conditions and the following
13 13
#      disclaimer in the documentation and/or other materials
14 14
#      provided with the distribution.
15
# 
15
#
16 16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
......
25 25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
28
#
29 29
# The views and conclusions contained in the software and
30 30
# documentation are those of the authors and should not be
31 31
# interpreted as representing official policies, either expressed
32 32
# or implied, of GRNET S.A.
33 33

  
34

  
34 35
def camelCase(s):
35 36
    return s[0].lower() + s[1:]
36 37

  
......
42 43
        self.details = details
43 44
        self.name = name or camelCase(self.__class__.__name__)
44 45

  
46

  
45 47
class BadRequest(Fault):
46 48
    code = 400
47 49

  
50

  
48 51
class Unauthorized(Fault):
49 52
    code = 401
50 53

  
54

  
51 55
class ResizeNotAllowed(Fault):
52 56
    code = 403
53 57

  
58

  
54 59
class Forbidden(Fault):
55 60
    code = 403
56 61

  
62

  
57 63
class ItemNotFound(Fault):
58 64
    code = 404
59 65

  
66

  
60 67
class BuildInProgress(Fault):
61 68
    code = 409
62 69

  
70

  
63 71
class OverLimit(Fault):
64 72
    code = 413
65 73

  
74

  
66 75
class BadMediaType(Fault):
67 76
    code = 415
68 77

  
78

  
69 79
class NetworkInUse(Fault):
70 80
    code = 421
71 81

  
82

  
72 83
class ServiceUnavailable(Fault):
73 84
    code = 503
b/snf-cyclades-app/synnefo/api/flavors.py
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
# 
1
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
5 5
# conditions are met:
6
# 
6
#
7 7
#   1. Redistributions of source code must retain the above
8 8
#      copyright notice, this list of conditions and the following
9 9
#      disclaimer.
10
# 
10
#
11 11
#   2. Redistributions in binary form must reproduce the above
12 12
#      copyright notice, this list of conditions and the following
13 13
#      disclaimer in the documentation and/or other materials
14 14
#      provided with the distribution.
15
# 
15
#
16 16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
......
25 25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
28
#
29 29
# The views and conclusions contained in the software and
30 30
# documentation are those of the authors and should not be
31 31
# interpreted as representing official policies, either expressed
......
45 45
log = getLogger('synnefo.api')
46 46

  
47 47

  
48
urlpatterns = patterns('synnefo.api.flavors',
48
urlpatterns = patterns(
49
    'synnefo.api.flavors',
49 50
    (r'^(?:/|.json|.xml)?$', 'list_flavors'),
50 51
    (r'^/detail(?:.json|.xml)?$', 'list_flavors', {'detail': True}),
51 52
    (r'^/(\d+)(?:.json|.xml)?$', 'get_flavor_details'),
......
73 74

  
74 75
    log.debug('list_flavors detail=%s', detail)
75 76
    active_flavors = Flavor.objects.exclude(deleted=True)
76
    flavors = [flavor_to_dict(flavor, detail)\
77
    flavors = [flavor_to_dict(flavor, detail)
77 78
               for flavor in active_flavors.order_by('id')]
78 79

  
79 80
    if request.serialization == 'xml':
b/snf-cyclades-app/synnefo/api/images.py
51 51

  
52 52
log = getLogger('synnefo.api')
53 53

  
54
urlpatterns = patterns('synnefo.api.images',
54
urlpatterns = patterns(
55
    'synnefo.api.images',
55 56
    (r'^(?:/|.json|.xml)?$', 'demux'),
56 57
    (r'^/detail(?:.json|.xml)?$', 'list_images', {'detail': True}),
57 58
    (r'^/([\w-]+)(?:.json|.xml)?$', 'image_demux'),
......
59 60
    (r'^/([\w-]+)/meta/(.+?)(?:.json|.xml)?$', 'metadata_item_demux')
60 61
)
61 62

  
63

  
62 64
def demux(request):
63 65
    if request.method == 'GET':
64 66
        return list_images(request)
......
67 69
    else:
68 70
        return method_not_allowed(request)
69 71

  
72

  
70 73
def image_demux(request, image_id):
71 74
    if request.method == 'GET':
72 75
        return get_image_details(request, image_id)
......
75 78
    else:
76 79
        return method_not_allowed(request)
77 80

  
81

  
78 82
def metadata_demux(request, image_id):
79 83
    if request.method == 'GET':
80 84
        return list_metadata(request, image_id)
......
83 87
    else:
84 88
        return method_not_allowed(request)
85 89

  
90

  
86 91
def metadata_item_demux(request, image_id, key):
87 92
    if request.method == 'GET':
88 93
        return get_metadata_item(request, image_id, key)
......
114 119
    finally:
115 120
        backend.close()
116 121

  
122

  
117 123
@api_method('GET')
118 124
def list_images(request, detail=False):
119 125
    # Normal Response Codes: 200, 203
b/snf-cyclades-app/synnefo/api/networks.py
54 54

  
55 55
log = getLogger('synnefo.api')
56 56

  
57
urlpatterns = patterns('synnefo.api.networks',
57
urlpatterns = patterns(
58
    'synnefo.api.networks',
58 59
    (r'^(?:/|.json|.xml)?$', 'demux'),
59 60
    (r'^/detail(?:.json|.xml)?$', 'list_networks', {'detail': True}),
60 61
    (r'^/(\w+)(?:.json|.xml)?$', 'network_demux'),
......
97 98
        d['public'] = network.public
98 99

  
99 100
        attachments = [util.construct_nic_id(nic)
100
                       for nic in network.nics.filter(machine__userid=user_id)\
101
                       for nic in network.nics.filter(machine__userid=user_id)
101 102
                                              .order_by('machine')]
102 103
        d['attachments'] = {'values': attachments}
103 104
    return d
......
200 201
        try:
201 202
            mode, link, mac_prefix, tags = util.values_from_flavor(flavor)
202 203
            network = Network.objects.create(
203
                    name=name,
204
                    userid=user_id,
205
                    subnet=subnet,
206
                    subnet6=subnet6,
207
                    gateway=gateway,
208
                    gateway6=gateway6,
209
                    dhcp=dhcp,
210
                    flavor=flavor,
211
                    mode=mode,
212
                    link=link,
213
                    mac_prefix=mac_prefix,
214
                    tags=tags,
215
                    action='CREATE',
216
                    state='PENDING',
217
                    serial=serial)
204
                name=name,
205
                userid=user_id,
206
                subnet=subnet,
207
                subnet6=subnet6,
208
                gateway=gateway,
209
                gateway6=gateway6,
210
                dhcp=dhcp,
211
                flavor=flavor,
212
                mode=mode,
213
                link=link,
214
                mac_prefix=mac_prefix,
215
                tags=tags,
216
                action='CREATE',
217
                state='PENDING',
218
                serial=serial)
218 219
        except EmptyPool:
219 220
            log.error("Failed to allocate resources for network of type: %s",
220 221
                      flavor)
......
305 306
    if net.machines.all():  # Nics attached on network
306 307
        raise NetworkInUse('Machines are connected to network.')
307 308

  
308

  
309 309
    net.action = 'DESTROY'
310 310
    net.save()
311 311

  
b/snf-cyclades-app/synnefo/api/servers.py
57 57
from logging import getLogger
58 58
log = getLogger('synnefo.api')
59 59

  
60
urlpatterns = patterns('synnefo.api.servers',
60
urlpatterns = patterns(
61
    'synnefo.api.servers',
61 62
    (r'^(?:/|.json|.xml)?$', 'demux'),
62 63
    (r'^/detail(?:.json|.xml)?$', 'list_servers', {'detail': True}),
63 64
    (r'^/(\d+)(?:.json|.xml)?$', 'server_demux'),
......
128 129
    if detail:
129 130
        d['status'] = get_rsapi_state(vm)
130 131
        d['progress'] = 100 if get_rsapi_state(vm) == 'ACTIVE' \
131
                        else vm.buildpercentage
132
            else vm.buildpercentage
132 133
        d['hostId'] = vm.hostid
133 134
        d['updated'] = util.isoformat(vm.updated)
134 135
        d['created'] = util.isoformat(vm.created)
......
229 230
    else:
230 231
        user_vms = user_vms.filter(deleted=False)
231 232

  
232
    servers = [vm_to_dict(server, detail)\
233
    servers = [vm_to_dict(server, detail)
233 234
               for server in user_vms.order_by('id')]
234 235

  
235 236
    if request.serialization == 'xml':
......
455 456
# additional server actions
456 457
ARBITRARY_ACTIONS = ['console', 'firewallProfile']
457 458

  
459

  
458 460
@util.api_method('POST')
459 461
def server_action(request, server_id):
460 462
    req = util.get_request_dict(request)
461 463
    log.debug('server_action %s %s', server_id, req)
462 464

  
463

  
464 465
    if len(req) != 1:
465 466
        raise faults.BadRequest("Malformed request")
466 467

  
b/snf-cyclades-app/synnefo/api/tests.py
83 83
            content_type = 'application/json'
84 84
        with astakos_user(user):
85 85
            response = self.client.put(url, params, content_type=content_type,
86
                    *args, **kwargs)
86
                                       *args, **kwargs)
87 87
        return response
88 88

  
89 89
    def assertSuccess(self, response):
b/snf-cyclades-app/synnefo/api/urls.py
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
# 
1
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
5 5
# conditions are met:
6
# 
6
#
7 7
#   1. Redistributions of source code must retain the above
8 8
#      copyright notice, this list of conditions and the following
9 9
#      disclaimer.
10
# 
10
#
11 11
#   2. Redistributions in binary form must reproduce the above
12 12
#      copyright notice, this list of conditions and the following
13 13
#      disclaimer in the documentation and/or other materials
14 14
#      provided with the distribution.
15
# 
15
#
16 16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
......
25 25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
28
#
29 29
# The views and conclusions contained in the software and
30 30
# documentation are those of the authors and should not be
31 31
# interpreted as representing official policies, either expressed
......
41 41
#
42 42
# The OpenStack Compute API v1.1
43 43
#
44
api11_patterns = patterns('',
44
api11_patterns = patterns(
45
    '',
45 46
    (r'^servers', include(servers)),
46 47
    (r'^flavors', include(flavors)),
47 48
    (r'^images', include(images)),
......
49 50
)
50 51

  
51 52

  
52
urlpatterns = patterns('',
53
urlpatterns = patterns(
54
    '',
53 55
    (r'^(?:.json|.xml|.atom)?$', versions_list),
54
    (r'^v1.1/(?:.json|.xml|.atom)?$', version_details, {'api_version': 'v1.1'}),
56
    (r'^v1.1/(?:.json|.xml|.atom)?$', version_details,
57
        {'api_version': 'v1.1'}),
55 58
    (r'^v1.1/', include(api11_patterns)),
56 59
    (r'^.+', not_found),
57 60
)
b/snf-cyclades-app/synnefo/api/util.py
206 206
    properties = img.get('properties', {})
207 207
    image['backend_id'] = img['location']
208 208
    image['format'] = img['disk_format']
209
    image['metadata'] = dict((key.upper(), val) \
209
    image['metadata'] = dict((key.upper(), val)
210 210
                             for key, val in properties.items())
211 211
    image['checksum'] = img['checksum']
212 212

  
......
318 318
    matching_nics = vm.nics.filter(index=nic_index)
319 319
    matching_nics_len = len(matching_nics)
320 320
    if matching_nics_len < 1:
321
        raise  ItemNotFound('NIC not found on VM')
321
        raise ItemNotFound('NIC not found on VM')
322 322
    elif matching_nics_len > 1:
323 323
        raise BadMediaType('NIC index conflict on VM')
324 324
    nic = matching_nics[0]
......
379 379
    if request.serialization == 'xml':
380 380
        data = render_to_string('fault.xml', {'fault': fault})
381 381
    else:
382
        d = {fault.name: {
383
                'code': fault.code,
384
                'message': fault.message,
385
                'details': fault.details}}
382
        d = {fault.name: {'code': fault.code,
383
                          'message': fault.message,
384
                          'details': fault.details}}
386 385
        data = json.dumps(d)
387 386

  
388 387
    resp = HttpResponse(data, status=fault.code)
......
468 467
    """Verify that a a list of personalities is well formed"""
469 468
    if len(personality) > settings.MAX_PERSONALITY:
470 469
        raise OverLimit("Maximum number of personalities"
471
                               " exceeded")
470
                        " exceeded")
472 471
    for p in personality:
473 472
        # Verify that personalities are well-formed
474 473
        try:
......
500 499
        disk_template, provider = disk_template.split("_", 1)
501 500
    return disk_template, provider
502 501

  
502

  
503 503
def values_from_flavor(flavor):
504 504
    """Get Ganeti connectivity info from flavor type.
505 505

  
......
560 560
    from synnefo.db.models import VirtualMachine, Network
561 561

  
562 562
    keypairusernames = PublicKeyPair.objects.filter().values_list('user',
563
                                                               flat=True)
563
                                                                  flat=True)
564 564
    serverusernames = VirtualMachine.objects.filter().values_list('userid',
565
                                                                   flat=True)
565
                                                                  flat=True)
566 566
    networkusernames = Network.objects.filter().values_list('userid',
567 567
                                                            flat=True)
568 568

  
569
    return set(list(keypairusernames) + list(serverusernames) + \
570
           list(networkusernames))
571

  
569
    return set(list(keypairusernames) + list(serverusernames) +
570
               list(networkusernames))
b/snf-cyclades-app/synnefo/api/versions.py
1 1
# Copyright 2011 GRNET S.A. All rights reserved.
2
# 
2
#
3 3
# Redistribution and use in source and binary forms, with or
4 4
# without modification, are permitted provided that the following
5 5
# conditions are met:
6
# 
6
#
7 7
#   1. Redistributions of source code must retain the above
8 8
#      copyright notice, this list of conditions and the following
9 9
#      disclaimer.
10
# 
10
#
11 11
#   2. Redistributions in binary form must reproduce the above
12 12
#      copyright notice, this list of conditions and the following
13 13
#      disclaimer in the documentation and/or other materials
14 14
#      provided with the distribution.
15
# 
15
#
16 16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
......
25 25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
28
#
29 29
# The views and conclusions contained in the software and
30 30
# documentation are those of the authors and should not be
31 31
# interpreted as representing official policies, either expressed
......
100 100
    #                       unauthorized (401),
101 101
    #                       badRequest (400),
102 102
    #                       overLimit(413)
103
    
103

  
104 104
    log.debug('version_details %s', api_version)
105 105
    # We hardcode to v1.1 since it is the only one we support
106 106
    version = VERSION_1_1.copy()

Also available in: Unified diff