]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/lib/grpc-query.py
Merge pull request #13455 from sri-mohan1/srib-ldpd
[mirror_frr.git] / tests / topotests / lib / grpc-query.py
CommitLineData
e00241ad
CH
1#!/usr/bin/env python3
2# -*- coding: utf-8 eval: (blacken-mode 1) -*-
acddc0ed 3# SPDX-License-Identifier: MIT
e00241ad
CH
4#
5# February 22 2022, Christian Hopps <chopps@labn.net>
6#
7# Copyright (c) 2022, LabN Consulting, L.L.C.
e00241ad
CH
8
9import argparse
10import logging
11import os
12import sys
13
14import pytest
15
16CWD = os.path.dirname(os.path.realpath(__file__))
17
18# This is painful but works if you have installed grpc and grpc_tools would be *way*
19# better if we actually built and installed these but ... python packaging.
20try:
21 import grpc
22 import grpc_tools
23
60e03778
CH
24 sys.path.append(os.path.dirname(CWD))
25 from munet.base import commander
e00241ad
CH
26
27 commander.cmd_raises(f"cp {CWD}/../../../grpc/frr-northbound.proto .")
28 commander.cmd_raises(
29 f"python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I . frr-northbound.proto"
30 )
31except Exception as error:
32 logging.error("can't create proto definition modules %s", error)
33 raise
34
35try:
36 sys.path[0:0] = "."
37 import frr_northbound_pb2
38 import frr_northbound_pb2_grpc
39
40 # Would be nice if compiling the modules internally from the source worked
41 # # import grpc_tools.protoc
42 # # proto_include = pkg_resources.resource_filename("grpc_tools", "_proto")
43 # from grpc_tools.protoc import _proto_file_to_module_name, _protos_and_services
44 # try:
45 # frr_northbound_pb2, frr_northbound_pb2_grpc = _protos_and_services(
46 # "frr_northbound.proto"
47 # )
48 # finally:
49 # os.chdir(CWD)
50except Exception as error:
51 logging.error("can't import proto definition modules %s", error)
52 raise
53
54
55class GRPCClient:
56 def __init__(self, server, port):
57 self.channel = grpc.insecure_channel("{}:{}".format(server, port))
58 self.stub = frr_northbound_pb2_grpc.NorthboundStub(self.channel)
59
60 def get_capabilities(self):
61 request = frr_northbound_pb2.GetCapabilitiesRequest()
62 response = "NONE"
63 try:
64 response = self.stub.GetCapabilities(request)
65 except Exception as error:
66 logging.error("Got exception from stub: %s", error)
67
68 logging.debug("GRPC Capabilities: %s", response)
69 return response
70
71 def get(self, xpath):
72 request = frr_northbound_pb2.GetRequest()
73 request.path.append(xpath)
74 request.type = frr_northbound_pb2.GetRequest.ALL
75 request.encoding = frr_northbound_pb2.XML
76 xml = ""
77 for r in self.stub.Get(request):
78 logging.info('GRPC Get path: "%s" value: %s', request.path, r)
79 xml += str(r.data.data)
80 return xml
81
82
83def next_action(action_list=None):
84 "Get next action from list or STDIN"
85 if action_list:
86 for action in action_list:
87 yield action
88 else:
89 while True:
90 try:
91 action = input("")
92 if not action:
93 break
94 yield action.strip()
95 except EOFError:
96 break
97
98
99def main(*args):
100 parser = argparse.ArgumentParser(description="gRPC Client")
101 parser.add_argument(
102 "-s", "--server", default="localhost", help="gRPC Server Address"
103 )
104 parser.add_argument(
105 "-p", "--port", type=int, default=50051, help="gRPC Server TCP Port"
106 )
107 parser.add_argument("-v", "--verbose", action="store_true", help="be verbose")
108 parser.add_argument("--check", action="store_true", help="check runable")
109 parser.add_argument("actions", nargs="*", help="GETCAP|GET,xpath")
110 args = parser.parse_args(*args)
111
112 level = logging.DEBUG if args.verbose else logging.INFO
113 logging.basicConfig(
114 level=level,
115 format="%(asctime)s %(levelname)s: GRPC-CLI-CLIENT: %(name)s %(message)s",
116 )
117
118 if args.check:
119 sys.exit(0)
120
121 c = GRPCClient(args.server, args.port)
122
123 for action in next_action(args.actions):
124 action = action.casefold()
125 logging.info("GOT ACTION: %s", action)
126 if action == "getcap":
127 caps = c.get_capabilities()
128 print("Capabilities:", caps)
129 elif action.startswith("get,"):
130 # Print Interface State and Config
131 _, xpath = action.split(",", 1)
132 print("Get XPath: ", xpath)
133 xml = c.get(xpath)
134 print("{}: {}".format(xpath, xml))
135 # for _ in range(0, 1):
136
137
138if __name__ == "__main__":
139 main()