# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from oslo_config import cfg from heat.common import exception from heat.common.i18n import _ from heat.engine import constraints from heat.engine import properties from heat.engine import resource from heat.engine import support from heat.engine import watchrule class CloudWatchAlarm(resource.Resource): PROPERTIES = ( COMPARISON_OPERATOR, ALARM_DESCRIPTION, EVALUATION_PERIODS, METRIC_NAME, NAMESPACE, PERIOD, STATISTIC, ALARM_ACTIONS, OKACTIONS, DIMENSIONS, INSUFFICIENT_DATA_ACTIONS, THRESHOLD, UNITS, ) = ( 'ComparisonOperator', 'AlarmDescription', 'EvaluationPeriods', 'MetricName', 'Namespace', 'Period', 'Statistic', 'AlarmActions', 'OKActions', 'Dimensions', 'InsufficientDataActions', 'Threshold', 'Units', ) properties_schema = { COMPARISON_OPERATOR: properties.Schema( properties.Schema.STRING, _('Operator used to compare the specified Statistic with ' 'Threshold.'), constraints=[ constraints.AllowedValues(['GreaterThanOrEqualToThreshold', 'GreaterThanThreshold', 'LessThanThreshold', 'LessThanOrEqualToThreshold']), ], required=True, update_allowed=True ), ALARM_DESCRIPTION: properties.Schema( properties.Schema.STRING, _('Description for the alarm.'), update_allowed=True ), EVALUATION_PERIODS: properties.Schema( properties.Schema.STRING, _('Number of periods to evaluate over.'), required=True, update_allowed=True ), METRIC_NAME: properties.Schema( properties.Schema.STRING, _('Metric name watched by the alarm.'), required=True ), NAMESPACE: properties.Schema( properties.Schema.STRING, _('Namespace for the metric.'), required=True ), PERIOD: properties.Schema( properties.Schema.STRING, _('Period (seconds) to evaluate over.'), required=True, update_allowed=True ), STATISTIC: properties.Schema( properties.Schema.STRING, _('Metric statistic to evaluate.'), constraints=[ constraints.AllowedValues(['SampleCount', 'Average', 'Sum', 'Minimum', 'Maximum']), ], required=True, update_allowed=True ), ALARM_ACTIONS: properties.Schema( properties.Schema.LIST, _('A list of actions to execute when state transitions to alarm.'), update_allowed=True ), OKACTIONS: properties.Schema( properties.Schema.LIST, _('A list of actions to execute when state transitions to ok.'), update_allowed=True ), DIMENSIONS: properties.Schema( properties.Schema.LIST, _('A list of dimensions (arbitrary name/value pairs) associated ' 'with the metric.') ), INSUFFICIENT_DATA_ACTIONS: properties.Schema( properties.Schema.LIST, _('A list of actions to execute when state transitions to ' 'insufficient-data.'), update_allowed=True ), THRESHOLD: properties.Schema( properties.Schema.STRING, _('Threshold to evaluate against.'), required=True, update_allowed=True ), UNITS: properties.Schema( properties.Schema.STRING, _('Unit for the metric.'), constraints=[ constraints.AllowedValues(['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]), ], update_allowed=True ), } strict_dependency = False support_status = support.SupportStatus( status=support.DEPRECATED, message=_('OS::Heat::CWLiteAlarm is deprecated, ' 'use OS::Ceilometer::Alarm instead.')) def handle_create(self): wr = watchrule.WatchRule(context=self.context, watch_name=self.physical_resource_name(), rule=self.parsed_template('Properties'), stack_id=self.stack.id) wr.store() def handle_update(self, json_snippet, tmpl_diff, prop_diff): # If Properties has changed, update self.properties, so we # get the new values during any subsequent adjustment if prop_diff: self.properties = json_snippet.properties(self.properties_schema, self.context) loader = watchrule.WatchRule.load wr = loader(self.context, watch_name=self.physical_resource_name()) wr.rule = self.parsed_template('Properties') wr.store() def handle_delete(self): try: wr = watchrule.WatchRule.load( self.context, watch_name=self.physical_resource_name()) wr.destroy() except exception.WatchRuleNotFound: pass def handle_suspend(self): wr = watchrule.WatchRule.load(self.context, watch_name=self.physical_resource_name()) wr.state_set(wr.SUSPENDED) def handle_resume(self): wr = watchrule.WatchRule.load(self.context, watch_name=self.physical_resource_name()) # Just set to NODATA, which will be re-evaluated next periodic task wr.state_set(wr.NODATA) def handle_check(self): watch_name = self.physical_resource_name() watchrule.WatchRule.load(self.context, watch_name=watch_name) def FnGetRefId(self): return self.physical_resource_name_or_FnGetRefId() def physical_resource_name(self): return '%s-%s' % (self.stack.name, self.name) def resource_mapping(): cfg.CONF.import_opt('enable_cloud_watch_lite', 'heat.common.config') if cfg.CONF.enable_cloud_watch_lite: return { 'OS::Heat::CWLiteAlarm': CloudWatchAlarm, } else: return {}