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
1=== modified file 'etc/maas/templates/power/amt.template'
2--- etc/maas/templates/power/amt.template 2014-01-27 16:56:02 +0000
3+++ etc/maas/templates/power/amt.template 2014-02-13 11:16:49 +0000
4@@ -2,19 +2,18 @@
5 # -*- mode: shell-script -*-
6 #
7 # Control a system via amttool
8-power_address='{{power_address}}'
9 power_change='{{power_change}}'
10 power_pass='{{power_pass}}'
11
12 echo amt.template starting $*
13
14-echo power_address $power_address
15+echo ip_address $ip_address
16 echo power_change $power_change
17 echo power_pass $power_pass
18
19 amt() {
20- echo running amttool "$power_address" $*
21- AMT_PASSWORD="$power_pass" amttool "$power_address" "$@"
22+ echo running amttool "$ip_address" $*
23+ AMT_PASSWORD="$power_pass" amttool "$ip_address" "$@"
24 }
25
26 state() {
27
28=== modified file 'src/maasserver/power_parameters.py'
29--- src/maasserver/power_parameters.py 2014-02-10 12:06:51 +0000
30+++ src/maasserver/power_parameters.py 2014-02-13 11:16:49 +0000
31@@ -199,7 +199,8 @@
32 {
33 'name': 'amt',
34 'fields': [
35- make_json_field('power_address', "Power address"),
36+ make_json_field(
37+ 'mac_address', "MAC Address", field_type='mac_address'),
38 make_json_field('power_pass', "Power password"),
39 ],
40 },
41
42=== modified file 'src/provisioningserver/tasks.py'
43--- src/provisioningserver/tasks.py 2014-01-05 21:27:58 +0000
44+++ src/provisioningserver/tasks.py 2014-02-13 11:16:49 +0000
45@@ -134,6 +134,8 @@
46 assert power_change in ('on', 'off'), (
47 "Unknown power change keyword: %s" % power_change)
48 kwargs['power_change'] = power_change
49+ if 'mac_address' in kwargs:
50+ kwargs['ip_address'] = find_ip_via_arp(kwargs['mac_address'])
51 try:
52 pa = PowerAction(power_type)
53 pa.execute(**kwargs)
54
55=== modified file 'src/provisioningserver/tests/test_tasks.py'
56--- src/provisioningserver/tests/test_tasks.py 2014-01-27 20:16:45 +0000
57+++ src/provisioningserver/tests/test_tasks.py 2014-02-13 11:16:49 +0000
58@@ -39,6 +39,7 @@
59 from mock import (
60 ANY,
61 Mock,
62+ sentinel,
63 )
64 from netaddr import IPNetwork
65 from provisioningserver import (
66@@ -158,6 +159,43 @@
67 "ether_wake", mac=arbitrary_mac)
68
69
70+class TestPowerTasksResolveMACAddresses(PservTestCase):
71+
72+ def test_ip_address_is_looked_up_from_mac_address(self):
73+ # Patch out PowerAction; we're just trying to demonstrate that
74+ # it's invoked with an IP address even if one is not supplied.
75+ PowerAction = self.patch(tasks, "PowerAction")
76+ # find_ip_via_arp() is tested elsewhere; we just want to know
77+ # that it has been used.
78+ self.patch(tasks, "find_ip_via_arp").return_value = sentinel.ip_address
79+ # PowerAction.execute() is passed an ip_address argument in
80+ # addition to the mac_address argument when the latter is
81+ # supplied.
82+ tasks.issue_power_action(
83+ sentinel.power_type, "on", mac_address=sentinel.mac_address)
84+ PowerAction.assert_called_once_with(sentinel.power_type)
85+ PowerAction.return_value.execute.assert_called_once_with(
86+ power_change="on", mac_address=sentinel.mac_address,
87+ ip_address=sentinel.ip_address)
88+
89+ def test_ip_address_is_looked_up_when_already_supplied(self):
90+ # Patch out PowerAction; we're just trying to demonstrate that
91+ # it's invoked with an IP address even if one is not supplied.
92+ PowerAction = self.patch(tasks, "PowerAction")
93+ # find_ip_via_arp() is tested elsewhere; we just want to know
94+ # that it has been used.
95+ self.patch(tasks, "find_ip_via_arp").return_value = sentinel.ip_address
96+ # The ip_address argument passed to PowerAction.execute() is
97+ # looked-up via find_ip_via_arp() even if an ip_address is
98+ # passed into issue_power_action().
99+ tasks.issue_power_action(
100+ sentinel.power_type, "on", mac_address=sentinel.mac_address,
101+ ip_address=sentinel.another_ip_address)
102+ PowerAction.return_value.execute.assert_called_once_with(
103+ power_change="on", mac_address=sentinel.mac_address,
104+ ip_address=sentinel.ip_address)
105+
106+
107 class TestDHCPTasks(PservTestCase):
108
109 resources = (