~ubuntu-branches/ubuntu/raring/maas/raring

« back to all changes in this revision

Viewing changes to src/maasserver/tests/test_commands_config_master_dhcp.py

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez, Raphaël Badin, Julian Edwards, Andres Rodriguez, Gavin Panella, Jeroen Vermeulen
  • Date: 2012-11-13 14:58:21 UTC
  • mfrom: (1.2.2)
  • Revision ID: package-import@ubuntu.com-20121113145821-6jq53jtljo3qou80
Tags: 1.2+bzr1349+dfsg-0ubuntu1
* New upstream bugfix release. Fixes:
  - The DNS configuration is not created if maas-dns is installed after
    the DNS config has been set up (LP: #1085865).
  - IPMI detection ends up with power_address of 0.0.0.0 (LP: #1064224)
  - Main page slow to load with many nodes (LP: #1066775)
  - maas-cluster-controller doesn't have images for
    provisioning (LP: #1068843)
  - Filestorage is unique to each appserver instance (LP: #1069734)
  - import_pxe_files does not include quantal (LP: #1069850)
  - maas-cli nodes new incomplete documentation (LP: #1070522)
  - DNS forward zone ends up with nonsensical entries (LP: #1070765)
  - The hostname of a node can still be changed once the node is in
    use. (LP: #1070774)
  - The zone name (attached to a cluster controller) can still be changed
    when it contains in-use nodes and DNS is managed. (LP: #1070775)
  - Duplicated prefix in the url used by the CLI (LP: #1075597)
  - Not importing Quantal boot images (LP: #1077180)
  - Nodes are deployed with wrong domain name. (LP: #1078744)
  - src/maasserver/api.py calls request.data.getlist with a 'default'
    parameter. That parameter is not supported by Django 1.3. (LP: #1080673)
  - API calls that return a node leak private data (LP: #1034318)
  - MAAS hostnames should be 5 easily disambiguated characters (LP: #1058998)
  - URI in API description wrong when accessing machine via alternative
    interface. (LP: #1059645)
  - Oops when renaming nodegroup w/o interface (LP: #1077075)
  - Error in log when using 'Start node' button: MAASAPINotFound: No user
    data available for this node. (LP: #1069603)

[ Raphaël Badin ]
* debian/maas-dns.postinst: Call write_dns_config (LP: #1085865).
* debian/maas-dns.postinst: fix permissions and group ownership of
  file /etc/bind/maas/named.conf.rndc.maas. (LP: #1066935)

[ Julian Edwards ]
* debian/maas-region-controller.install: Remove installation of maas-gc; it
  is no longer required as upstream no longer stores files in the filesystem.
  (LP: #1069734)
* debian/maas-cluster-controller.postinst: Ensure that /etc/maas/pserv.yaml
  is updated when reconfiguring. (LP: #1081212)

[ Andres Rodriguez ]
* debian/control:
  - maas-cluster-controller Conflicts with tftpd-hpa (LP: #1076028)
  - maas-dns: Conflicts with dnsmasq
  - Drop Dependency on rabbitmq-server for maas-cluster-controller.
    (LP: #1072744)
  - Add conflicts/replaces for maas-region-controller to
    maas-cluster-controller.
* debian/maas-cluster-controller.config: If URL has been detected, add
  /MAAS if it doesn't contain it. This helps upgrades from versions where
  DEFAULT_MAAS_URL didn't use /MAAS.
* Install maas-import-pxe-files and related files with
  maas-cluster-controller, as well as configure tgtd, as
  maas-region-controller no longer stores images. Thanks to Jeroen
  Vermuelen.

[ Gavin Panella ]
* debian/extras/99-maas: squashfs image download is no longer needed.
* debian/maas-cluster-controller.install: maas-import-squashfs and its
  configuration file are no longer part of upstream.

[ Jeroen Vermeulen ]
* debian/maas-cluster-controller.maas-pserv.upstart: Source maas_cluster.conf
  before starting pserv (tftpd) process.
* debian/maas-cluster-controller.postinst: Duplicate CLUSTER_UUID setting
  to maas_cluster.conf.
* Bumped revision number to current 1.2 revision 1342 (requested by rvba).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2012 Canonical Ltd.  This software is licensed under the
2
 
# GNU Affero General Public License version 3 (see the file LICENSE).
3
 
 
4
 
"""Tests for the config_master_dhcp command."""
5
 
 
6
 
from __future__ import (
7
 
    absolute_import,
8
 
    print_function,
9
 
    unicode_literals,
10
 
    )
11
 
 
12
 
__metaclass__ = type
13
 
__all__ = []
14
 
 
15
 
from optparse import OptionValueError
16
 
 
17
 
from django.conf import settings
18
 
from django.core.management import call_command
19
 
from maasserver import dhcp
20
 
from maasserver.enum import NODEGROUPINTERFACE_MANAGEMENT
21
 
from maasserver.management.commands.config_master_dhcp import name_option
22
 
from maasserver.models import NodeGroup
23
 
from maasserver.testing.factory import factory
24
 
from maasserver.testing.testcase import TestCase
25
 
from testtools.matchers import MatchesStructure
26
 
 
27
 
 
28
 
def make_master_constants():
29
 
    """Return the standard, unchanging config for the master nodegroup."""
30
 
    return {
31
 
        'name': 'master',
32
 
    }
33
 
 
34
 
 
35
 
def make_dhcp_settings():
36
 
    """Return an arbitrary dict of DHCP settings."""
37
 
    network = factory.getRandomNetwork()
38
 
    return {
39
 
        'ip': factory.getRandomIPInNetwork(network),
40
 
        'interface': factory.make_name('interface'),
41
 
        'subnet_mask': str(network.netmask),
42
 
        'broadcast_ip': str(network.broadcast),
43
 
        'router_ip': factory.getRandomIPInNetwork(network),
44
 
        'ip_range_low': factory.getRandomIPInNetwork(network),
45
 
        'ip_range_high': factory.getRandomIPInNetwork(network),
46
 
    }
47
 
 
48
 
 
49
 
def make_cleared_dhcp_settings():
50
 
    """Return dict of cleared DHCP settings."""
51
 
    return dict.fromkeys(make_dhcp_settings())
52
 
 
53
 
 
54
 
class TestConfigMasterDHCP(TestCase):
55
 
 
56
 
    def setUp(self):
57
 
        super(TestConfigMasterDHCP, self).setUp()
58
 
        # Make sure any attempts to write a dhcp config do nothing.
59
 
        self.patch(dhcp, 'configure_dhcp')
60
 
        self.patch(settings, 'DHCP_CONNECT', True)
61
 
 
62
 
    def test_configures_dhcp_for_master_nodegroup(self):
63
 
        settings = make_dhcp_settings()
64
 
        call_command('config_master_dhcp', **settings)
65
 
        master = NodeGroup.objects.get(name='master')
66
 
        interface = master.get_managed_interface()
67
 
        self.assertThat(
68
 
            master,
69
 
            MatchesStructure.byEquality(**make_master_constants()))
70
 
        self.assertThat(
71
 
            interface, MatchesStructure.byEquality(
72
 
                management=NODEGROUPINTERFACE_MANAGEMENT.DHCP, **settings))
73
 
 
74
 
    def test_configures_dhcp_for_master_nodegroup_existing_master(self):
75
 
        management = NODEGROUPINTERFACE_MANAGEMENT.DHCP_AND_DNS
76
 
        master = factory.make_node_group(uuid='master', management=management)
77
 
        settings = make_dhcp_settings()
78
 
        call_command('config_master_dhcp', **settings)
79
 
        master = NodeGroup.objects.ensure_master()
80
 
        interface = master.get_managed_interface()
81
 
        self.assertThat(
82
 
            interface, MatchesStructure.byEquality(
83
 
                management=interface.management, **settings))
84
 
 
85
 
    def test_clears_dhcp_settings(self):
86
 
        master = NodeGroup.objects.ensure_master()
87
 
        for attribute, value in make_dhcp_settings().items():
88
 
            setattr(master, attribute, value)
89
 
        master.save()
90
 
        call_command('config_master_dhcp', clear=True)
91
 
        self.assertThat(
92
 
            master,
93
 
            MatchesStructure.byEquality(**make_master_constants()))
94
 
        self.assertIsNone(master.get_managed_interface())
95
 
 
96
 
    def test_does_not_accept_partial_dhcp_settings(self):
97
 
        settings = make_dhcp_settings()
98
 
        del settings['subnet_mask']
99
 
        self.assertRaises(
100
 
            OptionValueError,
101
 
            call_command, 'config_master_dhcp', **settings)
102
 
 
103
 
    def test_ignores_nonsense_settings_when_clear_is_passed(self):
104
 
        settings = make_dhcp_settings()
105
 
        call_command('config_master_dhcp', **settings)
106
 
        settings['subnet_mask'] = '@%$^&'
107
 
        settings['broadcast_ip'] = ''
108
 
        call_command('config_master_dhcp', clear=True, **settings)
109
 
        master = NodeGroup.objects.get(name='master')
110
 
        self.assertIsNone(master.get_managed_interface())
111
 
 
112
 
    def test_clear_conflicts_with_ensure(self):
113
 
        self.assertRaises(
114
 
            OptionValueError,
115
 
            call_command, 'config_master_dhcp', clear=True, ensure=True)
116
 
 
117
 
    def test_ensure_creates_master_nodegroup_without_dhcp_settings(self):
118
 
        call_command('config_master_dhcp', ensure=True)
119
 
        self.assertIsNone(
120
 
            NodeGroup.objects.get(name='master').get_managed_interface())
121
 
 
122
 
    def test_ensure_leaves_cleared_settings_cleared(self):
123
 
        call_command('config_master_dhcp', clear=True)
124
 
        call_command('config_master_dhcp', ensure=True)
125
 
        master = NodeGroup.objects.get(name='master')
126
 
        self.assertIsNone(master.get_managed_interface())
127
 
 
128
 
    def test_ensure_leaves_dhcp_settings_intact(self):
129
 
        settings = make_dhcp_settings()
130
 
        call_command('config_master_dhcp', **settings)
131
 
        call_command('config_master_dhcp', ensure=True)
132
 
        self.assertThat(
133
 
            NodeGroup.objects.get(name='master').get_managed_interface(),
134
 
            MatchesStructure.byEquality(**settings))
135
 
 
136
 
    def test_name_option_turns_dhcp_setting_name_into_option(self):
137
 
        self.assertEqual('--subnet-mask', name_option('subnet_mask'))
138
 
 
139
 
    def test_configures_dhcp(self):
140
 
        NodeGroup.objects.ensure_master()
141
 
        self.patch(dhcp, 'configure_dhcp')
142
 
        settings = make_dhcp_settings()
143
 
        call_command('config_master_dhcp', **settings)
144
 
        self.assertEqual(1, dhcp.configure_dhcp.call_count)