From 80cc8ed4b1d2e10e7c4a518dd4ca1a5305ed8ede Mon Sep 17 00:00:00 2001
From: Kevin Carter <kecarter@redhat.com>
Date: Mon, 16 Dec 2019 18:29:23 -0600
Subject: [PATCH] Add traps for py3 and fix remote src

This change adds traps for the FileNotFound exception which is used instead
of OSError when a file is not found. This will ensure that that fall back
exception handeling works properly in py2 and py3.

The remote_src flag was not being respected with the new fallback options,
this change adds a check for remote_src so it works in normal and fallback
mode.

Change-Id: I136dd1f3220d3b004d5275a9fa15edea53d58f6b
Signed-off-by: Kevin Carter <kecarter@redhat.com>
---
 action/config_template.py | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/action/config_template.py b/action/config_template.py
index a255ba9..843ff9e 100644
--- a/action/config_template.py
+++ b/action/config_template.py
@@ -63,6 +63,10 @@ try:
     PermissionError = PermissionError
 except NameError:
     PermissionError = (IOError, OSError)
+try:
+    FileNotFoundError = FileNotFoundError
+except NameError:
+    FileNotFoundError = OSError
 
 
 class IDumper(AnsibleDumper):
@@ -121,6 +125,8 @@ class MultiKeyDict(OrderedDict):
                 if str(value) not in items:
                     items += tuple([str(value)])
                     super(MultiKeyDict, self).__setitem__(key, items)
+            elif isinstance(self[key], MultiKeyDict):
+                pass
             else:
                 if str(self[key]) != str(value):
                     items = tuple([str(self[key]), str(value)])
@@ -313,7 +319,6 @@ class ConfigTemplateParser(ConfigParser.RawConfigParser):
                     )
                 cursect[optname] = optval
             else:
-
                 optname = '%s-%d' % (
                     STRIP_MARKER,
                     marker_counter
@@ -612,16 +617,19 @@ class ActionModule(ActionBase):
                       ',' in value or (
                         '\n' in value and not yml_multilines))):
                     base_items[key] = re.split(',|\n', value)
-                    base_items[key] = [i.strip() for i in base_items[key] if i]
+                    base_items[key] = [
+                        i.strip() for i in base_items[key] if i
+                    ]
                 elif isinstance(value, list):
                     if isinstance(base_items.get(key), list) and list_extend:
                         base_items[key].extend(value)
                     else:
                         base_items[key] = value
                 elif isinstance(value, (tuple, set)):
-                    if isinstance(base_items.get(key), tuple) and list_extend:
+                    le = list_extend  # assigned for pep8
+                    if isinstance(base_items.get(key), tuple) and le:
                         base_items[key] += tuple(value)
-                    elif isinstance(base_items.get(key), list) and list_extend:
+                    elif isinstance(base_items.get(key), list) and le:
                         base_items[key].extend(list(value))
                     else:
                         base_items[key] = value
@@ -798,9 +806,11 @@ class ActionModule(ActionBase):
                 template_uid = temp_vars['template_uid'] = os.stat(
                     source
                 ).st_uid
-        except PermissionError:
+        except (PermissionError, FileNotFoundError):
             local_task_vars = temp_vars.copy()
-            local_task_vars['connection'] = 'local'
+            if not boolean(self._task.args.get('remote_src', False),
+                           strict=False):
+                local_task_vars['connection'] = 'local'
             stat = self._execute_module(
                 module_name='stat',
                 module_args=dict(path=source),
@@ -829,12 +839,14 @@ class ActionModule(ActionBase):
         try:
             with open(source, 'r') as f:
                 template_data = to_text(f.read())
-        except PermissionError:
+        except (PermissionError, FileNotFoundError):
             local_temp_vars = task_vars.copy()
-            local_temp_vars['connection'] = 'local'
+            if not boolean(self._task.args.get('remote_src', False),
+                           strict=False):
+                local_temp_vars['connection'] = 'local'
             template_data_slurpee = self._execute_module(
                 module_name='slurp',
-                module_args=dict(src=_vars['dest']),
+                module_args=dict(src=source),
                 task_vars=local_temp_vars
             )
             template_data = base64.b64decode(