Merge lp:~lamont/maas/bug-1645912-2.1b into lp:maas/2.1

Proposed by LaMont Jones
Status: Merged
Approved by: LaMont Jones
Approved revision: no longer in the source branch.
Merged at revision: 5588
Proposed branch: lp:~lamont/maas/bug-1645912-2.1b
Merge into: lp:maas/2.1
Diff against target: 202 lines (+121/-17)
4 files modified
src/maasserver/models/bmc.py (+4/-1)
src/maasserver/models/tests/test_bmc.py (+24/-0)
src/provisioningserver/templates/commissioning-user-data/snippets/maas_ipmi_autodetect.py (+30/-8)
src/provisioningserver/templates/commissioning-user-data/snippets/tests/test_maas_ipmi_autodetect.py (+63/-8)
To merge this branch: bzr merge lp:~lamont/maas/bug-1645912-2.1b
Reviewer Review Type Date Requested Status
Mike Pontillo (community) Approve
Review via email: mp+316971@code.launchpad.net

Commit message

Backport r5710 from trunk: Have ipmi_autodetect wrap IPv6 literals in brackets. Parse those correctly.

Description of the change

Backport r5710 from trunk: Have ipmi_autodetect wrap IPv6 literals in brackets. Parse those correctly.

To post a comment you must log in.
Revision history for this message
Mike Pontillo (mpontillo) wrote :

