better backwards compat handling of status

restored 'rc' inspection but only when failed is not specified
removed redundant changed from basic.py as task_executor already adds
removed redundant filters, they are tests
added aliases to tests removed from filters
fixed test to new rc handling
This commit is contained in:
Brian Coca 2017-07-05 13:50:32 -04:00 committed by Brian Coca
parent fba76444e0
commit 2a041d10d2
6 changed files with 36 additions and 101 deletions

View file

@ -572,7 +572,11 @@ class TaskExecutor:
# set the failed property if it was missing. # set the failed property if it was missing.
if 'failed' not in result: if 'failed' not in result:
result['failed'] = False # rc is here for backwards compatibility and modules that use it instead of 'failed'
if 'rc' in result and result['rc'] not in [0, "0"]:
result['failed'] = True
else:
result['failed'] = False
# set the changed property if it was missing. # set the changed property if it was missing.
if 'changed' not in result: if 'changed' not in result:

View file

@ -2118,9 +2118,6 @@ class AnsibleModule(object):
def exit_json(self, **kwargs): def exit_json(self, **kwargs):
''' return from the module, without error ''' ''' return from the module, without error '''
if 'changed' not in kwargs:
kwargs['changed'] = False
self.do_cleanup_files() self.do_cleanup_files()
self._return_formatted(kwargs) self._return_formatted(kwargs)
sys.exit(0) sys.exit(0)
@ -2131,9 +2128,6 @@ class AnsibleModule(object):
assert 'msg' in kwargs, "implementation error -- msg to explain the error is required" assert 'msg' in kwargs, "implementation error -- msg to explain the error is required"
kwargs['failed'] = True kwargs['failed'] = True
if 'changed' not in kwargs:
kwargs['changed'] = False
# add traceback if debug or high verbosity and it is missing # add traceback if debug or high verbosity and it is missing
# Note: badly named as exception, it is really always been 'traceback' # Note: badly named as exception, it is really always been 'traceback'
if 'exception' not in kwargs and sys.exc_info()[2] and (self._debug or self._verbosity >= 3): if 'exception' not in kwargs and sys.exc_info()[2] and (self._debug or self._verbosity >= 3):

View file

@ -432,52 +432,6 @@ def extract(item, container, morekeys=None):
return value return value
def failed(*a, **kw):
''' Test if task result yields failed '''
item = a[0]
if not isinstance(item, MutableMapping):
raise errors.AnsibleFilterError("|failed expects a dictionary")
rc = item.get('rc', 0)
failed = item.get('failed', False)
if rc != 0 or failed:
return True
else:
return False
def success(*a, **kw):
''' Test if task result yields success '''
return not failed(*a, **kw)
def changed(*a, **kw):
''' Test if task result yields changed '''
item = a[0]
if not isinstance(item, MutableMapping):
raise errors.AnsibleFilterError("|changed expects a dictionary")
if 'changed' not in item:
changed = False
if (
'results' in item and # some modules return a 'results' key
isinstance(item['results'], MutableSequence) and
isinstance(item['results'][0], MutableMapping)
):
for result in item['results']:
changed = changed or result.get('changed', False)
else:
changed = item.get('changed', False)
return changed
def skipped(*a, **kw):
''' Test if task result yields skipped '''
item = a[0]
if not isinstance(item, MutableMapping):
raise errors.AnsibleFilterError("|skipped expects a dictionary")
skipped = item.get('skipped', False)
return skipped
@environmentfilter @environmentfilter
def do_groupby(environment, value, attribute): def do_groupby(environment, value, attribute):
"""Overridden groupby filter for jinja2, to address an issue with """Overridden groupby filter for jinja2, to address an issue with
@ -593,20 +547,6 @@ class FilterModule(object):
# array and dict lookups # array and dict lookups
'extract': extract, 'extract': extract,
# failure testing
'failed': failed,
'failure': failed,
'success': success,
'succeeded': success,
# changed testing
'changed': changed,
'change': changed,
# skip testing
'skipped': skipped,
'skip': skipped,
# debug # debug
'type_debug': lambda o: o.__class__.__name__, 'type_debug': lambda o: o.__class__.__name__,
} }

