diff --git a/Dockerfile b/Dockerfile index b033f972..55891c7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,8 +17,7 @@ COPY controllers/ controllers/ COPY pkg/ pkg/ ARG VERSION=latest -ARG DEFAULT_AUTHORINO_IMAGE=quay.io/kuadrant/authorino:latest -RUN CGO_ENABLED=0 GO111MODULE=on go build -a -ldflags "-X main.version=${VERSION} -X github.com/kuadrant/authorino-operator/controllers.DefaultAuthorinoImage=${DEFAULT_AUTHORINO_IMAGE}" -o manager main.go +RUN CGO_ENABLED=0 GO111MODULE=on go build -a -ldflags "-X main.version=${VERSION}" -o manager main.go # Use Red Hat minimal base image to package the binary # https://catalog.redhat.com/software/containers/ubi9-minimal diff --git a/Makefile b/Makefile index 1597efab..f0795369 100644 --- a/Makefile +++ b/Makefile @@ -174,18 +174,19 @@ endif # Run the tests test: manifests generate fmt vet setup-envtest echo $(SETUP_ENVTEST) - KUBEBUILDER_ASSETS='$(strip $(shell $(SETUP_ENVTEST) --arch=amd64 use -p path 1.22.x))' go test -ldflags="-X github.com/kuadrant/authorino-operator/controllers.DefaultAuthorinoImage=$(DEFAULT_AUTHORINO_IMAGE)" ./... -coverprofile cover.out + KUBEBUILDER_ASSETS='$(strip $(shell $(SETUP_ENVTEST) --arch=amd64 use -p path 1.22.x))' go test ./... -coverprofile cover.out ##@ Build build: generate fmt vet ## Build manager binary. - go build -ldflags "-X main.version=$(VERSION) -X github.com/kuadrant/authorino-operator/controllers.DefaultAuthorinoImage=$(DEFAULT_AUTHORINO_IMAGE)" -o bin/manager main.go + go build -ldflags "-X main.version=$(VERSION)" -o bin/manager main.go +run: export DEFAULT_AUTHORINO_IMAGE := $(DEFAULT_AUTHORINO_IMAGE) run: manifests generate fmt vet ## Run a controller from your host. - go run -ldflags "-X main.version=$(VERSION) -X github.com/kuadrant/authorino-operator/controllers.DefaultAuthorinoImage=$(DEFAULT_AUTHORINO_IMAGE)" ./main.go + go run -ldflags "-X main.version=$(VERSION)" ./main.go docker-build: ## Build docker image with the manager. - docker build --build-arg VERSION=$(VERSION) --build-arg DEFAULT_AUTHORINO_IMAGE=$(DEFAULT_AUTHORINO_IMAGE) -t $(OPERATOR_IMAGE) . + docker build --build-arg VERSION=$(VERSION) -t $(OPERATOR_IMAGE) . docker-push: ## Push docker image with the manager. docker push ${OPERATOR_IMAGE} @@ -234,6 +235,7 @@ DEPLOYMENT_FILE = $(DEPLOYMENT_DIR)/manifests.yaml deploy-manifest: mkdir -p $(DEPLOYMENT_DIR) cd $(PROJECT_DIR)/config/manager && $(KUSTOMIZE) edit set image controller=$(OPERATOR_IMAGE) ;\ + echo "DEFAULT_AUTHORINO_IMAGE=$(DEFAULT_AUTHORINO_IMAGE)" > $(PROJECT_DIR)/config/manager/env-vars.env cd $(PROJECT_DIR) && $(KUSTOMIZE) build config/deploy > $(DEPLOYMENT_FILE) # clean up cd $(PROJECT_DIR)/config/manager && $(KUSTOMIZE) edit set image controller=${DEFAULT_OPERATOR_IMAGE} @@ -325,6 +327,7 @@ verify-manifests: manifests $(YQ) ## Verify manifests update. [ -z "$$(git ls-files --other --exclude-standard --directory --no-empty-directory ./config)" ] $(YQ) ea -e 'select([.][].kind == "Deployment") | select([.][].metadata.name == "authorino-operator").spec.template.spec.containers[0].image | . == "$(OPERATOR_IMAGE)"' config/deploy/manifests.yaml $(YQ) ea -e 'select([.][].kind == "Deployment") | select([.][].metadata.name == "authorino-webhooks").spec.template.spec.containers[0].image | . == "$(EXPECTED_DEFAULT_AUTHORINO_IMAGE)"' config/deploy/manifests.yaml + $(YQ) ea -e 'select([.][].kind == "ConfigMap") | select([.][].metadata.name == "authorino-operator-env").data.DEFAULT_AUTHORINO_IMAGE | . == "$(EXPECTED_DEFAULT_AUTHORINO_IMAGE)"' config/deploy/manifests.yaml $(YQ) e -e '.metadata.annotations.containerImage == "$(OPERATOR_IMAGE)"' config/manifests/bases/authorino-operator.clusterserviceversion.yaml .PHONY: verify-bundle @@ -334,6 +337,7 @@ verify-bundle: bundle $(YQ) ## Verify bundle update. $(YQ) e -e '.metadata.annotations.containerImage == "$(OPERATOR_IMAGE)"' $(BUNDLE_CSV) $(YQ) e -e '.spec.install.spec.deployments[0].spec.template.spec.containers[0].image == "$(OPERATOR_IMAGE)"' $(BUNDLE_CSV) $(YQ) e -e '.spec.install.spec.deployments[1].spec.template.spec.containers[0].image == "$(EXPECTED_DEFAULT_AUTHORINO_IMAGE)"' $(BUNDLE_CSV) + $(YQ) e -e '.data.DEFAULT_AUTHORINO_IMAGE == "$(EXPECTED_DEFAULT_AUTHORINO_IMAGE)"' ./bundle/manifests/authorino-operator-env_v1_configmap.yaml .PHONY: verify-fmt verify-fmt: fmt ## Verify fmt update. diff --git a/RELEASE.md b/RELEASE.md index d79232e4..8aba680f 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -66,25 +66,24 @@ to match the latest . * Tons of Authorino docs and examples rely on this * The `manifests` make target is used to generate the compiled version of all manifests (operator’s and operand’s). It accepts as parameters: - + * `VERSION`: sets the version of the manifests of the operator generated by the operator-sdk command and image tag of the deployment added to `config/deploy/manifests.yaml` (default: latest) * `AUTHORINO_VERSION`: sets the operand’s branch that sources the manifests (CRD, role definitions) that are appended to `config/deploy/manifests.yaml` (default: latest) - + * Changes in the operand’s CRD/role definitions out date the `config/deploy/manifests.yaml` file, thus requiring a PR to the operator repo ([example](https://github.com/Kuadrant/authorino-operator/pull/68)) - + * The `verify-manifests` make target is used to verify consistency of the manifests * Triggered in the CI tests * Causes all PRs in the Operator repo to break whenever there’s a change in the operand’s API committed to the main branch → requires immediate update of the copy of operand’s manifests in the main branch of the operator and rebase of all PRs - -* Apart from the operand’s manifests pinned to a specific or latest version in the copy committed to -`config/deploy/manifests.yaml`, the Operator’s code contains hard-coded references to the default version of the operand -to install: - * Set at compilation time ([`controllers.DefaultAuthorinoImage`](https://github.com/Kuadrant/authorino-operator/blob/03b42633627337bc7d908e36e579340a0d8e12fb/controllers/constants.go#L95)) + +* Each build of the operator is matched to a default Auhtorino image: + * Controlled by the value of the `DEFAULT_AUTHORINO_IMAGE` environment variable set in the operator's deployment + * Should match the version of the `authorino-webhook` deployment * Configured in the `build.yaml` file ([example](https://github.com/Kuadrant/authorino-operator/blob/release-v0.10.0/build.yaml)) - * It can be overwritten in the Authorino CR → good for dev/test/staging workflows * Set to "latest" in the main branch + * For individual Authorino instances, it can be overwritten in the Authorino CR → good for dev/test/staging workflows diff --git a/bundle/manifests/authorino-operator-env_v1_configmap.yaml b/bundle/manifests/authorino-operator-env_v1_configmap.yaml new file mode 100644 index 00000000..f36d98d4 --- /dev/null +++ b/bundle/manifests/authorino-operator-env_v1_configmap.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +data: + DEFAULT_AUTHORINO_IMAGE: quay.io/kuadrant/authorino:latest +kind: ConfigMap +metadata: + name: authorino-operator-env diff --git a/bundle/manifests/authorino-operator.clusterserviceversion.yaml b/bundle/manifests/authorino-operator.clusterserviceversion.yaml index 61285912..cea19082 100644 --- a/bundle/manifests/authorino-operator.clusterserviceversion.yaml +++ b/bundle/manifests/authorino-operator.clusterserviceversion.yaml @@ -314,6 +314,12 @@ spec: - --leader-elect command: - /manager + env: + - name: DEFAULT_AUTHORINO_IMAGE + valueFrom: + configMapKeyRef: + key: DEFAULT_AUTHORINO_IMAGE + name: authorino-operator-env image: quay.io/kuadrant/authorino-operator:latest livenessProbe: httpGet: diff --git a/config/deploy/manifests.yaml b/config/deploy/manifests.yaml index 577605dc..22584164 100644 --- a/config/deploy/manifests.yaml +++ b/config/deploy/manifests.yaml @@ -6095,6 +6095,14 @@ subjects: namespace: authorino-operator --- apiVersion: v1 +data: + DEFAULT_AUTHORINO_IMAGE: quay.io/kuadrant/authorino:latest +kind: ConfigMap +metadata: + name: authorino-operator-env + namespace: authorino-operator +--- +apiVersion: v1 data: controller_manager_config.yaml: | apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 @@ -6152,6 +6160,12 @@ spec: - --leader-elect command: - /manager + env: + - name: DEFAULT_AUTHORINO_IMAGE + valueFrom: + configMapKeyRef: + key: DEFAULT_AUTHORINO_IMAGE + name: authorino-operator-env image: quay.io/kuadrant/authorino-operator:latest livenessProbe: httpGet: diff --git a/config/manager/.gitignore b/config/manager/.gitignore new file mode 100644 index 00000000..3af49083 --- /dev/null +++ b/config/manager/.gitignore @@ -0,0 +1 @@ +env-vars.env diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 1cca0209..f641f3a2 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -1,3 +1,6 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + resources: - manager.yaml @@ -8,8 +11,10 @@ configMapGenerator: - files: - controller_manager_config.yaml name: manager-config -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization +- envs: + - env-vars.env + name: authorino-operator-env + images: - name: controller newName: quay.io/kuadrant/authorino-operator diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index b7cada2d..ea64d826 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -29,6 +29,12 @@ spec: - /manager args: - --leader-elect + env: + - name: DEFAULT_AUTHORINO_IMAGE + valueFrom: + configMapKeyRef: + name: authorino-operator-env + key: DEFAULT_AUTHORINO_IMAGE image: controller:latest name: manager securityContext: diff --git a/controllers/authorino_controller.go b/controllers/authorino_controller.go index dabe2d68..61627ca9 100644 --- a/controllers/authorino_controller.go +++ b/controllers/authorino_controller.go @@ -45,6 +45,8 @@ type AuthorinoReconciler struct { client.Client Log logr.Logger Scheme *runtime.Scheme + + DefaultAuthorinoImage string } //+kubebuilder:rbac:groups=operator.authorino.kuadrant.io,resources=authorinos,verbs=get;list;watch;create;update;patch;delete @@ -192,7 +194,7 @@ func (r *AuthorinoReconciler) buildAuthorinoDeployment(authorino *api.Authorino) var saName = authorino.Name + "-authorino" if authorino.Spec.Image == "" { - authorino.Spec.Image = DefaultAuthorinoImage + authorino.Spec.Image = r.DefaultAuthorinoImage } var volumes []k8score.Volume diff --git a/controllers/authorino_controller_test.go b/controllers/authorino_controller_test.go index eb002c7b..0fdf137f 100644 --- a/controllers/authorino_controller_test.go +++ b/controllers/authorino_controller_test.go @@ -121,14 +121,13 @@ var _ = Describe("Authorino controller", func() { }, testTimeout, testInterval).Should(BeTrue()) replicas := int32(testAuthorinoReplicas) - image := DefaultAuthorinoImage existContainer := false Expect(deployment.Spec.Replicas).Should(Equal(&replicas)) Expect(deployment.Labels).Should(Equal(map[string]string{"thisLabel": "willPropagate"})) for _, container := range deployment.Spec.Template.Spec.Containers { if container.Name == authorinoContainerName { - Expect(container.Image).Should(Equal(image)) + Expect(container.Image).Should(Equal("authorino:latest")) Expect(container.ImagePullPolicy).Should(Equal(k8score.PullAlways)) checkAuthorinoArgs(authorinoInstance, container.Args) Expect(len(container.Env)).Should(Equal(0)) @@ -238,7 +237,6 @@ func newExtServerConfigMap() *k8score.ConfigMap { func newFullAuthorinoInstance() *api.Authorino { name := "a" + string(uuid.NewUUID()) - image := DefaultAuthorinoImage replicas := int32(testAuthorinoReplicas) tslEnable := true tlsDisabled := false @@ -254,7 +252,7 @@ func newFullAuthorinoInstance() *api.Authorino { Labels: map[string]string{"thisLabel": "willPropagate"}, }, Spec: api.AuthorinoSpec{ - Image: image, + Image: "authorino:latest", Replicas: &replicas, ImagePullPolicy: k8score.PullAlways, Volumes: api.VolumesSpec{ diff --git a/controllers/constants.go b/controllers/constants.go index 147922c3..835d9bdc 100644 --- a/controllers/constants.go +++ b/controllers/constants.go @@ -90,6 +90,3 @@ const ( statusUnableToUpdateDeployment = "UnableToUpdateDeployment" statusDeploymentNotReady = "DeploymentNotReady" ) - -// ldflags -var DefaultAuthorinoImage string diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 62120cf4..b81ea25d 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -88,9 +88,10 @@ var _ = BeforeSuite(func() { Expect(k8sClient.Create(context.TODO(), newCertSecret())).Should(Succeed()) err = (&AuthorinoReconciler{ - Client: k8sClient, - Log: ctrl.Log.WithName("authorino-operator").WithName("controller").WithName("Authorino"), - Scheme: mgr.GetScheme(), + Client: k8sClient, + Log: ctrl.Log.WithName("authorino-operator").WithName("controller").WithName("Authorino"), + Scheme: mgr.GetScheme(), + DefaultAuthorinoImage: "authorino:latest", }).SetupWithManager(mgr) Expect(err).ToNot(HaveOccurred()) diff --git a/main.go b/main.go index 54946103..a336ebda 100644 --- a/main.go +++ b/main.go @@ -41,10 +41,11 @@ import ( ) var ( - scheme = runtime.NewScheme() - setupLog = ctrl.Log.WithName("setup") - logger log.Logger - version string // value injected in compilation-time + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") + logger log.Logger + version string // value injected at compilation-time + defaultAuthorinoImage = os.Getenv("DEFAULT_AUTHORINO_IMAGE") ) func init() { @@ -89,7 +90,7 @@ func main() { ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - setupLog.Info("booting up authorino operator", "version", version, "default authorino image", controllers.DefaultAuthorinoImage) + setupLog.Info("booting up authorino operator", "version", version, "default authorino image", defaultAuthorinoImage) mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, @@ -105,9 +106,10 @@ func main() { } if err = (&controllers.AuthorinoReconciler{ - Client: mgr.GetClient(), - Log: logger, - Scheme: mgr.GetScheme(), + Client: mgr.GetClient(), + Log: logger, + Scheme: mgr.GetScheme(), + DefaultAuthorinoImage: defaultAuthorinoImage, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "Authorino") os.Exit(1)