Skip to content

plexctl label

Synopsis

plexctl label is the operator surface for the Label aggregate. It spans three independent /v1 surfaces under a single cobra parent:

  • /v1/label-definitions — CRUD on Label Definitions (the schema for a label key plus its value contract).
  • /v1/labels/selectors/preview — parser tester that walks a raw selector expression and renders either the parsed AST or the list of parse errors the server returned.
  • /v1/objects/{kind}/{id}/labels — per-object Assignment management: set (upsert), list, delete.
  • /v1/objects/search — selector → objects search, filtered to the caller's access (object search).

The Label context's ubiquitous language (Definition vs. Assignment, qualified key, value-schema kind, on-delete policy) is documented in ../../contexts/labels/index.md. This page documents only the CLI surface: every flag, every required input, and the exit-code mapping.

Invocation

text
plexctl label define <subcommand> [flags]
plexctl label selector preview --selector <expression>
plexctl label object <subcommand> <kind:id> [flags]

The <kind:id> positional argument addresses an object by its kind discriminator and UUID — for example node:0190a8b8-… or project:0190a8b8-…. Malformed references fail before the wire so an operator typo does not blow past flag-parse and surface as a 404 .

plexctl label define create

Creates a Label Definition. The --type flag is checked against the OpenAPI ValueSchemaKind enum at flag-parse time, so an invalid kind surfaces as exit 2 instead of a 400 round-trip.

plexctl label define list

Lists Label Definitions in a scope. The --scope flag carries the OpenAPI's compact scope coordinate: platform, domain:<uuid>, or project:<uuid>. Pagination is keyset-based via --cursor.

plexctl label define get

Returns a single Label Definition by UUID.

plexctl label define update

Updates a Label Definition's mutable fields. scope, scope_id, local_key, and immutable are frozen after creation per the OpenAPI contract.

plexctl label define delete

Deletes a Label Definition. Requires the persistent --yes flag — delete is destructive and the policy on Definition delete (block / cascade / orphan) is encoded on the Definition itself, not on this command. block refuses the delete while Assignments still reference the Definition; cascade deletes those Assignments with it; orphan detaches them — the Assignments stay readable per object (with a null parent definition) but drop out of Definition-scoped listings — then deletes the Definition.

plexctl label selector preview

POSTs a raw selector expression to /v1/labels/selectors/preview and renders the parsed AST in text mode (depth-first walk, one row per node) or the typed wire shape in json / yaml mode. When the server returns parse errors, each error renders as an ERROR row with the offending position.

plexctl label object set

Upserts a Label Assignment on an object. The --value flag is sent as a string literal; the server validates against the parent Definition's value-schema (boolean / numeric / regex / enum / string).

plexctl label object list

Lists every Label Assignment on an object.

plexctl label object delete

Deletes a Label Assignment from an object. The Assignment is addressed by qualified key (e.g. platform/env) — addressing by Definition id would force a lookup hop, so the CLI mirrors the wire shape. Like label define delete, this subcommand requires the persistent --yes flag: removing an Assignment is destructive, so the API call is refused until the operator confirms intent.

Resolves a --selector to the objects within a scope that carry the matching Labels, then filters them to the ones the caller can reach via --relation — the direct "which objects carry Label X=Y that I can access?" query, replacing the manual rebac lookup-resources | jq intersection. The result renders as a KIND/ID table (or the typed shape under --output json/yaml). An empty result is a normal answer (exit 0): objects the caller cannot reach are silently omitted, never surfaced as a permission error. Pagination is filter-after-page — a page may hold fewer than --limit matches while a continuation cursor is still returned.

Flags

plexctl label define create

FlagTypeRequiredDefaultDescription
--scopeenumyesplatform | domain | project.
--scope-idUUIDconditionalScope UUID. Required when --scope=domain or --scope=project.
--keystringyesLocal key, e.g. env.
--typeenumyesValue-schema kind: string | enum | boolean | numeric | regex.
--applicable-kindsstring sliceyesObject kinds the Definition applies to (repeat or comma-separate).
--descriptionstringnoHuman description (max 512 chars).
--requiredboolnofalseAssignments mandatory on every applicable object.
--immutableboolnofalseFreeze the value schema and Assignment values after creation.
--cardinalityintno0Per-object Assignment cap (0 = unlimited).
--on-deleteenumnoserver defaultPolicy on Definition delete: block | cascade | orphan.
--enum-valuesstring sliceconditionalPermitted values for --type=enum.
--regex-patternstringconditionalGo regexp pattern for --type=regex.
--max-lenintnoMaximum byte length for --type=string.
--minint64noLower bound for --type=numeric.
--maxint64noUpper bound for --type=numeric.

plexctl label define list

FlagTypeRequiredDefaultDescription
--scopestringyesScope coordinate: platform | domain:<uuid> | project:<uuid>.
--limitintnoserver defaultMaximum items per page.
--cursorstringnoContinuation token from a previous call's next_cursor.

plexctl label define get

FlagTypeRequiredDefaultDescription
--idUUIDyesLabel Definition UUID.

plexctl label define update

FlagTypeRequiredDefaultDescription
--idUUIDyesLabel Definition UUID.
--descriptionstringnoNew human description (max 512 chars).
--applicable-kindsstring slicenoNew list of applicable object kinds.
--requiredboolnoNew required flag.
--on-deleteenumnoPolicy on Definition delete: block | cascade | orphan.

Only flags explicitly set on the command line are sent in the PATCH body — unset flags leave the server-side value untouched.

plexctl label define delete

