libknot 3.3.13.dev0__tar.gz → 3.3.15.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/PKG-INFO +101 -70
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/README.md +100 -69
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/libknot.egg-info/PKG-INFO +101 -70
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/pyproject.toml +1 -1
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/setup.py +1 -1
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/libknot/__init__.py +0 -0
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/libknot/control.py +0 -0
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/libknot/dname.py +0 -0
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/libknot/probe.py +0 -0
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/libknot.egg-info/SOURCES.txt +0 -0
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/libknot.egg-info/dependency_links.txt +0 -0
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/libknot.egg-info/top_level.txt +0 -0
- {libknot-3.3.13.dev0 → libknot-3.3.15.dev0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: libknot
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.15.dev0
|
|
4
4
|
Summary: Python bindings for libknot
|
|
5
5
|
Home-page: https://gitlab.nic.cz/knot/knot-dns/-/tree/master/python/libknot
|
|
6
6
|
Author: CZ.NIC, z.s.p.o.
|
|
@@ -28,10 +28,10 @@ A Python interface for managing the Knot DNS daemon.
|
|
|
28
28
|
|
|
29
29
|
* [Introduction](#introduction)
|
|
30
30
|
* [Control module](#control-module)
|
|
31
|
-
+ [
|
|
32
|
-
+ [
|
|
33
|
-
+ [
|
|
34
|
-
+ [
|
|
31
|
+
+ [Protocol reference](#kctl-proto)
|
|
32
|
+
+ [Commands reference](#kctl-cmds)
|
|
33
|
+
+ [Usage](#control-usage)
|
|
34
|
+
+ [Examples](#control-examples)
|
|
35
35
|
* [Probe module](#probe-module)
|
|
36
36
|
+ [Probe usage](#probe-usage)
|
|
37
37
|
+ [Probe examples](#probe-examples)
|
|
@@ -58,25 +58,15 @@ i.e. communication via a Unix socket.
|
|
|
58
58
|
|
|
59
59
|
The module API is stored in `libknot.control`.
|
|
60
60
|
|
|
61
|
-
###
|
|
62
|
-
|
|
63
|
-
The module usage consists of several steps:
|
|
64
|
-
|
|
65
|
-
* Initialization and connection to the daemon control socket.
|
|
66
|
-
* One or more control operations. An operation is called by sending a command
|
|
67
|
-
with optional data to the daemon. The operation result has to be received
|
|
68
|
-
afterwards.
|
|
69
|
-
* Closing the connection and deinitialization.
|
|
70
|
-
|
|
71
|
-
### KnotCTL protocol overview<a id="kctl-proto"></a>
|
|
61
|
+
### Protocol overview<a id="kctl-proto"></a>
|
|
72
62
|
|
|
73
63
|
Connections are supposed to be short-lived, because maintaining a passive
|
|
74
|
-
connection is costly for the server. Therefore the expected usage of the
|
|
64
|
+
connection is costly for the server. Therefore the expected usage of the CTL
|
|
75
65
|
interface is to always open a new connection on demand, then close it once it's
|
|
76
66
|
not immediately needed.
|
|
77
67
|
|
|
78
|
-
Messages are composed of units. These are of four types
|
|
79
|
-
defined in `libknot.control.KnotCtlType`:
|
|
68
|
+
Messages are composed of units. These are of four types the identifiers of
|
|
69
|
+
which are defined in `libknot.control.KnotCtlType`:
|
|
80
70
|
|
|
81
71
|
| Type | Description | IO action |
|
|
82
72
|
| ------- | ---------------------------------------------------------- | --------- |
|
|
@@ -85,6 +75,9 @@ defined in `libknot.control.KnotCtlType`:
|
|
|
85
75
|
| `EXTRA` | Additional data. | cache |
|
|
86
76
|
| `BLOCK` | End of data block. | flush |
|
|
87
77
|
|
|
78
|
+
`DATA` and `EXTRA` units aren't immediately sent, rather they're buffered and
|
|
79
|
+
then sent along with the next `END` or `BLOCK` unit.
|
|
80
|
+
|
|
88
81
|
A unit can optionaly hold data, though this is only meaningful for the `DATA`
|
|
89
82
|
and `EXTRA` types. The data consists of several sections of which usually only
|
|
90
83
|
a few at a time will be present. For example when a unit issuing a `stats`
|
|
@@ -92,65 +85,71 @@ command is sent, there is no reason for it to contain an `ERROR` section.
|
|
|
92
85
|
|
|
93
86
|
The data section identifiers are defined in `libknot.control.KnotCtlDataIdx`:
|
|
94
87
|
|
|
95
|
-
| Section name | Description |
|
|
96
|
-
| ------------ | ------------------------------------------------------ |
|
|
97
|
-
| `COMMAND` | Command name. |
|
|
98
|
-
| `FLAGS` | Command flags. |
|
|
99
|
-
| `ERROR` | Error message.
|
|
100
|
-
| `SECTION` | Configuration section name. |
|
|
101
|
-
| `ITEM` | Configuration item name. |
|
|
102
|
-
| `ID` | Configuration item identifier. |
|
|
103
|
-
| `ZONE` | Zone name. |
|
|
104
|
-
| `OWNER` | Zone record owner |
|
|
105
|
-
| `TTL` | Zone record TTL. |
|
|
106
|
-
| `TYPE` | Zone record type name. |
|
|
107
|
-
| `DATA` | Configuration item/zone record data. |
|
|
108
|
-
| `FILTERS` | Command options or filters for output data processing. |
|
|
109
|
-
|
|
110
|
-
###
|
|
88
|
+
| Section name | `send_block()` arg name | Description |
|
|
89
|
+
| ------------ | ----------------------- | ------------------------------------------------------ |
|
|
90
|
+
| `COMMAND` | cmd | Command name. |
|
|
91
|
+
| `FLAGS` | flags | Command flags. |
|
|
92
|
+
| `ERROR` | *n/a* | Error message. Only sent by the server. |
|
|
93
|
+
| `SECTION` | section | Configuration section name. |
|
|
94
|
+
| `ITEM` | item | Configuration item name. |
|
|
95
|
+
| `ID` | identifier | Configuration item identifier. |
|
|
96
|
+
| `ZONE` | zone | Zone name. |
|
|
97
|
+
| `OWNER` | owner | Zone record owner |
|
|
98
|
+
| `TTL` | ttl | Zone record TTL. |
|
|
99
|
+
| `TYPE` | rtype | Zone record type name. |
|
|
100
|
+
| `DATA` | data | Configuration item/zone record data. |
|
|
101
|
+
| `FILTERS` | filters | Command options or filters for output data processing. |
|
|
102
|
+
|
|
103
|
+
### Commands reference<a id="kctl-cmds"></a>
|
|
111
104
|
|
|
112
105
|
The following is a reference for the low-level CTL API. In case you're unsure
|
|
113
106
|
of the commands' semantics, please consult the
|
|
114
|
-
<a href="https://
|
|
107
|
+
<a href="https://www.knot-dns.cz/docs/latest/singlehtml/index.html#actions">knotc documentation</a>.
|
|
115
108
|
|
|
116
109
|
A concise notation is used for command synopsis:
|
|
117
110
|
|
|
118
|
-
|
|
119
|
-
cmd-name
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
111
|
+
```
|
|
112
|
+
# command "cmd-name" accepts section of type SECTION_NAME and optionally
|
|
113
|
+
# another section of type OPT_SECTION
|
|
114
|
+
cmd-name(SECTION_NAME, [OPT_SECTION])
|
|
115
|
+
|
|
116
|
+
[OPT_SECTION="literal value"], # Optional section with fixed expected value.
|
|
117
|
+
[SECTION1, SECTION2] # Sections must be present together or not at all.
|
|
118
|
+
[PRIMARY, [SECONDARY]] # SECONDARY may only appear if PRIMARY is present.
|
|
119
|
+
SECTION_NAME="option1"|"option2" # Either one or the other literal may be used.
|
|
120
|
+
SECTION_NAME={"asdf"} # Any subset of characters may be used.
|
|
121
|
+
```
|
|
128
122
|
|
|
129
|
-
The
|
|
123
|
+
The `B` flag always represents an option to execute in blocking mode.
|
|
130
124
|
|
|
131
125
|
#### Server
|
|
132
126
|
|
|
133
127
|
* `status([TYPE="cert-key"|"configure"|"version"|"workers"])`
|
|
134
128
|
* `stop()`
|
|
135
129
|
* `reload()`
|
|
136
|
-
* `stats([SECTION
|
|
130
|
+
* `stats([SECTION], [ITEM], [FLAGS="F"])`
|
|
131
|
+
+ `SECTION` stores the module, `ITEM` stores the counter
|
|
132
|
+
+ the `F` flag specifies to include 0 counters in server's response
|
|
137
133
|
|
|
138
134
|
#### Zone events
|
|
139
135
|
|
|
140
|
-
|
|
136
|
+
The following commands apply to all zones if `ZONE` is left empty.
|
|
141
137
|
|
|
142
138
|
* `zone-status([ZONE], [FILTERS={"rstefc"}])`
|
|
143
|
-
+
|
|
144
|
-
* `zone-reload([ZONE], [FLAGS={"
|
|
139
|
+
+ filters: **r**ole, **s**erial, **t**ransaction, **e**vents, **f**reeze, **c**atalog <!-- , **u**nixtime -->
|
|
140
|
+
* `zone-reload([ZONE], [FLAGS={"BF"}])`
|
|
141
|
+
+ the `F` flag commands to also reload modules
|
|
145
142
|
* `zone-refresh([ZONE], [FLAGS="B"])`
|
|
146
143
|
* `zone-retransfer([ZONE], [FLAGS="B"])`
|
|
147
144
|
* `zone-notify([ZONE], [FLAGS="B"])`
|
|
148
|
-
* `zone-flush([ZONE], [FILTERS="d", DATA
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
-
|
|
153
|
-
|
|
145
|
+
* `zone-flush([ZONE], [FILTERS="d", DATA], [FLAGS="B"])`
|
|
146
|
+
+ the output**d**ir filter commands that zone(s) be flushed to path stored in the `DATA` section
|
|
147
|
+
* `zone-backup([ZONE], [FILTERS={"dzjtkocqZJTKOCQ"}, [DATA]], [FLAGS="B"])`
|
|
148
|
+
+ filters
|
|
149
|
+
- the backup**d**ir filter commands that backups be made to path stored in the `DATA` section
|
|
150
|
+
- **z**onefile, **j**ournal, **t**imers, **k**aspdb, keys**o**nly, **c**atalog, **q**uic
|
|
151
|
+
- negative counterparts (eg. no**Z**onefile) are symmetrical and capitalized
|
|
152
|
+
* `zone-restore` *analogous to `zone-backup`*
|
|
154
153
|
* `zone-sign([ZONE], [FLAGS="B"])`
|
|
155
154
|
* `zone-validate([ZONE], [FLAGS="B"])`
|
|
156
155
|
* `zone-keys-load([ZONE], [FLAGS="B"])`
|
|
@@ -163,39 +162,71 @@ The **`"B"`** flag always represents an option to execute in blocking mode.
|
|
|
163
162
|
|
|
164
163
|
#### Zone editing
|
|
165
164
|
|
|
166
|
-
Use
|
|
165
|
+
Use `@` as `OWNER` if you want to denote `ZONE` itself as the owner.
|
|
167
166
|
|
|
168
|
-
* `zone-read([ZONE
|
|
169
|
-
|
|
167
|
+
* `zone-read([ZONE], [OWNER], [TYPE])`
|
|
168
|
+
+ if `ZONE` is left empty all zones are read
|
|
169
|
+
* `zone-begin(ZONE, [FILTERS="b"])`
|
|
170
|
+
+ filters: **b**enevolent
|
|
170
171
|
* `zone-commit(ZONE)`
|
|
171
172
|
* `zone-abort(ZONE)`
|
|
172
173
|
* `zone-diff(ZONE)`
|
|
173
|
-
* `zone-get(ZONE, [OWNER], [TYPE])`
|
|
174
|
+
* `zone-get(ZONE, [OWNER], [TYPE])`
|
|
174
175
|
* `zone-set(ZONE, OWNER, [TTL], TYPE, DATA)`
|
|
175
176
|
* `zone-unset(ZONE, OWNER, [TYPE, [DATA]])`
|
|
176
177
|
* `zone-purge(ZONE, [FILTERS={ocejktf}], [FLAGS="B"])`
|
|
177
|
-
+
|
|
178
|
-
* `zone-stats(ZONE, [SECTION
|
|
178
|
+
+ filters: **o**rphan, **c**atalog, **e**xpire, **j**ournal, **k**aspdb, **t**imers, zone**f**ile
|
|
179
|
+
* `zone-stats(ZONE, [SECTION], [ITEM], [FLAGS="F"])`
|
|
180
|
+
+ `SECTION` stores the module, `ITEM` stores the counter
|
|
181
|
+
+ the `F` flag specifies to include 0 counters in server's response
|
|
179
182
|
|
|
180
183
|
#### Configuration
|
|
181
184
|
|
|
182
|
-
|
|
185
|
+
For the following commands:
|
|
186
|
+
|
|
187
|
+
* `SECTION` holds the configuration section name (eg. `template`)
|
|
188
|
+
* `ID` holds the configuration id (eg. `default`)
|
|
189
|
+
* `ITEM` holds the configuration item name (eg. `storage`)
|
|
183
190
|
|
|
184
|
-
|
|
185
|
-
· `SECTION` holds the configuration section name (eg. `template`)<br/>
|
|
186
|
-
· `ID` holds the configuration id (eg. `default`)<br/>
|
|
187
|
-
· `ITEM` holds the configuration item name (eg. `storage`)<br/>
|
|
191
|
+
<!-- hacky comment to separate markdown lists -->
|
|
188
192
|
|
|
189
|
-
* `conf-list([SECTION, [ID], [ITEM]], [FILTERS="
|
|
193
|
+
* `conf-list([SECTION, [ID], [ITEM]], [FILTERS="z"|{"st"}])`
|
|
194
|
+
+ filters:
|
|
195
|
+
- **z**one: list all zone names, including those from the catalog
|
|
196
|
+
- li**s**t: list configuration section items instead of its identifiers
|
|
197
|
+
- **t**ransaction: If a transaction is open (`conf-begin`) queries the
|
|
198
|
+
transaction's configuration schema instead of the server's
|
|
190
199
|
* `conf-read([SECTION, [ID], [ITEM]])`
|
|
191
200
|
* `conf-begin()`
|
|
192
201
|
* `conf-commit()`
|
|
193
202
|
* `conf-abort()`
|
|
194
203
|
* `conf-diff([SECTION, [ID], [ITEM]])`
|
|
195
204
|
* `conf-get([SECTION, [ID], [ITEM]])`
|
|
196
|
-
* `conf-set(SECTION, ID, ITEM, [DATA]
|
|
205
|
+
* `conf-set(SECTION, ID, ITEM, [DATA])`
|
|
197
206
|
* `conf-unset([SECTION, [ID], [ITEM]], [DATA])`
|
|
198
207
|
|
|
208
|
+
### Control usage<a id="control-usage"></a>
|
|
209
|
+
|
|
210
|
+
The module usage consists of several steps:
|
|
211
|
+
|
|
212
|
+
* Initialization and connection to the daemon control socket.
|
|
213
|
+
* One or more control operations. An operation is called by sending a command
|
|
214
|
+
with optional data to the daemon. The operation result has to be received
|
|
215
|
+
afterwards.
|
|
216
|
+
* Closing the connection and deinitialization.
|
|
217
|
+
|
|
218
|
+
#### Sending
|
|
219
|
+
|
|
220
|
+
There are two methods on the `KnotCtl` class which send data to the socket.
|
|
221
|
+
|
|
222
|
+
`KnotCtl.send(KnotCtlType, KnotCtlData)` is the more rudimentary one. It only
|
|
223
|
+
sends the section identifier along with its data, if any are provided. When
|
|
224
|
+
using this function users must beware of the different characteristics
|
|
225
|
+
regarding buffering of different unit types.
|
|
226
|
+
|
|
227
|
+
`KnotCtl.send_block(...)` is more convenient in that it always flushes by
|
|
228
|
+
sending a `BLOCK` unit. Otherwise the two methods are functionally equivalent.
|
|
229
|
+
|
|
199
230
|
### Control examples<a id="control-examples"></a>
|
|
200
231
|
|
|
201
232
|
```python3
|
|
@@ -6,10 +6,10 @@ A Python interface for managing the Knot DNS daemon.
|
|
|
6
6
|
|
|
7
7
|
* [Introduction](#introduction)
|
|
8
8
|
* [Control module](#control-module)
|
|
9
|
-
+ [
|
|
10
|
-
+ [
|
|
11
|
-
+ [
|
|
12
|
-
+ [
|
|
9
|
+
+ [Protocol reference](#kctl-proto)
|
|
10
|
+
+ [Commands reference](#kctl-cmds)
|
|
11
|
+
+ [Usage](#control-usage)
|
|
12
|
+
+ [Examples](#control-examples)
|
|
13
13
|
* [Probe module](#probe-module)
|
|
14
14
|
+ [Probe usage](#probe-usage)
|
|
15
15
|
+ [Probe examples](#probe-examples)
|
|
@@ -36,25 +36,15 @@ i.e. communication via a Unix socket.
|
|
|
36
36
|
|
|
37
37
|
The module API is stored in `libknot.control`.
|
|
38
38
|
|
|
39
|
-
###
|
|
40
|
-
|
|
41
|
-
The module usage consists of several steps:
|
|
42
|
-
|
|
43
|
-
* Initialization and connection to the daemon control socket.
|
|
44
|
-
* One or more control operations. An operation is called by sending a command
|
|
45
|
-
with optional data to the daemon. The operation result has to be received
|
|
46
|
-
afterwards.
|
|
47
|
-
* Closing the connection and deinitialization.
|
|
48
|
-
|
|
49
|
-
### KnotCTL protocol overview<a id="kctl-proto"></a>
|
|
39
|
+
### Protocol overview<a id="kctl-proto"></a>
|
|
50
40
|
|
|
51
41
|
Connections are supposed to be short-lived, because maintaining a passive
|
|
52
|
-
connection is costly for the server. Therefore the expected usage of the
|
|
42
|
+
connection is costly for the server. Therefore the expected usage of the CTL
|
|
53
43
|
interface is to always open a new connection on demand, then close it once it's
|
|
54
44
|
not immediately needed.
|
|
55
45
|
|
|
56
|
-
Messages are composed of units. These are of four types
|
|
57
|
-
defined in `libknot.control.KnotCtlType`:
|
|
46
|
+
Messages are composed of units. These are of four types the identifiers of
|
|
47
|
+
which are defined in `libknot.control.KnotCtlType`:
|
|
58
48
|
|
|
59
49
|
| Type | Description | IO action |
|
|
60
50
|
| ------- | ---------------------------------------------------------- | --------- |
|
|
@@ -63,6 +53,9 @@ defined in `libknot.control.KnotCtlType`:
|
|
|
63
53
|
| `EXTRA` | Additional data. | cache |
|
|
64
54
|
| `BLOCK` | End of data block. | flush |
|
|
65
55
|
|
|
56
|
+
`DATA` and `EXTRA` units aren't immediately sent, rather they're buffered and
|
|
57
|
+
then sent along with the next `END` or `BLOCK` unit.
|
|
58
|
+
|
|
66
59
|
A unit can optionaly hold data, though this is only meaningful for the `DATA`
|
|
67
60
|
and `EXTRA` types. The data consists of several sections of which usually only
|
|
68
61
|
a few at a time will be present. For example when a unit issuing a `stats`
|
|
@@ -70,65 +63,71 @@ command is sent, there is no reason for it to contain an `ERROR` section.
|
|
|
70
63
|
|
|
71
64
|
The data section identifiers are defined in `libknot.control.KnotCtlDataIdx`:
|
|
72
65
|
|
|
73
|
-
| Section name | Description |
|
|
74
|
-
| ------------ | ------------------------------------------------------ |
|
|
75
|
-
| `COMMAND` | Command name. |
|
|
76
|
-
| `FLAGS` | Command flags. |
|
|
77
|
-
| `ERROR` | Error message.
|
|
78
|
-
| `SECTION` | Configuration section name. |
|
|
79
|
-
| `ITEM` | Configuration item name. |
|
|
80
|
-
| `ID` | Configuration item identifier. |
|
|
81
|
-
| `ZONE` | Zone name. |
|
|
82
|
-
| `OWNER` | Zone record owner |
|
|
83
|
-
| `TTL` | Zone record TTL. |
|
|
84
|
-
| `TYPE` | Zone record type name. |
|
|
85
|
-
| `DATA` | Configuration item/zone record data. |
|
|
86
|
-
| `FILTERS` | Command options or filters for output data processing. |
|
|
87
|
-
|
|
88
|
-
###
|
|
66
|
+
| Section name | `send_block()` arg name | Description |
|
|
67
|
+
| ------------ | ----------------------- | ------------------------------------------------------ |
|
|
68
|
+
| `COMMAND` | cmd | Command name. |
|
|
69
|
+
| `FLAGS` | flags | Command flags. |
|
|
70
|
+
| `ERROR` | *n/a* | Error message. Only sent by the server. |
|
|
71
|
+
| `SECTION` | section | Configuration section name. |
|
|
72
|
+
| `ITEM` | item | Configuration item name. |
|
|
73
|
+
| `ID` | identifier | Configuration item identifier. |
|
|
74
|
+
| `ZONE` | zone | Zone name. |
|
|
75
|
+
| `OWNER` | owner | Zone record owner |
|
|
76
|
+
| `TTL` | ttl | Zone record TTL. |
|
|
77
|
+
| `TYPE` | rtype | Zone record type name. |
|
|
78
|
+
| `DATA` | data | Configuration item/zone record data. |
|
|
79
|
+
| `FILTERS` | filters | Command options or filters for output data processing. |
|
|
80
|
+
|
|
81
|
+
### Commands reference<a id="kctl-cmds"></a>
|
|
89
82
|
|
|
90
83
|
The following is a reference for the low-level CTL API. In case you're unsure
|
|
91
84
|
of the commands' semantics, please consult the
|
|
92
|
-
<a href="https://
|
|
85
|
+
<a href="https://www.knot-dns.cz/docs/latest/singlehtml/index.html#actions">knotc documentation</a>.
|
|
93
86
|
|
|
94
87
|
A concise notation is used for command synopsis:
|
|
95
88
|
|
|
96
|
-
|
|
97
|
-
cmd-name
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
89
|
+
```
|
|
90
|
+
# command "cmd-name" accepts section of type SECTION_NAME and optionally
|
|
91
|
+
# another section of type OPT_SECTION
|
|
92
|
+
cmd-name(SECTION_NAME, [OPT_SECTION])
|
|
93
|
+
|
|
94
|
+
[OPT_SECTION="literal value"], # Optional section with fixed expected value.
|
|
95
|
+
[SECTION1, SECTION2] # Sections must be present together or not at all.
|
|
96
|
+
[PRIMARY, [SECONDARY]] # SECONDARY may only appear if PRIMARY is present.
|
|
97
|
+
SECTION_NAME="option1"|"option2" # Either one or the other literal may be used.
|
|
98
|
+
SECTION_NAME={"asdf"} # Any subset of characters may be used.
|
|
99
|
+
```
|
|
106
100
|
|
|
107
|
-
The
|
|
101
|
+
The `B` flag always represents an option to execute in blocking mode.
|
|
108
102
|
|
|
109
103
|
#### Server
|
|
110
104
|
|
|
111
105
|
* `status([TYPE="cert-key"|"configure"|"version"|"workers"])`
|
|
112
106
|
* `stop()`
|
|
113
107
|
* `reload()`
|
|
114
|
-
* `stats([SECTION
|
|
108
|
+
* `stats([SECTION], [ITEM], [FLAGS="F"])`
|
|
109
|
+
+ `SECTION` stores the module, `ITEM` stores the counter
|
|
110
|
+
+ the `F` flag specifies to include 0 counters in server's response
|
|
115
111
|
|
|
116
112
|
#### Zone events
|
|
117
113
|
|
|
118
|
-
|
|
114
|
+
The following commands apply to all zones if `ZONE` is left empty.
|
|
119
115
|
|
|
120
116
|
* `zone-status([ZONE], [FILTERS={"rstefc"}])`
|
|
121
|
-
+
|
|
122
|
-
* `zone-reload([ZONE], [FLAGS={"
|
|
117
|
+
+ filters: **r**ole, **s**erial, **t**ransaction, **e**vents, **f**reeze, **c**atalog <!-- , **u**nixtime -->
|
|
118
|
+
* `zone-reload([ZONE], [FLAGS={"BF"}])`
|
|
119
|
+
+ the `F` flag commands to also reload modules
|
|
123
120
|
* `zone-refresh([ZONE], [FLAGS="B"])`
|
|
124
121
|
* `zone-retransfer([ZONE], [FLAGS="B"])`
|
|
125
122
|
* `zone-notify([ZONE], [FLAGS="B"])`
|
|
126
|
-
* `zone-flush([ZONE], [FILTERS="d", DATA
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
-
|
|
131
|
-
|
|
123
|
+
* `zone-flush([ZONE], [FILTERS="d", DATA], [FLAGS="B"])`
|
|
124
|
+
+ the output**d**ir filter commands that zone(s) be flushed to path stored in the `DATA` section
|
|
125
|
+
* `zone-backup([ZONE], [FILTERS={"dzjtkocqZJTKOCQ"}, [DATA]], [FLAGS="B"])`
|
|
126
|
+
+ filters
|
|
127
|
+
- the backup**d**ir filter commands that backups be made to path stored in the `DATA` section
|
|
128
|
+
- **z**onefile, **j**ournal, **t**imers, **k**aspdb, keys**o**nly, **c**atalog, **q**uic
|
|
129
|
+
- negative counterparts (eg. no**Z**onefile) are symmetrical and capitalized
|
|
130
|
+
* `zone-restore` *analogous to `zone-backup`*
|
|
132
131
|
* `zone-sign([ZONE], [FLAGS="B"])`
|
|
133
132
|
* `zone-validate([ZONE], [FLAGS="B"])`
|
|
134
133
|
* `zone-keys-load([ZONE], [FLAGS="B"])`
|
|
@@ -141,39 +140,71 @@ The **`"B"`** flag always represents an option to execute in blocking mode.
|
|
|
141
140
|
|
|
142
141
|
#### Zone editing
|
|
143
142
|
|
|
144
|
-
Use
|
|
143
|
+
Use `@` as `OWNER` if you want to denote `ZONE` itself as the owner.
|
|
145
144
|
|
|
146
|
-
* `zone-read([ZONE
|
|
147
|
-
|
|
145
|
+
* `zone-read([ZONE], [OWNER], [TYPE])`
|
|
146
|
+
+ if `ZONE` is left empty all zones are read
|
|
147
|
+
* `zone-begin(ZONE, [FILTERS="b"])`
|
|
148
|
+
+ filters: **b**enevolent
|
|
148
149
|
* `zone-commit(ZONE)`
|
|
149
150
|
* `zone-abort(ZONE)`
|
|
150
151
|
* `zone-diff(ZONE)`
|
|
151
|
-
* `zone-get(ZONE, [OWNER], [TYPE])`
|
|
152
|
+
* `zone-get(ZONE, [OWNER], [TYPE])`
|
|
152
153
|
* `zone-set(ZONE, OWNER, [TTL], TYPE, DATA)`
|
|
153
154
|
* `zone-unset(ZONE, OWNER, [TYPE, [DATA]])`
|
|
154
155
|
* `zone-purge(ZONE, [FILTERS={ocejktf}], [FLAGS="B"])`
|
|
155
|
-
+
|
|
156
|
-
* `zone-stats(ZONE, [SECTION
|
|
156
|
+
+ filters: **o**rphan, **c**atalog, **e**xpire, **j**ournal, **k**aspdb, **t**imers, zone**f**ile
|
|
157
|
+
* `zone-stats(ZONE, [SECTION], [ITEM], [FLAGS="F"])`
|
|
158
|
+
+ `SECTION` stores the module, `ITEM` stores the counter
|
|
159
|
+
+ the `F` flag specifies to include 0 counters in server's response
|
|
157
160
|
|
|
158
161
|
#### Configuration
|
|
159
162
|
|
|
160
|
-
|
|
163
|
+
For the following commands:
|
|
164
|
+
|
|
165
|
+
* `SECTION` holds the configuration section name (eg. `template`)
|
|
166
|
+
* `ID` holds the configuration id (eg. `default`)
|
|
167
|
+
* `ITEM` holds the configuration item name (eg. `storage`)
|
|
161
168
|
|
|
162
|
-
|
|
163
|
-
· `SECTION` holds the configuration section name (eg. `template`)<br/>
|
|
164
|
-
· `ID` holds the configuration id (eg. `default`)<br/>
|
|
165
|
-
· `ITEM` holds the configuration item name (eg. `storage`)<br/>
|
|
169
|
+
<!-- hacky comment to separate markdown lists -->
|
|
166
170
|
|
|
167
|
-
* `conf-list([SECTION, [ID], [ITEM]], [FILTERS="
|
|
171
|
+
* `conf-list([SECTION, [ID], [ITEM]], [FILTERS="z"|{"st"}])`
|
|
172
|
+
+ filters:
|
|
173
|
+
- **z**one: list all zone names, including those from the catalog
|
|
174
|
+
- li**s**t: list configuration section items instead of its identifiers
|
|
175
|
+
- **t**ransaction: If a transaction is open (`conf-begin`) queries the
|
|
176
|
+
transaction's configuration schema instead of the server's
|
|
168
177
|
* `conf-read([SECTION, [ID], [ITEM]])`
|
|
169
178
|
* `conf-begin()`
|
|
170
179
|
* `conf-commit()`
|
|
171
180
|
* `conf-abort()`
|
|
172
181
|
* `conf-diff([SECTION, [ID], [ITEM]])`
|
|
173
182
|
* `conf-get([SECTION, [ID], [ITEM]])`
|
|
174
|
-
* `conf-set(SECTION, ID, ITEM, [DATA]
|
|
183
|
+
* `conf-set(SECTION, ID, ITEM, [DATA])`
|
|
175
184
|
* `conf-unset([SECTION, [ID], [ITEM]], [DATA])`
|
|
176
185
|
|
|
186
|
+
### Control usage<a id="control-usage"></a>
|
|
187
|
+
|
|
188
|
+
The module usage consists of several steps:
|
|
189
|
+
|
|
190
|
+
* Initialization and connection to the daemon control socket.
|
|
191
|
+
* One or more control operations. An operation is called by sending a command
|
|
192
|
+
with optional data to the daemon. The operation result has to be received
|
|
193
|
+
afterwards.
|
|
194
|
+
* Closing the connection and deinitialization.
|
|
195
|
+
|
|
196
|
+
#### Sending
|
|
197
|
+
|
|
198
|
+
There are two methods on the `KnotCtl` class which send data to the socket.
|
|
199
|
+
|
|
200
|
+
`KnotCtl.send(KnotCtlType, KnotCtlData)` is the more rudimentary one. It only
|
|
201
|
+
sends the section identifier along with its data, if any are provided. When
|
|
202
|
+
using this function users must beware of the different characteristics
|
|
203
|
+
regarding buffering of different unit types.
|
|
204
|
+
|
|
205
|
+
`KnotCtl.send_block(...)` is more convenient in that it always flushes by
|
|
206
|
+
sending a `BLOCK` unit. Otherwise the two methods are functionally equivalent.
|
|
207
|
+
|
|
177
208
|
### Control examples<a id="control-examples"></a>
|
|
178
209
|
|
|
179
210
|
```python3
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: libknot
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.15.dev0
|
|
4
4
|
Summary: Python bindings for libknot
|
|
5
5
|
Home-page: https://gitlab.nic.cz/knot/knot-dns/-/tree/master/python/libknot
|
|
6
6
|
Author: CZ.NIC, z.s.p.o.
|
|
@@ -28,10 +28,10 @@ A Python interface for managing the Knot DNS daemon.
|
|
|
28
28
|
|
|
29
29
|
* [Introduction](#introduction)
|
|
30
30
|
* [Control module](#control-module)
|
|
31
|
-
+ [
|
|
32
|
-
+ [
|
|
33
|
-
+ [
|
|
34
|
-
+ [
|
|
31
|
+
+ [Protocol reference](#kctl-proto)
|
|
32
|
+
+ [Commands reference](#kctl-cmds)
|
|
33
|
+
+ [Usage](#control-usage)
|
|
34
|
+
+ [Examples](#control-examples)
|
|
35
35
|
* [Probe module](#probe-module)
|
|
36
36
|
+ [Probe usage](#probe-usage)
|
|
37
37
|
+ [Probe examples](#probe-examples)
|
|
@@ -58,25 +58,15 @@ i.e. communication via a Unix socket.
|
|
|
58
58
|
|
|
59
59
|
The module API is stored in `libknot.control`.
|
|
60
60
|
|
|
61
|
-
###
|
|
62
|
-
|
|
63
|
-
The module usage consists of several steps:
|
|
64
|
-
|
|
65
|
-
* Initialization and connection to the daemon control socket.
|
|
66
|
-
* One or more control operations. An operation is called by sending a command
|
|
67
|
-
with optional data to the daemon. The operation result has to be received
|
|
68
|
-
afterwards.
|
|
69
|
-
* Closing the connection and deinitialization.
|
|
70
|
-
|
|
71
|
-
### KnotCTL protocol overview<a id="kctl-proto"></a>
|
|
61
|
+
### Protocol overview<a id="kctl-proto"></a>
|
|
72
62
|
|
|
73
63
|
Connections are supposed to be short-lived, because maintaining a passive
|
|
74
|
-
connection is costly for the server. Therefore the expected usage of the
|
|
64
|
+
connection is costly for the server. Therefore the expected usage of the CTL
|
|
75
65
|
interface is to always open a new connection on demand, then close it once it's
|
|
76
66
|
not immediately needed.
|
|
77
67
|
|
|
78
|
-
Messages are composed of units. These are of four types
|
|
79
|
-
defined in `libknot.control.KnotCtlType`:
|
|
68
|
+
Messages are composed of units. These are of four types the identifiers of
|
|
69
|
+
which are defined in `libknot.control.KnotCtlType`:
|
|
80
70
|
|
|
81
71
|
| Type | Description | IO action |
|
|
82
72
|
| ------- | ---------------------------------------------------------- | --------- |
|
|
@@ -85,6 +75,9 @@ defined in `libknot.control.KnotCtlType`:
|
|
|
85
75
|
| `EXTRA` | Additional data. | cache |
|
|
86
76
|
| `BLOCK` | End of data block. | flush |
|
|
87
77
|
|
|
78
|
+
`DATA` and `EXTRA` units aren't immediately sent, rather they're buffered and
|
|
79
|
+
then sent along with the next `END` or `BLOCK` unit.
|
|
80
|
+
|
|
88
81
|
A unit can optionaly hold data, though this is only meaningful for the `DATA`
|
|
89
82
|
and `EXTRA` types. The data consists of several sections of which usually only
|
|
90
83
|
a few at a time will be present. For example when a unit issuing a `stats`
|
|
@@ -92,65 +85,71 @@ command is sent, there is no reason for it to contain an `ERROR` section.
|
|
|
92
85
|
|
|
93
86
|
The data section identifiers are defined in `libknot.control.KnotCtlDataIdx`:
|
|
94
87
|
|
|
95
|
-
| Section name | Description |
|
|
96
|
-
| ------------ | ------------------------------------------------------ |
|
|
97
|
-
| `COMMAND` | Command name. |
|
|
98
|
-
| `FLAGS` | Command flags. |
|
|
99
|
-
| `ERROR` | Error message.
|
|
100
|
-
| `SECTION` | Configuration section name. |
|
|
101
|
-
| `ITEM` | Configuration item name. |
|
|
102
|
-
| `ID` | Configuration item identifier. |
|
|
103
|
-
| `ZONE` | Zone name. |
|
|
104
|
-
| `OWNER` | Zone record owner |
|
|
105
|
-
| `TTL` | Zone record TTL. |
|
|
106
|
-
| `TYPE` | Zone record type name. |
|
|
107
|
-
| `DATA` | Configuration item/zone record data. |
|
|
108
|
-
| `FILTERS` | Command options or filters for output data processing. |
|
|
109
|
-
|
|
110
|
-
###
|
|
88
|
+
| Section name | `send_block()` arg name | Description |
|
|
89
|
+
| ------------ | ----------------------- | ------------------------------------------------------ |
|
|
90
|
+
| `COMMAND` | cmd | Command name. |
|
|
91
|
+
| `FLAGS` | flags | Command flags. |
|
|
92
|
+
| `ERROR` | *n/a* | Error message. Only sent by the server. |
|
|
93
|
+
| `SECTION` | section | Configuration section name. |
|
|
94
|
+
| `ITEM` | item | Configuration item name. |
|
|
95
|
+
| `ID` | identifier | Configuration item identifier. |
|
|
96
|
+
| `ZONE` | zone | Zone name. |
|
|
97
|
+
| `OWNER` | owner | Zone record owner |
|
|
98
|
+
| `TTL` | ttl | Zone record TTL. |
|
|
99
|
+
| `TYPE` | rtype | Zone record type name. |
|
|
100
|
+
| `DATA` | data | Configuration item/zone record data. |
|
|
101
|
+
| `FILTERS` | filters | Command options or filters for output data processing. |
|
|
102
|
+
|
|
103
|
+
### Commands reference<a id="kctl-cmds"></a>
|
|
111
104
|
|
|
112
105
|
The following is a reference for the low-level CTL API. In case you're unsure
|
|
113
106
|
of the commands' semantics, please consult the
|
|
114
|
-
<a href="https://
|
|
107
|
+
<a href="https://www.knot-dns.cz/docs/latest/singlehtml/index.html#actions">knotc documentation</a>.
|
|
115
108
|
|
|
116
109
|
A concise notation is used for command synopsis:
|
|
117
110
|
|
|
118
|
-
|
|
119
|
-
cmd-name
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
111
|
+
```
|
|
112
|
+
# command "cmd-name" accepts section of type SECTION_NAME and optionally
|
|
113
|
+
# another section of type OPT_SECTION
|
|
114
|
+
cmd-name(SECTION_NAME, [OPT_SECTION])
|
|
115
|
+
|
|
116
|
+
[OPT_SECTION="literal value"], # Optional section with fixed expected value.
|
|
117
|
+
[SECTION1, SECTION2] # Sections must be present together or not at all.
|
|
118
|
+
[PRIMARY, [SECONDARY]] # SECONDARY may only appear if PRIMARY is present.
|
|
119
|
+
SECTION_NAME="option1"|"option2" # Either one or the other literal may be used.
|
|
120
|
+
SECTION_NAME={"asdf"} # Any subset of characters may be used.
|
|
121
|
+
```
|
|
128
122
|
|
|
129
|
-
The
|
|
123
|
+
The `B` flag always represents an option to execute in blocking mode.
|
|
130
124
|
|
|
131
125
|
#### Server
|
|
132
126
|
|
|
133
127
|
* `status([TYPE="cert-key"|"configure"|"version"|"workers"])`
|
|
134
128
|
* `stop()`
|
|
135
129
|
* `reload()`
|
|
136
|
-
* `stats([SECTION
|
|
130
|
+
* `stats([SECTION], [ITEM], [FLAGS="F"])`
|
|
131
|
+
+ `SECTION` stores the module, `ITEM` stores the counter
|
|
132
|
+
+ the `F` flag specifies to include 0 counters in server's response
|
|
137
133
|
|
|
138
134
|
#### Zone events
|
|
139
135
|
|
|
140
|
-
|
|
136
|
+
The following commands apply to all zones if `ZONE` is left empty.
|
|
141
137
|
|
|
142
138
|
* `zone-status([ZONE], [FILTERS={"rstefc"}])`
|
|
143
|
-
+
|
|
144
|
-
* `zone-reload([ZONE], [FLAGS={"
|
|
139
|
+
+ filters: **r**ole, **s**erial, **t**ransaction, **e**vents, **f**reeze, **c**atalog <!-- , **u**nixtime -->
|
|
140
|
+
* `zone-reload([ZONE], [FLAGS={"BF"}])`
|
|
141
|
+
+ the `F` flag commands to also reload modules
|
|
145
142
|
* `zone-refresh([ZONE], [FLAGS="B"])`
|
|
146
143
|
* `zone-retransfer([ZONE], [FLAGS="B"])`
|
|
147
144
|
* `zone-notify([ZONE], [FLAGS="B"])`
|
|
148
|
-
* `zone-flush([ZONE], [FILTERS="d", DATA
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
-
|
|
153
|
-
|
|
145
|
+
* `zone-flush([ZONE], [FILTERS="d", DATA], [FLAGS="B"])`
|
|
146
|
+
+ the output**d**ir filter commands that zone(s) be flushed to path stored in the `DATA` section
|
|
147
|
+
* `zone-backup([ZONE], [FILTERS={"dzjtkocqZJTKOCQ"}, [DATA]], [FLAGS="B"])`
|
|
148
|
+
+ filters
|
|
149
|
+
- the backup**d**ir filter commands that backups be made to path stored in the `DATA` section
|
|
150
|
+
- **z**onefile, **j**ournal, **t**imers, **k**aspdb, keys**o**nly, **c**atalog, **q**uic
|
|
151
|
+
- negative counterparts (eg. no**Z**onefile) are symmetrical and capitalized
|
|
152
|
+
* `zone-restore` *analogous to `zone-backup`*
|
|
154
153
|
* `zone-sign([ZONE], [FLAGS="B"])`
|
|
155
154
|
* `zone-validate([ZONE], [FLAGS="B"])`
|
|
156
155
|
* `zone-keys-load([ZONE], [FLAGS="B"])`
|
|
@@ -163,39 +162,71 @@ The **`"B"`** flag always represents an option to execute in blocking mode.
|
|
|
163
162
|
|
|
164
163
|
#### Zone editing
|
|
165
164
|
|
|
166
|
-
Use
|
|
165
|
+
Use `@` as `OWNER` if you want to denote `ZONE` itself as the owner.
|
|
167
166
|
|
|
168
|
-
* `zone-read([ZONE
|
|
169
|
-
|
|
167
|
+
* `zone-read([ZONE], [OWNER], [TYPE])`
|
|
168
|
+
+ if `ZONE` is left empty all zones are read
|
|
169
|
+
* `zone-begin(ZONE, [FILTERS="b"])`
|
|
170
|
+
+ filters: **b**enevolent
|
|
170
171
|
* `zone-commit(ZONE)`
|
|
171
172
|
* `zone-abort(ZONE)`
|
|
172
173
|
* `zone-diff(ZONE)`
|
|
173
|
-
* `zone-get(ZONE, [OWNER], [TYPE])`
|
|
174
|
+
* `zone-get(ZONE, [OWNER], [TYPE])`
|
|
174
175
|
* `zone-set(ZONE, OWNER, [TTL], TYPE, DATA)`
|
|
175
176
|
* `zone-unset(ZONE, OWNER, [TYPE, [DATA]])`
|
|
176
177
|
* `zone-purge(ZONE, [FILTERS={ocejktf}], [FLAGS="B"])`
|
|
177
|
-
+
|
|
178
|
-
* `zone-stats(ZONE, [SECTION
|
|
178
|
+
+ filters: **o**rphan, **c**atalog, **e**xpire, **j**ournal, **k**aspdb, **t**imers, zone**f**ile
|
|
179
|
+
* `zone-stats(ZONE, [SECTION], [ITEM], [FLAGS="F"])`
|
|
180
|
+
+ `SECTION` stores the module, `ITEM` stores the counter
|
|
181
|
+
+ the `F` flag specifies to include 0 counters in server's response
|
|
179
182
|
|
|
180
183
|
#### Configuration
|
|
181
184
|
|
|
182
|
-
|
|
185
|
+
For the following commands:
|
|
186
|
+
|
|
187
|
+
* `SECTION` holds the configuration section name (eg. `template`)
|
|
188
|
+
* `ID` holds the configuration id (eg. `default`)
|
|
189
|
+
* `ITEM` holds the configuration item name (eg. `storage`)
|
|
183
190
|
|
|
184
|
-
|
|
185
|
-
· `SECTION` holds the configuration section name (eg. `template`)<br/>
|
|
186
|
-
· `ID` holds the configuration id (eg. `default`)<br/>
|
|
187
|
-
· `ITEM` holds the configuration item name (eg. `storage`)<br/>
|
|
191
|
+
<!-- hacky comment to separate markdown lists -->
|
|
188
192
|
|
|
189
|
-
* `conf-list([SECTION, [ID], [ITEM]], [FILTERS="
|
|
193
|
+
* `conf-list([SECTION, [ID], [ITEM]], [FILTERS="z"|{"st"}])`
|
|
194
|
+
+ filters:
|
|
195
|
+
- **z**one: list all zone names, including those from the catalog
|
|
196
|
+
- li**s**t: list configuration section items instead of its identifiers
|
|
197
|
+
- **t**ransaction: If a transaction is open (`conf-begin`) queries the
|
|
198
|
+
transaction's configuration schema instead of the server's
|
|
190
199
|
* `conf-read([SECTION, [ID], [ITEM]])`
|
|
191
200
|
* `conf-begin()`
|
|
192
201
|
* `conf-commit()`
|
|
193
202
|
* `conf-abort()`
|
|
194
203
|
* `conf-diff([SECTION, [ID], [ITEM]])`
|
|
195
204
|
* `conf-get([SECTION, [ID], [ITEM]])`
|
|
196
|
-
* `conf-set(SECTION, ID, ITEM, [DATA]
|
|
205
|
+
* `conf-set(SECTION, ID, ITEM, [DATA])`
|
|
197
206
|
* `conf-unset([SECTION, [ID], [ITEM]], [DATA])`
|
|
198
207
|
|
|
208
|
+
### Control usage<a id="control-usage"></a>
|
|
209
|
+
|
|
210
|
+
The module usage consists of several steps:
|
|
211
|
+
|
|
212
|
+
* Initialization and connection to the daemon control socket.
|
|
213
|
+
* One or more control operations. An operation is called by sending a command
|
|
214
|
+
with optional data to the daemon. The operation result has to be received
|
|
215
|
+
afterwards.
|
|
216
|
+
* Closing the connection and deinitialization.
|
|
217
|
+
|
|
218
|
+
#### Sending
|
|
219
|
+
|
|
220
|
+
There are two methods on the `KnotCtl` class which send data to the socket.
|
|
221
|
+
|
|
222
|
+
`KnotCtl.send(KnotCtlType, KnotCtlData)` is the more rudimentary one. It only
|
|
223
|
+
sends the section identifier along with its data, if any are provided. When
|
|
224
|
+
using this function users must beware of the different characteristics
|
|
225
|
+
regarding buffering of different unit types.
|
|
226
|
+
|
|
227
|
+
`KnotCtl.send_block(...)` is more convenient in that it always flushes by
|
|
228
|
+
sending a `BLOCK` unit. Otherwise the two methods are functionally equivalent.
|
|
229
|
+
|
|
199
230
|
### Control examples<a id="control-examples"></a>
|
|
200
231
|
|
|
201
232
|
```python3
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|