playground-ls-cli 4.14.1.dev8__py3-none-any.whl

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 (112) hide show
  1. localstack_cli/__init__.py +0 -0
  2. localstack_cli/cli/__init__.py +10 -0
  3. localstack_cli/cli/console.py +11 -0
  4. localstack_cli/cli/core_plugin.py +12 -0
  5. localstack_cli/cli/exceptions.py +19 -0
  6. localstack_cli/cli/localstack.py +951 -0
  7. localstack_cli/cli/lpm.py +138 -0
  8. localstack_cli/cli/main.py +22 -0
  9. localstack_cli/cli/plugin.py +39 -0
  10. localstack_cli/cli/plugins.py +134 -0
  11. localstack_cli/cli/profiles.py +65 -0
  12. localstack_cli/config.py +1689 -0
  13. localstack_cli/constants.py +165 -0
  14. localstack_cli/logging/__init__.py +0 -0
  15. localstack_cli/logging/format.py +194 -0
  16. localstack_cli/logging/setup.py +142 -0
  17. localstack_cli/packages/__init__.py +25 -0
  18. localstack_cli/packages/api.py +418 -0
  19. localstack_cli/packages/core.py +416 -0
  20. localstack_cli/pro/__init__.py +0 -0
  21. localstack_cli/pro/core/__init__.py +0 -0
  22. localstack_cli/pro/core/bootstrap/__init__.py +1 -0
  23. localstack_cli/pro/core/bootstrap/auth.py +213 -0
  24. localstack_cli/pro/core/bootstrap/dns_utils.py +55 -0
  25. localstack_cli/pro/core/bootstrap/entitlements.py +117 -0
  26. localstack_cli/pro/core/bootstrap/extensions/__init__.py +3 -0
  27. localstack_cli/pro/core/bootstrap/extensions/__main__.py +106 -0
  28. localstack_cli/pro/core/bootstrap/extensions/autoinstall.py +63 -0
  29. localstack_cli/pro/core/bootstrap/extensions/bootstrap.py +97 -0
  30. localstack_cli/pro/core/bootstrap/extensions/repository.py +374 -0
  31. localstack_cli/pro/core/bootstrap/licensingv2.py +1259 -0
  32. localstack_cli/pro/core/bootstrap/pods/__init__.py +0 -0
  33. localstack_cli/pro/core/bootstrap/pods/api_types.py +17 -0
  34. localstack_cli/pro/core/bootstrap/pods/constants.py +26 -0
  35. localstack_cli/pro/core/bootstrap/pods/remotes/__init__.py +0 -0
  36. localstack_cli/pro/core/bootstrap/pods/remotes/api.py +75 -0
  37. localstack_cli/pro/core/bootstrap/pods/remotes/configs.py +69 -0
  38. localstack_cli/pro/core/bootstrap/pods/remotes/params.py +86 -0
  39. localstack_cli/pro/core/bootstrap/pods_client.py +834 -0
  40. localstack_cli/pro/core/cli/__init__.py +0 -0
  41. localstack_cli/pro/core/cli/auth.py +226 -0
  42. localstack_cli/pro/core/cli/aws.py +16 -0
  43. localstack_cli/pro/core/cli/cli.py +99 -0
  44. localstack_cli/pro/core/cli/click_utils.py +21 -0
  45. localstack_cli/pro/core/cli/cloud_pods.py +465 -0
  46. localstack_cli/pro/core/cli/diff_view.py +41 -0
  47. localstack_cli/pro/core/cli/ephemeral.py +199 -0
  48. localstack_cli/pro/core/cli/extensions.py +492 -0
  49. localstack_cli/pro/core/cli/iam.py +180 -0
  50. localstack_cli/pro/core/cli/license.py +90 -0
  51. localstack_cli/pro/core/cli/localstack.py +118 -0
  52. localstack_cli/pro/core/cli/replicator.py +378 -0
  53. localstack_cli/pro/core/cli/state.py +183 -0
  54. localstack_cli/pro/core/cli/tree_view.py +235 -0
  55. localstack_cli/pro/core/config.py +556 -0
  56. localstack_cli/pro/core/constants.py +54 -0
  57. localstack_cli/pro/core/plugins.py +169 -0
  58. localstack_cli/runtime/__init__.py +6 -0
  59. localstack_cli/runtime/exceptions.py +7 -0
  60. localstack_cli/runtime/hooks.py +73 -0
  61. localstack_cli/testing/__init__.py +1 -0
  62. localstack_cli/testing/config.py +4 -0
  63. localstack_cli/utils/__init__.py +0 -0
  64. localstack_cli/utils/analytics/__init__.py +12 -0
  65. localstack_cli/utils/analytics/cli.py +67 -0
  66. localstack_cli/utils/analytics/client.py +111 -0
  67. localstack_cli/utils/analytics/events.py +30 -0
  68. localstack_cli/utils/analytics/logger.py +48 -0
  69. localstack_cli/utils/analytics/metadata.py +250 -0
  70. localstack_cli/utils/analytics/publisher.py +160 -0
  71. localstack_cli/utils/analytics/service_request_aggregator.py +133 -0
  72. localstack_cli/utils/archives.py +271 -0
  73. localstack_cli/utils/batching.py +258 -0
  74. localstack_cli/utils/bootstrap.py +1418 -0
  75. localstack_cli/utils/checksum.py +313 -0
  76. localstack_cli/utils/collections.py +554 -0
  77. localstack_cli/utils/common.py +229 -0
  78. localstack_cli/utils/container_networking.py +142 -0
  79. localstack_cli/utils/container_utils/__init__.py +0 -0
  80. localstack_cli/utils/container_utils/container_client.py +1585 -0
  81. localstack_cli/utils/container_utils/docker_cmd_client.py +987 -0
  82. localstack_cli/utils/container_utils/docker_sdk_client.py +1018 -0
  83. localstack_cli/utils/crypto.py +294 -0
  84. localstack_cli/utils/docker_utils.py +272 -0
  85. localstack_cli/utils/files.py +327 -0
  86. localstack_cli/utils/functions.py +92 -0
  87. localstack_cli/utils/http.py +326 -0
  88. localstack_cli/utils/json.py +219 -0
  89. localstack_cli/utils/net.py +516 -0
  90. localstack_cli/utils/no_exit_argument_parser.py +19 -0
  91. localstack_cli/utils/numbers.py +49 -0
  92. localstack_cli/utils/objects.py +235 -0
  93. localstack_cli/utils/patch.py +260 -0
  94. localstack_cli/utils/platform.py +77 -0
  95. localstack_cli/utils/run.py +514 -0
  96. localstack_cli/utils/server/__init__.py +0 -0
  97. localstack_cli/utils/server/tcp_proxy.py +108 -0
  98. localstack_cli/utils/serving.py +187 -0
  99. localstack_cli/utils/ssl.py +71 -0
  100. localstack_cli/utils/strings.py +245 -0
  101. localstack_cli/utils/sync.py +267 -0
  102. localstack_cli/utils/threads.py +163 -0
  103. localstack_cli/utils/time.py +81 -0
  104. localstack_cli/utils/urls.py +21 -0
  105. localstack_cli/utils/venv.py +100 -0
  106. localstack_cli/utils/xml.py +41 -0
  107. localstack_cli/version.py +34 -0
  108. playground_ls_cli-4.14.1.dev8.dist-info/METADATA +95 -0
  109. playground_ls_cli-4.14.1.dev8.dist-info/RECORD +112 -0
  110. playground_ls_cli-4.14.1.dev8.dist-info/WHEEL +5 -0
  111. playground_ls_cli-4.14.1.dev8.dist-info/entry_points.txt +17 -0
  112. playground_ls_cli-4.14.1.dev8.dist-info/top_level.txt +1 -0
