diff --git a/apis/core/v1alpha1/flagsourceconfiguration_types.go b/apis/core/v1alpha1/flagsourceconfiguration_types.go
index d745336db..89f01c1d3 100644
--- a/apis/core/v1alpha1/flagsourceconfiguration_types.go
+++ b/apis/core/v1alpha1/flagsourceconfiguration_types.go
@@ -132,6 +132,10 @@ type FlagSourceConfigurationSpec struct {
// OtelCollectorUri defines whether to enable --otel-collector-uri flag of flagd sidecar. Default false (disabled).
// +optional
OtelCollectorUri string `json:"otelCollectorUri"`
+
+ // Resources defines flagd sidecar resources. Default to operator sidecar-cpu-* and sidecar-ram-* 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/apis/core/v1alpha2/featureflagconfiguration_types.go b/apis/core/v1alpha2/featureflagconfiguration_types.go
index b284a709c..ad207d9d9 100644
--- a/apis/core/v1alpha2/featureflagconfiguration_types.go
+++ b/apis/core/v1alpha2/featureflagconfiguration_types.go
@@ -45,6 +45,9 @@ type FeatureFlagConfigurationSpec struct {
FlagDSpec *FlagDSpec `json:"flagDSpec"`
// FeatureFlagSpec is the structured representation of the feature flag specification
FeatureFlagSpec FeatureFlagSpec `json:"featureFlagSpec,omitempty"`
+ // Resources defines flagd sidecar resources. Default to operator sidecar-cpu-* and sidecar-ram-* flags.
+ // +optional
+ Resources corev1.ResourceRequirements `json:"resources"`
}
type FlagDSpec struct {
diff --git a/apis/core/v1alpha2/zz_generated.deepcopy.go b/apis/core/v1alpha2/zz_generated.deepcopy.go
index 51fc8722a..0e3f805e0 100644
--- a/apis/core/v1alpha2/zz_generated.deepcopy.go
+++ b/apis/core/v1alpha2/zz_generated.deepcopy.go
@@ -105,6 +105,7 @@ func (in *FeatureFlagConfigurationSpec) DeepCopyInto(out *FeatureFlagConfigurati
(*in).DeepCopyInto(*out)
}
in.FeatureFlagSpec.DeepCopyInto(&out.FeatureFlagSpec)
+ in.Resources.DeepCopyInto(&out.Resources)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagConfigurationSpec.
diff --git a/apis/core/v1alpha3/flagsourceconfiguration_types.go b/apis/core/v1alpha3/flagsourceconfiguration_types.go
index 56413e113..2eea0d9e7 100644
--- a/apis/core/v1alpha3/flagsourceconfiguration_types.go
+++ b/apis/core/v1alpha3/flagsourceconfiguration_types.go
@@ -96,6 +96,10 @@ type FlagSourceConfigurationSpec struct {
// OtelCollectorUri defines whether to enable --otel-collector-uri flag of flagd sidecar. Default false (disabled).
// +optional
OtelCollectorUri string `json:"otelCollectorUri"`
+
+ // Resources defines flagd sidecar resources. Default to operator sidecar-cpu-* and sidecar-ram-* flags.
+ // +optional
+ Resources corev1.ResourceRequirements `json:"resources"`
}
type Source struct {
diff --git a/apis/core/v1alpha3/zz_generated.deepcopy.go b/apis/core/v1alpha3/zz_generated.deepcopy.go
index 29962c22b..9e0f9f634 100644
--- a/apis/core/v1alpha3/zz_generated.deepcopy.go
+++ b/apis/core/v1alpha3/zz_generated.deepcopy.go
@@ -120,6 +120,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/chart/open-feature-operator/README.md b/chart/open-feature-operator/README.md
index 7bfd1936b..7defbc8bb 100644
--- a/chart/open-feature-operator/README.md
+++ b/chart/open-feature-operator/README.md
@@ -108,6 +108,7 @@ The command removes all the Kubernetes components associated with the chart and
| `sidecarConfiguration.probesEnabled` | Enable or Disable Liveness and Readiness probes of the flagd sidecar. When enabled, HTTP probes( paths - `/readyz`, `/healthz`) are set with an initial delay of 5 seconds. | `true` |
| `sidecarConfiguration.debugLogging` | Controls the addition of the `--debug` flag to the container startup arguments. | `false` |
| `sidecarConfiguration.otelCollectorUri` | Otel exporter uri. | `""` |
+| `sidecarConfiguration.resources` | Override resources of the flagd sidecar. | `{}` |
### Flagd-proxy configuration
diff --git a/chart/open-feature-operator/values.yaml b/chart/open-feature-operator/values.yaml
index a54897333..e7c6e82d9 100644
--- a/chart/open-feature-operator/values.yaml
+++ b/chart/open-feature-operator/values.yaml
@@ -33,6 +33,8 @@ sidecarConfiguration:
debugLogging: false
## @param sidecarConfiguration.otelCollectorUri Otel exporter uri.
otelCollectorUri: ""
+ ## @param sidecarConfiguration.resources Override resources of the flagd sidecar.
+ resources: { }
## @section Flagd-proxy configuration
flagdProxyConfiguration:
diff --git a/config/crd/bases/core.openfeature.dev_flagsourceconfigurations.yaml b/config/crd/bases/core.openfeature.dev_flagsourceconfigurations.yaml
index 9fce17478..da40f1f67 100644
--- a/config/crd/bases/core.openfeature.dev_flagsourceconfigurations.yaml
+++ b/config/crd/bases/core.openfeature.dev_flagsourceconfigurations.yaml
@@ -189,6 +189,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
diff --git a/controllers/common/flagd-injector.go b/controllers/common/flagd-injector.go
index f0fa4facb..3ad44679e 100644
--- a/controllers/common/flagd-injector.go
+++ b/controllers/common/flagd-injector.go
@@ -104,6 +104,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 b4613b5c7..c988b18d0 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"
@@ -137,6 +138,55 @@ func TestFlagdContainerInjector_InjectDefaultSyncProvider_WithOtelCollectorUri(t
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 f252a2702..bc8ebbe4e 100644
--- a/docs/crds.md
+++ b/docs/crds.md
@@ -733,6 +733,13 @@ FlagSourceConfigurationSpec defines the desired state of FlagSourceConfiguration
ProbesEnabled defines whether to enable liveness and readiness probes of flagd sidecar. Default true (enabled).
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 | +