2203 lines
87 KiB
Python
2203 lines
87 KiB
Python
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
|
|
import copy
|
|
import json
|
|
import uuid
|
|
|
|
import mock
|
|
import mox
|
|
import six
|
|
|
|
from heat.common import exception
|
|
from heat.common import template_format
|
|
from heat.engine import resource
|
|
from heat.engine import rsrc_defn
|
|
from heat.engine import scheduler
|
|
from heat.tests import common
|
|
from heat.tests import utils
|
|
|
|
from ..resources import cloud_loadbalancer as lb # noqa
|
|
|
|
# The following fakes are for pyrax
|
|
|
|
|
|
cert = """\n-----BEGIN CERTIFICATE-----
|
|
MIIFBjCCAu4CCQDWdcR5LY/+/jANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
|
|
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
|
|
cyBQdHkgTHRkMB4XDTE0MTAxNjE3MDYxNVoXDTE1MTAxNjE3MDYxNVowRTELMAkG
|
|
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
|
|
IFdpZGdpdHMgUHR5IEx0ZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
|
|
AMm5NcP0tMKHblT6Ud1k8TxZ9/8uOHwUNPbvFsvSyCupj0J0vGCTjbuC2I5T/CXR
|
|
tnLEIt/EarlNAqcjbDCWtSyEKs3zDmmkreoIDEa8pyAQ2ycsCXGMxDN97F3/wlLZ
|
|
agUNM0FwGHLZWBg62bM6l+bpTUcX0PqSyv/aVMhJ8EPDX0Dx1RYsVwUzIe/HWC7x
|
|
vCmtDApAp1Fwq7AwlRaKU17sGwPWJ8+I8PyouBdqNuslHm7LQ0XvBA5DfkQA6feB
|
|
ZeJIyOtctM9WFWQI5fKOsyt5P306B3Zztw9VZLAmZ8qHex+R1WY1zXxDAwKEQz/X
|
|
8bRqMA/VU8OxJcK0AmY/1v/TFmAlRh2XBCIc+5UGtCcftWvZJAsKur8Hg5pPluGv
|
|
ptyqSgSsSKtOVWkyTANP1LyOkpBA8Kmkeo2CKXu1SCFypY5Q6E+Fy8Y8RaHJPvzR
|
|
NHcm1tkBvHOKyRso6FjvxuJEyIC9EyUK010nwQm7Qui11VgCSHBoaKVvkIbFfQdK
|
|
aCes0oQO5dqY0+fC/IFDhrxlvSd2Wk7KjuNjNu9kVN9Ama2pRTxhYKaN+GsHfoL7
|
|
ra6G9HjbUVULAdjCko3zOKEUzFLLf1VZYk7hDhyv9kovk0b8sr5WowxW7+9Wy0NK
|
|
WL5f2QgVCcoHw9bGhyuYQCdBfztNmKOWe9pGj6bQAx4pAgMBAAEwDQYJKoZIhvcN
|
|
AQEFBQADggIBALFSj3G2TEL/UWtNcPeY2fbxSGBrboFx3ur8+zTkdZzvfC8H9/UK
|
|
w0aRH0rK4+lKYDqF6A9bUHP17DaJm1lF9In38VVMOuur0ehUIn1S2U3OvlDLN68S
|
|
p5D4wGKMcUfUQ6pzhSKJCMvGX561TKHCc5fZhPruy75Xq2DcwJENE189foKLFvJs
|
|
ca4sIARqP6v1vfARcfH5leSsdIq8hy6VfL0BRATXfNHZh4SNbyDJYYTxrEUPHYXW
|
|
pzW6TziZXYNMG2ZRdHF/mDJuFzw2EklOrPC9MySCZv2i9swnqyuwNYh/SAMhodTv
|
|
ZDGy4nbjWNe5BflTMBceh45VpyTcnQulFhZQFwP79fK10BoDrOc1mEefhIqT+fPI
|
|
LJepLOf7CSXtYBcWbmMCLHNh+PrlCiA1QMTyd/AC1vvoiyCbs3M419XbXcBSDEh8
|
|
tACplmhf6z1vDkElWiDr8y0kujJ/Gie24iLTun6oHG+f+o6bbQ9w196T0olLcGx0
|
|
oAYL0Olqli6cWHhraVAzZ5t5PH4X9TiESuQ+PMjqGImCIUscXY4objdnB5dfPHoz
|
|
eF5whPl36/GK8HUixCibkCyqEOBBuNqhOz7nVLM0eg5L+TE5coizEBagxVCovYSj
|
|
fQ9zkIgaC5oeH6L0C1FFG1vRNSWokheBk14ztVoJCJyFr6p0/6pD7SeR
|
|
-----END CERTIFICATE-----\n"""
|
|
|
|
private_key = """\n-----BEGIN PRIVATE KEY-----
|
|
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
|
|
LpTt0Xs1OFZxaNpolW5Qis4os7UmmIRV
|
|
-----END PRIVATE KEY-----\n"""
|
|
|
|
|
|
class FakeException(Exception):
|
|
pass
|
|
|
|
|
|
class FakeClient(object):
|
|
user_agent = "Fake"
|
|
USER_AGENT = "Fake"
|
|
|
|
|
|
class FakeManager(object):
|
|
api = FakeClient()
|
|
|
|
def list(self):
|
|
pass
|
|
|
|
def get(self, item):
|
|
pass
|
|
|
|
def delete(self, item):
|
|
pass
|
|
|
|
def create(self, *args, **kwargs):
|
|
pass
|
|
|
|
def find(self, *args, **kwargs):
|
|
pass
|
|
|
|
def action(self, item, action_type, body=None):
|
|
pass
|
|
|
|
|
|
class FakeLoadBalancerManager(object):
|
|
def __init__(self, api=None, *args, **kwargs):
|
|
pass
|
|
|
|
def set_content_caching(self, *args, **kwargs):
|
|
pass
|
|
|
|
|
|
class FakeNode(object):
|
|
def __init__(self, address=None, port=None, condition=None, weight=None,
|
|
status=None, parent=None, type=None, id=None):
|
|
if not (address and port):
|
|
# This mimics the check that pyrax does on Node instantiation
|
|
raise TypeError("You must include an address and "
|
|
"a port when creating a node.")
|
|
self.address = address
|
|
self.port = port
|
|
self.condition = condition
|
|
self.weight = weight
|
|
self.status = status
|
|
self.parent = parent
|
|
self.type = type
|
|
self.id = id
|
|
|
|
def __eq__(self, other):
|
|
return self.__dict__ == other.__dict__
|
|
|
|
def __ne__(self, other):
|
|
return not self.__eq__(other)
|
|
|
|
def update(self):
|
|
pass
|
|
|
|
def delete(self):
|
|
pass
|
|
|
|
|
|
class FakeVirtualIP(object):
|
|
def __init__(self, address=None, port=None, condition=None,
|
|
ipVersion=None, type=None, id=None):
|
|
self.address = address
|
|
self.port = port
|
|
self.condition = condition
|
|
self.ipVersion = ipVersion
|
|
self.type = type
|
|
self.id = id
|
|
self.ip_version = ipVersion
|
|
|
|
def __eq__(self, other):
|
|
return self.__dict__ == other.__dict__
|
|
|
|
def __ne__(self, other):
|
|
return not self.__eq__(other)
|
|
|
|
|
|
class FakeLoadBalancerClient(object):
|
|
def __init__(self, *args, **kwargs):
|
|
self.Node = FakeNode
|
|
self.VirtualIP = FakeVirtualIP
|
|
pass
|
|
|
|
def get(self, *args, **kwargs):
|
|
pass
|
|
|
|
def create(self, *args, **kwargs):
|
|
pass
|
|
|
|
|
|
class FakeLoadBalancer(object):
|
|
def __init__(self, name=None, info=None, *args, **kwargs):
|
|
name = name or uuid.uuid4()
|
|
info = info or {"fake": "fake"}
|
|
self.id = uuid.uuid4()
|
|
self.manager = FakeLoadBalancerManager()
|
|
self.Node = FakeNode
|
|
self.VirtualIP = FakeVirtualIP
|
|
self.nodes = []
|
|
self.algorithm = "ROUND_ROBIN"
|
|
self.session_persistence = "HTTP_COOKIE"
|
|
self.connection_logging = False
|
|
self.timeout = None
|
|
self.httpsRedirect = False
|
|
self.protocol = None
|
|
self.port = None
|
|
self.name = None
|
|
self.halfClosed = None
|
|
self.content_caching = False
|
|
|
|
def get(self, *args, **kwargs):
|
|
pass
|
|
|
|
def add_nodes(self, *args, **kwargs):
|
|
pass
|
|
|
|
def add_ssl_termination(self, *args, **kwargs):
|
|
pass
|
|
|
|
def set_error_page(self, *args, **kwargs):
|
|
pass
|
|
|
|
def clear_error_page(self, *args, **kwargs):
|
|
pass
|
|
|
|
def add_access_list(self, *args, **kwargs):
|
|
pass
|
|
|
|
def update(self, *args, **kwargs):
|
|
pass
|
|
|
|
def add_health_monitor(self, *args, **kwargs):
|
|
pass
|
|
|
|
def delete_health_monitor(self, *args, **kwargs):
|
|
pass
|
|
|
|
def delete_ssl_termination(self, *args, **kwargs):
|
|
pass
|
|
|
|
def set_metadata(self, *args, **kwargs):
|
|
pass
|
|
|
|
def delete_metadata(self, *args, **kwargs):
|
|
pass
|
|
|
|
def add_connection_throttle(self, *args, **kwargs):
|
|
pass
|
|
|
|
def delete_connection_throttle(self, *args, **kwargs):
|
|
pass
|
|
|
|
def delete(self, *args, **kwargs):
|
|
pass
|
|
|
|
def get_health_monitor(self, *args, **kwargs):
|
|
return {}
|
|
|
|
def get_metadata(self, *args, **kwargs):
|
|
return {}
|
|
|
|
def get_error_page(self, *args, **kwargs):
|
|
pass
|
|
|
|
def get_connection_throttle(self, *args, **kwargs):
|
|
pass
|
|
|
|
def get_ssl_termination(self, *args, **kwargs):
|
|
pass
|
|
|
|
def get_access_list(self, *args, **kwargs):
|
|
pass
|
|
|
|
|
|
class LoadBalancerWithFakeClient(lb.CloudLoadBalancer):
|
|
def cloud_lb(self):
|
|
return FakeLoadBalancerClient()
|
|
|
|
|
|
def override_resource():
|
|
return {
|
|
'Rackspace::Cloud::LoadBalancer': LoadBalancerWithFakeClient
|
|
}
|
|
|
|
|
|
class LoadBalancerTest(common.HeatTestCase):
|
|
|
|
def setUp(self):
|
|
super(LoadBalancerTest, self).setUp()
|
|
|
|
self.lb_props = {
|
|
"name": "test-clb",
|
|
"nodes": [{"addresses": ["166.78.103.141"],
|
|
"port": 80,
|
|
"condition": "ENABLED"}],
|
|
"protocol": "HTTP",
|
|
"port": 80,
|
|
"virtualIps": [
|
|
{"type": "PUBLIC", "ipVersion": "IPV6"}],
|
|
"algorithm": 'LEAST_CONNECTIONS',
|
|
"connectionThrottle": {'maxConnectionRate': 1000},
|
|
'timeout': 110,
|
|
'contentCaching': 'DISABLED'
|
|
}
|
|
|
|
self.lb_template = {
|
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
"Description": "fawef",
|
|
"Resources": {
|
|
self._get_lb_resource_name(): {
|
|
"Type": "Rackspace::Cloud::LoadBalancer",
|
|
"Properties": self.lb_props,
|
|
}
|
|
}
|
|
}
|
|
|
|
self.lb_name = 'test-clb'
|
|
self.expected_body = {
|
|
"nodes": [FakeNode(address=u"166.78.103.141", port=80,
|
|
condition=u"ENABLED", type=u"PRIMARY",
|
|
weight=1)],
|
|
"protocol": u'HTTP',
|
|
"port": 80,
|
|
"virtual_ips": [FakeVirtualIP(type=u"PUBLIC", ipVersion=u"IPV6")],
|
|
"algorithm": u'LEAST_CONNECTIONS',
|
|
"connectionThrottle": {'maxConnectionRate': 1000,
|
|
'maxConnections': None,
|
|
'rateInterval': None,
|
|
'minConnections': None},
|
|
"connectionLogging": None,
|
|
"halfClosed": None,
|
|
"healthMonitor": None,
|
|
"metadata": None,
|
|
"sessionPersistence": None,
|
|
"timeout": 110,
|
|
"httpsRedirect": False
|
|
|
|
}
|
|
|
|
lb.resource_mapping = override_resource
|
|
resource._register_class("Rackspace::Cloud::LoadBalancer",
|
|
LoadBalancerWithFakeClient)
|
|
|
|
def _get_lb_resource_name(self):
|
|
return "lb-" + str(uuid.uuid4())
|
|
|
|
def __getattribute__(self, name):
|
|
if name == 'expected_body' or name == 'lb_template':
|
|
return copy.deepcopy(super(LoadBalancerTest, self)
|
|
.__getattribute__(name))
|
|
return super(LoadBalancerTest, self).__getattribute__(name)
|
|
|
|
def _mock_create(self, tmpl, stack, resource_name, lb_name, lb_body):
|
|
resource_defns = tmpl.resource_definitions(stack)
|
|
rsrc = LoadBalancerWithFakeClient(resource_name,
|
|
resource_defns[resource_name],
|
|
stack)
|
|
|
|
fake_lb = FakeLoadBalancer(name=lb_name)
|
|
fake_lb.status = 'ACTIVE'
|
|
fake_lb.resource_id = 1234
|
|
|
|
self.m.StubOutWithMock(rsrc.clb, 'create')
|
|
rsrc.clb.create(lb_name, **lb_body).AndReturn(fake_lb)
|
|
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).MultipleTimes().AndReturn(
|
|
fake_lb)
|
|
|
|
return (rsrc, fake_lb)
|
|
|
|
def _get_first_resource_name(self, templ):
|
|
return next(k for k in templ['Resources'])
|
|
|
|
def _mock_loadbalancer(self, lb_template, expected_name, expected_body):
|
|
t = template_format.parse(json.dumps(lb_template))
|
|
self.stack = utils.parse_stack(t, stack_name=utils.random_name())
|
|
|
|
rsrc, fake_lb = self._mock_create(self.stack.t, self.stack,
|
|
self.
|
|
_get_first_resource_name(
|
|
lb_template),
|
|
expected_name,
|
|
expected_body)
|
|
return (rsrc, fake_lb)
|
|
|
|
def _set_template(self, templ, **kwargs):
|
|
for k, v in six.iteritems(kwargs):
|
|
templ['Resources'][self._get_first_resource_name(templ)][
|
|
'Properties'][k] = v
|
|
return templ
|
|
|
|
def _set_expected(self, expected, **kwargs):
|
|
for k, v in six.iteritems(kwargs):
|
|
expected[k] = v
|
|
return expected
|
|
|
|
def test_process_node(self):
|
|
nodes = [{'addresses': ['1234'], 'port': 80, 'enabled': True},
|
|
{'addresses': ['4567', '8901', '8903'], 'port': 80,
|
|
'enabled': True},
|
|
{'addresses': [], 'port': 80, 'enabled': True}]
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
expected_nodes = [{'address': '1234', 'port': 80, 'enabled': True},
|
|
{'address': '4567', 'port': 80, 'enabled': True},
|
|
{'address': '8901', 'port': 80, 'enabled': True},
|
|
{'address': '8903', 'port': 80, 'enabled': True}]
|
|
self.assertEqual(expected_nodes, list(rsrc._process_nodes(nodes)))
|
|
|
|
def test_nodeless(self):
|
|
"""It's possible to create a LoadBalancer resource with no nodes."""
|
|
template = self._set_template(self.lb_template,
|
|
nodes=[])
|
|
expected_body = copy.deepcopy(self.expected_body)
|
|
expected_body['nodes'] = []
|
|
rsrc, fake_lb = self._mock_loadbalancer(
|
|
template, self.lb_name, expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
self.m.VerifyAll()
|
|
|
|
def test_alter_properties(self):
|
|
# test alter properties functions
|
|
template = self._set_template(self.lb_template,
|
|
sessionPersistence='HTTP_COOKIE',
|
|
connectionLogging=True,
|
|
metadata={'yolo': 'heeyyy_gurl'})
|
|
|
|
expected = self._set_expected(self.expected_body,
|
|
sessionPersistence={
|
|
'persistenceType': 'HTTP_COOKIE'},
|
|
connectionLogging={'enabled': True},
|
|
metadata=[
|
|
{'key': 'yolo',
|
|
'value': 'heeyyy_gurl'}])
|
|
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
self.m.VerifyAll()
|
|
|
|
def test_validate_vip(self):
|
|
snippet = {
|
|
"nodes": [],
|
|
"protocol": 'HTTP',
|
|
"port": 80,
|
|
"halfClosed": None,
|
|
"algorithm": u'LEAST_CONNECTIONS',
|
|
"virtualIps": [{"id": "1234"}]
|
|
}
|
|
stack = mock.Mock()
|
|
stack.db_resource_get.return_value = None
|
|
stack.has_cache_data.return_value = False
|
|
# happy path
|
|
resdef = rsrc_defn.ResourceDefinition("testvip",
|
|
lb.CloudLoadBalancer,
|
|
properties=snippet)
|
|
rsrc = lb.CloudLoadBalancer("testvip", resdef, stack)
|
|
self.assertIsNone(rsrc.validate())
|
|
# make sure the vip id prop is exclusive
|
|
snippet["virtualIps"][0]["type"] = "PUBLIC"
|
|
exc = self.assertRaises(exception.StackValidationFailed,
|
|
rsrc.validate)
|
|
self.assertIn("Cannot specify type or version", str(exc))
|
|
# make sure you have to specify type and version if no id
|
|
snippet["virtualIps"] = [{}]
|
|
exc = self.assertRaises(exception.StackValidationFailed,
|
|
rsrc.validate)
|
|
self.assertIn("Must specify VIP type and version", str(exc))
|
|
|
|
def test_validate_half_closed(self):
|
|
# test failure (invalid protocol)
|
|
template = self._set_template(self.lb_template, halfClosed=True)
|
|
expected = self._set_expected(self.expected_body, halfClosed=True)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected)
|
|
exc = self.assertRaises(exception.StackValidationFailed,
|
|
rsrc.validate)
|
|
self.assertIn('The halfClosed property is only available for the TCP'
|
|
' or TCP_CLIENT_FIRST protocols', str(exc))
|
|
|
|
# test TCP protocol
|
|
template = self._set_template(template, protocol='TCP')
|
|
expected = self._set_expected(expected, protocol='TCP')
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected)
|
|
self.assertIsNone(rsrc.validate())
|
|
|
|
# test TCP_CLIENT_FIRST protocol
|
|
template = self._set_template(template,
|
|
protocol='TCP_CLIENT_FIRST')
|
|
expected = self._set_expected(expected,
|
|
protocol='TCP_CLIENT_FIRST')
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected)
|
|
self.assertIsNone(rsrc.validate())
|
|
|
|
def test_validate_health_monitor(self):
|
|
# test connect success
|
|
health_monitor = {
|
|
'type': 'CONNECT',
|
|
'attemptsBeforeDeactivation': 1,
|
|
'delay': 1,
|
|
'timeout': 1
|
|
}
|
|
template = self._set_template(self.lb_template,
|
|
healthMonitor=health_monitor)
|
|
expected = self._set_expected(self.expected_body,
|
|
healthMonitor=health_monitor)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected)
|
|
|
|
self.assertIsNone(rsrc.validate())
|
|
|
|
# test connect failure
|
|
# bodyRegex is only valid for type 'HTTP(S)'
|
|
health_monitor['bodyRegex'] = 'dfawefawe'
|
|
template = self._set_template(template,
|
|
healthMonitor=health_monitor)
|
|
expected = self._set_expected(expected,
|
|
healthMonitor=health_monitor)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected)
|
|
exc = self.assertRaises(exception.StackValidationFailed,
|
|
rsrc.validate)
|
|
self.assertIn('Unknown Property bodyRegex', str(exc))
|
|
|
|
# test http fields
|
|
health_monitor['type'] = 'HTTP'
|
|
health_monitor['bodyRegex'] = 'bodyRegex'
|
|
health_monitor['statusRegex'] = 'statusRegex'
|
|
health_monitor['hostHeader'] = 'hostHeader'
|
|
health_monitor['path'] = 'path'
|
|
|
|
template = self._set_template(template,
|
|
healthMonitor=health_monitor)
|
|
expected = self._set_expected(expected,
|
|
healthMonitor=health_monitor)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected)
|
|
self.assertIsNone(rsrc.validate())
|
|
|
|
def test_validate_ssl_termination(self):
|
|
ssl_termination = {
|
|
'privatekey': 'ewfawe',
|
|
'intermediateCertificate': 'fwaefawe',
|
|
'secureTrafficOnly': True
|
|
}
|
|
|
|
# test ssl termination enabled without required fields failure
|
|
template = self._set_template(self.lb_template,
|
|
sslTermination=ssl_termination)
|
|
expected = self._set_expected(self.expected_body,
|
|
sslTermination=ssl_termination)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected)
|
|
|
|
exc = self.assertRaises(exception.StackValidationFailed, rsrc.validate)
|
|
self.assertIn("Property certificate not assigned", six.text_type(exc))
|
|
|
|
ssl_termination['certificate'] = 'dfaewfwef'
|
|
template = self._set_template(template,
|
|
sslTermination=ssl_termination)
|
|
expected = self._set_expected(expected,
|
|
sslTermination=ssl_termination)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected)
|
|
self.assertIsNone(rsrc.validate())
|
|
|
|
def test_ssl_termination_unstripped_certificates(self):
|
|
ssl_termination_template = {
|
|
'securePort': 443,
|
|
'privatekey': 'afwefawe',
|
|
'certificate': ' \nfawefwea\n ',
|
|
'intermediateCertificate': "\n\nintermediate_certificate\n",
|
|
'secureTrafficOnly': False
|
|
}
|
|
ssl_termination_api = copy.deepcopy(ssl_termination_template)
|
|
|
|
template = self._set_template(self.lb_template,
|
|
sslTermination=ssl_termination_template)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.StubOutWithMock(fake_lb, 'get_ssl_termination')
|
|
fake_lb.get_ssl_termination().AndReturn({})
|
|
fake_lb.get_ssl_termination().AndReturn({
|
|
'securePort': 443,
|
|
'certificate': 'fawefwea',
|
|
'intermediateCertificate': "intermediate_certificate",
|
|
'secureTrafficOnly': False,
|
|
'enabled': True,
|
|
})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'add_ssl_termination')
|
|
fake_lb.add_ssl_termination(**ssl_termination_api)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
self.m.VerifyAll()
|
|
|
|
def test_ssl_termination_intermediateCertificate_None(self):
|
|
ssl_termination_template = {
|
|
'securePort': 443,
|
|
'privatekey': 'afwefawe',
|
|
'certificate': ' \nfawefwea\n ',
|
|
'intermediateCertificate': None,
|
|
'secureTrafficOnly': False
|
|
}
|
|
|
|
template = self._set_template(self.lb_template,
|
|
sslTermination=ssl_termination_template)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.StubOutWithMock(fake_lb, 'get_ssl_termination')
|
|
fake_lb.get_ssl_termination().AndReturn({})
|
|
fake_lb.get_ssl_termination().AndReturn({
|
|
'securePort': 443,
|
|
'certificate': 'fawefwea',
|
|
'secureTrafficOnly': False,
|
|
'enabled': True,
|
|
})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'add_ssl_termination')
|
|
add_ssl_termination_args = {
|
|
'securePort': 443,
|
|
'privatekey': 'afwefawe',
|
|
'certificate': ' \nfawefwea\n ',
|
|
'intermediateCertificate': '',
|
|
'secureTrafficOnly': False
|
|
}
|
|
fake_lb.add_ssl_termination(**add_ssl_termination_args)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
self.m.VerifyAll()
|
|
|
|
def test_post_creation_access_list(self):
|
|
access_list = [{"address": '192.168.1.1/0',
|
|
'type': 'ALLOW'},
|
|
{'address': '172.165.3.43',
|
|
'type': 'DENY'}]
|
|
api_access_list = [{"address": '192.168.1.1/0', 'id': 1234,
|
|
'type': 'ALLOW'},
|
|
{'address': '172.165.3.43', 'id': 3422,
|
|
'type': 'DENY'}]
|
|
|
|
template = self._set_template(self.lb_template,
|
|
accessList=access_list)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.StubOutWithMock(fake_lb, 'get_access_list')
|
|
fake_lb.get_access_list().AndReturn([])
|
|
fake_lb.get_access_list().AndReturn(api_access_list)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'add_access_list')
|
|
fake_lb.add_access_list(access_list)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
self.m.VerifyAll()
|
|
|
|
def test_ref_id(self):
|
|
"""The Reference ID of the resource is the resource ID."""
|
|
template = self._set_template(self.lb_template)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
self.m.VerifyAll()
|
|
|
|
self.assertEqual(rsrc.resource_id, rsrc.FnGetRefId())
|
|
|
|
def test_post_creation_error_page(self):
|
|
error_page = "REALLY BIG ERROR"
|
|
|
|
template = self._set_template(self.lb_template,
|
|
errorPage=error_page)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.StubOutWithMock(fake_lb, 'get_error_page')
|
|
fake_lb.get_error_page().AndReturn({u'errorpage': {u'content': u''}})
|
|
fake_lb.get_error_page().AndReturn(
|
|
{u'errorpage': {u'content': error_page}})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'set_error_page')
|
|
fake_lb.set_error_page(error_page)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
self.m.VerifyAll()
|
|
|
|
def test_post_creation_ssl_termination(self):
|
|
ssl_termination_template = {
|
|
'securePort': 443,
|
|
'privatekey': 'afwefawe',
|
|
'certificate': 'fawefwea',
|
|
'intermediateCertificate': "intermediate_certificate",
|
|
'secureTrafficOnly': False
|
|
}
|
|
ssl_termination_api = copy.deepcopy(ssl_termination_template)
|
|
|
|
template = self._set_template(self.lb_template,
|
|
sslTermination=ssl_termination_template)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.StubOutWithMock(fake_lb, 'get_ssl_termination')
|
|
fake_lb.get_ssl_termination().AndReturn({})
|
|
fake_lb.get_ssl_termination().AndReturn({
|
|
'securePort': 443,
|
|
'certificate': 'fawefwea',
|
|
'intermediateCertificate': "intermediate_certificate",
|
|
'secureTrafficOnly': False,
|
|
'enabled': True,
|
|
})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'add_ssl_termination')
|
|
fake_lb.add_ssl_termination(**ssl_termination_api)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
self.m.VerifyAll()
|
|
|
|
def test_post_creation_content_caching(self):
|
|
template = self._set_template(self.lb_template,
|
|
contentCaching='ENABLED')
|
|
rsrc = self._mock_loadbalancer(template, self.lb_name,
|
|
self.expected_body)[0]
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
self.m.VerifyAll()
|
|
|
|
def test_check(self):
|
|
stack = mock.Mock()
|
|
stack.db_resource_get.return_value = None
|
|
stack.has_cache_data.return_value = False
|
|
resdef = mock.Mock(spec=rsrc_defn.ResourceDefinition)
|
|
loadbalancer = lb.CloudLoadBalancer("test", resdef, stack)
|
|
loadbalancer._add_event = mock.Mock()
|
|
mock_cloud_lb = mock.Mock()
|
|
mock_get = mock.Mock(return_value=mock_cloud_lb)
|
|
loadbalancer.clb.get = mock_get
|
|
|
|
mock_cloud_lb.status = 'ACTIVE'
|
|
scheduler.TaskRunner(loadbalancer.check)()
|
|
self.assertEqual('CHECK', loadbalancer.action)
|
|
self.assertEqual('COMPLETE', loadbalancer.status)
|
|
|
|
mock_cloud_lb.status = 'FOOBAR'
|
|
exc = self.assertRaises(exception.ResourceFailure,
|
|
scheduler.TaskRunner(loadbalancer.check))
|
|
self.assertEqual('CHECK', loadbalancer.action)
|
|
self.assertEqual('FAILED', loadbalancer.status)
|
|
self.assertIn('FOOBAR', str(exc))
|
|
|
|
mock_get.side_effect = lb.NotFound('boom')
|
|
exc = self.assertRaises(exception.ResourceFailure,
|
|
scheduler.TaskRunner(loadbalancer.check))
|
|
self.assertEqual('CHECK', loadbalancer.action)
|
|
self.assertEqual('FAILED', loadbalancer.status)
|
|
self.assertIn('boom', str(exc))
|
|
|
|
def test_update_add_node_by_address(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
fake_lb.nodes = self.expected_body['nodes']
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
expected_ip = '172.168.1.4'
|
|
props['nodes'] = [
|
|
{"addresses": ["166.78.103.141"],
|
|
"port": 80,
|
|
"condition": "ENABLED",
|
|
"type": "PRIMARY",
|
|
"weight": 1},
|
|
{"addresses": [expected_ip],
|
|
"port": 80,
|
|
"condition": "ENABLED",
|
|
"type": "PRIMARY",
|
|
"weight": 1}]
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.nodes = [
|
|
FakeNode(address=u"172.168.1.4", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1),
|
|
FakeNode(address=u"166.78.103.141", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1),
|
|
]
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'add_nodes')
|
|
fake_lb.add_nodes([
|
|
fake_lb.Node(address=expected_ip,
|
|
port=80,
|
|
condition='ENABLED',
|
|
type="PRIMARY", weight=1)])
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_resolve_attr_noid(self):
|
|
stack = mock.Mock()
|
|
stack.db_resource_get.return_value = None
|
|
stack.has_cache_data.return_value = False
|
|
resdef = mock.Mock(spec=rsrc_defn.ResourceDefinition)
|
|
lbres = lb.CloudLoadBalancer("test", resdef, stack)
|
|
self.assertIsNone(lbres._resolve_attribute("PublicIp"))
|
|
|
|
def test_resolve_attr_virtualips(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
fake_lb.virtual_ips = [FakeVirtualIP(address='1.2.3.4',
|
|
type='PUBLIC',
|
|
ipVersion="IPv6",
|
|
id='test-id')]
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
expected = [{
|
|
'ip_version': 'IPv6',
|
|
'type': 'PUBLIC',
|
|
'id': 'test-id',
|
|
'address': '1.2.3.4'}]
|
|
self.m.ReplayAll()
|
|
self.assertEqual(expected, rsrc._resolve_attribute("virtualIps"))
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_nodes_immutable(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
current_nodes = [
|
|
FakeNode(address=u"1.1.1.1", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1),
|
|
FakeNode(address=u"2.2.2.2", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1),
|
|
FakeNode(address=u"3.3.3.3", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1)
|
|
]
|
|
fake_lb.nodes = current_nodes
|
|
fake_lb.tracker = "fake_lb"
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
expected_ip = '4.4.4.4'
|
|
props['nodes'] = [
|
|
{"addresses": ["1.1.1.1"], "port": 80, "condition": "ENABLED",
|
|
"type": "PRIMARY", "weight": 1},
|
|
{"addresses": ["2.2.2.2"], "port": 80, "condition": "DISABLED",
|
|
"type": "PRIMARY", "weight": 1},
|
|
{"addresses": [expected_ip], "port": 80, "condition": "ENABLED",
|
|
"type": "PRIMARY", "weight": 1}
|
|
]
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.status = "PENDING_UPDATE"
|
|
fake_lb1.tracker = "fake_lb1"
|
|
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb) # ACTIVE
|
|
|
|
# Add node `expected_ip`
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1) # PENDING_UPDATE
|
|
|
|
fake_lb2 = copy.deepcopy(fake_lb1)
|
|
fake_lb2.status = "ACTIVE"
|
|
fake_lb2.nodes = [
|
|
FakeNode(address=u"1.1.1.1", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1),
|
|
FakeNode(address=u"2.2.2.2", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1),
|
|
FakeNode(address=u"3.3.3.3", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1),
|
|
FakeNode(address=u"4.4.4.4", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1),
|
|
]
|
|
fake_lb2.tracker = "fake_lb2"
|
|
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb2) # ACTIVE
|
|
|
|
# Delete node 3.3.3.3
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1) # PENDING_UPDATE
|
|
|
|
fake_lb3 = copy.deepcopy(fake_lb2)
|
|
fake_lb3.status = "ACTIVE"
|
|
fake_lb3.nodes = [
|
|
FakeNode(address=u"1.1.1.1", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1),
|
|
FakeNode(address=u"2.2.2.2", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1),
|
|
FakeNode(address=u"4.4.4.4", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1)
|
|
]
|
|
fake_lb3.tracker = "fake_lb3"
|
|
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb3) # ACTIVE
|
|
|
|
# Update node 2.2.2.2
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1) # PENDING_UPDATE
|
|
|
|
fake_lb4 = copy.deepcopy(fake_lb3)
|
|
fake_lb4.status = "ACTIVE"
|
|
fake_lb4.nodes = [
|
|
FakeNode(address=u"1.1.1.1", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1),
|
|
FakeNode(address=u"2.2.2.2", port=80, condition=u"DISABLED",
|
|
type="PRIMARY", weight=1),
|
|
FakeNode(address=u"4.4.4.4", port=80, condition=u"ENABLED",
|
|
type="PRIMARY", weight=1)
|
|
]
|
|
fake_lb4.tracker = "fake_lb4"
|
|
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb4) # ACTIVE
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_pending_update_status(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['name'] = "updated_name"
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.name = "updated_name"
|
|
fake_lb1.status = "PENDING_UPDATE" # lb is immutable
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
fake_lb2 = copy.deepcopy(fake_lb)
|
|
fake_lb2.name = "updated_name"
|
|
fake_lb2.status = "ACTIVE"
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb2)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_immutable_exception(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['name'] = "updated_name"
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb) # initial iteration
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb) # immutable
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.name = "updated_name"
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1) # after update
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'update')
|
|
msg = ("Load Balancer '%s' has a status of 'PENDING_UPDATE' and "
|
|
"is considered immutable." % rsrc.resource_id)
|
|
fake_lb.update(name="updated_name").AndRaise(Exception(msg))
|
|
fake_lb.update(name="updated_name").AndReturn(None)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_create_immutable_exception(self):
|
|
access_list = [{"address": '192.168.1.1/0',
|
|
'type': 'ALLOW'},
|
|
{'address': '172.165.3.43',
|
|
'type': 'DENY'}]
|
|
|
|
template = self._set_template(self.lb_template,
|
|
accessList=access_list)
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.StubOutWithMock(fake_lb, 'get_access_list')
|
|
fake_lb.get_access_list().AndReturn({})
|
|
fake_lb.get_access_list().AndReturn({})
|
|
fake_lb.get_access_list().AndReturn(access_list)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'add_access_list')
|
|
msg = ("Load Balancer '%s' has a status of 'PENDING_UPDATE' and "
|
|
"is considered immutable." % rsrc.resource_id)
|
|
fake_lb.add_access_list(access_list).AndRaise(Exception(msg))
|
|
fake_lb.add_access_list(access_list)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_lb_name(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['name'] = "updated_name"
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.name = "updated_name"
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'update')
|
|
fake_lb.update(name="updated_name")
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_lb_multiple(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['name'] = "updated_name"
|
|
props['algorithm'] = "RANDOM"
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.name = "updated_name"
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
fake_lb2 = copy.deepcopy(fake_lb)
|
|
fake_lb2.algorithm = "RANDOM"
|
|
fake_lb2.name = "updated_name"
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb2)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'update')
|
|
fake_lb.update(name="updated_name", algorithm="RANDOM")
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_lb_algorithm(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['algorithm'] = "RANDOM"
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.algorithm = "ROUND_ROBIN"
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
|
|
self.m.StubOutWithMock(fake_lb1, 'update')
|
|
fake_lb1.update(algorithm="RANDOM")
|
|
|
|
fake_lb2 = copy.deepcopy(fake_lb)
|
|
fake_lb2.algorithm = "RANDOM"
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb2)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_lb_protocol(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['protocol'] = "IMAPS"
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.protocol = "IMAPS"
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'update')
|
|
fake_lb.update(protocol="IMAPS")
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_lb_redirect(self):
|
|
template = self._set_template(
|
|
self.lb_template, protocol="HTTPS")
|
|
|
|
expected = self._set_expected(
|
|
self.expected_body, protocol="HTTPS")
|
|
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(template['Resources'][rsrc.name]['Properties'])
|
|
props['httpsRedirect'] = True
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.httpsRedirect = True
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'update')
|
|
fake_lb.update(httpsRedirect=True)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
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_lb = 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_template = {
|
|
'privatekey': private_key,
|
|
'intermediateCertificate': 'fwaefawe',
|
|
'secureTrafficOnly': True,
|
|
'securePort': 443,
|
|
'certificate': cert
|
|
}
|
|
ssl_termination_api = copy.deepcopy(ssl_termination_template)
|
|
ssl_termination_api['enabled'] = True
|
|
del ssl_termination_api['privatekey']
|
|
template = self._set_template(
|
|
self.lb_template, sslTermination=ssl_termination_template,
|
|
protocol="HTTP", httpsRedirect=True)
|
|
|
|
expected = self._set_expected(
|
|
self.expected_body, protocol="HTTP", httpsRedirect=False)
|
|
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'create')
|
|
rsrc.clb.create(self.lb_name, **expected).AndReturn(fake_lb)
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.httpsRedirect = True
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'get_ssl_termination')
|
|
fake_lb.get_ssl_termination().AndReturn({})
|
|
fake_lb.get_ssl_termination().AndReturn(ssl_termination_api)
|
|
self.m.StubOutWithMock(fake_lb1, 'get_ssl_termination')
|
|
fake_lb1.get_ssl_termination().AndReturn(ssl_termination_api)
|
|
fake_lb1.get_ssl_termination().AndReturn(ssl_termination_api)
|
|
fake_lb1.get_ssl_termination().AndReturn(ssl_termination_api)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
|
|
|
|
def test_update_lb_half_closed(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['halfClosed'] = True
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.halfClosed = True
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'update')
|
|
fake_lb.update(halfClosed=True)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_lb_port(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['port'] = 1234
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.port = 1234
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'update')
|
|
fake_lb.update(port=1234)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_lb_timeout(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['timeout'] = 120
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.timeout = 120
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'update')
|
|
fake_lb.update(timeout=120)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_health_monitor_add(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['healthMonitor'] = {
|
|
'type': "HTTP", 'delay': 10, 'timeout': 10,
|
|
'attemptsBeforeDeactivation': 4, 'path': "/",
|
|
'statusRegex': "^[234][0-9][0-9]$", 'bodyRegex': ".* testing .*",
|
|
'hostHeader': "example.com"}
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'get_health_monitor')
|
|
fake_lb.get_health_monitor().AndReturn({})
|
|
fake_lb.get_health_monitor().AndReturn(
|
|
{'type': "HTTP", 'delay': 10, 'timeout': 10,
|
|
'attemptsBeforeDeactivation': 4, 'path': "/",
|
|
'statusRegex': "^[234][0-9][0-9]$", 'bodyRegex': ".* testing .*",
|
|
'hostHeader': "example.com"})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'add_health_monitor')
|
|
fake_lb.add_health_monitor(
|
|
attemptsBeforeDeactivation=4, bodyRegex='.* testing .*', delay=10,
|
|
hostHeader='example.com', path='/',
|
|
statusRegex='^[234][0-9][0-9]$', timeout=10, type='HTTP')
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_health_monitor_delete(self):
|
|
template = copy.deepcopy(self.lb_template)
|
|
lb_name = next(iter(template['Resources']))
|
|
hm = {'type': "HTTP", 'delay': 10, 'timeout': 10,
|
|
'attemptsBeforeDeactivation': 4, 'path': "/",
|
|
'statusRegex': "^[234][0-9][0-9]$", 'bodyRegex': ".* testing .*",
|
|
'hostHeader': "example.com"}
|
|
template['Resources'][lb_name]['Properties']['healthMonitor'] = hm
|
|
expected_body = copy.deepcopy(self.expected_body)
|
|
expected_body['healthMonitor'] = hm
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected_body)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
update_template = rsrc.t.freeze(properties=self.lb_props)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'get_health_monitor')
|
|
fake_lb.get_health_monitor().AndReturn(
|
|
{'type': "HTTP", 'delay': 10, 'timeout': 10,
|
|
'attemptsBeforeDeactivation': 4, 'path': "/",
|
|
'statusRegex': "^[234][0-9][0-9]$", 'bodyRegex': ".* testing .*",
|
|
'hostHeader': "example.com"})
|
|
fake_lb.get_health_monitor().AndReturn({})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'delete_health_monitor')
|
|
fake_lb.delete_health_monitor()
|
|
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_session_persistence_add(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['sessionPersistence'] = 'SOURCE_IP'
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.assertEqual('SOURCE_IP', fake_lb.session_persistence)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_session_persistence_delete(self):
|
|
template = copy.deepcopy(self.lb_template)
|
|
lb_name = next(iter(template['Resources']))
|
|
template['Resources'][lb_name]['Properties'][
|
|
'sessionPersistence'] = "SOURCE_IP"
|
|
expected_body = copy.deepcopy(self.expected_body)
|
|
expected_body['sessionPersistence'] = {'persistenceType': "SOURCE_IP"}
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected_body)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
update_template = rsrc.t.freeze(properties=self.lb_props)
|
|
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.assertEqual('', fake_lb.session_persistence)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_ssl_termination_add(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['sslTermination'] = {
|
|
'securePort': 443,
|
|
'privatekey': private_key,
|
|
'certificate': cert,
|
|
'secureTrafficOnly': False,
|
|
'intermediateCertificate': ''
|
|
}
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'get_ssl_termination')
|
|
fake_lb.get_ssl_termination().AndReturn({})
|
|
fake_lb.get_ssl_termination().AndReturn({
|
|
'securePort': 443, 'certificate': cert,
|
|
'secureTrafficOnly': False, 'enabled': True})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'add_ssl_termination')
|
|
fake_lb.add_ssl_termination(
|
|
securePort=443, privatekey=private_key, certificate=cert,
|
|
secureTrafficOnly=False, intermediateCertificate='')
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_ssl_termination_delete(self):
|
|
template = copy.deepcopy(self.lb_template)
|
|
ssl_termination_template = {
|
|
'securePort': 443, 'privatekey': private_key, 'certificate': cert,
|
|
'intermediateCertificate': '', 'secureTrafficOnly': False}
|
|
ssl_termination_api = copy.deepcopy(ssl_termination_template)
|
|
lb_name = next(iter(template['Resources']))
|
|
template['Resources'][lb_name]['Properties']['sslTermination'] = (
|
|
ssl_termination_template)
|
|
# The SSL termination config is done post-creation, so no need
|
|
# to modify self.expected_body
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'get_ssl_termination')
|
|
fake_lb.get_ssl_termination().AndReturn({})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'add_ssl_termination')
|
|
fake_lb.add_ssl_termination(**ssl_termination_api)
|
|
|
|
fake_lb.get_ssl_termination().AndReturn({
|
|
'securePort': 443, 'certificate': cert,
|
|
'secureTrafficOnly': False, 'enabled': True})
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
self.m.UnsetStubs()
|
|
update_template = rsrc.t.freeze(properties=self.lb_props)
|
|
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).MultipleTimes().AndReturn(
|
|
fake_lb)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'get_ssl_termination')
|
|
fake_lb.get_ssl_termination().AndReturn({
|
|
'securePort': 443, 'certificate': cert,
|
|
'secureTrafficOnly': False})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'delete_ssl_termination')
|
|
fake_lb.delete_ssl_termination()
|
|
|
|
fake_lb.get_ssl_termination().AndReturn({})
|
|
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_metadata_add(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['metadata'] = {'a': 1, 'b': 2}
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'get_metadata')
|
|
fake_lb.get_metadata().AndReturn({})
|
|
fake_lb.get_metadata().AndReturn({'a': 1, 'b': 2})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'set_metadata')
|
|
fake_lb.set_metadata({'a': 1, 'b': 2})
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_metadata_delete(self):
|
|
template = copy.deepcopy(self.lb_template)
|
|
lb_name = next(iter(template['Resources']))
|
|
template['Resources'][lb_name]['Properties']['metadata'] = {
|
|
'a': 1, 'b': 2}
|
|
expected_body = copy.deepcopy(self.expected_body)
|
|
expected_body['metadata'] = mox.SameElementsAs(
|
|
[{'key': 'a', 'value': 1},
|
|
{'key': 'b', 'value': 2}])
|
|
rsrc, fake_lb = self._mock_loadbalancer(
|
|
template, self.lb_name, expected_body)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
update_template = rsrc.t.freeze(properties=self.lb_props)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'get_metadata')
|
|
fake_lb.get_metadata().AndReturn({'a': 1, 'b': 2})
|
|
fake_lb.get_metadata().AndReturn({})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'delete_metadata')
|
|
fake_lb.delete_metadata()
|
|
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_errorpage_add(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
error_page = (
|
|
'<html><head><title>Service Unavailable</title></head><body><h2>'
|
|
'Service Unavailable</h2>The service is unavailable</body></html>')
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['errorPage'] = error_page
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'get_error_page')
|
|
fake_lb.get_error_page().AndReturn(
|
|
{'errorpage': {'content': 'foo'}})
|
|
fake_lb.get_error_page().AndReturn(
|
|
{'errorpage': {'content': error_page}})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'set_error_page')
|
|
fake_lb.set_error_page(error_page)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_errorpage_delete(self):
|
|
template = copy.deepcopy(self.lb_template)
|
|
lb_name = next(iter(template['Resources']))
|
|
error_page = (
|
|
'<html><head><title>Service Unavailable</title></head><body><h2>'
|
|
'Service Unavailable</h2>The service is unavailable</body></html>')
|
|
template['Resources'][lb_name]['Properties']['errorPage'] = error_page
|
|
# The error page config is done post-creation, so no need to
|
|
# modify self.expected_body
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'get_error_page')
|
|
fake_lb.get_error_page().AndReturn({})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'set_error_page')
|
|
fake_lb.set_error_page(error_page)
|
|
|
|
fake_lb.get_error_page().AndReturn({'errorpage':
|
|
{'content': error_page}})
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
self.m.UnsetStubs()
|
|
update_template = rsrc.t.freeze(properties=self.lb_props)
|
|
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).MultipleTimes().AndReturn(
|
|
fake_lb)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'clear_error_page')
|
|
fake_lb.clear_error_page()
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'get_error_page')
|
|
fake_lb.get_error_page().AndReturn(
|
|
{'errorpage': {'content': error_page}})
|
|
fake_lb.get_error_page().AndReturn({'errorpage': {'content': ""}})
|
|
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_connection_logging_enable(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['connectionLogging'] = True
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.assertTrue(fake_lb.connection_logging)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_connection_logging_delete(self):
|
|
template = copy.deepcopy(self.lb_template)
|
|
lb_name = next(iter(template['Resources']))
|
|
template['Resources'][lb_name]['Properties'][
|
|
'connectionLogging'] = True
|
|
expected_body = copy.deepcopy(self.expected_body)
|
|
expected_body['connectionLogging'] = {'enabled': True}
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected_body)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.connection_logging = True
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
|
|
fake_lb2 = copy.deepcopy(fake_lb)
|
|
fake_lb2.connection_logging = False
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb2)
|
|
|
|
update_template = rsrc.t.freeze(properties=self.lb_props)
|
|
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.assertFalse(fake_lb.connection_logging)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_connection_logging_disable(self):
|
|
template = copy.deepcopy(self.lb_template)
|
|
lb_name = next(iter(template['Resources']))
|
|
template['Resources'][lb_name]['Properties'][
|
|
'connectionLogging'] = True
|
|
expected_body = copy.deepcopy(self.expected_body)
|
|
expected_body['connectionLogging'] = {'enabled': True}
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected_body)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['connectionLogging'] = False
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.assertFalse(fake_lb.connection_logging)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_connection_throttle_add(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['connectionThrottle'] = {'maxConnections': 1000}
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'add_connection_throttle')
|
|
self.m.StubOutWithMock(fake_lb, 'get_connection_throttle')
|
|
fake_lb.get_connection_throttle().AndReturn(
|
|
{'maxConnectionRate': None, 'minConnections': None,
|
|
'rateInterval': None, 'maxConnections': 100})
|
|
|
|
fake_lb.add_connection_throttle(
|
|
maxConnections=1000, maxConnectionRate=None, minConnections=None,
|
|
rateInterval=None)
|
|
|
|
fake_lb.get_connection_throttle().AndReturn(
|
|
{'maxConnectionRate': None, 'minConnections': None,
|
|
'rateInterval': None, 'maxConnections': 1000})
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_connection_throttle_delete(self):
|
|
template = copy.deepcopy(self.lb_template)
|
|
lb_name = next(iter(template['Resources']))
|
|
template['Resources'][lb_name]['Properties'][
|
|
'connectionThrottle'] = {'maxConnections': 1000}
|
|
expected_body = copy.deepcopy(self.expected_body)
|
|
expected_body['connectionThrottle'] = {
|
|
'maxConnections': 1000, 'maxConnectionRate': None,
|
|
'rateInterval': None, 'minConnections': None}
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected_body)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
del props['connectionThrottle']
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'get_connection_throttle')
|
|
fake_lb.get_connection_throttle().AndReturn({
|
|
'maxConnections': 1000, 'maxConnectionRate': None,
|
|
'rateInterval': None, 'minConnections': None})
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'delete_connection_throttle')
|
|
fake_lb.delete_connection_throttle()
|
|
|
|
fake_lb.get_connection_throttle().AndReturn({})
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_content_caching_enable(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['contentCaching'] = 'ENABLED'
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.content_caching = False
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
fake_lb2 = copy.deepcopy(fake_lb)
|
|
fake_lb2.content_caching = True
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb2)
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_content_caching_deleted(self):
|
|
template = copy.deepcopy(self.lb_template)
|
|
lb_name = next(iter(template['Resources']))
|
|
template['Resources'][lb_name]['Properties'][
|
|
'contentCaching'] = 'ENABLED'
|
|
# Enabling the content cache is done post-creation, so no need
|
|
# to modify self.expected_body
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
del props['contentCaching']
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.content_caching = True
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
fake_lb2 = copy.deepcopy(fake_lb)
|
|
fake_lb2.content_caching = False
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb2)
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_content_caching_disable(self):
|
|
template = copy.deepcopy(self.lb_template)
|
|
lb_name = next(iter(template['Resources']))
|
|
template['Resources'][lb_name]['Properties'][
|
|
'contentCaching'] = 'ENABLED'
|
|
# Enabling the content cache is done post-creation, so no need
|
|
# to modify self.expected_body
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['contentCaching'] = 'DISABLED'
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb1.content_caching = True
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
fake_lb2 = copy.deepcopy(fake_lb)
|
|
fake_lb2.content_caching = False
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb2)
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_delete(self):
|
|
template = self._set_template(self.lb_template,
|
|
contentCaching='ENABLED')
|
|
rsrc, fake_lb = self._mock_loadbalancer(template, self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
self.m.VerifyAll()
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
rsrc.clb.get(mox.IgnoreArg()).AndRaise(lb.NotFound('foo'))
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.delete)()
|
|
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_delete_immutable(self):
|
|
template = self._set_template(self.lb_template,
|
|
contentCaching='ENABLED')
|
|
rsrc, fake_lb = self._mock_loadbalancer(template, self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
rsrc.clb.get(mox.IgnoreArg()).AndRaise(lb.NotFound('foo'))
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'delete')
|
|
fake_lb.delete().AndRaise(Exception('immutable'))
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.delete)()
|
|
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_delete_non_immutable_exc(self):
|
|
template = self._set_template(self.lb_template,
|
|
contentCaching='ENABLED')
|
|
rsrc, fake_lb = self._mock_loadbalancer(template, self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb)
|
|
|
|
self.m.StubOutWithMock(fake_lb, 'delete')
|
|
fake_lb.delete().AndRaise(FakeException())
|
|
self.m.ReplayAll()
|
|
|
|
exc = self.assertRaises(exception.ResourceFailure,
|
|
scheduler.TaskRunner(rsrc.delete))
|
|
self.assertIn('FakeException', six.text_type(exc))
|
|
self.m.VerifyAll()
|
|
|
|
def test_delete_states(self):
|
|
template = self._set_template(self.lb_template,
|
|
contentCaching='ENABLED')
|
|
rsrc, fake_lb = self._mock_loadbalancer(template, self.lb_name,
|
|
self.expected_body)
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
self.m.UnsetStubs()
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
fake_lb2 = copy.deepcopy(fake_lb)
|
|
fake_lb3 = copy.deepcopy(fake_lb)
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
|
|
fake_lb1.status = 'ACTIVE'
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
fake_lb2.status = 'PENDING_DELETE'
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb2)
|
|
fake_lb3.status = 'DELETED'
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb3)
|
|
|
|
self.m.ReplayAll()
|
|
|
|
scheduler.TaskRunner(rsrc.delete)()
|
|
self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_redir(self):
|
|
mock_stack = mock.Mock()
|
|
mock_stack.db_resource_get.return_value = None
|
|
mock_stack.has_cache_data.return_value = False
|
|
props = {'httpsRedirect': True,
|
|
'protocol': 'HTTPS',
|
|
'port': 443,
|
|
'nodes': [],
|
|
'virtualIps': [{'id': '1234'}]}
|
|
mock_resdef = rsrc_defn.ResourceDefinition("test_lb",
|
|
LoadBalancerWithFakeClient,
|
|
properties=props)
|
|
mock_lb = lb.CloudLoadBalancer("test", mock_resdef, mock_stack)
|
|
self.assertIsNone(mock_lb.validate())
|
|
props['protocol'] = 'HTTP'
|
|
props['sslTermination'] = {
|
|
'secureTrafficOnly': True,
|
|
'securePort': 443,
|
|
'privatekey': "bobloblaw",
|
|
'certificate': 'mycert'
|
|
}
|
|
mock_resdef = rsrc_defn.ResourceDefinition("test_lb_2",
|
|
LoadBalancerWithFakeClient,
|
|
properties=props)
|
|
mock_lb = lb.CloudLoadBalancer("test_2", mock_resdef, mock_stack)
|
|
self.assertIsNone(mock_lb.validate())
|
|
|
|
def test_invalid_redir_proto(self):
|
|
mock_stack = mock.Mock()
|
|
mock_stack.db_resource_get.return_value = None
|
|
mock_stack.has_cache_data.return_value = False
|
|
props = {'httpsRedirect': True,
|
|
'protocol': 'TCP',
|
|
'port': 1234,
|
|
'nodes': [],
|
|
'virtualIps': [{'id': '1234'}]}
|
|
mock_resdef = rsrc_defn.ResourceDefinition("test_lb",
|
|
LoadBalancerWithFakeClient,
|
|
properties=props)
|
|
mock_lb = lb.CloudLoadBalancer("test", mock_resdef, mock_stack)
|
|
ex = self.assertRaises(exception.StackValidationFailed,
|
|
mock_lb.validate)
|
|
self.assertIn("HTTPS redirect is only available", six.text_type(ex))
|
|
|
|
def test_invalid_redir_ssl(self):
|
|
mock_stack = mock.Mock()
|
|
mock_stack.db_resource_get.return_value = None
|
|
mock_stack.has_cache_data.return_value = False
|
|
props = {'httpsRedirect': True,
|
|
'protocol': 'HTTP',
|
|
'port': 1234,
|
|
'nodes': [],
|
|
'virtualIps': [{'id': '1234'}]}
|
|
mock_resdef = rsrc_defn.ResourceDefinition("test_lb",
|
|
LoadBalancerWithFakeClient,
|
|
properties=props)
|
|
mock_lb = lb.CloudLoadBalancer("test", mock_resdef, mock_stack)
|
|
ex = self.assertRaises(exception.StackValidationFailed,
|
|
mock_lb.validate)
|
|
self.assertIn("HTTPS redirect is only available", six.text_type(ex))
|
|
props['sslTermination'] = {
|
|
'secureTrafficOnly': False,
|
|
'securePort': 443,
|
|
'privatekey': "bobloblaw",
|
|
'certificate': 'mycert'
|
|
}
|
|
mock_lb = lb.CloudLoadBalancer("test", mock_resdef, mock_stack)
|
|
ex = self.assertRaises(exception.StackValidationFailed,
|
|
mock_lb.validate)
|
|
self.assertIn("HTTPS redirect is only available", six.text_type(ex))
|
|
props['sslTermination'] = {
|
|
'secureTrafficOnly': True,
|
|
'securePort': 1234,
|
|
'privatekey': "bobloblaw",
|
|
'certificate': 'mycert'
|
|
}
|
|
mock_lb = lb.CloudLoadBalancer("test", mock_resdef, mock_stack)
|
|
ex = self.assertRaises(exception.StackValidationFailed,
|
|
mock_lb.validate)
|
|
self.assertIn("HTTPS redirect is only available", six.text_type(ex))
|
|
|
|
def test_update_nodes_condition_draining(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
fake_lb.nodes = self.expected_body['nodes']
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
expected_ip = '172.168.1.4'
|
|
props['nodes'] = [
|
|
{"addresses": ["166.78.103.141"],
|
|
"port": 80,
|
|
"condition": "DRAINING",
|
|
"type": "PRIMARY",
|
|
"weight": 1},
|
|
{"addresses": [expected_ip],
|
|
"port": 80,
|
|
"condition": "DRAINING",
|
|
"type": "PRIMARY",
|
|
"weight": 1}]
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
|
|
self.m.StubOutWithMock(fake_lb1, 'add_nodes')
|
|
fake_lb1.add_nodes([
|
|
fake_lb1.Node(address=expected_ip,
|
|
port=80,
|
|
condition='DRAINING',
|
|
type="PRIMARY", weight=1)])
|
|
|
|
fake_lb2 = copy.deepcopy(fake_lb)
|
|
fake_lb2.nodes = [
|
|
FakeNode(address=u"166.78.103.141", port=80,
|
|
condition=u"DRAINING", type="PRIMARY", weight=1),
|
|
FakeNode(address=u"172.168.1.4", port=80,
|
|
condition=u"DRAINING", type="PRIMARY", weight=1),
|
|
]
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb2)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_nodes_add_same_address_different_port(self):
|
|
rsrc, fake_lb = self._mock_loadbalancer(self.lb_template,
|
|
self.lb_name,
|
|
self.expected_body)
|
|
fake_lb.nodes = self.expected_body['nodes']
|
|
fake_lb.tracker = "fake_lb"
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['nodes'] = [
|
|
{"addresses": ["166.78.103.141"],
|
|
"port": 80,
|
|
"condition": "ENABLED",
|
|
"type": "PRIMARY",
|
|
"weight": 1},
|
|
{"addresses": ["166.78.103.141"],
|
|
"port": 81,
|
|
"condition": "ENABLED",
|
|
"type": "PRIMARY",
|
|
"weight": 1}]
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb1)
|
|
|
|
self.m.StubOutWithMock(fake_lb1, 'add_nodes')
|
|
fake_lb1.add_nodes([
|
|
fake_lb1.Node(address="166.78.103.141",
|
|
port=81,
|
|
condition='ENABLED',
|
|
type="PRIMARY", weight=1)])
|
|
fake_lb1.tracker = "fake_lb1"
|
|
|
|
fake_lb2 = copy.deepcopy(fake_lb)
|
|
fake_lb2.nodes = [
|
|
FakeNode(address=u"166.78.103.141", port=80,
|
|
condition=u"ENABLED", type="PRIMARY", weight=1),
|
|
FakeNode(address=u"166.78.103.141", port=81,
|
|
condition=u"ENABLED", type="PRIMARY", weight=1),
|
|
]
|
|
fake_lb2.tracker = "fake_lb2"
|
|
rsrc.clb.get(mox.IgnoreArg()).AndReturn(fake_lb2)
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|
|
|
|
def test_update_nodes_defaults(self):
|
|
template = copy.deepcopy(self.lb_template)
|
|
lb_name = next(iter(template['Resources']))
|
|
tmpl_node = template['Resources'][lb_name]['Properties']['nodes'][0]
|
|
tmpl_node['type'] = "PRIMARY"
|
|
tmpl_node['condition'] = "ENABLED"
|
|
tmpl_node['weight'] = 1
|
|
expected_body = copy.deepcopy(self.expected_body)
|
|
expected_body['nodes'] = [FakeNode(address=u"166.78.103.141", port=80,
|
|
condition=u"ENABLED",
|
|
type="PRIMARY", weight=1)]
|
|
|
|
rsrc, fake_lb = self._mock_loadbalancer(template,
|
|
self.lb_name,
|
|
expected_body)
|
|
fake_lb.nodes = self.expected_body['nodes']
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.create)()
|
|
|
|
props = copy.deepcopy(self.lb_props)
|
|
props['nodes'] = [{"addresses": ["166.78.103.141"], "port": 80}]
|
|
update_template = rsrc.t.freeze(properties=props)
|
|
|
|
self.m.UnsetStubs()
|
|
self.m.StubOutWithMock(rsrc.clb, 'get')
|
|
fake_lb1 = copy.deepcopy(fake_lb)
|
|
rsrc.clb.get(mox.IgnoreArg()).MultipleTimes().AndReturn(fake_lb1)
|
|
|
|
self.m.StubOutWithMock(fake_lb1, 'add_nodes')
|
|
|
|
self.m.ReplayAll()
|
|
scheduler.TaskRunner(rsrc.update, update_template)()
|
|
self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state)
|
|
self.m.VerifyAll()
|