@@ -0,0 +1,138 @@
1
+ import itertools
2
+ import logging
3
+ from multiprocessing.pool import ThreadPool
4
+
5
+ import click
6
+ from rich.console import Console
7
+
8
+ from localstack_cli import config
9
+ from localstack_cli.cli.exceptions import CLIError
10
+ from localstack_cli.packages import InstallTarget, Package
11
+ from localstack_cli.packages.api import NoSuchPackageException, PackagesPluginManager
12
+ from localstack_cli.utils.bootstrap import setup_logging
13
+
14
+ LOG = logging.getLogger(__name__)
15
+
16
+ console = Console()
17
+
18
+
19
+ @click.group()
20
+ def cli():
21
+ """
22
+ The LocalStack Package Manager (lpm) CLI is a set of commands to install third-party packages used by localstack
23
+ service providers.
24
+
25
+ Here are some handy commands:
26
+
27
+ List all packages
28
+
29
+ python -m localstack.cli.lpm list
30
+
31
+ Install DynamoDB Local:
32
+
33
+ python -m localstack.cli.install dynamodb-local
34
+
35
+ Install all community packages, four in parallel:
36
+
37
+ python -m localstack.cli.lpm list | grep "/community" | cut -d'/' -f1 | xargs python -m localstack.cli.lpm install --parallel 4
38
+ """
39
+ setup_logging()
40
+
41
+
42
+ def _do_install_package(package: Package, version: str = None, target: InstallTarget = None):
43
+ console.print(f"installing... [bold]{package}[/bold]")
44
+ try:
45
+ package.install(version=version, target=target)
46
+ console.print(f"[green]installed[/green] [bold]{package}[/bold]")
47
+ except Exception as e:
48
+ console.print(f"[red]error[/red] installing {package}: {e}")
49
+ raise e
50
+
51
+
52
+ @cli.command()
53
+ @click.argument("package", nargs=-1, required=True)
54
+ @click.option(
55
+ "--parallel",
56
+ type=int,
57
+ default=1,
58
+ required=False,
59
+ help="how many installers to run in parallel processes",
60
+ )
61
+ @click.option(
62
+ "--version",
63
+ type=str,
64
+ default=None,
65
+ required=False,
66
+ help="version to install of a package",
67
+ )
68
+ @click.option(
69
+ "--target",
70
+ type=click.Choice([target.name.lower() for target in InstallTarget]),
71
+ default=None,
72
+ required=False,
73
+ help="target of the installation",
74
+ )
75
+ def install(
76
+ package: list[str],
77
+ parallel: int | None = 1,
78
+ version: str | None = None,
79
+ target: str | None = None,
80
+ ):
81
+ """Install one or more packages."""
82
+ try:
83
+ if target:
84
+ target = InstallTarget[str.upper(target)]
85
+ else:
86
+ # LPM is meant to be used at build-time, the default target is static_libs
87
+ target = InstallTarget.STATIC_LIBS
88
+
89
+ # collect installers and install in parallel:
90
+ console.print(f"resolving packages: {package}")
91
+ package_manager = PackagesPluginManager()
92
+ package_manager.load_all()
93
+ package_instances = package_manager.get_packages(package, version)
94
+
95
+ if parallel > 1:
96
+ console.print(f"install {parallel} packages in parallel:")
97
+
98
+ config.dirs.mkdirs()
99
+
100
+ with ThreadPool(processes=parallel) as pool:
101
+ pool.starmap(
102
+ _do_install_package,
103
+ zip(package_instances, itertools.repeat(version), itertools.repeat(target)),
104
+ )
105
+ except NoSuchPackageException as e:
106
+ LOG.debug(str(e), exc_info=e)
107
+ raise CLIError(str(e))
108
+ except Exception as e:
109
+ LOG.debug("one or more package installations failed.", exc_info=e)
110
+ raise CLIError("one or more package installations failed.")
111
+
112
+
113
+ @cli.command(name="list")
114
+ @click.option(
115
+ "-v",
116
+ "--verbose",
117
+ is_flag=True,
118
+ default=False,
119
+ required=False,
120
+ help="Verbose output (show additional info on packages)",
121
+ )
122
+ def list_packages(verbose: bool):
123
+ """List available packages of all repositories"""
124
+ package_manager = PackagesPluginManager()
125
+ package_manager.load_all()
126
+ packages = package_manager.get_all_packages()
127
+ for package_name, package_scope, package_instance in packages:
128
+ console.print(f"[green]{package_name}[/green]/{package_scope}")
129
+ if verbose:
130
+ for version in package_instance.get_versions():
131
+ if version == package_instance.default_version:
132
+ console.print(f" - [bold]{version} (default)[/bold]", highlight=False)
133
+ else:
134
+ console.print(f" - {version}", highlight=False)
135
+
136
+
137
+ if __name__ == "__main__":
138
+ cli()
@@ -0,0 +1,22 @@
1
+ import os
2
+
3
+
4
+ def main():
5
+ # indicate to the environment we are starting from the CLI
6
+ os.environ["LOCALSTACK_CLI"] = "1"
7
+
8
+ # config profiles are the first thing that need to be loaded (especially before localstack.config!)
9
+ from .profiles import set_and_remove_profile_from_sys_argv
10
+
11
+ # WARNING: This function modifies sys.argv to remove the profile argument.
12
+ set_and_remove_profile_from_sys_argv()
13
+
14
+ # initialize CLI plugins
15
+ from .localstack import create_with_plugins
16
+
17
+ cli = create_with_plugins()
18
+ cli()
19
+
20
+
21
+ if __name__ == "__main__":
22
+ main()
@@ -0,0 +1,39 @@
1
+ import abc
2
+ import logging
3
+ import os
4
+
5
+ import click
6
+ from plux import Plugin, PluginManager
7
+
8
+ LOG = logging.getLogger(__name__)
9
+
10
+
11
+ class LocalstackCli:
12
+ group: click.Group
13
+
14
+ def __call__(self, *args, **kwargs):
15
+ self.group(*args, **kwargs)
16
+
17
+
18
+ class LocalstackCliPlugin(Plugin):
19
+ namespace = "localstack_cli.plugins.cli"
20
+
21
+ def load(self, cli) -> None:
22
+ self.attach(cli)
23
+
24
+ @abc.abstractmethod
25
+ def attach(self, cli: LocalstackCli) -> None:
26
+ """
27
+ Attach commands to the `localstack` CLI.
28
+
29
+ :param cli: the cli object
30
+ """
31
+
32
+
33
+ def load_cli_plugins(cli):
34
+ if os.environ.get("DEBUG_PLUGINS", "0").lower() in ("true", "1"):
35
+ # importing localstack.config is still quite expensive...
36
+ logging.basicConfig(level=logging.DEBUG)
37
+
38
+ loader = PluginManager("localstack_cli.plugins.cli", load_args=(cli,))
39
+ loader.load_all()
@@ -0,0 +1,134 @@
1
+ import os
2
+ import time
3
+
4
+ import click
5
+ from plux import PluginManager
6
+ from plux.build.setuptools import find_plugins
7
+ from plux.core.entrypoint import spec_to_entry_point
8
+ from rich import print as rprint
9
+ from rich.console import Console
10
+ from rich.table import Table
11
+ from rich.tree import Tree
12
+
13
+ from localstack_cli.cli.exceptions import CLIError
14
+
15
+ console = Console()
16
+
17
+
18
+ @click.group()
19
+ def cli():
20
+ """
21
+ The plugins CLI is a set of commands to help troubleshoot LocalStack's plugin mechanism.
22
+ """
23
+ pass
24
+
25
+
26
+ @cli.command()
27
+ @click.option("--where", type=str, default=os.path.abspath(os.curdir))
28
+ @click.option("--exclude", multiple=True, default=())
29
+ @click.option("--include", multiple=True, default=("*",))
30
+ @click.option("--output", type=str, default="tree")
31
+ def find(where, exclude, include, output):
32
+ """
33
+ Find plugins by scanning the given path for PluginSpecs.
34
+ It starts from the current directory if --where is not specified.
35
+ This is what a setup.py method would run as a build step, i.e., discovering entry points.
36
+ """
37
+ with console.status(f"Scanning path {where}"):
38
+ plugins = find_plugins(where, exclude, include)
39
+
40
+ if output == "tree":
41
+ tree = Tree("Entrypoints")
42
+ for namespace, entry_points in plugins.items():
43
+ node = tree.add(f"[bold]{namespace}")
44
+
45
+ t = Table()
46
+ t.add_column("Name")
47
+ t.add_column("Location")
48
+
49
+ for ep in entry_points:
50
+ key, value = ep.split("=")
51
+ t.add_row(key, value)
52
+
53
+ node.add(t)
54
+
55
+ rprint(tree)
56
+ elif output == "dict":
57
+ rprint(dict(plugins))
58
+ else:
59
+ raise CLIError(f"unknown output format {output}")
60
+
61
+
62
+ @cli.command("list")
63
+ @click.option("--namespace", type=str, required=True)
64
+ def cmd_list(namespace):
65
+ """
66
+ List all available plugins using a PluginManager from available endpoints.
67
+ """
68
+ manager = PluginManager(namespace)
69
+
70
+ t = Table()
71
+ t.add_column("Name")
72
+ t.add_column("Factory")
73
+
74
+ for spec in manager.list_plugin_specs():
75
+ ep = spec_to_entry_point(spec)
76
+ t.add_row(spec.name, ep.value)
77
+
78
+ rprint(t)
79
+
80
+
81
+ @cli.command()
82
+ @click.option("--namespace", type=str, required=True)
83
+ @click.option("--name", type=str, required=True)
84
+ def load(namespace, name):
85
+ """
86
+ Attempts to load a plugin using a PluginManager.
87
+ """
88
+ manager = PluginManager(namespace)
89
+
90
+ with console.status(f"Loading {namespace}:{name}"):
91
+ then = time.time()
92
+ plugin = manager.load(name)
93
+ took = time.time() - then
94
+
95
+ rprint(
96
+ f":tada: successfully loaded [bold][green]{namespace}[/green][/bold]:[bold][cyan]{name}[/cyan][/bold] ({type(plugin)}"
97
+ )
98
+ rprint(f":stopwatch: loading took {took:.4f} s")
99
+
100
+
101
+ @cli.command()
102
+ @click.option("--namespace", type=str)
103
+ def cache(namespace):
104
+ """
105
+ Outputs the stevedore entrypoints cache from which plugins are loaded.
106
+ """
107
+ from stevedore._cache import _c
108
+
109
+ data = _c._get_data_for_path(None)
110
+
111
+ tree = Tree("Entrypoints")
112
+ for group, entry_points in data.get("groups").items():
113
+ if namespace and group != namespace:
114
+ continue
115
+ node = tree.add(f"[bold]{group}")
116
+
117
+ t = Table()
118
+ t.add_column("Name")
119
+ t.add_column("Value")
120
+
121
+ for key, value, _ in entry_points:
122
+ t.add_row(key, value)
123
+
124
+ node.add(t)
125
+
126
+ if namespace:
127
+ rprint(t)
128
+ return
129
+
130
+ rprint(tree)
131
+
132
+
133
+ if __name__ == "__main__":
134
+ cli()
@@ -0,0 +1,65 @@
1
+ import argparse
2
+ import os
3
+ import sys
4
+
5
+ # important: this needs to be free of localstack imports
6
+
7
+
8
+ def set_and_remove_profile_from_sys_argv():
9
+ """
10
+ Performs the following steps:
11
+
12
+ 1. Use argparse to parse the command line arguments for the --profile flag.
13
+ All occurrences are removed from the sys.argv list, and the value from
14
+ the last occurrence is used. This allows the user to specify a profile
15
+ at any point on the command line.
16
+
17
+ 2. If a --profile flag is not found, check for the -p flag. The first
18
+ occurrence of the -p flag is used and it is not removed from sys.argv.
19
+ The reasoning for this is that at least one of the CLI subcommands has
20
+ a -p flag, and we want to keep it in sys.argv for that command to
21
+ pick up. An existing bug means that if a -p flag is used with a
22
+ subcommand, it could erroneously be used as the profile value as well.
23
+ This behaviour is undesired, but we must maintain back-compatibility of
24
+ allowing the profile to be specified using -p.
25
+
26
+ 3. If a profile is found, the 'CONFIG_PROFILE' os variable is set
27
+ accordingly. This is later picked up by ``localstack.config``.
28
+
29
+ WARNING: Any --profile options are REMOVED from sys.argv, so that they are
30
+ not passed to the localstack CLI. This allows the profile option
31
+ to be set at any point on the command line.
32
+ """
33
+ parser = argparse.ArgumentParser(add_help=False)
34
+ parser.add_argument("--profile")
35
+ namespace, sys.argv = parser.parse_known_args(sys.argv)
36
+ profile = namespace.profile
37
+
38
+ if not profile:
39
+ # if no profile is given, check for the -p argument
40
+ profile = parse_p_argument(sys.argv)
41
+
42
+ if profile:
43
+ os.environ["CONFIG_PROFILE"] = profile.strip()
44
+
45
+
46
+ def parse_p_argument(args) -> str | None:
47
+ """
48
+ Lightweight arg parsing to find the first occurrence of ``-p <config>``, or ``-p=<config>`` and return the value of
49
+ ``<config>`` from the given arguments.
50
+
51
+ :param args: list of CLI arguments
52
+ :returns: the value of ``-p``.
53
+ """
54
+ for i, current_arg in enumerate(args):
55
+ if current_arg.startswith("-p="):
56
+ # if using the "<arg>=<value>" notation, we remove the "-p=" prefix to get the value
57
+ return current_arg[3:]
58
+ if current_arg == "-p":
59
+ # otherwise use the next arg in the args list as value
60
+ try:
61
+ return args[i + 1]
62
+ except IndexError:
63
+ return None
64
+
65
+ return None