From 3e68a86b7d6b7ef3b483e0838236137cff427abb Mon Sep 17 00:00:00 2001 From: Mallory Hill Date: Thu, 10 Sep 2026 10:53:21 -0400 Subject: [PATCH 1/4] HYPERFLEET-1411 - refactor: Update konflux + dev bundles --- Makefile | 22 +- bundle-hack/update_bundle.sh | 24 -- bundle.Dockerfile | 50 ++- bundle.konflux.Dockerfile | 57 ---- ...er-manager-metrics-service_v1_service.yaml | 20 -- ...c.authorization.k8s.io_v1_clusterrole.yaml | 21 -- ...c.authorization.k8s.io_v1_clusterrole.yaml | 27 -- ...c.authorization.k8s.io_v1_clusterrole.yaml | 23 -- ...c.authorization.k8s.io_v1_clusterrole.yaml | 13 - ...rfleet-operator.clusterserviceversion.yaml | 291 ----------------- ...perfleet.redhat.com_hyperfleetconfigs.yaml | 304 ------------------ bundle/metadata/annotations.yaml | 15 - bundle/tests/scorecard/config.yaml | 70 ---- config/manager/dev/kustomization.yaml | 26 ++ config/manager/kustomization.yaml | 40 --- config/manager/prod/kustomization.yaml | 28 ++ ...rfleet-operator.clusterserviceversion.yaml | 8 +- config/manifests/kustomization.yaml | 13 + 18 files changed, 126 insertions(+), 926 deletions(-) delete mode 100755 bundle-hack/update_bundle.sh delete mode 100644 bundle.konflux.Dockerfile delete mode 100644 bundle/manifests/hyperfleet-operator-controller-manager-metrics-service_v1_service.yaml delete mode 100644 bundle/manifests/hyperfleet-operator-hyperfleetconfig-admin-role_rbac.authorization.k8s.io_v1_clusterrole.yaml delete mode 100644 bundle/manifests/hyperfleet-operator-hyperfleetconfig-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml delete mode 100644 bundle/manifests/hyperfleet-operator-hyperfleetconfig-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml delete mode 100644 bundle/manifests/hyperfleet-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml delete mode 100644 bundle/manifests/hyperfleet-operator.clusterserviceversion.yaml delete mode 100644 bundle/manifests/hyperfleet.redhat.com_hyperfleetconfigs.yaml delete mode 100644 bundle/metadata/annotations.yaml delete mode 100644 bundle/tests/scorecard/config.yaml create mode 100644 config/manager/dev/kustomization.yaml delete mode 100644 config/manager/kustomization.yaml create mode 100644 config/manager/prod/kustomization.yaml diff --git a/Makefile b/Makefile index 87fc497..2d84c70 100644 --- a/Makefile +++ b/Makefile @@ -278,7 +278,6 @@ undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/confi ##@ Bundles/Catalog - # Non-olm installs # Generates dist/install.yaml # Install resources @@ -349,24 +348,19 @@ ifneq ($(origin CATALOG_BASE_IMG), undefined) FROM_INDEX_OPT := --from-index $(CATALOG_BASE_IMG) endif -.PHONY: bundle -bundle: manifests operator-sdk ## Generate bundle manifests and metadata, then validate generated files. - $(OPERATOR_SDK) generate kustomize manifests -q - $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS) - $(OPERATOR_SDK) bundle validate ./bundle - .PHONY: bundle-override-img bundle-override-img: manifests operator-sdk ## Generate bundle with IMG override, then restore kustomization.yaml $(OPERATOR_SDK) generate kustomize manifests -q - cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) - $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS) - $(OPERATOR_SDK) bundle validate ./bundle - @echo "Bundle generated with IMG=$(IMG)" - @echo "Note: config/manager/kustomization.yaml has been modified. Commit or reset as needed." + cd config/manager/dev && $(KUSTOMIZE) edit set image controller=$(IMG) .PHONY: bundle-build -bundle-build: ## Build the bundle image. - $(CONTAINER_TOOL) build -f bundle.Dockerfile -t $(BUNDLE_IMG) . +bundle-build: ## Builds the bundle and bundle image. + $(CONTAINER_TOOL) build -f bundle.Dockerfile \ + --platform $(PLATFORM) \ + --build-arg VERSION=$(VERSION) \ + --build-arg CHANNEL=$(CHANNELS) \ + --build-arg APP_VERSION=$(APP_VERSION) \ + -t $(BUNDLE_IMG) . .PHONY: bundle-push bundle-push: ## Push the bundle image. diff --git a/bundle-hack/update_bundle.sh b/bundle-hack/update_bundle.sh deleted file mode 100755 index 5f0ceed..0000000 --- a/bundle-hack/update_bundle.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -CSV_FILE="${CSV_FILE:-/manifests/hyperfleet-operator.clusterserviceversion.yaml}" - -# Update image references in the CSV file using yq -yq eval ' - # Update operator deployment image - (.spec.install.spec.deployments[].spec.template.spec.containers[] | select(.name == "manager") | .image) = strenv(HYPERFLEET_OPERATOR_IMAGE_PULLSPEC) | - - # Update RELATED_IMAGE_HYPERFLEET_API env var - (.spec.install.spec.deployments[].spec.template.spec.containers[] | select(.name == "manager") | .env[] | select(.name == "RELATED_IMAGE_HYPERFLEET_API") | .value) = strenv(HYPERFLEET_API_IMAGE_PULLSPEC) | - - # Update containerImage annotation - .metadata.annotations.containerImage = strenv(HYPERFLEET_OPERATOR_IMAGE_PULLSPEC) | - - # Update relatedImages - .spec.relatedImages = [ - {"name": "hyperfleet-operator", "image": strenv(HYPERFLEET_OPERATOR_IMAGE_PULLSPEC)}, - {"name": "hyperfleet-api", "image": strenv(HYPERFLEET_API_IMAGE_PULLSPEC)} - ] -' -i "${CSV_FILE}" - -cat "${CSV_FILE}" diff --git a/bundle.Dockerfile b/bundle.Dockerfile index ed59506..91a0201 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -1,3 +1,32 @@ +FROM registry.k8s.io/kustomize/kustomize:v5.0.0 AS kustomize + +COPY config/ /workdir/config/ + +# Override the base kustomization.yaml +ARG KUSTOMIZE_VARIANT=dev/kustomization.yaml +RUN cp /workdir/config/manager/${KUSTOMIZE_VARIANT} \ + /workdir/config/manager/kustomization.yaml && \ + kustomize build /workdir/config/manifests > /workdir/manifests.yaml + +FROM alpine:3.20 AS operator + +ARG OPERATOR_SDK_VERSION=v1.42.3 +ARG ARCH=amd64 + +RUN apk add --no-cache curl && \ + curl -fsSLo /usr/local/bin/operator-sdk \ + "https://github.com/operator-framework/operator-sdk/releases/download/${OPERATOR_SDK_VERSION}/operator-sdk_linux_${ARCH}" && \ + chmod +x /usr/local/bin/operator-sdk + +COPY --from=kustomize /workdir/manifests.yaml /workdir/manifests.yaml +ARG CHANNELS=stable +ARG VERSION=0.0.1 +WORKDIR /workdir +RUN cat manifests.yaml | operator-sdk generate bundle -q --version ${VERSION} \ + --channels=${CHANNELS} --default-channel=stable \ + --package=hyperfleet-operator && \ + operator-sdk bundle validate ./bundle + FROM scratch # Core bundle labels. @@ -15,7 +44,20 @@ LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v4 LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ -# Copy files to locations specified by labels. -COPY bundle/manifests /manifests/ -COPY bundle/metadata /metadata/ -COPY bundle/tests/scorecard /tests/scorecard/ +# Copy patched manifests from builder, metadata and tests from source. +COPY --from=operator /workdir/bundle/manifests /manifests/ +COPY --from=operator /workdir/bundle/metadata /metadata/ +COPY --from=operator /workdir/bundle/tests/scorecard /tests/scorecard/ + +ARG APP_VERSION="0.0.0-dev" +LABEL name="hyperfleet-operator-bundle" \ + vendor="Red Hat, Inc." \ + version="${APP_VERSION}" \ + summary="OLM bundle for the HyperFleet Operator" \ + description="OLM bundle for the HyperFleet Operator, which installs and manages HyperFleet." \ + com.redhat.component="hyperfleet-operator-bundle-container" \ + io.k8s.description="OLM bundle for the HyperFleet Operator, which installs and manages HyperFleet." \ + distribution-scope="public" \ + release="1" \ + url="https://github.com/openshift-hyperfleet/hyperfleet-operator" \ + maintainer="Red Hat HyperFleet Team" diff --git a/bundle.konflux.Dockerfile b/bundle.konflux.Dockerfile deleted file mode 100644 index f966404..0000000 --- a/bundle.konflux.Dockerfile +++ /dev/null @@ -1,57 +0,0 @@ -# Konflux bundle image build. Unlike the auto-generated bundle.Dockerfile (used -# for local dev with operator-sdk), this runs bundle-hack/update_bundle.sh to -# patch digest-pinned image references into the CSV at build time. -FROM registry.access.redhat.com/ubi9/ubi-minimal:latest AS builder-runner -RUN microdnf install -y tar gzip && \ - curl -sL https://github.com/mikefarah/yq/releases/download/v4.44.1/yq_linux_amd64.tar.gz | tar xz && \ - mv yq_linux_amd64 /usr/bin/yq - -FROM builder-runner AS builder -# Hack to set the operator container image in the deployment -# Konflux nudges update these variables with the latest digest-pinned pullspecs. -ARG HYPERFLEET_OPERATOR_IMAGE_PULLSPEC="quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator@sha256:7504189fc375ee65457baa568487b9f083b35b882d58601cd4f4ad8ee50e639e" -ENV HYPERFLEET_OPERATOR_IMAGE_PULLSPEC=${HYPERFLEET_OPERATOR_IMAGE_PULLSPEC} - -ARG HYPERFLEET_API_IMAGE_PULLSPEC="quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-api@sha256:99f8cdda580069de21ba0e13b5b171cf82b81b93dc88b12bcaa8294e72e84fc3" -ENV HYPERFLEET_API_IMAGE_PULLSPEC=${HYPERFLEET_API_IMAGE_PULLSPEC} - -COPY bundle-hack . -COPY bundle/manifests /manifests/ - -RUN ./update_bundle.sh - -FROM scratch - -# Core bundle labels. -LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1 -LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ -LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ -LABEL operators.operatorframework.io.bundle.package.v1=hyperfleet-operator -LABEL operators.operatorframework.io.bundle.channels.v1=stable -LABEL operators.operatorframework.io.bundle.channel.default.v1=stable -LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.42.3 -LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 -LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v4 - -# Labels for testing. -LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 -LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ - -# Copy patched manifests from builder, metadata and tests from source. -COPY --from=builder /manifests /manifests/ -COPY bundle/metadata /metadata/ -COPY bundle/tests/scorecard /tests/scorecard/ - - -ARG APP_VERSION="0.0.0-dev" -LABEL name="hyperfleet-operator-bundle" \ - vendor="Red Hat, Inc." \ - version="${APP_VERSION}" \ - summary="OLM bundle for the HyperFleet Operator" \ - description="OLM bundle for the HyperFleet Operator, which installs and manages HyperFleet." \ - com.redhat.component="hyperfleet-operator-bundle-container" \ - io.k8s.description="OLM bundle for the HyperFleet Operator, which installs and manages HyperFleet." \ - distribution-scope="public" \ - release="1" \ - url="https://github.com/openshift-hyperfleet/hyperfleet-operator" \ - maintainer="Red Hat HyperFleet Team" diff --git a/bundle/manifests/hyperfleet-operator-controller-manager-metrics-service_v1_service.yaml b/bundle/manifests/hyperfleet-operator-controller-manager-metrics-service_v1_service.yaml deleted file mode 100644 index b042de1..0000000 --- a/bundle/manifests/hyperfleet-operator-controller-manager-metrics-service_v1_service.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - creationTimestamp: null - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: hyperfleet-operator - control-plane: controller-manager - name: hyperfleet-operator-controller-manager-metrics-service -spec: - ports: - - name: https - port: 8443 - protocol: TCP - targetPort: 8443 - selector: - app.kubernetes.io/name: hyperfleet-operator - control-plane: controller-manager -status: - loadBalancer: {} diff --git a/bundle/manifests/hyperfleet-operator-hyperfleetconfig-admin-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/manifests/hyperfleet-operator-hyperfleetconfig-admin-role_rbac.authorization.k8s.io_v1_clusterrole.yaml deleted file mode 100644 index 99652ea..0000000 --- a/bundle/manifests/hyperfleet-operator-hyperfleetconfig-admin-role_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: hyperfleet-operator - name: hyperfleet-operator-hyperfleetconfig-admin-role -rules: -- apiGroups: - - hyperfleet.redhat.com - resources: - - hyperfleetconfigs - verbs: - - '*' -- apiGroups: - - hyperfleet.redhat.com - resources: - - hyperfleetconfigs/status - verbs: - - get diff --git a/bundle/manifests/hyperfleet-operator-hyperfleetconfig-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/manifests/hyperfleet-operator-hyperfleetconfig-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml deleted file mode 100644 index 9ffd846..0000000 --- a/bundle/manifests/hyperfleet-operator-hyperfleetconfig-editor-role_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: hyperfleet-operator - name: hyperfleet-operator-hyperfleetconfig-editor-role -rules: -- apiGroups: - - hyperfleet.redhat.com - resources: - - hyperfleetconfigs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - hyperfleet.redhat.com - resources: - - hyperfleetconfigs/status - verbs: - - get diff --git a/bundle/manifests/hyperfleet-operator-hyperfleetconfig-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/manifests/hyperfleet-operator-hyperfleetconfig-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml deleted file mode 100644 index cf45968..0000000 --- a/bundle/manifests/hyperfleet-operator-hyperfleetconfig-viewer-role_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: hyperfleet-operator - name: hyperfleet-operator-hyperfleetconfig-viewer-role -rules: -- apiGroups: - - hyperfleet.redhat.com - resources: - - hyperfleetconfigs - verbs: - - get - - list - - watch -- apiGroups: - - hyperfleet.redhat.com - resources: - - hyperfleetconfigs/status - verbs: - - get diff --git a/bundle/manifests/hyperfleet-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/manifests/hyperfleet-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml deleted file mode 100644 index 4450500..0000000 --- a/bundle/manifests/hyperfleet-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - creationTimestamp: null - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: hyperfleet-operator - name: hyperfleet-operator-metrics-reader -rules: -- nonResourceURLs: - - /metrics - verbs: - - get diff --git a/bundle/manifests/hyperfleet-operator.clusterserviceversion.yaml b/bundle/manifests/hyperfleet-operator.clusterserviceversion.yaml deleted file mode 100644 index e3e02f2..0000000 --- a/bundle/manifests/hyperfleet-operator.clusterserviceversion.yaml +++ /dev/null @@ -1,291 +0,0 @@ -apiVersion: operators.coreos.com/v1alpha1 -kind: ClusterServiceVersion -metadata: - annotations: - alm-examples: |- - [ - { - "apiVersion": "hyperfleet.redhat.com/v1alpha1", - "kind": "HyperFleetConfig", - "metadata": { - "labels": { - "app.kubernetes.io/managed-by": "kustomize", - "app.kubernetes.io/name": "hyperfleet-operator" - }, - "name": "cluster" - }, - "spec": { - "api": { - "auth": { - "audience": "hyperfleet-api", - "enabled": true, - "issuer": "https://issuer.example.com" - }, - "database": { - "secretRef": { - "name": "hyperfleet-db" - } - }, - "profile": "small" - }, - "bundle": "cloud-capi" - } - } - ] - capabilities: Basic Install - createdAt: "2026-09-04T09:48:43Z" - features.operators.openshift.io/disconnected: "true" - features.operators.openshift.io/fips-compliant: "false" - features.operators.openshift.io/proxy-aware: "false" - features.operators.openshift.io/tls-profiles: "false" - features.operators.openshift.io/token-auth-aws: "false" - features.operators.openshift.io/token-auth-azure: "false" - features.operators.openshift.io/token-auth-gcp: "false" - operators.openshift.io/valid-subscription: '["OpenShift Container Platform"]' - operators.operatorframework.io/builder: operator-sdk-v1.42.3 - operators.operatorframework.io/project_layout: go.kubebuilder.io/v4 - name: hyperfleet-operator.v0.0.1 - namespace: placeholder -spec: - apiservicedefinitions: {} - customresourcedefinitions: - owned: - - description: |- - HyperFleetConfig is the Schema for the hyperfleetconfigs API. It is a - cluster-scoped singleton: exactly one instance, named "cluster", is permitted. - displayName: Hyper Fleet Config - kind: HyperFleetConfig - name: hyperfleetconfigs.hyperfleet.redhat.com - version: v1alpha1 - description: |- - Delivers HyperFleet as a standard Kubernetes operator, installed and - managed through OLM. It exposes a single cluster-scoped CR: HyperFleetConfig. - displayName: HyperFleet Operator - icon: - - base64data: "" - mediatype: "" - install: - spec: - clusterPermissions: - - rules: - - apiGroups: - - "" - resources: - - configmaps - - serviceaccounts - - services - verbs: - - create - - get - - list - - patch - - update - - watch - - apiGroups: - - apps - resources: - - deployments - verbs: - - create - - get - - list - - patch - - update - - watch - - apiGroups: - - hyperfleet.redhat.com - resources: - - hyperfleetconfigs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - hyperfleet.redhat.com - resources: - - hyperfleetconfigs/finalizers - verbs: - - update - - apiGroups: - - hyperfleet.redhat.com - resources: - - hyperfleetconfigs/status - verbs: - - get - - patch - - update - - apiGroups: - - rbac.authorization.k8s.io - resources: - - rolebindings - - roles - verbs: - - create - - get - - list - - patch - - update - - watch - - apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create - - apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create - serviceAccountName: hyperfleet-operator-controller-manager - deployments: - - label: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: hyperfleet-operator - control-plane: controller-manager - name: hyperfleet-operator-controller-manager - spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: hyperfleet-operator - control-plane: controller-manager - strategy: {} - template: - metadata: - annotations: - kubectl.kubernetes.io/default-container: manager - labels: - app.kubernetes.io/name: hyperfleet-operator - control-plane: controller-manager - spec: - containers: - - args: - - --metrics-bind-address=:8443 - - --leader-elect - - --health-probe-bind-address=:8081 - command: - - /manager - env: - - name: OPERATOR_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: RELATED_IMAGE_HYPERFLEET_API - value: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-api:latest - image: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator:latest - livenessProbe: - httpGet: - path: /healthz - port: 8081 - initialDelaySeconds: 15 - periodSeconds: 20 - name: manager - readinessProbe: - httpGet: - path: /readyz - port: 8081 - initialDelaySeconds: 5 - periodSeconds: 10 - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 10m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - securityContext: - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - serviceAccountName: hyperfleet-operator-controller-manager - terminationGracePeriodSeconds: 10 - permissions: - - rules: - - apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete - - apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete - - apiGroups: - - "" - resources: - - events - verbs: - - create - - patch - - apiGroups: - - "" - resources: - - secrets - verbs: - - get - - list - - watch - - apiGroups: - - networking.k8s.io - resources: - - networkpolicies - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - serviceAccountName: hyperfleet-operator-controller-manager - strategy: deployment - installModes: - - supported: false - type: OwnNamespace - - supported: false - type: SingleNamespace - - supported: false - type: MultiNamespace - - supported: true - type: AllNamespaces - keywords: - - hyperfleet - - cluster-management - - multicluster - links: - - name: HyperFleet Operator - url: https://github.com/openshift-hyperfleet/hyperfleet-operator - minKubeVersion: 1.27.0 - provider: - name: Red Hat - url: https://github.com/openshift-hyperfleet - relatedImages: - - image: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-api:latest - name: hyperfleet-api - version: 0.0.1 diff --git a/bundle/manifests/hyperfleet.redhat.com_hyperfleetconfigs.yaml b/bundle/manifests/hyperfleet.redhat.com_hyperfleetconfigs.yaml deleted file mode 100644 index 18a37a1..0000000 --- a/bundle/manifests/hyperfleet.redhat.com_hyperfleetconfigs.yaml +++ /dev/null @@ -1,304 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.21.0 - creationTimestamp: null - labels: - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/name: hyperfleet-operator - name: hyperfleetconfigs.hyperfleet.redhat.com -spec: - group: hyperfleet.redhat.com - names: - kind: HyperFleetConfig - listKind: HyperFleetConfigList - plural: hyperfleetconfigs - shortNames: - - hfc - singular: hyperfleetconfig - scope: Cluster - versions: - - additionalPrinterColumns: - - jsonPath: .spec.bundle - name: Bundle - type: string - - jsonPath: .spec.api.profile - name: Profile - type: string - - jsonPath: .status.conditions[?(@.type=="Available")].status - name: Available - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: |- - HyperFleetConfig is the Schema for the hyperfleetconfigs API. It is a - cluster-scoped singleton: exactly one instance, named "cluster", is permitted. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: |- - HyperFleetConfigSpec defines the desired state of HyperFleetConfig. It captures - partner intent only; internal machinery (broker, adapters, sentinel) is never - expressed here. - properties: - api: - description: api is the partner-facing configuration for the HyperFleet - API component. - properties: - auth: - description: auth configures partner-facing JWT authentication - intent. - properties: - audience: - description: |- - audience is the token audience the API requires. Required and non-empty - when enabled is true. - maxLength: 253 - minLength: 1 - type: string - enabled: - default: true - description: |- - enabled turns JWT authentication on for the API endpoint. It defaults to - true, so a config that omits it gets authentication ON. It is a pointer to - distinguish "unset" (apply the default, true) from an explicit false - (disable auth), which a non-pointer bool cannot express: with omitempty a - plain false is dropped and re-defaulted to true, so auth could never be - turned off via the typed client; without omitempty an unset field serializes - as false and suppresses the default. Only *bool avoids both traps. - type: boolean - issuer: - description: |- - issuer is the OIDC issuer URL that mints accepted tokens. Required when - enabled is true. Whenever it is set (regardless of enabled) it must be a - valid https URL with a host, so a malformed issuer is rejected at admission - rather than surfacing later at token-validation time. - maxLength: 2048 - minLength: 1 - type: string - x-kubernetes-validations: - - message: issuer must be a valid https URL - rule: isURL(self) && url(self).getScheme() == 'https' && - url(self).getHostname() != '' - jwkCertSecretRef: - description: |- - jwkCertSecretRef optionally references a Secret holding the JWKS document, - for air-gapped or private environments where the API cannot reach a JWKS - URL. The Secret must provide the key "jwks.json" containing a JSON Web Key - Set (the format the API parses; see HYPERFLEET-1408). When unset, the - operator derives the JWKS URL from the issuer via OIDC discovery - ({issuer}/.well-known/openid-configuration → jwks_uri). - properties: - name: - description: |- - name is the name of the Secret in the operator's namespace. It must be a - valid DNS-1123 subdomain, matching what k8s.io/apimachinery/pkg/util/validation - enforces for Secret names (IsDNS1123Subdomain, max length 253), so an - unresolvable reference is rejected at admission rather than failing opaquely - when the reference is later resolved. - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - type: object - x-kubernetes-validations: - - message: issuer and audience are required when auth is enabled - rule: '!self.enabled || (has(self.issuer) && has(self.audience))' - database: - description: database configures the external PostgreSQL connection. - properties: - secretRef: - description: |- - secretRef references a Secret holding the database connection credentials. - The Secret must provide the keys db.host, db.port, db.name, db.user and - db.password. - properties: - name: - description: |- - name is the name of the Secret in the operator's namespace. It must be a - valid DNS-1123 subdomain, matching what k8s.io/apimachinery/pkg/util/validation - enforces for Secret names (IsDNS1123Subdomain, max length 253), so an - unresolvable reference is rejected at admission rather than failing opaquely - when the reference is later resolved. - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - required: - - secretRef - type: object - profile: - default: small - description: profile selects a sizing profile for the API. Defaults - to "small". - enum: - - small - - medium - - large - type: string - tls: - description: |- - tls optionally configures TLS for the API endpoint. When omitted, the - operator applies its default serving configuration. - properties: - secretRef: - description: |- - secretRef references a kubernetes.io/tls Secret (providing tls.crt and - tls.key) used to serve the API endpoint. - properties: - name: - description: |- - name is the name of the Secret in the operator's namespace. It must be a - valid DNS-1123 subdomain, matching what k8s.io/apimachinery/pkg/util/validation - enforces for Secret names (IsDNS1123Subdomain, max length 253), so an - unresolvable reference is rejected at admission rather than failing opaquely - when the reference is later resolved. - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - required: - - secretRef - type: object - required: - - auth - - database - type: object - bundle: - description: |- - bundle selects one of the operator-internal bundle definitions. It is - immutable after creation: switching deployments requires recreating the - resource. - enum: - - cloud-capi - - onprem-agent - type: string - x-kubernetes-validations: - - message: bundle is immutable - rule: self == oldSelf - required: - - api - - bundle - type: object - status: - description: |- - HyperFleetConfigStatus defines the observed state of HyperFleetConfig. It is - populated by the bundle controller in later stories; this story defines the - schema only. - properties: - conditions: - description: |- - conditions represent the current installation health of the operand. - Recognized types are Available, Progressing and Degraded. - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - observedGeneration: - description: observedGeneration is the .metadata.generation the operator - last acted on. - format: int64 - minimum: 0 - type: integer - type: object - required: - - spec - type: object - x-kubernetes-validations: - - message: the only permitted name is 'cluster'; HyperFleetConfig is a cluster-scoped - singleton - rule: self.metadata.name == 'cluster' - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml deleted file mode 100644 index d1973b6..0000000 --- a/bundle/metadata/annotations.yaml +++ /dev/null @@ -1,15 +0,0 @@ -annotations: - # Core bundle annotations. - operators.operatorframework.io.bundle.mediatype.v1: registry+v1 - operators.operatorframework.io.bundle.manifests.v1: manifests/ - operators.operatorframework.io.bundle.metadata.v1: metadata/ - operators.operatorframework.io.bundle.package.v1: hyperfleet-operator - operators.operatorframework.io.bundle.channels.v1: stable - operators.operatorframework.io.bundle.channel.default.v1: stable - operators.operatorframework.io.metrics.builder: operator-sdk-v1.42.3 - operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 - operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v4 - - # Annotations for testing. - operators.operatorframework.io.test.mediatype.v1: scorecard+v1 - operators.operatorframework.io.test.config.v1: tests/scorecard/ diff --git a/bundle/tests/scorecard/config.yaml b/bundle/tests/scorecard/config.yaml deleted file mode 100644 index b2761e6..0000000 --- a/bundle/tests/scorecard/config.yaml +++ /dev/null @@ -1,70 +0,0 @@ -apiVersion: scorecard.operatorframework.io/v1alpha3 -kind: Configuration -metadata: - name: config -stages: -- parallel: true - tests: - - entrypoint: - - scorecard-test - - basic-check-spec - image: quay.io/operator-framework/scorecard-test:v1.42.3 - labels: - suite: basic - test: basic-check-spec-test - storage: - spec: - mountPath: {} - - entrypoint: - - scorecard-test - - olm-bundle-validation - image: quay.io/operator-framework/scorecard-test:v1.42.3 - labels: - suite: olm - test: olm-bundle-validation-test - storage: - spec: - mountPath: {} - - entrypoint: - - scorecard-test - - olm-crds-have-validation - image: quay.io/operator-framework/scorecard-test:v1.42.3 - labels: - suite: olm - test: olm-crds-have-validation-test - storage: - spec: - mountPath: {} - - entrypoint: - - scorecard-test - - olm-crds-have-resources - image: quay.io/operator-framework/scorecard-test:v1.42.3 - labels: - suite: olm - test: olm-crds-have-resources-test - storage: - spec: - mountPath: {} - - entrypoint: - - scorecard-test - - olm-spec-descriptors - image: quay.io/operator-framework/scorecard-test:v1.42.3 - labels: - suite: olm - test: olm-spec-descriptors-test - storage: - spec: - mountPath: {} - - entrypoint: - - scorecard-test - - olm-status-descriptors - image: quay.io/operator-framework/scorecard-test:v1.42.3 - labels: - suite: olm - test: olm-status-descriptors-test - storage: - spec: - mountPath: {} -storage: - spec: - mountPath: {} diff --git a/config/manager/dev/kustomization.yaml b/config/manager/dev/kustomization.yaml new file mode 100644 index 0000000..72bbc94 --- /dev/null +++ b/config/manager/dev/kustomization.yaml @@ -0,0 +1,26 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- manager.yaml + +images: +- name: controller + newName: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator + newTag: latest + +patches: +- patch: |- + - op: add + path: /spec/template/spec/containers/0/env/- + value: + name: RELATED_IMAGE_HYPERFLEET_API + value: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-api:latest + - op: add + path: /spec/template/spec/containers/0/env/- + value: + name: RELATED_IMAGE_HYPERFLEET_OPERATOR + value: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator:latest + target: + kind: Deployment + name: controller-manager diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml deleted file mode 100644 index 93a768e..0000000 --- a/config/manager/kustomization.yaml +++ /dev/null @@ -1,40 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: -- manager.yaml - -# Base image configuration for local development -# For production/Konflux builds, digest-pinned images are set via bundle.konflux.Dockerfile ARG overrides -# -# Local development override: -# make bundle-override-img IMG=quay.io//hyperfleet-operator:dev- -# make build-deployer-override-img IMG=quay.io//hyperfleet-operator:dev- -# -# NOTE: These commands modify this file in place. Restore before committing: -# git checkout config/manager/kustomization.yaml -images: -- name: controller - newName: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator - newTag: latest - -# RELATED_IMAGE_HYPERFLEET_API environment variable -# Sets the image used for the API operand. -# -# IMPORTANT: Must stay in sync with api.DefaultImage in the operator code -# (v0.4.0+: config schema compatibility plus HYPERFLEET-1603 database *_FILE support) -# -# For local development with a custom API image, manually edit the value below -# or use yq to update programmatically, then restore before committing. -# -# Production/Konflux: Digest-pinned via bundle.konflux.Dockerfile ARG overrides -patches: -- patch: |- - - op: add - path: /spec/template/spec/containers/0/env/- - value: - name: RELATED_IMAGE_HYPERFLEET_API - value: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-api:latest - target: - kind: Deployment - name: controller-manager diff --git a/config/manager/prod/kustomization.yaml b/config/manager/prod/kustomization.yaml new file mode 100644 index 0000000..6cd91c1 --- /dev/null +++ b/config/manager/prod/kustomization.yaml @@ -0,0 +1,28 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +# Konflux nudges update the digest-pinned pullspecs in this file. + +resources: +- manager.yaml + +images: +- name: controller + newName: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator + digest: sha256:7504189fc375ee65457baa568487b9f083b35b882d58601cd4f4ad8ee50e639e + +patches: +- patch: |- + - op: add + path: /spec/template/spec/containers/0/env/- + value: + name: RELATED_IMAGE_HYPERFLEET_API + value: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-api@sha256:99f8cdda580069de21ba0e13b5b171cf82b81b93dc88b12bcaa8294e72e84fc3 + - op: add + path: /spec/template/spec/containers/0/env/- + value: + name: RELATED_IMAGE_HYPERFLEET_OPERATOR + value: quay.io/redhat-services-prod/hyperfleet-tenant/hyperfleet/hyperfleet-operator@sha256:7504189fc375ee65457baa568487b9f083b35b882d58601cd4f4ad8ee50e639e + target: + kind: Deployment + name: controller-manager diff --git a/config/manifests/bases/hyperfleet-operator.clusterserviceversion.yaml b/config/manifests/bases/hyperfleet-operator.clusterserviceversion.yaml index 8e3a240..99b99bd 100644 --- a/config/manifests/bases/hyperfleet-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/hyperfleet-operator.clusterserviceversion.yaml @@ -33,9 +33,6 @@ metadata: } ] capabilities: Basic Install - # Conforma olm.feature_annotations_format requires all seven as string booleans. - # disconnected is true because relatedImages are digest-pinned. fips-compliant - # flips to "true" only after a verified FIPS build. HYPERFLEET-1614. features.operators.openshift.io/disconnected: "true" features.operators.openshift.io/fips-compliant: "false" features.operators.openshift.io/proxy-aware: "false" @@ -88,4 +85,9 @@ spec: provider: name: Red Hat url: https://github.com/openshift-hyperfleet + relatedImages: + - image: "" + name: hyperfleet-api + - image: "" + name: hyperfleet-operator version: 0.0.0 diff --git a/config/manifests/kustomization.yaml b/config/manifests/kustomization.yaml index bb7f880..536bdcf 100644 --- a/config/manifests/kustomization.yaml +++ b/config/manifests/kustomization.yaml @@ -6,6 +6,19 @@ resources: - ../samples - ../scorecard +replacements: +- source: + kind: Deployment + name: hyperfleet-operator-controller-manager + fieldPath: spec.template.spec.containers.[name=manager].image + targets: + - select: + kind: ClusterServiceVersion + fieldPaths: + - metadata.annotations.containerImage + options: + create: true + # [WEBHOOK] To enable webhooks, uncomment all the sections with [WEBHOOK] prefix. # Do NOT uncomment sections with prefix [CERTMANAGER], as OLM does not support cert-manager. # These patches remove the unnecessary "cert" volume and its manager container volumeMount. From f44c1e2e01cfb126fdb4e0c3ca4e6f56d5bcbc12 Mon Sep 17 00:00:00 2001 From: Mallory Hill Date: Thu, 10 Sep 2026 15:58:05 -0400 Subject: [PATCH 2/4] HYPERFLEET-1411 - feat: Updates --- .tekton/hyperfleet-operator-bundle-push.yaml | 5 ++--- .tekton/hyperfleet-operator-push.yaml | 7 ++----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.tekton/hyperfleet-operator-bundle-push.yaml b/.tekton/hyperfleet-operator-bundle-push.yaml index ba6ed1a..f52b247 100644 --- a/.tekton/hyperfleet-operator-bundle-push.yaml +++ b/.tekton/hyperfleet-operator-bundle-push.yaml @@ -8,8 +8,7 @@ metadata: pipelinesascode.tekton.dev/cancel-in-progress: "false" pipelinesascode.tekton.dev/max-keep-runs: "3" pipelinesascode.tekton.dev/on-cel-expression: event == "push" && target_branch - == "main" && ( ".tekton/hyperfleet-operator-bundle-push.yaml".pathChanged() || "bundle.konflux.Dockerfile".pathChanged() - || "bundle-hack/***".pathChanged() || "bundle/***".pathChanged() ) + == "main" && ( ".tekton/hyperfleet-operator-bundle-push.yaml".pathChanged() || "bundle.Dockerfile".pathChanged()) labels: appstudio.openshift.io/application: hyperfleet appstudio.openshift.io/component: hyperfleet-operator-bundle @@ -25,7 +24,7 @@ spec: - name: output-image value: quay.io/redhat-user-workloads/hyperfleet-tenant/hyperfleet/hyperfleet-operator-bundle:{{revision}} - name: dockerfile - value: ./bundle.konflux.Dockerfile + value: ./bundle.Dockerfile - name: path-context value: . pipelineSpec: diff --git a/.tekton/hyperfleet-operator-push.yaml b/.tekton/hyperfleet-operator-push.yaml index 6e90ce6..544120a 100644 --- a/.tekton/hyperfleet-operator-push.yaml +++ b/.tekton/hyperfleet-operator-push.yaml @@ -2,7 +2,7 @@ apiVersion: tekton.dev/v1 kind: PipelineRun metadata: annotations: - build.appstudio.openshift.io/build-nudge-files: bundle.konflux.Dockerfile + build.appstudio.openshift.io/build-nudge-files: config/manager/prod/kustomization.yaml build.appstudio.openshift.io/repo: https://github.com/openshift-hyperfleet/hyperfleet-operator?rev={{revision}} build.appstudio.redhat.com/commit_sha: '{{revision}}' build.appstudio.redhat.com/target_branch: '{{target_branch}}' @@ -12,10 +12,7 @@ metadata: event == "push" && target_branch == "main" && !(files.all.all(x, - x.matches('^bundle\\.konflux\\.Dockerfile$') - || x.matches('^bundle\\.Dockerfile$') - || x.matches('^bundle-hack/') - || x.matches('^bundle/') + x.matches('^bundle\\.Dockerfile$') || x.matches('^\\.tekton/hyperfleet-operator-bundle-push\\.yaml$') )) labels: From e1f686cc9099eaf434bd15be894b5066f94f4579 Mon Sep 17 00:00:00 2001 From: Mallory Hill Date: Thu, 10 Sep 2026 16:03:05 -0400 Subject: [PATCH 3/4] HYPERFLEET-1411 - feat: Updates --- .tekton/hyperfleet-operator-bundle-push.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.tekton/hyperfleet-operator-bundle-push.yaml b/.tekton/hyperfleet-operator-bundle-push.yaml index f52b247..170af8a 100644 --- a/.tekton/hyperfleet-operator-bundle-push.yaml +++ b/.tekton/hyperfleet-operator-bundle-push.yaml @@ -221,6 +221,7 @@ spec: value: $(tasks.clone-repository.results.commit) - name: BUILD_ARGS value: + - KUSTOMIZE_VARIANT=config/manager/prod/kustomization.yaml - $(params.build-args[*]) - name: BUILD_ARGS_FILE value: $(params.build-args-file) From 158d158c169ded9f4e8d01bc56a2b149058cb817 Mon Sep 17 00:00:00 2001 From: Mallory Hill Date: Thu, 10 Sep 2026 16:07:08 -0400 Subject: [PATCH 4/4] HYPERFLEET-1411 - feat: Updates --- bundle.Dockerfile | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/bundle.Dockerfile b/bundle.Dockerfile index 91a0201..50cfee9 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -8,16 +8,7 @@ RUN cp /workdir/config/manager/${KUSTOMIZE_VARIANT} \ /workdir/config/manager/kustomization.yaml && \ kustomize build /workdir/config/manifests > /workdir/manifests.yaml -FROM alpine:3.20 AS operator - -ARG OPERATOR_SDK_VERSION=v1.42.3 -ARG ARCH=amd64 - -RUN apk add --no-cache curl && \ - curl -fsSLo /usr/local/bin/operator-sdk \ - "https://github.com/operator-framework/operator-sdk/releases/download/${OPERATOR_SDK_VERSION}/operator-sdk_linux_${ARCH}" && \ - chmod +x /usr/local/bin/operator-sdk - +FROM quay.io/operator-framework/operator-sdk:v1.42.3 AS operator COPY --from=kustomize /workdir/manifests.yaml /workdir/manifests.yaml ARG CHANNELS=stable ARG VERSION=0.0.1