diff --git a/README.md b/README.md index 995c5d1..edae890 100644 --- a/README.md +++ b/README.md @@ -101,9 +101,7 @@ A very important part, probably needs the most work in the long term future. #### load balancer script - scripts/loadbalancer -Round Robin DNS based load balancer, script for health checking and updating records. It pushes status messages to a Telegram bot. - -Currently it's running in read-only mode, DNS updates need manual confirmation. +A Round Robin DNS based load balancer script for health checking and updating records. It pushes status messages to a Telegram bot. ## Self hosting @@ -167,6 +165,10 @@ See [dev setup docs](docs/dev_setup.md). ## Changelog +##### v0.2 + +Load-balancing script is running in write mode, updating records when needed. + ##### v0.1 Everything works. 1 server for tile gen, 2 servers for HTTP host. Load-balancing script is running in a read-only mode. diff --git a/scripts/loadbalancer/cron.d/ofm_loadbalancer b/scripts/loadbalancer/cron.d/ofm_loadbalancer index 3adca38..03d2dd6 100644 --- a/scripts/loadbalancer/cron.d/ofm_loadbalancer +++ b/scripts/loadbalancer/cron.d/ofm_loadbalancer @@ -1,4 +1,4 @@ # every minute -* * * * * ofm sudo /data/ofm/venv/bin/python -u /data/ofm/loadbalancer/loadbalancer.py check >> /data/ofm/loadbalancer/logs/check.log 2>&1 +* * * * * ofm sudo /data/ofm/venv/bin/python -u /data/ofm/loadbalancer/loadbalancer.py fix >> /data/ofm/loadbalancer/logs/check.log 2>&1 diff --git a/scripts/loadbalancer/loadbalancer.py b/scripts/loadbalancer/loadbalancer.py index 9d86360..c36ce8e 100755 --- a/scripts/loadbalancer/loadbalancer.py +++ b/scripts/loadbalancer/loadbalancer.py @@ -76,7 +76,15 @@ def check_or_fix(fix=False): if not working_hosts: working_hosts = set(c['http_host_list']) - update_records(c, working_hosts) + message = 'OFM loadbalancer FIX found no working hosts, reverting to full list!' + print(message) + telegram_send_message(message, c['telegram_token'], c['telegram_chat_id']) + + updated = update_records(c, working_hosts) + if updated: + message = f'OFM loadbalancer FIX modified records, new records: {working_hosts}' + print(message) + telegram_send_message(message, c['telegram_token'], c['telegram_chat_id']) def run_area(c, area): @@ -117,14 +125,16 @@ def get_target_version(area): return response.text.strip() -def update_records(c, working_hosts): +def update_records(c, working_hosts) -> bool: config = dotenv_values('/data/ofm/config/cloudflare.ini') cloudflare_api_token = config['dns_cloudflare_api_token'] domain = '.'.join(c['domain_ledns'].split('.')[-2:]) zone_id = get_zone_id(domain, cloudflare_api_token=cloudflare_api_token) - set_records_round_robin( + updated = False + + updated |= set_records_round_robin( zone_id=zone_id, name=c['domain_ledns'], host_ip_set=working_hosts, @@ -134,7 +144,7 @@ def update_records(c, working_hosts): cloudflare_api_token=cloudflare_api_token, ) - set_records_round_robin( + updated |= set_records_round_robin( zone_id=zone_id, name=c['domain_cf'], host_ip_set=working_hosts, @@ -143,6 +153,8 @@ def update_records(c, working_hosts): cloudflare_api_token=cloudflare_api_token, ) + return updated + if __name__ == '__main__': cli() diff --git a/scripts/loadbalancer/loadbalancer_lib/cloudflare.py b/scripts/loadbalancer/loadbalancer_lib/cloudflare.py index b871a07..06c28ad 100644 --- a/scripts/loadbalancer/loadbalancer_lib/cloudflare.py +++ b/scripts/loadbalancer/loadbalancer_lib/cloudflare.py @@ -55,7 +55,7 @@ def set_records_round_robin( proxied: bool, comment: str = None, cloudflare_api_token: str, -): +) -> bool: headers = {'Authorization': f'Bearer {cloudflare_api_token}'} dns_records = get_dns_records_round_robin(zone_id, cloudflare_api_token=cloudflare_api_token) @@ -64,7 +64,7 @@ def set_records_round_robin( current_ips = {r['content'] for r in current_records} if current_ips == host_ip_set: print(f'No need to update records: {name} currently set: {sorted(current_ips)}') - return + return False # changing records @@ -92,6 +92,8 @@ def set_records_round_robin( data = res.json() assert data['success'] is True + return True + def delete_record(zone_id, *, id_: str, cloudflare_api_token: str): headers = {'Authorization': f'Bearer {cloudflare_api_token}'} diff --git a/scripts/loadbalancer/loadbalancer_lib/curl.py b/scripts/loadbalancer/loadbalancer_lib/curl.py index 72242b3..d347710 100644 --- a/scripts/loadbalancer/loadbalancer_lib/curl.py +++ b/scripts/loadbalancer/loadbalancer_lib/curl.py @@ -14,6 +14,7 @@ def pycurl_status(url, domain, host_ip): c.setopt(c.CAINFO, '/etc/ssl/certs/ca-certificates.crt') c.setopt(c.RESOLVE, [f'{domain}:443:{host_ip}']) c.setopt(c.NOBODY, True) + c.setopt(c.TIMEOUT, 5) c.perform() status_code = c.getinfo(c.RESPONSE_CODE) c.close() @@ -33,6 +34,7 @@ def pycurl_get(url, domain, host_ip): c.setopt(c.CAINFO, '/etc/ssl/certs/ca-certificates.crt') c.setopt(c.RESOLVE, [f'{domain}:443:{host_ip}']) c.setopt(c.WRITEDATA, buffer) + c.setopt(c.TIMEOUT, 5) c.perform() status_code = c.getinfo(c.RESPONSE_CODE) c.close() diff --git a/website/src/pages/index.astro b/website/src/pages/index.astro index 4729ffb..5ede9ab 100644 --- a/website/src/pages/index.astro +++ b/website/src/pages/index.astro @@ -23,7 +23,8 @@ import { Content as RestText } from '../content/index/rest.md' Have a look at the default styles and read more about how to integrate it to your website or app here:

-

Quick Start Guide

+ + Quick Start Guide