Пример #1
0
    def test__writes_config_and_calls_restart_when_no_current_state(self):
        write_file = self.patch_sudo_write_file()
        restart_service = self.patch_restartService()

        failover_peers = make_failover_peer_config()
        shared_network = make_shared_network()
        [shared_network] = fix_shared_networks_failover(
            [shared_network], [failover_peers]
        )
        host = make_host()
        interface = make_interface()
        global_dhcp_snippets = make_global_dhcp_snippets()
        expected_config = factory.make_name("config")
        self.patch_get_config().return_value = expected_config

        dhcp_service = dhcp.service_monitor.getServiceByName(
            self.server.dhcp_service
        )
        on = self.patch_autospec(dhcp_service, "on")

        omapi_key = factory.make_name("omapi_key")
        yield self.configure(
            omapi_key,
            [failover_peers],
            [shared_network],
            [host],
            [interface],
            global_dhcp_snippets,
        )

        self.assertThat(
            write_file,
            MockCallsMatch(
                call(
                    self.server.config_filename,
                    expected_config.encode("utf-8"),
                    mode=0o640,
                ),
                call(
                    self.server.interfaces_filename,
                    interface["name"].encode("utf-8"),
                    mode=0o640,
                ),
            ),
        )
        self.assertThat(on, MockCalledOnceWith())
        self.assertThat(
            restart_service, MockCalledOnceWith(self.server.dhcp_service)
        )
        self.assertEquals(
            dhcp._current_server_state[self.server.dhcp_service],
            dhcp.DHCPState(
                omapi_key,
                [failover_peers],
                [shared_network],
                [host],
                [interface],
                global_dhcp_snippets,
            ),
        )
Пример #2
0
    def test__writes_config_and_doesnt_use_omapi_when_was_off(self):
        write_file = self.patch_sudo_write_file()
        get_service_state = self.patch_getServiceState()
        get_service_state.return_value = ServiceState(
            SERVICE_STATE.OFF, "dead")
        restart_service = self.patch_restartService()
        ensure_service = self.patch_ensureService()
        update_hosts = self.patch_update_hosts()

        failover_peers = make_failover_peer_config()
        shared_network = make_shared_network()
        [shared_network] = fix_shared_networks_failover(
            [shared_network], [failover_peers])
        host = make_host(dhcp_snippets=[])
        interface = make_interface()
        global_dhcp_snippets = make_global_dhcp_snippets()
        expected_config = factory.make_name('config')
        self.patch_get_config().return_value = expected_config

        dhcp_service = dhcp.service_monitor.getServiceByName(
            self.server.dhcp_service)
        on = self.patch_autospec(dhcp_service, "on")

        omapi_key = factory.make_name('omapi_key')
        old_host = make_host(dhcp_snippets=[])
        old_state = dhcp.DHCPState(
            omapi_key, [failover_peers], [shared_network],
            [old_host], [interface], global_dhcp_snippets)
        dhcp._current_server_state[self.server.dhcp_service] = old_state

        yield self.configure(
            omapi_key,
            [failover_peers], [shared_network], [host], [interface],
            global_dhcp_snippets)

        self.assertThat(
            write_file,
            MockCallsMatch(
                call(
                    self.server.config_filename,
                    expected_config.encode("utf-8")),
                call(
                    self.server.interfaces_filename,
                    interface["name"].encode("utf-8")),
                ))
        self.assertThat(on, MockCalledOnceWith())
        self.assertThat(
            get_service_state,
            MockCalledOnceWith(self.server.dhcp_service, now=True))
        self.assertThat(
            restart_service, MockNotCalled())
        self.assertThat(
            ensure_service, MockCalledOnceWith(self.server.dhcp_service))
        self.assertThat(
            update_hosts, MockNotCalled())
        self.assertEquals(
            dhcp._current_server_state[self.server.dhcp_service],
            dhcp.DHCPState(
                omapi_key, [failover_peers], [shared_network],
                [host], [interface], global_dhcp_snippets))
Пример #3
0
 def make_args(self):
     omapi_key = factory.make_name("omapi_key")
     failover_peers = [make_failover_peer_config() for _ in range(3)]
     shared_networks = [make_shared_network() for _ in range(3)]
     shared_networks = fix_shared_networks_failover(shared_networks,
                                                    failover_peers)
     hosts = [make_host() for _ in range(3)]
     interfaces = [make_interface() for _ in range(3)]
     return (omapi_key, failover_peers, shared_networks, hosts, interfaces,
             make_global_dhcp_snippets())
