@@ -22,24 +22,31 @@ def main():
22
22
"capabilities" : gnmi_capabilities ,
23
23
"subscribe" : gnmi_subscribe ,
24
24
"get" : gnmi_get ,
25
- "set" : gnmi_set
25
+ "set" : gnmi_set ,
26
26
}
27
- parser = argparse .ArgumentParser (description = "gNMI CLI demonstrating library usage." , usage = """
27
+ parser = argparse .ArgumentParser (
28
+ description = "gNMI CLI demonstrating library usage." ,
29
+ usage = """
28
30
gnmcli <rpc> [<args>]
29
31
30
32
Supported RPCs:
31
33
%s
32
34
33
35
See --help for RPC options.
34
- """ .format ('\n ' .join (rpc_map .keys ())))
36
+ """ .format (
37
+ "\n " .join (rpc_map .keys ())
38
+ ),
39
+ )
35
40
parser .add_argument ("rpc" , help = "gNMI RPC to perform against network element." )
36
41
if len (sys .argv ) < 2 :
37
42
logging .error ("Must at minimum provide RPC and required arguments!" )
38
43
parser .print_help ()
39
44
exit (1 )
40
45
args = parser .parse_args (sys .argv [1 :2 ])
41
46
if args .rpc not in rpc_map .keys ():
42
- logging .error ("%s not in supported RPCs: %s!" , args .rpc , ', ' .join (rpc_map .keys ()))
47
+ logging .error (
48
+ "%s not in supported RPCs: %s!" , args .rpc , ", " .join (rpc_map .keys ())
49
+ )
43
50
parser .print_help ()
44
51
exit (1 )
45
52
try :
@@ -48,13 +55,16 @@ def main():
48
55
logging .exception ("Error during usage!" )
49
56
exit (1 )
50
57
58
+
51
59
def gnmi_capabilities ():
52
60
parser = argparse .ArgumentParser (
53
61
description = "Performs Capabilities RPC against network element."
54
62
)
55
63
args = __common_args_handler (parser )
56
64
client = __gen_client (args )
57
- logging .info (client .capabilities ())
65
+ capability_response = client .capabilities ()
66
+ logging .info (__format_message (capability_response ))
67
+
58
68
59
69
def gnmi_subscribe ():
60
70
"""Performs a sampled Subscribe against network element.
@@ -64,33 +74,34 @@ def gnmi_subscribe():
64
74
description = "Performs Subscribe RPC against network element."
65
75
)
66
76
parser .add_argument (
67
- "-xpath" ,
68
- help = "XPath to subscribe to." ,
69
- type = str ,
70
- action = "append"
77
+ "-xpath" , help = "XPath to subscribe to." , type = str , action = "append"
71
78
)
72
79
parser .add_argument (
73
80
"-interval" ,
74
81
help = "Sample interval in seconds for Subscription." ,
75
82
type = int ,
76
- default = 10 * int (1e9 )
83
+ default = 10 * int (1e9 ),
77
84
)
78
85
parser .add_argument (
79
86
"-dump_file" ,
80
87
help = "Filename to dump to. Defaults to stdout." ,
81
88
type = str ,
82
- default = "stdout"
89
+ default = "stdout" ,
83
90
)
84
91
parser .add_argument (
85
92
"-dump_json" ,
86
93
help = "Dump as JSON instead of textual protos." ,
87
- action = "store_true"
94
+ action = "store_true" ,
88
95
)
89
96
parser .add_argument (
90
97
"-sync_stop" , help = "Stop on sync_response." , action = "store_true"
91
98
)
92
99
parser .add_argument (
93
- "-encoding" , help = "gNMI subscription encoding." , type = str , nargs = "?" , choices = list (proto .gnmi_pb2 .Encoding .keys ())
100
+ "-encoding" ,
101
+ help = "gNMI subscription encoding." ,
102
+ type = str ,
103
+ nargs = "?" ,
104
+ choices = list (proto .gnmi_pb2 .Encoding .keys ()),
94
105
)
95
106
args = __common_args_handler (parser )
96
107
# Set default XPath outside of argparse due to default being persistent in argparse.
@@ -104,19 +115,19 @@ def gnmi_subscribe():
104
115
if args .sample_interval :
105
116
kwargs ["sample_interval" ] = args .sample_interval
106
117
try :
107
- logging .info ("Dumping responses to %s as %s ..." , args .dump_file , "JSON" if args .dump_json else "textual proto" )
108
- logging .info ("Subscribing to:\n %s" , '\n ' .join (args .xpath ))
118
+ logging .info (
119
+ "Dumping responses to %s as %s ..." ,
120
+ args .dump_file ,
121
+ "JSON" if args .dump_json else "textual proto" ,
122
+ )
123
+ logging .info ("Subscribing to:\n %s" , "\n " .join (args .xpath ))
109
124
for subscribe_response in client .subscribe_xpaths (args .xpath , ** kwargs ):
110
125
if subscribe_response .sync_response :
111
126
logging .debug ("sync_response received." )
112
127
if args .sync_stop :
113
128
logging .warning ("Stopping on sync_response." )
114
129
break
115
- formatted_message = None
116
- if args .dump_json :
117
- formatted_message = json_format .MessageToJson (subscribe_response , sort_keys = True )
118
- else :
119
- formatted_message = text_format .MessageToString (subscribe_response )
130
+ formatted_message = __format_message (subscribe_response )
120
131
if args .dump_file == "stdout" :
121
132
logging .info (formatted_message )
122
133
else :
@@ -127,29 +138,37 @@ def gnmi_subscribe():
127
138
except Exception :
128
139
logging .exception ("Stopping due to exception!" )
129
140
141
+
130
142
def gnmi_get ():
131
143
"""Provides Get RPC usage. Assumes JSON or JSON_IETF style configurations.
132
144
TODO: This is the least well understood/implemented. Need to validate if there is an OOO for update/replace/delete.
133
145
"""
134
146
parser = argparse .ArgumentParser (
135
147
description = "Performs Get RPC against network element."
136
148
)
149
+ parser .add_argument ("-xpath" , help = "XPaths to Get." , type = str , action = "append" )
137
150
parser .add_argument (
138
- "-xpath " ,
139
- help = "XPaths to Get ." ,
151
+ "-encoding " ,
152
+ help = "gNMI subscription encoding ." ,
140
153
type = str ,
141
- action = "append"
142
- )
143
- parser .add_argument (
144
- "-encoding" , help = "gNMI subscription encoding." , type = str , nargs = "?" , choices = list (proto .gnmi_pb2 .Encoding .keys ())
154
+ nargs = "?" ,
155
+ choices = list (proto .gnmi_pb2 .Encoding .keys ()),
145
156
)
146
157
parser .add_argument (
147
- "-data_type" , help = "gNMI GetRequest DataType" , type = str , nargs = "?" , choices = list (enum_type_wrapper .EnumTypeWrapper (proto .gnmi_pb2 ._GETREQUEST_DATATYPE ).keys ())
158
+ "-data_type" ,
159
+ help = "gNMI GetRequest DataType" ,
160
+ type = str ,
161
+ nargs = "?" ,
162
+ choices = list (
163
+ enum_type_wrapper .EnumTypeWrapper (
164
+ proto .gnmi_pb2 ._GETREQUEST_DATATYPE
165
+ ).keys ()
166
+ ),
148
167
)
149
168
parser .add_argument (
150
169
"-dump_json" ,
151
170
help = "Dump as JSON instead of textual protos." ,
152
- action = "store_true"
171
+ action = "store_true" ,
153
172
)
154
173
args = __common_args_handler (parser )
155
174
# Set default XPath outside of argparse due to default being persistent in argparse.
@@ -162,12 +181,8 @@ def gnmi_get():
162
181
if args .data_type :
163
182
kwargs ["data_type" ] = args .data_type
164
183
get_response = client .get_xpaths (args .xpath , ** kwargs )
165
- formatted_message = None
166
- if args .dump_json :
167
- formatted_message = json_format .MessageToJson (get_response , sort_keys = True )
168
- else :
169
- formatted_message = text_format .MessageToString (get_response )
170
- logging .info (formatted_message )
184
+ logging .info (__format_message (get_response ))
185
+
171
186
172
187
def gnmi_set ():
173
188
"""Provides Set RPC usage. Assumes JSON or JSON_IETF style configurations.
@@ -178,37 +193,32 @@ def gnmi_set():
178
193
description = "Performs Set RPC against network element."
179
194
)
180
195
parser .add_argument (
181
- "-update_json_config" ,
182
- description = "JSON-modeled config to apply as an update."
196
+ "-update_json_config" , description = "JSON-modeled config to apply as an update."
183
197
)
184
198
parser .add_argument (
185
- "-replace_json_config" ,
186
- description = "JSON-modeled config to apply as an update."
199
+ "-replace_json_config" , description = "JSON-modeled config to apply as an update."
187
200
)
188
201
parser .add_argument (
189
- "-delete_xpath" ,
190
- help = "XPaths to delete." ,
191
- type = str ,
192
- action = "append"
202
+ "-delete_xpath" , help = "XPaths to delete." , type = str , action = "append"
193
203
)
194
204
parser .add_argument (
195
- "-no_ietf" ,
196
- help = "JSON is not IETF conformant." ,
197
- action = "store_true"
205
+ "-no_ietf" , help = "JSON is not IETF conformant." , action = "store_true"
198
206
)
199
207
parser .add_argument (
200
208
"-dump_json" ,
201
209
help = "Dump as JSON instead of textual protos." ,
202
- action = "store_true"
210
+ action = "store_true" ,
203
211
)
204
212
args = __common_args_handler (parser )
205
213
if not any ([args .update_json_config , args .replace_json_config , args .delete_xpath ]):
206
214
raise Exception ("Must specify update, replace, or delete parameters!" )
215
+
207
216
def load_json_file (filename ):
208
217
config = None
209
218
with open (filename , "r" ) as config_fd :
210
219
config = json .load (config_fd )
211
220
return config
221
+
212
222
kwargs = {}
213
223
if args .update_json_config :
214
224
kwargs ["update_json_configs" ] = load_json_file (args .update_json_config )
@@ -218,23 +228,16 @@ def load_json_file(filename):
218
228
kwargs ["ietf" ] = False
219
229
client = __gen_client (args )
220
230
set_response = client .set_json (** kwargs )
221
- formatted_message = None
222
- if args .dump_json :
223
- formatted_message = json_format .MessageToJson (set_response , sort_keys = True )
224
- else :
225
- formatted_message = text_format .MessageToString (set_response )
226
- logging .info (formatted_message )
231
+ logging .info (__format_message (set_response ))
227
232
if args .delete_xpath :
228
233
if getattr (client , "delete_xpaths" , None ) is not None :
229
234
delete_response = client .delete_xpaths (args .xpath )
230
- formatted_message = None
231
- if args .dump_json :
232
- formatted_message = json_format .MessageToJson (delete_response , sort_keys = True )
233
- else :
234
- formatted_message = text_format .MessageToString (delete_response )
235
- logging .info (formatted_message )
235
+ logging .info (__format_message (delete_response ))
236
236
else :
237
- raise Exception ("Convenience delete_xpaths is not supported in the client library!" )
237
+ raise Exception (
238
+ "Convenience delete_xpaths is not supported in the client library!"
239
+ )
240
+
238
241
239
242
def __gen_client (args ):
240
243
builder = ClientBuilder (args .netloc )
@@ -243,13 +246,25 @@ def __gen_client(args):
243
246
if not any ([args .root_certificates , args .private_key , args .certificate_chain ]):
244
247
builder .set_secure_from_target ()
245
248
else :
246
- builder .set_secure_from_file (args .root_certificates , args .private_key , args .certificate_chain )
249
+ builder .set_secure_from_file (
250
+ args .root_certificates , args .private_key , args .certificate_chain
251
+ )
247
252
if args .ssl_target_override :
248
253
builder .set_ssl_target_override (args .ssl_target_override )
249
254
elif args .auto_ssl_target_override :
250
255
builder .set_ssl_target_override ()
251
256
return builder .construct ()
252
257
258
+
259
+ def __format_message (message , as_json = False ):
260
+ formatted_message = None
261
+ if as_json :
262
+ formatted_message = json_format .MessageToJson (message , sort_keys = True )
263
+ else :
264
+ formatted_message = text_format .MessageToString (message )
265
+ return formatted_message
266
+
267
+
253
268
def __common_args_handler (parser ):
254
269
"""Ideally would be a decorator."""
255
270
parser .add_argument ("netloc" , help = "<host>:<port>" , type = str )
@@ -260,11 +275,23 @@ def __common_args_handler(parser):
260
275
default = "IOS XR" ,
261
276
choices = list (ClientBuilder .os_class_map .keys ()),
262
277
)
263
- parser .add_argument ("-root_certificates" , description = "Root certificates for secure connection." )
264
- parser .add_argument ("-private_key" , description = "Private key for secure connection." )
265
- parser .add_argument ("-certificate_chain" , description = "Certificate chain for secure connection." )
266
- parser .add_argument ("-ssl_target_override" , description = "gRPC SSL target override option." )
267
- parser .add_argument ("-auto_ssl_target_override" , description = "Root certificates for secure connection." , action = "store_true" )
278
+ parser .add_argument (
279
+ "-root_certificates" , description = "Root certificates for secure connection."
280
+ )
281
+ parser .add_argument (
282
+ "-private_key" , description = "Private key for secure connection."
283
+ )
284
+ parser .add_argument (
285
+ "-certificate_chain" , description = "Certificate chain for secure connection."
286
+ )
287
+ parser .add_argument (
288
+ "-ssl_target_override" , description = "gRPC SSL target override option."
289
+ )
290
+ parser .add_argument (
291
+ "-auto_ssl_target_override" ,
292
+ description = "Root certificates for secure connection." ,
293
+ action = "store_true" ,
294
+ )
268
295
parser .add_argument ("-debug" , help = "Print debug messages" , action = "store_true" )
269
296
args = parser .parse_args (sys .argv [2 :])
270
297
logging .basicConfig (level = logging .DEBUG if args .debug else logging .INFO )
@@ -274,4 +301,4 @@ def __common_args_handler(parser):
274
301
275
302
276
303
if __name__ == "__main__" :
277
- main ()
304
+ main ()
0 commit comments