Merge lp:~allenap/maas/remove-ip-from-amt into lp:~maas-committers/maas/trunk

Proposed by Gavin Panella
Status: Merged
Approved by: Gavin Panella
Approved revision: no longer in the source branch.
Merged at revision: 1944
Proposed branch: lp:~allenap/maas/remove-ip-from-amt
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 109 lines (+45/-5)
4 files modified
etc/maas/templates/power/amt.template (+3/-4)
src/maasserver/power_parameters.py (+2/-1)
src/provisioningserver/tasks.py (+2/-0)
src/provisioningserver/tests/test_tasks.py (+38/-0)
To merge this branch: bzr merge lp:~allenap/maas/remove-ip-from-amt
Reviewer Review Type Date Requested Status
Julian Edwards (community) Approve
Review via email: mp+206057@code.launchpad.net

Commit message

Don't record IP address in AMT power parameters.

Instead use its MAC address to find it on the network because we cannot guarantee that the recorded IP address will not change.

Description of the change

This is based on Tycho's work in lp:~tycho-s/maas/remove-ip-from-amt.

To post a comment you must log in.
Revision history for this message
Julian Edwards (julian-edwards) wrote :

Mostly fine but a question and a nit! Setting to approved though as I don't want to block you.

[1]
49 + if 'mac_address' in kwargs:
50 + kwargs['ip_address'] = find_ip_via_arp(kwargs['mac_address'])

If ip_address is not set, then the template will blow up. Why would mac_address not be set in kwargs here?

[2]
You're using a bit of a testing antipattern by initialising sentinel.ip_address in the setup and then depending on it in the test assertions. I think it would be better if each test patched out this separately, despite the lack of factoring.

BTW I think we should use more sentinel, it's much easier on the eye that the factory.makeRandomXXX stuff!

review: Approve
Revision history for this message
Gavin Panella (allenap) wrote :

> Mostly fine but a question and a nit!  Setting to approved though as I don't
> want to block you.
>
> [1]
> 49      +    if 'mac_address' in kwargs:
> 50      +        kwargs['ip_address'] = find_ip_via_arp(kwargs['mac_address'])
>
> If ip_address is not set, then the template will blow up.  Why would
> mac_address not be set in kwargs here?

It's only in the power parameters for Etherwake and AMT.

>
> [2]
> You're using a bit of a testing antipattern by initialising
> sentinel.ip_address in the setup and then depending on it in the test
> assertions.  I think it would be better if each test patched out this
> separately, despite the lack of factoring.

Okay, I'll fix that up.

>
> BTW I think we should use more sentinel, it's much easier on the eye that the
> factory.makeRandomXXX stuff!

Indeed! It doesn't always work - sometimes we really do need quacking
ducks - but when it does it's concise and clear.

Revision history for this message
Julian Edwards (julian-edwards) wrote :

On Thursday 13 Feb 2014 10:11:09 you wrote:
> > Mostly fine but a question and a nit! Setting to approved though as I
> > don't want to block you.
> >
> > [1]
> > 49 + if 'mac_address' in kwargs:
> > 50 + kwargs['ip_address'] =
> > find_ip_via_arp(kwargs['mac_address'])
> >
> > If ip_address is not set, then the template will blow up. Why would
> > mac_address not be set in kwargs here?
>
> It's only in the power parameters for Etherwake and AMT.

Oh OK - the diff segment confused me more than it should have.

cheers.

Revision history for this message
MAAS Lander (maas-lander) wrote :
Download full text (18.1 KiB)

The attempt to merge lp:~allenap/maas/remove-ip-from-amt into lp:maas failed. Below is the output from the failed tests.

