mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-28 05:11:25 -07:00
Merge pull request #1452 from dhozac/with_items-as-plugin
Make with_items a lookup plugin
This commit is contained in:
commit
19a5f86c2e
4 changed files with 48 additions and 24 deletions
|
@ -104,10 +104,16 @@ class Play(object):
|
||||||
if 'include' in x:
|
if 'include' in x:
|
||||||
task_vars = self.vars.copy()
|
task_vars = self.vars.copy()
|
||||||
tokens = shlex.split(x['include'])
|
tokens = shlex.split(x['include'])
|
||||||
if 'with_items' in x:
|
|
||||||
items = utils.varReplaceWithItems(self.basedir, x['with_items'], task_vars)
|
|
||||||
else:
|
|
||||||
items = ['']
|
items = ['']
|
||||||
|
for k in x:
|
||||||
|
if not k.startswith("with_"):
|
||||||
|
continue
|
||||||
|
plugin_name = k[5:]
|
||||||
|
if plugin_name not in self.playbook.lookup_plugins_list:
|
||||||
|
raise errors.AnsibleError("cannot find lookup plugin named %s for usage in with_%s" % (plugin_name, plugin_name))
|
||||||
|
terms = utils.varReplaceWithItems(self.basedir, x[k], task_vars)
|
||||||
|
items = self.playbook.lookup_plugins_list[plugin_name].LookupModule(None).run(terms)
|
||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
mv = task_vars.copy()
|
mv = task_vars.copy()
|
||||||
mv['item'] = item
|
mv['item'] = item
|
||||||
|
|
|
@ -24,7 +24,7 @@ class Task(object):
|
||||||
__slots__ = [
|
__slots__ = [
|
||||||
'name', 'action', 'only_if', 'async_seconds', 'async_poll_interval',
|
'name', 'action', 'only_if', 'async_seconds', 'async_poll_interval',
|
||||||
'notify', 'module_name', 'module_args', 'module_vars',
|
'notify', 'module_name', 'module_args', 'module_vars',
|
||||||
'play', 'notified_by', 'tags', 'register', 'with_items',
|
'play', 'notified_by', 'tags', 'register',
|
||||||
'delegate_to', 'first_available_file', 'ignore_errors',
|
'delegate_to', 'first_available_file', 'ignore_errors',
|
||||||
'local_action', 'transport', 'sudo', 'sudo_user', 'sudo_pass',
|
'local_action', 'transport', 'sudo', 'sudo_user', 'sudo_pass',
|
||||||
'items_lookup_plugin', 'items_lookup_terms'
|
'items_lookup_plugin', 'items_lookup_terms'
|
||||||
|
@ -32,7 +32,7 @@ class Task(object):
|
||||||
|
|
||||||
# to prevent typos and such
|
# to prevent typos and such
|
||||||
VALID_KEYS = [
|
VALID_KEYS = [
|
||||||
'name', 'action', 'only_if', 'async', 'poll', 'notify', 'with_items',
|
'name', 'action', 'only_if', 'async', 'poll', 'notify',
|
||||||
'first_available_file', 'include', 'tags', 'register', 'ignore_errors',
|
'first_available_file', 'include', 'tags', 'register', 'ignore_errors',
|
||||||
'delegate_to', 'local_action', 'transport', 'sudo', 'sudo_user',
|
'delegate_to', 'local_action', 'transport', 'sudo', 'sudo_user',
|
||||||
'sudo_pass'
|
'sudo_pass'
|
||||||
|
@ -49,7 +49,7 @@ class Task(object):
|
||||||
ds.pop(x)
|
ds.pop(x)
|
||||||
|
|
||||||
# code to allow "with_glob" and to reference a lookup plugin named glob
|
# code to allow "with_glob" and to reference a lookup plugin named glob
|
||||||
elif x.startswith("with_") and x != 'with_items':
|
elif x.startswith("with_"):
|
||||||
plugin_name = x.replace("with_","")
|
plugin_name = x.replace("with_","")
|
||||||
if plugin_name in play.playbook.lookup_plugins_list:
|
if plugin_name in play.playbook.lookup_plugins_list:
|
||||||
ds['items_lookup_plugin'] = plugin_name
|
ds['items_lookup_plugin'] = plugin_name
|
||||||
|
@ -112,7 +112,6 @@ class Task(object):
|
||||||
self.async_poll_interval = int(ds.get('poll', 10)) # default poll = 10 seconds
|
self.async_poll_interval = int(ds.get('poll', 10)) # default poll = 10 seconds
|
||||||
self.notify = ds.get('notify', [])
|
self.notify = ds.get('notify', [])
|
||||||
self.first_available_file = ds.get('first_available_file', None)
|
self.first_available_file = ds.get('first_available_file', None)
|
||||||
self.with_items = ds.get('with_items', None)
|
|
||||||
|
|
||||||
self.items_lookup_plugin = ds.get('items_lookup_plugin', None)
|
self.items_lookup_plugin = ds.get('items_lookup_plugin', None)
|
||||||
self.items_lookup_terms = ds.get('items_lookup_terms', None)
|
self.items_lookup_terms = ds.get('items_lookup_terms', None)
|
||||||
|
@ -142,19 +141,14 @@ class Task(object):
|
||||||
self.action = utils.template(None, self.action, self.module_vars)
|
self.action = utils.template(None, self.action, self.module_vars)
|
||||||
|
|
||||||
# handle mutually incompatible options
|
# handle mutually incompatible options
|
||||||
incompatibles = [ x for x in [ self.with_items, self.first_available_file, self.items_lookup_plugin ] if x is not None ]
|
incompatibles = [ x for x in [ self.first_available_file, self.items_lookup_plugin ] if x is not None ]
|
||||||
if len(incompatibles) > 1:
|
if len(incompatibles) > 1:
|
||||||
raise errors.AnsibleError("with_items, with_(plugin), and first_available_file are mutually incompatible in a single task")
|
raise errors.AnsibleError("with_(plugin), and first_available_file are mutually incompatible in a single task")
|
||||||
|
|
||||||
# make first_available_file accessable to Runner code
|
# make first_available_file accessable to Runner code
|
||||||
if self.first_available_file:
|
if self.first_available_file:
|
||||||
self.module_vars['first_available_file'] = self.first_available_file
|
self.module_vars['first_available_file'] = self.first_available_file
|
||||||
|
|
||||||
# process with_items so it can be used by Runner code
|
|
||||||
if self.with_items is None:
|
|
||||||
self.with_items = [ ]
|
|
||||||
self.module_vars['items'] = self.with_items
|
|
||||||
|
|
||||||
if self.items_lookup_plugin is not None:
|
if self.items_lookup_plugin is not None:
|
||||||
self.module_vars['items_lookup_plugin'] = self.items_lookup_plugin
|
self.module_vars['items_lookup_plugin'] = self.items_lookup_plugin
|
||||||
self.module_vars['items_lookup_terms'] = self.items_lookup_terms
|
self.module_vars['items_lookup_terms'] = self.items_lookup_terms
|
||||||
|
|
|
@ -280,22 +280,17 @@ class Runner(object):
|
||||||
inject['group_names'] = host_variables.get('group_names', [])
|
inject['group_names'] = host_variables.get('group_names', [])
|
||||||
inject['groups'] = self.inventory.groups_list()
|
inject['groups'] = self.inventory.groups_list()
|
||||||
|
|
||||||
# allow with_items to work in playbooks...
|
# allow with_foo to work in playbooks...
|
||||||
# apt and yum are converted into a single call, others run in a loop
|
items = []
|
||||||
items = self.module_vars.get('items', [])
|
|
||||||
if isinstance(items, basestring) and items.startswith("$"):
|
|
||||||
items = utils.varReplaceWithItems(self.basedir, items, inject)
|
|
||||||
|
|
||||||
# if we instead said 'with_foo' and there is a lookup module named foo...
|
|
||||||
items_plugin = self.module_vars.get('items_lookup_plugin', None)
|
items_plugin = self.module_vars.get('items_lookup_plugin', None)
|
||||||
if items_plugin is not None:
|
if items_plugin is not None:
|
||||||
items_terms = self.module_vars.get('items_lookup_terms', '')
|
items_terms = self.module_vars.get('items_lookup_terms', '')
|
||||||
if items_plugin in self.lookup_plugins:
|
if items_plugin in self.lookup_plugins:
|
||||||
items_terms = utils.template(self.basedir, items_terms, inject)
|
items_terms = utils.varReplaceWithItems(self.basedir, items_terms, inject)
|
||||||
items = self.lookup_plugins[items_plugin].run(items_terms)
|
items = self.lookup_plugins[items_plugin].run(items_terms)
|
||||||
|
|
||||||
if type(items) != list:
|
if type(items) != list:
|
||||||
raise errors.AnsibleError("with_items only takes a list: %s" % items)
|
raise errors.AnsibleError("lookup plugins have to return a list: %r" % items)
|
||||||
|
|
||||||
if len(items) and self.module_name in [ 'apt', 'yum' ]:
|
if len(items) and self.module_name in [ 'apt', 'yum' ]:
|
||||||
# hack for apt and soon yum, with_items maps back into a single module call
|
# hack for apt and soon yum, with_items maps back into a single module call
|
||||||
|
|
29
lib/ansible/runner/lookup_plugins/items.py
Normal file
29
lib/ansible/runner/lookup_plugins/items.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of Ansible
|
||||||
|
#
|
||||||
|
# Ansible is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Ansible is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
class LookupModule(object):
|
||||||
|
|
||||||
|
def __init__(self, runner):
|
||||||
|
self.runner = runner
|
||||||
|
|
||||||
|
def run(self, terms):
|
||||||
|
return terms
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue