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