Skip to content

Commit

Permalink
feat: Helm configuration (#304)
Browse files Browse the repository at this point in the history
Signed-off-by: James Milligan <james@omnant.co.uk>
Signed-off-by: James Milligan <75740990+james-milligan@users.noreply.github.com>
Co-authored-by: Skye Gill <gill.skye95@gmail.com>
  • Loading branch information
james-milligan and skyerus committed Jan 25, 2023
1 parent 75bdd8b commit 99edfeb
Show file tree
Hide file tree
Showing 18 changed files with 399 additions and 114 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Update flagd tag
run: make update-flagd
- name: Set up QEMU
uses: docker/setup-qemu-action@master
with:
Expand Down
94 changes: 70 additions & 24 deletions apis/core/v1alpha1/flagsourceconfiguration_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,30 @@ package v1alpha1
import (
"fmt"
"os"
"strconv"
"strings"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
FlagdMetricPortEnvVar string = "FLAGD_METRICS_PORT"
FlagdPortEnvVar string = "FLAGD_PORT"
FlagdSocketPathEnvVar string = "FLAGD_SOCKET_PATH"
FlagdEvaluatorEnvVar string = "FLAGD_EVALUATOR"
flagDVersionEnvVar string = "FLAGD_VERSION"
defaultMetricPort int32 = 8014
defaultPort int32 = 8013
defaultSocketPath string = ""
defaultEvaluator string = "json"
defaultImage string = "ghcr.io/open-feature/flagd"
defaultTag string = "main"
SidecarEnvVarPrefix string = "SIDECAR_ENV_VAR_PREFIX"
SidecarMetricPortEnvVar string = "METRICS_PORT"
SidecarPortEnvVar string = "PORT"
SidecarSocketPathEnvVar string = "SOCKET_PATH"
SidecarEvaluatorEnvVar string = "EVALUATOR"
SidecarImageEnvVar string = "IMAGE"
SidecarVersionEnvVar string = "TAG"
SidecarProviderArgsEnvVar string = "PROVIDER_ARGS"
defaultSidecarEnvVarPrefix string = "FLAGD"
InputConfigurationEnvVarPrefix string = "SIDECAR"
defaultMetricPort int32 = 8014
defaultPort int32 = 8013
defaultSocketPath string = ""
defaultEvaluator string = "json"
defaultImage string = "ghcr.io/open-feature/flagd"
defaultTag string = "v0.3.1"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
Expand Down Expand Up @@ -66,29 +73,63 @@ type FlagSourceConfigurationSpec struct {
// +optional
Evaluator string `json:"evaluator"`

// Image allows for the flagd image to be overridden, defaults to 'ghcr.io/open-feature/flagd'
// Image allows for the sidecar image to be overridden, defaults to 'ghcr.io/open-feature/flagd'
// +optional
Image string `json:"image"`

// Tag to be appended to the flagd image, defaults to 'main'
// Tag to be appended to the sidecar image, defaults to 'main'
// +optional
Tag string `json:"tag"`
}

func NewFlagSourceConfigurationSpec() *FlagSourceConfigurationSpec {
var tag = defaultTag
if flagDVersion := os.Getenv(flagDVersionEnvVar); flagDVersion != "" {
tag = flagDVersion
}
return &FlagSourceConfigurationSpec{
func NewFlagSourceConfigurationSpec() (*FlagSourceConfigurationSpec, error) {
fsc := &FlagSourceConfigurationSpec{
MetricsPort: defaultMetricPort,
Port: defaultPort,
SocketPath: defaultSocketPath,
SyncProviderArgs: []string{},
Evaluator: defaultEvaluator,
Image: defaultImage,
Tag: tag,
Tag: defaultTag,
}

if metricsPort := os.Getenv(fmt.Sprintf("%s_%s", InputConfigurationEnvVarPrefix, SidecarMetricPortEnvVar)); metricsPort != "" {
metricsPortI, err := strconv.Atoi(metricsPort)
if err != nil {
return fsc, fmt.Errorf("unable to parse metrics port value %s to int32: %w", metricsPort, err)
}
fsc.MetricsPort = int32(metricsPortI)
}

if port := os.Getenv(fmt.Sprintf("%s_%s", InputConfigurationEnvVarPrefix, SidecarPortEnvVar)); port != "" {
portI, err := strconv.Atoi(port)
if err != nil {
return fsc, fmt.Errorf("unable to parse sidecar port value %s to int32: %w", port, err)
}
fsc.Port = int32(portI)
}

if socketPath := os.Getenv(fmt.Sprintf("%s_%s", InputConfigurationEnvVarPrefix, SidecarSocketPathEnvVar)); socketPath != "" {
fsc.SocketPath = socketPath
}

if evaluator := os.Getenv(fmt.Sprintf("%s_%s", InputConfigurationEnvVarPrefix, SidecarEvaluatorEnvVar)); evaluator != "" {
fsc.Evaluator = evaluator
}

if image := os.Getenv(fmt.Sprintf("%s_%s", InputConfigurationEnvVarPrefix, SidecarImageEnvVar)); image != "" {
fsc.Image = image
}

if tag := os.Getenv(fmt.Sprintf("%s_%s", InputConfigurationEnvVarPrefix, SidecarVersionEnvVar)); tag != "" {
fsc.Tag = tag
}

if syncProviderArgs := os.Getenv(fmt.Sprintf("%s_%s", InputConfigurationEnvVarPrefix, SidecarProviderArgsEnvVar)); syncProviderArgs != "" {
fsc.SyncProviderArgs = strings.Split(syncProviderArgs, ",") // todo: add documentation for this
}

return fsc, nil
}

func (fc *FlagSourceConfigurationSpec) Merge(new *FlagSourceConfigurationSpec) {
Expand Down Expand Up @@ -121,30 +162,35 @@ func (fc *FlagSourceConfigurationSpec) Merge(new *FlagSourceConfigurationSpec) {
func (fc *FlagSourceConfigurationSpec) ToEnvVars() []corev1.EnvVar {
envs := []corev1.EnvVar{}

prefix := defaultSidecarEnvVarPrefix
if p := os.Getenv(SidecarEnvVarPrefix); p != "" {
prefix = p
}

if fc.MetricsPort != defaultMetricPort {
envs = append(envs, corev1.EnvVar{
Name: FlagdMetricPortEnvVar,
Name: fmt.Sprintf("%s_%s", prefix, SidecarMetricPortEnvVar),
Value: fmt.Sprintf("%d", fc.MetricsPort),
})
}

if fc.Port != defaultPort {
envs = append(envs, corev1.EnvVar{
Name: FlagdPortEnvVar,
Name: fmt.Sprintf("%s_%s", prefix, SidecarPortEnvVar),
Value: fmt.Sprintf("%d", fc.Port),
})
}

if fc.Evaluator != defaultEvaluator {
envs = append(envs, corev1.EnvVar{
Name: FlagdEvaluatorEnvVar,
Name: fmt.Sprintf("%s_%s", prefix, SidecarEvaluatorEnvVar),
Value: fc.Evaluator,
})
}

if fc.SocketPath != defaultSocketPath {
envs = append(envs, corev1.EnvVar{
Name: FlagdSocketPathEnvVar,
Name: fmt.Sprintf("%s_%s", prefix, SidecarSocketPathEnvVar),
Value: fc.SocketPath,
})
}
Expand Down
37 changes: 35 additions & 2 deletions chart/open-feature-operator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ To install/upgrade the chart with the release name `open-feature-operator`:
helm upgrade -i open-feature-operator openfeature/open-feature-operator
```
This installation will use the default helm configuration, described in the [configuration section](#configuration)
To overwrite these default values use the `--set` flag when calling `helm upgrade` or `helm install`, for example:
```
helm upgrade -i open-feature-operator ./chart/open-feature-operator --set sidecarConfiguration.port=8080 --set controllerManager.kubeRbacProxy.resources.limits.cpu=400m
```

## Uninstall

Expand All @@ -38,10 +42,39 @@ The command removes all the Kubernetes components associated with the chart and
## Configuration
<a name="configuration"></a>

### Sidecar configuration
| Value | Default | Explanation |
| ----------- | ----------- | ----------- |
| `defaultNamespace` | `open-feature-operator` | [INTERNAL USE ONLY] 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.|
| `sidecarConfiguration.envVarPrefix` | `FLAGD` | Sets the prefix for all environment variables set in the injected sidecar. |
| `sidecarConfiguration.port` | 8013 | Sets the value of the `XXX_PORT` environment variable for the injected sidecar container.|
| `sidecarConfiguration.metricsPort` | 8014 | Sets the value of the `XXX_METRICS_PORT` environment variable for the injected sidecar container.|
| `sidecarConfiguration.socketPath` | `""` | Sets the value of the `XXX_SOCKET_PATH` environment variable for the injected sidecar container.|
| `sidecarConfiguration.repository` | `ghcr.io/open-feature/flagd` | Sets the image for the injected sidecar container. |
| `sidecarConfiguration.tag` | current flagd version: `v0.3.0` | Sets the version tag for the injected sidecar container. |
| `sidecarConfiguration.providerArgs` | `""` | Used to append arguments to the sidecar startup command. This value is a comma separated string of key values separated by '=', e.g. `key=value,key2=value2` results in the appending of `--sync-provider-args key=value --sync-provider-args key2=value2` |

### Operator resource configuration
<!-- x-release-please-start-version -->
| Value | Default |
| ----------- | ----------- |
| `defaultNamespace` | `open-feature-operator` | [INTERNAL USE ONLY] 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.|
| `controllerManager.kubeRbacProxy.image.repository` | `gcr.io/kubebuilder/kube-rbac-proxy` |
| `controllerManager.kubeRbacProxy.image.tag` | `v0.13.1` |
| `controllerManager.kubeRbacProxy.resources.limits.cpu` | `500m` |
| `controllerManager.kubeRbacProxy.resources.limits.memory` | `128Mi` |
| `controllerManager.kubeRbacProxy.resources.requests.cpu` | `5m` |
| `controllerManager.kubeRbacProxy.resources.requests.memory` | `64Mi` |
| `controllerManager.manager.image.repository` | `ghcr.io/open-feature/open-feature-operator` |
| `controllerManager.manager.image.tag` | `v0.2.23` |
| `controllerManager.manager.resources.limits.cpu` | `500m` |
| `controllerManager.manager.resources.limits.memory` | `128Mi` |
| `controllerManager.manager.resources.requests.cpu` | `10m` |
| `controllerManager.manager.resources.requests.memory` | `64Mi` |
| `managerConfig.controllerManagerConfigYaml` | `1` |
| `managerConfig.replicas.health.healthProbeBindAddress` | `:8081` |
| `managerConfig.replicas.metrics.bindAddress` | `127.0.0.1:8080` |
| `managerConfig.replicas.webhook.port` | `9443` |
<!-- x-release-please-end -->
## Changelog

See [CHANGELOG.md](https://github.com/open-feature/open-feature-operator/blob/main/CHANGELOG.md)
See [CHANGELOG.md](https://github.com/open-feature/open-feature-operator/blob/main/CHANGELOG.md)
66 changes: 42 additions & 24 deletions chart/open-feature-operator/templates/rendered.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -611,8 +611,8 @@ spec:
description: Evaluator sets an evaluator, defaults to 'json'
type: string
image:
description: Image allows for the flagd image to be overridden, defaults
to 'ghcr.io/open-feature/flagd'
description: Image allows for the sidecar image to be overridden,
defaults to 'ghcr.io/open-feature/flagd'
type: string
metricsPort:
description: MetricsPort defines the port to serve metrics on, defaults
Expand All @@ -633,7 +633,8 @@ spec:
type: string
type: array
tag:
description: Tag to be appended to the flagd image, defaults to 'main'
description: Tag to be appended to the sidecar image, defaults to
'main'
type: string
type: object
status:
Expand Down Expand Up @@ -950,14 +951,11 @@ data:
apiVersion: controller-runtime.sigs.k8s.io/v1alpha1
kind: ControllerManagerConfig
health:
healthProbeBindAddress: :8081
healthProbeBindAddress: "{{ .Values.managerConfig.controllerManagerConfigYaml.health.healthProbeBindAddress }}"
metrics:
bindAddress: 127.0.0.1:8080
bindAddress: "{{ .Values.managerConfig.controllerManagerConfigYaml.metrics.bindAddress }}"
webhook:
port: 9443
leaderElection:
leaderElect: true
resourceName: 131bf64c.openfeature.dev
port: 0{{ .Values.managerConfig.controllerManagerConfigYaml.webhook.port }}
kind: ConfigMap
metadata:
name: open-feature-operator-manager-config
Expand Down Expand Up @@ -1002,7 +1000,7 @@ metadata:
name: open-feature-operator-controller-manager
namespace: '{{ include "chart.namespace" . }}'
spec:
replicas: 1
replicas: 0{{ .Values.controllerManager.replicas }}
selector:
matchLabels:
control-plane: controller-manager
Expand All @@ -1018,14 +1016,27 @@ spec:
- --health-probe-bind-address=:8081
- --metrics-bind-address=127.0.0.1:8080
- --leader-elect
- --flagd-cpu-limit=0.5
- --flagd-ram-limit=64M
- --sidecar-cpu-limit=0.5
- --sidecar-ram-limit=64M
command:
- /manager
env:
- name: FLAGD_VERSION
value: v0.3.1
image: ghcr.io/open-feature/open-feature-operator:main
- name: SIDECAR_METRICS_PORT
value: '{{ .Values.sidecarConfiguration.metricsPort }}'
- name: SIDECAR_PORT
value: '{{ .Values.sidecarConfiguration.port }}'
- name: SIDECAR_SOCKET_PATH
value: '{{ .Values.sidecarConfiguration.socketPath }}'
- name: SIDECAR_IMAGE
value: '{{ .Values.sidecarConfiguration.image.repository }}'
- name: SIDECAR_TAG
value: '{{ .Values.sidecarConfiguration.image.tag }}'
- name: SIDECAR_PROVIDER_ARGS
value: '{{ .Values.sidecarConfiguration.providerArgs }}'
- name: SIDECAR_ENV_VAR_PREFIX
value: '{{ .Values.sidecarConfiguration.envVarPrefix }}'
image: '{{ .Values.controllerManager.manager.image.repository }}:{{ .Values.controllerManager.manager.image.tag
}}'
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
Expand All @@ -1046,11 +1057,13 @@ spec:
periodSeconds: 10
resources:
limits:
cpu: 500m
memory: 128Mi
cpu: '{{ .Values.controllerManager.manager.resources.limits.cpu }}'
memory: '{{ .Values.controllerManager.manager.resources.limits.memory
}}'
requests:
cpu: 10m
memory: 64Mi
cpu: '{{ .Values.controllerManager.manager.resources.requests.cpu }}'
memory: '{{ .Values.controllerManager.manager.resources.requests.memory
}}'
securityContext:
allowPrivilegeEscalation: false
volumeMounts:
Expand All @@ -1062,19 +1075,24 @@ spec:
- --upstream=http://127.0.0.1:8080/
- --logtostderr=true
- --v=0
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.1
image: '{{ .Values.controllerManager.kubeRbacProxy.image.repository }}:{{
.Values.controllerManager.kubeRbacProxy.image.tag }}'
name: kube-rbac-proxy
ports:
- containerPort: 8443
name: https
protocol: TCP
resources:
limits:
cpu: 500m
memory: 128Mi
cpu: '{{ .Values.controllerManager.kubeRbacProxy.resources.limits.cpu
}}'
memory: '{{ .Values.controllerManager.kubeRbacProxy.resources.limits.memory
}}'
requests:
cpu: 5m
memory: 64Mi
cpu: '{{ .Values.controllerManager.kubeRbacProxy.resources.requests.cpu
}}'
memory: '{{ .Values.controllerManager.kubeRbacProxy.resources.requests.memory
}}'
securityContext:
runAsNonRoot: true
serviceAccountName: open-feature-operator-controller-manager
Expand Down
30 changes: 13 additions & 17 deletions chart/open-feature-operator/values.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
# If this namespace is changed the value must be reflected in /open-feature-operator/values.yaml
defaultNamespace: open-feature-operator-system

sidecarConfiguration:
port: 8013
metricsPort: 8014
socketPath: ""
image:
# these fields must remain in the same order, renovate uses a regex to update the tag value
repository: "ghcr.io/open-feature/flagd"
tag: v0.3.1
providerArgs: ""
envVarPrefix: "FLAGD"

controllerManager:
kubeRbacProxy:
image:
repository: gcr.io/kubebuilder/kube-rbac-proxy
tag: v0.13.1
tag: "v0.13.0"
resources:
limits:
cpu: 500m
Expand All @@ -25,27 +36,12 @@ controllerManager:
cpu: 10m
memory: 64Mi
replicas: 1

managerConfig:
controllerManagerConfigYaml:
health:
healthProbeBindAddress: :8081
leaderElection:
leaderElect: true
resourceName: 131bf64c.openfeature.dev
metrics:
bindAddress: 127.0.0.1:8080
webhook:
port: 9443
metricsService:
ports:
- name: https
port: 8443
protocol: TCP
targetPort: https
type: ClusterIP
webhookService:
ports:
- port: 443
protocol: TCP
targetPort: 9443
type: ClusterIP
Loading

0 comments on commit 99edfeb

Please sign in to comment.