localstack 4.13.2.dev3__tar.gz → 4.13.2.dev36__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.
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/Makefile +5 -1
- {localstack-4.13.2.dev3/localstack.egg-info → localstack-4.13.2.dev36}/PKG-INFO +2 -2
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36/localstack.egg-info}/PKG-INFO +2 -2
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack.egg-info/SOURCES.txt +11 -14
- localstack-4.13.2.dev36/localstack.egg-info/entry_points.txt +17 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack.egg-info/requires.txt +1 -1
- localstack-4.13.2.dev36/localstack_cli/pro/core/bootstrap/extensions/bootstrap.py +97 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/licensingv2.py +4 -143
- localstack-4.13.2.dev36/localstack_cli/pro/core/plugins.py +81 -0
- localstack-4.13.2.dev36/localstack_cli/runtime/__init__.py +6 -0
- localstack-4.13.2.dev36/localstack_cli/runtime/exceptions.py +7 -0
- localstack-4.13.2.dev36/localstack_cli/runtime/hooks.py +73 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/analytics/metadata.py +14 -20
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/bootstrap.py +3 -8
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/version.py +3 -3
- localstack-4.13.2.dev36/plux.ini +15 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/pyproject.toml +8 -6
- localstack-4.13.2.dev3/localstack.egg-info/entry_points.txt +0 -6
- localstack-4.13.2.dev3/localstack_cli/pro/core/bootstrap/decryption.py +0 -160
- localstack-4.13.2.dev3/localstack_cli/utils/analytics/metrics/__init__.py +0 -6
- localstack-4.13.2.dev3/localstack_cli/utils/analytics/metrics/api.py +0 -58
- localstack-4.13.2.dev3/localstack_cli/utils/analytics/metrics/counter.py +0 -212
- localstack-4.13.2.dev3/localstack_cli/utils/analytics/metrics/publisher.py +0 -45
- localstack-4.13.2.dev3/localstack_cli/utils/analytics/metrics/registry.py +0 -97
- localstack-4.13.2.dev3/localstack_cli/utils/analytics/service_providers.py +0 -22
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/.github/workflows/tests-cli.yml +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/.gitignore +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/README.md +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/bin/localstack +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack.egg-info/dependency_links.txt +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack.egg-info/top_level.txt +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/cli/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/cli/console.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/cli/core_plugin.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/cli/exceptions.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/cli/localstack.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/cli/lpm.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/cli/main.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/cli/plugin.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/cli/plugins.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/cli/profiles.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/config.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/constants.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/logging/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/logging/format.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/logging/setup.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/packages/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/packages/api.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/packages/core.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/auth.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/dns_utils.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/entitlements.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/extensions/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/extensions/__main__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/extensions/autoinstall.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/extensions/repository.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/pods/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/pods/api_types.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/pods/constants.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/pods/remotes/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/pods/remotes/api.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/pods/remotes/configs.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/pods/remotes/params.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/pods_client.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/auth.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/aws.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/cli.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/click_utils.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/cloud_pods.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/diff_view.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/ephemeral.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/extensions.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/iam.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/license.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/localstack.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/replicator.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/state.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/cli/tree_view.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/config.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/constants.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/analytics/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/analytics/cli.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/analytics/client.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/analytics/events.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/analytics/logger.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/analytics/publisher.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/analytics/service_request_aggregator.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/archives.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/batching.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/checksum.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/collections.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/common.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/container_networking.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/container_utils/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/container_utils/container_client.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/container_utils/docker_cmd_client.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/container_utils/docker_sdk_client.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/crypto.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/docker_utils.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/files.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/functions.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/http.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/json.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/net.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/no_exit_argument_parser.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/numbers.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/objects.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/patch.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/platform.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/run.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/server/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/server/tcp_proxy.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/serving.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/ssl.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/strings.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/sync.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/threads.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/time.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/urls.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/venv.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/utils/xml.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/setup.cfg +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/cli/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/cli/conftest.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/cli/test_cli.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/cli/test_cli_pro.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/conftest.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/unit/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/unit/cli/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/unit/cli/test_cli.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/unit/cli/test_lpm.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/unit/cli/test_profiles.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/unit/pro/__init__.py +0 -0
- {localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/tests/unit/pro/test_cli.py +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.PHONY: install test test-unit test-integration lint clean
|
|
1
|
+
.PHONY: install test test-unit test-integration lint clean entrypoints
|
|
2
2
|
|
|
3
3
|
VENV_DIR ?= .venv
|
|
4
4
|
PYTHON ?= python3
|
|
@@ -29,6 +29,10 @@ format: install
|
|
|
29
29
|
$(VENV_DIR)/bin/ruff check --fix localstack_cli tests
|
|
30
30
|
$(VENV_DIR)/bin/ruff format localstack_cli tests
|
|
31
31
|
|
|
32
|
+
entrypoints: install
|
|
33
|
+
$(VENV_DIR)/bin/python -m plux entrypoints
|
|
34
|
+
@test -s plux.ini || (echo "Entrypoints not created correctly!" && exit 1)
|
|
35
|
+
|
|
32
36
|
clean:
|
|
33
37
|
rm -rf $(VENV_DIR)
|
|
34
38
|
rm -rf build dist *.egg-info
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: localstack
|
|
3
|
-
Version: 4.13.2.
|
|
3
|
+
Version: 4.13.2.dev36
|
|
4
4
|
Summary: The LocalStack Command Line Interface
|
|
5
5
|
Author-email: LocalStack Contributors <info@localstack.cloud>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -24,7 +24,7 @@ Requires-Dist: cryptography
|
|
|
24
24
|
Requires-Dist: dnslib>=0.9.10
|
|
25
25
|
Requires-Dist: dnspython>=1.16.0
|
|
26
26
|
Requires-Dist: docker>=6.1.1
|
|
27
|
-
Requires-Dist: plux>=1.
|
|
27
|
+
Requires-Dist: plux>=1.14.0
|
|
28
28
|
Requires-Dist: psutil>=5.4.8
|
|
29
29
|
Requires-Dist: python-dotenv>=0.19.1
|
|
30
30
|
Requires-Dist: pyyaml>=5.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: localstack
|
|
3
|
-
Version: 4.13.2.
|
|
3
|
+
Version: 4.13.2.dev36
|
|
4
4
|
Summary: The LocalStack Command Line Interface
|
|
5
5
|
Author-email: LocalStack Contributors <info@localstack.cloud>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -24,7 +24,7 @@ Requires-Dist: cryptography
|
|
|
24
24
|
Requires-Dist: dnslib>=0.9.10
|
|
25
25
|
Requires-Dist: dnspython>=1.16.0
|
|
26
26
|
Requires-Dist: docker>=6.1.1
|
|
27
|
-
Requires-Dist: plux>=1.
|
|
27
|
+
Requires-Dist: plux>=1.14.0
|
|
28
28
|
Requires-Dist: psutil>=5.4.8
|
|
29
29
|
Requires-Dist: python-dotenv>=0.19.1
|
|
30
30
|
Requires-Dist: pyyaml>=5.1
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
.gitignore
|
|
2
2
|
Makefile
|
|
3
3
|
README.md
|
|
4
|
+
plux.ini
|
|
4
5
|
pyproject.toml
|
|
5
6
|
./localstack_cli/__init__.py
|
|
6
7
|
./localstack_cli/config.py
|
|
@@ -26,9 +27,9 @@ pyproject.toml
|
|
|
26
27
|
./localstack_cli/pro/core/__init__.py
|
|
27
28
|
./localstack_cli/pro/core/config.py
|
|
28
29
|
./localstack_cli/pro/core/constants.py
|
|
30
|
+
./localstack_cli/pro/core/plugins.py
|
|
29
31
|
./localstack_cli/pro/core/bootstrap/__init__.py
|
|
30
32
|
./localstack_cli/pro/core/bootstrap/auth.py
|
|
31
|
-
./localstack_cli/pro/core/bootstrap/decryption.py
|
|
32
33
|
./localstack_cli/pro/core/bootstrap/dns_utils.py
|
|
33
34
|
./localstack_cli/pro/core/bootstrap/entitlements.py
|
|
34
35
|
./localstack_cli/pro/core/bootstrap/licensingv2.py
|
|
@@ -36,6 +37,7 @@ pyproject.toml
|
|
|
36
37
|
./localstack_cli/pro/core/bootstrap/extensions/__init__.py
|
|
37
38
|
./localstack_cli/pro/core/bootstrap/extensions/__main__.py
|
|
38
39
|
./localstack_cli/pro/core/bootstrap/extensions/autoinstall.py
|
|
40
|
+
./localstack_cli/pro/core/bootstrap/extensions/bootstrap.py
|
|
39
41
|
./localstack_cli/pro/core/bootstrap/extensions/repository.py
|
|
40
42
|
./localstack_cli/pro/core/bootstrap/pods/__init__.py
|
|
41
43
|
./localstack_cli/pro/core/bootstrap/pods/api_types.py
|
|
@@ -59,6 +61,9 @@ pyproject.toml
|
|
|
59
61
|
./localstack_cli/pro/core/cli/replicator.py
|
|
60
62
|
./localstack_cli/pro/core/cli/state.py
|
|
61
63
|
./localstack_cli/pro/core/cli/tree_view.py
|
|
64
|
+
./localstack_cli/runtime/__init__.py
|
|
65
|
+
./localstack_cli/runtime/exceptions.py
|
|
66
|
+
./localstack_cli/runtime/hooks.py
|
|
62
67
|
./localstack_cli/utils/__init__.py
|
|
63
68
|
./localstack_cli/utils/archives.py
|
|
64
69
|
./localstack_cli/utils/batching.py
|
|
@@ -96,13 +101,7 @@ pyproject.toml
|
|
|
96
101
|
./localstack_cli/utils/analytics/logger.py
|
|
97
102
|
./localstack_cli/utils/analytics/metadata.py
|
|
98
103
|
./localstack_cli/utils/analytics/publisher.py
|
|
99
|
-
./localstack_cli/utils/analytics/service_providers.py
|
|
100
104
|
./localstack_cli/utils/analytics/service_request_aggregator.py
|
|
101
|
-
./localstack_cli/utils/analytics/metrics/__init__.py
|
|
102
|
-
./localstack_cli/utils/analytics/metrics/api.py
|
|
103
|
-
./localstack_cli/utils/analytics/metrics/counter.py
|
|
104
|
-
./localstack_cli/utils/analytics/metrics/publisher.py
|
|
105
|
-
./localstack_cli/utils/analytics/metrics/registry.py
|
|
106
105
|
./localstack_cli/utils/container_utils/__init__.py
|
|
107
106
|
./localstack_cli/utils/container_utils/container_client.py
|
|
108
107
|
./localstack_cli/utils/container_utils/docker_cmd_client.py
|
|
@@ -140,9 +139,9 @@ localstack_cli/pro/__init__.py
|
|
|
140
139
|
localstack_cli/pro/core/__init__.py
|
|
141
140
|
localstack_cli/pro/core/config.py
|
|
142
141
|
localstack_cli/pro/core/constants.py
|
|
142
|
+
localstack_cli/pro/core/plugins.py
|
|
143
143
|
localstack_cli/pro/core/bootstrap/__init__.py
|
|
144
144
|
localstack_cli/pro/core/bootstrap/auth.py
|
|
145
|
-
localstack_cli/pro/core/bootstrap/decryption.py
|
|
146
145
|
localstack_cli/pro/core/bootstrap/dns_utils.py
|
|
147
146
|
localstack_cli/pro/core/bootstrap/entitlements.py
|
|
148
147
|
localstack_cli/pro/core/bootstrap/licensingv2.py
|
|
@@ -150,6 +149,7 @@ localstack_cli/pro/core/bootstrap/pods_client.py
|
|
|
150
149
|
localstack_cli/pro/core/bootstrap/extensions/__init__.py
|
|
151
150
|
localstack_cli/pro/core/bootstrap/extensions/__main__.py
|
|
152
151
|
localstack_cli/pro/core/bootstrap/extensions/autoinstall.py
|
|
152
|
+
localstack_cli/pro/core/bootstrap/extensions/bootstrap.py
|
|
153
153
|
localstack_cli/pro/core/bootstrap/extensions/repository.py
|
|
154
154
|
localstack_cli/pro/core/bootstrap/pods/__init__.py
|
|
155
155
|
localstack_cli/pro/core/bootstrap/pods/api_types.py
|
|
@@ -173,6 +173,9 @@ localstack_cli/pro/core/cli/localstack.py
|
|
|
173
173
|
localstack_cli/pro/core/cli/replicator.py
|
|
174
174
|
localstack_cli/pro/core/cli/state.py
|
|
175
175
|
localstack_cli/pro/core/cli/tree_view.py
|
|
176
|
+
localstack_cli/runtime/__init__.py
|
|
177
|
+
localstack_cli/runtime/exceptions.py
|
|
178
|
+
localstack_cli/runtime/hooks.py
|
|
176
179
|
localstack_cli/utils/__init__.py
|
|
177
180
|
localstack_cli/utils/archives.py
|
|
178
181
|
localstack_cli/utils/batching.py
|
|
@@ -210,13 +213,7 @@ localstack_cli/utils/analytics/events.py
|
|
|
210
213
|
localstack_cli/utils/analytics/logger.py
|
|
211
214
|
localstack_cli/utils/analytics/metadata.py
|
|
212
215
|
localstack_cli/utils/analytics/publisher.py
|
|
213
|
-
localstack_cli/utils/analytics/service_providers.py
|
|
214
216
|
localstack_cli/utils/analytics/service_request_aggregator.py
|
|
215
|
-
localstack_cli/utils/analytics/metrics/__init__.py
|
|
216
|
-
localstack_cli/utils/analytics/metrics/api.py
|
|
217
|
-
localstack_cli/utils/analytics/metrics/counter.py
|
|
218
|
-
localstack_cli/utils/analytics/metrics/publisher.py
|
|
219
|
-
localstack_cli/utils/analytics/metrics/registry.py
|
|
220
217
|
localstack_cli/utils/container_utils/__init__.py
|
|
221
218
|
localstack_cli/utils/container_utils/container_client.py
|
|
222
219
|
localstack_cli/utils/container_utils/docker_cmd_client.py
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[console_scripts]
|
|
2
|
+
localstack = localstack_cli.cli.main:main
|
|
3
|
+
|
|
4
|
+
[localstack.hooks.configure_localstack_container]
|
|
5
|
+
configure_extensions_dev_container = localstack_cli.pro.core.plugins:configure_extensions_dev_container
|
|
6
|
+
configure_pro_container = localstack_cli.pro.core.plugins:configure_pro_container
|
|
7
|
+
set_analytics_header = localstack_cli.utils.analytics.metadata:set_analytics_header
|
|
8
|
+
|
|
9
|
+
[localstack.hooks.prepare_host]
|
|
10
|
+
activate_pro_key_on_host = localstack_cli.pro.core.plugins:activate_pro_key_on_host
|
|
11
|
+
configure_extensions_dev_host = localstack_cli.pro.core.plugins:configure_extensions_dev_host
|
|
12
|
+
patch_community_pro_detection = localstack_cli.pro.core.plugins:patch_community_pro_detection
|
|
13
|
+
publish_invocation_metadata = localstack_cli.utils.analytics.metadata:publish_invocation_metadata
|
|
14
|
+
|
|
15
|
+
[localstack_cli.plugins.cli]
|
|
16
|
+
core = localstack_cli.cli.core_plugin:CoreCliPlugin
|
|
17
|
+
pro = localstack_cli.pro.core.cli.localstack:ProCliPlugins
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Hooks for extension developer mode on the host CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from tempfile import gettempdir
|
|
9
|
+
|
|
10
|
+
from localstack_cli import config
|
|
11
|
+
from localstack_cli.utils.bootstrap import Container
|
|
12
|
+
from localstack_cli.utils.container_utils.container_client import BindMount
|
|
13
|
+
from localstack_cli.utils.json import FileMappedDocument
|
|
14
|
+
from localstack_cli.utils.strings import md5
|
|
15
|
+
|
|
16
|
+
LOG = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
_ENTRYPOINT_SCRIPT = """#!/bin/bash
|
|
19
|
+
echo "=================================================="
|
|
20
|
+
echo "LocalStack extension developer mode enabled"
|
|
21
|
+
shopt -s nullglob
|
|
22
|
+
|
|
23
|
+
pkgs=$(echo /opt/code/localstack/.venv/lib/python3*/site-packages)
|
|
24
|
+
|
|
25
|
+
echo "import localstack_extensions_resolve;localstack_extensions_resolve.resolve()" > ${pkgs}/localstack-extensions-resolve.pth
|
|
26
|
+
|
|
27
|
+
cat << EOF >> ${pkgs}/localstack_extensions_resolve.py
|
|
28
|
+
import os
|
|
29
|
+
import sys
|
|
30
|
+
import glob
|
|
31
|
+
|
|
32
|
+
base_dirs_visited = set()
|
|
33
|
+
|
|
34
|
+
def append_pth_recursively(base_dir):
|
|
35
|
+
if base_dir in base_dirs_visited:
|
|
36
|
+
return
|
|
37
|
+
base_dirs_visited.add(base_dir)
|
|
38
|
+
|
|
39
|
+
for f in glob.glob(f"{base_dir}/*.pth", recursive=True):
|
|
40
|
+
with open(f, "r") as fd:
|
|
41
|
+
abs_path = os.path.abspath(os.path.dirname(f))
|
|
42
|
+
lines = fd.readlines()
|
|
43
|
+
for line in lines:
|
|
44
|
+
if line := line.strip():
|
|
45
|
+
if "import" in line:
|
|
46
|
+
continue
|
|
47
|
+
module_dir = os.path.abspath(os.path.join(abs_path, line)) if not os.path.isabs(line) else line
|
|
48
|
+
if os.path.exists(module_dir) and os.path.isdir(module_dir):
|
|
49
|
+
if module_dir not in sys.path:
|
|
50
|
+
sys.path.append(module_dir)
|
|
51
|
+
append_pth_recursively(module_dir)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def resolve():
|
|
55
|
+
append_pth_recursively(os.path.dirname(__file__))
|
|
56
|
+
EOF
|
|
57
|
+
|
|
58
|
+
for d in /opt/code/extensions/* ;
|
|
59
|
+
do
|
|
60
|
+
echo "- mounting extension ${d}"
|
|
61
|
+
find ${d} -type d -name "site-packages" >> ${pkgs}/localstack-extensions-venv.pth
|
|
62
|
+
echo ${d} >> ${pkgs}/localstack-extensions-venv.pth
|
|
63
|
+
done
|
|
64
|
+
echo "Resuming normal execution, ..."
|
|
65
|
+
echo "=================================================="
|
|
66
|
+
exec /usr/local/bin/docker-entrypoint.sh
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
_host_extension_dirs: list[str] = []
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def run_on_configure_host_hook():
|
|
73
|
+
"""Load extension directories from ~/.localstack/extensions-dev.json."""
|
|
74
|
+
doc = FileMappedDocument(os.path.join(config.CONFIG_DIR, "extensions-dev.json"))
|
|
75
|
+
|
|
76
|
+
for extensions_spec in doc.get("extensions", []):
|
|
77
|
+
path = extensions_spec.get("host_path")
|
|
78
|
+
if path and os.path.exists(path):
|
|
79
|
+
_host_extension_dirs.append(path)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def run_on_configure_localstack_container_hook(container: Container):
|
|
83
|
+
"""Configure container for extension dev mode."""
|
|
84
|
+
# Create and mount custom entrypoint script
|
|
85
|
+
h = md5(_ENTRYPOINT_SCRIPT)
|
|
86
|
+
file = Path(gettempdir(), f"docker-entrypoint-{h}.sh")
|
|
87
|
+
if not file.exists():
|
|
88
|
+
file.write_text(_ENTRYPOINT_SCRIPT, newline="\n", encoding="utf-8")
|
|
89
|
+
file.chmod(0o777)
|
|
90
|
+
|
|
91
|
+
container.config.volumes.add(BindMount(str(file), f"/tmp/{file.name}"))
|
|
92
|
+
container.config.entrypoint = f"/tmp/{file.name}"
|
|
93
|
+
|
|
94
|
+
# Mount extension directories
|
|
95
|
+
for ext_dir in _host_extension_dirs:
|
|
96
|
+
target = os.path.join("/opt/code/extensions", os.path.basename(ext_dir))
|
|
97
|
+
container.config.volumes.add(BindMount(ext_dir, target, read_only=True))
|
{localstack-4.13.2.dev3 → localstack-4.13.2.dev36}/localstack_cli/pro/core/bootstrap/licensingv2.py
RENAMED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import base64
|
|
2
|
-
import binascii
|
|
3
2
|
import copy
|
|
4
3
|
import dataclasses
|
|
5
|
-
import hashlib
|
|
6
4
|
import hmac
|
|
7
5
|
import json
|
|
8
6
|
import logging
|
|
@@ -26,9 +24,8 @@ from localstack_cli.pro.core.bootstrap.entitlements import (
|
|
|
26
24
|
ProductInfo,
|
|
27
25
|
)
|
|
28
26
|
from localstack_cli.pro.core.constants import PLATFORM_PLUGIN_NAMESPACE
|
|
29
|
-
from localstack_cli.utils.files import load_file
|
|
30
27
|
from localstack_cli.utils.objects import singleton_factory
|
|
31
|
-
from localstack_cli.utils.strings import md5
|
|
28
|
+
from localstack_cli.utils.strings import md5
|
|
32
29
|
from plux import Plugin, PluginDisabled, PluginLifecycleListener, PluginSpec
|
|
33
30
|
|
|
34
31
|
LOG = logging.getLogger(__name__)
|
|
@@ -446,20 +443,6 @@ class LicensingClient:
|
|
|
446
443
|
"""
|
|
447
444
|
raise NotImplementedError
|
|
448
445
|
|
|
449
|
-
def decode_decryption_key(self, credentials: Credentials, license: License) -> bytes:
|
|
450
|
-
raise NotImplementedError
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
class LicenseSecretDecoder:
|
|
454
|
-
"""
|
|
455
|
-
Class to decode the ``license_secret`` field from the given license. The field contains a secret which is
|
|
456
|
-
the decryption key for the localstack code.
|
|
457
|
-
"""
|
|
458
|
-
|
|
459
|
-
def decode_license_secret(self, license: LicenseV1) -> bytes: # noqa
|
|
460
|
-
raise NotImplementedError
|
|
461
|
-
|
|
462
|
-
|
|
463
446
|
#####################
|
|
464
447
|
# v1 implementation #
|
|
465
448
|
#####################
|
|
@@ -518,64 +501,6 @@ class LicenseParser:
|
|
|
518
501
|
raise LicenseFormatError(f"error parsing license file: {e}") from e
|
|
519
502
|
|
|
520
503
|
|
|
521
|
-
class AESLicenseV1SecretDecoder(LicenseSecretDecoder):
|
|
522
|
-
"""
|
|
523
|
-
Uses a custom AES encryption scheme to decode the source decryption key from the license key. This is
|
|
524
|
-
mostly obfuscation and not really a trust mechanism.
|
|
525
|
-
|
|
526
|
-
The shared key is the sha256 digest of the licensing credentials concatenated with the license signature.
|
|
527
|
-
"""
|
|
528
|
-
|
|
529
|
-
scheme = "LS1.0"
|
|
530
|
-
|
|
531
|
-
def __init__(self, credentials: Credentials):
|
|
532
|
-
self.credentials = credentials
|
|
533
|
-
|
|
534
|
-
def decode_license_secret(self, license: LicenseV1) -> bytes: # noqa
|
|
535
|
-
if not license.signature:
|
|
536
|
-
raise LicenseFormatError("license is not signed")
|
|
537
|
-
|
|
538
|
-
# use the signature of the license as well as the credentials to encode the license key
|
|
539
|
-
hash_ = hashlib.sha256()
|
|
540
|
-
hash_.update(self.credentials.to_bytes())
|
|
541
|
-
hash_.update(binascii.unhexlify(license.signature)) # use the byte value, not the string
|
|
542
|
-
key = hash_.digest()
|
|
543
|
-
|
|
544
|
-
# extract the scheme from the base64 encoded string
|
|
545
|
-
license_secret = base64.b64decode(license.license_secret)
|
|
546
|
-
parts = license_secret.split(b":", maxsplit=1)
|
|
547
|
-
if len(parts) != 2: # noqa PLR2004
|
|
548
|
-
raise LicenseFormatError("invalid license key format")
|
|
549
|
-
scheme, secret = parts
|
|
550
|
-
|
|
551
|
-
if scheme.decode("utf-8") != self.scheme:
|
|
552
|
-
raise ValueError(f"unknown scheme {scheme}")
|
|
553
|
-
|
|
554
|
-
iv = secret[:16]
|
|
555
|
-
encrypted_data = secret[16:]
|
|
556
|
-
|
|
557
|
-
return self._aes_decrypt(key, iv, encrypted_data)
|
|
558
|
-
|
|
559
|
-
def _aes_decrypt(self, key: bytes, iv: bytes, encrypted_data: bytes):
|
|
560
|
-
from cryptography.hazmat.primitives import padding
|
|
561
|
-
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
562
|
-
|
|
563
|
-
# Create an AES cipher with the provided key and CBC mode
|
|
564
|
-
cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
|
|
565
|
-
|
|
566
|
-
# Create a decryptor object using the AES cipher
|
|
567
|
-
decryptor = cipher.decryptor()
|
|
568
|
-
|
|
569
|
-
# Decrypt the encrypted data
|
|
570
|
-
decrypted_data = decryptor.update(encrypted_data) + decryptor.finalize()
|
|
571
|
-
|
|
572
|
-
# Remove PKCS7 padding from the decrypted data
|
|
573
|
-
unpadder = padding.PKCS7(128).unpadder()
|
|
574
|
-
unpadded_data = unpadder.update(decrypted_data)
|
|
575
|
-
|
|
576
|
-
return unpadded_data + unpadder.finalize()
|
|
577
|
-
|
|
578
|
-
|
|
579
504
|
class LicenseV1ClientBase(LicensingClient):
|
|
580
505
|
def validate_license(self, credentials: Credentials, license: LicenseV1):
|
|
581
506
|
try:
|
|
@@ -640,17 +565,6 @@ class LicenseV1Client(LicenseV1ClientBase):
|
|
|
640
565
|
license_.offline_data["localstack_version"] = VERSION
|
|
641
566
|
return license_
|
|
642
567
|
|
|
643
|
-
def decode_decryption_key(self, credentials: Credentials, license: LicenseV1) -> bytes:
|
|
644
|
-
key = base64.b64decode(license.license_secret)
|
|
645
|
-
parts = key.split(b":", maxsplit=1)
|
|
646
|
-
scheme = to_str(parts[0])
|
|
647
|
-
if scheme == AESLicenseV1SecretDecoder.scheme:
|
|
648
|
-
decoder = AESLicenseV1SecretDecoder(credentials)
|
|
649
|
-
else:
|
|
650
|
-
raise LicenseFormatError(f"unknown license key scheme {scheme}")
|
|
651
|
-
|
|
652
|
-
return decoder.decode_license_secret(license)
|
|
653
|
-
|
|
654
568
|
def _get_machine_data(self) -> dict:
|
|
655
569
|
from localstack_cli.utils.analytics.metadata import get_client_metadata
|
|
656
570
|
|
|
@@ -826,10 +740,9 @@ class LicensedLocalstackEnvironment:
|
|
|
826
740
|
|
|
827
741
|
def activate(self, offline_only: bool = False):
|
|
828
742
|
"""
|
|
829
|
-
This high-level method
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
activation and code decryption.
|
|
743
|
+
This high-level method activates the license using credentials from the environment.
|
|
744
|
+
Once completed, it sets ``self.license`` to the license document that was activated.
|
|
745
|
+
This method will also set the env var ``PRO_ACTIVATED=1`` after successful license activation.
|
|
833
746
|
|
|
834
747
|
See ``activate_license`` for the activation algorithm.
|
|
835
748
|
|
|
@@ -854,9 +767,6 @@ class LicensedLocalstackEnvironment:
|
|
|
854
767
|
|
|
855
768
|
self.activate_license(offline_only)
|
|
856
769
|
|
|
857
|
-
if not self.is_decryption_enabled():
|
|
858
|
-
self.enable_decryption()
|
|
859
|
-
|
|
860
770
|
os.environ[constants.ENV_PRO_ACTIVATED] = "1"
|
|
861
771
|
|
|
862
772
|
def activate_license(self, offline_only: bool = False):
|
|
@@ -974,55 +884,6 @@ class LicensedLocalstackEnvironment:
|
|
|
974
884
|
"""
|
|
975
885
|
return self.product_entitlements.has_entitlement(product_name)
|
|
976
886
|
|
|
977
|
-
def enable_decryption(self):
|
|
978
|
-
"""
|
|
979
|
-
Called by ``activate`` to read the source decryption key from the license key and register the
|
|
980
|
-
``DecryptionHandler`` into the sys path.
|
|
981
|
-
"""
|
|
982
|
-
if not self.activated or not self.license:
|
|
983
|
-
raise ValueError("license not yet activated")
|
|
984
|
-
|
|
985
|
-
from localstack_cli.pro.core.bootstrap.decryption import (
|
|
986
|
-
DecryptionHandler,
|
|
987
|
-
init_source_decryption,
|
|
988
|
-
)
|
|
989
|
-
from localstack_cli.pro.core.config import ROOT_FOLDER
|
|
990
|
-
|
|
991
|
-
decryption_handler = DecryptionHandler(
|
|
992
|
-
self.client.decode_decryption_key(self.require_valid_credentials(), self.license)
|
|
993
|
-
)
|
|
994
|
-
|
|
995
|
-
try:
|
|
996
|
-
file_name = f"{ROOT_FOLDER}/localstack/pro/core/utils/decryption_check.py.enc"
|
|
997
|
-
encrypted_file_content = load_file(file_name, mode="rb")
|
|
998
|
-
if not encrypted_file_content:
|
|
999
|
-
raise ValueError(
|
|
1000
|
-
"Decryption check file not found. Are you using localstack pro in host mode?"
|
|
1001
|
-
)
|
|
1002
|
-
file_content = decryption_handler.decrypt(encrypted_file_content)
|
|
1003
|
-
if b"decryption_check" not in file_content:
|
|
1004
|
-
raise ValueError("Decryption resulted in invalid python file")
|
|
1005
|
-
except Exception as e:
|
|
1006
|
-
raise LicenseActivationError(
|
|
1007
|
-
"Error while trying to perform code activation. You may be using a "
|
|
1008
|
-
"version of LocalStack that is not within your license agreement."
|
|
1009
|
-
) from e
|
|
1010
|
-
|
|
1011
|
-
init_source_decryption(decryption_handler)
|
|
1012
|
-
|
|
1013
|
-
def is_decryption_enabled(self) -> bool:
|
|
1014
|
-
"""
|
|
1015
|
-
Checks whether decryption is enabled. Decryption can be enabled in a test environment when the
|
|
1016
|
-
source code is available. So this can return true even if a license has not been activated.
|
|
1017
|
-
|
|
1018
|
-
:return: true if the normally encrypted source code can be accessed.
|
|
1019
|
-
"""
|
|
1020
|
-
try:
|
|
1021
|
-
from localstack_cli.pro.core.utils.decryption_check import decryption_check # noqa
|
|
1022
|
-
|
|
1023
|
-
return True
|
|
1024
|
-
except ImportError:
|
|
1025
|
-
return False
|
|
1026
887
|
|
|
1027
888
|
def save_license(self):
|
|
1028
889
|
"""
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pro plugin hooks for the LocalStack CLI.
|
|
3
|
+
|
|
4
|
+
These hooks are executed on the host machine when running CLI commands like `localstack start`.
|
|
5
|
+
They handle license activation, container configuration, and extension developer mode.
|
|
6
|
+
|
|
7
|
+
Note: This file was extracted from localstack-pro-core/localstack/pro/core/plugins.py
|
|
8
|
+
and rewritten to contain only CLI-relevant functionality.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import logging
|
|
14
|
+
import os
|
|
15
|
+
|
|
16
|
+
from localstack_cli import config as localstack_config
|
|
17
|
+
from localstack_cli.config import HostAndPort
|
|
18
|
+
from localstack_cli.pro.core import config as pro_config
|
|
19
|
+
from localstack_cli.pro.core.bootstrap import licensingv2
|
|
20
|
+
from localstack_cli.runtime import hooks
|
|
21
|
+
from localstack_cli.runtime.exceptions import LocalstackExit
|
|
22
|
+
from localstack_cli.utils.bootstrap import Container
|
|
23
|
+
|
|
24
|
+
LOG = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def modify_gateway_listen_config(cfg):
|
|
28
|
+
"""
|
|
29
|
+
Modifies the localstack config to additionally listen to port 443.
|
|
30
|
+
Needs to be called before any edge URLs are resolved using the config.
|
|
31
|
+
"""
|
|
32
|
+
if os.getenv("GATEWAY_LISTEN") is None:
|
|
33
|
+
host = "0.0.0.0" if localstack_config.in_docker() else "127.0.0.1"
|
|
34
|
+
cfg.GATEWAY_LISTEN.append(HostAndPort(host=host, port=443))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@hooks.prepare_host(priority=200)
|
|
38
|
+
def patch_community_pro_detection():
|
|
39
|
+
"""This is currently needed to make localstack core aware of the `localstack auth set-token`
|
|
40
|
+
functionality, where we set the key into the ``~/.localstack/auth.json`` file that community does not
|
|
41
|
+
yet know about. ``is_api_key_configured`` is used in the LocalStack CLI to determine whether to start
|
|
42
|
+
the localstack or localstack-pro container image."""
|
|
43
|
+
from localstack_cli.utils import bootstrap
|
|
44
|
+
|
|
45
|
+
bootstrap.is_auth_token_configured = pro_config.is_auth_token_configured
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@hooks.prepare_host(priority=100, should_load=pro_config.ACTIVATE_PRO)
|
|
49
|
+
def activate_pro_key_on_host():
|
|
50
|
+
"""Activate license on host (needed for DNS forward and EC2 daemon)."""
|
|
51
|
+
try:
|
|
52
|
+
licensingv2.get_licensed_environment().activate()
|
|
53
|
+
except licensingv2.LicensingError as e:
|
|
54
|
+
raise LocalstackExit(reason=e.get_user_friendly(), code=55)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@hooks.configure_localstack_container(priority=10, should_load=pro_config.ACTIVATE_PRO)
|
|
58
|
+
def configure_pro_container(container: Container):
|
|
59
|
+
"""Configure the LocalStack container for pro features."""
|
|
60
|
+
modify_gateway_listen_config(localstack_config)
|
|
61
|
+
container.configure(licensingv2.configure_container_licensing)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@hooks.prepare_host(should_load=pro_config.ACTIVATE_PRO and pro_config.EXTENSION_DEV_MODE)
|
|
65
|
+
def configure_extensions_dev_host():
|
|
66
|
+
"""Load extension directories from ~/.localstack/extensions-dev.json."""
|
|
67
|
+
from localstack_cli.pro.core.bootstrap.extensions.bootstrap import run_on_configure_host_hook
|
|
68
|
+
|
|
69
|
+
run_on_configure_host_hook()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@hooks.configure_localstack_container(
|
|
73
|
+
should_load=pro_config.ACTIVATE_PRO and pro_config.EXTENSION_DEV_MODE
|
|
74
|
+
)
|
|
75
|
+
def configure_extensions_dev_container(container: Container):
|
|
76
|
+
"""Configure container for extension developer mode."""
|
|
77
|
+
from localstack_cli.pro.core.bootstrap.extensions.bootstrap import (
|
|
78
|
+
run_on_configure_localstack_container_hook,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
run_on_configure_localstack_container_hook(container)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
|
|
3
|
+
from plux import PluginManager, plugin
|
|
4
|
+
|
|
5
|
+
# plugin namespace constants
|
|
6
|
+
HOOKS_CONFIGURE_LOCALSTACK_CONTAINER = "localstack.hooks.configure_localstack_container"
|
|
7
|
+
HOOKS_PREPARE_HOST = "localstack.hooks.prepare_host"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def hook(namespace: str, priority: int = 0, **kwargs):
|
|
11
|
+
"""
|
|
12
|
+
Decorator for creating functional plugins that have a hook_priority attribute. Hooks with a higher priority value
|
|
13
|
+
will be executed earlier.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def wrapper(fn):
|
|
17
|
+
fn.hook_priority = priority
|
|
18
|
+
return plugin(namespace=namespace, **kwargs)(fn)
|
|
19
|
+
|
|
20
|
+
return wrapper
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def hook_spec(namespace: str):
|
|
24
|
+
"""
|
|
25
|
+
Creates a new hook decorator bound to a namespace.
|
|
26
|
+
|
|
27
|
+
on_infra_start = hook_spec("localstack.hooks.on_infra_start")
|
|
28
|
+
|
|
29
|
+
@on_infra_start()
|
|
30
|
+
def foo():
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
# run all hooks in order
|
|
34
|
+
on_infra_start.run()
|
|
35
|
+
"""
|
|
36
|
+
fn = functools.partial(hook, namespace=namespace)
|
|
37
|
+
# attach hook manager and run method to decorator for convenience calls
|
|
38
|
+
fn.manager = HookManager(namespace)
|
|
39
|
+
fn.run = fn.manager.run_in_order
|
|
40
|
+
return fn
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class HookManager(PluginManager):
|
|
44
|
+
def load_all_sorted(self, propagate_exceptions=False):
|
|
45
|
+
"""
|
|
46
|
+
Loads all hook plugins and sorts them by their hook_priority attribute.
|
|
47
|
+
"""
|
|
48
|
+
plugins = self.load_all(propagate_exceptions)
|
|
49
|
+
# the hook_priority attribute is part of the function wrapped in the FunctionPlugin
|
|
50
|
+
plugins.sort(
|
|
51
|
+
key=lambda _fn_plugin: getattr(_fn_plugin.fn, "hook_priority", 0), reverse=True
|
|
52
|
+
)
|
|
53
|
+
return plugins
|
|
54
|
+
|
|
55
|
+
def run_in_order(self, *args, **kwargs):
|
|
56
|
+
"""
|
|
57
|
+
Loads and runs all plugins in order them with the given arguments.
|
|
58
|
+
"""
|
|
59
|
+
for fn_plugin in self.load_all_sorted():
|
|
60
|
+
fn_plugin(*args, **kwargs)
|
|
61
|
+
|
|
62
|
+
def __str__(self):
|
|
63
|
+
return f"HookManager({self.namespace})"
|
|
64
|
+
|
|
65
|
+
def __repr__(self):
|
|
66
|
+
return self.__str__()
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
configure_localstack_container = hook_spec(HOOKS_CONFIGURE_LOCALSTACK_CONTAINER)
|
|
70
|
+
"""Hooks to configure the LocalStack container before it starts. Executed on the host when invoking the CLI."""
|
|
71
|
+
|
|
72
|
+
prepare_host = hook_spec(HOOKS_PREPARE_HOST)
|
|
73
|
+
"""Hooks to prepare the host that's starting LocalStack. Executed on the host when invoking the CLI."""
|