From 1ed9379c9c57281e39246458f82197b09bbbd9e9 Mon Sep 17 00:00:00 2001
From: Thomas Woerner <twoerner@redhat.com>
Date: Thu, 21 Jun 2018 13:08:44 +0200
Subject: [PATCH] ipaclient: Fix OTP action plugin to work with python3
 bindings

As the action plugin is used with the default python interpreter and
the change to python3 for FreeIPA, the use of OTP was not working anymore.

The ansible_python_interpreter is not automatically used for the module
part of the action plugin. Therefore ansible_python_interpreter needed to
be added to the action plugin call as a new var to make sure that the
module part is used with the proper python version.

Also a new import for the Python2/3 import test has been added to discover
of the server is supporting python2 or python3. The old
ansible_python_interpreter setting is saved before doing this and restored
after the one-time password has been generated on the server.
---
 roles/ipaclient/action_plugins/ipahost.py |  4 +++-
 roles/ipaclient/library/ipahost.py        |  4 ++++
 roles/ipaclient/tasks/install.yml         | 21 ++++++++++++++++++---
 3 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/roles/ipaclient/action_plugins/ipahost.py b/roles/ipaclient/action_plugins/ipahost.py
index d4bd4b02..92f3a5b6 100644
--- a/roles/ipaclient/action_plugins/ipahost.py
+++ b/roles/ipaclient/action_plugins/ipahost.py
@@ -149,6 +149,8 @@ class ActionModule(ActionBase):
         keytab = self._task.args.get('keytab', None)
         password = self._task.args.get('password', None)
         lifetime = self._task.args.get('lifetime', '1h')
+        ansible_python_interpreter = self._task.args.get('ansible_python_interpreter', None)
+        task_vars["ansible_python_interpreter"] = ansible_python_interpreter
 
         if (not keytab and not password):
             result['failed'] = True
@@ -161,7 +163,7 @@ class ActionModule(ActionBase):
             return result
 
         data = self._execute_module(module_name='ipa_facts', module_args=dict(),
-                                    task_vars=None)
+                                    task_vars={ "ansible_python_interpreter": ansible_python_interpreter })
         try:
             domain = data['ansible_facts']['ipa']['domain']
             realm = data['ansible_facts']['ipa']['realm']
diff --git a/roles/ipaclient/library/ipahost.py b/roles/ipaclient/library/ipahost.py
index 68904e3d..b6da08e5 100644
--- a/roles/ipaclient/library/ipahost.py
+++ b/roles/ipaclient/library/ipahost.py
@@ -71,6 +71,9 @@ options:
   ipaddress:
     description: the IP address for the host
     required: false
+  ansible_python_interpreter:
+    desciption: The ansible python interpreter used in the action plugin part, ignored here
+    required: false
 
 requirements:
     - gssapi on the Ansible controller
@@ -315,6 +318,7 @@ def main():
             ipaddress = dict(required=False),
             random = dict(default=False, type='bool'),
             state = dict(default='present', choices=[ 'present', 'absent' ]),
+            ansible_python_interpreter = dict(required=False),
         ),
         supports_check_mode=True,
     )
diff --git a/roles/ipaclient/tasks/install.yml b/roles/ipaclient/tasks/install.yml
index 1730b5ac..1ecb36d0 100644
--- a/roles/ipaclient/tasks/install.yml
+++ b/roles/ipaclient/tasks/install.yml
@@ -71,8 +71,17 @@
     - fail: msg="Keytab or password is required for otp"
       when: ipaadmin_keytab is undefined and ipaadmin_password is undefined
 
-    - name: Install - Get a One-Time Password for client enrollment
-      no_log: yes
+    - name: Install - Save client ansible_python_interpreter setting
+      set_fact:
+        ipaclient_ansible_python_interpreter: "{{ ansible_python_interpreter }}"
+
+    - name: Install - Include Python2/3 import test
+      include: "{{role_path}}/tasks/python_2_3_test.yml"
+      static: yes
+      delegate_to: "{{ ipadiscovery.servers[0] }}"
+
+    - name: Install - Get One-Time Password for client enrollment
+      #no_log: yes
       ipahost:
         state: present
         principal: "{{ ipaadmin_principal | default('admin') }}"
@@ -81,17 +90,23 @@
         fqdn: "{{ ipadiscovery.hostname }}"
         lifetime: "{{ ipaclient_lifetime | default(omit) }}"
         random: True
+        ansible_python_interpreter: "{{ ansible_python_interpreter }}"
       register: ipahost_output
       # If the host is already enrolled, this command will exit on error
       # The error can be ignored
-      failed_when: ipahost_output|failed and "Password cannot be set on enrolled host" not in ipahost_output.msg
+      failed_when: ipahost_output is failed and "Password cannot be set on enrolled host" not in ipahost_output.msg
       delegate_to: "{{ ipadiscovery.servers[0] }}"
+      delegate_facts: True
 
     - name: Install - Store the previously obtained OTP
       no_log: yes
       set_fact:
         ipaadmin_password: "{{ ipahost_output.host.randompassword if ipahost_output.host is defined }}"
 
+    - name: Install - Restore client ansible_python_interpreter setting
+      set_fact:
+        ansible_python_interpreter: "{{ ipaclient_ansible_python_interpreter }}"
+
     when: ipaclient_use_otp | bool
 
   - block:
-- 
GitLab