def delete_network(request, network_id): # Normal Response Code: 204 # Error Response Codes: computeFault (400, 500), # serviceUnavailable (503), # unauthorized (401), # forbidden (403) # itemNotFound (404), # overLimit (413) log.info('delete_network %s', network_id) net = util.get_network(network_id, request.user_uniq, for_update=True) if net.public: raise faults.Forbidden('Can not delete the public network.') if net.deleted: raise faults.BadRequest("Network has been deleted.") if net.machines.all(): # Nics attached on network raise faults.NetworkInUse('Machines are connected to network.') net.action = 'DESTROY' net.save() backend_networks = net.backend_networks.exclude(operstate="DELETED") for bnet in backend_networks: backend.delete_network(net, bnet.backend) if not backend_networks: backend.update_network_state(net) return HttpResponse(status=204)
def delete(network_id, credentials, atomic_context=None): network = util.get_network(network_id, credentials, for_update=True, non_deleted=True) if network.public and not credentials.is_admin: raise faults.Forbidden("Cannot delete the public network.") validate_network_action(network, "DESTROY") if network.nics.exists(): raise faults.Conflict("Cannot delete network. There are ports still" " configured on network network %s" % network.id) if network.ips.filter(deleted=False, floating_ip=True).exists(): msg = "Cannot delete netowrk. Network has allocated floating IPs." raise faults.Conflict(msg) network.action = "DESTROY" # Mark network as drained to prevent automatic allocation of # public/floating IPs while the network is being deleted if network.public: network.drained = True network.save() # Delete network to all backends that exists for bnet in network.backend_networks.exclude(operstate="DELETED"): backend_mod.delete_network(network, bnet.backend) else: # If network does not exist in any backend, update the network state backend_mod.update_network_state(network, atomic_context=atomic_context) return network
def delete(network): if network.nics.exists(): raise faults.Conflict("Cannot delete network. There are ports still" " configured on network network %s" % network.id) if network.ips.filter(deleted=False, floating_ip=True).exists(): msg = "Cannot delete netowrk. Network has allocated floating IPs." raise faults.Conflict(msg) network.action = "DESTROY" # Mark network as drained to prevent automatic allocation of # public/floating IPs while the network is being deleted if network.public: network.drained = True network.save() # Delete network to all backends that exists for bnet in network.backend_networks.exclude(operstate="DELETED"): backend_mod.delete_network(network, bnet.backend) else: # If network does not exist in any backend, update the network state backend_mod.update_network_state(network) return network
def reconcile_network_state(self, network, atomic_context=None): if network.state != "ACTIVE": network = Network.objects.select_for_update().get(id=network.id) backend_mod.update_network_state(network, atomic_context=atomic_context)
def _reconcile_network(self, network): """Reconcile a network with corresponging Ganeti networks. Reconcile a Network and the associated BackendNetworks with the corresponding Ganeti networks in all Ganeti backends. """ if network.subnets.filter(ipversion=4, dhcp=True).exists(): ip_pools = network.get_ip_pools() # X-Lock on IP pools else: ip_pools = None for bend in self.backends: bnet = get_backend_network(network, bend) gnet = self.ganeti_networks[bend].get(network.id) if bnet is None and gnet is not None: # Network exists in backend but not in DB for this backend bnet = self.reconcile_parted_network(network, bend) if bnet is None: continue if gnet is None: # Network does not exist in Ganeti. If the network action # is DESTROY, we have to mark as deleted in DB, else we # have to create it in Ganeti. if network.action == "DESTROY": if bnet.operstate != "DELETED": self.reconcile_stale_network(bnet) else: self.reconcile_missing_network(network, bend) # Skip rest reconciliation! continue try: hanging_groups = self.ganeti_hanging_networks[bend][network.id] except KeyError: # Network is connected to all nodegroups hanging_groups = [] if hanging_groups: # CASE-3: Ganeti networks not connected to all nodegroups self.reconcile_hanging_groups(network, bend, hanging_groups) continue if bnet.operstate != 'ACTIVE': # CASE-4: Unsynced network state. At this point the network # exists and is connected to all nodes so is must be # active! self.reconcile_unsynced_network(network, bend, bnet) # Check that externally reserved IPs of the network in Ganeti are # also externally reserved to the IP pool externally_reserved = gnet['external_reservations'] if externally_reserved and ip_pools is not None: for ip in externally_reserved.split(","): ip = ip.strip() for ip_pool in ip_pools: if ip_pool.contains(ip): if not ip_pool.is_reserved(ip): msg = ("D: IP '%s' is reserved for network" " '%s' in backend '%s' but not in DB.") self.log.info(msg, ip, network, bend) if self.fix: ip_pool.reserve(ip, external=True) ip_pool.save() self.log.info("F: Reserved IP '%s'", ip) if network.state != "ACTIVE": network = Network.objects.select_for_update().get(id=network.id) backend_mod.update_network_state(network)