mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 01:06:53 +00:00
Merge pull request #6886 from opensourcerouting/grpc-doc
doc: initial documentation for gRPC
This commit is contained in:
commit
b2a18903e7
249
doc/developer/grpc.rst
Normal file
249
doc/developer/grpc.rst
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
.. _grpc-dev:
|
||||||
|
|
||||||
|
***************
|
||||||
|
Northbound gRPC
|
||||||
|
***************
|
||||||
|
|
||||||
|
.. _grpc-languages-bindings:
|
||||||
|
|
||||||
|
Programming Language Bindings
|
||||||
|
=============================
|
||||||
|
|
||||||
|
The gRPC supported programming language bindings can be found here:
|
||||||
|
https://grpc.io/docs/languages/
|
||||||
|
|
||||||
|
After picking a programming language that supports gRPC bindings, the
|
||||||
|
next step is to generate the FRR northbound bindings. To generate the
|
||||||
|
northbound bindings you'll need the programming language binding
|
||||||
|
generator tools and those are language specific.
|
||||||
|
|
||||||
|
Next sections will use Ruby as an example for writing scripts to use
|
||||||
|
the northbound.
|
||||||
|
|
||||||
|
|
||||||
|
.. _grpc-ruby-generate:
|
||||||
|
|
||||||
|
Generating Ruby FRR Bindings
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Generating FRR northbound bindings for Ruby example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Install the required gems:
|
||||||
|
# - grpc: the gem that will talk with FRR's gRPC plugin.
|
||||||
|
# - grpc-tools: the gem that provides the code generator.
|
||||||
|
gem install grpc
|
||||||
|
gem install grpc-tools
|
||||||
|
|
||||||
|
# Create your project/scripts directory:
|
||||||
|
mkdir /tmp/frr-ruby
|
||||||
|
|
||||||
|
# Go to FRR's grpc directory:
|
||||||
|
cd grpc
|
||||||
|
|
||||||
|
# Generate the ruby bindings:
|
||||||
|
grpc_tools_ruby_protoc \
|
||||||
|
--ruby_out=/tmp/frr-ruby \
|
||||||
|
--grpc_out=/tmp/frr-ruby \
|
||||||
|
frr-northbound.proto
|
||||||
|
|
||||||
|
|
||||||
|
.. _grpc-ruby-if-sample:
|
||||||
|
|
||||||
|
Using Ruby To Get Interfaces State
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
Here is a sample script to print all interfaces FRR discovered:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
require 'frr-northbound_services_pb'
|
||||||
|
|
||||||
|
# Create the connection with FRR's gRPC:
|
||||||
|
stub = Frr::Northbound::Stub.new('localhost:50051', :this_channel_is_insecure)
|
||||||
|
|
||||||
|
# Create a new state request to get interface state:
|
||||||
|
request = Frr::GetRequest.new
|
||||||
|
request.type = :STATE
|
||||||
|
request.path.push('/frr-interface:lib')
|
||||||
|
|
||||||
|
# Ask FRR.
|
||||||
|
response = stub.get(request)
|
||||||
|
|
||||||
|
# Print the response.
|
||||||
|
response.each do |result|
|
||||||
|
result.data.data.each_line do |line|
|
||||||
|
puts line
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The generated files will assume that they are in the search path (e.g.
|
||||||
|
inside gem) so you'll need to either edit it to use ``require_relative`` or
|
||||||
|
tell Ruby where to look for them. For simplicity we'll use ``-I .`` to tell
|
||||||
|
it is in the current directory.
|
||||||
|
|
||||||
|
|
||||||
|
The previous script will output something like this:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ cd /tmp/frr-ruby
|
||||||
|
# Add `-I.` so ruby finds the FRR generated file locally.
|
||||||
|
$ ruby -I. interface.rb
|
||||||
|
{
|
||||||
|
"frr-interface:lib": {
|
||||||
|
"interface": [
|
||||||
|
{
|
||||||
|
"name": "eth0",
|
||||||
|
"vrf": "default",
|
||||||
|
"state": {
|
||||||
|
"if-index": 2,
|
||||||
|
"mtu": 1500,
|
||||||
|
"mtu6": 1500,
|
||||||
|
"speed": 1000,
|
||||||
|
"metric": 0,
|
||||||
|
"phy-address": "11:22:33:44:55:66"
|
||||||
|
},
|
||||||
|
"frr-zebra:zebra": {
|
||||||
|
"state": {
|
||||||
|
"up-count": 0,
|
||||||
|
"down-count": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lo",
|
||||||
|
"vrf": "default",
|
||||||
|
"state": {
|
||||||
|
"if-index": 1,
|
||||||
|
"mtu": 0,
|
||||||
|
"mtu6": 65536,
|
||||||
|
"speed": 0,
|
||||||
|
"metric": 0,
|
||||||
|
"phy-address": "00:00:00:00:00:00"
|
||||||
|
},
|
||||||
|
"frr-zebra:zebra": {
|
||||||
|
"state": {
|
||||||
|
"up-count": 0,
|
||||||
|
"down-count": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.. _grpc-ruby-bfd-profile-sample:
|
||||||
|
|
||||||
|
Using Ruby To Create BFD Profiles
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
In this example you'll learn how to edit configuration using JSON
|
||||||
|
and programmatic (XPath) format.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
require 'frr-northbound_services_pb'
|
||||||
|
|
||||||
|
# Create the connection with FRR's gRPC:
|
||||||
|
stub = Frr::Northbound::Stub.new('localhost:50051', :this_channel_is_insecure)
|
||||||
|
|
||||||
|
# Create a new candidate configuration change.
|
||||||
|
new_candidate = stub.create_candidate(Frr::CreateCandidateRequest.new)
|
||||||
|
|
||||||
|
# Use JSON to configure.
|
||||||
|
request = Frr::LoadToCandidateRequest.new
|
||||||
|
request.candidate_id = new_candidate.candidate_id
|
||||||
|
request.type = :MERGE
|
||||||
|
request.config = Frr::DataTree.new
|
||||||
|
request.config.encoding = :JSON
|
||||||
|
request.config.data = <<-EOJ
|
||||||
|
{
|
||||||
|
"frr-bfdd:bfdd": {
|
||||||
|
"bfd": {
|
||||||
|
"profile": [
|
||||||
|
{
|
||||||
|
"name": "test-prof",
|
||||||
|
"detection-multiplier": 4,
|
||||||
|
"required-receive-interval": 800000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOJ
|
||||||
|
|
||||||
|
# Load configuration to candidate.
|
||||||
|
stub.load_to_candidate(request)
|
||||||
|
|
||||||
|
# Commit candidate.
|
||||||
|
stub.commit(
|
||||||
|
Frr::CommitRequest.new(
|
||||||
|
candidate_id: new_candidate.candidate_id,
|
||||||
|
phase: :ALL,
|
||||||
|
comment: 'create test-prof'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Now lets delete the previous profile and create a new one.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Create a new candidate configuration change.
|
||||||
|
new_candidate = stub.create_candidate(Frr::CreateCandidateRequest.new)
|
||||||
|
|
||||||
|
# Edit the configuration candidate.
|
||||||
|
request = Frr::EditCandidateRequest.new
|
||||||
|
request.candidate_id = new_candidate.candidate_id
|
||||||
|
|
||||||
|
# Delete previously created profile.
|
||||||
|
request.delete.push(
|
||||||
|
Frr::PathValue.new(
|
||||||
|
path: "/frr-bfdd:bfdd/bfd/profile[name='test-prof']",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add new profile with two configurations.
|
||||||
|
request.update.push(
|
||||||
|
Frr::PathValue.new(
|
||||||
|
path: "/frr-bfdd:bfdd/bfd/profile[name='test-prof-2']/detection-multiplier",
|
||||||
|
value: 5.to_s
|
||||||
|
)
|
||||||
|
)
|
||||||
|
request.update.push(
|
||||||
|
Frr::PathValue.new(
|
||||||
|
path: "/frr-bfdd:bfdd/bfd/profile[name='test-prof-2']/desired-transmission-interval",
|
||||||
|
value: 900_000.to_s
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Modify the candidate.
|
||||||
|
stub.edit_candidate(request)
|
||||||
|
|
||||||
|
# Commit the candidate configuration.
|
||||||
|
stub.commit(
|
||||||
|
Frr::CommitRequest.new(
|
||||||
|
candidate_id: new_candidate.candidate_id,
|
||||||
|
phase: :ALL,
|
||||||
|
comment: 'replace test-prof with test-prof-2'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
And here is the new FRR configuration:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ sudo vtysh -c 'show running-config'
|
||||||
|
...
|
||||||
|
bfd
|
||||||
|
profile test-prof-2
|
||||||
|
detect-multiplier 5
|
||||||
|
transmit-interval 900
|
||||||
|
!
|
||||||
|
!
|
@ -12,6 +12,7 @@ FRRouting Developer's Guide
|
|||||||
testing
|
testing
|
||||||
bgpd
|
bgpd
|
||||||
fpm
|
fpm
|
||||||
|
grpc
|
||||||
ospf
|
ospf
|
||||||
zebra
|
zebra
|
||||||
vtysh
|
vtysh
|
||||||
|
@ -28,6 +28,7 @@ dev_RSTFILES = \
|
|||||||
doc/developer/cli.rst \
|
doc/developer/cli.rst \
|
||||||
doc/developer/conf.py \
|
doc/developer/conf.py \
|
||||||
doc/developer/frr-release-procedure.rst \
|
doc/developer/frr-release-procedure.rst \
|
||||||
|
doc/developer/grpc.rst \
|
||||||
doc/developer/hooks.rst \
|
doc/developer/hooks.rst \
|
||||||
doc/developer/include-compile.rst \
|
doc/developer/include-compile.rst \
|
||||||
doc/developer/index.rst \
|
doc/developer/index.rst \
|
||||||
|
66
doc/user/grpc.rst
Normal file
66
doc/user/grpc.rst
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
.. _grpc:
|
||||||
|
|
||||||
|
***************
|
||||||
|
Northbound gRPC
|
||||||
|
***************
|
||||||
|
|
||||||
|
.. program:: configure
|
||||||
|
|
||||||
|
*gRPC* provides a combined front end to all FRR daemons using the YANG
|
||||||
|
northbound. It is currently disabled by default due its experimental
|
||||||
|
stage, but it can be enabled with :option:`--enable-grpc` option in the
|
||||||
|
configure script.
|
||||||
|
|
||||||
|
|
||||||
|
.. _grpc-features:
|
||||||
|
|
||||||
|
Northbound gRPC Features
|
||||||
|
========================
|
||||||
|
|
||||||
|
* Get/set configuration using JSON/XML/XPath encondings.
|
||||||
|
* Execute YANG RPC calls.
|
||||||
|
* Lock/unlock configuration.
|
||||||
|
* Create/edit/load/update/commit candidate configuration.
|
||||||
|
* List/get transactions.
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
There is currently no support for YANG notifications.
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
You can find more information on how to code programs to interact
|
||||||
|
with FRR by reading the gRPC Programming Language Bindings section
|
||||||
|
in the `developer's documentation
|
||||||
|
<http://docs.frrouting.org/projects/dev-guide/en/latest/grpc.html>`_.
|
||||||
|
|
||||||
|
|
||||||
|
.. _grpc-config:
|
||||||
|
|
||||||
|
Daemon gRPC Configuration
|
||||||
|
=========================
|
||||||
|
|
||||||
|
The *gRPC* module accepts the following run time option:
|
||||||
|
|
||||||
|
- ``port``: the port to listen to (defaults to ``50051``).
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
At the moment only localhost connections with no SSL/TLS are
|
||||||
|
supported.
|
||||||
|
|
||||||
|
|
||||||
|
To configure FRR daemons to listen to gRPC you need to append the
|
||||||
|
following parameter to the daemon's command line: ``-M grpc``
|
||||||
|
(optionally ``-M grpc:PORT`` to specify listening port).
|
||||||
|
|
||||||
|
To do that in production you need to edit the ``/etc/frr/daemons`` file
|
||||||
|
so the daemons get started with the command line argument. Example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# other daemons...
|
||||||
|
bfdd_options=" --daemon -A 127.0.0.1 -M grpc"
|
@ -23,6 +23,7 @@ Basics
|
|||||||
|
|
||||||
basic
|
basic
|
||||||
vtysh
|
vtysh
|
||||||
|
grpc
|
||||||
filter
|
filter
|
||||||
routemap
|
routemap
|
||||||
ipv6
|
ipv6
|
||||||
|
@ -15,6 +15,7 @@ user_RSTFILES = \
|
|||||||
doc/user/filter.rst \
|
doc/user/filter.rst \
|
||||||
doc/user/frr-reload.rst \
|
doc/user/frr-reload.rst \
|
||||||
doc/user/glossary.rst \
|
doc/user/glossary.rst \
|
||||||
|
doc/user/grpc.rst \
|
||||||
doc/user/index.rst \
|
doc/user/index.rst \
|
||||||
doc/user/installation.rst \
|
doc/user/installation.rst \
|
||||||
doc/user/ipv6.rst \
|
doc/user/ipv6.rst \
|
||||||
|
Loading…
Reference in New Issue
Block a user