|
20 | 20 | from re import sub
|
21 | 21 | from subprocess import CalledProcessError
|
22 | 22 | from sys import exit as sysexit
|
23 |
| -from sys import stdin, stdout, stderr |
| 23 | +from sys import stderr, stdin, stdout |
24 | 24 | from xml.sax.xmlreader import InputSource
|
25 | 25 |
|
26 | 26 | from jwt.exceptions import PyJWTError
|
| 27 | +from milc import set_metadata # this function needed to set metadata immediately below |
27 | 28 | from pygments import highlight
|
28 | 29 | from pygments.formatters import Terminal256Formatter
|
29 | 30 | from pygments.lexers import get_lexer_by_name, load_lexer_from_file
|
|
35 | 36 | from netfoundry import __version__ as netfoundry_version
|
36 | 37 |
|
37 | 38 | from .exceptions import NeedUserInput, NFAPINoCredentials
|
38 |
| -from .network import Networks, Network |
| 39 | +from .network import Network, Networks |
39 | 40 | from .network_group import NetworkGroup
|
40 | 41 | from .organization import Organization
|
41 |
| -from .utility import DC_PROVIDERS, MUTABLE_NET_RESOURCES, MUTABLE_RESOURCE_ABBREV, RESOURCE_ABBREV, RESOURCES, is_jwt, normalize_caseless, plural, singular |
| 42 | +from .utility import DC_PROVIDERS, EMBED_NET_RESOURCES, MUTABLE_NET_RESOURCES, MUTABLE_RESOURCE_ABBREV, RESOURCE_ABBREV, RESOURCES, is_jwt, normalize_caseless, plural, singular |
42 | 43 |
|
43 |
| -from milc import set_metadata # this function needed to set metadata immediately below |
44 | 44 | set_metadata(version=f"v{netfoundry_version}", author="NetFoundry", name="nfctl") # must precend import milc.cli
|
45 | 45 | from milc import cli, questions # this uses metadata set above
|
46 | 46 | from milc.subcommand import config # this creates the config subcommand
|
@@ -373,21 +373,21 @@ def edit(cli):
|
373 | 373 | @cli.argument('query', arg_only=True, action=StoreDictKeyPair, nargs='?', help="id=UUIDv4 or query params as k=v,k=v comma-separated pairs")
|
374 | 374 | @cli.argument('-k', '--keys', arg_only=True, action=StoreListKeys, help="list of keys as a,b,c to print only selected keys (columns)")
|
375 | 375 | @cli.argument('-a', '--as', dest='accept', arg_only=True, choices=['create'], help="request the as=create alternative form of the resource")
|
| 376 | +@cli.argument('-e', '--embed', arg_only=True, action=StoreListKeys, default=None, help="applies to 'get network': optionally embed comma-sep list of resource types or 'all' of a network's resource collections", choices=[plural(type) for type in EMBED_NET_RESOURCES.keys()]) |
376 | 377 | @cli.argument('resource_type', arg_only=True, help='type of resource', metavar="RESOURCE_TYPE", choices=[choice for group in [[singular(type), RESOURCES[type].abbreviation] for type in RESOURCES.keys()] for choice in group])
|
377 | 378 | @cli.subcommand('get a single resource by type and query')
|
378 |
| -def get(cli, echo: bool = True, embed='all', spinner: object = None): |
| 379 | +def get(cli, echo: bool = True, spinner: object = None): |
379 | 380 | """
|
380 | 381 | Get a single resource as YAML or JSON.
|
381 | 382 |
|
382 |
| - :param echo: False allows capture instead of print the match |
383 |
| - :param embed: False avoids expensive operations when we just need a shallow view |
| 383 | + :param echo: False allows the caller to capture the return instead of printing the match |
384 | 384 | """
|
385 | 385 | if RESOURCE_ABBREV.get(cli.args.resource_type):
|
386 | 386 | cli.args.resource_type = singular(RESOURCE_ABBREV[cli.args.resource_type].name)
|
387 | 387 | if not cli.config.general.verbose and cli.args.output in ["yaml", "json"]: # don't change level if output=text
|
388 | 388 | cli.log.setLevel(logging.WARN) # don't emit INFO messages to stdout because they will break deserialization
|
389 | 389 | if cli.args.accept and not MUTABLE_NET_RESOURCES.get(plural(cli.args.resource_type)):
|
390 |
| - logging.warning("ignoring --as=create becuase it is applicable only to mutable resources in the network domain") |
| 390 | + logging.warning("ignoring --as=create because it is applicable only to mutable resources in the network domain") |
391 | 391 | cli.args['accept'] = None
|
392 | 392 | match = {}
|
393 | 393 | matches = []
|
@@ -458,39 +458,35 @@ def get(cli, echo: bool = True, embed='all', spinner: object = None):
|
458 | 458 | if len(query_keys) > 1:
|
459 | 459 | query_keys.remove('id')
|
460 | 460 | cli.log.warn(f"using 'id' only, ignoring params: '{', '.join(query_keys)}'")
|
461 |
| - match = organization.get_network(network_id=cli.args.query['id'], embed=embed, accept=cli.args.accept) |
| 461 | + match = organization.get_network(network_id=cli.args.query['id'], embed=cli.args.embed, accept=cli.args.accept) |
462 | 462 | else:
|
463 | 463 | if cli.config.general.network_group and not cli.config.general.network:
|
464 | 464 | network_group = use_network_group(
|
465 | 465 | cli,
|
466 | 466 | organization,
|
467 |
| - group=cli.config.general.network_group, |
468 |
| - ) |
| 467 | + group=cli.config.general.network_group) |
469 | 468 | matches = organization.find_networks_by_group(network_group.id, **cli.args.query)
|
470 | 469 | elif cli.config.general.network:
|
471 | 470 | network, network_group = use_network(
|
472 | 471 | cli,
|
473 | 472 | organization=organization,
|
474 |
| - network_name=cli.config.general.network, |
475 |
| - ) |
476 |
| - match = organization.get_network(network_id=network.id, embed=embed, accept=cli.args.accept) |
| 473 | + network_name=cli.config.general.network) |
| 474 | + match = organization.get_network(network_id=network.id, embed=cli.args.embed, accept=cli.args.accept) |
477 | 475 | else:
|
478 | 476 | matches = organization.find_networks_by_organization(**cli.args.query)
|
479 | 477 | if len(matches) == 1:
|
480 | 478 | network, network_group = use_network(
|
481 | 479 | cli,
|
482 | 480 | organization=organization,
|
483 |
| - network_name=matches[0]['name'], |
484 |
| - ) |
485 |
| - match = organization.get_network(network_id=network.id, embed=embed, accept=cli.args.accept) |
| 481 | + network_name=matches[0]['name']) |
| 482 | + match = organization.get_network(network_id=network.id, embed=cli.args.embed, accept=cli.args.accept) |
486 | 483 | else: # is a resource in the network domain
|
487 | 484 | if cli.config.general.network:
|
488 | 485 | network, network_group = use_network(
|
489 | 486 | cli,
|
490 | 487 | organization=organization,
|
491 | 488 | group=cli.config.general.network_group, # None unless configured
|
492 |
| - network_name=cli.config.general.network, |
493 |
| - ) |
| 489 | + network_name=cli.config.general.network) |
494 | 490 | else:
|
495 | 491 | cli.log.error("need --network=ACMENet")
|
496 | 492 | sysexit(1)
|
@@ -707,7 +703,7 @@ def delete(cli):
|
707 | 703 | cli.config.general['wait'] = 0
|
708 | 704 | spinner.text = f"Finding {cli.args.resource_type} {'by' if query_keys else '...'} {', '.join(query_keys)}"
|
709 | 705 | with spinner:
|
710 |
| - match, network, network_group, organization = get(cli, echo=False, embed=None, spinner=spinner) |
| 706 | + match, network, network_group, organization = get(cli, echo=False, spinner=spinner) |
711 | 707 | if cli.args.resource_type == 'network':
|
712 | 708 | try:
|
713 | 709 | delete_confirmed = False
|
|
0 commit comments