Пример #4
0
 def test__converts_dhcp_restart_failure_to_CannotConfigureDHCP(self):
     self.patch_sudo_write_file()
     self.patch_sudo_delete_file()
     self.patch_restartService().side_effect = ServiceActionError()
     failover_peers = [make_failover_peer_config()]
     shared_networks = fix_shared_networks_failover(
         [make_shared_network()], failover_peers)
     with ExpectedException(exceptions.CannotConfigureDHCP):
         yield self.configure(
             factory.make_name('key'),
             failover_peers, shared_networks,
             [make_host()], [make_interface()], make_global_dhcp_snippets())
Пример #5
0
    def test__bad_config(self):
        omapi_key = factory.make_name("omapi_key")
        failover_peers = make_failover_peer_config()
        shared_network = make_shared_network()
        [shared_network] = fix_shared_networks_failover(
            [shared_network], [failover_peers]
        )
        host = make_host()
        interface = make_interface()
        global_dhcp_snippets = make_global_dhcp_snippets()
        dhcpd_error = (
            "Internet Systems Consortium DHCP Server 4.3.3\n"
            "Copyright 2004-2015 Internet Systems Consortium.\n"
            "All rights reserved.\n"
            "For info, please visit https://www.isc.org/software/dhcp/\n"
            "/tmp/maas-dhcpd-z5c7hfzt line 14: semicolon expected.\n"
            "ignore \n"
            "^\n"
            "Configuration file errors encountered -- exiting\n"
            "\n"
            "If you think you have received this message due to a bug rather\n"
            "than a configuration issue please read the section on submitting"
            "\n"
            "bugs on either our web page at www.isc.org or in the README file"
            "\n"
            "before submitting a bug.  These pages explain the proper\n"
            "process and the information we find helpful for debugging..\n"
            "\n"
            "exiting."
        )
        self.mock_call_and_check.side_effect = ExternalProcessError(
            returncode=1, cmd=("dhcpd",), output=dhcpd_error
        )

        self.assertEqual(
            [
                {
                    "error": "semicolon expected.",
                    "line_num": 14,
                    "line": "ignore ",
                    "position": "^",
                }
            ],
            self.validate(
                omapi_key,
                [failover_peers],
                [shared_network],
                [host],
                [interface],
                global_dhcp_snippets,
            ),
        )
Пример #6
0
 def test__does_not_log_ServiceActionError_when_restarting(self):
     self.patch_sudo_write_file()
     self.patch_restartService().side_effect = ServiceActionError()
     failover_peers = [make_failover_peer_config()]
     shared_networks = fix_shared_networks_failover([make_shared_network()],
                                                    failover_peers)
     with FakeLogger("maas") as logger:
         with ExpectedException(exceptions.CannotConfigureDHCP):
             yield self.configure(factory.make_name('key'), failover_peers,
                                  shared_networks, [make_host()],
                                  [make_interface()],
                                  make_global_dhcp_snippets())
     self.assertDocTestMatches("", logger.output)
Пример #7
0
    def test__good_config(self):
        omapi_key = factory.make_name('omapi_key')
        failover_peers = make_failover_peer_config()
        shared_network = make_shared_network()
        [shared_network] = fix_shared_networks_failover([shared_network],
                                                        [failover_peers])
        host = make_host()
        interface = make_interface()
        global_dhcp_snippets = make_global_dhcp_snippets()

        self.assertEqual(
            None,
            self.validate(omapi_key, [failover_peers], [shared_network],
                          [host], [interface], global_dhcp_snippets))
Пример #8
0
 def test_converts_failure_writing_file_to_CannotConfigureDHCP(self):
     self.patch_sudo_delete_file()
     self.patch_sudo_write_file().side_effect = ExternalProcessError(
         1, "sudo something")
     self.patch_restartService()
     failover_peers = [make_failover_peer_config()]
     shared_networks = fix_shared_networks_failover([make_shared_network()],
                                                    failover_peers)
     with ExpectedException(exceptions.CannotConfigureDHCP):
         yield self.configure(
             factory.make_name("key"),
             failover_peers,
             shared_networks,
             [make_host()],
             [make_interface()],
             make_global_dhcp_snippets(),
         )
