Pass the correct matching_metadata to Ceilometer

When using the Cloud Watch Resource Template don't really have
the json functions to prepend a prefix to the matching_metadata.

The issue here is the nova metadata get converted by Ceilometer from
"metering" to "user_metadata" so depending on the meter name we need to
search for different metadata.

Change-Id: Id3577c8af3f0433577b1ec7b5068585a74f4c3cc
This commit is contained in:
Angus Salkeld 2014-09-25 15:33:58 +10:00
parent 3f73f82a0d
commit 7555fc9f04
2 changed files with 45 additions and 2 deletions

View File

@ -11,6 +11,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import six
from heat.common import exception
from heat.engine import constraints
from heat.engine import properties
@ -68,6 +70,23 @@ common_properties_schema = {
}
NOVA_METERS = ['instance', 'memory', 'memory.usage',
'cpu', 'cpu_util', 'vcpus',
'disk.read.requests', 'disk.read.requests.rate',
'disk.write.requests', 'disk.write.requests.rate',
'disk.read.bytes', 'disk.read.bytes.rate',
'disk.write.bytes', 'disk.write.bytes.rate',
'disk.device.read.requests', 'disk.device.read.requests.rate',
'disk.device.write.requests', 'disk.device.write.requests.rate',
'disk.device.read.bytes', 'disk.device.read.bytes.rate',
'disk.device.write.bytes', 'disk.device.write.bytes.rate',
'disk.root.size', 'disk.ephemeral.size',
'network.incoming.bytes', 'network.incoming.bytes.rate',
'network.outgoing.bytes', 'network.outgoing.bytes.rate',
'network.incoming.packets', 'network.incoming.packets.rate',
'network.outgoing.packets', 'network.outgoing.packets.rate']
def actions_to_urls(stack, properties):
kwargs = {}
for k, v in iter(properties.items()):
@ -151,8 +170,29 @@ class CeilometerAlarm(resource.Resource):
default_client_name = 'ceilometer'
def cfn_to_ceilometer(self, stack, properties):
kwargs = actions_to_urls(stack, properties)
if kwargs.get(self.METER_NAME) in NOVA_METERS:
prefix = 'user_metadata.'
else:
prefix = 'metering.'
for k, v in iter(properties.items()):
if k == self.MATCHING_METADATA:
# make sure we have matching_metadata that looks like this:
# matching_metadata: {metadata.$prefix.x}
kwargs[k] = {}
for m_k, m_v in six.iteritems(v):
if m_k.startswith('metadata.%s' % prefix):
kwargs[k][m_k] = m_v
elif m_k.startswith(prefix):
kwargs[k]['metadata.%s' % m_k] = m_v
else:
kwargs[k]['metadata.%s%s' % (prefix, m_k)] = m_v
return kwargs
def handle_create(self):
props = actions_to_urls(self.stack, self.parsed_template('Properties'))
props = self.cfn_to_ceilometer(self.stack,
self.parsed_template('Properties'))
props['name'] = self.physical_resource_name()
alarm = self.ceilometer().alarms.create(**props)
@ -174,7 +214,7 @@ class CeilometerAlarm(resource.Resource):
kwargs = {'alarm_id': self.resource_id}
kwargs.update(prop_diff)
alarms_client = self.ceilometer().alarms
alarms_client.update(**actions_to_urls(self.stack, kwargs))
alarms_client.update(**self.cfn_to_ceilometer(self.stack, kwargs))
def handle_suspend(self):
if self.resource_id is not None:

View File

@ -157,6 +157,9 @@ class CeilometerAlarmTest(HeatTestCase):
al['description'] = mox.IgnoreArg()
al['name'] = mox.IgnoreArg()
al['alarm_actions'] = mox.IgnoreArg()
al['matching_metadata'] = dict(
('metadata.metering.%s' % k, v)
for k, v in al['matching_metadata'].items())
self.m.StubOutWithMock(self.fa.alarms, 'create')
self.fa.alarms.create(**al).AndReturn(FakeCeilometerAlarm())
return stack