Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / neutron / router_views.py @ 5cf968ab

History | View | Annotate | Download (10.1 kB)

1 2e0916f2 Marios Kogias
from django.http import HttpResponse
2 2e0916f2 Marios Kogias
from django.utils import simplejson as json
3 2e0916f2 Marios Kogias
from django.db import transaction
4 2e0916f2 Marios Kogias
from django.db.models import Q
5 2e0916f2 Marios Kogias
from synnefo.db.pools import EmptyPool
6 2e0916f2 Marios Kogias
from synnefo.db.utils import validate_mac
7 2e0916f2 Marios Kogias
from django.conf import settings
8 2e0916f2 Marios Kogias
from snf_django.lib import api
9 2e0916f2 Marios Kogias
from snf_django.lib.api import utils
10 2e0916f2 Marios Kogias
from synnefo.logic import backend
11 2e0916f2 Marios Kogias
from django.template.loader import render_to_string
12 2e0916f2 Marios Kogias
from synnefo.api import util
13 2e0916f2 Marios Kogias
14 2e0916f2 Marios Kogias
from synnefo.db.models import VirtualMachine
15 2e0916f2 Marios Kogias
import models
16 5cf968ab Marios Kogias
import subnet_views
17 2e0916f2 Marios Kogias
from logging import getLogger
18 2e0916f2 Marios Kogias
19 2e0916f2 Marios Kogias
import network_views as nv
20 2e0916f2 Marios Kogias
#from synnefo.logic import servers
21 2e0916f2 Marios Kogias
22 2e0916f2 Marios Kogias
log = getLogger(__name__)
23 2e0916f2 Marios Kogias
24 2e0916f2 Marios Kogias
25 2e0916f2 Marios Kogias
def demux(request):
26 2e0916f2 Marios Kogias
    if request.method == 'GET':
27 2e0916f2 Marios Kogias
        #return HttpResponse("list routers")
28 2e0916f2 Marios Kogias
        return list_routers(request)
29 2e0916f2 Marios Kogias
    elif request.method == 'POST':
30 5cf968ab Marios Kogias
        return create_router(request)
31 5cf968ab Marios Kogias
        #return HttpResponse("create router")
32 2e0916f2 Marios Kogias
    else:
33 2e0916f2 Marios Kogias
        return api.api_method_not_allowed(request)
34 2e0916f2 Marios Kogias
35 2e0916f2 Marios Kogias
36 2e0916f2 Marios Kogias
def router_demux(request, offset):
37 2e0916f2 Marios Kogias
    if request.method == 'GET':
38 2e0916f2 Marios Kogias
        #return HttpResponse("get single router")
39 2e0916f2 Marios Kogias
        return get_router(request,  offset)
40 2e0916f2 Marios Kogias
    elif request.method == 'DELETE':
41 2e0916f2 Marios Kogias
        #return HttpResponse("delete router")
42 2e0916f2 Marios Kogias
        return delete_router(request, offset)
43 2e0916f2 Marios Kogias
    elif request.method == 'PUT':
44 2e0916f2 Marios Kogias
        #return HttpResponse("put router")
45 5cf968ab Marios Kogias
        return update_router(request, offset)
46 2e0916f2 Marios Kogias
    else:
47 2e0916f2 Marios Kogias
        return api.api_method_not_allowed(request)
48 2e0916f2 Marios Kogias
49 2e0916f2 Marios Kogias
50 2e0916f2 Marios Kogias
def rinterface_demux(request, offset1, offset2):
51 2e0916f2 Marios Kogias
    if request.method == 'PUT':
52 2e0916f2 Marios Kogias
        if offset2 == "add_router_interface":
53 2e0916f2 Marios Kogias
            #return HttpResponse("add interface")
54 5cf968ab Marios Kogias
            return add_interface(request, offset1)
55 2e0916f2 Marios Kogias
        elif offset2 == "remove_router_interface":
56 2e0916f2 Marios Kogias
            #return HttpResponse("remove interface")
