fix: the name server is the primary of any number of domains, each with secondary name servers and a switch for the records of the sites.
Release / release (push) Successful in 13s
Release / release (push) Successful in 13s
This commit is contained in:
1 parent
57e8bbcffe
commit
1697e1aa38
9 files changed
+412
-150
No files matched your search
@@ -52,8 +52,8 @@ Pages:
|
||||
/sites the web sites Caddy serves: the settings of sites, list, add, change and remove (see sites()),
|
||||
and the files of each: list, download, upload, extract a zip archive, create a folder, rename and
|
||||
remove (see Handler.site_files()); a member of a site's editors group may use the site's files
|
||||
/dns the name server of dns.zone: its settings, the records it serves, and the manual records: add and
|
||||
remove (see dns())
|
||||
/dns the primary name server of the router's domains: its settings, and the domains: add, change and
|
||||
remove, each with its secondaries, the records it serves, and its manual records (see dns())
|
||||
/postgresql
|
||||
the databases of each PostgreSQL cluster on the router with their sizes, as JSON (see
|
||||
postgresql_databases()); /config has the clusters' settings
|
||||
@@ -1264,44 +1264,69 @@ def site_file_action(name, target, body):
|
||||
def dns(method, path, query, body):
|
||||
"""Answer a /dns request with vpnrouter_dns: the HTTP status and the JSON document.
|
||||
|
||||
GET /dns {"settings", "installed", "running", "records", "manual", "problem"}: the dns section of the
|
||||
configuration, whether PowerDNS is installed and runs, the records the name server serves,
|
||||
the manual records, and why the records cannot be read, null when they can
|
||||
GET /dns {"settings", "installed", "running", "domains", "problem"}: the dns section of the
|
||||
configuration, whether PowerDNS is installed and runs, the domains, each {"name", "sites",
|
||||
"ttl", "secondaries", "manual", "records"} with its secondaries {"nameserver", "address"},
|
||||
its manual records and the records the name server serves, and why the domains cannot be
|
||||
read, null when they can
|
||||
PUT /dns change any of the settings of the dns section
|
||||
POST /dns/records add a manual record: {"name", "type", "content", "ttl"?}; name is relative to dns.zone, @
|
||||
for the zone itself, or absolute with a final dot; ttl is dns.ttl without it
|
||||
DELETE /dns/records remove the manual records of name= and type=, with content= only that one
|
||||
POST /dns/domains add a domain: {"name", "sites"?, "ttl"?}; sites gives the host names of the enabled sites
|
||||
in it records; ttl is dns.ttl when null or absent; an existing name is 409
|
||||
PUT /dns/domains/<domain>
|
||||
change "sites" or "ttl" of the domain
|
||||
DELETE /dns/domains/<domain>
|
||||
remove the domain with its secondaries and manual records
|
||||
POST /dns/domains/<domain>/secondaries
|
||||
add a secondary name server of the domain, or change its address: {"nameserver", "address"}
|
||||
DELETE /dns/domains/<domain>/secondaries/<nameserver>
|
||||
remove the secondary name server
|
||||
POST /dns/domains/<domain>/records
|
||||
add a manual record: {"name", "type", "content", "ttl"?}; name is relative to the domain,
|
||||
@ for the domain itself, or absolute with a final dot; ttl is the domain's without it
|
||||
DELETE /dns/domains/<domain>/records
|
||||
remove the manual records of name= and type=, with content= only that one
|
||||
|
||||
A change is applied by restarting vpn-router-setup without waiting for it.
|
||||
"""
|
||||
if body == 'invalid' or (body is not None and not isinstance(body, dict)):
|
||||
return 400, {'error': 'the body must be a JSON object'}
|
||||
body = body or {}
|
||||
parts = path.strip('/').split('/')
|
||||
route = (method, *parts[:2], *parts[3:4])
|
||||
try:
|
||||
cfg = vpnrouter.load_config()
|
||||
if (method, path) == ('GET', '/dns'):
|
||||
served, manual, problem = [], [], None
|
||||
if route == ('GET', 'dns'):
|
||||
domains, problem = [], None
|
||||
try:
|
||||
manual = vpnrouter_dns.manual()
|
||||
served = vpnrouter_dns.served(cfg['dns']['zone'].strip())
|
||||
domains = vpnrouter_dns.listing()
|
||||
except vpnrouter_dns.DatabaseError as exc:
|
||||
problem = str(exc)
|
||||
return 200, {'settings': cfg['dns'], 'installed': vpnrouter_dns.PDNS_SERVER.exists(),
|
||||
'running': unit_state(vpnrouter_dns.UNIT) == 'active', 'records': served, 'manual': manual,
|
||||
'running': unit_state(vpnrouter_dns.UNIT) == 'active', 'domains': domains,
|
||||
'problem': problem}
|
||||
if (method, path) == ('PUT', '/dns'):
|
||||
if route == ('PUT', 'dns'):
|
||||
changed = section_change('dns', body)
|
||||
return changed if isinstance(changed, tuple) else (200, {'settings': changed})
|
||||
if (method, path) == ('POST', '/dns/records'):
|
||||
document, code = vpnrouter_dns.add(cfg, body), 201
|
||||
elif (method, path) == ('DELETE', '/dns/records'):
|
||||
if route == ('POST', 'dns', 'domains') and len(parts) == 2:
|
||||
document, code = vpnrouter_dns.domain_add(body), 201
|
||||
elif route == ('PUT', 'dns', 'domains') and len(parts) == 3:
|
||||
document, code = vpnrouter_dns.domain_change(parts[2], body), 200
|
||||
elif route == ('DELETE', 'dns', 'domains') and len(parts) == 3:
|
||||
document, code = vpnrouter_dns.domain_remove(parts[2]), 200
|
||||
elif route == ('POST', 'dns', 'domains', 'secondaries') and len(parts) == 4:
|
||||
document, code = vpnrouter_dns.secondary_add(parts[2], body), 201
|
||||
elif route == ('DELETE', 'dns', 'domains', 'secondaries') and len(parts) == 5:
|
||||
document, code = vpnrouter_dns.secondary_remove(parts[2], parts[4]), 200
|
||||
elif route == ('POST', 'dns', 'domains', 'records') and len(parts) == 4:
|
||||
document, code = vpnrouter_dns.add(cfg, parts[2], body), 201
|
||||
elif route == ('DELETE', 'dns', 'domains', 'records') and len(parts) == 4:
|
||||
content = query.get('content', [None])[0]
|
||||
document = vpnrouter_dns.remove(cfg, query.get('name', [''])[0], query.get('type', [''])[0], content)
|
||||
document = vpnrouter_dns.remove(parts[2], query.get('name', [''])[0], query.get('type', [''])[0], content)
|
||||
code = 200
|
||||
else:
|
||||
return 404, {'error': f'no route {method} {path}'}
|
||||
except vpnrouter_dns.Failure as failure:
|
||||
return (404 if failure.status == 3 else 400), {'error': str(failure)}
|
||||
return {3: 404, 4: 409}.get(failure.status, 400), {'error': str(failure)}
|
||||
except vpnrouter_dns.DatabaseError as exc:
|
||||
return 500, {'error': str(exc)}
|
||||
except SystemExit as exc:
|
||||
|
||||
Reference in new issue
Block a user