freeipa/ipatests/test_integration/test_server_del.py
Petr Vobornik 60e992ca56 Fix test_server_del::TestLastServices
The reason why the test started to fail is probably commit be3ad1e where the checks
were reordered. TestLastServices relies on execution of tests in a specific order.
So it fails given that checks were changed but tests weren't.

Given that master is installed with DNS and CA and replica with anything and given
that checks in server-del command are in order: DNS, DNSSec, CA, KRA then the test
should be something like:
* install master (with DNS, CA)
* install replica
* test test_removal_of_master_raises_error_about_last_dns
* test_install_dns_on_replica1_and_dnssec_on_master (installing DNS and
  DNSSec will allow DNSSec check)
* test_removal_of_master_raises_error_about_dnssec
* test_disable_dnssec_on_master (will allow CA check)
* test_removal_of_master_raises_error_about_last_ca
* test_forced_removal_of_master

https://pagure.io/freeipa/issue/7517

Signed-off-by: Petr Vobornik <pvoborni@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2018-05-15 14:15:34 -04:00

312 lines
9.9 KiB
Python

#
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
#
from itertools import permutations
from ipatests.test_integration.base import IntegrationTest
from ipatests.pytest_plugins.integration import tasks
from ipalib.constants import DOMAIN_LEVEL_1, DOMAIN_SUFFIX_NAME, CA_SUFFIX_NAME
REMOVAL_ERR_TEMPLATE = ("Removal of '{hostname}' leads to disconnected "
"topology in suffix '{suffix}'")
def check_master_removal(host, hostname_to_remove,
force=False,
ignore_topology_disconnect=False,
ignore_last_of_role=False):
result = tasks.run_server_del(
host,
hostname_to_remove,
force=force,
ignore_topology_disconnect=ignore_topology_disconnect,
ignore_last_of_role=ignore_last_of_role)
assert result.returncode == 0
if force:
assert ("Forcing removal of {hostname}".format(
hostname=hostname_to_remove) in result.stderr_text)
if ignore_topology_disconnect:
assert "Ignoring topology connectivity errors." in result.stderr_text
if ignore_last_of_role:
assert ("Ignoring these warnings and proceeding with removal" in
result.stderr_text)
tasks.assert_error(
host.run_command(
['ipa', 'server-show', hostname_to_remove], raiseonerr=False
),
"{}: server not found".format(hostname_to_remove),
returncode=2
)
def check_removal_disconnects_topology(
host, hostname_to_remove,
affected_suffixes=(DOMAIN_SUFFIX_NAME,)):
result = tasks.run_server_del(host, hostname_to_remove)
assert len(affected_suffixes) <= 2
err_messages_by_suffix = {
CA_SUFFIX_NAME: REMOVAL_ERR_TEMPLATE.format(
hostname=hostname_to_remove,
suffix=CA_SUFFIX_NAME
),
DOMAIN_SUFFIX_NAME: REMOVAL_ERR_TEMPLATE.format(
hostname=hostname_to_remove,
suffix=DOMAIN_SUFFIX_NAME
)
}
for suffix in err_messages_by_suffix:
if suffix in affected_suffixes:
tasks.assert_error(
result, err_messages_by_suffix[suffix], returncode=1)
else:
assert err_messages_by_suffix[suffix] not in result.stderr_text
class ServerDelBase(IntegrationTest):
num_replicas = 2
num_clients = 1
domain_level = DOMAIN_LEVEL_1
topology = 'star'
@classmethod
def install(cls, mh):
super(ServerDelBase, cls).install(mh)
cls.client = cls.clients[0]
cls.replica1 = cls.replicas[0]
cls.replica2 = cls.replicas[1]
class TestServerDel(ServerDelBase):
@classmethod
def install(cls, mh):
super(TestServerDel, cls).install(mh)
# prepare topologysegments for negative test cases
# it should look like this for DOMAIN_SUFFIX_NAME:
# master
# /
# /
# /
# replica1------- replica2
# and like this for CA_SUFFIX_NAME
# master
# \
# \
# \
# replica1------- replica2
tasks.create_segment(cls.client, cls.replica1, cls.replica2)
tasks.create_segment(cls.client, cls.replica1, cls.replica2,
suffix=CA_SUFFIX_NAME)
# try to delete all relevant segment connecting master and replica1/2
segment_name_fmt = '{p[0].hostname}-to-{p[1].hostname}'
for domain_pair in permutations((cls.master, cls.replica2)):
tasks.destroy_segment(
cls.client, segment_name_fmt.format(p=domain_pair))
for ca_pair in permutations((cls.master, cls.replica1)):
tasks.destroy_segment(
cls.client, segment_name_fmt.format(p=ca_pair),
suffix=CA_SUFFIX_NAME)
def test_removal_of_nonexistent_master_raises_error(self):
"""
tests that removal of non-existent master raises an error
"""
hostname = u'bogus-master.bogus.domain'
err_message = "{}: server not found".format(hostname)
tasks.assert_error(
tasks.run_server_del(self.client, hostname),
err_message,
returncode=2
)
def test_forced_removal_of_nonexistent_master(self):
"""
tests that removal of non-existent master with '--force' does not raise
an error
"""
hostname = u'bogus-master.bogus.domain'
result = tasks.run_server_del(self.client, hostname, force=True)
assert result.returncode == 0
assert ('Deleted IPA server "{}"'.format(hostname) in
result.stdout_text)
assert ("Server has already been deleted" in result.stderr_text)
def test_removal_of_replica1_disconnects_domain_topology(self):
"""
tests that given the used topology, attempted removal of replica1 fails
with disconnected DOMAIN topology but not CA
"""
check_removal_disconnects_topology(
self.client,
self.replica1.hostname,
affected_suffixes=(DOMAIN_SUFFIX_NAME,)
)
def test_removal_of_replica2_disconnects_ca_topology(self):
"""
tests that given the used topology, attempted removal of replica2 fails
with disconnected CA topology but not DOMAIN
"""
check_removal_disconnects_topology(
self.client,
self.replica2.hostname,
affected_suffixes=(CA_SUFFIX_NAME,)
)
def test_ignore_topology_disconnect_replica1(self):
"""
tests that removal of replica1 with '--ignore-topology-disconnect'
destroys master for good
"""
check_master_removal(
self.client,
self.replica1.hostname,
ignore_topology_disconnect=True
)
# reinstall the replica
tasks.uninstall_master(self.replica1)
tasks.install_replica(self.master, self.replica1, setup_ca=True)
def test_ignore_topology_disconnect_replica2(self):
"""
tests that removal of replica2 with '--ignore-topology-disconnect'
destroys master for good
"""
check_master_removal(
self.client,
self.replica2.hostname,
ignore_topology_disconnect=True
)
# reinstall the replica
tasks.uninstall_master(self.replica2)
tasks.install_replica(self.master, self.replica2, setup_ca=True)
def test_removal_of_master_disconnects_both_topologies(self):
"""
tests that master removal will now raise errors in both suffixes.
"""
check_removal_disconnects_topology(
self.client,
self.master.hostname,
affected_suffixes=(CA_SUFFIX_NAME, DOMAIN_SUFFIX_NAME)
)
def test_removal_of_replica1(self):
"""
tests the removal of replica1 which should now pass without errors
"""
check_master_removal(
self.client,
self.replica1.hostname
)
def test_removal_of_replica2(self):
"""
tests the removal of replica2 which should now pass without errors
"""
check_master_removal(
self.client,
self.replica2.hostname
)
class TestLastServices(ServerDelBase):
"""
Test the checks for last services during server-del and their bypassing
using when forcing the removal
"""
num_replicas = 1
domain_level = DOMAIN_LEVEL_1
topology = 'line'
@classmethod
def install(cls, mh):
tasks.install_topo(
cls.topology, cls.master, cls.replicas, [],
domain_level=cls.domain_level, setup_replica_cas=False)
def test_removal_of_master_raises_error_about_last_dns(self):
"""
Now server-del should complain about the removal of last DNS server
"""
tasks.assert_error(
tasks.run_server_del(self.replicas[0], self.master.hostname),
"Deleting this server will leave your installation "
"without a DNS.",
1
)
def test_install_dns_on_replica1_and_dnssec_on_master(self):
"""
install DNS server on replica and DNSSec on master
"""
tasks.install_dns(self.replicas[0])
args = [
"ipa-dns-install",
"--dnssec-master",
"--forwarder", self.master.config.dns_forwarder,
"-U",
]
self.master.run_command(args)
def test_removal_of_master_raises_error_about_dnssec(self):
tasks.assert_error(
tasks.run_server_del(self.replicas[0], self.master.hostname),
"Replica is active DNSSEC key master. Uninstall "
"could break your DNS system. Please disable or replace "
"DNSSEC key master first.",
1
)
def test_disable_dnssec_on_master(self):
"""
Disable DNSSec master so that it is not tested anymore. Normal way
would be to move the DNSSec master to replica, but that is tested in
DNSSec tests.
"""
args = [
"ipa-dns-install",
"--disable-dnssec-master",
"--forwarder", self.master.config.dns_forwarder,
"--force",
"-U",
]
self.master.run_command(args)
def test_removal_of_master_raises_error_about_last_ca(self):
"""
test that removal of master fails on the last
"""
tasks.assert_error(
tasks.run_server_del(self.replicas[0], self.master.hostname),
"Deleting this server is not allowed as it would leave your "
"installation without a CA.",
1
)
def test_forced_removal_of_master(self):
"""
Tests that we can still force remove the master using
'--ignore-last-of-role'
"""
check_master_removal(
self.replicas[0], self.master.hostname,
ignore_last_of_role=True
)