57 5cf968ab Marios Kogias
            return remove_interface(request, offset1)
58 2e0916f2 Marios Kogias
    else:
59 2e0916f2 Marios Kogias
        return api.api_method_not_allowed(request)
60 2e0916f2 Marios Kogias
61 2e0916f2 Marios Kogias
62 2e0916f2 Marios Kogias
@api.api_method(http_method='GET', user_required=True, logger=log)
63 2e0916f2 Marios Kogias
def list_routers(request):
64 2e0916f2 Marios Kogias
    log.debug('list_routers')
65 2e0916f2 Marios Kogias
66 5cf968ab Marios Kogias
    user_routers = VirtualMachine.objects.filter(userid=request.user_uniq,
67 5cf968ab Marios Kogias
                                                 router=True)
68 2e0916f2 Marios Kogias
69 2e0916f2 Marios Kogias
    user_routers = utils.filter_modified_since(request, objects=user_routers)
70 2e0916f2 Marios Kogias
71 2e0916f2 Marios Kogias
    routers = [router_to_dict(router)
72 2e0916f2 Marios Kogias
               for router in user_routers.order_by('id')]
73 2e0916f2 Marios Kogias
74 2e0916f2 Marios Kogias
    if request.serialization == 'xml':
75 2e0916f2 Marios Kogias
        data = render_to_string('list_routers.xml', {
76 2e0916f2 Marios Kogias
            'routers': routers})
77 2e0916f2 Marios Kogias
    else:
78 2e0916f2 Marios Kogias
        data = json.dumps({"routers": routers})
79 2e0916f2 Marios Kogias
80 2e0916f2 Marios Kogias
    return HttpResponse(data, status=200)
81 2e0916f2 Marios Kogias
82 5cf968ab Marios Kogias
83 2e0916f2 Marios Kogias
@api.api_method(http_method='POST', user_required=True, logger=log)
84 2e0916f2 Marios Kogias
@transaction.commit_manually
85 2e0916f2 Marios Kogias
def create_router(request):
86 2e0916f2 Marios Kogias
    user_id = request.user_uniq
87 2e0916f2 Marios Kogias
    req = utils.get_request_dict(request)
88 2e0916f2 Marios Kogias
89 2e0916f2 Marios Kogias
    try:
90 2e0916f2 Marios Kogias
        server = req['router']
91 2e0916f2 Marios Kogias
        name = server['name']
92 2e0916f2 Marios Kogias
    except (KeyError, AssertionError):
93 2e0916f2 Marios Kogias
        raise api.faults.BadRequest("Malformed request")
94 5cf968ab Marios Kogias
95 5cf968ab Marios Kogias
    try:
96 5cf968ab Marios Kogias
        netid = server[external_gateway_info]["network_id"]
97 5cf968ab Marios Kogias
        net = nv.get_network_fromdb(netid, request.user_uniq)
98 5cf968ab Marios Kogias
    except (KeyError, AssertionError):
99 5cf968ab Marios Kogias
        pass
100 5cf968ab Marios Kogias
101 5cf968ab Marios Kogias
    '''
102 2e0916f2 Marios Kogias
    vm = servers.create(user_id,
103 2e0916f2 Marios Kogias
                        name,
104 2e0916f2 Marios Kogias
                        #password,
105 2e0916f2 Marios Kogias
                        #flavor,
106 2e0916f2 Marios Kogias
                        #image,
107 2e0916f2 Marios Kogias
                        #metadata=metadata,
108 2e0916f2 Marios Kogias
                        #personality=personality,
109 2e0916f2 Marios Kogias
                        #private_networks=private_networks,
110 2e0916f2 Marios Kogias
                        #floating_ips=floating_ips
111 2e0916f2 Marios Kogias
                        )
112 5cf968ab Marios Kogias
    '''
113 5cf968ab Marios Kogias
114 5cf968ab Marios Kogias
    try:
115 5cf968ab Marios Kogias
        net
