53
53
NodeGroupDefineForm,
56
from maasserver.models import (
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,
68
63
from maasserver.utils.orm import get_one
70
import simplejson as json
73
66
DISPLAYED_NODEGROUP_FIELDS = ('uuid', 'status', 'name', 'cluster_name')
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.
240
cluster.nodegroupinterface_set
241
.exclude(ip_range_low__isnull=True)
242
.exclude(ip_range_high__isnull=True)
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)
252
interface_ranges[interface] = (ip_range, static_range)
253
for ip, mac in leases.items():
255
mac_address = MACAddress.objects.get(mac_address=mac)
256
except MACAddress.DoesNotExist:
257
# Silently ignore MAC addresses that we don't know about.
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
265
# Locate the Network to which this MAC belongs.
266
ipnetwork = interface.network
267
if ipnetwork is not None:
269
network = Network.objects.get(ip=ipnetwork.ip.format())
270
network.macaddress_set.add(mac_address)
271
except Network.DoesNotExist:
274
# Cheap optimisation. No other interfaces will match, so
275
# break out of the loop.
279
228
class NodeGroupsHandler(OperationsHandler):
280
229
"""Manage the collection of all the nodegroups in this MAAS."""
409
358
raise ValidationError(form.errors)
411
@operation(idempotent=False)
412
def update_leases(self, request, uuid):
413
"""Submit latest state of DHCP leases within the cluster.
415
The cluster controller calls this periodically to tell the region
416
controller about the IP addresses it manages.
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)
427
361
@operation(idempotent=False)
428
362
def import_boot_images(self, request, uuid):