diff --git a/software/caddy-frontend/buildout.hash.cfg b/software/caddy-frontend/buildout.hash.cfg index 33ffcde36bc268a9cc4f811db040d7b66cba502f..12b53db4878ad35983bd124540f71039c42fb69f 100644 --- a/software/caddy-frontend/buildout.hash.cfg +++ b/software/caddy-frontend/buildout.hash.cfg @@ -26,7 +26,7 @@ md5sum = 750e2b1c922bf14511a3bc8a42468b1b [template-apache-replicate] filename = instance-apache-replicate.cfg.in -md5sum = e5e537052c533c6d6f1c2197428f77fd +md5sum = aaac56847a966ec4f155cba10570bb3c [template-slave-list] filename = templates/apache-custom-slave-list.cfg.in diff --git a/software/caddy-frontend/instance-apache-replicate.cfg.in b/software/caddy-frontend/instance-apache-replicate.cfg.in index 2c07f30c35b1f59a9f2355be8afb39c871148d57..83274be91ebe6193bda393181d50fada9d41f215 100644 --- a/software/caddy-frontend/instance-apache-replicate.cfg.in +++ b/software/caddy-frontend/instance-apache-replicate.cfg.in @@ -66,24 +66,25 @@ context = {% set authorized_slave_string = slapparameter_dict.pop('-frontend-authorized-slave-string', '') %} {% set authorized_slave_list = [] %} -{% set rejected_slave_list = [] %} +{% set rejected_slave_dict = {} %} {% set used_host_list = [] %} +{% set unauthorised_message = 'slave not authorised' %} {% for slave in slave_instance_list %} -{% set slave_dict = {'state': True} %} +{% set slave_error_list = [] %} {# BBB: apache_custom_https AND apache_custom_http #} {% set custom_domain = slave.get('custom_domain') %} {% if custom_domain and custom_domain in used_host_list %} -{% do slave_dict.__setitem__('state', False) %} +{% do slave_error_list.append('custom_domain %r clashes' % (custom_domain,)) %} {% else %} {% do used_host_list.append(custom_domain) %} {% endif %} {% if slave.get('server-alias') %} {% for slave_alias in slave['server-alias'].split() %} {% if not validators.domain(slave_alias) %} -{% do slave_dict.__setitem__('state', False) %} +{% do slave_error_list.append('server-alias %r not valid' % (slave_alias,)) %} {% else %} {% if slave_alias in used_host_list %} -{% do slave_dict.__setitem__('state', False) %} +{% do slave_error_list.append('server-alias %r clashes' % (slave_alias,)) %} {% else %} {% do used_host_list.append(slave_alias) %} {% endif %} @@ -93,20 +94,22 @@ context = {% for key in ['caddy_custom_http', 'caddy_custom_https', 'apache_custom_http', 'apache_custom_https'] %} {% if slave.get(key) %} {% if not slave.get('slave_reference') in authorized_slave_string %} -{% do slave_dict.__setitem__('state', False) %} +{% if not unauthorised_message in slave_error_list %} +{% do slave_error_list.append(unauthorised_message) %} +{% endif %} {% elif subprocess_module.call([caddy_custom_http_validator, slave[key]]) == 1 %} -{% do slave_dict.__setitem__('state', False) %} +{% do slave_error_list.append('slave %s configuration invalid' % (key,)) %} {% endif %} {% endif %} {% endfor %} {# for key in ['caddy_custom_http', 'caddy_custom_https', 'apache_custom_http', 'apache_custom_https'] #} {% if slave.get('url') %} {% if subprocess_module.call([caddy_backend_url_validator, slave['url']]) == 1 %} -{% do slave_dict.__setitem__('state', False) %} +{% do slave_error_list.append('slave url %r invalid' % (slave['url'],)) %} {% endif %} {% endif %} {% if slave.get('https-url') %} {% if subprocess_module.call([caddy_backend_url_validator, slave['https-url']]) == 1 %} -{% do slave_dict.__setitem__('state', False) %} +{% do slave_error_list.append('slave https-url %r invalid' % (slave['https-url'],)) %} {% endif %} {% endif %} {% if slave.get('ssl_key') and slave.get('ssl_crt') %} @@ -115,18 +118,18 @@ context = {% set key_modulus = key_popen.communicate(slave['ssl_key'])[0] | trim %} {% set crt_modulus = crt_popen.communicate(slave['ssl_crt'])[0] | trim %} {% if not key_modulus or key_modulus != crt_modulus %} -{% do slave_dict.__setitem__('state', False) %} +{% do slave_error_list.append('slave ssl_key and ssl_crt does not match') %} {% endif %} {% endif %} {% if slave.get('custom_domain') %} {% if not validators.domain(slave['custom_domain']) %} -{% do slave_dict.__setitem__('state', False) %} +{% do slave_error_list.append('custom_domain %r invalid' % (slave['custom_domain'],)) %} {% endif %} {% endif %} -{% if slave_dict['state'] %} +{% if len(slave_error_list) == 0 %} {% do authorized_slave_list.append(slave) %} {% else %} -{% do rejected_slave_list.append(slave.get('slave_reference')) %} +{% do rejected_slave_dict.__setitem__(slave.get('slave_reference'), slave_error_list) %} {% endif %} {% endfor %} @@ -177,8 +180,8 @@ recipe = slapos.cookbook:publish domain = {{ slapparameter_dict.get('domain') }} slave-amount = {{ slave_instance_list | length }} accepted-slave-amount = {{ authorized_slave_list | length }} -rejected-slave-amount = {{ rejected_slave_list | length }} -rejected-slave-list = {{ json_module.dumps(rejected_slave_list) }} +rejected-slave-amount = {{ rejected_slave_dict | length }} +rejected-slave-dict = {{ dumps(json_module.dumps(rejected_slave_dict)) }} #---------------------------- #-- diff --git a/software/caddy-frontend/instance-output-schema.json b/software/caddy-frontend/instance-output-schema.json index cbad7214cd0c1e684683d373da2f59e2f5d6bafd..d8c1746597f7636d1e35823f4a99d56d51852cbd 100644 --- a/software/caddy-frontend/instance-output-schema.json +++ b/software/caddy-frontend/instance-output-schema.json @@ -26,12 +26,12 @@ "description": "User to access the monitor", "type": "string" }, - "reject-slave-amount": { + "rejected-slave-amount": { "description": "Rejected Amount of Slaves allocated to the Instance which are not deployed", "type": "integer" }, - "rejected-slave-list": { - "description": "List of slave instances references which are rejected", + "rejected-slave-dict": { + "description": "Dict of slaves which were rejected. Keys are slave references, values are lists of errors on slaves.", "type": "array" }, "slave-amount": { diff --git a/software/caddy-frontend/test/test.py b/software/caddy-frontend/test/test.py index 0266ae40bdc0e9e2014b1b58a17e7ac990b385e2..b7295747ac5af9ae7033026401dc571faab84f2f 100644 --- a/software/caddy-frontend/test/test.py +++ b/software/caddy-frontend/test/test.py @@ -262,7 +262,7 @@ class TestMasterRequest(HttpFrontendTestCase, TestDataMixin): 'accepted-slave-amount': '0', 'rejected-slave-amount': '0', 'slave-amount': '0', - 'rejected-slave-list': '[]'}, + 'rejected-slave-dict': '{}'}, parameter_dict ) @@ -296,7 +296,7 @@ class TestMasterRequestDomain(HttpFrontendTestCase, TestDataMixin): 'accepted-slave-amount': '0', 'rejected-slave-amount': '0', 'slave-amount': '0', - 'rejected-slave-list': '[]' + 'rejected-slave-dict': '{}' }, parameter_dict ) @@ -727,8 +727,10 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s { 'accepted-slave-amount': '33', 'rejected-slave-amount': '2', 'slave-amount': '35', - 'rejected-slave-list': - '["_caddy_custom_http_s-rejected", "_apache_custom_http_s-rejected"]'} + 'rejected-slave-dict': + '{"_apache_custom_http_s-rejected": ["slave not authorised"], ' + '"_caddy_custom_http_s-rejected": ["slave not authorised"]}' + } self.assertEqual( expected_parameter_dict, @@ -2638,7 +2640,11 @@ class TestMalformedBackenUrlSlave(SlaveHttpFrontendTestCase, 'accepted-slave-amount': '1', 'rejected-slave-amount': '2', 'slave-amount': '3', - 'rejected-slave-list': '["_url", "_https-url"]'} + 'rejected-slave-dict': + '{"_https-url": ["slave https-url \\"https://[fd46::c2ae]:!py!u\'123123' + '\'\\" invalid"], "_url": ["slave url \\"https://[fd46::c2ae]:!py!u\'' + '123123\'\\" invalid"]}' + } self.assertEqual( expected_parameter_dict, @@ -2917,9 +2923,15 @@ https://www.google.com {}""", 'accepted-slave-amount': '8', 'rejected-slave-amount': '4', 'slave-amount': '12', - 'rejected-slave-list': - '["_caddy_custom_http_s-reject", "_ssl_key-ssl_crt-unsafe", ' - '"_custom_domain-unsafe", "_server-alias-unsafe"]'} + 'rejected-slave-dict': + '{"_caddy_custom_http_s-reject": ["slave caddy_custom_http ' + 'configuration invalid", "slave caddy_custom_https configuration ' + 'invalid"], "_server-alias-unsafe": ["server-alias \'${section:option}\'' + ' not valid", "server-alias \'afterspace\' not valid"], ' + '"_custom_domain-unsafe": ["custom_domain \'${section:option} ' + 'afterspace\\\\nafternewline\' invalid"], "_ssl_key-ssl_crt-unsafe": ' + '["slave ssl_key and ssl_crt does not match"]}' + } self.assertEqual( expected_parameter_dict, @@ -3286,7 +3298,11 @@ class TestDuplicateSiteKeyProtection(SlaveHttpFrontendTestCase, TestDataMixin): 'accepted-slave-amount': '1', 'rejected-slave-amount': '3', 'slave-amount': '4', - 'rejected-slave-list': '["_site_3", "_site_1", "_site_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"]}'} self.assertEqual( expected_parameter_dict,