def test_requires_restart_returns_True_when_omapi_key_different(self): ( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets, ) = self.make_args() state = dhcp.DHCPState( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets, ) new_state = dhcp.DHCPState( factory.make_name("new_omapi_key"), copy.deepcopy(failover_peers), copy.deepcopy(shared_networks), copy.deepcopy(hosts), copy.deepcopy(interfaces), copy.deepcopy(global_dhcp_snippets), ) self.assertTrue(new_state.requires_restart(state))
def test_host_diff_returns_removal_added_and_modify(self): ( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets, ) = self.make_args() state = dhcp.DHCPState( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets, ) changed_hosts = copy.deepcopy(hosts) removed_host = changed_hosts.pop() modified_host = changed_hosts[0] modified_host["ip"] = factory.make_ip_address() added_host = make_host() changed_hosts.append(added_host) new_state = dhcp.DHCPState( omapi_key, copy.deepcopy(failover_peers), copy.deepcopy(shared_networks), changed_hosts, copy.deepcopy(interfaces), copy.deepcopy(global_dhcp_snippets), ) self.assertEqual( ([removed_host], [added_host], [modified_host]), new_state.host_diff(state), )
def test_requires_restart_returns_False_when_hosts_different(self): ( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets, ) = self.make_args() state = dhcp.DHCPState( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets, ) changed_hosts = copy.deepcopy(hosts) changed_hosts.append(make_host(dhcp_snippets=[])) new_state = dhcp.DHCPState( omapi_key, copy.deepcopy(failover_peers), copy.deepcopy(shared_networks), changed_hosts, copy.deepcopy(interfaces), copy.deepcopy(global_dhcp_snippets), ) self.assertFalse(new_state.requires_restart(state))
def test_requires_restart_True_when_hosts_dhcp_snippets_diff(self): ( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets, ) = self.make_args() state = dhcp.DHCPState( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets, ) changed_hosts = copy.deepcopy(hosts) for host in changed_hosts: host["dhcp_snippets"] = make_host_dhcp_snippets(allow_empty=False) new_state = dhcp.DHCPState( omapi_key, copy.deepcopy(failover_peers), copy.deepcopy(shared_networks), changed_hosts, copy.deepcopy(interfaces), copy.deepcopy(global_dhcp_snippets), ) self.assertTrue(new_state.requires_restart(state))
def test_requires_restart_returns_False_when_hosts_are_ipv6_and_server_is_ipv6( self, ): ( omapi_key, failover_peers, shared_networks, _, interfaces, global_dhcp_snippets, ) = self.make_args() state = dhcp.DHCPState( omapi_key, failover_peers, shared_networks, [], interfaces, global_dhcp_snippets, ) new_hosts = [make_host(dhcp_snippets=[], ipv6=True) for _ in range(3)] new_state = dhcp.DHCPState( omapi_key, copy.deepcopy(failover_peers), copy.deepcopy(shared_networks), new_hosts, copy.deepcopy(interfaces), copy.deepcopy(global_dhcp_snippets), ) self.assertFalse( new_state.requires_restart(state, is_dhcpv6_server=True))
def test_requires_restart_returns_False_when_all_the_same(self): ( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets, ) = self.make_args() state = dhcp.DHCPState( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets, ) new_state = dhcp.DHCPState( omapi_key, copy.deepcopy(failover_peers), copy.deepcopy(shared_networks), copy.deepcopy(hosts), copy.deepcopy(interfaces), copy.deepcopy(global_dhcp_snippets), ) self.assertFalse(new_state.requires_restart(state))
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))
def test_new_sorts_properties(self): ( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets, ) = self.make_args() state = dhcp.DHCPState( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets, ) self.assertThat( state, MatchesStructure.byEquality( omapi_key=omapi_key, failover_peers=sorted(failover_peers, key=itemgetter("name")), shared_networks=sorted(shared_networks, key=itemgetter("name")), hosts={host["mac"]: host for host in hosts}, interfaces=sorted( [interface["name"] for interface in interfaces]), global_dhcp_snippets=sorted(global_dhcp_snippets, key=itemgetter("name")), ), )
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, ), )
def test_requires_restart_True_when_subnet_dhcp_snippets_diff(self): (omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets) = self.make_args() state = dhcp.DHCPState(omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets) changed_shared_networks = copy.deepcopy(shared_networks) for shared_network in changed_shared_networks: for subnet in shared_network['subnets']: subnet['dhcp_snippets'] = (make_subnet_dhcp_snippets( allow_empty=False)) new_state = dhcp.DHCPState(omapi_key, copy.deepcopy(failover_peers), changed_shared_networks, copy.deepcopy(hosts), copy.deepcopy(interfaces), copy.deepcopy(global_dhcp_snippets)) self.assertTrue(new_state.requires_restart(state))
def test_get_config_returns_config_and_calls_with_params(self): mock_get_config = self.patch_autospec(dhcp, 'get_config') mock_get_config.return_value = sentinel.config (omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets) = self.make_args() state = dhcp.DHCPState( omapi_key, failover_peers, shared_networks, hosts, interfaces, global_dhcp_snippets) server = Mock() self.assertEqual( (sentinel.config, " ".join(state.interfaces)), state.get_config(server)) self.assertThat( mock_get_config, MockCalledOnceWith( server.template_basename, omapi_key=omapi_key, ipv6=ANY, failover_peers=state.failover_peers, shared_networks=state.shared_networks, hosts=sorted(state.hosts.values(), key=itemgetter("host")), global_dhcp_snippets=sorted( global_dhcp_snippets, key=itemgetter("name"))))
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, ), )
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, )