Revision bfb3f9c2 snf-cyclades-app/synnefo/logic/backend.py
b/snf-cyclades-app/synnefo/logic/backend.py | ||
---|---|---|
37 | 37 |
from synnefo.db.models import (Backend, VirtualMachine, Network, |
38 | 38 |
BackendNetwork, BACKEND_STATUSES, |
39 | 39 |
pooled_rapi_client, VirtualMachineDiagnostic, |
40 |
Flavor, IPAddressLog) |
|
40 |
Flavor, IPAddress, IPAddressLog)
|
|
41 | 41 |
from synnefo.logic import utils, ips |
42 | 42 |
from synnefo import quotas |
43 | 43 |
from synnefo.api.util import release_resource |
... | ... | |
266 | 266 |
# Update the NIC in DB with the values from Ganeti NIC |
267 | 267 |
setattr(db_nic, f, ganeti_nic[f]) |
268 | 268 |
db_nic.save() |
269 |
|
|
269 | 270 |
# Special case where the IPv4 address has changed, because you |
270 | 271 |
# need to release the old IPv4 address and reserve the new one |
271 | 272 |
ipv4_address = ganeti_nic["ipv4_address"] |
272 | 273 |
if db_nic.ipv4_address != ipv4_address: |
273 |
remove_nic_ips(db_nic) |
|
274 |
if ipv4_address: |
|
275 |
network = ganeti_nic["network"] |
|
276 |
ipaddress = ips.allocate_ip(network, vm.userid, |
|
277 |
address=ipv4_address) |
|
278 |
ipaddress.nic = nic |
|
279 |
ipaddress.save() |
|
274 |
change_address_of_port(db_nic, vm.userid, |
|
275 |
old_address=db_nic.ipv4_address, |
|
276 |
new_address=ipv4_address, |
|
277 |
version=4) |
|
278 |
|
|
279 |
ipv6_address = ganeti_nic["ipv6_address"] |
|
280 |
if db_nic.ipv6_address != ipv6_address: |
|
281 |
change_address_of_port(db_nic, vm.userid, |
|
282 |
old_address=db_nic.ipv6_address, |
|
283 |
new_address=ipv6_address, |
|
284 |
version=6) |
|
280 | 285 |
|
281 | 286 |
vm.backendtime = etime |
282 | 287 |
vm.save() |
283 | 288 |
|
284 | 289 |
|
290 |
def change_address_of_port(port, userid, old_address, new_address, version): |
|
291 |
"""Change.""" |
|
292 |
if old_address is not None: |
|
293 |
msg = ("IPv%s Address of server '%s' changed from '%s' to '%s'" |
|
294 |
% (version, port.machine_id, old_address, new_address)) |
|
295 |
log.critical(msg) |
|
296 |
|
|
297 |
# Remove the old IP address |
|
298 |
remove_nic_ips(port, version=version) |
|
299 |
|
|
300 |
if version == 4: |
|
301 |
ipaddress = ips.allocate_ip(port.network, userid, address=new_address) |
|
302 |
ipaddress.nic = port |
|
303 |
ipaddress.save() |
|
304 |
elif version == 6: |
|
305 |
subnet6 = port.network.subnet6 |
|
306 |
ipaddress = IPAddress.objects.create(userid=userid, |
|
307 |
network=port.network, |
|
308 |
subnet=subnet6, |
|
309 |
nic=port, |
|
310 |
address=new_address) |
|
311 |
else: |
|
312 |
raise ValueError("Unknown version: %s" % version) |
|
313 |
|
|
314 |
# New address log |
|
315 |
ip_log = IPAddressLog.objects.create(server_id=port.machine_id, |
|
316 |
network_id=port.network_id, |
|
317 |
address=new_address, |
|
318 |
active=True) |
|
319 |
log.info("Created IP log entry '%s' for address '%s' to server '%s'", |
|
320 |
ip_log.id, new_address, port.machine_id) |
|
321 |
|
|
322 |
return ipaddress |
|
323 |
|
|
324 |
|
|
285 | 325 |
def nics_are_equal(db_nic, gnt_nic): |
286 | 326 |
for field in NIC_FIELDS: |
287 | 327 |
if getattr(db_nic, field) != gnt_nic[field]: |
... | ... | |
308 | 348 |
mac = gnic.get('mac') |
309 | 349 |
ipv4 = gnic.get('ip') |
310 | 350 |
subnet6 = network.subnet6 |
311 |
ipv6 = mac2eui64(mac, subnet6) if subnet6 else None |
|
351 |
ipv6 = mac2eui64(mac, subnet6.cidr) if subnet6 else None
|
|
312 | 352 |
|
313 | 353 |
firewall = gnic.get('firewall') |
314 | 354 |
firewall_profile = _reverse_tags.get(firewall) |
... | ... | |
328 | 368 |
return dict(new_nics) |
329 | 369 |
|
330 | 370 |
|
331 |
def remove_nic_ips(nic): |
|
371 |
def remove_nic_ips(nic, version=None):
|
|
332 | 372 |
"""Remove IP addresses associated with a NetworkInterface. |
333 | 373 |
|
334 | 374 |
Remove all IP addresses that are associated with the NetworkInterface |
335 | 375 |
object, by returning them to the pool and deleting the IPAddress object. If |
336 | 376 |
the IP is a floating IP, then it is just disassociated from the NIC. |
377 |
If version is specified, then only IP addressses of that version will be |
|
378 |
removed. |
|
337 | 379 |
|
338 | 380 |
""" |
339 |
|
|
340 | 381 |
for ip in nic.ips.all(): |
382 |
if version and ip.ipversion != version: |
|
383 |
continue |
|
384 |
|
|
341 | 385 |
# Update the DB table holding the logging of all IP addresses |
342 |
update_ip_address_log(nic, ip)
|
|
386 |
terminate_active_ipaddress_log(nic, ip)
|
|
343 | 387 |
|
344 |
if ip.ipversion == 4: |
|
345 |
if ip.floating_ip: |
|
346 |
ip.nic = None |
|
347 |
ip.save() |
|
348 |
else: |
|
349 |
ip.release_address() |
|
350 |
if not ip.floating_ip: |
|
388 |
if ip.floating_ip: |
|
389 |
ip.nic = None |
|
390 |
ip.save() |
|
391 |
else: |
|
392 |
# Release the IPv4 address |
|
393 |
ip.release_address() |
|
351 | 394 |
ip.delete() |
352 | 395 |
|
353 | 396 |
|
354 |
def update_ip_address_log(nic, ip):
|
|
397 |
def terminate_active_ipaddress_log(nic, ip):
|
|
355 | 398 |
"""Update DB logging entry for this IP address.""" |
356 | 399 |
if not ip.network.public or nic.machine is None: |
357 | 400 |
return |
Also available in: Unified diff