def compliance( device_type: ShowFirmwareDevType = typer.Argument(..., metavar="[ap|gw|switch]",), _group: List[str] = typer.Argument(None, metavar="[GROUP-NAME]", autocompletion=cli.cache.group_completion), group_name: str = typer.Option(None, "--group", help="Filter by group", autocompletion=cli.cache.group_completion), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", help="Output in table format",), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), no_pager: bool = typer.Option(False, "--no-pager", help="Disable Paged Output"), update_cache: bool = typer.Option(False, "-U", hidden=True), # Force Update of cli.cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", show_default=False,), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging",), account: str = typer.Option("central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)",), ): central = cli.central cli.cache(refresh=update_cache) _type_to_name = { "AP": "IAP", "GATEWAY": "CONTROLLER", "GW": "CONTROLLER", "SWITCH": "HP" } # Allows both: # show firmware compliance <dev-type> <group iden> # show firmware compliance <dev-type> group <group iden> if len(_group) > 2: typer.echo(f"Unknown extra arguments in {[x for x in list(_group)[0:-1] if x.lower() != 'group']}") raise typer.Exit(1) _group = None if not _group else _group[-1] group = _group or group_name if group: group = cli.cache.get_group_identifier(group).name # TODO make device_type optional add 'all' keyword and implied 'all' if no device_type # add macro method to get compliance for all device_types. kwargs = { 'device_type': _type_to_name.get(device_type.upper(), device_type), 'group': group } resp = central.request(central.get_firmware_compliance, **kwargs) if resp.status == 404 and resp.output.lower() == "not found": resp.output = ( f"Invalid URL or No compliance set for {device_type.lower()} " f"{'Globally' if not group else f'in group {group}'}" ) typer.echo(str(resp).replace("404", typer.style("404", fg="red"))) else: tablefmt = cli.get_format(do_json=do_json, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table) cli.display_results( resp, tablefmt=tablefmt, title=f"{'Global ' if not group else f'{group} '}Firmware Compliance", pager=not no_pager, outfile=outfile )
def show_devices( dev_type: str, *args, outfile: Path = None, update_cache: bool = False, group: str = None, status: str = None, state: str = None, label: Union[str, List[str]] = None, pub_ip: str = None, do_clients: bool = False, do_stats: bool = False, sort_by: str = None, no_pager: bool = False, do_json: bool = False, do_csv: bool = False, do_yaml: bool = False, do_table: bool = False ) -> None: central = cli.central cli.cache(refresh=update_cache) _formatter = "yaml" if group: group = cli.cache.get_group_identifier(group) # -- // Peform GET Call \\ -- resp = None params = { "group": None if not group else group.name, "status": None if not status else status.title(), "label": label, "public_ip_address": pub_ip, "calculate_client_count": do_clients, "show_resource_details": do_stats, "sort": None if not sort_by else sort_by._value_ } # status and state keywords both allowed if params["status"] is None and state is not None: params["status"] = state.title() params = {k: v for k, v in params.items() if v is not None} if dev_type == "device": if args: # show devices [name|ip|mac|serial] dev = cli.cache.get_dev_identifier(args) resp = central.request(central.get_dev_details, dev.type, dev.serial, **params) else: # show devices ... equiv to show all _formatter = "rich" resp = central.request(central.get_all_devicesv2, **params) elif dev_type == "all": _formatter = "rich" # if no params (expected result may differ) update cli.cache if not updated this session and return results from there if len(params) == 2 and list(params.values()).count(False) == 2: if central.get_all_devicesv2 not in cli.cache.updated: asyncio.run(cli.cache.update_dev_db()) resp = Response(output=cli.cache.devices) else: # will only run if user specifies params (filters) resp = central.request(central.get_all_devicesv2, **params) # aps, switches, gateways, ... elif args: dev = cli.cache.get_dev_identifier(args, dev_type=dev_type) resp = central.request(central.get_dev_details, dev_type, dev.serial) else: resp = central.request(central.get_devices, dev_type, **params) # device details is a lot of data default to yaml output, default horizontal would typically overrun tty tablefmt = cli.get_format(do_json=do_json, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table, default=_formatter) cli.display_results(resp, tablefmt=tablefmt, pager=not no_pager, outfile=outfile, cleaner=cleaner.sort_result_keys)
def interfaces( device: str = typer.Argument(..., metavar=iden_meta.dev, hidden=False), slot: str = typer.Argument(None, help="Slot name of the ports to query (chassis only)",), # port: List[int] = typer.Argument(None, help="Optional list of interfaces to filter on"), sort_by: SortOptions = typer.Option(None, "--sort"), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", help="Output in table format",), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), no_pager: bool = typer.Option(False, "--no-pager", help="Disable Paged Output"), update_cache: bool = typer.Option(False, "-U", hidden=True), # Force Update of cli.cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", callback=cli.default_callback), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback), account: str = typer.Option("central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", callback=cli.account_name_callback), ): cli.cache(refresh=update_cache) dev = cli.cache.get_dev_identifier(device, ret_field="type-serial") resp = cli.central.request(cli.central.get_switch_ports, dev.serial, slot=slot, cx=dev.type == "CX") tablefmt = cli.get_format(do_json=do_json, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table, default="json") cli.display_results(resp, tablefmt=tablefmt, pager=not no_pager, outfile=outfile)
def clients( filter: ClientArgs = typer.Argument('all', case_sensitive=False, ), args: List[str] = typer.Argument(None, metavar=iden_meta.dev, help="Show clients for a specific device"), # os_type: # band: group: str = typer.Option(None, metavar="<Device Group>", help="Filter by Group", ), label: str = typer.Option(None, metavar="<Device Label>", help="Filter by Label", ), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON",), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML",), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV",), do_table: bool = typer.Option(False, "--table", help="Output in table format",), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True,), update_cache: bool = typer.Option(False, "-U", hidden=True,), # Force Update of cli.cache for testing sort_by: SortOptions = typer.Option(None, "--sort", hidden=True,), # TODO Unhide after implemented reverse: SortOptions = typer.Option(None, "-r", hidden=True,), # TODO Unhide after implemented verbose: bool = typer.Option(False, "-v", hidden=True,), # TODO Unhide after implemented no_pager: bool = typer.Option(False, "--no-pager", help="Disable Paged Output",), default: bool = typer.Option( False, "-d", is_flag=True, help="Use default central account", callback=cli.default_callback, ), debug: bool = typer.Option( False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback, ), account: str = typer.Option( "central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", callback=cli.account_name_callback, ), ) -> None: central = cli.central resp = central.request(central.get_clients, filter, *args,) # callback_kwargs={'cache': cli.cache}) tablefmt = cli.get_format(do_json=do_json, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table, default="json") cli.display_results( resp, tablefmt=tablefmt, pager=not no_pager, outfile=outfile, cleaner=cleaner.get_clients, cache=cli.cache )
def vlans( dev_site: str = typer.Argument( ..., metavar=f"{iden_meta.dev} (vlans for a device) OR {iden_meta.site} (vlans for a site)", ), # port: List[int] = typer.Argument(None, help="Optional list of interfaces to filter on"), # sort_by: SortOptions = typer.Option(None, "--sort", hidden=True), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", help="Output in table format",), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), no_pager: bool = typer.Option(False, "--no-pager", help="Disable Paged Output"), update_cache: bool = typer.Option(False, "-U", hidden=True), # Force Update of cli.cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", callback=cli.default_callback), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback), account: str = typer.Option("central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", callback=cli.account_name_callback), ) -> None: # TODO cli command lacks the filtering options available from method currently. central = cli.central cli.cache(refresh=update_cache) obj = cli.cache.get_identifier(dev_site, qry_funcs=("dev", "site")) if obj: if obj.is_site: resp = central.request(central.get_site_vlans, obj.id) elif obj.is_dev: if obj.type.lower() in ['cx', 'sw']: resp = central.request(central.get_switch_vlans, obj.serial, cx=obj.type == "CX") elif obj.type.lower() == 'gateway': resp = central.request(central.get_gateway_vlans, obj.serial) elif obj.type.lower() == 'mobility_controllers': resp = central.request(central.get_controller_vlans, obj.serial) else: typer.secho(f"show vlans not implemented for {dev_site}", fg="red") typer.echo(str(obj)) raise typer.exit(1) tablefmt = cli.get_format(do_json=do_json, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table, default="rich") cli.display_results(resp, tablefmt=tablefmt, pager=not no_pager, outfile=outfile, cleaner=cleaner.get_vlans)
def wlans( name: str = typer.Argument(None, metavar="[WLAN NAME]", help="Get Details for a specific WLAN"), group: str = typer.Option(None, metavar="<Device Group>", help="Filter by Group", ), label: str = typer.Option(None, metavar="<Device Label>", help="Filter by Label", ), site: str = typer.Option(None, metavar="[site identifier]", help="Filter by device status"), swarm_id: str = typer.Option(None,), do_clients: bool = typer.Option(False, "--clients", is_flag=True, help="Calculate client count (per SSID)"), sort_by: SortOptions = typer.Option(None, "--sort"), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", help="Output in table format",), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), no_pager: bool = typer.Option(False, "--no-pager", help="Disable Paged Output"), update_cache: bool = typer.Option(False, "-U", hidden=True), # Force Update of cli.cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", callback=cli.default_callback), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback), account: str = typer.Option("central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", callback=cli.account_name_callback), ) -> None: cli.cache(refresh=update_cache) central = cli.central if site: _site = cli.cache.get_site_identifier(site, retry=False) site = _site.name or site params = { "name": name, "group": group, "swarm_id": swarm_id, "label": label, "site": site, "calculate_client_count": do_clients, } if sort_by: typer.secho("sort not implemented yet.", fg="red") tablefmt = cli.get_format(do_json=do_json, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table, default="rich") resp = central.request(central.get_wlans, **params) cli.display_results(resp, tablefmt=tablefmt, pager=not no_pager, outfile=outfile)
def sites( args: List[str] = typer.Argument(None, metavar=iden_meta.site, hidden=False), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", help="Output in table format",), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), sort_by: SortOptions = typer.Option(None, "--sort"), no_pager: bool = typer.Option(False, "--no-pager", help="Disable Paged Output"), update_cache: bool = typer.Option(False, "-U", hidden=True), # Force Update of cli.cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", callback=cli.default_callback), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback), account: str = typer.Option("central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", callback=cli.account_name_callback), ): central = cli.central cli.cache(refresh=update_cache) site = None if args: args = tuple([i for i in args if i != "all"]) if args: site = cli.cache.get_site_identifier(args, multi_ok=True) if not site: if central.get_all_sites not in cli.cache.updated: asyncio.run(cli.cache.update_site_db()) resp = Response(output=cli.cache.sites) else: resp = central.request(central.get_site_details, site.id) tablefmt = cli.get_format(do_json=do_json, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table) cli.display_results( resp, tablefmt=tablefmt, title="Sites" if not args else f"{site.name} site details", pager=not no_pager, outfile=outfile )
def certs( name: str = typer.Argument(None, metavar='[certificate name|certificate hash]', hidden=False), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", help="Output in table format",), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), sort_by: SortOptions = typer.Option(None, "--sort"), no_pager: bool = typer.Option(False, "--no-pager", help="Disable Paged Output"), default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", callback=cli.default_callback), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback), account: str = typer.Option("central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", callback=cli.account_name_callback) ) -> None: resp = cli.central.request(cli.central.get_certificates, name, callback=cleaner.get_certificates) tablefmt = cli.get_format(do_json=do_json, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table, default="rich") cli.display_results(resp, tablefmt=tablefmt, pager=not no_pager, outfile=outfile)
def lldp( device: List[str] = typer.Argument(..., metavar=iden_meta.dev, hidden=False), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", help="Output in table format",), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), sort_by: SortOptions = typer.Option(None, "--sort"), no_pager: bool = typer.Option(False, "--no-pager", help="Disable Paged Output"), update_cache: bool = typer.Option(False, "-U", hidden=True), # Force Update of cli.cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", callback=cli.default_callback), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback), account: str = typer.Option("central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", callback=cli.account_name_callback) ) -> None: central = cli.central cli.cache(refresh=update_cache) # We take last arg [-1] from list so they can type "neighbor" if they want. dev = cli.cache.get_dev_identifier(device[-1], dev_type="ap") if dev.type == "ap": resp = central.request(central.get_ap_lldp_neighbor, dev.serial) tablefmt = cli.get_format(do_json=do_json, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table, default="rich") cli.display_results( resp, tablefmt=tablefmt, title="AP lldp neighbor", pager=not no_pager, outfile=outfile, cleaner=cleaner.get_lldp_neighbor, ) else: typer.secho(f"This command is currently only valid for APs. {dev.name} is type: {dev.type}", fg="red") raise typer.Exit(1)
def _cache( args: List[CacheArgs] = typer.Argument(None, hidden=False), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", help="Output in table format",), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), no_pager: bool = typer.Option(False, "--no-pager", help="Disable Paged Output"), update_cache: bool = typer.Option(False, "-U", hidden=True), # Force Update of cli.cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", callback=cli.default_callback), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback), account: str = typer.Option("central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", callback=cli.account_name_callback), ): cli.cache(refresh=update_cache) args = ('all',) if not args else args for arg in args: cache_out = getattr(cli.cache, arg) tablefmt = cli.get_format(do_json=None, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table, default="json") cli.display_results(data=cache_out, tablefmt=tablefmt, tile=f"Cache {args[-1]}", pager=not no_pager, outfile=outfile)
def variables( args: List[str] = typer.Argument(None, metavar=iden_meta.dev, hidden=False), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", help="Output in table format",), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), sort_by: SortOptions = typer.Option(None, "--sort"), no_pager: bool = typer.Option(False, "--no-pager", help="Disable Paged Output"), update_cache: bool = typer.Option(False, "-U", hidden=True), # Force Update of cli.cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", callback=cli.default_callback), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback), account: str = typer.Option("central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", callback=cli.account_name_callback) ): central = cli.central cli.cache(refresh=update_cache) if args and args != "all": args = cli.cache.get_dev_identifier(args) resp = central.request(central.get_variables, () if not args else args.serial) tablefmt = cli.get_format(do_json=do_json, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table, default="json") cli.display_results( resp, tablefmt=tablefmt, title="Variables" if not args else f"{args.name} Variables", pager=not no_pager, outfile=outfile, sort_by=sort_by )
def method_test( method: str = typer.Argument(...), kwargs: List[str] = typer.Argument(None), do_json: bool = typer.Option(True, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", is_flag=True, help="Output in Table"), outfile: Path = typer.Option(None, help="Output to file (and terminal)", writable=True), no_pager: bool = typer.Option(True, "--pager", help="Enable Paged Output"), update_cache: bool = typer.Option( False, "-U", hidden=True), # Force Update of cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", callback=cli.default_callback), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback), account: str = typer.Option( "central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", callback=cli.account_name_callback), ) -> None: """dev testing commands to run CentralApi methods from command line Args: method (str, optional): CentralAPI method to test. kwargs (List[str], optional): list of args kwargs to pass to function. format: arg1 arg2 keyword=value keyword2=value or arg1, arg2, keyword = value, keyword2=value Displays all attributes of Response object """ cli.cache(refresh=update_cache) central = CentralApi(account) if not hasattr(central, method): typer.secho(f"{method} does not exist", fg="red") raise typer.Exit(1) args = [k for k in kwargs if "=" not in k] kwargs = [ k.replace(" =", "=").replace("= ", "=").replace(",", " ").replace(" ", " ") for k in kwargs ] kwargs = [k.split("=") for k in kwargs if "=" in k] kwargs = {k[0]: k[1] for k in kwargs} typer.secho( f"session.{method}({', '.join(a for a in args)}, " f"{', '.join([f'{k}={kwargs[k]}' for k in kwargs]) if kwargs else ''})", fg="cyan") resp = central.request(getattr(central, method), *args, **kwargs) for k, v in resp.__dict__.items(): if k != "output": if debug or not k.startswith("_"): typer.echo(f" {typer.style(k, fg='cyan')}: {v}") tablefmt = cli.get_format(do_json, do_yaml, do_csv, do_table) typer.echo(f"\n{typer.style('CentralCLI Response Output', fg='cyan')}:") cli.display_results(resp, tablefmt=tablefmt, pager=not no_pager, outfile=outfile) typer.echo(f"\n{typer.style('Raw Response Output', fg='cyan')}:") cli.display_results(data=resp.raw, tablefmt=tablefmt, pager=not no_pager, outfile=outfile)
def logs( args: List[str] = typer.Argument(None, metavar='[LOG_ID]', help="Show details for a specific log_id"), user: str = typer.Option(None, help="Filter logs by user"), start: str = typer.Option(None, help="Start time of range to collect logs, provide value in epoch", hidden=True,), end: str = typer.Option(None, help="End time of range to collect logs, provide value in epoch", hidden=True,), device: str = typer.Option(None, metavar=iden_meta.dev, help="Collect logs for a specific device",), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", help="Output in table format"), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), update_cache: bool = typer.Option(False, "-U", hidden=True), # Force Update of cli.cache for testing sort_by: SortOptions = typer.Option(None, "--sort", hidden=True,), # TODO Unhide after implemented reverse: SortOptions = typer.Option(None, "-r", hidden=True,), # TODO Unhide after implemented verbose: bool = typer.Option(False, "-v", hidden=True,), # TODO Unhide after implemented no_pager: bool = typer.Option(False, "--no-pager", help="Disable Paged Output"), default: bool = typer.Option( False, "-d", is_flag=True, help="Use default central account", callback=cli.default_callback, ), debug: bool = typer.Option( False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback, ), account: str = typer.Option( "central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", callback=cli.account_name_callback, ), ) -> None: cli.cache(refresh=update_cache) if device: device = cli.cache.get_dev_identifier(device) kwargs = { "log_id": None if not args else args[-1], "username": user, "start_time": start or int(time.time() - 172800), "end_time": end, # "description": description, "target": None if not device else device.serial, # "classification": classification, # TODO add support for filters # "customer_name": customer_name, # "ip_address": ip_address, # "app_id": app_id, # "offset": offset, # "limit": limit, } # TODO start_time typer.Option pendumlum.... 3H 5h 20m etc. add other filter options central = cli.central resp = central.request(central.get_audit_logs, **kwargs) # TODO add -v flag or something to trigger auto index of log_ids and provide a menu where they can select the log # they want to see details on. if kwargs.get("log_id"): typer.secho(str(resp), fg="green" if resp else "red") else: tablefmt = cli.get_format(do_json=do_json, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table) cli.display_results( resp, tablefmt=tablefmt, pager=not no_pager, outfile=outfile, # sort_by=sort_by, # reverse=reverse, cleaner=cleaner.get_audit_logs, )
def health( site: str = typer.Argument(None, metavar=iden_meta.site, autocompletion=cli.cache.site_completion), wan_down: bool = typer.Option( False, "--wan-down", help="Show branches with wan uplinks or tunnels Down."), down: bool = typer.Option(None, "--down", help="Show branches with down devices."), sort_by: str = typer.Option( None, "--sort", ), # Uses post formatting field headers reverse: bool = typer.Option(True, "-r", help="Reverse Output order.", show_default=False), verbose: bool = typer.Option( False, "-v", help="Show raw unformatted response (vertically)"), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option( False, "--table", help="Output in table format", ), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), pager: bool = typer.Option(False, "--pager", help="Enable Paged Output"), update_cache: bool = typer.Option( False, "-U", hidden=True), # Force Update of cli.cache for testing default: bool = typer.Option( False, "-d", is_flag=True, help="Use default central account", show_default=False, ), debug: bool = typer.Option( False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", ), account: str = typer.Option( "central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", ), ): central = cli.central cli.cache(refresh=update_cache) resp = central.request(central.get_brach_health, name=site) tablefmt = cli.get_format(do_json, do_yaml, do_csv, do_table, default="rich" if not verbose else "yaml") cf = "[italic dark_olive_green2]" caption = f"[reset]{cf}Branch Count: [reset][cyan italic]{len(resp)}[/]" title = "Branch Health" if down: data = [d for d in resp.output if d["device_down"] > 0] caption = f"{caption}{cf} Showing [/][cyan]{len(data)}[/]{cf} branches that have [/][bright_red]down[/] {cf}devices." title = f"{title} - Branches with [bright_red]down[/] devices" resp.output = data elif wan_down: data = [ d for d in resp.output if d["wan_tunnels_down"] > 0 or d["wan_uplinks_down"] > 0 ] caption = f"{caption}{cf} Showing [/][cyan]{len(data)}[/]{cf} branches that have tunnels or uplinks [/][bright_red]down[/]." title = f"{title} - Branches with [bright_red]down[/] WAN links" resp.output = data cli.display_results( resp, tablefmt=tablefmt, title=title, pager=pager, outfile=outfile, sort_by=sort_by, reverse=reverse, cleaner=cleaner.get_branch_health if not verbose else None, # wan_down=wan_down, # down=down, caption=f"{caption}\n")
def templates( # args: List[str] = typer.Argument(None, metavar=iden_meta.dev, hidden=False), name: str = typer.Argument(None, hidden=False, help=f"Template: [name] or Device: {iden_meta.dev}"), group: List[str] = typer.Argument(None, help="Get Templates for Group"), _group: str = typer.Option(None, "--group", help="Get Templates for Group"), # _name: str = typer.Option(None, "--template", help="Get details for template by name"), device_type: str = typer.Option(None, "--dev-type", metavar="[IAP|ArubaSwitch|MobilityController|CX]>", help="[Templates] Filter by Device Type"), version: str = typer.Option(None, metavar="<version>", help="[Templates] Filter by dev version Template is assigned to"), model: str = typer.Option(None, metavar="<model>", help="[Templates] Filter by model"), # variablised: str = typer.Option(False, "--with-vars", # help="[Templates] Show Template with variable place-holders and vars."), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", help="Output in table format",), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), # sort_by: SortOptions = typer.Option(None, "--sort"),show no_pager: bool = typer.Option(False, "--no-pager", help="Disable Paged Output"), update_cache: bool = typer.Option(False, "-U", hidden=True), # Force Update of cli.cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", callback=cli.default_callback), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback), account: str = typer.Option("central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", callback=cli.account_name_callback), ) -> None: if _group: group = _group elif group: group = group[-1] if group: group = cli.cache.get_group_identifier(group) group = group.name central = cli.central cli.cache(refresh=update_cache) params = { # "name": name, "device_type": device_type, # valid = IAP, ArubaSwitch, MobilityController, CX "version": version, "model": model } params = {k: v for k, v in params.items() if v is not None} # TODO simplify if name: log_name = name name = cli.cache.get_identifier(name, ("dev", "template"), device_type=device_type, group=group) if not name: typer.secho(f"Unabled to find a match for {log_name}. Listing all templates.", fg="red") if not name: if not group: if not params: # show templates - Just update and show data from cache if central.get_all_templates not in cli.cache.updated: asyncio.run(cli.cache.update_template_db()) resp = Response(output=cli.cache.templates) else: # Can't use cache due to filtering options resp = central.request(central.get_all_templates, **params) else: # show templates --group <group name> resp = central.request(central.get_all_templates_in_group, group, **params) elif group: # show template <name> --group <group_name> or show template <name> <group name> if name.is_template: resp = central.request(central.get_template, group, name.name) elif name.is_dev: # They provided a dev identifier resp = central.request(central.get_variablised_template, name.serial) else: typer.secho(f"Something went wrong {name}", fg="red") else: # provided args but no group get group from device iden if name.is_dev: resp = central.request(central.get_variablised_template, name.serial) elif name.is_template: resp = central.request(central.get_template, name.group, name.name) tablefmt = cli.get_format(do_json=do_json, do_yaml=do_yaml, do_csv=do_csv, do_table=do_table) cli.display_results(resp, tablefmt=tablefmt, pager=not no_pager, outfile=outfile)
def rogues( start: str = typer.Option(None, help="Start time of range to collect logs, format: yyyy-mm-ddThh:mm (24 hour notation)",), end: str = typer.Option(None, help="End time of range to collect logs, formnat: yyyy-mm-ddThh:mm (24 hour notation)",), past: str = typer.Option(None, help="Collect Logs for last <past>, d=days, h=hours, m=mins i.e.: 3h"), group: str = typer.Argument(None, metavar="[GROUP-NAME]", autocompletion=cli.cache.group_completion), label: str = typer.Argument(None, metavar="[LABEL]",), # autocompletion=cli.cache.group_completion), # TODO cache labels site: str = typer.Argument(None, metavar="[SITE-NAME]", autocompletion=cli.cache.site_completion), # swarm: str = typer.Argument(None, metavar="[SWARM NAME or ID]", autocompletion=cli.cache.swarm_completion), # TODO sort_by: str = typer.Option(None, "--sort",), # Uses post formatting field headers reverse: bool = typer.Option( True, "-r", help="Reverse Output order.", show_default=False ), verbose: bool = typer.Option(False, "-v", help="Show raw unformatted response (vertically)"), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON"), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML"), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV"), do_table: bool = typer.Option(False, "--table", help="Output in table format",), outfile: Path = typer.Option(None, "--out", help="Output to file (and terminal)", writable=True), pager: bool = typer.Option(False, "--pager", help="Enable Paged Output"), update_cache: bool = typer.Option(False, "-U", hidden=True), # Force Update of cli.cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", show_default=False,), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging",), account: str = typer.Option("central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)",), ): central = cli.central cli.cache(refresh=update_cache) if group: group = cli.cache.get_group_identifier(group).name if start: try: dt = pendulum.from_format(start, 'YYYY-MM-DDTHH:mm') start = (dt.int_timestamp) except Exception: typer.secho(f"start appears to be invalid {start}", fg="red") raise typer.Exit(1) if end: try: dt = pendulum.from_format(end, 'YYYY-MM-DDTHH:mm') end = (dt.int_timestamp) except Exception: typer.secho(f"end appears to be invalid {start}", fg="red") raise typer.Exit(1) if past: now = int(time.time()) past = past.lower().replace(" ", "") if past.endswith("d"): start = now - (int(past.rstrip("d")) * 86400) if past.endswith("h"): start = now - (int(past.rstrip("h")) * 3600) if past.endswith("m"): start = now - (int(past.rstrip("m")) * 60) kwargs = { "from_timestamp": start, "to_timestamp": end, "group": group, "label": label, "site": site, # "swarm_id": swarm, TODO } resp = central.request(central.wids_get_rogue_aps, **kwargs) tablefmt = cli.get_format(do_json, do_yaml, do_csv, do_table, default="rich" if not verbose else "yaml") cli.display_results( resp, tablefmt=tablefmt, title="Rogues", pager=pager, outfile=outfile, sort_by=sort_by if not sort_by else sort_by.replace("_", " "), reverse=reverse, # cleaner=cleaner.get_audit_logs if not verbose else None, # cache_update_func=cli.cache.update_log_db if not verbose else None, # caption=f"Use {_cmd_txt} to see details for a log. Logs lacking an id don\'t have details.", )
def method( method: str = typer.Argument(..., autocompletion=cli.cache.method_test_completion), kwargs: List[str] = typer.Argument(None), _help: bool = typer.Option(False, "--doc", help="Get details on required args/keyword args for provided method."), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON", show_default=False), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML", show_default=False), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV", show_default=False), do_table: bool = typer.Option(False, "--table", is_flag=True, help="Output in Table", show_default=False), outfile: Path = typer.Option(None, help="Output to file (and terminal)", writable=True), pager: bool = typer.Option(False, help="Enable Paged Output"), update_cache: bool = typer.Option(False, "-U", hidden=True), # Force Update of cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", show_default=False, callback=cli.default_callback), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Debug Logging", callback=cli.debug_callback), debugv: bool = typer.Option( False, "--debugv", envvar="ARUBACLI_VERBOSE_DEBUG", help="Enable verbose Debug Logging", hidden=True, callback=cli.verbose_debug_callback, ), account: str = typer.Option( "central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", autocompletion=cli.cache.account_completion, ), ) -> None: """Dev testing commands to run CentralApi methods from command line. Refer to central.py and the schema generated code in the boilerplate dir for available calls. Tab completion will also return available methods. Use --doc to get details on arguments for the provided method. Args: method (str, optional): CentralAPI method to test. kwargs (List[str], optional): list of args kwargs to pass to function. format: arg1 arg2 keyword=value keyword2=value or arg1, arg2, keyword = value, keyword2=value Examples: cencli test method platform_get_devices all_ap Use --doc flag to see documentation for usage of a method. cencli test method platform_get_devices --doc Displays all attributes of Response object """ # FIXME account only works if method is in central.py central = CentralApi(account) cli.cache(refresh=update_cache) if not hasattr(central, method): if account != "central_info": print("Testing methods only supports the --account option for methods in central.py") raise typer.Exit(1) bpdir = Path(__file__).parent / "boilerplate" all_calls = [ importlib.import_module(f"centralcli.{bpdir.name}.{f.stem}") for f in bpdir.iterdir() if not f.name.startswith("_") and f.suffix == ".py" ] for m in all_calls: log.debug(f"Looking for {method} in {m.__file__.split('/')[-1]}") if hasattr(m.AllCalls(), method): central = m.AllCalls() break if not hasattr(central, method): typer.secho(f"{method} does not exist", fg="red") raise typer.Exit(1) if _help: old_ret = "Response: CentralAPI Response object" new_ret = "Response from Aruba Central API gateway." print(getattr(central, method).__doc__.replace(old_ret, new_ret)) raise typer.Exit(0) kwargs = ( "~".join(kwargs).replace("'", "").replace('"', '').replace("~=", "=").replace("=~", "=").replace(",~", "~").split("~") ) args = [k if not k.isdigit() else int(k) for k in kwargs if k and "=" not in k] kwargs = [k.split("=") for k in kwargs if "=" in k] kwargs = {k[0]: k[1] if not k[1].isdigit() else int(k[1]) for k in kwargs} for arg in args: if isinstance(arg, str): if arg.startswith("[") and arg.endswith("]"): args[args.index(arg)] = [a if not a.isdigit() else int(a) for a in arg.strip("[]").split(",")] for k, v in kwargs.items(): if isinstance(v, str): if v.startswith("[") and v.endswith("]"): kwargs[k] = [vv if not vv.isdigit() else int(vv) for vv in v.strip("[]").split(",")] if v.lower() in ["true", "false"]: kwargs[k] = True if v.lower() == "true" else False from rich.console import Console c = Console(file=outfile) req = ( f"central.{method}({', '.join(str(a) for a in args)}{', ' if args else ''}" f"{', '.join([f'{k}={kwargs[k]}' for k in kwargs]) if kwargs else ''})" ) resp = central.request(getattr(central, method), *args, **kwargs) if "should be str" in resp.output and "bool" in resp.output: c.log(f"{resp.output}. LAME! Converting to str!") args = tuple([str(a).lower() if isinstance(a, bool) else a for a in args]) kwargs = {k: str(v).lower() if isinstance(v, bool) else v for k, v in kwargs.items()} resp = central.request(getattr(central, method), *args, **kwargs) attrs = { k: v for k, v in resp.__dict__.items() if k not in ["output", "raw"] and (log.DEBUG or not k.startswith("_")) } c.print(req) c.print("\n".join([f" {k}: {v}" for k, v in attrs.items()])) tablefmt = cli.get_format( do_json, do_yaml, do_csv, do_table, default="yaml" ) if resp.raw and resp.output != resp.raw: typer.echo(f"\n{typer.style('CentralCLI Response Output', fg='bright_green')}:") cli.display_results(data=resp.output, tablefmt=tablefmt, pager=pager, outfile=outfile) if resp.raw: typer.echo(f"\n{typer.style('Raw Response Output', fg='bright_green')}:") cli.display_results(data=resp.raw, tablefmt="json", pager=pager, outfile=outfile)
def method_test( method: str = typer.Argument(...), kwargs: List[str] = typer.Argument(None), do_json: bool = typer.Option(False, "--json", is_flag=True, help="Output in JSON", show_default=False), do_yaml: bool = typer.Option(False, "--yaml", is_flag=True, help="Output in YAML", show_default=False), do_csv: bool = typer.Option(False, "--csv", is_flag=True, help="Output in CSV", show_default=False), do_table: bool = typer.Option(False, "--table", is_flag=True, help="Output in Table", show_default=False), outfile: Path = typer.Option(None, help="Output to file (and terminal)", writable=True), no_pager: bool = typer.Option(True, "--pager", help="Enable Paged Output"), update_cache: bool = typer.Option( False, "-U", hidden=True), # Force Update of cache for testing default: bool = typer.Option(False, "-d", is_flag=True, help="Use default central account", show_default=False, callback=cli.default_callback), debug: bool = typer.Option(False, "--debug", envvar="ARUBACLI_DEBUG", help="Enable Additional Debug Logging", callback=cli.debug_callback), account: str = typer.Option( "central_info", envvar="ARUBACLI_ACCOUNT", help="The Aruba Central Account to use (must be defined in the config)", autocompletion=cli.cache.account_completion, ), ) -> None: """dev testing commands to run CentralApi methods from command line Args: method (str, optional): CentralAPI method to test. kwargs (List[str], optional): list of args kwargs to pass to function. format: arg1 arg2 keyword=value keyword2=value or arg1, arg2, keyword = value, keyword2=value Displays all attributes of Response object """ cli.cache(refresh=update_cache) central = CentralApi(account) if not hasattr(central, method): bpdir = Path(__file__).parent / "boilerplate" all_calls = [ importlib.import_module(f"centralcli.{bpdir.name}.{f.stem}") for f in bpdir.iterdir() if not f.name.startswith("_") and f.suffix == ".py" ] for m in all_calls: if hasattr(m.AllCalls(), method): central = m.AllCalls() break if not hasattr(central, method): typer.secho(f"{method} does not exist", fg="red") raise typer.Exit(1) kwargs = ("~".join(kwargs).replace("'", "").replace('"', '').replace( "~=", "=").replace("=~", "=").replace(",~", ",").split("~")) args = [k if not k.isdigit() else int(k) for k in kwargs if "=" not in k] kwargs = [k.split("=") for k in kwargs if "=" in k] kwargs = {k[0]: k[1] if not k[1].isdigit() else int(k[1]) for k in kwargs} for k, v in kwargs.items(): if v.startswith("[") and v.endswith("]"): kwargs[k] = [ vv if not vv.isdigit() else int(vv) for vv in v.strip("[]").split(",") ] if v.lower() in ["true", "false"]: kwargs[k] = True if v.lower() == "true" else False from rich.console import Console c = Console(file=outfile) req = ( f"central.{method}({', '.join(str(a) for a in args)}, " f"{', '.join([f'{k}={kwargs[k]}' for k in kwargs]) if kwargs else ''})" ) resp = central.request(getattr(central, method), *args, **kwargs) if "should be str" in resp.output and "bool" in resp.output: c.log(f"{resp.output}. LAME! Converting to str!") args = tuple( [str(a).lower() if isinstance(a, bool) else a for a in args]) kwargs = { k: str(v).lower() if isinstance(v, bool) else v for k, v in kwargs.items() } resp = central.request(getattr(central, method), *args, **kwargs) attrs = { k: v for k, v in resp.__dict__.items() if k not in ["output", "raw"] and (log.DEBUG or not k.startswith("_")) } c.print(req) c.print("\n".join([f" {k}: {v}" for k, v in attrs.items()])) tablefmt = cli.get_format(do_json, do_yaml, do_csv, do_table, default="yaml") typer.echo( f"\n{typer.style('CentralCLI Response Output', fg='bright_green')}:") cli.display_results(data=resp.output, tablefmt=tablefmt, pager=not no_pager, outfile=outfile) if resp.raw: typer.echo( f"\n{typer.style('Raw Response Output', fg='bright_green')}:") cli.display_results(data=resp.raw, tablefmt="json", pager=not no_pager, outfile=outfile)