Compare commits

..

No commits in common. "main" and "v0.2.18" have entirely different histories.

239 changed files with 4114 additions and 34269 deletions

View File

@ -1,10 +0,0 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/configuration-chainsaw-v1alpha1.json
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Configuration
metadata:
name: configuration-local
spec:
template: true
timeouts:
assert: 2m
error: 2m

View File

@ -1,11 +0,0 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/configuration-chainsaw-v1alpha1.json
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Configuration
metadata:
name: configuration
spec:
skipDelete: true
template: true
timeouts:
assert: 2m
error: 2m

View File

@ -1,37 +0,0 @@
#!/bin/bash
ignore="--ignore-not-found"
logsDir="logs"
createResourceReport () {
path=$1
namespace=$2
resource=$3
withLogs=$4
mkdir -p "$path/$resource"
kubectl get "$resource" -n "$namespace" "$ignore" > "$path/$resource/list-$resource.txt"
for r in $(kubectl get "$resource" -n "$namespace" "$ignore" -o jsonpath='{.items[*].metadata.name}'); do
kubectl describe "$resource/$r" -n "$namespace" > "$path/$resource/$r-describe.txt"
if $withLogs ; then
kubectl logs "$resource/$r" --all-containers=true -n "$namespace" > "$path/$resource/$r-logs.txt"
fi
done
}
# Go through each namespace in the cluster
for namespace in $(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}'); do
mkdir -p "$logsDir/$namespace"
createResourceReport "$logsDir/$namespace" "$namespace" "Pods" true
createResourceReport "$logsDir/$namespace" "$namespace" "Deployments" false
createResourceReport "$logsDir/$namespace" "$namespace" "Daemonsets" false
createResourceReport "$logsDir/$namespace" "$namespace" "Statefulsets" false
createResourceReport "$logsDir/$namespace" "$namespace" "Jobs" false
createResourceReport "$logsDir/$namespace" "$namespace" "FeatureFlag" false
createResourceReport "$logsDir/$namespace" "$namespace" "FeatureFlagSource" false
done

View File

@ -1,30 +0,0 @@
#!/bin/bash
# Readme generator for OpenFeature Operator Helm Chart
#
# This script will install the readme generator if it's not installed already
# and then it will generate the README.md file from the local Helm values
#
# Dependencies:
# Node >=16
# renovate: datasource=github-releases depName=bitnami-labs/readme-generator-for-helm
GENERATOR_VERSION="2.7.0"
echo "Checking if readme generator is installed already..."
if [[ $(npm list -g | grep -c "readme-generator-for-helm@${GENERATOR_VERSION}") -eq 0 ]]; then
echo "Readme Generator v${GENERATOR_VERSION} not installed, installing now..."
git clone https://github.com/bitnami-labs/readme-generator-for-helm.git
cd ./readme-generator-for-helm || exit
git checkout ${GENERATOR_VERSION}
npm ci
cd ..
npm install -g ./readme-generator-for-helm
else
echo "Readme Generator is already installed, continuing..."
fi
echo "Generating readme now..."
readme-generator --config $(pwd)/chart/open-feature-operator/helm-docs-config.json --values=./chart/open-feature-operator/values.yaml --readme=./chart/open-feature-operator/README.md
# Please be aware, the readme file needs to exist and needs to have a Parameters section, as only this section will be re-generated

View File

@ -1,34 +0,0 @@
#!/usr/bin/env bash
# This script is a hack to support helm flow control in kustomize overlays, which would otherwise break them.
# It allows us to render helm template bindings and add newlines.
# For instance, it transforms "___{{ .Value.myValue }}___" to {{ .Value.myValue }}.
# It also adds newlines wherever ___newline___ is found, and other operations. See
# sed_expressions below.
echo 'Running strip-kustomize-helm.sh script'
CHARTS_DIR='./chart/open-feature-operator/templates'
# Careful! Ordering of these expressions matter!
sed_expressions=(
"s/___newline___/\\n/g"
"s/___space___/ /g"
"s/\"___//g"
"s/___\"//g"
"/___delete_me___/d"
"s/___//g"
)
find $CHARTS_DIR -name "*.yaml" | while read file; do
for expr in "${sed_expressions[@]}"; do
if [[ "$OSTYPE" == "darwin"* ]]; then
# macOS (BSD) version
sed -i '' "$expr" "$file"
else
# Linux (GNU) version
sed -i "$expr" "$file"
fi
done
done
echo 'Done running strip-kustomize-helm.sh script'

View File

@ -1,12 +0,0 @@
name: DCO
on:
merge_group:
# Workaround because the DCO app doesn't run on a merge_group trigger
# https://github.com/dcoapp/app/pull/200
jobs:
DCO:
runs-on: ubuntu-latest
if: ${{ github.actor != 'renovate[bot]' }}
steps:
- run: echo "dummy DCO workflow (it won't run any check actually) to trigger by merge_group in order to enable merge queue"

View File

@ -1,70 +0,0 @@
name: E2E-Test
on:
workflow_call:
inputs:
kind_tag:
description: "Tag of Kind image"
type: "string"
env:
GO_VERSION: "~1.23"
defaults:
run:
shell: bash
jobs:
e2e-test:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download image
uses: actions/download-artifact@v4
with:
name: open-feature-operator-local-${{ github.sha }}
path: ${{ github.workspace }}
- name: Cache build tools
id: cache-build-tools
uses: actions/cache@v4
with:
path: ./bin
key: build-tools-${{ github.ref_name }}
- name: Load open-feature-operator image into docker
run: |
docker load --input ${{ github.workspace }}/open-feature-operator-local.tar
- name: Create k8s Kind Cluster
uses: helm/kind-action@v1.12.0
with:
config: ./test/e2e/kind-cluster.yml
cluster_name: open-feature-operator-test
node_image: kindest/node:${{ inputs.kind_tag }}
- name: Load open-feature-operator image into Kind cluster
run: |
kind load docker-image open-feature-operator-local:${{ github.sha }} --name open-feature-operator-test
- name: Install Chainsaw
uses: kyverno/action-install-chainsaw@f2b47b97dc889c12702113753d713f01ec268de5 # v0.2.12
- name: Install OFO
run: |
IMG=open-feature-operator-local:${{ github.sha }} make deploy-operator
- name: Run e2e test
run: |
make e2e-test-chainsaw
- name: Create reports
if: failure()
working-directory: ./.github/scripts
run: ./create-reports.sh
- name: Upload cluster logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: e2e-tests
path: .github/scripts/logs

View File

@ -1,45 +0,0 @@
name: Lint checks
on:
push:
branches:
- 'main'
- '[0-9]+.[1-9][0-9]*.x'
pull_request:
branches:
- 'main'
- '[0-9]+.[1-9][0-9]*.x'
paths:
- "**.go"
- "**/go.mod"
- "**/go.sum"
- ".golangi.yml"
- ".github/workflows/golangci-lint.yml"
- "!docs/**"
env:
# renovate: datasource=github-releases depName=golangci/golangci-lint
GOLANGCI_LINT_VERSION: "v1.63.4"
GO_VERSION: "~1.23"
jobs:
golangci-lint:
name: golangci-lint
runs-on: ubuntu-24.04
strategy:
fail-fast: false
steps:
- name: Check out code
uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
- name: Workspace Init
run: make workspace-init
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
working-directory: ./
version: ${{ env.GOLANGCI_LINT_VERSION }}
args: --config ./.golangci.yml -v

View File

@ -5,105 +5,93 @@ on:
branches:
- main
pull_request:
types:
- opened
- synchronize
- reopened
branches:
- main
merge_group:
env:
# Default minimum version of Go to support.
DEFAULT_GO_VERSION: 1.18
permissions:
contents: read
jobs:
unit-test:
name: Unit Tests
runs-on: ubuntu-24.04
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Go
uses: actions/setup-go@v5
uses: actions/setup-go@v3
with:
go-version-file: 'go.mod'
go-version: ${{ env.DEFAULT_GO_VERSION }}
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Environment
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
- name: Module cache
uses: actions/cache@v4
uses: actions/cache@v3
env:
cache-name: go-mod-cache
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/go.sum') }}
- name: Run linter
run: make lint
- name: Workspace Init
run: make workspace-init
- name: Unit Test
run: make unit-test
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
test:
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v3
with:
flags: unit-tests
go-version: ${{ env.DEFAULT_GO_VERSION }}
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Environment
run: |
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
- name: Module cache
uses: actions/cache@v3
env:
cache-name: go-mod-cache
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/go.sum') }}
- name: Run tests
run: make test
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
docker-local:
permissions:
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v3
with:
submodules: recursive
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@master
with:
platforms: all
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@master
- name: Build
uses: docker/build-push-action@v6
uses: docker/build-push-action@v3
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
outputs: type=docker,dest=${{ github.workspace }}/open-feature-operator-local.tar
tags: open-feature-operator-local:${{ github.sha }}
cache-from: type=gha,scope=${{ github.ref_name }}-ofo
cache-to: type=gha,scope=${{ github.ref_name }}-ofo
tags: open-feature-operator-local:test
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@0.29.0
uses: aquasecurity/trivy-action@master
with:
input: ${{ github.workspace }}/open-feature-operator-local.tar
format: "sarif"
input: /github/workspace/open-feature-operator-local.tar
format: "template"
template: "@/contrib/sarif.tpl"
output: "trivy-results.sarif"
severity: "CRITICAL,HIGH"
env:
# use an alternative trivvy db to avoid rate limits
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db:2,ghcr.io/aquasecurity/trivy-db:2
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: "trivy-results.sarif"
- name: Upload image as artifact
uses: actions/upload-artifact@v4
with:
name: open-feature-operator-local-${{ github.sha }}
path: ${{ github.workspace }}/open-feature-operator-local.tar
e2e_tests:
name: E2E Tests
needs:
- docker-local
strategy:
matrix:
kind_tag: [ v1.22.17, v1.23.17, v1.24.15, v1.25.11, v1.26.3, v1.27.3, v1.28.0 ]
with:
kind_tag: ${{ matrix.kind_tag }}
uses: ./.github/workflows/e2e.yml

View File

@ -13,37 +13,11 @@ permissions:
jobs:
main:
permissions:
# for amannn/action-semantic-pull-request to analyze PR titles
# for marocchino/sticky-pull-request-comment to add comments to the PR
pull-requests: write
pull-requests: read # for amannn/action-semantic-pull-request to analyze PRs
statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR
name: Validate PR title
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
id: lint_pr_title
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: marocchino/sticky-pull-request-comment@v2
# When the previous steps fails, the workflow would stop. By adding this
# condition you can continue the execution with the populated error message.
if: always() && (steps.lint_pr_title.outputs.error_message != null)
with:
header: pr-title-lint-error
message: |
Hey there and thank you for opening this pull request! 👋🏼
We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted.
Details:
```
${{ steps.lint_pr_title.outputs.error_message }}
```
# Delete a previous comment when the issue has been resolved
- if: ${{ steps.lint_pr_title.outputs.error_message == null }}
uses: marocchino/sticky-pull-request-comment@v2
with:
header: pr-title-lint-error
delete: true

View File

@ -6,15 +6,8 @@ on:
- main
env:
# Default minimum version of Go to support.
DEFAULT_GO_VERSION: "~1.23"
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
GITHUB_PAGES_BRANCH: gh-pages
defaults:
run:
shell: bash
permissions:
contents: read
@ -24,7 +17,7 @@ jobs:
permissions:
contents: write # for google-github-actions/release-please-action to create release commit
pull-requests: write # for google-github-actions/release-please-action to create release PR
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
# Release-please creates a PR that tracks all changes
steps:
@ -32,28 +25,26 @@ jobs:
id: release
with:
command: manifest
token: ${{secrets.RELEASE_PLEASE_ACTION_TOKEN}}
token: ${{secrets.GITHUB_TOKEN}}
default-branch: main
signoff: "OpenFeature Bot <109696520+openfeaturebot@users.noreply.github.com>"
outputs:
release_created: ${{ steps.release.outputs.release_created }}
release_tag_name: ${{ steps.release.outputs.tag_name }}
build-oci:
needs: release-please
permissions:
packages: write # to push the container image
runs-on: ubuntu-24.04
packages: write # to push the container image
needs: release-please
runs-on: ubuntu-latest
if: ${{ needs.release-please.outputs.release_created }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v3
with:
ref: ${{ needs.release-please.outputs.release_tag_name }}
- name: Log in to the Container registry
uses: docker/login-action@327cd5a69de6c009b9ce71bce8395f28e651bf99
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
@ -61,7 +52,7 @@ jobs:
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@60a0d343a0d8a18aedee9d34e62251f752153bdb
uses: docker/metadata-action@57396166ad8aefe6098280995947635806a0e6ea
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
@ -75,7 +66,7 @@ jobs:
uses: docker/setup-buildx-action@master
- name: Build
uses: docker/build-push-action@v6
uses: docker/build-push-action@v3
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
@ -87,8 +78,6 @@ jobs:
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:main
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.release-please.outputs.release_tag_name }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=${{ github.ref_name }}-ofo
cache-to: type=gha,scope=${{ github.ref_name }}-ofo
- name: Install cosign
@ -107,23 +96,23 @@ jobs:
if: ${{ env.DRY_RUN != 'true' }}
release-assets:
needs: release-please
permissions:
contents: write # for softprops/action-gh-release to create GitHub release
runs-on: ubuntu-24.04
needs: release-please
runs-on: ubuntu-latest
if: ${{ needs.release-please.outputs.release_created }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v3
with:
ref: ${{ needs.release-please.outputs.release_tag_name }}
- name: Setup go
uses: actions/setup-go@v5
uses: actions/setup-go@v3
with:
go-version: ${{ env.DEFAULT_GO_VERSION }}
go-version: '1.17.11'
- run: |
make workspace-init
make update-flagd
go mod tidy
make controller-gen
IMG=ghcr.io/open-feature/open-feature-operator:${{ needs.release-please.outputs.release_tag_name }} make helm-package
@ -138,47 +127,7 @@ jobs:
with:
tag_name: ${{ needs.release-please.outputs.release_tag_name }}
files: |
config/webhook/certificate.yaml
config/rendered/release.yaml
config/samples/end-to-end.yaml
open-feature-operator-sbom.spdx.json
release-charts:
needs: release-please
permissions:
contents: write
runs-on: ubuntu-24.04
if: ${{ needs.release-please.outputs.release_created }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ env.GITHUB_PAGES_BRANCH }}
- name: Setup go
uses: actions/setup-go@v5
with:
go-version: ${{ env.DEFAULT_GO_VERSION }}
- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Merge release to gh-pages
run: git merge ${{ needs.release-please.outputs.release_tag_name }}
- name: Generate helm charts
run: IMG=ghcr.io/open-feature/open-feature-operator:${{ needs.release-please.outputs.release_tag_name }} make helm-package
- name: Commit files
run: |
git add charts/
git add index.yaml
git commit -s -m "chore: released charts ${{ needs.release-please.outputs.release_tag_name }}"
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ env.GITHUB_PAGES_BRANCH }}

View File

@ -1,38 +0,0 @@
name: Validate CRD Docs
on:
pull_request:
branches:
- 'main'
defaults:
run:
shell: bash
jobs:
check-helm-docs:
name: Check crd documentation values
runs-on: ubuntu-24.04
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Cache build tools
id: cache-build-tools
uses: actions/cache@v4
with:
path: ./bin
key: build-tools-${{ github.ref_name }}
- name: Check if crds.md is up to date
run: |
cp ./docs/crds.md ./docs/crds-old.md
make generate-crdocs
cd ./docs/
if ! cmp --quiet ./crds-old.md ./crds.md; then
echo "The crd values have changes that are not reflected in the documentation. Please use make generate-crdocs to re-generate the docs."
echo ""
echo "=========== Diff ==========="
diff -u ./crds-old.md ./crds.md
exit 1
else
echo ""
echo "CRDs documentation is correct!"
fi

View File

@ -1,51 +0,0 @@
name: Validate Helm Docs
on:
pull_request:
branches:
- 'main'
paths:
- 'chart/**'
defaults:
run:
shell: bash
jobs:
check-helm-docs:
name: Check helm documentation values
runs-on: ubuntu-24.04
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4.4.0
with:
node-version: 16
- name: Generate helm charts
env:
RELEASE_REGISTRY: ghcr.io/openfeature
run: make helm-package
- name: Install readme generator
run: |
git clone https://github.com/bitnami-labs/readme-generator-for-helm.git
cd ./readme-generator-for-helm
npm ci
npm install --location=global ./
cd ..
- name: Check Helm doc up to date
run: |
cd ./chart/open-feature-operator/
cp ./README.md ./README-old.md
readme-generator --config $(pwd)/helm-docs-config.json --values=./values.yaml --readme=./README.md
if ! cmp --quiet ./README-old.md ./README.md; then
echo "The Helm values have changes that are not reflected in the readme. Please use ./.github/scripts/generate-helm-docs.sh to re-generate the docs."
echo ""
echo "=========== Diff ==========="
diff -u ./README-old.md ./README.md
exit 1
else
echo ""
echo "Helm values documentation is correct!"
fi

7
.gitignore vendored
View File

@ -2,10 +2,9 @@ config/rendered/release.yaml
.tar.gz
config/manager/manager.yaml
config/manager/kustomization.yaml
readme-generator-for-helm
tmpcrd.yaml
schemas
.vscode
open-feature-operator
of-agent
# Binaries for programs and plugins
*.exe
@ -32,7 +31,3 @@ testbin/*
*.swo
*~
go.work
go.work.sum
dist

View File

@ -1,34 +0,0 @@
run:
timeout: 5m
go: '1.23'
linters:
enable:
- gofmt # Gofmt checks whether code was gofmt-ed. By default, this tool runs with -s option to check for code simplification
- gci # Gci controls golang package import order and makes it always deterministic.
- errorlint # errorlint can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
- containedctx # containedctx is a linter that detects struct contained context.Context field
- dogsled # Checks assignments with too many blank identifiers (e.g. x, , , _, := f())
- nilnil # Checks that there is no simultaneous return of nil error and an invalid value.
- noctx # noctx finds sending http request without context.Context
- gocyclo # measure cyclomatic complexity
- gocognit # measure cognitive complexity
- funlen # limit function length
- dupl # Detect code duplication
issues:
exclude-rules:
- linters:
- containedctx
- gocyclo
- gocognit
- funlen
path: _test\.go
linters-settings:
gocyclo:
min-complexity: 10
gocognit:
min-complexity: 20
funlen:
lines: 120
statements: 120

View File

@ -1,4 +1,3 @@
{
".": "0.8.7",
"apis": "0.2.45"
".": "0.2.18"
}

View File

@ -1,780 +1,5 @@
# Changelog
## [0.8.7](https://github.com/open-feature/open-feature-operator/compare/v0.8.6...v0.8.7) (2025-07-14)
### 🐛 Bug Fixes
* API server warning for empty imagePullSecrets ([#774](https://github.com/open-feature/open-feature-operator/issues/774)) ([6f7152c](https://github.com/open-feature/open-feature-operator/commit/6f7152cffc75b1b00a4f941afc9e8ee2593151d7))
* end-to-end.yaml ([#771](https://github.com/open-feature/open-feature-operator/issues/771)) ([4b76e47](https://github.com/open-feature/open-feature-operator/commit/4b76e479c44c3dd90ab237ac7ba319617b61f6b9))
* Ingress annotations not reconciling ([#773](https://github.com/open-feature/open-feature-operator/issues/773)) ([6cbc0fa](https://github.com/open-feature/open-feature-operator/commit/6cbc0fa1a19ef89660b0816b0e92425d1e414d96))
### 🧹 Chore
* **deps:** update actions/setup-node action to v4.4.0 ([#767](https://github.com/open-feature/open-feature-operator/issues/767)) ([1e5af9d](https://github.com/open-feature/open-feature-operator/commit/1e5af9d5f0933d93fb55c8df0c6e2b463fae4b4c))
## [0.8.6](https://github.com/open-feature/open-feature-operator/compare/v0.8.5...v0.8.6) (2025-06-03)
### ✨ New Features
* **flagd:** add support for GCS ([#765](https://github.com/open-feature/open-feature-operator/issues/765)) ([349c176](https://github.com/open-feature/open-feature-operator/commit/349c176ee5eb9f2738f1354c8987760620363aa6))
### 🐛 Bug Fixes
* **deps:** update kubernetes packages to v0.32.3 ([#756](https://github.com/open-feature/open-feature-operator/issues/756)) ([a4b4216](https://github.com/open-feature/open-feature-operator/commit/a4b4216d2009a5703214cfb9efacea60d9e1f8d0))
* **deps:** update open-feature/flagd ([#755](https://github.com/open-feature/open-feature-operator/issues/755)) ([20f6f40](https://github.com/open-feature/open-feature-operator/commit/20f6f4095669e4b0b0f895da683a2fe9e580ee5e))
* namespace for ca injection for mutatingwebhook solving [#759](https://github.com/open-feature/open-feature-operator/issues/759) ([#763](https://github.com/open-feature/open-feature-operator/issues/763)) ([d39973b](https://github.com/open-feature/open-feature-operator/commit/d39973b0ea9801829d146ad7649a2b25985fb7af))
### 🧹 Chore
* **deps:** update dependency ubuntu to v24 ([#748](https://github.com/open-feature/open-feature-operator/issues/748)) ([3014013](https://github.com/open-feature/open-feature-operator/commit/301401391ec352a4e23ba96a479aad0a42ddb07f))
* **deps:** update helm/kind-action action to v1.12.0 ([#744](https://github.com/open-feature/open-feature-operator/issues/744)) ([3fc56cd](https://github.com/open-feature/open-feature-operator/commit/3fc56cd89d3f220f8131184fbe4e9245f554c680))
### 📚 Documentation
* Replace the old events calendar by the OpenFeature community Page link ([#751](https://github.com/open-feature/open-feature-operator/issues/751)) ([c4c0c59](https://github.com/open-feature/open-feature-operator/commit/c4c0c59f7f522c8c2f4d3f7fed57dd1cda4e92bb))
## [0.8.5](https://github.com/open-feature/open-feature-operator/compare/v0.8.4...v0.8.5) (2025-01-31)
### 🐛 Bug Fixes
* **deps:** update open-feature/flagd ([#736](https://github.com/open-feature/open-feature-operator/issues/736)) ([9eb1ca8](https://github.com/open-feature/open-feature-operator/commit/9eb1ca8bebe6cfc5d33a905e610ea8a908381740))
### 🧹 Chore
* **deps:** update actions/setup-node action to v4.2.0 ([#737](https://github.com/open-feature/open-feature-operator/issues/737)) ([15d55c5](https://github.com/open-feature/open-feature-operator/commit/15d55c587d6edee562bd86564fa60bb559eed132))
* **deps:** update aquasecurity/trivy-action action to v0.29.0 ([#738](https://github.com/open-feature/open-feature-operator/issues/738)) ([8ac429b](https://github.com/open-feature/open-feature-operator/commit/8ac429beeced6d06883fa66de0e9a50819986f69))
* **deps:** update busybox docker tag to v1.37.0 ([#739](https://github.com/open-feature/open-feature-operator/issues/739)) ([740205f](https://github.com/open-feature/open-feature-operator/commit/740205fc2a6a89dcf2572d9f604f7ba69afc6573))
* **deps:** update curlimages/curl docker tag to v8.11.1 ([#703](https://github.com/open-feature/open-feature-operator/issues/703)) ([383c116](https://github.com/open-feature/open-feature-operator/commit/383c1168d4640d2fe57782982829f68d349b1828))
* **deps:** update dependency bitnami-labs/readme-generator-for-helm to v2.7.0 ([#741](https://github.com/open-feature/open-feature-operator/issues/741)) ([963d155](https://github.com/open-feature/open-feature-operator/commit/963d155d0a847718a9bde15b6e90e56b09812ebb))
* **deps:** update docker/build-push-action action to v6 ([#694](https://github.com/open-feature/open-feature-operator/issues/694)) ([3d2ddfe](https://github.com/open-feature/open-feature-operator/commit/3d2ddfe8d6b2b9b31ba6100f008d079b5e42d19c))
* **deps:** update docker/login-action digest to 327cd5a ([#728](https://github.com/open-feature/open-feature-operator/issues/728)) ([0038e45](https://github.com/open-feature/open-feature-operator/commit/0038e45a72f088976378d647d2ccf721182e0318))
* **deps:** update golang docker tag to v1.23.5 ([#481](https://github.com/open-feature/open-feature-operator/issues/481)) ([06f43a9](https://github.com/open-feature/open-feature-operator/commit/06f43a9241fda9700ef6d6361a65dc50fac7ecb3))
* remove rbac-proxy values and doc ([#742](https://github.com/open-feature/open-feature-operator/issues/742)) ([def1434](https://github.com/open-feature/open-feature-operator/commit/def14340603c2c9976e3a6142ab494764933f682))
* replace deprecated gcr.io/kubebuilder/kube-rbac-proxy ([#733](https://github.com/open-feature/open-feature-operator/issues/733)) ([5358d1e](https://github.com/open-feature/open-feature-operator/commit/5358d1eacfd44cf01016c4bc6f68c496e757354f))
## [0.8.4](https://github.com/open-feature/open-feature-operator/compare/v0.8.3...v0.8.4) (2025-01-13)
### 🧹 Chore
* release apis 0.2.45 ([#727](https://github.com/open-feature/open-feature-operator/issues/727)) ([dbe1222](https://github.com/open-feature/open-feature-operator/commit/dbe12227bc551dcda472b6c1afedb57321852e33))
## [0.8.3](https://github.com/open-feature/open-feature-operator/compare/v0.8.2...v0.8.3) (2025-01-13)
### 🐛 Bug Fixes
* Add --port argument in flagd pods for set flagd service port ([#710](https://github.com/open-feature/open-feature-operator/issues/710)) ([674dd16](https://github.com/open-feature/open-feature-operator/commit/674dd16ac4dca94f04160247c55121e266979e25))
* flagd environment variables missing prefix ([#730](https://github.com/open-feature/open-feature-operator/issues/730)) ([0aa61ec](https://github.com/open-feature/open-feature-operator/commit/0aa61ec1419ec1d99f3c875dd6526ec8ca8e6014))
## [0.8.2](https://github.com/open-feature/open-feature-operator/compare/v0.8.1...v0.8.2) (2025-01-13)
### ✨ New Features
* add gateway api support ([#725](https://github.com/open-feature/open-feature-operator/issues/725)) ([b393a26](https://github.com/open-feature/open-feature-operator/commit/b393a2669c05d58afe453867401f8d697464b145))
* allow setting mutating webhook failurepolicy and objectSelector via helm ([#715](https://github.com/open-feature/open-feature-operator/issues/715)) ([e3f1e24](https://github.com/open-feature/open-feature-operator/commit/e3f1e2471f2f2bd1a29539c57aa8161dc9fdd570))
### 🐛 Bug Fixes
* Add missing poddisruptionbudget update verb ([#722](https://github.com/open-feature/open-feature-operator/issues/722)) ([9b8e8c3](https://github.com/open-feature/open-feature-operator/commit/9b8e8c322ecc07d4d7f85d491a5cae0187b2db92))
## [0.8.1](https://github.com/open-feature/open-feature-operator/compare/v0.8.0...v0.8.1) (2024-10-30)
### 🐛 Bug Fixes
* Add missing poddisruption budget permissions in manager cluster role ([#718](https://github.com/open-feature/open-feature-operator/issues/718)) ([69efcf0](https://github.com/open-feature/open-feature-operator/commit/69efcf021dfa4915bba9c943d0b8a8d137bfb2b2))
* make flagd replica count configureable in helm chart ([#716](https://github.com/open-feature/open-feature-operator/issues/716)) ([8ae6ee8](https://github.com/open-feature/open-feature-operator/commit/8ae6ee81ac48589d01fd6e75f9c16bcd62c336b0))
### 🧹 Chore
* **deps:** update docker/login-action digest to 0689575 ([#714](https://github.com/open-feature/open-feature-operator/issues/714)) ([20e4045](https://github.com/open-feature/open-feature-operator/commit/20e4045d1ad45a5047f4f81a544b96643528dda7))
## [0.8.0](https://github.com/open-feature/open-feature-operator/compare/v0.7.2...v0.8.0) (2024-10-22)
### ⚠ BREAKING CHANGES
* Fix typo flagsValidatonEnabled into flagsValidationEnabled ([#707](https://github.com/open-feature/open-feature-operator/issues/707))
### ✨ New Features
* add flagd-proxy HA configuration ([#712](https://github.com/open-feature/open-feature-operator/issues/712)) ([e115159](https://github.com/open-feature/open-feature-operator/commit/e115159936773e11353912bb11739a51108eb297))
### 🐛 Bug Fixes
* Fix typo flagsValidatonEnabled into flagsValidationEnabled ([#707](https://github.com/open-feature/open-feature-operator/issues/707)) ([64cdc25](https://github.com/open-feature/open-feature-operator/commit/64cdc25a031cd6991cca9425ec3052fc892ce720))
### 🧹 Chore
* **deps:** update golangci/golangci-lint-action action to v6 ([#704](https://github.com/open-feature/open-feature-operator/issues/704)) ([696e2ed](https://github.com/open-feature/open-feature-operator/commit/696e2edf83a6ba358bf6e19337e69c7b70162d37))
## [0.7.2](https://github.com/open-feature/open-feature-operator/compare/v0.7.1...v0.7.2) (2024-08-02)
### ✨ New Features
* Custom labels and annotations for namespace. ([#702](https://github.com/open-feature/open-feature-operator/issues/702)) ([a21f278](https://github.com/open-feature/open-feature-operator/commit/a21f278c2ee994223eb715796c963d109237dff5))
### 🐛 Bug Fixes
* Case-align FROM and AS in Dockerfile ([#699](https://github.com/open-feature/open-feature-operator/issues/699)) ([4a43871](https://github.com/open-feature/open-feature-operator/commit/4a43871bfacbd9b38a0225b50520daa37bef97c9))
* Fix Kustomize installation ([#700](https://github.com/open-feature/open-feature-operator/issues/700)) ([b5ad594](https://github.com/open-feature/open-feature-operator/commit/b5ad5943cc0edf4298efa571a50482f8991314e9))
### 🧹 Chore
* **deps:** update codecov/codecov-action action to v4 ([#693](https://github.com/open-feature/open-feature-operator/issues/693)) ([1588ef8](https://github.com/open-feature/open-feature-operator/commit/1588ef85202c14fb2bcf47925f99bb2ab5dd1ac3))
## [0.7.1](https://github.com/open-feature/open-feature-operator/compare/v0.7.0...v0.7.1) (2024-07-23)
### ✨ New Features
* Add labels and annotations to pods. ([#681](https://github.com/open-feature/open-feature-operator/issues/681)) ([7ec44a6](https://github.com/open-feature/open-feature-operator/commit/7ec44a6a06ce570bf80d2cf6d78632f61a73fe89))
### 🐛 Bug Fixes
* **deps:** update golang.org/x/exp digest to 8a7402a ([#691](https://github.com/open-feature/open-feature-operator/issues/691)) ([db53303](https://github.com/open-feature/open-feature-operator/commit/db53303d14ca0fada38db97981dd5ed95d95f7ad))
* **deps:** update module github.com/stretchr/testify to v1.9.0 ([#671](https://github.com/open-feature/open-feature-operator/issues/671)) ([1d2713d](https://github.com/open-feature/open-feature-operator/commit/1d2713dad6381e56aa3b552c33e1cb3513574a6e))
### 🧹 Chore
* **deps:** update actions/setup-go action to v5 ([#673](https://github.com/open-feature/open-feature-operator/issues/673)) ([b27a9eb](https://github.com/open-feature/open-feature-operator/commit/b27a9eb7163b23c4febec9721126639297a41217))
* **deps:** update actions/setup-node action to v4 ([#675](https://github.com/open-feature/open-feature-operator/issues/675)) ([6f77899](https://github.com/open-feature/open-feature-operator/commit/6f77899bdefefdf43f4cee02c6f1def3ccaf758a))
* **deps:** update docker/login-action digest to 9780b0c ([#605](https://github.com/open-feature/open-feature-operator/issues/605)) ([486a4fd](https://github.com/open-feature/open-feature-operator/commit/486a4fd8b2d647d1666f745ed07a601fcc8b7af8))
* **deps:** update docker/metadata-action digest to 60a0d34 ([#690](https://github.com/open-feature/open-feature-operator/issues/690)) ([473929c](https://github.com/open-feature/open-feature-operator/commit/473929c3d80f1abe9a9dd92e5a4db542c8b32da8))
* **deps:** update module golang.org/x/net to v0.27.0 ([#669](https://github.com/open-feature/open-feature-operator/issues/669)) ([0fdd6db](https://github.com/open-feature/open-feature-operator/commit/0fdd6db6e1809f3e94fe68ca6d3094725ce51b4c))
* **deps:** update open-feature/flagd ([#689](https://github.com/open-feature/open-feature-operator/issues/689)) ([0d331a9](https://github.com/open-feature/open-feature-operator/commit/0d331a9bc5db752cb3aa49f7ce5afc0830f115fe))
* release apis 0.2.44 ([#688](https://github.com/open-feature/open-feature-operator/issues/688)) ([9997ea4](https://github.com/open-feature/open-feature-operator/commit/9997ea443ecc025afd7aff2e33e92fb05acb3b1a))
## [0.7.0](https://github.com/open-feature/open-feature-operator/compare/v0.6.1...v0.7.0) (2024-07-04)
### ⚠ BREAKING CHANGES
* split bind address to manage host and port separately ([#679](https://github.com/open-feature/open-feature-operator/issues/679))
### ✨ New Features
* Add hostNetwork flag. ([#680](https://github.com/open-feature/open-feature-operator/issues/680)) ([8e00a35](https://github.com/open-feature/open-feature-operator/commit/8e00a35c89732a1b76ab07a923ae7aee13028615))
* split bind address to manage host and port separately ([#679](https://github.com/open-feature/open-feature-operator/issues/679)) ([31cddba](https://github.com/open-feature/open-feature-operator/commit/31cddbaf95649701a5c981e8fd0c1f0a5461e980))
### 🐛 Bug Fixes
* remove duplicated port in helm ([#686](https://github.com/open-feature/open-feature-operator/issues/686)) ([65c3c26](https://github.com/open-feature/open-feature-operator/commit/65c3c262110cca3b1d913b680e4b49973ce1a09a))
## [0.6.1](https://github.com/open-feature/open-feature-operator/compare/v0.6.0...v0.6.1) (2024-06-06)
### ✨ New Features
* add image pull secrets ([#655](https://github.com/open-feature/open-feature-operator/issues/655)) ([2d7b30c](https://github.com/open-feature/open-feature-operator/commit/2d7b30c407f5c4d83cdf5bb08ff9de52bcc841a2))
### 🐛 Bug Fixes
* **deps:** update module github.com/go-logr/logr to v1.4.2 ([#601](https://github.com/open-feature/open-feature-operator/issues/601)) ([f245658](https://github.com/open-feature/open-feature-operator/commit/f245658ffbc33db5814798182a1e7d9a538ba4e8))
* **deps:** update module go.uber.org/zap to v1.27.0 ([#614](https://github.com/open-feature/open-feature-operator/issues/614)) ([3746216](https://github.com/open-feature/open-feature-operator/commit/3746216b6e3c7b20dff2788954eb11e94e8a4a34))
* flagd path defaults ([#658](https://github.com/open-feature/open-feature-operator/issues/658)) ([aef1010](https://github.com/open-feature/open-feature-operator/commit/aef1010dff162e8d232942e642c68e3e9ba3f35f))
* handle multiple imagePullSecrets ([#666](https://github.com/open-feature/open-feature-operator/issues/666)) ([df3d6d9](https://github.com/open-feature/open-feature-operator/commit/df3d6d922a262ccfe3082a972a8f3fe495a7d4ca))
### 🧹 Chore
* add rule for env cfg tags ([#674](https://github.com/open-feature/open-feature-operator/issues/674)) ([499661e](https://github.com/open-feature/open-feature-operator/commit/499661e53318f7476e9cb4c9a551eb0c3a626090))
* **deps:** update actions/setup-node action to v3.8.2 ([#580](https://github.com/open-feature/open-feature-operator/issues/580)) ([e43ce5f](https://github.com/open-feature/open-feature-operator/commit/e43ce5f0a6e207b3f03262d29b1ab0a5e6baa817))
* **deps:** update curlimages/curl docker tag to v8.8.0 ([#616](https://github.com/open-feature/open-feature-operator/issues/616)) ([ab7cfde](https://github.com/open-feature/open-feature-operator/commit/ab7cfde2b8bc284f7d67fdc69ff5a7bad6665790))
* **deps:** update dependency bitnami-labs/readme-generator-for-helm to v2.6.1 ([#662](https://github.com/open-feature/open-feature-operator/issues/662)) ([fdce5f9](https://github.com/open-feature/open-feature-operator/commit/fdce5f9a4a4faa5618ffa1bed7f7058d0354e7ad))
* **deps:** update dependency golangci/golangci-lint to v1.59.0 ([#606](https://github.com/open-feature/open-feature-operator/issues/606)) ([692a325](https://github.com/open-feature/open-feature-operator/commit/692a325f70bb902a1b51e44efd5ce004bb832c05))
* **deps:** update dependency kubernetes-sigs/controller-tools to v0.15.0 ([#667](https://github.com/open-feature/open-feature-operator/issues/667)) ([60f528f](https://github.com/open-feature/open-feature-operator/commit/60f528f464141a3c93f15684ca5f7c37213a2b6f))
* **deps:** update docker/metadata-action digest to f7b4ed1 ([#598](https://github.com/open-feature/open-feature-operator/issues/598)) ([28700ce](https://github.com/open-feature/open-feature-operator/commit/28700ce600c74bae921d88ede113313fe9924efb))
* **deps:** update helm/kind-action action to v1.10.0 ([#668](https://github.com/open-feature/open-feature-operator/issues/668)) ([e0b1748](https://github.com/open-feature/open-feature-operator/commit/e0b1748a265a741a17317730dfbb6270f7c43f31))
* **deps:** update open-feature/flagd ([#670](https://github.com/open-feature/open-feature-operator/issues/670)) ([1174a1b](https://github.com/open-feature/open-feature-operator/commit/1174a1b277c1f335b5f73ee76e0c111fd16ace4b))
* release apis 0.2.43 ([#660](https://github.com/open-feature/open-feature-operator/issues/660)) ([aed8ba1](https://github.com/open-feature/open-feature-operator/commit/aed8ba19ffd00f202cdfa980ef063bae49468faa))
## [0.6.0](https://github.com/open-feature/open-feature-operator/compare/v0.5.7...v0.6.0) (2024-05-29)
### ⚠ BREAKING CHANGES
* remove flagdResourceEnabled ([#652](https://github.com/open-feature/open-feature-operator/issues/652))
### 🐛 Bug Fixes
* remove flagdResourceEnabled ([#652](https://github.com/open-feature/open-feature-operator/issues/652)) ([640ff10](https://github.com/open-feature/open-feature-operator/commit/640ff10c5976df1d0fc66251781b8b0cfeff0df0))
## [0.5.7](https://github.com/open-feature/open-feature-operator/compare/v0.5.6...v0.5.7) (2024-05-29)
### 🐛 Bug Fixes
* adapt rolebinding to modified manager role ([#647](https://github.com/open-feature/open-feature-operator/issues/647)) ([e627f11](https://github.com/open-feature/open-feature-operator/commit/e627f112e92bea221fcf40aacdf92eec157ffaea))
* include parameters with default values to envVars ([#648](https://github.com/open-feature/open-feature-operator/issues/648)) ([4f0477c](https://github.com/open-feature/open-feature-operator/commit/4f0477c8e0da571a1cf11e4ac8b57dba3d98efe2))
### 🧹 Chore
* bump k8s libs ([#644](https://github.com/open-feature/open-feature-operator/issues/644)) ([a18d272](https://github.com/open-feature/open-feature-operator/commit/a18d27270eeb9eb7aaccd9e6fb368a55b94f98ba))
* release apis 0.2.42 ([#650](https://github.com/open-feature/open-feature-operator/issues/650)) ([b6cd29f](https://github.com/open-feature/open-feature-operator/commit/b6cd29f787650f6a85f9799fa0c54464dcef58f5))
## [0.5.6](https://github.com/open-feature/open-feature-operator/compare/v0.5.5...v0.5.6) (2024-05-28)
### ✨ New Features
* add `flagd` CRD with ingress support ([#633](https://github.com/open-feature/open-feature-operator/issues/633)) ([b0b99a7](https://github.com/open-feature/open-feature-operator/commit/b0b99a7d101fb7e281394acd0d8b22a16546708f))
* introduce new CRD for in-process evaluation ([#632](https://github.com/open-feature/open-feature-operator/issues/632)) ([51db913](https://github.com/open-feature/open-feature-operator/commit/51db913bc708cc60f00e430e372b68c28c7cbda2))
### 🐛 Bug Fixes
* helm sidecar resources not applied ([#639](https://github.com/open-feature/open-feature-operator/issues/639)) ([d549144](https://github.com/open-feature/open-feature-operator/commit/d54914460b9f01e10bdc958a46ff210fd0f4c374))
* inject env variables to all pod containers ([#634](https://github.com/open-feature/open-feature-operator/issues/634)) ([b21378e](https://github.com/open-feature/open-feature-operator/commit/b21378e4e58b050b36abb8492f6f15be5bca6268))
* use flagd standalone tag instead of sidecar tag for flagd deployments ([#643](https://github.com/open-feature/open-feature-operator/issues/643)) ([a8b7ad4](https://github.com/open-feature/open-feature-operator/commit/a8b7ad49d8364492ffef9c96bfe08c66cfaf6fe3))
### 🧹 Chore
* init workspace before linting ([#638](https://github.com/open-feature/open-feature-operator/issues/638)) ([65e20cf](https://github.com/open-feature/open-feature-operator/commit/65e20cf72b3e1c90e3c3a6ab714fd82c2189cd33))
* release apis 0.2.41 ([#627](https://github.com/open-feature/open-feature-operator/issues/627)) ([546635e](https://github.com/open-feature/open-feature-operator/commit/546635e6d486fd0dbc4aba985e43a928918fd1f4))
### 📚 Documentation
* document new Flagd CRD ([#641](https://github.com/open-feature/open-feature-operator/issues/641)) ([06b399e](https://github.com/open-feature/open-feature-operator/commit/06b399e0cf39bcee3a2804759649e7a28a38a55a))
* support in-process evaluation ([#640](https://github.com/open-feature/open-feature-operator/issues/640)) ([9721825](https://github.com/open-feature/open-feature-operator/commit/972182539ea9ce0440f700456ddeb7d36672a8fb))
## [0.5.5](https://github.com/open-feature/open-feature-operator/compare/v0.5.4...v0.5.5) (2024-05-13)
### ✨ New Features
* introduce validating webhook for FeatureFlag CR ([#622](https://github.com/open-feature/open-feature-operator/issues/622)) ([c4831a3](https://github.com/open-feature/open-feature-operator/commit/c4831a3cdc00aec36f3fe9bec9abceafba1f8aa8))
* operator interval ([#621](https://github.com/open-feature/open-feature-operator/issues/621)) ([bcc5912](https://github.com/open-feature/open-feature-operator/commit/bcc59120423610a37a3e0aec2d6c347f7fed095b))
### 🐛 Bug Fixes
* Add capability to skip crd installation during helm install ([#625](https://github.com/open-feature/open-feature-operator/issues/625)) ([a40e13b](https://github.com/open-feature/open-feature-operator/commit/a40e13b421e7a95c1d4635a87cde8b3203b4571b))
### 🧹 Chore
* bump operator builder tools versions ([#626](https://github.com/open-feature/open-feature-operator/issues/626)) ([918a697](https://github.com/open-feature/open-feature-operator/commit/918a69732fabb34af2f83ca8f650e433e87d0212))
* **deps:** update actions/checkout action to v4 ([#603](https://github.com/open-feature/open-feature-operator/issues/603)) ([4eda2ca](https://github.com/open-feature/open-feature-operator/commit/4eda2ca837c7a8c967d53d4902ed223cbc7e1a6e))
* **deps:** update helm/kind-action action to v1.9.0 ([#608](https://github.com/open-feature/open-feature-operator/issues/608)) ([8800728](https://github.com/open-feature/open-feature-operator/commit/8800728e14998b88a7f2b86977d980a3200e4e1d))
* **deps:** update module golang.org/x/net to v0.24.0 ([#613](https://github.com/open-feature/open-feature-operator/issues/613)) ([b6daece](https://github.com/open-feature/open-feature-operator/commit/b6daece6c4bb6dc42e059fcbef4544cb7825e0c2))
* release apis 0.2.40 ([#620](https://github.com/open-feature/open-feature-operator/issues/620)) ([e39e763](https://github.com/open-feature/open-feature-operator/commit/e39e7638a1cc7985e665229303f18dcb57b4b95a))
* update API to the latest version ([#631](https://github.com/open-feature/open-feature-operator/issues/631)) ([2c39428](https://github.com/open-feature/open-feature-operator/commit/2c394282592bf9f6626c80bdeea2e5e20cabd274))
* use workspaces to make api changes easier ([#635](https://github.com/open-feature/open-feature-operator/issues/635)) ([0479540](https://github.com/open-feature/open-feature-operator/commit/04795403f69d64f85ad53a7e8d0fa5cbc908c169))
### 📚 Documentation
* bump cert manager version ([2e59477](https://github.com/open-feature/open-feature-operator/commit/2e594773444087a109bfccef54a091f23ff7f9c6))
* bump cert manager version ([de2f2b5](https://github.com/open-feature/open-feature-operator/commit/de2f2b59b39911b29cca1b22ffd0c5dd32b32e9b))
## [0.5.4](https://github.com/open-feature/open-feature-operator/compare/v0.5.3...v0.5.4) (2024-02-21)
### ✨ New Features
* auto-upgrade flagd-proxy with OFO upgrades ([#596](https://github.com/open-feature/open-feature-operator/issues/596)) ([3271f33](https://github.com/open-feature/open-feature-operator/commit/3271f33623518408b0055b808c22434a46462a05))
### 🧹 Chore
* add link to tutorial in README ([#594](https://github.com/open-feature/open-feature-operator/issues/594)) ([f3f9427](https://github.com/open-feature/open-feature-operator/commit/f3f9427287199e28d3e11313bad616f0e781048b))
* bump go to 1.21 ([#604](https://github.com/open-feature/open-feature-operator/issues/604)) ([73d6319](https://github.com/open-feature/open-feature-operator/commit/73d6319820220fc114cdfc7d72f8c2327a35ec37))
* **deps:** update actions/cache action to v4 ([#602](https://github.com/open-feature/open-feature-operator/issues/602)) ([e4476e2](https://github.com/open-feature/open-feature-operator/commit/e4476e2e5d2e2178ef280e6da324590115b80cb6))
* **deps:** update curlimages/curl docker tag to v8.6.0 ([#599](https://github.com/open-feature/open-feature-operator/issues/599)) ([2b9d63a](https://github.com/open-feature/open-feature-operator/commit/2b9d63a6dbde5a716dc2e472e65b55ba36085c40))
* **deps:** update open-feature/flagd ([#600](https://github.com/open-feature/open-feature-operator/issues/600)) ([0e03f47](https://github.com/open-feature/open-feature-operator/commit/0e03f47c295592fd9eb94185b1a8d69c5fe52559))
* regex to match all go files ([#607](https://github.com/open-feature/open-feature-operator/issues/607)) ([a1fc38a](https://github.com/open-feature/open-feature-operator/commit/a1fc38a4186f297712ee077780a1c372026e58fb))
* release apis 0.2.39 ([#590](https://github.com/open-feature/open-feature-operator/issues/590)) ([c53a72b](https://github.com/open-feature/open-feature-operator/commit/c53a72b0d4f0ecbb6f839ae1af54621f4c152f42))
### 📚 Documentation
* fix link to the flagd flag definition ([ffc6cec](https://github.com/open-feature/open-feature-operator/commit/ffc6cec3b19d6d59f103c8d6083836bafa14c352))
## [0.5.3](https://github.com/open-feature/open-feature-operator/compare/v0.5.2...v0.5.3) (2023-12-29)
### 🐛 Bug Fixes
* create index for pod annotation path for allowkubernetessync annotation instead of deployment ([#582](https://github.com/open-feature/open-feature-operator/issues/582)) ([a6fa04f](https://github.com/open-feature/open-feature-operator/commit/a6fa04f590ad4ad6779ce85f4fc167b59f1b17a7))
* flagd mgmt port setting ignored ([#588](https://github.com/open-feature/open-feature-operator/issues/588)) ([1444328](https://github.com/open-feature/open-feature-operator/commit/1444328691450ee3967d862eebf3a293b4f9fe7c))
### 🧹 Chore
* add default timeout to make ([#593](https://github.com/open-feature/open-feature-operator/issues/593)) ([a5dfbe1](https://github.com/open-feature/open-feature-operator/commit/a5dfbe1aa24e17bd21fe4c5073e0cd40f11b6203))
* **deps:** update dependency bitnami-labs/readme-generator-for-helm to v2.6.0 ([#525](https://github.com/open-feature/open-feature-operator/issues/525)) ([70fb5d9](https://github.com/open-feature/open-feature-operator/commit/70fb5d95497346dac9f83058105de4d828d75c96))
* Remove metrics-port flag/usage from flagdproxy startup ([#587](https://github.com/open-feature/open-feature-operator/issues/587)) ([f79c46f](https://github.com/open-feature/open-feature-operator/commit/f79c46f36cfda1134c523e962925cfdfd0d2b0b3))
* update `FeatureFlagSource` documentation for v1beta1 ([#584](https://github.com/open-feature/open-feature-operator/issues/584)) ([5a7b2c6](https://github.com/open-feature/open-feature-operator/commit/5a7b2c6be1d38fe344c98f0e7d816852e9eb744f))
* update readme tag version ([#592](https://github.com/open-feature/open-feature-operator/issues/592)) ([f6a154d](https://github.com/open-feature/open-feature-operator/commit/f6a154d92a6ed0633761523b5cb43606604a48a1))
## [0.5.2](https://github.com/open-feature/open-feature-operator/compare/v0.5.1...v0.5.2) (2023-12-06)
### 🐛 Bug Fixes
* bump flagd and flagd proxy version ([#577](https://github.com/open-feature/open-feature-operator/issues/577)) ([5d8c829](https://github.com/open-feature/open-feature-operator/commit/5d8c8299bc3030a2b14baaa6a0fb5b4f6f0d47ea))
### 🧹 Chore
* add helm migration section ([#573](https://github.com/open-feature/open-feature-operator/issues/573)) ([361d068](https://github.com/open-feature/open-feature-operator/commit/361d068a46d8d6ca5c96aa0889cdbe1ac53d538b))
* **deps:** update docker/metadata-action digest to 31cebac ([#520](https://github.com/open-feature/open-feature-operator/issues/520)) ([5262fa7](https://github.com/open-feature/open-feature-operator/commit/5262fa7dc15458330cdc13c277a7b0a115199326))
* migration docs ([#571](https://github.com/open-feature/open-feature-operator/issues/571)) ([8bf9e42](https://github.com/open-feature/open-feature-operator/commit/8bf9e42fbc8300d614b398e0b91146082a66abba))
## [0.5.1](https://github.com/open-feature/open-feature-operator/compare/v0.5.0...v0.5.1) (2023-12-01)
### 🐛 Bug Fixes
* use webhook ns if empty, more test versions ([#568](https://github.com/open-feature/open-feature-operator/issues/568)) ([b9b619d](https://github.com/open-feature/open-feature-operator/commit/b9b619dcd5133a48ca1248eba14419a30922e961))
## [0.5.0](https://github.com/open-feature/open-feature-operator/compare/v0.4.0...v0.5.0) (2023-11-29)
### ⚠ BREAKING CHANGES
* use v1beta1 in operator logic ([#539](https://github.com/open-feature/open-feature-operator/issues/539))
### ✨ New Features
* Introduce v1beta1 API version ([#535](https://github.com/open-feature/open-feature-operator/issues/535)) ([3acd492](https://github.com/open-feature/open-feature-operator/commit/3acd49289a40e8f07fd20aad46185ac42ceb1b7a))
* prepare apis for v1beta1 controllers onboarding ([#549](https://github.com/open-feature/open-feature-operator/issues/549)) ([e3c8b42](https://github.com/open-feature/open-feature-operator/commit/e3c8b4290be99d78b88ffef686531a38b97e61be))
* release APIs and Operator independently ([#541](https://github.com/open-feature/open-feature-operator/issues/541)) ([7b1af42](https://github.com/open-feature/open-feature-operator/commit/7b1af42ac41e63ccbb1820b31f579ffea679cff6))
* restricting sidecar image and tag setup ([#550](https://github.com/open-feature/open-feature-operator/issues/550)) ([233be79](https://github.com/open-feature/open-feature-operator/commit/233be79b56ccca32a1cb041bce53a9848f032a60))
* update api version to v0.2.38 ([#561](https://github.com/open-feature/open-feature-operator/issues/561)) ([d1f2477](https://github.com/open-feature/open-feature-operator/commit/d1f247727c5b6f4cb5154e94f1090aee0a442346))
* use v1beta1 in operator logic ([#539](https://github.com/open-feature/open-feature-operator/issues/539)) ([d234410](https://github.com/open-feature/open-feature-operator/commit/d234410a809760ba1c8592f95be56891e0cae855))
### 🐛 Bug Fixes
* fix build ([#566](https://github.com/open-feature/open-feature-operator/issues/566)) ([c8c6101](https://github.com/open-feature/open-feature-operator/commit/c8c61019266dc3fc379759bc22a9360279ee194a))
* Revert "chore: release apis 0.2.38" ([#557](https://github.com/open-feature/open-feature-operator/issues/557)) ([ccb8c1d](https://github.com/open-feature/open-feature-operator/commit/ccb8c1d6e12aa36e33239fd96bebbc57fc4ea3bc))
* Revert "feat: update api version to v0.2.38" ([#562](https://github.com/open-feature/open-feature-operator/issues/562)) ([e231787](https://github.com/open-feature/open-feature-operator/commit/e2317877451163b70d0fe8fb073937d3c7586b31))
### 🧹 Chore
* clean up unused API code after moving to v1beta1 ([#543](https://github.com/open-feature/open-feature-operator/issues/543)) ([1287b07](https://github.com/open-feature/open-feature-operator/commit/1287b0785fd99cb8bfeaf9fe112aa8a0ed6f5cf9))
* **deps:** update actions/setup-node action to v3.8.1 ([#522](https://github.com/open-feature/open-feature-operator/issues/522)) ([32ddf00](https://github.com/open-feature/open-feature-operator/commit/32ddf002e6c20732d990283946ec124304827bd3))
* fix file source documentation ([#556](https://github.com/open-feature/open-feature-operator/issues/556)) ([318c52d](https://github.com/open-feature/open-feature-operator/commit/318c52d2ba38dbfee6deb3f06d3392dc14d80a6c))
* ignore component for release tag and make release dependable ([#564](https://github.com/open-feature/open-feature-operator/issues/564)) ([5ac4be3](https://github.com/open-feature/open-feature-operator/commit/5ac4be3a24f73f1b66346840a3084f1ff5030627))
* refactor code to decrease complexity ([#554](https://github.com/open-feature/open-feature-operator/issues/554)) ([17a547f](https://github.com/open-feature/open-feature-operator/commit/17a547f88595cb6c177ca93e1a8b4ad49f3c1a5f))
* release 0.4.0 ([#563](https://github.com/open-feature/open-feature-operator/issues/563)) ([e32a872](https://github.com/open-feature/open-feature-operator/commit/e32a8724c9a0bbcb5226b16cd36d065ee358cd2d))
* release apis 0.2.37 ([#544](https://github.com/open-feature/open-feature-operator/issues/544)) ([854e72d](https://github.com/open-feature/open-feature-operator/commit/854e72d964fce51082220a60fc8a7319676e49c3))
* release apis 0.2.38 ([#548](https://github.com/open-feature/open-feature-operator/issues/548)) ([c6165d4](https://github.com/open-feature/open-feature-operator/commit/c6165d426b5be2af89e03695d24fe0b802fb1fe2))
* release apis 0.2.38 ([#558](https://github.com/open-feature/open-feature-operator/issues/558)) ([4ecbc9b](https://github.com/open-feature/open-feature-operator/commit/4ecbc9b8eeac4e1e86c0f4e11ffedf3dbc376f9a))
* release apis 0.2.38 ([#560](https://github.com/open-feature/open-feature-operator/issues/560)) ([069e275](https://github.com/open-feature/open-feature-operator/commit/069e2754210d1a71bc5b70c0d4e6e193f62a7bcb))
* release operator 0.3.0 ([#545](https://github.com/open-feature/open-feature-operator/issues/545)) ([002f2dd](https://github.com/open-feature/open-feature-operator/commit/002f2ddec77a2caf919280fb9bfe74ab092c27a5))
* revert recent release ([#559](https://github.com/open-feature/open-feature-operator/issues/559)) ([f7c79e4](https://github.com/open-feature/open-feature-operator/commit/f7c79e4c6f5a5dee05d7db1796bfb9891dbd53a0))
* use apis tag instead of local replace ([#546](https://github.com/open-feature/open-feature-operator/issues/546)) ([1856918](https://github.com/open-feature/open-feature-operator/commit/18569182c1f2eca3e29e9428a64239ac16ea3c08))
* use github-action for golangci-lint workflow ([#538](https://github.com/open-feature/open-feature-operator/issues/538)) ([a97d336](https://github.com/open-feature/open-feature-operator/commit/a97d336468d5a9b50662f4979784c8388ec10ec1))
### 📚 Documentation
* use v1beta1 API version ([#553](https://github.com/open-feature/open-feature-operator/issues/553)) ([ccc0471](https://github.com/open-feature/open-feature-operator/commit/ccc0471c15cb42a338cd4c1a69b0b1f7c7828837))
## [0.4.0](https://github.com/open-feature/open-feature-operator/compare/v0.3.0...v0.4.0) (2023-11-29)
### ⚠ BREAKING CHANGES
* use v1beta1 in operator logic ([#539](https://github.com/open-feature/open-feature-operator/issues/539))
### ✨ New Features
* Introduce v1beta1 API version ([#535](https://github.com/open-feature/open-feature-operator/issues/535)) ([3acd492](https://github.com/open-feature/open-feature-operator/commit/3acd49289a40e8f07fd20aad46185ac42ceb1b7a))
* prepare apis for v1beta1 controllers onboarding ([#549](https://github.com/open-feature/open-feature-operator/issues/549)) ([e3c8b42](https://github.com/open-feature/open-feature-operator/commit/e3c8b4290be99d78b88ffef686531a38b97e61be))
* release APIs and Operator independently ([#541](https://github.com/open-feature/open-feature-operator/issues/541)) ([7b1af42](https://github.com/open-feature/open-feature-operator/commit/7b1af42ac41e63ccbb1820b31f579ffea679cff6))
* restricting sidecar image and tag setup ([#550](https://github.com/open-feature/open-feature-operator/issues/550)) ([233be79](https://github.com/open-feature/open-feature-operator/commit/233be79b56ccca32a1cb041bce53a9848f032a60))
* update api version to v0.2.38 ([#561](https://github.com/open-feature/open-feature-operator/issues/561)) ([d1f2477](https://github.com/open-feature/open-feature-operator/commit/d1f247727c5b6f4cb5154e94f1090aee0a442346))
* use v1beta1 in operator logic ([#539](https://github.com/open-feature/open-feature-operator/issues/539)) ([d234410](https://github.com/open-feature/open-feature-operator/commit/d234410a809760ba1c8592f95be56891e0cae855))
### 🐛 Bug Fixes
* Revert "chore: release apis 0.2.38" ([#557](https://github.com/open-feature/open-feature-operator/issues/557)) ([ccb8c1d](https://github.com/open-feature/open-feature-operator/commit/ccb8c1d6e12aa36e33239fd96bebbc57fc4ea3bc))
* Revert "feat: update api version to v0.2.38" ([#562](https://github.com/open-feature/open-feature-operator/issues/562)) ([e231787](https://github.com/open-feature/open-feature-operator/commit/e2317877451163b70d0fe8fb073937d3c7586b31))
### 🧹 Chore
* clean up unused API code after moving to v1beta1 ([#543](https://github.com/open-feature/open-feature-operator/issues/543)) ([1287b07](https://github.com/open-feature/open-feature-operator/commit/1287b0785fd99cb8bfeaf9fe112aa8a0ed6f5cf9))
* **deps:** update actions/setup-node action to v3.8.1 ([#522](https://github.com/open-feature/open-feature-operator/issues/522)) ([32ddf00](https://github.com/open-feature/open-feature-operator/commit/32ddf002e6c20732d990283946ec124304827bd3))
* fix file source documentation ([#556](https://github.com/open-feature/open-feature-operator/issues/556)) ([318c52d](https://github.com/open-feature/open-feature-operator/commit/318c52d2ba38dbfee6deb3f06d3392dc14d80a6c))
* ignore component for release tag and make release dependable ([#564](https://github.com/open-feature/open-feature-operator/issues/564)) ([5ac4be3](https://github.com/open-feature/open-feature-operator/commit/5ac4be3a24f73f1b66346840a3084f1ff5030627))
* refactor code to decrease complexity ([#554](https://github.com/open-feature/open-feature-operator/issues/554)) ([17a547f](https://github.com/open-feature/open-feature-operator/commit/17a547f88595cb6c177ca93e1a8b4ad49f3c1a5f))
* release apis 0.2.37 ([#544](https://github.com/open-feature/open-feature-operator/issues/544)) ([854e72d](https://github.com/open-feature/open-feature-operator/commit/854e72d964fce51082220a60fc8a7319676e49c3))
* release apis 0.2.38 ([#548](https://github.com/open-feature/open-feature-operator/issues/548)) ([c6165d4](https://github.com/open-feature/open-feature-operator/commit/c6165d426b5be2af89e03695d24fe0b802fb1fe2))
* release apis 0.2.38 ([#558](https://github.com/open-feature/open-feature-operator/issues/558)) ([4ecbc9b](https://github.com/open-feature/open-feature-operator/commit/4ecbc9b8eeac4e1e86c0f4e11ffedf3dbc376f9a))
* release apis 0.2.38 ([#560](https://github.com/open-feature/open-feature-operator/issues/560)) ([069e275](https://github.com/open-feature/open-feature-operator/commit/069e2754210d1a71bc5b70c0d4e6e193f62a7bcb))
* release operator 0.3.0 ([#545](https://github.com/open-feature/open-feature-operator/issues/545)) ([002f2dd](https://github.com/open-feature/open-feature-operator/commit/002f2ddec77a2caf919280fb9bfe74ab092c27a5))
* revert recent release ([#559](https://github.com/open-feature/open-feature-operator/issues/559)) ([f7c79e4](https://github.com/open-feature/open-feature-operator/commit/f7c79e4c6f5a5dee05d7db1796bfb9891dbd53a0))
* use apis tag instead of local replace ([#546](https://github.com/open-feature/open-feature-operator/issues/546)) ([1856918](https://github.com/open-feature/open-feature-operator/commit/18569182c1f2eca3e29e9428a64239ac16ea3c08))
* use github-action for golangci-lint workflow ([#538](https://github.com/open-feature/open-feature-operator/issues/538)) ([a97d336](https://github.com/open-feature/open-feature-operator/commit/a97d336468d5a9b50662f4979784c8388ec10ec1))
### 📚 Documentation
* use v1beta1 API version ([#553](https://github.com/open-feature/open-feature-operator/issues/553)) ([ccc0471](https://github.com/open-feature/open-feature-operator/commit/ccc0471c15cb42a338cd4c1a69b0b1f7c7828837))
## [0.3.0](https://github.com/open-feature/open-feature-operator/compare/operator-v0.2.36...operator/v0.3.0) (2023-11-29)
### ⚠ BREAKING CHANGES
* use v1beta1 in operator logic ([#539](https://github.com/open-feature/open-feature-operator/issues/539))
### ✨ New Features
* Introduce v1beta1 API version ([#535](https://github.com/open-feature/open-feature-operator/issues/535)) ([3acd492](https://github.com/open-feature/open-feature-operator/commit/3acd49289a40e8f07fd20aad46185ac42ceb1b7a))
* prepare apis for v1beta1 controllers onboarding ([#549](https://github.com/open-feature/open-feature-operator/issues/549)) ([e3c8b42](https://github.com/open-feature/open-feature-operator/commit/e3c8b4290be99d78b88ffef686531a38b97e61be))
* release APIs and Operator independently ([#541](https://github.com/open-feature/open-feature-operator/issues/541)) ([7b1af42](https://github.com/open-feature/open-feature-operator/commit/7b1af42ac41e63ccbb1820b31f579ffea679cff6))
* restricting sidecar image and tag setup ([#550](https://github.com/open-feature/open-feature-operator/issues/550)) ([233be79](https://github.com/open-feature/open-feature-operator/commit/233be79b56ccca32a1cb041bce53a9848f032a60))
* update api version to v0.2.38 ([#561](https://github.com/open-feature/open-feature-operator/issues/561)) ([d1f2477](https://github.com/open-feature/open-feature-operator/commit/d1f247727c5b6f4cb5154e94f1090aee0a442346))
* use v1beta1 in operator logic ([#539](https://github.com/open-feature/open-feature-operator/issues/539)) ([d234410](https://github.com/open-feature/open-feature-operator/commit/d234410a809760ba1c8592f95be56891e0cae855))
### 🐛 Bug Fixes
* Revert "chore: release apis 0.2.38" ([#557](https://github.com/open-feature/open-feature-operator/issues/557)) ([ccb8c1d](https://github.com/open-feature/open-feature-operator/commit/ccb8c1d6e12aa36e33239fd96bebbc57fc4ea3bc))
### 🧹 Chore
* clean up unused API code after moving to v1beta1 ([#543](https://github.com/open-feature/open-feature-operator/issues/543)) ([1287b07](https://github.com/open-feature/open-feature-operator/commit/1287b0785fd99cb8bfeaf9fe112aa8a0ed6f5cf9))
* **deps:** update actions/setup-node action to v3.8.1 ([#522](https://github.com/open-feature/open-feature-operator/issues/522)) ([32ddf00](https://github.com/open-feature/open-feature-operator/commit/32ddf002e6c20732d990283946ec124304827bd3))
* fix file source documentation ([#556](https://github.com/open-feature/open-feature-operator/issues/556)) ([318c52d](https://github.com/open-feature/open-feature-operator/commit/318c52d2ba38dbfee6deb3f06d3392dc14d80a6c))
* refactor code to decrease complexity ([#554](https://github.com/open-feature/open-feature-operator/issues/554)) ([17a547f](https://github.com/open-feature/open-feature-operator/commit/17a547f88595cb6c177ca93e1a8b4ad49f3c1a5f))
* release apis 0.2.37 ([#544](https://github.com/open-feature/open-feature-operator/issues/544)) ([854e72d](https://github.com/open-feature/open-feature-operator/commit/854e72d964fce51082220a60fc8a7319676e49c3))
* release apis 0.2.38 ([#548](https://github.com/open-feature/open-feature-operator/issues/548)) ([c6165d4](https://github.com/open-feature/open-feature-operator/commit/c6165d426b5be2af89e03695d24fe0b802fb1fe2))
* release apis 0.2.38 ([#558](https://github.com/open-feature/open-feature-operator/issues/558)) ([4ecbc9b](https://github.com/open-feature/open-feature-operator/commit/4ecbc9b8eeac4e1e86c0f4e11ffedf3dbc376f9a))
* release apis 0.2.38 ([#560](https://github.com/open-feature/open-feature-operator/issues/560)) ([069e275](https://github.com/open-feature/open-feature-operator/commit/069e2754210d1a71bc5b70c0d4e6e193f62a7bcb))
* revert recent release ([#559](https://github.com/open-feature/open-feature-operator/issues/559)) ([f7c79e4](https://github.com/open-feature/open-feature-operator/commit/f7c79e4c6f5a5dee05d7db1796bfb9891dbd53a0))
* use apis tag instead of local replace ([#546](https://github.com/open-feature/open-feature-operator/issues/546)) ([1856918](https://github.com/open-feature/open-feature-operator/commit/18569182c1f2eca3e29e9428a64239ac16ea3c08))
* use github-action for golangci-lint workflow ([#538](https://github.com/open-feature/open-feature-operator/issues/538)) ([a97d336](https://github.com/open-feature/open-feature-operator/commit/a97d336468d5a9b50662f4979784c8388ec10ec1))
### 📚 Documentation
* use v1beta1 API version ([#553](https://github.com/open-feature/open-feature-operator/issues/553)) ([ccc0471](https://github.com/open-feature/open-feature-operator/commit/ccc0471c15cb42a338cd4c1a69b0b1f7c7828837))
## [0.2.36](https://github.com/open-feature/open-feature-operator/compare/v0.2.35...v0.2.36) (2023-08-07)
### ✨ New Features
* add flagd sidecar resources attribute ([#514](https://github.com/open-feature/open-feature-operator/issues/514)) ([56ad0bd](https://github.com/open-feature/open-feature-operator/commit/56ad0bdc3a04457c35d906085e74b39e56970f82))
* add otel collector uri flag ([#513](https://github.com/open-feature/open-feature-operator/issues/513)) ([31d8d5a](https://github.com/open-feature/open-feature-operator/commit/31d8d5a4f9f1132d3b1b517c3acb76c2cb42e0c7))
### 🧹 Chore
* **deps:** update actions/setup-node action to v3.7.0 ([#504](https://github.com/open-feature/open-feature-operator/issues/504)) ([2f78b83](https://github.com/open-feature/open-feature-operator/commit/2f78b836de144234ef222af28069a543f1850eee))
* **deps:** update curlimages/curl docker tag to v8.2.1 ([#505](https://github.com/open-feature/open-feature-operator/issues/505)) ([ae1be55](https://github.com/open-feature/open-feature-operator/commit/ae1be55091086bc0791aaea8a3eed88dd47f5390))
* **deps:** update dependency bitnami-labs/readme-generator-for-helm to v2.5.1 ([#506](https://github.com/open-feature/open-feature-operator/issues/506)) ([54d59db](https://github.com/open-feature/open-feature-operator/commit/54d59db82ce834145cb1d21cdb6595920ad1a0d7))
* **deps:** update docker/login-action digest to a979406 ([#493](https://github.com/open-feature/open-feature-operator/issues/493)) ([22a1e55](https://github.com/open-feature/open-feature-operator/commit/22a1e557adee524006a4eef488a9e6c684a24464))
* **deps:** update helm/kind-action action to v1.8.0 ([#507](https://github.com/open-feature/open-feature-operator/issues/507)) ([e740068](https://github.com/open-feature/open-feature-operator/commit/e74006872ebbc6595332a3722657f64e34ef1f29))
* **deps:** update open-feature/flagd ([#516](https://github.com/open-feature/open-feature-operator/issues/516)) ([74dd65c](https://github.com/open-feature/open-feature-operator/commit/74dd65cd8fa3e45f6935c7bc9394f2341e593cd3))
* update K8s deps and fix api changes ([#518](https://github.com/open-feature/open-feature-operator/issues/518)) ([644144f](https://github.com/open-feature/open-feature-operator/commit/644144ffabfc4b7d527abf030223cef202c22bfe))
## [0.2.35](https://github.com/open-feature/open-feature-operator/compare/v0.2.34...v0.2.35) (2023-08-01)
### 🐛 Bug Fixes
* **deps:** update module github.com/stretchr/testify to v1.8.3 ([#488](https://github.com/open-feature/open-feature-operator/issues/488)) ([426be04](https://github.com/open-feature/open-feature-operator/commit/426be041d0530b8c3a77ba8176ec9e7e280dc162))
* **deps:** update module github.com/stretchr/testify to v1.8.4 ([#490](https://github.com/open-feature/open-feature-operator/issues/490)) ([660da11](https://github.com/open-feature/open-feature-operator/commit/660da11eccb6d6bf6d047d4bdb23225df6610da5))
* remove 'grpc://' prefix from proxy sync address ([#479](https://github.com/open-feature/open-feature-operator/issues/479)) ([50151ff](https://github.com/open-feature/open-feature-operator/commit/50151ffcfd239764da19e76cf657cd511ec882b0))
* use admission webhook namespace if pod namespace is empty ([#503](https://github.com/open-feature/open-feature-operator/issues/503)) ([ffd3e0a](https://github.com/open-feature/open-feature-operator/commit/ffd3e0a8ca1dbc1dbdbe81e36dec0921bd386dc9))
### 🧹 Chore
* adapt ServiceAccount only in case of K8s Provider ([#498](https://github.com/open-feature/open-feature-operator/issues/498)) ([786d511](https://github.com/open-feature/open-feature-operator/commit/786d51160292fcea6f1085891824091a4acb4fcb))
* adding troubleshooting guide ([#501](https://github.com/open-feature/open-feature-operator/issues/501)) ([0befb8f](https://github.com/open-feature/open-feature-operator/commit/0befb8fadbcb4f1925c29faac1e741b77c6ce6a7))
* attempt to improve documentation ([#496](https://github.com/open-feature/open-feature-operator/issues/496)) ([603e74e](https://github.com/open-feature/open-feature-operator/commit/603e74e62bf6d0e248130ac3eeb69e6c574134d1))
* **deps:** update curlimages/curl docker tag to v7.88.1 ([#459](https://github.com/open-feature/open-feature-operator/issues/459)) ([ea98e1e](https://github.com/open-feature/open-feature-operator/commit/ea98e1e77ac616acc4aebf1ea042fc812486ece7))
* **deps:** update curlimages/curl docker tag to v8 ([#461](https://github.com/open-feature/open-feature-operator/issues/461)) ([1271eab](https://github.com/open-feature/open-feature-operator/commit/1271eab2eb4ad6aaab226116cd317345c02f55ac))
* **deps:** update curlimages/curl docker tag to v8.1.2 ([#487](https://github.com/open-feature/open-feature-operator/issues/487)) ([b9720bb](https://github.com/open-feature/open-feature-operator/commit/b9720bb15737786fc1d207d104f2a42b2ec38d6e))
* **deps:** update docker/login-action digest to 40891eb ([#473](https://github.com/open-feature/open-feature-operator/issues/473)) ([630518a](https://github.com/open-feature/open-feature-operator/commit/630518a06b9439753c9a671271b9045d680083fd))
* **deps:** update docker/metadata-action digest to 35e9aff ([#494](https://github.com/open-feature/open-feature-operator/issues/494)) ([27a7efd](https://github.com/open-feature/open-feature-operator/commit/27a7efdc804a4d17531f8505f036978c24b5e2d1))
* **deps:** update docker/metadata-action digest to c4ee3ad ([#471](https://github.com/open-feature/open-feature-operator/issues/471)) ([5f3d98a](https://github.com/open-feature/open-feature-operator/commit/5f3d98a21484a6011a8dde20c9a8018c735cdb63))
* **deps:** update gcr.io/kubebuilder/kube-rbac-proxy docker tag to v0.14.1 ([#477](https://github.com/open-feature/open-feature-operator/issues/477)) ([8183725](https://github.com/open-feature/open-feature-operator/commit/818372531414cdd242b11016a177bc48635c7b28))
* **deps:** update helm/kind-action action to v1.7.0 ([#486](https://github.com/open-feature/open-feature-operator/issues/486)) ([09dcbc1](https://github.com/open-feature/open-feature-operator/commit/09dcbc1b181ae67f7b5e524fad0d2a55f3ded02d))
* **deps:** update module golang.org/x/net to v0.12.0 ([#484](https://github.com/open-feature/open-feature-operator/issues/484)) ([5af75bb](https://github.com/open-feature/open-feature-operator/commit/5af75bb6f4daf760d7869b24183d7b7bc4d2ee96))
* **deps:** update open-feature/flagd ([#480](https://github.com/open-feature/open-feature-operator/issues/480)) ([cfeddc8](https://github.com/open-feature/open-feature-operator/commit/cfeddc89cb8d83019246eb288b4ad4663a3c6cad))
* **deps:** update open-feature/flagd ([#499](https://github.com/open-feature/open-feature-operator/issues/499)) ([83fbb00](https://github.com/open-feature/open-feature-operator/commit/83fbb007ff1fb55c6da299ddfb5f4c0973a17ef1))
* extract flagd container injection into its own component ([#474](https://github.com/open-feature/open-feature-operator/issues/474)) ([9ed8e59](https://github.com/open-feature/open-feature-operator/commit/9ed8e598f8612f5f0935dbd115cd7a8053aa1210))
* generalize renovate configuration ([#495](https://github.com/open-feature/open-feature-operator/issues/495)) ([1ec3183](https://github.com/open-feature/open-feature-operator/commit/1ec3183f750ad929136b76131ff4711effefb398))
### 📚 Documentation
* add advanced flagd links ([#492](https://github.com/open-feature/open-feature-operator/issues/492)) ([eb44c61](https://github.com/open-feature/open-feature-operator/commit/eb44c6110333c0e0a8f39dc32c29245ab40b6bd2))
* add instruction for using OFO and GitOps ([#497](https://github.com/open-feature/open-feature-operator/issues/497)) ([244a625](https://github.com/open-feature/open-feature-operator/commit/244a62593445f5c057e1f098112ca9840cdf8449))
* Doc fixes ([#469](https://github.com/open-feature/open-feature-operator/issues/469)) ([5a7918a](https://github.com/open-feature/open-feature-operator/commit/5a7918a94615621b6c6430e7ddec28c3d39a45e1))
* replace `make deploy-demo` command with a link to the `cloud-native-demo` repo ([#476](https://github.com/open-feature/open-feature-operator/issues/476)) ([fff12a8](https://github.com/open-feature/open-feature-operator/commit/fff12a8dca900478c8f58762ce00ebaf23958dc6))
* update crd version in getting started guide ([#485](https://github.com/open-feature/open-feature-operator/issues/485)) ([eb3b950](https://github.com/open-feature/open-feature-operator/commit/eb3b9501cbfb0f5c2c70337dfc5e499a3b4d755f))
## [0.2.34](https://github.com/open-feature/open-feature-operator/compare/v0.2.33...v0.2.34) (2023-04-13)
### 🧹 Chore
* **deps:** update open-feature/flagd ([#466](https://github.com/open-feature/open-feature-operator/issues/466)) ([3b8d156](https://github.com/open-feature/open-feature-operator/commit/3b8d1564af5fa2991f3e26a0cb8fbf6ff722a9b1))
## [0.2.33](https://github.com/open-feature/open-feature-operator/compare/v0.2.32...v0.2.33) (2023-04-12)
### 🐛 Bug Fixes
* removed old prefix from flagd-proxy provider config ([#463](https://github.com/open-feature/open-feature-operator/issues/463)) ([39a99c6](https://github.com/open-feature/open-feature-operator/commit/39a99c622bb0a7a0fca63d07cc546b2a86f952a5))
## [0.2.32](https://github.com/open-feature/open-feature-operator/compare/v0.2.31...v0.2.32) (2023-04-12)
### 📚 Documentation
* add killercoda demo link ([#413](https://github.com/open-feature/open-feature-operator/issues/413)) ([bbeeea2](https://github.com/open-feature/open-feature-operator/commit/bbeeea27feb3bca805a8be504c6ad447a580582d))
### 🐛 Bug Fixes
* **deps:** update kubernetes packages to v0.26.3 ([#273](https://github.com/open-feature/open-feature-operator/issues/273)) ([abe56e1](https://github.com/open-feature/open-feature-operator/commit/abe56e14305309d4a4c776f4dfa3c8110cd16d23))
* **deps:** update module github.com/go-logr/logr to v1.2.4 ([#428](https://github.com/open-feature/open-feature-operator/issues/428)) ([8d07dab](https://github.com/open-feature/open-feature-operator/commit/8d07dab7eec3f467c84f09512bbf4c4cb066e35f))
* **deps:** update module github.com/onsi/gomega to v1.27.5 ([#357](https://github.com/open-feature/open-feature-operator/issues/357)) ([8624958](https://github.com/open-feature/open-feature-operator/commit/86249582d4bea32f9942c3940590ef399648e6e9))
* **deps:** update module github.com/onsi/gomega to v1.27.6 ([#429](https://github.com/open-feature/open-feature-operator/issues/429)) ([987815c](https://github.com/open-feature/open-feature-operator/commit/987815c05e933d3bfa4020a3864e4493b3b6e80d))
* **deps:** update module github.com/stretchr/testify to v1.8.2 ([#396](https://github.com/open-feature/open-feature-operator/issues/396)) ([f24b6c4](https://github.com/open-feature/open-feature-operator/commit/f24b6c4e536f56cde412827606eacd722637da89))
* **deps:** update module sigs.k8s.io/controller-runtime to v0.14.6 ([#426](https://github.com/open-feature/open-feature-operator/issues/426)) ([0e779e8](https://github.com/open-feature/open-feature-operator/commit/0e779e8d8f53861b0c1a824701ff8668b9fb1907))
* remove unneeded OF namespace prefix from clusterrolebindings ([#453](https://github.com/open-feature/open-feature-operator/issues/453)) ([b23edef](https://github.com/open-feature/open-feature-operator/commit/b23edefc0d403e02dc2279bf275406bd988294f8))
* restrict permissions to only access specific CRB ([#436](https://github.com/open-feature/open-feature-operator/issues/436)) ([6f1f93c](https://github.com/open-feature/open-feature-operator/commit/6f1f93c98c7b8fbee534cc7db63fc396fa5b73c7))
* update flagd proxy env var prefix ([#440](https://github.com/open-feature/open-feature-operator/issues/440)) ([b451d47](https://github.com/open-feature/open-feature-operator/commit/b451d47184c37a5c218ce66a37a448f357dce11f))
### ✨ New Features
* flagd proxy resource ownership ([#442](https://github.com/open-feature/open-feature-operator/issues/442)) ([31b5f7b](https://github.com/open-feature/open-feature-operator/commit/31b5f7bdc62fde593c10797d0f177446aba5d71e))
* introduce debugLogging parameter to FlagSourceConfiguration CRD ([#434](https://github.com/open-feature/open-feature-operator/issues/434)) ([26ae125](https://github.com/open-feature/open-feature-operator/commit/26ae1257f7611ea78dc34247b2f866b0d2043525))
* kube-flagd-proxy deployment ([#412](https://github.com/open-feature/open-feature-operator/issues/412)) ([651c63c](https://github.com/open-feature/open-feature-operator/commit/651c63c5feeb00349db3233554ece2d289e9ccf2))
* migrate flagd startup argument to sources flag ([#427](https://github.com/open-feature/open-feature-operator/issues/427)) ([1c67f34](https://github.com/open-feature/open-feature-operator/commit/1c67f34dca6a6f58e09a7e8b56ce2a2523c1d260))
* **test:** substitute kuttl to bash e2e test ([#411](https://github.com/open-feature/open-feature-operator/issues/411)) ([ff199f1](https://github.com/open-feature/open-feature-operator/commit/ff199f1ae3c72d5472937eef7c2409b186bbb314))
### 🧹 Chore
* add unit tests to pod webhook ([#419](https://github.com/open-feature/open-feature-operator/issues/419)) ([4290978](https://github.com/open-feature/open-feature-operator/commit/42909784b6a3a0642f07b5c5e093f9d4c549a21c))
* attempt renovate fix ([48b6c7f](https://github.com/open-feature/open-feature-operator/commit/48b6c7fabce54270b06f53c033801be5ec100633))
* attempt versioning fix in test ([58d0145](https://github.com/open-feature/open-feature-operator/commit/58d0145f0a3ae1d67be002961faf82d8ef050015))
* **deps:** update actions/setup-go action to v4 ([#398](https://github.com/open-feature/open-feature-operator/issues/398)) ([ee9ecb9](https://github.com/open-feature/open-feature-operator/commit/ee9ecb9d693cdccbcac38a5c6c97d20a8a9c769f))
* **deps:** update dependency open-feature/flagd to v0.2.1 ([#462](https://github.com/open-feature/open-feature-operator/issues/462)) ([d2d53b7](https://github.com/open-feature/open-feature-operator/commit/d2d53b75791eef407ba0b1dd5377aff8277301ea))
* **deps:** update docker/login-action digest to 65b78e6 ([#421](https://github.com/open-feature/open-feature-operator/issues/421)) ([8d2ebe2](https://github.com/open-feature/open-feature-operator/commit/8d2ebe27193379fb54e5a39455e8db787f8eae89))
* **deps:** update docker/metadata-action digest to 3f6690a ([#432](https://github.com/open-feature/open-feature-operator/issues/432)) ([991b2bd](https://github.com/open-feature/open-feature-operator/commit/991b2bd3c320b8b576812f72a2d98ab30436f6c8))
* **deps:** update golang docker tag to v1.20.3 ([#445](https://github.com/open-feature/open-feature-operator/issues/445)) ([b8f6c5b](https://github.com/open-feature/open-feature-operator/commit/b8f6c5b9e7bfc986f2208b2d7a2f402d7210ca7a))
* **deps:** update module golang.org/x/net to v0.8.0 ([#397](https://github.com/open-feature/open-feature-operator/issues/397)) ([096c889](https://github.com/open-feature/open-feature-operator/commit/096c889c87e80b5cfef0254869dc1e096ee23ad8))
* **deps:** update module golang.org/x/net to v0.9.0 ([#451](https://github.com/open-feature/open-feature-operator/issues/451)) ([4cbe4f1](https://github.com/open-feature/open-feature-operator/commit/4cbe4f1a02517d89a53fde6ca1a5861da2691747))
* **deps:** update open-feature/flagd ([#457](https://github.com/open-feature/open-feature-operator/issues/457)) ([db9af7a](https://github.com/open-feature/open-feature-operator/commit/db9af7a02dbfcd4be10b170dab4bb5e65614221f))
* **deps:** update open-feature/flagd to v0.5.0 ([#422](https://github.com/open-feature/open-feature-operator/issues/422)) ([6846aa2](https://github.com/open-feature/open-feature-operator/commit/6846aa206a9ffb4aa9b1cff1ca7078b93ede927c))
* fix renovate config, add recommended preset ([#418](https://github.com/open-feature/open-feature-operator/issues/418)) ([78c5970](https://github.com/open-feature/open-feature-operator/commit/78c597024241158ebf2e9b07e82610766efd85de))
* improve container build layer caching ([#414](https://github.com/open-feature/open-feature-operator/issues/414)) ([3212eba](https://github.com/open-feature/open-feature-operator/commit/3212eba809744c8dc1c94d8bf558523a0fbbf326))
* increase backoffLimit for inject-flagd ([#423](https://github.com/open-feature/open-feature-operator/issues/423)) ([29d7cf0](https://github.com/open-feature/open-feature-operator/commit/29d7cf069d68ce2b81718b0297194b3ba53c3ed9))
* introduce additional unit tests for api packages ([#420](https://github.com/open-feature/open-feature-operator/issues/420)) ([5ba5bc9](https://github.com/open-feature/open-feature-operator/commit/5ba5bc97faa8bf18a07a380d685c518f6e093145))
* refactor admission webhook tests ([#409](https://github.com/open-feature/open-feature-operator/issues/409)) ([29c7c28](https://github.com/open-feature/open-feature-operator/commit/29c7c28b4a6fb76bc565e32f46d0ab74fc2e5371))
* refactor pod webhook mutator ([#410](https://github.com/open-feature/open-feature-operator/issues/410)) ([2a86b03](https://github.com/open-feature/open-feature-operator/commit/2a86b032888fef4bd3e7d93e3a5cb1cc376fcd22))
* refactored component test using fake client ([#435](https://github.com/open-feature/open-feature-operator/issues/435)) ([08a50ac](https://github.com/open-feature/open-feature-operator/commit/08a50accff516be1f8226c4f1051eef8843c9190))
* remove ignored renovate paths ([#441](https://github.com/open-feature/open-feature-operator/issues/441)) ([c1d8929](https://github.com/open-feature/open-feature-operator/commit/c1d89291d75ef0d594a071ef5055b55a404d9b73))
* reorder containers in e2e assertion ([1d895c3](https://github.com/open-feature/open-feature-operator/commit/1d895c33c32cefc9858cf2ef0f283d1ba62a4f00))
* split controllers to separate packages + cover them with unit tests ([#404](https://github.com/open-feature/open-feature-operator/issues/404)) ([6ed4cef](https://github.com/open-feature/open-feature-operator/commit/6ed4cef4a7d1ec889300459f73e930d4b6d2ba6f))
* troubleshoot renovate ([de4ac14](https://github.com/open-feature/open-feature-operator/commit/de4ac1475717201ec6a828ffc7700d3c28de4d33))
* troubleshoot renovate ([89a7b5b](https://github.com/open-feature/open-feature-operator/commit/89a7b5b9890f127a5af1d321f40b8f2a8635fcb5))
* troubleshoot renovate ([244bd3a](https://github.com/open-feature/open-feature-operator/commit/244bd3ade508c476a9783c9ee11d608e2536bb9f))
* troubleshoot renovate ([eafa670](https://github.com/open-feature/open-feature-operator/commit/eafa6702e1663a02b24b48e3b61ea6252b2a9b40))
* troubleshoot renovate ([c3d9523](https://github.com/open-feature/open-feature-operator/commit/c3d95232d0f1ca6e8c898ffffb165537462fe2e9))
* troubleshoot renovatge ([35054cb](https://github.com/open-feature/open-feature-operator/commit/35054cb6917dcacbafb9fbccb00a85493922f245))
* troubleshoot renvoate ([7ac3c90](https://github.com/open-feature/open-feature-operator/commit/7ac3c90a358baf6f0dd00bd2f7295665ebf46a59))
* update codeowners to use cloud native team ([6133060](https://github.com/open-feature/open-feature-operator/commit/613306011016a3cbb7fbc23a2273aecfd26a3bbf))
* update flagd renovate detection ([#439](https://github.com/open-feature/open-feature-operator/issues/439)) ([3d1540c](https://github.com/open-feature/open-feature-operator/commit/3d1540c67c7d43c69feb61654b7d2a3c8a72a5a1))
* update renovate config to watch the assert yaml directly ([9ef25a0](https://github.com/open-feature/open-feature-operator/commit/9ef25a0abbdeb15666679fd43d4f2c032b825722))
* use renovate to bump flagd version ([#395](https://github.com/open-feature/open-feature-operator/issues/395)) ([fd5b072](https://github.com/open-feature/open-feature-operator/commit/fd5b072214f1c3c74dfc4bc53ca1ff6c14d72ffa))
## [0.2.31](https://github.com/open-feature/open-feature-operator/compare/v0.2.30...v0.2.31) (2023-03-16)
### 📚 Documentation
* fix rendering issue with operator resource config table ([#401](https://github.com/open-feature/open-feature-operator/issues/401)) ([71ea8a6](https://github.com/open-feature/open-feature-operator/commit/71ea8a68bbb97052822552ffce3c498c3da0e52d))
### 🐛 Bug Fixes
* update flagd version ([#402](https://github.com/open-feature/open-feature-operator/issues/402)) ([dc6aa3c](https://github.com/open-feature/open-feature-operator/commit/dc6aa3c3dd9fec6c508b34608384247b63b42eeb))
## [0.2.30](https://github.com/open-feature/open-feature-operator/compare/v0.2.29...v0.2.30) (2023-03-16)
### 📚 Documentation
* add AND operator to sequential commands ([#368](https://github.com/open-feature/open-feature-operator/issues/368)) ([6f73a62](https://github.com/open-feature/open-feature-operator/commit/6f73a6214d87771f9555469fe4d60dbb6d301198))
### ✨ New Features
* enable flagd probes ([#390](https://github.com/open-feature/open-feature-operator/issues/390)) ([41efb15](https://github.com/open-feature/open-feature-operator/commit/41efb155994b3cfb768cc39e59bfc09781c57f2e))
* improve deployment pattern ([#344](https://github.com/open-feature/open-feature-operator/issues/344)) ([572ba96](https://github.com/open-feature/open-feature-operator/commit/572ba961912ada2c07eb6143925d16ab6a6a85a3))
### 🐛 Bug Fixes
* **deps:** update module sigs.k8s.io/controller-runtime to v0.14.5 ([#279](https://github.com/open-feature/open-feature-operator/issues/279)) ([8a80bff](https://github.com/open-feature/open-feature-operator/commit/8a80bff886af404e897e6a247cea2f4c88d88499))
### 🧹 Chore
* add additional sections to the release notes ([4bec5af](https://github.com/open-feature/open-feature-operator/commit/4bec5af5fc5fc589d920f0c17a1213a036b558a0))
* add artifact hub metadata ([#372](https://github.com/open-feature/open-feature-operator/issues/372)) ([c6f539f](https://github.com/open-feature/open-feature-operator/commit/c6f539f5bdd9dc18ac197eb3303d91131e863011))
* **deps:** update dependency open-feature/flagd to v0.4.0 ([#342](https://github.com/open-feature/open-feature-operator/issues/342)) ([0640f46](https://github.com/open-feature/open-feature-operator/commit/0640f469daa3c0adce920bb73e901fe83bc275e7))
* **deps:** update dependency open-feature/flagd to v0.4.1 ([#373](https://github.com/open-feature/open-feature-operator/issues/373)) ([756cf7a](https://github.com/open-feature/open-feature-operator/commit/756cf7a96c05fdfa8ffa2bf933225b84af400e37))
* **deps:** update dependency open-feature/flagd to v0.4.4 ([#400](https://github.com/open-feature/open-feature-operator/issues/400)) ([3e0a666](https://github.com/open-feature/open-feature-operator/commit/3e0a666f2824071c49250a4467d62b96a5af5ee7))
* **deps:** update docker/login-action digest to 219c305 ([#365](https://github.com/open-feature/open-feature-operator/issues/365)) ([ee84954](https://github.com/open-feature/open-feature-operator/commit/ee849546322516019ea19a205c22c4ee38ac36ed))
* **deps:** update docker/metadata-action digest to 766400c ([#267](https://github.com/open-feature/open-feature-operator/issues/267)) ([38a1464](https://github.com/open-feature/open-feature-operator/commit/38a14644e687b928e51d1350f6d57ef9d493330c))
* **deps:** update docker/metadata-action digest to 9ec57ed ([#366](https://github.com/open-feature/open-feature-operator/issues/366)) ([884d444](https://github.com/open-feature/open-feature-operator/commit/884d44422ad7bfa28a8fb88156cd66e252e2eba5))
* **deps:** update gcr.io/kubebuilder/kube-rbac-proxy docker tag to v0.14.0 ([#376](https://github.com/open-feature/open-feature-operator/issues/376)) ([708e4bc](https://github.com/open-feature/open-feature-operator/commit/708e4bc44d8493d4f0aaa7f7036c2b7ecd2efd32))
* **deps:** update ghcr.io/open-feature/flagd docker tag to v0.4.4 ([#381](https://github.com/open-feature/open-feature-operator/issues/381)) ([a253761](https://github.com/open-feature/open-feature-operator/commit/a253761af8565fdcf6e6f9ca92c740f25b4b0620))
* **deps:** update golang docker tag to v1.20.2 ([#374](https://github.com/open-feature/open-feature-operator/issues/374)) ([e2de529](https://github.com/open-feature/open-feature-operator/commit/e2de52997b44835a4a8515e9fd37c976d3539272))
* e2e test for openfeature.dev/enabled annotation set to false ([#375](https://github.com/open-feature/open-feature-operator/issues/375)) ([b03fb14](https://github.com/open-feature/open-feature-operator/commit/b03fb145e317f987727d76b98041fa783e5c2202))
* improve formatting and content ([#384](https://github.com/open-feature/open-feature-operator/issues/384)) ([c5a6a32](https://github.com/open-feature/open-feature-operator/commit/c5a6a32f0ccccc6449fc581de08c283434c1adb6))
* remove unneeded conversion webhooks + introduce unit tests for conversion functions ([#385](https://github.com/open-feature/open-feature-operator/issues/385)) ([dd34801](https://github.com/open-feature/open-feature-operator/commit/dd34801fd71ac4f1e6c0b0f39f78ddf738f5601d))
## [0.2.29](https://github.com/open-feature/open-feature-operator/compare/v0.2.28...v0.2.29) (2023-02-23)
### Features
* add log format configuration options through helm chart ([#346](https://github.com/open-feature/open-feature-operator/issues/346)) ([bcef736](https://github.com/open-feature/open-feature-operator/commit/bcef7368fc4905b351f81f5dfa10eb4c26bf8764))
* Introduced context to the readyz endpoint, added wait to test suite ([#336](https://github.com/open-feature/open-feature-operator/issues/336)) ([ed81c02](https://github.com/open-feature/open-feature-operator/commit/ed81c0284f8d759eb228d3af7030efb0b94ee280))
### Bug Fixes
* Security issues ([#348](https://github.com/open-feature/open-feature-operator/issues/348)) ([5bd0b19](https://github.com/open-feature/open-feature-operator/commit/5bd0b192a5db7f1557e1161e4bb425bbf0e31e2a))
* set defaultTag to INPUT_FLAGD_VERSION ([#332](https://github.com/open-feature/open-feature-operator/issues/332)) ([23547a1](https://github.com/open-feature/open-feature-operator/commit/23547a1e155e0cde2f085882bfd43128681466cd))
## [0.2.28](https://github.com/open-feature/open-feature-operator/compare/v0.2.27...v0.2.28) (2023-01-28)
### Bug Fixes
* mount dirs not files ([#326](https://github.com/open-feature/open-feature-operator/issues/326)) ([089ab3c](https://github.com/open-feature/open-feature-operator/commit/089ab3c48c0937e64060057e43ff07cf8fd47f67))
## [0.2.27](https://github.com/open-feature/open-feature-operator/compare/v0.2.26...v0.2.27) (2023-01-27)
### Features
* default sync provider configuration ([#320](https://github.com/open-feature/open-feature-operator/issues/320)) ([7cba7e1](https://github.com/open-feature/open-feature-operator/commit/7cba7e14c223a083f02ff8313b899583253120f3))
### Bug Fixes
* gave configmaps volume mounts a subpath to allow for multiple mounts ([#321](https://github.com/open-feature/open-feature-operator/issues/321)) ([2ec454c](https://github.com/open-feature/open-feature-operator/commit/2ec454c036149ebeaf34f81cbf4ad7895f0bb995))
* uniqueness of featureflagconfiguration file path ([#323](https://github.com/open-feature/open-feature-operator/issues/323)) ([2b10945](https://github.com/open-feature/open-feature-operator/commit/2b109452893abd053640ffbb9c79b834b78feb7b))
## [0.2.26](https://github.com/open-feature/open-feature-operator/compare/v0.2.25...v0.2.26) (2023-01-26)
### Bug Fixes
* **deps:** update module github.com/open-feature/schemas to v0.2.8 ([#269](https://github.com/open-feature/open-feature-operator/issues/269)) ([ed48060](https://github.com/open-feature/open-feature-operator/commit/ed48060b1f9e591ddadca4f9478728a823e10685))
## [0.2.25](https://github.com/open-feature/open-feature-operator/compare/v0.2.24...v0.2.25) (2023-01-25)
### Features
* Helm configuration ([#304](https://github.com/open-feature/open-feature-operator/issues/304)) ([99edfeb](https://github.com/open-feature/open-feature-operator/commit/99edfeb8c32ada435f830c6799540ebdf3b5fcdd))
### Bug Fixes
* removed duplicate config map generation, resolve permissions issue ([#305](https://github.com/open-feature/open-feature-operator/issues/305)) ([eec16af](https://github.com/open-feature/open-feature-operator/commit/eec16af28eb963a3d0f276d382e808079e663a50))
* update x/net for CVE-2022-41721 ([#301](https://github.com/open-feature/open-feature-operator/issues/301)) ([bbe9837](https://github.com/open-feature/open-feature-operator/commit/bbe983786ff74b59046b95082d79f71089fe2b67))
## [0.2.24](https://github.com/open-feature/open-feature-operator/compare/v0.2.23...v0.2.24) (2023-01-16)
### Features
* backfill flagd-kubernetes-sync cluster role binding on startup ([#295](https://github.com/open-feature/open-feature-operator/pull/295))
* decouple feature flag spec from flagd config ([#276](https://github.com/open-feature/open-feature-operator/pull/276))
### Features
* upgrade flagd to v0.3.0 ([20571e1](https://github.com/open-feature/open-feature-operator/commit/20571e1018e102ffbcf01b2518fcbf8b66a287be))
## [0.2.22](https://github.com/open-feature/open-feature-operator/compare/v0.2.21...v0.2.22) (2022-12-16)
### Bug Fixes
* **deps:** update module go.uber.org/zap to v1.24.0 ([#268](https://github.com/open-feature/open-feature-operator/issues/268)) ([b7bdde8](https://github.com/open-feature/open-feature-operator/commit/b7bdde8944446621751e6ef70e6b0f0646adee21))
* Version fix ([#284](https://github.com/open-feature/open-feature-operator/issues/284)) ([a9c6f15](https://github.com/open-feature/open-feature-operator/commit/a9c6f154589f1e00e60883c229b3ee29d7d2e9aa))
## [0.2.21](https://github.com/open-feature/open-feature-operator/compare/v0.2.20...v0.2.21) (2022-12-16)
### Features
* add ff shortname, commit httpSyncConfiguration ([11e4652](https://github.com/open-feature/open-feature-operator/commit/11e46528fcd06cdc0c8e6f46944656224cd97441))
* introduce configurable resource limits for flagd sidecar ([e4affcf](https://github.com/open-feature/open-feature-operator/commit/e4affcfb0ccf13dc0406ef1c21c2b884a836f71f))
### Bug Fixes
* **deps:** update github.com/open-feature/schemas digest to 302d0fa ([#246](https://github.com/open-feature/open-feature-operator/issues/246)) ([7d22374](https://github.com/open-feature/open-feature-operator/commit/7d22374afb7a5e2e166550544d327ec7b5b3d1bf))
* **deps:** update kubernetes packages to v0.25.4 ([75bab2d](https://github.com/open-feature/open-feature-operator/commit/75bab2d441c945d51f17f0d32195a217072c3c15))
* include release tag in helm charts publishing ([2746716](https://github.com/open-feature/open-feature-operator/commit/27467164dcd05b0220e0857bf79e42d62e7a40a9))
## [0.2.20](https://github.com/open-feature/open-feature-operator/compare/v0.2.19...v0.2.20) (2022-11-18)
### Bug Fixes
* **deps:** update module sigs.k8s.io/controller-runtime to v0.13.1 ([edeffcd](https://github.com/open-feature/open-feature-operator/commit/edeffcd3ef6fe9a8d52d0d5c414512ef8cd80629))
## [0.2.19](https://github.com/open-feature/open-feature-operator/compare/v0.2.18...v0.2.19) (2022-11-15)
### Features
* introduced v1beta1 of featureflagconfiguration CRD with conversion webhook to v1alpha1 ([a45bdef](https://github.com/open-feature/open-feature-operator/commit/a45bdef5eec87738ce731af5825daffeb69eb6cb))
* structured the featureflagconfiguration CRD ([b056c7c](https://github.com/open-feature/open-feature-operator/commit/b056c7cdd76f4653c1a728342687beaa8279e314))
## [0.2.18](https://github.com/open-feature/open-feature-operator/compare/v0.2.17...v0.2.18) (2022-11-10)

View File

@ -1,6 +1,3 @@
# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence
#
# Managed by Peribolos: https://github.com/open-feature/community/blob/main/config/open-feature/cloud-native/workgroup.yaml
#
* @open-feature/cloud-native-maintainers
* @AlexsJones @beeme1mr

View File

@ -1,48 +0,0 @@
## Guidelines
Welcome!
There are a few things to consider before contributing to open-feature-operator.
Firstly, there's [a code of conduct](https://github.com/open-feature/.github/blob/main/CODE_OF_CONDUCT.md).
TLDR: be respectful.
Any contributions are expected to include tests. These can be validated with `make unit-test` or the automated github workflow will run them on PR creation.
The go version in the `go.mod` is the currently supported version of go.
Thanks! Issues and pull requests following these guidelines are welcome.
## Development
### FeatureFlag custom resource definition versioning
Custom resource definitions support multiple versions. The kubebuilder framework exposes a system to seamlessly convert between versions (using a "hub and spoke" model) maintaining backwards compatibility. It does this by injecting conversion webhooks that call our defined convert functions. The hub version of the `FeatureFlag` custom resource definition (the version to which all other versions are converted) is `v1beta1`.
Follow [this tutorial](https://book.kubebuilder.io/multiversion-tutorial/conversion-concepts.html) to implement a new version of the custom resource definition.
### Local build
The operator can be build and deployed to your cluster by using a single command:
```
make build-deploy-operator TAG=myTag RELEASE_REGISTRY=docker.io/user1 RELEASE_NAME=myImgName
```
Which will result in building the operator image `docker.io/user1/myImgName:myTag`, uploading it to your image registry
and deploying to your cluster. Please be aware that it is using the cluster your current kube-context is pointing to.
> [!NOTE]
> All bash variables are optional, the default values are set and will result in an image `ghcr.io/openfeature/operator:latest`
### Autogenerated Documentation
Some part of the project docs may be autogenerated and require running a script.
#### Re-generating helm docs after modifying the chart
` ./.github/scripts/generate-helm-docs.sh`
#### CRDs Docs
If you modified or added crds to the project, then you should recreate the crds.md file. To do so run:
```
make generate-crdocs
```

View File

@ -1,33 +1,29 @@
# Build the manager binary
FROM --platform=$BUILDPLATFORM golang:1.23.5-alpine3.20 AS builder
FROM --platform=$BUILDPLATFORM golang:1.19-alpine AS builder
WORKDIR /workspace
ARG TARGETOS
ARG TARGETARCH
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# Copy the go source
COPY cmd/ cmd/
COPY api/ api/
COPY internal/ internal/
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
RUN go work init . ./api && go mod download
RUN go mod download
ARG TARGETOS
ARG TARGETARCH
# Copy the go source
COPY main.go main.go
COPY apis/ apis/
COPY webhooks/ webhooks/
COPY controllers/ controllers/
COPY pkg/ pkg/
# Build
# the GOARCH has not a default value to allow the binary be built according to the host where the command
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -a -o manager main.go
# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM gcr.io/distroless/static:nonroot AS production
FROM gcr.io/distroless/static:nonroot
WORKDIR /
COPY --from=builder /workspace/manager .
USER 65532:65532

155
Makefile
View File

@ -1,17 +1,12 @@
RELEASE_REGISTRY?=ghcr.io/openfeature
TAG?=latest
RELEASE_NAME?=operator
RELEASE_IMAGE?=$(RELEASE_NAME):$(TAG)
ARCH?=amd64
IMG?=$(RELEASE_REGISTRY)/$(RELEASE_IMAGE)
# Image URL to use all building/pushing image targets
IMG ?= controller:latest
# customize overlay to be used in the build, DEFAULT or HELM
KUSTOMIZE_OVERLAY ?= DEFAULT
CHART_VERSION=v0.8.7# x-release-please-version
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.26.1
WAIT_TIMEOUT_SECONDS?=60
ALL_GO_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | sort)
FLAGD_VERSION=v0.2.5
CHART_VERSION=v0.2.18# x-release-please-version
ENVTEST_K8S_VERSION = 1.23
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
@ -52,8 +47,11 @@ help: ## Display this help.
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
.PHONY: update-flagd
update-flagd:
./hack/update-flagd.sh ${FLAGD_VERSION}
.PHONY: generate
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
generate: update-flagd controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
.PHONY: fmt
@ -64,76 +62,32 @@ fmt: ## Run go fmt against code.
vet: ## Run go vet against code.
go vet ./...
.PHONY: unit-test
unit-test: manifests generate envtest fmt vet ## Run tests.
cd api && go test ./... -v -coverprofile ../cover-apis.out cover-main.out cover-pkg.out
go test ./... -v -coverprofile cover-operator.out
sed -i '/mode: set/d' "cover-operator.out"
sed -i '/mode: set/d' "cover-apis.out"
echo "mode: set" > cover.out
cat cover-operator.out cover-apis.out >> cover.out
rm cover-operator.out cover-apis.out
############
# CHAINSAW #
############
.PHONY: e2e-test-chainsaw #these tests should run on a real cluster!
e2e-test-chainsaw:
chainsaw test --test-dir ./test/e2e/chainsaw
.PHONY: e2e-test-chainsaw-local #these tests should run on a real cluster!
e2e-test-chainsaw-local:
chainsaw test --test-dir ./test/e2e/chainsaw --config ./.chainsaw-local.yaml
.PHONY: e2e-test-validate-local
e2e-test-validate-local:
docker build . -t open-feature-operator-local:validate
kind create cluster --config ./test/e2e/kind-cluster.yml --name e2e-tests
kind load docker-image open-feature-operator-local:validate --name e2e-tests
IMG=open-feature-operator-local:validate make deploy-operator
IMG=open-feature-operator-local:validate make e2e-test-chainsaw
kind delete cluster --name e2e-tests
.PHONY: test
test: manifests generate fmt vet envtest ## Run tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test ./... -coverprofile cover.out
.PHONY: lint
lint:
go install -v github.com/golangci/golangci-lint/cmd/golangci-lint@latest
${GOPATH}/bin/golangci-lint run --timeout=3m --config=./.golangci.yml -v ./... # Run linters
.PHONY: generate-crdocs
generate-crdocs: kustomize crdocs
$(KUSTOMIZE) build config/crd > tmpcrd.yaml
perl -i -pe "s/\_/\&lowbar;/gm" tmpcrd.yaml #escape _
perl -i -pe "s/\</\&lt;/gm" tmpcrd.yaml #escape <
perl -i -pe "s/\>/\&gt;/gm" tmpcrd.yaml #escape <
$(CRDOC) --resources tmpcrd.yaml --output docs/crds.md
${GOPATH}/bin/golangci-lint run --deadline=3m --timeout=3m ./... # Run linters
##@ Build
.PHONY: build
build: manifests generate fmt vet ## Build manager binary.
go build -o bin/manager cmd/main.go
build: generate fmt vet ## Build manager binary.
go build -o bin/manager main.go
.PHONY: run
run: manifests generate fmt vet ## Run a controller from your host.
go run ./cmd/main.go
go run ./main.go
.PHONY: docker-build
docker-build: clean ## Build docker image with the manager.
DOCKER_BUILDKIT=1 docker build \
-t $(IMG)-$(ARCH) \
--platform linux/$(ARCH) \
.
docker tag $(IMG)-$(ARCH) $(IMG)
docker-build: ## Build docker image with the manager.
docker buildx build --platform="linux/amd64,linux/arm64" -t ${IMG} . --push
.PHONY: docker-push
docker-push: ## Push docker image with the manager.
docker push $(IMG)
.PHONY: clean
clean:
rm -rf ./bin
docker push ${IMG}
##@ Deployment
@ -151,7 +105,7 @@ uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified
.PHONY: release-manifests
release-manifests: manifests kustomize
cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
mkdir -p config/rendered/
@if [ ${KUSTOMIZE_OVERLAY} = DEFAULT ]; then\
echo building default overlay;\
@ -159,39 +113,24 @@ release-manifests: manifests kustomize
fi
@if [ ${KUSTOMIZE_OVERLAY} = HELM ]; then\
echo building helm overlay;\
$(KUSTOMIZE) build config/overlays/helm -o chart/open-feature-operator/templates/ ;\
$(KUSTOMIZE) build config/overlays/helm > chart/templates/rendered.yaml;\
fi
.PHONY: deploy
deploy: generate kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
deploy: generate manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default | kubectl apply -f -
.PHONY: undeploy
undeploy: generate ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
$(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
.PHONY: deploy-operator
deploy-operator:
kubectl create ns 'open-feature-operator-system' --dry-run=client -o yaml | kubectl apply -f -
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.5/cert-manager.yaml
kubectl wait --for=condition=Available=True deploy --all -n 'cert-manager' --timeout=$(WAIT_TIMEOUT_SECONDS)s
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml
kubectl wait --for=condition=Available=True deploy --all -n 'cert-manager'
make deploy
kubectl wait --for=condition=Available=True deploy --all -n 'open-feature-operator-system' --timeout=$(WAIT_TIMEOUT_SECONDS)s
.PHONY: build-deploy-operator
build-deploy-operator:
make docker-build
make docker-push
make deploy-operator
deploy-demo:
kubectl apply -f https://raw.githubusercontent.com/open-feature/playground/main/config/k8s/end-to-end.yaml
kubectl wait -l app=open-feature-demo --for=condition=Available=True deploy --timeout=$(WAIT_TIMEOUT_SECONDS)s
kubectl port-forward service/open-feature-demo-service 30000:30000
delete-demo-deployment:
kubectl delete -f https://raw.githubusercontent.com/open-feature/playground/main/config/k8s/end-to-end.yaml
kubectl wait --for=condition=Available=True deploy --all -n 'open-feature-operator-system'
##@ Build Dependencies
@ -205,31 +144,23 @@ KUSTOMIZE ?= $(LOCALBIN)/kustomize
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
HELM ?= $(LOCALBIN)/HELM
ENVTEST ?= $(LOCALBIN)/setup-envtest
CRDOC ?= $(LOCALBIN)/crdoc
## Tool Versions
# renovate: datasource=github-tags depName=kubernetes-sigs/kustomize
KUSTOMIZE_VERSION ?= v5.4.1
# renovate: datasource=github-releases depName=kubernetes-sigs/controller-tools
CONTROLLER_TOOLS_VERSION ?= v0.16.5
CRDOC_VERSION ?= v0.6.2
KUSTOMIZE_VERSION ?= v4.5.7
CONTROLLER_TOOLS_VERSION ?= v0.8.0
KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
.PHONY: kustomize
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
$(KUSTOMIZE): $(LOCALBIN)
[ -e "$(KUSTOMIZE)" ] && rm -rf "$(KUSTOMIZE)" || true
test -s ${LOCALBIN}/kustomize || GOBIN=${LOCALBIN} GO111MODULE=on go install sigs.k8s.io/kustomize/kustomize/v5@$(KUSTOMIZE_VERSION)
curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN)
.PHONY: controller-gen
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
$(CONTROLLER_GEN): $(LOCALBIN)
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
.PHONY: crdocs
crdocs: $(CRDOC) ## Download crdoc locally if necessary.
$(CRDOC): $(LOCALBIN)
GOBIN=$(LOCALBIN) go install fybrik.io/crdoc@$(CRDOC_VERSION)
.PHONY: envtest
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
$(ENVTEST): $(LOCALBIN)
@ -249,27 +180,7 @@ set-helm-overlay:
${eval KUSTOMIZE_OVERLAY = HELM}
helm-package: set-helm-overlay generate release-manifests helm
mkdir -p chart/open-feature-operator/templates/crds
mv chart/open-feature-operator/templates/*customresourcedefinition* chart/open-feature-operator/templates/crds
.github/scripts/strip-kustomize-helm.sh
$(HELM) package --version $(CHART_VERSION) chart/open-feature-operator
mkdir -p charts && mv open-feature-operator-*.tgz charts
$(HELM) package --version $(CHART_VERSION) chart
mkdir -p charts && mv ofo-*.tgz charts
$(HELM) repo index --url https://open-feature.github.io/open-feature-operator/charts charts
mv charts/index.yaml index.yaml
install-mockgen:
go install github.com/golang/mock/mockgen@v1.6.0
mockgen: install-mockgen
mockgen -source=./common/flagdinjector/flagdinjector.go -destination=./common/flagdinjector/mock/flagd-injector.go -package=commonmock
mockgen -source=./controllers/core/flagd/controller.go -destination=controllers/core/flagd/mock/mock.go -package=commonmock
mockgen -source=./controllers/core/flagd/resources/interface.go -destination=controllers/core/flagd/resources/mock/mock.go -package=commonmock
workspace-init: workspace-clean
go work init
$(foreach module, $(ALL_GO_MOD_DIRS), go work use $(module);)
workspace-update:
$(foreach module, $(ALL_GO_MOD_DIRS), go work use $(module);)
workspace-clean:
rm -rf go.work

73
PROJECT
View File

@ -1,13 +1,7 @@
# Code generated by tool. DO NOT EDIT.
# This file is used to track the info used to scaffold your project
# and allow the plugins properly work.
# More info: https://book.kubebuilder.io/reference/project-config.html
domain: openfeature.dev
layout:
- go.kubebuilder.io/v4
- go.kubebuilder.io/v3
multigroup: true
plugins:
helm.kubebuilder.io/v1-alpha: {}
projectName: open-feature-operator
repo: github.com/open-feature/open-feature-operator
resources:
@ -20,69 +14,4 @@ resources:
kind: FeatureFlagConfiguration
path: github.com/open-feature/open-feature-operator/apis/core/v1alpha1
version: v1alpha1
webhooks:
conversion: true
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
domain: openfeature.dev
group: core
kind: FeatureFlagConfiguration
path: github.com/open-feature/open-feature-operator/apis/core/v1alpha2
version: v1alpha2
- api:
crdVersion: v1
namespaced: true
controller: true
domain: openfeature.dev
group: core
kind: FlagSourceConfiguration
path: github.com/open-feature/open-feature-operator/apis/core/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: openfeature.dev
group: core
kind: FlagSourceConfiguration
path: github.com/open-feature/open-feature-operator/apis/core/v1alpha3
version: v1alpha3
- api:
crdVersion: v1
namespaced: true
domain: openfeature.dev
group: core
kind: FeatureFlag
path: github.com/open-feature/open-feature-operator/apis/core/v1beta1
version: v1beta1
webhooks:
validation: true
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
domain: openfeature.dev
group: core
kind: FeatureFlagSource
path: github.com/open-feature/open-feature-operator/apis/core/v1beta1
version: v1beta1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: openfeature.dev
group: core
kind: Flagd
path: github.com/open-feature/open-feature-operator/apis/core/v1beta1
version: v1beta1
- api:
crdVersion: v1
namespaced: true
domain: openfeature.dev
group: core
kind: InProcessConfiguration
path: github.com/open-feature/open-feature-operator/apis/core/v1beta1
version: v1beta1
version: "3"

177
README.md
View File

@ -4,42 +4,175 @@
<img alt="OpenFeature Logo" src="./images/openfeature-horizontal-black.svg">
</picture>
![build](https://img.shields.io/github/actions/workflow/status/open-feature/open-feature-operator/pr-checks.yml?branch=main)
![build](https://img.shields.io/github/workflow/status/open-feature/open-feature-operator/ci)
![goversion](https://img.shields.io/github/go-mod/go-version/open-feature/open-feature-operator/main)
![version](https://img.shields.io/badge/version-pre--alpha-green)
![status](https://img.shields.io/badge/status-not--for--production-red)
[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/open-feature-operator)](https://artifacthub.io/packages/search?repo=open-feature-operator)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/6615/badge)](https://bestpractices.coreinfrastructure.org/projects/6615)
[![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)
## Get started
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.
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 and exposes gRPC and HTTP interfaces for flag evaluation.
To get started, follow the installation instructions in the [docs](./docs).
## Deploy the latest release
> [!NOTE]
> With version [v0.5.0](https://github.com/open-feature/open-feature-operator/releases/tag/v0.5.0), we have migrated
> to API version `v1beta1`. Please check the [migration guide](./docs/v1beta_migration.md) to migrate from old configurations.
_Requires [cert manager](https://cert-manager.io/docs/installation/kubernetes/) installed (see why [here](#cert-manager))_
## Demos
## Helm
- [Try the OpenFeature Operator locally on your machine](https://openfeature.dev/docs/tutorials/ofo)
- [Try the OpenFeature Operator in the Killercoda Playground (in browser)](https://killercoda.com/open-feature/scenario/openfeature-operator-demo)
```
helm repo add openfeature https://open-feature.github.io/open-feature-operator/
```
## Changelog
```
helm install ofo openfeature/ofo
```
See [CHANGELOG.md](https://github.com/open-feature/open-feature-operator/blob/main/CHANGELOG.md)
## Contributing
## Kubectl
See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to the OpenFeature project.
<!---x-release-please-start-version-->
Our community meetings are held regularly and open to everyone, as well as other community channels.
Check the [OpenFeature community page]https://openfeature.dev/community/) for the links and participation guidelines.
```
kubectl create namespace open-feature-operator-system
kubectl apply -f https://github.com/open-feature/open-feature-operator/releases/download/v0.2.18/release.yaml
```
Thanks so much to our contributors.
<!---x-release-please-end-->
<a href="https://github.com/open-feature/flagd/graphs/contributors">
<img src="https://contrib.rocks/image?repo=open-feature/open-feature-operator" />
</a>
Made with [contrib.rocks](https://contrib.rocks).
### Release contents
- `release.yaml` contains the configuration of:
- `FeatureFlagConfiguration` `CustomResourceDefinition` (custom type that holds the configured state of feature flags).
- Standard kubernetes primitives (e.g. namespace, accounts, roles, bindings, configmaps).
- Operator controller manager service.
- Operator webhook service.
- Deployment with containers kube-rbac-proxy & manager.
- `MutatingWebhookConfiguration` (configures webhooks to call the webhook service).
### How to deploy a flag consuming application
_Prerequisite: the release and certificates have been deployed as outlined above._
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)):
#### FeatureFlagConfiguration
This is a `CustomResourceDefinition` which contains the feature flags specification and a name of the spec.
#### Deployment (or Statefulset/Daemonset)
This is a kubernetes primitive for deploying an application. The metadata annotations must include `openfeature.dev/featureflagconfiguration`
with the value set as the name of the `FeatureFlagConfiguration` created in the step prior.
e.g.
```
metadata:
annotations:
openfeature.dev/featureflagconfiguration: "demo"
```
## Architecture
As per the issue [here](https://github.com/open-feature/ofep/issues/1)
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).
High level architecture is as follows:
<img src="images/arch-0.png" width="700">
### Requirements
#### Namespace
The Kubernetes resources created by OpenFeature Operator are under the `open-feature-operator-system` namespace. This means
any resources that want to communicate with the OFO system (e.g. an application calling flag evaluations) must fall under
this namespace.
#### Cert Manager
OpenFeature Operator is a server that communicates with Kubernetes components within the cluster, as such it requires a means of
authorizing requests between peers. [Cert manager](https://cert-manager.io/) handles the authorization by
adding certificates and certificate issuers as resource types in Kubernetes clusters, and simplifies the process of
obtaining, renewing and using those certificates.
## Example
When wishing to leverage feature flagging within the local pod, the following steps are required:
1. Create a new feature flag custom resource.
_See [here](config/samples/crds/custom_provider.yaml) for additional custom resource parameters_
```
apiVersion: core.openfeature.dev/v1alpha1
kind: FeatureFlagConfiguration
metadata:
name: featureflagconfiguration-sample
spec:
featureFlagSpec: |
{
"flags": {
"foo": {
"state": "ENABLED",
"variants": {
"bar": "BAR",
"baz": "BAZ"
},
"defaultVariant": "bar",
"targeting": {}
}
}
}
```
1. Reference the CR within the pod spec annotations
```
apiVersion: v1
kind: Pod
metadata:
name: nginx
annotations:
openfeature.dev: "enabled"
openfeature.dev/featureflagconfiguration: "featureflagconfiguration-sample"
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
```
3. Example usage from host container
```
root@nginx:/# curl -X POST "localhost:8013/schema.v1.Service/ResolveString" -d '{"flagKey":"foo","context":{}}' -H "Content-Type: application/json"
{"value":"BAR","reason":"DEFAULT","variant":"bar"}
```
### Running the operator locally
#### Create a local cluster with cert manager and our operator
1. Create a local cluster with MicroK8s or Kind (forward requests from your localhost:30000 to your cluster, see MicroK8s/Kind doc)
1. `IMG=ghcr.io/open-feature/open-feature-operator:main make deploy-operator`
#### Run the example
1. Apply the end-to-end example: `kubectl apply -f config/samples/end-to-end.yaml`
1. Visit `http://localhost:30000/`
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!
1. Visit `http://localhost:30000/` and see the change!
## Testing
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.
This provides means of asserting that the Kubernetes components reach the desired state without the overhead of using an actual cluster, keeping
test runtime and resource consumption down.
## Releases
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.

View File

@ -1,125 +0,0 @@
# Changelog
## [0.2.45](https://github.com/open-feature/open-feature-operator/compare/apis/v0.2.44...apis/v0.2.45) (2025-01-13)
### ✨ New Features
* add gateway api support ([#725](https://github.com/open-feature/open-feature-operator/issues/725)) ([b393a26](https://github.com/open-feature/open-feature-operator/commit/b393a2669c05d58afe453867401f8d697464b145))
### 🐛 Bug Fixes
* flagd environment variables missing prefix ([#730](https://github.com/open-feature/open-feature-operator/issues/730)) ([0aa61ec](https://github.com/open-feature/open-feature-operator/commit/0aa61ec1419ec1d99f3c875dd6526ec8ca8e6014))
## [0.2.44](https://github.com/open-feature/open-feature-operator/compare/apis/v0.2.43...apis/v0.2.44) (2024-07-23)
### 🐛 Bug Fixes
* **deps:** update module github.com/stretchr/testify to v1.9.0 ([#671](https://github.com/open-feature/open-feature-operator/issues/671)) ([1d2713d](https://github.com/open-feature/open-feature-operator/commit/1d2713dad6381e56aa3b552c33e1cb3513574a6e))
### 🧹 Chore
* **deps:** update open-feature/flagd ([#689](https://github.com/open-feature/open-feature-operator/issues/689)) ([0d331a9](https://github.com/open-feature/open-feature-operator/commit/0d331a9bc5db752cb3aa49f7ce5afc0830f115fe))
## [0.2.43](https://github.com/open-feature/open-feature-operator/compare/apis/v0.2.42...apis/v0.2.43) (2024-06-06)
### 🐛 Bug Fixes
* flagd path defaults ([#658](https://github.com/open-feature/open-feature-operator/issues/658)) ([aef1010](https://github.com/open-feature/open-feature-operator/commit/aef1010dff162e8d232942e642c68e3e9ba3f35f))
### 🧹 Chore
* **deps:** update open-feature/flagd ([#670](https://github.com/open-feature/open-feature-operator/issues/670)) ([1174a1b](https://github.com/open-feature/open-feature-operator/commit/1174a1b277c1f335b5f73ee76e0c111fd16ace4b))
### 📚 Documentation
* require hosts, mention host-less rules ([#659](https://github.com/open-feature/open-feature-operator/issues/659)) ([dcab14a](https://github.com/open-feature/open-feature-operator/commit/dcab14a2c55ada5f1df34b3ed164c8b334877b68))
## [0.2.42](https://github.com/open-feature/open-feature-operator/compare/apis/v0.2.41...apis/v0.2.42) (2024-05-29)
### 🐛 Bug Fixes
* include parameters with default values to envVars ([#648](https://github.com/open-feature/open-feature-operator/issues/648)) ([4f0477c](https://github.com/open-feature/open-feature-operator/commit/4f0477c8e0da571a1cf11e4ac8b57dba3d98efe2))
### 🧹 Chore
* bump k8s libs ([#644](https://github.com/open-feature/open-feature-operator/issues/644)) ([a18d272](https://github.com/open-feature/open-feature-operator/commit/a18d27270eeb9eb7aaccd9e6fb368a55b94f98ba))
## [0.2.41](https://github.com/open-feature/open-feature-operator/compare/apis/v0.2.40...apis/v0.2.41) (2024-05-28)
### ✨ New Features
* add `flagd` CRD with ingress support ([#633](https://github.com/open-feature/open-feature-operator/issues/633)) ([b0b99a7](https://github.com/open-feature/open-feature-operator/commit/b0b99a7d101fb7e281394acd0d8b22a16546708f))
* introduce new CRD for in-process evaluation ([#632](https://github.com/open-feature/open-feature-operator/issues/632)) ([51db913](https://github.com/open-feature/open-feature-operator/commit/51db913bc708cc60f00e430e372b68c28c7cbda2))
* introduce validating webhook for FeatureFlag CR ([#622](https://github.com/open-feature/open-feature-operator/issues/622)) ([c4831a3](https://github.com/open-feature/open-feature-operator/commit/c4831a3cdc00aec36f3fe9bec9abceafba1f8aa8))
### 🧹 Chore
* bump operator builder tools versions ([#626](https://github.com/open-feature/open-feature-operator/issues/626)) ([918a697](https://github.com/open-feature/open-feature-operator/commit/918a69732fabb34af2f83ca8f650e433e87d0212))
## [0.2.40](https://github.com/open-feature/open-feature-operator/compare/apis/v0.2.39...apis/v0.2.40) (2024-04-22)
### ✨ New Features
* added interval to the openfeature api source ([#619](https://github.com/open-feature/open-feature-operator/issues/619)) ([18ac733](https://github.com/open-feature/open-feature-operator/commit/18ac7331916f5fa19b2f0c8d2fe34f7ba9f1e595))
## [0.2.39](https://github.com/open-feature/open-feature-operator/compare/apis/v0.2.38...apis/v0.2.39) (2024-02-21)
### 🐛 Bug Fixes
* flagd mgmt port setting ignored ([#588](https://github.com/open-feature/open-feature-operator/issues/588)) ([1444328](https://github.com/open-feature/open-feature-operator/commit/1444328691450ee3967d862eebf3a293b4f9fe7c))
### 🧹 Chore
* bump go to 1.21 ([#604](https://github.com/open-feature/open-feature-operator/issues/604)) ([73d6319](https://github.com/open-feature/open-feature-operator/commit/73d6319820220fc114cdfc7d72f8c2327a35ec37))
## [0.2.38](https://github.com/open-feature/open-feature-operator/compare/apis/v0.2.37...apis/v0.2.38) (2023-11-29)
### ✨ New Features
* introduce v1beta1/common package ([#547](https://github.com/open-feature/open-feature-operator/issues/547)) ([cdc4af4](https://github.com/open-feature/open-feature-operator/commit/cdc4af495f370da7165fd67ad9ef54ccf74be3bf))
* prepare apis for v1beta1 controllers onboarding ([#549](https://github.com/open-feature/open-feature-operator/issues/549)) ([e3c8b42](https://github.com/open-feature/open-feature-operator/commit/e3c8b4290be99d78b88ffef686531a38b97e61be))
### 🐛 Bug Fixes
* Revert "chore: release apis 0.2.38" ([#557](https://github.com/open-feature/open-feature-operator/issues/557)) ([ccb8c1d](https://github.com/open-feature/open-feature-operator/commit/ccb8c1d6e12aa36e33239fd96bebbc57fc4ea3bc))
### 🧹 Chore
* adapt API for sidecar image and tag restriction ([#552](https://github.com/open-feature/open-feature-operator/issues/552)) ([726a7f7](https://github.com/open-feature/open-feature-operator/commit/726a7f7149067d2e2696f746a236151fbb67808c))
* adapt shortcuts for custom resources ([#551](https://github.com/open-feature/open-feature-operator/issues/551)) ([61c77c0](https://github.com/open-feature/open-feature-operator/commit/61c77c0c137ec624892c9738ee45828a137f6823))
* clean up unused API code after moving to v1beta1 ([#543](https://github.com/open-feature/open-feature-operator/issues/543)) ([1287b07](https://github.com/open-feature/open-feature-operator/commit/1287b0785fd99cb8bfeaf9fe112aa8a0ed6f5cf9))
* fix file source documentation ([#556](https://github.com/open-feature/open-feature-operator/issues/556)) ([318c52d](https://github.com/open-feature/open-feature-operator/commit/318c52d2ba38dbfee6deb3f06d3392dc14d80a6c))
* refactor code to decrease complexity ([#554](https://github.com/open-feature/open-feature-operator/issues/554)) ([17a547f](https://github.com/open-feature/open-feature-operator/commit/17a547f88595cb6c177ca93e1a8b4ad49f3c1a5f))
* release apis 0.2.38 ([#548](https://github.com/open-feature/open-feature-operator/issues/548)) ([c6165d4](https://github.com/open-feature/open-feature-operator/commit/c6165d426b5be2af89e03695d24fe0b802fb1fe2))
* release apis 0.2.38 ([#558](https://github.com/open-feature/open-feature-operator/issues/558)) ([4ecbc9b](https://github.com/open-feature/open-feature-operator/commit/4ecbc9b8eeac4e1e86c0f4e11ffedf3dbc376f9a))
* revert recent release ([#559](https://github.com/open-feature/open-feature-operator/issues/559)) ([f7c79e4](https://github.com/open-feature/open-feature-operator/commit/f7c79e4c6f5a5dee05d7db1796bfb9891dbd53a0))
## [0.2.37](https://github.com/open-feature/open-feature-operator/compare/apis-v0.2.36...apis/v0.2.37) (2023-11-15)
### ✨ New Features
* Introduce v1beta1 API version ([#535](https://github.com/open-feature/open-feature-operator/issues/535)) ([3acd492](https://github.com/open-feature/open-feature-operator/commit/3acd49289a40e8f07fd20aad46185ac42ceb1b7a))
* release APIs and Operator independently ([#541](https://github.com/open-feature/open-feature-operator/issues/541)) ([7b1af42](https://github.com/open-feature/open-feature-operator/commit/7b1af42ac41e63ccbb1820b31f579ffea679cff6))
### 🧹 Chore
* use github-action for golangci-lint workflow ([#538](https://github.com/open-feature/open-feature-operator/issues/538)) ([a97d336](https://github.com/open-feature/open-feature-operator/commit/a97d336468d5a9b50662f4979784c8388ec10ec1))

View File

@ -1,157 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type SyncProviderType string
// FlagSourceConfigurationSpec defines the desired state of FlagSourceConfiguration
type FlagSourceConfigurationSpec struct {
// MetricsPort defines the port to serve metrics on, defaults to 8014
// +optional
MetricsPort int32 `json:"metricsPort"`
// Port defines the port to listen on, defaults to 8013
// +optional
Port int32 `json:"port"`
// SocketPath defines the unix socket path to listen on
// +optional
SocketPath string `json:"socketPath"`
// SyncProviderArgs are string arguments passed to all sync providers, defined as key values separated by =
// +optional
SyncProviderArgs []string `json:"syncProviderArgs"`
// Evaluator sets an evaluator, defaults to 'json'
// +optional
Evaluator string `json:"evaluator"`
// 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 sidecar image, defaults to 'main'
// +optional
Tag string `json:"tag"`
// DefaultSyncProvider defines the default sync provider
// +optional
DefaultSyncProvider SyncProviderType `json:"defaultSyncProvider"`
// Sources defines the syncProviders and associated configuration to be applied to the sidecar
// +kubebuilder:validation:MinItems=1
Sources []Source `json:"sources"`
// EnvVars define the env vars to be applied to the sidecar, any env vars in FeatureFlagConfiguration CRs
// are added at the lowest index, all values will have the EnvVarPrefix applied
// +optional
EnvVars []corev1.EnvVar `json:"envVars"`
// EnvVarPrefix defines the prefix to be applied to all environment variables applied to the sidecar, default FLAGD
// +optional
EnvVarPrefix string `json:"envVarPrefix"`
// LogFormat allows for the sidecar log format to be overridden, defaults to 'json'
// +optional
LogFormat string `json:"logFormat"`
// RolloutOnChange dictates whether annotated deployments will be restarted when configuration changes are
// detected in this CR, defaults to false
// +optional
RolloutOnChange *bool `json:"rolloutOnChange"`
// ProbesEnabled defines whether to enable liveness and readiness probes of flagd sidecar. Default true (enabled).
// +optional
ProbesEnabled *bool `json:"probesEnabled"`
// DebugLogging defines whether to enable --debug flag of flagd sidecar. Default false (disabled).
// +optional
DebugLogging *bool `json:"debugLogging"`
// 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 {
// Source is a URI of the flag sources
Source string `json:"source"`
// Provider type - kubernetes, http, grpc or filepath
// +optional
Provider SyncProviderType `json:"provider"`
// HttpSyncBearerToken is a bearer token. Used by http(s) sync provider only
// +optional
HttpSyncBearerToken string `json:"httpSyncBearerToken"`
// TLS - Enable/Disable secure TLS connectivity. Currently used only by GRPC sync
// +optional
TLS bool `json:"tls"`
// CertPath is a path of a certificate to be used by grpc TLS connection
// +optional
CertPath string `json:"certPath"`
// ProviderID is an identifier to be used in grpc provider
// +optional
ProviderID string `json:"providerID"`
// Selector is a flag configuration selector used by grpc provider
// +optional
Selector string `json:"selector,omitempty"`
}
// FlagSourceConfigurationStatus defines the observed state of FlagSourceConfiguration
type FlagSourceConfigurationStatus struct {
}
// +kubebuilder:resource:shortName="fsc"
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:storageversion
// FlagSourceConfiguration is the Schema for the FlagSourceConfigurations API
type FlagSourceConfiguration struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec FlagSourceConfigurationSpec `json:"spec,omitempty"`
Status FlagSourceConfigurationStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// FlagSourceConfigurationList contains a list of FlagSourceConfiguration
type FlagSourceConfigurationList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []FlagSourceConfiguration `json:"items"`
}
func init() {
SchemeBuilder.Register(&FlagSourceConfiguration{}, &FlagSourceConfigurationList{})
}

View File

@ -1,132 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha2
import (
"encoding/json"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// FeatureFlagConfigurationSpec defines the desired state of FeatureFlagConfiguration
type FeatureFlagConfigurationSpec struct {
// ServiceProvider [DEPRECATED]: superseded by FlagSourceConfiguration
// +optional
// +nullable
ServiceProvider *FeatureFlagServiceProvider `json:"serviceProvider"`
// SyncProvider [DEPRECATED]: superseded by FlagSourceConfiguration
// +optional
// +nullable
SyncProvider *FeatureFlagSyncProvider `json:"syncProvider"`
// FlagDSpec [DEPRECATED]: superseded by FlagSourceConfiguration
// +optional
// +nullable
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 {
// +optional
Envs []corev1.EnvVar `json:"envs"`
}
type FeatureFlagSpec struct {
Flags map[string]FlagSpec `json:"flags"`
// +optional
// +kubebuilder:validation:Schemaless
// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:Type=object
Evaluators json.RawMessage `json:"$evaluators,omitempty"`
}
type FlagSpec struct {
// +kubebuilder:validation:Enum=ENABLED;DISABLED
State string `json:"state"`
// +kubebuilder:validation:Schemaless
// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:Type=object
Variants json.RawMessage `json:"variants"`
DefaultVariant string `json:"defaultVariant"`
// +optional
// +kubebuilder:validation:Schemaless
// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:Type=object
// Targeting is the json targeting rule
Targeting json.RawMessage `json:"targeting,omitempty"`
}
type FeatureFlagSyncProvider struct {
Name string `json:"name"`
// +optional
// +nullable
HttpSyncConfiguration *HttpSyncConfiguration `json:"httpSyncConfiguration"`
}
// HttpSyncConfiguration defines the desired configuration for a http sync
type HttpSyncConfiguration struct {
// Target is the target url for flagd to poll
Target string `json:"target"`
// +optional
BearerToken string `json:"bearerToken,omitempty"`
}
func (ffsp FeatureFlagSyncProvider) IsKubernetes() bool {
return ffsp.Name == "kubernetes"
}
type FeatureFlagServiceProvider struct {
// +kubebuilder:validation:Enum=flagd
Name string `json:"name"`
// +optional
// +nullable
Credentials *corev1.ObjectReference `json:"credentials"`
}
// FeatureFlagConfigurationStatus defines the observed state of FeatureFlagConfiguration
type FeatureFlagConfigurationStatus struct {
}
//+kubebuilder:resource:shortName="ffc"
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// FeatureFlagConfiguration is the Schema for the featureflagconfigurations API
type FeatureFlagConfiguration struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec FeatureFlagConfigurationSpec `json:"spec,omitempty"`
Status FeatureFlagConfigurationStatus `json:"status,omitempty"`
}
//+kubebuilder:object:root=true
// FeatureFlagConfigurationList contains a list of FeatureFlagConfiguration
type FeatureFlagConfigurationList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []FeatureFlagConfiguration `json:"items"`
}
func init() {
SchemeBuilder.Register(&FeatureFlagConfiguration{}, &FeatureFlagConfigurationList{})
}

View File

@ -1,98 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha2
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// FlagSourceConfigurationSpec defines the desired state of FlagSourceConfiguration
type FlagSourceConfigurationSpec struct {
// MetricsPort defines the port to serve metrics on, defaults to 8013
// +optional
MetricsPort int32 `json:"metricsPort"`
// Port defines the port to listen on, defaults to 8014
// +optional
Port int32 `json:"port"`
// SocketPath defines the unix socket path to listen on
// +optional
SocketPath string `json:"socketPath"`
// SyncProviderArgs are string arguments passed to all sync providers, defined as key values separated by =
// +optional
SyncProviderArgs []string `json:"syncProviderArgs"`
// Evaluator sets an evaluator, defaults to 'json'
// +optional
Evaluator string `json:"evaluator"`
// 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 sidecar image, defaults to 'main'
// +optional
Tag string `json:"tag"`
// DefaultSyncProvider defines the default sync provider
// +optional
DefaultSyncProvider string `json:"defaultSyncProvider"`
// LogFormat allows for the sidecar log format to be overridden, defaults to 'json'
// +optional
LogFormat string `json:"logFormat"`
// ProbesEnabled defines whether to enable liveness and readiness probes of flagd sidecar. Default true (enabled).
// +optional
ProbesEnabled *bool `json:"probesEnabled"`
// OtelCollectorUri defines whether to enable --otel-collector-uri flag of flagd sidecar. Default false (disabled).
// +optional
OtelCollectorUri string `json:"otelCollectorUri"`
}
// FlagSourceConfigurationStatus defines the observed state of FlagSourceConfiguration
type FlagSourceConfigurationStatus struct {
}
//+kubebuilder:resource:shortName="fsc"
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// FlagSourceConfiguration is the Schema for the FlagSourceConfigurations API
type FlagSourceConfiguration struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec FlagSourceConfigurationSpec `json:"spec,omitempty"`
Status FlagSourceConfigurationStatus `json:"status,omitempty"`
}
//+kubebuilder:object:root=true
// FlagSourceConfigurationList contains a list of FlagSourceConfiguration
type FlagSourceConfigurationList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []FlagSourceConfiguration `json:"items"`
}
func init() {
SchemeBuilder.Register(&FlagSourceConfiguration{}, &FlagSourceConfigurationList{})
}

View File

@ -1,36 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package v1alpha2 contains API Schema definitions for the core v1alpha2 API group
// +kubebuilder:object:generate=true
// +groupName=core.openfeature.dev
package v1alpha2
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)
var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "core.openfeature.dev", Version: "v1alpha2"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)

View File

@ -1,361 +0,0 @@
//go:build !ignore_autogenerated
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by controller-gen. DO NOT EDIT.
package v1alpha2
import (
"encoding/json"
"k8s.io/api/core/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagConfiguration) DeepCopyInto(out *FeatureFlagConfiguration) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagConfiguration.
func (in *FeatureFlagConfiguration) DeepCopy() *FeatureFlagConfiguration {
if in == nil {
return nil
}
out := new(FeatureFlagConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FeatureFlagConfiguration) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagConfigurationList) DeepCopyInto(out *FeatureFlagConfigurationList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]FeatureFlagConfiguration, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagConfigurationList.
func (in *FeatureFlagConfigurationList) DeepCopy() *FeatureFlagConfigurationList {
if in == nil {
return nil
}
out := new(FeatureFlagConfigurationList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FeatureFlagConfigurationList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagConfigurationSpec) DeepCopyInto(out *FeatureFlagConfigurationSpec) {
*out = *in
if in.ServiceProvider != nil {
in, out := &in.ServiceProvider, &out.ServiceProvider
*out = new(FeatureFlagServiceProvider)
(*in).DeepCopyInto(*out)
}
if in.SyncProvider != nil {
in, out := &in.SyncProvider, &out.SyncProvider
*out = new(FeatureFlagSyncProvider)
(*in).DeepCopyInto(*out)
}
if in.FlagDSpec != nil {
in, out := &in.FlagDSpec, &out.FlagDSpec
*out = new(FlagDSpec)
(*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.
func (in *FeatureFlagConfigurationSpec) DeepCopy() *FeatureFlagConfigurationSpec {
if in == nil {
return nil
}
out := new(FeatureFlagConfigurationSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagConfigurationStatus) DeepCopyInto(out *FeatureFlagConfigurationStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagConfigurationStatus.
func (in *FeatureFlagConfigurationStatus) DeepCopy() *FeatureFlagConfigurationStatus {
if in == nil {
return nil
}
out := new(FeatureFlagConfigurationStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagServiceProvider) DeepCopyInto(out *FeatureFlagServiceProvider) {
*out = *in
if in.Credentials != nil {
in, out := &in.Credentials, &out.Credentials
*out = new(v1.ObjectReference)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagServiceProvider.
func (in *FeatureFlagServiceProvider) DeepCopy() *FeatureFlagServiceProvider {
if in == nil {
return nil
}
out := new(FeatureFlagServiceProvider)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagSpec) DeepCopyInto(out *FeatureFlagSpec) {
*out = *in
if in.Flags != nil {
in, out := &in.Flags, &out.Flags
*out = make(map[string]FlagSpec, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
if in.Evaluators != nil {
in, out := &in.Evaluators, &out.Evaluators
*out = make(json.RawMessage, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagSpec.
func (in *FeatureFlagSpec) DeepCopy() *FeatureFlagSpec {
if in == nil {
return nil
}
out := new(FeatureFlagSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagSyncProvider) DeepCopyInto(out *FeatureFlagSyncProvider) {
*out = *in
if in.HttpSyncConfiguration != nil {
in, out := &in.HttpSyncConfiguration, &out.HttpSyncConfiguration
*out = new(HttpSyncConfiguration)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagSyncProvider.
func (in *FeatureFlagSyncProvider) DeepCopy() *FeatureFlagSyncProvider {
if in == nil {
return nil
}
out := new(FeatureFlagSyncProvider)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagDSpec) DeepCopyInto(out *FlagDSpec) {
*out = *in
if in.Envs != nil {
in, out := &in.Envs, &out.Envs
*out = make([]v1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagDSpec.
func (in *FlagDSpec) DeepCopy() *FlagDSpec {
if in == nil {
return nil
}
out := new(FlagDSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSourceConfiguration) DeepCopyInto(out *FlagSourceConfiguration) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfiguration.
func (in *FlagSourceConfiguration) DeepCopy() *FlagSourceConfiguration {
if in == nil {
return nil
}
out := new(FlagSourceConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FlagSourceConfiguration) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSourceConfigurationList) DeepCopyInto(out *FlagSourceConfigurationList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]FlagSourceConfiguration, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfigurationList.
func (in *FlagSourceConfigurationList) DeepCopy() *FlagSourceConfigurationList {
if in == nil {
return nil
}
out := new(FlagSourceConfigurationList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FlagSourceConfigurationList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSourceConfigurationSpec) DeepCopyInto(out *FlagSourceConfigurationSpec) {
*out = *in
if in.SyncProviderArgs != nil {
in, out := &in.SyncProviderArgs, &out.SyncProviderArgs
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.ProbesEnabled != nil {
in, out := &in.ProbesEnabled, &out.ProbesEnabled
*out = new(bool)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfigurationSpec.
func (in *FlagSourceConfigurationSpec) DeepCopy() *FlagSourceConfigurationSpec {
if in == nil {
return nil
}
out := new(FlagSourceConfigurationSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSourceConfigurationStatus) DeepCopyInto(out *FlagSourceConfigurationStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfigurationStatus.
func (in *FlagSourceConfigurationStatus) DeepCopy() *FlagSourceConfigurationStatus {
if in == nil {
return nil
}
out := new(FlagSourceConfigurationStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSpec) DeepCopyInto(out *FlagSpec) {
*out = *in
if in.Variants != nil {
in, out := &in.Variants, &out.Variants
*out = make(json.RawMessage, len(*in))
copy(*out, *in)
}
if in.Targeting != nil {
in, out := &in.Targeting, &out.Targeting
*out = make(json.RawMessage, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSpec.
func (in *FlagSpec) DeepCopy() *FlagSpec {
if in == nil {
return nil
}
out := new(FlagSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HttpSyncConfiguration) DeepCopyInto(out *HttpSyncConfiguration) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HttpSyncConfiguration.
func (in *HttpSyncConfiguration) DeepCopy() *HttpSyncConfiguration {
if in == nil {
return nil
}
out := new(HttpSyncConfiguration)
in.DeepCopyInto(out)
return out
}

View File

@ -1,156 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha3
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type SyncProviderType string
// FlagSourceConfigurationSpec defines the desired state of FlagSourceConfiguration
type FlagSourceConfigurationSpec struct {
// MetricsPort defines the port to serve metrics on, defaults to 8014
// +optional
MetricsPort int32 `json:"metricsPort"`
// Port defines the port to listen on, defaults to 8013
// +optional
Port int32 `json:"port"`
// SocketPath defines the unix socket path to listen on
// +optional
SocketPath string `json:"socketPath"`
// Evaluator sets an evaluator, defaults to 'json'
// +optional
Evaluator string `json:"evaluator"`
// 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 sidecar image, defaults to 'main'
// +optional
Tag string `json:"tag"`
// SyncProviders define the syncProviders and associated configuration to be applied to the sidecar
// +kubebuilder:validation:MinItems=1
Sources []Source `json:"sources"`
// EnvVars define the env vars to be applied to the sidecar, any env vars in FeatureFlagConfiguration CRs
// are added at the lowest index, all values will have the EnvVarPrefix applied, default FLAGD
// +optional
EnvVars []corev1.EnvVar `json:"envVars"`
// SyncProviderArgs are string arguments passed to all sync providers, defined as key values separated by =
// +optional
SyncProviderArgs []string `json:"syncProviderArgs"`
// DefaultSyncProvider defines the default sync provider
// +optional
DefaultSyncProvider string `json:"defaultSyncProvider"`
// LogFormat allows for the sidecar log format to be overridden, defaults to 'json'
// +optional
LogFormat string `json:"logFormat"`
// EnvVarPrefix defines the prefix to be applied to all environment variables applied to the sidecar, default FLAGD
// +optional
EnvVarPrefix string `json:"envVarPrefix"`
// RolloutOnChange dictates whether annotated deployments will be restarted when configuration changes are
// detected in this CR, defaults to false
// +optional
RolloutOnChange *bool `json:"rolloutOnChange"`
// ProbesEnabled defines whether to enable liveness and readiness probes of flagd sidecar. Default true (enabled).
// +optional
ProbesEnabled *bool `json:"probesEnabled"`
// DebugLogging defines whether to enable --debug flag of flagd sidecar. Default false (disabled).
// +optional
DebugLogging *bool `json:"debugLogging"`
// 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 {
// Source is a URI of the flag sources
Source string `json:"source"`
// Provider type - kubernetes, http(s), grpc(s) or filepath
// +optional
Provider SyncProviderType `json:"provider"`
// HttpSyncBearerToken is a bearer token. Used by http(s) sync provider only
// +optional
HttpSyncBearerToken string `json:"httpSyncBearerToken"`
// TLS - Enable/Disable secure TLS connectivity. Currently used only by GRPC sync
// +optional
TLS bool `json:"tls"`
// CertPath is a path of a certificate to be used by grpc TLS connection
// +optional
CertPath string `json:"certPath"`
// ProviderID is an identifier to be used in grpc provider
// +optional
ProviderID string `json:"providerID"`
// Selector is a flag configuration selector used by grpc provider
// +optional
Selector string `json:"selector,omitempty"`
}
// FlagSourceConfigurationStatus defines the observed state of FlagSourceConfiguration
type FlagSourceConfigurationStatus struct {
}
//+kubebuilder:resource:shortName="fsc"
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// FlagSourceConfiguration is the Schema for the FlagSourceConfigurations API
type FlagSourceConfiguration struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec FlagSourceConfigurationSpec `json:"spec,omitempty"`
Status FlagSourceConfigurationStatus `json:"status,omitempty"`
}
//+kubebuilder:object:root=true
// FlagSourceConfigurationList contains a list of FlagSourceConfiguration
type FlagSourceConfigurationList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []FlagSourceConfiguration `json:"items"`
}
func init() {
SchemeBuilder.Register(&FlagSourceConfiguration{}, &FlagSourceConfigurationList{})
}

View File

@ -1,36 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package v1alpha3 contains API Schema definitions for the core v1alpha3 API group
// +kubebuilder:object:generate=true
// +groupName=core.openfeature.dev
package v1alpha3
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)
var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "core.openfeature.dev", Version: "v1alpha3"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)

View File

@ -1,163 +0,0 @@
//go:build !ignore_autogenerated
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by controller-gen. DO NOT EDIT.
package v1alpha3
import (
"k8s.io/api/core/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSourceConfiguration) DeepCopyInto(out *FlagSourceConfiguration) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfiguration.
func (in *FlagSourceConfiguration) DeepCopy() *FlagSourceConfiguration {
if in == nil {
return nil
}
out := new(FlagSourceConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FlagSourceConfiguration) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSourceConfigurationList) DeepCopyInto(out *FlagSourceConfigurationList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]FlagSourceConfiguration, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfigurationList.
func (in *FlagSourceConfigurationList) DeepCopy() *FlagSourceConfigurationList {
if in == nil {
return nil
}
out := new(FlagSourceConfigurationList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FlagSourceConfigurationList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSourceConfigurationSpec) DeepCopyInto(out *FlagSourceConfigurationSpec) {
*out = *in
if in.Sources != nil {
in, out := &in.Sources, &out.Sources
*out = make([]Source, len(*in))
copy(*out, *in)
}
if in.EnvVars != nil {
in, out := &in.EnvVars, &out.EnvVars
*out = make([]v1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.SyncProviderArgs != nil {
in, out := &in.SyncProviderArgs, &out.SyncProviderArgs
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.RolloutOnChange != nil {
in, out := &in.RolloutOnChange, &out.RolloutOnChange
*out = new(bool)
**out = **in
}
if in.ProbesEnabled != nil {
in, out := &in.ProbesEnabled, &out.ProbesEnabled
*out = new(bool)
**out = **in
}
if in.DebugLogging != nil {
in, out := &in.DebugLogging, &out.DebugLogging
*out = new(bool)
**out = **in
}
in.Resources.DeepCopyInto(&out.Resources)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfigurationSpec.
func (in *FlagSourceConfigurationSpec) DeepCopy() *FlagSourceConfigurationSpec {
if in == nil {
return nil
}
out := new(FlagSourceConfigurationSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSourceConfigurationStatus) DeepCopyInto(out *FlagSourceConfigurationStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfigurationStatus.
func (in *FlagSourceConfigurationStatus) DeepCopy() *FlagSourceConfigurationStatus {
if in == nil {
return nil
}
out := new(FlagSourceConfigurationStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Source) DeepCopyInto(out *Source) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Source.
func (in *Source) DeepCopy() *Source {
if in == nil {
return nil
}
out := new(Source)
in.DeepCopyInto(out)
return out
}

View File

@ -1,131 +0,0 @@
package common
import (
"fmt"
corev1 "k8s.io/api/core/v1"
)
type SyncProviderType string
const (
SyncProviderKubernetes SyncProviderType = "kubernetes"
SyncProviderFilepath SyncProviderType = "file"
SyncProviderGcs SyncProviderType = "gcs"
SyncProviderHttp SyncProviderType = "http"
SyncProviderGrpc SyncProviderType = "grpc"
SyncProviderFlagdProxy SyncProviderType = "flagd-proxy"
)
const (
ManagementPortEnvVar string = "MANAGEMENT_PORT"
PortEnvVar string = "PORT"
HostEnvVar string = "HOST"
TLSEnvVar string = "TLS"
SocketPathEnvVar string = "SOCKET_PATH"
OfflineFlagSourcePathEnvVar string = "OFFLINE_FLAG_SOURCE_PATH"
SelectorEnvVar string = "SOURCE_SELECTOR"
CacheEnvVar string = "CACHE"
CacheMaxSizeEnvVar string = "MAX_CACHE_SIZE"
ResolverEnvVar string = "RESOLVER"
EvaluatorEnvVar string = "EVALUATOR"
ImageEnvVar string = "IMAGE"
VersionEnvVar string = "TAG"
ProviderArgsEnvVar string = "PROVIDER_ARGS"
DefaultSyncProviderEnvVar string = "SYNC_PROVIDER"
LogFormatEnvVar string = "LOG_FORMAT"
ProbesEnabledVar string = "PROBES_ENABLED"
DefaultEnvVarPrefix string = "FLAGD"
DefaultManagementPort int32 = 8014
DefaultRPCPort int32 = 8013
DefaultInProcessPort int32 = 8015
DefaultEvaluator string = "json"
DefaultLogFormat string = "json"
DefaultProbesEnabled bool = true
DefaultTLS bool = false
DefaultHost string = "localhost"
DefaultCache string = "lru"
DefaultCacheMaxSize int32 = 1000
InProcessResolverType string = "in-process"
RPCResolverType string = "rpc"
)
func (s SyncProviderType) IsKubernetes() bool {
return s == SyncProviderKubernetes
}
func (s SyncProviderType) IsHttp() bool {
return s == SyncProviderHttp
}
func (s SyncProviderType) IsGcs() bool {
return s == SyncProviderGcs
}
func (s SyncProviderType) IsFilepath() bool {
return s == SyncProviderFilepath
}
func (s SyncProviderType) IsGrpc() bool {
return s == SyncProviderGrpc
}
func (s SyncProviderType) IsFlagdProxy() bool {
return s == SyncProviderFlagdProxy
}
func TrueVal() *bool {
b := true
return &b
}
func FalseVal() *bool {
b := false
return &b
}
func EnvVarKey(prefix string, suffix string) string {
return fmt.Sprintf("%s_%s", prefix, suffix)
}
// unique string used to create unique volume mount and file name
func FeatureFlagConfigurationId(namespace, name string) string {
return EnvVarKey(namespace, name)
}
// unique key (and filename) for configMap data
func FeatureFlagConfigMapKey(namespace, name string) string {
return fmt.Sprintf("%s.flagd.json", FeatureFlagConfigurationId(namespace, name))
}
func RemoveDuplicateEnvVars(input []corev1.EnvVar) []corev1.EnvVar {
out := make([]corev1.EnvVar, 0, len(input))
for i := len(input) - 1; i >= 0; i-- {
if !isEnvVarNamePresent(out, input[i]) {
out = append(out, input[i])
}
}
return out
}
func isEnvVarNamePresent(slice []corev1.EnvVar, item corev1.EnvVar) bool {
for _, i := range slice {
if i.Name == item.Name {
return true
}
}
return false
}
func RemoveDuplicatesFromSlice[T comparable](input []T) []T {
seen := make(map[T]bool)
result := []T{}
for _, item := range input {
if _, ok := seen[item]; !ok {
seen[item] = true
result = append(result, item)
}
}
return result
}

View File

@ -1,151 +0,0 @@
package common
import (
"testing"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
)
func Test_FeatureFlagSource_SyncProvider(t *testing.T) {
k := SyncProviderKubernetes
f := SyncProviderFilepath
h := SyncProviderHttp
g := SyncProviderGrpc
gcs := SyncProviderGcs
require.True(t, k.IsKubernetes())
require.True(t, f.IsFilepath())
require.True(t, h.IsHttp())
require.True(t, g.IsGrpc())
require.True(t, gcs.IsGcs())
require.False(t, f.IsKubernetes())
require.False(t, h.IsFilepath())
require.False(t, k.IsGrpc())
require.False(t, g.IsHttp())
require.False(t, g.IsGcs())
}
func Test_FLagSourceConfiguration_EnvVarKey(t *testing.T) {
require.Equal(t, "pre_suf", EnvVarKey("pre", "suf"))
}
func Test_FLagSourceConfiguration_FeatureFlagConfigurationId(t *testing.T) {
require.Equal(t, "pre_suf", FeatureFlagConfigurationId("pre", "suf"))
}
func Test_FLagSourceConfiguration_FeatureFlagConfigMapKey(t *testing.T) {
require.Equal(t, "pre_suf.flagd.json", FeatureFlagConfigMapKey("pre", "suf"))
}
func Test_RemoveDuplicateEnvVars(t *testing.T) {
input1 := []corev1.EnvVar{
{
Name: "key1",
Value: "val1",
},
{
Name: "key2",
Value: "val2",
},
{
Name: "key1",
Value: "val3",
},
}
input2 := []corev1.EnvVar{
{
Name: "key1",
Value: "val1",
},
{
Name: "key2",
Value: "val2",
},
{
Name: "key3",
Value: "val3",
},
}
input3 := []corev1.EnvVar{
{
Name: "key1",
Value: "val1",
},
{
Name: "key2",
Value: "val2",
},
{
Name: "key1",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "secret",
},
},
},
},
}
out1 := RemoveDuplicateEnvVars(input1)
require.Len(t, out1, 2)
require.Contains(t, out1, corev1.EnvVar{
Name: "key1",
Value: "val3",
})
require.Contains(t, out1, corev1.EnvVar{
Name: "key2",
Value: "val2",
})
out2 := RemoveDuplicateEnvVars(input2)
require.Len(t, out2, 3)
require.Contains(t, out2, corev1.EnvVar{
Name: "key1",
Value: "val1",
})
require.Contains(t, out2, corev1.EnvVar{
Name: "key2",
Value: "val2",
})
require.Contains(t, out2, corev1.EnvVar{
Name: "key3",
Value: "val3",
})
out3 := RemoveDuplicateEnvVars(input3)
require.Len(t, out3, 2)
require.Contains(t, out3, corev1.EnvVar{
Name: "key1",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "secret",
},
},
},
})
require.Contains(t, out3, corev1.EnvVar{
Name: "key2",
Value: "val2",
})
}
func Test_RRemoveDuplicatesFromSlice(t *testing.T) {
input1 := []string{
"some", "input", "duplicate", "some",
}
input2 := []int{
1, 2, 3, 4, 2,
}
require.Equal(t, RemoveDuplicatesFromSlice(input1), []string{
"some", "input", "duplicate",
})
require.Equal(t, RemoveDuplicatesFromSlice(input2), []int{
1, 2, 3, 4,
})
}

View File

@ -1,122 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta1
import (
"encoding/json"
"github.com/open-feature/open-feature-operator/apis/core/v1beta1/common"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// FeatureFlagSpec defines the desired state of FeatureFlag
type FeatureFlagSpec struct {
// FlagSpec is the structured representation of the feature flag specification
FlagSpec FlagSpec `json:"flagSpec,omitempty"`
}
type FlagSpec struct {
Flags `json:",inline"`
// +optional
// +kubebuilder:validation:Schemaless
// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:Type=object
Evaluators json.RawMessage `json:"$evaluators,omitempty"`
}
// Flags represent the flags specification
type Flags struct {
FlagsMap map[string]Flag `json:"flags"`
}
type Flag struct {
// +kubebuilder:validation:Enum=ENABLED;DISABLED
State string `json:"state"`
// +kubebuilder:validation:Schemaless
// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:Type=object
Variants json.RawMessage `json:"variants"`
DefaultVariant string `json:"defaultVariant"`
// +optional
// +kubebuilder:validation:Schemaless
// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:Type=object
// Targeting is the json targeting rule
Targeting json.RawMessage `json:"targeting,omitempty"`
}
// FeatureFlagStatus defines the observed state of FeatureFlag
type FeatureFlagStatus struct {
}
//+kubebuilder:resource:shortName="ff"
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:storageversion
// FeatureFlag is the Schema for the featureflags API
type FeatureFlag struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec FeatureFlagSpec `json:"spec,omitempty"`
Status FeatureFlagStatus `json:"status,omitempty"`
}
//+kubebuilder:object:root=true
// FeatureFlagList contains a list of FeatureFlag
type FeatureFlagList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []FeatureFlag `json:"items"`
}
func init() {
SchemeBuilder.Register(&FeatureFlag{}, &FeatureFlagList{})
}
func (ff *FeatureFlag) GetReference() metav1.OwnerReference {
return metav1.OwnerReference{
APIVersion: ff.APIVersion,
Kind: ff.Kind,
Name: ff.Name,
UID: ff.UID,
Controller: common.TrueVal(),
}
}
func (ff *FeatureFlag) GenerateConfigMap(name string, namespace string, references []metav1.OwnerReference) (*corev1.ConfigMap, error) {
b, err := json.Marshal(ff.Spec.FlagSpec)
if err != nil {
return nil, err
}
return &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Annotations: map[string]string{
"openfeature.dev/featureflag": name,
},
OwnerReferences: references,
},
Data: map[string]string{
common.FeatureFlagConfigMapKey(namespace, name): string(b),
},
}, nil
}

View File

@ -1,70 +0,0 @@
package v1beta1
import (
"testing"
"github.com/open-feature/open-feature-operator/apis/core/v1beta1/common"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)
func Test_FeatureFlag(t *testing.T) {
ff := FeatureFlag{
ObjectMeta: v1.ObjectMeta{
Name: "ffconf1",
Namespace: "test",
OwnerReferences: []v1.OwnerReference{
{
APIVersion: "ver",
Kind: "kind",
Name: "ffconf1",
UID: types.UID("5"),
Controller: common.TrueVal(),
},
},
},
Spec: FeatureFlagSpec{
FlagSpec: FlagSpec{
Flags: Flags{},
},
},
}
require.Equal(t, v1.OwnerReference{
APIVersion: ff.APIVersion,
Kind: ff.Kind,
Name: ff.Name,
UID: ff.UID,
Controller: common.TrueVal(),
}, ff.GetReference())
name := "cmname"
namespace := "cmnamespace"
references := []v1.OwnerReference{
{
APIVersion: "ver",
Kind: "kind",
Name: "ffconf1",
UID: types.UID("5"),
Controller: common.TrueVal(),
},
}
cm, _ := ff.GenerateConfigMap(name, namespace, references)
require.Equal(t, corev1.ConfigMap{
ObjectMeta: v1.ObjectMeta{
Name: name,
Namespace: namespace,
Annotations: map[string]string{
"openfeature.dev/featureflag": name,
},
OwnerReferences: references,
},
Data: map[string]string{
"cmnamespace_cmname.flagd.json": "{\"flags\":null}",
},
}, *cm)
}

View File

@ -1,257 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta1
import (
"fmt"
"github.com/open-feature/open-feature-operator/apis/core/v1beta1/common"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// FeatureFlagSourceSpec defines the desired state of FeatureFlagSource
type FeatureFlagSourceSpec struct {
// ManagemetPort defines the port to serve management on, defaults to 8014
// +optional
// +kubebuilder:default:=8014
ManagementPort int32 `json:"managementPort"`
// Port defines the port to listen on, defaults to 8013
// +optional
// +kubebuilder:default:=8013
Port int32 `json:"port"`
// SocketPath defines the unix socket path to listen on
// +optional
SocketPath string `json:"socketPath"`
// Evaluator sets an evaluator, defaults to 'json'
// +optional
// +kubebuilder:default:="json"
Evaluator string `json:"evaluator"`
// SyncProviders define the syncProviders and associated configuration to be applied to the sidecar
// +kubebuilder:validation:MinItems=1
Sources []Source `json:"sources"`
// EnvVars define the env vars to be applied to the sidecar, any env vars in FeatureFlag CRs
// are added at the lowest index, all values will have the EnvVarPrefix applied, default FLAGD
// +optional
EnvVars []corev1.EnvVar `json:"envVars"`
// SyncProviderArgs are string arguments passed to all sync providers, defined as key values separated by =
// +optional
SyncProviderArgs []string `json:"syncProviderArgs"`
// DefaultSyncProvider defines the default sync provider
// +optional
DefaultSyncProvider common.SyncProviderType `json:"defaultSyncProvider"`
// LogFormat allows for the sidecar log format to be overridden, defaults to 'json'
// +optional
// +kubebuilder:default:="json"
LogFormat string `json:"logFormat"`
// EnvVarPrefix defines the prefix to be applied to all environment variables applied to the sidecar, default FLAGD
// +optional
// +kubebuilder:default:="FLAGD"
EnvVarPrefix string `json:"envVarPrefix"`
// RolloutOnChange dictates whether annotated deployments will be restarted when configuration changes are
// detected in this CR, defaults to false
// +optional
RolloutOnChange *bool `json:"rolloutOnChange"`
// ProbesEnabled defines whether to enable liveness and readiness probes of flagd sidecar. Default true (enabled).
// +optional
ProbesEnabled *bool `json:"probesEnabled"`
// DebugLogging defines whether to enable --debug flag of flagd sidecar. Default false (disabled).
// +optional
DebugLogging *bool `json:"debugLogging"`
// 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 {
// Source is a URI of the flag sources
Source string `json:"source"`
// Provider type - kubernetes, http(s), grpc(s) or file
// +optional
Provider common.SyncProviderType `json:"provider"`
// HttpSyncBearerToken is a bearer token. Used by http(s) sync provider only
// +optional
HttpSyncBearerToken string `json:"httpSyncBearerToken"`
// TLS - Enable/Disable secure TLS connectivity. Currently used only by GRPC sync
// +optional
TLS bool `json:"tls"`
// CertPath is a path of a certificate to be used by grpc TLS connection
// +optional
CertPath string `json:"certPath"`
// ProviderID is an identifier to be used in grpc provider
// +optional
ProviderID string `json:"providerID"`
// Selector is a flag configuration selector used by grpc provider
// +optional
Selector string `json:"selector,omitempty"`
// Interval is a flag configuration interval in seconds used by http provider
// +optional
Interval uint32 `json:"interval,omitempty"`
}
// FeatureFlagSourceStatus defines the observed state of FeatureFlagSource
type FeatureFlagSourceStatus struct {
}
//+kubebuilder:resource:shortName="ffs"
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:storageversion
// FeatureFlagSource is the Schema for the FeatureFlagSources API
type FeatureFlagSource struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec FeatureFlagSourceSpec `json:"spec,omitempty"`
Status FeatureFlagSourceStatus `json:"status,omitempty"`
}
//+kubebuilder:object:root=true
// FeatureFlagSourceList contains a list of FeatureFlagSource
type FeatureFlagSourceList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []FeatureFlagSource `json:"items"`
}
func init() {
SchemeBuilder.Register(&FeatureFlagSource{}, &FeatureFlagSourceList{})
}
//nolint:gocyclo
func (fc *FeatureFlagSourceSpec) Merge(new *FeatureFlagSourceSpec) {
if new == nil {
return
}
if new.ManagementPort != 0 {
fc.ManagementPort = new.ManagementPort
}
if new.Port != 0 {
fc.Port = new.Port
}
if new.SocketPath != "" {
fc.SocketPath = new.SocketPath
}
if new.Evaluator != "" {
fc.Evaluator = new.Evaluator
}
if len(new.Sources) != 0 {
fc.Sources = append(fc.Sources, new.Sources...)
}
if len(new.EnvVars) != 0 {
fc.EnvVars = append(fc.EnvVars, new.EnvVars...)
fc.EnvVars = common.RemoveDuplicateEnvVars(fc.EnvVars)
}
if len(new.SyncProviderArgs) != 0 {
fc.SyncProviderArgs = append(fc.SyncProviderArgs, new.SyncProviderArgs...)
fc.SyncProviderArgs = common.RemoveDuplicatesFromSlice[string](fc.SyncProviderArgs)
}
if new.EnvVarPrefix != "" {
fc.EnvVarPrefix = new.EnvVarPrefix
}
if new.DefaultSyncProvider != "" {
fc.DefaultSyncProvider = new.DefaultSyncProvider
}
if new.LogFormat != "" {
fc.LogFormat = new.LogFormat
}
if new.RolloutOnChange != nil {
fc.RolloutOnChange = new.RolloutOnChange
}
if new.ProbesEnabled != nil {
fc.ProbesEnabled = new.ProbesEnabled
}
if new.DebugLogging != nil {
fc.DebugLogging = new.DebugLogging
}
if new.OtelCollectorUri != "" {
fc.OtelCollectorUri = new.OtelCollectorUri
}
}
func (fc *FeatureFlagSourceSpec) ToEnvVars() []corev1.EnvVar {
envs := []corev1.EnvVar{}
for _, envVar := range fc.EnvVars {
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, envVar.Name),
Value: envVar.Value,
})
}
// default values are always included in the envVars
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.ManagementPortEnvVar),
Value: fmt.Sprintf("%d", fc.ManagementPort),
})
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.PortEnvVar),
Value: fmt.Sprintf("%d", fc.Port),
})
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.EvaluatorEnvVar),
Value: fc.Evaluator,
})
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.LogFormatEnvVar),
Value: fc.LogFormat,
})
// sets the FLAGD_RESOLVER var to "rpc" to configure the provider for RPC evaluation mode
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.ResolverEnvVar),
Value: common.RPCResolverType,
})
if fc.SocketPath != "" {
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.SocketPathEnvVar),
Value: fc.SocketPath,
})
}
return envs
}

View File

@ -1,227 +0,0 @@
package v1beta1
import (
"testing"
"github.com/open-feature/open-feature-operator/apis/core/v1beta1/common"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
)
func Test_FLagSourceConfiguration_Merge(t *testing.T) {
ff_old := &FeatureFlagSource{
Spec: FeatureFlagSourceSpec{
EnvVars: []v1.EnvVar{
{
Name: "env1",
Value: "val1",
},
{
Name: "env2",
Value: "val2",
},
},
EnvVarPrefix: "PRE",
ManagementPort: 22,
Port: 33,
Evaluator: "evaluator",
SocketPath: "socket-path",
LogFormat: "log",
Sources: []Source{
{
Source: "src1",
Provider: common.SyncProviderGrpc,
TLS: true,
CertPath: "etc/cert.ca",
ProviderID: "app",
Selector: "source=database",
Interval: 5,
},
},
SyncProviderArgs: []string{"arg1", "arg2"},
DefaultSyncProvider: common.SyncProviderKubernetes,
RolloutOnChange: common.TrueVal(),
ProbesEnabled: common.TrueVal(),
DebugLogging: common.TrueVal(),
OtelCollectorUri: "",
},
}
ff_old.Spec.Merge(nil)
require.Equal(t, &FeatureFlagSource{
Spec: FeatureFlagSourceSpec{
EnvVars: []v1.EnvVar{
{
Name: "env1",
Value: "val1",
},
{
Name: "env2",
Value: "val2",
},
},
EnvVarPrefix: "PRE",
ManagementPort: 22,
Port: 33,
Evaluator: "evaluator",
SocketPath: "socket-path",
LogFormat: "log",
Sources: []Source{
{
Source: "src1",
Provider: common.SyncProviderGrpc,
TLS: true,
CertPath: "etc/cert.ca",
ProviderID: "app",
Selector: "source=database",
Interval: 5,
},
},
SyncProviderArgs: []string{"arg1", "arg2"},
DefaultSyncProvider: common.SyncProviderKubernetes,
RolloutOnChange: common.TrueVal(),
ProbesEnabled: common.TrueVal(),
DebugLogging: common.TrueVal(),
OtelCollectorUri: "",
},
}, ff_old)
ff_new := &FeatureFlagSource{
Spec: FeatureFlagSourceSpec{
EnvVars: []v1.EnvVar{
{
Name: "env3",
Value: "val3",
},
{
Name: "env4",
Value: "val4",
},
},
EnvVarPrefix: "PREFIX",
ManagementPort: 221,
Port: 331,
Evaluator: "evaluator1",
SocketPath: "socket-path1",
LogFormat: "log1",
Sources: []Source{
{
Source: "src2",
Provider: common.SyncProviderFilepath,
},
},
SyncProviderArgs: []string{"arg3", "arg4"},
DefaultSyncProvider: common.SyncProviderFilepath,
RolloutOnChange: common.FalseVal(),
ProbesEnabled: common.FalseVal(),
DebugLogging: common.FalseVal(),
OtelCollectorUri: "",
},
}
ff_old.Spec.Merge(&ff_new.Spec)
require.Equal(t, ff_old.Spec.EnvVarPrefix, "PREFIX")
require.Equal(t, ff_old.Spec.Port, int32(331))
require.Equal(t, ff_old.Spec.ManagementPort, int32(221))
require.Equal(t, ff_old.Spec.SocketPath, "socket-path1")
require.Equal(t, ff_old.Spec.Evaluator, "evaluator1")
require.Equal(t, ff_old.Spec.LogFormat, "log1")
require.Equal(t, ff_old.Spec.Sources, []Source{
{
Source: "src1",
Provider: common.SyncProviderGrpc,
TLS: true,
CertPath: "etc/cert.ca",
ProviderID: "app",
Selector: "source=database",
Interval: 5,
},
{
Source: "src2",
Provider: common.SyncProviderFilepath,
},
})
require.Equal(t, ff_old.Spec.SyncProviderArgs, []string{"arg1", "arg2", "arg3", "arg4"})
require.Equal(t, ff_old.Spec.DefaultSyncProvider, common.SyncProviderFilepath)
require.Equal(t, ff_old.Spec.RolloutOnChange, common.FalseVal())
require.Equal(t, ff_old.Spec.ProbesEnabled, common.FalseVal())
require.Equal(t, ff_old.Spec.DebugLogging, common.FalseVal())
require.Equal(t, ff_old.Spec.OtelCollectorUri, "")
require.Len(t, ff_old.Spec.EnvVars, 4)
require.Contains(t, ff_old.Spec.EnvVars, v1.EnvVar{
Name: "env1",
Value: "val1",
})
require.Contains(t, ff_old.Spec.EnvVars, v1.EnvVar{
Name: "env2",
Value: "val2",
})
require.Contains(t, ff_old.Spec.EnvVars, v1.EnvVar{
Name: "env3",
Value: "val3",
})
require.Contains(t, ff_old.Spec.EnvVars, v1.EnvVar{
Name: "env4",
Value: "val4",
})
}
func Test_FLagSourceConfiguration_ToEnvVars(t *testing.T) {
ff := FeatureFlagSource{
Spec: FeatureFlagSourceSpec{
EnvVars: []v1.EnvVar{
{
Name: "env1",
Value: "val1",
},
{
Name: "env2",
Value: "val2",
},
},
EnvVarPrefix: "PRE",
ManagementPort: 22,
Port: 33,
Evaluator: "evaluator",
SocketPath: "socket-path",
LogFormat: "log",
},
}
expected := []v1.EnvVar{
{
Name: "PRE_env1",
Value: "val1",
},
{
Name: "PRE_env2",
Value: "val2",
},
{
Name: "PRE_MANAGEMENT_PORT",
Value: "22",
},
{
Name: "PRE_PORT",
Value: "33",
},
{
Name: "PRE_EVALUATOR",
Value: "evaluator",
},
{
Name: "PRE_LOG_FORMAT",
Value: "log",
},
{
Name: "PRE_RESOLVER",
Value: "rpc",
},
{
Name: "PRE_SOCKET_PATH",
Value: "socket-path",
},
}
require.Equal(t, expected, ff.Spec.ToEnvVars())
}

View File

@ -1,145 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta1
import (
v1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
gatewayApiv1 "sigs.k8s.io/gateway-api/apis/v1"
)
// FlagdSpec defines the desired state of Flagd
type FlagdSpec struct {
// Replicas defines the number of replicas to create for the service.
// Default: 1
// +optional
// +kubebuilder:default=1
Replicas *int32 `json:"replicas,omitempty"`
// ServiceType represents the type of Service to create.
// Must be one of: ClusterIP, NodePort, LoadBalancer, and ExternalName.
// Default: ClusterIP
// +optional
// +kubebuilder:default=ClusterIP
// +kubebuilder:validation:Enum:=ClusterIP;NodePort;LoadBalancer;ExternalName
ServiceType v1.ServiceType `json:"serviceType,omitempty"`
// ServiceAccountName the service account name for the flagd deployment
// +optional
ServiceAccountName string `json:"serviceAccountName,omitempty"`
// FeatureFlagSource references to a FeatureFlagSource from which the created flagd instance retrieves
// the feature flag configurations
FeatureFlagSource string `json:"featureFlagSource"`
// Ingress
// +optional
Ingress IngressSpec `json:"ingress"`
// GatewayApiRoutes
// +optional
GatewayApiRoutes GatewayApiSpec `json:"gatewayApiRoutes"`
}
// IngressSpec defines the options to be used when deploying the ingress for flagd
type IngressSpec struct {
// Enabled enables/disables the ingress for flagd
Enabled bool `json:"enabled,omitempty"`
// Annotations the annotations to be added to the ingress
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
// Hosts list of hosts to be added to the ingress.
// Empty string corresponds to rule with no host.
Hosts []string `json:"hosts"`
// TLS configuration for the ingress
TLS []networkingv1.IngressTLS `json:"tls,omitempty"`
// IngressClassName defines the name if the ingress class to be used for flagd
// +optional
IngressClassName *string `json:"ingressClassName,omitempty"`
// PathType is the path type to be used for the ingress rules
// +optional
PathType networkingv1.PathType `json:"pathType,omitempty"`
// FlagdPath is the path to be used for accessing the flagd flag evaluation API
// Default: /flagd.evaluation.v1.Service
// +optional
FlagdPath string `json:"flagdPath,omitempty"`
// OFREPPath is the path to be used for accessing the OFREP API
// Default: /ofrep
// +optional
OFREPPath string `json:"ofrepPath,omitempty"`
// SyncPath is the path to be used for accessing the sync API
// Default: /flagd.sync.v1.Service
// +optional
SyncPath string `json:"syncPath,omitempty"`
}
// GatewayApiSpec defines the options to be used when deploying Gateway API routes for flagd
type GatewayApiSpec struct {
// Enabled enables/disables the Gateway API routes for flagd
Enabled bool `json:"enabled,omitempty"`
// Annotations to be added to the Gateway API routes
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
// Hosts list of hosts to be added to the ingress.
// Empty string corresponds to rule with no host.
// +optional
Hosts []string `json:"hosts,omitempty"`
// ParentRefs references the resources (usually Gateways) that the Routes should
// be attached to.
ParentRefs []gatewayApiv1.ParentReference `json:"parentRefs"`
}
// FlagdStatus defines the observed state of Flagd
type FlagdStatus struct {
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// Flagd is the Schema for the flagds API
type Flagd struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec FlagdSpec `json:"spec,omitempty"`
Status FlagdStatus `json:"status,omitempty"`
}
//+kubebuilder:object:root=true
// FlagdList contains a list of Flagd
type FlagdList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Flagd `json:"items"`
}
func init() {
SchemeBuilder.Register(&Flagd{}, &FlagdList{})
}

View File

@ -1,36 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package v1beta1 contains API Schema definitions for the core v1beta1 API group
// +kubebuilder:object:generate=true
// +groupName=core.openfeature.dev
package v1beta1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)
var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "core.openfeature.dev", Version: "v1beta1"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)

View File

@ -1,209 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta1
import (
"fmt"
"github.com/open-feature/open-feature-operator/apis/core/v1beta1/common"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// InProcessConfigurationSpec defines the desired state of InProcessConfiguration
type InProcessConfigurationSpec struct {
// Port defines the port to listen on, defaults to 8015
// +kubebuilder:default:=8015
// +optional
Port int32 `json:"port"`
// SocketPath defines the unix socket path to listen on
// +optional
SocketPath string `json:"socketPath"`
// Host
// +kubebuilder:default:=localhost
// +optional
Host string `json:"host"`
// TLS
// +kubebuilder:default:=false
// +optional
TLS bool `json:"tls"`
// OfflineFlagSourcePath
// +optional
OfflineFlagSourcePath string `json:"offlineFlagSourcePath"`
// Selector
// +optional
Selector string `json:"selector"`
// Cache
// +kubebuilder:default:="lru"
// +kubebuilder:validation:Pattern="^(lru|disabled)$"
// +kubebuilder:validation:Type:=string
// +optional
Cache string `json:"cache"`
// CacheMaxSize
// +kubebuilder:default:=1000
// +optional
CacheMaxSize int `json:"cacheMaxSize"`
// EnvVars
// +optional
EnvVars []corev1.EnvVar `json:"envVars"`
// EnvVarPrefix defines the prefix to be applied to all environment variables applied to the sidecar, default FLAGD
// +optional
// +kubebuilder:default:=FLAGD
EnvVarPrefix string `json:"envVarPrefix"`
}
// InProcessConfigurationStatus defines the observed state of InProcessConfiguration
type InProcessConfigurationStatus struct {
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// InProcessConfiguration is the Schema for the inprocesconfigurations API
type InProcessConfiguration struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec InProcessConfigurationSpec `json:"spec,omitempty"`
Status InProcessConfigurationStatus `json:"status,omitempty"`
}
//+kubebuilder:object:root=true
// InProcessConfigurationList contains a list of InProcessConfiguration
type InProcessConfigurationList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []InProcessConfiguration `json:"items"`
}
func init() {
SchemeBuilder.Register(&InProcessConfiguration{}, &InProcessConfigurationList{})
}
func (fc *InProcessConfigurationSpec) Merge(new *InProcessConfigurationSpec) {
if new == nil {
return
}
if len(new.EnvVars) != 0 {
fc.EnvVars = append(fc.EnvVars, new.EnvVars...)
fc.EnvVars = common.RemoveDuplicateEnvVars(fc.EnvVars)
}
if new.Port != common.DefaultInProcessPort {
fc.Port = new.Port
}
if new.SocketPath != "" {
fc.SocketPath = new.SocketPath
}
if new.Host != common.DefaultHost {
fc.Host = new.Host
}
if new.EnvVarPrefix != common.DefaultEnvVarPrefix {
fc.EnvVarPrefix = new.EnvVarPrefix
}
if new.OfflineFlagSourcePath != "" {
fc.OfflineFlagSourcePath = new.OfflineFlagSourcePath
}
if new.Selector != "" {
fc.Selector = new.Selector
}
if new.Cache != common.DefaultCache {
fc.Cache = new.Cache
}
if new.CacheMaxSize != int(common.DefaultCacheMaxSize) {
fc.CacheMaxSize = new.CacheMaxSize
}
if new.TLS != common.DefaultTLS {
fc.TLS = new.TLS
}
}
func (fc *InProcessConfigurationSpec) ToEnvVars() []corev1.EnvVar {
envs := []corev1.EnvVar{}
for _, envVar := range fc.EnvVars {
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, envVar.Name),
Value: envVar.Value,
})
}
// default values are always included in the envVars
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.HostEnvVar),
Value: fc.Host,
})
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.PortEnvVar),
Value: fmt.Sprintf("%d", fc.Port),
})
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.TLSEnvVar),
Value: fmt.Sprintf("%t", fc.TLS),
})
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.CacheEnvVar),
Value: fc.Cache,
})
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.CacheMaxSizeEnvVar),
Value: fmt.Sprintf("%d", fc.CacheMaxSize),
})
// sets the FLAGD_RESOLVER var to "in-process" to configure the provider for in-process evaluation mode
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.ResolverEnvVar),
Value: common.InProcessResolverType,
})
if fc.SocketPath != "" {
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.SocketPathEnvVar),
Value: fc.SocketPath,
})
}
if fc.OfflineFlagSourcePath != "" {
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.OfflineFlagSourcePathEnvVar),
Value: fc.OfflineFlagSourcePath,
})
}
if fc.Selector != "" {
envs = append(envs, corev1.EnvVar{
Name: common.EnvVarKey(fc.EnvVarPrefix, common.SelectorEnvVar),
Value: fc.Selector,
})
}
return envs
}

View File

@ -1,178 +0,0 @@
package v1beta1
import (
"testing"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
)
func Test_InProcessConfiguration_Merge(t *testing.T) {
ff_old := &InProcessConfiguration{
Spec: InProcessConfigurationSpec{
EnvVars: []v1.EnvVar{
{
Name: "env1",
Value: "val1",
},
{
Name: "env2",
Value: "val2",
},
},
EnvVarPrefix: "PRE",
Port: 33,
SocketPath: "socket-path",
Host: "host",
TLS: true,
OfflineFlagSourcePath: "path1",
Selector: "selector",
Cache: "cache",
CacheMaxSize: 12,
},
}
ff_old.Spec.Merge(nil)
require.Equal(t, &InProcessConfiguration{
Spec: InProcessConfigurationSpec{
EnvVars: []v1.EnvVar{
{
Name: "env1",
Value: "val1",
},
{
Name: "env2",
Value: "val2",
},
},
EnvVarPrefix: "PRE",
Port: 33,
SocketPath: "socket-path",
Host: "host",
TLS: true,
OfflineFlagSourcePath: "path1",
Selector: "selector",
Cache: "cache",
CacheMaxSize: 12,
},
}, ff_old)
ff_new := &InProcessConfiguration{
Spec: InProcessConfigurationSpec{
EnvVars: []v1.EnvVar{
{
Name: "env3",
Value: "val3",
},
},
EnvVarPrefix: "PRE_SECOND",
Port: 33,
SocketPath: "",
Host: "host",
TLS: true,
OfflineFlagSourcePath: "",
Selector: "",
Cache: "lru",
CacheMaxSize: 1000,
},
}
ff_old.Spec.Merge(&ff_new.Spec)
require.Equal(t, ff_old.Spec.EnvVarPrefix, "PRE_SECOND")
require.Equal(t, ff_old.Spec.Port, int32(33))
require.Equal(t, ff_old.Spec.SocketPath, "socket-path")
require.Equal(t, ff_old.Spec.Host, "host")
require.Equal(t, ff_old.Spec.TLS, true)
require.Equal(t, ff_old.Spec.OfflineFlagSourcePath, "path1")
require.Equal(t, ff_old.Spec.Selector, "selector")
require.Equal(t, ff_old.Spec.Cache, "cache")
require.Equal(t, ff_old.Spec.CacheMaxSize, 12)
require.Len(t, ff_old.Spec.EnvVars, 3)
require.Contains(t, ff_old.Spec.EnvVars, v1.EnvVar{
Name: "env1",
Value: "val1",
})
require.Contains(t, ff_old.Spec.EnvVars, v1.EnvVar{
Name: "env2",
Value: "val2",
})
require.Contains(t, ff_old.Spec.EnvVars, v1.EnvVar{
Name: "env3",
Value: "val3",
})
}
func Test_InProcessConfiguration_ToEnvVars(t *testing.T) {
ff := InProcessConfiguration{
Spec: InProcessConfigurationSpec{
EnvVars: []v1.EnvVar{
{
Name: "env1",
Value: "val1",
},
{
Name: "env2",
Value: "val2",
},
},
EnvVarPrefix: "PRE",
Port: 33,
SocketPath: "socket-path",
Host: "host",
TLS: true,
OfflineFlagSourcePath: "path1",
Selector: "selector",
Cache: "cache",
CacheMaxSize: 12,
},
}
expected := []v1.EnvVar{
{
Name: "PRE_env1",
Value: "val1",
},
{
Name: "PRE_env2",
Value: "val2",
},
{
Name: "PRE_HOST",
Value: "host",
},
{
Name: "PRE_PORT",
Value: "33",
},
{
Name: "PRE_TLS",
Value: "true",
},
{
Name: "PRE_CACHE",
Value: "cache",
},
{
Name: "PRE_MAX_CACHE_SIZE",
Value: "12",
},
{
Name: "PRE_RESOLVER",
Value: "in-process",
},
{
Name: "PRE_SOCKET_PATH",
Value: "socket-path",
},
{
Name: "PRE_OFFLINE_FLAG_SOURCE_PATH",
Value: "path1",
},
{
Name: "PRE_SOURCE_SELECTOR",
Value: "selector",
},
}
require.Equal(t, expected, ff.Spec.ToEnvVars())
}

View File

@ -1,589 +0,0 @@
//go:build !ignore_autogenerated
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by controller-gen. DO NOT EDIT.
package v1beta1
import (
"encoding/json"
"k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
apisv1 "sigs.k8s.io/gateway-api/apis/v1"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlag) DeepCopyInto(out *FeatureFlag) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlag.
func (in *FeatureFlag) DeepCopy() *FeatureFlag {
if in == nil {
return nil
}
out := new(FeatureFlag)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FeatureFlag) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagList) DeepCopyInto(out *FeatureFlagList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]FeatureFlag, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagList.
func (in *FeatureFlagList) DeepCopy() *FeatureFlagList {
if in == nil {
return nil
}
out := new(FeatureFlagList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FeatureFlagList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagSource) DeepCopyInto(out *FeatureFlagSource) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagSource.
func (in *FeatureFlagSource) DeepCopy() *FeatureFlagSource {
if in == nil {
return nil
}
out := new(FeatureFlagSource)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FeatureFlagSource) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagSourceList) DeepCopyInto(out *FeatureFlagSourceList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]FeatureFlagSource, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagSourceList.
func (in *FeatureFlagSourceList) DeepCopy() *FeatureFlagSourceList {
if in == nil {
return nil
}
out := new(FeatureFlagSourceList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FeatureFlagSourceList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagSourceSpec) DeepCopyInto(out *FeatureFlagSourceSpec) {
*out = *in
if in.Sources != nil {
in, out := &in.Sources, &out.Sources
*out = make([]Source, len(*in))
copy(*out, *in)
}
if in.EnvVars != nil {
in, out := &in.EnvVars, &out.EnvVars
*out = make([]v1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.SyncProviderArgs != nil {
in, out := &in.SyncProviderArgs, &out.SyncProviderArgs
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.RolloutOnChange != nil {
in, out := &in.RolloutOnChange, &out.RolloutOnChange
*out = new(bool)
**out = **in
}
if in.ProbesEnabled != nil {
in, out := &in.ProbesEnabled, &out.ProbesEnabled
*out = new(bool)
**out = **in
}
if in.DebugLogging != nil {
in, out := &in.DebugLogging, &out.DebugLogging
*out = new(bool)
**out = **in
}
in.Resources.DeepCopyInto(&out.Resources)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagSourceSpec.
func (in *FeatureFlagSourceSpec) DeepCopy() *FeatureFlagSourceSpec {
if in == nil {
return nil
}
out := new(FeatureFlagSourceSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagSourceStatus) DeepCopyInto(out *FeatureFlagSourceStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagSourceStatus.
func (in *FeatureFlagSourceStatus) DeepCopy() *FeatureFlagSourceStatus {
if in == nil {
return nil
}
out := new(FeatureFlagSourceStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagSpec) DeepCopyInto(out *FeatureFlagSpec) {
*out = *in
in.FlagSpec.DeepCopyInto(&out.FlagSpec)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagSpec.
func (in *FeatureFlagSpec) DeepCopy() *FeatureFlagSpec {
if in == nil {
return nil
}
out := new(FeatureFlagSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagStatus) DeepCopyInto(out *FeatureFlagStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagStatus.
func (in *FeatureFlagStatus) DeepCopy() *FeatureFlagStatus {
if in == nil {
return nil
}
out := new(FeatureFlagStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Flag) DeepCopyInto(out *Flag) {
*out = *in
if in.Variants != nil {
in, out := &in.Variants, &out.Variants
*out = make(json.RawMessage, len(*in))
copy(*out, *in)
}
if in.Targeting != nil {
in, out := &in.Targeting, &out.Targeting
*out = make(json.RawMessage, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Flag.
func (in *Flag) DeepCopy() *Flag {
if in == nil {
return nil
}
out := new(Flag)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSpec) DeepCopyInto(out *FlagSpec) {
*out = *in
in.Flags.DeepCopyInto(&out.Flags)
if in.Evaluators != nil {
in, out := &in.Evaluators, &out.Evaluators
*out = make(json.RawMessage, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSpec.
func (in *FlagSpec) DeepCopy() *FlagSpec {
if in == nil {
return nil
}
out := new(FlagSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Flagd) DeepCopyInto(out *Flagd) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Flagd.
func (in *Flagd) DeepCopy() *Flagd {
if in == nil {
return nil
}
out := new(Flagd)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Flagd) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagdList) DeepCopyInto(out *FlagdList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Flagd, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagdList.
func (in *FlagdList) DeepCopy() *FlagdList {
if in == nil {
return nil
}
out := new(FlagdList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FlagdList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagdSpec) DeepCopyInto(out *FlagdSpec) {
*out = *in
if in.Replicas != nil {
in, out := &in.Replicas, &out.Replicas
*out = new(int32)
**out = **in
}
in.Ingress.DeepCopyInto(&out.Ingress)
in.GatewayApiRoutes.DeepCopyInto(&out.GatewayApiRoutes)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagdSpec.
func (in *FlagdSpec) DeepCopy() *FlagdSpec {
if in == nil {
return nil
}
out := new(FlagdSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagdStatus) DeepCopyInto(out *FlagdStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagdStatus.
func (in *FlagdStatus) DeepCopy() *FlagdStatus {
if in == nil {
return nil
}
out := new(FlagdStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Flags) DeepCopyInto(out *Flags) {
*out = *in
if in.FlagsMap != nil {
in, out := &in.FlagsMap, &out.FlagsMap
*out = make(map[string]Flag, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Flags.
func (in *Flags) DeepCopy() *Flags {
if in == nil {
return nil
}
out := new(Flags)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GatewayApiSpec) DeepCopyInto(out *GatewayApiSpec) {
*out = *in
if in.Annotations != nil {
in, out := &in.Annotations, &out.Annotations
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.Hosts != nil {
in, out := &in.Hosts, &out.Hosts
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.ParentRefs != nil {
in, out := &in.ParentRefs, &out.ParentRefs
*out = make([]apisv1.ParentReference, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayApiSpec.
func (in *GatewayApiSpec) DeepCopy() *GatewayApiSpec {
if in == nil {
return nil
}
out := new(GatewayApiSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InProcessConfiguration) DeepCopyInto(out *InProcessConfiguration) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InProcessConfiguration.
func (in *InProcessConfiguration) DeepCopy() *InProcessConfiguration {
if in == nil {
return nil
}
out := new(InProcessConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *InProcessConfiguration) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InProcessConfigurationList) DeepCopyInto(out *InProcessConfigurationList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]InProcessConfiguration, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InProcessConfigurationList.
func (in *InProcessConfigurationList) DeepCopy() *InProcessConfigurationList {
if in == nil {
return nil
}
out := new(InProcessConfigurationList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *InProcessConfigurationList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InProcessConfigurationSpec) DeepCopyInto(out *InProcessConfigurationSpec) {
*out = *in
if in.EnvVars != nil {
in, out := &in.EnvVars, &out.EnvVars
*out = make([]v1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InProcessConfigurationSpec.
func (in *InProcessConfigurationSpec) DeepCopy() *InProcessConfigurationSpec {
if in == nil {
return nil
}
out := new(InProcessConfigurationSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InProcessConfigurationStatus) DeepCopyInto(out *InProcessConfigurationStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InProcessConfigurationStatus.
func (in *InProcessConfigurationStatus) DeepCopy() *InProcessConfigurationStatus {
if in == nil {
return nil
}
out := new(InProcessConfigurationStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IngressSpec) DeepCopyInto(out *IngressSpec) {
*out = *in
if in.Annotations != nil {
in, out := &in.Annotations, &out.Annotations
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.Hosts != nil {
in, out := &in.Hosts, &out.Hosts
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.TLS != nil {
in, out := &in.TLS, &out.TLS
*out = make([]networkingv1.IngressTLS, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.IngressClassName != nil {
in, out := &in.IngressClassName, &out.IngressClassName
*out = new(string)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressSpec.
func (in *IngressSpec) DeepCopy() *IngressSpec {
if in == nil {
return nil
}
out := new(IngressSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Source) DeepCopyInto(out *Source) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Source.
func (in *Source) DeepCopy() *Source {
if in == nil {
return nil
}
out := new(Source)
in.DeepCopyInto(out)
return out
}

View File

@ -1,75 +0,0 @@
module github.com/open-feature/open-feature-operator/apis
go 1.23.0
toolchain go1.23.3
require (
github.com/open-feature/flagd-schemas v0.2.9-0.20250529171004-2852d7772e6b
github.com/stretchr/testify v1.10.0
github.com/xeipuuv/gojsonschema v1.2.0
k8s.io/api v0.32.3
k8s.io/apimachinery v0.32.3
sigs.k8s.io/controller-runtime v0.20.1
sigs.k8s.io/gateway-api v1.2.1
)
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.20.5 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/oauth2 v0.25.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/term v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.9.0 // indirect
golang.org/x/tools v0.29.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/protobuf v1.36.4 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.32.1 // indirect
k8s.io/client-go v0.32.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect
k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

View File

@ -1,198 +0,0 @@
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU=
github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI=
github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg=
github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0 h1:my2ucqBZmv+cWHIhZNSIYKzgN8EBGyHdC7zD5sASRAg=
github.com/google/pprof v0.0.0-20250125003558-7fdb3d7e6fa0/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/open-feature/flagd-schemas v0.2.9-0.20240708163558-2aa89b314322 h1:5zbNHqcZAc9jlhSrC0onuVL2RPpvYcDaNvW2wOZBfUY=
github.com/open-feature/flagd-schemas v0.2.9-0.20240708163558-2aa89b314322/go.mod h1:WKtwo1eW9/K6D+4HfgTXWBqCDzpvMhDa5eRxW7R5B2U=
github.com/open-feature/flagd-schemas v0.2.9-0.20250127221449-bb763438abc5/go.mod h1:WKtwo1eW9/K6D+4HfgTXWBqCDzpvMhDa5eRxW7R5B2U=
github.com/open-feature/flagd-schemas v0.2.9-0.20250529171004-2852d7772e6b/go.mod h1:WKtwo1eW9/K6D+4HfgTXWBqCDzpvMhDa5eRxW7R5B2U=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc=
k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k=
k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls=
k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k=
k8s.io/apiextensions-apiserver v0.32.1 h1:hjkALhRUeCariC8DiVmb5jj0VjIc1N0DREP32+6UXZw=
k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto=
k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs=
k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU=
k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg=
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas=
k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.20.1 h1:JbGMAG/X94NeM3xvjenVUaBjy6Ui4Ogd/J5ZtjZnHaE=
sigs.k8s.io/controller-runtime v0.20.1/go.mod h1:BrP3w158MwvB3ZbNpaAcIKkHQ7YGpYnzpoSTZ8E14WU=
sigs.k8s.io/gateway-api v1.2.1 h1:fZZ/+RyRb+Y5tGkwxFKuYuSRQHu9dZtbjenblleOLHM=
sigs.k8s.io/gateway-api v1.2.1/go.mod h1:EpNfEXNjiYfUJypf0eZ0P5iXA9ekSGWaS1WgPaM42X0=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk=
sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

View File

@ -17,21 +17,24 @@ limitations under the License.
package v1alpha1
import (
"github.com/open-feature/open-feature-operator/pkg/utils"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// FeatureFlagConfigurationSpec defines the desired state of FeatureFlagConfiguration
type FeatureFlagConfigurationSpec struct {
// ServiceProvider [DEPRECATED]: superseded by FlagSourceConfiguration
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// +optional
// +nullable
ServiceProvider *FeatureFlagServiceProvider `json:"serviceProvider"`
// SyncProvider [DEPRECATED]: superseded by FlagSourceConfiguration
// +optional
// +nullable
SyncProvider *FeatureFlagSyncProvider `json:"syncProvider"`
// FlagDSpec [DEPRECATED]: superseded by FlagSourceConfiguration
// +optional
// +nullable
FlagDSpec *FlagDSpec `json:"flagDSpec"`
@ -48,17 +51,10 @@ type FlagDSpec struct {
type FeatureFlagSyncProvider struct {
Name string `json:"name"`
// +optional
// +nullable
HttpSyncConfiguration *HttpSyncConfiguration `json:"httpSyncConfiguration"`
}
// HttpSyncConfiguration defines the desired configuration for a http sync
type HttpSyncConfiguration struct {
// Target is the target url for flagd to poll
Target string `json:"target"`
// +optional
BearerToken string `json:"bearerToken,omitempty"`
func (ffsp FeatureFlagSyncProvider) IsKubernetes() bool {
return ffsp.Name == "kubernetes"
}
type FeatureFlagServiceProvider struct {
@ -71,11 +67,12 @@ type FeatureFlagServiceProvider struct {
// FeatureFlagConfigurationStatus defines the observed state of FeatureFlagConfiguration
type FeatureFlagConfigurationStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:storageversion
// FeatureFlagConfiguration is the Schema for the featureflagconfigurations API
type FeatureFlagConfiguration struct {
@ -98,3 +95,29 @@ type FeatureFlagConfigurationList struct {
func init() {
SchemeBuilder.Register(&FeatureFlagConfiguration{}, &FeatureFlagConfigurationList{})
}
func GetFfReference(ff *FeatureFlagConfiguration) metav1.OwnerReference {
return metav1.OwnerReference{
APIVersion: ff.APIVersion,
Kind: ff.Kind,
Name: ff.Name,
UID: ff.UID,
Controller: utils.TrueVal(),
}
}
func GenerateFfConfigMap(name string, namespace string, references []metav1.OwnerReference, spec FeatureFlagConfigurationSpec) corev1.ConfigMap {
return corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Annotations: map[string]string{
"openfeature.dev/featureflagconfiguration": name,
},
OwnerReferences: references,
},
Data: map[string]string{
"config.json": spec.FeatureFlagSpec,
},
}
}

View File

@ -1,4 +1,5 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 2022.
@ -95,7 +96,7 @@ func (in *FeatureFlagConfigurationSpec) DeepCopyInto(out *FeatureFlagConfigurati
if in.SyncProvider != nil {
in, out := &in.SyncProvider, &out.SyncProvider
*out = new(FeatureFlagSyncProvider)
(*in).DeepCopyInto(*out)
**out = **in
}
if in.FlagDSpec != nil {
in, out := &in.FlagDSpec, &out.FlagDSpec
@ -152,11 +153,6 @@ func (in *FeatureFlagServiceProvider) DeepCopy() *FeatureFlagServiceProvider {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FeatureFlagSyncProvider) DeepCopyInto(out *FeatureFlagSyncProvider) {
*out = *in
if in.HttpSyncConfiguration != nil {
in, out := &in.HttpSyncConfiguration, &out.HttpSyncConfiguration
*out = new(HttpSyncConfiguration)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureFlagSyncProvider.
@ -190,155 +186,3 @@ func (in *FlagDSpec) DeepCopy() *FlagDSpec {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSourceConfiguration) DeepCopyInto(out *FlagSourceConfiguration) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfiguration.
func (in *FlagSourceConfiguration) DeepCopy() *FlagSourceConfiguration {
if in == nil {
return nil
}
out := new(FlagSourceConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FlagSourceConfiguration) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSourceConfigurationList) DeepCopyInto(out *FlagSourceConfigurationList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]FlagSourceConfiguration, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfigurationList.
func (in *FlagSourceConfigurationList) DeepCopy() *FlagSourceConfigurationList {
if in == nil {
return nil
}
out := new(FlagSourceConfigurationList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *FlagSourceConfigurationList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSourceConfigurationSpec) DeepCopyInto(out *FlagSourceConfigurationSpec) {
*out = *in
if in.SyncProviderArgs != nil {
in, out := &in.SyncProviderArgs, &out.SyncProviderArgs
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Sources != nil {
in, out := &in.Sources, &out.Sources
*out = make([]Source, len(*in))
copy(*out, *in)
}
if in.EnvVars != nil {
in, out := &in.EnvVars, &out.EnvVars
*out = make([]v1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.RolloutOnChange != nil {
in, out := &in.RolloutOnChange, &out.RolloutOnChange
*out = new(bool)
**out = **in
}
if in.ProbesEnabled != nil {
in, out := &in.ProbesEnabled, &out.ProbesEnabled
*out = new(bool)
**out = **in
}
if in.DebugLogging != nil {
in, out := &in.DebugLogging, &out.DebugLogging
*out = new(bool)
**out = **in
}
in.Resources.DeepCopyInto(&out.Resources)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfigurationSpec.
func (in *FlagSourceConfigurationSpec) DeepCopy() *FlagSourceConfigurationSpec {
if in == nil {
return nil
}
out := new(FlagSourceConfigurationSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FlagSourceConfigurationStatus) DeepCopyInto(out *FlagSourceConfigurationStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagSourceConfigurationStatus.
func (in *FlagSourceConfigurationStatus) DeepCopy() *FlagSourceConfigurationStatus {
if in == nil {
return nil
}
out := new(FlagSourceConfigurationStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HttpSyncConfiguration) DeepCopyInto(out *HttpSyncConfiguration) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HttpSyncConfiguration.
func (in *HttpSyncConfiguration) DeepCopy() *HttpSyncConfiguration {
if in == nil {
return nil
}
out := new(HttpSyncConfiguration)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Source) DeepCopyInto(out *Source) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Source.
func (in *Source) DeepCopy() *Source {
if in == nil {
return nil
}
out := new(Source)
in.DeepCopyInto(out)
return out
}

View File

@ -1,5 +1,5 @@
apiVersion: v2
name: open-feature-operator
name: ofo
description: A feature flag operator for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
@ -13,29 +13,9 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: "v0.8.7" # x-release-please-version
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "v0.8.7" # x-release-please-version
home: https://openfeature.dev
icon: https://open-feature.github.io/open-feature-operator/chart/open-feature-operator/openfeature-logo.png
keywords:
- OpenFeature
- feature flags
- feature toggles
- OpenFeature Operator
- open feature
- open feature operator
- OFO
sources:
- https://github.com/open-feature/open-feature-operator
annotations:
artifacthub.io/operator: "true"
artifacthub.io/category: "integration-delivery"
artifacthub.io/links: |
- name: support
url: https://github.com/open-feature/open-feature-operator/issues
appVersion: "v0.2.18" # x-release-please-version

View File

@ -1,6 +0,0 @@
# ignore generated templates
templates/*.yaml
templates/crds/*.yaml
# the following files are not generated, they are special cases
!templates/namespace.yaml
!templates/admissionregistration.k8s.io_v1_validatingwebhookconfiguration_open-feature-operator-validating-webhook-configuration.yaml

View File

@ -1,195 +0,0 @@
# OpenFeature Operator
## TL;DR
> This helm chart has a dependency on [cert manager](https://cert-manager.io/docs/installation/)
```
helm repo add openfeature https://open-feature.github.io/open-feature-operator/
helm repo update
helm upgrade --install open-feature-operator openfeature/open-feature-operator
```
## Introduction
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.
The full documentation for this project can be found here: [OpenFeature Operator](https://github.com/open-feature/open-feature-operator/tree/main/docs)
## Prerequisites
The OpenFeature Operator requires [cert manager](https://cert-manager.io/docs/installation/) to be installed on the target cluster.
## Install
To install the chart with the release name `open-feature-operator`:
```
helm repo add openfeature https://open-feature.github.io/open-feature-operator/
helm repo update
helm upgrade --install 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
```
## Upgrade
To install the chart with the release name `open-feature-operator`:
```sh
helm repo update
helm upgrade --install open-feature-operator openfeature/open-feature-operator
```
> [!NOTE]
> If you upgrade to OFO `v0.5.4` or higher while using a `flagd-proxy` provider, the instance of
`flagd-proxy` will be automatically upgraded to the latest supported version by the `open-feature-operator`.
The upgrade of `flagd-proxy` will also consider your current `FeatureFlagSource` configuration and adapt
the `flagd-proxy` Deployment accordingly.
If you are upgrading OFO to `v0.5.3` or lower, `flagd-proxy` (if present) won't be upgraded automatically.
#### Upgrade CRDs
CRDs are not upgraded automatically with helm (https://helm.sh/docs/chart_best_practices/custom_resource_definitions/).
OpenFeature Operator's CRDs are templated, and can be updated apart from the operator itself by using helm's template functionality and piping the output to `kubectl`:
```console
helm template openfeature/open-feature-operator -s templates/{CRD} | kubectl apply -f -
```
For the `featureflags.core.openfeature.dev` CRD:
```sh
helm template openfeature/open-feature-operator -s templates/apiextensions.k8s.io_v1_customresourcedefinition_featureflags.core.openfeature.dev.yaml | kubectl apply -f -
```
For the `featureflagsources.core.openfeature.dev` CRD:
```sh
helm template openfeature/open-feature-operator -s templates/apiextensions.k8s.io_v1_customresourcedefinition_featureflagsources.core.openfeature.dev.yaml | kubectl apply -f -
```
Keep in mind, you can set values as usual during this process:
```console
helm template openfeature/open-feature-operator -s templates/{CRD} --set defaultNamespace=myns | kubectl apply -f -
```
## Uninstall
To uninstall the `open-feature-operator`:
```
helm uninstall open-feature-operator
```
The command removes all the Kubernetes components associated with the chart and deletes the release.
## Configuration
### Global
| Name | Description | Value |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------ |
| `defaultNamespace` | 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. | `open-feature-operator-system` |
### namespace
| Name | Description | Value |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
| `namespace.create` | Whether to create the namespace as part of this chart. | `true` |
| `namespace.labels` | Labels for the namespace if created as part of the chart. | `{}` |
| `namespace.annotations` | Annotations for the namespace if created as part of the chart. | `{}` |
| `imagePullSecrets` | Array of ImagePullSecret objects containing credentials for images pulled by the operator (flagdProxyConfiguration.image, flagdConfiguration.image, controllerManager.manager.image). Example: imagePullSecrets: [{"name": "my-secret"}] | `[]` |
| `labels` | Labels to apply to all of the pods in the operator. | `{}` |
| `annotations` | Annotations to apply to all of the pods in the operator. | `{}` |
### Mutating Webhook configuration
| Name | Description | Value |
| -------------------------------- | --------------------------------------------------------- | -------- |
| `mutatingWebhook.failurePolicy` | FailurePolicy when the webhook does not respond | `Ignore` |
| `mutatingWebhook.objectSelector` | ObjectSelector on which pods the mutatingWebhook will run | `{}` |
### Sidecar configuration
| Name | Description | Value |
| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
| `sidecarConfiguration.port` | Sets the value of the `XXX_PORT` environment variable for the injected sidecar. | `8013` |
| `sidecarConfiguration.managementPort` | Sets the value of the `XXX_MANAGEMENT_PORT` environment variable for the injected sidecar. | `8014` |
| `sidecarConfiguration.socketPath` | Sets the value of the `XXX_SOCKET_PATH` environment variable for the injected sidecar. | `""` |
| `sidecarConfiguration.image.repository` | Sets the image for the injected sidecar. | `ghcr.io/open-feature/flagd` |
| `sidecarConfiguration.image.tag` | Sets the version tag for the injected sidecar. | `v0.12.4` |
| `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`. | `""` |
| `sidecarConfiguration.envVarPrefix` | Sets the prefix for all environment variables set in the injected sidecar. | `FLAGD` |
| `sidecarConfiguration.defaultSyncProvider` | Sets the value of the `XXX_SYNC_PROVIDER` environment variable for the injected sidecar container. There are 4 valid sync providers: `kubernetes`, `grpc`, `file` and `http`. | `kubernetes` |
| `sidecarConfiguration.evaluator` | Sets the value of the `XXX_EVALUATOR` environment variable for the injected sidecar container. | `json` |
| `sidecarConfiguration.logFormat` | Sets the value of the `XXX_LOG_FORMAT` environment variable for the injected sidecar container. There are 2 valid log formats: `json` and `console`. | `json` |
| `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.limits.cpu` | Sets cpu resource limits for kube-rbac-proxy. | `500m` |
| `sidecarConfiguration.resources.limits.memory` | Sets memory resource limits for kube-rbac-proxy. | `64Mi` |
| `sidecarConfiguration.resources.requests.cpu` | Sets cpu resource requests for kube-rbac-proxy. | `200m` |
| `sidecarConfiguration.resources.requests.memory` | Sets memory resource requests for kube-rbac-proxy. | `32Mi` |
### In-process configuration
| Name | Description | Value |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------- |
| `inProcessConfiguration.port` | Sets the value of the `XXX_PORT` environment variable for the pod containers. | `8015` |
| `inProcessConfiguration.host` | Sets the value of the `XXX_HOST` environment variable for the pod containers. | `localhost` |
| `inProcessConfiguration.socketPath` | Sets the value of the `XXX_SOCKET_PATH` environment variable for the pod containers. | `""` |
| `inProcessConfiguration.tls` | Sets the value of the `XXX_TLS` environment variable for the pod containers. | `false` |
| `inProcessConfiguration.offlineFlagSourcePath` | Sets the value of the `XXX_OFFLINE_FLAG_SOURCE_PATH` environment variable for the pod containers. | `""` |
| `inProcessConfiguration.selector` | Sets the value of the `XXX_SELECTOR` environment variable for the pod containers. | `""` |
| `inProcessConfiguration.envVarPrefix` | Sets the value of the `XXX_ENV_VAR_PREFIX` environment variable for the pod containers. | `FLAGD` |
| `inProcessConfiguration.cache.type` | Sets the value of the `XXX_CACHE` environment variable for the pod containers. | `lru` |
| `inProcessConfiguration.cache.size` | Sets the value of the `XXX_CACHE_MAX_SIZE` environment variable for the pod containers. | `1000` |
### Flagd-proxy configuration
| Name | Description | Value |
| ------------------------------------------ | ------------------------------------------------------------------------------- | ---------------------------------- |
| `flagdProxyConfiguration.replicaCount` | sets the number of replicas for the flagd-proxy deployment. | `1` |
| `flagdProxyConfiguration.port` | Sets the port to expose the sync API on. | `8015` |
| `flagdProxyConfiguration.managementPort` | Sets the port to expose the management API on. | `8016` |
| `flagdProxyConfiguration.image.repository` | Sets the image for the flagd-proxy deployment. | `ghcr.io/open-feature/flagd-proxy` |
| `flagdProxyConfiguration.image.tag` | Sets the tag for the flagd-proxy deployment. | `v0.7.4` |
| `flagdProxyConfiguration.debugLogging` | Controls the addition of the `--debug` flag to the container startup arguments. | `false` |
### Flagd configuration
| Name | Description | Value |
| ------------------------------------- | ------------------------------------------------------------------------------- | ---------------------------- |
| `flagdConfiguration.port` | Sets the port to expose the flagd API on. | `8013` |
| `flagdConfiguration.ofrepPort` | Sets the port to expose the ofrep API on. | `8016` |
| `flagdConfiguration.syncPort` | Sets the port to expose the sync API on. | `8015` |
| `flagdConfiguration.managementPort` | Sets the port to expose the management API on. | `8014` |
| `flagdConfiguration.image.repository` | Sets the image for the flagd deployment. | `ghcr.io/open-feature/flagd` |
| `flagdConfiguration.image.tag` | Sets the tag for the flagd deployment. | `v0.12.4` |
| `flagdConfiguration.debugLogging` | Controls the addition of the `--debug` flag to the container startup arguments. | `false` |
### Operator resource configuration
| Name | Description | Value |
| ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| `controllerManager.manager.image.repository` | Sets the image for the operator. | `ghcr.io/open-feature/open-feature-operator` |
| `controllerManager.manager.image.tag` | Sets the version tag for the operator. | `v0.8.7` |
| `controllerManager.manager.resources.limits.cpu` | Sets cpu resource limits for operator. | `500m` |
| `controllerManager.manager.resources.limits.memory` | Sets memory resource limits for operator. | `128Mi` |
| `controllerManager.manager.resources.requests.cpu` | Sets cpu resource requests for operator. | `10m` |
| `controllerManager.manager.resources.requests.memory` | Sets memory resource requests for operator. | `64Mi` |
| `controllerManager.manager.hostNetwork` | Should the injector pods run on the host network (useful when using an alternate CNI in EKS) | `false` |
| `controllerManager.manager.dnsPolicy` | Pod DNS resolution scheme. Should be `ClusterFirstWithHostNet` if hostNetwork is true, `ClusterFirst` otherwise. | `ClusterFirst` |
| `controllerManager.replicas` | Sets number of replicas of the OpenFeature operator pod. | `1` |
| `managerConfig.flagsValidationEnabled` | Enables the validating webhook for FeatureFlag CR. | `true` |
| `managerConfig.controllerManagerConfigYaml.health.healthProbeBindAddress` | Sets the bind address for health probes. | `:8081` |
| `managerConfig.controllerManagerConfigYaml.metrics.bindAddress` | Sets the bind address for metrics (combined with bindPort). | `127.0.0.1` |
| `managerConfig.controllerManagerConfigYaml.metrics.bindPort` | Sets the bind port for metrics. | `8080` |
| `managerConfig.controllerManagerConfigYaml.webhook.port` | Sets the bind address for webhook. | `9443` |

View File

@ -1,22 +0,0 @@
{
"comments": {
"format": "##"
},
"tags": {
"param": "@param",
"section": "@section",
"descriptionStart": "@descriptionStart",
"descriptionEnd": "@descriptionEnd",
"skip": "@skip",
"extra": "@extra"
},
"modifiers": {
"array": "array",
"object": "object",
"string": "string",
"nullable": "nullable"
},
"regexp": {
"paramsSectionTitle": "Configuration"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,11 +0,0 @@
. ___ ___ _
/ _ \ _ __ ___ _ _ | __| ___ __ _ | |_ _ _ _ _ ___
| (_) | | '_ \ / -_) | ' \ | _| / -_) / _` | | _| | || | | '_| / -_)
\___/ | .__/ \___| |_||_| |_| \___| \__,_| \__| \_,_| |_| \___|
|_|
Thank you for installing {{ .Chart.Name }}.
Your release version is {{ .Chart.AppVersion }}.
Documentation and configuration options can be found here: https://github.com/open-feature/open-feature-operator

View File

@ -1,29 +0,0 @@
{{ if eq .Values.managerConfig.flagsValidationEnabled "true" }}
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
annotations:
cert-manager.io/inject-ca-from: '{{ include "chart.namespace" . }}/open-feature-operator-serving-cert'
name: open-feature-operator-validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: open-feature-operator-webhook-service
namespace: '{{ include "chart.namespace" . }}'
path: /validate-core-openfeature-dev-v1beta1-featureflag
failurePolicy: Fail
name: vfeatureflag.kb.io
rules:
- apiGroups:
- core.openfeature.dev
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- featureflags
sideEffects: None
{{ end }}

View File

@ -1,17 +0,0 @@
# Only deploy the namespace if the default is being used (helm install should fail if the namespace isnt present)
# when one is defined with -n
{{- if and (eq (include "chart.namespace" .) .Values.defaultNamespace) .Values.namespace.create }}
apiVersion: v1
kind: Namespace
metadata:
name: '{{ include "chart.namespace" . }}'
labels:
control-plane: controller-manager
{{- range $key, $value := $.Values.namespace.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
annotations:
{{- range $key, $value := $.Values.namespace.annotations }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{ end }}

View File

@ -1,165 +0,0 @@
# If this namespace is changed the value must be reflected in /open-feature-operator/values.yaml
## @section Global
## @param defaultNamespace 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.
defaultNamespace: open-feature-operator-system
## @section namespace
namespace:
## @param namespace.create Whether to create the namespace as part of this chart.
create: true
## @param namespace.labels Labels for the namespace if created as part of the chart.
labels: {}
## @param namespace.annotations Annotations for the namespace if created as part of the chart.
annotations: {}
## @param imagePullSecrets Array of ImagePullSecret objects containing credentials for images pulled by the operator (flagdProxyConfiguration.image, flagdConfiguration.image, controllerManager.manager.image). Example: imagePullSecrets: [{"name": "my-secret"}]
imagePullSecrets: []
## @param labels Labels to apply to all of the pods in the operator.
labels: {}
## @param annotations Annotations to apply to all of the pods in the operator.
annotations: {}
## @section Mutating Webhook configuration
mutatingWebhook:
## @param mutatingWebhook.failurePolicy FailurePolicy when the webhook does not respond
failurePolicy: Ignore
## @param mutatingWebhook.objectSelector ObjectSelector on which pods the mutatingWebhook will run
objectSelector: {}
## @section Sidecar configuration
sidecarConfiguration:
## @param sidecarConfiguration.port Sets the value of the `XXX_PORT` environment variable for the injected sidecar.
port: 8013
## @param sidecarConfiguration.managementPort Sets the value of the `XXX_MANAGEMENT_PORT` environment variable for the injected sidecar.
managementPort: 8014
## @param sidecarConfiguration.socketPath Sets the value of the `XXX_SOCKET_PATH` environment variable for the injected sidecar.
socketPath: ""
image:
# these fields must remain in the same order, renovate uses a regex to update the tag value
## @param sidecarConfiguration.image.repository Sets the image for the injected sidecar.
repository: "ghcr.io/open-feature/flagd"
## @param sidecarConfiguration.image.tag Sets the version tag for the injected sidecar.
tag: v0.12.4
## @param 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`.
providerArgs: ""
## @param sidecarConfiguration.envVarPrefix Sets the prefix for all environment variables set in the injected sidecar.
envVarPrefix: "FLAGD"
## @param sidecarConfiguration.defaultSyncProvider Sets the value of the `XXX_SYNC_PROVIDER` environment variable for the injected sidecar container. There are 4 valid sync providers: `kubernetes`, `grpc`, `file` and `http`.
defaultSyncProvider: kubernetes
## @param sidecarConfiguration.evaluator Sets the value of the `XXX_EVALUATOR` environment variable for the injected sidecar container.
evaluator: json
## @param sidecarConfiguration.logFormat Sets the value of the `XXX_LOG_FORMAT` environment variable for the injected sidecar container. There are 2 valid log formats: `json` and `console`.
logFormat: "json"
## @param 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.
probesEnabled: true
## @param sidecarConfiguration.debugLogging Controls the addition of the `--debug` flag to the container startup arguments.
debugLogging: false
## @param sidecarConfiguration.otelCollectorUri Otel exporter uri.
otelCollectorUri: ""
resources:
limits:
## @param sidecarConfiguration.resources.limits.cpu Sets cpu resource limits for kube-rbac-proxy.
cpu: 500m
## @param sidecarConfiguration.resources.limits.memory Sets memory resource limits for kube-rbac-proxy.
memory: 64Mi
requests:
## @param sidecarConfiguration.resources.requests.cpu Sets cpu resource requests for kube-rbac-proxy.
cpu: 200m
## @param sidecarConfiguration.resources.requests.memory Sets memory resource requests for kube-rbac-proxy.
memory: 32Mi
## @section In-process configuration
inProcessConfiguration:
## @param inProcessConfiguration.port Sets the value of the `XXX_PORT` environment variable for the pod containers.
port: 8015
## @param inProcessConfiguration.host Sets the value of the `XXX_HOST` environment variable for the pod containers.
host: "localhost"
## @param inProcessConfiguration.socketPath Sets the value of the `XXX_SOCKET_PATH` environment variable for the pod containers.
socketPath: ""
## @param inProcessConfiguration.tls Sets the value of the `XXX_TLS` environment variable for the pod containers.
tls: "false"
## @param inProcessConfiguration.offlineFlagSourcePath Sets the value of the `XXX_OFFLINE_FLAG_SOURCE_PATH` environment variable for the pod containers.
offlineFlagSourcePath: ""
## @param inProcessConfiguration.selector Sets the value of the `XXX_SELECTOR` environment variable for the pod containers.
selector: ""
## @param inProcessConfiguration.envVarPrefix Sets the value of the `XXX_ENV_VAR_PREFIX` environment variable for the pod containers.
envVarPrefix: "FLAGD"
cache:
## @param inProcessConfiguration.cache.type Sets the value of the `XXX_CACHE` environment variable for the pod containers.
type: "lru"
## @param inProcessConfiguration.cache.size Sets the value of the `XXX_CACHE_MAX_SIZE` environment variable for the pod containers.
size: 1000
## @section Flagd-proxy configuration
flagdProxyConfiguration:
## @param flagdProxyConfiguration.replicaCount sets the number of replicas for the flagd-proxy deployment.
replicaCount: 1
## @param flagdProxyConfiguration.port Sets the port to expose the sync API on.
port: 8015
## @param flagdProxyConfiguration.managementPort Sets the port to expose the management API on.
managementPort: 8016
image:
## @param flagdProxyConfiguration.image.repository Sets the image for the flagd-proxy deployment.
repository: "ghcr.io/open-feature/flagd-proxy"
## @param flagdProxyConfiguration.image.tag Sets the tag for the flagd-proxy deployment.
tag: v0.7.4
## @param flagdProxyConfiguration.debugLogging Controls the addition of the `--debug` flag to the container startup arguments.
debugLogging: false
## @section Flagd configuration
flagdConfiguration:
## @param flagdConfiguration.port Sets the port to expose the flagd API on.
port: 8013
## @param flagdConfiguration.ofrepPort Sets the port to expose the ofrep API on.
ofrepPort: 8016
## @param flagdConfiguration.syncPort Sets the port to expose the sync API on.
syncPort: 8015
## @param flagdConfiguration.managementPort Sets the port to expose the management API on.
managementPort: 8014
image:
## @param flagdConfiguration.image.repository Sets the image for the flagd deployment.
repository: "ghcr.io/open-feature/flagd"
## @param flagdConfiguration.image.tag Sets the tag for the flagd deployment.
tag: v0.12.4
## @param flagdConfiguration.debugLogging Controls the addition of the `--debug` flag to the container startup arguments.
debugLogging: false
## @section Operator resource configuration
controllerManager:
manager:
image:
## @param controllerManager.manager.image.repository Sets the image for the operator.
repository: ghcr.io/open-feature/open-feature-operator
## @param controllerManager.manager.image.tag Sets the version tag for the operator.
tag: v0.8.7 # x-release-please-version
resources:
limits:
## @param controllerManager.manager.resources.limits.cpu Sets cpu resource limits for operator.
cpu: 500m
## @param controllerManager.manager.resources.limits.memory Sets memory resource limits for operator.
memory: 128Mi
requests:
## @param controllerManager.manager.resources.requests.cpu Sets cpu resource requests for operator.
cpu: 10m
## @param controllerManager.manager.resources.requests.memory Sets memory resource requests for operator.
memory: 64Mi
## @param controllerManager.manager.hostNetwork Should the injector pods run on the host network (useful when using an alternate CNI in EKS)
hostNetwork: false
## @param controllerManager.manager.dnsPolicy Pod DNS resolution scheme. Should be `ClusterFirstWithHostNet` if hostNetwork is true, `ClusterFirst` otherwise.
dnsPolicy: ClusterFirst
## @param controllerManager.replicas Sets number of replicas of the OpenFeature operator pod.
replicas: 1
managerConfig:
## @param managerConfig.flagsValidationEnabled Enables the validating webhook for FeatureFlag CR.
flagsValidationEnabled: "true"
controllerManagerConfigYaml:
health:
## @param managerConfig.controllerManagerConfigYaml.health.healthProbeBindAddress Sets the bind address for health probes.
healthProbeBindAddress: :8081
metrics:
## @param managerConfig.controllerManagerConfigYaml.metrics.bindAddress Sets the bind address for metrics (combined with bindPort).
bindAddress: 127.0.0.1
## @param managerConfig.controllerManagerConfigYaml.metrics.bindPort Sets the bind port for metrics.
bindPort: 8080
webhook:
## @param managerConfig.controllerManagerConfigYaml.webhook.port Sets the bind address for webhook.
port: 9443

View File

@ -0,0 +1,10 @@
# Only deploy the namespace if the default is being used (helm install should fail if the namespace isnt present)
# when one is defined with -n
{{ if eq ( include "chart.namespace" . ) .Values.defaultNamespace }}
apiVersion: v1
kind: Namespace
metadata:
labels:
control-plane: controller-manager
name: '{{ include "chart.namespace" . }}'
{{ end }}

View File

@ -0,0 +1,683 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: featureflagconfigurations.core.openfeature.dev
spec:
group: core.openfeature.dev
names:
kind: FeatureFlagConfiguration
listKind: FeatureFlagConfigurationList
plural: featureflagconfigurations
singular: featureflagconfiguration
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: FeatureFlagConfiguration is the Schema for the featureflagconfigurations
API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: FeatureFlagConfigurationSpec defines the desired state of
FeatureFlagConfiguration
properties:
featureFlagSpec:
description: FeatureFlagSpec is the json representation of the feature
flag
type: string
flagDSpec:
nullable: true
properties:
envs:
items:
description: EnvVar represents an environment variable present
in a Container.
properties:
name:
description: Name of the environment variable. Must be a
C_IDENTIFIER.
type: string
value:
description: 'Variable references $(VAR_NAME) are expanded
using the previously defined environment variables in
the container and any service environment variables. If
a variable cannot be resolved, the reference in the input
string will be unchanged. Double $$ are reduced to a single
$, which allows for escaping the $(VAR_NAME) syntax: i.e.
"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
Escaped references will never be expanded, regardless
of whether the variable exists or not. Defaults to "".'
type: string
valueFrom:
description: Source for the environment variable's value.
Cannot be used if value is not empty.
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind,
uid?'
type: string
optional:
description: Specify whether the ConfigMap or its
key must be defined
type: boolean
required:
- key
type: object
fieldRef:
description: 'Selects a field of the pod: supports metadata.name,
metadata.namespace, `metadata.labels[''<KEY>'']`,
`metadata.annotations[''<KEY>'']`, spec.nodeName,
spec.serviceAccountName, status.hostIP, status.podIP,
status.podIPs.'
properties:
apiVersion:
description: Version of the schema the FieldPath
is written in terms of, defaults to "v1".
type: string
fieldPath:
description: Path of the field to select in the
specified API version.
type: string
required:
- fieldPath
type: object
resourceFieldRef:
description: 'Selects a resource of the container: only
resources limits and requests (limits.cpu, limits.memory,
limits.ephemeral-storage, requests.cpu, requests.memory
and requests.ephemeral-storage) are currently supported.'
properties:
containerName:
description: 'Container name: required for volumes,
optional for env vars'
type: string
divisor:
anyOf:
- type: integer
- type: string
description: Specifies the output format of the
exposed resources, defaults to "1"
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
resource:
description: 'Required: resource to select'
type: string
required:
- resource
type: object
secretKeyRef:
description: Selects a key of a secret in the pod's
namespace
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind,
uid?'
type: string
optional:
description: Specify whether the Secret or its key
must be defined
type: boolean
required:
- key
type: object
type: object
required:
- name
type: object
type: array
metricsPort:
format: int32
type: integer
type: object
serviceProvider:
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
Important: Run "make" to regenerate code after modifying this file'
nullable: true
properties:
credentials:
description: "ObjectReference contains enough information to let
you inspect or modify the referred object. --- New uses of this
type are discouraged because of difficulty describing its usage
when embedded in APIs. 1. Ignored fields. It includes many
fields which are not generally honored. For instance, ResourceVersion
and FieldPath are both very rarely valid in actual usage. 2.
Invalid usage help. It is impossible to add specific help for
individual usage. In most embedded usages, there are particular
restrictions like, \"must refer only to types A and B\" or \"UID
not honored\" or \"name must be restricted\". Those cannot be
well described when embedded. 3. Inconsistent validation. Because
the usages are different, the validation rules are different
by usage, which makes it hard for users to predict what will
happen. 4. The fields are both imprecise and overly precise.
\ Kind is not a precise mapping to a URL. This can produce ambiguity
during interpretation and require a REST mapping. In most cases,
the dependency is on the group,resource tuple and the version
of the actual struct is irrelevant. 5. We cannot easily change
it. Because this type is embedded in many locations, updates
to this type will affect numerous schemas. Don't make new APIs
embed an underspecified API type they do not control. \n Instead
of using this type, create a locally provided and used type
that is well-focused on your reference. For example, ServiceReferences
for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
."
nullable: true
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a valid
JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container within
a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container that triggered
the event) or if no container name is specified "spec.containers[2]"
(container with index 2 in this pod). This syntax is chosen
only to have some well-defined way of referencing a part
of an object. TODO: this design is not final and this field
is subject to change in the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
name:
enum:
- flagd
type: string
required:
- name
type: object
syncProvider:
nullable: true
properties:
name:
type: string
required:
- name
type: object
type: object
status:
description: FeatureFlagConfigurationStatus defines the observed state
of FeatureFlagConfiguration
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: open-feature-operator-controller-manager
namespace: '{{ include "chart.namespace" . }}'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: open-feature-operator-leader-election-role
namespace: '{{ include "chart.namespace" . }}'
rules:
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: open-feature-operator-flagd-kubernetes-sync
rules:
- apiGroups:
- core.openfeature.dev
resources:
- '*'
verbs:
- get
- watch
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: open-feature-operator-manager-role
rules:
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- pods
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- get
- list
- watch
- apiGroups:
- core.openfeature.dev
resources:
- featureflagconfigurations
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- core.openfeature.dev
resources:
- featureflagconfigurations/finalizers
verbs:
- update
- apiGroups:
- core.openfeature.dev
resources:
- featureflagconfigurations/status
verbs:
- get
- patch
- update
- apiGroups:
- rbac.authorization.k8s.io
resources:
- '*'
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: open-feature-operator-metrics-reader
rules:
- nonResourceURLs:
- /metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: open-feature-operator-proxy-role
rules:
- apiGroups:
- authentication.k8s.io
resources:
- tokenreviews
verbs:
- create
- apiGroups:
- authorization.k8s.io
resources:
- subjectaccessreviews
verbs:
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: open-feature-operator-leader-election-rolebinding
namespace: '{{ include "chart.namespace" . }}'
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: open-feature-operator-leader-election-role
subjects:
- kind: ServiceAccount
name: open-feature-operator-controller-manager
namespace: '{{ include "chart.namespace" . }}'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: open-feature-operator-flagd-kubernetes-sync
roleRef:
apiGroup: ""
kind: ClusterRole
name: open-feature-operator-flagd-kubernetes-sync
subjects:
- apiGroup: ""
kind: ServiceAccount
name: open-feature-operator-controller-manager
namespace: '{{ include "chart.namespace" . }}'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: open-feature-operator-manager-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: open-feature-operator-manager-role
subjects:
- kind: ServiceAccount
name: open-feature-operator-controller-manager
namespace: '{{ include "chart.namespace" . }}'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: open-feature-operator-proxy-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: open-feature-operator-proxy-role
subjects:
- kind: ServiceAccount
name: open-feature-operator-controller-manager
namespace: '{{ include "chart.namespace" . }}'
---
apiVersion: v1
data:
controller_manager_config.yaml: |
apiVersion: controller-runtime.sigs.k8s.io/v1alpha1
kind: ControllerManagerConfig
health:
healthProbeBindAddress: :8081
metrics:
bindAddress: 127.0.0.1:8080
webhook:
port: 9443
leaderElection:
leaderElect: true
resourceName: 131bf64c.openfeature.dev
kind: ConfigMap
metadata:
name: open-feature-operator-manager-config
namespace: '{{ include "chart.namespace" . }}'
---
apiVersion: v1
kind: Service
metadata:
labels:
control-plane: controller-manager
name: open-feature-operator-controller-manager-metrics-service
namespace: '{{ include "chart.namespace" . }}'
spec:
ports:
- name: https
port: 8443
protocol: TCP
targetPort: https
selector:
control-plane: controller-manager
---
apiVersion: v1
kind: Service
metadata:
annotations:
cert-manager.io/inject-ca-from: open-feature-operator-system/webhook-cert
name: open-feature-operator-webhook-service
namespace: '{{ include "chart.namespace" . }}'
spec:
ports:
- port: 443
protocol: TCP
targetPort: 9443
selector:
control-plane: controller-manager
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
control-plane: controller-manager
name: open-feature-operator-controller-manager
namespace: '{{ include "chart.namespace" . }}'
spec:
replicas: 1
selector:
matchLabels:
control-plane: controller-manager
template:
metadata:
annotations:
kubectl.kubernetes.io/default-container: manager
labels:
control-plane: controller-manager
spec:
containers:
- args:
- --health-probe-bind-address=:8081
- --metrics-bind-address=127.0.0.1:8080
- --leader-elect
command:
- /manager
env:
- name: FLAGD_VERSION
value: v0.2.5
image: ghcr.io/open-feature/open-feature-operator:main
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: 15
periodSeconds: 20
name: manager
ports:
- containerPort: 9443
name: webhook-server
protocol: TCP
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
securityContext:
allowPrivilegeEscalation: false
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
readOnly: true
- args:
- --secure-listen-address=0.0.0.0:8443
- --upstream=http://127.0.0.1:8080/
- --logtostderr=true
- --v=0
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0
name: kube-rbac-proxy
ports:
- containerPort: 8443
name: https
protocol: TCP
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 5m
memory: 64Mi
securityContext:
runAsNonRoot: true
serviceAccountName: open-feature-operator-controller-manager
terminationGracePeriodSeconds: 10
volumes:
- name: cert
secret:
defaultMode: 420
secretName: webhook-server-cert
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: open-feature-operator-serving-cert
namespace: '{{ include "chart.namespace" . }}'
spec:
dnsNames:
- open-feature-operator-webhook-service.{{ include "chart.namespace" . }}.svc
- open-feature-operator-webhook-service.{{ include "chart.namespace" . }}.svc.cluster.local
issuerRef:
kind: Issuer
name: open-feature-operator-selfsigned-issuer
secretName: webhook-server-cert
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: open-feature-operator-selfsigned-issuer
namespace: '{{ include "chart.namespace" . }}'
spec:
selfSigned: {}
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
annotations:
cert-manager.io/inject-ca-from: '{{ include "chart.namespace" . }}/open-feature-operator-serving-cert'
name: open-feature-operator-mutating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: open-feature-operator-webhook-service
namespace: '{{ include "chart.namespace" . }}'
path: /mutate-v1-pod
failurePolicy: Ignore
name: mutate.openfeature.dev
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- pods
sideEffects: NoneOnDryRun
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
annotations:
cert-manager.io/inject-ca-from: '{{ include "chart.namespace" . }}/open-feature-operator-serving-cert'
name: open-feature-operator-validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: open-feature-operator-webhook-service
namespace: '{{ include "chart.namespace" . }}'
path: /validate-v1alpha1-featureflagconfiguration
failurePolicy: Fail
name: validate.featureflagconfiguration.openfeature.dev
rules:
- apiGroups:
- core.openfeature.dev
apiVersions:
- v1alpha1
operations:
- CREATE
- UPDATE
resources:
- featureflagconfigurations
sideEffects: None

50
chart/values.yaml Normal file
View File

@ -0,0 +1,50 @@
# If this namespace is changed the value must be reflected in /chart/values.yaml
defaultNamespace: open-feature-operator-system
controllerManager:
kubeRbacProxy:
image:
repository: gcr.io/kubebuilder/kube-rbac-proxy
tag: v0.8.0
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 5m
memory: 64Mi
manager:
image:
repository: ghcr.io/open-feature/open-feature-operator
tag: v0.2.18 # x-release-please-version
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
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

View File

@ -0,0 +1,4 @@
repositoryID: cad3d073-cdc2-4cc4-8fe6-351de5532d98
owners: # used to claim ownership, we can add more.
- name: Alex Jones
email: alexsimonjones@gmail.com

BIN
charts/ofo-v0.2.16.tgz Normal file

Binary file not shown.

View File

@ -1,522 +0,0 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"context"
"crypto/tls"
"flag"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"time"
"github.com/kelseyhightower/envconfig"
corev1beta1 "github.com/open-feature/open-feature-operator/apis/core/v1beta1"
"github.com/open-feature/open-feature-operator/internal/common"
"github.com/open-feature/open-feature-operator/internal/common/flagdinjector"
"github.com/open-feature/open-feature-operator/internal/common/flagdproxy"
"github.com/open-feature/open-feature-operator/internal/common/types"
"github.com/open-feature/open-feature-operator/internal/common/utils"
"github.com/open-feature/open-feature-operator/internal/controller/core/featureflagsource"
"github.com/open-feature/open-feature-operator/internal/controller/core/flagd"
flagdResources "github.com/open-feature/open-feature-operator/internal/controller/core/flagd/resources"
webhooks "github.com/open-feature/open-feature-operator/internal/webhook"
"go.uber.org/zap/zapcore"
appsV1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
_ "k8s.io/client-go/plugin/pkg/client/auth"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
"sigs.k8s.io/controller-runtime/pkg/client"
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
"sigs.k8s.io/controller-runtime/pkg/metrics/server"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
gatewayApiv1 "sigs.k8s.io/gateway-api/apis/v1"
)
const (
healthProbeBindAddressFlagName = "health-probe-bind-address"
metricsBindAddressFlagName = "metrics-bind-address"
verboseFlagName = "verbose"
leaderElectFlagName = "leader-elect"
sidecarCpuLimitFlagName = "sidecar-cpu-limit"
sidecarCpuLimitDefault = "0.5"
sidecarRamLimitFlagName = "sidecar-ram-limit"
sidecarRamLimitDefault = "64M"
sidecarCpuRequestFlagName = "sidecar-cpu-request"
sidecarCpuRequestDefault = "0.2"
sidecarRamRequestFlagName = "sidecar-ram-request"
sidecarRamRequestDefault = "32M"
imagePullSecretFlagName = "image-pull-secrets"
imagePullSecretFlagDefault = ""
labelsFlagName = "labels"
labelsFlagDefault = ""
annotationsFlagName = "annotations"
annotationsFlagDefault = ""
)
var (
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
metricsAddr string
metricsCertPath, metricsCertName, metricsCertKey string
webhookCertPath, webhookCertName, webhookCertKey string
secureMetrics bool
enableHTTP2 bool
tlsOpts []func(*tls.Config)
enableLeaderElection bool
probeAddr string
verbose bool
sidecarCpuLimit, sidecarRamLimit, sidecarCpuRequest, sidecarRamRequest string
imagePullSecrets string
labels string
annotations string
)
// StringToMap transforms a string into a map[string]string
func StringToMap(s string) map[string]string {
m := map[string]string{}
for _, pair := range strings.Split(s, ",") {
kv := strings.SplitN(pair, ":", 2)
if len(kv) == 2 {
m[kv[0]] = kv[1]
}
}
return m
}
// CommaSeparatedStringToSlice transforms a comma-separated string into a slice of strings
func CommaSeparatedStringToSlice(s string) []string {
if s == "" {
return []string{}
}
return strings.Split(s, ",")
}
func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(corev1beta1.AddToScheme(scheme))
utilruntime.Must(gatewayApiv1.Install(scheme))
//+kubebuilder:scaffold:scheme
}
//nolint:funlen,gocyclo,gocognit
func main() {
var env types.EnvConfig
if err := envconfig.Process("", &env); err != nil {
log.Fatalf("Failed to process env var: %s", err)
}
flag.StringVar(&metricsAddr, metricsBindAddressFlagName, ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&probeAddr, healthProbeBindAddressFlagName, ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&verbose, verboseFlagName, true, "Disable verbose logging")
flag.BoolVar(&enableLeaderElection, leaderElectFlagName, false,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
flag.BoolVar(&secureMetrics, "metrics-secure", true,
"If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
flag.StringVar(&webhookCertPath, "webhook-cert-path", "", "The directory that contains the webhook certificate.")
flag.StringVar(&webhookCertName, "webhook-cert-name", "tls.crt", "The name of the webhook certificate file.")
flag.StringVar(&webhookCertKey, "webhook-cert-key", "tls.key", "The name of the webhook key file.")
flag.StringVar(&metricsCertPath, "metrics-cert-path", "",
"The directory that contains the metrics server certificate.")
flag.StringVar(&metricsCertName, "metrics-cert-name", "tls.crt", "The name of the metrics server certificate file.")
flag.StringVar(&metricsCertKey, "metrics-cert-key", "tls.key", "The name of the metrics server key file.")
flag.BoolVar(&enableHTTP2, "enable-http2", false,
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
// the following default values are chosen as a result of load testing: https://github.com/open-feature/flagd/blob/main/tests/loadtest/README.MD#performance-observations
flag.StringVar(&sidecarCpuLimit, sidecarCpuLimitFlagName, sidecarCpuLimitDefault, "sidecar CPU limit, in cores. (500m = .5 cores)")
flag.StringVar(&sidecarRamLimit, sidecarRamLimitFlagName, sidecarRamLimitDefault, "sidecar memory limit, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)")
flag.StringVar(&sidecarCpuRequest, sidecarCpuRequestFlagName, sidecarCpuRequestDefault, "sidecar CPU minimum, in cores. (500m = .5 cores)")
flag.StringVar(&sidecarRamRequest, sidecarRamRequestFlagName, sidecarRamRequestDefault, "sidecar memory minimum, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)")
flag.StringVar(&imagePullSecrets, imagePullSecretFlagName, imagePullSecretFlagDefault, "Comma-delimited list of secrets containing credentials to pull images.")
flag.StringVar(&labels, labelsFlagName, labelsFlagDefault, "Map of labels to add to the deployed pods. Formatted like key1:value1,key2:value2,key3:value3")
flag.StringVar(&annotations, annotationsFlagName, annotationsFlagDefault, "Map of annotations to add to the deployed pods. Formatted like key1:value1,key2:value2,key3:value3")
flag.Parse()
level := zapcore.InfoLevel
if verbose {
level = zapcore.DebugLevel
}
opts := zap.Options{
Development: verbose,
Level: level,
}
opts.BindFlags(flag.CommandLine)
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
// if the enable-http2 flag is false (the default), http/2 should be disabled
// due to its vulnerabilities. More specifically, disabling http/2 will
// prevent from being vulnerable to the HTTP/2 Stream Cancellation and
// Rapid Reset CVEs. For more information see:
// - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
// - https://github.com/advisories/GHSA-4374-p667-p6c8
disableHTTP2 := func(c *tls.Config) {
setupLog.Info("disabling http/2")
c.NextProtos = []string{"http/1.1"}
}
if !enableHTTP2 {
tlsOpts = append(tlsOpts, disableHTTP2)
}
// Create watchers for metrics and webhooks certificates
var metricsCertWatcher, webhookCertWatcher *certwatcher.CertWatcher
// Initial webhook TLS options
webhookTLSOpts := tlsOpts
if len(webhookCertPath) > 0 {
setupLog.Info("Initializing webhook certificate watcher using provided certificates",
"webhook-cert-path", webhookCertPath, "webhook-cert-name", webhookCertName, "webhook-cert-key", webhookCertKey)
var err error
webhookCertWatcher, err = certwatcher.New(
filepath.Join(webhookCertPath, webhookCertName),
filepath.Join(webhookCertPath, webhookCertKey),
)
if err != nil {
setupLog.Error(err, "Failed to initialize webhook certificate watcher")
os.Exit(1)
}
webhookTLSOpts = append(webhookTLSOpts, func(config *tls.Config) {
config.GetCertificate = webhookCertWatcher.GetCertificate
})
}
webhookServer := webhook.NewServer(webhook.Options{
TLSOpts: webhookTLSOpts,
Port: 9443,
})
// Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
// More info:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.20.0/pkg/metrics/server
// - https://book.kubebuilder.io/reference/metrics.html
metricsServerOptions := metricsserver.Options{
BindAddress: metricsAddr,
SecureServing: secureMetrics,
TLSOpts: tlsOpts,
}
if secureMetrics {
// FilterProvider is used to protect the metrics endpoint with authn/authz.
// These configurations ensure that only authorized users and service accounts
// can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info:
// https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.20.0/pkg/metrics/filters#WithAuthenticationAndAuthorization
metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization
}
// If the certificate is not specified, controller-runtime will automatically
// generate self-signed certificates for the metrics server. While convenient for development and testing,
// this setup is not recommended for production.
//
// - [METRICS-WITH-CERTS] at config/default/kustomization.yaml to generate and use certificates
// managed by cert-manager for the metrics server.
// - [PROMETHEUS-WITH-CERTS] at config/prometheus/kustomization.yaml for TLS certification.
if len(metricsCertPath) > 0 {
setupLog.Info("Initializing metrics certificate watcher using provided certificates",
"metrics-cert-path", metricsCertPath, "metrics-cert-name", metricsCertName, "metrics-cert-key", metricsCertKey)
var err error
metricsCertWatcher, err = certwatcher.New(
filepath.Join(metricsCertPath, metricsCertName),
filepath.Join(metricsCertPath, metricsCertKey),
)
if err != nil {
setupLog.Error(err, "to initialize metrics certificate watcher", "error", err)
os.Exit(1)
}
metricsServerOptions.TLSOpts = append(metricsServerOptions.TLSOpts, func(config *tls.Config) {
config.GetCertificate = metricsCertWatcher.GetCertificate
})
}
resources, err := processResources()
if err != nil {
os.Exit(1)
}
disableCacheFor := []client.Object{&v1.ClusterRoleBinding{}}
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
Metrics: server.Options{
BindAddress: metricsAddr,
},
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "131bf64c.openfeature.dev",
Client: ctrlclient.Options{
Cache: &ctrlclient.CacheOptions{
DisableFor: disableCacheFor,
},
},
WebhookServer: webhookServer,
})
if err != nil {
setupLog.Error(err, "unable to start manager")
os.Exit(1)
}
if metricsCertWatcher != nil {
setupLog.Info("Adding metrics certificate watcher to manager")
if err := mgr.Add(metricsCertWatcher); err != nil {
setupLog.Error(err, "unable to add metrics certificate watcher to manager")
os.Exit(1)
}
}
if webhookCertWatcher != nil {
setupLog.Info("Adding webhook certificate watcher to manager")
if err := mgr.Add(webhookCertWatcher); err != nil {
setupLog.Error(err, "unable to add webhook certificate watcher to manager")
os.Exit(1)
}
}
// setup indexer for backfilling permissions on the flagd-kubernetes-sync role binding
if err := mgr.GetFieldIndexer().IndexField(
context.Background(),
&corev1.Pod{},
fmt.Sprintf("%s/%s", common.PodOpenFeatureAnnotationPath, common.AllowKubernetesSyncAnnotation),
webhooks.OpenFeatureEnabledAnnotationIndex,
); err != nil {
setupLog.Error(
err,
"unable to create indexer",
"webhook",
fmt.Sprintf("%s/%s", common.PodOpenFeatureAnnotationPath, common.AllowKubernetesSyncAnnotation),
)
os.Exit(1)
}
if err := mgr.GetFieldIndexer().IndexField(
context.Background(),
&appsV1.Deployment{},
fmt.Sprintf("%s/%s", common.OpenFeatureAnnotationPath, common.FeatureFlagSourceAnnotation),
common.FeatureFlagSourceIndex,
); err != nil {
setupLog.Error(
err,
"unable to create indexer",
"webhook",
fmt.Sprintf("%s/%s", common.OpenFeatureAnnotationPath, common.FeatureFlagSourceAnnotation),
)
os.Exit(1)
}
labelsMap := StringToMap(labels)
annotationsMap := StringToMap(annotations)
kph := flagdproxy.NewFlagdProxyHandler(
flagdproxy.NewFlagdProxyConfiguration(
env,
CommaSeparatedStringToSlice(imagePullSecrets),
labelsMap,
annotationsMap,
),
mgr.GetClient(),
ctrl.Log.WithName("FeatureFlagSource FlagdProxyHandler"),
)
flagSourceController := &featureflagsource.FeatureFlagSourceReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Log: ctrl.Log.WithName("FeatureFlagSource Controller"),
FlagdProxy: kph,
FlagdProxyBackoff: &utils.ExponentialBackoff{
StartDelay: time.Second,
MaxDelay: time.Minute,
},
}
if err = flagSourceController.SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "FeatureFlagSource")
os.Exit(1)
}
flagdContainerInjector := &flagdinjector.FlagdContainerInjector{
Client: mgr.GetClient(),
Logger: ctrl.Log.WithName("flagd-container injector"),
FlagdProxyConfig: kph.Config(),
FlagdResourceRequirements: *resources,
Image: env.SidecarImage,
Tag: env.SidecarTag,
}
flagdControllerLogger := ctrl.Log.WithName("Flagd Controller")
flagdResourceReconciler := &flagd.ResourceReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Log: flagdControllerLogger,
}
flagdConfig := flagd.NewFlagdConfiguration(
env,
CommaSeparatedStringToSlice(imagePullSecrets),
labelsMap,
annotationsMap,
)
if err = (&flagd.FlagdReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
ResourceReconciler: flagdResourceReconciler,
FlagdDeployment: &flagdResources.FlagdDeployment{
Client: mgr.GetClient(),
Log: flagdControllerLogger,
FlagdInjector: flagdContainerInjector,
FlagdConfig: flagdConfig,
},
FlagdService: &flagdResources.FlagdService{
FlagdConfig: flagdConfig,
},
FlagdIngress: &flagdResources.FlagdIngress{
FlagdConfig: flagdConfig,
},
FlagdGatewayApiHttpRoute: &flagdResources.FlagdGatewayApiHttpRoute{
FlagdConfig: flagdConfig,
},
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Flagd")
os.Exit(1)
}
if env.FlagsValidationEnabled {
if err = (&webhooks.FeatureFlagCustomValidator{}).SetupWebhookWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create the validation webhook for FeatureFlag CRD", "webhook", "FeatureFlag")
os.Exit(1)
}
}
//+kubebuilder:scaffold:builder
hookServer := mgr.GetWebhookServer()
podMutator := &webhooks.PodMutator{
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("mutating-pod-webhook"),
FlagdProxyConfig: kph.Config(),
Env: env,
FlagdInjector: flagdContainerInjector,
}
if err := podMutator.InjectDecoder(admission.NewDecoder(mgr.GetScheme())); err != nil {
setupLog.Error(err, "unable to inject decoder into mutating webhook")
os.Exit(1)
}
hookServer.Register("/mutate-v1-pod", &webhook.Admission{Handler: podMutator})
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up health check")
os.Exit(1)
}
if err := mgr.AddReadyzCheck("readyz", podMutator.IsReady); err != nil {
setupLog.Error(err, "unable to set up ready check")
os.Exit(1)
}
setupLog.Info("starting manager")
ctx := ctrl.SetupSignalHandler()
errChan := make(chan error, 1)
go func(chan error) {
if err := mgr.Start(ctx); err != nil {
errChan <- err
}
}(errChan)
setupLog.Info("restoring flagd-kubernetes-sync cluster role binding subjects from current cluster state")
// backfill can be handled asynchronously, so we do not need to block via the channel
go func() {
if err := podMutator.BackfillPermissions(ctx); err != nil {
setupLog.Error(err, "podMutator backfill permissions error")
}
}()
if err := <-errChan; err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
}
}
func processResources() (*corev1.ResourceRequirements, error) {
cpuLimitResource, err := resource.ParseQuantity(sidecarCpuLimit)
if err != nil {
setupLog.Error(err, "parse sidecar cpu limit", sidecarCpuLimitFlagName, sidecarCpuLimit)
return nil, err
}
ramLimitResource, err := resource.ParseQuantity(sidecarRamLimit)
if err != nil {
setupLog.Error(err, "parse sidecar ram limit", sidecarRamLimitFlagName, sidecarRamLimit)
return nil, err
}
cpuRequestResource, err := resource.ParseQuantity(sidecarCpuRequest)
if err != nil {
setupLog.Error(err, "parse sidecar cpu request", sidecarCpuRequestFlagName, sidecarCpuRequest)
return nil, err
}
ramRequestResource, err := resource.ParseQuantity(sidecarRamRequest)
if err != nil {
setupLog.Error(err, "parse sidecar ram request", sidecarRamRequestFlagName, sidecarRamRequest)
return nil, err
}
if cpuRequestResource.Value() > cpuLimitResource.Value() ||
ramRequestResource.Value() > ramLimitResource.Value() {
setupLog.Error(err, "sidecar resource request is higher than the resource maximum")
return nil, err
}
return &corev1.ResourceRequirements{
Limits: map[corev1.ResourceName]resource.Quantity{
corev1.ResourceCPU: cpuLimitResource,
corev1.ResourceMemory: ramLimitResource,
},
Requests: map[corev1.ResourceName]resource.Quantity{
corev1.ResourceCPU: cpuRequestResource,
corev1.ResourceMemory: ramRequestResource,
},
}, nil
}

View File

@ -1,35 +0,0 @@
coverage:
status:
project:
default:
# basic
target: auto
threshold: 2% # allow cov to drop by 2% (just in case)
patch:
default:
threshold: 1% # allow patch
ignore:
- "**/*.yaml" # ignore all yaml files (Kubernetes manifests, etc...)
- "**/*.yml" # same as above
- "**/*.md" # ignore all markdown files, those are not relevant for building/testing
- "**/Dockerfile" # ignore Dockerfiles, those are build with GH Actions
- "**/*.sh" # ignore shell scripts
- "**/test_utils.go" # test utils don't need to be covered
- "**/zz_generated.deepcopy.go" # auto-generated deepcopy files for CRD structs
comment:
layout: "diff, files, flags"
github_checks:
annotations: false
flags:
unit-tests:
paths:
- ./
carryforward: true
tests:
paths:
- ./
carryforward: true

View File

@ -5,9 +5,6 @@ apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
labels:
app.kubernetes.io/name: open-feature-operator
app.kubernetes.io/managed-by: kustomize
spec:
selfSigned: {}
---
@ -15,35 +12,12 @@ apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
labels:
app.kubernetes.io/name: open-feature-operator
app.kubernetes.io/managed-by: kustomize
spec:
# SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize
# $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize
dnsNames:
- SERVICE_NAME.SERVICE_NAMESPACE.svc
- SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local
- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc
- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local
issuerRef:
kind: Issuer
name: selfsigned-issuer
secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize
---
# The following manifests contain a self-signed issuer CR and a metrics certificate CR.
# More document can be found at https://docs.cert-manager.io
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: metrics-certs # this name should match the one appeared in kustomizeconfig.yaml
labels:
app.kubernetes.io/name: open-feature-operator
app.kubernetes.io/managed-by: kustomize
spec:
dnsNames:
# SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize
# replacements in the config/default/kustomization.yaml file.
- SERVICE_NAME.SERVICE_NAMESPACE.svc
- SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local
issuerRef:
kind: Issuer
name: selfsigned-issuer
secretName: metrics-server-cert

View File

@ -6,3 +6,11 @@ nameReference:
- kind: Certificate
group: cert-manager.io
path: spec/issuerRef/name
varReference:
- kind: Certificate
group: cert-manager.io
path: spec/commonName
- kind: Certificate
group: cert-manager.io
path: spec/dnsNames

View File

@ -3,7 +3,8 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
name: featureflagconfigurations.core.openfeature.dev
spec:
group: core.openfeature.dev
@ -11,8 +12,6 @@ spec:
kind: FeatureFlagConfiguration
listKind: FeatureFlagConfigurationList
plural: featureflagconfigurations
shortNames:
- ffc
singular: featureflagconfiguration
scope: Namespaced
versions:
@ -23,19 +22,14 @@ spec:
API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
@ -48,7 +42,6 @@ spec:
flag
type: string
flagDSpec:
description: 'FlagDSpec [DEPRECATED]: superseded by FlagSourceConfiguration'
nullable: true
properties:
envs:
@ -61,16 +54,15 @@ spec:
C_IDENTIFIER.
type: string
value:
description: |-
Variable references $(VAR_NAME) are expanded
using the previously defined environment variables in the container and
any service environment variables. If a variable cannot be resolved,
the reference in the input string will be unchanged. Double $$ are reduced
to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
description: 'Variable references $(VAR_NAME) are expanded
using the previously defined environment variables in
the container and any service environment variables. If
a variable cannot be resolved, the reference in the input
string will be unchanged. Double $$ are reduced to a single
$, which allows for escaping the $(VAR_NAME) syntax: i.e.
"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
Escaped references will never be expanded, regardless of whether the variable
exists or not.
Defaults to "".
Escaped references will never be expanded, regardless
of whether the variable exists or not. Defaults to "".'
type: string
valueFrom:
description: Source for the environment variable's value.
@ -83,13 +75,9 @@ spec:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind,
uid?'
type: string
optional:
description: Specify whether the ConfigMap or its
@ -98,11 +86,12 @@ spec:
required:
- key
type: object
x-kubernetes-map-type: atomic
fieldRef:
description: |-
Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,
spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
description: 'Selects a field of the pod: supports metadata.name,
metadata.namespace, `metadata.labels[''<KEY>'']`,
`metadata.annotations[''<KEY>'']`, spec.nodeName,
spec.serviceAccountName, status.hostIP, status.podIP,
status.podIPs.'
properties:
apiVersion:
description: Version of the schema the FieldPath
@ -115,11 +104,11 @@ spec:
required:
- fieldPath
type: object
x-kubernetes-map-type: atomic
resourceFieldRef:
description: |-
Selects a resource of the container: only resources limits and requests
(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
description: 'Selects a resource of the container: only
resources limits and requests (limits.cpu, limits.memory,
limits.ephemeral-storage, requests.cpu, requests.memory
and requests.ephemeral-storage) are currently supported.'
properties:
containerName:
description: 'Container name: required for volumes,
@ -139,7 +128,6 @@ spec:
required:
- resource
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a secret in the pod's
namespace
@ -149,13 +137,9 @@ spec:
be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind,
uid?'
type: string
optional:
description: Specify whether the Secret or its key
@ -164,7 +148,6 @@ spec:
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
required:
- name
@ -175,54 +158,71 @@ spec:
type: integer
type: object
serviceProvider:
description: 'ServiceProvider [DEPRECATED]: superseded by FlagSourceConfiguration'
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
Important: Run "make" to regenerate code after modifying this file'
nullable: true
properties:
credentials:
description: ObjectReference contains enough information to let
you inspect or modify the referred object.
description: "ObjectReference contains enough information to let
you inspect or modify the referred object. --- New uses of this
type are discouraged because of difficulty describing its usage
when embedded in APIs. 1. Ignored fields. It includes many
fields which are not generally honored. For instance, ResourceVersion
and FieldPath are both very rarely valid in actual usage. 2.
Invalid usage help. It is impossible to add specific help for
individual usage. In most embedded usages, there are particular
restrictions like, \"must refer only to types A and B\" or \"UID
not honored\" or \"name must be restricted\". Those cannot be
well described when embedded. 3. Inconsistent validation. Because
the usages are different, the validation rules are different
by usage, which makes it hard for users to predict what will
happen. 4. The fields are both imprecise and overly precise.
\ Kind is not a precise mapping to a URL. This can produce ambiguity
during interpretation and require a REST mapping. In most cases,
the dependency is on the group,resource tuple and the version
of the actual struct is irrelevant. 5. We cannot easily change
it. Because this type is embedded in many locations, updates
to this type will affect numerous schemas. Don't make new APIs
embed an underspecified API type they do not control. \n Instead
of using this type, create a locally provided and used type
that is well-focused on your reference. For example, ServiceReferences
for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533
."
nullable: true
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: |-
If referring to a piece of an object instead of an entire object, this string
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container within a pod, this would take on a value like:
"spec.containers{name}" (where "name" refers to the name of the container that triggered
the event) or if no container name is specified "spec.containers[2]" (container with
index 2 in this pod). This syntax is chosen only to have some well-defined way of
referencing a part of an object.
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a valid
JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container within
a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container that triggered
the event) or if no container name is specified "spec.containers[2]"
(container with index 2 in this pod). This syntax is chosen
only to have some well-defined way of referencing a part
of an object. TODO: this design is not final and this field
is subject to change in the future.'
type: string
kind:
description: |-
Kind of the referent.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: |-
Namespace of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: |-
Specific resourceVersion to which this reference is made, if any.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: |-
UID of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
x-kubernetes-map-type: atomic
name:
enum:
- flagd
@ -231,22 +231,8 @@ spec:
- name
type: object
syncProvider:
description: 'SyncProvider [DEPRECATED]: superseded by FlagSourceConfiguration'
nullable: true
properties:
httpSyncConfiguration:
description: HttpSyncConfiguration defines the desired configuration
for a http sync
nullable: true
properties:
bearerToken:
type: string
target:
description: Target is the target url for flagd to poll
type: string
required:
- target
type: object
name:
type: string
required:
@ -262,335 +248,9 @@ spec:
storage: true
subresources:
status: {}
- name: v1alpha2
schema:
openAPIV3Schema:
description: FeatureFlagConfiguration is the Schema for the featureflagconfigurations
API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: FeatureFlagConfigurationSpec defines the desired state of
FeatureFlagConfiguration
properties:
featureFlagSpec:
description: FeatureFlagSpec is the structured representation of the
feature flag specification
properties:
$evaluators:
type: object
x-kubernetes-preserve-unknown-fields: true
flags:
additionalProperties:
properties:
defaultVariant:
type: string
state:
enum:
- ENABLED
- DISABLED
type: string
targeting:
description: Targeting is the json targeting rule
type: object
x-kubernetes-preserve-unknown-fields: true
variants:
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- defaultVariant
- state
- variants
type: object
type: object
required:
- flags
type: object
flagDSpec:
description: 'FlagDSpec [DEPRECATED]: superseded by FlagSourceConfiguration'
nullable: true
properties:
envs:
items:
description: EnvVar represents an environment variable present
in a Container.
properties:
name:
description: Name of the environment variable. Must be a
C_IDENTIFIER.
type: string
value:
description: |-
Variable references $(VAR_NAME) are expanded
using the previously defined environment variables in the container and
any service environment variables. If a variable cannot be resolved,
the reference in the input string will be unchanged. Double $$ are reduced
to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
Escaped references will never be expanded, regardless of whether the variable
exists or not.
Defaults to "".
type: string
valueFrom:
description: Source for the environment variable's value.
Cannot be used if value is not empty.
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its
key must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
fieldRef:
description: |-
Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,
spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
properties:
apiVersion:
description: Version of the schema the FieldPath
is written in terms of, defaults to "v1".
type: string
fieldPath:
description: Path of the field to select in the
specified API version.
type: string
required:
- fieldPath
type: object
x-kubernetes-map-type: atomic
resourceFieldRef:
description: |-
Selects a resource of the container: only resources limits and requests
(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
properties:
containerName:
description: 'Container name: required for volumes,
optional for env vars'
type: string
divisor:
anyOf:
- type: integer
- type: string
description: Specifies the output format of the
exposed resources, defaults to "1"
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
resource:
description: 'Required: resource to select'
type: string
required:
- resource
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a secret in the pod's
namespace
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key
must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
required:
- name
type: object
type: array
type: object
resources:
description: Resources defines flagd sidecar resources. Default to
operator sidecar-cpu-* and sidecar-ram-* flags.
properties:
claims:
description: |-
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.
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
request:
description: |-
Request is the name chosen for a request in the referenced claim.
If empty, everything from the claim is made available, otherwise
only the result of this request.
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. Requests cannot exceed Limits.
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
type: object
type: object
serviceProvider:
description: 'ServiceProvider [DEPRECATED]: superseded by FlagSourceConfiguration'
nullable: true
properties:
credentials:
description: ObjectReference contains enough information to let
you inspect or modify the referred object.
nullable: true
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: |-
If referring to a piece of an object instead of an entire object, this string
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container within a pod, this would take on a value like:
"spec.containers{name}" (where "name" refers to the name of the container that triggered
the event) or if no container name is specified "spec.containers[2]" (container with
index 2 in this pod). This syntax is chosen only to have some well-defined way of
referencing a part of an object.
type: string
kind:
description: |-
Kind of the referent.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
namespace:
description: |-
Namespace of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
type: string
resourceVersion:
description: |-
Specific resourceVersion to which this reference is made, if any.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
type: string
uid:
description: |-
UID of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
type: string
type: object
x-kubernetes-map-type: atomic
name:
enum:
- flagd
type: string
required:
- name
type: object
syncProvider:
description: 'SyncProvider [DEPRECATED]: superseded by FlagSourceConfiguration'
nullable: true
properties:
httpSyncConfiguration:
description: HttpSyncConfiguration defines the desired configuration
for a http sync
nullable: true
properties:
bearerToken:
type: string
target:
description: Target is the target url for flagd to poll
type: string
required:
- target
type: object
name:
type: string
required:
- name
type: object
type: object
status:
description: FeatureFlagConfigurationStatus defines the observed state
of FeatureFlagConfiguration
type: object
type: object
served: true
storage: false
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@ -1,85 +0,0 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
name: featureflags.core.openfeature.dev
spec:
group: core.openfeature.dev
names:
kind: FeatureFlag
listKind: FeatureFlagList
plural: featureflags
shortNames:
- ff
singular: featureflag
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: FeatureFlag is the Schema for the featureflags API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: FeatureFlagSpec defines the desired state of FeatureFlag
properties:
flagSpec:
description: FlagSpec is the structured representation of the feature
flag specification
properties:
$evaluators:
type: object
x-kubernetes-preserve-unknown-fields: true
flags:
additionalProperties:
properties:
defaultVariant:
type: string
state:
enum:
- ENABLED
- DISABLED
type: string
targeting:
description: Targeting is the json targeting rule
type: object
x-kubernetes-preserve-unknown-fields: true
variants:
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- defaultVariant
- state
- variants
type: object
type: object
required:
- flags
type: object
type: object
status:
description: FeatureFlagStatus defines the observed state of FeatureFlag
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -1,330 +0,0 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
name: featureflagsources.core.openfeature.dev
spec:
group: core.openfeature.dev
names:
kind: FeatureFlagSource
listKind: FeatureFlagSourceList
plural: featureflagsources
shortNames:
- ffs
singular: featureflagsource
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: FeatureFlagSource is the Schema for the FeatureFlagSources API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: FeatureFlagSourceSpec defines the desired state of FeatureFlagSource
properties:
debugLogging:
description: DebugLogging defines whether to enable --debug flag of
flagd sidecar. Default false (disabled).
type: boolean
defaultSyncProvider:
description: DefaultSyncProvider defines the default sync provider
type: string
envVarPrefix:
default: FLAGD
description: EnvVarPrefix defines the prefix to be applied to all
environment variables applied to the sidecar, default FLAGD
type: string
envVars:
description: |-
EnvVars define the env vars to be applied to the sidecar, any env vars in FeatureFlag CRs
are added at the lowest index, all values will have the EnvVarPrefix applied, default FLAGD
items:
description: EnvVar represents an environment variable present in
a Container.
properties:
name:
description: Name of the environment variable. Must be a C_IDENTIFIER.
type: string
value:
description: |-
Variable references $(VAR_NAME) are expanded
using the previously defined environment variables in the container and
any service environment variables. If a variable cannot be resolved,
the reference in the input string will be unchanged. Double $$ are reduced
to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
Escaped references will never be expanded, regardless of whether the variable
exists or not.
Defaults to "".
type: string
valueFrom:
description: Source for the environment variable's value. Cannot
be used if value is not empty.
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key
must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
fieldRef:
description: |-
Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,
spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
properties:
apiVersion:
description: Version of the schema the FieldPath is
written in terms of, defaults to "v1".
type: string
fieldPath:
description: Path of the field to select in the specified
API version.
type: string
required:
- fieldPath
type: object
x-kubernetes-map-type: atomic
resourceFieldRef:
description: |-
Selects a resource of the container: only resources limits and requests
(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
properties:
containerName:
description: 'Container name: required for volumes,
optional for env vars'
type: string
divisor:
anyOf:
- type: integer
- type: string
description: Specifies the output format of the exposed
resources, defaults to "1"
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
resource:
description: 'Required: resource to select'
type: string
required:
- resource
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a secret in the pod's namespace
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must
be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
required:
- name
type: object
type: array
evaluator:
default: json
description: Evaluator sets an evaluator, defaults to 'json'
type: string
logFormat:
default: json
description: LogFormat allows for the sidecar log format to be overridden,
defaults to 'json'
type: string
managementPort:
default: 8014
description: ManagemetPort defines the port to serve management on,
defaults to 8014
format: int32
type: integer
otelCollectorUri:
description: OtelCollectorUri defines whether to enable --otel-collector-uri
flag of flagd sidecar. Default false (disabled).
type: string
port:
default: 8013
description: Port defines the port to listen on, defaults to 8013
format: int32
type: integer
probesEnabled:
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-* and sidecar-ram-* flags.
properties:
claims:
description: |-
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.
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
request:
description: |-
Request is the name chosen for a request in the referenced claim.
If empty, everything from the claim is made available, otherwise
only the result of this request.
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. Requests cannot exceed Limits.
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 CR, defaults to false
type: boolean
socketPath:
description: SocketPath defines the unix socket path to listen on
type: string
sources:
description: SyncProviders define the syncProviders and associated
configuration to be applied to the sidecar
items:
properties:
certPath:
description: CertPath is a path of a certificate to be used
by grpc TLS connection
type: string
httpSyncBearerToken:
description: HttpSyncBearerToken is a bearer token. Used by
http(s) sync provider only
type: string
interval:
description: Interval is a flag configuration interval in seconds
used by http provider
format: int32
type: integer
provider:
description: Provider type - kubernetes, http(s), grpc(s) or
file
type: string
providerID:
description: ProviderID is an identifier to be used in grpc
provider
type: string
selector:
description: Selector is a flag configuration selector used
by grpc provider
type: string
source:
description: Source is a URI of the flag sources
type: string
tls:
description: TLS - Enable/Disable secure TLS connectivity. Currently
used only by GRPC sync
type: boolean
required:
- source
type: object
minItems: 1
type: array
syncProviderArgs:
description: SyncProviderArgs are string arguments passed to all sync
providers, defined as key values separated by =
items:
type: string
type: array
required:
- sources
type: object
status:
description: FeatureFlagSourceStatus defines the observed state of FeatureFlagSource
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -1,324 +0,0 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
name: flagds.core.openfeature.dev
spec:
group: core.openfeature.dev
names:
kind: Flagd
listKind: FlagdList
plural: flagds
singular: flagd
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: Flagd is the Schema for the flagds API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: FlagdSpec defines the desired state of Flagd
properties:
featureFlagSource:
description: |-
FeatureFlagSource references to a FeatureFlagSource from which the created flagd instance retrieves
the feature flag configurations
type: string
gatewayApiRoutes:
description: GatewayApiRoutes
properties:
annotations:
additionalProperties:
type: string
description: Annotations to be added to the Gateway API routes
type: object
enabled:
description: Enabled enables/disables the Gateway API routes for
flagd
type: boolean
hosts:
description: |-
Hosts list of hosts to be added to the ingress.
Empty string corresponds to rule with no host.
items:
type: string
type: array
parentRefs:
description: |-
ParentRefs references the resources (usually Gateways) that the Routes should
be attached to.
items:
description: |-
ParentReference identifies an API object (usually a Gateway) that can be considered
a parent of this resource (usually a route). There are two kinds of parent resources
with "Core" support:
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
This API may be extended in the future to support additional kinds of parent
resources.
The API object must be valid in the cluster; the Group and Kind must
be registered in the cluster for this reference to be valid.
properties:
group:
default: gateway.networking.k8s.io
description: |-
Group is the group of the referent.
When unspecified, "gateway.networking.k8s.io" is inferred.
To set the core API group (such as for a "Service" kind referent),
Group must be explicitly set to "" (empty string).
Support: Core
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
default: Gateway
description: |-
Kind is kind of the referent.
There are two kinds of parent resources with "Core" support:
* Gateway (Gateway conformance profile)
* Service (Mesh conformance profile, ClusterIP Services only)
Support for other resources is Implementation-Specific.
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
name:
description: |-
Name is the name of the referent.
Support: Core
maxLength: 253
minLength: 1
type: string
namespace:
description: |-
Namespace is the namespace of the referent. When unspecified, this refers
to the local namespace of the Route.
Note that there are specific rules for ParentRefs which cross namespace
boundaries. Cross-namespace references are only valid if they are explicitly
allowed by something in the namespace they are referring to. For example:
Gateway has the AllowedRoutes field, and ReferenceGrant provides a
generic way to enable any other kind of cross-namespace reference.
<gateway:experimental:description>
ParentRefs from a Route to a Service in the same namespace are "producer"
routes, which apply default routing rules to inbound connections from
any namespace to the Service.
ParentRefs from a Route to a Service in a different namespace are
"consumer" routes, and these routing rules are only applied to outbound
connections originating from the same namespace as the Route, for which
the intended destination of the connections are a Service targeted as a
ParentRef of the Route.
</gateway:experimental:description>
Support: Core
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
port:
description: |-
Port is the network port this Route targets. It can be interpreted
differently based on the type of parent resource.
When the parent resource is a Gateway, this targets all listeners
listening on the specified port that also support this kind of Route(and
select this Route). It's not recommended to set `Port` unless the
networking behaviors specified in a Route must apply to a specific port
as opposed to a listener(s) whose port(s) may be changed. When both Port
and SectionName are specified, the name and port of the selected listener
must match both specified values.
<gateway:experimental:description>
When the parent resource is a Service, this targets a specific port in the
Service spec. When both Port (experimental) and SectionName are specified,
the name and port of the selected port must match both specified values.
</gateway:experimental:description>
Implementations MAY choose to support other parent resources.
Implementations supporting other types of parent resources MUST clearly
document how/if Port is interpreted.
For the purpose of status, an attachment is considered successful as
long as the parent resource accepts it partially. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
namespace, or hostname. If 1 of 2 Gateway listeners accept attachment
from the referencing Route, the Route MUST be considered successfully
attached. If no Gateway listeners accept attachment from this Route,
the Route MUST be considered detached from the Gateway.
Support: Extended
format: int32
maximum: 65535
minimum: 1
type: integer
sectionName:
description: |-
SectionName is the name of a section within the target resource. In the
following resources, SectionName is interpreted as the following:
* Gateway: Listener name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
* Service: Port name. When both Port (experimental) and SectionName
are specified, the name and port of the selected listener must match
both specified values.
Implementations MAY choose to support attaching Routes to other resources.
If that is the case, they MUST clearly document how SectionName is
interpreted.
When unspecified (empty string), this will reference the entire resource.
For the purpose of status, an attachment is considered successful if at
least one section in the parent resource accepts it. For example, Gateway
listeners can restrict which Routes can attach to them by Route kind,
namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from
the referencing Route, the Route MUST be considered successfully
attached. If no Gateway listeners accept attachment from this Route, the
Route MUST be considered detached from the Gateway.
Support: Core
maxLength: 253
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
required:
- name
type: object
type: array
required:
- parentRefs
type: object
ingress:
description: Ingress
properties:
annotations:
additionalProperties:
type: string
description: Annotations the annotations to be added to the ingress
type: object
enabled:
description: Enabled enables/disables the ingress for flagd
type: boolean
flagdPath:
description: |-
FlagdPath is the path to be used for accessing the flagd flag evaluation API
Default: /flagd.evaluation.v1.Service
type: string
hosts:
description: |-
Hosts list of hosts to be added to the ingress.
Empty string corresponds to rule with no host.
items:
type: string
type: array
ingressClassName:
description: IngressClassName defines the name if the ingress
class to be used for flagd
type: string
ofrepPath:
description: |-
OFREPPath is the path to be used for accessing the OFREP API
Default: /ofrep
type: string
pathType:
description: PathType is the path type to be used for the ingress
rules
type: string
syncPath:
description: |-
SyncPath is the path to be used for accessing the sync API
Default: /flagd.sync.v1.Service
type: string
tls:
description: TLS configuration for the ingress
items:
description: IngressTLS describes the transport layer security
associated with an ingress.
properties:
hosts:
description: |-
hosts is a list of hosts included in the TLS certificate. The values in
this list must match the name/s used in the tlsSecret. Defaults to the
wildcard host setting for the loadbalancer controller fulfilling this
Ingress, if left unspecified.
items:
type: string
type: array
x-kubernetes-list-type: atomic
secretName:
description: |-
secretName is the name of the secret used to terminate TLS traffic on
port 443. Field is left optional to allow TLS routing based on SNI
hostname alone. If the SNI host in a listener conflicts with the "Host"
header field used by an IngressRule, the SNI host is used for termination
and value of the "Host" header is used for routing.
type: string
type: object
type: array
required:
- hosts
type: object
replicas:
default: 1
description: |-
Replicas defines the number of replicas to create for the service.
Default: 1
format: int32
type: integer
serviceAccountName:
description: ServiceAccountName the service account name for the flagd
deployment
type: string
serviceType:
default: ClusterIP
description: |-
ServiceType represents the type of Service to create.
Must be one of: ClusterIP, NodePort, LoadBalancer, and ExternalName.
Default: ClusterIP
enum:
- ClusterIP
- NodePort
- LoadBalancer
- ExternalName
type: string
required:
- featureFlagSource
type: object
status:
description: FlagdStatus defines the observed state of Flagd
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -1,724 +0,0 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
name: flagsourceconfigurations.core.openfeature.dev
spec:
group: core.openfeature.dev
names:
kind: FlagSourceConfiguration
listKind: FlagSourceConfigurationList
plural: flagsourceconfigurations
shortNames:
- fsc
singular: flagsourceconfiguration
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: FlagSourceConfiguration is the Schema for the FlagSourceConfigurations
API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: FlagSourceConfigurationSpec defines the desired state of
FlagSourceConfiguration
properties:
debugLogging:
description: DebugLogging defines whether to enable --debug flag of
flagd sidecar. Default false (disabled).
type: boolean
defaultSyncProvider:
description: DefaultSyncProvider defines the default sync provider
type: string
envVarPrefix:
description: EnvVarPrefix defines the prefix to be applied to all
environment variables applied to the sidecar, default FLAGD
type: string
envVars:
description: |-
EnvVars define the env vars to be applied to the sidecar, any env vars in FeatureFlagConfiguration CRs
are added at the lowest index, all values will have the EnvVarPrefix applied
items:
description: EnvVar represents an environment variable present in
a Container.
properties:
name:
description: Name of the environment variable. Must be a C_IDENTIFIER.
type: string
value:
description: |-
Variable references $(VAR_NAME) are expanded
using the previously defined environment variables in the container and
any service environment variables. If a variable cannot be resolved,
the reference in the input string will be unchanged. Double $$ are reduced
to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
Escaped references will never be expanded, regardless of whether the variable
exists or not.
Defaults to "".
type: string
valueFrom:
description: Source for the environment variable's value. Cannot
be used if value is not empty.
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key
must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
fieldRef:
description: |-
Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,
spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
properties:
apiVersion:
description: Version of the schema the FieldPath is
written in terms of, defaults to "v1".
type: string
fieldPath:
description: Path of the field to select in the specified
API version.
type: string
required:
- fieldPath
type: object
x-kubernetes-map-type: atomic
resourceFieldRef:
description: |-
Selects a resource of the container: only resources limits and requests
(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
properties:
containerName:
description: 'Container name: required for volumes,
optional for env vars'
type: string
divisor:
anyOf:
- type: integer
- type: string
description: Specifies the output format of the exposed
resources, defaults to "1"
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
resource:
description: 'Required: resource to select'
type: string
required:
- resource
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a secret in the pod's namespace
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must
be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
required:
- name
type: object
type: array
evaluator:
description: Evaluator sets an evaluator, defaults to 'json'
type: string
image:
description: Image allows for the sidecar image to be overridden,
defaults to 'ghcr.io/open-feature/flagd'
type: string
logFormat:
description: LogFormat allows for the sidecar log format to be overridden,
defaults to 'json'
type: string
metricsPort:
description: MetricsPort defines the port to serve metrics on, defaults
to 8014
format: int32
type: integer
otelCollectorUri:
description: OtelCollectorUri defines whether to enable --otel-collector-uri
flag of flagd sidecar. Default false (disabled).
type: string
port:
description: Port defines the port to listen on, defaults to 8013
format: int32
type: integer
probesEnabled:
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-* and sidecar-ram-* flags.
properties:
claims:
description: |-
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.
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
request:
description: |-
Request is the name chosen for a request in the referenced claim.
If empty, everything from the claim is made available, otherwise
only the result of this request.
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. Requests cannot exceed Limits.
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 CR, defaults to false
type: boolean
socketPath:
description: SocketPath defines the unix socket path to listen on
type: string
sources:
description: Sources defines the syncProviders and associated configuration
to be applied to the sidecar
items:
properties:
certPath:
description: CertPath is a path of a certificate to be used
by grpc TLS connection
type: string
httpSyncBearerToken:
description: HttpSyncBearerToken is a bearer token. Used by
http(s) sync provider only
type: string
provider:
description: Provider type - kubernetes, http, grpc or filepath
type: string
providerID:
description: ProviderID is an identifier to be used in grpc
provider
type: string
selector:
description: Selector is a flag configuration selector used
by grpc provider
type: string
source:
description: Source is a URI of the flag sources
type: string
tls:
description: TLS - Enable/Disable secure TLS connectivity. Currently
used only by GRPC sync
type: boolean
required:
- source
type: object
minItems: 1
type: array
syncProviderArgs:
description: SyncProviderArgs are string arguments passed to all sync
providers, defined as key values separated by =
items:
type: string
type: array
tag:
description: Tag to be appended to the sidecar image, defaults to
'main'
type: string
required:
- sources
type: object
status:
description: FlagSourceConfigurationStatus defines the observed state
of FlagSourceConfiguration
type: object
type: object
served: true
storage: true
subresources:
status: {}
- name: v1alpha2
schema:
openAPIV3Schema:
description: FlagSourceConfiguration is the Schema for the FlagSourceConfigurations
API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: FlagSourceConfigurationSpec defines the desired state of
FlagSourceConfiguration
properties:
defaultSyncProvider:
description: DefaultSyncProvider defines the default sync provider
type: string
evaluator:
description: Evaluator sets an evaluator, defaults to 'json'
type: string
image:
description: Image allows for the sidecar image to be overridden,
defaults to 'ghcr.io/open-feature/flagd'
type: string
logFormat:
description: LogFormat allows for the sidecar log format to be overridden,
defaults to 'json'
type: string
metricsPort:
description: MetricsPort defines the port to serve metrics on, defaults
to 8013
format: int32
type: integer
otelCollectorUri:
description: OtelCollectorUri defines whether to enable --otel-collector-uri
flag of flagd sidecar. Default false (disabled).
type: string
port:
description: Port defines the port to listen on, defaults to 8014
format: int32
type: integer
probesEnabled:
description: ProbesEnabled defines whether to enable liveness and
readiness probes of flagd sidecar. Default true (enabled).
type: boolean
socketPath:
description: SocketPath defines the unix socket path to listen on
type: string
syncProviderArgs:
description: SyncProviderArgs are string arguments passed to all sync
providers, defined as key values separated by =
items:
type: string
type: array
tag:
description: Tag to be appended to the sidecar image, defaults to
'main'
type: string
type: object
status:
description: FlagSourceConfigurationStatus defines the observed state
of FlagSourceConfiguration
type: object
type: object
served: true
storage: false
subresources:
status: {}
- name: v1alpha3
schema:
openAPIV3Schema:
description: FlagSourceConfiguration is the Schema for the FlagSourceConfigurations
API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: FlagSourceConfigurationSpec defines the desired state of
FlagSourceConfiguration
properties:
debugLogging:
description: DebugLogging defines whether to enable --debug flag of
flagd sidecar. Default false (disabled).
type: boolean
defaultSyncProvider:
description: DefaultSyncProvider defines the default sync provider
type: string
envVarPrefix:
description: EnvVarPrefix defines the prefix to be applied to all
environment variables applied to the sidecar, default FLAGD
type: string
envVars:
description: |-
EnvVars define the env vars to be applied to the sidecar, any env vars in FeatureFlagConfiguration CRs
are added at the lowest index, all values will have the EnvVarPrefix applied, default FLAGD
items:
description: EnvVar represents an environment variable present in
a Container.
properties:
name:
description: Name of the environment variable. Must be a C_IDENTIFIER.
type: string
value:
description: |-
Variable references $(VAR_NAME) are expanded
using the previously defined environment variables in the container and
any service environment variables. If a variable cannot be resolved,
the reference in the input string will be unchanged. Double $$ are reduced
to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
Escaped references will never be expanded, regardless of whether the variable
exists or not.
Defaults to "".
type: string
valueFrom:
description: Source for the environment variable's value. Cannot
be used if value is not empty.
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key
must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
fieldRef:
description: |-
Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,
spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
properties:
apiVersion:
description: Version of the schema the FieldPath is
written in terms of, defaults to "v1".
type: string
fieldPath:
description: Path of the field to select in the specified
API version.
type: string
required:
- fieldPath
type: object
x-kubernetes-map-type: atomic
resourceFieldRef:
description: |-
Selects a resource of the container: only resources limits and requests
(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
properties:
containerName:
description: 'Container name: required for volumes,
optional for env vars'
type: string
divisor:
anyOf:
- type: integer
- type: string
description: Specifies the output format of the exposed
resources, defaults to "1"
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
resource:
description: 'Required: resource to select'
type: string
required:
- resource
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a secret in the pod's namespace
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must
be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
required:
- name
type: object
type: array
evaluator:
description: Evaluator sets an evaluator, defaults to 'json'
type: string
image:
description: Image allows for the sidecar image to be overridden,
defaults to 'ghcr.io/open-feature/flagd'
type: string
logFormat:
description: LogFormat allows for the sidecar log format to be overridden,
defaults to 'json'
type: string
metricsPort:
description: MetricsPort defines the port to serve metrics on, defaults
to 8014
format: int32
type: integer
otelCollectorUri:
description: OtelCollectorUri defines whether to enable --otel-collector-uri
flag of flagd sidecar. Default false (disabled).
type: string
port:
description: Port defines the port to listen on, defaults to 8013
format: int32
type: integer
probesEnabled:
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-* and sidecar-ram-* flags.
properties:
claims:
description: |-
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.
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
request:
description: |-
Request is the name chosen for a request in the referenced claim.
If empty, everything from the claim is made available, otherwise
only the result of this request.
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. Requests cannot exceed Limits.
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 CR, defaults to false
type: boolean
socketPath:
description: SocketPath defines the unix socket path to listen on
type: string
sources:
description: SyncProviders define the syncProviders and associated
configuration to be applied to the sidecar
items:
properties:
certPath:
description: CertPath is a path of a certificate to be used
by grpc TLS connection
type: string
httpSyncBearerToken:
description: HttpSyncBearerToken is a bearer token. Used by
http(s) sync provider only
type: string
provider:
description: Provider type - kubernetes, http(s), grpc(s) or
filepath
type: string
providerID:
description: ProviderID is an identifier to be used in grpc
provider
type: string
selector:
description: Selector is a flag configuration selector used
by grpc provider
type: string
source:
description: Source is a URI of the flag sources
type: string
tls:
description: TLS - Enable/Disable secure TLS connectivity. Currently
used only by GRPC sync
type: boolean
required:
- source
type: object
minItems: 1
type: array
syncProviderArgs:
description: SyncProviderArgs are string arguments passed to all sync
providers, defined as key values separated by =
items:
type: string
type: array
tag:
description: Tag to be appended to the sidecar image, defaults to
'main'
type: string
required:
- sources
type: object
status:
description: FlagSourceConfigurationStatus defines the observed state
of FlagSourceConfiguration
type: object
type: object
served: true
storage: false
subresources:
status: {}

View File

@ -1,206 +0,0 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.5
name: inprocessconfigurations.core.openfeature.dev
spec:
group: core.openfeature.dev
names:
kind: InProcessConfiguration
listKind: InProcessConfigurationList
plural: inprocessconfigurations
singular: inprocessconfiguration
scope: Namespaced
versions:
- name: v1beta1
schema:
openAPIV3Schema:
description: InProcessConfiguration is the Schema for the inprocesconfigurations
API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: InProcessConfigurationSpec defines the desired state of InProcessConfiguration
properties:
cache:
default: lru
description: Cache
pattern: ^(lru|disabled)$
type: string
cacheMaxSize:
default: 1000
description: CacheMaxSize
type: integer
envVarPrefix:
default: FLAGD
description: EnvVarPrefix defines the prefix to be applied to all
environment variables applied to the sidecar, default FLAGD
type: string
envVars:
description: EnvVars
items:
description: EnvVar represents an environment variable present in
a Container.
properties:
name:
description: Name of the environment variable. Must be a C_IDENTIFIER.
type: string
value:
description: |-
Variable references $(VAR_NAME) are expanded
using the previously defined environment variables in the container and
any service environment variables. If a variable cannot be resolved,
the reference in the input string will be unchanged. Double $$ are reduced
to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
Escaped references will never be expanded, regardless of whether the variable
exists or not.
Defaults to "".
type: string
valueFrom:
description: Source for the environment variable's value. Cannot
be used if value is not empty.
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the ConfigMap or its key
must be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
fieldRef:
description: |-
Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,
spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
properties:
apiVersion:
description: Version of the schema the FieldPath is
written in terms of, defaults to "v1".
type: string
fieldPath:
description: Path of the field to select in the specified
API version.
type: string
required:
- fieldPath
type: object
x-kubernetes-map-type: atomic
resourceFieldRef:
description: |-
Selects a resource of the container: only resources limits and requests
(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
properties:
containerName:
description: 'Container name: required for volumes,
optional for env vars'
type: string
divisor:
anyOf:
- type: integer
- type: string
description: Specifies the output format of the exposed
resources, defaults to "1"
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
resource:
description: 'Required: resource to select'
type: string
required:
- resource
type: object
x-kubernetes-map-type: atomic
secretKeyRef:
description: Selects a key of a secret in the pod's namespace
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
default: ""
description: |-
Name of the referent.
This field is effectively required, but due to backwards compatibility is
allowed to be empty. Instances of this type with an empty value here are
almost certainly wrong.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
type: string
optional:
description: Specify whether the Secret or its key must
be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
required:
- name
type: object
type: array
host:
default: localhost
description: Host
type: string
offlineFlagSourcePath:
description: OfflineFlagSourcePath
type: string
port:
default: 8015
description: Port defines the port to listen on, defaults to 8015
format: int32
type: integer
selector:
description: Selector
type: string
socketPath:
description: SocketPath defines the unix socket path to listen on
type: string
tls:
default: false
description: TLS
type: boolean
type: object
status:
description: InProcessConfigurationStatus defines the observed state of
InProcessConfiguration
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -2,21 +2,20 @@
# since it depends on service name and namespace that are out of this kustomize package.
# It should be run by config/default
resources:
- bases/core.openfeature.dev_featureflags.yaml
- bases/core.openfeature.dev_featureflagsources.yaml
- bases/core.openfeature.dev_flagds.yaml
- bases/core.openfeature.dev_inprocessconfigurations.yaml
- bases/core.openfeature.dev_featureflagconfigurations.yaml
#+kubebuilder:scaffold:crdkustomizeresource
patches:
patchesStrategicMerge:
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
# patches here are for enabling the conversion webhook for each CRD
#- patches/webhook_in_featureflags.yaml
#- patches/webhook_in_featureflagsources.yaml
#- patches/webhook_in_flagds.yaml
#- patches/webhook_in_inprocessconfigurations.yaml
#- patches/webhook_in_featureflagconfigurations.yaml
#+kubebuilder:scaffold:crdkustomizewebhookpatch
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD
#- patches/cainjection_in_featureflagconfigurations.yaml
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
# the following config is for teaching kustomize how to do kustomization for CRDs.
configurations:
- kustomizeconfig.yaml

View File

@ -1,19 +1,19 @@
# This file is for teaching kustomize how to substitute name and namespace reference in CRD
nameReference:
- kind: Service
version: v1
fieldSpecs:
- kind: CustomResourceDefinition
version: v1
group: apiextensions.k8s.io
path: spec/conversion/webhook/clientConfig/service/name
namespace:
- kind: Service
version: v1
fieldSpecs:
- kind: CustomResourceDefinition
version: v1
group: apiextensions.k8s.io
path: spec/conversion/webhook/clientConfig/service/namespace
create: false
path: spec/conversion/webhook/clientConfig/service/name
namespace:
- kind: CustomResourceDefinition
version: v1
group: apiextensions.k8s.io
path: spec/conversion/webhook/clientConfig/service/namespace
create: false
varReference:
- path: metadata/annotations
- path: metadata/annotations

View File

@ -0,0 +1,7 @@
# The following patch adds a directive for certmanager to inject CA into the CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
name: featureflagconfigurations.core.openfeature.dev

View File

@ -1,16 +0,0 @@
# The following patch enables a conversion webhook for the CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: inprocessconfigurations.core.openfeature.dev
spec:
conversion:
strategy: Webhook
webhook:
clientConfig:
service:
namespace: system
name: webhook-service
path: /convert
conversionReviewVersions:
- v1

View File

@ -2,7 +2,7 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: flagds.core.openfeature.dev
name: featureflagconfigurations.core.openfeature.dev
spec:
conversion:
strategy: Webhook

View File

@ -1,30 +0,0 @@
# This patch adds the args, volumes, and ports to allow the manager to use the metrics-server certs.
# Add the volumeMount for the metrics-server certs
- op: add
path: /spec/template/spec/containers/0/volumeMounts/-
value:
mountPath: /tmp/k8s-metrics-server/metrics-certs
name: metrics-certs
readOnly: true
# Add the --metrics-cert-path argument for the metrics server
- op: add
path: /spec/template/spec/containers/0/args/-
value: --metrics-cert-path=/tmp/k8s-metrics-server/metrics-certs
# Add the metrics-server certs volume configuration
- op: add
path: /spec/template/spec/volumes/-
value:
name: metrics-certs
secret:
secretName: metrics-server-cert
optional: false
items:
- key: ca.crt
path: ca.crt
- key: tls.crt
path: tls.crt
- key: tls.key
path: tls.key

View File

@ -1,4 +1,4 @@
# Adds namespace to all resources. If this namespace is changed the value must be reflected in /chart/open-feature-operator/values.yaml
# Adds namespace to all resources. If this namespace is changed the value must be reflected in /chart/values.yaml
namespace: open-feature-operator-system
# Value of this field is prepended to the
@ -12,206 +12,63 @@ namePrefix: open-feature-operator-
#commonLabels:
# someName: someValue
resources:
bases:
- ../crd
- ../rbac
- ../manager
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
# crd/kustomization.yaml
- ../webhook
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required.
- ../certmanager
# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
#- ../prometheus
# [NETWORK POLICY] Protect the /metrics endpoint and Webhook Server with NetworkPolicy.
# Only Pod(s) running a namespace labeled with 'metrics: enabled' will be able to gather the metrics.
# Only CR(s) which requires webhooks and are applied on namespaces labeled with 'webhooks: enabled' will
# be able to communicate with the Webhook Server.
#- ../network-policy
patchesStrategicMerge:
# Protect the /metrics endpoint by putting it behind auth.
# If you want your controller-manager to expose the /metrics
# endpoint w/o any authn/z, please comment the following line.
- manager_auth_proxy_patch.yaml
patches:
# Mount the controller config file for loading manager configurations
# through a ComponentConfig type
#- manager_config_patch.yaml
# [METRICS] The following patch will enable the metrics endpoint using HTTPS and the port :8443.
# More info: https://book.kubebuilder.io/reference/metrics
- path: manager_metrics_patch.yaml
target:
kind: Deployment
# Uncomment the patches line if you enable Metrics and CertManager
# [METRICS-WITH-CERTS] To enable metrics protected with certManager, uncomment the following line.
# This patch will protect the metrics with certManager self-signed certs.
- path: cert_metrics_manager_patch.yaml
target:
kind: Deployment
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
# crd/kustomization.yaml
- path: manager_webhook_patch.yaml
target:
kind: Deployment
- manager_webhook_patch.yaml
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'.
# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks.
# 'CERTMANAGER' needs to be enabled to use ca injection
- webhookcainjection_patch.yaml
# the following config is for teaching kustomize how to do var substitution
vars:
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix.
# Uncomment the following replacements to add the cert-manager CA injection annotations
replacements:
- source: # Uncomment the following block to enable certificates for metrics
kind: Service
version: v1
name: controller-manager-metrics-service
fieldPath: metadata.name
targets:
- select:
kind: Certificate
group: cert-manager.io
version: v1
name: metrics-certs
fieldPaths:
- spec.dnsNames.0
- spec.dnsNames.1
options:
delimiter: '.'
index: 0
create: true
- source:
kind: Service
version: v1
name: controller-manager-metrics-service
fieldPath: metadata.namespace
targets:
- select:
kind: Certificate
group: cert-manager.io
version: v1
name: metrics-certs
fieldPaths:
- spec.dnsNames.0
- spec.dnsNames.1
options:
delimiter: '.'
index: 1
create: true
- source: # Uncomment the following block if you have any webhook
kind: Service
version: v1
name: webhook-service
fieldPath: .metadata.name # Name of the service
targets:
- select:
kind: Certificate
group: cert-manager.io
version: v1
name: serving-cert
fieldPaths:
- .spec.dnsNames.0
- .spec.dnsNames.1
options:
delimiter: '.'
index: 0
create: true
- source:
kind: Service
version: v1
name: webhook-service
fieldPath: .metadata.namespace # Namespace of the service
targets:
- select:
kind: Certificate
group: cert-manager.io
version: v1
name: serving-cert
fieldPaths:
- .spec.dnsNames.0
- .spec.dnsNames.1
options:
delimiter: '.'
index: 1
create: true
- source: # Uncomment the following block if you have a ValidatingWebhook (--programmatic-validation)
kind: Certificate
group: cert-manager.io
version: v1
name: serving-cert # This name should match the one in certificate.yaml
fieldPath: .metadata.namespace # Namespace of the certificate CR
targets:
- select:
kind: ValidatingWebhookConfiguration
fieldPaths:
- .metadata.annotations.[cert-manager.io/inject-ca-from]
options:
delimiter: '/'
index: 0
create: true
- source:
kind: Certificate
group: cert-manager.io
version: v1
name: serving-cert
fieldPath: .metadata.name
targets:
- select:
kind: ValidatingWebhookConfiguration
fieldPaths:
- .metadata.annotations.[cert-manager.io/inject-ca-from]
options:
delimiter: '/'
index: 1
create: true
- source: # Uncomment the following block if you have a DefaultingWebhook (--defaulting )
kind: Certificate
group: cert-manager.io
version: v1
name: serving-cert
fieldPath: .metadata.namespace # Namespace of the certificate CR
targets:
- select:
kind: MutatingWebhookConfiguration
fieldPaths:
- .metadata.annotations.[cert-manager.io/inject-ca-from]
options:
delimiter: '/'
index: 0
create: true
- source:
kind: Certificate
group: cert-manager.io
version: v1
name: serving-cert
fieldPath: .metadata.name
targets:
- select:
kind: MutatingWebhookConfiguration
fieldPaths:
- .metadata.annotations.[cert-manager.io/inject-ca-from]
options:
delimiter: '/'
index: 1
create: true
# - source: # Uncomment the following block if you have a ConversionWebhook (--conversion)
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert
# fieldPath: .metadata.namespace # Namespace of the certificate CR
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
# +kubebuilder:scaffold:crdkustomizecainjectionns
# - source:
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert
# fieldPath: .metadata.name
# targets: # Do not remove or uncomment the following scaffold marker; required to generate code for target CRD.
# +kubebuilder:scaffold:crdkustomizecainjectionname
- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR
objref:
kind: Certificate
group: cert-manager.io
version: v1
name: serving-cert # this name should match the one in certificate.yaml
fieldref:
fieldpath: metadata.namespace
- name: CERTIFICATE_NAME
objref:
kind: Certificate
group: cert-manager.io
version: v1
name: serving-cert # this name should match the one in certificate.yaml
- name: SERVICE_NAMESPACE # namespace of the service
objref:
kind: Service
version: v1
name: webhook-service
fieldref:
fieldpath: metadata.namespace
- name: SERVICE_NAME
objref:
kind: Service
version: v1
name: webhook-service

View File

@ -0,0 +1,34 @@
# This patch inject a sidecar container which is a HTTP proxy for the
# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews.
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- name: kube-rbac-proxy
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0
args:
- "--secure-listen-address=0.0.0.0:8443"
- "--upstream=http://127.0.0.1:8080/"
- "--logtostderr=true"
- "--v=0"
ports:
- containerPort: 8443
protocol: TCP
name: https
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 5m
memory: 64Mi
- name: manager
args:
- "--health-probe-bind-address=:8081"
- "--metrics-bind-address=127.0.0.1:8080"
- "--leader-elect"

View File

@ -1,4 +0,0 @@
# This patch adds the args to allow exposing the metrics endpoint using HTTPS
- op: add
path: /spec/template/spec/containers/0/args/0
value: --metrics-bind-address=:8443

View File

@ -1,31 +1,23 @@
# This patch ensures the webhook certificates are properly mounted in the manager container.
# It configures the necessary arguments, volumes, volume mounts, and container ports.
# Add the --webhook-cert-path argument for configuring the webhook certificate path
- op: add
path: /spec/template/spec/containers/0/args/-
value: --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs
# Add the volumeMount for the webhook certificates
- op: add
path: /spec/template/spec/containers/0/volumeMounts/-
value:
mountPath: /tmp/k8s-webhook-server/serving-certs
name: webhook-certs
readOnly: true
# Add the port configuration for the webhook server
- op: add
path: /spec/template/spec/containers/0/ports/-
value:
containerPort: 9443
name: webhook-server
protocol: TCP
# Add the volume configuration for the webhook certificates
- op: add
path: /spec/template/spec/volumes/-
value:
name: webhook-certs
secret:
secretName: webhook-server-cert
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- name: manager
ports:
- containerPort: 9443
name: webhook-server
protocol: TCP
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
readOnly: true
volumes:
- name: cert
secret:
defaultMode: 420
secretName: webhook-server-cert

View File

@ -1,18 +0,0 @@
apiVersion: v1
kind: Service
metadata:
labels:
control-plane: controller-manager
app.kubernetes.io/name: open-feature-operator
app.kubernetes.io/managed-by: kustomize
name: controller-manager-metrics-service
namespace: system
spec:
ports:
- name: https
port: 8443
protocol: TCP
targetPort: 8443
selector:
control-plane: controller-manager
app.kubernetes.io/name: open-feature-operator

View File

@ -0,0 +1,15 @@
# This patch add annotation to admission webhook config and
# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize.
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: mutating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)

View File

@ -1,6 +1,3 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- manager.yaml
@ -11,8 +8,9 @@ configMapGenerator:
- files:
- controller_manager_config.yaml
name: manager-config
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: controller
newName: open-feature-operator-local
newTag: validate
newName: controller
newTag: latest

View File

@ -3,7 +3,6 @@ kind: Namespace
metadata:
labels:
control-plane: controller-manager
app.kubernetes.io/name: open-feature-operator
name: system
---
apiVersion: apps/v1
@ -13,13 +12,10 @@ metadata:
namespace: system
labels:
control-plane: controller-manager
app.kubernetes.io/name: open-feature-operator
app.kubernetes.io/managed-by: kustomize
spec:
selector:
matchLabels:
control-plane: controller-manager
app.kubernetes.io/name: open-feature-operator
replicas: 1
template:
metadata:
@ -27,32 +23,22 @@ spec:
kubectl.kubernetes.io/default-container: manager
labels:
control-plane: controller-manager
app.kubernetes.io/name: open-feature-operator
app.kubernetes.io/managed-by: kustomize
spec:
securityContext:
runAsNonRoot: true
containers:
- command:
- /manager
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
args:
- --leader-elect
- --sidecar-cpu-limit=500m
- --sidecar-ram-limit=64Mi
- --sidecar-cpu-request=200m
- --sidecar-ram-request=32Mi
imagePullPolicy: IfNotPresent
imagePullPolicy: Always
image: controller:main
name: manager
ports: []
env:
- name: FLAGD_VERSION
value: v0.2.5
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
livenessProbe:
httpGet:
path: /healthz
@ -74,7 +60,5 @@ spec:
requests:
cpu: 10m
memory: 64Mi
volumeMounts: []
volumes: []
serviceAccountName: controller-manager
terminationGracePeriodSeconds: 10

View File

@ -1,27 +0,0 @@
# This NetworkPolicy allows ingress traffic
# with Pods running on namespaces labeled with 'metrics: enabled'. Only Pods on those
# namespaces are able to gather data from the metrics endpoint.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
app.kubernetes.io/name: open-feature-operator
app.kubernetes.io/managed-by: kustomize
name: allow-metrics-traffic
namespace: system
spec:
podSelector:
matchLabels:
control-plane: controller-manager
app.kubernetes.io/name: open-feature-operator
policyTypes:
- Ingress
ingress:
# This allows ingress traffic from any namespace with the label metrics: enabled
- from:
- namespaceSelector:
matchLabels:
metrics: enabled # Only from namespaces with this label
ports:
- port: 8443
protocol: TCP

View File

@ -1,27 +0,0 @@
# This NetworkPolicy allows ingress traffic to your webhook server running
# as part of the controller-manager from specific namespaces and pods. CR(s) which uses webhooks
# will only work when applied in namespaces labeled with 'webhook: enabled'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
app.kubernetes.io/name: open-feature-operator
app.kubernetes.io/managed-by: kustomize
name: allow-webhook-traffic
namespace: system
spec:
podSelector:
matchLabels:
control-plane: controller-manager
app.kubernetes.io/name: open-feature-operator
policyTypes:
- Ingress
ingress:
# This allows ingress traffic from any namespace with the label webhook: enabled
- from:
- namespaceSelector:
matchLabels:
webhook: enabled # Only from namespaces with this label
ports:
- port: 443
protocol: TCP

View File

@ -1,2 +0,0 @@
resources:
- allow-metrics-traffic.yaml

View File

@ -1,21 +0,0 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
spec:
dnsNames:
- SERVICE_NAME.{{ include "chart.namespace" . }}.svc
- SERVICE_NAME.{{ include "chart.namespace" . }}.svc.cluster.local
---
# The following manifests contain a self-signed issuer CR and a metrics certificate CR.
# More document can be found at https://docs.cert-manager.io
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: metrics-certs # this name should match the one appeared in kustomizeconfig.yaml
spec:
dnsNames:
# SERVICE_NAME and SERVICE_NAMESPACE will be substituted by kustomize
# replacements in the config/default/kustomization.yaml file.
- SERVICE_NAME.{{ include "chart.namespace" . }}.svc
- SERVICE_NAME.{{ include "chart.namespace" . }}.svc.cluster.local

View File

@ -1,8 +0,0 @@
apiVersion: controller-runtime.sigs.k8s.io/v1alpha1
kind: ControllerManagerConfig
health:
healthProbeBindAddress: "{{ .Values.managerConfig.controllerManagerConfigYaml.health.healthProbeBindAddress }}"
metrics:
bindAddress: "{{ .Values.managerConfig.controllerManagerConfigYaml.metrics.bindAddress }}:{{ .Values.managerConfig.controllerManagerConfigYaml.metrics.bindPort }}"
webhook:
port: 0{{ .Values.managerConfig.controllerManagerConfigYaml.webhook.port }}

View File

@ -1,5 +0,0 @@
$patch: delete
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: validating-webhook-configuration

View File

@ -1,16 +0,0 @@
# delete the default webhook-server port (to avoid duplicate) since we build it from helm
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- name: manager
ports:
- containerPort: 9443
name: webhook-server
protocol: TCP
$patch: delete

View File

@ -1,5 +1,5 @@
# import the default deployment as the base
resources:
bases:
- ../../default
# replace the default namespace with {{ include "chart.namespace" . }}
@ -11,55 +11,5 @@ namespace: |-
# merge the exclude-ns.yaml with the existing namespace definition, this contains the `$patch: delete` directive allowing
# for the helm chart to define the namespace conditionally (only deploys when no namespace is provided and the default
# (open-feature-operator-system) is used
patches:
- path: exclude-ns.yaml
- path: manager.yaml
- path: exclude-webhook-server-container-port.yaml
- path: exclude-validatingwebhook.yaml
- path: mutatingwebhook.yaml
- path: certificate-patch.yaml
configMapGenerator:
- name: manager-config
behavior: merge
files:
- controller_manager_config.yaml
replacements:
- source: # Uncomment the following block to enable certificates for metrics
kind: Service
version: v1
name: controller-manager-metrics-service
fieldPath: metadata.name
targets:
- select:
kind: Certificate
group: cert-manager.io
version: v1
name: metrics-certs
fieldPaths:
- spec.dnsNames.0
- spec.dnsNames.1
options:
delimiter: '.'
index: 0
create: true
- source: # Uncomment the following block if you have any webhook
kind: Service
version: v1
name: webhook-service
fieldPath: .metadata.name # Name of the service
targets:
- select:
kind: Certificate
group: cert-manager.io
version: v1
name: serving-cert
fieldPaths:
- spec.dnsNames.0
- spec.dnsNames.1
options:
delimiter: '.'
index: 0
create: true
patchesStrategicMerge:
- exclude-ns.yaml

View File

@ -1,117 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
replicas: 0{{ .Values.controllerManager.replicas }}
template:
metadata:
# this is transformed by .github/scripts/strip-kustomize-helm.sh
annotations:
___delete_me___: "___ ___newline___{{ if .Values.annotations }}{{___space___toYaml___space___.Values.annotations___space___|___space___indent___space___8___space___}}{{ end }}___"
# this is transformed by .github/scripts/strip-kustomize-helm.sh
labels:
___delete_me___: "___ ___newline___{{ if .Values.labels }}___newline___{{___space___toYaml___space___.Values.labels___space___|___space___indent___space___8___space___}}{{ end }}___"
spec:
# this is transformed by .github/scripts/strip-kustomize-helm.sh
___imagePullSecrets___: "___ ___newline___ {{ toYaml .Values.imagePullSecrets___space___|___space___indent___space___8___space___}}___"
# this is transformed by .github/scripts/strip-kustomize-helm.sh
hostNetwork: "___{{ .Values.controllerManager.manager.hostNetwork }}___"
dnsPolicy: "{{ .Values.controllerManager.manager.dnsPolicy }}"
containers:
- name: manager
image: "{{ .Values.controllerManager.manager.image.repository }}:{{ .Values.controllerManager.manager.image.tag }}"
resources:
limits:
cpu: "{{ .Values.controllerManager.manager.resources.limits.cpu }}"
memory: "{{ .Values.controllerManager.manager.resources.limits.memory }}"
requests:
cpu: "{{ .Values.controllerManager.manager.resources.requests.cpu }}"
memory: "{{ .Values.controllerManager.manager.resources.requests.memory }}"
ports:
- containerPort: "___ {{ .Values.managerConfig.controllerManagerConfigYaml.webhook.port }} ___"
name: webhook-server
protocol: TCP
- containerPort: "___ {{ .Values.managerConfig.controllerManagerConfigYaml.metrics.bindPort }} ___"
name: metrics-server
protocol: TCP
env:
- name: SIDECAR_MANAGEMENT_PORT
value: "{{ .Values.sidecarConfiguration.managementPort }}"
- 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 }}"
- name: SIDECAR_SYNC_PROVIDER
value: "{{ .Values.sidecarConfiguration.defaultSyncProvider }}"
- name: SIDECAR_EVALUATOR
value: "{{ .Values.sidecarConfiguration.evaluator }}"
- name: SIDECAR_LOG_FORMAT
value: "{{ .Values.sidecarConfiguration.logFormat }}"
- name: SIDECAR_PROBES_ENABLED
value: "{{ .Values.sidecarConfiguration.probesEnabled }}"
- name: FLAGD_PROXY_IMAGE
value: "{{ .Values.flagdProxyConfiguration.image.repository }}"
- name: FLAGD_PROXY_REPLICA_COUNT
value: "{{ .Values.flagdProxyConfiguration.replicaCount }}"
- name: FLAGD_PROXY_TAG
value: "{{ .Values.flagdProxyConfiguration.image.tag }}"
- name: FLAGD_PROXY_PORT
value: "{{ .Values.flagdProxyConfiguration.port }}"
- name: FLAGD_PROXY_MANAGEMENT_PORT
value: "{{ .Values.flagdProxyConfiguration.managementPort }}"
- name: FLAGD_PROXY_DEBUG_LOGGING
value: "{{ .Values.flagdProxyConfiguration.debugLogging }}"
- name: FLAGD_IMAGE
value: "{{ .Values.flagdConfiguration.image.repository }}"
- name: FLAGD_TAG
value: "{{ .Values.flagdConfiguration.image.tag }}"
- name: FLAGD_PORT
value: "{{ .Values.flagdConfiguration.port }}"
- name: FLAGD_OFREP_PORT
value: "{{ .Values.flagdConfiguration.ofrepPort }}"
- name: FLAGD_SYNC_PORT
value: "{{ .Values.flagdConfiguration.syncPort }}"
- name: FLAGD_MANAGEMENT_PORT
value: "{{ .Values.flagdConfiguration.managementPort }}"
- name: FLAGD_DEBUG_LOGGING
value: "{{ .Values.flagdConfiguration.debugLogging }}"
- name: FLAGS_VALIDATION_ENABLED
value: "{{ .Values.managerConfig.flagsValidationEnabled }}"
- name: IN_PROCESS_PORT
value: "{{ .Values.inProcessConfiguration.port }}"
- name: IN_PROCESS_HOST
value: "{{ .Values.inProcessConfiguration.host }}"
- name: IN_PROCESS_SOCKET_PATH
value: "{{ .Values.inProcessConfiguration.socketPath }}"
- name: IN_PROCESS_TLS
value: "{{ .Values.inProcessConfiguration.tls }}"
- name: IN_PROCESS_OFFLINE_FLAG_SOURCE_PATH
value: "{{ .Values.inProcessConfiguration.offlineFlagSourcePath }}"
- name: IN_PROCESS_SELECTOR
value: "{{ .Values.inProcessConfiguration.selector }}"
- name: IN_PROCESS_CACHE
value: "{{ .Values.inProcessConfiguration.cache.type }}"
- name: IN_PROCESS_ENV_VAR_PREFIX
value: "{{ .Values.inProcessConfiguration.envVarPrefix }}"
- name: IN_PROCESS_CACHE_MAX_SIZE
value: "{{ .Values.inProcessConfiguration.cache.size }}"
args:
- --leader-elect
- --sidecar-cpu-limit={{ .Values.sidecarConfiguration.resources.limits.cpu }}
- --sidecar-ram-limit={{ .Values.sidecarConfiguration.resources.limits.memory }}
- --sidecar-cpu-request={{ .Values.sidecarConfiguration.resources.requests.cpu }}
- --sidecar-ram-request={{ .Values.sidecarConfiguration.resources.requests.memory }}
- --image-pull-secrets={{ range .Values.imagePullSecrets }}{{ .name }},{{- end }}
- --metrics-bind-address=:{{ .Values.managerConfig.controllerManagerConfigYaml.metrics.bindPort }}
- --labels={{ $labelKeys := keys .Values.labels -}}{{- $labelPairs := list -}}{{- range $key := $labelKeys -}}{{- $labelPairs = append $labelPairs (printf "%s:%s" $key (index $.Values.labels $key)) -}}{{- end -}}{{- join "," $labelPairs }}
- --annotations={{ $annotationKeys := keys .Values.annotations -}}{{- $annotationPairs := list -}}{{- range $key := $annotationKeys -}}{{- $annotationPairs = append $annotationPairs (printf "%s:%s" $key (index $.Values.annotations $key)) -}}{{- end -}}{{- join "," $annotationPairs }}

View File

@ -1,10 +0,0 @@
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: mutating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: "___'{{ include \"chart.namespace\" . }}/open-feature-operator-serving-cert'___"
webhooks:
- name: mutate.openfeature.dev
failurePolicy: "___{{ .Values.mutatingWebhook.failurePolicy }}___"
objectSelector: "___{{ toYaml .Values.mutatingWebhook.objectSelector | nindent 4 }}___"

View File

@ -1,11 +1,2 @@
resources:
- monitor.yaml
# [PROMETHEUS-WITH-CERTS] The following patch configures the ServiceMonitor in ../prometheus
# to securely reference certificates created and managed by cert-manager.
# Additionally, ensure that you uncomment the [METRICS WITH CERTMANAGER] patch under config/default/kustomization.yaml
# to mount the "metrics-server-cert" secret in the Manager Deployment.
patches:
- path: monitor_tls_patch.yaml
target:
kind: ServiceMonitor

Some files were not shown because too many files have changed in this diff Show More