116 5cf968ab Marios Kogias
        mock_connect(vm, net)
117 5cf968ab Marios Kogias
    except NameError:
118 5cf968ab Marios Kogias
        pass
119 5cf968ab Marios Kogias
        #mock_connect(vm, random_public_net)
120 2e0916f2 Marios Kogias
121 2e0916f2 Marios Kogias
    server = router_to_dict(vm, detail=True)
122 2e0916f2 Marios Kogias
123 2e0916f2 Marios Kogias
    response = render_router(request, server, status=202)
124 2e0916f2 Marios Kogias
125 2e0916f2 Marios Kogias
    return response
126 2e0916f2 Marios Kogias
127 2e0916f2 Marios Kogias
128 2e0916f2 Marios Kogias
@api.api_method(http_method='GET', user_required=True, logger=log)
129 2e0916f2 Marios Kogias
def get_router(request, router_id):
130 2e0916f2 Marios Kogias
    log.debug('get_router_details %s', router_id)
131 2e0916f2 Marios Kogias
    router = util.get_vm(router_id, request.user_uniq)
132 2e0916f2 Marios Kogias
133 2e0916f2 Marios Kogias
    router_dict = router_to_dict(router)
134 2e0916f2 Marios Kogias
    return render_router(request, router_dict)
135 2e0916f2 Marios Kogias
136 2e0916f2 Marios Kogias
137 2e0916f2 Marios Kogias
@api.api_method(http_method='DELETE', user_required=True, logger=log)
138 2e0916f2 Marios Kogias
@transaction.commit_on_success
139 2e0916f2 Marios Kogias
def delete_router(request, router_id):
140 2e0916f2 Marios Kogias
    log.debug('delete router  %s', router_id)
141 2e0916f2 Marios Kogias
    router = util.get_vm(router_id, request.user_uniq)
142 2e0916f2 Marios Kogias
143 2e0916f2 Marios Kogias
    if router.neutron_networks.filter(public=False):
144 5cf968ab Marios Kogias
        return HttpResponse("There are internal interfaces on the router",
145 5cf968ab Marios Kogias
                            status=409)
146 2e0916f2 Marios Kogias
147 2e0916f2 Marios Kogias
    #servers.destroy(router)
148 2e0916f2 Marios Kogias
149 2e0916f2 Marios Kogias
    router.deleted = True
150 2e0916f2 Marios Kogias
    router.save()
151 2e0916f2 Marios Kogias
    return HttpResponse(status=204)
152 2e0916f2 Marios Kogias
153 2e0916f2 Marios Kogias
154 2e0916f2 Marios Kogias
@api.api_method(http_method='PUT', user_required=True, logger=log)
155 2e0916f2 Marios Kogias
def update_router(request, router_id):
156 2e0916f2 Marios Kogias
    log.debug('update router %s', router_id)
157 2e0916f2 Marios Kogias
    router = util.get_vm(router_id, request.user_uniq)
158 2e0916f2 Marios Kogias
159 2e0916f2 Marios Kogias
    req = utils.get_request_dict(request)
160 2e0916f2 Marios Kogias
    try:
161 2e0916f2 Marios Kogias
        server = req['router']
162 2e0916f2 Marios Kogias
    except (KeyError, AssertionError):
163 2e0916f2 Marios Kogias
        raise api.faults.BadRequest("Malformed request")
164 2e0916f2 Marios Kogias
165 2e0916f2 Marios Kogias
    try:
166 2e0916f2 Marios Kogias
        name = server['name']
167 2e0916f2 Marios Kogias
        router.name = name
168 2e0916f2 Marios Kogias
    except KeyError:
169 2e0916f2 Marios Kogias
        pass
170 2e0916f2 Marios Kogias
171 2e0916f2 Marios Kogias
    try:
172 2e0916f2 Marios Kogias
        net = server['external_gateway_info']['network_id']
173 2e0916f2 Marios Kogias
174 2e0916f2 Marios Kogias
        #find the new network
