Skip to content
Open
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
6 changes: 3 additions & 3 deletions openshift/catalogd/manifests-experimental.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,7 @@ spec:
type: Image
image:
pollIntervalMinutes: 10
ref: registry.redhat.io/redhat/certified-operator-index:v4.22
ref: registry.redhat.io/redhat/certified-operator-index:v4.23
---
# Source: olmv1/templates/openshift-catalogs/clustercatalog-openshift-community-operators.yml
apiVersion: olm.operatorframework.io/v1
Expand All @@ -1018,7 +1018,7 @@ spec:
type: Image
image:
pollIntervalMinutes: 10
ref: registry.redhat.io/redhat/community-operator-index:v4.22
ref: registry.redhat.io/redhat/community-operator-index:v4.23
---
# Source: olmv1/templates/openshift-catalogs/clustercatalog-openshift-redhat-operators.yml
apiVersion: olm.operatorframework.io/v1
Expand All @@ -1031,7 +1031,7 @@ spec:
type: Image
image:
pollIntervalMinutes: 10
ref: registry.redhat.io/redhat/redhat-operator-index:v4.22
ref: registry.redhat.io/redhat/redhat-operator-index:v4.23
---
# Source: olmv1/templates/mutatingwebhookconfiguration-catalogd-mutating-webhook-configuration.yml
apiVersion: admissionregistration.k8s.io/v1
Expand Down
6 changes: 3 additions & 3 deletions openshift/catalogd/manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,7 @@ spec:
type: Image
image:
pollIntervalMinutes: 10
ref: registry.redhat.io/redhat/certified-operator-index:v4.22
ref: registry.redhat.io/redhat/certified-operator-index:v4.23
---
# Source: olmv1/templates/openshift-catalogs/clustercatalog-openshift-community-operators.yml
apiVersion: olm.operatorframework.io/v1
Expand All @@ -1017,7 +1017,7 @@ spec:
type: Image
image:
pollIntervalMinutes: 10
ref: registry.redhat.io/redhat/community-operator-index:v4.22
ref: registry.redhat.io/redhat/community-operator-index:v4.23
---
# Source: olmv1/templates/openshift-catalogs/clustercatalog-openshift-redhat-operators.yml
apiVersion: olm.operatorframework.io/v1
Expand All @@ -1030,7 +1030,7 @@ spec:
type: Image
image:
pollIntervalMinutes: 10
ref: registry.redhat.io/redhat/redhat-operator-index:v4.22
ref: registry.redhat.io/redhat/redhat-operator-index:v4.23
---
# Source: olmv1/templates/mutatingwebhookconfiguration-catalogd-mutating-webhook-configuration.yml
apiVersion: admissionregistration.k8s.io/v1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var _ = Describe("OLM-Catalog-Validation", func() {

sysCtx := &types.SystemContext{}
if authPath != "" {
fmt.Println("Using registry auth file:", authPath)
fmt.Fprintf(os.Stderr, "Using registry auth file\n")
sysCtx.AuthFilePath = authPath
}

Expand Down
2 changes: 1 addition & 1 deletion openshift/helm/catalogd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ options:
openshift:
enabled: true
catalogs:
version: v4.22
version: v4.23

# The set of namespaces
namespaces:
Expand Down
124 changes: 124 additions & 0 deletions openshift/tests-extension/pkg/helpers/catalog_discovery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package helpers

import (
"bufio"
"context"
"encoding/json"
"fmt"
"net/http"
"strings"

//nolint:staticcheck // ST1001: dot-imports for readability
. "github.com/onsi/ginkgo/v2"
//nolint:staticcheck // ST1001: dot-imports for readability
. "github.com/onsi/gomega"

"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/rest"

olmv1 "github.com/operator-framework/operator-controller/api/v1"

"github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/pkg/env"
)

// preferredPackages is tried in order; the first one present in any serving catalog wins.
// Falls back to the first available package if none of these are found.
var preferredPackages = []string{
"quay-operator",
"cluster-logging",
"serverless-operator",
"cli-manager",
"logic-operator",
}

// FindInstallablePackage searches all serving ClusterCatalogs for an installable package,
// favouring preferredPackages in order. Returns the catalog name and package name,
// or fails the test if no packages are found in any serving catalog.
func FindInstallablePackage(ctx context.Context) (string, string) {
cfg := env.Get().RestCfg
httpClient, err := rest.HTTPClientFor(cfg)
Expect(err).ToNot(HaveOccurred(), "failed to build HTTP client from REST config")

k8sClient := env.Get().K8sClient
catalogList := &olmv1.ClusterCatalogList{}
Expect(k8sClient.List(ctx, catalogList)).To(Succeed(), "failed to list ClusterCatalogs")

// Collect packages from every serving catalog: map[catalogName][]packageName
available := map[string][]string{}
for i := range catalogList.Items {
cc := &catalogList.Items[i]
if !meta.IsStatusConditionPresentAndEqual(cc.Status.Conditions, olmv1.TypeServing, metav1.ConditionTrue) {
fmt.Fprintf(GinkgoWriter, "Catalog %q is not serving, skipping\n", cc.Name)
continue
}
pkgs, err := listPackagesInCatalog(ctx, httpClient, cfg.Host, cc.Name)
if err != nil {
fmt.Fprintf(GinkgoWriter, "Warning: could not list packages in catalog %q: %v\n", cc.Name, err)
continue
}
available[cc.Name] = pkgs
fmt.Fprintf(GinkgoWriter, "Catalog %q: %d packages available\n", cc.Name, len(pkgs))
}

// Try preferred packages in order across all serving catalogs.
for _, preferred := range preferredPackages {
for cat, pkgs := range available {
for _, pkg := range pkgs {
if pkg == preferred {
fmt.Fprintf(GinkgoWriter, "Selected package %q from catalog %q (preferred)\n", pkg, cat)
return cat, pkg
}
}
}
}

// Fall back to the first package found in any catalog.
for cat, pkgs := range available {
if len(pkgs) > 0 {
fmt.Fprintf(GinkgoWriter, "Selected package %q from catalog %q (fallback)\n", pkgs[0], cat)
return cat, pkgs[0]
}
}

Fail("no installable packages found in any serving catalog")
return "", "" // unreachable
}

// listPackagesInCatalog queries the catalogd /api/v1/metas?schema=olm.package endpoint
// via the Kubernetes API-server proxy and returns all package names.
func listPackagesInCatalog(ctx context.Context, httpClient *http.Client, apiServerHost, catalogName string) ([]string, error) {
url := strings.TrimRight(apiServerHost, "/") +
fmt.Sprintf("/api/v1/namespaces/openshift-catalogd/services/https:catalogd-service:443/proxy/catalogs/%s/api/v1/metas?schema=olm.package",
catalogName)

req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, fmt.Errorf("build request: %w", err)
}
resp, err := httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("GET %s: %w", url, err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status %d from %s", resp.StatusCode, url)
}

// Response is JSONL: one JSON object per line.
// Each olm.package line has at minimum a "name" field.
var packages []string
scanner := bufio.NewScanner(resp.Body)
scanner.Buffer(make([]byte, 1024*1024), 1024*1024)
for scanner.Scan() {
var obj struct {
Name string `json:"name"`
}
if err := json.Unmarshal(scanner.Bytes(), &obj); err != nil || obj.Name == "" {
continue
}
packages = append(packages, obj.Name)
}
return packages, scanner.Err()
}
13 changes: 8 additions & 5 deletions openshift/tests-extension/test/olmv1.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,17 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLM][Skipped:Disconnected] OLMv1
})