Ign http://security.ubuntu.com trusty-security InRelease
Hit http://security.ubuntu.com trusty-security Release.gpg
Hit http://security.ubuntu.com trusty-security Release
Ign http://nova.clouds.archive.ubuntu.com trusty InRelease
Ign http://nova.clouds.archive.ubuntu.com trusty-updates InRelease
Get:1 http://nova.clouds.archive.ubuntu.com trusty Release.gpg [933 B]
Hit http://nova.clouds.archive.ubuntu.com trusty-updates Release.gpg
Get:2 http://nova.clouds.archive.ubuntu.com trusty Release [58.5 kB]
Hit http://nova.clouds.archive.ubuntu.com trusty-updates Release
Hit http://security.ubuntu.com trusty-security/main Sources
Hit http://security.ubuntu.com trusty-security/universe Sources
Hit http://security.ubuntu.com trusty-security/main amd64 Packages
Hit http://security.ubuntu.com trusty-security/universe amd64 Packages
Hit http://security.ubuntu.com trusty-security/main Translation-en
Hit http://security.ubuntu.com trusty-security/universe Translation-en
Get:3 http://nova.clouds.archive.ubuntu.com trusty/main Sources [1,061 kB]
Ign http://security.ubuntu.com trusty-security/main Translation-en_US
Ign http://security.ubuntu.com trusty-security/universe Translation-en_US
Get:4 http://nova.clouds.archive.ubuntu.com trusty/universe Sources [6,414 kB]
Get:5 http://nova.clouds.archive.ubuntu.com trusty/main amd64 Packages [1,343 kB]
Get:6 http://nova.clouds.archive.ubuntu.com trusty/universe amd64 Packages [5,881 kB]
Get:7 http://nova.clouds.archive.ubuntu.com trusty/main Translation-en [760 kB]
Get:8 http://nova.clouds.archive.ubuntu.com trusty/universe Translation-en [4,055 kB]
Hit http://nova.clouds.archive.ubuntu.com trusty-updates/main Sources
Hit http://nova.clouds.archive.ubuntu.com trusty-updates/universe Sources
Hit http://nova.clouds.archive.ubuntu.com trusty-updates/main amd64 Packages
Hit http://nova.clouds.archive.ubuntu.com trusty-updates/universe amd64 Packages
Hit http://nova.clouds.archive.ubuntu.com trusty-updates/main Translation-en
Hit http://nova.clouds.archive.ubuntu.com trusty-updates/universe Translation-en
Ign http://nova.clouds.archive.ubuntu.com trusty/main Translation-en_US
Ign http://nova.clouds.archive.ubuntu.com trusty/universe Translation-en_US
Ign http://nova.clouds.archive.ubuntu.com trusty-updates/main Translation-en_US
Ign http://nova.clouds.archive.ubuntu.com trusty-updates/universe Translation-en_US
Fetched 19.6 MB in 7s (2,610 kB/s)
Reading package lists...
sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
     --no-install-recommends install apache2 bind9 bind9utils build-essential curl daemontools distro-info dnsutils firefox freeipmi-tools ipython isc-dhcp-common libjs-raphael libjs-yui3-full libjs-yui3-min libpq-dev make postgresql python-amqplib python-bzrlib python-celery python-convoy python-cssselect python-curtin python-dev python-distro-info python-django python-django-piston python-django-south python-djorm-ext-pgarray python-docutils python-formencode python-httplib2 python-jinja2 python-jsonschema python-lockfile python-lxml python-netaddr python-netifaces python-oauth python-...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'etc/maas/templates/power/amt.template'
