bt-cli 0.4.46__tar.gz → 0.4.47__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.
- {bt_cli-0.4.46 → bt_cli-0.4.47}/CLAUDE.md +1 -1
- {bt_cli-0.4.46 → bt_cli-0.4.47}/PKG-INFO +3 -3
- {bt_cli-0.4.46 → bt_cli-0.4.47}/README.md +2 -2
- {bt_cli-0.4.46 → bt_cli-0.4.47}/pyproject.toml +1 -1
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/__init__.py +1 -1
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/data/skills/secrets/SKILL.md +19 -8
- bt_cli-0.4.47/src/bt_cli/secrets/commands/_hints.py +30 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/secrets/commands/dynamic.py +8 -2
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/secrets/commands/folders.py +8 -2
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/secrets/commands/static.py +8 -2
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/secrets/test_commands.py +43 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/.claude/skills/bt/SKILL.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/.claude/skills/entitle/SKILL.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/.claude/skills/epml/SKILL.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/.claude/skills/epmw/SKILL.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/.claude/skills/pra/SKILL.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/.claude/skills/pws/SKILL.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/.env.example +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/.github/workflows/ci.yml +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/.github/workflows/release.yml +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/.gitignore +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/assets/cli-help.png +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/assets/cli-output.png +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/bt-cli.spec +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/bt_entry.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/epml-clients-server-side-filters-plan.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/epml-implementation-plan.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/pf-implementation-plan.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/scripts/bt_entry.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/scripts/pf_onboard.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/scripts/sync-package-data.sh +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/cli.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/commands/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/commands/configure.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/commands/learn.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/commands/quick.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/core/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/core/auth.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/core/client.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/core/config.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/core/config_file.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/core/csv_utils.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/core/errors.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/core/output.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/core/prompts.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/core/rest_debug.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/data/CLAUDE.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/data/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/data/skills/bt/SKILL.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/data/skills/entitle/SKILL.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/data/skills/epml/SKILL.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/data/skills/epmw/SKILL.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/data/skills/pra/SKILL.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/data/skills/pws/SKILL.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/client/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/client/base.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/accounts.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/applications.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/auth.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/bundles.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/integrations.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/permissions.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/policies.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/requests.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/resources.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/roles.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/users.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/commands/workflows.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/models/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/models/bundle.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/models/common.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/models/integration.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/models/permission.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/models/policy.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/models/resource.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/models/role.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/models/user.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/entitle/models/workflow.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/client/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/client/base.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/audit.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/auth.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/client_pkg.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/clients.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/external_apis.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/hosts.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/iolog.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/license.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/quick.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/rbp_cmdgrps.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/rbp_entitlement.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/rbp_hostgrps.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/rbp_policy.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/rbp_roles.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/rbp_tests.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/rbp_tmdategrps.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/rbp_tx.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/rbp_usergrps.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/settings.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/siems.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/commands/users.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epml/models/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/client/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/client/base.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/commands/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/commands/audits.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/commands/auth.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/commands/computers.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/commands/events.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/commands/groups.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/commands/policies.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/commands/quick.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/commands/requests.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/commands/roles.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/commands/tasks.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/commands/users.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/epmw/models/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/client/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/client/base.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/auth.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/group_policies.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/import_export.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/jump_clients.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/jump_groups.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/jump_items.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/jumpoints.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/policies.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/quick.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/teams.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/users.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/commands/vault.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/models/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/models/common.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/models/group_policy.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/models/jump_client.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/models/jump_group.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/models/jump_item.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/models/jumpoint.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/models/team.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/models/user.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pra/models/vault.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/client/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/client/base.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/client/beyondinsight.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/client/passwordsafe.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/accounts.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/assets.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/attributes.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/auth.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/clouds.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/config.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/credentials.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/databases.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/directories.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/functional.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/import_export.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/platforms.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/quick.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/search.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/secrets.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/systems.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/users.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/commands/workgroups.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/config.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/models/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/models/account.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/models/asset.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/models/common.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/pws/models/system.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/secrets/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/secrets/client/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/secrets/client/base.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/secrets/commands/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/secrets/commands/auth.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/secrets/commands/integrations.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/secrets/commands/leases.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/src/bt_cli/secrets/models/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/conftest.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/core/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/core/test_auth.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/core/test_config.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/core/test_errors.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/core/test_rest_debug.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/entitle/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/entitle/test_client.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/entitle/test_commands.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/entitle-smoke-test.sh +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/epml/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/epml/test_client.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/epml/test_commands.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/epmw/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/epmw/test_client.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/epmw/test_commands.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/epmw-quick-test-plan.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/fixtures/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/fixtures/responses.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/integration/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/integration/conftest.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/integration/helpers.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/integration/test_entitle_integration.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/integration/test_epmw_integration.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/integration/test_epmw_lifecycle.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/integration/test_pra_integration.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/integration/test_pra_lifecycle.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/integration/test_pws_integration.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/integration/test_pws_lifecycle.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/pra/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/pra/test_client.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/pra/test_commands.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/pra-smoke-test.sh +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/pra-test-plan.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/pws/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/pws/test_client.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/pws/test_commands.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/pws-quick-test-plan.md +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/pws-smoke-test.sh +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/secrets/__init__.py +0 -0
- {bt_cli-0.4.46 → bt_cli-0.4.47}/tests/secrets/test_client.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# BT-CLI
|
|
2
2
|
|
|
3
|
-
BeyondTrust Platform CLI for Password Safe, Entitle, PRA, EPM Windows, EPM Linux, and the BeyondTrust Secrets API. **Version: 0.4.
|
|
3
|
+
BeyondTrust Platform CLI for Password Safe, Entitle, PRA, EPM Windows, EPM Linux, and the BeyondTrust Secrets API. **Version: 0.4.47**
|
|
4
4
|
|
|
5
5
|
## Setup
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bt-cli
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.47
|
|
4
4
|
Summary: BeyondTrust Platform CLI (unofficial) - Password Safe, Entitle, PRA, EPM
|
|
5
5
|
Author-email: Dave Grendysz <dgrendysz@beyondtrust.com>
|
|
6
6
|
License: MIT
|
|
@@ -121,8 +121,8 @@ export BT_SECRETS_API_VERSION=2026-02-16 # default (doc page is
|
|
|
121
121
|
Common commands:
|
|
122
122
|
|
|
123
123
|
```bash
|
|
124
|
-
bt secrets folders list -p lab # filter server-side
|
|
125
|
-
bt secrets dynamic list -p lab
|
|
124
|
+
bt secrets folders list -p lab # filter server-side (recursive default)
|
|
125
|
+
bt secrets dynamic list -p lab # all dynamic-secret configs under lab/
|
|
126
126
|
bt secrets dynamic generate lab/aws/ec2-readonly # mint shell `export AWS_*` lines
|
|
127
127
|
eval $(bt secrets dynamic generate lab/aws/ec2-readonly) # load into current shell
|
|
128
128
|
bt secrets leases list lab/aws/ec2-readonly # who has active leases
|
|
@@ -74,8 +74,8 @@ export BT_SECRETS_API_VERSION=2026-02-16 # default (doc page is
|
|
|
74
74
|
Common commands:
|
|
75
75
|
|
|
76
76
|
```bash
|
|
77
|
-
bt secrets folders list -p lab # filter server-side
|
|
78
|
-
bt secrets dynamic list -p lab
|
|
77
|
+
bt secrets folders list -p lab # filter server-side (recursive default)
|
|
78
|
+
bt secrets dynamic list -p lab # all dynamic-secret configs under lab/
|
|
79
79
|
bt secrets dynamic generate lab/aws/ec2-readonly # mint shell `export AWS_*` lines
|
|
80
80
|
eval $(bt secrets dynamic generate lab/aws/ec2-readonly) # load into current shell
|
|
81
81
|
bt secrets leases list lab/aws/ec2-readonly # who has active leases
|
|
@@ -56,10 +56,13 @@ bt secrets folders get lab/aws # folder=lab, name=aws
|
|
|
56
56
|
|
|
57
57
|
## Folders
|
|
58
58
|
|
|
59
|
+
`list` is **recursive by default** (mirrors how users browse the UI tree).
|
|
60
|
+
Pass `--shallow` / `-S` for direct children only.
|
|
61
|
+
|
|
59
62
|
```bash
|
|
60
|
-
bt secrets folders list # all
|
|
61
|
-
bt secrets folders list -p lab #
|
|
62
|
-
bt secrets folders list -p lab
|
|
63
|
+
bt secrets folders list # all folders, anywhere in the site
|
|
64
|
+
bt secrets folders list -p lab # everything under lab/ recursively
|
|
65
|
+
bt secrets folders list -p lab --shallow # only direct children of lab/
|
|
63
66
|
bt secrets folders get lab/aws # metadata
|
|
64
67
|
bt secrets folders create lab/aws/staging
|
|
65
68
|
bt secrets folders delete lab/aws/staging
|
|
@@ -72,7 +75,9 @@ Versioned key/value secrets. The body is a JSON object — pass it inline via
|
|
|
72
75
|
`--data` or from disk via `--data-file`.
|
|
73
76
|
|
|
74
77
|
```bash
|
|
75
|
-
bt secrets static list
|
|
78
|
+
bt secrets static list # everything in the site (recursive default)
|
|
79
|
+
bt secrets static list -p lab # everything under lab/
|
|
80
|
+
bt secrets static list -p lab --shallow # direct children of lab/ only
|
|
76
81
|
bt secrets static get lab/db-pass # default JSON output (values are structured)
|
|
77
82
|
bt secrets static get lab/db-pass --version 2 # specific historical version
|
|
78
83
|
bt secrets static create lab/db-pass -d '{"password":"hunter2","username":"admin"}'
|
|
@@ -85,7 +90,9 @@ bt secrets static delete lab/db-pass --force
|
|
|
85
90
|
Configurations that mint short-lived credentials on demand (AWS STS today).
|
|
86
91
|
|
|
87
92
|
```bash
|
|
88
|
-
bt secrets dynamic list -
|
|
93
|
+
bt secrets dynamic list # all dynamic-secret configs in the site
|
|
94
|
+
bt secrets dynamic list -p lab # everything under lab/
|
|
95
|
+
bt secrets dynamic list -p lab --shallow # only items directly at lab/ (usually none — they nest)
|
|
89
96
|
bt secrets dynamic get lab/aws/ec2-readonly
|
|
90
97
|
|
|
91
98
|
# Mint fresh credentials — default prints shell `export AWS_*` lines.
|
|
@@ -188,11 +195,15 @@ bt secrets leases list lab/aws/full-admin -o json \
|
|
|
188
195
|
### Browse the tree
|
|
189
196
|
|
|
190
197
|
```bash
|
|
191
|
-
bt secrets folders list -p lab
|
|
192
|
-
bt secrets static list -p lab
|
|
193
|
-
bt secrets dynamic list -p lab
|
|
198
|
+
bt secrets folders list -p lab
|
|
199
|
+
bt secrets static list -p lab
|
|
200
|
+
bt secrets dynamic list -p lab
|
|
194
201
|
```
|
|
195
202
|
|
|
203
|
+
`list` is recursive by default; the API otherwise only returns items
|
|
204
|
+
directly at the requested path (this trips up newcomers — passing
|
|
205
|
+
`-p lab` returns 0 in shallow mode because the items live in `lab/aws`).
|
|
206
|
+
|
|
196
207
|
## API Notes
|
|
197
208
|
|
|
198
209
|
- Base URL: `https://api.beyondtrust.io/site/<site-id>/secrets`
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Shared empty-result hint for `bt secrets <X> list` commands.
|
|
2
|
+
|
|
3
|
+
When server-side filtering returns 0 rows it's almost always one of:
|
|
4
|
+
* --path points one level too high (items live in subfolders)
|
|
5
|
+
* --shallow was passed but the user thought it was recursive
|
|
6
|
+
* the path simply doesn't exist
|
|
7
|
+
|
|
8
|
+
The default "No results found" output gives no clue which. This helper
|
|
9
|
+
prints a one-liner that nudges the user toward the next thing to try.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from typing import Optional
|
|
13
|
+
|
|
14
|
+
from bt_cli.core.output import console
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def empty_hint(path: Optional[str], recursive: bool, kind: str) -> None:
|
|
18
|
+
"""Print a tip when a list call returns no rows."""
|
|
19
|
+
if recursive:
|
|
20
|
+
where = f" under {path!r}" if path else ""
|
|
21
|
+
console.print(f"[dim]No {kind} found{where}.[/dim]")
|
|
22
|
+
console.print(
|
|
23
|
+
"[dim]Tip: pass --shallow for direct children only, or check the path.[/dim]"
|
|
24
|
+
)
|
|
25
|
+
else:
|
|
26
|
+
at = f" directly at {path!r}" if path else " at the root"
|
|
27
|
+
console.print(f"[dim]No {kind}{at} (--shallow mode).[/dim]")
|
|
28
|
+
console.print(
|
|
29
|
+
"[dim]Tip: drop --shallow (default is recursive) to search subfolders.[/dim]"
|
|
30
|
+
)
|
|
@@ -20,6 +20,7 @@ from bt_cli.core.output import (
|
|
|
20
20
|
print_table,
|
|
21
21
|
)
|
|
22
22
|
from bt_cli.secrets.client import split_path
|
|
23
|
+
from bt_cli.secrets.commands._hints import empty_hint
|
|
23
24
|
|
|
24
25
|
app = typer.Typer(no_args_is_help=True, help="Dynamic secrets (e.g. AWS STS, mint on demand)")
|
|
25
26
|
|
|
@@ -77,11 +78,14 @@ def _format_credentials(secret: dict, fmt: GenerateFormat) -> str:
|
|
|
77
78
|
@app.command("list")
|
|
78
79
|
def list_dynamic(
|
|
79
80
|
path: Optional[str] = typer.Option(None, "--path", "-p", help="Path prefix to filter"),
|
|
80
|
-
recursive: bool = typer.Option(
|
|
81
|
+
recursive: bool = typer.Option(
|
|
82
|
+
True, "--recursive/--shallow", "-r/-S",
|
|
83
|
+
help="Recurse into subfolders (default). Use --shallow / -S for direct children only.",
|
|
84
|
+
),
|
|
81
85
|
deleted_only: bool = typer.Option(False, "--deleted-only", help="Only list soft-deleted configs"),
|
|
82
86
|
output: OutputFormat = typer.Option(OutputFormat.TABLE, "--output", "-o", help="Output format"),
|
|
83
87
|
) -> None:
|
|
84
|
-
"""List dynamic-secret configs
|
|
88
|
+
"""List dynamic-secret configs. Recursive by default — pass --shallow for direct children only."""
|
|
85
89
|
from bt_cli.secrets.client import get_client
|
|
86
90
|
|
|
87
91
|
try:
|
|
@@ -90,6 +94,8 @@ def list_dynamic(
|
|
|
90
94
|
|
|
91
95
|
if output == OutputFormat.JSON:
|
|
92
96
|
print_json(data)
|
|
97
|
+
elif not data:
|
|
98
|
+
empty_hint(path, recursive, "dynamic secrets")
|
|
93
99
|
else:
|
|
94
100
|
print_table(
|
|
95
101
|
[_dynamic_row(r) for r in data],
|
|
@@ -14,6 +14,7 @@ from bt_cli.core.output import (
|
|
|
14
14
|
print_table,
|
|
15
15
|
)
|
|
16
16
|
from bt_cli.secrets.client import split_path
|
|
17
|
+
from bt_cli.secrets.commands._hints import empty_hint
|
|
17
18
|
|
|
18
19
|
app = typer.Typer(no_args_is_help=True, help="Folders for organizing secrets")
|
|
19
20
|
|
|
@@ -30,11 +31,14 @@ def _folder_row(item: dict) -> dict:
|
|
|
30
31
|
@app.command("list")
|
|
31
32
|
def list_folders(
|
|
32
33
|
path: Optional[str] = typer.Option(None, "--path", "-p", help="Path prefix to filter folders"),
|
|
33
|
-
recursive: bool = typer.Option(
|
|
34
|
+
recursive: bool = typer.Option(
|
|
35
|
+
True, "--recursive/--shallow", "-r/-S",
|
|
36
|
+
help="Recurse into subfolders (default). Use --shallow / -S for direct children only.",
|
|
37
|
+
),
|
|
34
38
|
deleted_only: bool = typer.Option(False, "--deleted-only", help="Only list soft-deleted folders"),
|
|
35
39
|
output: OutputFormat = typer.Option(OutputFormat.TABLE, "--output", "-o", help="Output format"),
|
|
36
40
|
) -> None:
|
|
37
|
-
"""List folders
|
|
41
|
+
"""List folders. Recursive by default — pass --shallow for direct children only."""
|
|
38
42
|
from bt_cli.secrets.client import get_client
|
|
39
43
|
|
|
40
44
|
try:
|
|
@@ -43,6 +47,8 @@ def list_folders(
|
|
|
43
47
|
|
|
44
48
|
if output == OutputFormat.JSON:
|
|
45
49
|
print_json(data)
|
|
50
|
+
elif not data:
|
|
51
|
+
empty_hint(path, recursive, "folders")
|
|
46
52
|
else:
|
|
47
53
|
print_table(
|
|
48
54
|
[_folder_row(r) for r in data],
|
|
@@ -16,6 +16,7 @@ from bt_cli.core.output import (
|
|
|
16
16
|
print_table,
|
|
17
17
|
)
|
|
18
18
|
from bt_cli.secrets.client import split_path
|
|
19
|
+
from bt_cli.secrets.commands._hints import empty_hint
|
|
19
20
|
|
|
20
21
|
app = typer.Typer(no_args_is_help=True, help="Static (key/value, versioned) secrets")
|
|
21
22
|
|
|
@@ -34,12 +35,15 @@ def _static_row(item: dict) -> dict:
|
|
|
34
35
|
@app.command("list")
|
|
35
36
|
def list_static(
|
|
36
37
|
path: Optional[str] = typer.Option(None, "--path", "-p", help="Path prefix to filter (server-side)"),
|
|
37
|
-
recursive: bool = typer.Option(
|
|
38
|
+
recursive: bool = typer.Option(
|
|
39
|
+
True, "--recursive/--shallow", "-r/-S",
|
|
40
|
+
help="Recurse into subfolders (default). Use --shallow / -S for direct children only.",
|
|
41
|
+
),
|
|
38
42
|
versions: bool = typer.Option(False, "--versions", help="Include version history"),
|
|
39
43
|
deleted_only: bool = typer.Option(False, "--deleted-only", help="Only list soft-deleted secrets"),
|
|
40
44
|
output: OutputFormat = typer.Option(OutputFormat.TABLE, "--output", "-o", help="Output format"),
|
|
41
45
|
) -> None:
|
|
42
|
-
"""List static secrets
|
|
46
|
+
"""List static secrets. Recursive by default — pass --shallow for direct children only."""
|
|
43
47
|
from bt_cli.secrets.client import get_client
|
|
44
48
|
|
|
45
49
|
try:
|
|
@@ -50,6 +54,8 @@ def list_static(
|
|
|
50
54
|
|
|
51
55
|
if output == OutputFormat.JSON:
|
|
52
56
|
print_json(data)
|
|
57
|
+
elif not data:
|
|
58
|
+
empty_hint(path, recursive, "static secrets")
|
|
53
59
|
else:
|
|
54
60
|
print_table(
|
|
55
61
|
[_static_row(r) for r in data],
|
|
@@ -133,6 +133,49 @@ class TestDynamic:
|
|
|
133
133
|
assert "ec2-readonly" in result.stdout
|
|
134
134
|
assert route.called
|
|
135
135
|
|
|
136
|
+
@respx.mock
|
|
137
|
+
def test_dynamic_list_recursive_is_default(self, env_overrides):
|
|
138
|
+
"""No -r / --recursive flag → still sends recursive=true (new default)."""
|
|
139
|
+
route = respx.get(_url("/dynamic")).mock(
|
|
140
|
+
return_value=httpx.Response(200, json={"data": []})
|
|
141
|
+
)
|
|
142
|
+
result = CliRunner().invoke(secrets_app, ["dynamic", "list", "-p", "lab"])
|
|
143
|
+
assert result.exit_code == 0
|
|
144
|
+
assert "recursive=true" in str(route.calls[0].request.url)
|
|
145
|
+
|
|
146
|
+
@respx.mock
|
|
147
|
+
def test_dynamic_list_shallow_opts_out(self, env_overrides):
|
|
148
|
+
"""--shallow turns off recursion."""
|
|
149
|
+
route = respx.get(_url("/dynamic")).mock(
|
|
150
|
+
return_value=httpx.Response(200, json={"data": []})
|
|
151
|
+
)
|
|
152
|
+
result = CliRunner().invoke(secrets_app, ["dynamic", "list", "-p", "lab", "--shallow"])
|
|
153
|
+
assert result.exit_code == 0
|
|
154
|
+
assert "recursive=true" not in str(route.calls[0].request.url)
|
|
155
|
+
|
|
156
|
+
@respx.mock
|
|
157
|
+
def test_dynamic_list_empty_recursive_hint(self, env_overrides):
|
|
158
|
+
"""Empty + recursive → hint nudges toward path check."""
|
|
159
|
+
respx.get(_url("/dynamic")).mock(
|
|
160
|
+
return_value=httpx.Response(200, json={"data": []})
|
|
161
|
+
)
|
|
162
|
+
result = CliRunner().invoke(secrets_app, ["dynamic", "list", "-p", "nowhere"])
|
|
163
|
+
assert result.exit_code == 0
|
|
164
|
+
assert "No dynamic secrets" in result.stdout
|
|
165
|
+
assert "'nowhere'" in result.stdout
|
|
166
|
+
assert "--shallow" in result.stdout # hint mentions the alternative
|
|
167
|
+
|
|
168
|
+
@respx.mock
|
|
169
|
+
def test_dynamic_list_empty_shallow_hint(self, env_overrides):
|
|
170
|
+
"""Empty + --shallow → hint nudges toward dropping --shallow."""
|
|
171
|
+
respx.get(_url("/dynamic")).mock(
|
|
172
|
+
return_value=httpx.Response(200, json={"data": []})
|
|
173
|
+
)
|
|
174
|
+
result = CliRunner().invoke(secrets_app, ["dynamic", "list", "-p", "lab", "--shallow"])
|
|
175
|
+
assert result.exit_code == 0
|
|
176
|
+
assert "--shallow mode" in result.stdout
|
|
177
|
+
assert "drop --shallow" in result.stdout
|
|
178
|
+
|
|
136
179
|
@respx.mock
|
|
137
180
|
def test_dynamic_generate_export_shape(self, env_overrides):
|
|
138
181
|
respx.post(_url("/dynamic/ec2-readonly/generate")).mock(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|