It("should install an openshift catalog cluster extension", Label("original-name:[sig-olmv1][OCPFeatureGate:NewOLM][Skipped:Disconnected] OLMv1 operator installation should install an openshift catalog cluster extension"), func(ctx SpecContext) {
By("ensuring no ClusterExtension and CRD for quay-operator")
helpers.EnsureCleanupClusterExtension(context.Background(), "quay-operator", "quayregistries.quay.redhat.com")
catalog, pkg := helpers.FindInstallablePackage(ctx)

By("applying the ClusterExtension resource")
name, cleanup := helpers.CreateClusterExtension("quay-operator", "3.13.10", namespace, "")
By(fmt.Sprintf("ensuring no existing ClusterExtension for %q", pkg))
helpers.EnsureCleanupClusterExtension(context.Background(), pkg, "")

By(fmt.Sprintf("applying ClusterExtension for %q from catalog %q", pkg, catalog))
name, cleanup := helpers.CreateClusterExtension(pkg, "", namespace, "",
helpers.WithCatalogNameSelector(catalog))
DeferCleanup(cleanup)

By("waiting for the quay-operator ClusterExtension to be installed")
By(fmt.Sprintf("waiting for %q to be installed", pkg))
helpers.ExpectClusterExtensionToBeInstalled(ctx, name)
})
})
Expand Down