in source/idea/idea-cluster-manager/src/ideaclustermanager/app/accounts/helpers/preset_computer_helper.py [0:0]
def get_domain_controller_ip_addresses(self) -> List[str]:
"""
perform adcli discovery on the AD domain name and return all the domain controller hostnames.
:return: hostnames all available domain controllers
"""
cmd = [
self.ADCLI,
'info',
]
if self.use_ldaps:
cmd.append("--use-ldaps")
cmd.append(self.ldap_client.options.domain_name.upper())
result = self._shell.invoke(
cmd=cmd,
)
if result.returncode != 0:
raise exceptions.soca_exception(
error_code=errorcodes.AD_AUTOMATION_PRESET_COMPUTER_RETRY,
message=f'{self.log_tag} failed to perform adcli information discovery on AD domain: {self.ldap_client.options.domain_name}'
)
# self.logger.debug(f'ADCLI Domain info: {result.stdout}')
# Example output for a domain with 6 domain controllers:
# [domain]
# domain-name = idea.local
# domain-short = IDEA
# domain-forest = idea.local
# domain-controller = IP-C6130254.idea.local
# domain-controller-site = us-east-1
# domain-controller-flags = gc ldap ds kdc timeserv closest writable full-secret ads-web
# domain-controller-usable = yes
# domain-controllers = IP-C6130254.idea.local IP-C6120243.idea.local ip-c61301a7.idea.local ip-c61202c6.idea.local ip-c6120053.idea.local ip-c612008c.idea.local
# [computer]
# computer-site = us-east-1
# store the output in domain_query for quick review of params
domain_query = {}
lines = str(result.stdout).splitlines()
for line in lines:
line = line.strip()
if line.startswith('['):
continue
try:
result_key = line.split(' =')[0]
result_value = line.split('= ')[1]
except IndexError as e:
self.logger.warning(f'Error parsing AD discovery output: {e}. Line skipped: {line}')
continue
self.logger.debug(f'Key: [{result_key:25}] Value: [{result_value:25}]')
if (
not Utils.get_as_string(result_key, default='') or
not Utils.get_as_string(result_value, default='')
):
self.logger.warning(f'Error parsing AD discovery output. Unable to parse Key/Value Pair. Check adcli version/output. Line skipped: {line}')
continue
# Save for later
domain_query[result_key] = result_value
# Sanity check our query results
# todo - should domain-controller-flags be evaluated for writeable or other health flags?
# domain-name must be present and match our configuration
domain_name = Utils.get_value_as_string('domain-name', domain_query, default=None)
if domain_name is None:
raise exceptions.soca_exception(
error_code=errorcodes.AD_AUTOMATION_PRESET_COMPUTER_RETRY,
message=f'{self.log_tag} Unable to validate AD domain discovery for domain-name: {self.ldap_client.options.domain_name}'
)
if domain_name.upper() != self.ldap_client.options.domain_name.upper():
raise exceptions.soca_exception(
error_code=errorcodes.AD_AUTOMATION_PRESET_COMPUTER_RETRY,
message=f"{self.log_tag} AD domain discovery mismatch for domain-name: Got: {domain_name.upper()} Expected: {self.ldap_client.options.domain_name.upper()}"
)
# domain_controllers must be a list of domain controllers
# split() vs. split(' ') - we don't want empty entries in the list
# else our len() check would be incorrect
domain_controllers = domain_query.get('domain-controllers', '').strip().split()
if len(domain_controllers) == 0:
raise exceptions.soca_exception(
error_code=errorcodes.AD_AUTOMATION_PRESET_COMPUTER_RETRY,
message=f'{self.log_tag} no domain controllers found for AD domain: {self.ldap_client.options.domain_name}. check your firewall settings and verify if traffic is allowed on port 53.'
)
return domain_controllers