refactor: move cloudflare domain list to dynamic state file
This commit is contained in:
parent
837bafba09
commit
064144134e
3 changed files with 74 additions and 11 deletions
14
README.md
14
README.md
|
|
@ -62,10 +62,18 @@ infra dns add-host "aa:bb:cc:dd:ee:ff" "10.32.70.100" "new-app"
|
|||
infra dns add-dns "api.loopaware.com" "10.32.70.100"
|
||||
```
|
||||
|
||||
### 4. Public Ingress (HAProxy)
|
||||
### 4. Cloudflare DDNS
|
||||
The list of domains to update is managed dynamically on the server.
|
||||
|
||||
```bash
|
||||
# Expose the service to the internet
|
||||
infra ingress add "app.loopaware.com" "10.32.70.100" 80
|
||||
# Add a domain to the update list
|
||||
infra cloudflare add-ddns "my-new-domain.com"
|
||||
|
||||
# List all domains being updated
|
||||
infra cloudflare list-ddns
|
||||
|
||||
# Run the update (usually via cron)
|
||||
infra cloudflare update-ddns
|
||||
```
|
||||
|
||||
## Advanced Workflows for AI Agents
|
||||
|
|
|
|||
|
|
@ -1,16 +1,51 @@
|
|||
import requests
|
||||
import sys
|
||||
import json
|
||||
import os
|
||||
|
||||
class CloudflareManager:
|
||||
def __init__(self, config):
|
||||
self.token = config.get('cloudflare.token')
|
||||
self.ddns_domains = config.get('cloudflare.ddns_domains', [])
|
||||
# Path to store the dynamic list of domains
|
||||
self.state_file = config.get('cloudflare.ddns_state_file', '/etc/haproxy/dynamic/ddns_domains.json')
|
||||
self.api_url = "https://api.cloudflare.com/client/v4"
|
||||
self.headers = {
|
||||
"Authorization": f"Bearer {self.token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
def _load_domains(self):
|
||||
if not os.path.exists(self.state_file):
|
||||
return []
|
||||
try:
|
||||
with open(self.state_file, 'r') as f:
|
||||
return json.load(f)
|
||||
except (json.JSONDecodeError, IOError):
|
||||
return []
|
||||
|
||||
def _save_domains(self, domains):
|
||||
os.makedirs(os.path.dirname(self.state_file), exist_ok=True)
|
||||
with open(self.state_file, 'w') as f:
|
||||
json.dump(list(set(domains)), f, indent=4)
|
||||
|
||||
def add_domain(self, domain):
|
||||
domains = self._load_domains()
|
||||
if domain not in domains:
|
||||
domains.append(domain)
|
||||
self._save_domains(domains)
|
||||
return True
|
||||
return False
|
||||
|
||||
def remove_domain(self, domain):
|
||||
domains = self._load_domains()
|
||||
if domain in domains:
|
||||
domains.remove(domain)
|
||||
self._save_domains(domains)
|
||||
return True
|
||||
return False
|
||||
|
||||
def list_domains(self):
|
||||
return self._load_domains()
|
||||
|
||||
def get_external_ip(self):
|
||||
try:
|
||||
return requests.get("https://checkip.amazonaws.com").text.strip()
|
||||
|
|
@ -30,8 +65,12 @@ class CloudflareManager:
|
|||
if not current_ip:
|
||||
return "Failed to determine current external IP."
|
||||
|
||||
domains = self._load_domains()
|
||||
if not domains:
|
||||
return "No domains configured for DDNS."
|
||||
|
||||
results = []
|
||||
for domain in self.ddns_domains:
|
||||
for domain in domains:
|
||||
zone_id = self.get_zone_id(domain)
|
||||
if not zone_id:
|
||||
results.append(f"[{domain}] Zone not found.")
|
||||
|
|
@ -42,7 +81,6 @@ class CloudflareManager:
|
|||
records = res.json().get('result', [])
|
||||
|
||||
if not records:
|
||||
# Create if missing? For now, just report
|
||||
results.append(f"[{domain}] No A record found to update.")
|
||||
continue
|
||||
|
||||
|
|
@ -67,7 +105,4 @@ class CloudflareManager:
|
|||
else:
|
||||
results.append(f"[{domain}] Update failed: {u_res.text}")
|
||||
|
||||
return "\n".join(results)
|
||||
|
||||
def list_domains(self):
|
||||
return self.ddns_domains
|
||||
return "\n".join(results)
|
||||
|
|
@ -31,6 +31,26 @@ def cf_list_ddns(config):
|
|||
for domain in mgr.list_domains():
|
||||
click.echo(domain)
|
||||
|
||||
@cloudflare.command(name='add-ddns')
|
||||
@click.argument('domain')
|
||||
@click.pass_obj
|
||||
def cf_add_ddns(config, domain):
|
||||
mgr = CloudflareManager(config)
|
||||
if mgr.add_domain(domain):
|
||||
click.echo(f"Added {domain} to DDNS update list")
|
||||
else:
|
||||
click.echo(f"{domain} already in DDNS update list")
|
||||
|
||||
@cloudflare.command(name='remove-ddns')
|
||||
@click.argument('domain')
|
||||
@click.pass_obj
|
||||
def cf_remove_ddns(config, domain):
|
||||
mgr = CloudflareManager(config)
|
||||
if mgr.remove_domain(domain):
|
||||
click.echo(f"Removed {domain} from DDNS update list")
|
||||
else:
|
||||
click.echo(f"{domain} not found in DDNS update list")
|
||||
|
||||
@cloudflare.command(name='update-ddns')
|
||||
@click.option('--force', is_flag=True, help='Force update even if IP matches')
|
||||
@click.pass_obj
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue