Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor subscribe_xpaths into base Client #48

Merged
merged 8 commits into from
Apr 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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