|
|
@ -26,6 +26,7 @@ from ansible.playbook.conditional import Conditional
|
|
|
|
from ansible.playbook.task import Task
|
|
|
|
from ansible.playbook.task import Task
|
|
|
|
from ansible.plugins import get_plugin_class
|
|
|
|
from ansible.plugins import get_plugin_class
|
|
|
|
from ansible.plugins.loader import become_loader, cliconf_loader, connection_loader, httpapi_loader, netconf_loader, terminal_loader
|
|
|
|
from ansible.plugins.loader import become_loader, cliconf_loader, connection_loader, httpapi_loader, netconf_loader, terminal_loader
|
|
|
|
|
|
|
|
from ansible.plugins.test.core import unreachable
|
|
|
|
from ansible.template import Templar
|
|
|
|
from ansible.template import Templar
|
|
|
|
from ansible.utils.collection_loader import AnsibleCollectionConfig
|
|
|
|
from ansible.utils.collection_loader import AnsibleCollectionConfig
|
|
|
|
from ansible.utils.listify import listify_lookup_plugin_terms
|
|
|
|
from ansible.utils.listify import listify_lookup_plugin_terms
|
|
|
@ -126,49 +127,43 @@ class TaskExecutor:
|
|
|
|
self._loop_eval_error = e
|
|
|
|
self._loop_eval_error = e
|
|
|
|
|
|
|
|
|
|
|
|
if items is not None:
|
|
|
|
if items is not None:
|
|
|
|
if len(items) > 0:
|
|
|
|
if items:
|
|
|
|
item_results = self._run_loop(items)
|
|
|
|
res = {'results': self._run_loop(items)}
|
|
|
|
|
|
|
|
# set the global changed/failed/skipped result flags based on any item
|
|
|
|
# create the overall result item
|
|
|
|
warnings = set()
|
|
|
|
res = dict(results=item_results)
|
|
|
|
deprecations = set()
|
|
|
|
|
|
|
|
skipped = True
|
|
|
|
# loop through the item results and set the global changed/failed/skipped result flags based on any item.
|
|
|
|
changed = failed = unreachable = False
|
|
|
|
res['skipped'] = True
|
|
|
|
for item in res['results']:
|
|
|
|
for item in item_results:
|
|
|
|
skipped &= item.get('skipped', False)
|
|
|
|
if 'changed' in item and item['changed'] and not res.get('changed'):
|
|
|
|
changed |= item.get('changed', False)
|
|
|
|
res['changed'] = True
|
|
|
|
failed |= (failed_item := item.get('failed', False))
|
|
|
|
if res['skipped'] and ('skipped' not in item or ('skipped' in item and not item['skipped'])):
|
|
|
|
unreachable |= (unreachable_item := item.get('unreachable', False))
|
|
|
|
res['skipped'] = False
|
|
|
|
|
|
|
|
if 'failed' in item and item['failed']:
|
|
|
|
if failed_item:
|
|
|
|
item_ignore = item.pop('_ansible_ignore_errors')
|
|
|
|
self._task.ignore_errors |= item.pop('_ansible_ignore_errors')
|
|
|
|
if not res.get('failed'):
|
|
|
|
if unreachable_item:
|
|
|
|
res['failed'] = True
|
|
|
|
self._task.ignore_unreachable |= item.pop('_ansible_ignore_unreachable')
|
|
|
|
res['msg'] = 'One or more items failed'
|
|
|
|
|
|
|
|
self._task.ignore_errors = item_ignore
|
|
|
|
warnings.update(item.pop('warnings', []))
|
|
|
|
elif self._task.ignore_errors and not item_ignore:
|
|
|
|
deprecations.update(item.pop('deprecations', []))
|
|
|
|
self._task.ignore_errors = item_ignore
|
|
|
|
|
|
|
|
if 'unreachable' in item and item['unreachable']:
|
|
|
|
if warnings:
|
|
|
|
item_ignore_unreachable = item.pop('_ansible_ignore_unreachable')
|
|
|
|
res['warnings'] = list(warnings)
|
|
|
|
if not res.get('unreachable'):
|
|
|
|
if deprecations:
|
|
|
|
res['unreachable'] = True
|
|
|
|
res['deprecations'] = list(deprecations)
|
|
|
|
self._task.ignore_unreachable = item_ignore_unreachable
|
|
|
|
|
|
|
|
elif self._task.ignore_unreachable and not item_ignore_unreachable:
|
|
|
|
if skipped:
|
|
|
|
self._task.ignore_unreachable = item_ignore_unreachable
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ensure to accumulate these
|
|
|
|
|
|
|
|
for array in ['warnings', 'deprecations']:
|
|
|
|
|
|
|
|
if array in item and item[array]:
|
|
|
|
|
|
|
|
if array not in res:
|
|
|
|
|
|
|
|
res[array] = []
|
|
|
|
|
|
|
|
if not isinstance(item[array], list):
|
|
|
|
|
|
|
|
item[array] = [item[array]]
|
|
|
|
|
|
|
|
res[array] = res[array] + item[array]
|
|
|
|
|
|
|
|
del item[array]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not res.get('failed', False):
|
|
|
|
|
|
|
|
res['msg'] = 'All items completed'
|
|
|
|
|
|
|
|
if res['skipped']:
|
|
|
|
|
|
|
|
res['msg'] = 'All items skipped'
|
|
|
|
res['msg'] = 'All items skipped'
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
res['msg'] = 'One or more items failed' if failed else 'All items completed'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
res.update(
|
|
|
|
|
|
|
|
skipped=skipped,
|
|
|
|
|
|
|
|
changed=changed,
|
|
|
|
|
|
|
|
failed=failed,
|
|
|
|
|
|
|
|
unreachable=unreachable,
|
|
|
|
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
res = dict(changed=False, skipped=True, skipped_reason='No items in the list', results=[])
|
|
|
|
res = dict(changed=False, skipped=True, skipped_reason='No items in the list', results=[])
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|