master
md 185 lines 6.22 KB
Rendered Raw
1 # Verify network-connections layout tokens
2
3 ## Question
4
5 How can a developer verify that a local Cloud-connected Netdata Agent serves
6 `topology:network-connections` with the expected v1 link layout tokens and
7 correlation rule wiring, without exposing Cloud tokens, agent bearers, node ids,
8 machine GUIDs, claim ids, cookies, or raw endpoint rows?
9
10 This is a producer-contract validation recipe. It belongs to the developer
11 topology skill, not to the public/operator query skills.
12
13 ## Inputs
14
15 - Local Agent URL, usually `http://127.0.0.1:19999`; set `AGENT_URL` when
16 using a non-default address.
17 - `NETDATA_CLOUD_TOKEN` and `NETDATA_CLOUD_HOSTNAME` in `<repo>/.env`.
18 - A local Agent that exposes `topology:network-connections`.
19
20 ## Steps
21
22 1. Capture the local identity tuple in memory and print only presence
23 checks:
24
25 ```bash
26 AGENT_URL="${AGENT_URL:-http://127.0.0.1:19999}"
27 AGENT_URL="${AGENT_URL%/}"
28 AGENT_HOST="${AGENT_URL#http://}"
29 AGENT_HOST="${AGENT_HOST#https://}"
30 AGENT_HOST="${AGENT_HOST%%/*}"
31 AGENT_SCHEME="http"
32 case "$AGENT_URL" in
33 https://*) AGENT_SCHEME="https" ;;
34 esac
35 AGENT_ORIGIN="${AGENT_SCHEME}://${AGENT_HOST}"
36
37 INFO_JSON="$(curl --fail -sS --max-time 10 "${AGENT_ORIGIN}/api/v3/info")"
38
39 jq '{
40 agent_count: (.agents | length),
41 node_id_present: ((.agents[0].nd // "") | length > 0),
42 machine_guid_present: ((.agents[0].mg // "") | length > 0),
43 claim_id_present: ((.agents[0].cloud.claim_id // "") | length > 0),
44 cloud_status: .agents[0].cloud.status
45 }' <<<"$INFO_JSON"
46 ```
47
48 2. Load the token-safe direct-agent wrappers:
49
50 ```bash
51 source docs/netdata-ai/skills/query-netdata-agents/scripts/_lib.sh
52 agents_load_env
53 ```
54
55 3. Query the topology Function through the direct-agent path. Store the
56 raw response only under `.local/`:
57
58 ```bash
59 NODE_UUID="$(jq -r '.agents[0].nd' <<<"$INFO_JSON")"
60 MACHINE_GUID="$(jq -r '.agents[0].mg' <<<"$INFO_JSON")"
61 FUNCTION_NAME="topology:network-connections processes:by_name mode:aggregated sockets:inbound,outbound,listening,local protocols:ipv4_tcp,ipv6_tcp,ipv4_udp,ipv6_udp endpoints:by_ip"
62 FUNCTION_ENCODED="$(printf '%s' "$FUNCTION_NAME" | jq -sRr @uri)"
63 OUT="$(agents_audit_dir)/network-connections-aggregated-live.json"
64
65 agents_query_agent \
66 --node "$NODE_UUID" \
67 --host "$AGENT_HOST" \
68 --machine-guid "$MACHINE_GUID" \
69 GET "/api/v3/function?function=${FUNCTION_ENCODED}&timeout=120000&last=200" \
70 > "$OUT"
71 ```
72
73 4. Print a sanitized response summary:
74
75 ```bash
76 jq '{
77 status,
78 type,
79 schema_version: .data.schema_version,
80 actor_rows: .data.actors.rows,
81 link_rows: .data.links.rows,
82 correlation_point_rows: .data.correlation.points.rows,
83 correlation_claim_rows: .data.correlation.claims.rows
84 }' "$OUT"
85 ```
86
87 5. Verify the producer's link layout tokens:
88
89 ```bash
90 jq '.data.types.link_types
91 | with_entries({
92 key: .key,
93 value: {
94 label: .value.presentation.label,
95 color_slot: .value.presentation.color_slot,
96 line_style: .value.presentation.line_style,
97 width: .value.presentation.width,
98 variable: .value.presentation.variable,
99 layout: .value.presentation.layout
100 }
101 })' "$OUT"
102 ```
103
104 6. Verify correlation rule wiring without printing endpoint rows:
105
106 ```bash
107 jq '.data.correlation.rules
108 | with_entries({
109 key: .key,
110 value: {
111 action: .value.action,
112 priority: .value.priority,
113 key_space: .value.key_space,
114 point_actor_types: .value.point_actor_types,
115 claim_actor_types: .value.claim_actor_types,
116 correlation_link_types: .value.correlation_link_types,
117 output_link_type: .value.output_link_type
118 }
119 })' "$OUT"
120 ```
121
122 7. Count graph links by type from the compact table:
123
124 ```bash
125 jq -r '
126 .data as $d
127 | def col($table; $name):
128 ($table.columns | map(.id) | index($name)) as $i
129 | $table.values[$i];
130 def v($c; $i):
131 if $c.codec == "const" then $c.value
132 elif $c.codec == "values" then $c.values[$i]
133 elif $c.codec == "dict" then $c.values[$c.indexes[$i]]
134 else null end;
135 (col($d.links; "type")) as $typeCol
136 | (col($d.links; "socket_count")) as $socketCol
137 | [range(0; $d.links.rows)
138 | {type: v($typeCol; .), socket_count: (v($socketCol; .) // 0)}]
139 | group_by(.type)
140 | map({type: .[0].type, links: length, sockets: (map(.socket_count) | add)})
141 | sort_by(.type)
142 | .[]
143 | [.type, .links, .sockets]
144 | @tsv
145 ' "$OUT"
146 ```
147
148 ## Output
149
150 For the current network-connections v1 contract, expect these link
151 types:
152
153 - `endpoint_socket`: visible unresolved endpoint links, weakest
154 strength, normal distance.
155 - `correlated_socket`: Cloud aggregator output after exact absorption,
156 weakest strength, farthest distance.
157 - `socket`: local/resolved process links, stronger strength, farther
158 distance, variable width by `socket_count`.
159 - `ownership`: graph-coherence node-to-process links, dotted/faded,
160 normal strength, normal distance.
161
162 The `socket_exact` correlation rule should consume `endpoint_socket`
163 through `correlation_link_types` and emit `correlated_socket` through
164 `output_link_type`.
165
166 ## Notes / gotchas
167
168 - The wrapper logs masked curl commands on stderr. Cloud tokens,
169 per-agent bearers, node ids, machine GUIDs, and claim ids must not
170 appear in stdout or committed files.
171 - Keep the raw Function response under `.local/`; it may contain
172 hostnames, private addresses, and process names.
173 - A rendered graph can still look stretched even when the payload uses
174 `endpoint_socket` with normal distance. That is a frontend force-layout
175 issue, not proof that the backend emitted `farthest`.
176 - Compact topology tables require decoding the column codec before
177 counting rows by type. Do not assume the high-cardinality rows are
178 emitted as arrays of objects.
179
180 ## Source guides
181
182 - [Topology producer skill](../SKILL.md)
183 - [Direct-agent operator skill](../../../../docs/netdata-ai/skills/query-netdata-agents/SKILL.md)
184 - [Direct Function calls](../../../../docs/netdata-ai/skills/query-netdata-agents/query-functions.md)
185 - [Direct topology calls](../../../../docs/netdata-ai/skills/query-netdata-agents/query-topology.md)