Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / networks.py @ cad4793e

History | View | Annotate | Download (6.8 kB)

1 a96e84cf Christos Stavrakakis
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2 a96e84cf Christos Stavrakakis
#
3 a96e84cf Christos Stavrakakis
# Redistribution and use in source and binary forms, with or
4 a96e84cf Christos Stavrakakis
# without modification, are permitted provided that the following
5 a96e84cf Christos Stavrakakis
# conditions are met:
6 a96e84cf Christos Stavrakakis
#
7 a96e84cf Christos Stavrakakis
#   1. Redistributions of source code must retain the above
8 a96e84cf Christos Stavrakakis
#      copyright notice, this list of conditions and the following
9 a96e84cf Christos Stavrakakis
#      disclaimer.
10 a96e84cf Christos Stavrakakis
#
11 a96e84cf Christos Stavrakakis
#   2. Redistributions in binary form must reproduce the above
12 a96e84cf Christos Stavrakakis
#      copyright notice, this list of conditions and the following
13 a96e84cf Christos Stavrakakis
#      disclaimer in the documentation and/or other materials
14 a96e84cf Christos Stavrakakis
#      provided with the distribution.
15 a96e84cf Christos Stavrakakis
#
16 a96e84cf Christos Stavrakakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 a96e84cf Christos Stavrakakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 a96e84cf Christos Stavrakakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 a96e84cf Christos Stavrakakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 a96e84cf Christos Stavrakakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 a96e84cf Christos Stavrakakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 a96e84cf Christos Stavrakakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 a96e84cf Christos Stavrakakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 a96e84cf Christos Stavrakakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 a96e84cf Christos Stavrakakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 a96e84cf Christos Stavrakakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 a96e84cf Christos Stavrakakis
# POSSIBILITY OF SUCH DAMAGE.
28 a96e84cf Christos Stavrakakis
#
29 a96e84cf Christos Stavrakakis
# The views and conclusions contained in the software and
30 a96e84cf Christos Stavrakakis
# documentation are those of the authors and should not be
31 a96e84cf Christos Stavrakakis
# interpreted as representing official policies, either expressed
32 a96e84cf Christos Stavrakakis
# or implied, of GRNET S.A.
33 a96e84cf Christos Stavrakakis
34 ce55f211 Kostas Papadimitriou
from django.conf import settings
35 6b256427 Christos Stavrakakis
from django.conf.urls import patterns
36 0269afd6 Giorgos Verigakis
from django.http import HttpResponse
37 0269afd6 Giorgos Verigakis
from django.utils import simplejson as json
38 0baa1e3d Buildbot
from django.db import transaction
39 0baa1e3d Buildbot
from django.db.models import Q
40 0baa1e3d Buildbot
from django.template.loader import render_to_string
41 a96e84cf Christos Stavrakakis
42 a96e84cf Christos Stavrakakis
from snf_django.lib import api
43 a96e84cf Christos Stavrakakis
44 5061546f Christos Stavrakakis
from synnefo.api import util
45 03992c72 Christos Stavrakakis
from synnefo.db.models import Network
46 a96e84cf Christos Stavrakakis
from synnefo.logic import networks
47 9e98ba3c Giorgos Verigakis
48 b3fd98ae Christos Stavrakakis
from logging import getLogger
49 0baa1e3d Buildbot
50 b3fd98ae Christos Stavrakakis
log = getLogger(__name__)
51 b36f78fa Giorgos Verigakis
52 e440e835 Christos Stavrakakis
urlpatterns = patterns(
53 e440e835 Christos Stavrakakis
    'synnefo.api.networks',
54 95a213d4 Christos Stavrakakis
    (r'^(?:/|.json|.xml)?$', 'demux'),
55 a96e84cf Christos Stavrakakis
    (r'^/detail(?:.json|.xml)?$', 'list_networks', {'detail': True}),
56 95a213d4 Christos Stavrakakis
    (r'^/(\w+)(?:/|.json|.xml)?$', 'network_demux'))
57 95a213d4 Christos Stavrakakis
58 0269afd6 Giorgos Verigakis
59 0269afd6 Giorgos Verigakis
def demux(request):
60 0269afd6 Giorgos Verigakis
    if request.method == 'GET':
61 0269afd6 Giorgos Verigakis
        return list_networks(request)
62 0269afd6 Giorgos Verigakis
    elif request.method == 'POST':
63 0269afd6 Giorgos Verigakis
        return create_network(request)
64 0269afd6 Giorgos Verigakis
    else:
65 c0720b78 Kostas Papadimitriou
        return api.api_method_not_allowed(request)
