Merge lp:~mpontillo/maas/commissioning-fixes-trunk into lp:~maas-committers/maas/trunk

Proposed by Mike Pontillo
Status: Merged
Approved by: Mike Pontillo
Approved revision: no longer in the source branch.
Merged at revision: 4553
Proposed branch: lp:~mpontillo/maas/commissioning-fixes-trunk
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 188 lines (+68/-25)
4 files modified
src/maasserver/models/interface.py (+13/-1)
src/maasserver/models/tests/test_interface.py (+32/-0)
src/maasserver/testing/factory.py (+12/-6)
src/metadataserver/models/commissioningscript.py (+11/-18)
To merge this branch: bzr merge lp:~mpontillo/maas/commissioning-fixes-trunk
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+280228@code.launchpad.net

Commit message

Merge fix for bug 1524924 from MAAS 1.9 at revsion 4530. Fixes node interfaces being configured in an incorrect subnet after commissioning.

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/models/interface.py'
2--- src/maasserver/models/interface.py 2015-12-09 02:02:23 +0000
3+++ src/maasserver/models/interface.py 2015-12-11 03:55:02 +0000
4@@ -455,8 +455,20 @@
5 # to create or update the Subnet)
6 try:
7 subnet = Subnet.objects.get(cidr=cidr)
8+ # Update VLAN based on the VLAN this Subnet belongs to.
9+ if subnet.vlan != self.vlan:
10+ vlan = subnet.vlan
11+ maaslog.info("%s: Observed connected to %s via %s." % (
12+ self.get_log_string(), vlan.fabric.get_name(), cidr))
13+ self.vlan = vlan
14+ self.save()
15 except Subnet.DoesNotExist:
16- # XXX mpontillo 2015-11-01 configuration != state
17+ # XXX mpontillo 2015-11-01 Configuration != state. That is,
18+ # this means we have just a subnet on an unknown Fabric/VLAN,
19+ # and this fact should be recorded somewhere, so that the user
20+ # gets a chance to configure it. Note, however, that if this
21+ # is already a managed cluster interface, a Fabric/VLAN will
22+ # already have been created.
23 subnet = Subnet.objects.create_from_cidr(cidr)
24 maaslog.info(
25 "Creating subnet %s connected to interface %s "
26
27=== modified file 'src/maasserver/models/tests/test_interface.py'
28--- src/maasserver/models/tests/test_interface.py 2015-12-09 02:02:23 +0000
29+++ src/maasserver/models/tests/test_interface.py 2015-12-11 03:55:02 +0000
30@@ -1038,6 +1038,38 @@
31 alloc_type=IPADDRESS_TYPE.DISCOVERED, subnet=subnet_list[i],
32 ip=str(IPNetwork(cidr_list[i]).ip)))
33
34+ def test__links_interface_to_vlan_on_existing_subnet_with_logging(self):
35+ ng = factory.make_NodeGroup()
36+ fabric2 = factory.make_Fabric()
37+ fabric3 = factory.make_Fabric()
38+ ngi1 = factory.make_NodeGroupInterface(ng)
39+ ngi2 = factory.make_NodeGroupInterface(ng, fabric=fabric2)
40+ ngi3 = factory.make_NodeGroupInterface(ng, fabric=fabric3)
41+ interface1 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
42+ interface2 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
43+ interface3 = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
44+ vlan1 = ngi1.subnet.vlan
45+ vlan2 = ngi2.subnet.vlan
46+ vlan3 = ngi3.subnet.vlan
47+ maaslog = self.patch_autospec(interface_module, "maaslog")
48+ interface1.update_ip_addresses([ngi1.subnet.cidr])
49+ interface2.update_ip_addresses([ngi2.subnet.cidr])
50+ interface3.update_ip_addresses([ngi3.subnet.cidr])
51+ self.assertThat(interface1.vlan, Equals(vlan1))
52+ self.assertThat(interface2.vlan, Equals(vlan2))
53+ self.assertThat(interface3.vlan, Equals(vlan3))
54+ self.assertThat(maaslog.info, MockCallsMatch(
55+ call(("%s: Observed connected to %s via %s." % (
56+ interface1.get_log_string(), interface1.vlan.fabric.get_name(),
57+ ngi1.subnet.cidr))),
58+ call(("%s: Observed connected to %s via %s." % (
59+ interface2.get_log_string(), interface2.vlan.fabric.get_name(),
60+ ngi2.subnet.cidr))),
61+ call(("%s: Observed connected to %s via %s." % (
62+ interface3.get_log_string(), interface3.vlan.fabric.get_name(),
63+ ngi3.subnet.cidr))),
64+ ))
65+
66 def test__deletes_old_discovered_ip_addresses_on_interface(self):
67 interface = factory.make_Interface(INTERFACE_TYPE.PHYSICAL)
68 # Create existing DISCOVERED IP address on the interface. These should
69
70=== modified file 'src/maasserver/testing/factory.py'
71--- src/maasserver/testing/factory.py 2015-12-09 01:24:24 +0000
72+++ src/maasserver/testing/factory.py 2015-12-11 03:55:02 +0000
73@@ -482,7 +482,8 @@
74 ip_range_low=None, ip_range_high=None,
75 interface=None, management=None,
76 static_ip_range_low=None,
77- static_ip_range_high=None, **kwargs):
78+ static_ip_range_high=None, fabric=None,
79+ **kwargs):
80 interface_settings = self.get_interface_fields(
81 name=name, ip=ip, router_ip=router_ip,
82 network=network, subnet=subnet, subnet_mask=subnet_mask,
83@@ -498,12 +499,17 @@
84 cidr = create_cidr(
85 interface_settings['ip'], interface_settings['subnet_mask'])
86
87+ defaults = {
88+ 'name': cidr,
89+ 'cidr': cidr,
90+ 'space': Space.objects.get_default_space(),
91+ }
92+
93+ if fabric is not None:
94+ defaults['vlan'] = fabric.get_default_vlan()
95+
96 subnet, _ = Subnet.objects.get_or_create(
97- cidr=cidr, defaults={
98- 'name': cidr,
99- 'cidr': cidr,
100- 'space': Space.objects.get_default_space(),
101- })
102+ cidr=cidr, defaults=defaults)
103 elif interface_settings['subnet']:
104 subnet = interface_settings.pop('subnet')
105 interface_settings['subnet_mask'] = subnet.get_ipnetwork().netmask
106
107=== modified file 'src/metadataserver/models/commissioningscript.py'
108--- src/metadataserver/models/commissioningscript.py 2015-12-01 18:12:59 +0000
109+++ src/metadataserver/models/commissioningscript.py 2015-12-11 03:55:02 +0000
110@@ -130,8 +130,7 @@
111 """
112
113
114-def _create_default_physical_interface(
115- node, ifname, mac, fabric=None, vlan=None):
116+def _create_default_physical_interface(node, ifname, mac):
117 """Assigns the specified interface to the specified Node.
118
119 Creates or updates a PhysicalInterface that corresponds to the given MAC.
120@@ -140,18 +139,15 @@
121 :param ifname: the interface name (for example, 'eth0')
122 :param mac: the Interface to update and associate
123 """
124- if fabric is None:
125- fabric = Fabric.objects.get_default_fabric()
126-
127- if vlan is None:
128- vlan = fabric.get_default_vlan()
129-
130+ # We don't yet have enough information to put this newly-created Interface
131+ # into the proper Fabric/VLAN. (We'll do this on a "best effort" basis
132+ # later, if we are able to determine that the interface is on a particular
133+ # subnet due to a DHCP reply during commissioning.)
134+ fabric = Fabric.objects.get_default_fabric()
135+ vlan = fabric.get_default_vlan()
136 interface = PhysicalInterface.objects.create(
137 mac_address=mac, name=ifname, node=node, vlan=vlan)
138
139- # XXX:fabric - for now we use the default fabric, but we need to be smarter
140- # about determining which fabric the node is in. (perhaps the cluster
141- # interface the node is linked to has an associated fabric, for example)
142 return interface
143
144
145@@ -185,7 +181,6 @@
146 else:
147 ifname = link['name']
148 try:
149- # XXX:fabric - this MAC might exist on a different Fabric
150 interface = PhysicalInterface.objects.get(
151 mac_address=link_mac)
152 if interface.node is not None and interface.node != node:
153@@ -195,7 +190,6 @@
154 (interface.mac_address, interface.node.fqdn,
155 node.fqdn))
156 interface.delete()
157- # XXX: mpontillo 2015-08-27 how do we get Fabric/VLAN here?
158 interface = _create_default_physical_interface(
159 node, ifname, link_mac)
160 else:
161@@ -204,7 +198,6 @@
162 interface.name = ifname
163 interface.save()
164 except PhysicalInterface.DoesNotExist:
165- # XXX: mpontillo 2015-08-27 how do we get Fabric/VLAN here?
166 interface = _create_default_physical_interface(
167 node, ifname, link_mac)
168
169@@ -681,10 +674,6 @@
170 'content': LIST_MODALIASES_SCRIPT.encode('ascii'),
171 'hook': null_hook,
172 },
173- '00-maas-05-network-interfaces.out': {
174- 'content': IPADDR_SCRIPT.encode('ascii'),
175- 'hook': update_node_network_information,
176- },
177 '00-maas-06-dhcp-unconfigured-ifaces': {
178 'content': make_function_call_script(dhcp_explore),
179 'hook': null_hook,
180@@ -702,6 +691,10 @@
181 'content': make_function_call_script(lldpd_capture),
182 'hook': set_node_routers,
183 },
184+ '99-maas-03-network-interfaces.out': {
185+ 'content': IPADDR_SCRIPT.encode('ascii'),
186+ 'hook': update_node_network_information,
187+ },
188 }
189
190