Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / api / old_networks.py @ f32e8021

History | View | Annotate | Download (10.2 kB)

1 0baa1e3d Buildbot
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2 0baa1e3d Buildbot
#
3 0baa1e3d Buildbot
# Redistribution and use in source and binary forms, with or
4 0baa1e3d Buildbot
# without modification, are permitted provided that the following
5 0baa1e3d Buildbot
# conditions are met:
6 0baa1e3d Buildbot
#
7 0baa1e3d Buildbot
#   1. Redistributions of source code must retain the above
8 0baa1e3d Buildbot
#      copyright notice, this list of conditions and the following
9 0baa1e3d Buildbot
#      disclaimer.
10 0baa1e3d Buildbot
#
11 0baa1e3d Buildbot
#   2. Redistributions in binary form must reproduce the above
12 0baa1e3d Buildbot
#      copyright notice, this list of conditions and the following
13 0baa1e3d Buildbot
#      disclaimer in the documentation and/or other materials
14 0baa1e3d Buildbot
#      provided with the distribution.
15 0baa1e3d Buildbot
#
16 0baa1e3d Buildbot
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 0baa1e3d Buildbot
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 0baa1e3d Buildbot
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 0baa1e3d Buildbot
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 0baa1e3d Buildbot
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 0baa1e3d Buildbot
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 0baa1e3d Buildbot
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 0baa1e3d Buildbot
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 0baa1e3d Buildbot
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 0baa1e3d Buildbot
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 0baa1e3d Buildbot
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 0baa1e3d Buildbot
# POSSIBILITY OF SUCH DAMAGE.
28 0baa1e3d Buildbot
#
29 0baa1e3d Buildbot
# The views and conclusions contained in the software and
30 0baa1e3d Buildbot
# documentation are those of the authors and should not be
31 0baa1e3d Buildbot
# interpreted as representing official policies, either expressed
32 0baa1e3d Buildbot
# or implied, of GRNET S.A.
33 0baa1e3d Buildbot
from django.conf import settings
34 0baa1e3d Buildbot
from django.conf.urls import patterns
35 0baa1e3d Buildbot
36 0baa1e3d Buildbot
from django.db.models import Q
37 0baa1e3d Buildbot
from django.http import HttpResponse
38 0baa1e3d Buildbot
from django.template.loader import render_to_string
39 0baa1e3d Buildbot
from django.utils import simplejson as json
40 0baa1e3d Buildbot
41 0baa1e3d Buildbot
from snf_django.lib import api
42 0baa1e3d Buildbot
from snf_django.lib.api import faults, utils
43 0baa1e3d Buildbot
from synnefo.api import util
44 0baa1e3d Buildbot
from synnefo.api.servers import network_actions
45 0baa1e3d Buildbot
from synnefo.db.models import Network
46 0baa1e3d Buildbot
from synnefo.logic import networks
47 0baa1e3d Buildbot
48 0baa1e3d Buildbot
49 0baa1e3d Buildbot
from logging import getLogger
50 0baa1e3d Buildbot
log = getLogger(__name__)
51 0baa1e3d Buildbot
52 0baa1e3d Buildbot
urlpatterns = patterns(
53 0baa1e3d Buildbot
    'synnefo.api.networks',
54 0baa1e3d Buildbot
    (r'^(?:/|.json|.xml)?$', 'demux'),
55 0baa1e3d Buildbot
    (r'^/detail(?:.json|.xml)?$', 'list_networks', {'detail': True}),
56 0baa1e3d Buildbot
    (r'^/(\w+)(?:.json|.xml)?$', 'network_demux'),
57 0baa1e3d Buildbot
    (r'^/(\w+)/action(?:.json|.xml)?$', 'demux_network_action'),
58 0baa1e3d Buildbot
)
59 0baa1e3d Buildbot
60 0baa1e3d Buildbot
61 0baa1e3d Buildbot
def demux(request):
62 0baa1e3d Buildbot
    if request.method == 'GET':
63 0baa1e3d Buildbot
        return list_networks(request)
64 0baa1e3d Buildbot
    elif request.method == 'POST':
65 0baa1e3d Buildbot
        return create_network(request)
66 0baa1e3d Buildbot
    else:
67 0baa1e3d Buildbot
        return api.api_method_not_allowed(request)
68 0baa1e3d Buildbot
69 0baa1e3d Buildbot
70 0baa1e3d Buildbot
def network_demux(request, network_id):
71 0baa1e3d Buildbot
    if request.method == 'GET':
72 0baa1e3d Buildbot
        return get_network_details(request, network_id)
73 0baa1e3d Buildbot
    elif request.method == 'PUT':
74 0baa1e3d Buildbot
        return update_network_name(request, network_id)
75 0baa1e3d Buildbot
    elif request.method == 'DELETE':
