Skip to main content

Spec-driven network API CLI for operators, with first-class ClearPass support

Project description

 _   _      _   _
| \ | | ___| |_| | ___   ___  _ __ ___
|  \| |/ _ \ __| |/ _ \ / _ \| '_ ` _ \
| |\  |  __/ |_| | (_) | (_) | | | | | |
|_| \_|\___|\__|_|\___/ \___/|_| |_| |_|

Weave your network APIs into one CLI.

Version Python Platform

About

netloom is a spec-driven network API CLI for operators and automation engineers. It discovers available API actions from vendor documentation, turns them into a consistent command surface, and keeps the workflow centered around operational tasks like listing objects, replaying payloads, refreshing API caches, and copying configuration between environments.

[!NOTE] The runtime is organized so shared CLI logic lives in netloom/ and vendor-specific behavior lives under netloom/plugins/<plugin>/. ClearPass is currently the only bundled plugin. The CLI and repo layout are already modular, so adding more plugins does not require changing the shared command surface. More vendor support is planned for the future.

Version: 1.8.3

Detailed changelog documented in CHANGELOG.md.

Highlights

  • shared modular runtime under netloom/
  • plugin-specific code under netloom/plugins/<plugin>/
  • built-in load, server, cache, and copy workflows
  • profile-aware configuration through ~/.config/netloom/plugins/<plugin>/
  • dynamic API discovery from live vendor documentation
  • structured JSON, CSV, and raw output
  • shell completion and context-aware help

Planned features

The roadmap is focused on improving the core CLI first, then expanding automation workflows, and finally adding broader user-experience features.

ClearPass privilege-aware cache filtering and the default visible/full catalog split are now in place through v1.8.3. The next step is to keep expanding mapping coverage and tighten action-level visibility where that can be verified safely.

Phase 1: Access-aware discovery and comparison

  • add a netloom <module> <service> diff --from=X --to=Y action to compare config between <profiles> within a <service>
  • continue refining the visible catalog so action-level exposure matches the active API client as closely as verified mappings allow
  • keep the explicit opt-in full catalog view for troubleshooting, vendor doc comparison, and mapping validation
  • continue expanding the verified ClearPass privilege mapping table as Aruba adds or changes endpoints and privilege keys

Phase 2: Safe multi-service workflows

  • implement netloom <module> copy --from=X --to=Y to copy all config from all <services> within a <module>
  • add structured copy and diff plans with stable JSON output for automation and review
  • add validation and dry-run helpers to verify whether objects and payloads are safe to apply before changes are made

Phase 3: Change tracking and UX expansion

  • add version control support for exported configs, plans, and environment comparisons
  • add a GUI on top of the stabilized CLI workflows

Installation

Standard install:

pip install netloom-tool

Install directly from GitHub:

pip install git+https://github.com/mathias-granlund/netloom

Install the bundled man pages:

netloom-install-manpage
man netloom
man netloom-clearpass

First run

[!NOTE] Load a plugin and build the API cache before expecting context-aware help, completion, or live module/service discovery to work well. This creates the active plugin marker at ~/.config/netloom/config.env

netloom load clearpass
netloom cache update
netloom server use dev
netloom identities endpoint list --limit=10

Configuration

[!TIP] Example templates are included as defaults.env.example, profiles.env.example, and credentials.env.example. Copy them into the plugin directory ~/.config/netloom/plugins/<plugin>/

The runtime separates global plugin selection from plugin-specific profile settings:

~/.config/netloom/config.env
~/.config/netloom/plugins/<plugin>/defaults.env
~/.config/netloom/plugins/<plugin>/profiles/<profile>.env
~/.config/netloom/plugins/<plugin>/credentials/<profile>.env

config.env usually only needs the active plugin and is normally managed with:

netloom load clearpass

defaults.env holds the active profile and any plugin-wide fallback values:

NETLOOM_ACTIVE_PROFILE="prod"
NETLOOM_VERIFY_SSL="true"
NETLOOM_TIMEOUT="30"

Required per-profile connection settings in profiles/<profile>.env:

NETLOOM_SERVER="clearpass.example.com:443"

Required per-profile credentials in credentials/<profile>.env:

NETLOOM_CLIENT_ID="your-client-id"
NETLOOM_CLIENT_SECRET="your-client-secret"

[!IMPORTANT] Direct NETLOOM_* environment variables still override profile files when they are set in the current shell session.

