2626Because we're not using a wrapper, we are going to need to build our own protos.
2727"""
2828
29+ import json
30+ from getpass import getpass
2931from cisco_gnmi import ClientBuilder , proto
3032
3133"""First let's build a Client. We are not going to specify an OS
3840 * Pass full <RPC>Request protos to client.service.<RPC>()
3941This code passes args to the client.<RPC>() methods.
4042"""
43+ target = input ("Host/Port: " )
44+ username = input ("Username: " )
45+ password = getpass ()
4146client = (
42- ClientBuilder ("127.0.0.1:9339" )
47+ ClientBuilder (target )
4348 .set_secure_from_target ()
4449 .set_ssl_target_override ()
45- .set_authentication ( "admin" , "its_a_secret" )
50+ .set_call_authentication ( username , password )
4651 .construct ()
4752)
4853"""Capabilities is an easy RPC to test."""
54+ input ("Press Enter for Capabilities..." )
4955capabilities = client .capabilities ()
5056print (capabilities )
5157"""Let's build a Get!
5460Generally OS wrappers will override this function to specialize on origins, etc.
5561But we are not using a wrapper, and if using OpenConfig pathing we don't need an origin.
5662"""
63+ input ("Press Enter for Get..." )
5764get_path = client .parse_xpath_to_gnmi_path ("/interfaces/interface/state/counters" )
5865get_response = client .get ([get_path ], data_type = "STATE" , encoding = "JSON_IETF" )
5966print (get_response )
6067"""Let's build a sampled Subscribe!
6168client.subscribe() accepts an iterable of SubscriptionLists
6269"""
70+ input ("Press Enter for Subscribe SAMPLE..." )
6371subscription_list = proto .gnmi_pb2 .SubscriptionList ()
6472subscription_list .mode = proto .gnmi_pb2 .SubscriptionList .Mode .Value ("STREAM" )
6573subscription_list .encoding = proto .gnmi_pb2 .Encoding .Value ("PROTO" )
7078sampled_subscription .mode = proto .gnmi_pb2 .SubscriptionMode .Value ("SAMPLE" )
7179sampled_subscription .sample_interval = 10 * int (1e9 )
7280subscription_list .subscription .append (sampled_subscription )
73- # Only print 2 responses
74- for msg_idx , subscribe_response in enumerate (client .subscribe ([subscription_list ])):
81+ for subscribe_response in client .subscribe ([subscription_list ]):
7582 print (subscribe_response )
76- if msg_idx + 1 == 2 :
77- break
83+ break
7884"""Now let's do ON_CHANGE. Just have to put SubscriptionMode to ON_CHANGE."""
85+ input ("Press Enter for Subscribe ON_CHANGE..." )
7986subscription_list = proto .gnmi_pb2 .SubscriptionList ()
8087subscription_list .mode = proto .gnmi_pb2 .SubscriptionList .Mode .Value ("STREAM" )
8188subscription_list .encoding = proto .gnmi_pb2 .Encoding .Value ("PROTO" )
8794)
8895onchange_subscription .mode = proto .gnmi_pb2 .SubscriptionMode .Value ("ON_CHANGE" )
8996subscription_list .subscription .append (onchange_subscription )
90- # Only print 2 responses
91- for msg_idx , subscribe_response in enumerate (client .subscribe ([subscription_list ])):
97+ synced = False
98+ for subscribe_response in client .subscribe ([subscription_list ]):
99+ if subscribe_response .sync_response :
100+ synced = True
101+ print ("Synced. Now perform action that will create a changed value." )
102+ print ("If using XR syslog as written, just try SSH'ing to device." )
103+ continue
104+ if not synced :
105+ continue
92106 print (subscribe_response )
93- if msg_idx + 1 == 2 :
94- break
107+ break
95108"""Let's build a Set!
96109client.set() expects updates, replaces, and/or deletes to be provided.
97110updates is a list of Updates
98111replaces is a list of Updates
99112deletes is a list of Paths
100- Let's do an update, and then a delete .
113+ Let's do an update.
101114"""
115+ input ("Press Enter for Set update..." )
102116set_update = proto .gnmi_pb2 .Update ()
103- set_json = """
117+ # This is the fully modeled JSON we want to update with
118+ update_json = json .loads ("""
104119{
105- "config": {
106- "login-banner": "Hello, gNMI!"
120+ "openconfig-interfaces:interfaces": {
121+ "interface": [
122+ {
123+ "name": "Loopback9339"
124+ }
125+ ]
107126 }
108127}
109- """
128+ """ )
129+ # Let's just do an update from the very top element
130+ top_element = next (iter (update_json .keys ()))
131+ set_update .path .CopyFrom (client .parse_xpath_to_gnmi_path (top_element ))
132+ # Remove the top element from the config since it's now in Path
133+ update_json = update_json .pop (top_element )
134+ # Set our update payload
135+ set_update .val .json_ietf_val = json .dumps (update_json ).encode ("utf-8" )
136+ set_result = client .set (updates = [set_update ])
137+ print (set_result )
138+ # This may all seem somewhat obtuse, and that's what the client wrappers are for.
0 commit comments