Skip to content

Commit

Permalink
Merge pull request #48 from cisco-ie/subscribe-xpaths-refactor
Browse files Browse the repository at this point in the history
Refactor subscribe_xpaths into base Client
  • Loading branch information
remingtonc authored Apr 16, 2020
2 parents fb94dd2 + d824e7c commit de478bf
Show file tree
Hide file tree
Showing 9 changed files with 384 additions and 223 deletions.
91 changes: 52 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,12 @@ cisco-gnmi capabilities 127.0.0.1:57500 -auto_ssl_target_override
```
cisco-gnmi capabilities --help
usage: cisco-gnmi [-h] [-os {None,IOS XR,NX-OS,IOS XE}]
[-root_certificates ROOT_CERTIFICATES]
[-private_key PRIVATE_KEY]
[-certificate_chain CERTIFICATE_CHAIN]
[-ssl_target_override SSL_TARGET_OVERRIDE]
[-auto_ssl_target_override] [-debug]
netloc
[-root_certificates ROOT_CERTIFICATES]
[-private_key PRIVATE_KEY]
[-certificate_chain CERTIFICATE_CHAIN]
[-ssl_target_override SSL_TARGET_OVERRIDE]
[-auto_ssl_target_override] [-debug]
netloc
Performs Capabilities RPC against network element.
Expand Down Expand Up @@ -309,16 +309,17 @@ cisco-gnmi get 127.0.0.1:57500 -os "IOS XR" -xpath /interfaces/interface/state/c

#### Usage
```
cisco-gnmi get --help
usage: cisco-gnmi [-h] [-xpath XPATH]
[-encoding [{JSON,BYTES,PROTO,ASCII,JSON_IETF}]]
[-data_type [{ALL,CONFIG,STATE,OPERATIONAL}]] [-dump_json]
[-os {None,IOS XR,NX-OS,IOS XE}]
[-root_certificates ROOT_CERTIFICATES]
[-private_key PRIVATE_KEY]
[-certificate_chain CERTIFICATE_CHAIN]
[-ssl_target_override SSL_TARGET_OVERRIDE]
[-auto_ssl_target_override] [-debug]
netloc
[-encoding {JSON,BYTES,PROTO,ASCII,JSON_IETF}]
[-data_type {ALL,CONFIG,STATE,OPERATIONAL}] [-dump_json]
[-os {None,IOS XR,NX-OS,IOS XE}]
[-root_certificates ROOT_CERTIFICATES]
[-private_key PRIVATE_KEY]
[-certificate_chain CERTIFICATE_CHAIN]
[-ssl_target_override SSL_TARGET_OVERRIDE]
[-auto_ssl_target_override] [-debug]
netloc
Performs Get RPC against network element.
Expand All @@ -328,9 +329,9 @@ positional arguments:
optional arguments:
-h, --help show this help message and exit
-xpath XPATH XPaths to Get.
-encoding [{JSON,BYTES,PROTO,ASCII,JSON_IETF}]
-encoding {JSON,BYTES,PROTO,ASCII,JSON_IETF}
gNMI Encoding.
-data_type [{ALL,CONFIG,STATE,OPERATIONAL}]
-data_type {ALL,CONFIG,STATE,OPERATIONAL}
gNMI GetRequest DataType
-dump_json Dump as JSON instead of textual protos.
-os {None,IOS XR,NX-OS,IOS XE}
Expand Down Expand Up @@ -381,16 +382,17 @@ Please note that `Set` operations may be destructive to operations and should be

#### Usage
```
cisco-gnmi set --help
usage: cisco-gnmi [-h] [-update_json_config UPDATE_JSON_CONFIG]
[-replace_json_config REPLACE_JSON_CONFIG]
[-delete_xpath DELETE_XPATH] [-no_ietf] [-dump_json]
[-os {None,IOS XR,NX-OS,IOS XE}]
[-root_certificates ROOT_CERTIFICATES]
[-private_key PRIVATE_KEY]
[-certificate_chain CERTIFICATE_CHAIN]
[-ssl_target_override SSL_TARGET_OVERRIDE]
[-auto_ssl_target_override] [-debug]
netloc
[-replace_json_config REPLACE_JSON_CONFIG]
[-delete_xpath DELETE_XPATH] [-no_ietf] [-dump_json]
[-os {None,IOS XR,NX-OS,IOS XE}]
[-root_certificates ROOT_CERTIFICATES]
[-private_key PRIVATE_KEY]
[-certificate_chain CERTIFICATE_CHAIN]
[-ssl_target_override SSL_TARGET_OVERRIDE]
[-auto_ssl_target_override] [-debug]
netloc
Performs Set RPC against network element.
Expand Down Expand Up @@ -469,24 +471,28 @@ interface Loopback9339
```