CLI syntax

  netloom load [list | show | <plugin>]
  netloom server [list | show | use <profile>]
  netloom cache [clear | update]
  netloom <module> <service> <action> [options] [flags]
  netloom <module> <service> copy --from=SOURCE --to=TARGET [options] [flags]
  netloom [--help | ?]
  netloom --version

Examples:

netloom load clearpass
netloom server use dev
netloom cache update
netloom identities endpoint list --limit=10
netloom identities endpoint list --filter=name:equals:TEST
netloom policyelements network-device get --id=1337 --console
netloom policyelements network-device update --id=1337 --description="Core switch"
netloom policyelements network-device copy --from=dev --to=prod --filter='{"description":{"$contains":"Core switch"}}' --dry-run

Command-line token overrides are supported:

netloom identities endpoint list --api-token=your-token
netloom identities endpoint list --token-file=./token.json

[!CAUTION] --api-token, --token-file, and especially --decrypt together with --console can expose sensitive data in shell history or terminal output.

When --filter= is used, both shorthand and full JSON syntax are available:

Simple shorthand for common filters:

--filter=name:equals:TEST
--filter=name:contains:guest
--filter=id:in:1,2,3
--filter=enabled:exists:true

Supported shorthand operators:

  • equals
  • not-equals
  • contains
  • in
  • not-in
  • gt
  • gte
  • lt
  • lte
  • exists

Use full JSON for advanced cases such as $and, $or, $not, regex, or nested expressions.

[!IMPORTANT] JSON filter expressions are passed as strings, so shell quoting matters.

  Key is equal to 'value'                  '{"key":{"$eq":"value"}}'
  Key is one of a list of values           '{"key":{"$in":["value1", "value2"]}}'
  Key is not one of a list of values       '{"key":{"$nin":["value1", "value2"]}}'
  Key contains a substring 'value'         '{"key":{"$contains":"value"}}'
  key is not equal to 'value'              '{"key":{"$ne":"value"}}'
  Key is greater than 'value'              '{"key":{"$gt":"value"}}'
  Key is greater than or equal to 'value'  '{"key":{"$gte":"value"}}'
  Key is less than 'value'                 '{"key":{"$lt":"value"}}'
  Key is less than or equal to 'value'     '{"key":{"$lte":"value"}}'
  Key matches a regex (case-sensitive)     '{"key":{"$regex":"regex"}}'
  Key exists (not null value)              '{"key":{"$exists":true}}'
  Key is absent / does not exist           '{"key":{"$exists":false}}'
  Combining filter expressions with AND    '{"$and":[filter1, filter2,...]}'
  Combining filter expressions with OR     '{"$or":[filter1, filter2,...]}'
  Inverting a filter expression            '{"$not":{filter}}'

Global options

Option Description
--log-level=LEVEL Set logging level
--console Print API response to terminal
--limit=N Page size for list/get --all requests
--offset=N Pagination offset
--sort=+-field Sort results
--filter=JSON|FIELD:OP:VALUE Server-side filter applied across all fetched pages
--calculate-count=true/false Request total count
--csv-fieldnames=a,b,c Fields and order for CSV output
--file=FILE Bulk import JSON/CSV
--out=FILE Override output file
--api-token=TOKEN Use an existing bearer token instead of logging in
--token-file=FILE Load a bearer token from JSON or plain text
--help Context-aware help
--version Show version
--encrypt=enable/disable Mask or show secret fields
--decrypt Shortcut for showing secrets

Discovery and cache

The active plugin discovers modules and services at runtime. The current ClearPass plugin uses live vendor docs such as:

  • /api-docs
  • /api/apigility/documentation/<Module-v1>

The generated cache stores actions as:

module -> service -> action -> {method, paths, params, response metadata, body hints}

For ClearPass, netloom cache update also checks /api/oauth/privileges, stores the full discovered catalog, and builds a stricter default visible view from verified privilege mappings so help, completion, and normal command discovery better match what the active API client can actually use.

By default, the CLI uses the visible catalog view. When you need to troubleshoot or compare against the raw vendor docs, use the full retained catalog view:

netloom --catalog-view=full ?
netloom --catalog-view=full <module> <service> <action> --help

Refresh the cache:

netloom cache clear
netloom cache update

Default paths

On Linux and macOS the defaults are:

