diff options
9 files changed, 105 insertions, 4 deletions
diff --git a/ansible/module_utils/kolla_docker_worker.py b/ansible/module_utils/kolla_docker_worker.py index f488bab66..db41d5599 100644 --- a/ansible/module_utils/kolla_docker_worker.py +++ b/ansible/module_utils/kolla_docker_worker.py @@ -41,8 +41,8 @@ class DockerWorker(ContainerWorker): def generate_tls(self): tls = {'verify': self.params.get('tls_verify')} - tls_cert = self.params.get('tls_cert'), - tls_key = self.params.get('tls_key'), + tls_cert = self.params.get('tls_cert') + tls_key = self.params.get('tls_key') tls_cacert = self.params.get('tls_cacert') if tls['verify']: diff --git a/ansible/roles/cloudkitty/defaults/main.yml b/ansible/roles/cloudkitty/defaults/main.yml index 0b74f8e27..8cfe7d3a4 100644 --- a/ansible/roles/cloudkitty/defaults/main.yml +++ b/ansible/roles/cloudkitty/defaults/main.yml @@ -16,9 +16,12 @@ cloudkitty_services: external: false port: "{{ cloudkitty_api_port }}" listen_port: "{{ cloudkitty_api_listen_port }}" + frontend_http_extra: + - "timeout client {{ haproxy_cloudkitty_api_client_timeout }}" backend_http_extra: - "option httpchk GET /healthcheck" - "http-check expect status 200" + - "timeout server {{ haproxy_cloudkitty_api_server_timeout }}" cloudkitty_api_external: enabled: "{{ enable_cloudkitty }}" mode: "http" @@ -26,9 +29,12 @@ cloudkitty_services: external_fqdn: "{{ cloudkitty_external_fqdn }}" port: "{{ cloudkitty_api_public_port }}" listen_port: "{{ cloudkitty_api_listen_port }}" + frontend_http_extra: + - "timeout client {{ haproxy_cloudkitty_api_client_timeout }}" backend_http_extra: - "option httpchk GET /healthcheck" - "http-check expect status 200" + - "timeout server {{ haproxy_cloudkitty_api_server_timeout }}" cloudkitty-processor: container_name: "cloudkitty_processor" group: "cloudkitty-processor" @@ -53,6 +59,12 @@ cloudkitty_database_user: "{% if use_preconfigured_databases | bool and use_comm cloudkitty_database_address: "{{ database_address | put_address_in_context('url') }}:{{ database_port }}" #################### +# HAProxy +#################### +haproxy_cloudkitty_api_client_timeout: "1m" +haproxy_cloudkitty_api_server_timeout: "1m" + +#################### # Database sharding #################### cloudkitty_database_shard_root_user: "{% if enable_proxysql | bool %}root_shard_{{ cloudkitty_database_shard_id }}{% else %}{{ database_user }}{% endif %}" diff --git a/ansible/roles/etcd/defaults/main.yml b/ansible/roles/etcd/defaults/main.yml index 563eff9dc..510e8fe2b 100644 --- a/ansible/roles/etcd/defaults/main.yml +++ b/ansible/roles/etcd/defaults/main.yml @@ -92,7 +92,9 @@ etcd_enable_healthchecks: "{{ enable_container_healthchecks }}" etcd_healthcheck_interval: "{{ default_container_healthcheck_interval }}" etcd_healthcheck_retries: "{{ default_container_healthcheck_retries }}" etcd_healthcheck_start_period: "{{ default_container_healthcheck_start_period }}" -etcd_healthcheck_test: ["CMD-SHELL", "healthcheck_curl http://{{ api_interface_address | put_address_in_context('url') }}:{{ etcd_client_port }}/health"] +etcd_healthcheck_test: + - "CMD-SHELL" + - "healthcheck_curl {{ etcd_protocol }}://{{ api_interface_address | put_address_in_context('url') }}:{{ etcd_client_port }}/health" etcd_healthcheck_timeout: "{{ default_container_healthcheck_timeout }}" etcd_healthcheck: interval: "{{ etcd_healthcheck_interval }}" diff --git a/ansible/roles/loadbalancer/templates/proxysql/proxysql.yaml.j2 b/ansible/roles/loadbalancer/templates/proxysql/proxysql.yaml.j2 index f7a8b0a08..549051383 100644 --- a/ansible/roles/loadbalancer/templates/proxysql/proxysql.yaml.j2 +++ b/ansible/roles/loadbalancer/templates/proxysql/proxysql.yaml.j2 @@ -111,6 +111,6 @@ mysql_galera_hostgroups: offline_hostgroup: {{ _offline_group }} max_connections: {{ proxysql_backend_max_connections }} max_writers: 1 - writer_is_also_reader: 0 + writer_is_also_reader: 2 comment: "Galera cluster for shard {{ shard_id }}" {% endfor %} diff --git a/ansible/roles/service-uwsgi-config/defaults/main.yml b/ansible/roles/service-uwsgi-config/defaults/main.yml index 9c5e13ed3..e5a452dc4 100644 --- a/ansible/roles/service-uwsgi-config/defaults/main.yml +++ b/ansible/roles/service-uwsgi-config/defaults/main.yml @@ -7,3 +7,4 @@ service_uwsgi_config_socket_port: "" service_uwsgi_config_tls_backend: false service_uwsgi_config_worker_timeout: 80 service_uwsgi_config_workers: "{{ openstack_service_workers }}" +service_uwsgi_config_env: {} diff --git a/ansible/roles/service-uwsgi-config/templates/uwsgi.ini.j2 b/ansible/roles/service-uwsgi-config/templates/uwsgi.ini.j2 index e8873eefc..1095aa1fc 100644 --- a/ansible/roles/service-uwsgi-config/templates/uwsgi.ini.j2 +++ b/ansible/roles/service-uwsgi-config/templates/uwsgi.ini.j2 @@ -46,3 +46,6 @@ uid = {{ service_uwsgi_config_uid }} {% endif %} worker-reload-mercy = {{ service_uwsgi_config_worker_timeout }} static-map = /static=/var/lib/kolla/venv/lib/python3/site-packages/static +{% for key, value in service_uwsgi_config_env.items() %} +env = {{ key }}={{ value }} +{% endfor %} diff --git a/releasenotes/notes/cloudkitty-haproxy-custom-timeouts-2f5c30619269d2f0.yaml b/releasenotes/notes/cloudkitty-haproxy-custom-timeouts-2f5c30619269d2f0.yaml new file mode 100644 index 000000000..cbab01202 --- /dev/null +++ b/releasenotes/notes/cloudkitty-haproxy-custom-timeouts-2f5c30619269d2f0.yaml @@ -0,0 +1,10 @@ +--- +features: + - | + CloudKitty v1 API does not support pagination, which may require increasing + timeouts for large requests. Adds two HAProxy timeout variables for the + CloudKitty API: ``haproxy_cloudkitty_api_client_timeout`` and + ``haproxy_cloudkitty_api_server_timeout``. These variables are used to + populate HAProxy's ``frontend_http_extra`` and ``backend_http_extra`` for + the ``cloudkitty_api`` and ``cloudkitty_api_external`` listeners. The + defaults are set to one minute. diff --git a/releasenotes/notes/fix-proxysql-distributed-reads-5142e40995499611.yaml b/releasenotes/notes/fix-proxysql-distributed-reads-5142e40995499611.yaml new file mode 100644 index 000000000..1ec90b0fd --- /dev/null +++ b/releasenotes/notes/fix-proxysql-distributed-reads-5142e40995499611.yaml @@ -0,0 +1,13 @@ +--- +fixes: + - | + Fix ProxySQL Galera configuration so that the backup writer + node also serves read queries, instead of leaving it idle + and sending all reads to the single remaining reader node. + This is done by setting ``writer_is_also_reader`` to ``2``, + which adds backup writer hostgroup nodes to the reader + hostgroup while still excluding the active writer node. See + the `ProxySQL documentation + <https://proxysql.com/documentation/group-replication-configuration/>`__ + for details. + `LP#2167037 <https://launchpad.net/bugs/2167037>`__ diff --git a/tests/kolla_container_tests/test_docker_worker.py b/tests/kolla_container_tests/test_docker_worker.py index e32da66cb..90f1a2d41 100644 --- a/tests/kolla_container_tests/test_docker_worker.py +++ b/tests/kolla_container_tests/test_docker_worker.py @@ -1161,6 +1161,66 @@ class TestVolume(base.BaseTestCase): ) +class TestTLS(base.BaseTestCase): + + @mock.patch('docker.tls.TLSConfig') + def test_tls_disabled_by_default(self, mock_tls_config): + self.dw = get_DockerWorker({'name': 'test_container'}) + self.dw.generate_tls() + mock_tls_config.assert_called_once_with(verify=None) + + @mock.patch('docker.tls.TLSConfig') + def test_tls_verify_enabled_no_certs(self, mock_tls_config): + self.dw = get_DockerWorker({ + 'name': 'test_container', + 'tls_verify': True}) + self.dw.generate_tls() + mock_tls_config.assert_called_once_with(verify=True) + + @mock.patch('os.path.isfile', return_value=True) + @mock.patch('os.access', return_value=True) + @mock.patch('docker.tls.TLSConfig') + def test_tls_verify_with_client_cert_and_key(self, mock_tls_config, + mock_access, mock_isfile): + self.dw = get_DockerWorker({ + 'name': 'test_container', + 'tls_verify': True, + 'tls_cert': '/path/to/cert.pem', + 'tls_key': '/path/to/key.pem'}) + self.dw.generate_tls() + mock_tls_config.assert_called_once_with( + verify=True, + client_cert=('/path/to/cert.pem', '/path/to/key.pem')) + + @mock.patch('os.path.isfile', return_value=True) + @mock.patch('os.access', return_value=True) + @mock.patch('docker.tls.TLSConfig') + def test_tls_verify_with_cacert(self, mock_tls_config, + mock_access, mock_isfile): + self.dw = get_DockerWorker({ + 'name': 'test_container', + 'tls_verify': True, + 'tls_cacert': '/path/to/ca.pem'}) + self.dw.generate_tls() + mock_tls_config.assert_called_once_with( + verify='/path/to/ca.pem') + + @mock.patch('os.path.isfile', return_value=False) + @mock.patch('os.access', return_value=True) + @mock.patch('docker.tls.TLSConfig') + def test_tls_verify_cert_file_missing_fails(self, mock_tls_config, + mock_access, mock_isfile): + self.dw = get_DockerWorker({ + 'name': 'test_container', + 'tls_verify': True, + 'tls_cert': '/missing/cert.pem', + 'tls_key': '/missing/key.pem'}) + self.dw.generate_tls() + self.dw.module.fail_json.assert_any_call( + failed=True, + msg='There is no file at "/missing/cert.pem"') + + class TestAttrComp(base.BaseTestCase): def setUp(self): |
