Improve cloudwatchevent_rule exception handling (#30823)

* Fix cloudwatchevent_rule exception handling

Where it is currently present, this change fixes the exception handling.
However, there are many places that it is lacking.

Fixes #30806

* Add new exception handling for cloudwatchevent_rule

Ensure all API calls are wrapped with exception handling

* PEP8 tidy up

* Remove unnecessary HAS_BOTO3 import and checks

Tidy up documentation so that NO_QA can be removed
pull/28844/head
Will Thames 7 years ago committed by Sloane Hertel
parent a14d0f3586
commit ce2f5d26ab

@ -107,24 +107,27 @@ rule:
description: CloudWatch Event rule data description: CloudWatch Event rule data
returned: success returned: success
type: dict type: dict
sample: "{ 'arn': 'arn:aws:events:us-east-1:123456789012:rule/MyCronTask', 'description': 'Run my scheduled task', 'name': 'MyCronTask', 'schedule_expression': 'cron(0 20 * * ? *)', 'state': 'ENABLED' }" sample:
arn: 'arn:aws:events:us-east-1:123456789012:rule/MyCronTask'
description: 'Run my scheduled task'
name: 'MyCronTask'
schedule_expression: 'cron(0 20 * * ? *)'
state: 'ENABLED'
targets: targets:
description: CloudWatch Event target(s) assigned to the rule description: CloudWatch Event target(s) assigned to the rule
returned: success returned: success
type: list type: list
sample: "[{ 'arn': 'arn:aws:lambda:us-east-1:123456789012:function:MyFunction', 'id': 'MyTargetId' }]" sample: "[{ 'arn': 'arn:aws:lambda:us-east-1:123456789012:function:MyFunction', 'id': 'MyTargetId' }]"
''' # NOQA '''
try: try:
import boto3.exception import botocore
import botocore.exceptions
except ImportError: except ImportError:
# module_utils.ec2.HAS_BOTO3 will do the right thing pass # handled by AnsibleAWSModule
pass
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.aws.core import AnsibleAWSModule
from ansible.module_utils.ec2 import (HAS_BOTO3, boto3_conn, camel_dict_to_snake_dict, from ansible.module_utils.ec2 import boto3_conn, camel_dict_to_snake_dict
ec2_argument_spec, get_aws_connection_info) from ansible.module_utils.ec2 import ec2_argument_spec, get_aws_connection_info
class CloudWatchEventRule(object): class CloudWatchEventRule(object):
@ -137,6 +140,7 @@ class CloudWatchEventRule(object):
self.event_pattern = event_pattern self.event_pattern = event_pattern
self.description = description self.description = description
self.role_arn = role_arn self.role_arn = role_arn
self.module = module
def describe(self): def describe(self):
"""Returns the existing details of the rule in AWS""" """Returns the existing details of the rule in AWS"""
@ -146,7 +150,9 @@ class CloudWatchEventRule(object):
error_code = e.response.get('Error', {}).get('Code') error_code = e.response.get('Error', {}).get('Code')
if error_code == 'ResourceNotFoundException': if error_code == 'ResourceNotFoundException':
return {} return {}
raise self.module.fail_json_aws(e, msg="Could not describe rule %s" % self.name)
except botocore.exceptions.BotoCoreError as e:
self.module.fail_json_aws(e, msg="Could not describe rule %s" % self.name)
return self._snakify(rule_info) return self._snakify(rule_info)
def put(self, enabled=True): def put(self, enabled=True):
@ -163,26 +169,39 @@ class CloudWatchEventRule(object):
request['Description'] = self.description request['Description'] = self.description
if self.role_arn: if self.role_arn:
request['RoleArn'] = self.role_arn request['RoleArn'] = self.role_arn
try:
response = self.client.put_rule(**request) response = self.client.put_rule(**request)
except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
self.module.fail_json_aws(e, msg="Could not create/update rule %s" % self.name)
self.changed = True self.changed = True
return response return response
def delete(self): def delete(self):
"""Deletes the rule in AWS""" """Deletes the rule in AWS"""
self.remove_all_targets() self.remove_all_targets()
try:
response = self.client.delete_rule(Name=self.name) response = self.client.delete_rule(Name=self.name)
except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
self.module.fail_json_aws(e, msg="Could not delete rule %s" % self.name)
self.changed = True self.changed = True
return response return response
def enable(self): def enable(self):
"""Enables the rule in AWS""" """Enables the rule in AWS"""
try:
response = self.client.enable_rule(Name=self.name) response = self.client.enable_rule(Name=self.name)
except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
self.module.fail_json_aws(e, msg="Could not enable rule %s" % self.name)
self.changed = True self.changed = True
return response return response
def disable(self): def disable(self):
"""Disables the rule in AWS""" """Disables the rule in AWS"""
try:
response = self.client.disable_rule(Name=self.name) response = self.client.disable_rule(Name=self.name)
except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
self.module.fail_json_aws(e, msg="Could not disable rule %s" % self.name)
self.changed = True self.changed = True
return response return response
@ -194,7 +213,9 @@ class CloudWatchEventRule(object):
error_code = e.response.get('Error', {}).get('Code') error_code = e.response.get('Error', {}).get('Code')
if error_code == 'ResourceNotFoundException': if error_code == 'ResourceNotFoundException':
return [] return []
raise self.module.fail_json_aws(e, msg="Could not find target for rule %s" % self.name)
except botocore.exceptions.BotoCoreError as e:
self.module.fail_json_aws(e, msg="Could not find target for rule %s" % self.name)
return self._snakify(targets)['targets'] return self._snakify(targets)['targets']
def put_targets(self, targets): def put_targets(self, targets):
@ -205,7 +226,10 @@ class CloudWatchEventRule(object):
'Rule': self.name, 'Rule': self.name,
'Targets': self._targets_request(targets), 'Targets': self._targets_request(targets),
} }
try:
response = self.client.put_targets(**request) response = self.client.put_targets(**request)
except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
self.module.fail_json_aws(e, msg="Could not create/update rule targets for rule %s" % self.name)
self.changed = True self.changed = True
return response return response
@ -217,7 +241,10 @@ class CloudWatchEventRule(object):
'Rule': self.name, 'Rule': self.name,
'Ids': target_ids 'Ids': target_ids
} }
try:
response = self.client.remove_targets(**request) response = self.client.remove_targets(**request)
except (botocore.exceptions.BotoCoreError, botocore.exceptions.ClientError) as e:
self.module.fail_json_aws(e, msg="Could not remove rule targets from rule %s" % self.name)
self.changed = True self.changed = True
return response return response
@ -379,13 +406,14 @@ def get_cloudwatchevents_client(module):
resource='events', resource='events',
region=region, endpoint=ec2_url, region=region, endpoint=ec2_url,
**aws_conn_kwargs) **aws_conn_kwargs)
except boto3.exception.NoAuthHandlerFound as e: except botocore.exceptions.ProfileNotFound as e:
module.fail_json(msg=str(e)) module.fail_json(msg=str(e))
def main(): def main():
argument_spec = ec2_argument_spec() argument_spec = ec2_argument_spec()
argument_spec.update(dict( argument_spec.update(
dict(
name=dict(required=True), name=dict(required=True),
schedule_expression=dict(), schedule_expression=dict(),
event_pattern=dict(), event_pattern=dict(),
@ -394,11 +422,9 @@ def main():
description=dict(), description=dict(),
role_arn=dict(), role_arn=dict(),
targets=dict(type='list', default=[]), targets=dict(type='list', default=[]),
)) )
module = AnsibleModule(argument_spec=argument_spec) )
module = AnsibleAWSModule(argument_spec=argument_spec)
if not HAS_BOTO3:
module.fail_json(msg='boto3 required for this module')
rule_data = dict( rule_data = dict(
[(rf, module.params.get(rf)) for rf in CloudWatchEventRuleManager.RULE_FIELDS] [(rf, module.params.get(rf)) for rf in CloudWatchEventRuleManager.RULE_FIELDS]

@ -14,7 +14,6 @@ lib/ansible/modules/cloud/amazon/aws_kms.py
lib/ansible/modules/cloud/amazon/cloudformation.py lib/ansible/modules/cloud/amazon/cloudformation.py
lib/ansible/modules/cloud/amazon/cloudformation_facts.py lib/ansible/modules/cloud/amazon/cloudformation_facts.py
lib/ansible/modules/cloud/amazon/cloudfront_facts.py lib/ansible/modules/cloud/amazon/cloudfront_facts.py
lib/ansible/modules/cloud/amazon/cloudwatchevent_rule.py
lib/ansible/modules/cloud/amazon/dynamodb_table.py lib/ansible/modules/cloud/amazon/dynamodb_table.py
lib/ansible/modules/cloud/amazon/ec2_ami_copy.py lib/ansible/modules/cloud/amazon/ec2_ami_copy.py
lib/ansible/modules/cloud/amazon/ec2_ami_find.py lib/ansible/modules/cloud/amazon/ec2_ami_find.py

Loading…
Cancel
Save