cache:     ~/.cache/netloom/
state:     ~/.local/state/netloom/
responses: ~/.local/state/netloom/responses/
app logs:  ~/.local/state/netloom/logs/
config:    ~/.config/netloom/config.env
plugins:   ~/.config/netloom/plugins/<plugin>/

These can be overridden with:

  • NETLOOM_CACHE_DIR
  • NETLOOM_STATE_DIR
  • NETLOOM_OUT_DIR
  • NETLOOM_APP_LOG_DIR
  • NETLOOM_CONFIG_DIR

Bash completion

[!TIP] Completion quality depends on the local API cache. If module or service names look incomplete, run netloom cache update first.

Run once per session:

source /path/to/netloom/scripts/netloom-completion.bash

Permanent completion setup:

mkdir -p ~/.bash_completion.d

cp /path/to/netloom/scripts/netloom-completion.bash ~/.bash_completion.d

cat >> ~/.bashrc <<'EOF'
if [ -d "$HOME/.bash_completion.d" ]; then
  for f in "$HOME"/.bash_completion.d/*; do
    [ -r "$f" ] && source "$f"
  done
fi
EOF

Architecture

The repository layout is now centered on a shared netloom/ runtime and plugin-specific folders under netloom/plugins/.

.
|-- CHANGELOG.md
|-- README.md
|-- RELEASING.md
|-- RELEASE_NOTES.md
|-- pyproject.toml
|-- defaults.env.example
|-- profiles.env.example
|-- credentials.env.example
|-- examples/
|-- man/
|   |-- netloom.1
|   `-- netloom-clearpass.7
|-- scripts/
|   `-- netloom-completion.bash
|-- tests/
`-- netloom/
    |-- __init__.py
    |-- __main__.py
    |-- install_manpage.py
    |-- cli/
    |   |-- commands.py
    |   |-- completion.py
    |   |-- copy.py
    |   |-- help.py
    |   |-- load.py
    |   |-- main.py
    |   |-- parser.py
    |   `-- server.py
    |-- core/
    |   |-- config.py
    |   |-- help.py
    |   |-- pagination.py
    |   |-- plugin.py
    |   `-- resolver.py
    |-- io/
    |   |-- files.py
    |   `-- output.py
    |-- logging/
    |   `-- setup.py
    |-- data/
    |   `-- man/
    |       |-- netloom.1
    |       `-- netloom-clearpass.7
    `-- plugins/
        `-- clearpass/
            |-- catalog.py
            |-- client.py
            |-- copy_hooks.py
            |-- help.py
            `-- plugin.py

Development

Development install:

pip install -e .[dev]

Run tests:

pytest -q

Run lint and formatting:

ruff check .
ruff format .

Build release artifacts locally:

python -m build
python -m twine check dist/*

Release guidance is documented in RELEASING.md.

License

Proprietary / Internal Use
See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

netloom_tool-1.8.3.tar.gz (96.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

netloom_tool-1.8.3-py3-none-any.whl (69.8 kB view details)

Uploaded Python 3

File details

Details for the file netloom_tool-1.8.3.tar.gz.

File metadata

  • Download URL: netloom_tool-1.8.3.tar.gz
  • Upload date:
  • Size: 96.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for netloom_tool-1.8.3.tar.gz
Algorithm Hash digest
SHA256 2ba87712bd98a326cfc4c3d1df2f407ccf5d08505785f7df4dc8d97ef733e652
MD5 e993643f6ede488d8567e79f49f68bed
BLAKE2b-256 6796383ba43f4fc9ef97b203d102724379a41a63491c20d625ae5746dea74355

See more details on using hashes here.

Provenance

The following attestation bundles were made for netloom_tool-1.8.3.tar.gz:

Publisher: package.yml on mathias-granlund/netloom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file netloom_tool-1.8.3-py3-none-any.whl.

File metadata

  • Download URL: netloom_tool-1.8.3-py3-none-any.whl
  • Upload date:
  • Size: 69.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for netloom_tool-1.8.3-py3-none-any.whl
Algorithm Hash digest
SHA256 37621ad00c984f158f077b0219b17b5f8364761eb8a0434e5256b052dd9dbaa3
MD5 bd7f3c5e949f70ae47360bc1ba9fb3bb
BLAKE2b-256 1ddb83b17365337a6eebff64ce0ac1d63836471469f7862478bb7893eea4f9ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for netloom_tool-1.8.3-py3-none-any.whl:

Publisher: package.yml on mathias-granlund/netloom

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page