Teach ScalingPolicy and Restarter to create signed urls

This is so they will be able to support ceilometer webhooks

blueprint watch-ceilometer
Change-Id: I18b0dc22f95957a66f2287a7bd70613c8c8db3d6
This commit is contained in:
Angus Salkeld 2013-07-23 22:55:43 +10:00
parent 390757280c
commit c89c96fcf8
3 changed files with 77 additions and 4 deletions

View File

@ -15,6 +15,7 @@
from heat.common import exception from heat.common import exception
from heat.engine import resource from heat.engine import resource
from heat.engine import signal_responder
from heat.engine import scheduler from heat.engine import scheduler
from heat.openstack.common import log as logging from heat.openstack.common import log as logging
@ -434,7 +435,7 @@ class LaunchConfiguration(resource.Resource):
} }
class ScalingPolicy(resource.Resource, CooldownMixin): class ScalingPolicy(signal_responder.SignalResponder, CooldownMixin):
properties_schema = { properties_schema = {
'AutoScalingGroupName': {'Type': 'String', 'AutoScalingGroupName': {'Type': 'String',
'Required': True}, 'Required': True},
@ -451,6 +452,10 @@ class ScalingPolicy(resource.Resource, CooldownMixin):
update_allowed_keys = ('Properties',) update_allowed_keys = ('Properties',)
update_allowed_properties = ('ScalingAdjustment', 'AdjustmentType', update_allowed_properties = ('ScalingAdjustment', 'AdjustmentType',
'Cooldown',) 'Cooldown',)
attributes_schema = {
"AlarmUrl": ("A signed url to handle the alarm. "
"(Heat extension)")
}
def handle_update(self, json_snippet, tmpl_diff, prop_diff): def handle_update(self, json_snippet, tmpl_diff, prop_diff):
# If Properties has changed, update self.properties, so we # If Properties has changed, update self.properties, so we
@ -467,7 +472,7 @@ class ScalingPolicy(resource.Resource, CooldownMixin):
(self.name, self.properties['Cooldown'])) (self.name, self.properties['Cooldown']))
return return
group = self.stack.resources[self.properties['AutoScalingGroupName']] group = self.stack[self.properties['AutoScalingGroupName']]
logger.info('%s Alarm, adjusting Group %s by %s' % logger.info('%s Alarm, adjusting Group %s by %s' %
(self.name, group.name, (self.name, group.name,
@ -479,6 +484,17 @@ class ScalingPolicy(resource.Resource, CooldownMixin):
(self.properties['AdjustmentType'], (self.properties['AdjustmentType'],
self.properties['ScalingAdjustment'])) self.properties['ScalingAdjustment']))
def _resolve_attribute(self, name):
'''
heat extension: "AlarmUrl" returns the url to post to the policy
when there is an alarm.
'''
if name == 'AlarmUrl' and self.resource_id is not None:
return unicode(self._get_signed_url())
def FnGetRefId(self):
return unicode(self.name)
def resource_mapping(): def resource_mapping():
return { return {

View File

@ -22,6 +22,7 @@ from urlparse import urlparse
from oslo.config import cfg from oslo.config import cfg
from heat.engine import signal_responder
from heat.engine import clients from heat.engine import clients
from heat.engine import resource from heat.engine import resource
from heat.engine import scheduler from heat.engine import scheduler
@ -37,9 +38,13 @@ from heat.openstack.common import uuidutils
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Restarter(resource.Resource): class Restarter(signal_responder.SignalResponder):
properties_schema = {'InstanceId': {'Type': 'String', properties_schema = {'InstanceId': {'Type': 'String',
'Required': True}} 'Required': True}}
attributes_schema = {
"AlarmUrl": ("A signed url to handle the alarm. "
"(Heat extension)")
}
def _find_resource(self, resource_id): def _find_resource(self, resource_id):
''' '''
@ -63,6 +68,14 @@ class Restarter(resource.Resource):
(self.name, victim.name)) (self.name, victim.name))
self.stack.restart_resource(victim.name) self.stack.restart_resource(victim.name)
def _resolve_attribute(self, name):
'''
heat extension: "AlarmUrl" returns the url to post to the policy
when there is an alarm.
'''
if name == 'AlarmUrl' and self.resource_id is not None:
return unicode(self._get_signed_url())
class Instance(resource.Resource): class Instance(resource.Resource):
# AWS does not require InstanceType but Heat does because the nova # AWS does not require InstanceType but Heat does because the nova

View File

@ -17,6 +17,8 @@ import copy
import mox import mox
from oslo.config import cfg
from heat.common import template_format from heat.common import template_format
from heat.common import exception from heat.common import exception
from heat.engine.resources import autoscaling as asc from heat.engine.resources import autoscaling as asc
@ -28,6 +30,7 @@ from heat.engine import scheduler
from heat.engine.resource import Metadata from heat.engine.resource import Metadata
from heat.openstack.common import timeutils from heat.openstack.common import timeutils
from heat.tests.common import HeatTestCase from heat.tests.common import HeatTestCase
from heat.tests import fakes
from heat.tests.utils import setup_dummy_db from heat.tests.utils import setup_dummy_db
from heat.tests.utils import parse_stack from heat.tests.utils import parse_stack
@ -99,6 +102,9 @@ class AutoScalingTest(HeatTestCase):
def setUp(self): def setUp(self):
super(AutoScalingTest, self).setUp() super(AutoScalingTest, self).setUp()
setup_dummy_db() setup_dummy_db()
cfg.CONF.set_default('heat_waitcondition_server_url',
'http://127.0.0.1:8000/v1/waitcondition')
self.fc = fakes.FakeKeystoneClient()
def create_scaling_group(self, t, stack, resource_name): def create_scaling_group(self, t, stack, resource_name):
rsrc = asc.AutoScalingGroup(resource_name, rsrc = asc.AutoScalingGroup(resource_name,
@ -113,7 +119,6 @@ class AutoScalingTest(HeatTestCase):
rsrc = asc.ScalingPolicy(resource_name, rsrc = asc.ScalingPolicy(resource_name,
t['Resources'][resource_name], t['Resources'][resource_name],
stack) stack)
self.assertEqual(None, rsrc.validate()) self.assertEqual(None, rsrc.validate())
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
@ -930,6 +935,7 @@ class AutoScalingTest(HeatTestCase):
now = timeutils.utcnow() now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 1') self._stub_meta_expected(now, 'ExactCapacity : 1')
self._stub_create(1) self._stub_create(1)
self.m.ReplayAll() self.m.ReplayAll()
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup') rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
stack.resources['WebServerGroup'] = rsrc stack.resources['WebServerGroup'] = rsrc
@ -939,9 +945,17 @@ class AutoScalingTest(HeatTestCase):
self._stub_lb_reload(2) self._stub_lb_reload(2)
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2) self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
self._stub_create(1) self._stub_create(1)
self.m.StubOutWithMock(asc.ScalingPolicy, 'keystone')
asc.ScalingPolicy.keystone().MultipleTimes().AndReturn(
self.fc)
self.m.ReplayAll() self.m.ReplayAll()
up_policy = self.create_scaling_policy(t, stack, up_policy = self.create_scaling_policy(t, stack,
'WebServerScaleUpPolicy') 'WebServerScaleUpPolicy')
alarm_url = up_policy.FnGetAtt('AlarmUrl')
self.assertNotEqual(None, alarm_url)
up_policy.signal() up_policy.signal()
self.assertEqual('WebServerGroup-0,WebServerGroup-1', self.assertEqual('WebServerGroup-0,WebServerGroup-1',
rsrc.resource_id) rsrc.resource_id)
@ -969,6 +983,11 @@ class AutoScalingTest(HeatTestCase):
# Scale down one # Scale down one
self._stub_lb_reload(1) self._stub_lb_reload(1)
self._stub_meta_expected(now, 'ChangeInCapacity : -1', 2) self._stub_meta_expected(now, 'ChangeInCapacity : -1', 2)
self.m.StubOutWithMock(asc.ScalingPolicy, 'keystone')
asc.ScalingPolicy.keystone().MultipleTimes().AndReturn(
self.fc)
self.m.ReplayAll() self.m.ReplayAll()
down_policy = self.create_scaling_policy(t, stack, down_policy = self.create_scaling_policy(t, stack,
'WebServerScaleDownPolicy') 'WebServerScaleDownPolicy')
@ -996,6 +1015,11 @@ class AutoScalingTest(HeatTestCase):
self._stub_lb_reload(2) self._stub_lb_reload(2)
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2) self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
self._stub_create(1) self._stub_create(1)
self.m.StubOutWithMock(asc.ScalingPolicy, 'keystone')
asc.ScalingPolicy.keystone().MultipleTimes().AndReturn(
self.fc)
self.m.ReplayAll() self.m.ReplayAll()
up_policy = self.create_scaling_policy(t, stack, up_policy = self.create_scaling_policy(t, stack,
'WebServerScaleUpPolicy') 'WebServerScaleUpPolicy')
@ -1047,6 +1071,11 @@ class AutoScalingTest(HeatTestCase):
self._stub_lb_reload(2) self._stub_lb_reload(2)
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2) self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
self._stub_create(1) self._stub_create(1)
self.m.StubOutWithMock(asc.ScalingPolicy, 'keystone')
asc.ScalingPolicy.keystone().MultipleTimes().AndReturn(
self.fc)
self.m.ReplayAll() self.m.ReplayAll()
up_policy = self.create_scaling_policy(t, stack, up_policy = self.create_scaling_policy(t, stack,
'WebServerScaleUpPolicy') 'WebServerScaleUpPolicy')
@ -1099,6 +1128,11 @@ class AutoScalingTest(HeatTestCase):
self._stub_lb_reload(2) self._stub_lb_reload(2)
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2) self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
self._stub_create(1) self._stub_create(1)
self.m.StubOutWithMock(asc.ScalingPolicy, 'keystone')
asc.ScalingPolicy.keystone().MultipleTimes().AndReturn(
self.fc)
self.m.ReplayAll() self.m.ReplayAll()
up_policy = self.create_scaling_policy(t, stack, up_policy = self.create_scaling_policy(t, stack,
'WebServerScaleUpPolicy') 'WebServerScaleUpPolicy')
@ -1151,6 +1185,11 @@ class AutoScalingTest(HeatTestCase):
now = timeutils.utcnow() now = timeutils.utcnow()
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2) self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
self._stub_create(1) self._stub_create(1)
self.m.StubOutWithMock(asc.ScalingPolicy, 'keystone')
asc.ScalingPolicy.keystone().MultipleTimes().AndReturn(
self.fc)
self.m.ReplayAll() self.m.ReplayAll()
up_policy = self.create_scaling_policy(t, stack, up_policy = self.create_scaling_policy(t, stack,
'WebServerScaleUpPolicy') 'WebServerScaleUpPolicy')
@ -1190,6 +1229,11 @@ class AutoScalingTest(HeatTestCase):
now = timeutils.utcnow() now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 1') self._stub_meta_expected(now, 'ExactCapacity : 1')
self._stub_create(1) self._stub_create(1)
self.m.StubOutWithMock(asc.ScalingPolicy, 'keystone')
asc.ScalingPolicy.keystone().MultipleTimes().AndReturn(
self.fc)
self.m.ReplayAll() self.m.ReplayAll()
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup') rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
stack.resources['WebServerGroup'] = rsrc stack.resources['WebServerGroup'] = rsrc