76 0baa1e3d Buildbot
        return delete_network(request, network_id)
77 0baa1e3d Buildbot
    else:
78 0baa1e3d Buildbot
        return api.api_method_not_allowed(request)
79 0baa1e3d Buildbot
80 0baa1e3d Buildbot
81 0baa1e3d Buildbot
def network_to_dict(network, user_id, detail=True):
82 0baa1e3d Buildbot
    d = {'id': str(network.id), 'name': network.name}
83 0baa1e3d Buildbot
    d['links'] = util.network_to_links(network.id)
84 0baa1e3d Buildbot
    if detail:
85 0baa1e3d Buildbot
        d['user_id'] = network.userid
86 0baa1e3d Buildbot
        d['tenant_id'] = network.userid
87 0baa1e3d Buildbot
        d['cidr'] = network.subnet
88 0baa1e3d Buildbot
        d['cidr6'] = network.subnet6
89 0baa1e3d Buildbot
        d['gateway'] = network.gateway
90 0baa1e3d Buildbot
        d['gateway6'] = network.gateway6
91 0baa1e3d Buildbot
        d['dhcp'] = network.dhcp
92 0baa1e3d Buildbot
        d['type'] = network.flavor
93 0baa1e3d Buildbot
        d['updated'] = utils.isoformat(network.updated)
94 0baa1e3d Buildbot
        d['created'] = utils.isoformat(network.created)
95 0baa1e3d Buildbot
        d['status'] = network.state
96 0baa1e3d Buildbot
        d['public'] = network.public
97 0baa1e3d Buildbot
98 0baa1e3d Buildbot
        attachments = [nic.id
99 0baa1e3d Buildbot
                       for nic in network.nics.filter(machine__userid=user_id)
100 0baa1e3d Buildbot
                                              .filter(state="ACTIVE")
101 0baa1e3d Buildbot
                                              .order_by('machine')]
102 0baa1e3d Buildbot
        d['attachments'] = attachments
103 0baa1e3d Buildbot
    return d
104 0baa1e3d Buildbot
105 0baa1e3d Buildbot
106 0baa1e3d Buildbot
def render_network(request, networkdict, status=200):
107 0baa1e3d Buildbot
    if request.serialization == 'xml':
108 0baa1e3d Buildbot
        data = render_to_string('network.xml', {'network': networkdict})
109 0baa1e3d Buildbot
    else:
110 0baa1e3d Buildbot
        data = json.dumps({'network': networkdict})
111 0baa1e3d Buildbot
    return HttpResponse(data, status=status)
112 0baa1e3d Buildbot
113 0baa1e3d Buildbot
114 0baa1e3d Buildbot
@api.api_method(http_method='GET', user_required=True, logger=log)
115 0baa1e3d Buildbot
def list_networks(request, detail=False):
116 0baa1e3d Buildbot
    # Normal Response Codes: 200, 203
117 0baa1e3d Buildbot
    # Error Response Codes: computeFault (400, 500),
118 0baa1e3d Buildbot
    #                       serviceUnavailable (503),
119 0baa1e3d Buildbot
    #                       unauthorized (401),
120 0baa1e3d Buildbot
    #                       badRequest (400),
121 0baa1e3d Buildbot
    #                       overLimit (413)
122 0baa1e3d Buildbot
123 0baa1e3d Buildbot
    log.debug('list_networks detail=%s', detail)
124 0baa1e3d Buildbot
    user_networks = Network.objects.filter(Q(userid=request.user_uniq) |
125 0baa1e3d Buildbot
                                           Q(public=True))
126 0baa1e3d Buildbot
    user_networks = utils.filter_modified_since(request, objects=user_networks)
127 0baa1e3d Buildbot
128 0baa1e3d Buildbot
    networks_dict = [network_to_dict(network, request.user_uniq, detail)
129 0baa1e3d Buildbot
                     for network in user_networks.order_by('id')]
130 0baa1e3d Buildbot
131 0baa1e3d Buildbot
    if request.serialization == 'xml':
132 0baa1e3d Buildbot
        data = render_to_string('list_networks.xml', {
133 0baa1e3d Buildbot
            'networks': networks_dict,
134 0baa1e3d Buildbot
            'detail': detail})
135 0baa1e3d Buildbot
    else:
136 0baa1e3d Buildbot
        data = json.dumps({'networks': networks_dict})
137 0baa1e3d Buildbot
138 0baa1e3d Buildbot
    return HttpResponse(data, status=200)
139 0baa1e3d Buildbot
140 0baa1e3d Buildbot
141 0baa1e3d Buildbot
@api.api_method(http_method='POST', user_required=True, logger=log)
142 0baa1e3d Buildbot
def create_network(request):
143 0baa1e3d Buildbot
    # Normal Response Code: 202