--- etc/maas/templates/power/amt.template 2014-01-27 16:56:02 +0000
+++ etc/maas/templates/power/amt.template 2014-02-13 11:16:49 +0000
@@ -2,19 +2,18 @@
2# -*- mode: shell-script -*-2# -*- mode: shell-script -*-
3#3#
4# Control a system via amttool4# Control a system via amttool
5power_address='{{power_address}}'
6power_change='{{power_change}}'5power_change='{{power_change}}'
7power_pass='{{power_pass}}'6power_pass='{{power_pass}}'
87
9echo amt.template starting $*8echo amt.template starting $*
109
11echo power_address $power_address10echo ip_address $ip_address
12echo power_change $power_change11echo power_change $power_change
13echo power_pass $power_pass12echo power_pass $power_pass
1413
15amt() {14amt() {
16 echo running amttool "$power_address" $*15 echo running amttool "$ip_address" $*
17 AMT_PASSWORD="$power_pass" amttool "$power_address" "$@"16 AMT_PASSWORD="$power_pass" amttool "$ip_address" "$@"
18}17}
1918
20state() {19state() {
2120
=== modified file 'src/maasserver/power_parameters.py'
--- src/maasserver/power_parameters.py 2014-02-10 12:06:51 +0000
+++ src/maasserver/power_parameters.py 2014-02-13 11:16:49 +0000
@@ -199,7 +199,8 @@
199 {199 {
200 'name': 'amt',200 'name': 'amt',
201 'fields': [201 'fields': [
202 make_json_field('power_address', "Power address"),202 make_json_field(
203 'mac_address', "MAC Address", field_type='mac_address'),
203 make_json_field('power_pass', "Power password"),204 make_json_field('power_pass', "Power password"),
204 ],205 ],
205 },206 },
206207
=== modified file 'src/provisioningserver/tasks.py'
--- src/provisioningserver/tasks.py 2014-01-05 21:27:58 +0000
+++ src/provisioningserver/tasks.py 2014-02-13 11:16:49 +0000
@@ -134,6 +134,8 @@
134 assert power_change in ('on', 'off'), (134 assert power_change in ('on', 'off'), (
135 "Unknown power change keyword: %s" % power_change)135 "Unknown power change keyword: %s" % power_change)
136 kwargs['power_change'] = power_change136 kwargs['power_change'] = power_change
137 if 'mac_address' in kwargs:
138 kwargs['ip_address'] = find_ip_via_arp(kwargs['mac_address'])
137 try:139 try:
138 pa = PowerAction(power_type)140 pa = PowerAction(power_type)
139 pa.execute(**kwargs)141 pa.execute(**kwargs)
140142
=== modified file 'src/provisioningserver/tests/test_tasks.py'
--- src/provisioningserver/tests/test_tasks.py 2014-01-27 20:16:45 +0000
+++ src/provisioningserver/tests/test_tasks.py 2014-02-13 11:16:49 +0000
@@ -39,6 +39,7 @@
39from mock import (39from mock import (
40 ANY,40 ANY,
41 Mock,41 Mock,
42 sentinel,
42 )43 )
43from netaddr import IPNetwork44from netaddr import IPNetwork
44from provisioningserver import (45from provisioningserver import (
@@ -158,6 +159,43 @@
158 "ether_wake", mac=arbitrary_mac)159 "ether_wake", mac=arbitrary_mac)
159160
160161
162class TestPowerTasksResolveMACAddresses(PservTestCase):
163
164 def test_ip_address_is_looked_up_from_mac_address(self):
165 # Patch out PowerAction; we're just trying to demonstrate that
166 # it's invoked with an IP address even if one is not supplied.
167 PowerAction = self.patch(tasks, "PowerAction")
168 # find_ip_via_arp() is tested elsewhere; we just want to know
169 # that it has been used.
170 self.patch(tasks, "find_ip_via_arp").return_value = sentinel.ip_address
171 # PowerAction.execute() is passed an ip_address argument in
172 # addition to the mac_address argument when the latter is
173 # supplied.
174 tasks.issue_power_action(
175 sentinel.power_type, "on", mac_address=sentinel.mac_address)
176 PowerAction.assert_called_once_with(sentinel.power_type)
177 PowerAction.return_value.execute.assert_called_once_with(
178 power_change="on", mac_address=sentinel.mac_address,
179 ip_address=sentinel.ip_address)
180
181 def test_ip_address_is_looked_up_when_already_supplied(self):
182 # Patch out PowerAction; we're just trying to demonstrate that
183 # it's invoked with an IP address even if one is not supplied.
184 PowerAction = self.patch(tasks, "PowerAction")
185 # find_ip_via_arp() is tested elsewhere; we just want to know
186 # that it has been used.
187 self.patch(tasks, "find_ip_via_arp").return_value = sentinel.ip_address
188 # The ip_address argument passed to PowerAction.execute() is
189 # looked-up via find_ip_via_arp() even if an ip_address is
190 # passed into issue_power_action().
191 tasks.issue_power_action(
192 sentinel.power_type, "on", mac_address=sentinel.mac_address,
193 ip_address=sentinel.another_ip_address)
194 PowerAction.return_value.execute.assert_called_once_with(
195 power_change="on", mac_address=sentinel.mac_address,
196 ip_address=sentinel.ip_address)
197
198
161class TestDHCPTasks(PservTestCase):199class TestDHCPTasks(PservTestCase):
162200
163 resources = (201 resources = (