cloudsmith-cli 1.18.0__tar.gz → 1.20.0__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.
- {cloudsmith_cli-1.18.0/cloudsmith_cli.egg-info → cloudsmith_cli-1.20.0}/PKG-INFO +96 -23
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/README.md +89 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/__init__.py +1 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/cli/commands/credential_helper/__init__.py +39 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/cli/commands/credential_helper/docker.py +66 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/cli/commands/credential_helper/manage.py +299 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/mcp.py +4 -1
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/whoami.py +3 -1
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/config.py +46 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/decorators.py +117 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/utils.py +20 -1
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/validators.py +44 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/orgs.py +17 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/core/cache_utils.py +160 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/models.py +2 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/oidc/cache.py +10 -9
- cloudsmith_cli-1.20.0/cloudsmith_cli/core/credentials/oidc/detectors/__init__.py +122 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/oidc/detectors/aws.py +1 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/core/credentials/oidc/detectors/azure_devops.py +70 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/oidc/detectors/base.py +1 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/core/credentials/oidc/detectors/bitbucket_pipelines.py +35 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/core/credentials/oidc/detectors/circleci.py +40 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/core/credentials/oidc/detectors/generic.py +42 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/core/credentials/oidc/detectors/github_actions.py +64 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/core/credentials/oidc/detectors/gitlab_ci.py +49 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/download.py +1 -1
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/utils.py +1 -1
- cloudsmith_cli-1.20.0/cloudsmith_cli/credential_helpers/__init__.py +7 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/credential_helpers/backends.py +41 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/credential_helpers/common.py +111 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/credential_helpers/custom_domains.py +281 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/credential_helpers/docker/__init__.py +4 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/credential_helpers/docker/installer.py +349 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/credential_helpers/docker/runtime.py +117 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/credential_helpers/launchers.py +175 -0
- cloudsmith_cli-1.20.0/cloudsmith_cli/data/VERSION +1 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0/cloudsmith_cli.egg-info}/PKG-INFO +96 -23
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli.egg-info/SOURCES.txt +19 -45
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli.egg-info/requires.txt +3 -3
- cloudsmith_cli-1.20.0/pyproject.toml +138 -0
- cloudsmith_cli-1.20.0/setup.cfg +4 -0
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/conftest.py +0 -27
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/policy/__init__.py +0 -0
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/policy/test_deny.py +0 -175
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/policy/test_licence.py +0 -200
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/policy/test_vulnerability.py +0 -204
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_auth.py +0 -283
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_check.py +0 -73
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_download.py +0 -555
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_entitlements.py +0 -20
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_login.py +0 -30
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_logout.py +0 -147
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_main.py +0 -54
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_mcp.py +0 -581
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_metadata.py +0 -699
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_package_commands.py +0 -172
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_repos.py +0 -201
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_tokens.py +0 -187
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_upstream.py +0 -161
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands/test_vulnerabilities.py +0 -112
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/conftest.py +0 -78
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/test_metadata_common.py +0 -123
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/test_push.py +0 -1466
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/test_saml.py +0 -164
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/test_utils.py +0 -35
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/test_webserver.py +0 -159
- cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/utils.py +0 -12
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/credentials/__init__.py +0 -0
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/credentials/oidc/detectors/__init__.py +0 -42
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/mcp/__init__.py +0 -0
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/__init__.py +0 -0
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_cli_flag_provider.py +0 -46
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_credential_chain_priority.py +0 -135
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_credential_context.py +0 -30
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_credential_provider_chain.py +0 -80
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_credentials_file_provider.py +0 -47
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_download.py +0 -708
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_env_var_provider.py +0 -45
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_init.py +0 -120
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_keyring.py +0 -296
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_keyring_provider.py +0 -81
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_metadata.py +0 -605
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_rest.py +0 -67
- cloudsmith_cli-1.18.0/cloudsmith_cli/core/tests/test_version.py +0 -18
- cloudsmith_cli-1.18.0/cloudsmith_cli/data/VERSION +0 -1
- cloudsmith_cli-1.18.0/cloudsmith_cli.egg-info/not-zip-safe +0 -1
- cloudsmith_cli-1.18.0/setup.cfg +0 -40
- cloudsmith_cli-1.18.0/setup.py +0 -104
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/LICENSE +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/MANIFEST.in +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/__init__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/__main__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/__init__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/command.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/auth.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/check.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/copy.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/delete.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/dependencies.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/docs.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/download.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/entitlements.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/help_.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/list_.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/login.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/logout.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/main.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/metadata.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/metrics/__init__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/metrics/command.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/metrics/entitlements.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/metrics/packages.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/move.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/policy/__init__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/policy/command.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/policy/deny.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/policy/license.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/policy/vulnerability.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/push.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/quarantine.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/quota/__init__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/quota/command.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/quota/history.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/quota/quota.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/repos.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/resync.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/status.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/tags.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/tokens.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/upstream.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/commands/vulnerabilities.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/exceptions.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/metadata_common.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/saml.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/table.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/types.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/cli/webserver.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/__init__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/__init__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/distros.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/entitlements.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/exceptions.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/files.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/init.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/metadata.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/metrics.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/packages.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/quota.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/rates.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/repos.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/status.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/upstreams.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/user.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/version.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/api/vulnerabilities.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/config.py +0 -0
- {cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests → cloudsmith_cli-1.20.0/cloudsmith_cli/core/credentials}/__init__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/chain.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/oidc/__init__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/oidc/exchange.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/provider.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/providers/__init__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/providers/cli_flag.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/providers/credentials_file.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/providers/env_var.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/providers/keyring_provider.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/credentials/providers/oidc_provider.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/keyring.py +0 -0
- {cloudsmith_cli-1.18.0/cloudsmith_cli/cli/tests/commands → cloudsmith_cli-1.20.0/cloudsmith_cli/core/mcp}/__init__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/mcp/data.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/mcp/server.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/pagination.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/ratelimits.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/rest.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/core/version.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/data/config.ini +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/data/credentials.ini +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/templates/__init__.py +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/templates/auth_error.html +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli/templates/auth_success.html +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli.egg-info/dependency_links.txt +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli.egg-info/entry_points.txt +0 -0
- {cloudsmith_cli-1.18.0 → cloudsmith_cli-1.20.0}/cloudsmith_cli.egg-info/top_level.txt +0 -0
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cloudsmith-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.20.0
|
|
4
4
|
Summary: Cloudsmith Command-Line Interface (CLI)
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
License: Apache License 2.0
|
|
5
|
+
Author-email: Cloudsmith Ltd <support@cloudsmith.io>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/cloudsmith-io/cloudsmith-cli
|
|
9
8
|
Keywords: cloudsmith,cli,devops
|
|
10
|
-
Platform: any
|
|
11
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
12
10
|
Classifier: Environment :: Console
|
|
13
11
|
Classifier: Intended Audience :: Developers
|
|
14
12
|
Classifier: Intended Audience :: System Administrators
|
|
15
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
13
|
Classifier: Operating System :: POSIX :: Linux
|
|
17
14
|
Classifier: Programming Language :: Python
|
|
18
15
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -31,10 +28,10 @@ Requires-Dist: click-configfile>=0.2.3
|
|
|
31
28
|
Requires-Dist: click-didyoumean>=0.0.3
|
|
32
29
|
Requires-Dist: click-spinner>=0.1.7
|
|
33
30
|
Requires-Dist: json5>=0.9.0
|
|
34
|
-
Requires-Dist: cloudsmith-api<3.0,>=2.0.
|
|
31
|
+
Requires-Dist: cloudsmith-api<3.0,>=2.0.29
|
|
35
32
|
Requires-Dist: keyring>=25.4.1
|
|
36
|
-
Requires-Dist: mcp==1.
|
|
37
|
-
Requires-Dist: PyJWT>=2.0.0
|
|
33
|
+
Requires-Dist: mcp==1.27.2
|
|
34
|
+
Requires-Dist: PyJWT[crypto]>=2.0.0
|
|
38
35
|
Requires-Dist: python-toon==0.1.2
|
|
39
36
|
Requires-Dist: requests>=2.18.4
|
|
40
37
|
Requires-Dist: requests_toolbelt>=1.0.0
|
|
@@ -45,20 +42,7 @@ Provides-Extra: aws
|
|
|
45
42
|
Requires-Dist: boto3[crt]>=1.26.0; extra == "aws"
|
|
46
43
|
Provides-Extra: all
|
|
47
44
|
Requires-Dist: boto3[crt]>=1.26.0; extra == "all"
|
|
48
|
-
Dynamic: author
|
|
49
|
-
Dynamic: author-email
|
|
50
|
-
Dynamic: classifier
|
|
51
|
-
Dynamic: description
|
|
52
|
-
Dynamic: description-content-type
|
|
53
|
-
Dynamic: home-page
|
|
54
|
-
Dynamic: keywords
|
|
55
|
-
Dynamic: license
|
|
56
45
|
Dynamic: license-file
|
|
57
|
-
Dynamic: platform
|
|
58
|
-
Dynamic: provides-extra
|
|
59
|
-
Dynamic: requires-dist
|
|
60
|
-
Dynamic: requires-python
|
|
61
|
-
Dynamic: summary
|
|
62
46
|
|
|
63
47
|
# Cloudsmith Command Line Interface (CLI)
|
|
64
48
|
|
|
@@ -203,6 +187,30 @@ Or you can get the latest pre-release version from Cloudsmith:
|
|
|
203
187
|
pip install --upgrade cloudsmith-cli --extra-index-url=https://dl.cloudsmith.io/public/cloudsmith/cli/python/index/
|
|
204
188
|
```
|
|
205
189
|
|
|
190
|
+
### Standalone Binaries
|
|
191
|
+
|
|
192
|
+
Each release also ships self-contained binaries that bundle Python and all dependencies — no Python installation required. Download the archive for your platform from the [GitHub releases page](https://github.com/cloudsmith-io/cloudsmith-cli/releases) (or the [Cloudsmith CLI repository](https://cloudsmith.io/~cloudsmith/repos/cli/packages/)), verify it against the accompanying `.sha256` file, extract it, and add the extracted `cloudsmith` directory to your `PATH`:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
tar -xzf cloudsmith-<version>-<target>.tar.gz
|
|
196
|
+
./cloudsmith/cloudsmith --version
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Available targets: `linux-x86_64-gnu`, `linux-x86_64-musl`, `linux-aarch64-gnu`, `linux-aarch64-musl`, `macos-arm64`, `macos-x86_64`, and `windows-x86_64` (as a `.zip`).
|
|
200
|
+
|
|
201
|
+
Standalone binaries include all optional features, including AWS OIDC support.
|
|
202
|
+
|
|
203
|
+
#### Verifying Linux binaries
|
|
204
|
+
|
|
205
|
+
The four Linux archives (`linux-x86_64-gnu`, `linux-x86_64-musl`, `linux-aarch64-gnu`, `linux-aarch64-musl`) are GPG-signed with a detached binary signature published alongside each archive as `<archive>.sig`. To verify, import the Cloudsmith CLI release public key (`cloudsmith-cli-release-key.asc`, attached to each GitHub release) and check the signature:
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
gpg --import cloudsmith-cli-release-key.asc
|
|
209
|
+
gpg --verify cloudsmith-<version>-linux-x86_64-gnu.tar.gz.sig cloudsmith-<version>-linux-x86_64-gnu.tar.gz
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
A successful verification reports a good signature from the Cloudsmith CLI release key. (The macOS and Windows binaries are not GPG-signed; native signing for those platforms is tracked separately.)
|
|
213
|
+
|
|
206
214
|
### Optional Dependencies
|
|
207
215
|
|
|
208
216
|
The CLI supports optional extras for additional functionality:
|
|
@@ -227,6 +235,71 @@ pip install cloudsmith-cli[all]
|
|
|
227
235
|
|
|
228
236
|
**Note:** If you don't install the AWS extra, the AWS OIDC detector will gracefully skip itself with no errors.
|
|
229
237
|
|
|
238
|
+
#### Bitbucket Pipelines OIDC Support
|
|
239
|
+
|
|
240
|
+
In Bitbucket Pipelines, OIDC credential discovery works out of the box with no extra dependencies. Set `oidc: true` on the pipeline step and the CLI reads the token from the `BITBUCKET_STEP_OIDC_TOKEN` variable that Bitbucket populates. The Cloudsmith OIDC provider must expect the workspace audience that Bitbucket mints (`ari:cloud:bitbucket::workspace/<workspace-uuid>`):
|
|
241
|
+
|
|
242
|
+
```yaml
|
|
243
|
+
pipelines:
|
|
244
|
+
default:
|
|
245
|
+
- step:
|
|
246
|
+
oidc: true
|
|
247
|
+
script:
|
|
248
|
+
- cloudsmith push ...
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
See the [Bitbucket Pipelines OIDC documentation](https://support.atlassian.com/bitbucket-cloud/docs/integrate-pipelines-with-resource-servers-using-oidc/).
|
|
252
|
+
|
|
253
|
+
#### CircleCI OIDC Support
|
|
254
|
+
|
|
255
|
+
In CircleCI, OIDC credential discovery works out of the box with no extra dependencies — the CLI reads the token from the `CIRCLE_OIDC_TOKEN_V2` (preferred) or `CIRCLE_OIDC_TOKEN` environment variable that CircleCI injects into every job. The Cloudsmith OIDC provider must expect the audience CircleCI mints, which is your CircleCI organization UUID. See the [Cloudsmith CircleCI integration guide](https://docs.cloudsmith.com/integrations/integrating-with-circleci).
|
|
256
|
+
|
|
257
|
+
#### Azure DevOps OIDC Support
|
|
258
|
+
|
|
259
|
+
In Azure DevOps Pipelines, OIDC credential discovery works out of the box with no extra dependencies — the CLI fetches an OIDC token from the `SYSTEM_OIDCREQUESTURI` endpoint using the pipeline's `SYSTEM_ACCESSTOKEN`. Make sure `SYSTEM_ACCESSTOKEN` is mapped into the step's environment. The Cloudsmith OIDC provider must expect the audience `api://AzureADTokenExchange`, which Azure DevOps always mints (any requested audience is ignored). See the [Cloudsmith Azure DevOps integration guide](https://docs.cloudsmith.com/integrations/integrating-with-azure-devops).
|
|
260
|
+
|
|
261
|
+
#### GitHub Actions OIDC Support
|
|
262
|
+
|
|
263
|
+
In GitHub Actions, OIDC credential discovery works out of the box with no extra dependencies — the CLI fetches an OIDC token from the Actions runtime when the workflow requests `id-token: write` permission. See the [Cloudsmith GitHub Actions OIDC guide](https://docs.cloudsmith.com/authentication/setup-cloudsmith-to-authenticate-with-oidc-in-github-actions).
|
|
264
|
+
|
|
265
|
+
#### GitLab CI OIDC Support
|
|
266
|
+
|
|
267
|
+
In GitLab CI/CD, OIDC credential discovery works out of the box with no extra dependencies. Configure an [`id_tokens`](https://docs.gitlab.com/ci/cloud_services/) entry in your `.gitlab-ci.yml` with an `aud` of `https://api.cloudsmith.io/openid/<your-org>` and expose it as `CLOUDSMITH_OIDC_TOKEN`, and the CLI will pick it up automatically:
|
|
268
|
+
|
|
269
|
+
```yaml
|
|
270
|
+
job:
|
|
271
|
+
id_tokens:
|
|
272
|
+
CLOUDSMITH_OIDC_TOKEN:
|
|
273
|
+
aud: https://api.cloudsmith.io/openid/<your-org>
|
|
274
|
+
script:
|
|
275
|
+
- cloudsmith push ...
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
See the [Cloudsmith GitLab CI/CD integration guide](https://docs.cloudsmith.com/integrations/integrating-with-gitlab-cicd).
|
|
279
|
+
|
|
280
|
+
#### Generic OIDC Support (Jenkins, custom CI/CD)
|
|
281
|
+
|
|
282
|
+
As a fallback for environments without a dedicated detector (for example Jenkins with the [credentials binding plugin](https://plugins.jenkins.io/credentials-binding/), or any custom CI/CD system), set the `CLOUDSMITH_OIDC_TOKEN` environment variable to an OIDC JWT and the CLI will exchange it for a Cloudsmith access token. This detector runs last, so a dedicated environment is always preferred when present. See the [Cloudsmith Jenkins OIDC guide](https://docs.cloudsmith.com/authentication/setup-jenkins-to-authenticate-to-cloudsmith-using-oidc).
|
|
283
|
+
|
|
284
|
+
#### Controlling OIDC Detector Selection
|
|
285
|
+
|
|
286
|
+
By default the CLI tries each detector in a fixed priority order and uses the first that matches. Two controls let you override this when a detector matches an environment you don't want it to (for example, the AWS detector matching ambient instance credentials):
|
|
287
|
+
|
|
288
|
+
- **Disable a detector** — set `CLOUDSMITH_OIDC_<DETECTOR>_DISABLED=true` to skip it entirely. Only the literal value `true` (case-insensitive) disables; anything else leaves the detector enabled. For example, `CLOUDSMITH_OIDC_AWS_DISABLED=true` skips the AWS detector so an explicitly-set `CLOUDSMITH_OIDC_TOKEN` is picked up by the generic detector instead.
|
|
289
|
+
- **Reorder evaluation** — use `--oidc-detector-order` (or the `CLOUDSMITH_OIDC_DETECTOR_ORDER` environment variable) with a comma-separated list of detector ids to control both which detectors are considered and the order they are tried in (first match wins). Ids not listed are skipped; unrecognised ids are ignored with a warning. For example, `--oidc-detector-order=generic,aws` tries the generic detector first and considers only those two.
|
|
290
|
+
|
|
291
|
+
When both are set, the order list defines the candidate set and sequence, then the `*_DISABLED` flags are applied on top — so a disabled detector is always skipped even if it appears in the order list. Detector ids are: `aws`, `azure_devops`, `bitbucket`, `circleci`, `generic`, `github`, `gitlab`.
|
|
292
|
+
|
|
293
|
+
Both controls can also be set in `config.ini`, under `[default]` or a profile section:
|
|
294
|
+
|
|
295
|
+
```ini
|
|
296
|
+
[default]
|
|
297
|
+
oidc_detector_order = github, aws
|
|
298
|
+
oidc_disabled_detectors = aws, gitlab
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
The `--oidc-detector-order` flag (or the `CLOUDSMITH_OIDC_DETECTOR_ORDER` environment variable) overrides the `oidc_detector_order` config value. The `oidc_disabled_detectors` config key is additive with the per-detector `CLOUDSMITH_OIDC_<DETECTOR>_DISABLED` environment variables — a detector disabled by either is skipped.
|
|
302
|
+
|
|
230
303
|
## Configuration
|
|
231
304
|
|
|
232
305
|
There are two configuration files used by the CLI:
|
|
@@ -141,6 +141,30 @@ Or you can get the latest pre-release version from Cloudsmith:
|
|
|
141
141
|
pip install --upgrade cloudsmith-cli --extra-index-url=https://dl.cloudsmith.io/public/cloudsmith/cli/python/index/
|
|
142
142
|
```
|
|
143
143
|
|
|
144
|
+
### Standalone Binaries
|
|
145
|
+
|
|
146
|
+
Each release also ships self-contained binaries that bundle Python and all dependencies — no Python installation required. Download the archive for your platform from the [GitHub releases page](https://github.com/cloudsmith-io/cloudsmith-cli/releases) (or the [Cloudsmith CLI repository](https://cloudsmith.io/~cloudsmith/repos/cli/packages/)), verify it against the accompanying `.sha256` file, extract it, and add the extracted `cloudsmith` directory to your `PATH`:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
tar -xzf cloudsmith-<version>-<target>.tar.gz
|
|
150
|
+
./cloudsmith/cloudsmith --version
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Available targets: `linux-x86_64-gnu`, `linux-x86_64-musl`, `linux-aarch64-gnu`, `linux-aarch64-musl`, `macos-arm64`, `macos-x86_64`, and `windows-x86_64` (as a `.zip`).
|
|
154
|
+
|
|
155
|
+
Standalone binaries include all optional features, including AWS OIDC support.
|
|
156
|
+
|
|
157
|
+
#### Verifying Linux binaries
|
|
158
|
+
|
|
159
|
+
The four Linux archives (`linux-x86_64-gnu`, `linux-x86_64-musl`, `linux-aarch64-gnu`, `linux-aarch64-musl`) are GPG-signed with a detached binary signature published alongside each archive as `<archive>.sig`. To verify, import the Cloudsmith CLI release public key (`cloudsmith-cli-release-key.asc`, attached to each GitHub release) and check the signature:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
gpg --import cloudsmith-cli-release-key.asc
|
|
163
|
+
gpg --verify cloudsmith-<version>-linux-x86_64-gnu.tar.gz.sig cloudsmith-<version>-linux-x86_64-gnu.tar.gz
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
A successful verification reports a good signature from the Cloudsmith CLI release key. (The macOS and Windows binaries are not GPG-signed; native signing for those platforms is tracked separately.)
|
|
167
|
+
|
|
144
168
|
### Optional Dependencies
|
|
145
169
|
|
|
146
170
|
The CLI supports optional extras for additional functionality:
|
|
@@ -165,6 +189,71 @@ pip install cloudsmith-cli[all]
|
|
|
165
189
|
|
|
166
190
|
**Note:** If you don't install the AWS extra, the AWS OIDC detector will gracefully skip itself with no errors.
|
|
167
191
|
|
|
192
|
+
#### Bitbucket Pipelines OIDC Support
|
|
193
|
+
|
|
194
|
+
In Bitbucket Pipelines, OIDC credential discovery works out of the box with no extra dependencies. Set `oidc: true` on the pipeline step and the CLI reads the token from the `BITBUCKET_STEP_OIDC_TOKEN` variable that Bitbucket populates. The Cloudsmith OIDC provider must expect the workspace audience that Bitbucket mints (`ari:cloud:bitbucket::workspace/<workspace-uuid>`):
|
|
195
|
+
|
|
196
|
+
```yaml
|
|
197
|
+
pipelines:
|
|
198
|
+
default:
|
|
199
|
+
- step:
|
|
200
|
+
oidc: true
|
|
201
|
+
script:
|
|
202
|
+
- cloudsmith push ...
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
See the [Bitbucket Pipelines OIDC documentation](https://support.atlassian.com/bitbucket-cloud/docs/integrate-pipelines-with-resource-servers-using-oidc/).
|
|
206
|
+
|
|
207
|
+
#### CircleCI OIDC Support
|
|
208
|
+
|
|
209
|
+
In CircleCI, OIDC credential discovery works out of the box with no extra dependencies — the CLI reads the token from the `CIRCLE_OIDC_TOKEN_V2` (preferred) or `CIRCLE_OIDC_TOKEN` environment variable that CircleCI injects into every job. The Cloudsmith OIDC provider must expect the audience CircleCI mints, which is your CircleCI organization UUID. See the [Cloudsmith CircleCI integration guide](https://docs.cloudsmith.com/integrations/integrating-with-circleci).
|
|
210
|
+
|
|
211
|
+
#### Azure DevOps OIDC Support
|
|
212
|
+
|
|
213
|
+
In Azure DevOps Pipelines, OIDC credential discovery works out of the box with no extra dependencies — the CLI fetches an OIDC token from the `SYSTEM_OIDCREQUESTURI` endpoint using the pipeline's `SYSTEM_ACCESSTOKEN`. Make sure `SYSTEM_ACCESSTOKEN` is mapped into the step's environment. The Cloudsmith OIDC provider must expect the audience `api://AzureADTokenExchange`, which Azure DevOps always mints (any requested audience is ignored). See the [Cloudsmith Azure DevOps integration guide](https://docs.cloudsmith.com/integrations/integrating-with-azure-devops).
|
|
214
|
+
|
|
215
|
+
#### GitHub Actions OIDC Support
|
|
216
|
+
|
|
217
|
+
In GitHub Actions, OIDC credential discovery works out of the box with no extra dependencies — the CLI fetches an OIDC token from the Actions runtime when the workflow requests `id-token: write` permission. See the [Cloudsmith GitHub Actions OIDC guide](https://docs.cloudsmith.com/authentication/setup-cloudsmith-to-authenticate-with-oidc-in-github-actions).
|
|
218
|
+
|
|
219
|
+
#### GitLab CI OIDC Support
|
|
220
|
+
|
|
221
|
+
In GitLab CI/CD, OIDC credential discovery works out of the box with no extra dependencies. Configure an [`id_tokens`](https://docs.gitlab.com/ci/cloud_services/) entry in your `.gitlab-ci.yml` with an `aud` of `https://api.cloudsmith.io/openid/<your-org>` and expose it as `CLOUDSMITH_OIDC_TOKEN`, and the CLI will pick it up automatically:
|
|
222
|
+
|
|
223
|
+
```yaml
|
|
224
|
+
job:
|
|
225
|
+
id_tokens:
|
|
226
|
+
CLOUDSMITH_OIDC_TOKEN:
|
|
227
|
+
aud: https://api.cloudsmith.io/openid/<your-org>
|
|
228
|
+
script:
|
|
229
|
+
- cloudsmith push ...
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
See the [Cloudsmith GitLab CI/CD integration guide](https://docs.cloudsmith.com/integrations/integrating-with-gitlab-cicd).
|
|
233
|
+
|
|
234
|
+
#### Generic OIDC Support (Jenkins, custom CI/CD)
|
|
235
|
+
|
|
236
|
+
As a fallback for environments without a dedicated detector (for example Jenkins with the [credentials binding plugin](https://plugins.jenkins.io/credentials-binding/), or any custom CI/CD system), set the `CLOUDSMITH_OIDC_TOKEN` environment variable to an OIDC JWT and the CLI will exchange it for a Cloudsmith access token. This detector runs last, so a dedicated environment is always preferred when present. See the [Cloudsmith Jenkins OIDC guide](https://docs.cloudsmith.com/authentication/setup-jenkins-to-authenticate-to-cloudsmith-using-oidc).
|
|
237
|
+
|
|
238
|
+
#### Controlling OIDC Detector Selection
|
|
239
|
+
|
|
240
|
+
By default the CLI tries each detector in a fixed priority order and uses the first that matches. Two controls let you override this when a detector matches an environment you don't want it to (for example, the AWS detector matching ambient instance credentials):
|
|
241
|
+
|
|
242
|
+
- **Disable a detector** — set `CLOUDSMITH_OIDC_<DETECTOR>_DISABLED=true` to skip it entirely. Only the literal value `true` (case-insensitive) disables; anything else leaves the detector enabled. For example, `CLOUDSMITH_OIDC_AWS_DISABLED=true` skips the AWS detector so an explicitly-set `CLOUDSMITH_OIDC_TOKEN` is picked up by the generic detector instead.
|
|
243
|
+
- **Reorder evaluation** — use `--oidc-detector-order` (or the `CLOUDSMITH_OIDC_DETECTOR_ORDER` environment variable) with a comma-separated list of detector ids to control both which detectors are considered and the order they are tried in (first match wins). Ids not listed are skipped; unrecognised ids are ignored with a warning. For example, `--oidc-detector-order=generic,aws` tries the generic detector first and considers only those two.
|
|
244
|
+
|
|
245
|
+
When both are set, the order list defines the candidate set and sequence, then the `*_DISABLED` flags are applied on top — so a disabled detector is always skipped even if it appears in the order list. Detector ids are: `aws`, `azure_devops`, `bitbucket`, `circleci`, `generic`, `github`, `gitlab`.
|
|
246
|
+
|
|
247
|
+
Both controls can also be set in `config.ini`, under `[default]` or a profile section:
|
|
248
|
+
|
|
249
|
+
```ini
|
|
250
|
+
[default]
|
|
251
|
+
oidc_detector_order = github, aws
|
|
252
|
+
oidc_disabled_detectors = aws, gitlab
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
The `--oidc-detector-order` flag (or the `CLOUDSMITH_OIDC_DETECTOR_ORDER` environment variable) overrides the `oidc_detector_order` config value. The `oidc_disabled_detectors` config key is additive with the per-detector `CLOUDSMITH_OIDC_<DETECTOR>_DISABLED` environment variables — a detector disabled by either is skipped.
|
|
256
|
+
|
|
168
257
|
## Configuration
|
|
169
258
|
|
|
170
259
|
There are two configuration files used by the CLI:
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Copyright 2026 Cloudsmith Ltd
|
|
2
|
+
"""
|
|
3
|
+
Credential helper commands for Cloudsmith.
|
|
4
|
+
|
|
5
|
+
This module provides credential helper commands for package managers
|
|
6
|
+
that follow their respective credential helper protocols.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import click
|
|
10
|
+
|
|
11
|
+
from ..main import main
|
|
12
|
+
from .docker import docker as docker_cmd
|
|
13
|
+
from .manage import install_cmd, list_cmd, uninstall_cmd
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@click.group()
|
|
17
|
+
def credential_helper():
|
|
18
|
+
"""
|
|
19
|
+
Credential helpers for package managers.
|
|
20
|
+
|
|
21
|
+
These commands provide credentials for package managers like Docker.
|
|
22
|
+
Use ``install`` to set up the on-PATH launcher and configure the package
|
|
23
|
+
manager automatically, or run the runtime command directly for debugging.
|
|
24
|
+
|
|
25
|
+
Examples:
|
|
26
|
+
# Install Docker credential helper
|
|
27
|
+
$ cloudsmith credential-helper install docker
|
|
28
|
+
|
|
29
|
+
# Test Docker credential helper directly
|
|
30
|
+
$ echo "docker.cloudsmith.io" | cloudsmith credential-helper docker
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
credential_helper.add_command(docker_cmd, name="docker")
|
|
35
|
+
credential_helper.add_command(install_cmd, name="install")
|
|
36
|
+
credential_helper.add_command(uninstall_cmd, name="uninstall")
|
|
37
|
+
credential_helper.add_command(list_cmd, name="list")
|
|
38
|
+
|
|
39
|
+
main.add_command(credential_helper, name="credential-helper")
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Copyright 2026 Cloudsmith Ltd
|
|
2
|
+
"""
|
|
3
|
+
Docker credential helper command.
|
|
4
|
+
|
|
5
|
+
Implements the Docker credential helper protocol for Cloudsmith registries.
|
|
6
|
+
|
|
7
|
+
See: https://github.com/docker/docker-credential-helpers
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
import click
|
|
13
|
+
|
|
14
|
+
from ....credential_helpers.docker import execute
|
|
15
|
+
from ...decorators import common_api_auth_options, resolve_credentials
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@click.command()
|
|
19
|
+
@click.argument("operation", required=False, default="get")
|
|
20
|
+
@common_api_auth_options
|
|
21
|
+
@resolve_credentials
|
|
22
|
+
def docker(opts, operation):
|
|
23
|
+
"""
|
|
24
|
+
Docker credential helper for Cloudsmith registries.
|
|
25
|
+
|
|
26
|
+
Reads a Docker registry server URL from stdin and returns credentials in
|
|
27
|
+
JSON format. Implements the full Docker credential helper protocol
|
|
28
|
+
(get/store/erase/list).
|
|
29
|
+
|
|
30
|
+
Provides credentials for all Cloudsmith Docker registries: ``*.cloudsmith.io``,
|
|
31
|
+
``*.cloudsmith.com``, and any custom domains configured for the organisation
|
|
32
|
+
(requires CLOUDSMITH_ORG and a valid API key/token).
|
|
33
|
+
|
|
34
|
+
Input (stdin):
|
|
35
|
+
Server URL as plain text (e.g. "docker.cloudsmith.io")
|
|
36
|
+
|
|
37
|
+
Output (stdout):
|
|
38
|
+
JSON: {"Username": "token", "Secret": "<cloudsmith-token>"}
|
|
39
|
+
|
|
40
|
+
Exit codes:
|
|
41
|
+
0: Success
|
|
42
|
+
1: Error (no credentials available, not a Cloudsmith registry, etc.)
|
|
43
|
+
|
|
44
|
+
Examples:
|
|
45
|
+
# Manual testing
|
|
46
|
+
$ echo "docker.cloudsmith.io" | cloudsmith credential-helper docker
|
|
47
|
+
|
|
48
|
+
# Called by Docker via launcher
|
|
49
|
+
$ echo "docker.cloudsmith.io" | docker-credential-cloudsmith get
|
|
50
|
+
|
|
51
|
+
Environment variables:
|
|
52
|
+
CLOUDSMITH_API_KEY: API key for authentication (optional)
|
|
53
|
+
CLOUDSMITH_ORG: Organisation slug (required for custom domain support)
|
|
54
|
+
"""
|
|
55
|
+
exit_code, stdout, stderr = execute(
|
|
56
|
+
operation,
|
|
57
|
+
sys.stdin,
|
|
58
|
+
credential=opts.credential,
|
|
59
|
+
api_host=opts.api_host,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
if stdout is not None:
|
|
63
|
+
click.echo(stdout)
|
|
64
|
+
if stderr is not None:
|
|
65
|
+
click.echo(stderr, err=True)
|
|
66
|
+
sys.exit(exit_code)
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# Copyright 2026 Cloudsmith Ltd
|
|
2
|
+
"""Install/uninstall/list commands for credential helpers.
|
|
3
|
+
|
|
4
|
+
Provides ``credential-helper install``, ``credential-helper uninstall``, and
|
|
5
|
+
``credential-helper list`` to manage the on-PATH launcher binary and the
|
|
6
|
+
``config.json`` entries for each supported credential helper.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
|
|
14
|
+
import click
|
|
15
|
+
|
|
16
|
+
from ....credential_helpers.docker.installer import DockerInstaller
|
|
17
|
+
from ... import utils
|
|
18
|
+
from ...decorators import (
|
|
19
|
+
common_api_auth_options,
|
|
20
|
+
common_cli_config_options,
|
|
21
|
+
common_cli_output_options,
|
|
22
|
+
resolve_credentials,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
# ---------------------------------------------------------------------------
|
|
26
|
+
# Helper registry — extend here when new helpers are added
|
|
27
|
+
# ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
_INSTALLERS: dict[str, type] = {
|
|
30
|
+
"docker": DockerInstaller,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _get_installer(name: str):
|
|
35
|
+
"""Return an instantiated installer for *name*, or exit with a clear error.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
name:
|
|
40
|
+
The helper name as supplied by the user (e.g. ``"docker"``).
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
DockerInstaller
|
|
45
|
+
An instance of the appropriate installer class.
|
|
46
|
+
|
|
47
|
+
Raises
|
|
48
|
+
------
|
|
49
|
+
SystemExit
|
|
50
|
+
If *name* is not in :data:`_INSTALLERS`.
|
|
51
|
+
"""
|
|
52
|
+
cls = _INSTALLERS.get(name)
|
|
53
|
+
if cls is None:
|
|
54
|
+
available = ", ".join(sorted(_INSTALLERS))
|
|
55
|
+
click.echo(
|
|
56
|
+
f"Error: unknown helper {name!r}. Available helpers: {available}",
|
|
57
|
+
err=True,
|
|
58
|
+
)
|
|
59
|
+
sys.exit(1)
|
|
60
|
+
return cls()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# ---------------------------------------------------------------------------
|
|
64
|
+
# install
|
|
65
|
+
# ---------------------------------------------------------------------------
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@click.command("install")
|
|
69
|
+
@click.argument("helper")
|
|
70
|
+
@click.option(
|
|
71
|
+
"--bin-dir", default=None, help="Directory to install the launcher binary."
|
|
72
|
+
)
|
|
73
|
+
@click.option(
|
|
74
|
+
"--domain",
|
|
75
|
+
"domains",
|
|
76
|
+
multiple=True,
|
|
77
|
+
help="Additional registry hostname to configure (repeatable).",
|
|
78
|
+
)
|
|
79
|
+
@click.option(
|
|
80
|
+
"--dry-run",
|
|
81
|
+
is_flag=True,
|
|
82
|
+
default=False,
|
|
83
|
+
help="Show what would be done without making any changes.",
|
|
84
|
+
)
|
|
85
|
+
@click.option(
|
|
86
|
+
"--no-discover",
|
|
87
|
+
is_flag=True,
|
|
88
|
+
default=False,
|
|
89
|
+
help="Disable automatic discovery of custom Docker domains.",
|
|
90
|
+
)
|
|
91
|
+
@click.option(
|
|
92
|
+
"--refresh",
|
|
93
|
+
is_flag=True,
|
|
94
|
+
default=False,
|
|
95
|
+
help="Bypass the custom-domain cache and fetch fresh data from the API.",
|
|
96
|
+
)
|
|
97
|
+
@click.option(
|
|
98
|
+
"--org",
|
|
99
|
+
default=None,
|
|
100
|
+
help="Cloudsmith organisation slug for custom-domain discovery.",
|
|
101
|
+
)
|
|
102
|
+
@common_cli_config_options
|
|
103
|
+
@common_cli_output_options
|
|
104
|
+
@common_api_auth_options
|
|
105
|
+
@resolve_credentials
|
|
106
|
+
@click.pass_context
|
|
107
|
+
def install_cmd(
|
|
108
|
+
ctx,
|
|
109
|
+
opts,
|
|
110
|
+
helper: str,
|
|
111
|
+
bin_dir: str | None,
|
|
112
|
+
domains: tuple[str, ...],
|
|
113
|
+
dry_run: bool,
|
|
114
|
+
no_discover: bool,
|
|
115
|
+
refresh: bool,
|
|
116
|
+
org: str | None,
|
|
117
|
+
) -> None:
|
|
118
|
+
"""Install a credential helper launcher and configure the package manager.
|
|
119
|
+
|
|
120
|
+
HELPER is the name of the credential helper to install (e.g. ``docker``).
|
|
121
|
+
|
|
122
|
+
Examples:
|
|
123
|
+
|
|
124
|
+
\b
|
|
125
|
+
# Install Docker credential helper
|
|
126
|
+
$ cloudsmith credential-helper install docker
|
|
127
|
+
|
|
128
|
+
\b
|
|
129
|
+
# Install with a custom domain
|
|
130
|
+
$ cloudsmith credential-helper install docker --domain my.registry.example.com
|
|
131
|
+
|
|
132
|
+
\b
|
|
133
|
+
# Preview without making changes
|
|
134
|
+
$ cloudsmith credential-helper install docker --dry-run
|
|
135
|
+
|
|
136
|
+
\b
|
|
137
|
+
# Disable automatic custom-domain discovery
|
|
138
|
+
$ cloudsmith credential-helper install docker --no-discover
|
|
139
|
+
"""
|
|
140
|
+
installer = _get_installer(helper)
|
|
141
|
+
org = org or os.environ.get("CLOUDSMITH_ORG", "").strip() or None
|
|
142
|
+
api_key = opts.credential.api_key if opts.credential else None
|
|
143
|
+
auth_type = (
|
|
144
|
+
getattr(opts.credential, "auth_type", "api_key")
|
|
145
|
+
if opts.credential
|
|
146
|
+
else "api_key"
|
|
147
|
+
)
|
|
148
|
+
try:
|
|
149
|
+
actions = installer.install(
|
|
150
|
+
bin_dir=bin_dir,
|
|
151
|
+
domains=domains,
|
|
152
|
+
dry_run=dry_run,
|
|
153
|
+
discover=not no_discover,
|
|
154
|
+
refresh=refresh,
|
|
155
|
+
org=org,
|
|
156
|
+
api_key=api_key,
|
|
157
|
+
auth_type=auth_type,
|
|
158
|
+
api_host=opts.api_host,
|
|
159
|
+
)
|
|
160
|
+
except OSError as exc:
|
|
161
|
+
raise click.ClickException(
|
|
162
|
+
f"Failed to install {helper!r} credential helper: {exc}"
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
166
|
+
warnings = [a for a in actions if a.startswith("WARNING")]
|
|
167
|
+
normal = [a for a in actions if not a.startswith("WARNING")]
|
|
168
|
+
data = {
|
|
169
|
+
"helper": helper,
|
|
170
|
+
"dry_run": dry_run,
|
|
171
|
+
"actions": normal,
|
|
172
|
+
"warnings": warnings,
|
|
173
|
+
}
|
|
174
|
+
if utils.maybe_print_as_json(opts, data):
|
|
175
|
+
return
|
|
176
|
+
|
|
177
|
+
if dry_run:
|
|
178
|
+
click.echo("Dry run — no changes will be made:", err=use_stderr)
|
|
179
|
+
for action in normal:
|
|
180
|
+
click.echo(f" {action}" if dry_run else action, err=use_stderr)
|
|
181
|
+
for warning in warnings:
|
|
182
|
+
click.secho(f" {warning}" if dry_run else warning, err=True, fg="yellow")
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# ---------------------------------------------------------------------------
|
|
186
|
+
# uninstall
|
|
187
|
+
# ---------------------------------------------------------------------------
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
@click.command("uninstall")
|
|
191
|
+
@click.argument("helper")
|
|
192
|
+
@click.option(
|
|
193
|
+
"--bin-dir", default=None, help="Directory where the launcher binary was installed."
|
|
194
|
+
)
|
|
195
|
+
@click.option(
|
|
196
|
+
"--dry-run",
|
|
197
|
+
is_flag=True,
|
|
198
|
+
default=False,
|
|
199
|
+
help="Show what would be done without making any changes.",
|
|
200
|
+
)
|
|
201
|
+
@common_cli_config_options
|
|
202
|
+
@common_cli_output_options
|
|
203
|
+
@click.pass_context
|
|
204
|
+
def uninstall_cmd(ctx, opts, helper: str, bin_dir: str | None, dry_run: bool) -> None:
|
|
205
|
+
"""Uninstall a credential helper launcher and remove its config entries.
|
|
206
|
+
|
|
207
|
+
HELPER is the name of the credential helper to uninstall (e.g. ``docker``).
|
|
208
|
+
|
|
209
|
+
Examples:
|
|
210
|
+
|
|
211
|
+
\b
|
|
212
|
+
# Uninstall Docker credential helper
|
|
213
|
+
$ cloudsmith credential-helper uninstall docker
|
|
214
|
+
|
|
215
|
+
\b
|
|
216
|
+
# Preview without making changes
|
|
217
|
+
$ cloudsmith credential-helper uninstall docker --dry-run
|
|
218
|
+
"""
|
|
219
|
+
installer = _get_installer(helper)
|
|
220
|
+
try:
|
|
221
|
+
actions = installer.uninstall(bin_dir=bin_dir, dry_run=dry_run)
|
|
222
|
+
except OSError as exc:
|
|
223
|
+
raise click.ClickException(
|
|
224
|
+
f"Failed to uninstall {helper!r} credential helper: {exc}"
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
228
|
+
warnings = [a for a in actions if a.startswith("WARNING")]
|
|
229
|
+
normal = [a for a in actions if not a.startswith("WARNING")]
|
|
230
|
+
data = {
|
|
231
|
+
"helper": helper,
|
|
232
|
+
"dry_run": dry_run,
|
|
233
|
+
"actions": normal,
|
|
234
|
+
"warnings": warnings,
|
|
235
|
+
}
|
|
236
|
+
if utils.maybe_print_as_json(opts, data):
|
|
237
|
+
return
|
|
238
|
+
|
|
239
|
+
if dry_run:
|
|
240
|
+
click.echo("Dry run — no changes will be made:", err=use_stderr)
|
|
241
|
+
for action in normal:
|
|
242
|
+
click.echo(f" {action}" if dry_run else action, err=use_stderr)
|
|
243
|
+
for warning in warnings:
|
|
244
|
+
click.secho(f" {warning}" if dry_run else warning, err=True, fg="yellow")
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
# ---------------------------------------------------------------------------
|
|
248
|
+
# list
|
|
249
|
+
# ---------------------------------------------------------------------------
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
@click.command("list")
|
|
253
|
+
@common_cli_config_options
|
|
254
|
+
@common_cli_output_options
|
|
255
|
+
@click.pass_context
|
|
256
|
+
def list_cmd(ctx, opts) -> None:
|
|
257
|
+
"""List available credential helpers and their installation status.
|
|
258
|
+
|
|
259
|
+
Shows which helpers are available, whether their launcher binary is
|
|
260
|
+
present on PATH, and which registry hosts they are configured for.
|
|
261
|
+
|
|
262
|
+
Example:
|
|
263
|
+
|
|
264
|
+
\b
|
|
265
|
+
$ cloudsmith credential-helper list
|
|
266
|
+
"""
|
|
267
|
+
use_stderr = utils.should_use_stderr(opts)
|
|
268
|
+
|
|
269
|
+
data = []
|
|
270
|
+
for name, cls in sorted(_INSTALLERS.items()):
|
|
271
|
+
installer = cls()
|
|
272
|
+
st = installer.status()
|
|
273
|
+
data.append(
|
|
274
|
+
{
|
|
275
|
+
"helper": name,
|
|
276
|
+
"summary": installer.summary,
|
|
277
|
+
"launcher": st.get("launcher"),
|
|
278
|
+
"hosts": st.get("hosts", []),
|
|
279
|
+
}
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
if utils.maybe_print_as_json(opts, data):
|
|
283
|
+
return
|
|
284
|
+
|
|
285
|
+
for entry in data:
|
|
286
|
+
name = entry["helper"]
|
|
287
|
+
launcher = entry["launcher"]
|
|
288
|
+
hosts = entry["hosts"]
|
|
289
|
+
summary = entry["summary"]
|
|
290
|
+
|
|
291
|
+
click.echo(f"{name} ({summary})", err=use_stderr)
|
|
292
|
+
if launcher:
|
|
293
|
+
click.echo(f" launcher : {launcher}", err=use_stderr)
|
|
294
|
+
else:
|
|
295
|
+
click.echo(" launcher : not installed", err=use_stderr)
|
|
296
|
+
if hosts:
|
|
297
|
+
click.echo(f" hosts : {', '.join(hosts)}", err=use_stderr)
|
|
298
|
+
else:
|
|
299
|
+
click.echo(" hosts : none configured", err=use_stderr)
|