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: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ Key rules:
- Modify generated code (protocols.py)
- Bypass type checking without justification

## Knowledge base

Deep-dive docs on architecture and workflows live in `dev/knowledge/`. Read these before making changes to the areas they cover.

- [dev/knowledge/cli-architecture.md](dev/knowledge/cli-architecture.md) - CLI command hierarchy and design rules
- [dev/knowledge/doc-generation.md](dev/knowledge/doc-generation.md) - How docs are auto-generated from code

## Subdirectory guides

- [docs/AGENTS.md](docs/AGENTS.md) - Documentation (Docusaurus)
Expand Down
39 changes: 39 additions & 0 deletions dev/knowledge/cli-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# CLI Architecture

The `infrahubctl` CLI is built with [Typer](https://typer.tiangolo.com/) via a custom `AsyncTyper` subclass that supports async command functions.

## Entry point

The main Typer app lives in `infrahub_sdk/ctl/cli_commands.py`. It is re-exported through `infrahub_sdk/ctl/cli.py` which adds the `infrahubctl` entry point name.

## Command hierarchy

Commands are organized in two tiers:

- **Root commands** are registered directly on the main app with `app.command()`. These are standalone operations that don't belong to a logical group (e.g. `dump`, `load`, `check`, `render`, `run`, `transform`, `protocols`, `version`, `info`).
- **Subcommand groups** are separate `AsyncTyper()` instances registered with `app.add_typer(sub_app, name="group")`. Each group lives in its own module under `infrahub_sdk/ctl/`. Current groups: `branch`, `schema`, `validate`, `repository`, `menu`, `object`, `graphql`, `task`.

## Adding a new command

For a **root command**, define the function in the appropriate module and register it in `cli_commands.py`:

```python
app.command(name="mycommand")(my_function)
```

For a **subcommand**, add it to the relevant group's module. For example, object subcommands go in `infrahub_sdk/ctl/object.py` or in dedicated files under `infrahub_sdk/ctl/commands/` and are registered on the object app.

## The `commands/` directory

`infrahub_sdk/ctl/commands/` contains modular command implementations that are imported and registered on a group app. This keeps individual command logic separated from the group wiring. Shared utilities live in `commands/utils.py`.

## Decorators

- `@catch_exception(console=console)` wraps commands for consistent error handling via Rich.
- Async commands work natively thanks to `AsyncTyper`.

## Design rules

**Always check if a new command belongs in an existing group before adding it at the root.** A command that operates on a specific resource type (objects, branches, schemas, etc.) should go under the matching subgroup, not at the top level. Root-level commands are reserved for cross-cutting or standalone operations (e.g. `run`, `version`, `info`).

When in doubt, look at what the command acts on and find the group that matches. For example, anything that creates, reads, updates, or deletes Infrahub objects belongs under `object`, not at the root.
40 changes: 40 additions & 0 deletions dev/knowledge/doc-generation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Documentation Generation

CLI and SDK documentation is auto-generated from code. Always regenerate after changing commands, config, or public docstrings.

## How to run

```bash
uv run invoke docs-generate # Generate all docs (CLI + SDK)
uv run invoke docs-validate # Verify generated docs match committed versions
```

## CLI documentation

Defined in `tasks.py` (`_generate_infrahubctl_documentation`). The process:

1. Deletes all existing `infrahubctl-*.mdx` files in `docs/docs/infrahubctl/`.
2. Iterates `app.registered_commands` and creates a `TyperSingleCommand` for each.
3. Iterates `app.registered_groups` and creates a `TyperGroupCommand` for each.
4. Each command object generates an mdx file via `typer ... utils docs`.

### How it maps to files

- A **root command** named `foo` produces `infrahubctl-foo.mdx` using:
`uv run typer --func foo infrahub_sdk.ctl.cli_commands utils docs --name "infrahubctl foo"`
- A **subcommand group** named `bar` produces `infrahubctl-bar.mdx` using:
`uv run typer infrahub_sdk.ctl.bar utils docs --name "infrahubctl bar"`

The group variant documents all subcommands within that group automatically.

### Key implication

Moving a command from root to a group (or vice versa) changes which mdx files get generated. The old files are cleaned up automatically by the glob delete, but the new ones only appear after running `docs-generate`. Always regenerate and commit the result.

## SDK documentation

Other doc generators cover SDK config, compatibility matrix, templates, and API reference. These are independent of CLI structure and are also triggered by `docs-generate`.

## Validation in CI

`docs-validate` diffs the generated output against the committed files. If they don't match, CI fails. This ensures docs stay in sync with code.
31 changes: 0 additions & 31 deletions docs/docs/infrahubctl/infrahubctl-create.mdx

This file was deleted.

30 changes: 0 additions & 30 deletions docs/docs/infrahubctl/infrahubctl-delete.mdx

This file was deleted.

41 changes: 0 additions & 41 deletions docs/docs/infrahubctl/infrahubctl-get.mdx

This file was deleted.

134 changes: 134 additions & 0 deletions docs/docs/infrahubctl/infrahubctl-object.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,112 @@ $ infrahubctl object [OPTIONS] COMMAND [ARGS]...

**Commands**:

* `create`: Create a new object in Infrahub.
* `delete`: Delete an Infrahub object.
* `get`: Query and display Infrahub objects.
* `load`: Load one or multiple objects files into...
* `update`: Update an existing object in Infrahub.
* `validate`: Validate one or multiple objects files.

## `infrahubctl object create`

Create a new object in Infrahub.

Provide field values with repeatable --set flags or supply a
JSON/YAML object file via --file. The two modes are mutually exclusive.

Examples:
infrahubctl object create InfraDevice --set name=spine01 --set status=active
infrahubctl object create InfraDevice --set name=spine01 --set location=DC1
infrahubctl object create InfraDevice --file devices.yml

**Usage**:

```console
$ infrahubctl object create [OPTIONS] KIND
```

**Arguments**:

* `KIND`: Infrahub schema kind to create [required]

**Options**:

* `--set TEXT`: Field value in key=value format
* `-f, --file PATH`: JSON or YAML file with object data
* `-b, --branch TEXT`: Target branch
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
* `--help`: Show this message and exit.

## `infrahubctl object delete`

Delete an Infrahub object.

Fetches the object by KIND and IDENTIFIER, then deletes it.
Unless --yes is provided, a confirmation prompt is shown first.

Examples:
infrahubctl object delete InfraDevice spine01
infrahubctl object delete InfraDevice spine01 --yes

**Usage**:

```console
$ infrahubctl object delete [OPTIONS] KIND IDENTIFIER
```

**Arguments**:

* `KIND`: Infrahub schema kind [required]
* `IDENTIFIER`: UUID, name, or HFID (use / for multi-part, for example: Cisco/NX-OS) [required]

**Options**:

* `-y, --yes`: Skip confirmation prompt
* `-b, --branch TEXT`: Target branch
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
* `--help`: Show this message and exit.

## `infrahubctl object get`

Query and display Infrahub objects.

When IDENTIFIER is omitted the command lists all objects of the given
KIND. When IDENTIFIER is provided it displays a single object in
detail view. Empty columns are hidden by default (use --all-columns).

Examples:
infrahubctl object get InfraDevice
infrahubctl object get InfraDevice spine01
infrahubctl object get InfraDevice --filter name__value=spine01
infrahubctl object get InfraDevice --output json
infrahubctl object get InfraDevice --output yaml > backup.yml

Exit codes: 0 = results found, 1 = error (including not found in detail
mode), 80 = list query succeeded but returned zero objects.

**Usage**:

```console
$ infrahubctl object get [OPTIONS] KIND [IDENTIFIER]
```

**Arguments**:

* `KIND`: Infrahub schema kind to query [required]
* `[IDENTIFIER]`: UUID, name, or HFID (use / for multi-part, for example: Cisco/NX-OS)

**Options**:

* `--filter TEXT`: Filter in attr__value=x format
* `-o, --output [table|json|csv|yaml]`: Output format
* `-b, --branch TEXT`: Target branch
* `--limit INTEGER`: Maximum results
* `--offset INTEGER`: Skip first N results
* `--all-columns`: Show all columns including empty ones
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
* `--help`: Show this message and exit.

## `infrahubctl object load`

Load one or multiple objects files into Infrahub.
Expand All @@ -40,6 +143,37 @@ $ infrahubctl object load [OPTIONS] PATHS...
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
* `--help`: Show this message and exit.

## `infrahubctl object update`

Update an existing object in Infrahub.

Fetches the object by KIND and IDENTIFIER, applies the requested
changes, and saves back to the server. Use --set or --file.

Examples:
infrahubctl object update InfraDevice spine01 --set status=active
infrahubctl object update InfraDevice spine01 --set location=DC1
infrahubctl object update InfraDevice spine01 --file updates.yml

**Usage**:

```console
$ infrahubctl object update [OPTIONS] KIND IDENTIFIER
```

**Arguments**:

* `KIND`: Infrahub schema kind [required]
* `IDENTIFIER`: UUID, name, or HFID (use / for multi-part, for example: Cisco/NX-OS) [required]

**Options**:

* `--set TEXT`: Field value in key=value format
* `-f, --file PATH`: JSON or YAML file with update data
* `-b, --branch TEXT`: Target branch
* `--config-file TEXT`: [env var: INFRAHUBCTL_CONFIG; default: infrahubctl.toml]
* `--help`: Show this message and exit.

## `infrahubctl object validate`

Validate one or multiple objects files.
Expand Down
32 changes: 0 additions & 32 deletions docs/docs/infrahubctl/infrahubctl-update.mdx

This file was deleted.

Loading