Files
freeipa/ipatests/test_integration/test_server_del.py
T
Ganna Kaihorodova fd34877370 Add check for occuring traceback during uninstallation ipa master
Modified master uninstall task for traceback check
That approach give us wide coverage and multiple scenarious
to catch traceback during uninstallation process
Add verbose option to uninstall server and set to False

Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1480502

Reviewed-By: Tibor Dudlak <tdudlak@redhat.com>
Reviewed-By: Petr Cech <pcech@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2018-07-20 13:03:59 -04:00

312 lines
10 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 with verbose option for uninstallation
"""
check_master_removal(
self.client,
self.replica2.hostname,
ignore_topology_disconnect=True
)
# reinstall the replica
tasks.uninstall_master(self.replica2, verbose=True)
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
)