ipatests: allow AD hosts to be placed in separate domain config objects

Tests for AD trust can use three types (roles) of AD machines:
forest root, subdomain and tree domain.
All those machines were placed in one domain object of multihost configuration,
though they all have different domain names.
This is bad as we can not use domain attributes provided by multihost plugin
like host.domain.name and host.domain.basedn and others and need to reimplement
them, evaluating domain name from host.hostname.
And if we accidently used those properties it would lead to difficult to locate
errors (we would use same domain name for all AD hosts).
I modified multihost fixture function mh() to allow creating several AD domains.
As multihost plugin does not support requesting multiple domains with the same type,
I had to introduce new domain types: AD_SUBDOMAIN and AD_TREEDOMAIN.
Also there was a error in mh() which forced user to provide all three AD
machines when only one was needed (value from test class property num_ad_domains
was applied to subdomains and treedomains requirement).
I changed this behavior and now additional AD machines are specified with
properties num_ad_subdomains and num_ad_treedomains.

Related to https://pagure.io/freeipa/issue/7889

Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
Sergey Orlov
2019-03-27 17:24:26 +01:00
committed by Rob Crittenden
parent 03e2693a7d
commit 35a4642ad0
4 changed files with 132 additions and 16 deletions

View File

@@ -218,11 +218,17 @@ def mh(request, class_integration_logs):
for _i in range(cls.num_ad_domains):
domain_descriptions.append({
'type': 'AD',
'hosts': {
'ad': 1,
'ad_subdomain': cls.num_ad_domains,
'ad_treedomain': cls.num_ad_domains,
}
'hosts': {'ad': 1}
})
for _i in range(cls.num_ad_subdomains):
domain_descriptions.append({
'type': 'AD_SUBDOMAIN',
'hosts': {'ad_subdomain': 1}
})
for _i in range(cls.num_ad_treedomains):
domain_descriptions.append({
'type': 'AD_TREEDOMAIN',
'hosts': {'ad_treedomain': 1}
})
mh = make_multihost_fixture(
@@ -236,6 +242,17 @@ def mh(request, class_integration_logs):
[mh.master] = mh.domain.hosts_by_role('master')
mh.replicas = mh.domain.hosts_by_role('replica')
mh.clients = mh.domain.hosts_by_role('client')
ad_domains = mh.config.ad_domains
if ad_domains:
mh.ads = []
for domain in ad_domains:
mh.ads.extend(domain.hosts_by_role('ad'))
mh.ad_subdomains = []
for domain in ad_domains:
mh.ad_subdomains.extend(domain.hosts_by_role('ad_subdomain'))
mh.ad_treedomains = []
for domain in ad_domains:
mh.ad_treedomains.extend(domain.hosts_by_role('ad_treedomain'))
cls.logs_to_collect = class_integration_logs
@@ -276,6 +293,10 @@ def setup_class(cls, mh):
cls.replicas = mh.replicas
cls.clients = mh.clients
cls.ad_domains = mh.config.ad_domains
if cls.ad_domains:
cls.ads = mh.ads
cls.ad_subdomains = mh.ad_subdomains
cls.ad_treedomains = mh.ad_treedomains
def teardown_class(cls):
@@ -287,5 +308,9 @@ def teardown_class(cls):
del cls.master
del cls.replicas
del cls.clients
del cls.ad_domains
del cls.domain
if cls.ad_domains:
del cls.ads
del cls.ad_subdomains
del cls.ad_treedomains
del cls.ad_domains

View File

@@ -78,7 +78,7 @@ class Config(pytest_multihost.config.Config):
@property
def ad_domains(self):
return [d for d in self.domains if d.type == 'AD']
return [d for d in self.domains if d.is_ad_type]
def get_all_hosts(self):
for domain in self.domains:
@@ -122,10 +122,18 @@ class Domain(pytest_multihost.config.Domain):
self.name = str(name)
self.hosts = []
assert domain_type in ('IPA', 'AD')
assert self.is_ipa_type or self.is_ad_type
self.realm = self.name.upper()
self.basedn = DN(*(('dc', p) for p in name.split('.')))
@property
def is_ipa_type(self):
return self.type == 'IPA'
@property
def is_ad_type(self):
return self.type == 'AD' or self.type.startswith('AD_')
@property
def static_roles(self):
# Specific roles for each domain type are hardcoded
@@ -133,15 +141,19 @@ class Domain(pytest_multihost.config.Domain):
return ('master', 'replica', 'client', 'other')
elif self.type == 'AD':
return ('ad',)
elif self.type == 'AD_SUBDOMAIN':
return ('ad_subdomain',)
elif self.type == 'AD_TREEDOMAIN':
return ('ad_treedomain',)
else:
raise LookupError(self.type)
def get_host_class(self, host_dict):
from ipatests.pytest_ipa.integration.host import Host, WinHost
if self.type == 'IPA':
if self.is_ipa_type:
return Host
elif self.type == 'AD':
elif self.is_ad_type:
return WinHost
else:
raise LookupError(self.type)

View File

@@ -141,15 +141,21 @@ def config_from_env(env):
domain_index = 1
while (env.get('MASTER_env%s' % domain_index) or
env.get('AD_env%s' % domain_index)):
env.get('AD_env%s' % domain_index) or
env.get('AD_SUBDOMAIN_env%s' % domain_index) or
env.get('AD_TREEDOMAIN_env%s' % domain_index)):
if env.get('MASTER_env%s' % domain_index):
# IPA domain takes precedence to AD domain in case of conflict
config.domains.append(domain_from_env(env, config, domain_index,
domain_type='IPA'))
else:
config.domains.append(domain_from_env(env, config, domain_index,
domain_type='AD'))
for domain_type in ('AD', 'AD_SUBDOMAIN', 'AD_TREEDOMAIN'):
if env.get('%s_env%s' % (domain_type, domain_index)):
config.domains.append(
domain_from_env(env, config, domain_index,
domain_type=domain_type))
break
domain_index += 1
return config
@@ -274,7 +280,7 @@ def domain_from_env(env, config, index, domain_type):
if domain_type == 'IPA':
master_role = 'MASTER'
else:
master_role = 'AD'
master_role = domain_type
env_suffix = '_env%s' % index

