Merge "Fix RS CLB resource to handle HTTPS_REDIRECT correctly"

This commit is contained in:
Jenkins 2015-07-24 19:45:59 +00:00 committed by Gerrit Code Review
commit 40f900005e
2 changed files with 79 additions and 21 deletions

View File

@ -506,6 +506,17 @@ class CloudLoadBalancer(resource.Resource):
else: else:
return False return False
def _valid_HTTPS_redirect_with_HTTP_prot(self):
"""Determine if HTTPS redirect is valid when protocol is HTTP"""
proto = self.properties[self.PROTOCOL]
redir = self.properties[self.HTTPS_REDIRECT]
termcfg = self.properties.get(self.SSL_TERMINATION) or {}
seconly = termcfg.get(self.SSL_TERMINATION_SECURE_TRAFFIC_ONLY, False)
secport = termcfg.get(self.SSL_TERMINATION_SECURE_PORT, 0)
if (redir and (proto == "HTTP") and seconly and (secport == 443)):
return True
return False
def _configure_post_creation(self, loadbalancer): def _configure_post_creation(self, loadbalancer):
"""Configure all load balancer properties post creation. """Configure all load balancer properties post creation.
@ -535,6 +546,11 @@ class CloudLoadBalancer(resource.Resource):
secureTrafficOnly=ssl_term[ secureTrafficOnly=ssl_term[
self.SSL_TERMINATION_SECURE_TRAFFIC_ONLY]) self.SSL_TERMINATION_SECURE_TRAFFIC_ONLY])
if self._valid_HTTPS_redirect_with_HTTP_prot():
while not self._check_status(loadbalancer, ['ACTIVE']):
yield
loadbalancer.update(httpsRedirect=True)
if self.CONTENT_CACHING in self.properties: if self.CONTENT_CACHING in self.properties:
enabled = self.properties[self.CONTENT_CACHING] == 'ENABLED' enabled = self.properties[self.CONTENT_CACHING] == 'ENABLED'
while not self._check_status(loadbalancer, ['ACTIVE']): while not self._check_status(loadbalancer, ['ACTIVE']):
@ -555,6 +571,18 @@ class CloudLoadBalancer(resource.Resource):
node_itr = six.moves.map(self._process_node, node_list) node_itr = six.moves.map(self._process_node, node_list)
return itertools.chain.from_iterable(node_itr) return itertools.chain.from_iterable(node_itr)
def _validate_https_redirect(self):
redir = self.properties[self.HTTPS_REDIRECT]
proto = self.properties[self.PROTOCOL]
if (redir and (proto != "HTTPS") and
not self._valid_HTTPS_redirect_with_HTTP_prot()):
message = _("HTTPS redirect is only available for the HTTPS "
"protocol (port=443), or the HTTP protocol with "
"a properly configured SSL termination "
"(secureTrafficOnly=true, securePort=443).")
raise exception.StackValidationFailed(message=message)
def handle_create(self): def handle_create(self):
node_list = self._process_nodes(self.properties.get(self.NODES)) node_list = self._process_nodes(self.properties.get(self.NODES))
nodes = [self.clb.Node(**node) for node in node_list] nodes = [self.clb.Node(**node) for node in node_list]
@ -581,6 +609,9 @@ class CloudLoadBalancer(resource.Resource):
'connectionLogging': connection_logging, 'connectionLogging': connection_logging,
self.HTTPS_REDIRECT: self.properties[self.HTTPS_REDIRECT] self.HTTPS_REDIRECT: self.properties[self.HTTPS_REDIRECT]
} }
if self._valid_HTTPS_redirect_with_HTTP_prot():
lb_body[self.HTTPS_REDIRECT] = False
self._validate_https_redirect()
lb_name = (self.properties.get(self.NAME) or lb_name = (self.properties.get(self.NAME) or
self.physical_resource_name()) self.physical_resource_name())
@ -909,22 +940,8 @@ class CloudLoadBalancer(resource.Resource):
function.resolve, function.resolve,
self.name).validate() self.name).validate()
# validate if HTTPS_REDIRECT is true and we're not HTTPS # validate if HTTPS_REDIRECT is true
redir = self.properties[self.HTTPS_REDIRECT] self._validate_https_redirect()
proto = self.properties[self.PROTOCOL]
if redir and (proto != "HTTPS"):
termcfg = self.properties.get(self.SSL_TERMINATION) or {}
seconly = termcfg.get(self.SSL_TERMINATION_SECURE_TRAFFIC_ONLY,
False)
secport = termcfg.get(self.SSL_TERMINATION_SECURE_PORT, 0)
if not (seconly and (secport == 443) and (proto == "HTTP")):
message = _("HTTPS redirect is only available for the HTTPS "
"protocol (port=443), or the HTTP protocol with "
"a properly configured SSL termination "
"(secureTrafficOnly=true, securePort=443).")
raise exception.StackValidationFailed(message=message)
# if a vip specifies and id, it can't specify version or type; # if a vip specifies and id, it can't specify version or type;
# otherwise version and type are required # otherwise version and type are required
for vip in self.properties.get(self.VIRTUAL_IPS, []): for vip in self.properties.get(self.VIRTUAL_IPS, []):

View File

@ -913,12 +913,15 @@ class LoadBalancerTest(common.HeatTestCase):
self.m.VerifyAll() self.m.VerifyAll()
def test_update_lb_redirect(self): def test_update_lb_redirect(self):
templ = copy.deepcopy(self.lb_template) template = self._set_template(
rsrs = templ['Resources'].values()[0] self.lb_template, protocol="HTTPS")
rsrs['Properties']['protocol'] = "HTTPS"
rsrc, fake_loadbalancer = self._mock_loadbalancer(self.lb_template, expected = self._set_expected(
self.expected_body, protocol="HTTPS")
rsrc, fake_loadbalancer = self._mock_loadbalancer(template,
self.lb_name, self.lb_name,
self.expected_body) expected)
self.m.ReplayAll() self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
@ -936,6 +939,44 @@ class LoadBalancerTest(common.HeatTestCase):
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state) self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll() self.m.VerifyAll()
def test_lb_redirect_https(self):
template = self._set_template(
self.lb_template, protocol="HTTPS", httpsRedirect=True)
expected = self._set_expected(
self.expected_body, protocol="HTTPS", httpsRedirect=True)
rsrc, fake_loadbalancer = self._mock_loadbalancer(template,
self.lb_name,
expected)
self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
def test_lb_redirect_HTTP_with_SSL_term(self):
ssl_termination = {
'privatekey': private_key,
'intermediateCertificate': 'fwaefawe',
'secureTrafficOnly': True,
'securePort': 443,
'certificate': cert
}
template = self._set_template(
self.lb_template, sslTermination=ssl_termination, protocol="HTTP",
httpsRedirect=True)
expected = self._set_expected(
self.expected_body, protocol="HTTP", httpsRedirect=False)
rsrc, fake_loadbalancer = self._mock_loadbalancer(template,
self.lb_name,
expected)
self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)()
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
self.m.VerifyAll()
def test_update_lb_half_closed(self): def test_update_lb_half_closed(self):
rsrc, fake_loadbalancer = self._mock_loadbalancer(self.lb_template, rsrc, fake_loadbalancer = self._mock_loadbalancer(self.lb_template,
self.lb_name, self.lb_name,