Merge "Make LoadBalancer nested stack template configurable"
This commit is contained in:
commit
b81f794c9e
@ -116,6 +116,15 @@
|
|||||||
#cloud_backend=heat.engine.clients.OpenStackClients
|
#cloud_backend=heat.engine.clients.OpenStackClients
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Options defined in heat.engine.resources.loadbalancer
|
||||||
|
#
|
||||||
|
|
||||||
|
# Custom template for the built-in loadbalancer nested stack
|
||||||
|
# (string value)
|
||||||
|
#loadbalancer_template=<None>
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Options defined in heat.openstack.common.db.sqlalchemy.session
|
# Options defined in heat.openstack.common.db.sqlalchemy.session
|
||||||
#
|
#
|
||||||
|
@ -12,7 +12,11 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
import os
|
||||||
|
|
||||||
|
from oslo.config import cfg
|
||||||
|
|
||||||
|
from heat.common import exception
|
||||||
from heat.common import template_format
|
from heat.common import template_format
|
||||||
from heat.engine import constraints
|
from heat.engine import constraints
|
||||||
from heat.engine import properties
|
from heat.engine import properties
|
||||||
@ -24,7 +28,7 @@ from heat.openstack.common.gettextutils import _
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
lb_template = r'''
|
lb_template_default = r'''
|
||||||
{
|
{
|
||||||
"AWSTemplateFormatVersion": "2010-09-09",
|
"AWSTemplateFormatVersion": "2010-09-09",
|
||||||
"Description": "Built in HAProxy server",
|
"Description": "Built in HAProxy server",
|
||||||
@ -192,11 +196,15 @@ lb_template = r'''
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
#
|
# Allow user to provide alternative nested stack template to the above
|
||||||
# TODO(asalkeld) the above inline template _could_ be placed in an external
|
loadbalancer_opts = [
|
||||||
# file at the moment this is because we will probably need to implement a
|
cfg.StrOpt('loadbalancer_template',
|
||||||
# LoadBalancer based on keepalived as well (for for ssl support).
|
default=None,
|
||||||
#
|
help='Custom template for the built-in '
|
||||||
|
'loadbalancer nested stack')]
|
||||||
|
cfg.CONF.register_opts(loadbalancer_opts)
|
||||||
|
|
||||||
|
|
||||||
class LoadBalancer(stack_resource.StackResource):
|
class LoadBalancer(stack_resource.StackResource):
|
||||||
|
|
||||||
PROPERTIES = (
|
PROPERTIES = (
|
||||||
@ -414,8 +422,18 @@ class LoadBalancer(stack_resource.StackResource):
|
|||||||
|
|
||||||
return '%s%s%s%s\n' % (gl, frontend, backend, '\n'.join(servers))
|
return '%s%s%s%s\n' % (gl, frontend, backend, '\n'.join(servers))
|
||||||
|
|
||||||
|
def get_parsed_template(self):
|
||||||
|
if cfg.CONF.loadbalancer_template:
|
||||||
|
with open(cfg.CONF.loadbalancer_template) as templ_fd:
|
||||||
|
logger.info(_('Using custom loadbalancer template %s')
|
||||||
|
% cfg.CONF.loadbalancer_template)
|
||||||
|
contents = templ_fd.read()
|
||||||
|
else:
|
||||||
|
contents = lb_template_default
|
||||||
|
return template_format.parse(contents)
|
||||||
|
|
||||||
def handle_create(self):
|
def handle_create(self):
|
||||||
templ = template_format.parse(lb_template)
|
templ = self.get_parsed_template()
|
||||||
|
|
||||||
if self.properties[self.INSTANCES]:
|
if self.properties[self.INSTANCES]:
|
||||||
md = templ['Resources']['LB_instance']['Metadata']
|
md = templ['Resources']['LB_instance']['Metadata']
|
||||||
@ -441,7 +459,7 @@ class LoadBalancer(stack_resource.StackResource):
|
|||||||
rely on the cfn-hup to reconfigure HAProxy
|
rely on the cfn-hup to reconfigure HAProxy
|
||||||
'''
|
'''
|
||||||
if self.INSTANCES in prop_diff:
|
if self.INSTANCES in prop_diff:
|
||||||
templ = template_format.parse(lb_template)
|
templ = self.get_parsed_template()
|
||||||
cfg = self._haproxy_config(templ, prop_diff[self.INSTANCES])
|
cfg = self._haproxy_config(templ, prop_diff[self.INSTANCES])
|
||||||
|
|
||||||
md = self.nested()['LB_instance'].metadata
|
md = self.nested()['LB_instance'].metadata
|
||||||
@ -461,6 +479,11 @@ class LoadBalancer(stack_resource.StackResource):
|
|||||||
if res:
|
if res:
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
if cfg.CONF.loadbalancer_template and \
|
||||||
|
not os.access(cfg.CONF.loadbalancer_template, os.R_OK):
|
||||||
|
msg = _('Custom LoadBalancer template can not be found')
|
||||||
|
raise exception.StackValidationFailed(message=msg)
|
||||||
|
|
||||||
health_chk = self.properties[self.HEALTH_CHECK]
|
health_chk = self.properties[self.HEALTH_CHECK]
|
||||||
if health_chk:
|
if health_chk:
|
||||||
interval = float(health_chk[self.HEALTH_CHECK_INTERVAL])
|
interval = float(health_chk[self.HEALTH_CHECK_INTERVAL])
|
||||||
|
@ -179,8 +179,9 @@ class LoadBalancerTest(HeatTestCase):
|
|||||||
|
|
||||||
self.assertEqual('LoadBalancer', rsrc.FnGetRefId())
|
self.assertEqual('LoadBalancer', rsrc.FnGetRefId())
|
||||||
|
|
||||||
templ = template_format.parse(lb.lb_template)
|
templ = template_format.parse(lb.lb_template_default)
|
||||||
ha_cfg = rsrc._haproxy_config(templ, rsrc.properties['Instances'])
|
ha_cfg = rsrc._haproxy_config(templ, rsrc.properties['Instances'])
|
||||||
|
|
||||||
self.assertRegexpMatches(ha_cfg, 'bind \*:80')
|
self.assertRegexpMatches(ha_cfg, 'bind \*:80')
|
||||||
self.assertRegexpMatches(ha_cfg, 'server server1 1\.2\.3\.4:80 '
|
self.assertRegexpMatches(ha_cfg, 'server server1 1\.2\.3\.4:80 '
|
||||||
'check inter 30s fall 5 rise 3')
|
'check inter 30s fall 5 rise 3')
|
||||||
@ -228,3 +229,15 @@ class LoadBalancerTest(HeatTestCase):
|
|||||||
msg = '%s: %r not found in %r' % (msg,
|
msg = '%s: %r not found in %r' % (msg,
|
||||||
expected_regexp.pattern, text)
|
expected_regexp.pattern, text)
|
||||||
raise self.failureException(msg)
|
raise self.failureException(msg)
|
||||||
|
|
||||||
|
def test_loadbalancer_validate_badtemplate(self):
|
||||||
|
cfg.CONF.set_override('loadbalancer_template', '/a/noexist/x.y')
|
||||||
|
|
||||||
|
t = template_format.parse(lb_template)
|
||||||
|
s = utils.parse_stack(t)
|
||||||
|
s.store()
|
||||||
|
|
||||||
|
rsrc = lb.LoadBalancer('LoadBalancer',
|
||||||
|
t['Resources']['LoadBalancer'],
|
||||||
|
s)
|
||||||
|
self.assertRaises(exception.StackValidationFailed, rsrc.validate)
|
||||||
|
Loading…
Reference in New Issue
Block a user