144 0baa1e3d Buildbot
    # Error Response Codes: computeFault (400, 500),
145 0baa1e3d Buildbot
    #                       serviceUnavailable (503),
146 0baa1e3d Buildbot
    #                       unauthorized (401),
147 0baa1e3d Buildbot
    #                       badMediaType(415),
148 0baa1e3d Buildbot
    #                       badRequest (400),
149 0baa1e3d Buildbot
    #                       forbidden (403)
150 0baa1e3d Buildbot
    #                       overLimit (413)
151 0baa1e3d Buildbot
152 0baa1e3d Buildbot
    req = utils.get_request_dict(request)
153 0baa1e3d Buildbot
    log.info('create_network %s', req)
154 0baa1e3d Buildbot
    user_id = request.user_uniq
155 0baa1e3d Buildbot
    try:
156 0baa1e3d Buildbot
        d = req['network']
157 0baa1e3d Buildbot
        name = d['name']
158 0baa1e3d Buildbot
    except KeyError:
159 0baa1e3d Buildbot
        raise faults.BadRequest("Malformed request")
160 0baa1e3d Buildbot
161 0baa1e3d Buildbot
    # Get and validate flavor. Flavors are still exposed as 'type' in the
162 0baa1e3d Buildbot
    # API.
163 0baa1e3d Buildbot
    flavor = d.get("type", None)
164 0baa1e3d Buildbot
    if flavor is None:
165 0baa1e3d Buildbot
        raise faults.BadRequest("Missing request parameter 'type'")
166 0baa1e3d Buildbot
    elif flavor not in Network.FLAVORS.keys():
167 0baa1e3d Buildbot
        raise faults.BadRequest("Invalid network type '%s'" % flavor)
168 0baa1e3d Buildbot
    elif flavor not in settings.API_ENABLED_NETWORK_FLAVORS:
169 0baa1e3d Buildbot
        raise faults.Forbidden("Can not create network of type '%s'" %
170 0baa1e3d Buildbot
                               flavor)
171 0baa1e3d Buildbot
172 0baa1e3d Buildbot
    public = d.get("public", False)
173 0baa1e3d Buildbot
    if public:
174 0baa1e3d Buildbot
        raise faults.Forbidden("Can not create a public network.")
175 0baa1e3d Buildbot
176 0baa1e3d Buildbot
    dhcp = d.get('dhcp', True)
177 0baa1e3d Buildbot
178 0baa1e3d Buildbot
    # Get and validate network parameters
179 0baa1e3d Buildbot
    subnet = d.get('cidr', '192.168.1.0/24')
180 0baa1e3d Buildbot
    subnet6 = d.get('cidr6', None)
181 0baa1e3d Buildbot
    gateway = d.get('gateway', None)
182 0baa1e3d Buildbot
    gateway6 = d.get('gateway6', None)
183 0baa1e3d Buildbot
184 0baa1e3d Buildbot
    network = networks.create(user_id=user_id, name=name, flavor=flavor,
185 0baa1e3d Buildbot
                              subnet=subnet, gateway=gateway, subnet6=subnet6,
186 0baa1e3d Buildbot
                              gateway6=gateway6, dhcp=dhcp, public=False)
187 0baa1e3d Buildbot
188 0baa1e3d Buildbot
    networkdict = network_to_dict(network, request.user_uniq)
189 0baa1e3d Buildbot
    response = render_network(request, networkdict, status=202)
190 0baa1e3d Buildbot
191 0baa1e3d Buildbot
    return response
192 0baa1e3d Buildbot
193 0baa1e3d Buildbot
194 0baa1e3d Buildbot
@api.api_method(http_method='GET', user_required=True, logger=log)
195 0baa1e3d Buildbot
def get_network_details(request, network_id):
196 0baa1e3d Buildbot
    # Normal Response Codes: 200, 203
197 0baa1e3d Buildbot
    # Error Response Codes: computeFault (400, 500),
198 0baa1e3d Buildbot
    #                       serviceUnavailable (503),
199 0baa1e3d Buildbot
    #                       unauthorized (401),
200 0baa1e3d Buildbot
    #                       badRequest (400),
201 0baa1e3d Buildbot
    #                       itemNotFound (404),
202 0baa1e3d Buildbot
    #                       overLimit (413)
203 0baa1e3d Buildbot
204 0baa1e3d Buildbot
    log.debug('get_network_details %s', network_id)
205 0baa1e3d Buildbot
    net = util.get_network(network_id, request.user_uniq)
206 0baa1e3d Buildbot
    netdict = network_to_dict(net, request.user_uniq)
207 0baa1e3d Buildbot
    return render_network(request, netdict)
208 0baa1e3d Buildbot
209 0baa1e3d Buildbot
210 0baa1e3d Buildbot
@api.api_method(http_method='PUT', user_required=True, logger=log)
211 0baa1e3d Buildbot
def update_network_name(request, network_id):
212 0baa1e3d Buildbot
    # Normal Response Code: 204
