master
md 169 lines 6.79 KB
Rendered Raw
1 ---
2 name: project-snmp-profiles-authoring
3 description: Use when editing Netdata SNMP profile YAMLs, topology SNMP profiles, ddsnmp profile parsing, or profile-format documentation. Requires checking source MIB field accessibility, especially MAX-ACCESS not-accessible INDEX objects, before adding or changing profile symbols.
4 ---
5
6 # SNMP Profile Authoring
7
8 Use this skill before editing files under:
9
10 - `src/go/plugin/go.d/config/go.d/snmp.profiles/`
11 - `src/go/plugin/go.d/collector/snmp/ddsnmp/`
12 - `src/go/plugin/go.d/collector/snmp/profile-format.md`
13 - `src/go/plugin/go.d/collector/snmp_topology/`
14
15 ## Required Checks
16
17 1. Identify the source MIB object for every profile field being added or changed.
18 2. Check the object's `MAX-ACCESS`.
19 3. If the object is `not-accessible`, do not configure it as a readable `symbol.OID`.
20 4. If a `not-accessible` object appears in the table `INDEX`, derive it from the row OID index using `index` or `index_transform`.
21 5. Keep index extraction and value formatting separate:
22 - use `index` for one index component;
23 - use `index_transform` for multiple components;
24 - use `symbol.format` only for final formatting such as `ip_address`, `mac_address`, or `hex`.
25 6. Put SNMP topology rows under top-level `topology:` with a required closed
26 `kind`. Do not mark topology rows by naming metrics `_topology_*`.
27 7. Do not use chart/export-only value fields on topology row anchor symbols:
28 `chart_meta`, `metric_type`, `mapping`, `transform`, `scale_factor`,
29 `format`, or `constant_value_one`.
30 8. Keep regular `systemUptime` rows under `metrics:`. Do not model uptime as a
31 topology row kind; topology-specific uptime acquisition belongs in collector
32 code, not profile topology schema.
33 9. Put SNMP licensing rows under top-level `licensing:`. Do not model licensing
34 telemetry as underscore-prefixed hidden metrics or `_license_*` tag
35 protocols.
36 10. Licensing row value symbols may use `format` and exact `mapping`, but must
37 not use chart/export fields, transforms, scale factors, constant values, or
38 underscore-prefixed generated names.
39 11. For scalar licensing rows that combine multiple scalar signal OIDs into one
40 license row, declare an explicit stable `id:`. For table licensing rows,
41 keep `from:` references inside the same table OID and derive
42 `not-accessible` INDEX values from the row index.
43 12. Put SNMP BGP rows under top-level `bgp:`. Do not model BGP telemetry as
44 vendor-specific raw metrics, `virtual_metrics`, or underscore-prefixed tag
45 protocols when adding or migrating BGP coverage.
46 13. BGP peer-state mappings must use the six RFC 4271 canonical states
47 (`idle`, `connect`, `active`, `opensent`, `openconfirm`, `established`).
48 Use `partial: true` plus `partial_states` only when the source MIB is
49 intentionally partial.
50 14. For BGP table rows, derive `not-accessible` INDEX objects with exactly one
51 row-index selector: `index`, `index_from_end`, or `index_transform`. Use
52 `index_from_end` for trailing AFI/SAFI-like components after variable-length
53 indexes such as `InetAddress`.
54
55 ## Index Rules
56
57 - `index` is 1-based.
58 - `index_transform.start` and `index_transform.end` are 0-based and inclusive.
59 - `index_transform: [{start: N}]` keeps index component `N` through the last component when `N > 0`.
60 - `index_transform: [{start: 0, end: 0}]` keeps only the first index component.
61 - `drop_right` can be used when the right side has fixed trailing components.
62
63 ## Common Patterns
64
65 Q-BRIDGE learned FDB MAC:
66
67 ```yaml
68 - tag: dot1q_fdb_mac
69 symbol:
70 format: mac_address
71 index_transform:
72 - start: 1
73 ```
74
75 IP-MIB `ipNetToPhysicalTable` address:
76
77 ```yaml
78 - tag: arp_ip
79 symbol:
80 format: ip_address
81 index_transform:
82 - start: 3
83 ```
84
85 The `start: 3` skips `ifIndex`, address type, and the InetAddress length byte.
86
87 LLDP-MIB local management address:
88
89 ```yaml
90 - tag: lldp_loc_mgmt_addr
91 symbol:
92 name: lldpLocManAddr
93 format: hex
94 index_transform:
95 - start: 2
96 ```
97
98 The `start: 2` skips management-address subtype and length. Use `hex`, not
99 `ip_address`, because LLDP management addresses can carry non-IP subtypes; the
100 topology runtime normalizes IP-compatible bytes later.
101
102 ## Audit Recipe
103
104 When a profile reads a table column, verify that the MIB object is readable:
105
106 ```bash
107 rg -n -C 4 'OBJECT-TYPE|MAX-ACCESS[[:space:]]+not-accessible|ACCESS[[:space:]]+not-accessible' path/to/MIB
108 ```
109
110 For known topology-sensitive symbols, scan profile YAMLs before committing:
111
112 ```bash
113 rg -n 'name:[[:space:]]*(dot1qTpFdbAddress|ipNetToPhysicalIfIndex|ipNetToPhysicalNetAddressType|ipNetToPhysicalNetAddress|lldpLocManAddrSubtype|lldpLocManAddr)\b' src/go/plugin/go.d/config/go.d/snmp.profiles
114 ```
115
116 Any hit must be reviewed. It is valid only when the tag is index-derived and does not declare `symbol.OID` for a `not-accessible` object.
117
118 When adding a new topology kind, update all three parts together:
119
120 - profile YAML using `topology: - kind: <kind>`;
121 - the Go `TopologyKind` enum and validation;
122 - the topology cache handler registry and tests.
123
124 Verify that topology rows are delivered through `ProfileMetrics.TopologyMetrics`,
125 not through underscore-prefixed `HiddenMetrics`.
126
127 When adding or migrating licensing profile coverage, update all related parts
128 together:
129
130 - profile YAML using `licensing:`;
131 - the closed licensing signal/state/sentinel enums and validation when adding
132 new policy names;
133 - typed `ProfileMetrics.LicenseRows` producer/consumer tests;
134 - MIB evidence for every OID and every `not-accessible` index-derived field.
135
136 Verify that licensing rows are delivered through `ProfileMetrics.LicenseRows`,
137 not through underscore-prefixed `HiddenMetrics`.
138
139 When adding or migrating BGP profile coverage, update all related parts
140 together:
141
142 - profile YAML using `bgp:`;
143 - closed BGP row kind, peer-state, AFI/SAFI, and typed field validation when
144 adding new policy names or value domains;
145 - typed `ProfileMetrics.BGPRows` producer/consumer tests;
146 - MIB evidence for every OID and every `not-accessible` index-derived field;
147 - SNMP integration metadata and generated docs when public BGP capability
148 claims change.
149
150 Verify that BGP rows are delivered through `ProfileMetrics.BGPRows`, not
151 through `metrics:`, `virtual_metrics:`, or underscore-prefixed hidden metrics.
152
153 When adding or refactoring SNMP profile, parser, or topology tests, prefer
154 table-driven cases using `map[string]struct{}` keyed by test-case name when
155 the cases share setup and assertion shape. Use separate test functions only for
156 materially different setup or assertions.
157
158 ## Validation
159
160 Run the narrow suites for the changed area:
161
162 ```bash
163 cd src/go
164 go test ./plugin/go.d/collector/snmp/ddsnmp/ddprofiledefinition
165 go test ./plugin/go.d/collector/snmp/ddsnmp/ddsnmpcollector
166 go test ./plugin/go.d/collector/snmp_topology
167 ```
168
169 See `src/go/plugin/go.d/collector/snmp/profile-format.md` for the full profile syntax and the "Field accessibility" section.