Skip to content

Commit

Permalink
Merge pull request #26 from cisco-ie/xe-client
Browse files Browse the repository at this point in the history
IOS XE Client
  • Loading branch information
remingtonc committed Oct 24, 2019
2 parents 2215560 + 2829469 commit 3471e71
Show file tree
Hide file tree
Showing 6 changed files with 381 additions and 8 deletions.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ from cisco_gnmi import ClientBuilder

client = ClientBuilder(
'127.0.0.1:9339'
).set_os('IOS XR').set_secure_from_file(
).set_os('IOS XE').set_secure_from_file(
root_certificates='rootCA.pem',
private_key='client.key',
certificate_chain='client.crt',
Expand All @@ -125,10 +125,20 @@ client = ClientBuilder(

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

### NXClient
`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.

Methods and usage examples are documented in [`src/cisco_gnmi/nx.py`](src/cisco_gnmi/nx.py).

### XEClient
`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.

Methods and usage examples are documented in [`src/cisco_gnmi/xe.py`](src/cisco_gnmi/xe.py).

### XRClient
`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.
`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.

Methods are documented in [`src/cisco_gnmi/xr.py`](src/cisco_gnmi/xr.py).
Methods and usage examples are documented in [`src/cisco_gnmi/xr.py`](src/cisco_gnmi/xr.py).

## gNMI
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".
Expand Down
1 change: 1 addition & 0 deletions scripts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
certs/
32 changes: 32 additions & 0 deletions scripts/gen_certs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# 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

CERT_BASE="certs"

if [ -z $1 ]; then
echo "Usage: gen_certs.sh <hostname> [<password>]"
exit 1
fi

mkdir -p $CERT_BASE

# Setting up a CA
openssl genrsa -out $CERT_BASE/rootCA.key 2048
openssl req -subj /C=/ST=/L=/O=/CN=rootCA -x509 -new -nodes -key $CERT_BASE/rootCA.key -sha256 -out $CERT_BASE/rootCA.pem

# Setting up device cert and key
openssl genrsa -out $CERT_BASE/device.key 2048
openssl req -subj /C=/ST=/L=/O=/CN=$1 -new -key $CERT_BASE/device.key -out $CERT_BASE/device.csr
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

# Encrypt device key - needed for input to IOS
if [ ! -z $2 ]; then
openssl rsa -des3 -in $CERT_BASE/device.key -out $CERT_BASE/device.des3.key -passout pass:$2
else
echo "Skipping device key encryption."
fi

# Setting up client cert and key
openssl genrsa -out $CERT_BASE/client.key 2048
openssl req -subj /C=/ST=/L=/O=/CN=gnmi_client -new -key $CERT_BASE/client.key -out $CERT_BASE/client.csr
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
3 changes: 2 additions & 1 deletion src/cisco_gnmi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from .client import Client
from .xr import XRClient
from .nx import NXClient
from .xe import XEClient
from .builder import ClientBuilder

__version__ = "1.0.1"
__version__ = "1.0.2"
14 changes: 10 additions & 4 deletions src/cisco_gnmi/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import logging

import grpc
from . import Client, XRClient, NXClient
from . import Client, XRClient, NXClient, XEClient
from .auth import CiscoAuthPlugin
from .util import gen_target_netloc, get_cert_from_target, get_cn_from_cert

Expand Down Expand Up @@ -74,7 +74,12 @@ class ClientBuilder(object):
>>> print(capabilities)
"""

os_class_map = {None: Client, "IOS XR": XRClient, "NX-OS": NXClient}
os_class_map = {
None: Client,
"IOS XR": XRClient,
"NX-OS": NXClient,
"IOS XE": XEClient,
}

def __init__(self, target):
"""Initializes the builder, most initialization is done via set_* methods.
Expand Down Expand Up @@ -114,8 +119,9 @@ def set_os(self, name=None):
name : str
"IOS XR" maps to the XRClient class.
"NX-OS" maps to the NXClient class.
"IOS XE" maps to the XEClient class.
None maps to the base Client class which simply wraps the gNMI stub.
["IOS XR", "NX-OS", None]
["IOS XR", "NX-OS", "IOS XE", None]
Returns
-------
Expand Down Expand Up @@ -268,7 +274,7 @@ def construct(self):
Returns
-------
Client or XRClient
Client or NXClient or XEClient or XRClient
"""
channel = None
channel_ssl_creds = None
Expand Down
Loading

0 comments on commit 3471e71

Please sign in to comment.