66 0269afd6 Giorgos Verigakis
67 6ef51e9f Giorgos Verigakis
68 a96e84cf Christos Stavrakakis
def network_demux(request, network_id):
69 0baa1e3d Buildbot
70 0269afd6 Giorgos Verigakis
    if request.method == 'GET':
71 a96e84cf Christos Stavrakakis
        return get_network_details(request, network_id)
72 0269afd6 Giorgos Verigakis
    elif request.method == 'DELETE':
73 a96e84cf Christos Stavrakakis
        return delete_network(request, network_id)
74 0baa1e3d Buildbot
    elif request.method == 'PUT':
75 a96e84cf Christos Stavrakakis
        return update_network(request, network_id)
76 0269afd6 Giorgos Verigakis
    else:
77 c0720b78 Kostas Papadimitriou
        return api.api_method_not_allowed(request)
78 0269afd6 Giorgos Verigakis
79 0269afd6 Giorgos Verigakis
80 b3fd98ae Christos Stavrakakis
@api.api_method(http_method='GET', user_required=True, logger=log)
81 0269afd6 Giorgos Verigakis
def list_networks(request, detail=False):
82 0c37a721 Christos Stavrakakis
    log.debug('list_networks detail=%s', detail)
83 0baa1e3d Buildbot
84 a96e84cf Christos Stavrakakis
    user_networks = Network.objects.filter(Q(userid=request.user_uniq) |
85 a96e84cf Christos Stavrakakis
                                           Q(public=True))\
86 a96e84cf Christos Stavrakakis
                                   .prefetch_related("subnets")
87 0baa1e3d Buildbot
88 a96e84cf Christos Stavrakakis
    user_networks = api.utils.filter_modified_since(request,
89 a96e84cf Christos Stavrakakis
                                                    objects=user_networks)
90 ce55f211 Kostas Papadimitriou
91 a96e84cf Christos Stavrakakis
    network_dicts = [network_to_dict(network, detail)
92 a96e84cf Christos Stavrakakis
                     for network in user_networks.order_by('id')]
93 ce55f211 Kostas Papadimitriou
94 0269afd6 Giorgos Verigakis
    if request.serialization == 'xml':
95 b36f78fa Giorgos Verigakis
        data = render_to_string('list_networks.xml', {
96 a96e84cf Christos Stavrakakis
            "networks": network_dicts})
97 0269afd6 Giorgos Verigakis
    else:
98 a96e84cf Christos Stavrakakis
        data = json.dumps({'networks': network_dicts})
99 aa197ee4 Vangelis Koukis
100 0269afd6 Giorgos Verigakis
    return HttpResponse(data, status=200)
101 0269afd6 Giorgos Verigakis
102 6ef51e9f Giorgos Verigakis
103 b3fd98ae Christos Stavrakakis
@api.api_method(http_method='POST', user_required=True, logger=log)
104 2509ce17 Christos Stavrakakis
def create_network(request):
105 a96e84cf Christos Stavrakakis
    userid = request.user_uniq
106 a96e84cf Christos Stavrakakis
    req = api.utils.get_request_dict(request)
107 a96e84cf Christos Stavrakakis
    log.info('create_network %s', req)
108 a96e84cf Christos Stavrakakis
109 a96e84cf Christos Stavrakakis
    network_dict = api.utils.get_attribute(req, "network")
110 a96e84cf Christos Stavrakakis
    flavor = api.utils.get_attribute(network_dict, "type")
111 a96e84cf Christos Stavrakakis
112 a96e84cf Christos Stavrakakis
    if flavor not in Network.FLAVORS.keys():
113 a96e84cf Christos Stavrakakis
        raise api.faults.BadRequest("Invalid network type '%s'" % flavor)
114 a96e84cf Christos Stavrakakis
    if flavor not in settings.API_ENABLED_NETWORK_FLAVORS:
115 a96e84cf Christos Stavrakakis
        raise api.faults.Forbidden("Can not create network of type '%s'." %
116 a96e84cf Christos Stavrakakis
                                   flavor)
117 a96e84cf Christos Stavrakakis
118 a96e84cf Christos Stavrakakis
    name = api.utils.get_attribute(network_dict, "name", required=False)
119 a96e84cf Christos Stavrakakis
    if name is None:
120 a96e84cf Christos Stavrakakis
        name = ""
121 a96e84cf Christos Stavrakakis
122 a96e84cf Christos Stavrakakis
    network = networks.create(userid=userid, name=name, flavor=flavor,
123 a96e84cf Christos Stavrakakis
                              public=False)
124 a96e84cf Christos Stavrakakis
    networkdict = network_to_dict(network, detail=True)
125 0baa1e3d Buildbot
    response = render_network(request, networkdict, status=201)
