Skip to content

Commit 3471e71

Browse files
authored
Merge pull request #26 from cisco-ie/xe-client
IOS XE Client
2 parents 2215560 + 2829469 commit 3471e71

File tree

6 files changed

+381
-8
lines changed

6 files changed

+381
-8
lines changed

README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ from cisco_gnmi import ClientBuilder
109109

110110
client = ClientBuilder(
111111
'127.0.0.1:9339'
112-
).set_os('IOS XR').set_secure_from_file(
112+
).set_os('IOS XE').set_secure_from_file(
113113
root_certificates='rootCA.pem',
114114
private_key='client.key',
115115
certificate_chain='client.crt',
@@ -125,10 +125,20 @@ client = ClientBuilder(
125125

126126
Methods are documented in [`src/cisco_gnmi/client.py`](src/cisco_gnmi/client.py).
127127

128+
### NXClient
129+
`NXClient` inherits from `Client` and provides several wrapper methods which aid with NX-OS gNMI implementation usage. These are `subscribe_xpaths`, and the removal of `get` and `set` as they are not yet supported operations. These methods have some helpers and constraints around what is supported by the implementation.
130+
131+
Methods and usage examples are documented in [`src/cisco_gnmi/nx.py`](src/cisco_gnmi/nx.py).
132+
133+
### XEClient
134+
`XEClient` inherits from `Client` and provides several wrapper methods which aid with IOS XE gNMI implementation usage. These are `delete_xpaths`, `get_xpaths`, `set_json`, and `subscribe_xpaths`. These methods have some helpers and constraints around what is supported by the implementation.
135+
136+
Methods and usage examples are documented in [`src/cisco_gnmi/xe.py`](src/cisco_gnmi/xe.py).
137+
128138
### XRClient
129-
`XRClient` inherets from `Client` and provides several wrapper methods which aid with IOS XR-specific behaviors of the gNMI implementation. These are `delete_xpaths`, `get_xpaths`, `set_json`, and `subscribe_xpaths`. These methods make several assumptions about what kind of information will be supplied to them in order to simplify usage of the gNMI RPCs, detailed in the documentation.
139+
`XRClient` inherits from `Client` and provides several wrapper methods which aid with IOS XR gNMI implementation usage. These are `delete_xpaths`, `get_xpaths`, `set_json`, and `subscribe_xpaths`. These methods have some helpers and constraints around what is supported by the implementation.
130140

131-
Methods are documented in [`src/cisco_gnmi/xr.py`](src/cisco_gnmi/xr.py).
141+
Methods and usage examples are documented in [`src/cisco_gnmi/xr.py`](src/cisco_gnmi/xr.py).
132142

133143
## gNMI
134144
gRPC Network Management Interface (gNMI) is a service defining an interface for a network management system (NMS) to interact with a network element. It may be thought of as akin to NETCONF or other control protocols which define operations and behaviors. The scope of gNMI is relatively simple - it seeks to "[[define](https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md)] a gRPC-based protocol for the modification and retrieval of configuration from a target device, as well as the control and generation of telemetry streams from a target device to a data collection system. The intention is that a single gRPC service definition can cover both configuration and telemetry - allowing a single implementation on the target, as well as a single NMS element to interact with the device via telemetry and configuration RPCs".

scripts/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
certs/

scripts/gen_certs.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env bash
2+
# Derived from https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/prog/configuration/1612/b_1612_programmability_cg/grpc_network_management_interface.html#id_89031
3+
4+
CERT_BASE="certs"
5+
6+
if [ -z $1 ]; then
7+
echo "Usage: gen_certs.sh <hostname> [<password>]"
8+
exit 1
9+
fi
10+
11+
mkdir -p $CERT_BASE
12+
13+
# Setting up a CA
14+
openssl genrsa -out $CERT_BASE/rootCA.key 2048
15+
openssl req -subj /C=/ST=/L=/O=/CN=rootCA -x509 -new -nodes -key $CERT_BASE/rootCA.key -sha256 -out $CERT_BASE/rootCA.pem
16+
17+
# Setting up device cert and key
18+
openssl genrsa -out $CERT_BASE/device.key 2048
19+
openssl req -subj /C=/ST=/L=/O=/CN=$1 -new -key $CERT_BASE/device.key -out $CERT_BASE/device.csr
20+
openssl x509 -req -in $CERT_BASE/device.csr -CA $CERT_BASE/rootCA.pem -CAkey $CERT_BASE/rootCA.key -CAcreateserial -out $CERT_BASE/device.crt -sha256
21+
22+
# Encrypt device key - needed for input to IOS
23+
if [ ! -z $2 ]; then
24+
openssl rsa -des3 -in $CERT_BASE/device.key -out $CERT_BASE/device.des3.key -passout pass:$2
25+
else
26+
echo "Skipping device key encryption."
27+
fi
28+
29+
# Setting up client cert and key
30+
openssl genrsa -out $CERT_BASE/client.key 2048
31+
openssl req -subj /C=/ST=/L=/O=/CN=gnmi_client -new -key $CERT_BASE/client.key -out $CERT_BASE/client.csr
32+
openssl x509 -req -in $CERT_BASE/client.csr -CA $CERT_BASE/rootCA.pem -CAkey $CERT_BASE/rootCA.key -CAcreateserial -out $CERT_BASE/client.crt -sha256

src/cisco_gnmi/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from .client import Client
2828
from .xr import XRClient
2929
from .nx import NXClient
30+
from .xe import XEClient
3031
from .builder import ClientBuilder
3132

32-
__version__ = "1.0.1"
33+
__version__ = "1.0.2"

src/cisco_gnmi/builder.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import logging
2727

2828
import grpc
29-
from . import Client, XRClient, NXClient
29+
from . import Client, XRClient, NXClient, XEClient
3030
from .auth import CiscoAuthPlugin
3131
from .util import gen_target_netloc, get_cert_from_target, get_cn_from_cert
3232

@@ -74,7 +74,12 @@ class ClientBuilder(object):
7474
>>> print(capabilities)
7575
"""
7676

77-
os_class_map = {None: Client, "IOS XR": XRClient, "NX-OS": NXClient}
77+
os_class_map = {
78+
None: Client,
79+
"IOS XR": XRClient,
80+
"NX-OS": NXClient,
81+
"IOS XE": XEClient,
82+
}
7883

7984
def __init__(self, target):
8085
"""Initializes the builder, most initialization is done via set_* methods.
@@ -114,8 +119,9 @@ def set_os(self, name=None):
114119
name : str
115120
"IOS XR" maps to the XRClient class.
116121
"NX-OS" maps to the NXClient class.
122+
"IOS XE" maps to the XEClient class.
117123
None maps to the base Client class which simply wraps the gNMI stub.
118-
["IOS XR", "NX-OS", None]
124+
["IOS XR", "NX-OS", "IOS XE", None]
119125
120126
Returns
121127
-------
@@ -268,7 +274,7 @@ def construct(self):
268274
269275
Returns
270276
-------
271-
Client or XRClient
277+
Client or NXClient or XEClient or XRClient
272278
"""
273279
channel = None
274280
channel_ssl_creds = None

0 commit comments

Comments
 (0)