Merge lp:~mpontillo/maas/view-current-gateway--bug-1674807--2.1 into lp:maas/2.1

Proposed by Mike Pontillo
Status: Merged
Approved by: Mike Pontillo
Approved revision: no longer in the source branch.
Merged at revision: 5599
Proposed branch: lp:~mpontillo/maas/view-current-gateway--bug-1674807--2.1
Merge into: lp:maas/2.1
Diff against target: 188 lines (+123/-2)
4 files modified
docs/changelog.rst (+3/-1)
src/maasserver/api/machines.py (+18/-0)
src/maasserver/api/tests/test_enlistment.py (+2/-0)
src/maasserver/api/tests/test_machine.py (+100/-1)
To merge this branch: bzr merge lp:~mpontillo/maas/view-current-gateway--bug-1674807--2.1
Reviewer Review Type Date Requested Status
Mike Pontillo (community) Approve
Review via email: mp+321499@code.launchpad.net

Commit message

Allow viewing the currently-set default gateways for a machine using the API.

 * Merges revision 5895 from trunk to fix bug #1674807.

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

Self-approve backport.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'docs/changelog.rst'
2--- docs/changelog.rst 2017-03-30 17:18:49 +0000
3+++ docs/changelog.rst 2017-03-30 23:38:15 +0000
4@@ -8,7 +8,9 @@
5 Bugs fixed in this release
6 --------------------------
7
8-LP: ##1677507 Fix potential IP allocation from incorrect range.
9+LP: #1677507 Fix potential IP allocation from incorrect range.
10+
11+LP: #1674807 Fix missing default_gateways entry in machine API output.
12
13
14 2.1.5
15
16=== modified file 'src/maasserver/api/machines.py'
17--- src/maasserver/api/machines.py 2016-12-09 07:07:02 +0000
18+++ src/maasserver/api/machines.py 2017-03-30 23:38:15 +0000
19@@ -125,6 +125,7 @@
20 'node_type',
21 'node_type_name',
22 'special_filesystems',
23+ 'default_gateways',
24 )
25
26 # Limited set of machine fields exposed on the anonymous API.
27@@ -185,6 +186,23 @@
28 """The network interface which is used to boot over the network."""
29 return machine.get_boot_interface()
30
31+ @classmethod
32+ def default_gateways(handler, machine):
33+ """The default gateways that will be used for this machine."""
34+ gateways = machine.get_default_gateways()
35+ ipv4 = gateways.ipv4.gateway_ip if gateways.ipv4 is not None else None
36+ ipv6 = gateways.ipv6.gateway_ip if gateways.ipv6 is not None else None
37+ return {
38+ "ipv4": {
39+ "gateway_ip": ipv4,
40+ "link_id": machine.gateway_link_ipv4_id,
41+ },
42+ "ipv6": {
43+ "gateway_ip": ipv6,
44+ "link_id": machine.gateway_link_ipv6_id,
45+ }
46+ }
47+
48 @admin_method
49 def update(self, request, system_id):
50 """Update a specific Machine.
51
52=== modified file 'src/maasserver/api/tests/test_enlistment.py'
53--- src/maasserver/api/tests/test_enlistment.py 2016-10-20 19:41:25 +0000
54+++ src/maasserver/api/tests/test_enlistment.py 2017-03-30 23:38:15 +0000
55@@ -493,6 +493,7 @@
56 self.assertItemsEqual(
57 [
58 'hostname',
59+ 'default_gateways',
60 'domain',
61 'fqdn',
62 'owner',
63@@ -652,6 +653,7 @@
64 self.assertItemsEqual(
65 [
66 'hostname',
67+ 'default_gateways',
68 'domain',
69 'fqdn',
70 'owner',
71
72=== modified file 'src/maasserver/api/tests/test_machine.py'
73--- src/maasserver/api/tests/test_machine.py 2016-10-28 08:43:09 +0000
74+++ src/maasserver/api/tests/test_machine.py 2017-03-30 23:38:15 +0000
75@@ -1830,7 +1830,7 @@
76 "using status %d" % status)
77
78
79-class TestClearDefaultGateways(APITestCase.ForUser):
80+class TestDefaultGateways(APITestCase.ForUser):
81
82 def get_machine_uri(self, machine):
83 """Get the API URI for `machine`."""
84@@ -1873,6 +1873,105 @@
85 self.assertIsNone(machine.gateway_link_ipv4)
86 self.assertIsNone(machine.gateway_link_ipv6)
87
88+ def test__returns_null_gateway_if_no_explicit_gateway_exists(self):
89+ machine = factory.make_Node(
90+ owner=self.user, status=NODE_STATUS.ALLOCATED)
91+ interface = factory.make_Interface(
92+ INTERFACE_TYPE.PHYSICAL, node=machine)
93+ network_v4 = factory.make_ipv4_network()
94+ subnet_v4 = factory.make_Subnet(
95+ cidr=str(network_v4.cidr), vlan=interface.vlan, gateway_ip=None)
96+ factory.make_StaticIPAddress(
97+ alloc_type=IPADDRESS_TYPE.AUTO, ip="",
98+ subnet=subnet_v4, interface=interface)
99+ network_v6 = factory.make_ipv6_network()
100+ subnet_v6 = factory.make_Subnet(
101+ cidr=str(network_v6.cidr), vlan=interface.vlan, gateway_ip=None)
102+ factory.make_StaticIPAddress(
103+ alloc_type=IPADDRESS_TYPE.AUTO, ip="",
104+ subnet=subnet_v6, interface=interface)
105+ response = self.client.get(self.get_machine_uri(machine))
106+ self.assertEqual(
107+ http.client.OK, response.status_code, response.content)
108+ response = json_load_bytes(response.content)
109+ self.assertThat(response['default_gateways'], Equals({
110+ "ipv4": {
111+ "link_id": None,
112+ "gateway_ip": None,
113+ },
114+ "ipv6": {
115+ "link_id": None,
116+ "gateway_ip": None,
117+ },
118+ }))
119+
120+ def test__returns_effective_gateway_if_no_explicit_gateway_set(self):
121+ machine = factory.make_Node(
122+ owner=self.user, status=NODE_STATUS.ALLOCATED)
123+ interface = factory.make_Interface(
124+ INTERFACE_TYPE.PHYSICAL, node=machine)
125+ network_v4 = factory.make_ipv4_network()
126+ subnet_v4 = factory.make_Subnet(
127+ cidr=str(network_v4.cidr), vlan=interface.vlan)
128+ factory.make_StaticIPAddress(
129+ alloc_type=IPADDRESS_TYPE.AUTO, ip="",
130+ subnet=subnet_v4, interface=interface)
131+ network_v6 = factory.make_ipv6_network()
132+ subnet_v6 = factory.make_Subnet(
133+ cidr=str(network_v6.cidr), vlan=interface.vlan)
134+ factory.make_StaticIPAddress(
135+ alloc_type=IPADDRESS_TYPE.AUTO, ip="",
136+ subnet=subnet_v6, interface=interface)
137+ response = self.client.get(self.get_machine_uri(machine))
138+ self.assertEqual(
139+ http.client.OK, response.status_code, response.content)
140+ response = json_load_bytes(response.content)
141+ self.assertThat(response['default_gateways'], Equals({
142+ "ipv4": {
143+ "link_id": None,
144+ "gateway_ip": str(subnet_v4.gateway_ip),
145+ },
146+ "ipv6": {
147+ "link_id": None,
148+ "gateway_ip": str(subnet_v6.gateway_ip),
149+ },
150+ }))
151+
152+ def test__returns_links_if_set(self):
153+ machine = factory.make_Node(
154+ owner=self.user, status=NODE_STATUS.ALLOCATED)
155+ interface = factory.make_Interface(
156+ INTERFACE_TYPE.PHYSICAL, node=machine)
157+ network_v4 = factory.make_ipv4_network()
158+ subnet_v4 = factory.make_Subnet(
159+ cidr=str(network_v4.cidr), vlan=interface.vlan)
160+ link_v4 = factory.make_StaticIPAddress(
161+ alloc_type=IPADDRESS_TYPE.AUTO, ip="",
162+ subnet=subnet_v4, interface=interface)
163+ machine.gateway_link_ipv4 = link_v4
164+ network_v6 = factory.make_ipv6_network()
165+ subnet_v6 = factory.make_Subnet(
166+ cidr=str(network_v6.cidr), vlan=interface.vlan)
167+ link_v6 = factory.make_StaticIPAddress(
168+ alloc_type=IPADDRESS_TYPE.AUTO, ip="",
169+ subnet=subnet_v6, interface=interface)
170+ machine.gateway_link_ipv6 = link_v6
171+ machine.save()
172+ response = self.client.get(self.get_machine_uri(machine))
173+ self.assertEqual(
174+ http.client.OK, response.status_code, response.content)
175+ response = json_load_bytes(response.content)
176+ self.assertThat(response['default_gateways'], Equals({
177+ "ipv4": {
178+ "link_id": link_v4.id,
179+ "gateway_ip": str(subnet_v4.gateway_ip),
180+ },
181+ "ipv6": {
182+ "link_id": link_v6.id,
183+ "gateway_ip": str(subnet_v6.gateway_ip),
184+ },
185+ }))
186+
187
188 class TestGetCurtinConfig(APITestCase.ForUser):
189

Subscribers

People subscribed via source and target branches

to all changes: