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
=== modified file 'src/maasserver/api/ip_addresses.py'
--- src/maasserver/api/ip_addresses.py 2016-06-07 14:55:13 +0000
+++ src/maasserver/api/ip_addresses.py 2016-07-28 23:41:52 +0000
@@ -24,6 +24,7 @@
24)24)
25from maasserver.exceptions import (25from maasserver.exceptions import (
26 MAASAPIBadRequest,26 MAASAPIBadRequest,
27 MAASAPIForbidden,
27 MAASAPIValidationError,28 MAASAPIValidationError,
28)29)
29from maasserver.forms import (30from maasserver.forms import (
@@ -72,6 +73,12 @@
72 :type domain: Domain73 :type domain: Domain
73 :raises StaticIPAddressExhaustion: If no IPs available.74 :raises StaticIPAddressExhaustion: If no IPs available.
74 """75 """
76 dynamic_range = subnet.get_dynamic_maasipset()
77 if ip_address is not None and ip_address in dynamic_range:
78 raise MAASAPIForbidden(
79 "IP address %s belongs to an existing dynamic range. To "
80 "reserve this IP address, a MAC address is required. (Create "
81 "a device instead.)" % ip_address)
75 if hostname is not None and hostname.find('.') > 0:82 if hostname is not None and hostname.find('.') > 0:
76 hostname, domain = hostname.split('.', 1)83 hostname, domain = hostname.split('.', 1)
77 domain = Domain.objects.get_domain_or_404(84 domain = Domain.objects.get_domain_or_404(
7885
=== modified file 'src/maasserver/api/tests/test_ipaddresses.py'
--- src/maasserver/api/tests/test_ipaddresses.py 2016-06-07 14:55:13 +0000
+++ src/maasserver/api/tests/test_ipaddresses.py 2016-07-28 23:41:52 +0000
@@ -6,7 +6,6 @@
6__all__ = []6__all__ = []
77
8import http.client8import http.client
9from unittest import skip
109
11from django.conf import settings10from django.conf import settings
12from django.core.urlresolvers import reverse11from django.core.urlresolvers import reverse
@@ -23,6 +22,7 @@
23from maasserver.testing.factory import factory22from maasserver.testing.factory import factory
24from maasserver.utils.converters import json_load_bytes23from maasserver.utils.converters import json_load_bytes
25from maasserver.utils.orm import reload_object24from maasserver.utils.orm import reload_object
25from netaddr import IPAddress
26from testtools.matchers import Equals26from testtools.matchers import Equals
2727
2828
@@ -182,14 +182,10 @@
182 "The IP address %s is already in use." % ip_in_network).encode(182 "The IP address %s is already in use." % ip_in_network).encode(
183 settings.DEFAULT_CHARSET)))183 settings.DEFAULT_CHARSET)))
184184
185 @skip(
186 "XXX bug=1539248 2015-01-28 blake_r: We need to take into account "
187 "all dynamic ranges inside the subnet.")
188 def test_POST_reserve_ip_address_rejects_ip_in_dynamic_range(self):185 def test_POST_reserve_ip_address_rejects_ip_in_dynamic_range(self):
189 interface = self.make_interface()186 subnet = factory.make_ipv4_Subnet_with_IPRanges()
190 net = interface.network187 ip = str(IPAddress(subnet.get_dynamic_maasipset().first))
191 ip_in_network = interface.ip_range_low188 response = self.post_reservation_request(subnet, ip)
192 response = self.post_reservation_request(net, ip_in_network)
193 self.assertEqual(189 self.assertEqual(
194 http.client.FORBIDDEN, response.status_code, response.content)190 http.client.FORBIDDEN, response.status_code, response.content)
195191