Support RackConnect V3 LB in Rackspace AutoScaleGroup Resource
Currently, only Rackspace CloudLoadBalancers are supported by the ASG resource. Also update the requirements to use fork of pyrax that is maintained by the Rackspace heat team. Closes-Bug: #1525391 Change-Id: Iabb52b2a34f1c2a434e724b9a70e4b948e4d0d37
This commit is contained in:
parent
d069bd6245
commit
58624d4f1c
@ -15,6 +15,7 @@
|
||||
|
||||
import copy
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common.i18n import _
|
||||
from heat.engine import attributes
|
||||
from heat.engine import constraints
|
||||
@ -130,8 +131,7 @@ class Group(resource.Resource):
|
||||
),
|
||||
LAUNCH_CONFIG_ARGS_LOAD_BALANCER_PORT: properties.Schema(
|
||||
properties.Schema.INTEGER,
|
||||
_('Server port to connect the load balancer to.'),
|
||||
required=True
|
||||
_('Server port to connect the load balancer to.')
|
||||
),
|
||||
},
|
||||
)
|
||||
@ -294,6 +294,11 @@ class Group(resource.Resource):
|
||||
lbs = copy.deepcopy(lb_args)
|
||||
if lbs:
|
||||
for lb in lbs:
|
||||
# if the port is not specified, the lbid must be that of a
|
||||
# RackConnectV3 lb pool.
|
||||
if not lb[self.LAUNCH_CONFIG_ARGS_LOAD_BALANCER_PORT]:
|
||||
del lb[self.LAUNCH_CONFIG_ARGS_LOAD_BALANCER_PORT]
|
||||
continue
|
||||
lbid = int(lb[self.LAUNCH_CONFIG_ARGS_LOAD_BALANCER_ID])
|
||||
lb[self.LAUNCH_CONFIG_ARGS_LOAD_BALANCER_ID] = lbid
|
||||
personality = server_args.get(
|
||||
@ -391,6 +396,28 @@ class Group(resource.Resource):
|
||||
else:
|
||||
return True
|
||||
|
||||
def _check_rackconnect_v3_pool_exists(self, pool_id):
|
||||
pools = self.client("rackconnect").list_load_balancer_pools()
|
||||
if pool_id in (p.id for p in pools):
|
||||
return True
|
||||
return False
|
||||
|
||||
def validate(self):
|
||||
super(Group, self).validate()
|
||||
launchconf = self.properties[self.LAUNCH_CONFIGURATION]
|
||||
lcargs = launchconf[self.LAUNCH_CONFIG_ARGS]
|
||||
lb_args = lcargs.get(self.LAUNCH_CONFIG_ARGS_LOAD_BALANCERS)
|
||||
lbs = copy.deepcopy(lb_args)
|
||||
for lb in lbs:
|
||||
lb_port = lb.get(self.LAUNCH_CONFIG_ARGS_LOAD_BALANCER_PORT)
|
||||
lb_id = lb[self.LAUNCH_CONFIG_ARGS_LOAD_BALANCER_ID]
|
||||
if not lb_port:
|
||||
# check if lb id is a valid RCV3 pool id
|
||||
if not self._check_rackconnect_v3_pool_exists(lb_id):
|
||||
msg = _('Could not find RackConnectV3 pool '
|
||||
'with id %s') % (lb_id)
|
||||
raise exception.StackValidationFailed(msg)
|
||||
|
||||
def auto_scale(self):
|
||||
return self.client('auto_scale')
|
||||
|
||||
|
@ -15,6 +15,7 @@ import copy
|
||||
import itertools
|
||||
|
||||
import mock
|
||||
import six
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common import template_format
|
||||
@ -200,6 +201,10 @@ class ScalingGroupTest(common.HeatTestCase):
|
||||
networks:
|
||||
- uuid: "00000000-0000-0000-0000-000000000000"
|
||||
- uuid: "11111111-1111-1111-1111-111111111111"
|
||||
loadBalancers:
|
||||
- loadBalancerId: 234
|
||||
port: 80
|
||||
|
||||
''')
|
||||
|
||||
def setUp(self):
|
||||
@ -237,9 +242,12 @@ class ScalingGroupTest(common.HeatTestCase):
|
||||
'disk_config': None,
|
||||
'flavor': 'flavor-ref',
|
||||
'image': 'image-ref',
|
||||
'launch_config_type': 'launch_server',
|
||||
'load_balancers': None,
|
||||
'load_balancers': [{
|
||||
'loadBalancerId': 234,
|
||||
'port': 80,
|
||||
}],
|
||||
'key_name': "my-key",
|
||||
'launch_config_type': u'launch_server',
|
||||
'max_entities': 25,
|
||||
'group_metadata': {'group': 'metadata'},
|
||||
'metadata': {'server': 'metadata'},
|
||||
@ -668,3 +676,83 @@ class WebHookTest(common.HeatTestCase):
|
||||
del self.fake_auto_scale.webhooks['0']
|
||||
scheduler.TaskRunner(resource.delete)()
|
||||
self.assertEqual({}, self.fake_auto_scale.webhooks)
|
||||
|
||||
|
||||
@mock.patch.object(resource.Resource, "client_plugin")
|
||||
@mock.patch.object(resource.Resource, "client")
|
||||
class AutoScaleGroupValidationTests(common.HeatTestCase):
|
||||
def setUp(self):
|
||||
super(AutoScaleGroupValidationTests, self).setUp()
|
||||
self.mockstack = mock.Mock()
|
||||
self.mockstack.has_cache_data.return_value = False
|
||||
self.mockstack.db_resource_get.return_value = None
|
||||
|
||||
def test_validate_no_rcv3_pool(self, mock_client, mock_plugin):
|
||||
asg_properties = {
|
||||
"groupConfiguration": {
|
||||
"name": "My Group",
|
||||
"cooldown": 60,
|
||||
"minEntities": 1,
|
||||
"maxEntities": 25,
|
||||
"metadata": {
|
||||
"group": "metadata",
|
||||
},
|
||||
},
|
||||
"launchConfiguration": {
|
||||
"type": "launch_server",
|
||||
"args": {
|
||||
"loadBalancers": [{
|
||||
"loadBalancerId": 'not integer!',
|
||||
}],
|
||||
"server": {
|
||||
"name": "sdfsdf",
|
||||
"flavorRef": "ffdgdf",
|
||||
"imageRef": "image-ref",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
rsrcdef = rsrc_defn.ResourceDefinition(
|
||||
"test", auto_scale.Group, properties=asg_properties)
|
||||
asg = auto_scale.Group("test", rsrcdef, self.mockstack)
|
||||
|
||||
mock_client().list_load_balancer_pools.return_value = []
|
||||
error = self.assertRaises(
|
||||
exception.StackValidationFailed, asg.validate)
|
||||
self.assertEqual(
|
||||
'Could not find RackConnectV3 pool with id not integer!: ',
|
||||
six.text_type(error))
|
||||
|
||||
def test_validate_rcv3_pool_found(self, mock_client, mock_plugin):
|
||||
asg_properties = {
|
||||
"groupConfiguration": {
|
||||
"name": "My Group",
|
||||
"cooldown": 60,
|
||||
"minEntities": 1,
|
||||
"maxEntities": 25,
|
||||
"metadata": {
|
||||
"group": "metadata",
|
||||
},
|
||||
},
|
||||
"launchConfiguration": {
|
||||
"type": "launch_server",
|
||||
"args": {
|
||||
"loadBalancers": [{
|
||||
"loadBalancerId": 'pool_exists',
|
||||
}],
|
||||
"server": {
|
||||
"name": "sdfsdf",
|
||||
"flavorRef": "ffdgdf",
|
||||
"imageRef": "image-ref",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
rsrcdef = rsrc_defn.ResourceDefinition(
|
||||
"test", auto_scale.Group, properties=asg_properties)
|
||||
asg = auto_scale.Group("test", rsrcdef, self.mockstack)
|
||||
|
||||
mock_client().list_load_balancer_pools.return_value = [
|
||||
mock.Mock(id='pool_exists'),
|
||||
]
|
||||
self.assertIsNone(asg.validate())
|
||||
|
@ -1 +1 @@
|
||||
pyrax>=1.9.2
|
||||
-e git+https://github.com/rackerlabs/heat-pyrax.git#egg=pyrax
|
||||
|
Loading…
Reference in New Issue
Block a user