diff --git a/.github/actions/deploy-klt-on-cluster/action.yml b/.github/actions/deploy-klt-on-cluster/action.yml index 01e5691ca1..3114fd88d3 100644 --- a/.github/actions/deploy-klt-on-cluster/action.yml +++ b/.github/actions/deploy-klt-on-cluster/action.yml @@ -57,7 +57,8 @@ runs: run: | sed -i 's/imagePullPolicy: Always/imagePullPolicy: Never/g' ~/download/artifacts/keptn-lifecycle-operator-manifest-test/release.yaml sed -i 's/ghcr.keptn.sh\/keptn\/functions-runtime:.*/localhost:5000\/keptn\/functions-runtime:${{ inputs.functions_runtime_tag }}/g' ~/download/artifacts/keptn-lifecycle-operator-manifest-test/release.yaml - kubectl apply -f ~/download/artifacts/keptn-cert-manager-manifest-test + kubectl create namespace keptn-lifecycle-toolkit-system + kubectl apply -f ~/download/artifacts/klt-cert-manager-manifest-test kubectl rollout status deployment klt-cert-manager -n keptn-lifecycle-toolkit-system -w kubectl apply -f ~/download/artifacts/keptn-lifecycle-operator-manifest-test kubectl apply -f ~/download/artifacts/scheduler-manifest-test diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index a7ed141270..15f78cb6a0 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -68,7 +68,7 @@ jobs: folder: "operator/" - name: "scheduler" folder: "scheduler/" - - name: "keptn-cert-manager" + - name: "klt-cert-manager" folder: "klt-cert-manager/" steps: - name: Check out code @@ -109,7 +109,7 @@ jobs: folder: "scheduler/" - name: "functions-runtime" folder: "functions-runtime/" - - name: "keptn-cert-manager" + - name: "klt-cert-manager" folder: "klt-cert-manager/" steps: - name: Check out code @@ -215,7 +215,7 @@ jobs: folder: "scheduler/" - name: "functions-runtime" folder: "functions-runtime/" - - name: "keptn-cert-manager" + - name: "klt-cert-manager" folder: "klt-cert-manager/" permissions: packages: write # Needed for pushing images to the registry @@ -261,7 +261,7 @@ jobs: cache-to: type=gha,scope=${{ github.ref_name }}-${{ matrix.config.name }} - name: Install controller-gen - if: matrix.config.name == 'keptn-lifecycle-operator' || matrix.config.name == 'keptn-cert-manager' + if: matrix.config.name == 'keptn-lifecycle-operator' || matrix.config.name == 'klt-cert-manager' working-directory: ./${{ matrix.config.folder }} run: make controller-gen diff --git a/.gitignore b/.gitignore index f2f2130508..c611f2b795 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +bin/ + # Binaries for programs and plugins *.exe *.exe~ @@ -24,7 +26,7 @@ kubeconfig manifests/ /scheduler/config/rendered/release.yaml /operator/config/rendered/release.yaml - +/klt-cert-manager/config/rendered/release.yaml # macOS .DS_Store diff --git a/Makefile b/Makefile index 544de6094d..079c016f9c 100644 --- a/Makefile +++ b/Makefile @@ -2,13 +2,28 @@ # renovate: datasource=github-releases depName=cert-manager/cert-manager CERT_MANAGER_VERSION ?= v1.11.0 -TAG ?= "$(shell date +%Y%m%d%s)" -TAG := $(TAG) +# renovate: datasource=github-tags depName=kubernetes-sigs/kustomize +KUSTOMIZE_VERSION?=v4.5.7 +# renovate: datasource=github-tags depName=helm/helm +HELM_VERSION ?= v3.10.2 +CHART_VERSION = v0.5.0 # x-release-please-version + # RELEASE_REGISTRY is the container registry to push # into. RELEASE_REGISTRY?=ghcr.io/keptn ARCH?=amd64 +TAG ?= "$(shell date +%Y%m%d%s)" +TAG := $(TAG) + +## Location to install dependencies to +LOCALBIN ?= $(shell pwd)/bin +$(LOCALBIN): + mkdir -p $(LOCALBIN) + +## Tool Binaries +KUSTOMIZE ?= $(LOCALBIN)/kustomize + .PHONY: integration-test #these tests should run on a real cluster! integration-test: @@ -22,6 +37,30 @@ integration-test-local: cleanup-manifests: rm -rf manifests +KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" +.PHONY: kustomize +kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. +$(KUSTOMIZE): $(LOCALBIN) + test -s $(LOCALBIN)/kustomize || { curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); } + +.PHONY: release-helm-manifests +release-helm-manifests: kustomize + echo "building helm overlay" + $(KUSTOMIZE) build ./helm/overlay > ./helm/chart/templates/rendered.yaml + +.PHONY: helm-package +helm-package: build-release-manifests release-helm-manifests + cd ./helm && helm package ./chart + cd ./helm && mv keptn-lifecycle-toolkit-*.tgz ./chart/charts + +.PHONY: build-release-manifests +build-release-manifests: + $(MAKE) -C operator generate + $(MAKE) -C klt-cert-manager generate + $(MAKE) -C operator release-helm-manifests RELEASE_REGISTRY=$(RELEASE_REGISTRY) TAG=$(TAG) ARCH=$(ARCH) + $(MAKE) -C scheduler release-manifests RELEASE_REGISTRY=$(RELEASE_REGISTRY) TAG=$(TAG) ARCH=$(ARCH) + $(MAKE) -C klt-cert-manager release-manifests RELEASE_REGISTRY=$(RELEASE_REGISTRY) TAG=$(TAG) ARCH=$(ARCH) + .PHONY: build-deploy-operator build-deploy-operator: $(MAKE) -C operator release-local.$(ARCH) RELEASE_REGISTRY=$(RELEASE_REGISTRY) TAG=$(TAG) @@ -46,7 +85,5 @@ build-deploy-certmanager: kubectl create namespace keptn-lifecycle-toolkit-system --dry-run=client -o yaml | kubectl apply -f - kubectl apply -f klt-cert-manager/config/rendered/release.yaml - - .PHONY: build-deploy-dev-environment build-deploy-dev-environment: build-deploy-certmanager build-deploy-operator build-deploy-scheduler diff --git a/helm/.gitignore b/helm/.gitignore new file mode 100644 index 0000000000..98d068ad6d --- /dev/null +++ b/helm/.gitignore @@ -0,0 +1,3 @@ +*.tgz +chart/templates/rendered.yaml +chart/crds/*.yaml diff --git a/helm/chart/.helmignore b/helm/chart/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/helm/chart/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/chart/Chart.yaml b/helm/chart/Chart.yaml new file mode 100644 index 0000000000..b1961a7da8 --- /dev/null +++ b/helm/chart/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +name: keptn-lifecycle-toolkit +description: A Helm chart for Keptn Lifecycle Toolkit, a set of tools to enable cloud-native application lifecycle management + +type: application + +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.5.0" # x-release-please-version diff --git a/helm/chart/charts/.gitkeep b/helm/chart/charts/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helm/chart/crds/.gitkeep b/helm/chart/crds/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helm/chart/templates/.gitkeep b/helm/chart/templates/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/helm/chart/values.yaml b/helm/chart/values.yaml new file mode 100644 index 0000000000..0fc06dbf14 --- /dev/null +++ b/helm/chart/values.yaml @@ -0,0 +1,4 @@ +## @section OpenTelemetry +otelCollector: + ## @param otelCollector.url Sets the URL for the open telemetry collector + url: "otel-collector:4317" diff --git a/helm/overlay/kustomization.yaml b/helm/overlay/kustomization.yaml new file mode 100644 index 0000000000..94673d9cce --- /dev/null +++ b/helm/overlay/kustomization.yaml @@ -0,0 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +# import the default deployment as the base +bases: + - ../../operator/config/default/base + - ../../klt-cert-manager/config/default + - ../../scheduler/manifests/install +# replace the default namespace with {{ include "chart.namespace" . }} +# .Release.Namespace has not been used so that a custom _helpers.tpl file can maintain the expected behaviour of +# helm install -n +namespace: "{{ .Release.Namespace }}" +patchesStrategicMerge: + - patches/patch_deployment.yaml diff --git a/helm/overlay/patches/patch_deployment.yaml b/helm/overlay/patches/patch_deployment.yaml new file mode 100644 index 0000000000..c45b95a17d --- /dev/null +++ b/helm/overlay/patches/patch_deployment.yaml @@ -0,0 +1,46 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + env: + - name: OTEL_COLLECTOR_URL + value: "{{ .Values.otelCollector.url }}" + + +#--- +#apiVersion: apps/v1 #example patch for certmanager +#kind: Deployment +#metadata: +# name: cert-manager +# namespace: system +#spec: +# template: +# spec: +# containers: +# - name: manager +# env: +# - name: NEW_ENV_VAR +# value: "{{ .Values.myNewEnvVar }}" + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: keptn-scheduler + namespace: keptn-lifecycle-toolkit-system +spec: + template: + spec: + containers: + - name: keptn-scheduler + env: + - name: OTEL_COLLECTOR_URL + value: "{{ .Values.otelCollector.url }}" + diff --git a/klt-cert-manager/Makefile b/klt-cert-manager/Makefile index 39aa9824f3..bbdf776c87 100644 --- a/klt-cert-manager/Makefile +++ b/klt-cert-manager/Makefile @@ -1,13 +1,13 @@ # Image URL to use all building/pushing image targets -IMG ?= klc-certmanager:latest +IMG ?= klt-cert-manager:latest # RELEASE_REGISTRY is the container registry to push into. RELEASE_REGISTRY?=ghcr.io/keptn RELEASE_TIME=$(shell date +%Y%m%d%s) BUILD_TIME=$(shell date -u "+%F_%T") RELEASE_VERSION?=$(RELEASE_TIME)-v0.24.3#$(shell git describe --tags --match "v*") TAG?=latest -RELEASE_IMAGE:=keptn-cert-manager:$(TAG) +RELEASE_IMAGE:=klt-cert-manager:$(TAG) ARCHS = amd64 arm64 COMMONENVVAR=GOOS=$(shell uname -s | tr A-Z a-z) diff --git a/klt-cert-manager/config/manager/manager.yaml b/klt-cert-manager/config/manager/manager.yaml index 565cee822b..fcf5ffd73f 100644 --- a/klt-cert-manager/config/manager/manager.yaml +++ b/klt-cert-manager/config/manager/manager.yaml @@ -1,16 +1,4 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - control-plane: klt-cert-manager - app.kubernetes.io/name: namespace - app.kubernetes.io/instance: system - app.kubernetes.io/component: manager - app.kubernetes.io/created-by: klt-cert-manager - app.kubernetes.io/part-of: klt-cert-manager - app.kubernetes.io/managed-by: kustomize - name: system ---- + apiVersion: apps/v1 kind: Deployment metadata: @@ -47,6 +35,11 @@ spec: - --leader-elect image: controller:latest name: manager + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace securityContext: allowPrivilegeEscalation: false capabilities: diff --git a/klt-cert-manager/controllers/keptnwebhookcontroller/certificate_secret_test.go b/klt-cert-manager/controllers/keptnwebhookcontroller/certificate_secret_test.go index 139051349a..f40ddf4c24 100644 --- a/klt-cert-manager/controllers/keptnwebhookcontroller/certificate_secret_test.go +++ b/klt-cert-manager/controllers/keptnwebhookcontroller/certificate_secret_test.go @@ -26,7 +26,7 @@ func TestSetSecretFromReader(t *testing.T) { t.Run(`fill with empty secret if secret does not exist`, func(t *testing.T) { fakeclient := fake.NewClient() certSecret := newCertificateSecret(fakeclient) - err := certSecret.setSecretFromReader(context.TODO(), namespace, testr.New(t)) + err := certSecret.setSecretFromReader(context.TODO(), testnamespace, testr.New(t)) assert.NoError(t, err) assert.False(t, certSecret.existsInCluster) @@ -37,7 +37,7 @@ func TestSetSecretFromReader(t *testing.T) { fakeclient := fake.NewClient( createTestSecret(t, createInvalidTestCertData(t))) certSecret := newCertificateSecret(fakeclient) - err := certSecret.setSecretFromReader(context.TODO(), namespace, testr.New(t)) + err := certSecret.setSecretFromReader(context.TODO(), testnamespace, testr.New(t)) assert.NoError(t, err) assert.True(t, certSecret.existsInCluster) @@ -135,7 +135,7 @@ func TestCreateOrUpdateIfNecessary(t *testing.T) { certSecret.secret = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: buildSecretName(), - Namespace: namespace, + Namespace: testnamespace, }, } certSecret.certificates = &Certs{ @@ -147,7 +147,7 @@ func TestCreateOrUpdateIfNecessary(t *testing.T) { assert.NoError(t, err) newSecret := corev1.Secret{} - err = fakeClient.Get(context.TODO(), client.ObjectKey{Name: buildSecretName(), Namespace: namespace}, &newSecret) + err = fakeClient.Get(context.TODO(), client.ObjectKey{Name: buildSecretName(), Namespace: testnamespace}, &newSecret) assert.NoError(t, err) assert.NotNil(t, newSecret) @@ -159,7 +159,7 @@ func TestCreateOrUpdateIfNecessary(t *testing.T) { certSecret.secret = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: buildSecretName(), - Namespace: namespace, + Namespace: testnamespace, }, } certSecret.certificates = &Certs{ @@ -171,7 +171,7 @@ func TestCreateOrUpdateIfNecessary(t *testing.T) { require.NoError(t, err) newSecret := corev1.Secret{} - err = fakeClient.Get(context.TODO(), client.ObjectKey{Name: buildSecretName(), Namespace: namespace}, &newSecret) + err = fakeClient.Get(context.TODO(), client.ObjectKey{Name: buildSecretName(), Namespace: testnamespace}, &newSecret) require.NoError(t, err) require.NotNil(t, newSecret) @@ -184,7 +184,7 @@ func TestCreateOrUpdateIfNecessary(t *testing.T) { assert.NoError(t, err) - err = fakeClient.Get(context.TODO(), client.ObjectKey{Name: buildSecretName(), Namespace: namespace}, &newSecret) + err = fakeClient.Get(context.TODO(), client.ObjectKey{Name: buildSecretName(), Namespace: testnamespace}, &newSecret) assert.NoError(t, err) assert.NotNil(t, newSecret) diff --git a/klt-cert-manager/controllers/keptnwebhookcontroller/config.go b/klt-cert-manager/controllers/keptnwebhookcontroller/config.go index b78237eb3b..d34a0d51d6 100644 --- a/klt-cert-manager/controllers/keptnwebhookcontroller/config.go +++ b/klt-cert-manager/controllers/keptnwebhookcontroller/config.go @@ -17,7 +17,6 @@ const ( crdGroup = "lifecycle.keptn.sh" certificatesSecretEmptyErr = "certificates secret is empty" couldNotUpdateCRDErr = "could not update crd config" - namespace = "keptn-lifecycle-toolkit-system" ) var keptnCRD = schema.GroupVersionResource{Group: "lifecycle.keptn.sh"} diff --git a/klt-cert-manager/controllers/keptnwebhookcontroller/keptnwebhookcertificate_controller.go b/klt-cert-manager/controllers/keptnwebhookcontroller/keptnwebhookcertificate_controller.go index 06d03df943..b745e7bbef 100644 --- a/klt-cert-manager/controllers/keptnwebhookcontroller/keptnwebhookcertificate_controller.go +++ b/klt-cert-manager/controllers/keptnwebhookcontroller/keptnwebhookcertificate_controller.go @@ -25,6 +25,7 @@ type KeptnWebhookCertificateReconciler struct { Scheme *runtime.Scheme CancelMgrFunc context.CancelFunc Log logr.Logger + Namespace string } //clusterrole @@ -92,20 +93,20 @@ func (r *KeptnWebhookCertificateReconciler) Reconcile(ctx context.Context, reque func (r *KeptnWebhookCertificateReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&appsv1.Deployment{}). - WithEventFilter(eventfilter.ForObjectNameAndNamespace(DeploymentName, namespace)). + WithEventFilter(eventfilter.ForObjectNameAndNamespace(DeploymentName, r.Namespace)). Owns(&corev1.Secret{}). Complete(r) } func (r *KeptnWebhookCertificateReconciler) setCertificates(ctx context.Context, certSecret *certificateSecret) error { - err := certSecret.setSecretFromReader(ctx, namespace, r.Log) + err := certSecret.setSecretFromReader(ctx, r.Namespace, r.Log) if err != nil { r.Log.Error(err, "could not get secret") return err } - err = certSecret.setCertificates(namespace) + err = certSecret.setCertificates(r.Namespace) if err != nil { r.Log.Error(err, "could not validate certificate") return err diff --git a/klt-cert-manager/controllers/keptnwebhookcontroller/webhook_cert_controller_test.go b/klt-cert-manager/controllers/keptnwebhookcontroller/webhook_cert_controller_test.go index acfe893623..88c370abba 100644 --- a/klt-cert-manager/controllers/keptnwebhookcontroller/webhook_cert_controller_test.go +++ b/klt-cert-manager/controllers/keptnwebhookcontroller/webhook_cert_controller_test.go @@ -19,10 +19,11 @@ import ( ) const ( - testDomain = ServiceName + "." + namespace + ".svc" + testDomain = ServiceName + "." + testnamespace + ".svc" expectedSecretName = DeploymentName + secretPostfix strategyWebhook = "webhook" testBytes = 123 + testnamespace = "keptn-ns" ) func TestReconcileCertificate_Create(t *testing.T) { @@ -35,7 +36,7 @@ func TestReconcileCertificate_Create(t *testing.T) { assert.Equal(t, SuccessDuration, res.RequeueAfter) secret := &corev1.Secret{} - err = clt.Get(context.TODO(), client.ObjectKey{Name: expectedSecretName, Namespace: namespace}, secret) + err = clt.Get(context.TODO(), client.ObjectKey{Name: expectedSecretName, Namespace: testnamespace}, secret) require.NoError(t, err) assert.NotNil(t, secret.Data) @@ -62,7 +63,7 @@ func TestReconcileCertificate_Update(t *testing.T) { assert.Equal(t, SuccessDuration, res.RequeueAfter) secret := &corev1.Secret{} - err = clt.Get(context.TODO(), client.ObjectKey{Name: expectedSecretName, Namespace: namespace}, secret) + err = clt.Get(context.TODO(), client.ObjectKey{Name: expectedSecretName, Namespace: testnamespace}, secret) require.NoError(t, err) assert.NotNil(t, secret.Data) @@ -89,7 +90,7 @@ func TestReconcileCertificate_ExistingSecretWithValidCertificate(t *testing.T) { assert.Equal(t, SuccessDuration, res.RequeueAfter) secret := &corev1.Secret{} - err = clt.Get(context.TODO(), client.ObjectKey{Name: expectedSecretName, Namespace: namespace}, secret) + err = clt.Get(context.TODO(), client.ObjectKey{Name: expectedSecretName, Namespace: testnamespace}, secret) require.NoError(t, err) verifyCertificates(t, secret, clt, false) @@ -189,8 +190,8 @@ func TestReconcile(t *testing.T) { t.Run(`update crd successfully with up-to-date secret`, func(t *testing.T) { fakeClient := fake.NewClient(crd1, crd2, crd3) cs := newCertificateSecret(fakeClient) - _ = cs.setSecretFromReader(context.TODO(), namespace, testr.New(t)) - _ = cs.setCertificates(namespace) + _ = cs.setSecretFromReader(context.TODO(), testnamespace, testr.New(t)) + _ = cs.setCertificates(testnamespace) _ = cs.createOrUpdateIfNecessary(context.TODO()) controller, request := prepareController(t, fakeClient) @@ -245,8 +246,8 @@ func TestReconcile(t *testing.T) { }, }) cs := newCertificateSecret(fakeClient) - _ = cs.setSecretFromReader(context.TODO(), namespace, testr.New(t)) - _ = cs.setCertificates(namespace) + _ = cs.setSecretFromReader(context.TODO(), testnamespace, testr.New(t)) + _ = cs.setCertificates(testnamespace) _ = cs.createOrUpdateIfNecessary(context.TODO()) controller, request := prepareController(t, fakeClient) @@ -285,7 +286,7 @@ func TestReconcile(t *testing.T) { assert.NotNil(t, result) secret := &corev1.Secret{} - err = fakeClient.Get(context.TODO(), client.ObjectKey{Name: expectedSecretName, Namespace: namespace}, secret) + err = fakeClient.Get(context.TODO(), client.ObjectKey{Name: expectedSecretName, Namespace: testnamespace}, secret) assert.NoError(t, err) }) } @@ -395,7 +396,7 @@ func createValidTestCertData(_ *testing.T) map[string][]byte { func createTestSecret(_ *testing.T, certData map[string][]byte) *corev1.Secret { return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Namespace: namespace, + Namespace: testnamespace, Name: expectedSecretName, }, Data: certData, @@ -404,14 +405,16 @@ func createTestSecret(_ *testing.T, certData map[string][]byte) *corev1.Secret { func prepareController(t *testing.T, clt client.Client) (*KeptnWebhookCertificateReconciler, reconcile.Request) { rec := &KeptnWebhookCertificateReconciler{ - Client: clt, - Log: testr.New(t), + + Client: clt, + Log: testr.New(t), + Namespace: testnamespace, } request := reconcile.Request{ NamespacedName: types.NamespacedName{ Name: DeploymentName, - Namespace: namespace, + Namespace: testnamespace, }, } @@ -433,7 +436,7 @@ func testWebhookClientConfig( func verifyCertificates(t *testing.T, secret *corev1.Secret, clt client.Client, isUpdate bool) { cert := Certs{ - Domain: getDomain(namespace), + Domain: getDomain(testnamespace), Data: secret.Data, SrcData: secret.Data, Now: time.Now(), diff --git a/klt-cert-manager/go.mod b/klt-cert-manager/go.mod index 37a506ced1..ff230c7605 100644 --- a/klt-cert-manager/go.mod +++ b/klt-cert-manager/go.mod @@ -4,6 +4,7 @@ go 1.19 require ( github.com/go-logr/logr v1.2.3 + github.com/kelseyhightower/envconfig v1.4.0 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.8.1 k8s.io/api v0.26.1 diff --git a/klt-cert-manager/go.sum b/klt-cert-manager/go.sum index 9a6c77b92d..4359b6ae8a 100644 --- a/klt-cert-manager/go.sum +++ b/klt-cert-manager/go.sum @@ -180,6 +180,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= +github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= diff --git a/klt-cert-manager/main.go b/klt-cert-manager/main.go index 440692955f..2d0b2b302a 100644 --- a/klt-cert-manager/main.go +++ b/klt-cert-manager/main.go @@ -2,8 +2,10 @@ package main import ( "flag" + "log" "os" + "github.com/kelseyhightower/envconfig" "github.com/keptn/lifecycle-toolkit/klt-cert-manager/controllers/keptnwebhookcontroller" corev1 "k8s.io/api/core/v1" apiv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -24,8 +26,6 @@ var ( setupLog = ctrl.Log.WithName("setup") ) -const ns = "keptn-lifecycle-toolkit-system" - func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(corev1.AddToScheme(scheme)) @@ -33,7 +33,15 @@ func init() { //+kubebuilder:scaffold:scheme } +type envConfig struct { + KLTNamespace string `envconfig:"NAMESPACE" default:"keptn-lifecycle-toolkit-system"` +} + func main() { + var env envConfig + if err := envconfig.Process("", &env); err != nil { + log.Fatalf("Failed to process env var: %s", err) + } var metricsAddr string var enableLeaderElection bool var probeAddr string @@ -52,7 +60,7 @@ func main() { mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, - Namespace: ns, + Namespace: env.KLTNamespace, MetricsBindAddress: metricsAddr, Port: 9443, HealthProbeBindAddress: probeAddr, @@ -79,6 +87,7 @@ func main() { Scheme: mgr.GetScheme(), CancelMgrFunc: nil, Log: ctrl.Log.WithName("KeptnWebhookCert Controller"), + Namespace: env.KLTNamespace, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "Deployment") os.Exit(1) diff --git a/operator/Makefile b/operator/Makefile index 4c0bfe8468..3f1a8ee476 100644 --- a/operator/Makefile +++ b/operator/Makefile @@ -69,6 +69,12 @@ help: ## Display this help. manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases +.PHONY: gen-crds +gen-crds: controller-gen ## Generate CustomResourceDefinition objects. + echo $(shell pwd) + $(CONTROLLER_GEN) crd paths="./..." output:crd:artifacts:config=../helm/chart/crds + + .PHONY: generate generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." @@ -133,8 +139,15 @@ uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified .PHONY: release-manifests release-manifests: manifests kustomize cd config/manager && $(KUSTOMIZE) edit set image controller=$(RELEASE_REGISTRY)/$(RELEASE_IMAGE) + echo "building default overlay" $(KUSTOMIZE) build config/default > config/rendered/release.yaml +.PHONY: release-helm-manifests + release-helm-manifests: manifests gen-crds kustomize + echo "building helm overlay" + cd config/manager && $(KUSTOMIZE) edit set image controller=$(RELEASE_REGISTRY)/$(RELEASE_IMAGE) + $(KUSTOMIZE) build config/default/base > config/rendered/release.yaml + .PHONY: deploy deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} diff --git a/operator/config/default/.gitignore b/operator/config/default/.gitignore index 33b4c9e307..7fcfb9ab1a 100644 --- a/operator/config/default/.gitignore +++ b/operator/config/default/.gitignore @@ -1,4 +1,4 @@ # Ignore autogen patch file for webhooks -manager_webhook_patch.yaml -webhookcainjection_patch.yaml +base/manager_webhook_patch.yaml +base/webhookcainjection_patch.yaml diff --git a/operator/config/default/base/kustomization.yaml b/operator/config/default/base/kustomization.yaml new file mode 100644 index 0000000000..9a78853ee1 --- /dev/null +++ b/operator/config/default/base/kustomization.yaml @@ -0,0 +1,29 @@ +# Adds namespace to all resources. +namespace: keptn-lifecycle-toolkit-system + +namePrefix: klc- + +bases: +- ../../rbac +- ../../manager +- ../../webhook +- ../../metrics + +patchesStrategicMerge: +- manager_auth_proxy_patch.yaml +- webhooknamespaces_patch.yaml + +# the following config is for teaching kustomize how to do var substitution +vars: +- name: SERVICE_NAMESPACE # namespace of the service + objref: + kind: Service + version: v1 + name: webhook-service + fieldref: + fieldpath: metadata.namespace +- name: SERVICE_NAME + objref: + kind: Service + version: v1 + name: webhook-service diff --git a/operator/config/default/manager_auth_proxy_patch.yaml b/operator/config/default/base/manager_auth_proxy_patch.yaml similarity index 100% rename from operator/config/default/manager_auth_proxy_patch.yaml rename to operator/config/default/base/manager_auth_proxy_patch.yaml diff --git a/operator/config/default/manager_config_patch.yaml b/operator/config/default/base/manager_config_patch.yaml similarity index 100% rename from operator/config/default/manager_config_patch.yaml rename to operator/config/default/base/manager_config_patch.yaml diff --git a/operator/config/default/webhooknamespaces_patch.yaml b/operator/config/default/base/webhooknamespaces_patch.yaml similarity index 100% rename from operator/config/default/webhooknamespaces_patch.yaml rename to operator/config/default/base/webhooknamespaces_patch.yaml diff --git a/operator/config/default/kustomization.yaml b/operator/config/default/kustomization.yaml index 1777b02f97..59613a9874 100644 --- a/operator/config/default/kustomization.yaml +++ b/operator/config/default/kustomization.yaml @@ -1,56 +1,6 @@ # Adds namespace to all resources. namespace: keptn-lifecycle-toolkit-system -# Value of this field is prepended to the -# names of all resources, e.g. a deployment named -# "wordpress" becomes "alices-wordpress". -# Note that it should also match with the prefix (text before '-') of the namespace -# field above. -namePrefix: klc- - -# Labels to add to all resources and selectors. -#commonLabels: -# someName: someValue - bases: - ../crd -- ../rbac -- ../manager -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -- ../webhook -- ../metrics -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. -# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. -#- ../prometheus - -patchesStrategicMerge: -# Protect the /metrics endpoint by putting it behind auth. -# If you want your controller-manager to expose the /metrics -# endpoint w/o any authn/z, please comment the following line. -- manager_auth_proxy_patch.yaml - -# Mount the controller config file for loading manager configurations -# through a ComponentConfig type -#- manager_config_patch.yaml - -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in -# crd/kustomization.yaml -# manager_webhook_patch.yaml - -- webhooknamespaces_patch.yaml - -# the following config is for teaching kustomize how to do var substitution -vars: -- name: SERVICE_NAMESPACE # namespace of the service - objref: - kind: Service - version: v1 - name: webhook-service - fieldref: - fieldpath: metadata.namespace -- name: SERVICE_NAME - objref: - kind: Service - version: v1 - name: webhook-service +- ./base diff --git a/operator/controllers/common/providers/common.go b/operator/controllers/common/providers/common.go index a562ee78bf..40fa31f729 100644 --- a/operator/controllers/common/providers/common.go +++ b/operator/controllers/common/providers/common.go @@ -8,11 +8,12 @@ import ( const DynatraceProviderName = "dynatrace" const PrometheusProviderName = "prometheus" const KeptnMetricProviderName = "keptn-metric" -const KLTNamespace = "keptn-lifecycle-toolkit-system" -var MetricDefaultProvider = &klcv1alpha2.KeptnEvaluationProvider{ - ObjectMeta: metav1.ObjectMeta{ - Name: KeptnMetricProviderName, - Namespace: KLTNamespace, - }, +func GetDefaultMetricProvider(namespace string) *klcv1alpha2.KeptnEvaluationProvider { + return &klcv1alpha2.KeptnEvaluationProvider{ + ObjectMeta: metav1.ObjectMeta{ + Name: KeptnMetricProviderName, + Namespace: namespace, + }, + } } diff --git a/operator/controllers/lifecycle/keptnevaluation/controller.go b/operator/controllers/lifecycle/keptnevaluation/controller.go index de0c02afe7..33aa73067d 100644 --- a/operator/controllers/lifecycle/keptnevaluation/controller.go +++ b/operator/controllers/lifecycle/keptnevaluation/controller.go @@ -43,11 +43,12 @@ import ( // KeptnEvaluationReconciler reconciles a KeptnEvaluation object type KeptnEvaluationReconciler struct { client.Client - Scheme *runtime.Scheme - Recorder record.EventRecorder - Log logr.Logger - Meters apicommon.KeptnMeters - Tracer trace.Tracer + Scheme *runtime.Scheme + Recorder record.EventRecorder + Log logr.Logger + Meters apicommon.KeptnMeters + Tracer trace.Tracer + Namespace string } //clusterrole @@ -266,7 +267,7 @@ func (r *KeptnEvaluationReconciler) fetchDefinitionAndProvider(ctx context.Conte } if evaluationDefinition.Spec.Source == providers.KeptnMetricProviderName { - return evaluationDefinition, providers.MetricDefaultProvider, nil + return evaluationDefinition, providers.GetDefaultMetricProvider(r.Namespace), nil } namespacedProvider := types.NamespacedName{ diff --git a/operator/controllers/lifecycle/keptnevaluation/controller_test.go b/operator/controllers/lifecycle/keptnevaluation/controller_test.go index c923944daf..8c12893498 100644 --- a/operator/controllers/lifecycle/keptnevaluation/controller_test.go +++ b/operator/controllers/lifecycle/keptnevaluation/controller_test.go @@ -13,6 +13,8 @@ import ( "k8s.io/apimachinery/pkg/types" ) +const KltNamespace = "klt-namespace" + func TestKeptnEvaluationReconciler_fetchDefinitionAndProvider(t *testing.T) { metricEvalDef, DTEvalDef, PromEvalDef, EvalDef := setupEvalDefinitions() @@ -35,16 +37,16 @@ func TestKeptnEvaluationReconciler_fetchDefinitionAndProvider(t *testing.T) { { name: "keptn metrics", namespacedDefinition: types.NamespacedName{ - Namespace: providers.KLTNamespace, + Namespace: KltNamespace, Name: "myKeptn", }, wantDef: metricEvalDef, - wantProv: providers.MetricDefaultProvider, + wantProv: providers.GetDefaultMetricProvider(KltNamespace), }, { name: "DT metrics", namespacedDefinition: types.NamespacedName{ - Namespace: providers.KLTNamespace, + Namespace: KltNamespace, Name: "myDT", }, wantDef: DTEvalDef, @@ -54,7 +56,7 @@ func TestKeptnEvaluationReconciler_fetchDefinitionAndProvider(t *testing.T) { { name: "Prometheus metrics", namespacedDefinition: types.NamespacedName{ - Namespace: providers.KLTNamespace, + Namespace: KltNamespace, Name: "myProm", }, wantDef: PromEvalDef, @@ -64,7 +66,7 @@ func TestKeptnEvaluationReconciler_fetchDefinitionAndProvider(t *testing.T) { { name: "Unexisting Evaluation Def", namespacedDefinition: types.NamespacedName{ - Namespace: providers.KLTNamespace, + Namespace: KltNamespace, Name: "whatever", }, wantDef: nil, @@ -74,7 +76,7 @@ func TestKeptnEvaluationReconciler_fetchDefinitionAndProvider(t *testing.T) { { name: "Unexisting Provider", namespacedDefinition: types.NamespacedName{ - Namespace: providers.KLTNamespace, + Namespace: KltNamespace, Name: "mydef", }, wantDef: nil, @@ -109,7 +111,7 @@ func TestKeptnEvaluationReconciler_fetchDefinitionAndProvider(t *testing.T) { func setupEvalDefinitions() (*klcv1alpha2.KeptnEvaluationDefinition, *klcv1alpha2.KeptnEvaluationDefinition, *klcv1alpha2.KeptnEvaluationDefinition, *klcv1alpha2.KeptnEvaluationDefinition) { metricEvalDef := &klcv1alpha2.KeptnEvaluationDefinition{ ObjectMeta: metav1.ObjectMeta{ - Namespace: providers.KLTNamespace, + Namespace: KltNamespace, Name: "myKeptn", }, Spec: klcv1alpha2.KeptnEvaluationDefinitionSpec{ @@ -121,7 +123,7 @@ func setupEvalDefinitions() (*klcv1alpha2.KeptnEvaluationDefinition, *klcv1alpha DTEvalDef := &klcv1alpha2.KeptnEvaluationDefinition{ ObjectMeta: metav1.ObjectMeta{ - Namespace: providers.KLTNamespace, + Namespace: KltNamespace, Name: "myDT", }, Spec: klcv1alpha2.KeptnEvaluationDefinitionSpec{ @@ -133,7 +135,7 @@ func setupEvalDefinitions() (*klcv1alpha2.KeptnEvaluationDefinition, *klcv1alpha PromEvalDef := &klcv1alpha2.KeptnEvaluationDefinition{ ObjectMeta: metav1.ObjectMeta{ - Namespace: providers.KLTNamespace, + Namespace: KltNamespace, Name: "myProm", }, Spec: klcv1alpha2.KeptnEvaluationDefinitionSpec{ @@ -145,7 +147,7 @@ func setupEvalDefinitions() (*klcv1alpha2.KeptnEvaluationDefinition, *klcv1alpha EvalDef := &klcv1alpha2.KeptnEvaluationDefinition{ ObjectMeta: metav1.ObjectMeta{ - Namespace: providers.KLTNamespace, + Namespace: KltNamespace, Name: "mdef", }, Spec: klcv1alpha2.KeptnEvaluationDefinitionSpec{ @@ -162,14 +164,14 @@ func setupProviders() (*klcv1alpha2.KeptnEvaluationProvider, *klcv1alpha2.KeptnE DTProv := &klcv1alpha2.KeptnEvaluationProvider{ ObjectMeta: metav1.ObjectMeta{ Name: providers.DynatraceProviderName, - Namespace: providers.KLTNamespace, + Namespace: KltNamespace, }, } PromProv := &klcv1alpha2.KeptnEvaluationProvider{ ObjectMeta: metav1.ObjectMeta{ Name: providers.PrometheusProviderName, - Namespace: providers.KLTNamespace, + Namespace: KltNamespace, }, } diff --git a/operator/main.go b/operator/main.go index e2893bf2c3..69254a9ad4 100644 --- a/operator/main.go +++ b/operator/main.go @@ -342,12 +342,13 @@ func main() { } evaluationReconciler := &keptnevaluation.KeptnEvaluationReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Log: ctrl.Log.WithName("KeptnEvaluation Controller"), - Recorder: mgr.GetEventRecorderFor("keptnevaluation-controller"), - Tracer: otel.Tracer("keptn/operator/evaluation"), - Meters: meters, + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + Log: ctrl.Log.WithName("KeptnEvaluation Controller"), + Recorder: mgr.GetEventRecorderFor("keptnevaluation-controller"), + Tracer: otel.Tracer("keptn/operator/evaluation"), + Meters: meters, + Namespace: env.PodNamespace, } if err = (evaluationReconciler).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "KeptnEvaluation") diff --git a/operator/test/component/evaluationcontroller_test.go b/operator/test/component/evaluationcontroller_test.go index 4274c6bb22..d79588467c 100644 --- a/operator/test/component/evaluationcontroller_test.go +++ b/operator/test/component/evaluationcontroller_test.go @@ -20,6 +20,8 @@ import ( "k8s.io/apimachinery/pkg/types" ) +const KLTnamespace = "keptnlifecycle" + var _ = Describe("KeptnEvaluationController", Ordered, func() { var ( evaluationName string @@ -46,15 +48,16 @@ var _ = Describe("KeptnEvaluationController", Ordered, func() { ////setup controllers here controllers := []interfaces.Controller{&keptnevaluation.KeptnEvaluationReconciler{ - Client: k8sManager.GetClient(), - Scheme: k8sManager.GetScheme(), - Recorder: k8sManager.GetEventRecorderFor("test-evaluation-controller"), - Log: GinkgoLogr, - Meters: initKeptnMeters(), - Tracer: tracer.Tracer("test-evaluation-tracer"), + Client: k8sManager.GetClient(), + Scheme: k8sManager.GetScheme(), + Recorder: k8sManager.GetEventRecorderFor("test-evaluation-controller"), + Log: GinkgoLogr, + Meters: initKeptnMeters(), + Tracer: tracer.Tracer("test-evaluation-tracer"), + Namespace: KLTnamespace, }} setupManager(controllers) // we can register multiple time the same controller - ns = makeKLTDefaultNamespace(providers.KLTNamespace) + ns = makeKLTDefaultNamespace(KLTnamespace) }) BeforeEach(func() { // list var here they will be copied for every spec @@ -83,7 +86,7 @@ var _ = Describe("KeptnEvaluationController", Ordered, func() { metric2 := &metricsv1alpha1.KeptnMetric{} err := k8sClient.Get(context.TODO(), types.NamespacedName{ - Namespace: providers.KLTNamespace, + Namespace: KLTnamespace, Name: metric.Name, }, metric2) Expect(err).To(BeNil()) @@ -252,7 +255,7 @@ func makeKeptnMetric(name string) *metricsv1alpha1.KeptnMetric { metric := &metricsv1alpha1.KeptnMetric{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: providers.KLTNamespace, + Namespace: KLTnamespace, }, Spec: metricsv1alpha1.KeptnMetricSpec{ Provider: metricsv1alpha1.ProviderRef{