Commit a48041d0 by Łukasz Nowak Committed by Łukasz Nowak

caddy-frontend: Add error reporting to slave requester

Each slave rejected by the frontend will report back detailed information
to slave requester in key request-error-list being [json_list_of_found_errors]
1 parent 44b3fe29
......@@ -26,7 +26,7 @@ md5sum = 750e2b1c922bf14511a3bc8a42468b1b
[template-apache-replicate]
filename = instance-apache-replicate.cfg.in
md5sum = aaac56847a966ec4f155cba10570bb3c
md5sum = 1576859772052bcb85ff2b5a7b786410
[template-slave-list]
filename = templates/apache-custom-slave-list.cfg.in
......@@ -38,7 +38,7 @@ md5sum = 54ae95597a126ae552c3a913ddf29e5e
[template-replicate-publish-slave-information]
filename = templates/replicate-publish-slave-information.cfg.in
md5sum = 6a308c29b54d53cfd82ae23ba77a35dd
md5sum = 01efde8febafcff6dde2ebb43e75a9e4
[template-caddy-frontend-configuration]
filename = templates/Caddyfile.in
......
......@@ -194,6 +194,11 @@ replicate = ${dynamic-publish-slave-information:rendered}
custom-personal = ${dynamic-publish-slave-information:rendered}
custom-group = ${dynamic-publish-slave-information:rendered}
[rejected-slave-information]
{% for slave_id, rejected_list in rejected_slave_dict.iteritems() %}
{{ slave_id }} = {{ dumps(json_module.dumps(rejected_list)) }}
{% endfor %}
[slave-information]
{% for frontend_section in frontend_section_list %}
{{ frontend_section }} = {{ "${%s:connection-slave-instance-information-list}" % frontend_section }}
......@@ -206,6 +211,7 @@ filename = dynamic-publish-slave-information.cfg
extensions = jinja2.ext.do
extra-context =
section slave_information slave-information
section rejected_slave_information rejected-slave-information
[monitor-conf-parameters]
monitor-url-list +=
......
......@@ -29,6 +29,10 @@
"url": {
"description": "Default URL provided",
"type": "string"
},
"request-error-list": {
"description": "In case if slave has been rejected by master or has error in the request, the list contains information about each problem",
"type": "string"
}
},
"type": "object"
......
......@@ -27,6 +27,13 @@
{% endfor %}
{% endfor %}
{% for slave_reference, rejected_info_list in rejected_slave_information.iteritems() %}
{% if slave_reference not in slave_information_dict %}
{% do slave_information_dict.__setitem__(slave_reference, {}) %}
{% endif %}
{% do slave_information_dict[slave_reference].__setitem__('request-error-list', rejected_info_list) %}
{% endfor %}
# Publish information for each slave
{% for slave_reference, slave_information in slave_information_dict.iteritems() %}
{% set publish_section_title = 'publish-%s' % slave_reference %}
......@@ -34,9 +41,12 @@
[{{ publish_section_title }}]
recipe = slapos.cookbook:publish
-slave-reference = {{ slave_reference }}
log-access-url = {{ json_module.dumps(slave_information.pop('log-access-urls', 1000)) }}
{% set log_access_url = slave_information.pop('log-access-urls', None) %}
{% if log_access_url %}
log-access-url = {{ dumps(json_module.dumps(log_access_url)) }}
{% endif %}
{% for key, value in slave_information.iteritems() %}
{{ key }} = {{ value }}
{{ key }} = {{ dumps(value) }}
{% endfor %}
{% endfor %}
......@@ -45,4 +55,4 @@ extends = {{ common_profile }}
parts =
{% for part in part_list %}
{{ ' %s' % part }}
{% endfor %}
\ No newline at end of file
{% endfor %}
......@@ -2069,7 +2069,11 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s {
def test_apache_custom_http_s_rejected(self):
parameter_dict = self.slave_connection_parameter_dict_dict[
'apache_custom_http_s-rejected']
self.assertEqual({}, parameter_dict)
self.assertEqual(
{
'request-error-list': '["slave not authorised"]'
},
parameter_dict)
slave_configuration_file_list = glob.glob(os.path.join(
self.instance_path, '*', 'etc', '*slave-conf.d', '*.conf'))
# no configuration file contains provided custom http
......@@ -2143,7 +2147,11 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s {
def test_caddy_custom_http_s_rejected(self):
parameter_dict = self.slave_connection_parameter_dict_dict[
'caddy_custom_http_s-rejected']
self.assertEqual({}, parameter_dict)
self.assertEqual(
{
'request-error-list': '["slave not authorised"]'
},
parameter_dict)
slave_configuration_file_list = glob.glob(os.path.join(
self.instance_path, '*', 'etc', '*slave-conf.d', '*.conf'))
# no configuration file contains provided custom http
......@@ -2680,14 +2688,22 @@ class TestMalformedBackenUrlSlave(SlaveHttpFrontendTestCase,
parameter_dict = self.slave_connection_parameter_dict_dict[
'url'].copy()
self.assertEqual(
parameter_dict, {}
parameter_dict,
{
'request-error-list': '["slave url \\"https://[fd46::c2ae]:!py!'
'u\'123123\'\\" invalid"]'
}
)
def test_https_url(self):
parameter_dict = self.slave_connection_parameter_dict_dict[
'https-url'].copy()
self.assertEqual(
parameter_dict, {}
parameter_dict,
{
'request-error-list': '["slave https-url \\"https://[fd46::c2ae]:'
'!py!u\'123123\'\\" invalid"]'
}
)
......@@ -3048,7 +3064,11 @@ https://www.google.com {}""",
'custom_domain-unsafe']
self.assertEqual(
parameter_dict,
{}
{
'request-error-list':
'["custom_domain \'${section:option} afterspace\\\\nafternewline\' '
'invalid"]'
}
)
def test_server_alias_unsafe(self):
......@@ -3056,7 +3076,11 @@ https://www.google.com {}""",
'server-alias-unsafe']
self.assertEqual(
parameter_dict,
{}
{
'request-error-list':
'["server-alias \'${section:option}\' not valid", "server-alias '
'\'afterspace\' not valid"]'
}
)
def test_virtualhostroot_http_port_unsafe(self):
......@@ -3239,7 +3263,7 @@ https://www.google.com {}""",
'ssl_key-ssl_crt-unsafe']
self.assertEqual(
parameter_dict,
{}
{'request-error-list': '["slave ssl_key and ssl_crt does not match"]'}
)
def test_caddy_custom_http_s_reject(self):
......@@ -3247,7 +3271,11 @@ https://www.google.com {}""",
'caddy_custom_http_s-reject']
self.assertEqual(
parameter_dict,
{}
{
'request-error-list':
'["slave caddy_custom_http configuration invalid", '
'"slave caddy_custom_https configuration invalid"]'
}
)
......@@ -3299,16 +3327,28 @@ class TestDuplicateSiteKeyProtection(SlaveHttpFrontendTestCase, TestDataMixin):
'rejected-slave-amount': '3',
'slave-amount': '4',
'rejected-slave-dict':
'{"_site_4": ["custom_domain clashes", "server-alias '
'\'duplicate.example.com\' clashes"], "_site_1": '
'["custom_domain clashes"], "_site_3": ["server-alias '
'\'duplicate.example.com\' clashes"]}'}
'{"_site_4": ["custom_domain \'duplicate.example.com\' clashes", '
'"server-alias \'duplicate.example.com\' clashes"], "_site_1": '
'["custom_domain \'duplicate.example.com\' clashes"], "_site_3": '
'["server-alias \'duplicate.example.com\' clashes"]}'
}
self.assertEqual(
expected_parameter_dict,
parameter_dict
)
def test_site_1(self):
parameter_dict = self.slave_connection_parameter_dict_dict[
'site_1']
self.assertEqual(
parameter_dict,
{
'request-error-list':
'["custom_domain \'duplicate.example.com\' clashes"]'
}
)
def test_site_2(self):
parameter_dict = self.slave_connection_parameter_dict_dict[
'site_2']
......@@ -3324,3 +3364,26 @@ class TestDuplicateSiteKeyProtection(SlaveHttpFrontendTestCase, TestDataMixin):
'public-ipv4': LOCAL_IPV4,
}
)
def test_site_3(self):
parameter_dict = self.slave_connection_parameter_dict_dict[
'site_3']
self.assertEqual(
parameter_dict,
{
'request-error-list':
'["server-alias \'duplicate.example.com\' clashes"]'
}
)
def test_site_4(self):
parameter_dict = self.slave_connection_parameter_dict_dict[
'site_4']
self.assertEqual(
parameter_dict,
{
'request-error-list':
'["custom_domain \'duplicate.example.com\' clashes", "server-alias '
'\'duplicate.example.com\' clashes"]'
}
)
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!