diff --git a/apis/core/v1alpha1/flagsourceconfiguration_types.go b/apis/core/v1alpha1/flagsourceconfiguration_types.go index 6e7dde2e2..17fe206d2 100644 --- a/apis/core/v1alpha1/flagsourceconfiguration_types.go +++ b/apis/core/v1alpha1/flagsourceconfiguration_types.go @@ -128,6 +128,10 @@ type FlagSourceConfigurationSpec struct { // DebugLogging defines whether to enable --debug flag of flagd sidecar. Default false (disabled). // +optional DebugLogging *bool `json:"debugLogging"` + + // Resources defines flagd sidecar resources. Default to operator sidecar-cpu-limit and sidecar-ram-limit flags. + // +optional + Resources corev1.ResourceRequirements `json:"resources"` } type Source struct { diff --git a/apis/core/v1alpha1/zz_generated.deepcopy.go b/apis/core/v1alpha1/zz_generated.deepcopy.go index bb80a51e6..779a4fc86 100644 --- a/apis/core/v1alpha1/zz_generated.deepcopy.go +++ b/apis/core/v1alpha1/zz_generated.deepcopy.go @@ -286,6 +286,7 @@ func (in *FlagSourceConfigurationSpec) DeepCopyInto(out *FlagSourceConfiguration *out = new(bool) **out = **in } + in.Resources.DeepCopyInto(&out.Resources) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfigurationSpec. diff --git a/config/crd/bases/core.openfeature.dev_featureflagconfigurations.yaml b/config/crd/bases/core.openfeature.dev_featureflagconfigurations.yaml index 5d49b916f..dfb0ed59d 100644 --- a/config/crd/bases/core.openfeature.dev_featureflagconfigurations.yaml +++ b/config/crd/bases/core.openfeature.dev_featureflagconfigurations.yaml @@ -57,7 +57,15 @@ spec: C_IDENTIFIER. type: string value: - description: 'Variable references. More info: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#envvar-v1-core ' + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' type: string valueFrom: description: Source for the environment variable's value. @@ -330,7 +338,15 @@ spec: C_IDENTIFIER. type: string value: - description: 'Variable references. More info: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#envvar-v1-core' + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. If + a variable cannot be resolved, the reference in the input + string will be unchanged. Double $$ are reduced to a single + $, which allows for escaping the $(VAR_NAME) syntax: i.e. + "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless + of whether the variable exists or not. Defaults to "".' type: string valueFrom: description: Source for the environment variable's value. diff --git a/config/crd/bases/core.openfeature.dev_flagsourceconfigurations.yaml b/config/crd/bases/core.openfeature.dev_flagsourceconfigurations.yaml index 0df0c81fe..908664c5c 100644 --- a/config/crd/bases/core.openfeature.dev_flagsourceconfigurations.yaml +++ b/config/crd/bases/core.openfeature.dev_flagsourceconfigurations.yaml @@ -62,7 +62,15 @@ spec: description: Name of the environment variable. Must be a C_IDENTIFIER. type: string value: - description: 'Variable references. More info: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#envvar-v1-core' + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' type: string valueFrom: description: Source for the environment variable's value. Cannot @@ -177,6 +185,54 @@ spec: description: ProbesEnabled defines whether to enable liveness and readiness probes of flagd sidecar. Default true (enabled). type: boolean + resources: + description: Resources defines flagd sidecar resources. Default to + operator sidecar-cpu-limit and sidecar-ram-limit flags. + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object rolloutOnChange: description: RolloutOnChange dictates whether annotated deployments will be restarted when configuration changes are detected in this @@ -360,7 +416,15 @@ spec: description: Name of the environment variable. Must be a C_IDENTIFIER. type: string value: - description: 'Variable references. More info: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#envvar-v1-core' + description: 'Variable references $(VAR_NAME) are expanded using + the previously defined environment variables in the container + and any service environment variables. If a variable cannot + be resolved, the reference in the input string will be unchanged. + Double $$ are reduced to a single $, which allows for escaping + the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the + string literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists or + not. Defaults to "".' type: string valueFrom: description: Source for the environment variable's value. Cannot diff --git a/controllers/common/flagd-injector.go b/controllers/common/flagd-injector.go index b1cff5948..9eea887ed 100644 --- a/controllers/common/flagd-injector.go +++ b/controllers/common/flagd-injector.go @@ -89,6 +89,14 @@ func (fi *FlagdContainerInjector) InjectFlagd( ) } + if len(flagSourceConfig.Resources.Requests) != 0 { + flagdContainer.Resources.Requests = flagSourceConfig.Resources.Requests + } + + if len(flagSourceConfig.Resources.Limits) != 0 { + flagdContainer.Resources.Limits = flagSourceConfig.Resources.Limits + } + addFlagdContainer(podSpec, flagdContainer) return nil diff --git a/controllers/common/flagd-injector_test.go b/controllers/common/flagd-injector_test.go index c34980219..255dd91b2 100644 --- a/controllers/common/flagd-injector_test.go +++ b/controllers/common/flagd-injector_test.go @@ -9,6 +9,7 @@ import ( "github.com/open-feature/open-feature-operator/pkg/utils" "github.com/stretchr/testify/require" appsV1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -98,6 +99,55 @@ func TestFlagdContainerInjector_InjectDefaultSyncProvider_WithDebugLogging(t *te require.Equal(t, expectedDeployment, deployment) } +func TestFlagdContainerInjector_InjectDefaultSyncProvider_WithResources(t *testing.T) { + + namespace, fakeClient := initContainerInjectionTestEnv() + + fi := &FlagdContainerInjector{ + Client: fakeClient, + Logger: testr.New(t), + FlagdProxyConfig: getProxyConfig(), + FlagDResourceRequirements: getResourceRequirements(), + } + + deployment := appsV1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-deployment", + Namespace: namespace, + }, + Spec: appsV1.DeploymentSpec{}, + } + + flagSourceConfig := getFlagSourceConfigSpec() + + flagSourceConfig.DefaultSyncProvider = v1alpha1.SyncProviderGrpc + + flagSourceConfig.Resources = corev1.ResourceRequirements{ + Limits: map[corev1.ResourceName]resource.Quantity{ + corev1.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI), + corev1.ResourceMemory: *resource.NewQuantity(256*1<<20, resource.BinarySI), + }, + Requests: map[corev1.ResourceName]resource.Quantity{ + corev1.ResourceCPU: *resource.NewMilliQuantity(100, resource.DecimalSI), + corev1.ResourceMemory: *resource.NewQuantity(256*1<<20, resource.BinarySI), + }, + } + + flagSourceConfig.Sources = []v1alpha1.Source{{}} + + err := fi.InjectFlagd(context.Background(), &deployment.ObjectMeta, &deployment.Spec.Template.Spec, flagSourceConfig) + require.Nil(t, err) + + expectedDeployment := getExpectedDeployment(namespace) + + expectedDeployment.Annotations = nil + + expectedDeployment.Spec.Template.Spec.Containers[0].Args = []string{"start", "--sources", "[{\"uri\":\"\",\"provider\":\"grpc\"}]"} + expectedDeployment.Spec.Template.Spec.Containers[0].Resources = flagSourceConfig.Resources + + require.Equal(t, expectedDeployment, deployment) +} + func TestFlagdContainerInjector_InjectDefaultSyncProvider_WithSyncProviderArgs(t *testing.T) { namespace, fakeClient := initContainerInjectionTestEnv() diff --git a/docs/crds.md b/docs/crds.md index 57c9f836b..aae087d82 100644 --- a/docs/crds.md +++ b/docs/crds.md @@ -182,7 +182,7 @@ EnvVar represents an environment variable present in a Container.
Name | +Type | +Description | +Required | +
---|---|---|---|
claims | +[]object | +
+ Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container.
+ This is an alpha field and requires enabling the DynamicResourceAllocation feature gate.
+ This field is immutable. It can only be set for containers. + |
+ false | +
limits | +map[string]int or string | +
+ Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + |
+ false | +
requests | +map[string]int or string | +
+ Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + |
+ false | +
Name | +Type | +Description | +Required | +
---|---|---|---|
name | +string | +
+ Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + |
+ true | +