From bac19c330196b02b1cdb80a706dadd782d82602d Mon Sep 17 00:00:00 2001 From: Juan Antonio Osorio Date: Fri, 1 Feb 2019 10:19:05 +0200 Subject: [PATCH] identity: Autodetect FreeIPA server with DNS (#50988) * identity: Autodetect FreeIPA server with DNS This adds the ability for the freeIPA related modules to be able to auto-detect the IPA server through DNS. This takes advantage of the fact that a lot of FreeIPA deployments configure their hosts to use IPA as the nameserver. This check is only used if we didn't set neither the ipa_host parameter, nor the environment variable IPA_HOST. * identity: Specify docs for DNS discovery of ipa_host These docs specify that it can now default to DNS if the 'ipa-ca' entry is available. --- lib/ansible/module_utils/ipa.py | 19 +++++++++++++++++-- lib/ansible/plugins/doc_fragments/ipa.py | 4 +++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/ansible/module_utils/ipa.py b/lib/ansible/module_utils/ipa.py index 381afac7d12..0d3eb1d3b45 100644 --- a/lib/ansible/module_utils/ipa.py +++ b/lib/ansible/module_utils/ipa.py @@ -28,13 +28,28 @@ # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import json +import socket import re from ansible.module_utils._text import to_bytes, to_native, to_text from ansible.module_utils.six import PY3 from ansible.module_utils.six.moves.urllib.parse import quote from ansible.module_utils.urls import fetch_url -from ansible.module_utils.basic import env_fallback +from ansible.module_utils.basic import env_fallback, AnsibleFallbackNotFound + + +def _env_then_dns_fallback(*args, **kwargs): + ''' Load value from environment or DNS in that order''' + try: + return env_fallback(*args, **kwargs) + except AnsibleFallbackNotFound: + # If no host was given, we try to guess it from IPA. + # The ipa-ca entry is a standard entry that IPA will have set for + # the CA. + try: + return socket.gethostbyaddr(socket.gethostbyname('ipa-ca'))[0] + except Exception: + raise AnsibleFallbackNotFound class IPAClient(object): @@ -181,7 +196,7 @@ class IPAClient(object): def ipa_argument_spec(): return dict( ipa_prot=dict(type='str', default='https', choices=['http', 'https'], fallback=(env_fallback, ['IPA_PROT'])), - ipa_host=dict(type='str', default='ipa.example.com', fallback=(env_fallback, ['IPA_HOST'])), + ipa_host=dict(type='str', default='ipa.example.com', fallback=(_env_then_dns_fallback, ['IPA_HOST'])), ipa_port=dict(type='int', default=443, fallback=(env_fallback, ['IPA_PORT'])), ipa_user=dict(type='str', default='admin', fallback=(env_fallback, ['IPA_USER'])), ipa_pass=dict(type='str', required=True, no_log=True, fallback=(env_fallback, ['IPA_PASS'])), diff --git a/lib/ansible/plugins/doc_fragments/ipa.py b/lib/ansible/plugins/doc_fragments/ipa.py index d2017b7e4eb..20f4c81a17d 100644 --- a/lib/ansible/plugins/doc_fragments/ipa.py +++ b/lib/ansible/plugins/doc_fragments/ipa.py @@ -18,7 +18,9 @@ options: description: - IP or hostname of IPA server. - If the value is not specified in the task, the value of environment variable C(IPA_HOST) will be used instead. - - If both the environment variable C(IPA_HOST) and the value are not specified in the task, then default value is set. + - If both the environment variable C(IPA_HOST) and the value are not specified in the task, then DNS will be used to try to discover the FreeIPA server. + - The relevant entry needed in FreeIPA is the 'ipa-ca' entry. + - If neither the DNS entry, nor the environment C(IPA_HOST), nor the value are available in the task, then the default value will be used. - 'Environment variable fallback mechanism is added in version 2.5.' default: ipa.example.com ipa_user: