Merge ~mpontillo/maas:ha-dns-servers--bug-1753493 into maas:master
- Git
- lp:~mpontillo/maas
- ha-dns-servers--bug-1753493
- Merge into master
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Mike Pontillo | ||||
Approved revision: | 04614560bd9c49c79fc2ff6c0799eb19ed336386 | ||||
Merge reported by: | MAAS Lander | ||||
Merged at revision: | not available | ||||
Proposed branch: | ~mpontillo/maas:ha-dns-servers--bug-1753493 | ||||
Merge into: | maas:master | ||||
Diff against target: |
105 lines (+41/-7) 2 files modified
src/maasserver/server_address.py (+12/-3) src/maasserver/tests/test_server_address.py (+29/-4) |
||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andres Rodriguez (community) | Approve | ||
MAAS Lander | Approve | ||
Alberto Donato (community) | Needs Fixing | ||
Review via email: mp+342979@code.launchpad.net |
Commit message
LP: #1753493 - Make region IP addresses consistent for HA.
Description of the change
Note: I backported this to MAAS 2.3 and verified that it does the right thing.
- 40ef157... by Mike Pontillo
-
Fix maasserver.
models. tests.test_ node:TestGetDef aultDNSServers.
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b ha-dns-servers--bug-1753493 lp:~mpontillo/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: SUCCESS
COMMIT: 40ef15783f0ad0a
Alberto Donato (ack) : | # |
Andres Rodriguez (andreserl) wrote : | # |
Mike I have some inline comments, but also I have a few questions.
Say we have this:
1. Scenario 1:
region/rack1 - 10.1
region/rack2 - 10.2
This would yield DNS such as 10.1, 10.2
2. Scenario 2:
region/rack1 - 10.1 | foalting IP on same subnet 10.3
region/rack2 - 10.2
This would yield to DNS be 10.3, 10.1, 10.2
3. Scenario 3 (isolated region/rack networks):
region/rack1 - 9.1
region/rack2 - 9.2
rackd.conf:maas_url in both points to: 10.1 and they have a proxy in the rack.
This would yield to DNS be 10.1 and not (9.1 nor 9.2). This should be the same for deployed machines.
Andres Rodriguez (andreserl) wrote : | # |
fwiw, in other words:
Do we always add what's in rackd.conf:maas_url as a DNS + whatever other IP addresses of the region controller in the same subnet ?
Andres Rodriguez (andreserl) : | # |
Andres Rodriguez (andreserl) wrote : | # |
Ok, so I've quickly tested this, and it is dropping the IP of maas_url. I have this:
region/rack1: 90.1 & 90.2 (the latter is a "vip")
- rackd.conf:
region/rack2: 90.3
- rackd:confmaas_url: http://
Before this change region/rackd2 have the following, which is missing 1 ip (90.3), but it is correctly using the value on rackd.conf:maas_url (which is the VIP 90.2)
ubuntu@node01:~$ cat /var/lib/
option domain-name-servers 10.90.90.2, 10.90.90.1;
option domain-name-servers 10.90.90.2, 10.90.90.1;
AFter this change it is correctly using the value of both *actual* regions, but it is dropping the VIP.
ubuntu@node01:~$ cat /var/lib/
option domain-name-servers 10.90.90.1, 10.90.90.3;
option domain-name-servers 10.90.90.1, 10.90.90.3;
This branch is regressing things even further.
Andres Rodriguez (andreserl) wrote : | # |
FWIW, what's missing here (90.2) is the IP where a rack is told the region is. So this should have:
1. The IP the rack controller knows is maas_url
2. The IP of all regions in the same subnet as maas_url IP, if exist.
But (1) should never be missing.
Mike Pontillo (mpontillo) wrote : | # |
This is why I wanted to split up this function or add an additional
'purpose' parameter. (But I didn't do that yet, because I wanted the
smallest possible fix to backport.) Unless we know a floating IP address is
going to be used for HA, and not a reverse proxy, we cannot assume the IP
address from maas_url can be used for DNS. The simplest solution is to not
return it, but only in certain cases.
We will still return the maas_url based URL if you only ask for one IP
address. If you want alternatives, that means you're asking for DNS
servers, so the maas_url could actually be wrong, and what you really want
is to use the maas_url as an example of a known reachable subnet, and
return all the region IPs in that subnet. That's what this branch does.
On Wed, Apr 11, 2018, 07:26 Andres Rodriguez <email address hidden>
wrote:
> FWIW, what's missing here (90.2) is the IP where a rack is told the region
> is. So this should have:
>
> 1. The IP the rack controller knows is maas_url
> 2. The IP of all regions in the same subnet as maas_url IP, if exist.
>
> But (1) should never be missing.
> --
> https:/
> You are the owner of ~mpontillo/
>
Andres Rodriguez (andreserl) wrote : | # |
Mike,
Lets go to the original design and the original intent of how this is supposed to work.
It does *not* matter whether this IP is a VIP or a real IP assigned to a machine that is on the same subnet, or on a routed subnet. The premise is that the IP needs to be routable for the machines.
As such, the design is that machines need to be told two things:
1. The IP of maas_url from the rack they boot from, because that's the only place where we know where the region is (regardless of whether this is a VIP or not).
2. The *other* region IP address that face the machines.
What's missing here is maas_url which should *always* be present regardless of it being a single region/rack, a multi-region in the same subnet, a multi-region with VIP's or a split region/rack with a routed l3.
Andres Rodriguez (andreserl) wrote : | # |
FWIW, this is the output of a deployed machine. The rackd.conf:
That tells the machines being deployed that;
1. The region is in 90.2
2. The metadata server is in 90.2
3. The proxy is in 90.2
4. The DNS server is in 90.2
As such, it doesn't matter if this IP is routed, on same subnet, a VIP or whatever. MAAS needs to be smart about this, because:
1. Machine facing rack controllers know where the region is (10.2).
2. MAAS knows the network model, and can determine that there's regions on the same subnet (10.1, 10.3)
Based on your changes, there's a lot of inconsistencies here provided that everything but DNS is correct (note that NTP is a different story, because NTP is based on rack connections).
ubuntu@
apt/apt.
cloud/cloud.
cloud/cloud.
cloud/cloud.
cloud/cloud.
cloud/cloud.
cloud/cloud.
cloud/cloud.
network/
network/
network/
ntp.conf:server 10.90.90.1 iburst
ntp.conf:server 10.90.90.3 iburst
resolv.
resolv.
Mike Pontillo (mpontillo) wrote : | # |
@ack, thanks for your comments; the reason a sorted() set wasn't used is because the first returned IP address was supposed to be the maas_url, so we only wanted a partial sort. I'll consider your feedback as I'm fixing up this branch though.
Mike Pontillo (mpontillo) wrote : | # |
Additional comments inline.
- e160aa7... by Mike Pontillo
-
Address review comments.
- 0461456... by Mike Pontillo
-
Clean up comments.
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b ha-dns-servers--bug-1753493 lp:~mpontillo/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: SUCCESS
COMMIT: 04614560bd9c49c
Andres Rodriguez (andreserl) wrote : | # |
questions inline.
Mike Pontillo (mpontillo) wrote : | # |
Responses inline.
Andres Rodriguez (andreserl) wrote : | # |
Testing went well. I did notice a weird issue but could have been due to manual modifucation of the code. ONce this lands I'll do another round of testing.
Preview Diff
1 | diff --git a/src/maasserver/server_address.py b/src/maasserver/server_address.py | |||
2 | index b543556..e786068 100644 | |||
3 | --- a/src/maasserver/server_address.py | |||
4 | +++ b/src/maasserver/server_address.py | |||
5 | @@ -110,17 +110,21 @@ def get_maas_facing_server_addresses( | |||
6 | 110 | raise UnresolvableHost("No address found for host %s." % hostname) | 110 | raise UnresolvableHost("No address found for host %s." % hostname) |
7 | 111 | if not link_local: | 111 | if not link_local: |
8 | 112 | addresses = [ip for ip in addresses if not ip.is_link_local()] | 112 | addresses = [ip for ip in addresses if not ip.is_link_local()] |
9 | 113 | # Addresses must be returned in a consistent order, with the set of IP | ||
10 | 114 | # addresses found from get_maas_facing_server_host() (i.e. maas_url) | ||
11 | 115 | # coming first. | ||
12 | 116 | addresses = sorted(addresses) | ||
13 | 113 | if include_alternates: | 117 | if include_alternates: |
14 | 114 | maas_id = get_maas_id() | 118 | maas_id = get_maas_id() |
15 | 115 | if maas_id is not None: | 119 | if maas_id is not None: |
16 | 116 | # Circular imports | 120 | # Circular imports |
17 | 117 | from maasserver.models import Subnet | 121 | from maasserver.models import Subnet |
18 | 118 | from maasserver.models import StaticIPAddress | 122 | from maasserver.models import StaticIPAddress |
20 | 119 | # Keep track of the regions already represented. | 123 | # Don't include more than one alternate IP address, per region, |
21 | 124 | # per address-family. | ||
22 | 120 | regions = set() | 125 | regions = set() |
23 | 121 | alternate_ips = [] | 126 | alternate_ips = [] |
24 | 122 | for ip in addresses: | 127 | for ip in addresses: |
25 | 123 | regions.add(maas_id + str(ip.version)) | ||
26 | 124 | if not ip.is_link_local(): | 128 | if not ip.is_link_local(): |
27 | 125 | # Since we only know that the IP address given in the MAAS | 129 | # Since we only know that the IP address given in the MAAS |
28 | 126 | # URL is reachable, alternates must be pulled from the same | 130 | # URL is reachable, alternates must be pulled from the same |
29 | @@ -149,5 +153,10 @@ def get_maas_facing_server_addresses( | |||
30 | 149 | else: | 153 | else: |
31 | 150 | regions.add(id_plus_family) | 154 | regions.add(id_plus_family) |
32 | 151 | alternate_ips.append(ipa) | 155 | alternate_ips.append(ipa) |
34 | 152 | addresses.extend(alternate_ips) | 156 | # Append non-duplicate region IP addresses to the list of |
35 | 157 | # addresses to return. We don't want duplicates, but we | ||
36 | 158 | # also need to preserve the existing order. | ||
37 | 159 | for address in alternate_ips: | ||
38 | 160 | if address not in addresses: | ||
39 | 161 | addresses.append(address) | ||
40 | 153 | return addresses | 162 | return addresses |
41 | diff --git a/src/maasserver/tests/test_server_address.py b/src/maasserver/tests/test_server_address.py | |||
42 | index ff7640c..57d8ade 100644 | |||
43 | --- a/src/maasserver/tests/test_server_address.py | |||
44 | +++ b/src/maasserver/tests/test_server_address.py | |||
45 | @@ -214,12 +214,36 @@ class TestGetMAASFacingServerAddresses(MAASServerTestCase): | |||
46 | 214 | region_ips, | 214 | region_ips, |
47 | 215 | Equals([ | 215 | Equals([ |
48 | 216 | IPAddress("192.168.0.254"), | 216 | IPAddress("192.168.0.254"), |
49 | 217 | IPAddress("192.168.0.1"), | ||
50 | 217 | IPAddress("192.168.0.2"), | 218 | IPAddress("192.168.0.2"), |
51 | 218 | IPAddress("192.168.0.4"), | 219 | IPAddress("192.168.0.4"), |
52 | 219 | ]) | 220 | ]) |
53 | 220 | ) | 221 | ) |
54 | 221 | 222 | ||
56 | 222 | def test__alternates_include_one_ip_address_per_region(self): | 223 | def test__alternates_do_not_contain_duplicate_for_maas_url_ip(self): |
57 | 224 | # See bug #1753493. (This tests to ensure we don't provide the same | ||
58 | 225 | # IP address from maas_url twice.) Also ensures that the IP address | ||
59 | 226 | # from maas_url comes first. | ||
60 | 227 | factory.make_Subnet(cidr='192.168.0.0/24') | ||
61 | 228 | maas_url = 'http://192.168.0.2/MAAS' | ||
62 | 229 | rack = factory.make_RackController(url=maas_url) | ||
63 | 230 | r1 = factory.make_RegionController() | ||
64 | 231 | factory.make_Interface(node=r1, ip='192.168.0.1') | ||
65 | 232 | r2 = factory.make_RegionController() | ||
66 | 233 | factory.make_Interface(node=r2, ip='192.168.0.2') | ||
67 | 234 | # Make the "current" region controller r1. | ||
68 | 235 | self.patch(server_address, 'get_maas_id').return_value = r1.system_id | ||
69 | 236 | region_ips = get_maas_facing_server_addresses( | ||
70 | 237 | rack, include_alternates=True) | ||
71 | 238 | self.assertThat( | ||
72 | 239 | region_ips, | ||
73 | 240 | Equals([ | ||
74 | 241 | IPAddress("192.168.0.2"), | ||
75 | 242 | IPAddress("192.168.0.1"), | ||
76 | 243 | ]) | ||
77 | 244 | ) | ||
78 | 245 | |||
79 | 246 | def test__alternates_include_one_ip_address_per_region_and_maas_url(self): | ||
80 | 223 | factory.make_Subnet(cidr='192.168.0.0/24') | 247 | factory.make_Subnet(cidr='192.168.0.0/24') |
81 | 224 | maas_url = 'http://192.168.0.254/MAAS' | 248 | maas_url = 'http://192.168.0.254/MAAS' |
82 | 225 | rack = factory.make_RackController(url=maas_url) | 249 | rack = factory.make_RackController(url=maas_url) |
83 | @@ -240,6 +264,7 @@ class TestGetMAASFacingServerAddresses(MAASServerTestCase): | |||
84 | 240 | region_ips, | 264 | region_ips, |
85 | 241 | Equals([ | 265 | Equals([ |
86 | 242 | IPAddress("192.168.0.254"), | 266 | IPAddress("192.168.0.254"), |
87 | 267 | IPAddress("192.168.0.1"), | ||
88 | 243 | IPAddress("192.168.0.2"), | 268 | IPAddress("192.168.0.2"), |
89 | 244 | IPAddress("192.168.0.4"), | 269 | IPAddress("192.168.0.4"), |
90 | 245 | ]) | 270 | ]) |
91 | @@ -296,12 +321,12 @@ class TestGetMAASFacingServerAddresses(MAASServerTestCase): | |||
92 | 296 | self.assertThat( | 321 | self.assertThat( |
93 | 297 | region_ips, | 322 | region_ips, |
94 | 298 | Equals([ | 323 | Equals([ |
95 | 299 | IPAddress("2001:db8::1"), | ||
96 | 300 | IPAddress("192.168.0.1"), | 324 | IPAddress("192.168.0.1"), |
99 | 301 | IPAddress("2001:db8::2"), | 325 | IPAddress("2001:db8::1"), |
98 | 302 | IPAddress("2001:db8::4"), | ||
100 | 303 | IPAddress("192.168.0.2"), | 326 | IPAddress("192.168.0.2"), |
101 | 304 | IPAddress("192.168.0.4"), | 327 | IPAddress("192.168.0.4"), |
102 | 328 | IPAddress("2001:db8::2"), | ||
103 | 329 | IPAddress("2001:db8::4"), | ||
104 | 305 | ]) | 330 | ]) |
105 | 306 | ) | 331 | ) |
106 | 307 | 332 |
UNIT TESTS
-b ha-dns-servers--bug-1753493 lp:~mpontillo/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: FAILED maas-ci- jenkins. internal: 8080/job/ maas/job/ branch- tester/ 2379/console d9749d30dacdebb f3fbbca182
LOG: http://
COMMIT: a566ab08c57e4eb