Skip to content

🌱 Add test-operator with custom controller #2085

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
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: 6 additions & 0 deletions .bingo/Variables.mk
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ $(GORELEASER): $(BINGO_DIR)/goreleaser.mod
@echo "(re)installing $(GOBIN)/goreleaser-v1.26.2"
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=goreleaser.mod -o=$(GOBIN)/goreleaser-v1.26.2 "github.com/goreleaser/goreleaser"

HELM := $(GOBIN)/helm-v3.18.4
$(HELM): $(BINGO_DIR)/helm.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@echo "(re)installing $(GOBIN)/helm-v3.18.4"
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=helm.mod -o=$(GOBIN)/helm-v3.18.4 "helm.sh/helm/v3/cmd/helm"

KIND := $(GOBIN)/kind-v0.29.0
$(KIND): $(BINGO_DIR)/kind.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
Expand Down
5 changes: 5 additions & 0 deletions .bingo/helm.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT

go 1.24.3

require helm.sh/helm/v3 v3.18.4 // cmd/helm
303 changes: 303 additions & 0 deletions .bingo/helm.sum

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions .bingo/variables.env
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ GOLANGCI_LINT="${GOBIN}/golangci-lint-v2.1.6"

GORELEASER="${GOBIN}/goreleaser-v1.26.2"

HELM="${GOBIN}/helm-v3.18.4"

KIND="${GOBIN}/kind-v0.29.0"

KUSTOMIZE="${GOBIN}/kustomize-v5.6.0"
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/testdata.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: testdata
Copy link
Contributor

@camilamacedo86 camilamacedo86 Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we discuss the case scenarios:

The test-operator supports AllNamespaces, SingleNamespace, and OwnNamespace install modes.

  • v1.0.0: is just the crd and the existing configmap resource
  • v1.3.0: has the same crd as v1.0.0 and the updated configmap previously part of v2.0.0
  • v2.0.0: has validating, mutating and conversion webhooks

The DELTA between v1.0.0 and v2.0.0 is clear
V2.0.0 should introduce webhooks

But what is the DELTA between v1.0.0 and v1.3.0
What do we want to cover with v1.3.0?
Do we want to add any changes that would not be a breaking change?
What scenarios do we need to cover?

IHMO it should be:

  • v1.0.0 - Initial basic project ( no metrics. no networkpolicies )
  • v.1.1.0 - Enable network policy, metrics, etc (not a breaking change)
  • v2.0.0 - Has webhooks and v2 CRD -> migration from v1 to V2 using spoke

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1.3.0 is just to harmonize with what's already there. It's something that can definitely be revisited. Right now, 2.0.0 includes this configmap. We can probably just collapse it to 1.0.0 and do the check. I think it's just a sanity check to make sure that annotations that include template syntax don't get affected.

Copy link
Contributor Author

@perdasilva perdasilva Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the list you put there is fine. I don't even think we need the 1.1.0 version. We only care about what is in the payload insofar as it interacts with OLM features/behavior. I.e. whether it has network policies, exposes metrics, uses HA, etc. isn't important if it doesn't matter to OLM. We don't need to add the complexity.

When we get to things like probing the state of the installation, or want to test some boxcutter features etc, then I think this will become more necessary. For now, if it stamps out a configmap (or any other resource) just to say it stamped out a resource from the bundle, that's enough imo. I think v1.0.0 and v2.0.0 give us what we need for now.

Copy link
Contributor

@camilamacedo86 camilamacedo86 Jul 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I.e. whether it has network policies, exposes metrics, uses HA, etc. isn't important if it doesn't matter to OLM

IHMO: It is metter because we must support those configs
We must ensure that OLM works well with NP, and etc


on:
workflow_dispatch:
pull_request:
merge_group:
push:
branches:
- main

jobs:
unit-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Run test-operator unit tests
run: |
make test-operator-test-unit
29 changes: 26 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,23 @@ verify: k8s-pin kind-verify-versions fmt generate manifests crd-ref-docs generat

# Renders registry+v1 bundles in test/convert
# Used by CI in verify to catch regressions in the registry+v1 -> plain conversion code
.PHONY: generate-test-data
generate-test-data:
.PHONY: render-regv1-bundle
render-regv1-bundle:
go run test/convert/generate-manifests.go

.PHONY: generate-test-operator-bundles
generate-test-operator-bundles:
BUNDLE_VERSION=1.0.0 BUNDLE_CHANNELS=beta BUNDLE_MANIFEST_PATH=$(ROOT_DIR)/testdata/images/bundles/test-operator/v1.0.0 \
$(MAKE) -C ./testdata/operators/test-operator/v1 bundle
BUNDLE_VERSION=1.3.0 BUNDLE_CHANNELS=beta BUNDLE_MANIFEST_PATH=$(ROOT_DIR)/testdata/images/bundles/test-operator/v1.3.0 \
HELM_OPTS=--set=configmap.shouldNotTemplate=true $(MAKE) -C ./testdata/operators/test-operator/v1 bundle
BUNDLE_VERSION=2.0.0 BUNDLE_CHANNELS=beta BUNDLE_MANIFEST_PATH=$(ROOT_DIR)/testdata/images/bundles/test-operator/v2.0.0 \
$(MAKE) -C ./testdata/operators/test-operator/v2 bundle

.PHONY: generate-test-data
generate-test-data: render-regv1-bundle generate-test-operator-bundles


.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 @@ -246,11 +259,21 @@ test-unit: $(SETUP_ENVTEST) envtest-k8s-bins #HELP Run the unit tests
$(UNIT_TEST_DIRS) \
-test.gocoverdir=$(COVERAGE_UNIT_DIR)

