milestone 20: declarative configuration for iac
This commit is contained in:
+99
-1
@@ -29,6 +29,15 @@ info:
|
||||
- Mutations to groups, blocklists, rules, local records, forward zones,
|
||||
clients and client prefixes take effect live. Upstreams and
|
||||
`/api/settings` are restart-required.
|
||||
- nxdns runs under one of two configuration authorities. Started with
|
||||
`--config=<file>`, that file is the sole declarative source, and every
|
||||
operation that writes configuration answers 403 with the same error
|
||||
envelope, naming the file. Operations that change runtime state —
|
||||
`/api/pause`, `POST /api/blocklists/update`, `/api/certs/reload`, the
|
||||
login and the logout — stay live, as does `DELETE /api/clients/{id}`
|
||||
for a client the file does not declare. `GET /api/settings` reports
|
||||
the live authority, so a client reads the mode rather than
|
||||
discovering it from a rejection.
|
||||
|
||||
servers:
|
||||
- url: /
|
||||
@@ -391,6 +400,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"409":
|
||||
$ref: "#/components/responses/Conflict"
|
||||
"413":
|
||||
@@ -444,6 +455,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -466,6 +479,8 @@ paths:
|
||||
description: Deleted; applied live.
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -519,6 +534,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -575,6 +592,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"409":
|
||||
$ref: "#/components/responses/Conflict"
|
||||
"413":
|
||||
@@ -655,6 +674,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -674,6 +695,8 @@ paths:
|
||||
description: Deleted; applied live.
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -728,6 +751,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"409":
|
||||
$ref: "#/components/responses/Conflict"
|
||||
"413":
|
||||
@@ -780,6 +805,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -799,6 +826,8 @@ paths:
|
||||
description: Deleted; applied live.
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -853,6 +882,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"409":
|
||||
$ref: "#/components/responses/Conflict"
|
||||
"413":
|
||||
@@ -905,6 +936,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -924,6 +957,8 @@ paths:
|
||||
description: Deleted; applied live.
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -978,6 +1013,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"409":
|
||||
$ref: "#/components/responses/Conflict"
|
||||
"413":
|
||||
@@ -1030,6 +1067,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -1049,6 +1088,8 @@ paths:
|
||||
description: Deleted; applied live.
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -1133,6 +1174,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -1222,6 +1265,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"409":
|
||||
$ref: "#/components/responses/Conflict"
|
||||
"413":
|
||||
@@ -1277,6 +1322,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"409":
|
||||
$ref: "#/components/responses/Conflict"
|
||||
"413":
|
||||
@@ -1330,6 +1377,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -1350,6 +1399,8 @@ paths:
|
||||
description: Deleted; takes effect on restart.
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"404":
|
||||
$ref: "#/components/responses/NotFound"
|
||||
"409":
|
||||
@@ -1454,6 +1505,8 @@ paths:
|
||||
$ref: "#/components/responses/BadRequest"
|
||||
"401":
|
||||
$ref: "#/components/responses/Unauthorized"
|
||||
"403":
|
||||
$ref: "#/components/responses/ManagedByFile"
|
||||
"413":
|
||||
$ref: "#/components/responses/BodyTooLarge"
|
||||
"429":
|
||||
@@ -1526,6 +1579,16 @@ components:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
ManagedByFile:
|
||||
description: |
|
||||
nxdns is running under file authority and this operation writes
|
||||
configuration. The message names the file. Authentication is checked
|
||||
first, so an unauthenticated request to a protected route still
|
||||
answers 401 rather than disclosing that the route exists.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
NotFound:
|
||||
description: No row has this id.
|
||||
content:
|
||||
@@ -2193,7 +2256,7 @@ components:
|
||||
|
||||
SettingsEnvelope:
|
||||
type: object
|
||||
required: [settings, restart_required]
|
||||
required: [settings, restart_required, authority]
|
||||
properties:
|
||||
settings:
|
||||
$ref: "#/components/schemas/Settings"
|
||||
@@ -2203,6 +2266,41 @@ components:
|
||||
description: |
|
||||
Every `section.field` key that needs a restart to take effect —
|
||||
currently all of them.
|
||||
authority:
|
||||
$ref: "#/components/schemas/Authority"
|
||||
|
||||
Authority:
|
||||
type: object
|
||||
description: |
|
||||
Which source governs this process's configuration. This is how a
|
||||
client learns that configuration is read-only; it never has to probe
|
||||
a write route for a 403. The block rides this authenticated endpoint
|
||||
because `path` is a filesystem path, and never appears on the open
|
||||
`/api/version` or `/api/health`.
|
||||
required: [mode, path, reconciled_at]
|
||||
properties:
|
||||
mode:
|
||||
type: string
|
||||
enum: [database, managed_file]
|
||||
description: |
|
||||
`database` when nxdns runs without `--config`; `managed_file`
|
||||
when it runs with it, in which case every configuration write
|
||||
answers 403.
|
||||
path:
|
||||
type: string
|
||||
nullable: true
|
||||
description: The managed file, or null in `database` mode.
|
||||
reconciled_at:
|
||||
type: integer
|
||||
nullable: true
|
||||
description: |
|
||||
When this process loaded the managed file, in epoch seconds, and
|
||||
null in `database` mode. It means exactly that: a file whose
|
||||
mtime is newer has not been loaded by the running process. It
|
||||
cannot answer whether the file matches what the server serves —
|
||||
a stepped clock or a preserved mtime defeats the comparison
|
||||
either way, and `nxdns import` can move the database without
|
||||
moving either timestamp.
|
||||
|
||||
SettingsPatch:
|
||||
type: object
|
||||
|
||||
Reference in New Issue
Block a user