]> git.puffer.fish Git - mirror/frr.git/commitdiff
doc: expand documentation on gRPC
authorChristian Hopps <chopps@gmail.com>
Thu, 20 May 2021 14:03:37 +0000 (14:03 +0000)
committerIgor Ryzhov <iryzhov@nfware.com>
Thu, 27 May 2021 10:18:42 +0000 (13:18 +0300)
Add C++ and Python examples, and add compiling info, and known gRPC
version that works.

Signed-off-by: Christian Hopps <chopps@gmail.com>
doc/developer/grpc.rst

index 8029a08b734cdaef36875f55f099b702a3ce184d..cb164bdabf19b47b776eb6977bf4dd8d1d20bfd5 100644 (file)
@@ -4,6 +4,17 @@
 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:
 
 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
 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.
 
+.. _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:
 
 Generating Ruby FRR Bindings
-----------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Generating FRR northbound bindings for Ruby example:
 
@@ -52,7 +326,7 @@ Generating FRR northbound bindings for Ruby example:
 .. _grpc-ruby-if-sample:
 
 Using Ruby To Get Interfaces State
-----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 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:
 
 Using Ruby To Create BFD Profiles
----------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 In this example you'll learn how to edit configuration using JSON
 and programmatic (XPath) format.