View File

@@ -237,6 +237,15 @@ class TestComplexConfig(CheckConfig):
dict(name='master.ipadomain2.test', ip='192.0.2.65',
host_type=None),
]),
dict(name='adsubdomain.test', type='AD_SUBDOMAIN', hosts=[
dict(name='child_ad', ip='192.0.2.77', role='ad_subdomain',
host_type=None),
]),
dict(name='adtreedomain.test', type='AD_TREEDOMAIN', hosts=[
dict(name='tree_ad', ip='192.0.2.88', role='ad_treedomain',
host_type=None),
]),
],
)
extra_input_env = dict(
@@ -262,6 +271,12 @@ class TestComplexConfig(CheckConfig):
MASTER_env3='master.ipadomain2.test',
BEAKERMASTER1_IP_env3='192.0.2.65',
AD_SUBDOMAIN_env4='child_ad.adsubdomain.test',
BEAKERAD_SUBDOMAIN1_IP_env4='192.0.2.77',
AD_TREEDOMAIN_env5='tree_ad.adtreedomain.test',
BEAKERAD_TREEDOMAIN1_IP_env5='192.0.2.88',
)
extra_output_dict = dict(
domains=[
@@ -353,9 +368,37 @@ class TestComplexConfig(CheckConfig):
),
],
),
dict(
type="AD_SUBDOMAIN",
name="adsubdomain.test",
hosts=[
dict(
name='child_ad.adsubdomain.test',
ip="192.0.2.77",
external_hostname="child_ad.adsubdomain.test",
role="ad_subdomain",
host_type=None,
),
],
),
dict(
type="AD_TREEDOMAIN",
name="adtreedomain.test",
hosts=[
dict(
name='tree_ad.adtreedomain.test',
ip="192.0.2.88",
external_hostname="tree_ad.adtreedomain.test",
role="ad_treedomain",
host_type=None,
),
],
),
],
)
extra_output_env = extend_dict(extra_input_env,
extra_output_env = extend_dict(
extra_input_env,
DOMAIN_env1="ipadomain.test",
RELM_env1="IPADOMAIN.TEST",
BASEDN_env1="dc=ipadomain,dc=test",
@@ -434,10 +477,30 @@ class TestComplexConfig(CheckConfig):
MASTER1_env3="master.ipadomain2.test",
BEAKERMASTER1_env3="master.ipadomain2.test",
BEAKERMASTER1_IP_env3="192.0.2.65",
DOMAIN_env4="adsubdomain.test",
RELM_env4="ADSUBDOMAIN.TEST",
AD_SUBDOMAIN_env4='child_ad.adsubdomain.test',
AD_SUBDOMAIN1_env4='child_ad.adsubdomain.test',
BEAKERAD_SUBDOMAIN1_IP_env4='192.0.2.77',
BEAKERAD_SUBDOMAIN1_env4='child_ad.adsubdomain.test',
BEAKERAD_SUBDOMAIN_IP_env4='192.0.2.77',
BEAKERAD_SUBDOMAIN_env4='child_ad.adsubdomain.test',
BASEDN_env4='dc=adsubdomain,dc=test',
DOMAIN_env5="adtreedomain.test",
RELM_env5="ADTREEDOMAIN.TEST",
AD_TREEDOMAIN_env5='tree_ad.adtreedomain.test',
AD_TREEDOMAIN1_env5='tree_ad.adtreedomain.test',
BEAKERAD_TREEDOMAIN1_IP_env5='192.0.2.88',
BEAKERAD_TREEDOMAIN1_env5='tree_ad.adtreedomain.test',
BEAKERAD_TREEDOMAIN_IP_env5='192.0.2.88',
BEAKERAD_TREEDOMAIN_env5='tree_ad.adtreedomain.test',
BASEDN_env5='dc=adtreedomain,dc=test',
)
def check_config(self, conf):
assert len(conf.domains) == 3
assert len(conf.domains) == 5
main_dom = conf.domains[0]
(client1, client2, extra, extram1, extram2, _master,
replica1, replica2) = sorted(main_dom.hosts, key=lambda h: h.role)
@@ -463,3 +526,13 @@ class TestComplexConfig(CheckConfig):
assert ad_dom.roles == ['ad']
assert ad_dom.static_roles == ('ad',)
assert ad_dom.extra_roles == []
ad_sub_domain = conf.domains[3]
assert ad_sub_domain.roles == ['ad_subdomain']
assert ad_sub_domain.static_roles == ('ad_subdomain',)
assert ad_sub_domain.extra_roles == []
ad_tree_domain = conf.domains[4]
assert ad_tree_domain.roles == ['ad_treedomain']
assert ad_tree_domain.static_roles == ('ad_treedomain',)
assert ad_tree_domain.extra_roles == []