<commit_before>#!/usr/bin/python
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.

DOCUMENTATION = """
module: ec2_metric_alarm
short_description: "Create/update or delete AWS Cloudwatch 'metric alarms'"
description:
 - Can create or delete AWS metric alarms
 - Metrics you wish to alarm on must already exist
version_added: "1.6"
author: <NAME>
options:
    state:
        description:
          - register or deregister the alarm
        required: true
        choices: ['present', 'absent']
    name:
        desciption:
          - Unique name for the alarm
        required: true
    metric:
        description:
          - Name of the monitored metric (e.g. CPUUtilization)
          - Metric must already exist
        required: false
    namespace:
        description:
          - Name of the appropriate namespace ('AWS/EC2', 'System/Linux', etc.), which determines the category it will appear under in cloudwatch
        required: false
    statistic:
        description:
          - Operation applied to the metric
          - Works in conjunction with period and evaluation_periods to determine the comparison value
        required: false
        options: ['SampleCount','Average','Sum','Minimum','Maximum']
    comparison:
        description:
          - Determines how the threshold value is compared
        required: false
        options: ['<=','<','>','>=']
    threshold:
        description:
          - Sets the min/max bound for triggering the alarm
        required: false
    period:
        description:
          - The time (in seconds) between metric evaluations
        required: false
    evaluation_periods:
        description:
          - The number of times in which the metric is evaluated before final calculation
        required: false
    unit:
        description:
          - The threshold's unit of measurement
        required: false
        options: ['Seconds','Microseconds','Milliseconds','Bytes','Kilobytes','Megabytes','Gigabytes','Terabytes','Bits','Kilobits','Megabits','Gigabits','Terabits','Percent','Count','Bytes/Second','Kilobytes/Second','Megabytes/Second','Gigabytes/Second','Terabytes/Second','Bits/Second','Kilobits/Second','Megabits/Second','Gigabits/Second','Terabits/Second','Count/Second','None']
    description:
        description:
          - A longer desciption of the alarm
        required: false
    dimensions:
        description:
          - Describes to what the alarm is applied
        required: false
    alarm_actions:
        description:
          - A list of the names action(s) taken when the alarm is in the 'alarm' status
        required: false
    insufficient_data_actions:
        description:
          - A list of the names of action(s) to take when the alarm is in the 'insufficient_data' status
        required: false
    ok_actions:
        description:
          - A list of the names of action(s) to take when the alarm is in the 'ok' status
        required: false
extends_documentation_fragment: aws
"""

EXAMPLES = '''
  - name: create alarm
    ec2_metric_alarm:
      state: present
      region: ap-southeast-2
      name: "cpu-low"
      metric: "CPUUtilization"
      namespace: "AWS/EC2"
      statistic: Average
      comparison: "<="
      threshold: 5.0
      period: 300
      evaluation_periods: 3
      unit: "Percent"
      description: "This will alarm when a bamboo slave's cpu usage average is lower than 5% for 15 minutes "
      dimensions: {'InstanceId':'i-XXX'}
      alarm_actions: ["action1","action2"]


'''

import sys

from ansible.module_utils.basic import *
from ansible.module_utils.ec2 import *

try:
    import boto.ec2.cloudwatch
    from boto.ec2.cloudwatch import CloudWatchConnection, MetricAlarm
    from boto.exception import BotoServerError
except ImportError:
    print "failed=True msg='boto required for this module'"
    sys.exit(1)


