SnmpKit.Agent.Table (snmpkit v2.0.1)
Serves a conceptual table from rows produced by a function.
Register it at the table's entry OID (ifEntry, not ifTable):
SnmpKit.Agent.register(agent, "ifEntry", SnmpKit.Agent.Table,
columns: [{1, :integer}, {2, :octet_string}, {5, :gauge32}, {8, :integer}],
index: [:integer],
rows: fn ->
for {port, i} <- Enum.with_index(MyApp.Ports.all(), 1) do
{i, %{1 => i, 2 => port.name, 5 => port.speed, 8 => if(port.up?, do: 1, else: 2)}}
end
end
)Options
:columns- the column numbers and their types, as a list of{column, type}or a map:index- the INDEX objects' kinds, in order (default[:integer])::integer,:string(length-prefixed),:implied_string,:ip_address,:oid,:implied_oid:rows- a zero-arity function returning[{index, values}]whereindexis the index value (or a list of values, one per INDEX object) andvaluesmaps column numbers to values; a missing column isnoSuchInstance:set- optionalfun(index, column, {type, value}) :: :ok | {:error, reason}making the table writable; the row must already exist
Cost
Rows are fetched once per request (every PDU, including each GETBULK of a walk), so one request sees a consistent snapshot. Within that request the first GET or SET encodes every row's index once (O(rows)) and each further lookup is a map lookup; the first GETNEXT encodes and sorts every cell once (O(cells log cells)) and each further step is a binary search. A walk therefore costs one rows call and one sort per PDU, not per object. Tables with tens of thousands of rows are still better served by a handler of their own that can seek directly.
Summary
Functions
Encodes index values as instance sub-identifiers (RFC 2578 section 7.7).
Types
Functions
@spec encode_index(term() | [term()], [index_kind()]) :: [non_neg_integer()]
Encodes index values as instance sub-identifiers (RFC 2578 section 7.7).
iex> SnmpKit.Agent.Table.encode_index([{10, 0, 0, 1}, "eth0"], [:ip_address, :string])
[10, 0, 0, 1, 4, ?e, ?t, ?h, ?0]