175 2e0916f2 Marios Kogias
        new_net = nv.get_network_fromdb(net, request.user_uniq)
176 2e0916f2 Marios Kogias
177 2e0916f2 Marios Kogias
        #disconnect from the old net
178 2e0916f2 Marios Kogias
        external_net = router.neutron_networks.filter(public=True)
179 2e0916f2 Marios Kogias
        if external_net:
180 2e0916f2 Marios Kogias
            #servers.disconnect(router, external_net[0])
181 2e0916f2 Marios Kogias
            mock_disconnect(router, external_net[0])
182 2e0916f2 Marios Kogias
183 2e0916f2 Marios Kogias
        #connect to the new net
184 2e0916f2 Marios Kogias
        #servers.connect(router, new_net)
185 2e0916f2 Marios Kogias
        mock_connect(router, new_net)
186 2e0916f2 Marios Kogias
    except KeyError:
187 2e0916f2 Marios Kogias
        pass
188 2e0916f2 Marios Kogias
189 2e0916f2 Marios Kogias
    router.save()
190 2e0916f2 Marios Kogias
    routerdict = router_to_dict(router)
191 2e0916f2 Marios Kogias
    return render_router(request, routerdict, 200)
192 2e0916f2 Marios Kogias
193 2e0916f2 Marios Kogias
194 2e0916f2 Marios Kogias
@api.api_method(http_method='PUT', user_required=True, logger=log)
195 2e0916f2 Marios Kogias
def add_interface(request, router_id):
196 2e0916f2 Marios Kogias
    log.debug('add interface to router %s', router_id)
197 5cf968ab Marios Kogias
    info = utils.get_request_dict(request)
198 2e0916f2 Marios Kogias
    router = util.get_vm(router_id, request.user_uniq)
199 2e0916f2 Marios Kogias
200 2e0916f2 Marios Kogias
    subnet = False
201 2e0916f2 Marios Kogias
    try:
202 5cf968ab Marios Kogias
        subnet_id = info["subnet_id"]
203 2e0916f2 Marios Kogias
        subnet = True
204 2e0916f2 Marios Kogias
        subnet_obj = subnet_views.get_subnet_fromdb(subnet_id,
205 5cf968ab Marios Kogias
                                                    request.user_uniq)
206 2e0916f2 Marios Kogias
    except KeyError:
207 2e0916f2 Marios Kogias
        pass
208 2e0916f2 Marios Kogias
209 2e0916f2 Marios Kogias
    try:
210 5cf968ab Marios Kogias
        port_id = info['port_id']
211 2e0916f2 Marios Kogias
        if subnet:
212 2e0916f2 Marios Kogias
            raise api.faults.BadRequest("Both subnet and port provided")
213 2e0916f2 Marios Kogias
        try:
214 5cf968ab Marios Kogias
            nic_obj = models.NetworkInterface.objects.get(id=port_id)
215 5cf968ab Marios Kogias
        except (ValueError, models.NetworkInterface.DoesNotExist):
216 2e0916f2 Marios Kogias
            raise api.faults.ItemNotFound('Port not found')
217 2e0916f2 Marios Kogias
        if not nic_obj.ipv4:
218 2e0916f2 Marios Kogias
            raise api.faults.BadRequest("No ip-address")
219 2e0916f2 Marios Kogias
        if nic_obj.machine:
220 2e0916f2 Marios Kogias
            return HttpResponse(status=409)
221 2e0916f2 Marios Kogias
    except KeyError:
222 2e0916f2 Marios Kogias
        if not subnet:
223 2e0916f2 Marios Kogias
            raise api.faults.BadRequest("Malformed request")
224 2e0916f2 Marios Kogias
225 2e0916f2 Marios Kogias
    if subnet:
226 2e0916f2 Marios Kogias
        #create nic with the subnet and add to the vm
