From: Christian Hofstaedtler Date: Mon, 25 Aug 2014 16:33:00 +0000 (-0700) Subject: Import HTTP API docs X-Git-Tag: auth-3.4.0-rc2~34^2~3^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5a425f81d069f1b5eaa3bd2fd9a67c09c1c24101;p=pdns Import HTTP API docs --- diff --git a/pdns/docs/httpapi/README.md b/pdns/docs/httpapi/README.md new file mode 100644 index 000000000..4546e2b2c --- /dev/null +++ b/pdns/docs/httpapi/README.md @@ -0,0 +1,70 @@ +PowerDNS API +============ + +PowerDNS features a built-in API. For the Authoritative Server, starting with +version 3.4, for the Recursor starting with version 3.6. + +At the time of writing this, these versions were not released, but preliminary +support is available in git. + +You can get suitable packages for testing (RPM or DEB) from these links: + + * https://autotest.powerdns.com/job/auth-git-semistatic-deb-amd64/lastSuccessfulBuild/artifact/ + * https://autotest.powerdns.com/job/auth-git-semistatic-rpm-amd64/lastSuccessfulBuild/artifact/ + * https://autotest.powerdns.com/job/recursor-git-semistatic-pkgs-amd64/lastSuccessfulBuild/artifact/ + + +Try it +------ + +Install PowerDNS Authoritative with one of the gsql backends (i.e. MySQL, +PostgreSQL or SQLite3). + +Then configure as follows: + + experimental-json-interface=yes + webserver=yes + webserver-password=changeme + + +After restarting `pdns_server`, the following examples should start working: + + # List zones + curl -v http://a:changeme@127.0.0.1:8081/servers/localhost/zones | jq . + # Create new zone "example.org" with nameservers ns1.example.org, ns2.example.org + curl -X POST --data '{"name":"example.org", "kind": "Native", "masters": [], "nameservers": ["ns1.example.org", "ns2.example.org"]}' -v http://a:changeme@127.0.0.1:8081/servers/localhost/zones | jq . + # Show the new zone + curl -v http://a:changeme@127.0.0.1:8081/servers/localhost/zones/example.org | jq . + +`jq` is a highly recommended tool for pretty-printing JSON. If you don't have +`jq`, try `json_pp` or `python -mjson.tool` instead. + + +Try it (Recursor edition) +------------------------- + +Install PowerDNS Recursor, configured as follows: + + experimental-webserver=yes + experimental-webserver-password=changeme + auth-zones= + forward-zones= + forward-zones-recurse= + + +After restarting `pdns_recursor`, the following examples should start working: + + curl -v http://a:changeme@127.0.0.1:8082/servers/localhost | jq . + curl -v http://a:changeme@127.0.0.1:8082/servers/localhost/zones | jq . + + +API Specification +----------------- + +The complete API docs are available in `api_specs.md`. + + +Additional help +--------------- + +For additional help, come to the `#powerdns` IRC channel on `irc.oftc.net`. diff --git a/pdns/docs/httpapi/api_spec.md b/pdns/docs/httpapi/api_spec.md new file mode 100644 index 000000000..75e150ebc --- /dev/null +++ b/pdns/docs/httpapi/api_spec.md @@ -0,0 +1,855 @@ +API Spec +======== + +This API runs over HTTP, preferably HTTPS. + +Design Goals +------------ + +* Discovery endpoint +* Unified API Scheme for Daemons & Console. + Think of the Console Server as a proxy for all your pdns deployments. +* Have API docs (this!) for other consumers + +Data format +----------- + +Input data format: JSON. + +Output data formats: JSON, JSONP + +All GET requests support appending a `_callback` URL parameter, which, if +present, will turn the response into a JSONP response. + +The `Accept:` header determines the output format. An unknown value or +`*/*` will cause a `400 Bad Request`. + +All text is UTF-8 and HTTP headers will reflect this. + +Data types: + + * empty fields: `null` but present + * Regex: implementation defined + * Dates: ISO 8601 + + +REST +---- + +* GET: List/Retrieve. Success reply: `200 OK` +* POST: Create. Success reply: `201 Created`, with new object as body. +* PUT: Update. Success reply: `200 OK`, with modified object as body. +* DELETE: Delete. Success reply: `200 OK`, no body. + +not-so-REST +----------- + +For interactions that do not directly map onto CRUD, we use these: + +* GET: Query. Success reply: `200 OK` +* PUT: Action/Execute. Success reply: `200 OK` + + +Authentication +-------------- + +Clients SHOULD support: + +* HTTP Basic Auth (used by pdns, pdnsmgrd) +* OAuth (used by pdnscontrol) + * **TODO**: Not implemented yet. + +Errors +------ + +Response code `4xx` or `5xx`, depending on the situation. Never return `2xx` +for an error! + +* Invalid JSON body from client: `400 Bad Request` +* JSON body from client not a hash: `400 Bad Request` +* Input validation failed: `422 Unprocessable Entity` + +Error responses have a JSON body of this format: + + { + "error": "short error message", + "errors": [ + { ... }, + ] + } + +Where `errors` is optional, and the contents are error-specific. + + +URL: / +------ + +Allowed methods: `GET` + + { + "server_url": "/servers{/server}", + "api_features": [], + } + +**TODO**: + +* Not yet implemented. +* `api_features` + * `servers_modifiable` + * `oauth` + + +General Collections Interface +============================= + +Collections generally support `GET` and `POST` with these meanings: + +GET +--- + +Retrieve a list of all entries. + +The special `type` and `url` fields are included in the response objects: + + * `type`: name of the resource type + * `url`: url to the object + + +Response format: + + [ + obj1 + [, further objs] + ] + +Example: + + [ + { + "type": "AType", + "id": "anid", + "url": "/atype/anid", + "a_field": "a_value" + }, + { + "type": "AType", + "id": "anotherid", + "url": "/atype/anotherid", + "a_field": "another_value" + } + ] + + +POST +---- + +Create a new entry. The client has to supply the entry in the request body, +in JSON format. `application/x-www-form-urlencoded` data MUST NOT be sent. + +Clients SHOULD not send the 'url' field. + +Client body: + + obj1 + +Example: + + { + "type": "AType", + "id": "anewid", + "a_field": "anew_value" + } + + + + +Servers +======= + +**TODO**: further routes + + +server_resource +--------------- + +Example with server `"localhost"`, which is the only server returned by pdns. + +pdnsmgrd and pdnscontrol MUST NOT return “localhost”, but SHOULD return +other servers. + + { + "type": "Server", + "id": "localhost", + "url": "/servers/localhost", + "daemon_type": "recursor", + "version": "VERSION", + "config_url": "/servers/localhost/config{/config_setting}", + "zones_url": "/servers/localhost/zones{/zone}", + } + +Note: On a pdns server, the servers collection is read-only, and the only +allowed returned server is read-only as well. +On a pdnscontrol server, the servers collection is read-write, and the +returned server resources are read-write as well. Write permissions may +depend on the credentials you have supplied. + +* daemon_type + May be one of `authoritative`, `recursor`. + + +URL: /servers +------------- + +Collection access. + +Allowed REST methods: + +* pdns: `GET` +* pdnsmgrd: `GET` +* pdnscontrol: `GET`, `PUT`, `POST`, `DELETE` + + +URL: /servers/:server\_id +------------------------- + +Returns a single server_resource. + + + +Config +====== + + +config\_setting\_resource +------------------------- + + { + "type": "ConfigSetting", + "name": "config_setting_name", + "value": "config_setting_value" + } + + +URL: /servers/:server\_id/config +-------------------------------- + +Collection access. + +Allowed REST methods: `GET`, `POST` + +#### POST + +Creates a new config setting. This is useful for creating configuration for new backends. + +**TODO**: Not yet implemented. + + +URL: /servers/:server\_id/config/:config\_setting\_name +------------------------------------------------------- + +Allowed REST methods: `GET`, `PUT` + +**NOTE**: only the Recursors `allow_from` configuration setting can be retrieved or modified. + + +Zones +===== + +Authoritative DNS Zones. + +A Resource Record Set (below as "RRset") are all records for a given name and type. + +Comments are per-RRset. + + +zone_collection +--------------- + + { + "id": "", + "name": "", + "type": "Zone", + "url": "/servers/:server_id/zones/:id", + "kind": "", + "serial": , + "notified_serial": , + "masters": ["", ...], + "dnssec": , + "nsec3param": "", + "nsec3narrow": , + "presigned": , + "soa_edit": "", + "soa_edit_api": "", + "nameservers": ["", ...], + "servers": ["", ...], + "recursion_desired": , + "records": [, ...], + "comments": [, ...], + } + + +##### Parameters: + +* `id` + Opaque zone id (string), assigned by the Server. Do not interpret. + Guaranteed to be safe for embedding in URLs. + +* `kind` + Authoritative: ``: `Native`, `Master` or `Slave` + Recursor: ``: `Native`, or `Forwarded` + +* `dnssec` + inferred from `presigned` being `true` XOR presence of at + least one cryptokey with `active` being `true`. + + Switching `dnssec` to `true` (from `false`) sets up DNSSEC signing + based on the other flags, this includes running the equivalent of + `secure-zone` and `rectify-zone`. This also applies to newly created + zones. + If `presigned` is `true`, no DNSSEC changes will be made to the zone + or cryptokeys. + **Note**: Authoritative only. + + **TODO**: `dnssec`, `nsec3narrow`, `nsec3param`, `presigned` are not yet implemented. + +* `soa_edit` MAY be set to change the `SOA-EDIT` zone setting. See + http://doc.powerdns.com/html/domainmetadata.html for more information. + **Note**: Authoritative only. + +* `soa_edit_api` MAY be set. If it is set, on changes to the contents of + a zone made through the API, the SOA record will be edited according to + the SOA-EDIT-API rules. (Which are the same as the SOA-EDIT rules.) + **Note**: Authoritative only. + +* `notified_serial`, `serial` MUST NOT be sent in client bodies. + **Note**: Authoritative only. + +* `nameservers` MAY be sent in client bodies during creation, and MUST + NOT be sent by the server. Simple list of strings of nameserver names. + **Note**: Authoritative only. Not required for slave zones. + +* `servers`: list of forwarded-to servers, including port. + **Note**: Recursor only. + +* `recursion_desired`: for `Forwarded` zones, if the RD bit should + be set. + **Note**: Authoritative only. + +* `records`: list of DNS records in the zone. + **Note**: Modifications are supported on Authoritative only. + +* `comments`: list of comments in the zone. + **Note**: Authoritative only. + +##### Notes: + +Turning on DNSSEC with custom keys: just create the zone with `dnssec` +set to `false`, and add keys using the cryptokeys REST interface. Have +at least one of them `active` set to `true`. + +Changes made through the Zones API will always yield valid zone data, +and the zone will be properly "rectified". If changes are made through +other means (e.g. direct database access), this is not guranteed to be +true and clients SHOULD trigger rectify. + +Backends might implement additional features (by coincidence or not). +These things are not supported through the API. + +When creating a slave zone, it is recommended to not set any of +`nameservers`, `records`. + + +URL: /servers/:server\_id/zones +------------------------------- + +Allowed REST methods: `GET`, `POST` + +#### POST +Creates a new domain. + +* `dnssec`, `nsec3narrow`, `presigned`, `nsec3param`, `active-keys` are OPTIONAL. +* `dnssec`, `nsec3narrow`, `presigned` default to `false`. +* The server MUST create a SOA record. The created SOA record SHOULD have +serial set to the value given as `serial` (or 0 if missing), use the +nameserver name, email, TTL values as specified in the pdns configuration +(`default-soa-name`, `default-soa-mail`, etc). +These default values can be overridden by supplying a custom SOA record in +the records list. +If `soa_edit_api` is set, the SOA record is edited according to the SOA-EDIT-API +rules before storing it. (Also applies to custom SOA records.) + +**TODO**: `dnssec`, `nsec3narrow`, `nsec3param`, `presigned` are not yet implemented. + +URL: /servers/:server\_id/zones/:zone\_id +----------------------------------------- + +Allowed methods: `GET`, `PUT`, `DELETE`, `PATCH`. + +#### GET +Returns zone information. + +#### DELETE +Deletes this zone, all attached metadata and rrsets. + +#### PATCH + +Modifies present RRsets and comments. + +**Note**: Authoritative only. + +Client body for PATCH: + + { "rrsets": + [ + { + "name": , + "type": , + "changetype": , + "records": + [ + { + "content": , + "name": , + "priority": , + "ttl": , + "type": , + "disabled": + }, ... + ], + "comments": + [ + { + "account": , + "content": , + "modfied_at": + }, ... + ] + }, + { ... } + ] + } + +Having `type` inside an RR differ from `type` at the top level is an error. + +* `name` + Full name of the RRset to modify. (Example: `foo.example.org`) + +* `type` + Type of the RRset to modify. (Example: `AAAA`) + +* `changetype` + Must be `REPLACE` or `DELETE`. + With `DELETE`, all existing RRs matching `name` and `type` will be deleted, incl. all comments. + With `REPLACE`: when `records` is present, all existing RRs matching `name` and `type` will be deleted, and then new records given in `records` will be created. + If no records are left, any existing comments will be deleted as well. + When `comments` is present, all existing comments for the RRs matching `name` and `type` will be deleted, and then new comments given in `comments` will be created. + +* `records` + List of new records (replacing the old ones). Must be empty when `changetype` is set to `DELETE`. + An empty list results in deletion of all records (and comments). + +* `comments` + List of new comments (replacing the old ones). Must be empty when `changetype` is set to `DELETE`. + An empty list results in deletion of all comments. + `modified_at` is optional and defaults to the current server time. + +#### PUT + +Modifies basic zone data (metadata). + +Allowed fields in client body: all except `id` and `url`. + +Changing `name` renames the zone, as expected. + + +URL: /servers/:server\_id/zones/:zone\_id/notify +------------------------------------------------ + +Allowed methods: `PUT` + +Send a DNS NOTIFY to all slaves. + +Fails when zone kind is not `Master` or `Slave`, or `master` and `slave` are +disabled in pdns configuration. Only works for `Slave` if renotify is on. + +Not supported for recursors. + +Clients MUST NOT send a body. + +**TODO**: Not yet implemented. + + +URL: /servers/:server\_id/zones/:zone\_id/axfr-retrieve +------------------------------------------------------- + +Allowed methods: `PUT` + +Retrieves the zone from the master. + +Fails when zone kind is not `Slave`, or `slave` is disabled in pdns +configuration. + +Not supported for recursors. + +Clients MUST NOT send a body. + +**TODO**: Not yet implemented. + +URL: /servers/:server\_id/zones/:zone\_id/check +----------------------------------------------- + +Allowed methods: `GET` + +Verify zone contents/configuration. + +Return format: + + { + "zone": "", + "errors": ["error message1", ...], + "warnings": ["warning message1", ...] + } + +**TODO**: Not yet implemented. + +Zone Metadata +============= + +zone\_metadata\_resource +------------------------ + + { + "type": "Metadata", + "kind": , + "metadata": [ + "value1", + ... + ] + } + +Valid values for `` are specified in . + +Clients MUST NOT modify `NSEC3PARAM`, `NSEC3NARROW` or `PRESIGNED` +through this interface. The server SHOULD reject updates to these +metadata. + + +URL: /servers/:server\_id/zones/:zone\_name/metadata +---------------------------------------------------- + +Collection access. + +Allowed methods: `GET`, `POST` + +**TODO**: Not yet implemented. + +URL: /servers/:server\_id/zones/:zone\_name/metadata/:metadata\_kind +-------------------------------------------------------------------- + +Allowed methods: `GET`, `PUT`, `DELETE` + +**TODO**: Not yet implemented. + +CryptoKeys +========== + +cryptokey\_resource +------------------- + + {[ + "type": "CryptoKey", + "id": , + "active": , + "keytype": , + "dnskey": , + "content": , + "ds": [ , + , + .... ] + ]} + + +##### Parameters: + +`id`: read-only. + +`keytype`: `` is one of the following: `ksk` or `zsk`, and they are +both mutually exclusive. + +`dnskey`: the DNSKEY for this key + +`ds`: an array with all dses for this key + + +URL: /servers/:server\_id/zones/:zone\_name/cryptokeys +------------------------------------------------------ + +Allowed methods: `GET`, `POST` + +#### GET + +Returns all public data about cryptokeys, but not `content`. + +#### POST + +Creates a new, single cryptokey. + +**TODO**: Not yet implemented. + +##### Parameters: + +`content`: if `null`, pdns generates a new key. In this case, the +following additional fields MAY be supplied: + +* `bits`: `` +* `algo`: `` + +Where `` is one of the supported key algos in lowercase OR the +numeric id, see +[http://rtfm.powerdns.com/pdnssec.html](http://rtfm.powerdns.com/pdnssec.html) + +URL: /servers/:server\_id/zones/:zone\_name/cryptokeys/:cryptokey\_id +--------------------------------------------------------------------- + +Allowed methods: `GET`, `PUT`, `DELETE` + +#### GET + +Returns all public data about cryptokeys, including `content`, with all the private data. An array is returned, eventhough a single key is requested. + +#### PUT + +**TODO**: Not yet implemented. + +#### DELETE + +**TODO**: Not yet implemented. + +Cache Access +============ + +**TODO**: Peek at the cache, clear the cache, possibly dump it into a file? + +**TODO**: Not yet implemented. + +Logging & Statistics +==================== + +URL: /servers/:server\_id/search-log?q=:search\_term +---------------------------------------------------- + +Allowed methods: `GET` (Query) + +#### GET (Query) + +Query the log, filtered by `:search_term`. Response body: + + [ + "", + ... + ] + +URL: /servers/:server\_id/statistics +------------------------------------ + +Allowed methods: `GET` (Query) + +#### GET (Query) + +Query PowerDNS internal statistics. Response body: + + [ + { + "type": "StatisticItem", + "name": "", + "value": "" + }, + ... + ] + +The statistic entries are dependent on the daemon type. +Values are returned as strings. + + +URL: /servers/:server\_id/trace +------------------------------- + +**TODO**: Not yet implemented. + +#### PUT (Configure) + +Configure query tracing. + +Client body: + + { + "domains": "" + } + +Set `domains` to `null` to turn off tracing. + +#### GET (Query) + +Retrieve query tracing log and current config. Response body: + + { + "domains": "", + log: [ + "", + ... + ] + } + + +URL: /servers/:server\_id/failures +---------------------------------- + +**TODO**: Not yet implemented. + +#### PUT + +Configure query failure logging. + +Client body: + + { + "top-domains": , + "domains": "", + } + +##### Parameters: + +`top-domains` are the number of top resolved domains that are +automatically monitored for failures. + +`domains` is a Regex of domains that are additionally monitored for +resolve failures. + + +#### GET + +Retrieve query failure logging and current config. + +Response body: + + { + "top-domains": , + "domains": "", + "log": [ + { + "first_occurred": , + "domain": "", + "qtype": "", + "failure": , + "failed_parent": "", + "details": "", + "queried_servers": [ + { + "name": , + "address":
+ }, ... + ] + }, + ... + ] + } + +##### Parameters: + +`failed_parent` is generally OPTIONAL. + +Where `` is one of these: + + + `dnssec-validation-failed` + + DNSSEC Validation failed for this domain. + + + `dnssec-parent-validation-failed` + + DNSSEC Validation failed for one of the parent domains. Response + MUST contain failed\_parent. + + + `nxdomain` + + This domain was not present on the authoritative nameservers. + + + `nodata` + + `all-servers-unreachable` + + All auth nameservers that have been tried did not respond. + + + `parent-unresolvable` + + Response MUST contain `failed_parent`. + + + `refused` + + All auth nameservers that have been tried responded with refused. + + + `servfail` + + All auth nameservers that have been tried responded with servfail. + + + **TODO**: further failures + +Data Overrides +============== + +**TODO**: Not yet implemented. + +override\_type +-------------- + +`created` is filled by the Server. + + + { + "type": "Override", + "id": , + "override": "ignore-dnssec", + "domain": "nl", + "until": , + "created": + } + + + { + "type": "Override", + "id": , + "override": "replace", + "domain": "www.cnn.com", + "rrtype": "AAAA", + "values": ["1.1.1.1", "2.2.2.2"], + "until": , + "created": + } + +**TODO**: what about validation here? + + { + "type": "Override", + "id": , + "override": "purge", + "domain": "example.net", + "created": + } + +Clears recursively all cached data ("plain" DNS + DNSSEC) + +**TODO**: should this be stored? (for history) + +URL: /servers/:server\_id/overrides +---------------------------------- + +**TODO**: Not yet implemented. + +Collection access. + +Allowed Methods: `GET`, `POST` + +URL: /servers/:server\_id/overrides/:override\_id +------------------------------------------------- + +**TODO**: Not yet implemented. + +Allowed methods: `GET`, `PUT`, `DELETE` diff --git a/pdns/docs/httpapi/features.md b/pdns/docs/httpapi/features.md new file mode 100644 index 000000000..0f530f9f9 --- /dev/null +++ b/pdns/docs/httpapi/features.md @@ -0,0 +1,38 @@ + +Features that should be doable using the API +============================================ + +New Console Features +-------------------- + +* RBAC +* User Management +* Audit Trail, light Edition +* Cache Viewing +* Versioning / Rollback + * for Zone data? +* pcap capture triggering (-> pdnsmgr) +* Zone (de)provisioning + * with DNSSEC +* Improved Graphite + +DNSSEC Console for Recursor +--------------------------- + +* recent failures (not just DNSSEC) +* trigger live logging (e.g. for “*.nl”) +* DNSSEC partial blanking (“don’t check *.gov”) +* DNSSEC temporary blanking (“not for next 24h”) + +Meta Features enabled by pdnsmgrd +--------------------------------- + +* start +* stop +* upgrade +* restart + * TODO: can/should we do this inproc? +* *pcap* + * TODO: How will this work? + * Should this happen in-daemon? + diff --git a/pdns/docs/httpapi/intro.md b/pdns/docs/httpapi/intro.md new file mode 100644 index 000000000..b561fc207 --- /dev/null +++ b/pdns/docs/httpapi/intro.md @@ -0,0 +1,32 @@ +Everything open for discussion. + +TODO: + + * Everything marked as **TODO** + * Finish data management (tsigkeys, …) + * Incorporate applicable ideas from http://mailman.powerdns.com/pipermail/pdns-users/2013-February/009613.html + +Big Picture +=========== + +* HTTP with SSL in-process in Auth & Recursor +* JSON API + * make it really great for us and other consumers + * “unified” API across Daemons and Console +* pdnsmgrd + * cease to do SSL proxying + * become completely optional component + * only for “meta” features +* Console + * get rid of all the API hacks + * new features as detailed below +* CLI tool + * should talk to daemons and Console (if there) +* “Pure” OOTB install + * miniature single page js app for users not installing pdnscontrol + +“Secondary” goals +================= + +* keep everything lean +* minimal intrusions into existing code