-
Notifications
You must be signed in to change notification settings - Fork 17
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": 0
The 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 response
The 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 response
The 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 response
Please 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
end
The 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 response
As 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