Merge lp:~mpontillo/maas/prevent-static-address-in-dynamic-range--bug-1604461 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: 5220
Proposed branch: lp:~mpontillo/maas/prevent-static-address-in-dynamic-range--bug-1604461
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 61 lines (+11/-8)
2 files modified
src/maasserver/api/ip_addresses.py (+7/-0)
src/maasserver/api/tests/test_ipaddresses.py (+4/-8)
To merge this branch: bzr merge lp:~mpontillo/maas/prevent-static-address-in-dynamic-range--bug-1604461
Reviewer Review Type Date Requested Status
Andres Rodriguez (community) Approve
Review via email: mp+301438@code.launchpad.net

Commit message

Ensure a specified IP address is not within a dyanamic range before allowing it to be reserved.

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

lgtm! Please back port this. Btw, this has no impact on BMC's no?

review: Approve
Revision history for this message
Andres Rodriguez (andreserl) wrote :

I Mean, does this have any impact on BMC's? AS per our discussion a BMC will reserve an IP address.. I guess it shouldn't if we don't know the subnet, but as per discussion, we could have a dynamic range defined, which is where BMC's are DHCP'ing from, and when a BMC is added, do we reserve this IP?

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Correct, no impact on BMCs. This is validation at the API layer. That reminds me, I need to check the websocket path too.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

The websocket path is okay. We actually don't support this operation on the websocket; we expect the user to create devices in the UI instead, and this was never an issue for IP addresses where we know the MAC binding.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/api/ip_addresses.py'
2--- src/maasserver/api/ip_addresses.py 2016-06-07 14:55:13 +0000
3+++ src/maasserver/api/ip_addresses.py 2016-07-28 23:41:52 +0000
4@@ -24,6 +24,7 @@
5 )
6 from maasserver.exceptions import (
7 MAASAPIBadRequest,
8+ MAASAPIForbidden,
9 MAASAPIValidationError,
10 )
11 from maasserver.forms import (
12@@ -72,6 +73,12 @@
13 :type domain: Domain
14 :raises StaticIPAddressExhaustion: If no IPs available.
15 """
16+ dynamic_range = subnet.get_dynamic_maasipset()
17+ if ip_address is not None and ip_address in dynamic_range:
18+ raise MAASAPIForbidden(
19+ "IP address %s belongs to an existing dynamic range. To "
20+ "reserve this IP address, a MAC address is required. (Create "
21+ "a device instead.)" % ip_address)
22 if hostname is not None and hostname.find('.') > 0:
23 hostname, domain = hostname.split('.', 1)
24 domain = Domain.objects.get_domain_or_404(
25
26=== modified file 'src/maasserver/api/tests/test_ipaddresses.py'
27--- src/maasserver/api/tests/test_ipaddresses.py 2016-06-07 14:55:13 +0000
28+++ src/maasserver/api/tests/test_ipaddresses.py 2016-07-28 23:41:52 +0000
29@@ -6,7 +6,6 @@
30 __all__ = []
31
32 import http.client
33-from unittest import skip
34
35 from django.conf import settings
36 from django.core.urlresolvers import reverse
37@@ -23,6 +22,7 @@
38 from maasserver.testing.factory import factory
39 from maasserver.utils.converters import json_load_bytes
40 from maasserver.utils.orm import reload_object
41+from netaddr import IPAddress
42 from testtools.matchers import Equals
43
44
45@@ -182,14 +182,10 @@
46 "The IP address %s is already in use." % ip_in_network).encode(
47 settings.DEFAULT_CHARSET)))
48
49- @skip(
50- "XXX bug=1539248 2015-01-28 blake_r: We need to take into account "
51- "all dynamic ranges inside the subnet.")
52 def test_POST_reserve_ip_address_rejects_ip_in_dynamic_range(self):
53- interface = self.make_interface()
54- net = interface.network
55- ip_in_network = interface.ip_range_low
56- response = self.post_reservation_request(net, ip_in_network)
57+ subnet = factory.make_ipv4_Subnet_with_IPRanges()
58+ ip = str(IPAddress(subnet.get_dynamic_maasipset().first))
59+ response = self.post_reservation_request(subnet, ip)
60 self.assertEqual(
61 http.client.FORBIDDEN, response.status_code, response.content)
62