126 77f45438 Christos Stavrakakis
127 77f45438 Christos Stavrakakis
    return response
128 0269afd6 Giorgos Verigakis
129 6ef51e9f Giorgos Verigakis
130 b3fd98ae Christos Stavrakakis
@api.api_method(http_method='GET', user_required=True, logger=log)
131 a96e84cf Christos Stavrakakis
def get_network_details(request, network_id):
132 0c37a721 Christos Stavrakakis
    log.debug('get_network_details %s', network_id)
133 a96e84cf Christos Stavrakakis
    network = util.get_network(network_id, request.user_uniq)
134 a96e84cf Christos Stavrakakis
    return render_network(request, network_to_dict(network, detail=True))
135 6ef51e9f Giorgos Verigakis
136 a96e84cf Christos Stavrakakis
137 a96e84cf Christos Stavrakakis
@api.api_method(http_method='PUT', user_required=True, logger=log)
138 a96e84cf Christos Stavrakakis
def update_network(request, network_id):
139 a96e84cf Christos Stavrakakis
    info = api.utils.get_request_dict(request)
140 a96e84cf Christos Stavrakakis
141 a96e84cf Christos Stavrakakis
    network = api.utils.get_attribute(info, "network", required=True)
142 a96e84cf Christos Stavrakakis
    new_name = api.utils.get_attribute(network, "name")
143 a96e84cf Christos Stavrakakis
144 a96e84cf Christos Stavrakakis
    network = util.get_network(network_id, request.user_uniq, for_update=True)
145 a96e84cf Christos Stavrakakis
    if network.public:
146 a96e84cf Christos Stavrakakis
        raise api.faults.Forbidden("Can not rename the public network.")
147 a96e84cf Christos Stavrakakis
    network = networks.rename(network, new_name)
148 a96e84cf Christos Stavrakakis
    return render_network(request, network_to_dict(network), 200)
149 0269afd6 Giorgos Verigakis
150 6ef51e9f Giorgos Verigakis
151 b3fd98ae Christos Stavrakakis
@api.api_method(http_method='DELETE', user_required=True, logger=log)
152 0baa1e3d Buildbot
@transaction.commit_on_success
153 b19653d1 Giorgos Verigakis
def delete_network(request, network_id):
154 bf5c82dc Christos Stavrakakis
    log.info('delete_network %s', network_id)
155 a96e84cf Christos Stavrakakis
    network = util.get_network(network_id, request.user_uniq, for_update=True)
156 a96e84cf Christos Stavrakakis
    if network.public:
157 a96e84cf Christos Stavrakakis
        raise api.faults.Forbidden("Can not delete the public network.")
158 a96e84cf Christos Stavrakakis
    networks.delete(network)
159 ece5581b Christos Stavrakakis
    return HttpResponse(status=204)
160 5061546f Christos Stavrakakis
161 5061546f Christos Stavrakakis
162 0baa1e3d Buildbot
def network_to_dict(network, detail=True):
163 0baa1e3d Buildbot
    d = {'id': str(network.id), 'name': network.name}
164 0baa1e3d Buildbot
    d['links'] = util.network_to_links(network.id)
165 0baa1e3d Buildbot
    if detail:
166 0baa1e3d Buildbot
        d['user_id'] = network.userid
167 0baa1e3d Buildbot
        d['tenant_id'] = network.userid
168 0baa1e3d Buildbot
        d['type'] = network.flavor
169 a96e84cf Christos Stavrakakis
        d['updated'] = api.utils.isoformat(network.updated)
170 a96e84cf Christos Stavrakakis
        d['created'] = api.utils.isoformat(network.created)
171 0baa1e3d Buildbot
        d['status'] = network.state
172 0baa1e3d Buildbot
        d['public'] = network.public
173 0baa1e3d Buildbot
        d['external_router'] = network.external_router
174 0baa1e3d Buildbot
        d['admin_state_up'] = True
175 a96e84cf Christos Stavrakakis
        d['subnets'] = list(network.subnets.values_list('id', flat=True))
176 7421d45e Christos Stavrakakis
        d['SNF:floating_ip_pool'] = network.floating_ip_pool
177 0baa1e3d Buildbot
    return d
178 0baa1e3d Buildbot
179 0baa1e3d Buildbot
180 0baa1e3d Buildbot
def render_network(request, networkdict, status=200):
181 0baa1e3d Buildbot
    if request.serialization == 'xml':
182 0baa1e3d Buildbot
        data = render_to_string('network.xml', {'network': networkdict})
183 0baa1e3d Buildbot
    else:
184 0baa1e3d Buildbot
        data = json.dumps({'network': networkdict})
185 0baa1e3d Buildbot
    return HttpResponse(data, status=status)