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

caddy-frontend: Stabilise passed parameters to nodes

parent 49cce32f
...@@ -26,7 +26,7 @@ md5sum = 91fce5ebea302e9c9ccc20c140b76608 ...@@ -26,7 +26,7 @@ md5sum = 91fce5ebea302e9c9ccc20c140b76608
[profile-caddy-replicate] [profile-caddy-replicate]
filename = instance-apache-replicate.cfg.in filename = instance-apache-replicate.cfg.in
md5sum = 26b21124b898158c4f409a798eb253ad md5sum = ab85ee7bd22e559d87bb214bb22a0e9e
[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
......
...@@ -5,6 +5,25 @@ ...@@ -5,6 +5,25 @@
{%- set SERVER_POLLUTED_KEY_LIST = ['connection-parameter-hash', 'timestamp', 'slave_title', 'slap_software_type'] -%} {%- set SERVER_POLLUTED_KEY_LIST = ['connection-parameter-hash', 'timestamp', 'slave_title', 'slap_software_type'] -%}
{%- set TRUE_VALUES = ['y', 'yes', '1', 'true'] -%} {%- set TRUE_VALUES = ['y', 'yes', '1', 'true'] -%}
{%- set GOOD_CIPHER_LIST = ['ECDHE-ECDSA-AES256-GCM-SHA384', 'ECDHE-RSA-AES256-GCM-SHA384', 'ECDHE-ECDSA-AES128-GCM-SHA256', 'ECDHE-RSA-AES128-GCM-SHA256', 'ECDHE-ECDSA-WITH-CHACHA20-POLY1305', 'ECDHE-RSA-WITH-CHACHA20-POLY1305', 'ECDHE-RSA-AES256-CBC-SHA', 'ECDHE-RSA-AES128-CBC-SHA', 'ECDHE-ECDSA-AES256-CBC-SHA', 'ECDHE-ECDSA-AES128-CBC-SHA', 'RSA-AES256-CBC-SHA', 'RSA-AES128-CBC-SHA', 'ECDHE-RSA-3DES-EDE-CBC-SHA', 'RSA-3DES-EDE-CBC-SHA'] %} {%- set GOOD_CIPHER_LIST = ['ECDHE-ECDSA-AES256-GCM-SHA384', 'ECDHE-RSA-AES256-GCM-SHA384', 'ECDHE-ECDSA-AES128-GCM-SHA256', 'ECDHE-RSA-AES128-GCM-SHA256', 'ECDHE-ECDSA-WITH-CHACHA20-POLY1305', 'ECDHE-RSA-WITH-CHACHA20-POLY1305', 'ECDHE-RSA-AES256-CBC-SHA', 'ECDHE-RSA-AES128-CBC-SHA', 'ECDHE-ECDSA-AES256-CBC-SHA', 'ECDHE-ECDSA-AES128-CBC-SHA', 'RSA-AES256-CBC-SHA', 'RSA-AES128-CBC-SHA', 'ECDHE-RSA-3DES-EDE-CBC-SHA', 'RSA-3DES-EDE-CBC-SHA'] %}
{#- Allow to pass only some parameters to frontend nodes #}
{%- set FRONTEND_NODE_PASSED_KEY_LIST = [
'plain_http_port',
'port',
'apache-certificate',
'apache-key',
'domain',
'enable-http2-by-default',
'global-disable-http2',
'mpm-graceful-shutdown-timeout',
'public-ipv4',
're6st-verification-url',
'backend-connect-timeout',
'backend-connect-retries',
'ciphers',
'request-timeout',
'authenticate-to-backend',
]
%}
{% set aikc_enabled = slapparameter_dict.get('automatic-internal-kedifa-caucase-csr', 'true').lower() in TRUE_VALUES %} {% set aikc_enabled = slapparameter_dict.get('automatic-internal-kedifa-caucase-csr', 'true').lower() in TRUE_VALUES %}
{% set aibcc_enabled = slapparameter_dict.get('automatic-internal-backend-client-caucase-csr', 'true').lower() in TRUE_VALUES %} {% set aibcc_enabled = slapparameter_dict.get('automatic-internal-backend-client-caucase-csr', 'true').lower() in TRUE_VALUES %}
{# Ports 8401, 8402 and 8410+1..N are reserved for monitor ports on various partitions #} {# Ports 8401, 8402 and 8410+1..N are reserved for monitor ports on various partitions #}
...@@ -217,6 +236,13 @@ config-monitor-password = ${monitor-htpasswd:passwd} ...@@ -217,6 +236,13 @@ config-monitor-password = ${monitor-htpasswd:passwd}
software-type = {{frontend_type}} software-type = {{frontend_type}}
return = private-ipv4 public-ipv4 slave-instance-information-list monitor-base-url backend-client-csr_id-url csr_id-url csr_id-certificate backend-haproxy-statistic-url return = private-ipv4 public-ipv4 slave-instance-information-list monitor-base-url backend-client-csr_id-url csr_id-url csr_id-certificate backend-haproxy-statistic-url
{#- Send only needed parameters to frontend nodes #}
{%- set base_node_configuration_dict = {} %}
{%- for key in FRONTEND_NODE_PASSED_KEY_LIST %}
{%- if key in slapparameter_dict %}
{%- do base_node_configuration_dict.__setitem__(key, slapparameter_dict[key]) %}
{%- endif %}
{%- endfor %}
{% for section, frontend_request in request_dict.iteritems() %} {% for section, frontend_request in request_dict.iteritems() %}
{% set state = frontend_request.get('state', '') %} {% set state = frontend_request.get('state', '') %}
[{{section}}] [{{section}}]
...@@ -233,12 +259,15 @@ config-master-key-download-url = ${request-kedifa:connection-master-key-download ...@@ -233,12 +259,15 @@ config-master-key-download-url = ${request-kedifa:connection-master-key-download
config-cluster-identification = {{ instance_parameter_dict['root-instance-title'] }} config-cluster-identification = {{ instance_parameter_dict['root-instance-title'] }}
{# Do not send additional parameters for destroyed nodes #} {# Do not send additional parameters for destroyed nodes #}
{% if state != 'destroyed' %} {% if state != 'destroyed' %}
{% set slave_configuration_dict = slapparameter_dict %} {% set node_configuration_dict = {} %}
{% do slave_configuration_dict.update(frontend_request.get('config')) %} {% do node_configuration_dict.update(frontend_request.get('config')) %}
{# sort_keys are important in order to avoid shuffling parameters on each run #} {# sort_keys are important in order to avoid shuffling parameters on each run #}
{% do slave_configuration_dict.__setitem__(slave_list_name, json_module.dumps(authorized_slave_list, sort_keys=True)) %} {% do node_configuration_dict.__setitem__(slave_list_name, json_module.dumps(authorized_slave_list, sort_keys=True)) %}
{% do slave_configuration_dict.__setitem__("frontend-name", frontend_request.get('name')) %} {% do node_configuration_dict.__setitem__("frontend-name", frontend_request.get('name')) %}
{%- for config_key, config_value in slave_configuration_dict.iteritems() %} {%- for config_key, config_value in node_configuration_dict.iteritems() %}
config-{{ config_key }} = {{ dumps(config_value) }}
{% endfor -%}
{%- for config_key, config_value in base_node_configuration_dict.iteritems() %}
config-{{ config_key }} = {{ dumps(config_value) }} config-{{ config_key }} = {{ dumps(config_value) }}
{% endfor -%} {% endfor -%}
{% endif %} {% endif %}
......
...@@ -48,7 +48,6 @@ from slapos.recipe.librecipe import generateHashFromFiles ...@@ -48,7 +48,6 @@ from slapos.recipe.librecipe import generateHashFromFiles
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import urlparse import urlparse
import socket import socket
import sqlite3
try: try:
...@@ -6790,14 +6789,34 @@ class TestPassedRequestParameter(HttpFrontendTestCase): ...@@ -6790,14 +6789,34 @@ class TestPassedRequestParameter(HttpFrontendTestCase):
def test(self): def test(self):
self.instance_parameter_dict.update({ self.instance_parameter_dict.update({
# master partition parameters
'-frontend-quantity': 3, '-frontend-quantity': 3,
'-sla-2-computer_guid': self.slap._computer_id, '-sla-2-computer_guid': self.slap._computer_id,
'-sla-3-computer_guid': self.slap._computer_id,
'-frontend-2-state': 'stopped', '-frontend-2-state': 'stopped',
'-frontend-2-software-release-url': self.frontend_2_sr, '-frontend-2-software-release-url': self.frontend_2_sr,
'-sla-3-computer_guid': self.slap._computer_id,
'-frontend-3-state': 'stopped', '-frontend-3-state': 'stopped',
'-frontend-3-software-release-url': self.frontend_3_sr, '-frontend-3-software-release-url': self.frontend_3_sr,
'-kedifa-software-release-url': self.kedifa_sr, '-kedifa-software-release-url': self.kedifa_sr,
'automatic-internal-kedifa-caucase-csr': False,
'automatic-internal-backend-client-caucase-csr': False,
# all nodes partition parameters
'apache-certificate': self.certificate_pem,
'apache-key': self.key_pem,
'domain': 'example.com',
'enable-http2-by-default': True,
'global-disable-http2': True,
'mpm-graceful-shutdown-timeout': 2,
'public-ipv4': '255.255.255.255',
're6st-verification-url': 're6st-verification-url',
'backend-connect-timeout': 2,
'backend-connect-retries': 1,
'ciphers': 'ciphers',
'request-timeout': 100,
'authenticate-to-backend': True,
# specific parameters
'-frontend-config-1-ram-cache-size': '512K',
'-frontend-config-2-ram-cache-size': '256K',
}) })
# re-request instance with updated parameters # re-request instance with updated parameters
...@@ -6809,43 +6828,196 @@ class TestPassedRequestParameter(HttpFrontendTestCase): ...@@ -6809,43 +6828,196 @@ class TestPassedRequestParameter(HttpFrontendTestCase):
except Exception: except Exception:
pass pass
# inspect slapproxy, that the master correctly requested other partitions computer = self.slap._slap.registerComputer('local')
sqlitedb_file = os.path.join( # state of parameters of all instances
os.path.abspath( partition_parameter_dict_dict = {}
os.path.join( for partition in computer.getComputerPartitionList():
self.slap.instance_directory, os.pardir if partition.getState() == 'destroyed':
) continue
), 'var', 'proxy.db' parameter_dict = partition.getInstanceParameterDict()
) instance_title = parameter_dict['instance_title']
connection = sqlite3.connect(sqlitedb_file) if '_' in parameter_dict:
# "flatten" the instance parameter
def dict_factory(cursor, row): parameter_dict = json.loads(parameter_dict['_'])
d = {} partition_parameter_dict_dict[instance_title] = parameter_dict
for idx, col in enumerate(cursor.description): parameter_dict[
d[col[0]] = row[idx] 'X-software_release_url'] = partition.getSoftwareRelease().getURI()
return d
connection.row_factory = dict_factory
cursor = connection.cursor()
cursor.execute(
"select partition_reference, software_release "
"from partition14 where slap_state='busy';")
requested_partition_information = cursor.fetchall()
base_software_url = self.getSoftwareURL() base_software_url = self.getSoftwareURL()
# drop some very varying parameters
def assertKeyWithPop(d, k):
self.assertIn(k, d)
d.pop(k)
assertKeyWithPop(
partition_parameter_dict_dict['caddy-frontend-1'],
'master-key-download-url')
assertKeyWithPop(
partition_parameter_dict_dict['caddy-frontend-2'],
'master-key-download-url')
assertKeyWithPop(
partition_parameter_dict_dict['caddy-frontend-3'],
'master-key-download-url')
assertKeyWithPop(
partition_parameter_dict_dict['testing partition 0'],
'timestamp')
assertKeyWithPop(
partition_parameter_dict_dict['testing partition 0'],
'ip_list')
monitor_password = partition_parameter_dict_dict[
'caddy-frontend-1'].pop('monitor-password')
self.assertEqual(
monitor_password,
partition_parameter_dict_dict[
'caddy-frontend-2'].pop('monitor-password')
)
self.assertEqual(
monitor_password,
partition_parameter_dict_dict[
'caddy-frontend-3'].pop('monitor-password')
)
self.assertEqual(
monitor_password,
partition_parameter_dict_dict[
'kedifa'].pop('monitor-password')
)
backend_client_caucase_url = u'http://[%s]:8990' % (self._ipv6_address,)
kedifa_caucase_url = u'http://[%s]:15090' % (self._ipv6_address,)
expected_partition_parameter_dict_dict = {
'caddy-frontend-1': {
'X-software_release_url': base_software_url,
u'apache-certificate': unicode(self.certificate_pem),
u'apache-key': unicode(self.key_pem),
u'authenticate-to-backend': u'True',
u'backend-client-caucase-url': backend_client_caucase_url,
u'backend-connect-retries': u'1',
u'backend-connect-timeout': u'2',
u'ciphers': u'ciphers',
u'cluster-identification': u'testing partition 0',
u'domain': u'example.com',
u'enable-http2-by-default': u'True',
u'extra_slave_instance_list': u'[]',
u'frontend-name': u'caddy-frontend-1',
u'global-disable-http2': u'True',
u'kedifa-caucase-url': kedifa_caucase_url,
u'monitor-cors-domains': u'monitor.app.officejs.com',
u'monitor-httpd-port': 8411,
u'monitor-username': u'admin',
u'mpm-graceful-shutdown-timeout': u'2',
u'plain_http_port': '11080',
u'port': '11443',
u'public-ipv4': u'255.255.255.255',
u'ram-cache-size': u'512K',
u're6st-verification-url': u're6st-verification-url',
u'request-timeout': u'100',
u'slave-kedifa-information': u'{}'
},
'caddy-frontend-2': {
'X-software_release_url': self.frontend_2_sr,
u'apache-certificate': unicode(self.certificate_pem),
u'apache-key': unicode(self.key_pem),
u'authenticate-to-backend': u'True',
u'backend-client-caucase-url': backend_client_caucase_url,
u'backend-connect-retries': u'1',
u'backend-connect-timeout': u'2',
u'ciphers': u'ciphers',
u'cluster-identification': u'testing partition 0',
u'domain': u'example.com',
u'enable-http2-by-default': u'True',
u'extra_slave_instance_list': u'[]',
u'frontend-name': u'caddy-frontend-2',
u'global-disable-http2': u'True',
u'kedifa-caucase-url': kedifa_caucase_url,
u'monitor-cors-domains': u'monitor.app.officejs.com',
u'monitor-httpd-port': 8412,
u'monitor-username': u'admin',
u'mpm-graceful-shutdown-timeout': u'2',
u'plain_http_port': u'11080',
u'port': u'11443',
u'public-ipv4': u'255.255.255.255',
u'ram-cache-size': u'256K',
u're6st-verification-url': u're6st-verification-url',
u'request-timeout': u'100',
u'slave-kedifa-information': u'{}'
},
'caddy-frontend-3': {
'X-software_release_url': self.frontend_3_sr,
u'apache-certificate': unicode(self.certificate_pem),
u'apache-key': unicode(self.key_pem),
u'authenticate-to-backend': u'True',
u'backend-client-caucase-url': backend_client_caucase_url,
u'backend-connect-retries': u'1',
u'backend-connect-timeout': u'2',
u'ciphers': u'ciphers',
u'cluster-identification': u'testing partition 0',
u'domain': u'example.com',
u'enable-http2-by-default': u'True',
u'extra_slave_instance_list': u'[]',
u'frontend-name': u'caddy-frontend-3',
u'global-disable-http2': u'True',
u'kedifa-caucase-url': kedifa_caucase_url,
u'monitor-cors-domains': u'monitor.app.officejs.com',
u'monitor-httpd-port': 8413,
u'monitor-username': u'admin',
u'mpm-graceful-shutdown-timeout': u'2',
u'plain_http_port': u'11080',
u'port': u'11443',
u'public-ipv4': u'255.255.255.255',
u're6st-verification-url': u're6st-verification-url',
u'request-timeout': u'100',
u'slave-kedifa-information': u'{}'
},
'kedifa': {
'X-software_release_url': self.kedifa_sr,
u'caucase_port': u'15090',
u'cluster-identification': u'testing partition 0',
u'kedifa_port': u'15080',
u'monitor-cors-domains': u'monitor.app.officejs.com',
u'monitor-httpd-port': u'8402',
u'monitor-username': u'admin',
u'slave-list': []
},
'testing partition 0': {
'-frontend-2-software-release-url': self.frontend_2_sr,
'-frontend-2-state': 'stopped',
'-frontend-3-software-release-url': self.frontend_3_sr,
'-frontend-3-state': 'stopped',
'-frontend-config-1-ram-cache-size': '512K',
'-frontend-config-2-ram-cache-size': '256K',
'-frontend-quantity': '3',
'-kedifa-software-release-url': self.kedifa_sr,
'-sla-2-computer_guid': 'local',
'-sla-3-computer_guid': 'local',
'X-software_release_url': base_software_url,
'apache-certificate': unicode(self.certificate_pem),
'apache-key': unicode(self.key_pem),
'authenticate-to-backend': 'True',
'automatic-internal-backend-client-caucase-csr': 'False',
'automatic-internal-kedifa-caucase-csr': 'False',
'backend-connect-retries': '1',
'backend-connect-timeout': '2',
'caucase_port': '15090',
'ciphers': 'ciphers',
'domain': 'example.com',
'enable-http2-by-default': 'True',
'full_address_list': [],
'global-disable-http2': 'True',
'instance_title': 'testing partition 0',
'kedifa_port': '15080',
'mpm-graceful-shutdown-timeout': '2',
'plain_http_port': '11080',
'port': '11443',
'public-ipv4': '255.255.255.255',
're6st-verification-url': 're6st-verification-url',
'request-timeout': '100',
'root_instance_title': 'testing partition 0',
'slap_software_type': 'RootSoftwareInstance',
'slave_instance_list': []
}
}
self.assertEqual( self.assertEqual(
requested_partition_information, expected_partition_parameter_dict_dict,
[ partition_parameter_dict_dict
{'software_release': base_software_url,
'partition_reference': 'testing partition 0'},
{'software_release': self.kedifa_sr,
'partition_reference': 'kedifa'},
# that one is base, as expected
{'software_release': base_software_url,
'partition_reference': 'caddy-frontend-1'},
{'software_release': self.frontend_2_sr,
'partition_reference': 'caddy-frontend-2'},
{'software_release': self.frontend_3_sr,
'partition_reference': 'caddy-frontend-3'}]
) )
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