Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion docs/api-reference/catalogd-api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,26 @@ _Appears in:_
| --- | --- | --- | --- |
| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | conditions is a representation of the current state for this ClusterCatalog.<br />The status is represented by a set of "conditions".<br /><br />Each condition is generally structured in the following format:<br /> - Type: a string representation of the condition type. More or less the condition "name".<br /> - Status: a string representation of the state of the condition. Can be one of ["True", "False", "Unknown"].<br /> - Reason: a string representation of the reason for the current state of the condition. Typically useful for building automation around particular Type+Reason combinations.<br /> - Message: a human-readable message that further elaborates on the state of the condition.<br /><br />The current set of condition types are:<br /> - "Serving", which represents whether or not the contents of the catalog are being served via the HTTP(S) web server.<br /> - "Progressing", which represents whether or not the ClusterCatalog is progressing towards a new state.<br /><br />The current set of reasons are:<br /> - "Succeeded", this reason is set on the "Progressing" condition when progressing to a new state is successful.<br /> - "Blocked", this reason is set on the "Progressing" condition when the ClusterCatalog controller has encountered an error that requires manual intervention for recovery.<br /> - "Retrying", this reason is set on the "Progressing" condition when the ClusterCatalog controller has encountered an error that might be resolvable on subsequent reconciliation attempts.<br /> - "Available", this reason is set on the "Serving" condition when the contents of the ClusterCatalog are being served via an endpoint on the HTTP(S) web server.<br /> - "Unavailable", this reason is set on the "Serving" condition when there is not an endpoint on the HTTP(S) web server that is serving the contents of the ClusterCatalog. | | |
| `resolvedSource` _[ResolvedCatalogSource](#resolvedcatalogsource)_ | resolvedSource contains information about the resolved source based on the source type.<br /><br />Below is an example of a resolved source for an image source:<br />resolvedSource:<br /><br /> image:<br /> lastSuccessfulPollAttempt: "2024-09-10T12:22:13Z"<br /> ref: quay.io/operatorhubio/catalog@sha256:c7392b4be033da629f9d665fec30f6901de51ce3adebeff0af579f311ee5cf1b<br /> type: Image | | |
| `contentURL` _string_ | contentURL is a cluster-internal URL from which on-cluster components<br />can read the content of a catalog | | |
| `urls` _[ClusterCatalogURLs](#clustercatalogurls)_ | urls contains the URLs that can be used to access the catalog. | | |
| `lastUnpacked` _[Time](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#time-v1-meta)_ | lastUnpacked represents the time when the<br />ClusterCatalog object was last unpacked successfully. | | |


#### ClusterCatalogURLs



ClusterCatalogURLs contains the URLs that can be used to access the catalog.



_Appears in:_
- [ClusterCatalogStatus](#clustercatalogstatus)

| Field | Description | Default | Validation |
| --- | --- | --- | --- |
| `base` _string_ | base is a required cluster-internal URL which provides API access for this ClusterCatalog.<br />A suffix API access path can be added to retrieve catalog data for the ClusterCatalog.<br />Currently, a 'v1' API access provides complete FBC retrival via the path "/api/v1/all", with the general form `\{base\}/api/v1/all`. | | Required: \{\} <br /> |


#### ImageSource


Expand Down
15 changes: 9 additions & 6 deletions docs/api-reference/catalogd-webserver.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@
[Catalogd](https://github.com/operator-framework/catalogd), the OLM v1 component for making catalog contents available on cluster, includes
a web server that serves catalog contents to clients via an HTTP(S) endpoint.

The endpoint to retrieve this information is provided in the `.status.contentURL` of a `ClusterCatalog` resource.
As an example:
The endpoint to retrieve this information can be composed from the `.status.urls.base` of a `ClusterCatalog` resource with the selected access API path.
As an example, to access the full FBC via the v1 API endpoint (indicated by path `api/v1/all`) where `.status.urls.base` is

```yaml
contentURL: https://catalogd-service.olmv1-system.svc/catalogs/operatorhubio/all.json
urls:
base: https://catalogd-service.olmv1-system.svc/catalogs/operatorhubio
```

the URL to access the service would be `https://catalogd-service.olmv1-system.svc/catalogs/operatorhubio/api/v1/all`

!!! note

The value of the `.status.contentURL` field in a `ClusterCatalog` resource is an arbitrary string value and can change at any time.
While there are no guarantees on the exact value of this field, it will always be a URL that resolves successfully for clients using
it to make a request from within the cluster.
The values of the `.status.urls` field in a `ClusterCatalog` resource are arbitrary string values and can change at any time.
While there are no guarantees on the exact value of this field, it will always contain catalog-specific API endpoints for use
by clients to make a request from within the cluster.

## Interacting With the Server

Expand Down
2 changes: 1 addition & 1 deletion docs/howto/catalog-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The following examples will show this default behavior, but for simplicity's sak
You can use the `curl` command with `jq` to query catalogs that are installed on your cluster.

``` terminal title="Query syntax"
curl -k https://localhost:8443/catalogs/operatorhubio/all.json | <query>
curl -k https://localhost:8443/catalogs/operatorhubio/api/v1/all | <query>
```

## Package queries
Expand Down
3 changes: 2 additions & 1 deletion docs/tutorials/add-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ This catalog is distributed as an image [quay.io/operatorhubio/catalog](https://
Reason: Available
Status: True
Type: Serving
Content URL: https://catalogd-server.olmv1-system.svc/catalogs/operatorhubio/all.json
URLs:
Base: https://catalogd-server.olmv1-system.svc/catalogs/operatorhubio
Last Unpacked: 2024-03-12T19:35:34Z
Resolved Source:
Image:
Expand Down
8 changes: 4 additions & 4 deletions docs/tutorials/explore-available-content.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ The following examples will show this default behavior, but for simplicity's sak
kubectl -n olmv1-system port-forward svc/catalogd-service 8443:443
```

2. Return a list of all the extensions in a catalog:
2. Return a list of all the extensions in a catalog via the v1 API endpoint:
``` terminal
curl -k https://localhost:8443/catalogs/operatorhubio/all.json | jq -s '.[] | select(.schema == "olm.package") | .name'
curl -k https://localhost:8443/catalogs/operatorhubio/api/v1/all | jq -s '.[] | select(.schema == "olm.package") | .name'
```

??? success
Expand Down Expand Up @@ -96,7 +96,7 @@ The following examples will show this default behavior, but for simplicity's sak
* Return list of packages that support `AllNamespaces` install mode and do not use webhooks:

``` terminal
curl -k https://localhost:8443/catalogs/operatorhubio/all.json | jq -c 'select(.schema == "olm.bundle") | {"package":.package, "version":.properties[] | select(.type == "olm.bundle.object").value.data | @base64d | fromjson | select(.kind == "ClusterServiceVersion" and (.spec.installModes[] | select(.type == "AllNamespaces" and .supported == true) != null) and .spec.webhookdefinitions == null).spec.version}'
curl -k https://localhost:8443/catalogs/operatorhubio/api/v1/all | jq -c 'select(.schema == "olm.bundle") | {"package":.package, "version":.properties[] | select(.type == "olm.bundle.object").value.data | @base64d | fromjson | select(.kind == "ClusterServiceVersion" and (.spec.installModes[] | select(.type == "AllNamespaces" and .supported == true) != null) and .spec.webhookdefinitions == null).spec.version}'
```

??? success
Expand Down Expand Up @@ -127,7 +127,7 @@ The following examples will show this default behavior, but for simplicity's sak
3. Inspect the contents of an extension's metadata:

``` terminal
curl -k https://localhost:8443/catalogs/operatorhubio/all.json | jq -s '.[] | select( .schema == "olm.package") | select( .name == "<package_name>")'
curl -k https://localhost:8443/catalogs/operatorhubio/api/v1/all | jq -s '.[] | select( .schema == "olm.package") | select( .name == "<package_name>")'
```

`package_name`
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/onsi/gomega v1.34.2
github.com/opencontainers/go-digest v1.0.0
github.com/operator-framework/api v0.27.0
github.com/operator-framework/catalogd v0.33.0
github.com/operator-framework/catalogd v0.34.0
github.com/operator-framework/helm-operator-plugins v0.5.0
github.com/operator-framework/operator-registry v1.47.0
github.com/spf13/pflag v1.0.5
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,8 @@ github.com/openshift/crd-schema-checker v0.0.0-20240404194209-35a9033b1d11 h1:eT
github.com/openshift/crd-schema-checker v0.0.0-20240404194209-35a9033b1d11/go.mod h1:EmVJt97N+pfWFsli/ipXTBZqSG5F5KGQhm3c3IsGq1o=
github.com/operator-framework/api v0.27.0 h1:OrVaGKZJvbZo58HTv2guz7aURkhVKYhFqZ/6VpifiXI=
github.com/operator-framework/api v0.27.0/go.mod h1:lg2Xx+S8NQWGYlEOvFwQvH46E5EK5IrAIL7HWfAhciM=
github.com/operator-framework/catalogd v0.33.0 h1:hnLIFykO1FkjOAUFRPuYRIHQTE0oBF9jkGmWjKhxniQ=
github.com/operator-framework/catalogd v0.33.0/go.mod h1:anZurjcFMBvbkuyqlJ98v9z+yjniPKqmhlyitk9DuBQ=
github.com/operator-framework/catalogd v0.34.0 h1:zzCUTVrRJ4oCnjvAdairEWbUejLUnYRVsvAyhfREpyU=
github.com/operator-framework/catalogd v0.34.0/go.mod h1:anZurjcFMBvbkuyqlJ98v9z+yjniPKqmhlyitk9DuBQ=
github.com/operator-framework/helm-operator-plugins v0.5.0 h1:qph2OoECcI9mpuUBtOsWOMgvpx52mPTTSvzVxICsT04=
github.com/operator-framework/helm-operator-plugins v0.5.0/go.mod h1:yVncrZ/FJNqedMil+055fk6sw8aMKRrget/AqGM0ig0=
github.com/operator-framework/operator-lib v0.15.0 h1:0QeRM4PMtThqINpcFGCEBnIV3Z8u7/8fYLEx6mUtdcM=
Expand Down
16 changes: 9 additions & 7 deletions hack/tools/catalogs/download-catalog
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,14 @@ if [ "$UNPACKED_CONDITION" != "True" ]; then
exit 1
fi

# Get the contentURL
CONTENT_URL=$(echo "$CLUSTER_CATALOG" | jq -r '.status.contentURL')
if [ -z "$CONTENT_URL" ]; then
echo "Content URL not found for ClusterCatalog $CATALOG_NAME."
# Construct the API URL from the ClusterCatalog status
CATALOG_API_URL=$(echo "$CLUSTER_CATALOG" | jq -r '.status.urls.base')
if [ -z "$CATALOG_API_URL" ]; then
echo "ClusterCatalog $CATALOG_NAME does not express API endpoint in '.status.urls.base'."
exit 1
fi
# Assemble the v1 API URL from the base endpoint
CATALOG_CONTENT_URL="${CATALOG_API_URL}/api/v1/all"

# Start port forwarding
echo "Starting kubectl port-forward to $CATALOGD_SERVICE_NAME on port $CATALOGD_LOCAL_SERVICE_PORT..."
Expand All @@ -77,9 +79,9 @@ while ! curl -s "http://localhost:${CATALOGD_LOCAL_SERVICE_PORT}" >/dev/null; do
sleep 1
done

# Modify the contentURL to hit localhost:<port>
LOCAL_CONTENT_URL=${CONTENT_URL//https:\/\/$CATALOGD_SERVICE_NAME.$CATALOGD_CATALOGD_SERVICE_NAMESPACE.svc/https:\/\/localhost:$CATALOGD_LOCAL_SERVICE_PORT}
echo "Found content URL: $CONTENT_URL"
# Modify the catalogd service endpoint URL to hit localhost:<port>
LOCAL_CONTENT_URL=${CATALOG_CONTENT_URL//https:\/\/$CATALOGD_SERVICE_NAME.$CATALOGD_CATALOGD_SERVICE_NAMESPACE.svc/https:\/\/localhost:$CATALOGD_LOCAL_SERVICE_PORT}
echo "Calculated catalogd API pathcontent URL: $CATALOG_CONTENT_URL"
echo "Using local port: $CATALOGD_LOCAL_SERVICE_PORT"
echo "Using local content URL: $LOCAL_CONTENT_URL"

Expand Down
16 changes: 15 additions & 1 deletion internal/catalogmetadata/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"io/fs"
"net/http"
"net/url"

"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -15,6 +16,10 @@ import (
"github.com/operator-framework/operator-registry/alpha/declcfg"
)

const (
clusterCatalogV1ApiURL = "api/v1/all"
)

type Cache interface {
// Get returns cache for a specified catalog name and version (resolvedRef).
//
Expand Down Expand Up @@ -113,7 +118,16 @@ func (c *Client) PopulateCache(ctx context.Context, catalog *catalogd.ClusterCat
}

func (c *Client) doRequest(ctx context.Context, catalog *catalogd.ClusterCatalog) (*http.Response, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, catalog.Status.ContentURL, nil)
if catalog.Status.URLs == nil {
return nil, fmt.Errorf("error: catalog %q has a nil status.urls value", catalog.Name)
}

catalogdURL, err := url.JoinPath(catalog.Status.URLs.Base, clusterCatalogV1ApiURL)
if err != nil {
return nil, fmt.Errorf("error forming catalogd API endpoint: %v", err)
}

req, err := http.NewRequestWithContext(ctx, http.MethodGet, catalogdURL, nil)
if err != nil {
return nil, fmt.Errorf("error forming request: %v", err)
}
Expand Down
4 changes: 3 additions & 1 deletion internal/catalogmetadata/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ func defaultCatalog() *catalogd.ClusterCatalog {
ResolvedSource: &catalogd.ResolvedCatalogSource{Image: &catalogd.ResolvedImageSource{
Ref: "fake/catalog@sha256:fakesha",
}},
ContentURL: "https://fake-url.svc.local/all.json",
URLs: &catalogd.ClusterCatalogURLs{
Base: "https://fake-url.svc.local/catalogs/catalog-1",
},
},
}
}
Expand Down
Loading