]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
pylibknot: expanded CTL documentation python_libknot_api_doc
authorJan Doskočil <jan.doskocil@nic.cz>
Wed, 11 Dec 2024 14:06:23 +0000 (15:06 +0100)
committerJan Doskočil <jan.doskocil@nic.cz>
Thu, 2 Jan 2025 14:11:57 +0000 (15:11 +0100)
python/libknot/README.md

index 6ff68fc0d14e6cd18512a25522059b3ac3e45741..2de8c1e1034b7ce764e0dfb692e0439c5b282799 100644 (file)
@@ -6,8 +6,10 @@ A Python interface for managing the Knot DNS daemon.
 
 * [Introduction](#introduction)
 * [Control module](#control-module)
-  + [Control usage](#control-usage)
-  + [Control examples](#control-examples)
+  + [Protocol reference](#kctl-proto)
+  + [Commands reference](#kctl-cmds)
+  + [Usage](#control-usage)
+  + [Examples](#control-examples)
 * [Probe module](#probe-module)
   + [Probe usage](#probe-usage)
   + [Probe examples](#probe-examples)
@@ -34,6 +36,159 @@ i.e. communication via a Unix socket.
 
 The module API is stored in `libknot.control`.
 
+### Protocol overview<a id="kctl-proto"></a>
+
+Connections are supposed to be short-lived, because maintaining a passive
+connection is costly for the server. Therefore the expected usage of the control
+interface is to always open a new connection on demand, then close it once it's
+not immediately needed.
+
+Messages are composed of units. These are of four types the identifiers of
+which are defined in `libknot.control.KnotCtlType`:
+
+| Type    | Description                                                | IO action |
+| ------- | ---------------------------------------------------------- | --------- |
+| `END`   | Signals intent to terminate connection.                    | flush     |
+| `DATA`  | Holds various information - see about data sections below. | cache     |
+| `EXTRA` | Additional data.                                           | cache     |
+| `BLOCK` | End of data block.                                         | flush     |
+
+`DATA` and `EXTRA` units aren't immediately sent, rather they're buffered and
+then sent along with the next `END` or `BLOCK` unit.
+
+A unit can optionaly hold data, though this is only meaningful for the `DATA`
+and `EXTRA` types. The data consists of several sections of which usually only
+a few at a time will be present. For example when a unit issuing a `stats`
+command is sent, there is no reason for it to contain an `ID` section.
+
+The data section identifiers are defined in `libknot.control.KnotCtlDataIdx`:
+
+| Section name | `send_block()` arg name | Description                                            |
+| ------------ | ----------------------- | ------------------------------------------------------ |
+| `COMMAND`    | cmd                     | Command name.                                          |
+| `FLAGS`      | flags                   | Command flags.                                         |
+| `ERROR`      | *(n/a)*                 | Error message. Only sent by the server.                |
+| `SECTION`    | section                 | Configuration section name.                            |
+| `ITEM`       | item                    | Configuration item name.                               |
+| `ID`         | identifier              | Configuration item identifier.                         |
+| `ZONE`       | zone                    | Zone name.                                             |
+| `OWNER`      | owner                   | Zone record owner                                      |
+| `TTL`        | ttl                     | Zone record TTL.                                       |
+| `TYPE`       | rtype                   | Zone record type name.                                 |
+| `DATA`       | data                    | Configuration item/zone record data.                   |
+| `FILTERS`    | filters                 | Command options or filters for output data processing. |
+
+### Commands reference<a id="kctl-cmds"></a>
+
+The following is a reference for the low-level control API. In case you're unsure
+of the commands' semantics, please consult the
+<a href="https://www.knot-dns.cz/docs/latest/singlehtml/index.html#actions">knotc documentation</a>.
+
+A concise notation is used for command synopsis:
+
+```
+# command "cmd-name" accepts section of type SECTION_NAME and optionally
+# another section of type OPT_SECTION
+cmd-name(SECTION_NAME, [OPT_SECTION])
+
+[OPT_SECTION="literal value"],   # Optional section with fixed expected value.
+[SECTION1, SECTION2]             # Sections must be present together or not at all.
+[SECTION1, [SECTION2]]           # SECTION2 may only appear if SECTION1 is present.
+SECTION_NAME="option1"|"option2" # Either one or the other literal may be used.
+SECTION_NAME={"asdf"}            # Any subset of characters may be used.
+```
+
+The `B` flag always represents an option to execute in blocking mode.
+
+When listing the filters a command accepts, the letter which is passed into
+`FILTERS` will be boldened. Like this: zone**f**ile
+
+#### Server
+
+* `status([TYPE="cert-key"|"configure"|"version"|"workers"])`
+* `stop()`
+* `reload()`
+* `stats([SECTION, [ITEM]], [FLAGS="F"])`
+  + `SECTION` stores the module, `ITEM` stores the counter
+  + the `F` flag specifies to include 0 counters in server's response
+
+#### Zone events
+
+The following commands apply to all zones if `ZONE` is left empty.
+
+* `zone-status([ZONE], [FILTERS={"rstefc"}])`
+  + filters: **r**ole, **s**erial, **t**ransaction, **e**vents, **f**reeze, **c**atalog <!-- , **u**nixtime -->
+* `zone-reload([ZONE], [FLAGS={"BF"}])`
+  + the `F` flag commands to also reload modules
+* `zone-refresh([ZONE], [FLAGS="B"])`
+* `zone-retransfer([ZONE], [FLAGS="B"])`
+* `zone-notify([ZONE], [FLAGS="B"])`
+* `zone-flush([ZONE], [FILTERS="d", DATA], [FLAGS={"FB"}])`
+  + the output**d**ir filter commands that zone(s) be flushed to path stored in the `DATA` section
+  + the `F` flag is required if zonefile synchronization is disabled
+* `zone-backup([ZONE], [FILTERS={"dzjtkocqZJTKOCQ"}, [DATA]], [FLAGS="B"])`
+  + filters
+    - the backup**d**ir filter commands that backups be made to path stored in the `DATA` section
+    - **z**onefile, **j**ournal, **t**imers, **k**aspdb, keys**o**nly, **c**atalog, **q**uic
+    - negative counterparts (eg. no**Z**onefile) are symmetrical and capitalized
+  + the `F` flag allows for an existing backupdir to be overwritten
+* `zone-restore` *analogous to `zone-backup`*
+* `zone-sign([ZONE], [FLAGS="B"])`
+* `zone-validate([ZONE], [FLAGS="B"])`
+* `zone-keys-load([ZONE], [FLAGS="B"])`
+* `zone-key-rollover([ZONE], TYPE="ksk"|"zsk", [FLAGS="B"])`
+* `zone-ksk-submitted([ZONE], [FLAGS="B"])`
+* `zone-freeze([ZONE], [FLAGS="B"])`
+* `zone-thaw([ZONE], [FLAGS="B"])`
+* `zone-xfr-freeze([ZONE], [FLAGS="B"])`
+* `zone-xfr-thaw([ZONE], [FLAGS="B"])`
+
+#### Zone editing
+
+Use `@` as `OWNER` if you want to denote `ZONE` itself as the owner.
+
+* `zone-read([ZONE], [OWNER], [TYPE])`
+  + if `ZONE` is left empty all zones are read
+* `zone-begin(ZONE, [FILTERS="b"])`
+  + filters: **b**enevolent
+* `zone-commit([ZONE])`
+* `zone-abort([ZONE])`
+* `zone-diff([ZONE])`
+* `zone-get([ZONE], [OWNER], [TYPE])`
+* `zone-set([ZONE], OWNER, [TTL], TYPE, DATA)`
+* `zone-unset([ZONE], OWNER, [TYPE, [DATA]])`
+* `zone-purge([ZONE], [FILTERS={ocejktf}], [FLAGS="B"])`
+  + filters: **o**rphan, **c**atalog, **e**xpire, **j**ournal, **k**aspdb, **t**imers, zone**f**ile
+* `zone-stats([ZONE], [SECTION, [ITEM]], [FLAGS="F"])`
+  + `SECTION` stores the module, `ITEM` stores the counter
+  + the `F` flag specifies to include 0 counters in server's response
+
+#### Configuration
+
+For the following commands:
+
+* `SECTION` holds the configuration section name (eg. `template`)
+* `ID` holds the configuration id (eg. `default`)
+* `ITEM` holds the configuration item name (eg. `storage`)
+
+<!-- hacky comment to separate markdown lists -->
+
+* `conf-list([SECTION, [ID], [ITEM]], [FILTERS="z"|{"st"}])`
+  + filters:
+    - **z**one: list all zone names, including those from the catalog
+    - li**s**t: list configuration section items instead of its identifiers
+    - **t**ransaction: If a transaction is open (`conf-begin`) queries the
+      transaction's configuration schema instead of the server's
+* `conf-read([SECTION, [ID], [ITEM]])`
+* `conf-begin()`
+* `conf-commit()`
+* `conf-abort()`
+* `conf-diff([SECTION, [ID], [ITEM]])`
+* `conf-get([SECTION, [ID], [ITEM]])`
+* `conf-set(SECTION, ID, ITEM, [DATA])`
+* `conf-unset([SECTION, [ID], [ITEM], [DATA]])`
+  + `DATA` may only be meaningfully specified if the preceding sections are as well
+
 ### Control usage<a id="control-usage"></a>
 
 The module usage consists of several steps:
@@ -44,6 +199,18 @@ The module usage consists of several steps:
   afterwards.
 * Closing the connection and deinitialization.
 
+#### Sending
+
+There are two methods on the `KnotCtl` class which send data to the socket.
+
+`KnotCtl.send(KnotCtlType, KnotCtlData)` is the more rudimentary one. It only
+sends the section identifier along with its data, if any are provided. When
+using this function users must beware of the different characteristics
+regarding buffering of different unit types.
+
+`KnotCtl.send_block(...)` is more convenient in that it always flushes by
+sending a `BLOCK` unit. Otherwise the two methods are functionally equivalent.
+
 ### Control examples<a id="control-examples"></a>
 
 ```python3