From 62bf87115e4ae13ee7d3e234864cecf72b75f1c2 Mon Sep 17 00:00:00 2001
From: Zsolt Ero
Date: Sat, 22 Jun 2024 08:43:55 +0200
Subject: [PATCH] load balancer in fix mode
---
README.md | 8 +++++---
scripts/loadbalancer/cron.d/ofm_loadbalancer | 2 +-
scripts/loadbalancer/loadbalancer.py | 20 +++++++++++++++----
.../loadbalancer_lib/cloudflare.py | 6 ++++--
scripts/loadbalancer/loadbalancer_lib/curl.py | 2 ++
website/src/pages/index.astro | 3 ++-
6 files changed, 30 insertions(+), 11 deletions(-)
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