def create_metric_alarm(connection, module):

    name = module.params.get('name')
    metric = module.params.get('metric')
    namespace = module.params.get('namespace')
    statistic = module.params.get('statistic')
    comparison = module.params.get('comparison')
    threshold = module.params.get('threshold')
    period = module.params.get('period')
    evaluation_periods = module.params.get('evaluation_periods')
    unit = module.params.get('unit')
    description = module.params.get('description')
    dimensions = module.params.get('dimensions')
    alarm_actions = module.params.get('alarm_actions')
    insufficient_data_actions = module.params.get('insufficient_data_actions')
    ok_actions = module.params.get('ok_actions')

    alarms = connection.describe_alarms(alarm_names=[name])

    if not alarms:

        alm = MetricAlarm(
            name=name,
            metric=metric,
            namespace=namespace,
            statistic=statistic,
            comparison=comparison,
            threshold=threshold,
            period=period,
            evaluation_periods=evaluation_periods,
            unit=unit,
            description=description,
            dimensions=dimensions,
            alarm_actions=alarm_actions,
            insufficient_data_actions=insufficient_data_actions,
            ok_actions=ok_actions
        )
        try:
            connection.create_alarm(alm)
            changed = True
            alarms = connection.describe_alarms(alarm_names=[name])
        except BotoServerError, e:
            module.fail_json(msg=str(e))

    else:
        alarm = alarms[0]
        changed = False

        for attr in ('comparison','metric','namespace','statistic','threshold','period','evaluation_periods','unit','description'):
            if getattr(alarm, attr) != module.params.get(attr):
                changed = True
                setattr(alarm, attr, module.params.get(attr))
        #this is to deal with a current bug where you cannot assign '<=>' to the comparator when modifying an existing alarm
        comparison = alarm.comparison
        comparisons = {'<=' : 'LessThanOrEqualToThreshold', '<' : 'LessThanThreshold', '>=' : 'GreaterThanOrEqualToThreshold', '>' : 'GreaterThanThreshold'}
        alarm.comparison = comparisons[comparison]

        dim1 = module.params.get('dimensions')
        dim2 = alarm.dimensions

        for keys in dim1:
            if not isinstance(dim1[keys], list):
                dim1[keys] = [dim1[keys]]
            if dim1[keys] != dim2[keys]:
                changed=True
                setattr(alarm, 'dimensions', dim1)

        for attr in ('alarm_actions','insufficient_data_actions','ok_actions'):
            action = module.params.get(attr) or []
            if getattr(alarm, attr) != action:
                changed = True
                setattr(alarm, attr, module.params.get(attr))
<commit_msg>check keys is in dim2 before evaluating<commit_after>#!/usr/bin/python
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.

DOCUMENTATION = """
module: ec2_metric_alarm
short_description: "Create/update or delete AWS Cloudwatch 'metric alarms'"
description:
 - Can create or delete AWS metric alarms
 - Metrics you wish to alarm on must already exist
version_added: "1.6"
author: <NAME>
options:
    state:
        description:
          - register or deregister the alarm
        required: true
        choices: ['present', 'absent']
    name:
        desciption:
          - Unique name for the alarm
        required: true
    metric:
        description:
          - Name of the monitored metric (e.g. CPUUtilization)
          - Metric must already exist
        required: false
    namespace:
        description:
          - Name of the appropriate namespace ('AWS/EC2', 'System/Linux', etc.), which determines the category it will appear under in cloudwatch
        required: false
    statistic:
        description:
          - Operation applied to the metric
          - Works in conjunction with period and evaluation_periods to determine the comparison value
        required: false
        options: ['SampleCount','Average','Sum','Minimum','Maximum']
    comparison:
        description:
          - Determines how the threshold value is compared
        required: false
        options: ['<=','<','>','>=']
    threshold:
        description:
          - Sets the min/max bound for triggering the alarm
        required: false
    period:
        description:
          - The time (in seconds) between metric evaluations
        required: false
    evaluation_periods:
        description:
          - The number of times in which the metric is evaluated before final calculation
        required: false
    unit:
        description:
          - The threshold's unit of measurement
        required: false
        options: ['Seconds','Microseconds','Milliseconds','Bytes','Kilobytes','Megabytes','Gigabytes','Terabytes','Bits','Kilobits','Megabits','Gigabits','Terabits','Percent','Count','Bytes/Second','Kilobytes/Second','Megabytes/Second','Gigabytes/Second','Terabytes/Second','Bits/Second','Kilobits/Second','Megabits/Second','Gigabits/Second','Terabits/Second','Count/Second','None']
    description:
        description:
          - A longer desciption of the alarm
        required: false
    dimensions:
        description:
          - Describes to what the alarm is applied
        required: false
    alarm_actions:
        description:
          - A list of the names action(s) taken when the alarm is in the 'alarm' status
        required: false
    insufficient_data_actions:
        description:
          - A list of the names of action(s) to take when the alarm is in the 'insufficient_data' status
        required: false
    ok_actions:
        description:
          - A list of the names of action(s) to take when the alarm is in the 'ok' status
        required: false
extends_documentation_fragment: aws
"""