227 5cf968ab Marios Kogias
        nic_obj = models.NetworkInterface(machine=router,
228 5cf968ab Marios Kogias
                                          subnet=subnet_obj,
229 5cf968ab Marios Kogias
                                          network=subnet_obj.network,
230 5cf968ab Marios Kogias
                                          ipv4=subnet_obj.gateway)
231 5cf968ab Marios Kogias
        nic_obj.save()
232 5cf968ab Marios Kogias
233 2e0916f2 Marios Kogias
    else:
234 2e0916f2 Marios Kogias
        #connect the nic
235 2e0916f2 Marios Kogias
        nic_obj.machine = router
236 2e0916f2 Marios Kogias
        nic_obj.save()
237 5cf968ab Marios Kogias
    #FIX ME : do backend connection
238 2e0916f2 Marios Kogias
239 5cf968ab Marios Kogias
    res = {"port_id": nic_obj.id,
240 5cf968ab Marios Kogias
           "subnet_id": nic_obj.subnet.id}
241 2e0916f2 Marios Kogias
242 2e0916f2 Marios Kogias
    data = json.dumps(res)
243 2e0916f2 Marios Kogias
    return HttpResponse(data, status=200)
244 2e0916f2 Marios Kogias
245 5cf968ab Marios Kogias
246 2e0916f2 Marios Kogias
@api.api_method(http_method='PUT', user_required=True, logger=log)
247 2e0916f2 Marios Kogias
def remove_interface(request, router_id):
248 2e0916f2 Marios Kogias
249 2e0916f2 Marios Kogias
    log.debug('remove interface from router %s', router_id)
250 2e0916f2 Marios Kogias
251 2e0916f2 Marios Kogias
    info = utils.get_request_dict(request)
252 2e0916f2 Marios Kogias
253 5cf968ab Marios Kogias
    router = util.get_vm(router_id, request.user_uniq)
254 2e0916f2 Marios Kogias
    subnet = False
255 2e0916f2 Marios Kogias
    try:
256 2e0916f2 Marios Kogias
        subnet_id = info["subnet_id"]
257 2e0916f2 Marios Kogias
        subnet = True
258 2e0916f2 Marios Kogias
        subnet_db = subnet_views.get_subnet_fromdb(subnet_id,
259 5cf968ab Marios Kogias
                                                   request.user_uniq)
260 2e0916f2 Marios Kogias
    except KeyError:
261 2e0916f2 Marios Kogias
        pass
262 2e0916f2 Marios Kogias
263 2e0916f2 Marios Kogias
    port = False
264 2e0916f2 Marios Kogias
    try:
265 2e0916f2 Marios Kogias
        port_id = info['port_id']
266 2e0916f2 Marios Kogias
        port = True
267 2e0916f2 Marios Kogias
        try:
268 5cf968ab Marios Kogias
            port_db = models.NetworkInterface.objects.get(id=port_id)
269 5cf968ab Marios Kogias
        except (ValueError, models.NetworkInterface.DoesNotExist):
270 2e0916f2 Marios Kogias
            raise api.faults.ItemNotFound('Port not found')
271 2e0916f2 Marios Kogias
    except KeyError:
272 2e0916f2 Marios Kogias
        pass
273 2e0916f2 Marios Kogias
274 5cf968ab Marios Kogias
    if (port and subnet):
275 2e0916f2 Marios Kogias
        #validate port-subnet combination else return 409
276 2e0916f2 Marios Kogias
        #subnet must be the first of the port
277 5cf968ab Marios Kogias
        if not (port_db.subnet.id == subnet_db.id):
278 2e0916f2 Marios Kogias
            return HttpResponse(status=409)
279 2e0916f2 Marios Kogias
280 2e0916f2 Marios Kogias
    if subnet:
281 2e0916f2 Marios Kogias
        #get the port
282 5cf968ab Marios Kogias
        try:
283 5cf968ab Marios Kogias
            port_db
284 5cf968ab Marios Kogias
        except NameError:
285 5cf968ab Marios Kogias
            try:
