]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
UpdateStack for AWS::AutoScaling::ScalingPolicy
authorWinson Chan <winson.c.chan@intel.com>
Fri, 17 May 2013 18:30:33 +0000 (11:30 -0700)
committerWinson Chan <winson.c.chan@intel.com>
Mon, 20 May 2013 16:08:28 +0000 (09:08 -0700)
Implemented update support of the ScalingPolicy resource
in an existing stack. ScalingAdjustment, AdjustmentType,
and Cooldown properties are allowed properties for update.
A handle_update method is added to update differences in
the template.

Change-Id: Ieeae93560a315a8a35c6fb2d8f1d78a89123bec3
blueprint: scalingpolicy-update-stack

heat/engine/resources/autoscaling.py
heat/tests/test_autoscaling.py

index 81a0f027b3bd290092b0f238a06ef0958105a486..3f1401417519b8245410ec656ce24724894c5f92 100644 (file)
@@ -426,9 +426,36 @@ class ScalingPolicy(resource.Resource, CooldownMixin):
         'Cooldown': {'Type': 'Number'},
     }
 
+    update_allowed_keys = ('Properties',)
+    update_allowed_properties = ('ScalingAdjustment', 'AdjustmentType',
+                                 'Cooldown',)
+
     def __init__(self, name, json_snippet, stack):
         super(ScalingPolicy, self).__init__(name, json_snippet, stack)
 
+    def handle_update(self, json_snippet):
+        try:
+            tmpl_diff = self.update_template_diff(json_snippet)
+        except NotImplementedError:
+            logger.error("Could not update %s, invalid key" % self.name)
+            return self.UPDATE_REPLACE
+
+        try:
+            prop_diff = self.update_template_diff_properties(json_snippet)
+        except NotImplementedError:
+            logger.error("Could not update %s, invalid Property" % self.name)
+            return self.UPDATE_REPLACE
+
+        # If Properties has changed, update self.properties, so we
+        # get the new values during any subsequent adjustment
+        if prop_diff:
+            self.properties = Properties(self.properties_schema,
+                                         json_snippet.get('Properties', {}),
+                                         self.stack.resolve_runtime_data,
+                                         self.name)
+
+        return self.UPDATE_COMPLETE
+
     def alarm(self):
         if self._cooldown_inprogress():
             logger.info("%s NOT performing scaling action, cooldown %s" %
index dc6578cc6040bf9b39fea363393ba34f19aa2443..f556ebcf7dd1ab1b18097afc292e06ff3fa289f4 100644 (file)
@@ -41,7 +41,7 @@ as_template = '''
         "AvailabilityZones" : ["nova"],
         "LaunchConfigurationName" : { "Ref" : "LaunchConfig" },
         "MinSize" : "1",
-        "MaxSize" : "3",
+        "MaxSize" : "5",
         "LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ]
       }
     },
@@ -354,7 +354,7 @@ class AutoScalingTest(HeatTestCase):
                          resource.resource_id)
 
         # raise above the max
-        resource.adjust(2)
+        resource.adjust(4)
         self.assertEqual('WebServerGroup-0,WebServerGroup-1',
                          resource.resource_id)
 
@@ -825,3 +825,70 @@ class AutoScalingTest(HeatTestCase):
 
         resource.delete()
         self.m.VerifyAll()
+
+    def test_scaling_policy_update(self):
+        t = template_format.parse(as_template)
+        stack = parse_stack(t)
+
+        # Create initial group
+        self._stub_lb_reload(['WebServerGroup-0'])
+        now = timeutils.utcnow()
+        self._stub_meta_expected(now, 'ExactCapacity : 1')
+        self._stub_create(1)
+        self.m.ReplayAll()
+        resource = self.create_scaling_group(t, stack, 'WebServerGroup')
+        stack.resources['WebServerGroup'] = resource
+        self.assertEqual('WebServerGroup-0', resource.resource_id)
+
+        # Create initial scaling policy
+        up_policy = self.create_scaling_policy(t, stack,
+                                               'WebServerScaleUpPolicy')
+
+        # Scale up one
+        self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1'])
+        self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
+        self._stub_create(1)
+        self.m.ReplayAll()
+
+        # Trigger alarm
+        up_policy.alarm()
+        self.assertEqual('WebServerGroup-0,WebServerGroup-1',
+                         resource.resource_id)
+
+        # Update scaling policy
+        update_snippet = copy.deepcopy(up_policy.parsed_template())
+        update_snippet['Properties']['ScalingAdjustment'] = '2'
+        self.assertEqual(asc.ScalingPolicy.UPDATE_COMPLETE,
+                         up_policy.handle_update(update_snippet))
+        self.assertEqual('2',
+                         up_policy.properties['ScalingAdjustment'])
+
+        # Now move time on 61 seconds - Cooldown in template is 60
+        # so this should trigger a scale-up
+        previous_meta = {timeutils.strtime(now): 'ChangeInCapacity : 1'}
+        self.m.VerifyAll()
+        self.m.UnsetStubs()
+
+        self.m.StubOutWithMock(Metadata, '__get__')
+        Metadata.__get__(mox.IgnoreArg(), up_policy, mox.IgnoreArg()
+                         ).AndReturn(previous_meta)
+        Metadata.__get__(mox.IgnoreArg(), resource, mox.IgnoreArg()
+                         ).AndReturn(previous_meta)
+
+        now = now + datetime.timedelta(seconds=61)
+
+        self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1',
+                              'WebServerGroup-2', 'WebServerGroup-3'],
+                             unset=False)
+        self._stub_meta_expected(now, 'ChangeInCapacity : 2', 2)
+        self._stub_create(2)
+        self.m.ReplayAll()
+
+        # Trigger alarm
+        up_policy.alarm()
+        self.assertEqual('WebServerGroup-0,WebServerGroup-1,'
+                         'WebServerGroup-2,WebServerGroup-3',
+                         resource.resource_id)
+
+        resource.delete()
+        self.m.VerifyAll()