ceilometer: new Gnocchi Alarm resources
Ceilometer offers two new kind of alarms. This change adds the associated resources to Heat. Implements blueprint ceilometer-gnocchi-alarm Change-Id: I0d3dfcbda7d09361bb90fd16122b903bf4c03fbe
This commit is contained in:
parent
70747cdc1a
commit
f9fa8da05c
18
contrib/heat_gnocchi/README.md
Normal file
18
contrib/heat_gnocchi/README.md
Normal file
@ -0,0 +1,18 @@
|
||||
Gnocchi plugin for OpenStack Heat
|
||||
=================================
|
||||
|
||||
This plugin adds Ceilometer Gnocchi Alarm resources in a Heat template.
|
||||
|
||||
|
||||
### 1. Install the Gnocchi plugin in Heat
|
||||
|
||||
NOTE: These instructions assume the value of heat.conf plugin_dirs includes the
|
||||
default directory /usr/lib/heat.
|
||||
|
||||
To install the plugin, from this directory run:
|
||||
sudo python ./setup.py install
|
||||
|
||||
### 2. Restart heat
|
||||
|
||||
Only the process "heat-engine" needs to be restarted to load the newly installed
|
||||
plugin.
|
0
contrib/heat_gnocchi/heat_gnocchi/__init__.py
Normal file
0
contrib/heat_gnocchi/heat_gnocchi/__init__.py
Normal file
132
contrib/heat_gnocchi/heat_gnocchi/resources/gnocchi_alarm.py
Normal file
132
contrib/heat_gnocchi/heat_gnocchi/resources/gnocchi_alarm.py
Normal file
@ -0,0 +1,132 @@
|
||||
#
|
||||
# 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 heat.common.i18n import _
|
||||
from heat.engine import constraints
|
||||
from heat.engine import properties
|
||||
from heat.engine.resources.ceilometer import alarm
|
||||
from heat.engine import support
|
||||
|
||||
|
||||
COMMON_GNOCCHI_PROPERTIES = (
|
||||
COMPARISON_OPERATOR, EVALUATION_PERIODS, GRANULARITY,
|
||||
AGGREGATION_METHOD, THRESHOLD,
|
||||
) = (
|
||||
'comparison_operator', 'evaluation_periods', 'granularity',
|
||||
'aggregation_method', 'threshold',
|
||||
)
|
||||
|
||||
|
||||
common_gnocchi_properties_schema = {
|
||||
COMPARISON_OPERATOR: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Operator used to compare specified statistic with threshold.'),
|
||||
constraints=[
|
||||
constraints.AllowedValues(['ge', 'gt', 'eq', 'ne', 'lt',
|
||||
'le']),
|
||||
],
|
||||
update_allowed=True
|
||||
),
|
||||
EVALUATION_PERIODS: properties.Schema(
|
||||
properties.Schema.INTEGER,
|
||||
_('Number of periods to evaluate over.'),
|
||||
update_allowed=True
|
||||
),
|
||||
AGGREGATION_METHOD: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('The aggregation method to compare to the threshold'),
|
||||
constraints=[
|
||||
constraints.AllowedValues(['mean', 'sum', 'last', 'max', 'min',
|
||||
'std', 'median', 'first', 'count']),
|
||||
],
|
||||
update_allowed=True
|
||||
),
|
||||
GRANULARITY: properties.Schema(
|
||||
properties.Schema.INTEGER,
|
||||
_('The time range in seconds.'),
|
||||
update_allowed=True
|
||||
),
|
||||
THRESHOLD: properties.Schema(
|
||||
properties.Schema.NUMBER,
|
||||
_('Threshold to evaluate against.'),
|
||||
required=True,
|
||||
update_allowed=True
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
class CeilometerGnocchiResourcesAlarm(alarm.BaseCeilometerAlarm):
|
||||
|
||||
support_status = support.SupportStatus(version='2015.1')
|
||||
|
||||
PROPERTIES = (
|
||||
METRIC, RESOURCE_CONSTRAINT, RESOURCE_TYPE
|
||||
) = (
|
||||
'metric', 'resource_constraint', 'resource_type'
|
||||
)
|
||||
PROPERTIES += COMMON_GNOCCHI_PROPERTIES
|
||||
|
||||
properties_schema = {
|
||||
METRIC: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Metric name watched by the alarm.'),
|
||||
required=True,
|
||||
update_allowed=True
|
||||
),
|
||||
RESOURCE_CONSTRAINT: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Id of a resource or expression to select multiple resources'),
|
||||
required=True,
|
||||
update_allowed=True
|
||||
),
|
||||
RESOURCE_TYPE: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Resource type'),
|
||||
required=True,
|
||||
update_allowed=True
|
||||
),
|
||||
}
|
||||
properties_schema.update(common_gnocchi_properties_schema)
|
||||
properties_schema.update(alarm.common_properties_schema)
|
||||
|
||||
ceilometer_alarm_type = 'gnocchi_resources_threshold'
|
||||
|
||||
|
||||
class CeilometerGnocchiMetricsAlarm(CeilometerGnocchiResourcesAlarm):
|
||||
|
||||
support_status = support.SupportStatus(version='2015.1')
|
||||
|
||||
PROPERTIES = (METRICS,) = ('metrics',)
|
||||
PROPERTIES += COMMON_GNOCCHI_PROPERTIES
|
||||
|
||||
properties_schema = {
|
||||
METRICS: properties.Schema(
|
||||
properties.Schema.LIST,
|
||||
_('A list of metric ids.'),
|
||||
required=True,
|
||||
update_allowed=True,
|
||||
),
|
||||
}
|
||||
properties_schema.update(common_gnocchi_properties_schema)
|
||||
properties_schema.update(alarm.common_properties_schema)
|
||||
|
||||
ceilometer_alarm_type = 'gnocchi_metrics_threshold'
|
||||
|
||||
|
||||
def resource_mapping():
|
||||
return {
|
||||
'OS::Ceilometer::GnocchiResourcesAlarm':
|
||||
CeilometerGnocchiResourcesAlarm,
|
||||
'OS::Ceilometer::GnocchiMetricslarm': CeilometerGnocchiMetricsAlarm,
|
||||
}
|
0
contrib/heat_gnocchi/heat_gnocchi/tests/__init__.py
Normal file
0
contrib/heat_gnocchi/heat_gnocchi/tests/__init__.py
Normal file
366
contrib/heat_gnocchi/heat_gnocchi/tests/test_gnocchi_alarm.py
Normal file
366
contrib/heat_gnocchi/heat_gnocchi/tests/test_gnocchi_alarm.py
Normal file
@ -0,0 +1,366 @@
|
||||
#
|
||||
# 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.
|
||||
|
||||
import copy
|
||||
|
||||
from ceilometerclient import exc as ceilometerclient_exc
|
||||
import mock
|
||||
import mox
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common import template_format
|
||||
from heat.engine.clients.os import ceilometer
|
||||
from heat.engine import resource
|
||||
from heat.engine import scheduler
|
||||
from heat.tests import common
|
||||
from heat.tests import utils
|
||||
|
||||
from ..resources import gnocchi_alarm # noqa
|
||||
|
||||
gnocchi_resources_alarm_template = '''
|
||||
heat_template_version: 2013-05-23
|
||||
description: Gnocchi Resources Alarm Test
|
||||
resources:
|
||||
GnoResAlarm:
|
||||
type: OS::Ceilometer::GnocchiResourcesAlarm
|
||||
properties:
|
||||
description: Do stuff with gnocchi
|
||||
metric: cpu_util
|
||||
aggregation_method: mean
|
||||
granularity: 60
|
||||
evaluation_periods: 1
|
||||
threshold: 50
|
||||
alarm_actions: []
|
||||
resource_type: instance
|
||||
resource_constraint: server_group=mystack
|
||||
comparison_operator: gt
|
||||
'''
|
||||
|
||||
|
||||
gnocchi_metrics_alarm_template = '''
|
||||
heat_template_version: 2013-05-23
|
||||
description: Gnocchi Metrics Alarm Test
|
||||
resources:
|
||||
GnoMetricsAlarm:
|
||||
type: OS::Ceilometer::GnocchiMetricsAlarm
|
||||
properties:
|
||||
description: Do stuff with gnocchi metrics
|
||||
metrics: ["911fce07-e0d7-4210-8c8c-4a9d811fcabc",
|
||||
"2543d435-fe93-4443-9351-fb0156930f94"]
|
||||
aggregation_method: mean
|
||||
granularity: 60
|
||||
evaluation_periods: 1
|
||||
threshold: 50
|
||||
alarm_actions: []
|
||||
comparison_operator: gt
|
||||
'''
|
||||
|
||||
|
||||
class FakeCeilometerAlarm(object):
|
||||
alarm_id = 'foo'
|
||||
|
||||
|
||||
class FakeCeilometerAlarms(object):
|
||||
def create(self, **kwargs):
|
||||
pass
|
||||
|
||||
def update(self, **kwargs):
|
||||
pass
|
||||
|
||||
def delete(self, alarm_id):
|
||||
pass
|
||||
|
||||
|
||||
class FakeCeilometerClient(object):
|
||||
alarms = FakeCeilometerAlarms()
|
||||
|
||||
|
||||
class GnocchiResourcesAlarmTest(common.HeatTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(GnocchiResourcesAlarmTest, self).setUp()
|
||||
self.fc = FakeCeilometerClient()
|
||||
resource._register_class("OS::Ceilometer::GnocchiResourcesAlarm",
|
||||
gnocchi_alarm.CeilometerGnocchiResourcesAlarm)
|
||||
self.m.StubOutWithMock(ceilometer.CeilometerClientPlugin, '_create')
|
||||
|
||||
def create_alarm(self):
|
||||
ceilometer.CeilometerClientPlugin._create().AndReturn(
|
||||
self.fc)
|
||||
self.m.StubOutWithMock(self.fc.alarms, 'create')
|
||||
self.fc.alarms.create(
|
||||
alarm_actions=[],
|
||||
description=u'Do stuff with gnocchi',
|
||||
enabled=True,
|
||||
insufficient_data_actions=None,
|
||||
ok_actions=None,
|
||||
name=mox.IgnoreArg(), type='gnocchi_resources_threshold',
|
||||
repeat_actions=True,
|
||||
gnocchi_resources_threshold_rule={
|
||||
"metric": "cpu_util",
|
||||
"aggregation_method": "mean",
|
||||
"granularity": 60,
|
||||
"evaluation_periods": 1,
|
||||
"threshold": 50,
|
||||
"resource_type": "instance",
|
||||
"resource_constraint": "server_group=mystack",
|
||||
"comparison_operator": "gt",
|
||||
}
|
||||
).AndReturn(FakeCeilometerAlarm())
|
||||
snippet = template_format.parse(gnocchi_resources_alarm_template)
|
||||
stack = utils.parse_stack(snippet)
|
||||
resource_defns = stack.t.resource_definitions(stack)
|
||||
return gnocchi_alarm.CeilometerGnocchiResourcesAlarm(
|
||||
'GnoResAlarm', resource_defns['GnoResAlarm'], stack)
|
||||
|
||||
def test_create(self):
|
||||
rsrc = self.create_alarm()
|
||||
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
|
||||
self.assertEqual('foo', rsrc.resource_id)
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_update(self):
|
||||
rsrc = self.create_alarm()
|
||||
self.m.StubOutWithMock(self.fc.alarms, 'update')
|
||||
self.fc.alarms.update(
|
||||
alarm_id='foo',
|
||||
gnocchi_resources_threshold_rule={
|
||||
'resource_constraint': 'd3d6c642-921e-4fc2-9c5f-15d9a5afb598'})
|
||||
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
|
||||
update_template = copy.deepcopy(rsrc.t)
|
||||
update_template['Properties']['resource_constraint'] = (
|
||||
'd3d6c642-921e-4fc2-9c5f-15d9a5afb598')
|
||||
scheduler.TaskRunner(rsrc.update, update_template)()
|
||||
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_suspend(self):
|
||||
rsrc = self.create_alarm()
|
||||
self.m.StubOutWithMock(self.fc.alarms, 'update')
|
||||
self.fc.alarms.update(alarm_id='foo', enabled=False)
|
||||
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
|
||||
scheduler.TaskRunner(rsrc.suspend)()
|
||||
self.assertEqual((rsrc.SUSPEND, rsrc.COMPLETE), rsrc.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_resume(self):
|
||||
rsrc = self.create_alarm()
|
||||
self.m.StubOutWithMock(self.fc.alarms, 'update')
|
||||
self.fc.alarms.update(alarm_id='foo', enabled=True)
|
||||
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
rsrc.state_set(rsrc.SUSPEND, rsrc.COMPLETE)
|
||||
|
||||
scheduler.TaskRunner(rsrc.resume)()
|
||||
self.assertEqual((rsrc.RESUME, rsrc.COMPLETE), rsrc.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_delete(self):
|
||||
rsrc = self.create_alarm()
|
||||
self.m.StubOutWithMock(self.fc.alarms, 'delete')
|
||||
self.fc.alarms.delete('foo')
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
scheduler.TaskRunner(rsrc.delete)()
|
||||
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_delete_not_found(self):
|
||||
rsrc = self.create_alarm()
|
||||
self.m.StubOutWithMock(self.fc.alarms, 'delete')
|
||||
self.fc.alarms.delete('foo').AndRaise(
|
||||
ceilometerclient_exc.HTTPNotFound())
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
scheduler.TaskRunner(rsrc.delete)()
|
||||
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def _prepare_check_resource(self):
|
||||
snippet = template_format.parse(gnocchi_resources_alarm_template)
|
||||
stack = utils.parse_stack(snippet)
|
||||
res = stack['GnoResAlarm']
|
||||
res.ceilometer = mock.Mock()
|
||||
mock_alarm = mock.Mock(enabled=True, state='ok')
|
||||
res.ceilometer().alarms.get.return_value = mock_alarm
|
||||
return res
|
||||
|
||||
def test_check(self):
|
||||
res = self._prepare_check_resource()
|
||||
scheduler.TaskRunner(res.check)()
|
||||
self.assertEqual((res.CHECK, res.COMPLETE), res.state)
|
||||
|
||||
def test_check_failure(self):
|
||||
res = self._prepare_check_resource()
|
||||
res.ceilometer().alarms.get.side_effect = Exception('Boom')
|
||||
|
||||
self.assertRaises(exception.ResourceFailure,
|
||||
scheduler.TaskRunner(res.check))
|
||||
self.assertEqual((res.CHECK, res.FAILED), res.state)
|
||||
self.assertIn('Boom', res.status_reason)
|
||||
|
||||
|
||||
class GnocchiMetricsAlarmTest(common.HeatTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(GnocchiMetricsAlarmTest, self).setUp()
|
||||
self.fc = FakeCeilometerClient()
|
||||
resource._register_class("OS::Ceilometer::GnocchiMetricsAlarm",
|
||||
gnocchi_alarm.CeilometerGnocchiMetricsAlarm)
|
||||
self.m.StubOutWithMock(ceilometer.CeilometerClientPlugin, '_create')
|
||||
|
||||
def create_alarm(self):
|
||||
ceilometer.CeilometerClientPlugin._create().AndReturn(
|
||||
self.fc)
|
||||
self.m.StubOutWithMock(self.fc.alarms, 'create')
|
||||
self.fc.alarms.create(
|
||||
alarm_actions=[],
|
||||
description=u'Do stuff with gnocchi metrics',
|
||||
enabled=True,
|
||||
insufficient_data_actions=None,
|
||||
ok_actions=None,
|
||||
name=mox.IgnoreArg(), type='gnocchi_metrics_threshold',
|
||||
repeat_actions=True,
|
||||
gnocchi_metrics_threshold_rule={
|
||||
"aggregation_method": "mean",
|
||||
"granularity": 60,
|
||||
"evaluation_periods": 1,
|
||||
"threshold": 50,
|
||||
"comparison_operator": "gt",
|
||||
"metrics": ["911fce07-e0d7-4210-8c8c-4a9d811fcabc",
|
||||
"2543d435-fe93-4443-9351-fb0156930f94"],
|
||||
}
|
||||
).AndReturn(FakeCeilometerAlarm())
|
||||
snippet = template_format.parse(gnocchi_metrics_alarm_template)
|
||||
stack = utils.parse_stack(snippet)
|
||||
resource_defns = stack.t.resource_definitions(stack)
|
||||
return gnocchi_alarm.CeilometerGnocchiMetricsAlarm(
|
||||
'GnoMetricsAlarm', resource_defns['GnoMetricsAlarm'], stack)
|
||||
|
||||
def test_create(self):
|
||||
rsrc = self.create_alarm()
|
||||
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
|
||||
self.assertEqual('foo', rsrc.resource_id)
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_update(self):
|
||||
rsrc = self.create_alarm()
|
||||
self.m.StubOutWithMock(self.fc.alarms, 'update')
|
||||
self.fc.alarms.update(
|
||||
alarm_id='foo',
|
||||
gnocchi_metrics_threshold_rule={
|
||||
'metrics': ['d3d6c642-921e-4fc2-9c5f-15d9a5afb598',
|
||||
'bc60f822-18a0-4a0c-94e7-94c554b00901']})
|
||||
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
|
||||
update_template = copy.deepcopy(rsrc.t)
|
||||
update_template['Properties']['metrics'] = [
|
||||
'd3d6c642-921e-4fc2-9c5f-15d9a5afb598',
|
||||
'bc60f822-18a0-4a0c-94e7-94c554b00901']
|
||||
scheduler.TaskRunner(rsrc.update, update_template)()
|
||||
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_suspend(self):
|
||||
rsrc = self.create_alarm()
|
||||
self.m.StubOutWithMock(self.fc.alarms, 'update')
|
||||
self.fc.alarms.update(alarm_id='foo', enabled=False)
|
||||
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
|
||||
scheduler.TaskRunner(rsrc.suspend)()
|
||||
self.assertEqual((rsrc.SUSPEND, rsrc.COMPLETE), rsrc.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_resume(self):
|
||||
rsrc = self.create_alarm()
|
||||
self.m.StubOutWithMock(self.fc.alarms, 'update')
|
||||
self.fc.alarms.update(alarm_id='foo', enabled=True)
|
||||
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
rsrc.state_set(rsrc.SUSPEND, rsrc.COMPLETE)
|
||||
|
||||
scheduler.TaskRunner(rsrc.resume)()
|
||||
self.assertEqual((rsrc.RESUME, rsrc.COMPLETE), rsrc.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_delete(self):
|
||||
rsrc = self.create_alarm()
|
||||
self.m.StubOutWithMock(self.fc.alarms, 'delete')
|
||||
self.fc.alarms.delete('foo')
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
scheduler.TaskRunner(rsrc.delete)()
|
||||
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_delete_not_found(self):
|
||||
rsrc = self.create_alarm()
|
||||
self.m.StubOutWithMock(self.fc.alarms, 'delete')
|
||||
self.fc.alarms.delete('foo').AndRaise(
|
||||
ceilometerclient_exc.HTTPNotFound())
|
||||
self.m.ReplayAll()
|
||||
scheduler.TaskRunner(rsrc.create)()
|
||||
scheduler.TaskRunner(rsrc.delete)()
|
||||
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def _prepare_check_resource(self):
|
||||
snippet = template_format.parse(gnocchi_metrics_alarm_template)
|
||||
stack = utils.parse_stack(snippet)
|
||||
res = stack['GnoMetricsAlarm']
|
||||
res.ceilometer = mock.Mock()
|
||||
mock_alarm = mock.Mock(enabled=True, state='ok')
|
||||
res.ceilometer().alarms.get.return_value = mock_alarm
|
||||
return res
|
||||
|
||||
def test_check(self):
|
||||
res = self._prepare_check_resource()
|
||||
scheduler.TaskRunner(res.check)()
|
||||
self.assertEqual((res.CHECK, res.COMPLETE), res.state)
|
||||
|
||||
def test_check_failure(self):
|
||||
res = self._prepare_check_resource()
|
||||
res.ceilometer().alarms.get.side_effect = Exception('Boom')
|
||||
|
||||
self.assertRaises(exception.ResourceFailure,
|
||||
scheduler.TaskRunner(res.check))
|
||||
self.assertEqual((res.CHECK, res.FAILED), res.state)
|
||||
self.assertIn('Boom', res.status_reason)
|
29
contrib/heat_gnocchi/setup.cfg
Normal file
29
contrib/heat_gnocchi/setup.cfg
Normal file
@ -0,0 +1,29 @@
|
||||
[metadata]
|
||||
name = heat-contrib-gnocchi
|
||||
summary = Heat resources for working gnocchi queues
|
||||
description-file =
|
||||
README.md
|
||||
author = OpenStack
|
||||
author-email = openstack-dev@lists.openstack.org
|
||||
home-page = http://www.openstack.org/
|
||||
classifier =
|
||||
Environment :: OpenStack
|
||||
Intended Audience :: Information Technology
|
||||
Intended Audience :: System Administrators
|
||||
License :: OSI Approved :: Apache Software License
|
||||
Operating System :: POSIX :: Linux
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: 2
|
||||
Programming Language :: Python :: 2.7
|
||||
Programming Language :: Python :: 2.6
|
||||
|
||||
[files]
|
||||
packages =
|
||||
heat_gnocchi
|
||||
# Copy to /usr/lib/heat for plugin loading
|
||||
data_files =
|
||||
lib/heat/gnocchi = heat_gnocchi/resources/*
|
||||
|
||||
[global]
|
||||
setup-hooks =
|
||||
pbr.hooks.setup_hook
|
30
contrib/heat_gnocchi/setup.py
Normal file
30
contrib/heat_gnocchi/setup.py
Normal file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
|
||||
import setuptools
|
||||
|
||||
# In python < 2.7.4, a lazy loading of package `pbr` will break
|
||||
# setuptools if some other modules registered functions in `atexit`.
|
||||
# solution from: http://bugs.python.org/issue15881#msg170215
|
||||
try:
|
||||
import multiprocessing # noqa
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['pbr'],
|
||||
pbr=True)
|
@ -313,51 +313,26 @@ class CeilometerAlarm(resource.Resource):
|
||||
self.ceilometer().alarms.get(self.resource_id)
|
||||
|
||||
|
||||
class CombinationAlarm(resource.Resource):
|
||||
|
||||
support_status = support.SupportStatus(version='2014.1')
|
||||
|
||||
PROPERTIES = (
|
||||
ALARM_IDS, OPERATOR,
|
||||
) = (
|
||||
'alarm_ids', 'operator',
|
||||
)
|
||||
|
||||
properties_schema = {
|
||||
ALARM_IDS: properties.Schema(
|
||||
properties.Schema.LIST,
|
||||
_('List of alarm identifiers to combine.'),
|
||||
required=True,
|
||||
constraints=[constraints.Length(min=1)],
|
||||
update_allowed=True),
|
||||
OPERATOR: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Operator used to combine the alarms.'),
|
||||
constraints=[constraints.AllowedValues(['and', 'or'])],
|
||||
update_allowed=True)
|
||||
}
|
||||
properties_schema.update(common_properties_schema)
|
||||
|
||||
class BaseCeilometerAlarm(resource.Resource):
|
||||
default_client_name = 'ceilometer'
|
||||
|
||||
def handle_create(self):
|
||||
properties = actions_to_urls(self.stack,
|
||||
self.properties)
|
||||
properties['name'] = self.physical_resource_name()
|
||||
properties['type'] = 'combination'
|
||||
|
||||
properties['type'] = self.ceilometer_alarm_type
|
||||
alarm = self.ceilometer().alarms.create(
|
||||
**self._reformat_properties(properties))
|
||||
self.resource_id_set(alarm.alarm_id)
|
||||
|
||||
def _reformat_properties(self, properties):
|
||||
combination_rule = {}
|
||||
for name in [self.ALARM_IDS, self.OPERATOR]:
|
||||
rule = {}
|
||||
for name in self.PROPERTIES:
|
||||
value = properties.pop(name, None)
|
||||
if value:
|
||||
combination_rule[name] = value
|
||||
if combination_rule:
|
||||
properties['combination_rule'] = combination_rule
|
||||
rule[name] = value
|
||||
if rule:
|
||||
properties['%s_rule' % self.ceilometer_alarm_type] = rule
|
||||
return properties
|
||||
|
||||
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
|
||||
@ -386,6 +361,34 @@ class CombinationAlarm(resource.Resource):
|
||||
self.ceilometer().alarms.get(self.resource_id)
|
||||
|
||||
|
||||
class CombinationAlarm(BaseCeilometerAlarm):
|
||||
|
||||
support_status = support.SupportStatus(version='2014.1')
|
||||
|
||||
PROPERTIES = (
|
||||
ALARM_IDS, OPERATOR,
|
||||
) = (
|
||||
'alarm_ids', 'operator',
|
||||
)
|
||||
|
||||
properties_schema = {
|
||||
ALARM_IDS: properties.Schema(
|
||||
properties.Schema.LIST,
|
||||
_('List of alarm identifiers to combine.'),
|
||||
required=True,
|
||||
constraints=[constraints.Length(min=1)],
|
||||
update_allowed=True),
|
||||
OPERATOR: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Operator used to combine the alarms.'),
|
||||
constraints=[constraints.AllowedValues(['and', 'or'])],
|
||||
update_allowed=True)
|
||||
}
|
||||
properties_schema.update(common_properties_schema)
|
||||
|
||||
ceilometer_alarm_type = 'combination'
|
||||
|
||||
|
||||
def resource_mapping():
|
||||
return {
|
||||
'OS::Ceilometer::Alarm': CeilometerAlarm,
|
||||
|
Loading…
Reference in New Issue
Block a user