Skip to content

Commit

Permalink
docs: support in-process evaluation (#640)
Browse files Browse the repository at this point in the history
Signed-off-by: odubajDT <ondrej.dubaj@dynatrace.com>
Signed-off-by: odubajDT <93584209+odubajDT@users.noreply.github.com>
Co-authored-by: Florian Bacher <florian.bacher@dynatrace.com>
Co-authored-by: Todd Baert <todd.baert@dynatrace.com>
  • Loading branch information
3 people committed May 28, 2024
1 parent 51db913 commit 9721825
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 16 deletions.
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

0 comments on commit 9721825

Please sign in to comment.