Don't update a LoadBalancer under autoscaling control
Unfortunately, Autoscaling currently uses the update() method of a
LoadBalancer resource to do updates, with the result that the current
member list gets persisted (good) and used to compare in the event of
future *stack* updates (bad).
With this patch, we assume that LoadBalancers under the control of
Autoscaling will never have a members list property supplied in the
template. We then ignore any updates to Autoscaling LoadBalancers that
don't actually modify the template.
The test changes revert the changes made in order to be able to merge
d32370233e
, before which LoadBalancers were
behaving correctly.
Change-Id: I9c02ab3d3dfbee0a8a90dd0ba345a5acdaf8a610
Closes-Bug: #1379619
This commit is contained in:
parent
5725b0e8b1
commit
7506d2c22f
@ -422,7 +422,7 @@ class LoadBalancer(stack_resource.StackResource):
|
||||
servers = []
|
||||
n = 1
|
||||
nova_cp = self.client_plugin('nova')
|
||||
for i in instances:
|
||||
for i in instances or []:
|
||||
ip = nova_cp.server_to_ipaddress(i) or '0.0.0.0'
|
||||
LOG.debug('haproxy server:%s' % ip)
|
||||
servers.append('%sserver server%d %s:%s %s' % (spaces, n,
|
||||
@ -481,7 +481,17 @@ class LoadBalancer(stack_resource.StackResource):
|
||||
save it to the db.
|
||||
rely on the cfn-hup to reconfigure HAProxy
|
||||
'''
|
||||
if self.INSTANCES in prop_diff:
|
||||
new_props = json_snippet.properties(self.properties_schema,
|
||||
self.context)
|
||||
|
||||
# Valid use cases are:
|
||||
# - Membership controlled by members property in template
|
||||
# - Empty members property in template; membership controlled by
|
||||
# "updates" triggered from autoscaling group.
|
||||
# Mixing the two will lead to undefined behaviour.
|
||||
if (self.INSTANCES in prop_diff and
|
||||
(self.properties[self.INSTANCES] is not None or
|
||||
new_props[self.INSTANCES] is not None)):
|
||||
templ = self.get_parsed_template()
|
||||
cfg = self._haproxy_config(templ, prop_diff[self.INSTANCES])
|
||||
|
||||
|
@ -640,7 +640,6 @@ class LoadBalancer(resource.Resource):
|
||||
MEMBERS: properties.Schema(
|
||||
properties.Schema.LIST,
|
||||
_('The list of Nova server IDs load balanced.'),
|
||||
default=[],
|
||||
update_allowed=True
|
||||
),
|
||||
}
|
||||
@ -652,7 +651,7 @@ class LoadBalancer(resource.Resource):
|
||||
client = self.neutron()
|
||||
protocol_port = self.properties[self.PROTOCOL_PORT]
|
||||
|
||||
for member in self.properties.get(self.MEMBERS):
|
||||
for member in self.properties[self.MEMBERS] or []:
|
||||
address = self.client_plugin('nova').server_to_ipaddress(member)
|
||||
lb_member = client.create_member({
|
||||
'member': {
|
||||
@ -662,8 +661,18 @@ class LoadBalancer(resource.Resource):
|
||||
self.data_set(member, lb_member['id'])
|
||||
|
||||
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
|
||||
if self.MEMBERS in prop_diff:
|
||||
members = set(prop_diff[self.MEMBERS])
|
||||
new_props = json_snippet.properties(self.properties_schema,
|
||||
self.context)
|
||||
|
||||
# Valid use cases are:
|
||||
# - Membership controlled by members property in template
|
||||
# - Empty members property in template; membership controlled by
|
||||
# "updates" triggered from autoscaling group.
|
||||
# Mixing the two will lead to undefined behaviour.
|
||||
if (self.MEMBERS in prop_diff and
|
||||
(self.properties[self.MEMBERS] is not None or
|
||||
new_props[self.MEMBERS] is not None)):
|
||||
members = set(new_props[self.MEMBERS] or [])
|
||||
rd_members = self.data()
|
||||
old_members = set(rd_members.keys())
|
||||
client = self.neutron()
|
||||
@ -688,7 +697,7 @@ class LoadBalancer(resource.Resource):
|
||||
|
||||
def handle_delete(self):
|
||||
client = self.neutron()
|
||||
for member in self.properties.get(self.MEMBERS):
|
||||
for member in self.properties[self.MEMBERS] or []:
|
||||
member_id = self.data().get(member)
|
||||
try:
|
||||
client.delete_member(member_id)
|
||||
|
@ -122,7 +122,6 @@ class AutoScalingTest(HeatTestCase):
|
||||
self.m.StubOutWithMock(neutronclient.Client, 'show_pool')
|
||||
self.m.StubOutWithMock(neutronclient.Client, 'show_vip')
|
||||
self.m.StubOutWithMock(neutronclient.Client, 'create_member')
|
||||
self.m.StubOutWithMock(neutronclient.Client, 'delete_member')
|
||||
self.m.StubOutWithMock(neutronclient.Client, 'list_members')
|
||||
|
||||
self.m.StubOutWithMock(nova.NovaClientPlugin, 'server_to_ipaddress')
|
||||
@ -310,8 +309,6 @@ class AutoScalingTest(HeatTestCase):
|
||||
nova.NovaClientPlugin.server_to_ipaddress(
|
||||
mox.IgnoreArg()).AndReturn('1.2.3.5')
|
||||
|
||||
neutronclient.Client.delete_member(mox.IgnoreArg()).AndReturn(None)
|
||||
|
||||
neutronclient.Client.create_member(memberb_block).\
|
||||
AndReturn(memberb_ret_block)
|
||||
|
||||
@ -321,12 +318,6 @@ class AutoScalingTest(HeatTestCase):
|
||||
neutronclient.Client.create_member(memberc_block).\
|
||||
AndReturn(memberc_ret_block)
|
||||
|
||||
nova.NovaClientPlugin.server_to_ipaddress(
|
||||
mox.IgnoreArg()).AndReturn('1.2.3.4')
|
||||
|
||||
neutronclient.Client.create_member(membera_block).\
|
||||
AndReturn(membera_ret_block)
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
||||
# Start of stack create
|
||||
|
Loading…
Reference in New Issue
Block a user