-
Notifications
You must be signed in to change notification settings - Fork 40
gRPC
The Holo daemon includes a gRPC module that can be used to configure and monitor the daemon programatically. The module is enabled by default and listens on the 50051 TCP port.
The interface's definition is specified in the holo.proto file, available at https://github.com/rwestphal/holo/blob/master/proto/holo.proto.
Compared to the gNMI interface, the gRPC interface is simpler and supports the following additional features:
- Confirmed commits: Commits are rolled back if they are not confirmed within a specified time frame.
- Configuration validation: Allows validation of configurations without committing them.
- Configuration rollbacks: Provides support for reverting to previous configurations stored in non-volatile memory.
- Network-wide transactions: The ability to update the entire network in a pseudo-atomic fashion. This means that either all devices are updated, or none of them are.
- Use of YANG Patch to update the running configuration.
- YANG RPC/Action support: Enables the invocation of YANG-modeled RPCs, such as clearing protocol statistics or resetting neighborships. (Note: In the OpenConfig space, the gNOI interface is used for that purpose)
- Support for the XML and LYB data encodings.
While the gRPC interface provides these benefits, the gNMI interface is an industry standard and may be the preferred choice for those working with a heterogeneous network where a single management interface for all devices is desired.
The following RPCs are supported:
The Capabilities RPC is used to retrieve the device capabilities, including the Holo version, supported modules, and supported data encodings.
Ruby example:
require 'holo_services_pb'
# Connect to holod
stub = Holo::Northbound::Stub.new('localhost:50051', :this_channel_is_insecure)
# Invoke RPC
request = Holo::CapabilitiesRequest.new
response = stub.capabilities(request)
# Print the response
pp response.version
pp response.supported_modules
pp response.supported_encodings$ ruby -I. ./caps.rb | head -n 10
"0.1.0"
[<Holo::ModuleData: name: "iana-if-type", organization: "IANA", revision: "2017-01-19">,
<Holo::ModuleData: name: "ietf-interfaces", organization: "IETF NETMOD (Network Modeling) Working Group", revision: "2018-01-09">,
<Holo::ModuleData: name: "ietf-routing-types", organization: "IETF RTGWG - Routing Area Working Group", revision: "2017-10-13">,
<Holo::ModuleData: name: "ietf-bfd-types", organization: "IETF BFD Working Group", revision: "2022-09-22">,
<Holo::ModuleData: name: "ietf-routing", organization: "IETF NETMOD (Network Modeling) Working Group", revision: "2018-03-13">,
<Holo::ModuleData: name: "ietf-key-chain", organization: "IETF RTGWG - Routing Area Working Group", revision: "2017-06-15">,
<Holo::ModuleData: name: "ietf-ip", organization: "IETF NETMOD (Network Modeling) Working Group", revision: "2018-01-09">,
<Holo::ModuleData: name: "ietf-segment-routing", organization: "IETF SPRING - SPRING Working Group", revision: "2021-05-26">,
<Holo::ModuleData: name: "ietf-segment-routing-common", organization: "IETF SPRING - SPRING Working Group", revision: "2021-05-26">,The Get RPC retrieves configuration data, state data, or both. Optionally, the request can be restricted to a single YANG path. If no data encoding is specified, the default encoding used is JSON.
Ruby example:
require 'holo_services_pb'
# Connect to holod
stub = Holo::Northbound::Stub.new('localhost:50051', :this_channel_is_insecure)
# Invoke RPC
request = Holo::GetRequest.new
request.type = :STATE
request.path = '/ietf-routing:routing/control-plane-protocols'
response = stub.get(request)
# Print the response
pp response$ ruby -I. ./get.rb | head -n 20
<Holo::GetResponse: timestamp: 1680547280, data: <Holo::DataTree: encoding: :JSON, data: "{
"ietf-routing:routing": {
"control-plane-protocols": {
"control-plane-protocol": [
{
"type": "ietf-bfd-types:bfdv1",
"name": "main",
"ietf-bfd:bfd": {
"summary": {
"number-of-sessions": 2,
"number-of-sessions-up": 2,
"number-of-sessions-down": 0,
"number-of-sessions-admin-down": 0
},
"ietf-bfd-ip-mh:ip-mh": {
"summary": {
"number-of-sessions": 0,
"number-of-sessions-up": 0,
"number-of-sessions-down": 0,
"number-of-sessions-admin-down": 0The Validate RPC performs validation on configuration data without committing it, including both YANG and internal validation checks.
Ruby example:
require 'holo_services_pb'
# Connect to holod
stub = Holo::Northbound::Stub.new('localhost:50051', :this_channel_is_insecure)
# Invoke RPC
request = Holo::ValidateRequest.new
request.config = Holo::DataTree.new
request.config.encoding = :JSON
request.config.data = '
{
"ietf-routing:routing": {
"control-plane-protocols": {
"control-plane-protocol": [
{
"type": "ietf-ospf:ospfv2",
"name": "main",
"ietf-ospf:ospf": {
"explicit-router-id": "1.1.1.3"
}
}
]
}
}
}
'
response = stub.validate(request)
# Print the response
pp responseThe Commit RPC creates a new configuration transaction using a two-phase commit protocol, with three available commit operations: merge, replace, and change (YANG Patch). The provided data tree can be specified using any of the supported data encodings.
For confirmed commits, the confirmed_timeout parameter must be specified with a non-zero value, representing the commit timeout in minutes. Within the given timeout, a new Commit RPC is expected to confirm the previous commit.
Additionally, the comment parameter can be used to describe the configuration changes being pushed to the device, making the rollback log more informative.
Ruby example:
require 'holo_services_pb'
# Connect to holod
stub = Holo::Northbound::Stub.new('localhost:50051', :this_channel_is_insecure)
# Invoke RPC
request = Holo::CommitRequest.new
request.operation = :MERGE
request.config = Holo::DataTree.new
request.config.encoding = :JSON
request.config.data = '
{
"ietf-routing:routing": {
"control-plane-protocols": {
"control-plane-protocol": [
{
"type": "ietf-ospf:ospfv2",
"name": "main",
"ietf-ospf:ospf": {
"explicit-router-id": "1.1.1.3"
}
}
]
}
}
}
'
request.confirmed_timeout = 1
response = stub.commit(request)
# Print the response
pp responseThe Execute RPC enables the execution of a YANG RPC/Action. The Execute request carries the YANG RPC/Action input parameters, while the response contains the corresponding output parameters.
Ruby example:
require 'holo_services_pb'
# Connect to holod
stub = Holo::Northbound::Stub.new('localhost:50051', :this_channel_is_insecure)
# Invoke RPC
request = Holo::ExecuteRequest.new
request.data = Holo::DataTree.new
request.data.encoding = :JSON
request.data.data = '
{
"ietf-ospf:clear-neighbor": {
"routing-protocol-name":"main"
}
}
'
response = stub.execute(request)
# Print the response
pp responsePlease note that the Ruby examples presented use manually written JSON for the sake of simplicity. Ideally, the management script should use YANG language bindings to achieve type safety and other benefits.
The ListTransactions RPC provides a list of all recorded transactions within the rollback log. This log is stored in non-volatile memory, ensuring the preservation of transaction records even in the event of power loss or system restarts.
Ruby example:
require 'holo_services_pb'
# Create the connection with holod:
stub = Holo::Northbound::Stub.new('localhost:50051', :this_channel_is_insecure)
# Create a new state request to get interface state:
request = Holo::ListTransactionsRequest.new
# Invoke RPC.
response = stub.list_transactions(request)
# Print the response.
response.each do |t|
pp t
endThe GetTransaction RPC allows querying data from the rollback log for a given configuration transaction ID.
Ruby example:
require 'holo_services_pb'
# Create the connection with holod:
stub = Holo::Northbound::Stub.new('localhost:50051', :this_channel_is_insecure)
# Create a new state request to get interface state:
request = Holo::GetTransactionRequest.new
request.transaction_id = 1
request.encoding = :XML
# Invoke RPC.
response = stub.get_transaction(request)
# Print the response.
pp responseAs of now, the gRPC module has the following limitations:
- No support for streaming telemetry
- No support for YANG notifications
The gRPC module has the following configuration options:
# gRPC northbound plugin configuration
[plugins.grpc]
# Enable or disable the plugin
enabled = true
# gRPC server listening address
address = "[::1]:50051"
# Optional gRPC TLS configuration
[plugins.grpc.tls]
# Enable or disable TLS authentication
enabled = false
# TLS certificate
certificate = "/etc/ssl/private/holo.pem"
# TLS key
key = "/etc/ssl/certs/holo.key"- Architecture
- Management Interfaces
- Developer's Documentation
- Example Topology
- Paul's Practical Guide