alembic-cli 0.1.2

Command line interface for Alembic.
# alembic

distills data between dcim/ipam systems, co-evolved with ai

alembic is a data-model-first converger + loader for dcim/ipam systems. it defines a canonical, vendor-neutral ir (intermediate representation) and an engine that validates, plans, and applies changes to a backend. it supports multiple backend adapters, including NetBox, Nautobot, Infrahub, generic REST APIs, and PeeringDB (read-only).

## concepts

- **ir objects**: typed objects with stable `uid` (uuid), a `type`, a human `key`, and `attrs`.
- **relationships**: references are always by `uid`, never backend ids.
- **plan**: a deterministic list of operations (create/update/delete) generated by diffing desired ir against observed backend state.
- **state store**: maps `uid` to backend ids (integers or uuids) per type to keep renames stable; defaults to `.alembic/state.json` and can use postgres.

## quickstart

1) create a brew file (yaml) describing your desired state. see `examples/brew.yaml`.

2) validate:

```bash
cargo run -p alembic-cli -- validate -f examples/brew.yaml
```

3) plan (writes a json plan file):

```bash
# netbox
NETBOX_URL=https://netbox.example.com NETBOX_TOKEN=... \
  cargo run -p alembic-cli -- plan --backend netbox -f examples/brew.yaml -o plan.json

# nautobot
NAUTOBOT_URL=https://nautobot.example.com NAUTOBOT_TOKEN=... \
  cargo run -p alembic-cli -- plan --backend nautobot -f examples/brew.yaml -o plan.json

# infrahub
INFRAHUB_URL=https://infrahub.example.com INFRAHUB_TOKEN=... \
  cargo run -p alembic-cli -- plan --backend infrahub -f examples/brew.yaml -o plan.json
```

4) apply:

```bash
NETBOX_URL=https://netbox.example.com NETBOX_TOKEN=... \
  cargo run -p alembic-cli -- apply --backend netbox -p plan.json --allow-delete
```

5) raw + retort:

```bash
cargo run -p alembic-cli -- distill -f examples/raw.yaml --retort examples/retort.yaml -o ir.json
cargo run -p alembic-cli -- plan -f examples/raw.yaml --retort examples/retort.yaml -o plan.json
```

6) optional: generate a django app from a brew inventory:

```bash
cargo run -p alembic-cli -- cast django -f examples/brew.yaml -o ./out \
  --project alembic_project --app alembic_app
```

## adapter coverage

netbox and nautobot adapters are schema-driven and resolve types dynamically via their content type/object type APIs.
the infrahub adapter uses graphql and can optionally provision missing types/fields by generating
an infrahub schema file and applying it during `apply`.

- any `type` with a REST endpoint can be observed and applied
- `attrs` are passed through using backend field names
- `ref`/`list_ref` fields are resolved via state mappings during apply
- custom fields and tags are mapped by adapters when supported by the backend
- netbox custom object types can be provisioned on apply when the netbox custom objects plugin is installed

relationships are validated strictly by schema and `uid` references.

## workspace layout

- `crates/alembic-core`: ir types, serde, validation primitives
- `crates/alembic-engine`: loader, graph validation, planning, state store
- `crates/alembic-adapter-registry`: adapter config + registry for the cli
- `crates/alembic-adapter-netbox`: netbox adapter
- `crates/alembic-adapter-nautobot`: nautobot adapter
- `crates/alembic-adapter-infrahub`: infrahub graphql adapter
- `crates/alembic-adapter-generic`: generic rest adapter
- `crates/alembic-adapter-peeringdb`: peeringdb adapter
- `crates/alembic-cli`: cli binary

## notes

- input files never contain backend ids.
- plans are deterministic and stable-sorted.
- deletes are gated behind `--allow-delete`.

## documentation

- `docs/index.md`
- `docs/ir.md`
- `docs/brew.md`
- `docs/retort.md`
- `docs/engine.md`
- `docs/plan.md`
- `docs/state.md`
- `docs/cli.md`
- `docs/cast.md`
- `docs/netbox.md`
- `docs/nautobot.md`
- `docs/infrahub.md`
- `docs/development.md`