Recursively remove args with omit as as their value, to match suboptions in argument_spec (#35299)

* Recursively remove args with omit as as their value, to match suboptions in argument_spec

* Add test for the new remove_omit function

(cherry picked from commit 7404dc6767)
This commit is contained in:
Matt Martz 2018-01-26 11:07:04 -06:00 committed by Toshio Kuratomi
parent 0ac3c990ed
commit 32ddcf96df
2 changed files with 55 additions and 2 deletions

View file

@ -46,6 +46,24 @@ except ImportError:
__all__ = ['TaskExecutor'] __all__ = ['TaskExecutor']
def remove_omit(task_args, omit_token):
'''
Remove args with a value equal to the ``omit_token`` recursively
to align with now having suboptions in the argument_spec
'''
new_args = {}
for i in iteritems(task_args):
if i[1] == omit_token:
continue
elif isinstance(i[1], dict):
new_args[i[0]] = remove_omit(i[1], omit_token)
else:
new_args[i[0]] = i[1]
return new_args
class TaskExecutor: class TaskExecutor:
''' '''
@ -498,7 +516,7 @@ class TaskExecutor:
# And filter out any fields which were set to default(omit), and got the omit token value # And filter out any fields which were set to default(omit), and got the omit token value
omit_token = variables.get('omit') omit_token = variables.get('omit')
if omit_token is not None: if omit_token is not None:
self._task.args = dict((i[0], i[1]) for i in iteritems(self._task.args) if i[1] != omit_token) self._task.args = remove_omit(self._task.args, omit_token)
# Read some values from the task, so that we can modify them if need be # Read some values from the task, so that we can modify them if need be
if self._task.until: if self._task.until:

View file

@ -22,7 +22,7 @@ __metaclass__ = type
from ansible.compat.tests import unittest from ansible.compat.tests import unittest
from ansible.compat.tests.mock import patch, MagicMock from ansible.compat.tests.mock import patch, MagicMock
from ansible.errors import AnsibleError, AnsibleParserError from ansible.errors import AnsibleError, AnsibleParserError
from ansible.executor.task_executor import TaskExecutor from ansible.executor.task_executor import TaskExecutor, remove_omit
from ansible.playbook.play_context import PlayContext from ansible.playbook.play_context import PlayContext
from ansible.plugins.loader import action_loader, lookup_loader from ansible.plugins.loader import action_loader, lookup_loader
from ansible.parsing.yaml.objects import AnsibleUnicode from ansible.parsing.yaml.objects import AnsibleUnicode
@ -484,3 +484,38 @@ class TestTaskExecutor(unittest.TestCase):
mock_templar = MagicMock() mock_templar = MagicMock()
res = te._poll_async_result(result=dict(ansible_job_id=1), templar=mock_templar) res = te._poll_async_result(result=dict(ansible_job_id=1), templar=mock_templar)
self.assertEqual(res, dict(finished=1)) self.assertEqual(res, dict(finished=1))
def test_recursive_remove_omit(self):
omit_token = 'POPCORN'
data = {
'foo': 'bar',
'baz': 1,
'qux': ['one', 'two', 'three'],
'subdict': {
'remove': 'POPCORN',
'keep': 'not_popcorn',
'subsubdict': {
'remove': 'POPCORN',
'keep': 'not_popcorn',
},
'a_list': ['POPCORN'],
},
'a_list': ['POPCORN'],
}
expected = {
'foo': 'bar',
'baz': 1,
'qux': ['one', 'two', 'three'],
'subdict': {
'keep': 'not_popcorn',
'subsubdict': {
'keep': 'not_popcorn',
},
'a_list': ['POPCORN'],
},
'a_list': ['POPCORN'],
}
self.assertEqual(remove_omit(data, omit_token), expected)