Merge lp:~rvb/maas/bug-1064210-dns into lp:~maas-committers/maas/trunk

Proposed by Raphaël Badin
Status: Merged
Approved by: Raphaël Badin
Approved revision: no longer in the source branch.
Merged at revision: 1233
Proposed branch: lp:~rvb/maas/bug-1064210-dns
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 88 lines (+38/-1)
2 files modified
src/maasserver/models/dhcplease.py (+10/-1)
src/maasserver/tests/test_dhcplease.py (+28/-0)
To merge this branch: bzr merge lp:~rvb/maas/bug-1064210-dns
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) Approve
Review via email: mp+128659@code.launchpad.net

Commit message

Strip out the domain part of the hostnames used to write out the DNS config files.

Description of the change

This branch is a band aid fix: strip out the domain part of the hostnames used to write out the DNS config files. Note that we can't really remove the domain part of the hostnames altogether because we need to be able to name nodes like 'hostname.local'.

To post a comment you must log in.
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Besides the miscellaneous code notes (see below), I do have to wonder where we use the domain name that's in Node.hostname at all. We also ignore the domain name in pxeconfig(), using the nodegroup's domain instead. Giving users the option to edit the domain name isn't much good if it doesn't go anywhere!

The only use I can find for the domain is in get_preseed_filenames, and I'm not sure it's essential there. So maybe we should either leave the domain name out of Node.hostname altogether, or make it optional (and by default either leave it out, or use the nodegroup's domain).

.

In src/maasserver/models/dhcplease.py, around l.30:

8 +def strip_out_domain(hostname):
9 + """Remove the domain part of a hostname, if any."""
10 + return hostname.split('.', 1)[0]

I'd omit the “out” from the name — just “strip” has a clear meaning in python, well established by convention. Saying “strip out” instead makes me think you may mean something different, such as returning the domain instead of the host part.

To follow the conventions even more, maybe the docstring could say “Return `hostname` with the domain part removed”?

.

In src/maasserver/models/dhcplease.py, l.144 or so:

28 - return dict(cursor.fetchall())
29 + return dict([
30 + (strip_out_domain(hostname), ip)
31 + for hostname, ip in cursor.fetchall()
32 + ])

You don't need the square brackets.

Jeroen

review: Approve
Revision history for this message
Raphaël Badin (rvb) wrote :

Thanks for the review!

> Besides the miscellaneous code notes (see below), I do have to wonder where we
> use the domain name that's in Node.hostname at all. We also ignore the domain
> name in pxeconfig(), using the nodegroup's domain instead. Giving users the
> option to edit the domain name isn't much good if it doesn't go anywhere!
>
> The only use I can find for the domain is in get_preseed_filenames, and I'm
> not sure it's essential there. So maybe we should either leave the domain
> name out of Node.hostname altogether, or make it optional (and by default
> either leave it out, or use the nodegroup's domain).

That would be the long term solution indeed.

But we need to cope with the mDNS model and in that case, we want to be able to name nodes like "hostname.local".

> 8 +def strip_out_domain(hostname):
> 9 + """Remove the domain part of a hostname, if any."""
> 10 + return hostname.split('.', 1)[0]
>
> I'd omit the “out” from the name — just “strip” has a clear meaning in python,
> well established by convention. Saying “strip out” instead makes me think you
> may mean something different, such as returning the domain instead of the host
> part.
>
> To follow the conventions even more, maybe the docstring could say “Return
> `hostname` with the domain part removed”?

Ok, done.

> In src/maasserver/models/dhcplease.py, l.144 or so:
>
> 28 - return dict(cursor.fetchall())
> 29 + return dict([
> 30 + (strip_out_domain(hostname), ip)
> 31 + for hostname, ip in cursor.fetchall()
> 32 + ])
>
> You don't need the square brackets.

Fixed.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/models/dhcplease.py'
2--- src/maasserver/models/dhcplease.py 2012-09-03 11:08:32 +0000
3+++ src/maasserver/models/dhcplease.py 2012-10-09 10:33:21 +0000
4@@ -27,6 +27,11 @@
5 from maasserver.models.cleansave import CleanSave
6
7
8+def strip_domain(hostname):
9+ """Return `hostname` with the domain part removed."""
10+ return hostname.split('.', 1)[0]
11+
12+
13 class DHCPLeaseManager(Manager):
14 """Utility that manages :class:`DHCPLease` objects.
15
16@@ -113,6 +118,7 @@
17 This will consider only the first interface (i.e. the first
18 MAC Address) associated with each node withing the given
19 `nodegroup`.
20+ If the hostnames contain a domain, it gets removed.
21 """
22 cursor = connection.cursor()
23 # The subquery fetches the IDs of the first MAC Address for
24@@ -135,7 +141,10 @@
25 AND mac.mac_address = lease.mac
26 AND lease.nodegroup_id = %s
27 """, (nodegroup.id, nodegroup.id))
28- return dict(cursor.fetchall())
29+ return dict(
30+ (strip_domain(hostname), ip)
31+ for hostname, ip in cursor.fetchall()
32+ )
33
34
35 class DHCPLease(CleanSave, Model):
36
37=== modified file 'src/maasserver/tests/test_dhcplease.py'
38--- src/maasserver/tests/test_dhcplease.py 2012-09-03 11:07:49 +0000
39+++ src/maasserver/tests/test_dhcplease.py 2012-10-09 10:33:21 +0000
40@@ -14,6 +14,7 @@
41
42 from maasserver import dns
43 from maasserver.models import DHCPLease
44+from maasserver.models.dhcplease import strip_domain
45 from maasserver.testing.factory import factory
46 from maasserver.testing.testcase import TestCase
47 from maasserver.utils import ignore_unused
48@@ -46,6 +47,20 @@
49 self.assertEqual(mac, lease.mac)
50
51
52+class TestUtitilies(TestCase):
53+
54+ def test_strip_domain(self):
55+ input_and_results = [
56+ ('name.domain', 'name'),
57+ ('name', 'name'),
58+ ('name.domain.what', 'name'),
59+ ('name..domain', 'name'),
60+ ]
61+ inputs = [input for input, _ in input_and_results]
62+ results = [result for _, result in input_and_results]
63+ self.assertEqual(results, map(strip_domain, inputs))
64+
65+
66 class TestDHCPLeaseManager(TestCase):
67 """Tests for :class:`DHCPLeaseManager`."""
68
69@@ -177,6 +192,19 @@
70 mapping = DHCPLease.objects.get_hostname_ip_mapping(nodegroup)
71 self.assertEqual(expected_mapping, mapping)
72
73+ def test_get_hostname_ip_mapping_strips_out_domain(self):
74+ nodegroup = factory.make_node_group()
75+ hostname = factory.make_name('hostname')
76+ domain = factory.make_name('domain')
77+ node = factory.make_node(
78+ nodegroup=nodegroup,
79+ hostname='%s.%s' % (hostname, domain))
80+ mac = factory.make_mac_address(node=node)
81+ lease = factory.make_dhcp_lease(
82+ nodegroup=nodegroup, mac=mac.mac_address)
83+ mapping = DHCPLease.objects.get_hostname_ip_mapping(nodegroup)
84+ self.assertEqual({hostname: lease.ip}, mapping)
85+
86 def test_get_hostname_ip_mapping_considers_only_first_mac(self):
87 nodegroup = factory.make_node_group()
88 node = factory.make_node(