EXAMPLES = '''
  - name: create alarm
    ec2_metric_alarm:
      state: present
      region: ap-southeast-2
      name: "cpu-low"
      metric: "CPUUtilization"
      namespace: "AWS/EC2"
      statistic: Average
      comparison: "<="
      threshold: 5.0
      period: 300
      evaluation_periods: 3
      unit: "Percent"
      description: "This will alarm when a bamboo slave's cpu usage average is lower than 5% for 15 minutes "
      dimensions: {'InstanceId':'i-XXX'}
      alarm_actions: ["action1","action2"]


'''

import sys

from ansible.module_utils.basic import *
from ansible.module_utils.ec2 import *

try:
    import boto.ec2.cloudwatch
    from boto.ec2.cloudwatch import CloudWatchConnection, MetricAlarm
    from boto.exception import BotoServerError
except ImportError:
    print "failed=True msg='boto required for this module'"
    sys.exit(1)


def create_metric_alarm(connection, module):

    name = module.params.get('name')
    metric = module.params.get('metric')
    namespace = module.params.get('namespace')
    statistic = module.params.get('statistic')
    comparison = module.params.get('comparison')
    threshold = module.params.get('threshold')
    period = module.params.get('period')
    evaluation_periods = module.params.get('evaluation_periods')
    unit = module.params.get('unit')
    description = module.params.get('description')
    dimensions = module.params.get('dimensions')
    alarm_actions = module.params.get('alarm_actions')
    insufficient_data_actions = module.params.get('insufficient_data_actions')
    ok_actions = module.params.get('ok_actions')

    alarms = connection.describe_alarms(alarm_names=[name])

    if not alarms:

        alm = MetricAlarm(
            name=name,
            metric=metric,
            namespace=namespace,
            statistic=statistic,
            comparison=comparison,
            threshold=threshold,
            period=period,
            evaluation_periods=evaluation_periods,
            unit=unit,
            description=description,
            dimensions=dimensions,
            alarm_actions=alarm_actions,
            insufficient_data_actions=insufficient_data_actions,
            ok_actions=ok_actions
        )
        try:
            connection.create_alarm(alm)
            changed = True
            alarms = connection.describe_alarms(alarm_names=[name])
        except BotoServerError, e:
            module.fail_json(msg=str(e))

    else:
        alarm = alarms[0]
        changed = False

        for attr in ('comparison','metric','namespace','statistic','threshold','period','evaluation_periods','unit','description'):
            if getattr(alarm, attr) != module.params.get(attr):
                changed = True
                setattr(alarm, attr, module.params.get(attr))
        #this is to deal with a current bug where you cannot assign '<=>' to the comparator when modifying an existing alarm
        comparison = alarm.comparison
        comparisons = {'<=' : 'LessThanOrEqualToThreshold', '<' : 'LessThanThreshold', '>=' : 'GreaterThanOrEqualToThreshold', '>' : 'GreaterThanThreshold'}
        alarm.comparison = comparisons[comparison]

        dim1 = module.params.get('dimensions')
        dim2 = alarm.dimensions

        for keys in dim1:
            if not isinstance(dim1[keys], list):
                dim1[keys] = [dim1[keys]]
            if keys not in dim2 or dim1[keys] != dim2[keys]:
                changed=True
                setattr(alarm, 'dimensions', dim1)

        for attr in ('alarm_actions','insufficient_data_actions','ok_actions'):
            action = module.params.get(attr) or []
            if getattr(alarm, attr) != action:
                changed = True
                setattr(alarm, attr, module.params.get(attr))

{'fraction_non_alphanumeric': 0.0963302752293578, 'fraction_numerical': 0.0045871559633027525, 'mean_word_length': 2.6933233682112605, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2490357', 'n_tokens_mistral': 4035, 'n_tokens_neox': 3939, 'n_words': 1189}