Merge ~mpontillo/maas:fix-pod-nonetype-relay-vlan--bug-1797135 into maas:master

Proposed by Mike Pontillo
Status: Merged
Approved by: Mike Pontillo
Approved revision: 692d6f1ae32eba85be5e024e5956a7eb1277ebd4
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~mpontillo/maas:fix-pod-nonetype-relay-vlan--bug-1797135
Merge into: maas:master
Diff against target: 198 lines (+138/-18)
2 files modified
src/maasserver/forms/pods.py (+31/-18)
src/maasserver/forms/tests/test_pods.py (+107/-0)
Reviewer Review Type Date Requested Status
Andres Rodriguez (community) Approve
Review via email: mp+356421@code.launchpad.net

Commit message

LP: #1797135 - Fix pod composition check for relay_vlan.

To post a comment you must log in.
Revision history for this message
Andres Rodriguez (andreserl) wrote :

lgtm!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/forms/pods.py b/src/maasserver/forms/pods.py
2index 1b945e5..77f9f3e 100644
3--- a/src/maasserver/forms/pods.py
4+++ b/src/maasserver/forms/pods.py
5@@ -353,6 +353,34 @@ class PodForm(MAASModelForm):
6 return update_db((discovered_pod, discovered))
7
8
9+def get_known_host_interfaces(host: Node) -> list:
10+ """Given the specified host node, calculates each KnownHostInterface.
11+
12+ :return: a list of KnownHostInterface objects for the specified Node.
13+ """
14+ interfaces = host.interface_set.all()
15+ result = []
16+ for interface in interfaces:
17+ ifname = interface.name
18+ if interface.type == INTERFACE_TYPE.BRIDGE:
19+ attach_type = InterfaceAttachType.BRIDGE
20+ else:
21+ attach_type = InterfaceAttachType.MACVLAN
22+ dhcp_enabled = False
23+ vlan = interface.vlan
24+ if vlan is not None:
25+ if vlan.dhcp_on:
26+ dhcp_enabled = True
27+ elif vlan.relay_vlan is not None:
28+ if vlan.relay_vlan.dhcp_on:
29+ dhcp_enabled = True
30+ result.append(
31+ KnownHostInterface(
32+ ifname=ifname, attach_type=attach_type,
33+ dhcp_enabled=dhcp_enabled))
34+ return result
35+
36+
37 class ComposeMachineForm(forms.Form):
38
39 def __init__(self, *args, **kwargs):
40@@ -543,26 +571,11 @@ class ComposeMachineForm(forms.Form):
41
42 # Find the pod's known host interfaces.
43 if self.pod.host is not None:
44- result = [
45- KnownHostInterface(
46- ifname=interface.name,
47- attach_type=(
48- InterfaceAttachType.BRIDGE
49- if interface.type == INTERFACE_TYPE.BRIDGE
50- else InterfaceAttachType.MACVLAN),
51- dhcp_enabled=(
52- True
53- if (interface.vlan is not None and
54- interface.vlan.dhcp_on) or (
55- interface.vlan.relay_vlan is not None and
56- interface.vlan.relay_vlan.dhcp_on)
57- else False))
58- for interface in self.pod.host.interface_set.all()
59- ]
60+ interfaces = get_known_host_interfaces(self.pod.host)
61 else:
62- result = []
63+ interfaces = []
64
65- return (client, result)
66+ return client, interfaces
67
68 def create_and_sync(result):
69 requested_machine, result = result
70diff --git a/src/maasserver/forms/tests/test_pods.py b/src/maasserver/forms/tests/test_pods.py
71index 0ba8616..e2c8675 100644
72--- a/src/maasserver/forms/tests/test_pods.py
73+++ b/src/maasserver/forms/tests/test_pods.py
74@@ -32,6 +32,7 @@ from maasserver.forms import pods as pods_module
75 from maasserver.forms.pods import (
76 ComposeMachineForm,
77 ComposeMachineForPodsForm,
78+ get_known_host_interfaces,
79 PodForm,
80 )
81 from maasserver.models import StaticIPAddress
82@@ -72,6 +73,7 @@ from provisioningserver.enum import (
83 from testtools import ExpectedException
84 from testtools.matchers import (
85 Equals,
86+ HasLength,
87 Is,
88 IsInstance,
89 MatchesAll,
90@@ -1811,3 +1813,108 @@ class TestComposeMachineForPodsForm(MAASServerTestCase):
91 data = self.make_data(pods)
92 form = ComposeMachineForPodsForm(request=request, data=data, pods=pods)
93 self.assertFalse(form.is_valid())
94+
95+
96+class TestGetKnownHostInterfaces(MAASServerTestCase):
97+
98+ def test__returns_empty_list_if_no_interfaces(self):
99+ node = factory.make_Machine_with_Interface_on_Subnet()
100+ node.interface_set.all().delete()
101+ interfaces = get_known_host_interfaces(node)
102+ self.assertThat(interfaces, HasLength(0))
103+
104+ def test__returns_appropriate_attach_type(self):
105+ node = factory.make_Machine_with_Interface_on_Subnet()
106+ vlan = factory.make_VLAN(dhcp_on=False)
107+ node.interface_set.all().delete()
108+ bridge = factory.make_Interface(
109+ iftype=INTERFACE_TYPE.BRIDGE, node=node, vlan=vlan)
110+ physical = factory.make_Interface(
111+ iftype=INTERFACE_TYPE.PHYSICAL, node=node, vlan=vlan)
112+ interfaces = get_known_host_interfaces(node)
113+ self.assertItemsEqual(
114+ interfaces, [
115+ KnownHostInterface(
116+ ifname=bridge.name,
117+ attach_type=InterfaceAttachType.BRIDGE,
118+ dhcp_enabled=False
119+ ),
120+ KnownHostInterface(
121+ ifname=physical.name,
122+ attach_type=InterfaceAttachType.MACVLAN,
123+ dhcp_enabled=False
124+ )
125+ ]
126+ )
127+
128+ def test__behaves_correctly_when_vlan_is_none(self):
129+ node = factory.make_Machine_with_Interface_on_Subnet()
130+ node.interface_set.all().delete()
131+ bridge = factory.make_Interface(
132+ iftype=INTERFACE_TYPE.BRIDGE, node=node, disconnected=True)
133+ physical = factory.make_Interface(
134+ iftype=INTERFACE_TYPE.PHYSICAL, node=node, disconnected=True)
135+ interfaces = get_known_host_interfaces(node)
136+ self.assertItemsEqual(
137+ interfaces, [
138+ KnownHostInterface(
139+ ifname=bridge.name,
140+ attach_type=InterfaceAttachType.BRIDGE,
141+ dhcp_enabled=False
142+ ),
143+ KnownHostInterface(
144+ ifname=physical.name,
145+ attach_type=InterfaceAttachType.MACVLAN,
146+ dhcp_enabled=False
147+ )
148+ ]
149+ )
150+
151+ def test__gets_dhcp_status_for_directly_enabled_vlan(self):
152+ node = factory.make_Machine_with_Interface_on_Subnet()
153+ vlan = factory.make_VLAN(dhcp_on=True)
154+ node.interface_set.all().delete()
155+ bridge = factory.make_Interface(
156+ iftype=INTERFACE_TYPE.BRIDGE, node=node, vlan=vlan)
157+ physical = factory.make_Interface(
158+ iftype=INTERFACE_TYPE.PHYSICAL, node=node, vlan=vlan)
159+ interfaces = get_known_host_interfaces(node)
160+ self.assertItemsEqual(
161+ interfaces, [
162+ KnownHostInterface(
163+ ifname=bridge.name,
164+ attach_type=InterfaceAttachType.BRIDGE,
165+ dhcp_enabled=True
166+ ),
167+ KnownHostInterface(
168+ ifname=physical.name,
169+ attach_type=InterfaceAttachType.MACVLAN,
170+ dhcp_enabled=True
171+ )
172+ ]
173+ )
174+
175+ def test__gets_dhcp_status_for_indirectly_enabled_vlan(self):
176+ node = factory.make_Machine_with_Interface_on_Subnet()
177+ relay_vlan = factory.make_VLAN(dhcp_on=True)
178+ vlan = factory.make_VLAN(dhcp_on=False, relay_vlan=relay_vlan)
179+ node.interface_set.all().delete()
180+ bridge = factory.make_Interface(
181+ iftype=INTERFACE_TYPE.BRIDGE, node=node, vlan=vlan)
182+ physical = factory.make_Interface(
183+ iftype=INTERFACE_TYPE.PHYSICAL, node=node, vlan=vlan)
184+ interfaces = get_known_host_interfaces(node)
185+ self.assertItemsEqual(
186+ interfaces, [
187+ KnownHostInterface(
188+ ifname=bridge.name,
189+ attach_type=InterfaceAttachType.BRIDGE,
190+ dhcp_enabled=True
191+ ),
192+ KnownHostInterface(
193+ ifname=physical.name,
194+ attach_type=InterfaceAttachType.MACVLAN,
195+ dhcp_enabled=True
196+ )
197+ ]
198+ )

Subscribers

People subscribed via source and target branches