gNMI Server#
Introduction#
On top of acting as gNMI client gNMIc can run a gNMI server that supports Get, Set and Subscribe RPCs.
The goal is to act as a caching point for the collected gNMI notifications and make them available to other collectors via the Subscribe RPC.
Using this gNMI server feature it is possible to build gNMI based clusters and pipelines with gNMIc.
The server keeps a cache of the gNMI notifications received from the defined subscriptions and serves the Subscribe and Get RPCs from it.
The Set RPC is relayed to known targets based on the Prefix.Target field, when enabled with read-only: false.
To relay every RPC to the targets instead of serving the cache, use the proxy command.
Supported features#
- Supports gNMI RPCs, Get, Set, Subscribe
- Serves
GetRPCs from the cache. - Acts as a gNMI gateway for Set RPCs (disabled by default, see read-only).
- Supports Service registration with Consul server.
- Supports all types of gNMI subscriptions,
once,poll,stream. - Supports all types of
streamsubscriptions,on-change,target-definedandsample. - Supports
updates-onlywithstreamandoncesubscriptions. - Supports
suppress-redundant. - Supports
heartbeat-intervalwithon-changeandsamplestream subscriptions.
Get RPC#
The server supports the gNMI Get RPC and answers it from its cache: the notifications stored for the selected target(s) under the requested path(s) are returned in a single GetResponse, as they were received from the targets, with their original timestamps and encoding.
It relies on the GetRequest Prefix.Target field to select the target(s).
If Prefix.Target is left empty or is equal to *, the notifications of all cached targets are returned.
Comma separated target names are also supported and allow to select a list of specific targets.
gnmic -a gnmic-server:57400 get --path /interfaces \
--target router1,router2,router3
The request Prefix path elements are prepended to each requested path. Wildcards (*) are supported in path keys.
Only data received through the configured subscriptions is present in the cache: a path that is not subscribed, or a target that has not sent any data yet, yields an empty GetResponse, not an error. Entries older than the cache expiration are not returned.
Since the values come from the cache, the GetRequest type and encoding fields are accepted but ignored: the values are returned in the encoding the targets produced.
Note
Prior to v0.49.0 the Get RPC was relayed to the targets. To relay Get RPCs to the targets, use the proxy command.
If the GetRequest Path has the Origin field set to gnmic, the request is performed against the internal gNMIc server configuration. Currently only the paths targets and subscriptions are supported.
gnmic -a gnmic-server:57400 get --path gnmic:/targets
gnmic -a gnmic-server:57400 get --path gnmic:/subscriptions
Set RPC#
This gNMI server supports the gNMI Set RPC, it allows a client to run a single Set RPC against multiple targets.
Note
The Set RPC is disabled by default: the server runs in read-only mode and rejects Set requests with an Unimplemented status code. Set read-only: false under the gnmi-server section to enable it.
Just like in the case of Get RPC, the server relies on the Prefix.Target field to select the target(s) against which it will run the Set RPC.
If Prefix.Target is left empty or is equal to *, a Set RPC is performed against all known targets. The received SetRequest is cloned, enriched with each target name and sent to the corresponding destination.
Comma separated target names are also supported and allow to select a list of specific targets to send the Set RPC to.
gnmic -a gnmic-server:57400 set \
--update /system/ssh-server/admin-state:::json:::disable \
--target router1,router2,router3
Once all SetResponses are received back successfully, the UpdateResults from each response are merged into a single SetResponse, with the addition of the target name set in Path.Target.
Note
Adding a target value to a non prefix path is not compliant with the gNMI specification which stipulates that the Target field should only be present in Prefix Paths
The resulting SetResponse is then returned to the gNMI client. If one of the RPCs fails, an error with status code Internal(13) is returned to the client.
Subscribe RPC#
The gNMIc server keeps a cache of gNMI notifications synched with the configured targets based on the configured subscriptions.
The Subscribe requests received from a client are run against the afore mentioned cache, this means that a client cannot get updates about a leaf that gNMIc did not subscribe to as a client.
Clients can subscribe to specific target using the gNMI Prefix.Target field, while leaving the Prefix.Target field empty or setting it to * is equivalent to subscribing to all known targets.
Subscription Mode#
gNMIc gNMI Server supports the 3 gNMI specified subscription modes: Once, Poll and Stream.
It also supports some subscription behavior modifiers:
updates-onlywithstreamandoncesubscriptions.suppress-redundant.heartbeat-intervalwithon-changeandsamplestream subscriptions.
Once#
A subscription operating in the ONCE mode acts as a single request/response channel. The target creates the relevant update messages, transmits them, and subsequently closes the RPC.
In this subscription mode, gNMIc server supports the updates-only knob.
Poll#
Polling subscriptions are used for on-demand retrieval of data items via long-lived RPCs. A poll subscription relates to a certain set of subscribed paths, and is initiated by sending a SubscribeRequest message with encapsulated SubscriptionList. Subscription messages contained within the SubscriptionList indicate the set of paths that are of interest to the polling client.
Stream#
Stream subscriptions are long-lived subscriptions which continue to transmit updates relating to the set of paths that are covered within the subscription indefinitely.
In this subscription mode, gNMIc server supports the updates-only knob.
On Change#
When a subscription is defined to be on-change, data updates are only sent to the client when the value of the data item changes.
In the case of gNMIc gNMI server, on-change subscriptions depend on the subscription writing data to the local cache, if it is a sample subscription, each update from a target will trigger an on-change update to the server client.
gNMIc gNMI server supports on-change subscriptions with heartbeat-interval. If the heartbeat-interval value is set to a non zero value, the value of the data item(s) MUST be re-sent once per heartbeat interval regardless of whether the value has changed or not.
Note
The minimum heartbeat-interval is configurable using the field min-heartbeat-interval. It defaults to 1s
If the received heartbeat-interval value is greater than zero but lower than min-heartbeat-interval, the min-heartbeat-interval value is used instead.
Target Defined#
When a client creates a subscription specifying the target defined mode, the target MUST determine the best type of subscription to be created on a per-leaf basis.
In the case of gNMIc gNMI server, a target-defined stream subscription, is treated as an on-change subscription.
Note that this does not mean that gNMIc will filter out the unchanged values received from a sample subscription to the actual targets.
Sample#
A sample subscription is one where data items are sent to the client once per sample-interval.
The minimum supported sample-interval is configurable using the field min-sample-interval, defaults to 1ms.
If within a SubscribeRequest the received sample-interval is zero, the default-sample-interval is used, defaults to 1s.
Configuration#
gnmi-server:
# the address the gNMI server will listen to
address: :57400
# tls config
tls:
# string, path to the CA certificate file,
# this certificate is used to verify the clients certificates.
ca-file:
# string, server certificate file.
cert-file:
# string, server key file.
key-file:
# string, one of `"", "request", "require", "verify-if-given", or "require-verify"
# - request: The server requests a certificate from the client but does not
# require the client to send a certificate.
# If the client sends a certificate, it is not required to be valid.
# - require: The server requires the client to send a certificate and does not
# fail if the client certificate is not valid.
# - verify-if-given: The server requests a certificate,
# does not fail if no certificate is sent.
# If a certificate is sent it is required to be valid.
# - require-verify: The server requires the client to send a valid certificate.
#
# if no ca-file is present, `client-auth` defaults to ""`
# if a ca-file is set, `client-auth` defaults to "require-verify"`
client-auth: ""
max-subscriptions: 64
# maximum number of active Get/Set RPCs
max-unary-rpc: 64
# Unary RPC request timeout
unary-rpc-timeout: 120s
# defines the maximum msg size (in bytes) the server can receive,
# defaults to 4MB
max-recv-msg-size:
# defines the maximum msg size (in bytes) the server can send,
# default to MaxInt32 (2147483647 bytes or 2.147483647 Gb)
max-send-msg-size:
# defines the maximum number of streams per streaming RPC.
max-concurrent-streams:
# defines the TCP keepalive tiem and interval for client connections,
# if unset it is enabled based on the OS. If negative it is disabled.
tcp-keepalive:
# set keepalive and max-age parameters on the server-side.
keepalive:
# MaxConnectionIdle is a duration for the amount of time after which an
# idle connection would be closed by sending a GoAway. Idleness duration is
# defined since the most recent time the number of outstanding RPCs became
# zero or the connection establishment.
# The current default value is infinity.
max-connection-idle:
# MaxConnectionAge is a duration for the maximum amount of time a
# connection may exist before it will be closed by sending a GoAway. A
# random jitter of +/-10% will be added to MaxConnectionAge to spread out
# connection storms.
# The current default value is infinity.
max-connection-age:
# MaxConnectionAgeGrace is an additive period after MaxConnectionAge after
# which the connection will be forcibly closed.
# The current default value is infinity.
max-connection-age-grace:
# After a duration of this time if the server doesn't see any activity it
# pings the client to see if the transport is still alive.
# If set below 1s, a minimum value of 1s will be used instead.
# The current default value is 2 hours.
time: 120m
# After having pinged for keepalive check, the server waits for a duration
# of Timeout and if no activity is seen even after that the connection is
# closed.
# The current default value is 20 seconds.
timeout: 20s
# defines the minimum allowed sample interval, this value is used when the received sample-interval
# is greater than zero but lower than this minimum value.
min-sample-interval: 1ms
# defines the default sample interval,
# this value is used when the received sample-interval is zero within a stream/sample subscription.
default-sample-interval: 1s
# defines the minimum heartbeat-interval
# this value is used when the received heartbeat-interval is greater than zero but
# lower than this minimum value
min-heartbeat-interval: 1s
# enables the collection of Prometheus gRPC server metrics
enable-metrics: false
# enable additional debug logs
debug: false
# when true, the server rejects Set RPCs with an `Unimplemented` status code.
# set to false to allow clients to run Set RPCs against the known targets.
read-only: true
# Enables Consul service registration
service-registration:
# Consul server address, default to localhost:8500
address:
# Consul Data center, defaults to dc1
datacenter:
# Consul username, to be used as part of HTTP basicAuth
username:
# Consul password, to be used as part of HTTP basicAuth
password:
# Consul Token, is used to provide a per-request ACL token
# which overrides the agent's default token
token:
# gnmi server service check interval, only TTL Consul check is enabled
# defaults to 5s
check-interval:
# Maximum number of failed checks before the service is deleted by Consul
# defaults to 3
max-fail:
# Consul service name
name:
# List of tags to be added to the service registration,
# if available, the instance-name and cluster-name will be added as tags,
# in the format: gnmic-instance=$instance-name and gnmic-cluster=$cluster-name
tags:
# cache configuration
cache:
# cache type, defaults to `oc`
type: oc
# string, address of the remote cache server,
# irrelevant if type is `oc`
address:
# string, the remote server username.
username:
# string, the remote server password.
password:
# string, expiration period of received messages.
expiration: 60s
# enable extra logging
debug: false
# int64, default: 1073741824 (1 GiB).
# Max number of bytes stored in the cache per subscription.
max-bytes:
# int64, default: 1048576.
# Max number of messages stored per subscription.
max-msgs-per-subscription:
# int, default 100.
# Batch size used by the JetStream pull subscriber.
fetch-batch-size:
# duration, default 100ms.
# Wait time used by the JetStream pull subscriber.
fetch-wait-time:
Secure vs Insecure Server#
Insecure Mode#
By default, the server runs in insecure mode, as long as skip-verify is false and none of ca-file, cert-file and key-file are set.
Secure Mode#
To run this gNMI server in secure mode, there are a few options:
- Using self signed certificates, without client certificate verification:
gnmi-server:
skip-verify: true
- Using self signed certificates, with client certificate verification:
gnmi-server:
# a valid CA certificate to verify the client provided certificates
ca-file: /path/to/caFile
- Using CA provided certificates, without client certificate verification:
gnmi-server:
skip-verify: true
# a valid server certificate
cert-file: /path/to/server-cert
# a valid server key
key-file: /path/to/server-key
- Using CA provided certificates, with client certificate verification:
gnmi-server:
# a valid CA certificate to verify the client provided certificates
ca-file: /path/to/caFile
# a valid server certificate
cert-file: /path/to/server-cert
# a valid server key
key-file: /path/to/server-key
Fields#
address#
Defines the address the gNMI server will listen to.
This can be a tcp socket in the format <addr:port> or a unix socket starting with unix:///
skip-verify#
If true, the server will not verify the client's certificates.
ca-file#
Defines the path to the CA certificate file to be used, irrelevant if skip-verify is true
cert-file#
Defines the path to the server certificate file to be used.
key-file#
Defines the path to the server key file to be used.
max-subscriptions#
Defines the maximum number of allowed subscriptions.
Defaults to 64.
max-unary-rpc#
Defines the maximum number of active Get/Set RPCs.
Defaults to 64.
min-sample-interval#
Defines the minimum allowed sample interval, this value is used when the received sample-interval is greater than zero but lower than this minimum value.
Defaults to 1ms
default-sample-interval#
Defines the default sample interval, this value is used when the received sample-interval is zero within a stream/sample subscription.
Defaults to 1s
min-heartbeat-interval#
Defines the minimum heartbeat-interval, this value is used when the received heartbeat-interval is greater than zero but lower than this minimum value.
Defaults to 1s
enable-metrics#
Enables the collection of Prometheus gRPC server metrics.
read-only#
When true, the server runs in read-only mode: Set RPCs are rejected with an Unimplemented status code.
Set it to false to allow clients to run Set RPCs against the known targets.
Defaults to true.
debug#
Enables additional debug logging.
Caching#
By default, the gNMI server uses Openconfig's gNMI cache as a backend.
Distributed caching is supported using any of the other cache types specified here.
When a distributed cache is used together with the gNMI server feature, a gNMI client can subscribe to any of the gNMI servers to get gNMI updates collected from all the targets.
On the other hand, if the gNMI client sends a unary RPC (Get, Set), it will have be directed to the gNMI server directly connected to the target.
gnmi-server:
#
# other gnmi-server attributes
#
cache:
# cache type, defaults to `oc`
type: oc # redis, nats or jetstream
# string, address of the remote cache server,
# irrelevant if type is `oc`
address:
# string, the remote server username.
username:
# string, the remote server password.
password:
# string, expiration period of received messages.
expiration: 60s
# enable extra logging.
debug: false
# int64, default: 1073741824 (1 GiB).
# Max number of bytes stored in the cache per subscription.
max-bytes:
# int64, default: 1048576.
# Max number of messages stored per subscription.
max-msgs-per-subscription:
# int, default 100.
# Batch size used by the JetStream pull subscriber.
fetch-batch-size:
# duration, default 100ms.
# Wait time used by the JetStream pull subscriber.
fetch-wait-time: