Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ jobs:
python -m venv "${smoke_root}/venv"
local smoke_python="${smoke_root}/venv/bin/python"
local smoke_cli="${smoke_root}/venv/bin/sccfm-cli"
local smoke_interactive="${smoke_root}/venv/bin/sccfm-cli-interactive"

cd "${smoke_root}"
"${smoke_python}" -I -m pip install --no-cache-dir "${artifact_path}"
Expand Down Expand Up @@ -469,11 +470,15 @@ jobs:
for entry in distribution("cisco-sccfm-devkit").entry_points
if entry.group == "console_scripts"
}
expected = {"sccfm-cli": "cisco_sccfm_cli.cli:cli"}
expected = {
"sccfm-cli": "cisco_sccfm_cli.cli:cli",
"sccfm-cli-interactive": "cisco_sccfm_cli.interactive:main",
}
if console_scripts != expected:
raise SystemExit(f"unexpected public console scripts: {console_scripts}")
PY
"${smoke_cli}" --help >/dev/null
"${smoke_interactive}" --help >/dev/null
"${smoke_cli}" schema export --format json | "${smoke_python}" -I -c \
'from importlib.metadata import version; import json, sys; payload = json.load(sys.stdin); commands = payload.get("commands"); assert payload.get("version") == version("cisco-sccfm-devkit"); assert isinstance(commands, list) and len(commands) == 57'
}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ jobs:
"cisco-sccfm-devkit==${RELEASE_VERSION}"
"${INSTALL_ROOT}/venv/bin/python" -I -m pip check
"${INSTALL_ROOT}/venv/bin/sccfm-cli" --help >/dev/null
"${INSTALL_ROOT}/venv/bin/sccfm-cli-interactive" --help >/dev/null
"${INSTALL_ROOT}/venv/bin/sccfm-cli" schema export --format json \
| "${INSTALL_ROOT}/venv/bin/python" -I -c \
'from importlib.metadata import version; import json, sys; payload=json.load(sys.stdin); assert payload.get("version") == version("cisco-sccfm-devkit"); assert len(payload.get("commands", [])) == 57'
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ sccfm-cli status
sccfm-cli inventory devices list --format table

# Interactive developer menu (test, lint, format, build collection, etc.)
sccfm-cli-interactive
sccfm-devkit
```

## Credential configuration
Expand Down
4 changes: 2 additions & 2 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ These are instructions to install the CLI and Python library from PyPI, plus the
## Installing the CLI

Follow these steps to install the `cisco-sccfm-devkit` Python package, which provides the
`sccfm-cli` command and the `cisco_sccfm_core` Python library.
`sccfm-cli` and `sccfm-cli-interactive` commands and the `cisco_sccfm_core` Python library.

### Prerequisites

Expand All @@ -47,7 +47,7 @@ pyenv global 3.12
### Install with pipx

`pipx` is the recommended install method for the CLI. It keeps the Python environment
isolated while exposing `sccfm-cli` on your `PATH`.
isolated while exposing `sccfm-cli` and `sccfm-cli-interactive` on your `PATH`.

```bash
pipx install cisco-sccfm-devkit
Expand Down
34 changes: 22 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Cisco Security Cloud Control Firewall Manager (SCCFM) DevKit ![CI](https://github.com/CiscoDevNet/sccfm-devkit/actions/workflows/ci.yml/badge.svg)

Toolkit for interacting with Security Cloud Control Firewall Manager (SCCFM): a Python
package with the `sccfm-cli` command, a reusable `cisco_sccfm_core` automation library,
and an Ansible collection. Shared business logic lives in `cisco_sccfm_core` so the CLI,
Python scripts, and collection can reuse the same SDK integrations.
package with the `sccfm-cli` and `sccfm-cli-interactive` commands, a reusable
`cisco_sccfm_core` automation library, and an Ansible collection. Shared business logic lives in
`cisco_sccfm_core` so the CLI, Python scripts, and collection can reuse the same SDK integrations.

**Documentation:** [Generated CLI and Ansible reference](https://ciscodevnet.github.io/sccfm-devkit/)

Expand All @@ -29,7 +29,8 @@ Python scripts, and collection can reuse the same SDK integrations.
cisco_sccfm_scripts/setup_environment.sh # installs pyenv, Python 3.12.4, Poetry deps
source cisco_sccfm_scripts/activate.sh # activates the project virtualenv
sccfm-cli --help # the main SCCFM CLI
sccfm-cli-interactive # interactive CLI and developer workflow menu
sccfm-cli-interactive # customer-facing interactive CLI menu
sccfm-devkit # repository development workflow menu
```

`setup_environment.sh` keeps everything local to the repository: pyenv provides Python 3.12.4, `.venv/` hosts the runtime, and Poetry installs the project plus dev dependencies.
Expand All @@ -45,14 +46,18 @@ sccfm-cli-interactive # interactive CLI and developer workflow menu
Set the active profile once via the global option: `sccfm-cli --profile lab status`.
Every command lives in `cisco_sccfm_cli/commands/` as a concrete implementation of the command-pattern friendly `BaseCommand`, keeping files small and behavior isolated.

`sccfm-cli-interactive` provides customer-facing shortcuts to configure or manage profiles and
to discover and run `sccfm-cli` commands. Repository maintenance tasks are kept separate in the
development-only `sccfm-devkit` menu.

By default, configuration is stored in `~/.sccfm-cli/config.json`. On POSIX systems the CLI
requires mode `0700` on `~/.sccfm-cli` and `0600` on the configuration file. Read-only commands
fail without changing metadata when those modes are unsafe; `sccfm-cli configure` repairs them
while updating a profile. Custom configuration files must also use mode `0600`, but the CLI does
not change an existing custom parent directory. On Windows, keep the configuration in your user
profile and rely on the filesystem's per-user access controls.

Generated CLI reference docs can be previewed locally:
From an activated source checkout, generated CLI reference docs can be previewed locally:

```bash
generate-cli-docs
Expand Down Expand Up @@ -93,7 +98,8 @@ The package root exports the supported public service classes and response model
## Ansible collection

- macOS: `brew install ansible` (this includes `ansible-galaxy`; verify with `ansible-galaxy --version`).
- Build and install the collection locally: `build-ansible-collection`.
- From an activated source checkout, build and install the collection with
`build-ansible-collection`.
- Configure profiles interactively: run `sccfm-cli-interactive` and select **configure-profile**.
- For IDEs/mypy, add `sccfm-ansible` to `ANSIBLE_COLLECTIONS_PATH` (or mark it as a source root) so imports under `ansible_collections.cisco.sccfm` resolve without installing.
- Ansible modules and inventory select the same named SCCFM profile; they do not duplicate its region or API token in environment variables, playbooks, or Ansible Vault.
Expand All @@ -103,15 +109,18 @@ The package root exports the supported public service classes and response model
or group variable. Do not use inventory output modes that render vars when your own
`group_vars` or `host_vars` contain secrets.
- A starter playbook is in `sccfm-ansible/examples/show_devices.yml`; it runs against the SCCFM devices discovered by the inventory plugin.
- Generated Ansible reference docs can be previewed locally with `generate-ansible-docs`; see [docs/README.md](https://github.com/CiscoDevNet/sccfm-devkit/blob/main/docs/README.md) for details.
- From an activated source checkout, generate Ansible reference docs with
`generate-ansible-docs`; see
[docs/README.md](https://github.com/CiscoDevNet/sccfm-devkit/blob/main/docs/README.md)
for details.

## Development

All common development tasks are available through the interactive CLI menu:
All common development tasks are available through the repository-only interactive menu:

```bash
source cisco_sccfm_scripts/activate.sh
sccfm-cli-interactive
sccfm-devkit
```

This presents an interactive selector with the following tasks:
Expand All @@ -120,8 +129,8 @@ This presents an interactive selector with the following tasks:
|------|-------------|
| **configure-profile** | Create or replace a canonical SCCFM profile |
| **manage-profiles** | Update or remove SCCFM profiles |
| **import-legacy-vault** | Copy profiles from the former vault token store without modifying it |
| **run-cli** | Discover and run an `sccfm-cli` command interactively |
| **import-legacy-vault** | Copy profiles from the former vault token store without modifying it (source only) |
| **run-ansible** | Select and run an example playbook |
| **build-collection** | Build the cisco.sccfm Ansible collection tarball |
| **generate-ansible-docs** | Generate Ansible reference docs from ansible-doc output |
Expand All @@ -130,7 +139,8 @@ This presents an interactive selector with the following tasks:
| **install-cli-man-docs** | Install generated CLI man pages for local man lookup |
| **setup-env** | Bootstrap environment (pyenv, venv, Poetry deps) |
| **test** | Run the test suite (pytest), with optional filter & verbose |
| **lint** | Run mypy + flake8 |
| **run-e2e** | Run Ansible e2e tests against a real SCCFM tenant |
| **lint** | Run black + isort + mypy |
| **format** | Auto-format code with black + isort |

After a task completes you're returned to the menu — select **Exit** when done.
Expand All @@ -151,7 +161,7 @@ See `CONTRIBUTING.md` for commit guidelines (Commitizen) and contribution expect
For contributors, use the repository environment from [Getting started](#getting-started).

For end users, install the published PyPI package with `pipx` when possible. `pipx`
keeps the CLI isolated while exposing `sccfm-cli` on `PATH`:
keeps the CLI isolated while exposing `sccfm-cli` and `sccfm-cli-interactive` on `PATH`:

```bash
pipx install cisco-sccfm-devkit
Expand Down
3 changes: 2 additions & 1 deletion RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,14 @@ The successful deployment run is the authoritative publication record. Confirm t
For an independent clean-install check:

```bash
RELEASE_VERSION=0.39.1
RELEASE_VERSION=X.Y.Z
RELEASE_CHECK_ROOT="$(mktemp -d)"
python3.12 -m venv "${RELEASE_CHECK_ROOT}/venv"
"${RELEASE_CHECK_ROOT}/venv/bin/python" -m pip install \
"cisco-sccfm-devkit==${RELEASE_VERSION}" \
"ansible-core>=2.20,<2.22"
"${RELEASE_CHECK_ROOT}/venv/bin/sccfm-cli" --help
"${RELEASE_CHECK_ROOT}/venv/bin/sccfm-cli-interactive" --help
"${RELEASE_CHECK_ROOT}/venv/bin/ansible-galaxy" collection install \
"cisco.sccfm:==${RELEASE_VERSION}" \
--collections-path "${RELEASE_CHECK_ROOT}/collections"
Expand Down
Loading