PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/boto_cloudwatch.py |
""" Connection module for Amazon CloudWatch .. versionadded:: 2014.7.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.keyid: GKTADJGHEIQSXMKKRBJ08H cloudwatch.key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs A region may also be specified in the configuration: .. code-block:: yaml cloudwatch.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: boto """ # keep lint from choking on _get_conn and _cache_id # pylint: disable=E0602 import logging import yaml # pylint: disable=blacklisted-import import salt.utils.json import salt.utils.odict as odict import salt.utils.versions try: import boto import boto.ec2.cloudwatch import boto.ec2.cloudwatch.dimension import boto.ec2.cloudwatch.listelement logging.getLogger("boto").setLevel(logging.CRITICAL) HAS_BOTO = True except ImportError: HAS_BOTO = False log = logging.getLogger(__name__) def __virtual__(): """ Only load if boto libraries exist. """ has_boto_reqs = salt.utils.versions.check_boto_reqs(check_boto3=False) if has_boto_reqs is True: __utils__["boto.assign_funcs"]( __name__, "cloudwatch", module="ec2.cloudwatch", pack=__salt__ ) return has_boto_reqs def get_alarm(name, region=None, key=None, keyid=None, profile=None): """ Get alarm details. Also can be used to check to see if an alarm exists. CLI Example: .. code-block:: bash salt myminion boto_cloudwatch.get_alarm myalarm region=us-east-1 """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) alarms = conn.describe_alarms(alarm_names=[name]) if not alarms: return None if len(alarms) > 1: log.error("multiple alarms matched name '%s'", name) return _metric_alarm_to_dict(alarms[0]) def _safe_dump(data): """ this presenter magic makes yaml.safe_dump work with the objects returned from boto.describe_alarms() """ custom_dumper = __utils__["yaml.get_dumper"]("SafeOrderedDumper") def boto_listelement_presenter(dumper, data): return dumper.represent_list(list(data)) yaml.add_representer( boto.ec2.cloudwatch.listelement.ListElement, boto_listelement_presenter, Dumper=custom_dumper, ) def dimension_presenter(dumper, data): return dumper.represent_dict(dict(data)) yaml.add_representer( boto.ec2.cloudwatch.dimension.Dimension, dimension_presenter, Dumper=custom_dumper, ) return __utils__["yaml.dump"](data, Dumper=custom_dumper) def get_all_alarms(region=None, prefix=None, key=None, keyid=None, profile=None): """ Get all alarm details. Produces results that can be used to create an sls file. If prefix parameter is given, alarm names in the output will be prepended with the prefix; alarms that have the prefix will be skipped. This can be used to convert existing alarms to be managed by salt, as follows: 1. Make a "backup" of all existing alarms $ salt-call boto_cloudwatch.get_all_alarms --out=txt | sed "s/local: //" > legacy_alarms.sls 2. Get all alarms with new prefixed names $ salt-call boto_cloudwatch.get_all_alarms "prefix=**MANAGED BY SALT** " --out=txt | sed "s/local: //" > managed_alarms.sls 3. Insert the managed alarms into cloudwatch $ salt-call state.template managed_alarms.sls 4. Manually verify that the new alarms look right 5. Delete the original alarms $ sed s/present/absent/ legacy_alarms.sls > remove_legacy_alarms.sls $ salt-call state.template remove_legacy_alarms.sls 6. Get all alarms again, verify no changes $ salt-call boto_cloudwatch.get_all_alarms --out=txt | sed "s/local: //" > final_alarms.sls $ diff final_alarms.sls managed_alarms.sls CLI Example: .. code-block:: bash salt myminion boto_cloudwatch.get_all_alarms region=us-east-1 --out=txt """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) alarms = conn.describe_alarms() results = odict.OrderedDict() for alarm in alarms: alarm = _metric_alarm_to_dict(alarm) name = alarm["name"] if prefix: if name.startswith(prefix): continue name = prefix + alarm["name"] del alarm["name"] alarm_sls = [{"name": name}, {"attributes": alarm}] results["manage alarm " + name] = {"boto_cloudwatch_alarm.present": alarm_sls} return _safe_dump(results) def create_or_update_alarm( connection=None, name=None, metric=None, namespace=None, statistic=None, comparison=None, threshold=None, period=None, evaluation_periods=None, unit=None, description="", dimensions=None, alarm_actions=None, insufficient_data_actions=None, ok_actions=None, region=None, key=None, keyid=None, profile=None, ): """ Create or update a cloudwatch alarm. Params are the same as: https://boto.readthedocs.io/en/latest/ref/cloudwatch.html#boto.ec2.cloudwatch.alarm.MetricAlarm. Dimensions must be a dict. If the value of Dimensions is a string, it will be json decoded to produce a dict. alarm_actions, insufficient_data_actions, and ok_actions must be lists of string. If the passed-in value is a string, it will be split on "," to produce a list. The strings themselves for alarm_actions, insufficient_data_actions, and ok_actions must be Amazon resource names (ARN's); however, this method also supports an arn lookup notation, as follows: arn:aws:.... ARN as per http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html scaling_policy:<as_name>:<scaling_policy_name> The named autoscale group scaling policy, for the named group (e.g. scaling_policy:my-asg:ScaleDown) This is convenient for setting up autoscaling as follows. First specify a boto_asg.present state for an ASG with scaling_policies, and then set up boto_cloudwatch_alarm.present states which have alarm_actions that reference the scaling_policy. CLI Example: .. code-block:: bash salt myminion boto_cloudwatch.create_alarm name=myalarm ... region=us-east-1 """ # clean up argument types, so that CLI works if threshold: threshold = float(threshold) if period: period = int(period) if evaluation_periods: evaluation_periods = int(evaluation_periods) if isinstance(dimensions, str): dimensions = salt.utils.json.loads(dimensions) if not isinstance(dimensions, dict): log.error( "could not parse dimensions argument: must be json encoding of a dict:" " '%s'", dimensions, ) return False if isinstance(alarm_actions, str): alarm_actions = alarm_actions.split(",") if isinstance(insufficient_data_actions, str): insufficient_data_actions = insufficient_data_actions.split(",") if isinstance(ok_actions, str): ok_actions = ok_actions.split(",") # convert provided action names into ARN's if alarm_actions: alarm_actions = convert_to_arn( alarm_actions, region=region, key=key, keyid=keyid, profile=profile ) if insufficient_data_actions: insufficient_data_actions = convert_to_arn( insufficient_data_actions, region=region, key=key, keyid=keyid, profile=profile, ) if ok_actions: ok_actions = convert_to_arn( ok_actions, region=region, key=key, keyid=keyid, profile=profile ) conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) alarm = boto.ec2.cloudwatch.alarm.MetricAlarm( connection=connection, 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, ) conn.create_alarm(alarm) log.info("Created/updated alarm %s", name) return True def convert_to_arn(arns, region=None, key=None, keyid=None, profile=None): """ Convert a list of strings into actual arns. Converts convenience names such as 'scaling_policy:...' CLI Example: .. code-block:: bash salt '*' convert_to_arn 'scaling_policy:' """ results = [] for arn in arns: if arn.startswith("scaling_policy:"): _, as_group, scaling_policy_name = arn.split(":") policy_arn = __salt__["boto_asg.get_scaling_policy_arn"]( as_group, scaling_policy_name, region, key, keyid, profile ) if policy_arn: results.append(policy_arn) else: log.error("Could not convert: %s", arn) else: results.append(arn) return results def delete_alarm(name, region=None, key=None, keyid=None, profile=None): """ Delete a cloudwatch alarm CLI example to delete a queue:: salt myminion boto_cloudwatch.delete_alarm myalarm region=us-east-1 """ conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile) conn.delete_alarms([name]) log.info("Deleted alarm %s", name) return True def _metric_alarm_to_dict(alarm): """ Convert a boto.ec2.cloudwatch.alarm.MetricAlarm into a dict. Convenience for pretty printing. """ d = odict.OrderedDict() fields = [ "name", "metric", "namespace", "statistic", "comparison", "threshold", "period", "evaluation_periods", "unit", "description", "dimensions", "alarm_actions", "insufficient_data_actions", "ok_actions", ] for f in fields: if hasattr(alarm, f): d[f] = getattr(alarm, f) return d