Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / neutron / router_views.py @ 2e0916f2

History | View | Annotate | Download (10.3 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 2e0916f2 Marios Kogias
from logging import getLogger
17 2e0916f2 Marios Kogias
18 2e0916f2 Marios Kogias
import network_views as nv
19 2e0916f2 Marios Kogias
#from synnefo.logic import servers
20 2e0916f2 Marios Kogias
21 2e0916f2 Marios Kogias
log = getLogger(__name__)
22 2e0916f2 Marios Kogias
23 2e0916f2 Marios Kogias
24 2e0916f2 Marios Kogias
def demux(request):
25 2e0916f2 Marios Kogias
    if request.method == 'GET':
26 2e0916f2 Marios Kogias
        #return HttpResponse("list routers")
27 2e0916f2 Marios Kogias
        return list_routers(request)
28 2e0916f2 Marios Kogias
    elif request.method == 'POST':
29 2e0916f2 Marios Kogias
        #return create_router(request)
30 2e0916f2 Marios Kogias
        return HttpResponse("create router")
31 2e0916f2 Marios Kogias
    else:
32 2e0916f2 Marios Kogias
        return api.api_method_not_allowed(request)
33 2e0916f2 Marios Kogias
34 2e0916f2 Marios Kogias
35 2e0916f2 Marios Kogias
def router_demux(request, offset):
36 2e0916f2 Marios Kogias
    if request.method == 'GET':
37 2e0916f2 Marios Kogias
        #return HttpResponse("get single router")
38 2e0916f2 Marios Kogias
        return get_router(request,  offset)
39 2e0916f2 Marios Kogias
    elif request.method == 'DELETE':
40 2e0916f2 Marios Kogias
        #return HttpResponse("delete router")
41 2e0916f2 Marios Kogias
        return delete_router(request, offset)
42 2e0916f2 Marios Kogias
    elif request.method == 'PUT':
43 2e0916f2 Marios Kogias
        #return HttpResponse("put router")
44 2e0916f2 Marios Kogias
        return update_router(request,offset)
45 2e0916f2 Marios Kogias
    else:
46 2e0916f2 Marios Kogias
        return api.api_method_not_allowed(request)
47 2e0916f2 Marios Kogias
48 2e0916f2 Marios Kogias
49 2e0916f2 Marios Kogias
def rinterface_demux(request, offset1, offset2):
50 2e0916f2 Marios Kogias
    if request.method == 'PUT':
51 2e0916f2 Marios Kogias
        if offset2 == "add_router_interface":
52 2e0916f2 Marios Kogias
            #return HttpResponse("add interface")
53 2e0916f2 Marios Kogias
            return add_interface(request, offset2)
54 2e0916f2 Marios Kogias
        elif offset2 == "remove_router_interface":
55 2e0916f2 Marios Kogias
            #return HttpResponse("remove interface")
56 2e0916f2 Marios Kogias
            return remove_interface(request, offset22)
57 2e0916f2 Marios Kogias
    else:
58 2e0916f2 Marios Kogias
        return api.api_method_not_allowed(request)
59 2e0916f2 Marios Kogias
60 2e0916f2 Marios Kogias
61 2e0916f2 Marios Kogias
@api.api_method(http_method='GET', user_required=True, logger=log)
62 2e0916f2 Marios Kogias
def list_routers(request):
63 2e0916f2 Marios Kogias
    log.debug('list_routers')
64 2e0916f2 Marios Kogias
65 2e0916f2 Marios Kogias
    user_routers = VirtualMachine.objects.filter(userid=request.user_uniq, router=True)
66 2e0916f2 Marios Kogias
67 2e0916f2 Marios Kogias
    user_routers = utils.filter_modified_since(request, objects=user_routers)
68 2e0916f2 Marios Kogias
69 2e0916f2 Marios Kogias
    routers = [router_to_dict(router)
70 2e0916f2 Marios Kogias
               for router in user_routers.order_by('id')]
71 2e0916f2 Marios Kogias
72 2e0916f2 Marios Kogias
    if request.serialization == 'xml':
73 2e0916f2 Marios Kogias
        data = render_to_string('list_routers.xml', {
74 2e0916f2 Marios Kogias
            'routers': routers})
75 2e0916f2 Marios Kogias
    else:
76 2e0916f2 Marios Kogias
        data = json.dumps({"routers": routers})
77 2e0916f2 Marios Kogias
78 2e0916f2 Marios Kogias
    return HttpResponse(data, status=200)
79 2e0916f2 Marios Kogias
80 2e0916f2 Marios Kogias
'''
81 2e0916f2 Marios Kogias
@api.api_method(http_method='POST', user_required=True, logger=log)
82 2e0916f2 Marios Kogias
@transaction.commit_manually
83 2e0916f2 Marios Kogias
def create_router(request):
84 2e0916f2 Marios Kogias
    user_id = request.user_uniq
85 2e0916f2 Marios Kogias
    req = utils.get_request_dict(request)
86 2e0916f2 Marios Kogias

87 2e0916f2 Marios Kogias
    try:
88 2e0916f2 Marios Kogias
        server = req['router']
89 2e0916f2 Marios Kogias
        name = server['name']
90 2e0916f2 Marios Kogias
    except (KeyError, AssertionError):
91 2e0916f2 Marios Kogias
        raise api.faults.BadRequest("Malformed request")
92 2e0916f2 Marios Kogias
    metadata = server.get('metadata', {})
93 2e0916f2 Marios Kogias
    assert isinstance(metadata, dict)
94 2e0916f2 Marios Kogias
    image_id = server['imageRef']
95 2e0916f2 Marios Kogias
    flavor_id = server['flavorRef']
96 2e0916f2 Marios Kogias
    personality = server.get('personality', [])
97 2e0916f2 Marios Kogias
    assert isinstance(personality, list)
98 2e0916f2 Marios Kogias
    private_networks = server.get("networks", [])
99 2e0916f2 Marios Kogias
    assert isinstance(private_networks, list)
100 2e0916f2 Marios Kogias
    floating_ips = server.get("floating_ips", [])
101 2e0916f2 Marios Kogias
    assert isinstance(floating_ips, list)
102 2e0916f2 Marios Kogias
    # Verify that personalities are well-formed
103 2e0916f2 Marios Kogias
    util.verify_personality(personality)
104 2e0916f2 Marios Kogias
    # Get image information
105 2e0916f2 Marios Kogias
    image = util.get_image_dict(image_id, user_id)
106 2e0916f2 Marios Kogias
    # Get flavor (ensure it is active)
107 2e0916f2 Marios Kogias
    flavor = util.get_flavor(flavor_id, include_deleted=False)
108 2e0916f2 Marios Kogias
    # Generate password
109 2e0916f2 Marios Kogias
    password = util.random_password()
110 2e0916f2 Marios Kogias
    vm = servers.create(user_id,
111 2e0916f2 Marios Kogias
                        name,
112 2e0916f2 Marios Kogias
                        #password,
113 2e0916f2 Marios Kogias
                        #flavor,
114 2e0916f2 Marios Kogias
                        #image,
115 2e0916f2 Marios Kogias
                        #metadata=metadata,
116 2e0916f2 Marios Kogias
                        #personality=personality,
117 2e0916f2 Marios Kogias
                        #private_networks=private_networks,
118 2e0916f2 Marios Kogias
                        #floating_ips=floating_ips
119 2e0916f2 Marios Kogias
                        )
120 2e0916f2 Marios Kogias

121 2e0916f2 Marios Kogias
    server = router_to_dict(vm, detail=True)
122 2e0916f2 Marios Kogias
    server['status'] = 'BUILD'
123 2e0916f2 Marios Kogias
    server['adminPass'] = password
124 2e0916f2 Marios Kogias

125 2e0916f2 Marios Kogias
    response = render_router(request, server, status=202)
126 2e0916f2 Marios Kogias

127 2e0916f2 Marios Kogias
    return response
128 2e0916f2 Marios Kogias

129 2e0916f2 Marios Kogias

130 2e0916f2 Marios Kogias
'''
131 2e0916f2 Marios Kogias
@api.api_method(http_method='GET', user_required=True, logger=log)
132 2e0916f2 Marios Kogias
def get_router(request, router_id):
133 2e0916f2 Marios Kogias
    log.debug('get_router_details %s', router_id)
134 2e0916f2 Marios Kogias
    router = util.get_vm(router_id, request.user_uniq)
135 2e0916f2 Marios Kogias
136 2e0916f2 Marios Kogias
    router_dict = router_to_dict(router)
137 2e0916f2 Marios Kogias
    return render_router(request, router_dict)
138 2e0916f2 Marios Kogias
139 2e0916f2 Marios Kogias
140 2e0916f2 Marios Kogias
@api.api_method(http_method='DELETE', user_required=True, logger=log)
141 2e0916f2 Marios Kogias
@transaction.commit_on_success
142 2e0916f2 Marios Kogias
def delete_router(request, router_id):
143 2e0916f2 Marios Kogias
    log.debug('delete router  %s', router_id)
144 2e0916f2 Marios Kogias
    router = util.get_vm(router_id, request.user_uniq)
145 2e0916f2 Marios Kogias
146 2e0916f2 Marios Kogias
    if router.neutron_networks.filter(public=False):
147 2e0916f2 Marios Kogias
        return HttpResponse("There are internal interfaces on the router", status=409)
148 2e0916f2 Marios Kogias
149 2e0916f2 Marios Kogias
    #servers.destroy(router)
150 2e0916f2 Marios Kogias
151 2e0916f2 Marios Kogias
    router.deleted = True
152 2e0916f2 Marios Kogias
    router.save()
153 2e0916f2 Marios Kogias
    return HttpResponse(status=204)
154 2e0916f2 Marios Kogias
155 2e0916f2 Marios Kogias
156 2e0916f2 Marios Kogias
@api.api_method(http_method='PUT', user_required=True, logger=log)
157 2e0916f2 Marios Kogias
def update_router(request, router_id):
158 2e0916f2 Marios Kogias
    log.debug('update router %s', router_id)
159 2e0916f2 Marios Kogias
    router = util.get_vm(router_id, request.user_uniq)
160 2e0916f2 Marios Kogias
161 2e0916f2 Marios Kogias
    req = utils.get_request_dict(request)
162 2e0916f2 Marios Kogias
    try:
163 2e0916f2 Marios Kogias
        server = req['router']
164 2e0916f2 Marios Kogias
    except (KeyError, AssertionError):
165 2e0916f2 Marios Kogias
        raise api.faults.BadRequest("Malformed request")
166 2e0916f2 Marios Kogias
167 2e0916f2 Marios Kogias
    try:
168 2e0916f2 Marios Kogias
        name = server['name']
169 2e0916f2 Marios Kogias
        router.name = name
170 2e0916f2 Marios Kogias
    except KeyError:
171 2e0916f2 Marios Kogias
        pass
172 2e0916f2 Marios Kogias
173 2e0916f2 Marios Kogias
    try:
174 2e0916f2 Marios Kogias
        net = server['external_gateway_info']['network_id']
175 2e0916f2 Marios Kogias
176 2e0916f2 Marios Kogias
        #find the new network
177 2e0916f2 Marios Kogias
        new_net = nv.get_network_fromdb(net, request.user_uniq)
178 2e0916f2 Marios Kogias
179 2e0916f2 Marios Kogias
        #disconnect from the old net
180 2e0916f2 Marios Kogias
        external_net = router.neutron_networks.filter(public=True)
181 2e0916f2 Marios Kogias
        if external_net:
182 2e0916f2 Marios Kogias
            #servers.disconnect(router, external_net[0])
183 2e0916f2 Marios Kogias
            mock_disconnect(router, external_net[0])
184 2e0916f2 Marios Kogias
185 2e0916f2 Marios Kogias
        #connect to the new net
186 2e0916f2 Marios Kogias
        #servers.connect(router, new_net)
187 2e0916f2 Marios Kogias
        mock_connect(router, new_net)
188 2e0916f2 Marios Kogias
    except KeyError:
189 2e0916f2 Marios Kogias
        pass
190 2e0916f2 Marios Kogias
191 2e0916f2 Marios Kogias
    router.save()
192 2e0916f2 Marios Kogias
    routerdict = router_to_dict(router)
193 2e0916f2 Marios Kogias
    return render_router(request, routerdict, 200)
194 2e0916f2 Marios Kogias
195 2e0916f2 Marios Kogias
196 2e0916f2 Marios Kogias
@api.api_method(http_method='PUT', user_required=True, logger=log)
197 2e0916f2 Marios Kogias
def add_interface(request, router_id):
198 2e0916f2 Marios Kogias
    log.debug('add interface to router %s', router_id)
199 2e0916f2 Marios Kogias
    router = util.get_vm(router_id, request.user_uniq)
200 2e0916f2 Marios Kogias
201 2e0916f2 Marios Kogias
    router_info = utils.get_request_dict(request)
202 2e0916f2 Marios Kogias
203 2e0916f2 Marios Kogias
    subnet = False
204 2e0916f2 Marios Kogias
    try:
205 2e0916f2 Marios Kogias
        subnet_id = router_info["subnet_id"]
206 2e0916f2 Marios Kogias
        subnet = True
207 2e0916f2 Marios Kogias
        subnet_obj = subnet_views.get_subnet_fromdb(subnet_id,
208 2e0916f2 Marios Kogias
                                        request.user_unique)
209 2e0916f2 Marios Kogias
    except KeyError:
210 2e0916f2 Marios Kogias
        pass
211 2e0916f2 Marios Kogias
212 2e0916f2 Marios Kogias
    try:
213 2e0916f2 Marios Kogias
        port_id = router_info['port_id']
214 2e0916f2 Marios Kogias
        if subnet:
215 2e0916f2 Marios Kogias
            raise api.faults.BadRequest("Both subnet and port provided")
216 2e0916f2 Marios Kogias
        try:
217 2e0916f2 Marios Kogias
            nic_obj = models.NetworkInteface.objects.get(id=port_id)
218 2e0916f2 Marios Kogias
        except (ValueError, models.NetworkInteraface.DoesNotExist):
219 2e0916f2 Marios Kogias
            raise api.faults.ItemNotFound('Port not found')
220 2e0916f2 Marios Kogias
        if not nic_obj.ipv4:
221 2e0916f2 Marios Kogias
            raise api.faults.BadRequest("No ip-address")
222 2e0916f2 Marios Kogias
        if nic_obj.machine:
223 2e0916f2 Marios Kogias
            return HttpResponse(status=409)
224 2e0916f2 Marios Kogias
    except KeyError:
225 2e0916f2 Marios Kogias
        if not subnet:
226 2e0916f2 Marios Kogias
            raise api.faults.BadRequest("Malformed request")
227 2e0916f2 Marios Kogias
228 2e0916f2 Marios Kogias
    if subnet:
229 2e0916f2 Marios Kogias
        #create nic with the subnet and add to the vm
230 2e0916f2 Marios Kogias
        nic = models.NetworkInteface(machine=router,
231 2e0916f2 Marios Kogias
                                    subnet=subnet_obj,
232 2e0916f2 Marios Kogias
                                    network=subnet_obj.network
233 2e0916f2 Marios Kogias
                                    ipv4=subnet.gateway
234 2e0916f2 Marios Kogias
                                    )
235 2e0916f2 Marios Kogias
        nic.save()
236 2e0916f2 Marios Kogias
        port_id = nic.id
237 2e0916f2 Marios Kogias
    else:
238 2e0916f2 Marios Kogias
        #connect the nic
239 2e0916f2 Marios Kogias
        nic_obj.machine = router
240 2e0916f2 Marios Kogias
        nic_obj.save()
241 2e0916f2 Marios Kogias
        subnet_id = nic.subnet.id
242 2e0916f2 Marios Kogias
243 2e0916f2 Marios Kogias
    res = {"port_id":port_db.id,
244 2e0916f2 Marios Kogias
            "subnet_id":subnet_db.id
245 2e0916f2 Marios Kogias
          }
246 2e0916f2 Marios Kogias
247 2e0916f2 Marios Kogias
    data = json.dumps(res)
248 2e0916f2 Marios Kogias
    return HttpResponse(data, status=200)
249 2e0916f2 Marios Kogias
250 2e0916f2 Marios Kogias
@api.api_method(http_method='PUT', user_required=True, logger=log)
251 2e0916f2 Marios Kogias
def remove_interface(request, router_id):
252 2e0916f2 Marios Kogias
253 2e0916f2 Marios Kogias
    log.debug('remove interface from router %s', router_id)
254 2e0916f2 Marios Kogias
    router = util.get_vm(router_id, request.user_uniq)
255 2e0916f2 Marios Kogias
256 2e0916f2 Marios Kogias
    info = utils.get_request_dict(request)
257 2e0916f2 Marios Kogias
258 2e0916f2 Marios Kogias
    subnet = False
259 2e0916f2 Marios Kogias
    try:
260 2e0916f2 Marios Kogias
        subnet_id = info["subnet_id"]
261 2e0916f2 Marios Kogias
        subnet = True
262 2e0916f2 Marios Kogias
        subnet_db = subnet_views.get_subnet_fromdb(subnet_id,
263 2e0916f2 Marios Kogias
                                request.user_unique)
264 2e0916f2 Marios Kogias
    except KeyError:
265 2e0916f2 Marios Kogias
        pass
266 2e0916f2 Marios Kogias
267 2e0916f2 Marios Kogias
    port = False
268 2e0916f2 Marios Kogias
    try:
269 2e0916f2 Marios Kogias
        port_id = info['port_id']
270 2e0916f2 Marios Kogias
        port = True
271 2e0916f2 Marios Kogias
        try:
272 2e0916f2 Marios Kogias
            nic_obj = models.NetworkInteface.objects.get(id=port_id)
273 2e0916f2 Marios Kogias
        except (ValueError, models.NetworkInteraface.DoesNotExist):
274 2e0916f2 Marios Kogias
            raise api.faults.ItemNotFound('Port not found')
275 2e0916f2 Marios Kogias
    except KeyError:
276 2e0916f2 Marios Kogias
        pass
277 2e0916f2 Marios Kogias
278 2e0916f2 Marios Kogias
    if port and subnet:
279 2e0916f2 Marios Kogias
        #validate port-subnet combination else return 409
280 2e0916f2 Marios Kogias
        #subnet must be the first of the port
281 2e0916f2 Marios Kogias
        if not port_db is subnet_db:
282 2e0916f2 Marios Kogias
            return HttpResponse(status=409)
283 2e0916f2 Marios Kogias
284 2e0916f2 Marios Kogias
    if subnet:
285 2e0916f2 Marios Kogias
        #get the port
286 2e0916f2 Marios Kogias
        if not port_db:
287 2e0916f2 Marios Kogias
            port_db = subnet_db.neutron_nics.get(machine=router)
288 2e0916f2 Marios Kogias
    elif port:
289 2e0916f2 Marios Kogias
        #get the subnet
290 2e0916f2 Marios Kogias
        if not subnet_db:
291 2e0916f2 Marios Kogias
            subnet_db = port_db.subnet
292 2e0916f2 Marios Kogias
    else:
293 2e0916f2 Marios Kogias
        raise api.faults.BadRequest("Malformed request")
294 2e0916f2 Marios Kogias
295 2e0916f2 Marios Kogias
    res = {"id":str(router.id),
296 2e0916f2 Marios Kogias
            "tenant_id":request.user_uniq,
297 2e0916f2 Marios Kogias
            "port_id":port_db.id,
298 2e0916f2 Marios Kogias
            "subnet_id":subnet_db.id
299 2e0916f2 Marios Kogias
          }
300 2e0916f2 Marios Kogias
301 2e0916f2 Marios Kogias
    port_db.delete()  # need to add backend stuff
302 2e0916f2 Marios Kogias
    data = json.dumps(res)
303 2e0916f2 Marios Kogias
    return HttpResponse(data, status=200)
304 2e0916f2 Marios Kogias
305 2e0916f2 Marios Kogias
306 2e0916f2 Marios Kogias
# util functions
307 2e0916f2 Marios Kogias
308 2e0916f2 Marios Kogias
309 2e0916f2 Marios Kogias
def router_to_dict(router):
310 2e0916f2 Marios Kogias
    d = {'id': str(router.id), 'name': router.name}
311 2e0916f2 Marios Kogias
    d['user_id'] = router.userid
312 2e0916f2 Marios Kogias
    d['tenant_id'] = router.userid
313 2e0916f2 Marios Kogias
    d['admin_state_up'] = True
314 2e0916f2 Marios Kogias
    external_net = router.neutron_networks.filter(public=True)
315 2e0916f2 Marios Kogias
    if external_net:
316 2e0916f2 Marios Kogias
        external_net = external_net[0]
317 2e0916f2 Marios Kogias
        d['external_gateway_info'] = {'network_id': external_net.id}
318 2e0916f2 Marios Kogias
    else:
319 2e0916f2 Marios Kogias
        d['external_gateway_info'] = None
320 2e0916f2 Marios Kogias
    return d
321 2e0916f2 Marios Kogias
322 2e0916f2 Marios Kogias
323 2e0916f2 Marios Kogias
def render_router(request, routerdict, status=200):
324 2e0916f2 Marios Kogias
    if request.serialization == 'xml':
325 2e0916f2 Marios Kogias
        data = render_to_string('router.xml', {'router': routerdict})
326 2e0916f2 Marios Kogias
    else:
327 2e0916f2 Marios Kogias
        data = json.dumps({'router': routerdict})
328 2e0916f2 Marios Kogias
    return HttpResponse(data, status=status)
329 2e0916f2 Marios Kogias
330 2e0916f2 Marios Kogias
331 2e0916f2 Marios Kogias
# mock functions
332 2e0916f2 Marios Kogias
333 2e0916f2 Marios Kogias
def mock_disconnect(router, net):
334 2e0916f2 Marios Kogias
    nic = models.NetworkInterface.objects.get(network=net, machine=router)
335 2e0916f2 Marios Kogias
    nic.delete()
336 2e0916f2 Marios Kogias
337 2e0916f2 Marios Kogias
def mock_connect(router, net):
338 2e0916f2 Marios Kogias
    nic = models.NetworkInterface(network=net, machine=router)
339 2e0916f2 Marios Kogias
    nic.save()