Commit a9d98dd1 authored by Łukasz Nowak's avatar Łukasz Nowak

caddy-frontend: Implement netloc-list

JSON schema uses simple string and internal process, and caddy instances are
not kept simple and are not considered future-proof.
parent 428e32c2
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
# not need these here). # not need these here).
[template] [template]
filename = instance.cfg.in filename = instance.cfg.in
md5sum = 1dfbd20c77fb3c1f01005a8a920d2ed9 md5sum = fb3a20e7f555a9ce7fe1ec547d0fcdfc
[profile-common] [profile-common]
filename = instance-common.cfg.in filename = instance-common.cfg.in
...@@ -26,11 +26,11 @@ md5sum = 0950e09ad1f03f0789308f5f7a7eb1b8 ...@@ -26,11 +26,11 @@ md5sum = 0950e09ad1f03f0789308f5f7a7eb1b8
[profile-caddy-replicate] [profile-caddy-replicate]
filename = instance-apache-replicate.cfg.in filename = instance-apache-replicate.cfg.in
md5sum = 7c2e52b76c42bed95702763c344e41dd md5sum = c5d1e235959a877b4f3157369c6f5e10
[profile-slave-list] [profile-slave-list]
_update_hash_filename_ = templates/apache-custom-slave-list.cfg.in _update_hash_filename_ = templates/apache-custom-slave-list.cfg.in
md5sum = 313671d343ceccfca5af1baa642132c5 md5sum = c67e172c0c6eca955b18962404056a33
[profile-replicate-publish-slave-information] [profile-replicate-publish-slave-information]
_update_hash_filename_ = templates/replicate-publish-slave-information.cfg.in _update_hash_filename_ = templates/replicate-publish-slave-information.cfg.in
...@@ -50,7 +50,7 @@ md5sum = 37475d79f28c5f126bc1947fdb938fdb ...@@ -50,7 +50,7 @@ md5sum = 37475d79f28c5f126bc1947fdb938fdb
[template-backend-haproxy-configuration] [template-backend-haproxy-configuration]
_update_hash_filename_ = templates/backend-haproxy.cfg.in _update_hash_filename_ = templates/backend-haproxy.cfg.in
md5sum = d2851c7ebd2c9baa2edecb3ca3485511 md5sum = ae4c9ce775ea003aa51eda5ecbbeec73
[template-empty] [template-empty]
_update_hash_filename_ = templates/empty.in _update_hash_filename_ = templates/empty.in
...@@ -98,7 +98,7 @@ md5sum = 8e1c6c06c09beb921965b3ce98c67c9e ...@@ -98,7 +98,7 @@ md5sum = 8e1c6c06c09beb921965b3ce98c67c9e
[caddyprofiledeps-dummy] [caddyprofiledeps-dummy]
filename = caddyprofiledummy.py filename = caddyprofiledummy.py
md5sum = 38792c2dceae38ab411592ec36fff6a8 md5sum = 59cb33f11272ee09eccea74981d2304a
[profile-kedifa] [profile-kedifa]
filename = instance-kedifa.cfg.in filename = instance-kedifa.cfg.in
......
import urlparse
class Recipe(object): class Recipe(object):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
pass pass
...@@ -7,3 +9,13 @@ class Recipe(object): ...@@ -7,3 +9,13 @@ class Recipe(object):
def update(self): def update(self):
return self.install() return self.install()
def validate_netloc(netloc):
# a bit crazy way to validate that the passed parameter is haproxy
# compatible server netloc
parsed = urlparse.urlparse('scheme://'+netloc)
if ':' in parsed.hostname:
hostname = '[%s]' % parsed.hostname
else:
hostname = parsed.hostname
return netloc == '%s:%s' % (hostname, parsed.port)
...@@ -207,6 +207,15 @@ context = ...@@ -207,6 +207,15 @@ context =
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% for url_key in ['url-netloc-list', 'https-url-netloc-list', 'health-check-failover-url-netloc-list'] %}
{% if url_key in slave %}
{% for netloc in slave[url_key].split() %}
{% if not caddyprofiledummy.validate_netloc(netloc) %}
{% do slave_error_list.append('slave %s %r invalid' % (url_key, netloc)) %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% for k in ['ssl_proxy_ca_crt', 'health-check-failover-ssl-proxy-ca-crt'] %} {% for k in ['ssl_proxy_ca_crt', 'health-check-failover-ssl-proxy-ca-crt'] %}
{% if k in slave %} {% if k in slave %}
{% set crt = slave.get(k, '') %} {% set crt = slave.get(k, '') %}
...@@ -909,4 +918,4 @@ parts = ...@@ -909,4 +918,4 @@ parts =
caucased-backend-client-promise caucased-backend-client-promise
{% for part in part_list %} {% for part in part_list %}
{{ ' %s' % part }} {{ ' %s' % part }}
{% endfor %} {% endfor %}
\ No newline at end of file
...@@ -348,6 +348,26 @@ ...@@ -348,6 +348,26 @@
], ],
"type": "string", "type": "string",
"default": "false" "default": "false"
},
"url-netloc-list": {
"type": "string",
"title": "[EXPERT] List of netlocs for \"Backend URL\"",
"description": "Space separated list of netlocs (ip and port) of backend to connect to. They will share the scheme and path of the original URL and additional backend parameters (like \"SSL Backend Authority's Certificate\"). Each of them will be used, and at least one is enough for the connectivity to work, and the best results are with \"Health Check\" feature enabled. Port is mandatory, so hostnames shall be provided as hostname:port (eg. example.com:80), IPv4 - as ipv4:port (eg. 127.0.0.1:80), IPv6 - as ipv6:port (eg. ::1:80). Simply this parameters only overrides netloc (network location) of the original URL."
},
"https-url-netloc-list": {
"type": "string",
"title": "[EXPERT] List of netlocs for \"HTTPS Backend URL\"",
"description": "See \"[EXPERT] List of netlocs for \"Backend URL\"\" description."
},
"health-check-failover-url-netloc-list": {
"type": "string",
"title": "[EXPERT] List of netlocs for \"Failover backend URL\"",
"description": "See \"[EXPERT] List of netlocs for \"Backend URL\"\" description."
},
"health-check-failover-https-url-netloc-list": {
"type": "string",
"title": "[EXPERT] List of netlocs for \"Failover HTTPS Backend URL\"",
"description": "See \"[EXPERT] List of netlocs for \"Backend URL\"\" description."
} }
}, },
"title": "Input Parameters", "title": "Input Parameters",
......
...@@ -55,6 +55,7 @@ extra-context = ...@@ -55,6 +55,7 @@ extra-context =
import subprocess_module subprocess import subprocess_module subprocess
import functools_module functools import functools_module functools
import validators validators import validators validators
import caddyprofiledummy caddyprofiledummy
# Must match the key id in [switch-softwaretype] which uses this section. # Must match the key id in [switch-softwaretype] which uses this section.
raw software_type RootSoftwareInstance-default-custom-personal-replicate raw software_type RootSoftwareInstance-default-custom-personal-replicate
......
...@@ -53,7 +53,7 @@ context = ...@@ -53,7 +53,7 @@ context =
{#- * stabilise values for backend #} {#- * stabilise values for backend #}
{%- for key, prefix in [('url', 'http_backend'), ('https-url', 'https_backend')] %} {%- for key, prefix in [('url', 'http_backend'), ('https-url', 'https_backend')] %}
{%- set parsed = urlparse_module.urlparse(slave_instance.get(key, '').strip()) %} {%- set parsed = urlparse_module.urlparse(slave_instance.get(key, '').strip()) %}
{%- set info_dict = {'scheme': parsed.scheme, 'hostname': parsed.hostname, 'port': parsed.port or DEFAULT_PORT[parsed.scheme], 'path': parsed.path, 'fragment': parsed.fragment, 'query': parsed.query} %} {%- set info_dict = {'scheme': parsed.scheme, 'hostname': parsed.hostname, 'port': parsed.port or DEFAULT_PORT[parsed.scheme], 'path': parsed.path, 'fragment': parsed.fragment, 'query': parsed.query, 'netloc-list': slave_instance.get(key + '-netloc-list', '').split() } %}
{%- do slave_instance.__setitem__(prefix, info_dict) %} {%- do slave_instance.__setitem__(prefix, info_dict) %}
{%- endfor %} {%- endfor %}
{%- do slave_instance.__setitem__('ssl_proxy_verify', ('' ~ slave_instance.get('ssl-proxy-verify', '')).lower() in TRUE_VALUES) %} {%- do slave_instance.__setitem__('ssl_proxy_verify', ('' ~ slave_instance.get('ssl-proxy-verify', '')).lower() in TRUE_VALUES) %}
...@@ -66,6 +66,7 @@ context = ...@@ -66,6 +66,7 @@ context =
{%- do info_dict.__setitem__('health-check-failover-path', parsed.path) %} {%- do info_dict.__setitem__('health-check-failover-path', parsed.path) %}
{%- do info_dict.__setitem__('health-check-failover-query', parsed.query) %} {%- do info_dict.__setitem__('health-check-failover-query', parsed.query) %}
{%- do info_dict.__setitem__('health-check-failover-fragment', parsed.fragment) %} {%- do info_dict.__setitem__('health-check-failover-fragment', parsed.fragment) %}
{%- do info_dict.__setitem__('health-check-netloc-list', slave_instance.get('health-check-failover-url-netloc-list', '').split()) %}
{%- do slave_instance.__setitem__(prefix, info_dict) %} {%- do slave_instance.__setitem__(prefix, info_dict) %}
{%- endfor %} {%- endfor %}
{%- do slave_instance.__setitem__('health-check-failover-ssl-proxy-verify', ('' ~ slave_instance.get('health-check-failover-ssl-proxy-verify', '')).lower() in TRUE_VALUES) %} {%- do slave_instance.__setitem__('health-check-failover-ssl-proxy-verify', ('' ~ slave_instance.get('health-check-failover-ssl-proxy-verify', '')).lower() in TRUE_VALUES) %}
...@@ -658,4 +659,4 @@ commands = ...@@ -658,4 +659,4 @@ commands =
promise = check_command_execute promise = check_command_execute
name = ${:_buildout_section_name_}.py name = ${:_buildout_section_name_}.py
config-command = config-command =
${logrotate:wrapper-path} -d ${logrotate:wrapper-path} -d
\ No newline at end of file
...@@ -106,7 +106,7 @@ backend {{ slave_instance['slave_reference'] }}-{{ scheme }} ...@@ -106,7 +106,7 @@ backend {{ slave_instance['slave_reference'] }}-{{ scheme }}
{%- do path_list.append(query) %} {%- do path_list.append(query) %}
{%- endif %} {%- endif %}
{%- set path = '?'.join(path_list) %} {%- set path = '?'.join(path_list) %}
{%- if hostname and port %} {%- if hostname and port or len(info_dict['netloc-list']) > 0 %}
timeout server {{ slave_instance['request-timeout'] }}s timeout server {{ slave_instance['request-timeout'] }}s
timeout connect {{ slave_instance['backend-connect-timeout'] }}s timeout connect {{ slave_instance['backend-connect-timeout'] }}s
retries {{ slave_instance['backend-connect-retries'] }} retries {{ slave_instance['backend-connect-retries'] }}
...@@ -122,7 +122,15 @@ backend {{ slave_instance['slave_reference'] }}-{{ scheme }} ...@@ -122,7 +122,15 @@ backend {{ slave_instance['slave_reference'] }}-{{ scheme }}
{%- endif %} {%- endif %}
{%- do active_check_option_list.append('timeout check %ss' % (slave_instance['health-check-timeout'])) %} {%- do active_check_option_list.append('timeout check %ss' % (slave_instance['health-check-timeout'])) %}
{%- endif %} {%- endif %}
{%- if len(info_dict['netloc-list']) > 0 %}
{%- set counter = {'count': 1} %}
{%- for netloc in info_dict['netloc-list'] %}
server {{ slave_instance['slave_reference'] }}-backend-{{ scheme }}-{{ counter['count'] }} {{ netloc }} {{ ' '.join(ssl_list) }} {{ ' ' + ' '.join(active_check_list)}}
{%- do counter.__setitem__('count', counter['count'] + 1) %}
{%- endfor %}
{%- else %}
server {{ slave_instance['slave_reference'] }}-backend-{{ scheme }} {{ hostname }}:{{ port }} {{ ' '.join(ssl_list) }} {{ ' ' + ' '.join(active_check_list)}} server {{ slave_instance['slave_reference'] }}-backend-{{ scheme }} {{ hostname }}:{{ port }} {{ ' '.join(ssl_list) }} {{ ' ' + ' '.join(active_check_list)}}
{%- endif %}
{%- for active_check_option in active_check_option_list %} {%- for active_check_option in active_check_option_list %}
{{ active_check_option }} {{ active_check_option }}
{%- endfor %} {%- endfor %}
...@@ -161,10 +169,18 @@ backend {{ slave_instance['slave_reference'] }}-{{ scheme }}-failover ...@@ -161,10 +169,18 @@ backend {{ slave_instance['slave_reference'] }}-{{ scheme }}-failover
{%- endif %} {%- endif %}
{%- set path = '?'.join(path_list) %} {%- set path = '?'.join(path_list) %}
{%- if hostname and port %} {%- if hostname and port %}
timeout server {{ slave_instance['request-timeout'] }}s {%- if len(info_dict['health-check-netloc-list']) > 0 %}
{%- set counter = {'count': 1} %}
{%- for netloc in info_dict['health-check-netloc-list'] %}
server {{ slave_instance['slave_reference'] }}-backend-{{ scheme }}-{{ counter['count'] }} {{ netloc }} {{ ' '.join(ssl_list) }}
{%- do counter.__setitem__('count', counter['count'] + 1) %}
{%- endfor %}
{%- else %}
server {{ slave_instance['slave_reference'] }}-backend-{{ scheme }} {{ hostname }}:{{ port }} {{ ' '.join(ssl_list) }}
{%- endif %}
timeout connect {{ slave_instance['backend-connect-timeout'] }}s timeout connect {{ slave_instance['backend-connect-timeout'] }}s
timeout server {{ slave_instance['request-timeout'] }}s
retries {{ slave_instance['backend-connect-retries'] }} retries {{ slave_instance['backend-connect-retries'] }}
server {{ slave_instance['slave_reference'] }}-backend-{{ scheme }} {{ hostname }}:{{ port }} {{ ' '.join(ssl_list) }}
{%- if path %} {%- if path %}
http-request set-path {{ path }}%[path] http-request set-path {{ path }}%[path]
{%- endif %} {%- endif %}
......
...@@ -644,16 +644,40 @@ class HttpFrontendTestCase(SlapOSInstanceTestCase): ...@@ -644,16 +644,40 @@ class HttpFrontendTestCase(SlapOSInstanceTestCase):
server_side=True) server_side=True)
cls.backend_url = 'http://%s:%s/' % server.server_address cls.backend_url = 'http://%s:%s/' % server.server_address
cls.server_process = multiprocessing.Process( server_process = multiprocessing.Process(
target=server.serve_forever, name='HTTPServer') target=server.serve_forever, name='HTTPServer')
cls.server_process.start() server_process.start()
cls.logger.debug('Started process %s' % (cls.server_process,)) cls.logger.debug('Started process %s' % (server_process,))
cls.backend_https_url = 'https://%s:%s/' % server_https.server_address cls.backend_https_url = 'https://%s:%s/' % server_https.server_address
cls.server_https_process = multiprocessing.Process( server_https_process = multiprocessing.Process(
target=server_https.serve_forever, name='HTTPSServer') target=server_https.serve_forever, name='HTTPSServer')
cls.server_https_process.start() server_https_process.start()
cls.logger.debug('Started process %s' % (cls.server_https_process,)) cls.logger.debug('Started process %s' % (server_https_process,))
class NetlocHandler(TestHandler):
identification = 'netloc'
netloc_a_http = ThreadedHTTPServer(
(cls._ipv4_address, cls._server_netloc_a_http_port),
NetlocHandler)
netloc_a_http_process = multiprocessing.Process(
target=netloc_a_http.serve_forever, name='netloc-a-http')
netloc_a_http_process.start()
netloc_b_http = ThreadedHTTPServer(
(cls._ipv4_address, cls._server_netloc_b_http_port),
NetlocHandler)
netloc_b_http_process = multiprocessing.Process(
target=netloc_b_http.serve_forever, name='netloc-b-http')
netloc_b_http_process.start()
cls.server_process_list = [
server_process,
server_https_process,
netloc_a_http_process,
netloc_b_http_process,
]
@classmethod @classmethod
def cleanUpCertificate(cls): def cleanUpCertificate(cls):
...@@ -662,8 +686,7 @@ class HttpFrontendTestCase(SlapOSInstanceTestCase): ...@@ -662,8 +686,7 @@ class HttpFrontendTestCase(SlapOSInstanceTestCase):
@classmethod @classmethod
def stopServerProcess(cls): def stopServerProcess(cls):
for server in ['server_process', 'server_https_process']: for process in cls.server_process_list:
process = getattr(cls, server, None)
if process is not None: if process is not None:
cls.logger.debug('Stopping process %s' % (process,)) cls.logger.debug('Stopping process %s' % (process,))
process.join(10) process.join(10)
...@@ -1033,6 +1056,8 @@ class HttpFrontendTestCase(SlapOSInstanceTestCase): ...@@ -1033,6 +1056,8 @@ class HttpFrontendTestCase(SlapOSInstanceTestCase):
cls._server_http_port = findFreeTCPPort(cls._ipv4_address) cls._server_http_port = findFreeTCPPort(cls._ipv4_address)
cls._server_https_port = findFreeTCPPort(cls._ipv4_address) cls._server_https_port = findFreeTCPPort(cls._ipv4_address)
cls._server_https_auth_port = findFreeTCPPort(cls._ipv4_address) cls._server_https_auth_port = findFreeTCPPort(cls._ipv4_address)
cls._server_netloc_a_http_port = findFreeTCPPort(cls._ipv4_address)
cls._server_netloc_b_http_port = findFreeTCPPort(cls._ipv4_address)
cls.startServerProcess() cls.startServerProcess()
except BaseException: except BaseException:
cls.logger.exception("Error during setUpClass") cls.logger.exception("Error during setUpClass")
...@@ -1071,6 +1096,12 @@ class HttpFrontendTestCase(SlapOSInstanceTestCase): ...@@ -1071,6 +1096,12 @@ class HttpFrontendTestCase(SlapOSInstanceTestCase):
class SlaveHttpFrontendTestCase(HttpFrontendTestCase): class SlaveHttpFrontendTestCase(HttpFrontendTestCase):
def _get_backend_haproxy_configuration(self):
backend_configuration_file = glob.glob(os.path.join(
self.instance_path, '*', 'etc', 'backend-haproxy.cfg'))[0]
with open(backend_configuration_file) as fh:
return fh.read()
@classmethod @classmethod
def requestDefaultInstance(cls, state='started'): def requestDefaultInstance(cls, state='started'):
default_instance = super( default_instance = super(
...@@ -1326,6 +1357,13 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -1326,6 +1357,13 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin):
# authenticating to http backend shall be no-op # authenticating to http backend shall be no-op
'authenticate-to-backend': True, 'authenticate-to-backend': True,
}, },
'url-netloc-list': {
'url': cls.backend_url,
'url-netloc-list': '%(ip)s:%(port_a)s %(ip)s:%(port_b)s' % {
'ip': cls._ipv4_address,
'port_a': cls._server_netloc_a_http_port,
'port_b': cls._server_netloc_b_http_port},
},
'auth-to-backend': { 'auth-to-backend': {
# in here use reserved port for the backend, which is going to be # in here use reserved port for the backend, which is going to be
# started later # started later
...@@ -1353,6 +1391,14 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -1353,6 +1391,14 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin):
'strict-transport-security-sub-domains': True, 'strict-transport-security-sub-domains': True,
'strict-transport-security-preload': True, 'strict-transport-security-preload': True,
}, },
'https-url-netloc-list': {
'url': cls.backend_url + 'http',
'https-url': cls.backend_url + 'https',
'https-url-netloc-list': '%(ip)s:%(port_a)s %(ip)s:%(port_b)s' % {
'ip': cls._ipv4_address,
'port_a': cls._server_netloc_a_http_port,
'port_b': cls._server_netloc_b_http_port},
},
'server-alias': { 'server-alias': {
'url': cls.backend_url, 'url': cls.backend_url,
'server-alias': 'alias1.example.com alias2.example.com', 'server-alias': 'alias1.example.com alias2.example.com',
...@@ -1721,9 +1767,9 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -1721,9 +1767,9 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin):
'monitor-base-url': 'https://[%s]:8401' % self._ipv6_address, 'monitor-base-url': 'https://[%s]:8401' % self._ipv6_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address, 'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'domain': 'example.com', 'domain': 'example.com',
'accepted-slave-amount': '52', 'accepted-slave-amount': '54',
'rejected-slave-amount': '0', 'rejected-slave-amount': '0',
'slave-amount': '52', 'slave-amount': '54',
'rejected-slave-dict': { 'rejected-slave-dict': {
}, },
'warning-slave-dict': { 'warning-slave-dict': {
...@@ -1965,6 +2011,15 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -1965,6 +2011,15 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin):
self.assertIn("backend _Url-http\n", content) self.assertIn("backend _Url-http\n", content)
self.assertNotIn("backend _Url-https\n", content) self.assertNotIn("backend _Url-https\n", content)
def test_url_netloc_list(self):
parameter_dict = self.assertSlaveBase('url-netloc-list')
result = fakeHTTPSResult(parameter_dict['domain'], 'path')
# assure that the request went to backend specified in the netloc
self.assertEqual(
result.headers['X-Backend-Identification'],
'netloc'
)
def test_auth_to_backend(self): def test_auth_to_backend(self):
parameter_dict = self.assertSlaveBase('auth-to-backend') parameter_dict = self.assertSlaveBase('auth-to-backend')
...@@ -4464,6 +4519,19 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -4464,6 +4519,19 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin):
timeout connect 10s timeout connect 10s
retries 5""" in content) retries 5""" in content)
def test_https_url_netloc_list(self):
parameter_dict = self.assertSlaveBase('https-url-netloc-list')
result = fakeHTTPSResult(parameter_dict['domain'], 'path')
# assure that the request went to backend specified in the netloc
self.assertEqual(
result.headers['X-Backend-Identification'],
'netloc'
)
result = fakeHTTPResult(parameter_dict['domain'], 'path')
# assure that the request went to backend NOT specified in the netloc
self.assertNotIn('X-Backend-Identification', result.headers)
class TestReplicateSlave(SlaveHttpFrontendTestCase, TestDataMixin): class TestReplicateSlave(SlaveHttpFrontendTestCase, TestDataMixin):
instance_parameter_dict = { instance_parameter_dict = {
...@@ -7168,6 +7236,23 @@ class TestSlaveHealthCheck(SlaveHttpFrontendTestCase, TestDataMixin): ...@@ -7168,6 +7236,23 @@ class TestSlaveHealthCheck(SlaveHttpFrontendTestCase, TestDataMixin):
'health-check-failover-https-url': 'health-check-failover-https-url':
cls.backend_url + 'failover-https-url?a=b&c=', cls.backend_url + 'failover-https-url?a=b&c=',
}, },
'health-check-failover-url-netloc-list': {
'https-only': False, # http and https access to check
'health-check-timeout': 1, # fail fast for test
'health-check-interval': 1, # fail fast for test
'url': cls.backend_url + 'url',
'https-url': cls.backend_url + 'https-url',
'health-check': True,
'health-check-http-path': '/health-check-failover-url',
'health-check-failover-url': cls.backend_url + 'failover-url?a=b&c=',
'health-check-failover-https-url':
cls.backend_url + 'failover-https-url?a=b&c=',
'health-check-failover-url-netloc-list':
'%(ip)s:%(port_a)s %(ip)s:%(port_b)s' % {
'ip': cls._ipv4_address,
'port_a': cls._server_netloc_a_http_port,
'port_b': cls._server_netloc_b_http_port},
},
'health-check-failover-url-auth-to-backend': { 'health-check-failover-url-auth-to-backend': {
'https-only': False, # http and https access to check 'https-only': False, # http and https access to check
'health-check-timeout': 1, # fail fast for test 'health-check-timeout': 1, # fail fast for test
...@@ -7257,12 +7342,6 @@ backend _health-check-default-http ...@@ -7257,12 +7342,6 @@ backend _health-check-default-http
timeout check 2s""" % (backend, ) timeout check 2s""" % (backend, )
} }
def _get_backend_haproxy_configuration(self):
backend_configuration_file = glob.glob(os.path.join(
self.instance_path, '*', 'etc', 'backend-haproxy.cfg'))[0]
with open(backend_configuration_file) as fh:
return fh.read()
def _test(self, key): def _test(self, key):
parameter_dict = self.assertSlaveBase(key) parameter_dict = self.assertSlaveBase(key)
self.assertIn( self.assertIn(
...@@ -7314,6 +7393,14 @@ backend _health-check-default-http ...@@ -7314,6 +7393,14 @@ backend _health-check-default-http
headers={'X-Reply-Status-Code': '502'}) headers={'X-Reply-Status-Code': '502'})
self.assertEqual(result.status_code, httplib.CREATED) self.assertEqual(result.status_code, httplib.CREATED)
def restoreBackend():
result = requests.put(
self.backend_url + slave_parameter_dict[
'health-check-http-path'].strip('/'),
headers={})
self.assertEqual(result.status_code, httplib.CREATED)
self.addCleanup(restoreBackend)
time.sleep(3) # > health-check-timeout + health-check-interval time.sleep(3) # > health-check-timeout + health-check-interval
result = fakeHTTPSResult(parameter_dict['domain'], '/failoverpath') result = fakeHTTPSResult(parameter_dict['domain'], '/failoverpath')
...@@ -7348,6 +7435,38 @@ backend _health-check-default-http ...@@ -7348,6 +7435,38 @@ backend _health-check-default-http
r'"GET /failoverpath HTTP/1.1"' r'"GET /failoverpath HTTP/1.1"'
) )
def test_health_check_failover_url_netloc_list(self):
parameter_dict = self.assertSlaveBase(
'health-check-failover-url-netloc-list')
slave_parameter_dict = self.getSlaveParameterDictDict()[
'health-check-failover-url-netloc-list']
# check normal access
result = fakeHTTPSResult(parameter_dict['domain'], '/path')
self.assertNotIn('X-Backend-Identification', result.headers)
# start replying with bad status code
result = requests.put(
self.backend_url + slave_parameter_dict[
'health-check-http-path'].strip('/'),
headers={'X-Reply-Status-Code': '502'})
self.assertEqual(result.status_code, httplib.CREATED)
self.assertEqual(result.status_code, httplib.CREATED)
def restoreBackend():
result = requests.put(
self.backend_url + slave_parameter_dict[
'health-check-http-path'].strip('/'),
headers={})
self.assertEqual(result.status_code, httplib.CREATED)
self.addCleanup(restoreBackend)
time.sleep(3) # > health-check-timeout + health-check-interval
# check failover, uses netloc
result = fakeHTTPSResult(parameter_dict['domain'], '/path')
self.assertEqual(
result.headers['X-Backend-Identification'],
'netloc'
)
def test_health_check_failover_url_auth_to_backend(self): def test_health_check_failover_url_auth_to_backend(self):
parameter_dict = self.assertSlaveBase( parameter_dict = self.assertSlaveBase(
'health-check-failover-url-auth-to-backend') 'health-check-failover-url-auth-to-backend')
......
...@@ -73,6 +73,9 @@ T-2/var/log/httpd/_enable_cache_server_alias_error_log ...@@ -73,6 +73,9 @@ T-2/var/log/httpd/_enable_cache_server_alias_error_log
T-2/var/log/httpd/_https-only_access_log T-2/var/log/httpd/_https-only_access_log
T-2/var/log/httpd/_https-only_backend_log T-2/var/log/httpd/_https-only_backend_log
T-2/var/log/httpd/_https-only_error_log T-2/var/log/httpd/_https-only_error_log
T-2/var/log/httpd/_https-url-netloc-list_access_log
T-2/var/log/httpd/_https-url-netloc-list_backend_log
T-2/var/log/httpd/_https-url-netloc-list_error_log
T-2/var/log/httpd/_monitor-ipv4-test_access_log T-2/var/log/httpd/_monitor-ipv4-test_access_log
T-2/var/log/httpd/_monitor-ipv4-test_error_log T-2/var/log/httpd/_monitor-ipv4-test_error_log
T-2/var/log/httpd/_monitor-ipv6-test_access_log T-2/var/log/httpd/_monitor-ipv6-test_access_log
...@@ -156,6 +159,9 @@ T-2/var/log/httpd/_type-zope-virtualhostroot-https-port_error_log ...@@ -156,6 +159,9 @@ T-2/var/log/httpd/_type-zope-virtualhostroot-https-port_error_log
T-2/var/log/httpd/_type-zope_access_log T-2/var/log/httpd/_type-zope_access_log
T-2/var/log/httpd/_type-zope_backend_log T-2/var/log/httpd/_type-zope_backend_log
T-2/var/log/httpd/_type-zope_error_log T-2/var/log/httpd/_type-zope_error_log
T-2/var/log/httpd/_url-netloc-list_access_log
T-2/var/log/httpd/_url-netloc-list_backend_log
T-2/var/log/httpd/_url-netloc-list_error_log
T-2/var/log/httpd/_url_https-url_access_log T-2/var/log/httpd/_url_https-url_access_log
T-2/var/log/httpd/_url_https-url_backend_log T-2/var/log/httpd/_url_https-url_backend_log
T-2/var/log/httpd/_url_https-url_error_log T-2/var/log/httpd/_url_https-url_error_log
......
...@@ -73,6 +73,9 @@ T-2/var/log/httpd/_enable_cache_server_alias_error_log ...@@ -73,6 +73,9 @@ T-2/var/log/httpd/_enable_cache_server_alias_error_log
T-2/var/log/httpd/_https-only_access_log T-2/var/log/httpd/_https-only_access_log
T-2/var/log/httpd/_https-only_backend_log T-2/var/log/httpd/_https-only_backend_log
T-2/var/log/httpd/_https-only_error_log T-2/var/log/httpd/_https-only_error_log
T-2/var/log/httpd/_https-url-netloc-list_access_log
T-2/var/log/httpd/_https-url-netloc-list_backend_log
T-2/var/log/httpd/_https-url-netloc-list_error_log
T-2/var/log/httpd/_monitor-ipv4-test_access_log T-2/var/log/httpd/_monitor-ipv4-test_access_log
T-2/var/log/httpd/_monitor-ipv4-test_error_log T-2/var/log/httpd/_monitor-ipv4-test_error_log
T-2/var/log/httpd/_monitor-ipv6-test_access_log T-2/var/log/httpd/_monitor-ipv6-test_access_log
...@@ -156,6 +159,9 @@ T-2/var/log/httpd/_type-zope-virtualhostroot-https-port_error_log ...@@ -156,6 +159,9 @@ T-2/var/log/httpd/_type-zope-virtualhostroot-https-port_error_log
T-2/var/log/httpd/_type-zope_access_log T-2/var/log/httpd/_type-zope_access_log
T-2/var/log/httpd/_type-zope_backend_log T-2/var/log/httpd/_type-zope_backend_log
T-2/var/log/httpd/_type-zope_error_log T-2/var/log/httpd/_type-zope_error_log
T-2/var/log/httpd/_url-netloc-list_access_log
T-2/var/log/httpd/_url-netloc-list_backend_log
T-2/var/log/httpd/_url-netloc-list_error_log
T-2/var/log/httpd/_url_https-url_access_log T-2/var/log/httpd/_url_https-url_access_log
T-2/var/log/httpd/_url_https-url_backend_log T-2/var/log/httpd/_url_https-url_backend_log
T-2/var/log/httpd/_url_https-url_error_log T-2/var/log/httpd/_url_https-url_error_log
......
...@@ -24,6 +24,9 @@ T-2/var/log/httpd/_health-check-disabled_error_log ...@@ -24,6 +24,9 @@ T-2/var/log/httpd/_health-check-disabled_error_log
T-2/var/log/httpd/_health-check-failover-url-auth-to-backend_access_log T-2/var/log/httpd/_health-check-failover-url-auth-to-backend_access_log
T-2/var/log/httpd/_health-check-failover-url-auth-to-backend_backend_log T-2/var/log/httpd/_health-check-failover-url-auth-to-backend_backend_log
T-2/var/log/httpd/_health-check-failover-url-auth-to-backend_error_log T-2/var/log/httpd/_health-check-failover-url-auth-to-backend_error_log
T-2/var/log/httpd/_health-check-failover-url-netloc-list_access_log
T-2/var/log/httpd/_health-check-failover-url-netloc-list_backend_log
T-2/var/log/httpd/_health-check-failover-url-netloc-list_error_log
T-2/var/log/httpd/_health-check-failover-url-ssl-proxy-verified_access_log T-2/var/log/httpd/_health-check-failover-url-ssl-proxy-verified_access_log
T-2/var/log/httpd/_health-check-failover-url-ssl-proxy-verified_backend_log T-2/var/log/httpd/_health-check-failover-url-ssl-proxy-verified_backend_log
T-2/var/log/httpd/_health-check-failover-url-ssl-proxy-verified_error_log T-2/var/log/httpd/_health-check-failover-url-ssl-proxy-verified_error_log
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment