|
1 | | -import logging |
2 | | -import logging.handlers |
3 | 1 | import json |
4 | | -import sys # (built-in module) |
5 | 2 | import os |
6 | | -import argparse |
| 3 | +import sys |
7 | 4 |
|
8 | 5 | from . import common |
9 | 6 | from . import host |
10 | 7 |
|
11 | | -def main(): |
12 | | - def dirpath(path): |
13 | | - if not os.path.isdir(path): |
14 | | - raise argparse.ArgumentTypeError(f"'{path}' is not a valid directory") |
15 | | - return path |
| 8 | +USAGE = """\ |
| 9 | +usage: yanger [-p PARAM] [-x PREFIX] [-r DIR | -c DIR] model |
16 | 10 |
|
17 | | - parser = argparse.ArgumentParser(description="YANG data creator") |
18 | | - parser.add_argument("model", help="YANG Model") |
19 | | - parser.add_argument("-p", "--param", |
20 | | - help="Model dependent parameter, e.g. interface name") |
21 | | - parser.add_argument("-x", "--cmd-prefix", metavar="PREFIX", |
22 | | - help="Use this prefix for all system commands, e.g. " + |
23 | | - "'ssh user@remotehost sudo'") |
| 11 | +YANG data creator |
24 | 12 |
|
25 | | - rrparser = parser.add_mutually_exclusive_group() |
26 | | - rrparser.add_argument("-r", "--replay", type=dirpath, metavar="DIR", |
27 | | - help="Generate output based on recorded system commands from DIR, " + |
28 | | - "rather than querying the local system") |
29 | | - rrparser.add_argument("-c", "--capture", metavar="DIR", |
30 | | - help="Capture system command output in DIR, such that the current system " + |
31 | | - "state can be recreated offline (with --replay) for testing purposes") |
| 13 | +positional arguments: |
| 14 | + model YANG Model |
32 | 15 |
|
33 | | - args = parser.parse_args() |
34 | | - if args.replay and args.cmd_prefix: |
35 | | - parser.error("--cmd-prefix cannot be used with --replay") |
| 16 | +options: |
| 17 | + -p, --param PARAM Model dependent parameter, e.g. interface name |
| 18 | + -x, --cmd-prefix PREFIX |
| 19 | + Use this prefix for all system commands, e.g. |
| 20 | + 'ssh user@remotehost sudo' |
| 21 | + -r, --replay DIR Generate output based on recorded system commands |
| 22 | + from DIR, rather than querying the local system |
| 23 | + -c, --capture DIR Capture system command output in DIR, such that the |
| 24 | + current system state can be recreated offline (with |
| 25 | + --replay) for testing purposes |
| 26 | +""" |
36 | 27 |
|
37 | | - # Set up syslog output for critical errors to aid debugging |
38 | | - common.LOG = logging.getLogger('yanger') |
39 | | - if os.path.exists('/dev/log'): |
40 | | - log = logging.handlers.SysLogHandler(address='/dev/log') |
41 | | - else: |
42 | | - # Use /dev/null as a fallback for unit tests |
43 | | - log = logging.FileHandler('/dev/null') |
| 28 | +def _parse_args(argv): |
| 29 | + model = None |
| 30 | + param = None |
| 31 | + cmd_prefix = None |
| 32 | + replay = None |
| 33 | + capture = None |
| 34 | + |
| 35 | + i = 1 |
| 36 | + while i < len(argv): |
| 37 | + arg = argv[i] |
| 38 | + if arg in ('-h', '--help'): |
| 39 | + sys.stdout.write(USAGE) |
| 40 | + sys.exit(0) |
| 41 | + elif arg in ('-p', '--param'): |
| 42 | + i += 1 |
| 43 | + if i >= len(argv): |
| 44 | + sys.exit(f"error: {arg} requires an argument") |
| 45 | + param = argv[i] |
| 46 | + elif arg in ('-x', '--cmd-prefix'): |
| 47 | + i += 1 |
| 48 | + if i >= len(argv): |
| 49 | + sys.exit(f"error: {arg} requires an argument") |
| 50 | + cmd_prefix = argv[i] |
| 51 | + elif arg in ('-r', '--replay'): |
| 52 | + i += 1 |
| 53 | + if i >= len(argv): |
| 54 | + sys.exit(f"error: {arg} requires an argument") |
| 55 | + replay = argv[i] |
| 56 | + if not os.path.isdir(replay): |
| 57 | + sys.exit(f"error: '{replay}' is not a valid directory") |
| 58 | + elif arg in ('-c', '--capture'): |
| 59 | + i += 1 |
| 60 | + if i >= len(argv): |
| 61 | + sys.exit(f"error: {arg} requires an argument") |
| 62 | + capture = argv[i] |
| 63 | + elif arg.startswith('-'): |
| 64 | + sys.exit(f"error: unknown option: {arg}") |
| 65 | + elif model is None: |
| 66 | + model = arg |
| 67 | + else: |
| 68 | + sys.exit(f"error: unexpected argument: {arg}") |
| 69 | + i += 1 |
44 | 70 |
|
45 | | - fmt = logging.Formatter('%(name)s[%(process)d]: %(message)s') |
46 | | - log.setFormatter(fmt) |
47 | | - common.LOG.setLevel(logging.INFO) |
48 | | - common.LOG.addHandler(log) |
| 71 | + if model is None: |
| 72 | + sys.exit("error: missing required argument: model") |
| 73 | + if replay and cmd_prefix: |
| 74 | + sys.exit("error: --cmd-prefix cannot be used with --replay") |
| 75 | + if replay and capture: |
| 76 | + sys.exit("error: --replay cannot be used with --capture") |
| 77 | + |
| 78 | + return model, param, cmd_prefix, replay, capture |
| 79 | + |
| 80 | +def main(): |
| 81 | + model, param, cmd_prefix, replay, capture = _parse_args(sys.argv) |
49 | 82 |
|
50 | | - if args.cmd_prefix or args.capture: |
51 | | - host.HOST = host.Remotehost(args.cmd_prefix, args.capture) |
52 | | - elif args.replay: |
53 | | - host.HOST = host.Replayhost(args.replay) |
| 83 | + if cmd_prefix or capture: |
| 84 | + host.HOST = host.Remotehost(cmd_prefix, capture) |
| 85 | + elif replay: |
| 86 | + host.HOST = host.Replayhost(replay) |
54 | 87 | else: |
55 | 88 | host.HOST = host.Localhost() |
56 | 89 |
|
57 | | - if args.model == 'ietf-interfaces': |
| 90 | + if model == 'ietf-interfaces': |
58 | 91 | from . import ietf_interfaces |
59 | | - yang_data = ietf_interfaces.operational(args.param) |
60 | | - elif args.model == 'ietf-routing': |
| 92 | + yang_data = ietf_interfaces.operational(param) |
| 93 | + elif model == 'ietf-routing': |
61 | 94 | from . import ietf_routing |
62 | 95 | yang_data = ietf_routing.operational() |
63 | | - elif args.model == 'ietf-ospf': |
| 96 | + elif model == 'ietf-ospf': |
64 | 97 | from . import ietf_ospf |
65 | 98 | yang_data = ietf_ospf.operational() |
66 | | - elif args.model == 'ietf-rip': |
| 99 | + elif model == 'ietf-rip': |
67 | 100 | from . import ietf_rip |
68 | 101 | yang_data = ietf_rip.operational() |
69 | | - elif args.model == 'ietf-hardware': |
| 102 | + elif model == 'ietf-hardware': |
70 | 103 | from . import ietf_hardware |
71 | 104 | yang_data = ietf_hardware.operational() |
72 | | - elif args.model == 'infix-containers': |
| 105 | + elif model == 'infix-containers': |
73 | 106 | from . import infix_containers |
74 | 107 | yang_data = infix_containers.operational() |
75 | | - elif args.model == 'infix-dhcp-server': |
| 108 | + elif model == 'infix-dhcp-server': |
76 | 109 | from . import infix_dhcp_server |
77 | 110 | yang_data = infix_dhcp_server.operational() |
78 | | - elif args.model == 'ietf-system': |
| 111 | + elif model == 'ietf-system': |
79 | 112 | from . import ietf_system |
80 | 113 | yang_data = ietf_system.operational() |
81 | | - elif args.model == 'ietf-ntp': |
| 114 | + elif model == 'ietf-ntp': |
82 | 115 | from . import ietf_ntp |
83 | 116 | yang_data = ietf_ntp.operational() |
84 | | - elif args.model == 'ieee802-dot1ab-lldp': |
| 117 | + elif model == 'ieee802-dot1ab-lldp': |
85 | 118 | from . import infix_lldp |
86 | 119 | yang_data = infix_lldp.operational() |
87 | | - elif args.model == 'infix-firewall': |
| 120 | + elif model == 'infix-firewall': |
88 | 121 | from . import infix_firewall |
89 | 122 | yang_data = infix_firewall.operational() |
90 | | - elif args.model == 'ietf-bfd-ip-sh': |
| 123 | + elif model == 'ietf-bfd-ip-sh': |
91 | 124 | from . import ietf_bfd_ip_sh |
92 | 125 | yang_data = ietf_bfd_ip_sh.operational() |
93 | 126 | else: |
94 | | - common.LOG.warning("Unsupported model %s", args.model) |
| 127 | + common.LOG.warning("Unsupported model %s", model) |
95 | 128 | sys.exit(1) |
96 | 129 |
|
97 | 130 | print(json.dumps(yang_data, indent=2, ensure_ascii=False)) |
|
0 commit comments