mirror of
https://github.com/hyperknot/openfreemap.git
synced 2026-05-21 14:02:15 +00:00
load balancer in fix mode
This commit is contained in:
@@ -101,9 +101,7 @@ A very important part, probably needs the most work in the long term future.
|
|||||||
|
|
||||||
#### load balancer script - scripts/loadbalancer
|
#### 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.
|
A 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.
|
|
||||||
|
|
||||||
## Self hosting
|
## Self hosting
|
||||||
|
|
||||||
@@ -167,6 +165,10 @@ See [dev setup docs](docs/dev_setup.md).
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
##### v0.2
|
||||||
|
|
||||||
|
Load-balancing script is running in write mode, updating records when needed.
|
||||||
|
|
||||||
##### v0.1
|
##### v0.1
|
||||||
|
|
||||||
Everything works. 1 server for tile gen, 2 servers for HTTP host. Load-balancing script is running in a read-only mode.
|
Everything works. 1 server for tile gen, 2 servers for HTTP host. Load-balancing script is running in a read-only mode.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# every minute
|
# 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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,15 @@ def check_or_fix(fix=False):
|
|||||||
if not working_hosts:
|
if not working_hosts:
|
||||||
working_hosts = set(c['http_host_list'])
|
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):
|
def run_area(c, area):
|
||||||
@@ -117,14 +125,16 @@ def get_target_version(area):
|
|||||||
return response.text.strip()
|
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')
|
config = dotenv_values('/data/ofm/config/cloudflare.ini')
|
||||||
cloudflare_api_token = config['dns_cloudflare_api_token']
|
cloudflare_api_token = config['dns_cloudflare_api_token']
|
||||||
|
|
||||||
domain = '.'.join(c['domain_ledns'].split('.')[-2:])
|
domain = '.'.join(c['domain_ledns'].split('.')[-2:])
|
||||||
zone_id = get_zone_id(domain, cloudflare_api_token=cloudflare_api_token)
|
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,
|
zone_id=zone_id,
|
||||||
name=c['domain_ledns'],
|
name=c['domain_ledns'],
|
||||||
host_ip_set=working_hosts,
|
host_ip_set=working_hosts,
|
||||||
@@ -134,7 +144,7 @@ def update_records(c, working_hosts):
|
|||||||
cloudflare_api_token=cloudflare_api_token,
|
cloudflare_api_token=cloudflare_api_token,
|
||||||
)
|
)
|
||||||
|
|
||||||
set_records_round_robin(
|
updated |= set_records_round_robin(
|
||||||
zone_id=zone_id,
|
zone_id=zone_id,
|
||||||
name=c['domain_cf'],
|
name=c['domain_cf'],
|
||||||
host_ip_set=working_hosts,
|
host_ip_set=working_hosts,
|
||||||
@@ -143,6 +153,8 @@ def update_records(c, working_hosts):
|
|||||||
cloudflare_api_token=cloudflare_api_token,
|
cloudflare_api_token=cloudflare_api_token,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return updated
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
cli()
|
cli()
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ def set_records_round_robin(
|
|||||||
proxied: bool,
|
proxied: bool,
|
||||||
comment: str = None,
|
comment: str = None,
|
||||||
cloudflare_api_token: str,
|
cloudflare_api_token: str,
|
||||||
):
|
) -> bool:
|
||||||
headers = {'Authorization': f'Bearer {cloudflare_api_token}'}
|
headers = {'Authorization': f'Bearer {cloudflare_api_token}'}
|
||||||
|
|
||||||
dns_records = get_dns_records_round_robin(zone_id, cloudflare_api_token=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}
|
current_ips = {r['content'] for r in current_records}
|
||||||
if current_ips == host_ip_set:
|
if current_ips == host_ip_set:
|
||||||
print(f'No need to update records: {name} currently set: {sorted(current_ips)}')
|
print(f'No need to update records: {name} currently set: {sorted(current_ips)}')
|
||||||
return
|
return False
|
||||||
|
|
||||||
# changing records
|
# changing records
|
||||||
|
|
||||||
@@ -92,6 +92,8 @@ def set_records_round_robin(
|
|||||||
data = res.json()
|
data = res.json()
|
||||||
assert data['success'] is True
|
assert data['success'] is True
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def delete_record(zone_id, *, id_: str, cloudflare_api_token: str):
|
def delete_record(zone_id, *, id_: str, cloudflare_api_token: str):
|
||||||
headers = {'Authorization': f'Bearer {cloudflare_api_token}'}
|
headers = {'Authorization': f'Bearer {cloudflare_api_token}'}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ def pycurl_status(url, domain, host_ip):
|
|||||||
c.setopt(c.CAINFO, '/etc/ssl/certs/ca-certificates.crt')
|
c.setopt(c.CAINFO, '/etc/ssl/certs/ca-certificates.crt')
|
||||||
c.setopt(c.RESOLVE, [f'{domain}:443:{host_ip}'])
|
c.setopt(c.RESOLVE, [f'{domain}:443:{host_ip}'])
|
||||||
c.setopt(c.NOBODY, True)
|
c.setopt(c.NOBODY, True)
|
||||||
|
c.setopt(c.TIMEOUT, 5)
|
||||||
c.perform()
|
c.perform()
|
||||||
status_code = c.getinfo(c.RESPONSE_CODE)
|
status_code = c.getinfo(c.RESPONSE_CODE)
|
||||||
c.close()
|
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.CAINFO, '/etc/ssl/certs/ca-certificates.crt')
|
||||||
c.setopt(c.RESOLVE, [f'{domain}:443:{host_ip}'])
|
c.setopt(c.RESOLVE, [f'{domain}:443:{host_ip}'])
|
||||||
c.setopt(c.WRITEDATA, buffer)
|
c.setopt(c.WRITEDATA, buffer)
|
||||||
|
c.setopt(c.TIMEOUT, 5)
|
||||||
c.perform()
|
c.perform()
|
||||||
status_code = c.getinfo(c.RESPONSE_CODE)
|
status_code = c.getinfo(c.RESPONSE_CODE)
|
||||||
c.close()
|
c.close()
|
||||||
|
|||||||
@@ -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
|
Have a look at the default styles and read more about how to integrate it to your website or
|
||||||
app here:
|
app here:
|
||||||
</p>
|
</p>
|
||||||
<p style="margin: 20px auto;"><a href="/quick_start">Quick Start Guide</a></p>
|
|
||||||
|
<a class="quick-start-button" href="/quick_start">Quick Start Guide</a>
|
||||||
|
|
||||||
<Donate />
|
<Donate />
|
||||||
<RestText />
|
<RestText />
|
||||||
|
|||||||
Reference in New Issue
Block a user