Example #1
0
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)
Example #2
0
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)
Example #3
0
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
Example #4
0
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
Example #5
0
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
Example #6
0
 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)
Example #7
0
    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)
Example #8
0
 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)
Example #9
0
    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)