Skip to content

docs: support in-process evaluation #640

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions docs/annotations.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,29 @@ Example:
openfeature.dev/featureflagsource: "config-A, config-B"
```

### `openfeature.dev/inprocessconfiguration`

This annotation specifies the names of the `InProcessConfigurations` used to configure the injected environment variables to support flagd's [in-process evaluation mode](https://flagd.dev/architecture/#in-process-evaluation).
The annotation value is a comma separated list of values following one of 2 patterns: {NAME} or {NAMESPACE}/{NAME}.

If no namespace is provided, it is assumed that the custom resource is within the **same namespace** as the annotated pod.
If multiple CRs are provided, they are merged with the latest taking precedence.

Users should not combine `openfeature.dev/inprocessconfiguration` and `openfeature.dev/featureflagsource` annotations
for the same pod. If this happens `openfeature.dev/featureflagsource` will take precedence.

For example, in the scenario below, `inProcessConfig-B` will take priority in the merge, replacing duplicated values that are set in `inProcessConfig-A`.

Example:
```yaml
metadata:
annotations:
openfeature.dev/enabled: "true"
openfeature.dev/inprocessconfiguration: "inProcessConfig-A, inProcessConfig-B"
```

### `openfeature.dev/allowkubernetessync`
*This annotation is used INTERNALLY by the operator.*

This annotation is used to mark pods which should have their permissions backfilled in the event of an upgrade.
When the OFO manager pod is started, all `Service Accounts` of any `Pods` with this annotation set to `"true"` will be added to the `flagd-kubernetes-sync` `Cluster Role Binding`.

## Deprecated annotations

Given below are references to **deprecated** annotations used by previous versions of the operator.
151 changes: 151 additions & 0 deletions docs/in_process_configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Feature Flag In-process Configuration

The `InProcessConfiguration` is a custom resource used to set up the
[configuration options](https://flagd.dev/providers/nodejs/?h=flagd_host#available-configuration-options)
for applications using `OpenFeature operator` with in-process evaluation mode enabled.

Below you can see a minimal example of `InProcessConfiguration` resource

```yaml
apiVersion: core.openfeature.dev/v1beta1
kind: InProcessConfiguration
metadata:
labels:
name: inprocessconfiguration-sample
spec:
port: 2424
tls: true
offlineFlagSourcePath: "my-path"
cacheMaxSize: 11
envVarPrefix: "my-prefix"
envVars:
- name: "name1"
value: "val1"
- name: "name2"
value: "val2"
```

## How does it work?

Similar to usage of [FeatureFlagSource](./feature_flag_source.md) configuration,
[annotations](./annotations.md#) are used to allow the injection of configuration data
into the annotated Pod.
The mutating webhook parses the annotations, retrieves the referenced `InProcessConfiguration` resources from the cluster and injects the data from the resource into all containers of the Pod via environment variables, which configure the provider in the workload to consume feature flag configuration from the available [sync implementation](https://flagd.dev/concepts/syncs/#grpc-sync) specified by the configuration.

## Merging of configurations

The value of `openfeature.dev/inprocessconfiguration` annotation is a comma separated list of values following one of two patterns: {NAME} or {NAMESPACE}/{NAME}.
If no namespace is provided, it is assumed that the CR is within the same namespace as the deployed pod, for example:

```yaml
metadata:
annotations:
openfeature.dev/enabled: "true"
openfeature.dev/inprocessconfiguration: "inProcessConfig-A, inProcessConfig-B"
```

When multiple `InProcessConfigurations` are provided, the custom resources are merged in runtime and the last `CR` takes precedence over the first, similarly how it's done for `FeatureFlagSource`.
In this example, 2 CRs are being used to set the injected configuration.

```yaml
apiVersion: core.openfeature.dev/v1beta1
kind: InProcessConfiguration
metadata:
name: inProcessConfig-A
spec:
port: 2424
tls: true
offlineFlagSourcePath: "my-path"
cacheMaxSize: 11
envVarPrefix: "my-prefix"
envVars:
- name: "name1"
value: "val1"
- name: "name2"
value: "val2"
---
apiVersion: core.openfeature.dev/v1beta1
kind: InProcessConfiguration
metadata:
name: inProcessConfig-B
spec:
envVarPrefix: "my-second-prefix"
host: "my-host"
```

The resources are merged in runtime, which means that no changes are made to the `InProcessConfiguration` resources
in the cluster, but the operator handles the merge and injection internally.

The resulting configuration will look like the following

```yaml
apiVersion: core.openfeature.dev/v1beta1
kind: InProcessConfiguration
metadata:
name: internal
spec:
port: 2424
tls: true
offlineFlagSourcePath: "my-path"
cacheMaxSize: 11
envVarPrefix: "my-seconf-prefix"
host: "my-host"
envVars:
- name: "name1"
value: "val1"
- name: "name2"
value: "val2"
```

This resulting resource is transformed into environment variables and injected into all containers
of the annotated Pod

```yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
openfeature.dev/enabled: "true"
openfeature.dev/inprocessconfiguration: "inProcessConfig-A, inProcessConfig-B"
name: ofo-pod
spec:
containers:
- name: container1
image: image1
env:
- name: my-second-prefix_name2
value: val2
- name: my-second-prefix_name1
value: val1
- name: my-second-prefix_HOST
value: my-host
- name: my-second-prefix_PORT
value: "2424"
- name: my-second-prefix_TLS
value: "true"
- name: my-second-prefix_OFFLINE_FLAG_SOURCE_PATH
value: my-path
- name: my-second-prefix_MAX_CACHE_SIZE
value: "11"
- name: my-second-prefix_RESOLVER
value: in-process
- name: container2
image: image2
env:
- name: my-second-prefix_name2
value: val2
- name: my-second-prefix_name1
value: val1
- name: my-second-prefix_HOST
value: my-host
- name: my-second-prefix_PORT
value: "2424"
- name: my-second-prefix_TLS
value: "true"
- name: my-second-prefix_OFFLINE_FLAG_SOURCE_PATH
value: my-path
- name: my-second-prefix_MAX_CACHE_SIZE
value: "11"
- name: my-second-prefix_RESOLVER
value: in-process
```
29 changes: 17 additions & 12 deletions docs/permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,23 @@ The `manager-role` applies the rules described below, its definition can be foun
It provides the operator with sufficient permissions over the `core.openfeature.dev` resources, and the required permissions for injecting the `flagd` sidecar into appropriate pods.
The `ConfigMap` permissions are needed to allow the mounting of `FeatureFlag` resources for file syncs.

| API Group | Resource | Verbs |
|-----------------------------|--------------------------|-------------------------------------------------|
| - | `ConfigMap` | create, delete, get, list, patch, update, watch |
| - | `Pod` | create, delete, get, list, patch, update, watch |
| - | `ServiceAccount` | get, list, watch |
| - | `Service` *(\*)* | create, delete, get, list, patch, update, watch |
| `networking.k8s.io` | `Ingress` *(\*)* | create, delete, get, list, patch, update, watch |
| `core.openfeature.dev` | `FeatureFlag` | create, delete, get, list, patch, update, watch |
| `core.openfeature.dev` | `FeatureFlag Finalizers` | update |
| `core.openfeature.dev` | `FeatureFlag Status` | get, patch, update |
| `core.openfeature.dev` | `Flagd` | create, delete, get, list, patch, update, watch |
| `rbac.authorization.k8s.io` | `ClusterRoleBinding` | get, list, update, watch |
| API Group | Resource | Verbs |
|-----------------------------|---------------------------------|-------------------------------------------------|
| - | `ConfigMap` | create, delete, get, list, patch, update, watch |
| - | `Pod` | create, delete, get, list, patch, update, watch |
| - | `ServiceAccount` | get, list, watch |
| - | `Service` *(\*)* | create, delete, get, list, patch, update, watch |
| `networking.k8s.io` | `Ingress` *(\*)* | create, delete, get, list, patch, update, watch |
| `core.openfeature.dev` | `FeatureFlag` | create, delete, get, list, patch, update, watch |
| `core.openfeature.dev` | `FeatureFlag Finalizers` | update |
| `core.openfeature.dev` | `FeatureFlag Status` | get, patch, update |
| `core.openfeature.dev` | `FeatureFlagSource` | create, delete, get, list, patch, update, watch |
| `core.openfeature.dev` | `FeatureFlagSource Finalizers` | get, update |
| `core.openfeature.dev` | `FeatureFlagSource Status` | get, patch, update |
| `core.openfeature.dev` | `Flagd` | create, delete, get, list, patch, update, watch |
| `core.openfeature.dev` | `Flagd Finalizers` | update |
| `core.openfeature.dev` | `InProcessConfiguration` | create, delete, get, list, patch, update, watch |
| `rbac.authorization.k8s.io` | `ClusterRoleBinding` | get, list, update, watch |

*(\*) Permissions for `Service` and `networking.k8s.ioIngress` are only granted if the `core.openfeature.dev.Flagd`
CRD has been enabled via the `managerConfig.flagdResourceEnabled` helm value.*
Expand Down