FlagTypeRequiredDefaultDescription
--idUUIDyesLabel Definition UUID.
--yes (persistent)boolyesfalseRequired confirmation for the destructive operation.

plexctl label selector preview

FlagTypeRequiredDefaultDescription
--selectorstringyesRaw selector expression to parse-test.

plexctl label object set

PositionalTypeRequiredDescription
<kind:id>stringyesObject reference, e.g. node:0190a8b8-….
FlagTypeRequiredDefaultDescription
--definition-idUUIDyesParent Label Definition UUID.
--valuestringyesAssignment value as a literal. The server validates it against the parent Definition's value schema.

plexctl label object list

PositionalTypeRequiredDescription
<kind:id>stringyesObject reference, e.g. node:0190a8b8-….

plexctl label object delete

PositionalTypeRequiredDescription
<kind:id>stringyesObject reference, e.g. node:0190a8b8-….
FlagTypeRequiredDefaultDescription
--qualified-keystringyesFully-qualified Label key, e.g. platform/env.
--yes (persistent)boolyesfalseRequired confirmation for the destructive operation.

plexctl label object search

FlagTypeRequiredDefaultDescription
--selectorstringyesLabel selector expression, e.g. env=production.
--relationstringnoreadReBAC relation the caller must hold on a match.
--scopestringnoplatformTenancy scope to resolve within (platform | domain | project). Unknown value → exit 2.
--scope-idstringnoDomain or Project UUID. Required for --scope domain/project; the API rejects a mismatched pair with 400.
--kindstringnoOptional object-kind filter, e.g. project.
--cursorstringnoOpaque continuation cursor from a previous page.
--limitint32no0Upper bound on the pre-filter page size (0 = server default).

Persistent flags inherited from root

--server, --profile, --token-file, --output, --yes, --reveal-secrets. The --yes flag is consumed by define delete and object delete (the destructive label subcommands); the others apply unchanged. See plexctl.md for the canonical list.

Exit codes

plexctl collapses every failure into the taxonomy below; the single source of truth is exitCodeFor in ../../../cmd/plexctl/app.go.

CodeReachableMeaning
0yesThe API returned the expected status (201 for define create, 200 for list / get / update / preview / object set / object list / object search, 204 for the deletes).
1yesRuntime / API error: transport failure, unexpected status code, a malformed response body, or a delete subcommand invoked without the persistent --yes flag.
2yesFlag-parse / misconfiguration: missing required flag, malformed UUID, or an unknown --type / --scope / --on-delete value.
3yesMissing or insecure credentials, or 401 Unauthorized from the API.
4yesPermission denied: 403 Forbidden from the API (e.g. the operator lacks domain:manage on a domain-scoped Definition).
64noNot reachable — label is fully implemented and never returns *NotImplementedError.

Examples

The examples below resolve the server from the exported PLEXSPHERE_URL environment variable. plexctl reads it automatically (precedence: --server flag → PLEXSPHERE_URL → the server plexctl login persisted in the profile), so --server is only needed to override that for a single call — the examples omit it.

Create an enum Label Definition

shell
export PLEXSPHERE_URL="${PLEXSPHERE_URL:-https://localhost:8080}"

plexctl label define create \
  --scope            domain \
  --scope-id         0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0a0 \
  --key              env \
  --type             enum \
  --applicable-kinds node,project \
  --enum-values      prod,staging,dev \
  --required         \
  --on-delete        block

Parse-test a selector

Clauses are joined by a comma — the comma is the AND operator; there is no AND keyword. The default text format prints one row per parsed AST node, indented to show nesting: the and row is the root of a multi-clause selector and the clauses it composes are indented two spaces beneath it.

shell
plexctl label selector preview \
  --selector 'env in (prod, staging), tier = backend'
text
OP    KEY   VALUE    VALUES
and
  in  env            prod,staging
  eq  tier  backend

--output json emits the typed AST instead (op/key/value/values with nested children), which is the shape to pipe through jq.

Set a Label on a Node

shell
plexctl label object set node:0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0e0 \
  --definition-id 0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0a1 \
  --value         prod

Find every object I can read that carries env=production

shell
plexctl label object search \
  --selector "env=production" \
  --relation read
# KIND     ID
# project  0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0aa
# node     0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0bb

Narrow to a Domain and a single kind:

shell
plexctl label object search \
  --selector "acme/env=production" \
  --scope    domain \
  --scope-id 0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a000 \
  --kind     project \
  --output   json

Permission denied on a domain-scoped Definition (exit 4)

shell
plexctl label define delete \
  --id     0190a8b8-a0c0-7a0a-8a0a-a0a0a0a0a0a1 \
  --yes
# stderr: plexctl: 403 Forbidden: insufficient_relation (need domain:manage)
echo $?  # 4

Cross-references

  • ../../../api/openapi/plexsphere-v1.yamlCreateLabelDefinition, ListLabelDefinitions, GetLabelDefinition, UpdateLabelDefinition, DeleteLabelDefinition, PreviewLabelSelector, PutObjectLabel, ListObjectLabels, DeleteObjectLabel, SearchObjectsByLabel operation definitions and the LabelDefinition, LabelDefinitionListResponse, LabelAssignment, LabelAssignmentList, LabelSelectorPreviewResponse schemas.
  • ../../contexts/labels/index.md — bounded-context reference for the Label aggregate, the value schema kinds, the qualified-key contract, the on-delete policy matrix, and the selector grammar.
  • ../../../cmd/plexctl/commands/label.go — source of truth for the cobra command, flag wiring, the AST walk in text mode, and the kind:id parser.