Skip to content

Commit 6891b70

Browse files
Merge pull request #278 from james-milligan/docs
docs: OFO doc updates
2 parents 5a4b586 + 559cddc commit 6891b70

File tree

11 files changed

+296
-161
lines changed

11 files changed

+296
-161
lines changed

README.md

Lines changed: 10 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -12,168 +12,21 @@
1212
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6615/badge)](https://bestpractices.coreinfrastructure.org/projects/6615)
1313
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fopen-feature%2Fopen-feature-operator.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fopen-feature%2Fopen-feature-operator?ref=badge_shield)
1414

15-
The OpenFeature Operator is a Kubernetes native operator that allows you to expose feature flags to your applications. It injects a [flagD](https://github.com/open-feature/flagd) sidecar into your pod and allows you to poll the flagD server for feature flags in a variety of ways.
1615

17-
## Deploy the latest release
16+
## Get started
1817

19-
_Requires [cert manager](https://cert-manager.io/docs/installation/kubernetes/) installed (see why [here](#cert-manager))_
18+
The OpenFeature Operator allows you to expose feature flags to your applications. It injects a [flagD](https://github.com/open-feature/flagd) sidecar into relevant pods exposes gRPC and HTTP interfaces for flag evaluation. To get started, follow the installation instructions in the [docs](./docs).
2019

21-
## Helm
20+
## Contributing
2221

23-
Install cert manager (if not already installed):
24-
```
25-
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml
26-
```
27-
Install helm charts:
28-
```
29-
helm repo add openfeature https://open-feature.github.io/open-feature-operator/
30-
```
22+
See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to the OpenFeature project.
3123

32-
```
33-
helm install ofo openfeature/ofo
34-
```
24+
Our community meetings are held regularly and open to everyone. Check the [OpenFeature community calendar](https://calendar.google.com/calendar/u/0?cid=MHVhN2kxaGl2NWRoMThiMjd0b2FoNjM2NDRAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ) for specific dates and for the Zoom meeting links.
3525

26+
Thanks so much to our contributors.
3627

37-
## Kubectl
28+
<a href="https://github.com/open-feature/flagd/graphs/contributors">
29+
<img src="https://contrib.rocks/image?repo=open-feature/open-feature-operator" />
30+
</a>
3831

39-
<!---x-release-please-start-version-->
40-
41-
```
42-
kubectl create namespace open-feature-operator-system
43-
kubectl apply -f https://github.com/open-feature/open-feature-operator/releases/download/v0.2.20/release.yaml
44-
```
45-
46-
<!---x-release-please-end-->
47-
48-
49-
### Release contents
50-
51-
- `release.yaml` contains the configuration of:
52-
- `FeatureFlagConfiguration` `CustomResourceDefinition` (custom type that holds the configured state of feature flags).
53-
- Standard kubernetes primitives (e.g. namespace, accounts, roles, bindings, configmaps).
54-
- Operator controller manager service.
55-
- Operator webhook service.
56-
- Deployment with containers kube-rbac-proxy & manager.
57-
- `MutatingWebhookConfiguration` (configures webhooks to call the webhook service).
58-
59-
### How to deploy a flag consuming application
60-
61-
_Prerequisite: the release and certificates have been deployed as outlined above._
62-
63-
Deploying a flag consuming application requires (at minimum) the creation of the following 2 resources (an example can be found [here](./config/samples/end-to-end.yaml)):
64-
65-
#### FeatureFlagConfiguration
66-
67-
This is a `CustomResourceDefinition` which contains the feature flags specification and a name of the spec.
68-
69-
#### Deployment (or Statefulset/Daemonset)
70-
71-
This is a kubernetes primitive for deploying an application. The metadata annotations must include `openfeature.dev/featureflagconfiguration`
72-
with the value set as the name of the `FeatureFlagConfiguration` created in the step prior.
73-
74-
e.g.
75-
```
76-
metadata:
77-
annotations:
78-
openfeature.dev/featureflagconfiguration: "demo"
79-
```
80-
81-
## Architecture
82-
83-
As per the issue [here](https://github.com/open-feature/ofep/issues/1)
84-
85-
As per v0.1.1, the default sync provider has been optimized as per this OpenFeature Enhancement Proposal [issue](https://github.com/open-feature/ofep/blob/main/004-OFEP-kubernetes-sync-service.md).
86-
87-
High level architecture is as follows:
88-
89-
<img src="images/arch-0.png" width="700">
90-
91-
### Requirements
92-
93-
#### Namespace
94-
95-
The Kubernetes resources created by OpenFeature Operator are under the `open-feature-operator-system` namespace. This means
96-
any resources that want to communicate with the OFO system (e.g. an application calling flag evaluations) must fall under
97-
this namespace.
98-
99-
#### Cert Manager
100-
101-
OpenFeature Operator is a server that communicates with Kubernetes components within the cluster, as such it requires a means of
102-
authorizing requests between peers. [Cert manager](https://cert-manager.io/) handles the authorization by
103-
adding certificates and certificate issuers as resource types in Kubernetes clusters, and simplifies the process of
104-
obtaining, renewing and using those certificates.
105-
106-
## Example
107-
108-
When wishing to leverage feature flagging within the local pod, the following steps are required:
109-
110-
1. Create a new feature flag custom resource.
111-
112-
_See [here](config/samples/crds/custom_provider.yaml) for additional custom resource parameters_
113-
114-
```
115-
apiVersion: core.openfeature.dev/v1alpha2
116-
kind: FeatureFlagConfiguration
117-
metadata:
118-
name: featureflagconfiguration-sample
119-
spec:
120-
featureFlagSpec:
121-
flags:
122-
foo:
123-
state: "ENABLED"
124-
variants:
125-
"bar": "BAR"
126-
"baz": "BAZ"
127-
defaultVariant: "bar",
128-
targeting: {}
129-
```
130-
131-
1. Reference the CR within the pod spec annotations
132-
The `openfeature.dev/featureflagconfiguration` annotation is a comma separated list of CR references, listed as `{namespace}/{name}`. e.g. `"default/featureflagconfiguration-sample, test/featureflagconfiguration-sample-2"`. If no namespace is defined, it is assumed that the flag configuration is in the same namespace as the deployed pod.
133-
134-
```
135-
apiVersion: v1
136-
kind: Pod
137-
metadata:
138-
name: nginx
139-
annotations:
140-
openfeature.dev/enabled: "true"
141-
openfeature.dev/featureflagconfiguration: "default/featureflagconfiguration-sample"
142-
spec:
143-
containers:
144-
- name: nginx
145-
image: nginx:1.14.2
146-
ports:
147-
- containerPort: 80
148-
```
149-
150-
3. Example usage from host container
151-
152-
```
153-
root@nginx:/# curl -X POST "localhost:8013/schema.v1.Service/ResolveString" -d '{"flagKey":"foo","context":{}}' -H "Content-Type: application/json"
154-
{"value":"BAR","reason":"DEFAULT","variant":"bar"}
155-
```
156-
157-
### Running the operator locally
158-
159-
#### Create a local cluster with cert manager and our operator
160-
161-
1. Create a local cluster with MicroK8s or Kind (forward requests from your localhost:30000 to your cluster, see MicroK8s/Kind doc)
162-
1. `IMG=ghcr.io/open-feature/open-feature-operator:main make deploy-operator`
163-
164-
#### Run the example
165-
166-
1. Apply the end-to-end example: `kubectl apply -f config/samples/end-to-end.yaml`
167-
1. Visit `http://localhost:30000/`
168-
1. Update the value of the `defaultVariant` field in the custom resource instance in `config/samples/end-to-end.yaml` and re-apply to update the flag value!
169-
1. Visit `http://localhost:30000/` and see the change!
170-
171-
## Testing
172-
173-
Run `make test` to run the test suite. The controller integration tests use [envtest](https://book.kubebuilder.io/reference/envtest.html), this sets up and starts an instance of etcd and the Kubernetes API server, without kubelet, controller-manager or other components.
174-
This provides means of asserting that the Kubernetes components reach the desired state without the overhead of using an actual cluster, keeping
175-
test runtime and resource consumption down.
176-
177-
## Releases
178-
179-
This repo uses _Release Please_ to release packages. Release Please sets up a running PR that tracks all changes for the library components, and maintains the versions according to [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/), generated when [PRs are merged](https://github.com/amannn/action-semantic-pull-request). When Release Please's running PR is merged, any changed artifacts are published.
32+
Made with [contrib.rocks](https://contrib.rocks).

docs/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Docs
2+
3+
This directory contains all OpenFeature Operator documentation, see table of contents below:
4+
5+
## Usage
6+
7+
Follow the documentation below to deploy the open feature operator to your local cluster, followed by a simple example app using `curl` to evaluate a static flag.
8+
9+
- [Installation](./installation.md)
10+
- [Getting Started](./getting_started.md)
11+
12+
## Configuration
13+
14+
Configuration of the deployed sidecars is handled through the `FeatureFlagConfiguration` CRs defined in the `openfeature.dev/featureflagconfiguration` annotation of a deployed `PodSpec`.
15+
> Further configuration of the operator will be possible in the future, to help contribute [click here](https://github.com/open-feature/open-feature-operator/issues)
16+
17+
- [Annotations](./annotations.md)
18+
- [FeatureFlagConfigurations](./feature_flag_configuration.md)
19+
20+
## Other Resources
21+
- [Architecture](./architecture.md)
22+
- [Permissions](./permissions.md)
23+
- [Development Notes](./development_notes.md)

docs/annotations.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ The following annotations are used by the operator to control the injection and
55
### `openfeature.dev/enabled`
66
When a value of `"true"` is provided, the operator will inject a flagd sidecar into the annotated pods.
77
Example:
8-
```
8+
```yaml
99
metadata:
1010
annotations:
1111
openfeature.dev/enabled: "true"
@@ -16,7 +16,7 @@ This annotation specifies the names of the FeatureFlagConfigurations used to con
1616
The annotation value a comma separated list of values following one of 2 patterns: {NAME} or {NAMESPACE}/{NAME}.
1717
If no namespace is provided it is assumed that the CR is within the same namespace as the deployed pod.
1818
Example:
19-
```
19+
```yaml
2020
metadata:
2121
annotations:
2222
openfeature.dev/enabled: "true"
@@ -28,7 +28,7 @@ Example:
2828

2929
When a value of `"enabled"` is provided, the operator will inject a flagd sidecar into the annotated pods.
3030
Example:
31-
```
31+
```yaml
3232
metadata:
3333
annotations:
3434
openfeature.dev: "enabled"

docs/architecture.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Architecture
2+
3+
The high level architecture of the operator is as follows:
4+
<p align="center">
5+
<img src="../images/arch-0.png" width="650">
6+
</p>

docs/development_notes.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Development Notes
2+
3+
## Running the operator locally
4+
5+
The project `Makefile` defines a useful method for locally deploying the operator, allowing for the operator image to be defined:
6+
```sh
7+
IMG=ghcr.io/open-feature/open-feature-operator:main make deploy-operator
8+
```
9+
10+
## Testing
11+
12+
Run `make test` to run the test suite. The controller integration tests use [envtest](https://book.kubebuilder.io/reference/envtest.html), this sets up and starts an instance of etcd and the Kubernetes API server, without kubelet, controller-manager or other components.
13+
This provides means of asserting that the Kubernetes components reach the desired state without the overhead of using an actual cluster, keeping
14+
test runtime and resource consumption down.
15+
16+
An e2e test suite can also be found in the [`/test/e2e`](../test/e2e/DEVELOPER.md) directory. These tests are run as part of the `pr-lint` github action, they work by deploying an nginx reverse proxy and asserting that curls to the proxy elicit expected behaviour from the flagd sidecar created by open-feature-operator.
17+
18+
## Releases
19+
20+
This repo uses _Release Please_ to release packages. Release Please sets up a running PR that tracks all changes for the library components, and maintains the versions according to [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/), generated when [PRs are merged](https://github.com/amannn/action-semantic-pull-request). When Release Please's running PR is merged, any changed artifacts are published.

docs/feature_flag_configuration.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Feature Flag Configuration
2+
3+
The `FeatureFlagConfiguration` version `v1alpha2` CRD defines the a CR with the following example structure:
4+
5+
```yaml
6+
apiVersion: core.openfeature.dev/v1alpha2
7+
kind: FeatureFlagConfiguration
8+
metadata:
9+
name: featureflagconfiguration-sample
10+
spec:
11+
flagDSpec:
12+
envs:
13+
- name: FLAGD_PORT
14+
value: "8080"
15+
featureFlagSpec:
16+
flags:
17+
foo:
18+
state: "ENABLED"
19+
variants:
20+
bar: "BAR"
21+
baz: "BAZ"
22+
defaultVariant: "bar"
23+
```
24+
25+
Within the CRD there are 2 main objects, namely the `flagDSpec` and the `featureFlagSpec`, both offering a different set of configuration for the injected `flagd` sidecars.
26+
27+
The `featureFlagSpec` is an object representing the flag configurations themselves, the documentation for this object can be found [here](https://github.com/open-feature/flagd/blob/main/docs/configuration/flag_configuration.md).
28+
29+
The `flagDSpec` has one property called `envs` which contains a list of environment variables used to override the default start command values in `flagd`, the documentation for this configuration can be found [here](https://github.com/open-feature/flagd/blob/main/docs/configuration/configuration.md). These environment variables are also made available in the workload `Pod` for simplified configuration.

docs/getting_started.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Getting Started
2+
3+
Once you have [installed the operator](./installation.md) you can follow this guide to deploy an example application demonstrating the operator.
4+
5+
### Deploy a `FeatureFlagConfiguration`
6+
7+
This `FeatureFlagConfiguration` is watched by the injected `flagd` container and used to construct its internal flag definitions state. If multiple configurations are supplied to `flagd` these states will be merged.
8+
9+
```yaml
10+
apiVersion: core.openfeature.dev/v1alpha2
11+
kind: FeatureFlagConfiguration
12+
metadata:
13+
name: featureflagconfiguration-sample
14+
spec:
15+
featureFlagSpec:
16+
flags:
17+
foo:
18+
state: "ENABLED"
19+
variants:
20+
"bar": "BAR"
21+
"baz": "BAZ"
22+
defaultVariant: "bar",
23+
targeting: {}
24+
```
25+
26+
### Reference the deployed FeatureFlagConfiguration within a Deployment spec annotation.
27+
28+
In this example, a`Deployment` containing a `busybox-curl` container is created. In the example below, the `metadata.annotations` object contains the required annotations for the operator to correctly configure and inject the `flagd` sidecar into each deployed `Pod`. The documentation for these annotations can be found [here](./annotations.md).
29+
30+
```yaml
31+
apiVersion: apps/v1
32+
kind: Deployment
33+
metadata:
34+
name: busybox-curl
35+
annotations:
36+
openfeature.dev/enabled: "true"
37+
openfeature.dev/featureflagconfiguration: "default/featureflagconfiguration-sample"
38+
spec:
39+
replicas: 1
40+
selector:
41+
matchLabels:
42+
app: my-busybox-curl-app
43+
template:
44+
metadata:
45+
labels:
46+
app: my-busybox-cur-app
47+
spec:
48+
containers:
49+
- name: busybox
50+
image: yauritux/busybox-curl:latest
51+
ports:
52+
- containerPort: 80
53+
args:
54+
- sleep
55+
- "30000"
56+
```
57+
58+
### Confirm that operator has injected the `flagd` sidecar
59+
60+
Once the `deployment.yaml` has been applied, our `Pod` should be created grouping 2 containers.
61+
```sh
62+
kubectl get pods -n default
63+
```
64+
Should give a similar output to the following
65+
```sh
66+
NAME READY STATUS RESTARTS AGE
67+
busybox-curl-7bd5767999-spf7v 0/2 ContainerCreating 0 2s
68+
```
69+
When the `Pod` is described, the injected sidecar has the following configuration:
70+
```sh
71+
kubectl describe pod busybox-curl-7bd5767999-spf7v
72+
```
73+
```yaml
74+
flagd:
75+
Image: ghcr.io/open-feature/flagd:v0.2.5
76+
Port: 8014/TCP
77+
Host Port: 0/TCP
78+
Args:
79+
start
80+
--uri/
81+
core.openfeature.dev/default/featureflagconfiguration-sample
82+
Environment:
83+
FLAGD_METRICS_PORT: 8014
84+
```
85+
86+
Now that we have confirmed that the `flagd` sidecar has been injected and the configuration is correct, we can test the flag evaluation using `curl`.
87+
88+
> This is not the usual suggested best practice for evaluating flags in applications, typically a language specific `flagd` provider would be used in conjunction with the OpenFeature SDK, documentation can be found [here](https://github.com/open-feature/flagd/blob/main/docs/usage/flagd_providers.md).
89+
90+
```sh
91+
kubectl exec -it busybox-curl-7bd5767999-spf7v sh
92+
curl -X POST "localhost:8013/schema.v1.Service/ResolveString" -d '{"flagKey":"foo","context":{}}' -H "Content-Type: application/json"
93+
```
94+
output:
95+
```sh
96+
{"value":"BAR","reason":"DEFAULT","variant":"bar"}
97+
```

0 commit comments

Comments
 (0)