Appearance
plexctl blueprint
Synopsis
plexctl blueprint is the operator surface for the Blueprint Catalog. The read subcommands inspect the catalog; the authorship subcommands register a Blueprint and publish immutable versions under it on /v1/blueprints.
text
plexctl blueprint <subcommand> [flags]Subcommands
plexctl blueprint list
GETs /v1/blueprints. Pagination is keyset-based via --cursor / --limit; the --all flag follows next_cursor until exhausted (mutually exclusive with --cursor).
With --project <uuid> the command GETs /v1/projects/{id}/blueprints instead: the same catalog, with a PROVISIONABLE column saying whether that Project can provision each Blueprint today and a PROVIDER_KINDS column naming the substrates the Blueprint's published versions accept. A leading REACHABLE_PROVIDER_KINDS line names the substrates the Project reaches through its approved Cloud Assignments, and reads none when it reaches nothing. Read against each other, the two answer which Cloud a non-provisionable Blueprint is waiting on. Malformed --project values are rejected locally before the wire. --limit, --cursor and --all work the same way against the nested endpoint; --output json and --output yaml render the raw response, which carries both kind sets.
plexctl blueprint get <id>
GETs /v1/blueprints/{id}. Local UUID validation rejects malformed id with exit 2 before the wire. The text render includes the embedded versions array and, for each version, the typed parameter_schema rows.
plexctl blueprint create
POSTs /v1/blueprints to register a new catalog entry. The call is gated by the platform-level manage relation (platform#manage); a caller without it receives a 403 (exit 4). A duplicate --slug surfaces as 409 blueprint_slug_conflict (exit 1). On success the registrar is granted owner on the new Blueprint, which confers publish — the grant is written asynchronously, so a version create issued in the same instant may be refused until it propagates.
plexctl blueprint version create
POSTs /v1/blueprints/{id}/versions to publish an immutable version under an existing Blueprint, gated by the Blueprint's publish permission (blueprint#publish). The XRD, Composition, and parameter-schema documents are read from JSON files. A duplicate --version surfaces as 409 blueprint_version_exists; a malformed manifest pair as 400 invalid_manifest; an out-of-set provider kind or injection strategy as 400 invalid_provider_kind / 400 invalid_injection_strategy.
plexctl blueprint catalog add
POSTs /v1/blueprint-catalogs to register an external OCI catalog source. Exactly one of --ref (tag-pinned, e.g. ghcr.io/org/catalog:v1.2.3) or --digest (digest-pinned, e.g. ghcr.io/org/catalog@sha256:…) names the bundle. The verification policy is either a pinned cosign identity (--verify-identity with --verify-issuer) or --insecure-unsigned; one of the two must be chosen. --track turns on tag re-resolution at the given interval (pinned when omitted). --domain-id scopes the source to a single Domain (catalog-global when omitted), which selects the relation the call is gated on (domain#manage versus platform#manage). A malformed reference is rejected locally with exit 2; the server is the authority on reference validity and returns 400 invalid_oci_reference, 400 invalid_verification_policy, or 400 invalid_tracking_policy for a policy it rejects.
plexctl blueprint catalog list
GETs /v1/blueprint-catalogs. The source set is small, operator-curated configuration returned whole, so the command carries no pagination flags; items is the subset the caller is authorised to see.
plexctl blueprint catalog get <id>
GETs /v1/blueprint-catalogs/{id}. Local UUID validation rejects a malformed id with exit 2 before the wire.
plexctl blueprint catalog rm <id>
DELETEs /v1/blueprint-catalogs/{id} to deregister a source. The operation is destructive and refuses to run without the root --yes flag. A 204 confirms removal.
plexctl blueprint catalog browse <id>
GETs /v1/blueprint-catalogs/{id}/blueprints to list the Blueprints a source's bundle offers. Nothing is imported — the response carries the bundle metadata (slug, display name, version, provider kinds, injection strategy) only.
plexctl blueprint import <catalog-id> [slug...]
POSTs /v1/blueprint-catalogs/{id}/import to import Blueprints from a registered source. Supply either an explicit list of slugs or --all to import every Blueprint the source offers; supplying neither or both is rejected locally with exit 2. Drift and conflict are reported per-Blueprint in the outcomes, not as a batch failure, so the command exits 0 and renders one row per requested slug.
Flags
plexctl blueprint list
| Flag | Type | Required | Description |
|---|---|---|---|
--limit | int | no | Maximum items per page (server default when zero). |
--cursor | string | no | Continuation token from a previous call. |
--all | bool | no | Follow next_cursor until exhausted. Mutually exclusive with --cursor. |
--project | string (uuid) | no | Read the catalog through one Project: adds the PROVISIONABLE verdict and the reachable-provider line. Malformed values fail before the request. |
plexctl blueprint create
| Flag | Type | Required | Description |
|---|---|---|---|
--slug | string | yes | Kebab-case catalog handle, unique across the catalog. |
--display-name | string | yes | Human-readable Blueprint name. |
--description | string | no | Free-form description. |
--domain-id | string | no | Owning Domain UUID; catalogue-wide when omitted. |
plexctl blueprint version create
| Flag | Type | Required | Description |
|---|---|---|---|
--blueprint-id | string | yes | Parent Blueprint UUID. |
--version | string | yes | Version label, unique within the Blueprint. |
--injection-strategy | string | yes | One of cloud-init-user-data, helm-values, provider-secret. |
--provider-kinds | strings | yes | Comma-separated subset of aws, azure, gcp, hetzner, openstack. |
--xrd-file | string | yes | Path to the Crossplane XRD manifest as a JSON file. |
--composition-file | string | yes | Path to the Crossplane Composition manifest as a JSON file. |
--parameter-schema-file | string | yes | Path to the parameter-schema document as a JSON file ({"parameters":[...]}). |
plexctl blueprint catalog add
| Flag | Type | Required | Description |
|---|---|---|---|
--name | string | yes | Human-facing label for the source. |
--ref | string | one of --ref/--digest | Tag-pinned OCI reference (registry/repository:tag). |
--digest | string | one of --ref/--digest | Digest-pinned OCI reference (registry/repository@sha256:…). |
--verify-identity | string | with --verify-issuer | Cosign signing-identity SAN regexp (pinned verification). |
--verify-issuer | string | with --verify-identity | Expected OIDC issuer (pinned verification). |
--insecure-unsigned | bool | one mode required | Accept the bundle without signature verification. Mutually exclusive with the verify flags. |
--track | duration | no | Re-resolve the source's tag on this interval (track-tag); pinned when zero. |
--domain-id | string | no | Owning Domain UUID; catalog-global when omitted. |
--registry-credential-ref | string | no | namespace/name of the registry-credential Secret. |
plexctl blueprint catalog rm
| Flag | Type | Required | Description |
|---|---|---|---|
--yes | bool | yes | Confirm the destructive deregistration (inherited from root). |
plexctl blueprint import
| Flag | Type | Required | Description |
|---|---|---|---|
--all | bool | one of --all/slugs | Import every Blueprint the source offers. Mutually exclusive with explicit slugs. |
Persistent flags inherited from root
--server, --profile, --token-file, --output. See ../plexctl.md.
Exit codes
See ../plexctl.md#exit-code-taxonomy.
Examples
List all Blueprints across pages
shell
plexctl blueprint list \
--server "${PLEXSPHERE_URL}" \
--all \
--output jsonSee which Blueprints a Project can provision
shell
plexctl blueprint list \
--server "${PLEXSPHERE_URL}" \
--project 0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0aatext
REACHABLE_PROVIDER_KINDS: aws
SLUG NAME STATUS PROVIDER_KINDS PROVISIONABLE
managed-postgres Managed PostgreSQL active aws yes
managed-bigquery Managed BigQuery active gcp noThe second row needs a gcp Cloud, and the Project reaches only aws. Request one with plexctl cloud assignment request and it becomes provisionable once an operator approves it.
Inspect a single Blueprint
shell
plexctl blueprint get 0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0b0 \
--server "${PLEXSPHERE_URL}" \
--output yamlRegister a Blueprint
shell
plexctl blueprint create \
--server "${PLEXSPHERE_URL}" \
--slug managed-postgres \
--display-name "Managed PostgreSQL" \
--description "A managed PostgreSQL database instance."Publish a version
shell
plexctl blueprint version create \
--server "${PLEXSPHERE_URL}" \
--blueprint-id 0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0b0 \
--version 1.0.0 \
--injection-strategy helm-values \
--provider-kinds aws,hetzner \
--xrd-file ./xrd.json \
--composition-file ./composition.json \
--parameter-schema-file ./parameter-schema.jsonRegister a catalog source with a pinned signing identity
shell
plexctl blueprint catalog add \
--server "${PLEXSPHERE_URL}" \
--name "Platform catalog" \
--ref ghcr.io/plexsphere/catalog:v1.2.3 \
--verify-identity '^https://github\.com/plexsphere/.*$' \
--verify-issuer https://token.actions.githubusercontent.comBrowse the Blueprints a source offers
shell
plexctl blueprint catalog browse 0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0e1 \
--server "${PLEXSPHERE_URL}"Import every Blueprint a source offers
shell
plexctl blueprint import 0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0e1 \
--server "${PLEXSPHERE_URL}" \
--all