.PHONY: test-operator-test-unit
test-operator-test-unit: $(SETUP_ENVTEST) envtest-k8s-bins
$(MAKE) -C ./testdata/operators/test-operator/v1 test-unit
$(MAKE) -C ./testdata/operators/test-operator/v2 test-unit

.PHONY: build-test-operator-controllers
build-test-operator-controllers:
CONTROLLER_BINARY_PATH=$(ROOT_DIR)/testdata/images/controllers/test-operator/v1.0.0 $(MAKE) -C ./testdata/operators/test-operator/v1 build
CONTROLLER_BINARY_PATH=$(ROOT_DIR)/testdata/images/controllers/test-operator/v2.0.0 $(MAKE) -C ./testdata/operators/test-operator/v2 build

.PHONY: image-registry
E2E_REGISTRY_IMAGE=localhost/e2e-test-registry:devel
image-registry: export GOOS=linux
image-registry: export GOARCH=amd64
image-registry: ## Build the testdata catalog used for e2e tests and push it to the image registry
image-registry: build-test-operator-controllers ## Build the testdata catalog used for e2e tests and push it to the image registry
go build $(GO_BUILD_FLAGS) $(GO_BUILD_EXTRA_FLAGS) -tags '$(GO_BUILD_TAGS)' -ldflags '$(GO_BUILD_LDFLAGS)' -gcflags '$(GO_BUILD_GCFLAGS)' -asmflags '$(GO_BUILD_ASMFLAGS)' -o ./testdata/push/bin/push ./testdata/push/push.go
$(CONTAINER_RUNTIME) build -f ./testdata/Dockerfile -t $(E2E_REGISTRY_IMAGE) ./testdata
$(CONTAINER_RUNTIME) save $(E2E_REGISTRY_IMAGE) | $(KIND) load image-archive /dev/stdin --name $(KIND_CLUSTER_NAME)
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/cluster_extension_install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ func TestClusterExtensionInstallReResolvesWhenCatalogIsPatched(t *testing.T) {
assert.Equal(ct, metav1.ConditionTrue, cond.Status)
assert.Equal(ct, ocv1.ReasonSucceeded, cond.Reason)
assert.Contains(ct, cond.Message, "Installed bundle")
assert.Contains(ct, clusterExtension.Status.Install.Bundle.Version, "2.0.0")
assert.Contains(ct, clusterExtension.Status.Install.Bundle.Version, "1.3.0")
}
}, pollDuration, pollInterval)

Expand Down
1 change: 1 addition & 0 deletions testdata/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
push/bin
images/controllers
1 change: 1 addition & 0 deletions testdata/images/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
controllers/*

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: v1
data:
name: test-configmap
version: v1.0.0
kind: ConfigMap
metadata:
name: test-configmap
data:
version: "v1.0.0"
name: "test-configmap"
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
annotations:
alm-examples: '[]'
capabilities: Basic Install
operators.operatorframework.io/builder: operator-sdk-v1.34.1
operators.operatorframework.io/project_layout: unknown
name: test.v1.0.0
namespace: placeholder
spec:
apiservicedefinitions: {}
customresourcedefinitions:
owned:
- description: TestOperator is the Schema for the testoperators API.
displayName: Test Operator
kind: TestOperator
name: testoperators.testolm.operatorframework.io
version: v1
description: Test OLM Operator
displayName: OLM Test Operator
icon:
- base64data: ""
mediatype: ""
install:
spec:
clusterPermissions:
- rules:
- apiGroups:
- testolm.operatorframework.io
resources:
- testoperators
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- testolm.operatorframework.io
resources:
- testoperators/finalizers
verbs:
- update
- apiGroups:
- testolm.operatorframework.io
resources:
- testoperators/status
verbs:
- get
- patch
- update
serviceAccountName: test-operator-manager
deployments:
- label:
app.kubernetes.io/name: test-operator
control-plane: controller-manager
name: controller-manager
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: test-operator
control-plane: controller-manager
strategy: {}
template:
metadata:
annotations:
kubectl.kubernetes.io/default-container: manager
labels:
app.kubernetes.io/name: test-operator
control-plane: controller-manager
spec:
containers:
- args:
- --health-probe-bind-address=:8081
command:
- /manager
env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.annotations['olm.targetNamespaces']
image: docker-registry.operator-controller-e2e.svc.cluster.local:5000/controllers/test-operator:v1.0.0
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: test-operator-manager
terminationGracePeriodSeconds: 10
strategy: deployment
installModes:
- supported: true
type: OwnNamespace
- supported: true
type: SingleNamespace
- supported: false
type: MultiNamespace
- supported: true
type: AllNamespaces
keywords:
- test
- operator
links:
- name: V1
url: https://github.com/operator-framework/operator-controller
maintainers:
- email: [email protected]
name: community
maturity: alpha
provider:
name: operator-framework
url: https://github.com/operator-framework/operator-controller
version: 1.0.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.18.0
creationTimestamp: null
name: testoperators.testolm.operatorframework.io
spec:
group: testolm.operatorframework.io
names:
kind: TestOperator
listKind: TestOperatorList
plural: testoperators
singular: testoperator
scope: Namespaced
versions:
- name: v1
schema:
openAPIV3Schema:
description: TestOperator is the Schema for the testoperators API.
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: TestOperatorSpec defines the desired state of TestOperator.
properties:
message:
type: string
type: object
status:
description: TestOperatorStatus defines the observed state of TestOperator.
properties:
echo:
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: null
storedVersions: null
Loading
Loading