LGTM.

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/bmc.py'
2--- src/maasserver/models/bmc.py 2016-06-04 00:21:58 +0000
3+++ src/maasserver/models/bmc.py 2017-02-10 15:17:08 +0000
4@@ -93,7 +93,10 @@
5 parameters has changed. """
6 new_ip = BMC.extract_ip_address(self.power_type, self.power_parameters)
7 current_ip = None if self.ip_address is None else self.ip_address.ip
8- # Set the ip_address field.
9+ # Set the ip_address field. If we have a bracketed address, assume
10+ # it's IPv6, and strip the brackets.
11+ if new_ip and new_ip.startswith('[') and new_ip.endswith(']'):
12+ new_ip = new_ip[1:-1]
13 if new_ip != current_ip:
14 if new_ip is None:
15 self.ip_address = None
16
17=== modified file 'src/maasserver/models/tests/test_bmc.py'
18--- src/maasserver/models/tests/test_bmc.py 2016-09-23 01:54:50 +0000
19+++ src/maasserver/models/tests/test_bmc.py 2017-02-10 15:17:08 +0000
20@@ -97,6 +97,30 @@
21 self.assertEqual(sticky_ip.ip, bmc.ip_address.ip)
22 self.assertEqual(subnet, bmc.ip_address.subnet)
23
24+ def test_bmc_save_accepts_naked_ipv6_address(self):
25+ subnet = factory.make_Subnet(cidr=factory.make_ipv6_network())
26+ sticky_ip = factory.make_StaticIPAddress(
27+ alloc_type=IPADDRESS_TYPE.STICKY, subnet=subnet)
28+ power_parameters = {
29+ 'power_address': '%s' % sticky_ip.ip,
30+ }
31+ bmc = factory.make_BMC(
32+ power_type="ipmi", power_parameters=power_parameters)
33+ self.assertEqual(sticky_ip.ip, bmc.ip_address.ip)
34+ self.assertEqual(subnet, bmc.ip_address.subnet)
35+
36+ def test_bmc_save_accepts_bracketed_ipv6_address(self):
37+ subnet = factory.make_Subnet(cidr=factory.make_ipv6_network())
38+ sticky_ip = factory.make_StaticIPAddress(
39+ alloc_type=IPADDRESS_TYPE.STICKY, subnet=subnet)
40+ power_parameters = {
41+ 'power_address': '[%s]' % sticky_ip.ip,
42+ }
43+ bmc = factory.make_BMC(
44+ power_type="ipmi", power_parameters=power_parameters)
45+ self.assertEqual(sticky_ip.ip, bmc.ip_address.ip)
46+ self.assertEqual(subnet, bmc.ip_address.subnet)
47+
48 def test_bmc_changing_power_parameters_changes_ip(self):
49 ip = factory.make_ipv4_address()
50 power_parameters = {
51
52=== modified file 'src/provisioningserver/templates/commissioning-user-data/snippets/maas_ipmi_autodetect.py'
53--- src/provisioningserver/templates/commissioning-user-data/snippets/maas_ipmi_autodetect.py 2016-09-23 16:21:57 +0000
54+++ src/provisioningserver/templates/commissioning-user-data/snippets/maas_ipmi_autodetect.py 2017-02-10 15:17:08 +0000
55@@ -142,14 +142,36 @@
56 bmc_set('Lan_Conf:IP_Address_Source', source)
57
58
59+def _bmc_get_ipmi_addresses(address_type):
60+ try:
61+ return bmc_get(address_type)
62+ except subprocess.CalledProcessError:
63+ return ""
64+
65+
66 def get_ipmi_ip_address():
67- output = bmc_get('Lan_Conf:IP_Address')
68 show_re = re.compile(
69 '((?:[0-9]{1,3}\.){3}[0-9]{1,3}|[0-9a-fA-F]*:[0-9a-fA-F:.]+)')
70- res = show_re.search(output)
71- if res is None:
72- return None
73- return res.group()
74+ for address_type in [
75+ 'Lan_Conf:IP_Address',
76+ 'Lan6_Conf:IPv6_Static_Addresses',
77+ 'Lan6_Conf:IPv6_Dynamic_Addresses']:
78+ output = _bmc_get_ipmi_addresses(address_type)
79+ # Loop through the addreses by preference: IPv4, static IPv6, dynamic
80+ # IPv6. Return the first valid, non-link-local address we find.
81+ # While we could conceivably allow link-local addresses, we would need
82+ # to devine which of our interfaces is the correct link, and then we
83+ # would need support for link-local addresses in freeipmi-tools.
84+ res = show_re.findall(output)
85+ for ip in res:
86+ if ip.lower().startswith('fe80::') or ip == '0.0.0.0':
87+ time.sleep(2)
88+ continue
89+ if address_type.startswith('Lan6_'):
90+ return '[%s]' % ip
91+ return ip
92+ # No valid IP address was found.
93+ return None
94
95
96 def verify_ipmi_user_settings(user_number, user_settings):
97@@ -281,15 +303,15 @@
98
99 # get the IP address
100 IPMI_IP_ADDRESS = get_ipmi_ip_address()
101- if IPMI_IP_ADDRESS == "0.0.0.0":
102- # if IPMI_IP_ADDRESS is 0.0.0.0, wait 60 seconds and retry.
103+ if IPMI_IP_ADDRESS is None:
104+ # if IPMI_IP_ADDRESS not set (or reserved), wait 60 seconds and retry.
105 set_ipmi_network_source("Static")
106 time.sleep(2)
107 set_ipmi_network_source("Use_DHCP")
108 time.sleep(60)
109 IPMI_IP_ADDRESS = get_ipmi_ip_address()
110
111- if IPMI_IP_ADDRESS is None or IPMI_IP_ADDRESS == "0.0.0.0":
112+ if IPMI_IP_ADDRESS is None:
113 # Exit (to not set power params in MAAS) if no IPMI_IP_ADDRESS
114 # has been detected
115 exit(1)
116
117=== modified file 'src/provisioningserver/templates/commissioning-user-data/snippets/tests/test_maas_ipmi_autodetect.py'
118--- src/provisioningserver/templates/commissioning-user-data/snippets/tests/test_maas_ipmi_autodetect.py 2016-09-23 19:44:23 +0000
119+++ src/provisioningserver/templates/commissioning-user-data/snippets/tests/test_maas_ipmi_autodetect.py 2017-02-10 15:17:08 +0000
120@@ -497,19 +497,74 @@
121
122 scenarios = [
123 ('none', dict(
124- output=' IP_Address \n\n', expected=None)),
125+ output4=' IP_Address \n\n',
126+ output_st='', output_dy='', expected=None)),
127 ('bogus', dict(
128- output=' IP_Address bogus\n\n', expected=None)),
129+ output4=' IP_Address bogus\n\n',
130+ output_st='', output_dy='', expected=None)),
131 ('ipv4', dict(
132- output=' IP_Address 192.168.1.1\n\n', expected='192.168.1.1')),
133- ('ipv6', dict(
134- output=' IP_Address 2001:db8::3\n\n', expected='2001:db8::3')),
135+ output4=' IP_Address 192.168.1.1\n\n',
136+ output_st='', output_dy='', expected='192.168.1.1')),
137+ ('ipv4-ipv6', dict(
138+ output4=' IP_Address 192.168.1.1\n\n',
139+ output_st=' IPv6_Static_Addresses 2001:db8::3\n\n',
140+ output_dy='', expected='192.168.1.1')),
141+ ('static6', dict(
142+ output4=' IP_Address 0.0.0.0\n\n',
143+ output_st=' IPv6_Static_Addresses 2001:db8::3\n\n',
144+ output_dy='',
145+ expected='[2001:db8::3]')),
146+ ('static6 multiple', dict(
147+ output4=' IP_Address 0.0.0.0\n\n',
148+ output_st=' IPv6_Static_Addresses fe80::3:7 2001:db8::3\n\n',
149+ output_dy='',
150+ expected='[2001:db8::3]')),
151+ ('mixed6', dict(
152+ output4=' IP_Address 0.0.0.0\n\n',
153+ output_st=' IPv6_Static_Addresses 2001:db8::9:5\n\n',
154+ output_dy=' ## IPv6_Dynamic_Addresses 2001:db8::3\n\n',
155+ expected='[2001:db8::9:5]')),
156+ ('dynamic6', dict(
157+ output4=' IP_Address 0.0.0.0\n\n',
158+ output_st='',
159+ output_dy=' ## IPv6_Dynamic_Addresses 2001:db8::3\n\n',
160+ expected='[2001:db8::3]')),
161+ ('dynamic6 with link-local', dict(
162+ output4=' IP_Address 0.0.0.0\n\n',
163+ output_st='',
164+ output_dy=' ## IPv6_Dynamic_Addresses fe80::3:7 2001:db8::3\n\n',
165+ expected='[2001:db8::3]')),
166+ ('dynamic6 multiple', dict(
167+ output4=' IP_Address 0.0.0.0\n\n',
168+ output_st='',
169+ output_dy=(
170+ ' ## IPv6_Dynamic_Addresses fe80::7 2001:db8::3 2001::5\n\n'
171+ ),
172+ expected='[2001:db8::3]')),
173 ('link-local', dict(
174- output=' IP_Address fe80::3:7\n\n', expected='fe80::3:7')),
175+ output4='',
176+ output_st='',
177+ output_dy=' ## IPv6_Dynamic_IP_Addresses fe80::7 fe80::3:9\n\n',
178+ expected=None)),
179+ ('0.0.0.0', dict(
180+ output4=' IP_Address 0.0.0.0\n\n',
181+ output_st='',
182+ output_dy='',
183+ expected=None)),
184 ]
185
186 def test_get_ipmi_ip_address(self):
187- run_command = self.patch(maas_ipmi_autodetect, 'run_command')
188- run_command.return_value = self.output
189+ ret_values = {
190+ 'Lan_Conf:IP_Address': self.output4,
191+ 'Lan6_Conf:IPv6_Static_Addresses': self.output_st,
192+ 'Lan6_Conf:IPv6_Dynamic_Addresses': self.output_dy
193+ }
194+
195+ def ret_val(arg):
196+ return ret_values[arg]
197+
198+ self.patch(
199+ maas_ipmi_autodetect,
200+ '_bmc_get_ipmi_addresses').side_effect = ret_val
201 actual = get_ipmi_ip_address()
202 self.assertEqual(self.expected, actual)

Subscribers

People subscribed via source and target branches

to all changes: