From c6ccfc16f77710055bc6040d63cde60ecea04743 Mon Sep 17 00:00:00 2001 From: Christopher Pitstick Date: Tue, 18 Jun 2024 14:14:18 -0400 Subject: [PATCH] Add labels and annotations to pods. Currently, there is only one deployment, so avoid premature optimization by making these global (and follow the same pattern for imagePullSecrets) Requires more aggressive usage of the `strip-kustomize-helm.sh` script because we have to preserve existing annotations and labels from the config/manager directory. Also update labels and annotations for injected pods (FlagD sidecar, FlagD standalone, and FlagD proxy). Signed-off-by: Christopher Pitstick --- .github/scripts/strip-kustomize-helm.sh | 30 +++++---- Makefile | 2 +- chart/open-feature-operator/README.md | 5 +- chart/open-feature-operator/values.yaml | 4 ++ common/flagdproxy/flagdproxy.go | 30 +++++++-- common/flagdproxy/flagdproxy_test.go | 33 +++++++--- config/overlays/helm/manager.yaml | 13 +++- .../core/featureflagsource/controller_test.go | 13 +++- controllers/core/flagd/common/common.go | 2 + controllers/core/flagd/config.go | 4 +- .../core/flagd/resources/deployment.go | 33 +++++++--- go.mod | 4 +- go.sum | 21 +++--- main.go | 64 +++++++++++++++---- 14 files changed, 189 insertions(+), 69 deletions(-) diff --git a/.github/scripts/strip-kustomize-helm.sh b/.github/scripts/strip-kustomize-helm.sh index 7647a83f0..62e47a015 100755 --- a/.github/scripts/strip-kustomize-helm.sh +++ b/.github/scripts/strip-kustomize-helm.sh @@ -1,18 +1,26 @@ -#!/bin/bash +#!/usr/bin/env bash # This script is a hack to support helm flow control in kustomize overlays, which would otherwise break them. # It allows us to render helm template bindings and add newlines. # For instance, it transforms "___{{ .Value.myValue }}___" to {{ .Value.myValue }}. -# It also adds newlines wherever ___newline___ is found. - -CHARTS_DIR='./chart/open-feature-operator/templates'; +# It also adds newlines wherever ___newline___ is found, and other operations. See +# sed_expressions below. echo 'Running strip-kustomize-helm.sh script' -filenames=`find $CHARTS_DIR -name "*.yaml"` -for file in $filenames; do - sed -i "s/___newline___/\\n/g" $file - sed -i "s/\"___//g" $file - sed -i "s/___\"//g" $file - sed -i "s/___//g" $file +CHARTS_DIR='./chart/open-feature-operator/templates' +# Careful! Ordering of these expressions matter! +sed_expressions=( + "s/___newline___/\\n/g" + "s/___space___/ /g" + "s/\"___//g" + "s/___\"//g" + "/___delete_me___/d" + "s/___//g" +) +find $CHARTS_DIR -name "*.yaml" | while read file; do + for expr in "${sed_expressions[@]}"; do + sed -i "$expr" "$file" + done done -echo 'Done running strip-kustomize-helm.sh script' \ No newline at end of file + +echo 'Done running strip-kustomize-helm.sh script' diff --git a/Makefile b/Makefile index 01c8a213a..0d90223d1 100644 --- a/Makefile +++ b/Makefile @@ -252,7 +252,7 @@ set-helm-overlay: helm-package: set-helm-overlay generate release-manifests helm mkdir -p chart/open-feature-operator/templates/crds mv chart/open-feature-operator/templates/*customresourcedefinition* chart/open-feature-operator/templates/crds - sh .github/scripts/strip-kustomize-helm.sh + .github/scripts/strip-kustomize-helm.sh $(HELM) package --version $(CHART_VERSION) chart/open-feature-operator mkdir -p charts && mv open-feature-operator-*.tgz charts $(HELM) repo index --url https://open-feature.github.io/open-feature-operator/charts charts diff --git a/chart/open-feature-operator/README.md b/chart/open-feature-operator/README.md index 4d0a07cba..cf78aa601 100644 --- a/chart/open-feature-operator/README.md +++ b/chart/open-feature-operator/README.md @@ -97,6 +97,8 @@ The command removes all the Kubernetes components associated with the chart and | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | | `defaultNamespace` | To override the namespace use the `--namespace` flag. This default is provided to ensure that the kustomize build charts in `/templates` deploy correctly when no `namespace` is provided via the `-n` flag. | `open-feature-operator-system` | | `imagePullSecrets` | Array of ImagePullSecret objects containing credentials for images pulled by the operator (flagdProxyConfiguration.image, flagdConfiguration.image, controllerManager.manager.image, controllerManager.kubeRbacProxy.image). Example: imagePullSecrets: [{"name": "my-secret"}] | `[]` | +| `labels` | Labels to apply to all of the pods in the operator. | `{}` | +| `annotations` | Annotations to apply to all of the pods in the operator. | `{}` | ### Sidecar configuration @@ -167,7 +169,7 @@ The command removes all the Kubernetes components associated with the chart and | `controllerManager.kubeRbacProxy.resources.requests.cpu` | Sets cpu resource requests for kube-rbac-proxy. | `5m` | | `controllerManager.kubeRbacProxy.resources.requests.memory` | Sets memory resource requests for kube-rbac-proxy. | `64Mi` | | `controllerManager.manager.image.repository` | Sets the image for the operator. | `ghcr.io/open-feature/open-feature-operator` | -| `controllerManager.manager.image.tag` | Sets the version tag for the operator. | `v0.6.1` | +| `controllerManager.manager.image.tag` | Sets the version tag for the operator. | `v0.7.0` | | `controllerManager.manager.resources.limits.cpu` | Sets cpu resource limits for operator. | `500m` | | `controllerManager.manager.resources.limits.memory` | Sets memory resource limits for operator. | `128Mi` | | `controllerManager.manager.resources.requests.cpu` | Sets cpu resource requests for operator. | `10m` | @@ -180,3 +182,4 @@ The command removes all the Kubernetes components associated with the chart and | `managerConfig.controllerManagerConfigYaml.metrics.bindAddress` | Sets the bind address for metrics (combined with bindPort). | `127.0.0.1` | | `managerConfig.controllerManagerConfigYaml.metrics.bindPort` | Sets the bind port for metrics. | `8080` | | `managerConfig.controllerManagerConfigYaml.webhook.port` | Sets the bind address for webhook. | `9443` | + diff --git a/chart/open-feature-operator/values.yaml b/chart/open-feature-operator/values.yaml index 42bec3d8d..8a6ef4002 100644 --- a/chart/open-feature-operator/values.yaml +++ b/chart/open-feature-operator/values.yaml @@ -4,6 +4,10 @@ defaultNamespace: open-feature-operator-system ## @param imagePullSecrets Array of ImagePullSecret objects containing credentials for images pulled by the operator (flagdProxyConfiguration.image, flagdConfiguration.image, controllerManager.manager.image, controllerManager.kubeRbacProxy.image). Example: imagePullSecrets: [{"name": "my-secret"}] imagePullSecrets: [] +## @param labels Labels to apply to all of the pods in the operator. +labels: {} +## @param annotations Annotations to apply to all of the pods in the operator. +annotations: {} ## @section Sidecar configuration sidecarConfiguration: diff --git a/common/flagdproxy/flagdproxy.go b/common/flagdproxy/flagdproxy.go index eefdb8abc..28131dd45 100644 --- a/common/flagdproxy/flagdproxy.go +++ b/common/flagdproxy/flagdproxy.go @@ -8,6 +8,7 @@ import ( "github.com/go-logr/logr" "github.com/open-feature/open-feature-operator/common" "github.com/open-feature/open-feature-operator/common/types" + "golang.org/x/exp/maps" appsV1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -39,9 +40,11 @@ type FlagdProxyConfiguration struct { Namespace string OperatorDeploymentName string ImagePullSecrets []string + Labels map[string]string + Annotations map[string]string } -func NewFlagdProxyConfiguration(env types.EnvConfig, imagePullSecrets []string) *FlagdProxyConfiguration { +func NewFlagdProxyConfiguration(env types.EnvConfig, imagePullSecrets []string, labels map[string]string, annotations map[string]string) *FlagdProxyConfiguration { return &FlagdProxyConfiguration{ Image: env.FlagdProxyImage, Tag: env.FlagdProxyTag, @@ -51,6 +54,8 @@ func NewFlagdProxyConfiguration(env types.EnvConfig, imagePullSecrets []string) ManagementPort: env.FlagdProxyManagementPort, DebugLogging: env.FlagdProxyDebugLogging, ImagePullSecrets: imagePullSecrets, + Labels: labels, + Annotations: annotations, } } @@ -151,6 +156,21 @@ func (f *FlagdProxyHandler) newFlagdProxyManifest(ownerReference *metav1.OwnerRe Name: secret, }) } + flagdLabels := map[string]string{ + "app": FlagdProxyDeploymentName, + "app.kubernetes.io/name": FlagdProxyDeploymentName, + "app.kubernetes.io/managed-by": common.ManagedByAnnotationValue, + "app.kubernetes.io/version": f.config.Tag, + } + if len(f.config.Labels) > 0 { + maps.Copy(flagdLabels, f.config.Labels) + } + + // No "built-in" annotations to merge at this time. If adding them follow the same pattern as labels. + flagdAnnotations := map[string]string{} + if len(f.config.Annotations) > 0 { + maps.Copy(flagdAnnotations, f.config.Annotations) + } return &appsV1.Deployment{ ObjectMeta: metav1.ObjectMeta{ @@ -172,12 +192,8 @@ func (f *FlagdProxyHandler) newFlagdProxyManifest(ownerReference *metav1.OwnerRe }, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - "app": FlagdProxyDeploymentName, - "app.kubernetes.io/name": FlagdProxyDeploymentName, - "app.kubernetes.io/managed-by": common.ManagedByAnnotationValue, - "app.kubernetes.io/version": f.config.Tag, - }, + Labels: flagdLabels, + Annotations: flagdAnnotations, }, Spec: corev1.PodSpec{ ServiceAccountName: FlagdProxyServiceAccountName, diff --git a/common/flagdproxy/flagdproxy_test.go b/common/flagdproxy/flagdproxy_test.go index ce324b2ed..8ab7d223c 100644 --- a/common/flagdproxy/flagdproxy_test.go +++ b/common/flagdproxy/flagdproxy_test.go @@ -21,12 +21,22 @@ import ( var pullSecrets = []string{"test-pullSecret"} +var labels = map[string]string{ + "label1": "labelValue1", + "label2": "labelValue2", +} + +var annotations = map[string]string{ + "annotation1": "annotationValue1", + "annotation2": "annotationValue2", +} + func TestNewFlagdProxyConfiguration(t *testing.T) { kpConfig := NewFlagdProxyConfiguration(types.EnvConfig{ FlagdProxyPort: 8015, FlagdProxyManagementPort: 8016, - }, pullSecrets) + }, pullSecrets, labels, annotations) require.NotNil(t, kpConfig) require.Equal(t, &FlagdProxyConfiguration{ @@ -35,6 +45,8 @@ func TestNewFlagdProxyConfiguration(t *testing.T) { DebugLogging: false, OperatorDeploymentName: common.OperatorDeploymentName, ImagePullSecrets: pullSecrets, + Labels: labels, + Annotations: annotations, }, kpConfig) } @@ -48,7 +60,7 @@ func TestNewFlagdProxyConfiguration_OverrideEnvVars(t *testing.T) { FlagdProxyDebugLogging: true, } - kpConfig := NewFlagdProxyConfiguration(env, pullSecrets) + kpConfig := NewFlagdProxyConfiguration(env, pullSecrets, labels, annotations) require.NotNil(t, kpConfig) require.Equal(t, &FlagdProxyConfiguration{ @@ -60,11 +72,13 @@ func TestNewFlagdProxyConfiguration_OverrideEnvVars(t *testing.T) { Namespace: "my-namespace", OperatorDeploymentName: common.OperatorDeploymentName, ImagePullSecrets: pullSecrets, + Labels: labels, + Annotations: annotations, }, kpConfig) } func TestNewFlagdProxyHandler(t *testing.T) { - kpConfig := NewFlagdProxyConfiguration(types.EnvConfig{}, pullSecrets) + kpConfig := NewFlagdProxyConfiguration(types.EnvConfig{}, pullSecrets, labels, annotations) require.NotNil(t, kpConfig) @@ -100,7 +114,7 @@ func TestDoesFlagdProxyExist(t *testing.T) { }, } - kpConfig := NewFlagdProxyConfiguration(env, pullSecrets) + kpConfig := NewFlagdProxyConfiguration(env, pullSecrets, labels, annotations) require.NotNil(t, kpConfig) @@ -128,7 +142,7 @@ func TestFlagdProxyHandler_HandleFlagdProxy_ProxyExistsWithBadVersion(t *testing env := types.EnvConfig{ PodNamespace: "ns", } - kpConfig := NewFlagdProxyConfiguration(env, pullSecrets) + kpConfig := NewFlagdProxyConfiguration(env, pullSecrets, labels, annotations) require.NotNil(t, kpConfig) @@ -187,7 +201,7 @@ func TestFlagdProxyHandler_HandleFlagdProxy_ProxyExistsWithoutLabel(t *testing.T env := types.EnvConfig{ PodNamespace: "ns", } - kpConfig := NewFlagdProxyConfiguration(env, pullSecrets) + kpConfig := NewFlagdProxyConfiguration(env, pullSecrets, labels, annotations) require.NotNil(t, kpConfig) @@ -236,7 +250,7 @@ func TestFlagdProxyHandler_HandleFlagdProxy_ProxyExistsWithNewestVersion(t *test env := types.EnvConfig{ PodNamespace: "ns", } - kpConfig := NewFlagdProxyConfiguration(env, pullSecrets) + kpConfig := NewFlagdProxyConfiguration(env, pullSecrets, labels, annotations) require.NotNil(t, kpConfig) @@ -280,7 +294,7 @@ func TestFlagdProxyHandler_HandleFlagdProxy_CreateProxy(t *testing.T) { FlagdProxyManagementPort: 90, FlagdProxyDebugLogging: true, } - kpConfig := NewFlagdProxyConfiguration(env, pullSecrets) + kpConfig := NewFlagdProxyConfiguration(env, pullSecrets, labels, annotations) require.NotNil(t, kpConfig) @@ -357,7 +371,10 @@ func TestFlagdProxyHandler_HandleFlagdProxy_CreateProxy(t *testing.T) { "app.kubernetes.io/name": FlagdProxyDeploymentName, "app.kubernetes.io/managed-by": common.ManagedByAnnotationValue, "app.kubernetes.io/version": "tag", + "label1": "labelValue1", + "label2": "labelValue2", }, + Annotations: annotations, }, Spec: corev1.PodSpec{ ServiceAccountName: FlagdProxyServiceAccountName, diff --git a/config/overlays/helm/manager.yaml b/config/overlays/helm/manager.yaml index e35ac993e..8f90f1fe2 100644 --- a/config/overlays/helm/manager.yaml +++ b/config/overlays/helm/manager.yaml @@ -6,12 +6,19 @@ metadata: spec: replicas: 0{{ .Values.controllerManager.replicas }} template: + metadata: + # this is transformed by .github/scripts/strip-kustomize-helm.sh + annotations: + ___delete_me___: "___ ___newline___{{ if .Values.annotations }}{{___space___toYaml___space___.Values.annotations___space___|___space___indent___space___8___space___}}{{ end }}___" + # this is transformed by .github/scripts/strip-kustomize-helm.sh + labels: + ___delete_me___: "___ ___newline___{{ if .Values.labels }}___newline___{{___space___toYaml___space___.Values.labels___space___|___space___indent___space___8___space___}}{{ end }}___" spec: # this is transformed by .github/scripts/strip-kustomize-helm.sh - ___imagePullSecrets___: "___ ___newline___{{ toYaml .Values.imagePullSecrets | indent 8 }}___" - dnsPolicy: "{{ .Values.controllerManager.manager.dnsPolicy }}" + ___imagePullSecrets___: "___ ___newline___ {{ toYaml .Values.imagePullSecrets___space___|___space___indent___space___8___space___}}___" # this is transformed by .github/scripts/strip-kustomize-helm.sh hostNetwork: "___{{ .Values.controllerManager.manager.hostNetwork }}___" + dnsPolicy: "{{ .Values.controllerManager.manager.dnsPolicy }}" containers: - name: manager image: "{{ .Values.controllerManager.manager.image.repository }}:{{ .Values.controllerManager.manager.image.tag }}" @@ -104,6 +111,8 @@ spec: - --sidecar-ram-request={{ .Values.sidecarConfiguration.resources.requests.memory }} - --image-pull-secrets={{ range .Values.imagePullSecrets }}{{ .name }},{{- end }} - --metrics-bind-address=:{{ .Values.managerConfig.controllerManagerConfigYaml.metrics.bindPort }} + - --labels={{ $labelKeys := keys .Values.labels -}}{{- $labelPairs := list -}}{{- range $key := $labelKeys -}}{{- $labelPairs = append $labelPairs (printf "%s:%s" $key (index $.Values.labels $key)) -}}{{- end -}}{{- join "," $labelPairs }} + - --annotations={{ $annotationKeys := keys .Values.annotations -}}{{- $annotationPairs := list -}}{{- range $key := $annotationKeys -}}{{- $annotationPairs = append $annotationPairs (printf "%s:%s" $key (index $.Values.annotations $key)) -}}{{- end -}}{{- join "," $annotationPairs }} - name: kube-rbac-proxy image: "{{ .Values.controllerManager.kubeRbacProxy.image.repository }}:{{ .Values.controllerManager.kubeRbacProxy.image.tag }}" resources: diff --git a/controllers/core/featureflagsource/controller_test.go b/controllers/core/featureflagsource/controller_test.go index e5f9b367e..6f2613b66 100644 --- a/controllers/core/featureflagsource/controller_test.go +++ b/controllers/core/featureflagsource/controller_test.go @@ -30,6 +30,16 @@ func TestFeatureFlagSourceReconciler_Reconcile(t *testing.T) { ) var pullSecrets = []string{"test-pullsecret"} + var labels = map[string]string{ + "label1": "labelValue1", + "label2": "labelValue2", + } + + var annotations = map[string]string{ + "annotation1": "annotationValue1", + "annotation2": "annotationValue2", + } + tests := []struct { name string fsConfig *api.FeatureFlagSource @@ -93,7 +103,7 @@ func TestFeatureFlagSourceReconciler_Reconcile(t *testing.T) { kpConfig := flagdproxy.NewFlagdProxyConfiguration(commontypes.EnvConfig{ FlagdProxyImage: "ghcr.io/open-feature/flagd-proxy", FlagdProxyTag: flagdProxyTag, - }, pullSecrets) + }, pullSecrets, labels, annotations) kpConfig.Namespace = testNamespace kph := flagdproxy.NewFlagdProxyHandler( @@ -169,6 +179,7 @@ func createTestDeployment(fsConfigName string, testNamespace string, deploymentN }, }, Spec: corev1.PodSpec{ + ImagePullSecrets: []corev1.LocalObjectReference{{Name: "test-pullSecret"}}, Containers: []corev1.Container{ { Name: "test", diff --git a/controllers/core/flagd/common/common.go b/controllers/core/flagd/common/common.go index fcdd61b74..fa88c55a9 100644 --- a/controllers/core/flagd/common/common.go +++ b/controllers/core/flagd/common/common.go @@ -9,6 +9,8 @@ type FlagdConfiguration struct { Image string Tag string ImagePullSecrets []string + Labels map[string]string + Annotations map[string]string OperatorNamespace string OperatorDeploymentName string diff --git a/controllers/core/flagd/config.go b/controllers/core/flagd/config.go index e4ce776b7..33a1c3434 100644 --- a/controllers/core/flagd/config.go +++ b/controllers/core/flagd/config.go @@ -6,7 +6,7 @@ import ( resources "github.com/open-feature/open-feature-operator/controllers/core/flagd/common" ) -func NewFlagdConfiguration(env types.EnvConfig, imagePullSecrets []string) resources.FlagdConfiguration { +func NewFlagdConfiguration(env types.EnvConfig, imagePullSecrets []string, labels map[string]string, annotations map[string]string) resources.FlagdConfiguration { return resources.FlagdConfiguration{ Image: env.FlagdImage, Tag: env.FlagdTag, @@ -17,5 +17,7 @@ func NewFlagdConfiguration(env types.EnvConfig, imagePullSecrets []string) resou ManagementPort: env.FlagdManagementPort, DebugLogging: env.FlagdDebugLogging, ImagePullSecrets: imagePullSecrets, + Labels: labels, + Annotations: annotations, } } diff --git a/controllers/core/flagd/resources/deployment.go b/controllers/core/flagd/resources/deployment.go index faedb5226..ba15567ce 100644 --- a/controllers/core/flagd/resources/deployment.go +++ b/controllers/core/flagd/resources/deployment.go @@ -11,6 +11,7 @@ import ( "github.com/open-feature/open-feature-operator/common" "github.com/open-feature/open-feature-operator/common/flagdinjector" resources "github.com/open-feature/open-feature-operator/controllers/core/flagd/common" + "golang.org/x/exp/maps" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -46,11 +47,20 @@ func (r *FlagdDeployment) GetResource(ctx context.Context, flagd *api.Flagd) (cl "app.kubernetes.io/managed-by": common.ManagedByAnnotationValue, "app.kubernetes.io/version": r.FlagdConfig.Tag, } + if len(r.FlagdConfig.Labels) > 0 { + maps.Copy(labels, r.FlagdConfig.Labels) + } + // No "built-in" annotations to merge at this time. If adding them follow the same pattern as labels. + annotations := map[string]string{} + if len(r.FlagdConfig.Annotations) > 0 { + maps.Copy(annotations, r.FlagdConfig.Annotations) + } deployment := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: flagd.Name, - Namespace: flagd.Namespace, - Labels: labels, + Name: flagd.Name, + Namespace: flagd.Namespace, + Labels: labels, + Annotations: annotations, OwnerReferences: []metav1.OwnerReference{{ APIVersion: flagd.APIVersion, Kind: flagd.Kind, @@ -77,11 +87,9 @@ func (r *FlagdDeployment) GetResource(ctx context.Context, flagd *api.Flagd) (cl } featureFlagSource := &api.FeatureFlagSource{} - imagePullSecrets := []corev1.LocalObjectReference{} - for _, secret := range r.FlagdConfig.ImagePullSecrets { - imagePullSecrets = append(imagePullSecrets, corev1.LocalObjectReference{ - Name: secret, - }) + imagePullSecrets := make([]corev1.LocalObjectReference, len(r.FlagdConfig.ImagePullSecrets)) + for i, secret := range r.FlagdConfig.ImagePullSecrets { + imagePullSecrets[i] = corev1.LocalObjectReference{Name: secret} } if err := r.Client.Get(ctx, client.ObjectKey{ @@ -100,9 +108,14 @@ func (r *FlagdDeployment) GetResource(ctx context.Context, flagd *api.Flagd) (cl return nil, errors.New("no flagd container has been injected into deployment") } - deployment.Spec.Template.Spec.ImagePullSecrets = imagePullSecrets - // override settings for the injected container for flagd standalone deployment mode + deployment.Spec.Template.Spec.ImagePullSecrets = imagePullSecrets + if len(r.FlagdConfig.Labels) > 0 { + maps.Copy(deployment.Spec.Template.ObjectMeta.Labels, r.FlagdConfig.Labels) + } + if len(r.FlagdConfig.Annotations) > 0 { + maps.Copy(deployment.Spec.Template.ObjectMeta.Annotations, r.FlagdConfig.Annotations) + } deployment.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s:%s", r.FlagdConfig.Image, r.FlagdConfig.Tag) deployment.Spec.Template.Spec.Containers[0].Ports = []corev1.ContainerPort{ diff --git a/go.mod b/go.mod index 83ba65500..53892ec9e 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/open-feature/open-feature-operator/apis v0.2.41-0.20240506125212-c4831a3cdc00 github.com/stretchr/testify v1.8.4 go.uber.org/zap v1.27.0 + golang.org/x/exp v0.0.0-20240707233637-46b078467d37 k8s.io/api v0.28.10 k8s.io/apimachinery v0.28.10 k8s.io/client-go v0.28.10 @@ -31,7 +32,7 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/imdario/mergo v0.3.12 // indirect @@ -54,7 +55,6 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/net v0.23.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/sys v0.19.0 // indirect diff --git a/go.sum b/go.sum index ac9f436ce..c4bfb4b8d 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,4 @@ github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -18,7 +16,6 @@ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -44,8 +41,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -130,21 +127,19 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -190,8 +185,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/main.go b/main.go index 779679648..c3902e062 100644 --- a/main.go +++ b/main.go @@ -58,16 +58,27 @@ const ( metricsBindAddressFlagName = "metrics-bind-address" verboseFlagName = "verbose" leaderElectFlagName = "leader-elect" - sidecarCpuLimitFlagName = "sidecar-cpu-limit" - sidecarRamLimitFlagName = "sidecar-ram-limit" - sidecarCpuRequestFlagName = "sidecar-cpu-request" - sidecarRamRequestFlagName = "sidecar-ram-request" - sidecarCpuLimitDefault = "0.5" - sidecarRamLimitDefault = "64M" - sidecarCpuRequestDefault = "0.2" - sidecarRamRequestDefault = "32M" - imagePullSecretFlagName = "image-pull-secrets" - imagePullSecretFlagDefault = "" + + sidecarCpuLimitFlagName = "sidecar-cpu-limit" + sidecarCpuLimitDefault = "0.5" + + sidecarRamLimitFlagName = "sidecar-ram-limit" + sidecarRamLimitDefault = "64M" + + sidecarCpuRequestFlagName = "sidecar-cpu-request" + sidecarCpuRequestDefault = "0.2" + + sidecarRamRequestFlagName = "sidecar-ram-request" + sidecarRamRequestDefault = "32M" + + imagePullSecretFlagName = "image-pull-secrets" + imagePullSecretFlagDefault = "" + + labelsFlagName = "labels" + labelsFlagDefault = "" + + annotationsFlagName = "annotations" + annotationsFlagDefault = "" ) var ( @@ -79,8 +90,22 @@ var ( verbose bool sidecarCpuLimit, sidecarRamLimit, sidecarCpuRequest, sidecarRamRequest string imagePullSecrets string + labels string + annotations string ) +// StringToMap transforms a string into a map[string]string +func StringToMap(s string) map[string]string { + m := map[string]string{} + for _, pair := range strings.Split(s, ",") { + kv := strings.SplitN(pair, ":", 2) + if len(kv) == 2 { + m[kv[0]] = kv[1] + } + } + return m +} + func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(corev1beta1.AddToScheme(scheme)) @@ -107,6 +132,8 @@ func main() { flag.StringVar(&sidecarCpuRequest, sidecarCpuRequestFlagName, sidecarCpuRequestDefault, "sidecar CPU minimum, in cores. (500m = .5 cores)") flag.StringVar(&sidecarRamRequest, sidecarRamRequestFlagName, sidecarRamRequestDefault, "sidecar memory minimum, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)") flag.StringVar(&imagePullSecrets, imagePullSecretFlagName, imagePullSecretFlagDefault, "Comma-delimited list of secrets containing credentials to pull images.") + flag.StringVar(&labels, labelsFlagName, labelsFlagDefault, "Map of labels to add to the deployed pods. Formatted like key1:value1,key2:value2,key3:value3") + flag.StringVar(&annotations, annotationsFlagName, annotationsFlagDefault, "Map of annotations to add to the deployed pods. Formatted like key1:value1,key2:value2,key3:value3") flag.Parse() @@ -182,8 +209,16 @@ func main() { os.Exit(1) } + labelsMap := StringToMap(labels) + annotationsMap := StringToMap(annotations) + kph := flagdproxy.NewFlagdProxyHandler( - flagdproxy.NewFlagdProxyConfiguration(env, strings.Split(imagePullSecrets, ",")), + flagdproxy.NewFlagdProxyConfiguration( + env, + strings.Split(imagePullSecrets, ","), + labelsMap, + annotationsMap, + ), mgr.GetClient(), ctrl.Log.WithName("FeatureFlagSource FlagdProxyHandler"), ) @@ -215,7 +250,12 @@ func main() { Scheme: mgr.GetScheme(), Log: flagdControllerLogger, } - flagdConfig := flagd.NewFlagdConfiguration(env, strings.Split(imagePullSecrets, ",")) + flagdConfig := flagd.NewFlagdConfiguration( + env, + strings.Split(imagePullSecrets, ","), + labelsMap, + annotationsMap, + ) if err = (&flagd.FlagdReconciler{ Client: mgr.GetClient(),