Merge lp:~mpontillo/maas/fix-random-failure--bug-1683503 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: 5991
Proposed branch: lp:~mpontillo/maas/fix-random-failure--bug-1683503
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 85 lines (+36/-6)
2 files modified
src/provisioningserver/utils/network.py (+11/-6)
src/provisioningserver/utils/tests/test_network.py (+25/-0)
To merge this branch: bzr merge lp:~mpontillo/maas/fix-random-failure--bug-1683503
Reviewer Review Type Date Requested Status
Lee Trager (community) Approve
Review via email: mp+322651@code.launchpad.net

Commit message

Fix dynamic range suggestion code to prevent suggesting a very small dynamic range.

To post a comment you must log in.
Revision history for this message
Lee Trager (ltrager) 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/provisioningserver/utils/network.py'
2--- src/provisioningserver/utils/network.py 2016-12-07 12:46:14 +0000
3+++ src/provisioningserver/utils/network.py 2017-04-17 23:20:00 +0000
4@@ -267,6 +267,8 @@
5 suggested_gateway = None
6 first_address = self.first_address_value
7 last_address = self.last_address_value
8+ if self.ip_version == 6 and self.total_addresses <= 2:
9+ return None
10 if self.ip_version == 6:
11 # For IPv6 addresses, always return the subnet-router anycast
12 # address. (See RFC 4291 section 2.6.1 for more information.)
13@@ -315,20 +317,23 @@
14 candidate.first, candidate.last - 1,
15 purpose=IPRANGE_TYPE.PROPOSED_DYNAMIC)
16 if candidate is not None:
17+ first = candidate.first
18 one_fourth_range = self.total_addresses >> 2
19 half_remaining_space = self.num_available >> 1
20 if candidate.size > one_fourth_range:
21 # Prevent the proposed range from taking up too much available
22 # space in the subnet.
23- candidate = MAASIPRange(
24- candidate.last - one_fourth_range, candidate.last,
25- purpose=IPRANGE_TYPE.PROPOSED_DYNAMIC)
26+ first = candidate.last - one_fourth_range
27 elif candidate.size >= half_remaining_space:
28 # Prevent the proposed range from taking up the remainder of
29 # the available IP addresses. (take at most half.)
30- candidate = MAASIPRange(
31- candidate.last - half_remaining_space + 1, candidate.last,
32- purpose=IPRANGE_TYPE.PROPOSED_DYNAMIC)
33+ first = candidate.last - half_remaining_space + 1
34+ if first >= candidate.last:
35+ # Calculated an impossible range.
36+ return None
37+ candidate = MAASIPRange(
38+ first, candidate.last,
39+ purpose=IPRANGE_TYPE.PROPOSED_DYNAMIC)
40 return candidate
41
42 @property
43
44=== modified file 'src/provisioningserver/utils/tests/test_network.py'
45--- src/provisioningserver/utils/tests/test_network.py 2017-04-04 07:42:31 +0000
46+++ src/provisioningserver/utils/tests/test_network.py 2017-04-17 23:20:00 +0000
47@@ -825,6 +825,12 @@
48 self.assertThat(u['10.0.0.2'].purpose, Not(Contains('unused')))
49 self.assertThat(u['10.0.0.254'].purpose, Contains('unused'))
50
51+ def test__calculates_full_range_for_small_ipv6(self):
52+ s = MAASIPSet([])
53+ u = s.get_full_range('2001:db8::/127')
54+ self.assertThat(u['2001:db8::'].purpose, Contains('unused'))
55+ self.assertThat(u['2001:db8::1'].purpose, Contains('unused'))
56+
57 def test__supports_ior(self):
58 s1 = MAASIPSet(['10.0.0.2', '10.0.0.4', '10.0.0.6', '10.0.0.8'])
59 s2 = MAASIPSet(['10.0.0.1', '10.0.0.3', '10.0.0.5', '10.0.0.7'])
60@@ -1082,6 +1088,25 @@
61 stats.suggested_dynamic_range, Not(Contains(
62 "2001:db8::bfff:ffff:ffff:ffff")))
63
64+ def test__no_suggestion_for_small_ipv6_slash_126(self):
65+ s = MAASIPSet([])
66+ u = s.get_full_range('2001:db8::/126')
67+ stats = IPRangeStatistics(u)
68+ self.assertThat(stats.suggested_gateway, Equals("2001:db8::"))
69+ self.assertThat(stats.suggested_dynamic_range, Is(None))
70+
71+ def test__no_suggestion_for_small_ipv6_slash_127(self):
72+ s = MAASIPSet([])
73+ u = s.get_full_range('2001:db8::/127')
74+ stats = IPRangeStatistics(u)
75+ self.assertThat(stats.suggested_gateway, Equals(None))
76+
77+ def test__no_suggestion_and_no_gateway_for_small_ipv6_slash_128(self):
78+ s = MAASIPSet([])
79+ u = s.get_full_range('2001:db8::/128')
80+ stats = IPRangeStatistics(u)
81+ self.assertThat(stats.suggested_gateway, Is(None))
82+
83 def test__suggests_half_available_for_ipv6(self):
84 s = MAASIPSet([MAASIPRange(
85 "2001:db8::1", "2001:db8::ffff:ffff:ffff:ff00")])