diff options
author | Ryan S. Brown <sb@ryansb.com> | 2016-10-18 10:58:09 -0400 |
---|---|---|
committer | Ryan S. Brown <sb@ryansb.com> | 2016-10-19 11:41:58 -0400 |
commit | cd9e39420bc1676ff7ed84f933e8e4e78c485bef (patch) | |
tree | 008bf56d036ccf08df2cb522056759c5a2c01962 | |
parent | d8b015d9c8607323a70c4fe7f026e0927376b0cd (diff) | |
download | ansible-modules-core-cd9e39420bc1676ff7ed84f933e8e4e78c485bef.tar.gz |
Fix cloudformation module return parameter documentation
Always return stack outputs, even if only an empty dict
-rw-r--r-- | cloud/amazon/cloudformation.py | 62 |
1 files changed, 34 insertions, 28 deletions
diff --git a/cloud/amazon/cloudformation.py b/cloud/amazon/cloudformation.py index 2d1890c4..5e7a5066 100644 --- a/cloud/amazon/cloudformation.py +++ b/cloud/amazon/cloudformation.py @@ -161,20 +161,24 @@ log: returned: always type: list sample: ["updating stack"] - stack_resources: - description: AWS stack resources and their status. List of dictionaries, one dict per resource. - type: list - sample: [ - { - "last_updated_time": "2016-10-11T19:40:14.979000+00:00", - "logical_resource_id": "CFTestSg", - "physical_resource_id": "cloudformation2-CFTestSg-16UQ4CYQ57O9F", - "resource_type": "AWS::EC2::SecurityGroup", - "status": "UPDATE_COMPLETE", - "status_reason": null - } - ] - +stack_resources: + description: AWS stack resources and their status. List of dictionaries, one dict per resource. + type: list + sample: [ + { + "last_updated_time": "2016-10-11T19:40:14.979000+00:00", + "logical_resource_id": "CFTestSg", + "physical_resource_id": "cloudformation2-CFTestSg-16UQ4CYQ57O9F", + "resource_type": "AWS::EC2::SecurityGroup", + "status": "UPDATE_COMPLETE", + "status_reason": null + } + ] +stack_outputs: + type: dict + description: A key:value dictionary of all the stack outputs currently defined. If there are no stack outputs, it is an empty dictionary. + returned: always + sample: {"MySg": "AnsibleModuleTestYAML-CFTestSg-C8UVS567B6NS"} ''' import json @@ -218,13 +222,13 @@ def boto_version_required(version_tuple): def get_stack_events(cfn, stack_name): '''This event data was never correct, it worked as a side effect. So the v2.3 format is different.''' - ret = { 'events':[], 'log':[] } + ret = {'events':[], 'log':[]} try: events = cfn.describe_stack_events(StackName=stack_name) - except (botocore.exceptions.ValidationError,botocore.exceptions.ClientError) as err: + except (botocore.exceptions.ValidationError, botocore.exceptions.ClientError) as err: error_msg = boto_exception(err) - if 'does not exist'.format(stack_name) in error_msg: + if 'does not exist' in error_msg: # missing stack, don't bail. ret['log'].append('Stack does not exist.') return ret @@ -253,36 +257,35 @@ def stack_operation(cfn, stack_name, operation): # been deleted successfully. if 'yes' in existed or operation == 'DELETE': # stacks may delete fast, look in a few ways. ret = get_stack_events(cfn, stack_name) - ret.update({ 'changed': True, 'output': 'Stack Deleted'}) + ret.update({'changed': True, 'output': 'Stack Deleted'}) return ret else: return {'changed': True, 'failed': True, 'output': 'Stack Not Found', 'exception': traceback.format_exc()} ret = get_stack_events(cfn, stack_name) if not stack: - if 'yes' in existed or operation=='DELETE': # stacks may delete fast, look in a few ways. + if 'yes' in existed or operation == 'DELETE': # stacks may delete fast, look in a few ways. ret = get_stack_events(cfn, stack_name) - ret.update({ 'changed': True, 'output': 'Stack Deleted'}) + ret.update({'changed': True, 'output': 'Stack Deleted'}) return ret else: - ret.update({'changed':False, 'failed':True, 'output' : 'Stack not found.'}) + ret.update({'changed': False, 'failed': True, 'output' : 'Stack not found.'}) return ret elif stack['StackStatus'].endswith('_ROLLBACK_COMPLETE'): - ret.update({'changed':True, 'failed':True, 'output' : 'Problem with %s. Rollback complete' % operation}) + ret.update({'changed': True, 'failed' :True, 'output': 'Problem with %s. Rollback complete' % operation}) return ret # note the ordering of ROLLBACK_COMPLETE and COMPLETE, because otherwise COMPLETE will match both cases. elif stack['StackStatus'].endswith('_COMPLETE'): - ret.update({'changed':True, 'output' : 'Stack %s complete' % operation }) + ret.update({'changed': True, 'output' : 'Stack %s complete' % operation }) return ret elif stack['StackStatus'].endswith('_ROLLBACK_FAILED'): - ret.update({'changed':True, 'failed':True, 'output' : 'Stack %s rollback failed' % operation}) + ret.update({'changed': True, 'failed': True, 'output': 'Stack %s rollback failed' % operation}) return ret # note the ordering of ROLLBACK_FAILED and FAILED, because otherwise FAILED will match both cases. elif stack['StackStatus'].endswith('_FAILED'): - ret.update({'changed':True, 'failed':True, 'output': 'Stack %s failed' % operation}) + ret.update({'changed': True, 'failed': True, 'output': 'Stack %s failed' % operation}) return ret else: # this can loop forever :/ - #return dict(changed=True, failed=True, output = str(stack), operation=operation) time.sleep(5) return {'failed': True, 'output':'Failed for unknown reasons.'} @@ -347,7 +350,7 @@ def main(): mutually_exclusive=[['template_url', 'template']], ) if not HAS_BOTO3: - module.fail_json(msg='boto3 required for this module') + module.fail_json(msg='boto3 and botocore are required for this module') # collect the parameters that are passed to boto3. Keeps us from having so many scalars floating around. stack_params = { @@ -434,6 +437,9 @@ def main(): if state == 'present' or update: stack = get_stack_facts(cfn, stack_params['StackName']) + if result.get('stack_outputs') is None: + # always define stack_outputs, but it may be empty + result['stack_outputs'] = {} for output in stack.get('Outputs', []): result['stack_outputs'][output['OutputKey']] = output['OutputValue'] stack_resources = [] @@ -458,7 +464,7 @@ def main(): try: stack = get_stack_facts(cfn, stack_params['StackName']) if not stack: - result = dict(changed=False, output='Stack not found.') + result = {'changed': False, 'output': 'Stack not found.'} else: cfn.delete_stack(StackName=stack_params['StackName']) result = stack_operation(cfn, stack_params['StackName'], 'DELETE') |