def get_domain_controller_ip_addresses()

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