diff --git a/lib/ansible/module_utils/ipa.py b/lib/ansible/module_utils/ipa.py index 381afac7d1..0d3eb1d3b4 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 d2017b7e4e..20f4c81a17 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: