mirror of
https://github.com/saltstack/salt.git
synced 2025-04-16 01:30:20 +00:00
325 lines
9.7 KiB
Python
325 lines
9.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
Connection module for Amazon CloudWatch Events
|
|
|
|
.. versionadded:: 2016.11.0
|
|
|
|
:configuration: This module accepts explicit credentials but can also utilize
|
|
IAM roles assigned to the instance through Instance Profiles. Dynamic
|
|
credentials are then automatically obtained from AWS API and no further
|
|
configuration is necessary. More Information available at:
|
|
|
|
.. code-block:: text
|
|
|
|
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
|
|
|
|
If IAM roles are not used you need to specify them either in a pillar or
|
|
in the minion's config file:
|
|
|
|
.. code-block:: yaml
|
|
|
|
cloudwatch_event.keyid: GKTADJGHEIQSXMKKRBJ08H
|
|
cloudwatch_event.key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
|
|
|
A region may also be specified in the configuration:
|
|
|
|
.. code-block:: yaml
|
|
|
|
cloudwatch_event.region: us-east-1
|
|
|
|
If a region is not specified, the default is us-east-1.
|
|
|
|
It's also possible to specify key, keyid and region via a profile, either
|
|
as a passed in dict, or as a string to pull from pillars or minion config:
|
|
|
|
.. code-block:: yaml
|
|
|
|
myprofile:
|
|
keyid: GKTADJGHEIQSXMKKRBJ08H
|
|
key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
|
|
region: us-east-1
|
|
|
|
:depends: boto3
|
|
'''
|
|
# keep lint from choking on _get_conn and _cache_id
|
|
#pylint: disable=E0602
|
|
|
|
from __future__ import absolute_import
|
|
|
|
# Import Python libs
|
|
import logging
|
|
import salt.utils.json
|
|
import salt.utils.compat
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
# Import third party libs
|
|
# pylint: disable=import-error
|
|
try:
|
|
#pylint: disable=unused-import
|
|
import boto
|
|
import boto3
|
|
#pylint: enable=unused-import
|
|
from botocore.exceptions import ClientError
|
|
logging.getLogger('boto3').setLevel(logging.CRITICAL)
|
|
HAS_BOTO = True
|
|
except ImportError as e:
|
|
HAS_BOTO = False
|
|
# pylint: enable=import-error
|
|
|
|
from salt.ext import six
|
|
|
|
|
|
def __virtual__():
|
|
'''
|
|
Only load if boto libraries exist.
|
|
'''
|
|
if not HAS_BOTO:
|
|
return (False, 'The boto_cloudwatch_event module cannot be loaded: boto libraries are unavailable.')
|
|
return True
|
|
|
|
|
|
def __init__(opts):
|
|
salt.utils.compat.pack_dunder(__name__)
|
|
if HAS_BOTO:
|
|
__utils__['boto3.assign_funcs'](__name__, 'events')
|
|
|
|
|
|
def exists(Name, region=None, key=None, keyid=None, profile=None):
|
|
'''
|
|
Given a rule name, check to see if the given rule exists.
|
|
|
|
Returns True if the given rule exists and returns False if the given
|
|
rule does not exist.
|
|
|
|
CLI example::
|
|
|
|
salt myminion boto_cloudwatch_event.exists myevent region=us-east-1
|
|
'''
|
|
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
|
|
|
try:
|
|
events = conn.list_rules(NamePrefix=Name)
|
|
if len(events) == 0:
|
|
return {'exists': False}
|
|
for rule in events.get('Rules', []):
|
|
if rule.get('Name', None) == Name:
|
|
return {'exists': True}
|
|
return {'exists': False}
|
|
except ClientError as e:
|
|
err = __utils__['boto3.get_error'](e)
|
|
return {'error': err}
|
|
|
|
|
|
def create_or_update(Name,
|
|
ScheduleExpression=None,
|
|
EventPattern=None,
|
|
Description=None,
|
|
RoleArn=None,
|
|
State=None,
|
|
region=None, key=None, keyid=None, profile=None):
|
|
'''
|
|
Given a valid config, create an event rule.
|
|
|
|
Returns {created: true} if the rule was created and returns
|
|
{created: False} if the rule was not created.
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion boto_cloudwatch_event.create_or_update my_rule
|
|
|
|
'''
|
|
|
|
try:
|
|
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
|
kwargs = {}
|
|
for arg in ('ScheduleExpression', 'EventPattern', 'State',
|
|
'Description', 'RoleArn'):
|
|
if locals()[arg] is not None:
|
|
kwargs[arg] = locals()[arg]
|
|
rule = conn.put_rule(Name=Name,
|
|
**kwargs)
|
|
if rule:
|
|
log.info('The newly created event rule is {0}'.format(rule.get('RuleArn')))
|
|
|
|
return {'created': True, 'arn': rule.get('RuleArn')}
|
|
else:
|
|
log.warning('Event rule was not created')
|
|
return {'created': False}
|
|
except ClientError as e:
|
|
return {'created': False, 'error': __utils__['boto3.get_error'](e)}
|
|
|
|
|
|
def delete(Name,
|
|
region=None, key=None, keyid=None, profile=None):
|
|
'''
|
|
Given a rule name, delete it.
|
|
|
|
Returns {deleted: true} if the rule was deleted and returns
|
|
{deleted: false} if the rule was not deleted.
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion boto_cloudwatch_event.delete myrule
|
|
|
|
'''
|
|
|
|
try:
|
|
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
|
conn.delete_rule(Name=Name)
|
|
return {'deleted': True}
|
|
except ClientError as e:
|
|
return {'deleted': False, 'error': __utils__['boto3.get_error'](e)}
|
|
|
|
|
|
def describe(Name,
|
|
region=None, key=None, keyid=None, profile=None):
|
|
'''
|
|
Given a rule name describe its properties.
|
|
|
|
Returns a dictionary of interesting properties.
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion boto_cloudwatch_event.describe myrule
|
|
|
|
'''
|
|
|
|
try:
|
|
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
|
rule = conn.describe_rule(Name=Name)
|
|
if rule:
|
|
keys = ('Name', 'Arn', 'EventPattern',
|
|
'ScheduleExpression', 'State',
|
|
'Description',
|
|
'RoleArn')
|
|
return {'rule': dict([(k, rule.get(k)) for k in keys])}
|
|
else:
|
|
return {'rule': None}
|
|
except ClientError as e:
|
|
err = __utils__['boto3.get_error'](e)
|
|
if e.response.get('Error', {}).get('Code') == 'RuleNotFoundException':
|
|
return {'error': "Rule {0} not found".format(Rule)}
|
|
return {'error': __utils__['boto3.get_error'](e)}
|
|
|
|
|
|
def list_rules(region=None, key=None, keyid=None, profile=None):
|
|
'''
|
|
List, with details, all Cloudwatch Event rules visible in the current scope.
|
|
|
|
CLI example::
|
|
|
|
salt myminion boto_cloudwatch_event.list_rules region=us-east-1
|
|
'''
|
|
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
|
|
|
try:
|
|
ret = []
|
|
NextToken = ''
|
|
while NextToken is not None:
|
|
args = {'NextToken': NextToken} if NextToken else {}
|
|
r = conn.list_rules(**args)
|
|
ret += r.get('Rules', [])
|
|
NextToken = r.get('NextToken')
|
|
return ret
|
|
except ClientError as e:
|
|
return {'error': __utils__['boto3.get_error'](e)}
|
|
|
|
|
|
def list_targets(Rule,
|
|
region=None, key=None, keyid=None, profile=None):
|
|
'''
|
|
Given a rule name list the targets of that rule.
|
|
|
|
Returns a dictionary of interesting properties.
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion boto_cloudwatch_event.list_targets myrule
|
|
|
|
'''
|
|
try:
|
|
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
|
targets = conn.list_targets_by_rule(Rule=Rule)
|
|
ret = []
|
|
if targets and 'Targets' in targets:
|
|
keys = ('Id', 'Arn', 'Input',
|
|
'InputPath')
|
|
for target in targets.get('Targets'):
|
|
ret.append(dict([(k, target.get(k)) for k in keys if k in target]))
|
|
return {'targets': ret}
|
|
else:
|
|
return {'targets': None}
|
|
except ClientError as e:
|
|
err = __utils__['boto3.get_error'](e)
|
|
if e.response.get('Error', {}).get('Code') == 'RuleNotFoundException':
|
|
return {'error': "Rule {0} not found".format(Rule)}
|
|
return {'error': __utils__['boto3.get_error'](e)}
|
|
|
|
|
|
def put_targets(Rule, Targets,
|
|
region=None, key=None, keyid=None, profile=None):
|
|
'''
|
|
Add the given targets to the given rule
|
|
|
|
Returns a dictionary describing any failures.
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion boto_cloudwatch_event.put_targets myrule [{'Id': 'target1', 'Arn': 'arn:***'}]
|
|
|
|
'''
|
|
try:
|
|
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
|
if isinstance(Targets, six.string_types):
|
|
Targets = salt.utils.json.loads(Targets)
|
|
failures = conn.put_targets(Rule=Rule, Targets=Targets)
|
|
if failures and failures.get('FailedEntryCount', 0) > 0:
|
|
return {'failures': failures.get('FailedEntries')}
|
|
else:
|
|
return {'failures': None}
|
|
except ClientError as e:
|
|
err = __utils__['boto3.get_error'](e)
|
|
if e.response.get('Error', {}).get('Code') == 'RuleNotFoundException':
|
|
return {'error': "Rule {0} not found".format(Rule)}
|
|
return {'error': __utils__['boto3.get_error'](e)}
|
|
|
|
|
|
def remove_targets(Rule, Ids,
|
|
region=None, key=None, keyid=None, profile=None):
|
|
'''
|
|
Given a rule name remove the named targets from the target list
|
|
|
|
Returns a dictionary describing any failures.
|
|
|
|
CLI Example:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion boto_cloudwatch_event.remove_targets myrule ['Target1']
|
|
|
|
'''
|
|
try:
|
|
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
|
if isinstance(Ids, six.string_types):
|
|
Ids = salt.utils.json.loads(Ids)
|
|
failures = conn.remove_targets(Rule=Rule, Ids=Ids)
|
|
if failures and failures.get('FailedEntryCount', 0) > 0:
|
|
return {'failures': failures.get('FailedEntries', 1)}
|
|
else:
|
|
return {'failures': None}
|
|
except ClientError as e:
|
|
err = __utils__['boto3.get_error'](e)
|
|
if e.response.get('Error', {}).get('Code') == 'RuleNotFoundException':
|
|
return {'error': "Rule {0} not found".format(Rule)}
|
|
return {'error': __utils__['boto3.get_error'](e)}
|