Skip to main content
Version: 1.2

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​

What kubectl handles on its own​

Hub APIs serve the get, list, create, update, and delete verbs. kubectl uses them directly:

You want toUse
Read one object or list a collectionkubectl get
Create an objectkubectl create -f
Change an existing objectkubectl replace -f with the full object
Delete an objectkubectl delete

Hub APIs don't serve patch, watch, or deletecollection. As a result:

  • kubectl apply works the first time, when it creates the object, but fails with 405 against an object that already exists. Use kubectl replace.
  • kubectl edit, kubectl patch, and kubectl label fail, because they send a patch. Read the object with kubectl get -o yaml, change it, and kubectl replace -f the result.
  • kubectl get --watch fails. 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:

ParameterWhat it does
searchMatches a substring against a set of identity fields defined per resource.
filterKeeps the items that match a filter expression. Needs URL encoding.
sortOrders the results by one or more fields.
page, pageSizeReturns one page of results. See Page through results.
transformMetadataOnly 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:

RequestWhat Hub returns
page and pageSizeOne page. Pages count from 1. pageSize defaults to 100, and a value above 500 returns 500.
limit and continueOne chunk and a continue value for the next. kubectl get reads lists this way.
NeitherThe 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:

StatusUsual cause
400An invalid filter expression, sort field, or page value.
403Your roles don't grant the verb, or you're changing an object you don't own, such as another user's lens.
404The object doesn't exist, or the feature that serves the endpoint isn't turned on.
405kubectl 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.

Next steps​