Пример #9
0
    def test__bad_config(self):
        omapi_key = factory.make_name('omapi_key')
        failover_peers = make_failover_peer_config()
        shared_network = make_shared_network()
        [shared_network] = fix_shared_networks_failover(
            [shared_network], [failover_peers])
        host = make_host()
        interface = make_interface()
        global_dhcp_snippets = make_global_dhcp_snippets()
        dhcpd_error = (
            'Internet Systems Consortium DHCP Server 4.3.3\n'
            'Copyright 2004-2015 Internet Systems Consortium.\n'
            'All rights reserved.\n'
            'For info, please visit https://www.isc.org/software/dhcp/\n'
            '/tmp/maas-dhcpd-z5c7hfzt line 14: semicolon expected.\n'
            'ignore \n'
            '^\n'
            'Configuration file errors encountered -- exiting\n'
            '\n'
            'If you think you have received this message due to a bug rather\n'
            'than a configuration issue please read the section on submitting'
            '\n'
            'bugs on either our web page at www.isc.org or in the README file'
            '\n'
            'before submitting a bug.  These pages explain the proper\n'
            'process and the information we find helpful for debugging..\n'
            '\n'
            'exiting.'
        )
        self.patch(dhcp, 'call_and_check').side_effect = ExternalProcessError(
            returncode=1, cmd=("dhcpd",), output=dhcpd_error)

        self.assertEqual([{
            'error': 'semicolon expected.',
            'line_num': 14,
            'line': 'ignore ',
            'position': '^',
            }],
            self.validate(
                omapi_key, [failover_peers], [shared_network], [host],
                [interface], global_dhcp_snippets))
Пример #10
0
 def test__does_log_other_exceptions_when_restarting(self):
     self.patch_sudo_write_file()
     self.patch_restartService().side_effect = factory.make_exception(
         "DHCP is on strike today")
     failover_peers = [make_failover_peer_config()]
     shared_networks = fix_shared_networks_failover([make_shared_network()],
                                                    failover_peers)
     with FakeLogger("maas") as logger:
         with ExpectedException(exceptions.CannotConfigureDHCP):
             yield self.configure(
                 factory.make_name("key"),
                 failover_peers,
                 shared_networks,
                 [make_host()],
                 [make_interface()],
                 make_global_dhcp_snippets(),
             )
     self.assertDocTestMatches(
         "DHCPv... server failed to restart: "
         "DHCP is on strike today",
         logger.output,
     )
Пример #11
0
    def test__writes_config_and_uses_omapi_to_update_hosts(self):
        write_file = self.patch_sudo_write_file()
        get_service_state = self.patch_getServiceState()
        get_service_state.return_value = ServiceState(SERVICE_STATE.ON,
                                                      "running")
        restart_service = self.patch_restartService()
        ensure_service = self.patch_ensureService()
        update_hosts = self.patch_update_hosts()

        failover_peers = make_failover_peer_config()
        shared_network = make_shared_network()
        [shared_network] = fix_shared_networks_failover([shared_network],
                                                        [failover_peers])
        old_hosts = [make_host(dhcp_snippets=[]) for _ in range(3)]
        interface = make_interface()
        global_dhcp_snippets = make_global_dhcp_snippets()
        expected_config = factory.make_name("config")
        self.patch_get_config().return_value = expected_config

        dhcp_service = dhcp.service_monitor.getServiceByName(
            self.server.dhcp_service)
        on = self.patch_autospec(dhcp_service, "on")

        omapi_key = factory.make_name("omapi_key")
        old_state = dhcp.DHCPState(
            omapi_key,
            [failover_peers],
            [shared_network],
            old_hosts,
            [interface],
            global_dhcp_snippets,
        )
        dhcp._current_server_state[self.server.dhcp_service] = old_state

        new_hosts = copy.deepcopy(old_hosts)
        removed_host = new_hosts.pop()
        modified_host = new_hosts[0]
        modified_host["ip"] = factory.make_ip_address()
        added_host = make_host(dhcp_snippets=[])
        new_hosts.append(added_host)

        yield self.configure(
            omapi_key,
            [failover_peers],
            [shared_network],
            new_hosts,
            [interface],
            global_dhcp_snippets,
        )

        self.assertThat(
            write_file,
            MockCallsMatch(
                call(
                    self.server.config_filename,
                    expected_config.encode("utf-8"),
                    mode=0o640,
                ),
                call(
                    self.server.interfaces_filename,
                    interface["name"].encode("utf-8"),
                    mode=0o640,
                ),
            ),
        )
        self.assertThat(on, MockCalledOnceWith())
        self.assertThat(
            get_service_state,
            MockCalledOnceWith(self.server.dhcp_service, now=True),
        )
        self.assertThat(restart_service, MockNotCalled())
        self.assertThat(ensure_service,
                        MockCalledOnceWith(self.server.dhcp_service))
        self.assertThat(
            update_hosts,
            MockCalledOnceWith(ANY, [removed_host], [added_host],
                               [modified_host]),
        )
        self.assertEquals(
            dhcp._current_server_state[self.server.dhcp_service],
            dhcp.DHCPState(
                omapi_key,
                [failover_peers],
                [shared_network],
                new_hosts,
                [interface],
                global_dhcp_snippets,
            ),
        )