### Subscribe
This command will output the `SubscribeResponse` to `stdout` or `-dump_file`. `-xpath` may be specified multiple times to specify multiple `Path`s for the `GetRequest`. Subscribe currently only supports a sampled stream. `ON_CHANGE` is possible but not implemented in the CLI, yet. :)
This command will output the `SubscribeResponse` to `stdout` or `-dump_file`. `-xpath` may be specified multiple times to specify multiple `Path`s for the `GetRequest`.

```
cisco-gnmi subscribe 127.0.0.1:57500 -os "IOS XR" -xpath /interfaces/interface/state/counters -auto_ssl_target_override
```

#### Usage
```
cisco-gnmi subscribe --help
usage: cisco-gnmi [-h] [-xpath XPATH] [-interval INTERVAL] [-dump_file DUMP_FILE]
[-dump_json] [-sync_stop]
[-encoding [{JSON,BYTES,PROTO,ASCII,JSON_IETF}]]
[-os {None,IOS XR,NX-OS,IOS XE}]
[-root_certificates ROOT_CERTIFICATES]
[-private_key PRIVATE_KEY]
[-certificate_chain CERTIFICATE_CHAIN]
[-ssl_target_override SSL_TARGET_OVERRIDE]
[-auto_ssl_target_override] [-debug]
netloc
usage: cisco-gnmi [-h] [-xpath XPATH] [-interval INTERVAL]
[-mode {TARGET_DEFINED,ON_CHANGE,SAMPLE}]
[-suppress_redundant]
[-heartbeat_interval HEARTBEAT_INTERVAL]
[-dump_file DUMP_FILE] [-dump_json] [-sync_stop]
[-sync_start] [-encoding {JSON,BYTES,PROTO,ASCII,JSON_IETF}]
[-os {None,IOS XR,NX-OS,IOS XE}]
[-root_certificates ROOT_CERTIFICATES]
[-private_key PRIVATE_KEY]
[-certificate_chain CERTIFICATE_CHAIN]
[-ssl_target_override SSL_TARGET_OVERRIDE]
[-auto_ssl_target_override] [-debug]
netloc
Performs Subscribe RPC against network element.
Expand All @@ -498,11 +504,18 @@ optional arguments:
-xpath XPATH XPath to subscribe to.
-interval INTERVAL Sample interval in seconds for Subscription. Defaults
to 10.
-mode {TARGET_DEFINED,ON_CHANGE,SAMPLE}
SubscriptionMode for Subscription. Defaults to SAMPLE.
-suppress_redundant Suppress redundant information in Subscription.
-heartbeat_interval HEARTBEAT_INTERVAL
Heartbeat interval in seconds.
-dump_file DUMP_FILE Filename to dump to. Defaults to stdout.
-dump_json Dump as JSON instead of textual protos.
-sync_stop Stop on sync_response.
-encoding [{JSON,BYTES,PROTO,ASCII,JSON_IETF}]
gNMI Encoding.
-sync_start Start processing messages after sync_response.
-encoding {JSON,BYTES,PROTO,ASCII,JSON_IETF}
gNMI Encoding. Defaults to whatever Client wrapper
prefers.
-os {None,IOS XR,NX-OS,IOS XE}
OS wrapper to utilize. Defaults to IOS XR.
-root_certificates ROOT_CERTIFICATES
Expand Down
51 changes: 38 additions & 13 deletions scripts/gen_certs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,55 @@

CERT_BASE="certs"

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

server_hostname=$1
ip=$2
password=$3

mkdir -p $CERT_BASE

function print_red () {
printf "\033[0;31m$1 ...\033[0m\n"
}

# 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
if [ -f "$CERT_BASE/rootCA.key" ] && [ -f "$CERT_BASE/rootCA.pem" ]; then
print_red "SKIPPING rootCA generation, already exist"
else
print_red "GENERATING rootCA"
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 -days 1095 -out $CERT_BASE/rootCA.pem
fi

# Setting up device cert and key
print_red "GENERATING device certificates with CN $server_hostname and IP $ip"
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
openssl req -subj /C=/ST=/L=/O=/CN=$server_hostname -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 -days 1095 -sha256 -extfile <(printf "%s" "subjectAltName=DNS:$server_hostname,IP:$ip")

# 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
# Encrypt device key
if [ ! -z $password ]; then
print_red "ENCRYPTING device certificates and bundling with password"
# DES 3 for device, needed for input to IOS XE
openssl rsa -des3 -in $CERT_BASE/device.key -out $CERT_BASE/device.des3.key -passout pass:$password
# PKCS #12 for device, needed for NX-OS
# Uncertain if this is correct
openssl pkcs12 -export -out $CERT_BASE/device.pfx -inkey $CERT_BASE/device.key -in $CERT_BASE/device.crt -certfile $CERT_BASE/rootCA.pem -password pass:$password
else
echo "Skipping device key encryption."
print_red "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
if [ -f "$CERT_BASE/client.key" ] && [ -f "$CERT_BASE/client.crt" ]; then
print_red "SKIPPING client certificates generation, already exist"
else
hostname=$(hostname)
print_red "GENERATING client certificates with CN $hostname"
openssl genrsa -out $CERT_BASE/client.key 2048
openssl req -subj /C=/ST=/L=/O=/CN=$hostname -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 -days 1095 -sha256
fi
2 changes: 1 addition & 1 deletion src/cisco_gnmi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@
from .xe import XEClient
from .builder import ClientBuilder

__version__ = "1.0.5"
__version__ = "1.0.6"
48 changes: 38 additions & 10 deletions src/cisco_gnmi/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import argparse
from getpass import getpass
from google.protobuf import json_format, text_format
from . import ClientBuilder, proto
from . import ClientBuilder, proto, __version__
from google.protobuf.internal import enum_type_wrapper
import sys

Expand All @@ -52,6 +52,8 @@ def main():
usage="""
cisco-gnmi <rpc> [<args>]
Version {version}
Supported RPCs:
{supported_rpcs}
Expand All @@ -62,7 +64,8 @@ def main():
See <rpc> --help for RPC options.
""".format(
supported_rpcs="\n".join(list(rpc_map.keys()))
version=__version__,
supported_rpcs="\n".join(sorted(list(rpc_map.keys())))
),
)
parser.add_argument("rpc", help="gNMI RPC to perform against network element.")
Expand Down Expand Up @@ -91,8 +94,7 @@ def gnmi_capabilities():


def gnmi_subscribe():
"""Performs a sampled Subscribe against network element.
TODO: ON_CHANGE
"""Performs a streaming Subscribe against network element.
"""
parser = argparse.ArgumentParser(
description="Performs Subscribe RPC against network element."
Expand All @@ -106,6 +108,20 @@ def gnmi_subscribe():
type=int,
default=10,
)
parser.add_argument(
"-mode",
help="SubscriptionMode for Subscription. Defaults to SAMPLE.",
default="SAMPLE",
choices=proto.gnmi_pb2.SubscriptionMode.keys(),
)
parser.add_argument(
"-suppress_redundant",
help="Suppress redundant information in Subscription.",
action="store_true",
)
parser.add_argument(
"-heartbeat_interval", help="Heartbeat interval in seconds.", type=int
)
parser.add_argument(
"-dump_file",
help="Filename to dump to. Defaults to stdout.",
Expand All @@ -120,11 +136,15 @@ def gnmi_subscribe():
parser.add_argument(
"-sync_stop", help="Stop on sync_response.", action="store_true"
)
parser.add_argument(
"-sync_start",
help="Start processing messages after sync_response.",
action="store_true",
)
parser.add_argument(
"-encoding",
help="gNMI Encoding.",
help="gNMI Encoding. Defaults to whatever Client wrapper prefers.",
type=str,
nargs="?",
choices=proto.gnmi_pb2.Encoding.keys(),
)
args = __common_args_handler(parser)
Expand All @@ -138,20 +158,30 @@ def gnmi_subscribe():
kwargs["encoding"] = args.encoding
if args.interval:
kwargs["sample_interval"] = args.interval * int(1e9)
if args.mode:
kwargs["sub_mode"] = args.mode
if args.suppress_redundant:
kwargs["suppress_redundant"] = args.suppress_redundant
if args.heartbeat_interval:
kwargs["heartbeat_interval"] = args.heartbeat_interval * int(1e9)
try:
logging.info(
logging.debug(
"Dumping responses to %s as %s ...",
args.dump_file,
"JSON" if args.dump_json else "textual proto",
)
logging.info("Subscribing to:\n%s", "\n".join(args.xpath))
logging.debug("Subscribing to:\n%s", "\n".join(args.xpath))
synced = False
for subscribe_response in client.subscribe_xpaths(args.xpath, **kwargs):
logging.debug("SubscribeResponse received.")
if subscribe_response.sync_response:
logging.debug("sync_response received.")
if args.sync_stop:
logging.warning("Stopping on sync_response.")
break
synced = True
if not synced and args.sync_start:
continue
formatted_message = __format_message(subscribe_response)
if args.dump_file == "stdout":
logging.info(formatted_message)
Expand All @@ -175,14 +205,12 @@ def gnmi_get():
"-encoding",
help="gNMI Encoding.",
type=str,
nargs="?",
choices=proto.gnmi_pb2.Encoding.keys(),
)
parser.add_argument(
"-data_type",
help="gNMI GetRequest DataType",
type=str,
nargs="?",
choices=enum_type_wrapper.EnumTypeWrapper(
proto.gnmi_pb2._GETREQUEST_DATATYPE
).keys(),
Expand Down
Loading

0 comments on commit de478bf

Please sign in to comment.