View file

@ -27,50 +27,43 @@ from distutils.version import LooseVersion, StrictVersion
from ansible import errors from ansible import errors
def failed(*a, **kw): def failed(result):
''' Test if task result yields failed ''' ''' Test if task result yields failed '''
item = a[0] if not isinstance(result, MutableMapping):
if not isinstance(item, MutableMapping):
raise errors.AnsibleFilterError("|failed expects a dictionary") raise errors.AnsibleFilterError("|failed expects a dictionary")
rc = item.get('rc', 0) return result.get('failed', False)
failed = item.get('failed', False)
if rc != 0 or failed:
return True
else:
return False
def success(*a, **kw): def success(result):
''' Test if task result yields success ''' ''' Test if task result yields success '''
return not failed(*a, **kw) return not failed(result)
def changed(*a, **kw): def changed(result):
''' Test if task result yields changed ''' ''' Test if task result yields changed '''
item = a[0] if not isinstance(result, MutableMapping):
if not isinstance(item, MutableMapping):
raise errors.AnsibleFilterError("|changed expects a dictionary") raise errors.AnsibleFilterError("|changed expects a dictionary")
if 'changed' not in item: if 'changed' not in result:
changed = False changed = False
if ( if (
'results' in item and # some modules return a 'results' key 'results' in result and # some modules return a 'results' key
isinstance(item['results'], MutableSequence) and isinstance(result['results'], MutableSequence) and
isinstance(item['results'][0], MutableMapping) isinstance(result['results'][0], MutableMapping)
): ):
for result in item['results']: for res in result['results']:
changed = changed or result.get('changed', False) if res.get('changed', False):
changed = True
break
else: else:
changed = item.get('changed', False) changed = result.get('changed', False)
return changed return changed
def skipped(*a, **kw): def skipped(result):
''' Test if task result yields skipped ''' ''' Test if task result yields skipped '''
item = a[0] if not isinstance(result, MutableMapping):
if not isinstance(item, MutableMapping):
raise errors.AnsibleFilterError("|skipped expects a dictionary") raise errors.AnsibleFilterError("|skipped expects a dictionary")
skipped = item.get('skipped', False) return result.get('skipped', False)
return skipped
def regex(value='', pattern='', ignorecase=False, multiline=False, match_type='search'): def regex(value='', pattern='', ignorecase=False, multiline=False, match_type='search'):
@ -133,13 +126,17 @@ class TestModule(object):
return { return {
# failure testing # failure testing
'failed': failed, 'failed': failed,
'failure': failed,
'succeeded': success, 'succeeded': success,
'success': success,
# changed testing # changed testing
'changed': changed, 'changed': changed,
'change': changed,
# skip testing # skip testing
'skipped': skipped, 'skipped': skipped,
'skip': skipped,
# regex # regex
'match': match, 'match': match,

View file

@ -108,11 +108,11 @@
args: args:
chdir: '{{ checkout_dir }}' chdir: '{{ checkout_dir }}'
- name: make sure the old commit was not fetched - name: "make sure the old commit was not fetched, task is 'forced success'"
assert: assert:
that: that:
- 'checkout_shallow.rc != 0' - 'checkout_shallow.rc != 0'
- checkout_shallow|failed - checkout_shallow|success
when: git_version.stdout | version_compare("{{git_version_supporting_depth}}", '>=') when: git_version.stdout | version_compare("{{git_version_supporting_depth}}", '>=')
- name: clear checkout_dir - name: clear checkout_dir

View file

@ -59,7 +59,7 @@ class TestAnsibleModuleExitJson(unittest.TestCase):
else: else:
self.assertEquals(ctx.exception.code, 0) self.assertEquals(ctx.exception.code, 0)
return_val = json.loads(self.fake_stream.getvalue()) return_val = json.loads(self.fake_stream.getvalue())
self.assertEquals(return_val, dict(changed=False, invocation=empty_invocation)) self.assertEquals(return_val, dict(invocation=empty_invocation))
def test_exit_json_args_exits(self): def test_exit_json_args_exits(self):
with self.assertRaises(SystemExit) as ctx: with self.assertRaises(SystemExit) as ctx:
@ -70,7 +70,7 @@ class TestAnsibleModuleExitJson(unittest.TestCase):
else: else:
self.assertEquals(ctx.exception.code, 0) self.assertEquals(ctx.exception.code, 0)
return_val = json.loads(self.fake_stream.getvalue()) return_val = json.loads(self.fake_stream.getvalue())
self.assertEquals(return_val, dict(msg="message", changed=False, invocation=empty_invocation)) self.assertEquals(return_val, dict(msg="message", invocation=empty_invocation))
def test_fail_json_exits(self): def test_fail_json_exits(self):
with self.assertRaises(SystemExit) as ctx: with self.assertRaises(SystemExit) as ctx:
@ -81,7 +81,7 @@ class TestAnsibleModuleExitJson(unittest.TestCase):
else: else:
self.assertEquals(ctx.exception.code, 1) self.assertEquals(ctx.exception.code, 1)
return_val = json.loads(self.fake_stream.getvalue()) return_val = json.loads(self.fake_stream.getvalue())
self.assertEquals(return_val, dict(msg="message", changed=False, failed=True, invocation=empty_invocation)) self.assertEquals(return_val, dict(msg="message", failed=True, invocation=empty_invocation))
def test_exit_json_proper_changed(self): def test_exit_json_proper_changed(self):
with self.assertRaises(SystemExit) as ctx: with self.assertRaises(SystemExit) as ctx:
@ -98,7 +98,7 @@ class TestAnsibleModuleExitValuesRemoved(unittest.TestCase):
dict(one=1, pwd='$ecret k3y', url='https://username:password12345@foo.com/login/', dict(one=1, pwd='$ecret k3y', url='https://username:password12345@foo.com/login/',
not_secret='following the leader', msg='here'), not_secret='following the leader', msg='here'),
dict(one=1, pwd=OMIT, url='https://username:password12345@foo.com/login/', dict(one=1, pwd=OMIT, url='https://username:password12345@foo.com/login/',
not_secret='following the leader', changed=False, msg='here', not_secret='following the leader', msg='here',
invocation=dict(module_args=dict(password=OMIT, token=None, username='person'))), invocation=dict(module_args=dict(password=OMIT, token=None, username='person'))),
), ),
( (
@ -106,7 +106,7 @@ class TestAnsibleModuleExitValuesRemoved(unittest.TestCase):
dict(one=1, pwd='$ecret k3y', url='https://username:password12345@foo.com/login/', dict(one=1, pwd='$ecret k3y', url='https://username:password12345@foo.com/login/',
not_secret='following the leader', msg='here'), not_secret='following the leader', msg='here'),
dict(one=1, pwd='$ecret k3y', url='https://username:********@foo.com/login/', dict(one=1, pwd='$ecret k3y', url='https://username:********@foo.com/login/',
not_secret='following the leader', changed=False, msg='here', not_secret='following the leader', msg='here',
invocation=dict(module_args=dict(password=OMIT, token=None, username='person'))), invocation=dict(module_args=dict(password=OMIT, token=None, username='person'))),
), ),
( (
@ -114,7 +114,7 @@ class TestAnsibleModuleExitValuesRemoved(unittest.TestCase):
dict(one=1, pwd='$ecret k3y', url='https://username:$ecret k3y@foo.com/login/', dict(one=1, pwd='$ecret k3y', url='https://username:$ecret k3y@foo.com/login/',
not_secret='following the leader', msg='here'), not_secret='following the leader', msg='here'),
dict(one=1, pwd=OMIT, url='https://username:********@foo.com/login/', dict(one=1, pwd=OMIT, url='https://username:********@foo.com/login/',
not_secret='following the leader', changed=False, msg='here', not_secret='following the leader', msg='here',
invocation=dict(module_args=dict(password=OMIT, token=None, username='person'))), invocation=dict(module_args=dict(password=OMIT, token=None, username='person'))),
), ),
) )