From ee0dd61793e56a35cd79ffc741ed5bbfe8935018 Mon Sep 17 00:00:00 2001 From: Max Erenberg <> Date: Sat, 11 Dec 2021 13:47:34 -0500 Subject: [PATCH] pre-checkout commit --- ceo/cli/cloud.py | 1 + ceod/model/CloudService.py | 19 +++++++++++++++++-- .../templates/nginx_cloud_vhost_config.j2 | 5 +++-- tests/ceo/cli/test_cloud.py | 5 ++++- tests/ceod_dev.ini | 2 +- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/ceo/cli/cloud.py b/ceo/cli/cloud.py index 0e44922..cae1650 100644 --- a/ceo/cli/cloud.py +++ b/ceo/cli/cloud.py @@ -58,6 +58,7 @@ def add_vhost(domain, ip_address): body = {'ip_address': ip_address} if '/' in domain: raise Abort('invalid domain name') + click.echo('Please wait, this may take a while...') resp = http_put('/api/cloud/vhosts/' + domain, json=body) handle_sync_response(resp) click.echo('Done.') diff --git a/ceod/model/CloudService.py b/ceod/model/CloudService.py index 7a34886..1dc38b6 100644 --- a/ceod/model/CloudService.py +++ b/ceod/model/CloudService.py @@ -211,8 +211,19 @@ class CloudService: else: d = {} now = int(utils.get_current_datetime().timestamp()) - if now - d.get(username, 0) < self.vhost_rate_limit_secs: - raise RateLimitError(f'Please wait {self.vhost_rate_limit_secs} seconds') + if username not in d: + return + time_passed = now - d[username] + if time_passed < self.vhost_rate_limit_secs: + time_remaining = self.vhost_rate_limit_secs - time_passed + raise RateLimitError(f'Please wait {time_remaining} seconds') + + def _update_rate_limit_timestamp(self, username: str): + if os.path.exists(self.vhost_rate_limit_file): + d = json.load(open(self.vhost_rate_limit_file)) + else: + d = {} + now = int(utils.get_current_datetime().timestamp()) d[username] = now json.dump(d, open(self.vhost_rate_limit_file, 'w')) @@ -225,7 +236,11 @@ class CloudService: if not self._is_valid_ip_address(ip_address): raise InvalidIPError() self._check_rate_limit(username) + # Wait for the vhost creation to succeed before updating the timestamp; + # we don't want to force people to wait if they had a typo in their + # domain or something. self.vhost_mgr.create_vhost(username, domain, ip_address) + self._update_rate_limit_timestamp(username) def delete_vhost(self, username: str, domain: str): if not self._is_valid_domain(username, domain): diff --git a/ceod/model/templates/nginx_cloud_vhost_config.j2 b/ceod/model/templates/nginx_cloud_vhost_config.j2 index 678e1ac..f6004e1 100644 --- a/ceod/model/templates/nginx_cloud_vhost_config.j2 +++ b/ceod/model/templates/nginx_cloud_vhost_config.j2 @@ -9,8 +9,8 @@ server { } server { - listen 443 ssl; - listen [::]:443 ssl; + listen 443 ssl http2; + listen [::]:443 ssl http2; server_name {{ domain }}; ssl_certificate {{ ssl_cert_path }}; ssl_certificate_key {{ ssl_key_path }}; @@ -18,6 +18,7 @@ server { location / { proxy_pass http://{{ ip_address }}; } + include proxy_params; access_log /var/log/nginx/member-{{ username }}-access.log; error_log /var/log/nginx/member-{{ username }}-error.log; diff --git a/tests/ceo/cli/test_cloud.py b/tests/ceo/cli/test_cloud.py index 326a85b..73c4fa9 100644 --- a/tests/ceo/cli/test_cloud.py +++ b/tests/ceo/cli/test_cloud.py @@ -37,7 +37,10 @@ def test_cloud_vhosts(cli_setup, new_user, cfg): runner = CliRunner() with gssapi_token_ctx(uid): result = runner.invoke(cli, ['cloud', 'vhosts', 'add', domain1, ip1]) - expected = 'Done.\n' + expected = ( + 'Please wait, this may take a while...\n' + 'Done.\n' + ) assert result.exit_code == 0 assert result.output == expected diff --git a/tests/ceod_dev.ini b/tests/ceod_dev.ini index b1fe1b0..cc6ec63 100644 --- a/tests/ceod_dev.ini +++ b/tests/ceod_dev.ini @@ -80,7 +80,7 @@ vhost_dir = /run/ceod/member-vhosts ssl_dir = /run/ceod/member-ssl default_ssl_cert = /etc/ssl/private/csclub.cloud.chain default_ssl_key = /etc/ssl/private/csclub.cloud.key -rate_limit_seconds = 10 +rate_limit_seconds = 30 max_vhosts_per_account = 10 members_domain = csclub.cloud ip_range_min = 172.19.134.10