From 4f7f40818a3f019907ecd4c9b932b78ff5863de7 Mon Sep 17 00:00:00 2001 From: "Bradley A. Thornton" Date: Wed, 28 Aug 2019 13:07:55 -0700 Subject: [PATCH 1/5] Handle network platform action plugin collection searching --- lib/ansible/executor/task_executor.py | 99 +++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 12 deletions(-) diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 3e524afc064beb..a03a0624b4b30b 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -1015,24 +1015,98 @@ def _set_connection_options(self, variables, templar): self._play_context.prompt = self._connection.become.prompt def _get_action_handler(self, connection, templar): - ''' + """ Returns the correct action plugin to handle the requestion task action - ''' - - module_prefix = self._task.action.split('_')[0] - + """ + action_loader = self._shared_loader_obj.action_loader collections = self._task.collections + # namespace.name.xxx_yyyy = xxx + module_prefix = self._task.action.split(".")[-1].split("_")[0] + # namespace.name.xxx_yyyy = namespace.name + collection_from_task = ".".join(self._task.action.split(".")[:-1]) + if collection_from_task: + derived_collections = [collection_from_task] + else: + derived_collections = None - # let action plugin override module, fallback to 'normal' action plugin otherwise - if self._shared_loader_obj.action_loader.has_plugin(self._task.action, collection_list=collections): + # let action plugin override module, fallback to 'normal' + # action plugin otherwise + if action_loader.has_plugin( + self._task.action, collection_list=collections + ): handler_name = self._task.action - # FIXME: is this code path even live anymore? check w/ networking folks; it trips sometimes when it shouldn't - elif all((module_prefix in C.NETWORK_GROUP_MODULES, module_prefix in self._shared_loader_obj.action_loader)): + + # user has specified a network_os and a list of collections + elif all( + ( + collections, + action_loader.has_plugin( + self._play_context.network_os, collection_list=collections + ), + ) + ): + + handler_name = self._play_context.network_os + display.vvv( + "Found network platform handler using network_os and provided" + " collection list: %s" + % action_loader.find_plugin( + self._play_context.network_os, collection_list=collections + ), + host=self._play_context.remote_addr, + ) + + # user has specified network_os, not specified collections + # default to using the module's local collection + # set the tasks collection to the module's collection name + elif all( + ( + collections is None, + action_loader.has_plugin( + self._play_context.network_os, + collection_list=derived_collections, + ), + ) + ): + handler_name = self._play_context.network_os + collections = derived_collections + display.vvv( + "Found network platform handler using network_os and" + " collection derived from task action: %s" + % action_loader.find_plugin( + self._play_context.network_os, + collection_list=derived_collections, + ), + host=self._play_context.remote_addr, + ) + + # user has not specified a network_os + # constrain this to NETWORK_GROUP_MODULES + # connection is local, no collection support here + # this stops working when the platform plugins are + # no longer in core and can be removed + elif all( + ( + self._play_context.connection == "local", + module_prefix in C.NETWORK_GROUP_MODULES, + action_loader.has_plugin(module_prefix), + ) + ): handler_name = module_prefix + display.vvv( + "Found network platform handler module_prefix and" + " NETWORK_GROUP_MODULES lookup: %s" + % action_loader.find_plugin(module_prefix), + host=self._play_context.remote_addr, + ) + else: - # FUTURE: once we're comfortable with collections impl, preface this action with ansible.builtin so it can't be hijacked - handler_name = 'normal' - collections = None # until then, we don't want the task's collection list to be consulted; use the builtin + # FUTURE: once we're comfortable with collections impl, preface + # this action with ansible.builtin so it can't be hijacked + handler_name = "normal" + # # until then, we don't want the task's collection list + # to be consulted; use the builtin + collections = None handler = self._shared_loader_obj.action_loader.get( handler_name, @@ -1051,6 +1125,7 @@ def _get_action_handler(self, connection, templar): return handler + def start_connection(play_context, variables): ''' Starts the persistent connection From 3b8aebf0f710d836400bf9032b82d75e795b5e66 Mon Sep 17 00:00:00 2001 From: "Bradley A. Thornton" Date: Wed, 28 Aug 2019 14:21:45 -0700 Subject: [PATCH 2/5] Use constant --- lib/ansible/executor/task_executor.py | 47 +++++++++------------------ 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index a03a0624b4b30b..8772765044286c 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -1036,70 +1036,53 @@ def _get_action_handler(self, connection, templar): ): handler_name = self._task.action - # user has specified a network_os and a list of collections + # module prefix is network and a list of collections provided + # this would return the core plugin if checked independant of + # collections elif all( ( collections, + module_prefix in C.NETWORK_GROUP_MODULES, action_loader.has_plugin( - self._play_context.network_os, collection_list=collections + module_prefix, collection_list=collections ), ) ): - handler_name = self._play_context.network_os + handler_name = module_prefix display.vvv( - "Found network platform handler using network_os and provided" + "Found network platform handler using module prefix with" " collection list: %s" % action_loader.find_plugin( - self._play_context.network_os, collection_list=collections + module_prefix, collection_list=collections ), host=self._play_context.remote_addr, ) - # user has specified network_os, not specified collections + # module prefix is network and no list of collections provided # default to using the module's local collection # set the tasks collection to the module's collection name elif all( ( collections is None, + module_prefix in C.NETWORK_GROUP_MODULES, action_loader.has_plugin( - self._play_context.network_os, + module_prefix, collection_list=derived_collections, ), ) ): - handler_name = self._play_context.network_os + handler_name = module_prefix collections = derived_collections display.vvv( - "Found network platform handler using network_os and" - " collection derived from task action: %s" + "Found network platform handler using module prefix with" + " collection from task: %s" % action_loader.find_plugin( - self._play_context.network_os, - collection_list=derived_collections, + module_prefix, collection_list=collections ), host=self._play_context.remote_addr, ) - # user has not specified a network_os - # constrain this to NETWORK_GROUP_MODULES - # connection is local, no collection support here - # this stops working when the platform plugins are - # no longer in core and can be removed - elif all( - ( - self._play_context.connection == "local", - module_prefix in C.NETWORK_GROUP_MODULES, - action_loader.has_plugin(module_prefix), - ) - ): - handler_name = module_prefix - display.vvv( - "Found network platform handler module_prefix and" - " NETWORK_GROUP_MODULES lookup: %s" - % action_loader.find_plugin(module_prefix), - host=self._play_context.remote_addr, - ) - else: # FUTURE: once we're comfortable with collections impl, preface # this action with ansible.builtin so it can't be hijacked From 8d4e0d5f4f60c6b0a666f7097a265447caf649ca Mon Sep 17 00:00:00 2001 From: "Bradley A. Thornton" Date: Wed, 28 Aug 2019 14:30:34 -0700 Subject: [PATCH 3/5] rpartition --- lib/ansible/executor/task_executor.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 8772765044286c..ada3efd708cb85 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -1020,10 +1020,9 @@ def _get_action_handler(self, connection, templar): """ action_loader = self._shared_loader_obj.action_loader collections = self._task.collections - # namespace.name.xxx_yyyy = xxx - module_prefix = self._task.action.split(".")[-1].split("_")[0] - # namespace.name.xxx_yyyy = namespace.name - collection_from_task = ".".join(self._task.action.split(".")[:-1]) + + collection_from_task, _, module_name = self._task.action.rpartition(".") + module_prefix = module_name.split("_")[0] if collection_from_task: derived_collections = [collection_from_task] else: From 768ff9ddb598820998244623bb0c12335672be9d Mon Sep 17 00:00:00 2001 From: "Bradley A. Thornton" Date: Wed, 28 Aug 2019 14:31:53 -0700 Subject: [PATCH 4/5] emptyline --- lib/ansible/executor/task_executor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index ada3efd708cb85..84162e32e315c3 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -1107,7 +1107,6 @@ def _get_action_handler(self, connection, templar): return handler - def start_connection(play_context, variables): ''' Starts the persistent connection From febfd00e8f4f15272e1ac36d67a275d4dd7d5be3 Mon Sep 17 00:00:00 2001 From: "Bradley A. Thornton" Date: Wed, 28 Aug 2019 15:29:42 -0700 Subject: [PATCH 5/5] In case handler was not found in collection list - Look in the collection local to the module --- lib/ansible/executor/task_executor.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 84162e32e315c3..c4e0467348c2c3 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -1058,12 +1058,11 @@ def _get_action_handler(self, connection, templar): host=self._play_context.remote_addr, ) - # module prefix is network and no list of collections provided + # module prefix is network and a handler wasn't found previously # default to using the module's local collection # set the tasks collection to the module's collection name elif all( ( - collections is None, module_prefix in C.NETWORK_GROUP_MODULES, action_loader.has_plugin( module_prefix, @@ -1074,8 +1073,10 @@ def _get_action_handler(self, connection, templar): handler_name = module_prefix collections = derived_collections display.vvv( - "Found network platform handler using module prefix with" - " collection from task: %s" + "Found network platform handler using module prefix, " + " handler was not found in provided collection list" + " or provided collection list was empty." + " Collection derived from task: %s" % action_loader.find_plugin( module_prefix, collection_list=collections ),