diff --git a/docs/netlab/defaults.md b/docs/netlab/defaults.md index 329977af3e..aaf8867874 100644 --- a/docs/netlab/defaults.md +++ b/docs/netlab/defaults.md @@ -19,26 +19,29 @@ ```text usage: netlab defaults [-h] [-r] [--delete] [-s] [--directory] [--project] [--user] [--system] [--package] [--yes] [--yaml] + [--format {yaml,env,export}] [setting] Manage netlab default settings positional arguments: - setting Specify setting to set (with s=v) or display (can be a glob) + setting Specify setting to set (with s=v) or display (can be a glob) options: - -h, --help show this help message and exit - -r, --regex Display default settings matching a regular expression - --delete Delete the settings matching the specified pattern from the specified - datastore - -s, --source Display the source of the default setting - --directory Display or store settings from the current directory - --project Display or store settings from the current project defaults - --user Display or store settings from the user default file - --system Display or store settings from the system default file - --package Display settings included in netlab package - --yes Overwrite existing settings without a confirmation - --yaml Store changed defaults in expanded YAML format + -h, --help show this help message and exit + -r, --regex Display default settings matching a regular expression + --delete Delete the settings matching the specified pattern from the + specified datastore + -s, --source Display the source of the default setting + --directory Display or store settings from the current directory + --project Display or store settings from the current project defaults + --user Display or store settings from the user default file + --system Display or store settings from the system default file + --package Display settings included in netlab package + --yes Overwrite existing settings without a confirmation + --yaml Store changed defaults in expanded YAML format + --format {yaml,env,export} + Alternate output format of the "show" action ``` ```{note} @@ -69,13 +72,24 @@ devices.csr.clab.image = vrnetlab/vr-csr:17.03.04 (netlab) devices.csr.clab.image = vrnetlab/cisco_csr1000v:17.03.08 (user) ``` +You can also display the default settings as environment variables (that you can change for subsequent **netlab up** commands) or as exported environment variables: + +```bash +$ netlab defaults --format env devices.srlinux.clab.image +NETLAB_DEVICES_SRLINUX_CLAB_IMAGE=ghcr.io/nokia/srlinux:26.3.2 +$ netlab defaults --format export devices.srlinux.clab.image +export NETLAB_DEVICES_SRLINUX_CLAB_IMAGE=ghcr.io/nokia/srlinux:26.3.2 +``` + Specify a default prefix to display a subset of defaults. For example, to display Arista EOS EVPN features, use **devices.eos.features.evpn** parameter: ``` $ netlab defaults devices.eos.features.evpn devices.eos.features.evpn.asymmetrical_irb = True -devices.eos.features.evpn.bundle = ['vlan_aware'] +devices.eos.features.evpn.bundle = [vlan_aware] +devices.eos.features.evpn.ipv6 = True devices.eos.features.evpn.irb = True +devices.eos.features.evpn.transport = [vxlan, mpls, sr] ``` You can also use glob expressions to select the parameters you want to display. For example, use `*clab.image*` to display all containerlab image settings: diff --git a/netsim/cli/defaults.py b/netsim/cli/defaults.py index 8f46d039cb..7f55487d00 100644 --- a/netsim/cli/defaults.py +++ b/netsim/cli/defaults.py @@ -5,6 +5,7 @@ import fnmatch import pathlib import re +import shlex import typing import yaml @@ -71,6 +72,12 @@ def defaults_parse(args: typing.List[str]) -> argparse.Namespace: dest='yaml', action='store_true', help='Store changed defaults in expanded YAML format') + parser.add_argument( + '--format', + dest='format', + action='store', + choices=['yaml','env','export'], + help='Alternate output format of the "show" action') parser.add_argument( dest='setting', action='store', @@ -221,10 +228,12 @@ def get_re_pattern(txt: str, regex: bool = False) -> re.Pattern: return reobj -def print_def_list(def_expanded: Box, show_source: bool) -> None: +def print_def_list(def_expanded: Box, args: argparse.Namespace) -> None: + def_dict = def_expanded.to_dict() + to_yaml = args.format == 'yaml' for k in sorted(def_expanded): ns_list = list(def_expanded[k]) - if show_source: + if args.source and not args.format: for ns in ns_list: txt = f'{k} = {def_expanded[k][ns]} ({ns})' if ns != ns_list[-1] and strings.rich_color: @@ -232,7 +241,18 @@ def print_def_list(def_expanded: Box, show_source: bool) -> None: else: print(txt) else: - print(f'{k} = {def_expanded[k][ns_list[-1]]}') + v = def_dict[k][ns_list[-1]] + is_obj = isinstance(v,(dict,list)) + v_txt = yaml.dump(v,default_flow_style=True,width=9999).split("\n")[0] if is_obj or to_yaml else str(v) + if not args.format: + print(f'{k} = {v_txt}') + elif args.format == 'yaml': + print(f'{k}: {v_txt}') + else: + key = 'NETLAB_'+k.replace('_','__').replace('.','_').upper() + if args.format == 'export': + key = 'export '+key + print(f'{key}={shlex.quote(v_txt)}') def default_show(args: argparse.Namespace) -> None: global D_SOURCES @@ -242,7 +262,7 @@ def default_show(args: argparse.Namespace) -> None: def_expanded = build_defaults_sources(reobj,d_sources) if def_expanded: - print_def_list(def_expanded,args.source) + print_def_list(def_expanded,args) else: d_src_txt = '' if d_sources == D_SOURCES else f' in {",".join(d_sources)} defaults' error_and_exit(f'{args.setting}{" regular expression" if args.regex else ""} not found{d_src_txt}',module='-')