286 5cf968ab Marios Kogias
                port_db = subnet_db.neutron_nics.get(machine=router)
287 5cf968ab Marios Kogias
            except (ValueError, models.NetworkInterface.DoesNotExist):
288 5cf968ab Marios Kogias
                raise api.faults.ItemNotFound('Port not found')
289 2e0916f2 Marios Kogias
    elif port:
290 2e0916f2 Marios Kogias
        #get the subnet
291 5cf968ab Marios Kogias
        try:
292 5cf968ab Marios Kogias
            subnet_db
293 5cf968ab Marios Kogias
        except NameError:
294 2e0916f2 Marios Kogias
            subnet_db = port_db.subnet
295 2e0916f2 Marios Kogias
    else:
296 2e0916f2 Marios Kogias
        raise api.faults.BadRequest("Malformed request")
297 2e0916f2 Marios Kogias
298 5cf968ab Marios Kogias
    res = {"id": str(router.id),
299 5cf968ab Marios Kogias
           "tenant_id": request.user_uniq,
300 5cf968ab Marios Kogias
           "port_id": port_db.id,
301 5cf968ab Marios Kogias
           "subnet_id": subnet_db.id}
302 2e0916f2 Marios Kogias
303 2e0916f2 Marios Kogias
    port_db.delete()  # need to add backend stuff
304 2e0916f2 Marios Kogias
    data = json.dumps(res)
305 2e0916f2 Marios Kogias
    return HttpResponse(data, status=200)
306 2e0916f2 Marios Kogias
307 2e0916f2 Marios Kogias
308 2e0916f2 Marios Kogias
# util functions
309 2e0916f2 Marios Kogias
310 2e0916f2 Marios Kogias
311 2e0916f2 Marios Kogias
def router_to_dict(router):
312 2e0916f2 Marios Kogias
    d = {'id': str(router.id), 'name': router.name}
313 2e0916f2 Marios Kogias
    d['user_id'] = router.userid
314 2e0916f2 Marios Kogias
    d['tenant_id'] = router.userid
315 2e0916f2 Marios Kogias
    d['admin_state_up'] = True
316 2e0916f2 Marios Kogias
    external_net = router.neutron_networks.filter(public=True)
317 2e0916f2 Marios Kogias
    if external_net:
318 2e0916f2 Marios Kogias
        external_net = external_net[0]
319 2e0916f2 Marios Kogias
        d['external_gateway_info'] = {'network_id': external_net.id}
320 2e0916f2 Marios Kogias
    else:
321 2e0916f2 Marios Kogias
        d['external_gateway_info'] = None
322 2e0916f2 Marios Kogias
    return d
323 2e0916f2 Marios Kogias
324 2e0916f2 Marios Kogias
325 2e0916f2 Marios Kogias
def render_router(request, routerdict, status=200):
326 2e0916f2 Marios Kogias
    if request.serialization == 'xml':
327 2e0916f2 Marios Kogias
        data = render_to_string('router.xml', {'router': routerdict})
328 2e0916f2 Marios Kogias
    else:
329 2e0916f2 Marios Kogias
        data = json.dumps({'router': routerdict})
330 2e0916f2 Marios Kogias
    return HttpResponse(data, status=status)
331 2e0916f2 Marios Kogias
332 2e0916f2 Marios Kogias
333 2e0916f2 Marios Kogias
# mock functions
334 2e0916f2 Marios Kogias
335 2e0916f2 Marios Kogias
def mock_disconnect(router, net):
336 2e0916f2 Marios Kogias
    nic = models.NetworkInterface.objects.get(network=net, machine=router)
337 2e0916f2 Marios Kogias
    nic.delete()
338 2e0916f2 Marios Kogias
339 5cf968ab Marios Kogias
340 2e0916f2 Marios Kogias
def mock_connect(router, net):
341 2e0916f2 Marios Kogias
    nic = models.NetworkInterface(network=net, machine=router)
342 2e0916f2 Marios Kogias
    nic.save()