Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
5528e3f
docs: add ADRs for OpenFGA operator proposal
emilic Apr 6, 2026
93292f3
feat: add operator for migration orchestration (Stage 1)
emilic Apr 10, 2026
22ee215
fix: address PR #309 review feedback from Copilot and CodeRabbit
emilic Apr 11, 2026
539bb14
fix: address additional Copilot review feedback on PR #309
emilic Apr 11, 2026
76c5b12
fix: address remaining PR #309 review feedback
emilic Apr 11, 2026
8c72503
fix: remove EnvFrom from migration Job to preserve least-privilege
emilic Apr 11, 2026
8c857ac
fix: address Copilot review round 3 on PR #309
emilic Apr 11, 2026
0cdaac8
fix: desired version to replace problematic ":" with "_" for label va…
emilic Apr 11, 2026
a7c8446
fix: address Copilot review comments
emilic Apr 11, 2026
95f30e7
fix: validate flags to prevent negative or out-of-range values (i.e. …
emilic Apr 11, 2026
5545a95
fix: gate legacy migration initContainers on operator.enabled
emilic Apr 11, 2026
80a55fa
fix: use single quotes for Helm annotations with nested template expr…
emilic Apr 11, 2026
af2ff38
fix: address Copilot review round 6 on PR #309
emilic Apr 11, 2026
b29322d
fix: remove env var filtering, fix tests, updated README.md to clarif…
emilic Apr 11, 2026
d1f4ff7
fix: update includes OwnerReferences
emilic Apr 11, 2026
00ba96d
feat: add PodDisruptionBudget to operator subchart
emilic Apr 11, 2026
cb2bb8a
fix: use Job conditions instead of status counters for failure detection
emilic Apr 11, 2026
174f3a1
test: add helm-unittest tests for operator mode
emilic Apr 11, 2026
b63aacc
fix: inherit resource limits in operator migration Job
emilic Apr 11, 2026
13c1f17
test: add missing controller unit tests for edge cases
emilic Apr 11, 2026
2b9de0b
fix: wire migration Job flags (backoff/deadline/TTL) through Helm values
emilic Apr 11, 2026
f4048d3
fix: document namespaceOverride in operator subchart values.yaml
emilic Apr 11, 2026
a80d4bf
fix: rename misleading ScaleToZero test to match actual behavior
emilic Apr 11, 2026
a9411bc
fix: require explicit serviceAccount.name when create=false
emilic Apr 11, 2026
bd2725a
docs: update chart structure
emilic Apr 11, 2026
962bb3f
fix: handle AlreadyExists on migration Job creation gracefully
emilic Apr 11, 2026
81e40ba
fix: harden openfga-operator chart security and quality defaults
emilic Apr 11, 2026
e4f18c5
fix: replace scale-to-zero with lookup-based zero-downtime upgrades
emilic Apr 11, 2026
da8cc98
refactor(operator): resolve container via annotation and tidy deploym…
emilic Apr 18, 2026
1e5ccdd
chore: remove ADRs not relevant to this PR
emilic Apr 19, 2026
9783077
fix: clear retry-after annotation after Job creation
emilic Apr 19, 2026
08c201a
fix: a migration Job without a version annotation or matching label i…
emilic Apr 19, 2026
8cf9f70
fix(chart): restore full label set on pod template metadata
emilic Apr 19, 2026
9e3e1b3
ci: add operator-mode coverage and v1.9.5 → v1.14.1 upgrade E2E
emilic Apr 20, 2026
5a40ae2
docs: update docs to reflect operator deployment changes
emilic Apr 20, 2026
c357a36
fix(operator): react to JobFailureTarget for fast failure detection
emilic Apr 20, 2026
be0c24b
chore(schema): reject unknown keys in operator and migration values
emilic Apr 20, 2026
9a3b933
ci(operator): build multi-arch on PRs, add immutable tag on main
emilic Apr 20, 2026
d53b8e3
docs(chart): explain 0-replica install in NOTES when operator is enabled
emilic Apr 20, 2026
b945de2
fix: add missing global block to fix helm unit tests
emilic Apr 20, 2026
5ad4877
fix(operator): use multi-arch base image digests + Go cross-compile
emilic Apr 20, 2026
4c1e8a9
docs(operator-chart): clarify watchNamespace default
emilic Apr 20, 2026
4fb7551
docs: update ADRs to clarify operator migration status
emilic Apr 23, 2026
dfb61af
Merge remote-tracking branch 'origin/main' into feat/operator-migration
SoulPancake Sep 22, 2026
e72ad42
fix(operator): resolve migration reconcile churn and review findings
SoulPancake Sep 22, 2026
26a04da
chore: bump openfga chart to 0.4.0 for operator integration
SoulPancake Sep 22, 2026
d162e4f
Merge remote-tracking branch 'origin/main' into feat/operator-migration
SoulPancake Sep 22, 2026
3676f42
fix(operator): harden migration lifecycle
Siddhant-K-code Sep 22, 2026
317ff91
operator: inherit pull policy, drop blockOwnerDeletion, strategic-mer…
SoulPancake Sep 23, 2026
c11869c
chart: omit spec.replicas in operator mode, gate annotations on apply…
SoulPancake Sep 23, 2026
5b42197
docs: operator migration replica model and limitations
SoulPancake Sep 23, 2026
6a740e1
Merge remote feat/operator-migration
SoulPancake Sep 23, 2026
504a979
operator CI: publish the version image tag once per version
SoulPancake Sep 23, 2026
d46096c
chart: keep legacy migration init containers identical to main
SoulPancake Sep 23, 2026
833a4a8
operator chart: allow the operator to record events
SoulPancake Sep 23, 2026
5a6fcde
operator: build with Go 1.26.8 and bump golang.org/x/net and x/text
SoulPancake Sep 23, 2026
1659b95
ci: pin operator workflow actions and add Dependabot for the operator
SoulPancake Sep 23, 2026
8e7e566
operator: only run migrations, leave the replica count to the chart
SoulPancake Sep 23, 2026
b645b0e
operator: use the module path the code lives at
SoulPancake Sep 23, 2026
572749f
ci: address actionlint findings in the operator workflows
SoulPancake Sep 23, 2026
3d544ba
chart: enable the operator with openfga-operator.enabled, drop migrat…
SoulPancake Sep 23, 2026
bccdb31
docs: document operator mode in the chart README and tidy the ADRs
SoulPancake Sep 23, 2026
1655b0c
ci: test operator changes against a cluster and guard the image version
SoulPancake Sep 23, 2026
fe2a3c7
operator: never interrupt a running migration when the image changes
SoulPancake Sep 23, 2026
ca25836
fix(operator): preserve migration lifecycle inputs
Siddhant-K-code Sep 23, 2026
9c4a1e1
operator: build the Job from the whole pod spec, key migrations on th…
SoulPancake Sep 23, 2026
7d71c51
Merge remote operator migration updates
Siddhant-K-code Sep 23, 2026
2c0f2b6
Merge latest operator migration updates
Siddhant-K-code Sep 23, 2026
0697705
test(operator): cover release version guard
Siddhant-K-code Sep 23, 2026
3bc8ab5
fix(operator): close migration release gaps
Siddhant-K-code Sep 23, 2026
a7e467c
operator: fix stuck-Job rebuild, datastore trigger and migration iden…
SoulPancake Sep 23, 2026
39a5911
ci: drop the operator image release gate
SoulPancake Sep 23, 2026
e1c9879
charts: add rbac.create to the operator chart, run migrations as the …
SoulPancake Sep 23, 2026
6f56fc5
operator: sign the image, disable metrics by default, document securi…
SoulPancake Sep 23, 2026
f6e353f
docs: mark both ADRs proposed, scope ADR-001 to stage 1
SoulPancake Sep 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions .github/ci/operator-postgres-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Values for the operator + Postgres E2E step in .github/workflows/test.yml,
# which installs one OpenFGA version and then upgrades to a newer one. Kept
# out of charts/openfga/ci/ because chart-testing only installs one version.
replicaCount: 1

datastore:
engine: postgres
uriSecret: openfga-e2e-postgres-credentials

openfga-operator:
enabled: true
image:
pullPolicy: Never

extraObjects:
- apiVersion: v1
kind: Secret
metadata:
name: openfga-e2e-postgres-credentials
stringData:
uri: "postgres://openfga:changeme@openfga-e2e-postgres:5432/openfga?sslmode=disable"
- apiVersion: apps/v1
kind: Deployment
metadata:
name: openfga-e2e-postgres
spec:
replicas: 1
selector:
matchLabels:
app: openfga-e2e-postgres
template:
metadata:
labels:
app: openfga-e2e-postgres
spec:
containers:
- name: postgres
image: postgres:17
ports:
- containerPort: 5432
env:
- name: POSTGRES_USER
value: openfga
- name: POSTGRES_PASSWORD
value: changeme
- name: POSTGRES_DB
value: openfga
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
readinessProbe:
exec:
command: ["pg_isready", "-U", "openfga", "-d", "openfga"]
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: data
emptyDir: {}
- apiVersion: v1
kind: Service
metadata:
name: openfga-e2e-postgres
spec:
selector:
app: openfga-e2e-postgres
ports:
- port: 5432
targetPort: 5432
18 changes: 18 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,21 @@ updates:
dependencies:
patterns:
- "*"

- package-ecosystem: "gomod"
directory: "/operator"
schedule:
interval: "weekly"
groups:
dependencies:
patterns:
- "*"

- package-ecosystem: "docker"
directory: "/operator"
schedule:
interval: "weekly"
groups:
dependencies:
patterns:
- "*"
61 changes: 61 additions & 0 deletions .github/scripts/check-operator-release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Fails when operator image or chart inputs changed but the chart versions that
# publish them did not. Usage: check-operator-release.sh <base-ref>, e.g. origin/main.
#
# CI publishes ghcr.io/openfga/openfga-operator:<appVersion> once and never
# overwrites it, and chart-releaser skips chart versions that already exist.
# Release inputs are therefore only published when, in the same PR:
# 1. charts/openfga-operator/Chart.yaml bumps version
# 2. image changes also bump appVersion
# 3. charts/openfga/Chart.yaml bumps version and pins the new operator chart
# Chart.lock has to match too; `helm dependency build` in CI fails if it does not.
set -euo pipefail

base=$1
image_inputs=(operator/cmd operator/internal operator/go.mod operator/go.sum operator/Dockerfile)
image_changed=false
chart_changed=false
if ! git diff --quiet "$base...HEAD" -- "${image_inputs[@]}"; then
image_changed=true
fi
if ! git diff --quiet "$base...HEAD" -- charts/openfga-operator; then
chart_changed=true
fi
if [[ "$image_changed" == "false" && "$chart_changed" == "false" ]]; then
echo "operator release inputs unchanged"
exit 0
fi

field() { grep "^$1:" "$2" | awk '{print $2}' | tr -d '"'; }
dependency_version() { awk '/name: openfga-operator/{f=1} f && /version:/{print $2; exit}' "$1" | tr -d '"'; }
at_base() { git show "$base:$1" 2>/dev/null; }
fail() { echo "::error file=$1::$2"; exit 1; }

operator_chart=charts/openfga-operator/Chart.yaml
parent_chart=charts/openfga/Chart.yaml
lock_file=charts/openfga/Chart.lock
operator_version=$(field version "$operator_chart")

if at_base "$operator_chart" > /tmp/base-operator-chart.yaml; then
if [[ "$(field version /tmp/base-operator-chart.yaml)" == "$(field version "$operator_chart")" ]]; then
fail "$operator_chart" "operator release inputs changed but version is still $(field version "$operator_chart"); bump it so the chart change is published"
fi
if [[ "$image_changed" == "true" ]] &&
[[ "$(field appVersion /tmp/base-operator-chart.yaml)" == "$(field appVersion "$operator_chart")" ]]; then
fail "$operator_chart" "operator image inputs changed but appVersion is still $(field appVersion "$operator_chart"); bump it so the image change is published"
fi
else
echo "operator chart is new in this PR"
fi

at_base "$parent_chart" > /tmp/base-parent-chart.yaml
if [[ "$(field version /tmp/base-parent-chart.yaml)" == "$(field version $parent_chart)" ]]; then
fail "$parent_chart" "operator release inputs changed but the openfga chart version is still $(field version $parent_chart); bump it so a chart with the new operator is released"
fi
if [[ "$(dependency_version "$parent_chart")" != "$operator_version" ]]; then
fail "$parent_chart" "openfga chart pins openfga-operator $(dependency_version "$parent_chart") but the operator chart is $operator_version; update the dependency and run helm dependency update charts/openfga"
fi
if [[ "$(dependency_version "$lock_file")" != "$operator_version" ]]; then
fail "$lock_file" "Chart.lock pins openfga-operator $(dependency_version "$lock_file") but the operator chart is $operator_version; run helm dependency update charts/openfga"
fi
echo "operator release versions are consistent"
100 changes: 100 additions & 0 deletions .github/scripts/check-operator-release_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/usr/bin/env bash
set -euo pipefail

repo=$(git rev-parse --show-toplevel)
check="$repo/.github/scripts/check-operator-release.sh"
failures=0

run_case() {
local name=$1 expected=$2 image_changed=$3 template_changed=$4 operator_version=$5 operator_app_version=$6
local parent_version=$7 parent_dependency=$8 lock_dependency=$9
local case_dir base result=0

case_dir=$(mktemp -d)
mkdir -p "$case_dir/operator/internal/controller" "$case_dir/charts/openfga-operator/templates" "$case_dir/charts/openfga"
(
cd "$case_dir"
git init -q
git config user.name "Release Guard Test"
git config user.email "release-guard@example.com"

printf 'package controller\n' > operator/internal/controller/controller.go
cat > charts/openfga-operator/Chart.yaml <<'EOF'
apiVersion: v2
name: openfga-operator
version: "1.0.0"
appVersion: "1.0.0"
EOF
printf 'value: base\n' > charts/openfga-operator/templates/config.yaml
cat > charts/openfga/Chart.yaml <<'EOF'
apiVersion: v2
name: openfga
version: "1.0.0"
dependencies:
- name: openfga-operator
version: "1.0.0"
EOF
cat > charts/openfga/Chart.lock <<'EOF'
dependencies:
- name: openfga-operator
version: 1.0.0
EOF
git add .
git commit -qm base
base=$(git rev-parse HEAD)

if [[ "$image_changed" == "true" ]]; then
printf 'var changed = true\n' >> operator/internal/controller/controller.go
fi
if [[ "$template_changed" == "true" ]]; then
printf 'value: candidate\n' > charts/openfga-operator/templates/config.yaml
fi
cat > charts/openfga-operator/Chart.yaml <<EOF
apiVersion: v2
name: openfga-operator
version: "$operator_version"
appVersion: "$operator_app_version"
EOF
cat > charts/openfga/Chart.yaml <<EOF
apiVersion: v2
name: openfga
version: "$parent_version"
dependencies:
- name: openfga-operator
version: "$parent_dependency"
EOF
cat > charts/openfga/Chart.lock <<EOF
dependencies:
- name: openfga-operator
version: $lock_dependency
EOF
git add .
if ! git diff --cached --quiet; then
git commit -qm candidate
fi

"$check" "$base" >/dev/null 2>&1 || result=$?
if [[ "$expected" == "pass" && "$result" -ne 0 ]] ||
[[ "$expected" == "fail" && "$result" -eq 0 ]]; then
printf 'FAIL: %s expected %s, exit code %d\n' "$name" "$expected" "$result"
exit 1
fi
) || failures=$((failures + 1))
}

run_case "unchanged release inputs" pass false false 1.0.0 1.0.0 1.0.0 1.0.0 1.0.0
run_case "consistent image release" pass true false 1.1.0 1.1.0 1.1.0 1.1.0 1.1.0
run_case "operator version unchanged" fail true false 1.0.0 1.1.0 1.1.0 1.0.0 1.0.0
run_case "operator appVersion unchanged" fail true false 1.1.0 1.0.0 1.1.0 1.1.0 1.1.0
run_case "parent version unchanged" fail true false 1.1.0 1.1.0 1.0.0 1.1.0 1.1.0
run_case "parent dependency mismatch" fail true false 1.1.0 1.1.0 1.1.0 1.0.0 1.1.0
run_case "lock dependency mismatch" fail true false 1.1.0 1.1.0 1.1.0 1.1.0 1.0.0
run_case "consistent chart-only release" pass false true 1.1.0 1.0.0 1.1.0 1.1.0 1.1.0
run_case "chart-only version unchanged" fail false true 1.0.0 1.0.0 1.1.0 1.0.0 1.0.0

if [[ "$failures" -ne 0 ]]; then
printf '%d release guard case(s) failed\n' "$failures"
exit 1
fi

echo "operator release guard matrix passed"
Loading
Loading