Query packages with the API
Use the Insights API to follow a package rollout from your own tooling, such as a pipeline step that waits until every control plane declares the new version, or a check that flags control planes still pinned to an old one.
Before you begin
- A
hubkubectl context. See Configure kubectl for the Hub. - Permission to read package objects, such as
ProviderorFunction, on at least one control plane. See the Roles reference. - At least one connected control plane or space.
jq.
Several steps send query parameters with kubectl get --raw. Use Hub APIs with
kubectl explains why, and how paging, sorting,
and counts work.
List packages
Packages are crossplanepackages in the inventory.hub.upbound.io/v1beta1 API
group. They're globally scoped, so the path has no namespace.
kubectl --context=hub get --raw \
'/apis/inventory.hub.upbound.io/v1beta1/crossplanepackages?pageSize=25' \
| jq -r '.items[] | [.definition.packageType, .definition.packageRepo, .summary.controlPlaneCount, .summary.versionCount] | @tsv'
Each item has two parts:
| Field | Contains |
|---|---|
definition | packageType, one of provider, configuration, function, or addon, and packageRepo, the repository without a tag or digest. |
summary | controlPlaneCount and versionCount. See Versions for how Hub counts versions. |
Search with search, which matches part of the repository. Sort with sort,
using name, packageType, controlPlaneCount, versionCount, createdAt,
or updatedAt. name sorts by repository. Prefix a field with - to sort in
descending order.
Find version skew
List the packages that run at more than one version, most versions first:
kubectl --context=hub get --raw \
'/apis/inventory.hub.upbound.io/v1beta1/crossplanepackages?sort=-versionCount&pageSize=100' \
| jq -r '.items[] | select(.summary.versionCount > 1) | [.summary.versionCount, .definition.packageRepo] | @tsv'
To narrow a list, filter with an expression on these fields, and URL-encode it. See Encode a filter expression.
| Filter field | Type | Matches |
|---|---|---|
packageType | string | provider, configuration, function, or addon. |
controlPlane | string | Packages declared on the named control plane. |
realm | string | Packages declared on a control plane in the named realm. |
FILTER=$(jq -rn --arg f 'packageType == "function" && controlPlane in ["webapp-us-west-1"]' '$f|@uri')
kubectl --context=hub get --raw \
"/apis/inventory.hub.upbound.io/v1beta1/crossplanepackages?pageSize=100&filter=$FILTER" \
| jq -r '.items[].definition.packageRepo'
Get one package
A package's name is its type and repository, joined by a dot, with every / in
the repository replaced by ~:
kubectl --context=hub get --raw \
'/apis/inventory.hub.upbound.io/v1beta1/crossplanepackages/function.xpkg.crossplane.io~crossplane-contrib~function-patch-and-transform'
See where each version runs
The distribution subresource lists each version and the control planes that
declare it:
kubectl --context=hub get --raw \
'/apis/inventory.hub.upbound.io/v1beta1/crossplanepackages/function.xpkg.crossplane.io~crossplane-contrib~function-patch-and-transform/distribution' \
| jq -r '.versions[] | .name as $v | .controlPlanes[] | [$v, .realm, .name, .crName] | @tsv'
Each entry in versions has the version's name, a tag or a digest, and a
controlPlanes list. Each row in that list has:
| Field | Contains |
|---|---|
name and realm | The control plane and its realm. |
crName | The name of the package object on the control plane. |
packageRef | The package reference exactly as the package object declares it. |
The distribution shows what each control plane declares, not whether the package installed. To check a package's health, query its package object in the resource list.
Troubleshoot
| Status | Cause |
|---|---|
404 on every request | Your platform team turned off the AggregatedTypes feature flag. |
404 for one package | You don't have permission to read a package object that declares it. See Access-scoped results. |
400 with "must be in the format" | The name is missing its package type, or the repository still contains /. |
400 on a list | The filter expression doesn't parse, or names a field or sort key the API doesn't accept. |