213 0baa1e3d Buildbot
    # Error Response Codes: computeFault (400, 500),
214 0baa1e3d Buildbot
    #                       serviceUnavailable (503),
215 0baa1e3d Buildbot
    #                       unauthorized (401),
216 0baa1e3d Buildbot
    #                       badRequest (400),
217 0baa1e3d Buildbot
    #                       forbidden (403)
218 0baa1e3d Buildbot
    #                       badMediaType(415),
219 0baa1e3d Buildbot
    #                       itemNotFound (404),
220 0baa1e3d Buildbot
    #                       overLimit (413)
221 0baa1e3d Buildbot
222 0baa1e3d Buildbot
    req = utils.get_request_dict(request)
223 0baa1e3d Buildbot
    log.info('update_network_name %s', network_id)
224 0baa1e3d Buildbot
225 0baa1e3d Buildbot
    try:
226 0baa1e3d Buildbot
        name = req['network']['name']
227 0baa1e3d Buildbot
    except (TypeError, KeyError):
228 0baa1e3d Buildbot
        raise faults.BadRequest('Malformed request.')
229 0baa1e3d Buildbot
230 0baa1e3d Buildbot
    network = util.get_network(network_id, request.user_uniq)
231 0baa1e3d Buildbot
    if network.public:
232 0baa1e3d Buildbot
        raise faults.Forbidden('Can not rename the public network.')
233 0baa1e3d Buildbot
    network = networks.rename(network, name)
234 0baa1e3d Buildbot
    return HttpResponse(status=204)
235 0baa1e3d Buildbot
236 0baa1e3d Buildbot
237 0baa1e3d Buildbot
@api.api_method(http_method='DELETE', user_required=True, logger=log)
238 0baa1e3d Buildbot
def delete_network(request, network_id):
239 0baa1e3d Buildbot
    # Normal Response Code: 204
240 0baa1e3d Buildbot
    # Error Response Codes: computeFault (400, 500),
241 0baa1e3d Buildbot
    #                       serviceUnavailable (503),
242 0baa1e3d Buildbot
    #                       unauthorized (401),
243 0baa1e3d Buildbot
    #                       forbidden (403)
244 0baa1e3d Buildbot
    #                       itemNotFound (404),
245 0baa1e3d Buildbot
    #                       overLimit (413)
246 0baa1e3d Buildbot
247 0baa1e3d Buildbot
    log.info('delete_network %s', network_id)
248 0baa1e3d Buildbot
    network = util.get_network(network_id, request.user_uniq, for_update=True)
249 0baa1e3d Buildbot
    if network.public:
250 0baa1e3d Buildbot
        raise faults.Forbidden('Can not delete the public network.')
251 0baa1e3d Buildbot
    networks.delete(network)
252 0baa1e3d Buildbot
    return HttpResponse(status=204)
253 0baa1e3d Buildbot
254 0baa1e3d Buildbot
255 0baa1e3d Buildbot
def key_to_action(action):
256 0baa1e3d Buildbot
    return action.upper()
257 0baa1e3d Buildbot
258 0baa1e3d Buildbot
259 0baa1e3d Buildbot
@api.api_method(http_method='POST', user_required=True, logger=log)
260 0baa1e3d Buildbot
def demux_network_action(request, network_id):
261 0baa1e3d Buildbot
    req = utils.get_request_dict(request)
262 0baa1e3d Buildbot
    log.debug('network_action %s %s', network_id, req)
263 0baa1e3d Buildbot
    if len(req) != 1:
264 0baa1e3d Buildbot
        raise faults.BadRequest('Malformed request.')
265 0baa1e3d Buildbot
266 0baa1e3d Buildbot
    net = util.get_network(network_id, request.user_uniq)
267 0baa1e3d Buildbot
    if net.public:
268 0baa1e3d Buildbot
        raise faults.Forbidden('Can not modify the public network.')
269 0baa1e3d Buildbot
    if net.deleted:
270 0baa1e3d Buildbot
        raise faults.BadRequest("Network has been deleted.")
271 0baa1e3d Buildbot
272 0baa1e3d Buildbot
    action = req.keys()[0]
273 0baa1e3d Buildbot
    if key_to_action(action) not in [x[0] for x in Network.ACTIONS]:
274 0baa1e3d Buildbot
        raise faults.BadRequest("Action %s not supported." % action)
275 0baa1e3d Buildbot
    action_args = req[action]
276 0baa1e3d Buildbot
    if not isinstance(action_args, dict):
277 0baa1e3d Buildbot
        raise faults.BadRequest("Invalid argument.")
278 0baa1e3d Buildbot
    return network_actions[action](request, net, action_args)