mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 16:04:49 +00:00
Merge pull request #8712 from LabNConsulting/chopps/grpc-doc-update
doc: expand documentation on gRPC
This commit is contained in:
commit
3511890fa1
@ -4,6 +4,17 @@
|
|||||||
Northbound gRPC
|
Northbound gRPC
|
||||||
***************
|
***************
|
||||||
|
|
||||||
|
To enable gRPC support one needs to add `--enable-grpc` when running
|
||||||
|
`configure`. Additionally, when launching each daemon one needs to request
|
||||||
|
the gRPC module be loaded and which port to bind to. This can be done by adding
|
||||||
|
`-M grpc:<port>` to the daemon's CLI arguments.
|
||||||
|
|
||||||
|
Currently there is no gRPC "routing" so you will need to bind your gRPC
|
||||||
|
`channel` to the particular daemon's gRPC port to interact with that daemon's
|
||||||
|
gRPC northbound interface.
|
||||||
|
|
||||||
|
The minimum version of gRPC known to work is 1.16.1.
|
||||||
|
|
||||||
.. _grpc-languages-bindings:
|
.. _grpc-languages-bindings:
|
||||||
|
|
||||||
Programming Language Bindings
|
Programming Language Bindings
|
||||||
@ -17,14 +28,277 @@ next step is to generate the FRR northbound bindings. To generate the
|
|||||||
northbound bindings you'll need the programming language binding
|
northbound bindings you'll need the programming language binding
|
||||||
generator tools and those are language specific.
|
generator tools and those are language specific.
|
||||||
|
|
||||||
Next sections will use Ruby as an example for writing scripts to use
|
C++ Example
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The next sections will use C++ as an example for accessing FRR
|
||||||
|
northbound through gRPC.
|
||||||
|
|
||||||
|
.. _grpc-c++-generate:
|
||||||
|
|
||||||
|
Generating C++ FRR Bindings
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Generating FRR northbound bindings for C++ example:
|
||||||
|
|
||||||
|
::
|
||||||
|
# Install gRPC (e.g., on Ubuntu 20.04)
|
||||||
|
sudo apt-get install libgrpc++-dev libgrpc-dev
|
||||||
|
|
||||||
|
mkdir /tmp/frr-cpp
|
||||||
|
cd grpc
|
||||||
|
|
||||||
|
protoc --cpp_out=/tmp/frr-cpp \
|
||||||
|
--grpc_out=/tmp/frr-cpp \
|
||||||
|
-I $(pwd) \
|
||||||
|
--plugin=protoc-gen-grpc=`which grpc_cpp_plugin` \
|
||||||
|
frr-northbound.proto
|
||||||
|
|
||||||
|
|
||||||
|
.. _grpc-c++-if-sample:
|
||||||
|
|
||||||
|
Using C++ To Get Version and Interfaces State
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Below is a sample program to print all interfaces discovered.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# test.cpp
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <grpc/grpc.h>
|
||||||
|
#include <grpcpp/create_channel.h>
|
||||||
|
#include "frr-northbound.pb.h"
|
||||||
|
#include "frr-northbound.grpc.pb.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
frr::GetRequest request;
|
||||||
|
frr::GetResponse reply;
|
||||||
|
grpc::ClientContext context;
|
||||||
|
grpc::Status status;
|
||||||
|
|
||||||
|
auto channel = grpc::CreateChannel("localhost:50051",
|
||||||
|
grpc::InsecureChannelCredentials());
|
||||||
|
auto stub = frr::Northbound::NewStub(channel);
|
||||||
|
|
||||||
|
request.set_type(frr::GetRequest::ALL);
|
||||||
|
request.set_encoding(frr::JSON);
|
||||||
|
request.set_with_defaults(true);
|
||||||
|
request.add_path("/frr-interface:lib");
|
||||||
|
auto stream = stub->Get(&context, request);
|
||||||
|
|
||||||
|
std::ostringstream ss;
|
||||||
|
while (stream->Read(&reply))
|
||||||
|
ss << reply.data().data() << std::endl;
|
||||||
|
|
||||||
|
status = stream->Finish();
|
||||||
|
assert(status.ok());
|
||||||
|
std::cout << "Interface Info:\n" << ss.str() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Below is how to compile and run the program, with the example output:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$ g++ -o test test.cpp frr-northbound.grpc.pb.cc frr-northbound.pb.cc -lgrpc++ -lprotobuf
|
||||||
|
$ ./test
|
||||||
|
Interface Info:
|
||||||
|
{
|
||||||
|
"frr-interface:lib": {
|
||||||
|
"interface": [
|
||||||
|
{
|
||||||
|
"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,
|
||||||
|
"ptm-status": "disabled"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "r1-eth0",
|
||||||
|
"vrf": "default",
|
||||||
|
"state": {
|
||||||
|
"if-index": 2,
|
||||||
|
"mtu": 1500,
|
||||||
|
"mtu6": 1500,
|
||||||
|
"speed": 10000,
|
||||||
|
"metric": 0,
|
||||||
|
"phy-address": "02:37:ac:63:59:b9"
|
||||||
|
},
|
||||||
|
"frr-zebra:zebra": {
|
||||||
|
"state": {
|
||||||
|
"up-count": 0,
|
||||||
|
"down-count": 0,
|
||||||
|
"ptm-status": "disabled"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"frr-zebra:zebra": {
|
||||||
|
"mcast-rpf-lookup": "mrib-then-urib",
|
||||||
|
"workqueue-hold-timer": 10,
|
||||||
|
"zapi-packets": 1000,
|
||||||
|
"import-kernel-table": {
|
||||||
|
"distance": 15
|
||||||
|
},
|
||||||
|
"dplane-queue-limit": 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. _grpc-python-example:
|
||||||
|
|
||||||
|
Python Example
|
||||||
|
--------------
|
||||||
|
|
||||||
|
The next sections will use Python as an example for writing scripts to use
|
||||||
the northbound.
|
the northbound.
|
||||||
|
|
||||||
|
.. _grpc-python-generate:
|
||||||
|
|
||||||
|
Generating Python FRR Bindings
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Generating FRR northbound bindings for Python example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Install python3 virtual environment capability e.g.,
|
||||||
|
sudo apt-get install python3-venv
|
||||||
|
|
||||||
|
# Create a virtual environment for python grpc and activate
|
||||||
|
python3 -m venv venv-grpc
|
||||||
|
source venv-grpc/bin/activate
|
||||||
|
|
||||||
|
# Install grpc requirements
|
||||||
|
pip install grpcio grpcio-tools
|
||||||
|
|
||||||
|
mkdir /tmp/frr-python
|
||||||
|
cd grpc
|
||||||
|
|
||||||
|
python3 -m grpc_tools.protoc \
|
||||||
|
--python_out=/tmp/frr-python \
|
||||||
|
--grpc_python_out=/tmp/frr-python \
|
||||||
|
-I $(pwd) \
|
||||||
|
frr-northbound.proto
|
||||||
|
|
||||||
|
.. _grpc-python-if-sample:
|
||||||
|
|
||||||
|
Using Python To Get Capabilities and Interfaces State
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Below is a sample script to print capabilities and all interfaces Python
|
||||||
|
discovered. This demostrates the 2 different RPC results one gets from gRPC,
|
||||||
|
Unary (`GetCapabilities`) and Streaming (`Get`) for the interface state.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
import grpc
|
||||||
|
import frr_northbound_pb2
|
||||||
|
import frr_northbound_pb2_grpc
|
||||||
|
|
||||||
|
channel = grpc.insecure_channel('localhost:50051')
|
||||||
|
stub = frr_northbound_pb2_grpc.NorthboundStub(channel)
|
||||||
|
|
||||||
|
# Print Capabilities
|
||||||
|
request = frr_northbound_pb2.GetCapabilitiesRequest()
|
||||||
|
response = stub.GetCapabilities(request)
|
||||||
|
print(response)
|
||||||
|
|
||||||
|
# Print Interface State and Config
|
||||||
|
request = frr_northbound_pb2.GetRequest()
|
||||||
|
request.path.append("/frr-interface:lib")
|
||||||
|
request.type=frr_northbound_pb2.GetRequest.ALL
|
||||||
|
request.encoding=frr_northbound_pb2.XML
|
||||||
|
|
||||||
|
for r in stub.Get(request):
|
||||||
|
print(r.data.data)
|
||||||
|
|
||||||
|
The previous script will output something like:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
frr_version: "7.7-dev-my-manual-build"
|
||||||
|
rollback_support: true
|
||||||
|
supported_modules {
|
||||||
|
name: "frr-filter"
|
||||||
|
organization: "FRRouting"
|
||||||
|
revision: "2019-07-04"
|
||||||
|
}
|
||||||
|
supported_modules {
|
||||||
|
name: "frr-interface"
|
||||||
|
organization: "FRRouting"
|
||||||
|
revision: "2020-02-05"
|
||||||
|
}
|
||||||
|
[...]
|
||||||
|
supported_encodings: JSON
|
||||||
|
supported_encodings: XML
|
||||||
|
|
||||||
|
<lib xmlns="http://frrouting.org/yang/interface">
|
||||||
|
<interface>
|
||||||
|
<name>lo</name>
|
||||||
|
<vrf>default</vrf>
|
||||||
|
<state>
|
||||||
|
<if-index>1</if-index>
|
||||||
|
<mtu>0</mtu>
|
||||||
|
<mtu6>65536</mtu6>
|
||||||
|
<speed>0</speed>
|
||||||
|
<metric>0</metric>
|
||||||
|
<phy-address>00:00:00:00:00:00</phy-address>
|
||||||
|
</state>
|
||||||
|
<zebra xmlns="http://frrouting.org/yang/zebra">
|
||||||
|
<state>
|
||||||
|
<up-count>0</up-count>
|
||||||
|
<down-count>0</down-count>
|
||||||
|
</state>
|
||||||
|
</zebra>
|
||||||
|
</interface>
|
||||||
|
<interface>
|
||||||
|
<name>r1-eth0</name>
|
||||||
|
<vrf>default</vrf>
|
||||||
|
<state>
|
||||||
|
<if-index>2</if-index>
|
||||||
|
<mtu>1500</mtu>
|
||||||
|
<mtu6>1500</mtu6>
|
||||||
|
<speed>10000</speed>
|
||||||
|
<metric>0</metric>
|
||||||
|
<phy-address>f2:62:2e:f3:4c:e4</phy-address>
|
||||||
|
</state>
|
||||||
|
<zebra xmlns="http://frrouting.org/yang/zebra">
|
||||||
|
<state>
|
||||||
|
<up-count>0</up-count>
|
||||||
|
<down-count>0</down-count>
|
||||||
|
</state>
|
||||||
|
</zebra>
|
||||||
|
</interface>
|
||||||
|
</lib>
|
||||||
|
|
||||||
|
.. _grpc-ruby-example:
|
||||||
|
|
||||||
|
Ruby Example
|
||||||
|
------------
|
||||||
|
|
||||||
|
Next sections will use Ruby as an example for writing scripts to use
|
||||||
|
the northbound.
|
||||||
|
|
||||||
.. _grpc-ruby-generate:
|
.. _grpc-ruby-generate:
|
||||||
|
|
||||||
Generating Ruby FRR Bindings
|
Generating Ruby FRR Bindings
|
||||||
----------------------------
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Generating FRR northbound bindings for Ruby example:
|
Generating FRR northbound bindings for Ruby example:
|
||||||
|
|
||||||
@ -52,7 +326,7 @@ Generating FRR northbound bindings for Ruby example:
|
|||||||
.. _grpc-ruby-if-sample:
|
.. _grpc-ruby-if-sample:
|
||||||
|
|
||||||
Using Ruby To Get Interfaces State
|
Using Ruby To Get Interfaces State
|
||||||
----------------------------------
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Here is a sample script to print all interfaces FRR discovered:
|
Here is a sample script to print all interfaces FRR discovered:
|
||||||
|
|
||||||
@ -141,7 +415,7 @@ The previous script will output something like this:
|
|||||||
.. _grpc-ruby-bfd-profile-sample:
|
.. _grpc-ruby-bfd-profile-sample:
|
||||||
|
|
||||||
Using Ruby To Create BFD Profiles
|
Using Ruby To Create BFD Profiles
|
||||||
---------------------------------
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
In this example you'll learn how to edit configuration using JSON
|
In this example you'll learn how to edit configuration using JSON
|
||||||
and programmatic (XPath) format.
|
and programmatic (XPath) format.
|
||||||
|
Loading…
Reference in New Issue
Block a user