Skip to content
Snippets Groups Projects
Commit 33d6b9a4 authored by Thomas Schneider's avatar Thomas Schneider
Browse files

Use Click for CLI

parent 56213186
No related branches found
No related tags found
No related merge requests found
......@@ -15,6 +15,15 @@ dependencies = [
"pycparser",
]
[[package]]
name = "click"
version = "8.1.3"
requires_python = ">=3.7"
summary = "Composable command line interface toolkit"
dependencies = [
"colorama; platform_system == \"Windows\"",
]
[[package]]
name = "colorama"
version = "0.4.6"
......@@ -103,7 +112,7 @@ dependencies = [
[metadata]
lock_version = "4.1"
content_hash = "sha256:e49493c40f029631f0f923d9f3306cb05766876dfc284149bcf2bfdc891be04f"
content_hash = "sha256:c98532200135ebeef1c30c0c059c06d6568956765158022c0eb9bb561d946e38"
[metadata.files]
"bcrypt 4.0.1" = [
......@@ -195,6 +204,10 @@ content_hash = "sha256:e49493c40f029631f0f923d9f3306cb05766876dfc284149bcf2bfdc8
{url = "https://files.pythonhosted.org/packages/f9/96/fc9e118c47b7adc45a0676f413b4a47554e5f3b6c99b8607ec9726466ef1/cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"},
{url = "https://files.pythonhosted.org/packages/ff/fe/ac46ca7b00e9e4f9c62e7928a11bc9227c86e2ff43526beee00cdfb4f0e8/cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"},
]
"click 8.1.3" = [
{url = "https://files.pythonhosted.org/packages/59/87/84326af34517fca8c58418d148f2403df25303e02736832403587318e9e8/click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
{url = "https://files.pythonhosted.org/packages/c2/f1/df59e28c642d583f7dacffb1e0965d0e00b218e0186d7858ac5233dce840/click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
]
"colorama 0.4.6" = [
{url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
......
......@@ -13,6 +13,7 @@ dependencies = [
"ncclient>=0.6.13",
"lxml>=4.9.2",
"tqdm>=4.65.0",
"click>=8.1.3",
]
[project.scripts]
......
import argparse
from getpass import getpass
import os
import os.path
import click
import lxml.etree as et
from ncclient import manager
......@@ -10,23 +11,38 @@ from ncclient import manager
from tqdm import tqdm
def get_models(args):
@click.group(context_settings=dict(help_option_names=["-h", "--help"]))
def main():
pass
@main.command()
@click.option("-a", "--host", required=True, help="Device IP address or Hostname")
@click.option(
"--port", type=int, default=830, show_default=True, help="Netconf agent port"
)
@click.option(
"-u", "--username", required=True, help="Device Username (netconf agent username)"
)
@click.option("-d", "--destination", default="models", help="Destination directory")
def get_models(host, port, username, destination):
"""Get YANG models from device"""
try:
password = getpass(prompt="Password (C-d for none/agent only): ")
except EOFError:
password = None
with manager.connect(
host=args.host,
port=args.port,
username=args.username,
host=host,
port=port,
username=username,
password=password,
timeout=90,
device_params={"name": "iosxe"},
) as m:
caps = list(map(lambda x: x.strip(), m.server_capabilities))
if not any(map(lambda x: x.startswith(manager.NETCONF_MONITORING_NS), caps)):
raise Exception("device does not support rfc6022")
raise click.ClickException("device does not support rfc6022")
_filter = et.fromstring(
f"""
......@@ -38,7 +54,7 @@ def get_models(args):
prefix = f"{{{manager.NETCONF_MONITORING_NS}}}"
os.makedirs(args.destination, exist_ok=True)
os.makedirs(destination, exist_ok=True)
pbar = tqdm(
res.data.findall(
......@@ -64,34 +80,5 @@ def get_models(args):
# Don’t pass format because IOS XE doesn’t eat its own definition.
r = m.get_schema(identifier, version)
with open(os.path.join(args.destination, filename), "w") as fp:
with open(os.path.join(destination, filename), "w") as fp:
fp.write(r.data)
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"-a", "--host", type=str, required=True, help="Device IP address or Hostname"
)
parser.add_argument(
"-u",
"--username",
type=str,
required=True,
help="Device Username (netconf agent username)",
)
parser.add_argument("--port", type=int, default=830, help="Netconf agent port")
subparsers = parser.add_subparsers(required=True)
parser_gm = subparsers.add_parser(
"get-models", aliases=["gm"], help="Get YANG models from device"
)
parser_gm.add_argument(
"-d", "--destination", default="models", help="Destination directory"
)
parser_gm.set_defaults(func=get_models)
args = parser.parse_args()
args.func(args)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment