centralcli 7.2.0__tar.gz → 7.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. {centralcli-7.2.0 → centralcli-7.2.3}/PKG-INFO +1 -1
  2. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/__init__.py +10 -9
  3. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/cache.py +21 -12
  4. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/cliupdate.py +19 -19
  5. {centralcli-7.2.0 → centralcli-7.2.3}/pyproject.toml +1 -1
  6. {centralcli-7.2.0 → centralcli-7.2.3}/LICENSE +0 -0
  7. {centralcli-7.2.0 → centralcli-7.2.3}/README.md +0 -0
  8. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/boilerplate/README.md +0 -0
  9. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/boilerplate/_cnx_allcalls.py +0 -0
  10. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/boilerplate/allcalls.py +0 -0
  11. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/caas.py +0 -0
  12. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/central.py +0 -0
  13. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/cleaner.py +0 -0
  14. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/cli.py +0 -0
  15. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/cliadd.py +0 -0
  16. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/cliassign.py +0 -0
  17. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clibatch.py +0 -0
  18. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clicaas.py +0 -0
  19. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clicheck.py +0 -0
  20. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/cliclone.py +0 -0
  21. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clicommon.py +0 -0
  22. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clidel.py +0 -0
  23. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clidelfirmware.py +0 -0
  24. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/cliexport.py +0 -0
  25. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clikick.py +0 -0
  26. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clioptions.py +0 -0
  27. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clirefresh.py +0 -0
  28. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clirename.py +0 -0
  29. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/cliset.py +0 -0
  30. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clisetfirmware.py +0 -0
  31. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clishow.py +0 -0
  32. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clishowaudit.py +0 -0
  33. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clishowbandwidth.py +0 -0
  34. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clishowbranch.py +0 -0
  35. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clishowcloudauth.py +0 -0
  36. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clishowfirmware.py +0 -0
  37. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clishowmpsk.py +0 -0
  38. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clishowospf.py +0 -0
  39. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clishowoverlay.py +0 -0
  40. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clishowtshoot.py +0 -0
  41. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clishowwids.py +0 -0
  42. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clitest.py +0 -0
  43. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/clitshoot.py +0 -0
  44. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/cliunassign.py +0 -0
  45. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/cliupgrade.py +0 -0
  46. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/config.py +0 -0
  47. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/constants.py +0 -0
  48. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/exceptions.py +0 -0
  49. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/logger.py +0 -0
  50. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/models.py +0 -0
  51. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/objects.py +0 -0
  52. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/render.py +0 -0
  53. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/response.py +0 -0
  54. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/setup.py +0 -0
  55. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/static/favicon.ico +0 -0
  56. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/strings.py +0 -0
  57. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/typedefs.py +0 -0
  58. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/utils.py +0 -0
  59. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/vendored/csvlexer/__init__.py +0 -0
  60. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/vendored/csvlexer/csv.py +0 -0
  61. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/vscodeargs.py +0 -0
  62. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/wh2snow.py +0 -0
  63. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/wh_proxy.py +0 -0
  64. {centralcli-7.2.0 → centralcli-7.2.3}/centralcli/wh_proxy_service.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: centralcli
3
- Version: 7.2.0
3
+ Version: 7.2.3
4
4
  Summary: A CLI for interacting with Aruba Central (Cloud Management Platform). Facilitates bulk imports, exports, reporting. A handy tool if you have devices managed by Aruba Central.
5
5
  Home-page: https://github.com/Pack3tL0ss/central-api-cli
6
6
  License: MIT
@@ -194,15 +194,16 @@ if "--capture-raw" in sys.argv: # captures raw responses into a flat file for l
194
194
  central = CentralApi(config.account)
195
195
  Cache.set_config(config)
196
196
  cache = Cache(central)
197
- CacheDevice.set_db(cache.DevDB)
198
- CacheInvDevice.set_db(cache.InvDB)
199
- CacheGroup.set_db(cache.GroupDB)
200
- CacheSite.set_db(cache.SiteDB)
201
- CacheClient.set_db(cache.ClientDB, cache=cache)
202
- CacheLabel.set_db(cache.LabelDB)
203
- CachePortal.set_db(cache.PortalDB)
204
- CacheTemplate.set_db(cache.TemplateDB)
205
- CacheMpskNetwork.set_db(cache.MpskDB)
197
+ if config.valid:
198
+ CacheDevice.set_db(cache.DevDB)
199
+ CacheInvDevice.set_db(cache.InvDB)
200
+ CacheGroup.set_db(cache.GroupDB)
201
+ CacheSite.set_db(cache.SiteDB)
202
+ CacheClient.set_db(cache.ClientDB, cache=cache)
203
+ CacheLabel.set_db(cache.LabelDB)
204
+ CachePortal.set_db(cache.PortalDB)
205
+ CacheTemplate.set_db(cache.TemplateDB)
206
+ CacheMpskNetwork.set_db(cache.MpskDB)
206
207
  cli = CLICommon(config.account, cache, central, raw_out=raw_out)
207
208
 
208
209
  # allow singular form and common synonyms for the defined show commands
@@ -464,6 +464,10 @@ class CachePortal(CentralObject):
464
464
  def __rich__(self) -> str:
465
465
  return f'[bright_green]Portal Profile[/]:[bright_green]{self.name}[/]|[cyan]{self.id}[/]'
466
466
 
467
+ @property
468
+ def help_text(self):
469
+ return render.rich_capture(self.__rich__())
470
+
467
471
 
468
472
  class CacheTemplate(CentralObject):
469
473
  db: Table | None = None
@@ -560,6 +564,12 @@ class CacheClient(CentralObject):
560
564
  def __rich__(self) -> str:
561
565
  return f'[bright_green]Client[/]:[cyan]{self.name}[/]|({utils.color([self.type, self.ip, self.mac, self.connected_name], "green_yellow", sep="|")}|s[green_yellow]{self.site})[/]'
562
566
 
567
+ @property
568
+ def help_text(self) -> str:
569
+ return render.rich_capture(
570
+ f"[bright_green]{self.name}[/]|[cyan]{self.mac}[/]|[bright_green]{self.ip}[/]|[cyan]{f's:{self.site}' if self.site else f'g:{self.group}'}[/]|[dark_olive_green2]{self.connected_name}[/]"
571
+ )
572
+
563
573
 
564
574
  class CacheMpskNetwork(CentralObject):
565
575
  db: Table | None = None
@@ -1349,9 +1359,9 @@ class Cache:
1349
1359
  match = [m for m in match if m.name not in args]
1350
1360
  for m in sorted(match, key=lambda i: i.name):
1351
1361
  if m.name.startswith(incomplete):
1352
- out += [tuple([m.name, m.id])]
1362
+ out += [tuple([m.name, m.help_text])]
1353
1363
  elif m.id.startswith(incomplete):
1354
- out += [tuple([m.id, m.name])]
1364
+ out += [tuple([m.id, m.help_text])]
1355
1365
  else:
1356
1366
  out += [tuple([m.name, m.help_text])] # failsafe, shouldn't hit
1357
1367
 
@@ -1959,19 +1969,18 @@ class Cache:
1959
1969
  # remove clients that are already on the command line
1960
1970
  match = [m for m in match if m.name not in args]
1961
1971
  for c in sorted(match, key=lambda i: i.name):
1962
- if c.name.startswith(incomplete):
1963
- out += c.help_text
1972
+ if c.name.lower().startswith(incomplete.lower()):
1973
+ out += [(c.name, c.help_text)]
1964
1974
  elif c.mac.strip(":.-").lower().startswith(incomplete.strip(":.-")):
1965
- out += c.help_text
1975
+ out += [(c.mac, c.help_text)]
1966
1976
  elif c.ip.startswith(incomplete):
1967
- out += c.help_text
1977
+ out += [(c.ip, c.help_text)]
1968
1978
  else:
1969
1979
  # failsafe, shouldn't hit
1970
- out += (c.help_text[0], f'{c.help_text[1]} FailSafe Match')
1980
+ out += [(c.name, f'{c.help_text} FailSafe Match')]
1971
1981
 
1972
-
1973
- for c in out: # TODO completion behavior has changed. This works-around issue bash doesn't complete past 00: and zsh treats each octet as a dev name when : is used.
1974
- yield c[0].replace(":", "-"), c[1]
1982
+ for c in out:
1983
+ yield c[0].replace(":", "-"), c[1] # TODO completion behavior has changed. This works-around issue bash doesn't complete past 00: and zsh treats each octet as a dev name when : is used.
1975
1984
 
1976
1985
  def event_log_completion(
1977
1986
  self,
@@ -2324,14 +2333,14 @@ class Cache:
2324
2333
  bool: _description_
2325
2334
  """
2326
2335
  _start_time = time.perf_counter()
2327
- if data:
2336
+ if data is not None:
2328
2337
  with econsole.status(f":arrows_clockwise: Updating [dark_olive_green2]{db.name}[/] Cache: [cyan]{len(data)}[/] records."):
2329
2338
  if truncate:
2330
2339
  db.truncate()
2331
2340
  db_res = db.insert_multiple([dict(d) for d in data]) # Converts any TinyDB.Documents to dict as that has unexpected results.
2332
2341
  return self.verify_db_action(db, expected=len(data), response=db_res, elapsed=round(time.perf_counter() - _start_time, 2))
2333
2342
 
2334
- doc_ids = utils.listify(doc_ids)
2343
+ doc_ids = utils.listify(doc_ids) or []
2335
2344
  with econsole.status(f":wastebasket: [red]Removing[/]] [cyan]{len(doc_ids)}[/] records from [dark_olive_green2]{db.name}[/] cache."):
2336
2345
  db_res = db.remove(doc_ids=doc_ids)
2337
2346
  return self.verify_db_action(db, expected=len(doc_ids), response=db_res, remove=True, elapsed=round(time.perf_counter() - _start_time, 2))
@@ -3,29 +3,34 @@
3
3
 
4
4
  from pathlib import Path
5
5
  import sys
6
- from typing import List, Union
6
+ from typing import TYPE_CHECKING, List, Union
7
7
  # from typing import List
8
8
  import typer
9
9
  from rich import print
10
10
  from rich.console import Console
11
+ from rich.text import Text
11
12
  from jinja2 import FileSystemLoader, Environment
12
13
  import yaml
13
14
 
14
15
  # Detect if called from pypi installed package or via cloned github repo (development)
15
16
  try:
16
- from centralcli import utils, cli, caas, cleaner, BatchRequest, log
17
+ from centralcli import utils, cli, cleaner, BatchRequest, log
17
18
  except (ImportError, ModuleNotFoundError) as e:
18
19
  pkg_dir = Path(__file__).absolute().parent
19
20
  if pkg_dir.name == "centralcli":
20
21
  sys.path.insert(0, str(pkg_dir.parent))
21
- from centralcli import utils, cli, caas, cleaner, BatchRequest, log
22
+ from centralcli import utils, cli, cleaner, BatchRequest, log
22
23
  else:
23
24
  print(pkg_dir.parts)
24
25
  raise e
25
26
 
26
- from centralcli.constants import IdenMetaVars, DevTypes, GatewayRole, state_abbrev_to_pretty
27
- from centralcli import CentralObject
27
+ from .constants import IdenMetaVars, DevTypes, GatewayRole, state_abbrev_to_pretty
28
+ from . import render
28
29
  from .cache import CacheTemplate
30
+ from .caas import CaasAPI
31
+
32
+ if TYPE_CHECKING:
33
+ from .cache import CacheDevice, CacheGroup
29
34
 
30
35
 
31
36
  SPIN_TXT_AUTH = "Establishing Session with Aruba Central API Gateway..."
@@ -277,7 +282,6 @@ def generate_template(template_file: Union[Path, str], var_file: Union[Path, str
277
282
  @app.command("config")
278
283
  def config_(
279
284
  group_dev: str = cli.arguments.group_dev,
280
- # TODO collect multi-line input as option to paste in config
281
285
  cli_file: Path = typer.Argument(..., help="File containing desired config/template in CLI format.", exists=True, autocompletion=lambda incomplete: tuple(), show_default=False,),
282
286
  var_file: Path = typer.Argument(None, help="File containing variables for j2 config template.", exists=True, autocompletion=lambda incomplete: tuple(), show_default=False,),
283
287
  do_gw: bool = typer.Option(None, "--gw", help="Update group level config for gateways."),
@@ -289,18 +293,12 @@ def config_(
289
293
  ) -> None:
290
294
  """Update group or device level config (ap or gw).
291
295
  """
292
- group_dev: CentralObject = cli.cache.get_identifier(group_dev, qry_funcs=["group", "dev"], device_type=["ap", "gw"])
296
+ group_dev: CacheDevice | CacheGroup = cli.cache.get_identifier(group_dev, qry_funcs=["group", "dev"], device_type=["ap", "gw"])
293
297
  config_out = utils.generate_template(cli_file, var_file=var_file)
294
298
  cli_cmds = utils.validate_config(config_out)
295
299
 
296
- # TODO render.py module with helper function to return styled rule/line
297
- console = Console(record=True, emoji=False)
298
- console.begin_capture()
299
- console.rule("Configuration to be sent")
300
- console.print("\n".join([f"[green]{line}[/green]" for line in cli_cmds]))
301
- console.rule()
302
- console.print(f"\nUpdating {'group' if group_dev.is_group else group_dev.generic_type.upper()} [cyan]{group_dev.name}[/]")
303
- _msg = console.end_capture()
300
+ output = render.output(cli_cmds)
301
+ output = Text.from_ansi(output.tty)
304
302
 
305
303
  if group_dev.is_group:
306
304
  device = None
@@ -313,7 +311,7 @@ def config_(
313
311
  if device and device.generic_type != "gw":
314
312
  cli.exit(f"Invalid input: --gw option conflicts with {device.name} which is an {device.generic_type}")
315
313
  use_caas = True
316
- caasapi = caas.CaasAPI(central=cli.central) # XXX Burried import
314
+ caasapi = CaasAPI(central=cli.central)
317
315
  node_iden = group_dev.name if group_dev.is_group else group_dev.mac
318
316
  elif do_ap or (device and device.generic_type == "ap"):
319
317
  if device and device.generic_type != "ap":
@@ -321,7 +319,10 @@ def config_(
321
319
  use_caas = False
322
320
  node_iden = group_dev.name if group_dev.is_group else group_dev.serial
323
321
 
324
- typer.echo(_msg)
322
+ cli.console.rule("Configuration to be sent")
323
+ cli.console.print(output, emoji=False)
324
+ cli.console.rule()
325
+ cli.console.print(f"\nUpdating {'group' if group_dev.is_group else group_dev.generic_type.upper()} [cyan]{group_dev.name}[/]")
325
326
  if cli.confirm(yes):
326
327
  if use_caas:
327
328
  resp = cli.central.request(caasapi.send_commands, node_iden, cli_cmds)
@@ -329,8 +330,7 @@ def config_(
329
330
  else:
330
331
  # FIXME this is OK for group level ap config , for AP this method is not valid
331
332
  if group_dev.is_dev:
332
- print("Not Implemented yet for AP device level updates")
333
- raise typer.Exit(1)
333
+ cli.exit("Not Implemented yet for AP device level updates")
334
334
  resp = cli.central.request(cli.central.replace_ap_config, node_iden, cli_cmds)
335
335
  cli.display_results(resp, tablefmt="action")
336
336
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "centralcli"
3
- version = "7.2.0"
3
+ version = "7.2.3"
4
4
  description = "A CLI for interacting with Aruba Central (Cloud Management Platform). Facilitates bulk imports, exports, reporting. A handy tool if you have devices managed by Aruba Central."
5
5
  license = "MIT"
6
6
  authors = ["Wade Wells (Pack3tL0ss) <wade@consolepi.org>"]
File without changes
File without changes
File without changes