master
md 334 lines 10.5 KB
Rendered Raw
1 # Query Netdata Dynamic Configuration (DynCfg)
2
3 This guide is part of the [`query-netdata-cloud`](./SKILL.md) skill.
4 Read the [SKILL.md prerequisites](./SKILL.md#prerequisites) first.
5
6 DynCfg is Netdata's dynamic-configuration system. Every plugin /
7 collector / module that participates registers configuration
8 objects which the user can list, view, edit, enable, disable, add,
9 remove, test, restart, and export -- through a single REST surface
10 distinct from the Function-call surface. Internally DynCfg is
11 implemented on top of Functions, but it has its own dedicated API
12 endpoint. Don't confuse the two: function-call paths
13 (`/api/v2/nodes/{nodeID}/function?function=...`) DO NOT operate on
14 configuration.
15
16 **Canonical references** (authoritative; read these for full detail):
17
18 | File | What it covers |
19 |---|---|
20 | `<repo>/src/daemon/dyncfg/README.md` | Internal-plugin DynCfg API and lifecycle (high-level + low-level) |
21 | `<repo>/src/plugins.d/DYNCFG.md` | External-plugin (go.d.plugin, etc.) DynCfg protocol |
22
23 ---
24
25 ## Mandatory Requirements (READ FIRST)
26
27 1. **Provide actionable instructions.** Each answer ends in a
28 runnable curl command.
29 2. **Never request credentials.** Use `YOUR_API_TOKEN`,
30 `YOUR_NODE_UUID`, etc. placeholders.
31 3. **Read actions are GET; write actions are POST.** Cloud's
32 permission gate is `PermissionFunctionExecPrivileged` for the
33 write paths. A read-only token cannot mutate configuration.
34 4. **The `action=tree` listing is the entry point.** Always start
35 there; the IDs returned are the inputs to all other actions.
36
37 ---
38
39 ## Endpoints
40
41 ### Cloud-proxied (preferred)
42
43 | Method | Path | Purpose | Permission |
44 |---|---|---|---|
45 | `GET` | `/api/v2/nodes/{nodeID}/config?action=tree&path=/` | List configuration objects | `nodeAuth()` |
46 | `GET` | `/api/v2/nodes/{nodeID}/config?action=<read-action>&id=<id>` | Read one configuration | `nodeAuth()` |
47 | `POST` | `/api/v2/nodes/{nodeID}/config?action=<write-action>&id=<id>[&name=<name>]` | Mutate configuration (body = the configuration JSON) | `PermissionFunctionExecPrivileged` |
48
49 Cloud-side route registration:
50 `cloud-charts-service/http/http.go:150-151`.
51
52 ### Direct-agent (fallback)
53
54 Same shape, served by the agent itself:
55 `http://<agent>:19999/host/{nodeID}/api/v3/config?...`. The agent
56 also accepts `/api/v1/config` for backwards compatibility -- both
57 paths use the same handler at
58 `<repo>/src/web/api/v1/api_v1_config.c`.
59
60 For direct-agent calls, `X-Netdata-Auth: Bearer <agent-bearer>` is
61 required when the agent is bearer-protected. See the
62 [`query-netdata-agents`](../query-netdata-agents/SKILL.md) skill
63 for the bearer mint/cache flow.
64
65 ---
66
67 ## Query parameters
68
69 The handler at `<repo>/src/web/api/v1/api_v1_config.c:5-80` accepts
70 these query parameters:
71
72 | Param | Required for | Purpose |
73 |---|---|---|
74 | `action` | every call (defaults to `tree`) | Which DynCfg command to execute |
75 | `path` | `tree` | Path within the configuration tree (e.g. `/`, `/health/alerts/prototypes`) |
76 | `id` | every action except `tree` | Configuration object id (colon-separated, e.g. `health:alert:prototype:ram_usage`) |
77 | `name` | `add`, `userconfig`, `test` | Job/object name when adding to a template, getting user-config, or testing |
78 | `timeout` | optional (default 120) | Operation timeout in seconds; minimum 10 |
79
80 The body of a `POST` carries the **payload** for write actions
81 (the configuration JSON to apply, or the test input for `test`).
82
83 ---
84
85 ## DynCfg actions
86
87 From `<repo>/src/daemon/dyncfg/README.md` and the agent's command
88 enum:
89
90 | `action` value | Method | Purpose |
91 |---|---|---|
92 | `tree` | GET | List configuration objects under `path` |
93 | `schema` | GET | JSON Schema for a configuration object |
94 | `get` | GET | Current value of a configuration object |
95 | `userconfig` | GET | Configuration in user-friendly form (used for conf files); requires `name` |
96 | `update` | POST | Replace a configuration object's value (body = new JSON) |
97 | `add` | POST | Add a new job to a template; requires `name` |
98 | `remove` | POST | Remove a `dyncfg`-source job (cannot remove user-file jobs) |
99 | `enable` | POST | Enable a configuration object |
100 | `disable` | POST | Disable a configuration object |
101 | `test` | POST | Test a configuration without applying it; requires `name`; body = the candidate JSON |
102 | `restart` | POST | Restart the configuration / re-apply |
103
104 ### DynCfg response codes
105
106 DynCfg uses HTTP-like codes verified against
107 `<repo>/src/daemon/dyncfg/README.md`:
108
109 | Code | Meaning |
110 |---|---|
111 | 200 | Running -- accepted and active |
112 | 202 | Accepted -- queued, not yet running |
113 | 298 | Accepted but disabled |
114 | 299 | Accepted but restart required |
115 | 400 | Bad request / invalid configuration |
116 | 404 | Configuration id not found |
117 | 500 | Internal error |
118 | 501 | Action not implemented for this object |
119
120 ---
121
122 ## Configuration ID structure
123
124 Configuration IDs follow a colon-separated hierarchy
125 (`<repo>/src/daemon/dyncfg/README.md`):
126
127 ```
128 component:category:name
129 component:template_name:job_name
130 ```
131
132 Examples (verified live -- agent-events node returns these under
133 `tree`):
134
135 - `/collectors/go.d/Jobs` -- the go.d.plugin Jobs tree
136 - `/collectors/go.d/ServiceDiscovery`
137 - `/collectors/go.d/Vnodes`
138 - `/collectors/ibm.d/Jobs`
139 - `/collectors/ibm.d/Vnodes`
140 - `/health/alerts/prototypes` -- alert prototypes
141 - `/logs/systemd-journal` -- systemd-journal collector configs
142
143 Each tree entry contains configuration objects with their own ids
144 (e.g. `health:alert:prototype:ram_usage`,
145 `go.d:nginx:local_server`).
146
147 ### Templates vs Jobs
148
149 - **Template id**: `component:template_name`. Templates DEFINE the
150 schema for jobs. They cannot be `update`d but can be `add`'d to.
151 - **Job id**: `component:template_name:job_name`. The portion
152 before the last colon must match an existing template id.
153 - **Single id**: `component:name`. A standalone configuration
154 object that is neither template nor job.
155
156 ---
157
158 ## Examples
159
160 ### Example 1: list every configuration object on a node
161
162 ```bash
163 TOKEN="YOUR_API_TOKEN"
164 NODE="YOUR_NODE_UUID"
165
166 curl -sS \
167 -H "Authorization: Bearer $TOKEN" \
168 "https://app.netdata.cloud/api/v2/nodes/$NODE/config?action=tree&path=/"
169 ```
170
171 Response top level (verified live): `{agent, attention, tree,
172 version}`. The `tree` is keyed by configuration path; each entry
173 lists per-object ids, types, statuses, supported commands, and
174 sources.
175
176 ### Example 2: get the JSON Schema for an alert prototype
177
178 ```bash
179 TOKEN="YOUR_API_TOKEN"
180 NODE="YOUR_NODE_UUID"
181 ID="health:alert:prototype:ram_usage"
182
183 curl -sS \
184 -H "Authorization: Bearer $TOKEN" \
185 "https://app.netdata.cloud/api/v2/nodes/$NODE/config?action=schema&id=$(printf %s "$ID" | jq -sRr @uri)"
186 ```
187
188 The schema describes which fields the configuration accepts and is
189 the basis for any UI form. Use this before constructing an
190 `update` payload.
191
192 ### Example 3: read the current value of a configuration
193
194 ```bash
195 TOKEN="YOUR_API_TOKEN"
196 NODE="YOUR_NODE_UUID"
197 ID="health:alert:prototype:ram_usage"
198
199 curl -sS \
200 -H "Authorization: Bearer $TOKEN" \
201 "https://app.netdata.cloud/api/v2/nodes/$NODE/config?action=get&id=$(printf %s "$ID" | jq -sRr @uri)"
202 ```
203
204 ### Example 4: add a new go.d.plugin job to a template
205
206 ```bash
207 TOKEN="YOUR_API_TOKEN"
208 NODE="YOUR_NODE_UUID"
209 TPL_ID="go.d:nginx"
210 JOB_NAME="local_server"
211
212 read -r -d '' PAYLOAD <<'EOF'
213 {
214 "url": "http://127.0.0.1:80/stub_status",
215 "update_every": 5,
216 "timeout": 2
217 }
218 EOF
219
220 curl -sS -X POST \
221 -H 'Content-Type: application/json' \
222 -H "Authorization: Bearer $TOKEN" \
223 "https://app.netdata.cloud/api/v2/nodes/$NODE/config?action=add&id=$(printf %s "$TPL_ID" | jq -sRr @uri)&name=$JOB_NAME" \
224 -d "$PAYLOAD"
225 ```
226
227 ### Example 5: test a configuration without applying it
228
229 ```bash
230 TOKEN="YOUR_API_TOKEN"
231 NODE="YOUR_NODE_UUID"
232 TPL_ID="go.d:nginx"
233 JOB_NAME="local_server"
234
235 read -r -d '' PAYLOAD <<'EOF'
236 {
237 "url": "http://127.0.0.1:80/stub_status",
238 "update_every": 5
239 }
240 EOF
241
242 curl -sS -X POST \
243 -H 'Content-Type: application/json' \
244 -H "Authorization: Bearer $TOKEN" \
245 "https://app.netdata.cloud/api/v2/nodes/$NODE/config?action=test&id=$(printf %s "$TPL_ID" | jq -sRr @uri)&name=$JOB_NAME" \
246 -d "$PAYLOAD"
247 ```
248
249 A successful response (200/202) means the configuration would
250 work; the test does NOT make the change persistent.
251
252 ### Example 6: enable / disable a configuration
253
254 ```bash
255 TOKEN="YOUR_API_TOKEN"
256 NODE="YOUR_NODE_UUID"
257 ID="go.d:nginx:local_server"
258
259 # Enable
260 curl -sS -X POST \
261 -H "Authorization: Bearer $TOKEN" \
262 "https://app.netdata.cloud/api/v2/nodes/$NODE/config?action=enable&id=$(printf %s "$ID" | jq -sRr @uri)"
263
264 # Disable
265 curl -sS -X POST \
266 -H "Authorization: Bearer $TOKEN" \
267 "https://app.netdata.cloud/api/v2/nodes/$NODE/config?action=disable&id=$(printf %s "$ID" | jq -sRr @uri)"
268 ```
269
270 ### Example 7: remove a dyncfg-created job
271
272 ```bash
273 TOKEN="YOUR_API_TOKEN"
274 NODE="YOUR_NODE_UUID"
275 ID="go.d:nginx:local_server"
276
277 curl -sS -X POST \
278 -H "Authorization: Bearer $TOKEN" \
279 "https://app.netdata.cloud/api/v2/nodes/$NODE/config?action=remove&id=$(printf %s "$ID" | jq -sRr @uri)"
280 ```
281
282 Only objects whose `source_type == DYNCFG_SOURCE_TYPE_DYNCFG` (i.e.
283 created via DynCfg, not from user files or internally) can be
284 removed.
285
286 ### Example 8: get a job's user-friendly configuration (for conf-file export)
287
288 ```bash
289 TOKEN="YOUR_API_TOKEN"
290 NODE="YOUR_NODE_UUID"
291 ID="go.d:nginx"
292 JOB_NAME="local_server"
293
294 curl -sS \
295 -H "Authorization: Bearer $TOKEN" \
296 "https://app.netdata.cloud/api/v2/nodes/$NODE/config?action=userconfig&id=$(printf %s "$ID" | jq -sRr @uri)&name=$JOB_NAME"
297 ```
298
299 ---
300
301 ## Source types
302
303 A configuration object's `source_type` (verified in
304 `<repo>/src/daemon/dyncfg/README.md`) determines what's allowed:
305
306 | Source type | Origin | Removable? |
307 |---|---|---|
308 | `INTERNAL` | Defined inside Netdata code | No |
309 | `DYNCFG` | Created or modified through DynCfg | Yes |
310 | `USER` | Loaded from user-provided conf files in `/etc/netdata/...` | No (edit the file instead) |
311
312 ---
313
314 ## Direct-agent reload note
315
316 There is **no REST endpoint to reload `/etc/netdata/health.d/*.conf`
317 files** -- DynCfg manages dynamic configuration objects, not raw
318 file reload. To reload static health/alert files, send `SIGHUP` to
319 the agent process or use the dyncfg `restart` action on the
320 relevant configuration object.
321
322 ---
323
324 ## Sensitive data
325
326 DynCfg responses can include credentials embedded in collector
327 job configurations (database URIs, API tokens used by collectors,
328 etc.). Treat raw responses as production-sensitive:
329
330 - Direct working output to `<repo>/.local/audits/...` (gitignored).
331 - Never paste raw `get` / `userconfig` payloads into committed
332 files.
333 - See `<repo>/.agents/sow/specs/sensitive-data-discipline.md` for
334 the full rule.