Use Hub APIs with kubectl
With a hub context set up, kubectl works against Hub APIs much as it does
against a Kubernetes cluster. However, kubectl doesn't natively support all of
the features Hub offers: free-text search, filter expressions, sorting,
page-by-page reads, and query resources that return a result instead of storing
an object. This page covers those differences once, so the feature guides can
link here instead of repeating them.
Before you begin
- A
hubkubectl context. See Configure kubectl for the Hub. - Permission for what you want to do. Each Hub API grants its verbs through your roles. See the Roles reference.
jq, to encode filter expressions and read responses.
What kubectl handles on its own
Hub APIs serve the get, list, create, update, and delete verbs.
kubectl uses them directly:
| You want to | Use |
|---|---|
| Read one object or list a collection | kubectl get |
| Create an object | kubectl create -f |
| Change an existing object | kubectl replace -f with the full object |
| Delete an object | kubectl delete |
Hub APIs don't serve patch, watch, or deletecollection. As a result:
kubectl applyworks the first time, when it creates the object, but fails with405against an object that already exists. Usekubectl replace.kubectl edit,kubectl patch, andkubectl labelfail, because they send a patch. Read the object withkubectl get -o yaml, change it, andkubectl replace -fthe result.kubectl get --watchfails. Run the command again to see changes.
kubectl get reads a long list in chunks and joins them, so it returns the
whole collection.
Send query parameters with --raw
List endpoints take query parameters that kubectl get has no flag for. Send
them with kubectl get --raw and the full API path:
| Parameter | What it does |
|---|---|
search | Matches a substring against a set of identity fields defined per resource. |
filter | Keeps the items that match a filter expression. Needs URL encoding. |
sort | Orders the results by one or more fields. |
page, pageSize | Returns one page of results. See Page through results. |
transform | MetadataOnly drops each item's heavyweight fields, for when you only need names. |
kubectl --context=hub get --raw \
'/apis/inventory.hub.upbound.io/v1beta1/resources?search=payments&pageSize=25'
--raw returns the API response as JSON. We recommend you use jq to pick out
individual fields.
Encode a filter expression
Any endpoint that takes a filter parameter needs the expression URL-encoded,
because expressions contain quotes, spaces, and operators. Encode the
expression with jq, then add it to the request path:
FILTER=$(jq -rn --arg f 'kind == "Bucket" && realm == "production"' '$f|@uri')
kubectl --context=hub get --raw \
"/apis/inventory.hub.upbound.io/v1beta1/resources?pageSize=100&filter=$FILTER"
The same encoded value works on every endpoint that accepts filter. Change
the path to query another one.
Sort results
sort takes a comma-separated list of fields, applied in order. Prefix a
field with - to sort it descending:
kubectl --context=hub get --raw \
'/apis/inventory.hub.upbound.io/v1beta1/resources?sort=kind,-createdAt&pageSize=25'
Each endpoint defines its own sortable fields. An unknown field returns an error.
Page through results
A list request reads its results in one of three ways:
| Request | What Hub returns |
|---|---|
page and pageSize | One page. Pages count from 1. pageSize defaults to 100, and a value above 500 returns 500. |
limit and continue | One chunk and a continue value for the next. kubectl get reads lists this way. |
| Neither | The whole collection, as long as it holds 500 items or fewer. A larger collection returns an error that asks you to page. |
Always set pageSize on a --raw list request, so the request still works
when the collection grows past 500 items.
Every paged response reports the number of matches in metadata.total:
{
"metadata": {
"total": { "count": 1000, "relation": "gt" },
"page": 1,
"pageSize": 100
}
}
count is exact up to 1000, and relation is eq. Above 1000, count reads
1000 and relation is gt. A chunked response reports a lower bound for the
same reason. For an exact count of resources, use
resourcestats.
Read a subresource
Some endpoints belong to a single object, such as a resource's events, a
type's distribution, or a control plane's registrationtoken. kubectl get
can't address them, so request their path with --raw:
kubectl --context=hub get --raw \
"/apis/inventory.hub.upbound.io/v1beta1/resources/<name>/events"
Run a query resource
Some Hub resources, such as ResourceStats and the metrics Query, are
queries rather than objects. You create one with the query in its body, and Hub
returns the result in the response without storing anything. Create it with
-o json so you see the response:
kubectl --context=hub create -o json -f - <<'EOF'
apiVersion: inventory.hub.upbound.io/v1beta1
kind: ResourceStats
query: {}
EOF
Find the fields an endpoint accepts
Hub publishes an API reference at https://<hub-host>/docs, where
<hub-host> is the host of the Hub API URL your platform team gave you. For
every endpoint, it shows the request and response schemas, the values each
filter and sort field accepts, and example requests and responses.
kubectl and other Kubernetes clients read the request and response schemas
and field descriptions from Hub's OpenAPI documents, at /openapi/v2 and
/openapi/v3. The examples and the filter and sort values appear only in the
API reference.
Read an error
Hub returns errors in the Kubernetes Status shape. Read the message field
first. It names the field or parameter that failed:
| Status | Usual cause |
|---|---|
400 | An invalid filter expression, sort field, or page value. |
403 | Your roles don't grant the verb, or you're changing an object you don't own, such as another user's lens. |
404 | The object doesn't exist, or the feature that serves the endpoint isn't turned on. |
405 | kubectl apply, edit, or patch against an existing object. Use kubectl replace. |
A list that returns fewer items than you expect isn't an error. Hub returns only what you have permission to read. See Access-scoped results.