CLI Reference
opampctl is a kubectl-style command-line client for the OpAMP Commander apiserver.
It manages agents, agent groups, packages, remote configs, certificates, namespaces,
users, roles, and role bindings.
Installation
go install github.com/minuk-dev/opampcommander/cmd/opampctl@latest
Or build from source:
git clone https://github.com/minuk-dev/opampcommander.git
cd opampcommander
go build -o opampctl ./cmd/opampctl
Configuration
Initialize a configuration file:
opampctl config init
This creates ~/.config/opampcommander/opampctl/config.yaml. The format follows the
kubectl model of contexts, clusters, and users:
currentContext: default-1
contexts:
- name: default-1
cluster: default
user: admin
- name: default-2
cluster: default
user: githubuser
- name: default-3
cluster: default
user: manual
users:
- name: admin
auth:
type: basic
username: admin
password: admin
- name: githubuser
auth:
type: github # browser or device OAuth flow
- name: manual
auth:
type: manual
bearerToken: "<your-bearer-token>"
clusters:
- name: default
opampcommander:
endpoint: http://localhost:8080
Three authentication types are supported per user:
basic— username/password basic authgithub— GitHub OAuth (browser or device flow; see--auth-flow)manual— a bearer token you supply directly
View the active configuration:
opampctl config view
Global flags
These flags apply to every command:
| Flag | Default | Description |
|---|---|---|
-c, --config | ~/.config/opampcommander/opampctl/config.yaml | Path to the config file |
-v, --verbose | false | Verbose output (equivalent to --log.level=debug) |
--log.format | text | Log format (text, json) |
--log.level | info | Log level (debug, info, warn) |
--auth-flow | — | Override the GitHub auth flow: browser or device |
Command overview
| Command | Description |
|---|---|
get | List or read resources |
create | Create resources (often from a -f manifest file) |
set | Update fields of a resource |
delete | Delete resources |
template | Print example manifests (template examples ...) |
restart | Send a restart command to agents |
config | Manage the local config file (init, view) |
context | Switch between contexts (ls, use) |
whoami | Show the authenticated identity |
version | Show client version |
Resource types
get, create, and delete operate on these resource types:
agent, agentgroup, agentpackage, agentremoteconfig, certificate,
connection (get only), container (get only), host (get only), namespace,
user, role, rolebinding.
Lookup failures
When you request specific identities, opampctl get prints successful results in
request order and reports each failed target with its identity and cause on stderr.
Any failed lookup (including invalid UIDs, missing resources, permission errors,
or timeouts) makes the command exit with status 1, even if other targets succeeded.
JSON/YAML stdout contains only the successful result array, or [] if none succeeded.
Bounded inventory lists
get agent, agentgroup, connection, endpoint, certificate, agentpackage,
agentremoteconfig, and remoteconfigschema print one page of at most 100 items
by default, including with --all-namespaces (-A). This replaces the previous
implicit full-inventory listing. Use --page-size (1–1000) to choose the request
size, --continue to resume, or --stream to explicitly traverse all pages.
opampctl get agent -n production --page-size 50
# Copy the cursor printed on stderr, keeping namespace and filters unchanged:
opampctl get agent -n production --page-size 50 --continue '<cursor>'
opampctl get agentgroup -A --stream -o json > groups.json
Text/short output is flushed after each page, with a header per page. JSON is one valid array on successful completion. Streaming YAML is a sequence of documents, each containing one page’s array. All formats retain only a page in memory. Across namespaces, a page covers one namespace; even an empty page may print a resume cursor for the next namespace.
Ctrl+C, an API error, or a failed output write stops traversal with a nonzero exit status. Stdout may contain incomplete JSON or partial YAML/text; stderr reports the cause and a retry cursor. Retrying a failed page can replay items already written from that page. Resume with the same resource, namespace scope, and filters. These are live reads, so inventory changes between pages can affect results; cursors do not provide a snapshot or survive every server-side change.
Filtering
opampctl get accepts four filtering flags on every resource whose list endpoint
answers them. The server does the filtering, so narrowing a view is a smaller query
rather than a larger fetch.
| Flag | Filters on |
|---|---|
-l, --selector | the resource’s labels or reported attributes, Kubernetes-style |
--field-selector | the resource’s own fields |
--name | a case-sensitive name prefix |
--name-contains | a case-insensitive name substring (a scan — pair it with --name on a large collection) |
-l/--selector sends whichever metadata parameter the resource answers —
labelSelector for metadata an operator set, attributeSelector for what an agent
reported about itself. A command already names its resource, so there is nothing to
disambiguate; see the API reference
for why the server keeps them apart. Resources with neither kind (roles, role
bindings) have no -l flag at all.
# agents in production that are not canaries
opampctl get agent -l 'service.namespace=prod,tier notin (canary,dev)'
# an agent's non-identifying attributes are part of the same attribute domain
opampctl get agent -l os.type=linux
# unhealthy agents
opampctl get agent --field-selector status.healthy=false
# endpoints whose name starts with tempo-
opampctl get endpoint --name tempo-
Expressions are parsed before the request is made, so a typo is a local error
naming the flag rather than a round-tripped 400. Which fields a resource supports
is not repeated in --help: the server owns that list and names it on rejection.
See the API reference for the full syntax and the
per-resource field lists.
Two listings take no selectors — get agent --agentgroup and
get agentgroup --agent, which read a group’s membership. There the label and name
filters are applied locally rather than dropped, and --field-selector is rejected,
because a caller must never mistake the whole membership for a narrowed one.
--non-identifying-selector is deprecated: -l/--selector reaches an agent’s
non-identifying attributes too.
Contexts
opampctl context ls # list contexts, highlighting the current one
opampctl context use default-2 # switch context
Authentication status
opampctl whoami
Agents
# list agents in the default namespace
opampctl get agent
# output formats: short (default), text, json, yaml
opampctl get agent -o yaml
# filter by agent group
opampctl get agent --agentgroup my-group -n my-namespace
# filter by label, server-side (see Filtering above)
opampctl get agent -l service.name=otel-collector
# across all namespaces
opampctl get agent -A
Update an agent (for example, assign a new instance UID):
opampctl set instance-uid agent/<instance-uid> <new-uid> -n default
Restart agents:
opampctl restart agent <instance-uid>
Agent groups
opampctl get agentgroup
opampctl get agentgroup <name>
# offer an existing certificate to the group's sole agent
opampctl set opamp-certificate agentgroup/<name> <certificate-name>
# create from a manifest file
opampctl create agentgroup -f ./agentgroup.yaml
# print an example manifest to start from
opampctl template examples agentgroup
opampctl delete agentgroup <name>
Most create commands accept -f/--file pointing at a YAML manifest. Use
opampctl template examples <resource> to print a starting template for a resource
type (agentgroup, agentpackage, agentremoteconfig, certificate, namespace,
role, rolebinding).
Connections
opampctl get connection # active agent connections
Users and RBAC
# create a user, optionally with a basic-auth password
opampctl create user --username alice --email alice@example.com --password-stdin
opampctl get user
opampctl get role
opampctl get rolebinding
opampctl create role -f ./role.yaml
opampctl create rolebinding -f ./rolebinding.yaml
create user flags include --username, --email, --password,
--password-stdin, -f/--file, and -o/--output.
Version
opampctl version
Troubleshooting
Config file not found — run opampctl config init to create a default file, or
pass --config with the correct path.
Authentication errors — verify your identity with opampctl whoami, check the
endpoint with opampctl config view, and confirm the user’s auth block in the
config file. For GitHub users, try --auth-flow device if a browser is unavailable.
Connection issues — ensure the apiserver is running and reachable at the cluster’s
endpoint, and that the value matches the running server’s --address.
Remote-config schema workflow
A RemoteConfigSchema describes a collector distribution/version and its component
catalog. Generate it from the collector you deploy, then create it in the same
namespace as your remote config:
opampctl generate remoteconfigschema --binary-path ./otelcol-contrib > schema.yaml
opampctl create remoteconfigschema -n default -f schema.yaml
opampctl get remoteconfigschema -n default
The generator uses the collector’s reported build command and version by default.
Use --namespace when generating a manifest for a namespace other than default;
create -f uses the namespace in that manifest. You can also read saved or piped
components output and choose JSON instead of the default YAML:
./otelcol-contrib components > components.yaml
opampctl generate remoteconfigschema --from components.yaml --namespace collectors \
-o json > schema.json
opampctl create remoteconfigschema -f schema.json
./otelcol-contrib components | opampctl generate remoteconfigschema --from - > schema.yaml
--binary, --version, and --name override the reported build identity and the
default schema name (<command>-<version>). --binary-path selects the executable;
--binary only sets the distribution label stored in the schema.
Use the name from the generated manifest’s metadata.name as SCHEMA below.
For a hand-written example, run opampctl template remoteconfigschema basic;
edit its name, version and component catalog to match your binary before creating
it. A catalog without field schemas only describes component availability.
# collector.yaml is a raw collector config, not an AgentRemoteConfig manifest.
opampctl create agentremoteconfig --name my-config -n default -f collector.yaml \
--schema-ref SCHEMA
# Repeat --schema-ref to target more than one catalog.
opampctl set schemaref my-config -n default --schema-ref SCHEMA --schema-ref SECOND_SCHEMA
# Remove all references without re-sending the collector config.
opampctl set schemaref my-config -n default --clear
set schemaref replaces the complete reference list, or clears it with --clear.
It reads the current resource version and sends only that precondition and
spec.schemaRefs in a merge PATCH. Config content, content type and attributes
are preserved. If another writer changes the resource, the command reports a
conflict; re-read the resource before retrying. Clearing references on an existing
config does not rerun creation-time auto-resolution.
When creating a remote config without explicit references, the server attempts best-effort matching against the schema catalogs in its namespace. Explicit references take precedence. To opt out, use:
opampctl create agentremoteconfig --name unpinned-config -n default -f collector.yaml \
--skip-schema-validation
This sets the metadata attribute
opampcommander.io/skip-schema-validation: "true", which disables automatic schema
matching. It does not remove explicit references. The annotation is the schema
validation opt-out marker; a schema reference alone is not proof that an agent has
accepted or successfully applied the config.
opampctl get remoteconfigschema shows the component count across catalog classes.
opampctl get agentremoteconfig shows schemaRefs and schemaRefsSource: explicit
for user-selected references, auto for creation-time matches, none when empty,
and unknown for legacy references without recorded provenance. Source is
server-managed; reapplying an unchanged list preserves its existing source.
Feedback
Was this page helpful?