Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
fed0ad5
:bug: Client go version metrics endpoint test (#1821)
bentito Mar 5, 2025
7b92a88
:seedling: Bump golang.org/x/sync from 0.11.0 to 0.12.0 (#1842)
dependabot[bot] Mar 6, 2025
e69f1ec
:seedling: Bump jinja2 from 3.1.5 to 3.1.6 (#1844)
dependabot[bot] Mar 6, 2025
564f35a
Revert "(fix): update PSA versions to match Kubernetes API version" (…
camilamacedo86 Mar 6, 2025
e4e76d2
:seedling: Bump golang.org/x/tools from 0.30.0 to 0.31.0 (#1848)
dependabot[bot] Mar 6, 2025
dbd2bd9
🌱 Add catalogd metas service demo (#1840)
grokspawn Mar 10, 2025
995dc2b
:seedling: Bump cssselect from 1.2.0 to 1.3.0 (#1857)
dependabot[bot] Mar 10, 2025
029d19f
(fix) Remove "Serving" condition type from ConditionSets (#1859)
anik120 Mar 12, 2025
7061d92
🐛 fix crdupgradesafety diff when items schema differ (#1863)
joelanford Mar 12, 2025
66b97ad
:seedling: Bump mkdocs-material from 9.6.7 to 9.6.8 (#1865)
dependabot[bot] Mar 14, 2025
416fbdc
:seedling: Bump helm.sh/helm/v3 from 3.17.1 to 3.17.2 (#1866)
dependabot[bot] Mar 14, 2025
e8c281e
🐛 Ensure fixed order in multi-line errors returned by crdupgradesafet…
azych Mar 17, 2025
18a4638
(docs) draft catalogd docs with new metas endpoint (#1841)
anik120 Mar 17, 2025
c9fa0b5
:seedling: Bump mkdocs-material from 9.6.8 to 9.6.9 (#1869)
dependabot[bot] Mar 17, 2025
1a01acb
Merge branch 'main' into synchronize
Mar 18, 2025
95168db
UPSTREAM: <carry>: Add OpenShift specific files
dtfranz Oct 26, 2023
6e16304
UPSTREAM: <carry>: Fix catalogd.Dockerfile to use new paths
tmshort Feb 26, 2025
1ebcedd
UPSTREAM: <carry>: Update DOWNSTREAM_OWNERS_ALIASES
tmshort Mar 6, 2025
a4d2b2d
UPSTREAM: <drop>: go mod vendor
Mar 18, 2025
de8b4cd
UPSTREAM: <drop>: remove upstream GitHub configuration
Mar 18, 2025
e334c09
UPSTREAM: <drop>: configure the commit-checker
Mar 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
25 changes: 14 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,9 @@ generate: $(CONTROLLER_GEN) #EXHELP Generate code containing DeepCopy, DeepCopyI
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."

.PHONY: verify
verify: tidy fmt generate manifests crd-ref-docs update-k8s-values #HELP Verify all generated code is up-to-date.
verify: tidy fmt generate manifests crd-ref-docs #HELP Verify all generated code is up-to-date.
git diff --exit-code

.PHONY: update-k8s-values # HELP Update PSA labels in config manifests with Kubernetes version
update-k8s-values:
find config -type f -name '*.yaml' -exec \
sed -i.bak -E 's/(pod-security.kubernetes.io\/[a-zA-Z-]+-version:).*/\1 "v$(K8S_VERSION)"/g' {} +;
find config -type f -name '*.yaml.bak' -delete

.PHONY: fix-lint
fix-lint: $(GOLANGCI_LINT) #EXHELP Fix lint issues
$(GOLANGCI_LINT) run --fix --build-tags $(GO_BUILD_TAGS) $(GOLANGCI_LINT_ARGS)
Expand Down Expand Up @@ -192,7 +186,7 @@ test: manifests generate fmt lint test-unit test-e2e #HELP Run all tests.

.PHONY: e2e
e2e: #EXHELP Run the e2e tests.
go test -count=1 -v ./test/e2e/...
go test -count=1 -v -run "$(if $(TEST_FILTER),$(TEST_FILTER),.)" ./test/e2e/...

E2E_REGISTRY_NAME := docker-registry
E2E_REGISTRY_NAMESPACE := operator-controller-e2e
Expand All @@ -208,7 +202,10 @@ test-ext-dev-e2e: $(OPERATOR_SDK) $(KUSTOMIZE) $(KIND) #HELP Run extension creat
test/extension-developer-e2e/setup.sh $(OPERATOR_SDK) $(CONTAINER_RUNTIME) $(KUSTOMIZE) $(KIND) $(KIND_CLUSTER_NAME) $(E2E_REGISTRY_NAMESPACE)
go test -count=1 -v ./test/extension-developer-e2e/...

UNIT_TEST_DIRS := $(shell go list ./... | grep -v /test/)
# Define TEST_PKGS to be either user-specified or a default set of packages:
ifeq ($(origin TEST_PKGS), undefined)
TEST_PKGS := $(shell go list ./... | grep -v /test/)
endif
COVERAGE_UNIT_DIR := $(ROOT_DIR)/coverage/unit

.PHONY: envtest-k8s-bins #HELP Uses setup-envtest to download and install the binaries required to run ENVTEST-test based locally at the project/bin directory.
Expand All @@ -224,7 +221,8 @@ test-unit: $(SETUP_ENVTEST) envtest-k8s-bins #HELP Run the unit tests
-tags '$(GO_BUILD_TAGS)' \
-cover -coverprofile ${ROOT_DIR}/coverage/unit.out \
-count=1 -race -short \
$(UNIT_TEST_DIRS) \
-run "$(if $(TEST_FILTER),$(TEST_FILTER),.)" \
$(TEST_PKGS) \
-test.gocoverdir=$(COVERAGE_UNIT_DIR)

.PHONY: image-registry
Expand Down Expand Up @@ -303,10 +301,15 @@ kind-clean: $(KIND) #EXHELP Delete the kind cluster.

#SECTION Build

ifeq ($(origin VERSION), undefined)
# attempt to generate the VERSION attribute for certificates
# fail if it is unset afterwards, since the side effects are indirect
ifeq ($(strip $(VERSION)),)
VERSION := $(shell git describe --tags --always --dirty)
endif
export VERSION
ifeq ($(strip $(VERSION)),)
$(error undefined VERSION; resulting certs will be invalid)
endif

ifeq ($(origin CGO_ENABLED), undefined)
CGO_ENABLED := 0
Expand Down
8 changes: 8 additions & 0 deletions api/v1/clustercatalog_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ const (

AvailabilityModeAvailable AvailabilityMode = "Available"
AvailabilityModeUnavailable AvailabilityMode = "Unavailable"

// Condition types
TypeServing = "Serving"

// Serving Reasons
ReasonAvailable = "Available"
ReasonUnavailable = "Unavailable"
ReasonUserSpecifiedUnavailable = "UserSpecifiedUnavailable"
)

//+kubebuilder:object:root=true
Expand Down
63 changes: 30 additions & 33 deletions api/v1/clusterextension_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"go/ast"
"go/parser"
"go/token"
"io/fs"
"strconv"
"strings"
"testing"
Expand Down Expand Up @@ -52,49 +51,47 @@ func TestClusterExtensionReasonRegistration(t *testing.T) {
}
}

// parseConstants parses the values of the top-level constants in the current
// directory whose names start with the given prefix. When running as part of a
// test, the current directory is the directory of the file that contains the
// test in which this function is called.
// parseConstants parses the values of the top-level constants that start with the given prefix,
// in the files clusterextension_types.go and common_types.go.
func parseConstants(prefix string) ([]string, error) {
fset := token.NewFileSet()
// ParseDir returns a map of package name to package ASTs. An AST is a representation of the source code
// that can be traversed to extract information. The map is keyed by the package name.
pkgs, err := parser.ParseDir(fset, ".", func(info fs.FileInfo) bool {
return !strings.HasSuffix(info.Name(), "_test.go")
}, 0)
if err != nil {
return nil, err
// An AST is a representation of the source code that can be traversed to extract information.
// Converting files to AST representation to extract information.
parseFiles, astFiles := []string{"clusterextension_types.go", "common_types.go"}, []*ast.File{}
for _, file := range parseFiles {
p, err := parser.ParseFile(fset, file, nil, 0)
if err != nil {
return nil, err
}
astFiles = append(astFiles, p)
}

var constValues []string

// Iterate all of the top-level declarations in each package's files,
// looking for constants that start with the prefix. When we find one,
// add its value to the constValues list.
for _, pkg := range pkgs {
for _, f := range pkg.Files {
for _, d := range f.Decls {
genDecl, ok := d.(*ast.GenDecl)
if !ok {
// Iterate all of the top-level declarations in each file, looking
// for constants that start with the prefix. When we find one, add
// its value to the constValues list.
for _, f := range astFiles {
for _, d := range f.Decls {
genDecl, ok := d.(*ast.GenDecl)
if !ok {
continue
}
for _, s := range genDecl.Specs {
valueSpec, ok := s.(*ast.ValueSpec)
if !ok || len(valueSpec.Names) != 1 || valueSpec.Names[0].Obj.Kind != ast.Con || !strings.HasPrefix(valueSpec.Names[0].String(), prefix) {
continue
}
for _, s := range genDecl.Specs {
valueSpec, ok := s.(*ast.ValueSpec)
if !ok || len(valueSpec.Names) != 1 || valueSpec.Names[0].Obj.Kind != ast.Con || !strings.HasPrefix(valueSpec.Names[0].String(), prefix) {
for _, val := range valueSpec.Values {
lit, ok := val.(*ast.BasicLit)
if !ok || lit.Kind != token.STRING {
continue
}
for _, val := range valueSpec.Values {
lit, ok := val.(*ast.BasicLit)
if !ok || lit.Kind != token.STRING {
continue
}
v, err := strconv.Unquote(lit.Value)
if err != nil {
return nil, fmt.Errorf("unquote literal string %s: %v", lit.Value, err)
}
constValues = append(constValues, v)
v, err := strconv.Unquote(lit.Value)
if err != nil {
return nil, fmt.Errorf("unquote literal string %s: %v", lit.Value, err)
}
constValues = append(constValues, v)
}
}
}
Expand Down
6 changes: 0 additions & 6 deletions api/v1/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package v1
const (
TypeInstalled = "Installed"
TypeProgressing = "Progressing"
TypeServing = "Serving"

// Progressing reasons
ReasonSucceeded = "Succeeded"
Expand All @@ -29,9 +28,4 @@ const (
// Terminal reasons
ReasonDeprecated = "Deprecated"
ReasonFailed = "Failed"

// Serving reasons
ReasonAvailable = "Available"
ReasonUnavailable = "Unavailable"
ReasonUserSpecifiedUnavailable = "UserSpecifiedUnavailable"
)
2 changes: 1 addition & 1 deletion commitchecker.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
expectedMergeBase: 7fc18c64660c97c70e4c6704147a746f657543f4
expectedMergeBase: c9fa0b5be4bd20214af72b13e8d9a0d326da9e8d
upstreamBranch: main
upstreamOrg: operator-framework
upstreamRepo: operator-controller
2 changes: 1 addition & 1 deletion config/base/common/namespace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ metadata:
labels:
app.kubernetes.io/part-of: olm
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: "v1.32"
pod-security.kubernetes.io/enforce-version: latest
name: system
111 changes: 111 additions & 0 deletions docs/draft/api-reference/catalogd-webserver-metas-endpoint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Catalogd web server

[Catalogd](https://github.com/operator-framework/operator-controller/tree/main/catalogd), the OLM v1 component for making catalog contents available on cluster, includes
a web server that serves catalog contents to clients via HTTP(S) endpoints.

The endpoints to retrieve information about installable clusterextentions can be composed from the `.status.urls.base` of a `ClusterCatalog` resource with the selected access API path.

Currently, there are two API endpoints:

1. `api/v1/all` endpoint that provides access to the FBC metadata in entirety.

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
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`

2. `api/v1/metas` endpoint that allows clients to retrieve filtered portions of the FBC.

The metas endpoint accepts parameters which are one of the sub-types of the `Meta` [definition](https://github.com/operator-framework/operator-registry/blob/e15668c933c03e229b6c80025fdadb040ab834e0/alpha/declcfg/declcfg.go#L111-L114), following the pattern `/api/v1/metas?<parameter>[&<parameter>...]`.

As an example, to access only the [package schema](https://olm.operatorframework.io/docs/reference/file-based-catalogs/#olmpackage-1) blobs of the FBC via the `api/v1/metas` endpoint where `.status.urls.base` is

```yaml
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/metas?schema=olm.package`

For more examples of valid queries that can be made to the `api/v1/metas` service endpoint, please see [Catalog Queries](../howto/catalog-queries.md).

!!! note

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

### Supported HTTP Methods

The HTTP request methods supported by the catalogd web server are:

- [GET](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET)
- [HEAD](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD)

### Response Format

Responses are encoded as a [JSON Lines](https://jsonlines.org/) stream of [File-Based Catalog](https://olm.operatorframework.io/docs/reference/file-based-catalogs) (FBC) [Meta](https://olm.operatorframework.io/docs/reference/file-based-catalogs/#schema) objects delimited by newlines.

??? example "Example JSON-encoded FBC snippet"

```json
{
"schema": "olm.package",
"name": "cockroachdb",
"defaultChannel": "stable-v6.x",
}
{
"schema": "olm.channel",
"name": "stable-v6.x",
"package": "cockroachdb",
"entries": [
{
"name": "cockroachdb.v6.0.0",
"skipRange": "<6.0.0"
}
]
}
{
"schema": "olm.bundle",
"name": "cockroachdb.v6.0.0",
"package": "cockroachdb",
"image": "quay.io/openshift-community-operators/cockroachdb@sha256:d3016b1507515fc7712f9c47fd9082baf9ccb070aaab58ed0ef6e5abdedde8ba",
"properties": [
{
"type": "olm.package",
"value": {
"packageName": "cockroachdb",
"version": "6.0.0"
}
},
],
}
```

Corresponding JSON lines response:
```jsonlines
{"schema":"olm.package","name":"cockroachdb","defaultChannel":"stable-v6.x"}
{"schema":"olm.channel","name":"stable-v6.x","package":"cockroachdb","entries":[{"name":"cockroachdb.v6.0.0","skipRange":"<6.0.0"}]}
{"schema":"olm.bundle","name":"cockroachdb.v6.0.0","package":"cockroachdb","image":"quay.io/openshift-community-operators/cockroachdb@sha256:d3016b1507515fc7712f9c47fd9082baf9ccb070aaab58ed0ef6e5abdedde8ba","properties":[{"type":"olm.package","value":{"packageName":"cockroachdb","version":"6.0.0"}}]}
```

### Compression Support

The `catalogd` web server supports gzip compression of responses, which can significantly reduce associated network traffic. In order to signal that the client handles compressed responses, the client must include `Accept-Encoding: gzip` as a header in the HTTP request.

The web server will include a `Content-Encoding: gzip` header in compressed responses.

!!! note

Only catalogs whose uncompressed response body would result in a response size greater than 1400 bytes will be compressed.

### Cache Header Support

For clients interested in caching the information returned from the `catalogd` web server, the `Last-Modified` header is set
on responses and the `If-Modified-Since` header is supported for requests.
Loading