~rvb/maas/transaction-1.7-bug-1409852

« back to all changes in this revision

Viewing changes to src/maasserver/api/node_groups.py

merged upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
    NodeGroupDefineForm,
54
54
    NodeGroupEdit,
55
55
    )
56
 
from maasserver.models import (
57
 
    DHCPLease,
58
 
    MACAddress,
59
 
    Network,
60
 
    Node,
61
 
    NodeGroup,
62
 
    )
 
56
from maasserver.models.node import Node
 
57
from maasserver.models.nodegroup import NodeGroup
63
58
from maasserver.models.nodeprobeddetails import get_probed_details
64
59
from maasserver.utils import (
65
60
    build_absolute_uri,
66
61
    get_local_cluster_UUID,
67
62
    )
68
63
from maasserver.utils.orm import get_one
69
 
import netaddr
70
 
import simplejson as json
71
64
 
72
65
 
73
66
DISPLAYED_NODEGROUP_FIELDS = ('uuid', 'status', 'name', 'cluster_name')
232
225
        nodegroup.save()
233
226
 
234
227
 
235
 
def update_mac_cluster_interfaces(leases, cluster):
236
 
    """Calculate and store which interface a MAC is attached to."""
237
 
    interface_ranges = {}
238
 
    # Only consider configured interfaces.
239
 
    interfaces = (
240
 
        cluster.nodegroupinterface_set
241
 
        .exclude(ip_range_low__isnull=True)
242
 
        .exclude(ip_range_high__isnull=True)
243
 
    )
244
 
    for interface in interfaces:
245
 
        ip_range = netaddr.IPRange(
246
 
            interface.ip_range_low, interface.ip_range_high)
247
 
        if interface.static_ip_range_low and interface.static_ip_range_high:
248
 
            static_range = netaddr.IPRange(
249
 
                interface.static_ip_range_low, interface.static_ip_range_high)
250
 
        else:
251
 
            static_range = []
252
 
        interface_ranges[interface] = (ip_range, static_range)
253
 
    for ip, mac in leases.items():
254
 
        try:
255
 
            mac_address = MACAddress.objects.get(mac_address=mac)
256
 
        except MACAddress.DoesNotExist:
257
 
            # Silently ignore MAC addresses that we don't know about.
258
 
            continue
259
 
        for interface, (ip_range, static_range) in interface_ranges.items():
260
 
            ipaddress = netaddr.IPAddress(ip)
261
 
            if ipaddress in ip_range or ipaddress in static_range:
262
 
                mac_address.cluster_interface = interface
263
 
                mac_address.save()
264
 
 
265
 
                # Locate the Network to which this MAC belongs.
266
 
                ipnetwork = interface.network
267
 
                if ipnetwork is not None:
268
 
                    try:
269
 
                        network = Network.objects.get(ip=ipnetwork.ip.format())
270
 
                        network.macaddress_set.add(mac_address)
271
 
                    except Network.DoesNotExist:
272
 
                        pass
273
 
 
274
 
                # Cheap optimisation. No other interfaces will match, so
275
 
                # break out of the loop.
276
 
                break
277
 
 
278
 
 
279
228
class NodeGroupsHandler(OperationsHandler):
280
229
    """Manage the collection of all the nodegroups in this MAAS."""
281
230
 
408
357
        else:
409
358
            raise ValidationError(form.errors)
410
359
 
411
 
    @operation(idempotent=False)
412
 
    def update_leases(self, request, uuid):
413
 
        """Submit latest state of DHCP leases within the cluster.
414
 
 
415
 
        The cluster controller calls this periodically to tell the region
416
 
        controller about the IP addresses it manages.
417
 
        """
418
 
        leases = get_mandatory_param(request.data, 'leases')
419
 
        nodegroup = get_object_or_404(NodeGroup, uuid=uuid)
420
 
        check_nodegroup_access(request, nodegroup)
421
 
        leases = json.loads(leases)
422
 
        DHCPLease.objects.update_leases(nodegroup, leases)
423
 
        update_mac_cluster_interfaces(leases, nodegroup)
424
 
        return HttpResponse("Leases updated.", status=httplib.OK)
425
 
 
426
360
    @admin_method
427
361
    @operation(idempotent=False)
428
362
    def import_boot_images(self, request, uuid):