Пример #12
0
    def test_writes_config_and_restarts_when_omapi_fails(self):
        write_file = self.patch_sudo_write_file()
        get_service_state = self.patch_getServiceState()
        get_service_state.return_value = ServiceState(SERVICE_STATE.ON,
                                                      "running")
        restart_service = self.patch_restartService()
        ensure_service = self.patch_ensureService()
        update_hosts = self.patch_update_hosts()
        update_hosts.side_effect = factory.make_exception()

        failover_peers = make_failover_peer_config()
        shared_network = make_shared_network()
        [shared_network] = fix_shared_networks_failover([shared_network],
                                                        [failover_peers])
        old_hosts = [make_host(dhcp_snippets=[]) for _ in range(3)]
        interface = make_interface()
        global_dhcp_snippets = make_global_dhcp_snippets()
        expected_config = factory.make_name("config")
        self.patch_get_config().return_value = expected_config

        dhcp_service = dhcp.service_monitor.getServiceByName(
            self.server.dhcp_service)
        on = self.patch_autospec(dhcp_service, "on")

        omapi_key = factory.make_name("omapi_key")
        old_state = dhcp.DHCPState(
            omapi_key,
            [failover_peers],
            [shared_network],
            old_hosts,
            [interface],
            global_dhcp_snippets,
        )
        dhcp._current_server_state[self.server.dhcp_service] = old_state

        new_hosts = copy.deepcopy(old_hosts)
        removed_host = new_hosts.pop()
        modified_host = new_hosts[0]
        modified_host["ip"] = factory.make_ip_address(
            ipv6=self.server.dhcp_service == "DHCPv6")
        added_host = make_host(dhcp_snippets=[])
        new_hosts.append(added_host)

        with FakeLogger("maas") as logger:
            yield self.configure(
                omapi_key,
                [failover_peers],
                [shared_network],
                new_hosts,
                [interface],
                global_dhcp_snippets,
            )

        self.assertThat(
            write_file,
            MockCallsMatch(
                call(
                    self.server.config_filename,
                    expected_config.encode("utf-8"),
                    mode=0o640,
                ),
                call(
                    self.server.interfaces_filename,
                    interface["name"].encode("utf-8"),
                    mode=0o640,
                ),
            ),
        )
        self.assertThat(on, MockCalledOnceWith())
        self.assertThat(
            get_service_state,
            MockCalledOnceWith(self.server.dhcp_service, now=True),
        )
        self.assertThat(restart_service,
                        MockCalledOnceWith(self.server.dhcp_service))
        self.assertThat(ensure_service,
                        MockCalledOnceWith(self.server.dhcp_service))
        self.assertThat(
            update_hosts,
            MockCalledOnceWith(ANY, [removed_host], [added_host],
                               [modified_host]),
        )
        self.assertEqual(
            dhcp._current_server_state[self.server.dhcp_service],
            dhcp.DHCPState(
                omapi_key,
                [failover_peers],
                [shared_network],
                new_hosts,
                [interface],
                global_dhcp_snippets,
            ),
        )
        self.assertDocTestMatches(
            "Failed to update all host maps. Restarting DHCPv... "
            "service to ensure host maps are in-sync.",
            logger.output,
        )