diff --git a/.agents/skills/gh-stack/SKILL.md b/.agents/skills/gh-stack/SKILL.md index 9f708b8f67..93704c260a 100644 --- a/.agents/skills/gh-stack/SKILL.md +++ b/.agents/skills/gh-stack/SKILL.md @@ -4,9 +4,9 @@ description: | metadata: author: github github-path: skills/gh-stack - github-ref: refs/tags/v0.2.0 + github-ref: refs/tags/v0.3.0 github-repo: https://github.com/github/gh-stack - github-tree-sha: bde7bcf5a96697d31aa55b33565fa0ff002167ca + github-tree-sha: 1f58c48379bc9fcab68e8a37cb41aad3ad937419 version: 0.2.0 internal: true name: gh-stack diff --git a/.agents/skills/gh-stack/references/commands.md b/.agents/skills/gh-stack/references/commands.md index 89ed80b043..54fd09a545 100644 --- a/.agents/skills/gh-stack/references/commands.md +++ b/.agents/skills/gh-stack/references/commands.md @@ -51,21 +51,25 @@ selects a non-default trunk. ## push -Pushes every active (non-merged, non-queued) branch in one multi-ref push with per-branch +Pushes every active (non-merged, non-queued) branch in one atomic multi-ref push with per-branch `--force-with-lease`. -**Not atomic.** Some branches may update while another is rejected. A rejection means that branch -moved on the remote; fix that branch and rerun — rerunning is safe and skips what already landed. +All branch updates succeed or fail together. `push`, `submit`, `sync`, and `link` accept +`--no-atomic` to allow partial updates. Any non-empty `GH_STACK_NO_ATOMIC` (for example, `1`) +opts out by default; `--no-atomic=false` overrides the environment. Failed atomic pushes never +automatically retry non-atomically. `push` never creates or updates pull requests. Use `submit` for that. ## submit -Pushes each active branch, then creates a PR for every branch that lacks one, basing it on the +Pushes all active branches together, then creates a PR for every branch that lacks one, basing it on the first non-merged ancestor, then links them into a Stack on GitHub. -- **Not atomic.** Branches are pushed sequentially with per-branch `--force-with-lease`. If a later - push is rejected, earlier pushes and PR updates stand. Fix the rejection and rerun the same command. +- **Atomic pushes by default.** One multi-ref push with per-branch `--force-with-lease` precedes + the bottom-to-top PR creation/update loop, even when opting out of atomicity. A failed push + stops before that loop. PR and stack API operations are not atomic; later API failures do not + undo the push. - **A fully merged stack cannot be extended.** When every PR in the current stack is already merged, `submit` forks the remaining unmerged branches into a **new** stack rooted at the trunk and creates it on GitHub, leaving the merged stack untouched. @@ -88,7 +92,7 @@ branches managed by another tool. Worktrees alone do not require `link`: local t exists.** In that case the remaining arguments are appended to the top of that stack and you do not re-list its current PRs: `gh stack link 7 feature-c`. Arguments already in the stack are skipped; arguments belonging to a different stack are rejected. -- Branch arguments are pushed automatically (non-force, atomic). Missing PRs are created with +- Branch arguments are pushed automatically (non-force, atomic by default). Missing PRs are created with auto-generated titles and correctly chained bases; existing PRs with a wrong base are corrected. - Stack membership is **additive only** — `link` never removes a PR from a stack. @@ -104,7 +108,7 @@ The routine command. Steps, in order: from its remote, or a branch no longer contains its expected parent. Merged PRs are handled automatically. On conflict, **all branches are restored** to their pre-rebase state and the command exits **3**. -5. **Push** all active branches, atomically. +5. **Push** all active branches, atomically by default. 6. **Refresh PR state** from GitHub. 7. **Sync the stack object** — link open PRs into a stack, additively. Only when two or more PRs exist. `sync` never opens PRs; that is `submit`. diff --git a/.agents/skills/gh-stack/references/troubleshooting.md b/.agents/skills/gh-stack/references/troubleshooting.md index 3bd45fb7ff..774a459365 100644 --- a/.agents/skills/gh-stack/references/troubleshooting.md +++ b/.agents/skills/gh-stack/references/troubleshooting.md @@ -70,12 +70,14 @@ Two resolution paths: ```bash gh stack unstack # removes the grouping; PRs and branches survive + gh stack init --base main branch-1 branch-2 # use your trunk and desired branch order gh stack submit --auto ``` Neither path deletes pull requests or branches. -Remote unstacking leaves PRs that are merging (auto-merge enabled) or are queued (in a merge queue) -stacked. If needed, clear that state before retrying. +Merged or queued PRs remain stacked on GitHub, but successful unstacking still removes local +tracking. If every PR is locked, GitHub rejects the operation and local tracking is retained. +Use `--local` to remove only local tracking. ## Restructuring a stack diff --git a/.agents/skills/gitops-cluster-debug/SKILL.md b/.agents/skills/gitops-cluster-debug/SKILL.md index 68604ad8c0..45fe30a461 100644 --- a/.agents/skills/gitops-cluster-debug/SKILL.md +++ b/.agents/skills/gitops-cluster-debug/SKILL.md @@ -1,13 +1,13 @@ --- -compatibility: Requires flux-operator-mcp +compatibility: Requires flux-operator-mcp v0.60 or later description: | - Debug and troubleshoot Flux CD on live Kubernetes clusters (not local repo files) via the Flux MCP server — inspects Flux resource status, reads controller logs, traces dependency chains, and performs installation health checks. Use when users report failing, stuck, or not-ready Flux resources on a cluster, reconciliation errors, controller issues, artifact pull failures, image automation not updating tags, alerts or webhooks not being delivered, or need live cluster Flux Operator troubleshooting. + Debug and troubleshoot Flux CD on live Kubernetes clusters via the Flux MCP server — inspects Flux resource status, events and controller logs, traces workloads back to the Flux objects and sources that deliver them, previews what a GitOps change will do on the cluster, and performs installation health checks. Use when users report failing, stuck, or not-ready Flux resources on a cluster, crashing or misbehaving workloads deployed by Flux, reconciliation errors, controller issues, artifact pull failures, image automation not updating tags, alerts or webhooks not being delivered, want to know what a local manifest change would modify on the cluster before committing, or need live cluster Flux Operator troubleshooting. license: Apache-2.0 metadata: github-path: skills/gitops-cluster-debug - github-ref: refs/tags/v0.3.0 + github-ref: refs/tags/v0.4.0 github-repo: https://github.com/fluxcd/agent-skills - github-tree-sha: 724378b05c1cc319c6216c6f55d3b44ec973abfc + github-tree-sha: c5259140b2e0aa18e788c22b17b84fd0554bd9c8 internal: true name: gitops-cluster-debug --- @@ -15,26 +15,77 @@ name: gitops-cluster-debug You are a Flux cluster debugger specialized in troubleshooting GitOps pipelines on live Kubernetes clusters. You use the `flux-operator-mcp` MCP tools to connect to clusters, -fetch Flux and Kubernetes resources, analyze status conditions, inspect logs, and identify -root causes. +fetch Flux and Kubernetes resources, trace delivery pipelines, analyze status conditions, +events and logs, and identify root causes. + +## MCP Tools + +The server exposes read-only tools in every mode and write tools only when it is not started +with `--read-only`. Check which tools you actually have before planning an action. + +| Purpose | Tool | Mode | +|---|---|---| +| Flux installation, controllers, CRD apiVersions | `get_flux_instance` | read-only | +| Read any resource (spec, status, `status.events`, `status.inventory`) | `get_kubernetes_resources` | read-only | +| apiVersion of any kind | `get_kubernetes_api_versions` | read-only | +| Object → managing Flux objects → source | `trace_kubernetes_resource` | read-only | +| Events of a workload, its ReplicaSets/Jobs and pods | `get_kubernetes_events` | read-only | +| Logs of a pod or workload | `get_kubernetes_logs` | read-only | +| Pod CPU and memory usage (needs metrics-server) | `get_kubernetes_metrics` | read-only | +| Preview a manifest or GitOps change against the cluster | `diff_kubernetes_manifest` | read-only | +| Flux documentation | `search_flux_docs`, `read_flux_doc` | read-only | +| Switch cluster | `get_kubeconfig_contexts`, `set_kubeconfig_context` | read-only | +| Trigger a sync | `reconcile_flux_resource` | write | +| Pause / unpause | `suspend_flux_reconciliation`, `resume_flux_reconciliation` | write | +| In-place change (rollout restart, scaling, finalizers) | `patch_kubernetes_resource` | write | +| Create / update / delete | `apply_kubernetes_manifest`, `delete_kubernetes_resource` | write | ## General Rules -- Don't assume the `apiVersion` of any Kubernetes or Flux resource — call - `get_kubernetes_api_versions` to find the correct one. -- To determine if a Kubernetes resource is Flux-managed, look for `fluxcd` labels in - the resource metadata. -- After switching context to a new cluster, always call `get_flux_instance` to determine - the Flux Operator status, version, and settings before doing anything else. -- When creating or updating resources on the cluster, generate a Kubernetes YAML manifest - and call the `apply_kubernetes_manifest` tool. When the target resource is managed by - Flux, the tool errors unless `overwrite` is set to `true`. Do not apply resources unless - explicitly requested by the user. Before generating any YAML manifest, verify the exact field names - and nesting against the field index in `assets/schemas/`. Index files follow the naming - convention `{kind}-{group}-{version}.fields.txt`; each line is a dotted field path — grep by - path prefix (e.g. `grep '^spec\.' assets/schemas/kustomization-kustomize-v1.fields.txt`) - instead of reading the whole file (see the CRD reference table below). -- You will not be able to read the values of Kubernetes Secrets, the MCP server will return only the `data` field with keys but empty values. +- Don't guess the `apiVersion` of a resource. `get_flux_instance` reports the Flux CRD + apiVersions; for any other kind call `get_kubernetes_api_versions`. +- When listing many resources or when only some fields matter, pass `fields` to + `get_kubernetes_resources` as kubectl JSONPath expressions (e.g. + `status.conditions[?(@.type=="Ready")].message`, `status.lastAppliedRevision`) to keep + results small. Include `status.events` and `status.inventory` when you need them. +- To find which Flux object delivers a resource, call `trace_kubernetes_resource` on it + instead of following `fluxcd` labels by hand. It returns the full `managedBy` chain + (Deployment → Kustomization/HelmRelease → ResourceSet → … → FluxInstance) with each + object's status and applied revision, plus the `source` with its URL and revision. Any + object in the chain that is not ready or is `suspended` is a lead. +- For workload problems, read events and logs at the workload level: pass `kind: Deployment` + (or StatefulSet, DaemonSet, Job, CronJob) with `name` and `namespace` to + `get_kubernetes_events` and `get_kubernetes_logs`. Both resolve the owned pods; there is no + need to look up pod names or label selectors first. +- Narrow events with `type: Warning`, `since` and `grep`. Narrow logs with `since`, `grep` + (e.g. `error|panic|fatal|exception`) and `limit`; for crashlooping containers set + `previous: true` to read the logs of the terminated container. +- After switching context to a new cluster, always call `get_flux_instance` before doing + anything else. +- Kubernetes Secret values are masked: you get the `data` keys with empty values. +- When you need the semantics of a Flux field or condition reason, call `search_flux_docs` + with the kind and field (e.g. `HelmRelease remediation`) and read the section with + `read_flux_doc`. + +### Changing the Cluster + +Do not change resources unless the user explicitly asks. When asked: + +- Preview first: build the manifest and call `diff_kubernetes_manifest` (no owner needed for + an ad-hoc manifest), then apply with `apply_kubernetes_manifest`. Flux-managed resources + need `overwrite: true`, and Flux reverts manual changes on its next reconciliation — the + durable fix belongs in Git. +- Use `patch_kubernetes_resource` for in-place changes (rollout restart annotation, replicas, + stuck finalizers); set `dry_run` to preview. Fields present in the Flux manifest are + reverted on the next reconciliation. +- After a fix lands in Git, call `reconcile_flux_resource` with `with_source: true` to fetch + the new revision immediately, then verify with `get_kubernetes_resources`. +- Before generating YAML for a Flux CRD, verify the exact field names against the field + index in `assets/schemas/` (see the CRD table below). Each line is a dotted field path — + grep by prefix (e.g. `grep '^spec\.' assets/schemas/kustomization-kustomize-v1.fields.txt`) + instead of reading the whole file. +- If the server is read-only (write tools are missing), give the user the exact `flux` / + `kubectl` command or manifest change instead. ## Cluster Context @@ -57,60 +108,54 @@ HelmRelease failing?") can skip straight to the relevant workflow. A broad reque ### Workflow 1: Flux Installation Check 1. Call `get_flux_instance` to check the Flux Operator status and settings. -2. Verify the FluxInstance reports `Ready: True`. +2. Verify the FluxInstance reports `Ready: True` and note the distribution version and + the components list. 3. Check controller deployment status — all controllers should be running. -4. Review the FluxReport for cluster-wide reconciliation summary. -5. If controllers are not running or crashlooping, analyze their logs using - `get_kubernetes_logs` on the controller pods. +4. Review the FluxReport for the cluster-wide reconciliation summary (failing and + suspended counts per kind). +5. List Flux resources that are not ready across namespaces with `get_kubernetes_resources` + and `fields` limited to the Ready condition, so the report names them. +6. If controllers are not running or crashlooping, read their events and logs at the + Deployment level (Workflow 8). ### Workflow 2: HelmRelease Debugging -Follow these steps when troubleshooting a HelmRelease: - -1. Call `get_flux_instance` to check the helm-controller deployment status and the - `apiVersion` of the HelmRelease kind. +1. Call `get_flux_instance` to check the helm-controller status and the HelmRelease + `apiVersion`. 2. Call `get_kubernetes_resources` to get the HelmRelease, then analyze the spec, - status, inventory, and events. -3. Determine which Flux object manages the HelmRelease by looking at the annotations — - it can be a Kustomization or a ResourceSet. + status conditions (`Ready`, `Released`, `Remediated`), history, inventory, and events. +3. Call `trace_kubernetes_resource` on the HelmRelease to see the Flux objects managing it + and its chart source with revision and status. 4. If `valuesFrom` is present, get all the referenced ConfigMap and Secret resources. -5. Identify the HelmRelease source by looking at the `chartRef` or `sourceRef` field. -6. Call `get_kubernetes_resources` to get the source, then analyze the source status - and events. -7. If the HelmRelease is in a failed state or in progress, check the managed resources - found in the inventory. -8. Call `get_kubernetes_resources` to get the managed resources and analyze their status. -9. If managed resources are failing, analyze their logs using `get_kubernetes_logs`. -10. Create a root cause analysis report. If no issues are found, report the current - status of the HelmRelease and its managed resources and container images. +5. Get the chart source (`chartRef`, `chart.spec.sourceRef`, or the OCIRepository generated + for `chart.kind: OCIRepository`) and analyze its status and events. +6. If the release failed or is in progress, get the managed workloads from the inventory and + check their status. +7. For failing workloads, follow Workflow 8 (events, logs, metrics at the workload level). +8. Create a root cause analysis report. If no issues are found, report the current status of + the HelmRelease, its managed resources and container images. ### Workflow 3: Kustomization Debugging -Follow these steps when troubleshooting a Kustomization: - -1. Call `get_flux_instance` to check the kustomize-controller deployment status and the - `apiVersion` of the Kustomization kind. -2. Call `get_kubernetes_resources` to get the Kustomization, then analyze the spec, - status, inventory, and events. -3. Determine which Flux object manages the Kustomization by looking at the annotations — - it can be another Kustomization or a ResourceSet. +1. Call `get_flux_instance` to check the kustomize-controller status and the Kustomization + `apiVersion`. +2. Call `get_kubernetes_resources` to get the Kustomization, then analyze the spec, status + conditions, inventory, and events. +3. Call `trace_kubernetes_resource` on the Kustomization to see the Flux objects managing it + and its source with URL, revision and status. 4. If `substituteFrom` is present, get all the referenced ConfigMap and Secret resources. -5. Identify the Kustomization source by looking at the `sourceRef` field. -6. Call `get_kubernetes_resources` to get the source, then analyze the source status - and events. -7. If the Kustomization is in a failed state or in progress, check the managed resources - found in the inventory. -8. Call `get_kubernetes_resources` to get the managed resources and analyze their status. -9. If managed resources are failing, analyze their logs using `get_kubernetes_logs`. -10. Create a root cause analysis report. If no issues are found, report the current - status of the Kustomization and its managed resources. +5. Get the source from `sourceRef` and analyze its status and events. A source that is not + ready (`Source artifact not found`) means the Kustomization never got an artifact — + continue with Workflow 5. +6. If the Kustomization failed or is in progress, check the managed resources from the + inventory; for failing workloads, follow Workflow 8. +7. Create a root cause analysis report. If no issues are found, report the current status of + the Kustomization and its managed resources. ### Workflow 4: ResourceSet Debugging -Follow these steps when troubleshooting a ResourceSet: - -1. Call `get_flux_instance` to check the Flux Operator status and the - `apiVersion` of the ResourceSet kind. +1. Call `get_flux_instance` to check the Flux Operator status and the ResourceSet + `apiVersion`. 2. Call `get_kubernetes_resources` to get the ResourceSet, then analyze the spec, status conditions, and events. 3. If the ResourceSet uses `inputsFrom`, get each referenced ResourceSetInputProvider @@ -120,11 +165,13 @@ Follow these steps when troubleshooting a ResourceSet: ResourceSet dependencies can reference any Kubernetes resource kind (other ResourceSets, Kustomizations, HelmReleases, CRDs) — check the `apiVersion` and `kind` in each entry. 5. Check the ResourceSet inventory for generated resources. Get the generated - Kustomizations, HelmReleases, or other Flux resources and analyze their status. -6. If generated resources are failing, follow Workflow 2 (HelmRelease) or - Workflow 3 (Kustomization) to debug them individually. + Kustomizations, HelmReleases, or other resources and analyze their status. A ResourceSet + can be `Ready` while the workloads it generated are failing — check them. +6. If generated Flux resources are failing, follow Workflow 2 or 3; for generated workloads, + follow Workflow 8. 7. Create a root cause analysis report. Distinguish between ResourceSet-level failures - (template errors, missing inputs, RBAC) and failures in the generated resources. + (template errors, missing inputs, RBAC) and failures in the generated resources, and + point the fix at the ResourceSet template or inputs rather than the generated objects. ### Workflow 5: Source Debugging @@ -176,29 +223,68 @@ Follow these steps when alerts are not being delivered or a webhook Receiver does not trigger reconciliation: 1. Call `get_flux_instance` to check the notification-controller deployment status. -2. Provider and Alert have **no status conditions** — diagnose - delivery from notification-controller logs (Workflow 8): look for dispatch - errors such as HTTP 401/404 or timeouts. +2. Provider and Alert have **no status conditions** — diagnose delivery from the + notification-controller logs: call `get_kubernetes_logs` with `kind: Deployment`, + `name: notification-controller`, `namespace: flux-system` and `grep` for the provider + name or `error`, looking for dispatch errors such as HTTP 401/404 or timeouts. 3. Get the Alert and verify `.spec.eventSources` matches the resources expected to produce events and `.spec.eventSeverity` is not filtering them out. 4. Get the referenced Provider and verify `.spec.type`, `.spec.address`, and the `secretRef` Secret key names. 5. For Receivers (these do have a `Ready` condition): verify `status.webhookPath` - and the webhook Secret, then check logs for incoming requests to that path — + and the webhook Secret, then check the logs for incoming requests to that path — none means the external service is not calling the webhook. -6. To generate a test event, suggest a manual reconcile request on a watched - resource and watch the logs for the dispatch attempt. Load - `references/troubleshooting.md` (Notification Failures) for cause lists. - -### Workflow 8: Kubernetes Logs Analysis - -When analyzing logs for any workload: - -1. Get the Kubernetes Deployment that manages the pods using `get_kubernetes_resources`. -2. Extract the `matchLabels` and container name from the deployment spec. -3. List the pods with `get_kubernetes_resources` using the found `matchLabels`. -4. Get the logs by calling `get_kubernetes_logs` with the pod name and container name. -5. Analyze the logs for errors, warnings, and patterns that indicate the root cause. +6. To generate a test event, reconcile a watched resource (`reconcile_flux_resource` when + available, otherwise suggest `flux reconcile`) and watch the logs for the dispatch + attempt. Load `references/troubleshooting.md` (Notification Failures) for cause lists. + +### Workflow 8: Workload Debugging (crashes, pull errors, pending pods) + +Use this when pods of a Flux-delivered workload are failing, or when you reach a failing +workload from another workflow: + +1. If you started from the workload, call `trace_kubernetes_resource` on it to find the + Kustomization, HelmRelease or ResourceSet that delivers it and the source revision. The + fix belongs in that object or in Git, not in the live workload. +2. Call `get_kubernetes_events` with the workload `kind`, `name` and `namespace` and + `type: Warning` — this covers the workload, its ReplicaSets and pods in one call. + `BackOff`, `Failed` (ErrImagePull / ImagePullBackOff), `FailedScheduling`, + `FailedMount` and `Unhealthy` point at different causes. +3. Call `get_kubernetes_logs` with the workload `kind`, `name`, `namespace` and a `grep` + such as `error|fatal|panic|exception`. For CrashLoopBackOff, also read with + `previous: true` — the current container may not have logged yet. +4. For OOMKilled or throttling, compare `get_kubernetes_metrics` for the pods with the + container resource limits in the workload spec. +5. Get the workload spec and any ConfigMaps/Secrets it references (`envFrom`, volumes) + to confirm missing or wrong configuration. +6. Create a root cause analysis report that names the delivering Flux object and the + exact change to make there. + +### Workflow 9: Previewing a Change Against the Cluster + +Use this when the user wants to know what a local manifest change will do on the cluster +before committing, or to check whether the cluster has drifted from the manifests: + +1. Build the manifests locally as Flux would: `kustomize build + --load-restrictor=LoadRestrictionsNone` for a Kustomization path, + `flux-operator build resourceset` for a ResourceSet, `helm template` for a chart. Pass + the complete output — a partial manifest makes every missing object show as a deletion. +2. Find the owning Flux object: the Kustomization whose `sourceRef` and `spec.path` match + the directory (list Kustomizations with `fields` for `spec.path` and `spec.sourceRef`), + or the HelmRelease/ResourceSet named by the user. Skip this when the user names it. +3. Call `diff_kubernetes_manifest` with the build output (`yaml_content`, or `yaml_path` + to a file for large builds) and `owner_kind`/`owner_name`/`owner_namespace`. If the + owner itself changes or is new, pass its YAML in `flux_object` instead. The diff applies + the owner's transforms (`targetNamespace`, `postBuild` substitutions, `commonMetadata`, + HelmRelease post-renderers) before the server-side dry-run. +4. The JSON patch of an update carries only the new values. For each `replace` or + `remove`, read the live object with `get_kubernetes_resources` and `fields` set to the + patched paths, so the report shows `old → new` for every changed field. +5. Report every object as create, update (old → new per field), recreate, unchanged or + delete. Inventory objects missing from the build are deleted when the owner has + `prune: true` — call these out explicitly, they are the riskiest part of a change. +6. Note the diff limitations that apply (Kustomization `components`, `namePrefix` / + `nameSuffix`, SOPS objects compared by key set only). ## Flux CRD Reference @@ -219,8 +305,8 @@ Use this table to check API versions and grep the field index when needed. | source-watcher | ArtifactGenerator | `source.extensions.fluxcd.io/v1beta1` | [artifactgenerator-source-v1beta1.fields.txt](assets/schemas/artifactgenerator-source-v1beta1.fields.txt) | | kustomize-controller | Kustomization | `kustomize.toolkit.fluxcd.io/v1` | [kustomization-kustomize-v1.fields.txt](assets/schemas/kustomization-kustomize-v1.fields.txt) | | helm-controller | HelmRelease | `helm.toolkit.fluxcd.io/v2` | [helmrelease-helm-v2.fields.txt](assets/schemas/helmrelease-helm-v2.fields.txt) | -| notification-controller | Provider | `notification.toolkit.fluxcd.io/v1beta3` | [provider-notification-v1beta3.fields.txt](assets/schemas/provider-notification-v1beta3.fields.txt) | -| notification-controller | Alert | `notification.toolkit.fluxcd.io/v1beta3` | [alert-notification-v1beta3.fields.txt](assets/schemas/alert-notification-v1beta3.fields.txt) | +| notification-controller | Provider | `notification.toolkit.fluxcd.io/v1` | [provider-notification-v1.fields.txt](assets/schemas/provider-notification-v1.fields.txt) | +| notification-controller | Alert | `notification.toolkit.fluxcd.io/v1` | [alert-notification-v1.fields.txt](assets/schemas/alert-notification-v1.fields.txt) | | notification-controller | Receiver | `notification.toolkit.fluxcd.io/v1` | [receiver-notification-v1.fields.txt](assets/schemas/receiver-notification-v1.fields.txt) | | image-reflector-controller | ImageRepository | `image.toolkit.fluxcd.io/v1` | [imagerepository-image-v1.fields.txt](assets/schemas/imagerepository-image-v1.fields.txt) | | image-reflector-controller | ImagePolicy | `image.toolkit.fluxcd.io/v1` | [imagepolicy-image-v1.fields.txt](assets/schemas/imagepolicy-image-v1.fields.txt) | @@ -246,12 +332,16 @@ Structure debugging findings as a markdown report with these sections: 4. **Root Cause** — identified root cause with evidence from status conditions, events, and logs 5. **Recommendations** — prioritized steps to resolve the issue, with exact commands or manifest changes +For a change preview (Workflow 9), report the owner, the per-object diff and the summary +counts instead, with deletions listed first. + ## Edge Cases - **No Flux installed**: If `get_flux_instance` returns no FluxInstance, tell the user that Flux is not installed on the cluster. Suggest installing the Flux Operator. - **MCP server unavailable**: If MCP tools fail to connect, tell the user that the `flux-operator-mcp` server is not running. Provide the install command. -- **Suspended resources**: If a Flux resource has `.spec.suspend: true`, note that it is intentionally suspended and won't reconcile until resumed. Don't flag this as an error unless the user expects it to be active. +- **Older MCP server**: If `trace_kubernetes_resource`, `get_kubernetes_events` or `diff_kubernetes_manifest` are missing, the server is older than v0.60 — fall back to following `fluxcd` labels, `status.events`, and pod-level logs, and suggest upgrading. +- **Suspended resources**: If a Flux resource has `.spec.suspend: true` (or `suspended` in a trace), note that it is intentionally suspended and won't reconcile until resumed. Don't flag this as an error unless the user expects it to be active. - **Progressing resources**: If a resource shows `Ready: Unknown` with reason `Progressing`, it is actively reconciling. Wait for the reconciliation to complete before diagnosing. Note the last transition time. -- **Flux-managed resources**: Resources with `fluxcd` labels are managed by Flux. Warn the user before applying manual changes — Flux will revert them on the next reconciliation. +- **Unmanaged objects**: If `trace_kubernetes_resource` reports `unmanaged: true`, the object is not delivered by Flux — say so instead of looking for a Flux fix. - **Stale status**: If the last reconciliation time is old relative to the configured interval, the controller may be overloaded or stuck. Check controller logs for backpressure or errors. - **Cluster context not found**: If the user's cluster name doesn't match any available context, list the available contexts and ask the user to clarify. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/alert-notification-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/alert-notification-v1.fields.txt new file mode 100644 index 0000000000..4cad134b74 --- /dev/null +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/alert-notification-v1.fields.txt @@ -0,0 +1,19 @@ +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 +apiVersion enum=notification.toolkit.fluxcd.io/v1 +kind enum=Alert +metadata.name (required) +metadata.namespace (required) +spec # AlertSpec defines an alerting rule for events involving a list of objects. +spec.eventMetadata # EventMetadata adds metadata to events. Sources, from lowest to highest precedence: `event.toolkit.fluxcd.io/` annotations on the involved object, Alert `.spec.eventMetadata`, and controller-defined `.toolkit.fluxcd.io/` event metadata. Higher precedence wins; conflicts produce an info log and a Warning Event. See the Alert API docs (Event metadata section). +spec.eventSeverity enum=info|error default="info" # EventSeverity specifies how to filter events based on severity. If set to 'info' no events will be filtered. +spec.eventSources <[]object> (required) # EventSources specifies how to filter events based on the involved object kind, name and namespace. +spec.eventSources[].apiVersion # API version of the referent +spec.eventSources[].kind (required) enum=Bucket|GitRepository|Kustomization|HelmRelease|HelmChart|HelmRepository|ImageRepository|ImagePolicy|ImageUpdateAutomation|OCIRepository|ArtifactGenerator|ExternalArtifact|FluxInstance|ResourceSet|ResourceSetInputProvider # Kind of the referent +spec.eventSources[].matchLabels # MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. MatchLabels requires the name to be set to `*`. +spec.eventSources[].name (required) min=1 max=253 # Name of the referent If multiple resources are targeted `*` may be set. +spec.eventSources[].namespace min=1 max=253 # Namespace of the referent +spec.exclusionList <[]string> # ExclusionList specifies a list of Golang regular expressions to be used for excluding messages. +spec.inclusionList <[]string> # InclusionList specifies a list of Golang regular expressions to be used for including messages. +spec.providerRef (required) # ProviderRef specifies which Provider this Alert should use. +spec.providerRef.name (required) # Name of the referent. +spec.suspend # Suspend tells the controller to suspend subsequent events handling for this Alert. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/alert-notification-v1beta3.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/alert-notification-v1beta3.fields.txt index d77f4a99da..6673ce4b00 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/alert-notification-v1beta3.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/alert-notification-v1beta3.fields.txt @@ -1,5 +1,5 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 -apiVersion enum=notification.toolkit.fluxcd.io/v1beta3 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 +apiVersion enum=notification.toolkit.fluxcd.io/v1beta3 (deprecated) # v1beta3 Alert is deprecated, upgrade to v1 kind enum=Alert metadata.name (required) metadata.namespace (required) diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/artifactgenerator-source-v1beta1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/artifactgenerator-source-v1beta1.fields.txt index 06c4ee4f78..31b74c312c 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/artifactgenerator-source-v1beta1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/artifactgenerator-source-v1beta1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.extensions.fluxcd.io/v1beta1 kind enum=ArtifactGenerator metadata.name (required) @@ -8,15 +8,32 @@ spec.artifacts <[]object> (required) min=1 max=1000 # OutputArtifacts is a list spec.artifacts[].copy <[]object> (required) min=1 # Copy defines a list of copy operations to perform from the sources to the generated artifact. The copy operations are performed in the order they are listed with existing files being overwritten by later copy operations. spec.artifacts[].copy[].exclude <[]string> max=100 # Exclude specifies a list of glob patterns to exclude files and dirs matched by the 'From' field. Patterns are matched against paths relative to the source alias root or to the non-glob prefix of 'From'. Patterns without a separator (e.g. "*.md") match the file name at any depth. spec.artifacts[].copy[].from (required) pattern="^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)/(.*)$" min=1 max=1024 # From specifies the source (by alias) and the glob pattern to match files. The format is "@/". When pathPattern is set, the path may use capture placeholders such as "{app}". +spec.artifacts[].copy[].optional # Optional, when set to true, allows the copy operation to silently skip when the source path or glob pattern matches no files. When false (default), the reconciliation fails with an error if no files are matched. spec.artifacts[].copy[].strategy enum=Overwrite|Merge|Extract # Strategy specifies the copy strategy to use. 'Overwrite' will overwrite existing files in the destination. 'Merge' is for merging YAML files using Helm values merge strategy. 'Extract' is for extracting the contents of tarball archives (.tar.gz, .tgz) When using glob patterns, non-tarball files are silently skipped. For single file sources, the file must be a tarball or an error is returned. Directories are not supported. If not specified, defaults to 'Overwrite'. spec.artifacts[].copy[].to (required) pattern="^@artifact/([^/]{0,1}|[^./][^/]|[.][^./]|[^/]{3,})(/([^/]{0,1}|[^./][^/]|[.][^./]|[^/]{3,}))*$" min=1 max=1024 # To specifies the destination path within the artifact. The format is "@artifact/path", the alias "artifact" refers to the root path of the generated artifact. When pathPattern is set, the path may use capture placeholders such as "{app}". -spec.artifacts[].name (required) min=1 max=253 # Name is the name of the generated artifact. When pathPattern is set, this field may use capture placeholders such as "{app}". +spec.artifacts[].inputsFrom pattern="^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)/(.*)$" min=1 max=1024 # InputsFrom specifies a source path to a YAML file whose contents are exported in the ExternalArtifact .status.exportedInputs field. The format is "@/", where references a source or "artifact" for the generated artifact itself. When pathPattern is set, the path may use capture placeholders such as "{module}". +spec.artifacts[].name (required) max=1024 # Name is the name of the generated artifact. When pathPattern is set, this field may use capture placeholders such as "{app}". The maximum length accommodates capture placeholders; the effective limits are enforced by the CEL validation when pathPattern is not set. +spec.artifacts[].namespace max=1024 # Namespace is the namespace of the generated artifact. If not provided, defaults to the same namespace as the ArtifactGenerator. When pathPattern is set, this field may use capture placeholders such as "{app}". The credentials used to reconcile the artifact are described in .spec.serviceAccountName: an explicit ServiceAccount applies to every generated artifact, while the --default-service-account flag only applies to artifacts in a namespace other than the ArtifactGenerator namespace. The maximum length accommodates capture placeholders; the effective limits are enforced by the CEL validation when pathPattern is not set. spec.artifacts[].originRevision pattern="^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)$" max=64 # OriginRevision is used to set the 'org.opencontainers.image.revision' annotation on the generated artifact metadata. If specified, it must point to an existing source alias in the format "@". If the referenced source has an origin revision (e.g. a Git commit SHA), it will be used to set the annotation on the generated artifact. If the referenced source does not have an origin revision, the field is ignored. spec.artifacts[].revision pattern="^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)$" max=64 # Revision is the revision of the generated artifact. If specified, it must point to an existing source alias in the format "@". If not specified, the revision is automatically set to the digest of the artifact content. spec.commonMetadata # CommonMetadata specifies the common labels and annotations that are applied to all resources. Any existing label or annotation will be overridden if its key matches a common one. spec.commonMetadata.annotations # Annotations to be added to the object's metadata. spec.commonMetadata.labels # Labels to be added to the object's metadata. +spec.managedNamespaces # ManagedNamespaces defines how the controller manages the namespaces targeted by the generated artifacts. When omitted, the target namespaces are unmanaged: they must already exist and are left untouched. +spec.managedNamespaces.allowedNames <[]string> (required) min=1 # AllowedNames is a list of CEL expressions that define the set of namespaces the ArtifactGenerator agrees to manage. Each expression receives the namespace name through the 'ns' string variable and must return a boolean. A namespace is managed only when at least one expression returns true. The 'default', 'kube-system', 'kube-public' and 'flux-system' namespaces are always rejected, regardless of the expressions. +spec.managedNamespaces.metadata # Metadata defines how the metadata of the desired namespaces is built, on top of .spec.commonMetadata. +spec.managedNamespaces.metadata.from <[]object> # From is a list of metadata operations applied in order to the desired namespaces, on top of .spec.commonMetadata and .fromSource. +spec.managedNamespaces.metadata.from[].annotations # Annotations to be applied to the namespace. +spec.managedNamespaces.metadata.from[].labels # Labels to be applied to the namespace. +spec.managedNamespaces.metadata.from[].namespace (required) pattern="^(\\*|[a-z0-9]([-a-z0-9]*[a-z0-9])?)$" max=63 # Namespace is the name of the desired namespace the metadata applies to, or '*' to apply the metadata to all desired namespaces. +spec.managedNamespaces.metadata.from[].strategy (required) enum=Reset|Override|Merge # Strategy specifies how the labels and annotations are applied. 'Reset' clears all the existing labels and annotations before applying the ones defined in the operation (fields that are not set clear the corresponding metadata), 'Override' merges the ones defined in the operation into the existing values, overriding existing keys, while 'Merge' merges only the absent keys, preserving existing values. +spec.managedNamespaces.metadata.fromSource # FromSource sources namespace metadata from a NamespaceMetadata file inside a source artifact. +spec.managedNamespaces.metadata.fromSource.allowedAnnotations # AllowedAnnotations is a schema for the annotations that the NamespaceMetadata file is allowed to set. Each key is an annotation key and each value is a CEL expression that receives the annotation value through the 'value' string variable and must return a boolean. Annotations whose key is not present in this map are ignored, while annotations whose value does not satisfy the respective expression are rejected. The expressions are compiled, so a malformed expression or one that does not return a boolean fails validation at the start of the reconciliation. +spec.managedNamespaces.metadata.fromSource.allowedLabels # AllowedLabels is a schema for the labels that the NamespaceMetadata file is allowed to set. Each key is a label key and each value is a CEL expression that receives the label value through the 'value' string variable and must return a boolean. Labels whose key is not present in this map are ignored, while labels whose value does not satisfy the respective expression are rejected. The expressions are compiled, so a malformed expression or one that does not return a boolean fails validation at the start of the reconciliation. +spec.managedNamespaces.metadata.fromSource.path (required) pattern="^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)/(.*)$" min=1 max=1024 # Path is the path to the NamespaceMetadata file inside a source artifact, in the format "@/". When pathPattern is set, the path may use capture placeholders such as "{namespace}". Only namespace-level captures are allowed, so that every artifact targeting a namespace resolves to the same file. +spec.managedNamespaces.prune (required) # Prune specifies whether the controller deletes managed namespaces that are no longer targeted by any generated artifact, or when the ArtifactGenerator is deleted. spec.pathPattern pattern="^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)/(.*)$" max=1024 # PathPattern specifies a directory traversal pattern to match within the sources. The format is "@/". Named captures in the pattern (e.g. "{app}") can be used as placeholders in OutputArtifacts fields. +spec.serviceAccountName pattern="^[a-z0-9]([-a-z0-9]*[a-z0-9])?$" min=1 max=63 # ServiceAccountName is the name of the ServiceAccount used to authorize the reconciliation of the generated ExternalArtifacts and the managed Namespaces. The name is resolved in the ArtifactGenerator namespace. When specified, the controller checks this ServiceAccount with SubjectAccessReview for every namespace targeted by the generated ExternalArtifacts, including the ArtifactGenerator namespace, and its RBAC bindings determine the namespaces in which they can be created, updated and deleted. When not specified, the controller uses its own credentials for ExternalArtifacts in the ArtifactGenerator namespace, and the ServiceAccount configured with the --default-service-account flag (when set) for artifacts targeting another namespace. Namespace management (.spec.managedNamespaces) always requires a ServiceAccount for authorization, so either this field or the --default-service-account flag must be set; otherwise the reconciliation fails with a terminal error. The controller performs the namespace operations with its own credentials. spec.sources <[]object> (required) min=1 max=1000 # Sources is a list of references to the Flux source-controller resources that will be used to generate the artifact. spec.sources[].alias (required) pattern="^[a-z0-9]([a-z0-9_-]*[a-z0-9])?$" max=63 # Alias of the source within the ArtifactGenerator context. The alias must be unique per ArtifactGenerator, and must consist of lower case alphanumeric characters, underscores, and hyphens. It must start and end with an alphanumeric character. spec.sources[].kind (required) enum=Bucket|GitRepository|OCIRepository|HelmChart|ExternalArtifact # Kind of the source. @@ -30,10 +47,11 @@ status.conditions[].observedGeneration format=int64 min=0 # observedGe status.conditions[].reason (required) pattern="^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$" min=1 max=1024 # reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. status.conditions[].status (required) enum=True|False|Unknown # status of the condition, one of True, False, Unknown. status.conditions[].type (required) pattern="^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$" max=316 # type of condition in CamelCase or in foo.example.com/CamelCase. -status.inventory <[]object> # Inventory contains the list of generated ExternalArtifact references. -status.inventory[].digest (required) # Digest of the referent artifact. -status.inventory[].filename (required) # Filename is the name of the artifact file. -status.inventory[].name (required) # Name of the referent artifact. -status.inventory[].namespace (required) # Namespace of the referent artifact. +status.inventory <[]object> # Inventory contains the list of objects managed by the ArtifactGenerator, such as the generated ExternalArtifacts and the managed Namespaces. +status.inventory[].digest (required) # Digest of the referent object. For generated artifacts this is the artifact content digest; for managed namespaces this is a digest of the metadata applied by the controller. +status.inventory[].filename # Filename is the name of the artifact file. +status.inventory[].kind enum=ExternalArtifact|Namespace # Kind is the kind of the referent object. +status.inventory[].name (required) # Name of the referent object. +status.inventory[].namespace # Namespace of the referent object. Empty for cluster-scoped objects. status.lastHandledReconcileAt # LastHandledReconcileAt holds the value of the most recent reconcile request value, so a change of the annotation value can be detected. status.observedSourcesDigest # ObservedSourcesDigest is a hash representing the current state of all the sources referenced by the ArtifactGenerator. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/bucket-source-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/bucket-source-v1.fields.txt index 5ee36407aa..429e7e9f25 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/bucket-source-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/bucket-source-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.toolkit.fluxcd.io/v1 kind enum=Bucket metadata.name (required) @@ -18,7 +18,7 @@ spec.proxySecretRef.name (required) # Name of the referent. spec.region # Region of the Endpoint where the BucketName is located in. spec.secretRef # SecretRef specifies the Secret containing authentication credentials for the Bucket. spec.secretRef.name (required) # Name of the referent. -spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the bucket. This field is only supported for the 'gcp' and 'aws' providers. For more information about workload identity: https://fluxcd.io/flux/components/source/buckets/#workload-identity +spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the bucket. This field is only supported for the 'gcp' and 'aws' providers. For more information about object identity: https://fluxcd.io/flux/integrations/object-identity/ spec.sts # STS specifies the required configuration to use a Security Token Service for fetching temporary credentials to authenticate in a Bucket provider. This field is only supported for the `aws` and `generic` providers. spec.sts.certSecretRef # CertSecretRef can be given the name of a Secret containing either or both of - a PEM-encoded client certificate (`tls.crt`) and private key (`tls.key`); - a PEM-encoded CA certificate (`ca.crt`) and whichever are supplied, will be used for connecting to the STS endpoint. The client cert and key are useful if you are authenticating with a certificate; the CA cert is useful if you are using a self-signed server certificate. The Secret must be of type `Opaque` or `kubernetes.io/tls`. This field is only supported for the `ldap` provider. spec.sts.certSecretRef.name (required) # Name of the referent. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/externalartifact-source-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/externalartifact-source-v1.fields.txt index 6eee8a4a4e..3a791085c5 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/externalartifact-source-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/externalartifact-source-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.toolkit.fluxcd.io/v1 kind enum=ExternalArtifact metadata.name (required) @@ -25,3 +25,4 @@ status.conditions[].observedGeneration format=int64 min=0 # observedGe status.conditions[].reason (required) pattern="^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$" min=1 max=1024 # reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. status.conditions[].status (required) enum=True|False|Unknown # status of the condition, one of True, False, Unknown. status.conditions[].type (required) pattern="^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$" max=316 # type of condition in CamelCase or in foo.example.com/CamelCase. +status.exportedInputs # ExportedInputs holds a map of structured data optionally extracted from the source resource. It may be used, for example, by downstream consumers such as templating engines like ResourceSet to consume these inputs for implementing templating logic. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/fluxinstance-fluxcd-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/fluxinstance-fluxcd-v1.fields.txt index bbb35b72f9..abedae5b9a 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/fluxinstance-fluxcd-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/fluxinstance-fluxcd-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux Operator v0.58.1 https://github.com/controlplaneio-fluxcd/flux-operator +# schema source: Flux Operator v0.62.0 https://github.com/controlplaneio-fluxcd/flux-operator apiVersion enum=fluxcd.controlplane.io/v1 kind enum=FluxInstance metadata.name (required) @@ -7,13 +7,15 @@ spec # FluxInstanceSpec defines the desired state of FluxInstance spec.cluster # Cluster holds the specification of the Kubernetes cluster. spec.cluster.domain default="cluster.local" # Domain is the cluster domain used for generating the FQDN of services. Defaults to 'cluster.local'. spec.cluster.multitenant default=false # Multitenant enables the multitenancy lockdown. Defaults to false. -spec.cluster.multitenantWorkloadIdentity default=false # MultitenantWorkloadIdentity enables the multitenancy lockdown for workload identity. Defaults to false. +spec.cluster.multitenantObjectIdentity default=false # MultitenantObjectIdentity enables the multitenancy lockdown for object identity. Defaults to false. +spec.cluster.multitenantWorkloadIdentity default=false # MultitenantWorkloadIdentity is now legacy. Legacy: Use MultitenantObjectIdentity instead. spec.cluster.networkPolicy default=true # NetworkPolicy restricts network access to the current namespace. Defaults to true. -spec.cluster.objectLevelWorkloadIdentity # ObjectLevelWorkloadIdentity enables the feature gate required for object-level workload identity. This feature is only available in Flux v2.6.0 and later. +spec.cluster.objectIdentityRBAC # ObjectIdentityRBAC configures the RBAC required for object identity using Kubernetes service account tokens. Object identity is the new name of the upstream Flux object-level workload identity feature. In Flux v2.6.0 to v2.9.x this enables the ObjectLevelWorkloadIdentity feature gate and leaves the RBAC for creating service account tokens in place. When disabled, the operator removes that RBAC from the Flux controllers' ClusterRole. Starting with Flux v2.10.0, the ObjectLevelWorkloadIdentity feature gate is retired and no longer changes behavior, so the operator no longer passes it to the controllers. Starting with Flux v2.10.0, the RBAC for creating service account tokens is removed from the Flux distribution, and this field controls whether the operator adds it. This feature is only available in Flux v2.6.0 and later. +spec.cluster.objectLevelWorkloadIdentity # ObjectLevelWorkloadIdentity is now legacy. Legacy: Use ObjectIdentityRBAC instead. spec.cluster.size enum=small|medium|large # Size defines the vertical scaling profile of the Flux controllers. The size is used to determine the concurrency and CPU/Memory limits for the Flux controllers. Accepted values are: 'small', 'medium' and 'large'. -spec.cluster.tenantDefaultDecryptionServiceAccount # TenantDefaultDecryptionServiceAccount is the name of the service account to use as default for kustomize-controller SOPS decryption when the multitenant lockdown for workload identity is enabled. Defaults to the 'default' service account from the tenant namespace. -spec.cluster.tenantDefaultKubeConfigServiceAccount # TenantDefaultKubeConfigServiceAccount is the name of the service account to use as default for kustomize-controller and helm-controller remote cluster access via spec.kubeConfig.configMapRef when the multitenant lockdown for workload identity is enabled. Defaults to the 'default' service account from the tenant namespace. -spec.cluster.tenantDefaultServiceAccount # TenantDefaultServiceAccount is the name of the service account to use as default when the multitenant lockdown is enabled, for kustomize-controller and helm-controller. This field will also be used for multitenant workload identity lockdown for source-controller, notification-controller, image-reflector-controller and image-automation-controller. Defaults to the 'default' service account from the tenant namespace. +spec.cluster.tenantDefaultDecryptionServiceAccount # TenantDefaultDecryptionServiceAccount is the name of the service account to use as default for kustomize-controller SOPS decryption when the multitenant lockdown for object identity is enabled. Defaults to the 'default' service account from the tenant namespace. +spec.cluster.tenantDefaultKubeConfigServiceAccount # TenantDefaultKubeConfigServiceAccount is the name of the service account to use as default for kustomize-controller and helm-controller remote cluster access via spec.kubeConfig.configMapRef when the multitenant lockdown for object identity is enabled. Defaults to the 'default' service account from the tenant namespace. +spec.cluster.tenantDefaultServiceAccount # TenantDefaultServiceAccount is the name of the service account to use as default when the multitenant lockdown is enabled, for kustomize-controller and helm-controller. This field will also be used for multitenant object identity lockdown for source-controller, notification-controller, image-reflector-controller and image-automation-controller. Defaults to the 'default' service account from the tenant namespace. spec.cluster.type enum=kubernetes|openshift|aws|azure|gcp default="kubernetes" # Type specifies the distro of the Kubernetes cluster. Defaults to 'kubernetes'. spec.commonMetadata # CommonMetadata specifies the common labels and annotations that are applied to all resources. Any existing label or annotation will be overridden if its key matches a common one. spec.commonMetadata.annotations # Annotations to be added to the object's metadata. @@ -42,6 +44,20 @@ spec.sharding # Sharding holds the specification of the sharding config spec.sharding.key default="sharding.fluxcd.io/key" # Key is the label key used to shard the resources. spec.sharding.shards <[]string> (required) min=1 # Shards is the list of shard names. spec.sharding.storage enum=ephemeral|persistent # Storage defines if the source-controller shards should use an emptyDir or a persistent volume claim for storage. Accepted values are 'ephemeral' or 'persistent', defaults to 'ephemeral'. When set to 'persistent', the '.spec.storage' field must be set. +spec.spiffe # SPIFFE holds the configuration for the SPIFFE integration. When set, the operator configures the Flux controllers to use the SPIFFE Workload API and optionally enables object identity and mTLS between the controllers. The flux-operator pod must also be configured with the same Workload API and, when used, Broker API settings, but does not need the inter-controller flags. +spec.spiffe.brokerAPI # BrokerAPI holds the configuration for the SPIFFE Broker API. When set, enables the object-level SPIFFE features. +spec.spiffe.brokerAPI.endpoint (required) pattern="^[!-~]+$" min=1 max=1024 # Endpoint is the address of the SPIFFE Broker API endpoint, e.g. 'dns:///spiffe-broker.example.com:443'. The flux-operator pod accepts the same --spiffe-broker-endpoint flag as the Flux controllers. For OLM installations, the endpoint can be set with the SPIFFE_BROKER_ENDPOINT environment variable. +spec.spiffe.brokerAPI.ids <[]string> (required) min=1 max=64 # IDs is the list of SPIFFE IDs or SPIFFE ID prefixes authorized for the SPIFFE Broker API endpoint. SPIFFE IDs ending with a slash are treated as prefixes. The flux-operator pod accepts the same repeatable --spiffe-broker-id flag as the Flux controllers. For OLM installations, the IDs can be set with the SPIFFE_BROKER_IDS environment variable as a comma-separated list. +spec.spiffe.mtls # MTLS holds the configuration for mTLS between the Flux controllers. The flux-operator reads the controller SPIFFE IDs from .status.spiffe. +spec.spiffe.mtls.componentIDTemplate (required) pattern="^spiffe://[a-z0-9._-]{1,255}(?:/(?:[a-zA-Z0-9_-]|[.][a-zA-Z0-9_-]|[{]component[}])[a-zA-Z0-9._-]*(?:[{]component[}][a-zA-Z0-9._-]*)*)+(?:/)?$" max=2048 # ComponentIDTemplate is the SPIFFE ID template for the Flux controllers. The '{component}' placeholder is replaced with the name of each installed component. A trailing slash indicates a SPIFFE ID prefix. The flux-operator ID is the SPIFFE ID of the operator's X.509-SVID, or this template with 'flux-operator' when the operator has no Workload API source. The flux-operator ID is always added to notification-controller as an authorized notifier, and to source-controller and source-watcher as an authorized artifact client for the Web UI artifact downloads. For a standalone Web UI, use ExtraArtifactClients and ExtraNotifiers. +spec.spiffe.mtls.enabled (required) # Enabled enables mTLS between the Flux controllers. +spec.spiffe.mtls.extraArtifactClients <[]string> max=64 # ExtraArtifactClients is a list of additional SPIFFE IDs added to source-controller and source-watcher as authorized artifact clients, e.g. the standalone Web UI or the Flux MCP Server. +spec.spiffe.mtls.extraArtifactServers <[]string> max=64 # ExtraArtifactServers is a list of additional SPIFFE IDs added to kustomize-controller, helm-controller and source-watcher as authorized artifact servers, e.g. an external source controller. +spec.spiffe.mtls.extraNotifiers <[]string> max=64 # ExtraNotifiers is a list of additional SPIFFE IDs added to notification-controller as authorized notifiers, e.g. the standalone Web UI or the Flux MCP Server. +spec.spiffe.mtls.receivers <[]string> max=64 # Receivers is the list of SPIFFE IDs of external Ingress or Gateway controllers authorized to send webhook requests to notification-controller. Setting at least one ID makes the receiver accept only SPIFFE mTLS clients. +spec.spiffe.workloadAPI (required) # WorkloadAPI holds the configuration for the SPIFFE Workload API. It is required for enabling any of the SPIFFE features and is used to render the go-spiffe environment variable and the SPIFFE CSI volume. +spec.spiffe.workloadAPI.csiDriver pattern="^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?)*$" min=1 max=63 # CSIDriver is the name of the SPIFFE CSI driver used to mount the Workload API socket into the Flux controller pods. When set, the operator mounts the CSI volume at /spiffe-workload-api and the endpoint must be a unix socket under that path. When omitted, no CSI volume is configured. +spec.spiffe.workloadAPI.endpoint (required) pattern="^(?:unix:(?:///[!$&->@-~]+|/[!$&-.0->@-~][!$&->@-~]*)|tcp://(?:[0-9]{1,3}(?:\\.[0-9]{1,3}){3}|\\[[0-9a-fA-F:.]+\\]):[0-9]{1,5})$" min=1 max=1024 # Endpoint is the address of the SPIFFE Workload API endpoint, in the form 'unix:///', 'unix:/' or 'tcp://:', e.g. 'unix:///spiffe-workload-api/agent.sock'. The flux-operator pod must be configured with the same endpoint through the SPIFFE_ENDPOINT_SOCKET environment variable. spec.storage # Storage holds the specification of the source-controller persistent volume claim. spec.storage.class (required) # Class is the storage class to use for the PVC. spec.storage.size (required) # Size is the size of the PVC. @@ -85,3 +101,8 @@ status.lastArtifactRevision # LastArtifactRevision is the digest of the status.lastAttemptedRevision # LastAttemptedRevision is the version and digest of the distribution config that was last attempted to reconcile. status.lastHandledForceAt # LastHandledForceAt holds the value of the most recent force request value, so a change of the annotation value can be detected. status.lastHandledReconcileAt # LastHandledReconcileAt holds the value of the most recent reconcile request value, so a change of the annotation value can be detected. +status.spiffe # SPIFFE holds the SPIFFE settings of the last applied distribution. +status.spiffe.mtls # MTLS holds the applied mTLS settings. +status.spiffe.mtls.componentIDTemplate # ComponentIDTemplate is the SPIFFE ID template of the Flux controllers. +status.spiffe.mtls.enabled (required) # Enabled is true when the Flux controllers were deployed with mTLS. +status.spiffe.mtls.extraArtifactServers <[]string> # ExtraArtifactServers is the list of additional SPIFFE IDs authorized as artifact servers. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/fluxreport-fluxcd-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/fluxreport-fluxcd-v1.fields.txt index 02e2afb175..71d1348cbf 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/fluxreport-fluxcd-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/fluxreport-fluxcd-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux Operator v0.58.1 https://github.com/controlplaneio-fluxcd/flux-operator +# schema source: Flux Operator v0.62.0 https://github.com/controlplaneio-fluxcd/flux-operator apiVersion enum=fluxcd.controlplane.io/v1 kind enum=FluxReport metadata.name (required) diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/gitrepository-source-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/gitrepository-source-v1.fields.txt index 6258cfba93..0ac953dae4 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/gitrepository-source-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/gitrepository-source-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.toolkit.fluxcd.io/v1 kind enum=GitRepository metadata.name (required) @@ -66,4 +66,5 @@ status.observedInclude[].repository.name (required) # Name of the refer status.observedInclude[].toPath # ToPath specifies the path to copy contents to, defaults to the name of the GitRepositoryRef. status.observedRecurseSubmodules # ObservedRecurseSubmodules is the observed resource submodules configuration used to produce the current Artifact. status.observedSparseCheckout <[]string> # ObservedSparseCheckout is the observed list of directories used to produce the current Artifact. +status.sourceVerificationFingerprint # SourceVerificationFingerprint is the fingerprint of the public keys used to verify the signature of the Git object(s) for the current Artifact. It is used to detect changes to the verification policy, such as a key rotation, that require the current revision to be verified again. status.sourceVerificationMode # SourceVerificationMode is the last used verification mode indicating which Git object(s) have been verified. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/helmchart-source-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/helmchart-source-v1.fields.txt index 3996a99426..3af821dbda 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/helmchart-source-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/helmchart-source-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.toolkit.fluxcd.io/v1 kind enum=HelmChart metadata.name (required) diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/helmrelease-helm-v2.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/helmrelease-helm-v2.fields.txt index dc5a6ccf13..e22f151f50 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/helmrelease-helm-v2.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/helmrelease-helm-v2.fields.txt @@ -1,29 +1,56 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=helm.toolkit.fluxcd.io/v2 kind enum=HelmRelease metadata.name (required) metadata.namespace (required) spec # HelmReleaseSpec defines the desired state of a Helm release. -spec.chart # Chart defines the template of the v1.HelmChart that should be created for this HelmRelease. +spec.chart # Chart defines the template of the source object that should be created for this HelmRelease. The Kind field determines whether a sourcev1.HelmChart or sourcev1.OCIRepository is created. +spec.chart.kind enum=HelmChart|OCIRepository # Kind is the kind of the source object generated from this template. Valid values: - HelmChart (default): generates a source.toolkit.fluxcd.io/v1 HelmChart from the HelmChartSpec-compatible fields under .spec.chart.spec. In particular, .spec.chart.spec.chart and .spec.chart.spec.sourceRef are required. - OCIRepository: generates a source.toolkit.fluxcd.io/v1 OCIRepository from the OCIRepositorySpec fields under .spec.chart.spec. In particular, .spec.chart.spec.url is required, and .spec.chart.spec.interval defaults to .spec.interval (interval is required in a plain OCIRepository). Use OCIRepository for charts hosted in OCI registries; use HelmChart for HelmRepository, GitRepository or Bucket sources. spec.chart.metadata # ObjectMeta holds the template for metadata like labels and annotations. spec.chart.metadata.annotations # Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ spec.chart.metadata.labels # Map of string keys and values that can be used to organize and categorize (scope and select) objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ -spec.chart.spec (required) # Spec holds the template for the v1.HelmChartSpec for this HelmRelease. -spec.chart.spec.chart (required) min=1 max=2048 # The name or path the Helm chart is available at in the SourceRef. +spec.chart.spec (required) # Spec holds the spec of the object generated for this HelmRelease. +spec.chart.spec.certSecretRef # CertSecretRef can be given the name of a Secret containing either or both of - a PEM-encoded client certificate (`tls.crt`) and private key (`tls.key`); - a PEM-encoded CA certificate (`ca.crt`) and whichever are supplied, will be used for connecting to the registry. The client cert and key are useful if you are authenticating with a certificate; the CA cert is useful if you are using a self-signed server certificate. The Secret must be of type `Opaque` or `kubernetes.io/tls`. +spec.chart.spec.certSecretRef.name (required) # Name of the referent. +spec.chart.spec.chart min=1 max=2048 # The name or path the Helm chart is available at in the SourceRef. +spec.chart.spec.ignore # Ignore overrides the set of excluded patterns in the .sourceignore format (which is the same as .gitignore). If not provided, a default will be used, consult the documentation for your version to find out what those are. spec.chart.spec.ignoreMissingValuesFiles # IgnoreMissingValuesFiles controls whether to silently ignore missing values files rather than failing. -spec.chart.spec.interval pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Interval at which to check the v1.Source for updates. Defaults to 'HelmReleaseSpec.Interval'. -spec.chart.spec.reconcileStrategy enum=ChartVersion|Revision default="ChartVersion" # Determines what enables the creation of a new artifact. Valid values are ('ChartVersion', 'Revision'). See the documentation of the values for an explanation on their behavior. Defaults to ChartVersion when omitted. -spec.chart.spec.sourceRef (required) # The name and namespace of the v1.Source the chart is available at. +spec.chart.spec.insecure # Insecure allows connecting to a non-TLS HTTP container registry. +spec.chart.spec.interval pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Interval at which the OCIRepository URL is checked for updates. This interval is approximate and may be subject to jitter to ensure efficient use of resources. +spec.chart.spec.layerSelector # LayerSelector specifies which layer should be extracted from the OCI artifact. When not specified, the first layer found in the artifact is selected. +spec.chart.spec.layerSelector.mediaType # MediaType specifies the OCI media type of the layer which should be extracted from the OCI Artifact. The first layer matching this type is selected. +spec.chart.spec.layerSelector.operation enum=extract|copy # Operation specifies how the selected layer should be processed. By default, the layer compressed content is extracted to storage. When the operation is set to 'copy', the layer compressed content is persisted to storage as it is. +spec.chart.spec.provider enum=generic|aws|azure|gcp # The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. When not specified, defaults to 'generic'. +spec.chart.spec.proxySecretRef # ProxySecretRef specifies the Secret containing the proxy configuration to use while communicating with the container registry. +spec.chart.spec.proxySecretRef.name (required) # Name of the referent. +spec.chart.spec.reconcileStrategy enum=ChartVersion|Revision # Determines what enables the creation of a new artifact. Valid values are ('ChartVersion', 'Revision'). See the documentation of the values for an explanation on their behavior. Defaults to ChartVersion when omitted. +spec.chart.spec.ref # The OCI reference to pull and monitor for changes, defaults to the latest tag. +spec.chart.spec.ref.digest # Digest is the image digest to pull, takes precedence over SemVer. The value should be in the format 'sha256:'. +spec.chart.spec.ref.semver # SemVer is the range of tags to pull selecting the latest within the range, takes precedence over Tag. +spec.chart.spec.ref.semverFilter # SemverFilter is a regex pattern to filter the tags within the SemVer range. +spec.chart.spec.ref.tag # Tag is the image tag to pull, defaults to latest. +spec.chart.spec.secretRef # SecretRef contains the secret name containing the registry login credentials to resolve image metadata. The secret must be of type kubernetes.io/dockerconfigjson. +spec.chart.spec.secretRef.name (required) # Name of the referent. +spec.chart.spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the image pull, either with the pull secrets attached to the service account or with an object identity. For more information about object identity: https://fluxcd.io/flux/integrations/object-identity/ For more information about image pull secrets: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account +spec.chart.spec.sourceRef # The name and namespace of the v1.Source the chart is available at. spec.chart.spec.sourceRef.apiVersion # APIVersion of the referent. spec.chart.spec.sourceRef.kind (required) enum=HelmRepository|GitRepository|Bucket # Kind of the referent. spec.chart.spec.sourceRef.name (required) min=1 max=253 # Name of the referent. spec.chart.spec.sourceRef.namespace min=1 max=63 # Namespace of the referent. +spec.chart.spec.suspend # This flag tells the controller to suspend the reconciliation of this source. +spec.chart.spec.timeout pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" # The timeout for remote OCI Repository operations like pulling, defaults to 60s. +spec.chart.spec.url pattern="^oci://.*$" # URL is a reference to an OCI artifact repository hosted on a remote container registry. spec.chart.spec.valuesFiles <[]string> # Alternative list of values files to use as the chart values (values.yaml is not included by default), expected to be a relative path in the SourceRef. Values files are merged in the order of this list with the last file overriding the first. Ignored when omitted. -spec.chart.spec.verify # Verify contains the secret name containing the trusted public keys used to verify the signature and specifies which provider to use to check whether OCI image is authentic. This field is only supported for OCI sources. Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified. -spec.chart.spec.verify.provider (required) enum=cosign|notation default="cosign" # Provider specifies the technology used to sign the OCI Helm chart. +spec.chart.spec.verify # Verify contains the secret name containing the trusted public keys used to verify the signature and specifies which provider to use to check whether OCI image is authentic. +spec.chart.spec.verify.matchOIDCIdentity <[]object> # MatchOIDCIdentity specifies the identity matching criteria to use while verifying an OCI artifact which was signed using Cosign keyless signing. The artifact's identity is deemed to be verified if any of the specified matchers match against the identity. +spec.chart.spec.verify.matchOIDCIdentity[].issuer (required) # Issuer specifies the regex pattern to match against to verify the OIDC issuer in the Fulcio certificate. The pattern must be a valid Go regular expression. +spec.chart.spec.verify.matchOIDCIdentity[].subject (required) # Subject specifies the regex pattern to match against to verify the identity subject in the Fulcio certificate. The pattern must be a valid Go regular expression. +spec.chart.spec.verify.provider (required) enum=cosign|notation default="cosign" # Provider specifies the technology used to sign the OCI Artifact. spec.chart.spec.verify.secretRef # SecretRef specifies the Kubernetes Secret containing the trusted public keys. spec.chart.spec.verify.secretRef.name (required) # Name of the referent. -spec.chart.spec.version default="*" # Version semver expression, ignored for charts from v1.GitRepository and v1beta2.Bucket sources. Defaults to latest when omitted. +spec.chart.spec.verify.trustedRootSecretRef # TrustedRootSecretRef specifies the Kubernetes Secret containing a Sigstore trusted_root.json file. This enables verification against self-hosted Sigstore infrastructure (custom Fulcio CA, self-hosted Rekor instance). The Secret must contain a key named "trusted_root.json". +spec.chart.spec.verify.trustedRootSecretRef.name (required) # Name of the referent. +spec.chart.spec.version # Version semver expression, ignored for charts from v1.GitRepository and v1beta2.Bucket sources. Defaults to latest when omitted i.e. to '*'. spec.chartRef # ChartRef holds a reference to a source controller resource containing the Helm chart artifact. spec.chartRef.apiVersion # APIVersion of the referent. spec.chartRef.kind (required) enum=OCIRepository|HelmChart|ExternalArtifact # Kind of the referent. @@ -75,8 +102,8 @@ spec.install.strategy.name (required) enum=RemediateOnFailure|RetryOnFa spec.install.strategy.retryInterval pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # RetryInterval is the interval at which to retry a failed install. Can be used only when Name is set to RetryOnFailure. Defaults to '5m'. spec.install.timeout pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Timeout is the time to wait for any individual Kubernetes operation (like Jobs for hooks) during the performance of a Helm install action. Defaults to 'HelmReleaseSpec.Timeout'. spec.interval (required) pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Interval at which to reconcile the Helm release. -spec.kubeConfig # KubeConfig for reconciling the HelmRelease on a remote cluster. When used in combination with HelmReleaseSpec.ServiceAccountName, forces the controller to act on behalf of that Service Account at the target cluster. If the --default-service-account flag is set, its value will be used as a controller level fallback for when HelmReleaseSpec.ServiceAccountName is empty. -spec.kubeConfig.configMapRef # ConfigMapRef holds an optional name of a ConfigMap that contains the following keys: - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or `generic`. Required. - `cluster`: the fully qualified resource name of the Kubernetes cluster in the cloud provider API. Not used by the `generic` provider. Required when one of `address` or `ca.crt` is not set. - `address`: the address of the Kubernetes API server. Required for `generic`. For the other providers, if not specified, the first address in the cluster resource will be used, and if specified, it must match one of the addresses in the cluster resource. If audiences is not set, will be used as the audience for the `generic` provider. - `ca.crt`: the optional PEM-encoded CA certificate for the Kubernetes API server. If not set, the controller will use the CA certificate from the cluster resource. - `audiences`: the optional audiences as a list of line-break-separated strings for the Kubernetes ServiceAccount token. Defaults to the `address` for the `generic` provider, or to specific values for the other providers depending on the provider. - `serviceAccountName`: the optional name of the Kubernetes ServiceAccount in the same namespace that should be used for authentication. If not specified, the controller ServiceAccount will be used. Mutually exclusive with SecretRef. +spec.kubeConfig # KubeConfig for reconciling the HelmRelease on a remote cluster. When used in combination with HelmReleaseSpec.ServiceAccountName, forces the controller to act on behalf of that Service Account at the target cluster. If the --default-service-account flag is set, its value will be used as the default for HelmReleaseSpec.ServiceAccountName when it is empty. +spec.kubeConfig.configMapRef # ConfigMapRef holds an optional name of a ConfigMap that contains the following keys: - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or `generic`. Required. - `cluster`: the fully qualified resource name of the Kubernetes cluster in the cloud provider API. Not used by the `generic` provider. Required when one of `address` or `ca.crt` is not set. - `address`: the address of the Kubernetes API server. Required for `generic`. For the other providers, if not specified, the first address in the cluster resource will be used, and if specified, it must match one of the addresses in the cluster resource. If audiences is not set, will be used as the audience for the `generic` provider. - `ca.crt`: the optional PEM-encoded CA certificate for the Kubernetes API server. If not set, the controller will use the CA certificate from the cluster resource. - `serviceAccountName`: the optional name of the Kubernetes ServiceAccount in the same namespace that should be used for authentication. If not specified, the controller ServiceAccount will be used. - `audiences`: the optional audiences as a list of string separated by commas and/or whitespaces/newlines for the Kubernetes ServiceAccount token. Defaults to the `address` for the `generic` provider, or to specific values for the other providers depending on the provider. Mutually exclusive with SecretRef. spec.kubeConfig.configMapRef.name (required) # Name of the referent. spec.kubeConfig.secretRef # SecretRef holds an optional name of a secret that contains a key with the kubeconfig file as the value. If no key is set, the key will default to 'value'. Mutually exclusive with ConfigMapRef. It is recommended that the kubeconfig is self-contained, and the secret is regularly updated if credentials such as a cloud-access-token expire. Cloud specific `cmd-path` auth helpers will not function without adding binaries and credentials to the Pod that is responsible for reconciling Kubernetes resources. Supported only for the generic provider. spec.kubeConfig.secretRef.key # Key in the Secret, when not specified an implementation-specific default key is used. @@ -170,7 +197,7 @@ status.conditions[].reason (required) pattern="^[A-Za-z]([A-Za-z0-9_,:] status.conditions[].status (required) enum=True|False|Unknown # status of the condition, one of True, False, Unknown. status.conditions[].type (required) pattern="^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$" max=316 # type of condition in CamelCase or in foo.example.com/CamelCase. status.failures format=int64 # Failures is the reconciliation failure count against the latest desired state. It is reset after a successful reconciliation. -status.helmChart # HelmChart is the namespaced name of the HelmChart resource created by the controller for the HelmRelease. +status.helmChart # HelmChart is the namespaced name of the HelmChart resource created by the controller for the HelmRelease, in the format '/', or the typed and namespaced name of the OCIRepository resource, in the format '//'. status.history <[]object> # History holds the history of Helm releases performed for this HelmRelease up to the last successfully completed release. status.history[].action # Action is the action that resulted in this snapshot being created. status.history[].apiVersion # APIVersion is the API version of the Snapshot. When the calculation method of the Digest field is changed, this field will be used to distinguish between the old and new methods. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/helmrepository-source-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/helmrepository-source-v1.fields.txt index 5d226215a2..2bb7c9c93d 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/helmrepository-source-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/helmrepository-source-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.toolkit.fluxcd.io/v1 kind enum=HelmRepository metadata.name (required) diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/imagepolicy-image-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/imagepolicy-image-v1.fields.txt index 0e3de7db0b..b95b122f13 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/imagepolicy-image-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/imagepolicy-image-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=image.toolkit.fluxcd.io/v1 kind enum=ImagePolicy metadata.name (required) diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/imagerepository-image-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/imagerepository-image-v1.fields.txt index 58faf50750..3dc106e760 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/imagerepository-image-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/imagerepository-image-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=image.toolkit.fluxcd.io/v1 kind enum=ImageRepository metadata.name (required) @@ -18,7 +18,7 @@ spec.proxySecretRef # ProxySecretRef specifies the Secret containing th spec.proxySecretRef.name (required) # Name of the referent. spec.secretRef # SecretRef can be given the name of a secret containing credentials to use for the image registry. The secret should be created with `kubectl create secret docker-registry`, or the equivalent. spec.secretRef.name (required) # Name of the referent. -spec.serviceAccountName max=253 # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the image pull if the service account has attached pull secrets. +spec.serviceAccountName max=253 # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the image pull, either with the pull secrets attached to the service account or with an object identity. For more information about object identity: https://fluxcd.io/flux/integrations/object-identity/ spec.suspend # This flag tells the controller to suspend subsequent image scans. It does not apply to already started scans. Defaults to false. spec.timeout pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" # Timeout for image scanning. Defaults to 'Interval' duration. status default={"observedGeneration":-1} # ImageRepositoryStatus defines the observed state of ImageRepository diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/imageupdateautomation-image-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/imageupdateautomation-image-v1.fields.txt index 8ecadb202c..5a3798045a 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/imageupdateautomation-image-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/imageupdateautomation-image-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=image.toolkit.fluxcd.io/v1 kind enum=ImageUpdateAutomation metadata.name (required) @@ -27,6 +27,7 @@ spec.git.push.branch # Branch specifies that commits should be pushed t spec.git.push.options # Options specifies the push options that are sent to the Git server when performing a push operation. For details, see: https://git-scm.com/docs/git-push#Documentation/git-push.txt---push-optionltoptiongt spec.git.push.refspec pattern="^$|^[^+:]" # Refspec specifies the Git Refspec to use for a push operation. If both Branch and Refspec are provided, then the commit is pushed to the branch and also using the specified refspec. Deletion refspecs and refspecs prefixed with '+' are not supported. For more details about Git Refspecs, see: https://git-scm.com/book/en/v2/Git-Internals-The-Refspec spec.interval (required) pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Interval gives an lower bound for how often the automation run should be attempted. +spec.policyChangeDelay pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # PolicyChangeDelay delays the run triggered by ImagePolicy changes, so that image updates arriving within the delay are committed together. If PolicySelector is also set, only changes to the selected policies trigger a run. By default, the automation runs as soon as a policy changes. spec.policySelector # PolicySelector allows to filter applied policies based on labels. By default includes all policies in namespace. spec.policySelector.matchExpressions <[]object> # matchExpressions is a list of label selector requirements. The requirements are ANDed. spec.policySelector.matchExpressions[].key (required) # key is the label key that the selector applies to. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/kustomization-kustomize-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/kustomization-kustomize-v1.fields.txt index 4cd60c6c65..d9d2eb8d9d 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/kustomization-kustomize-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/kustomization-kustomize-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=kustomize.toolkit.fluxcd.io/v1 kind enum=Kustomization metadata.name (required) @@ -48,8 +48,8 @@ spec.images[].name (required) # Name is a tag-less image name. spec.images[].newName # NewName is the value used to replace the original name. spec.images[].newTag # NewTag is the value used to replace the original tag. spec.interval (required) pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # The interval at which to reconcile the Kustomization. This interval is approximate and may be subject to jitter to ensure efficient use of resources. -spec.kubeConfig # The KubeConfig for reconciling the Kustomization on a remote cluster. When used in combination with KustomizationSpec.ServiceAccountName, forces the controller to act on behalf of that Service Account at the target cluster. If the --default-service-account flag is set, its value will be used as a controller level fallback for when KustomizationSpec.ServiceAccountName is empty. -spec.kubeConfig.configMapRef # ConfigMapRef holds an optional name of a ConfigMap that contains the following keys: - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or `generic`. Required. - `cluster`: the fully qualified resource name of the Kubernetes cluster in the cloud provider API. Not used by the `generic` provider. Required when one of `address` or `ca.crt` is not set. - `address`: the address of the Kubernetes API server. Required for `generic`. For the other providers, if not specified, the first address in the cluster resource will be used, and if specified, it must match one of the addresses in the cluster resource. If audiences is not set, will be used as the audience for the `generic` provider. - `ca.crt`: the optional PEM-encoded CA certificate for the Kubernetes API server. If not set, the controller will use the CA certificate from the cluster resource. - `audiences`: the optional audiences as a list of line-break-separated strings for the Kubernetes ServiceAccount token. Defaults to the `address` for the `generic` provider, or to specific values for the other providers depending on the provider. - `serviceAccountName`: the optional name of the Kubernetes ServiceAccount in the same namespace that should be used for authentication. If not specified, the controller ServiceAccount will be used. Mutually exclusive with SecretRef. +spec.kubeConfig # The KubeConfig for reconciling the Kustomization on a remote cluster. When used in combination with KustomizationSpec.ServiceAccountName, forces the controller to act on behalf of that Service Account at the target cluster. If the --default-service-account flag is set, its value will be used as the default for KustomizationSpec.ServiceAccountName when it is empty. +spec.kubeConfig.configMapRef # ConfigMapRef holds an optional name of a ConfigMap that contains the following keys: - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or `generic`. Required. - `cluster`: the fully qualified resource name of the Kubernetes cluster in the cloud provider API. Not used by the `generic` provider. Required when one of `address` or `ca.crt` is not set. - `address`: the address of the Kubernetes API server. Required for `generic`. For the other providers, if not specified, the first address in the cluster resource will be used, and if specified, it must match one of the addresses in the cluster resource. If audiences is not set, will be used as the audience for the `generic` provider. - `ca.crt`: the optional PEM-encoded CA certificate for the Kubernetes API server. If not set, the controller will use the CA certificate from the cluster resource. - `serviceAccountName`: the optional name of the Kubernetes ServiceAccount in the same namespace that should be used for authentication. If not specified, the controller ServiceAccount will be used. - `audiences`: the optional audiences as a list of string separated by commas and/or whitespaces/newlines for the Kubernetes ServiceAccount token. Defaults to the `address` for the `generic` provider, or to specific values for the other providers depending on the provider. Mutually exclusive with SecretRef. spec.kubeConfig.configMapRef.name (required) # Name of the referent. spec.kubeConfig.secretRef # SecretRef holds an optional name of a secret that contains a key with the kubeconfig file as the value. If no key is set, the key will default to 'value'. Mutually exclusive with ConfigMapRef. It is recommended that the kubeconfig is self-contained, and the secret is regularly updated if credentials such as a cloud-access-token expire. Cloud specific `cmd-path` auth helpers will not function without adding binaries and credentials to the Pod that is responsible for reconciling Kubernetes resources. Supported only for the generic provider. spec.kubeConfig.secretRef.key # Key in the Secret, when not specified an implementation-specific default key is used. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/ocirepository-source-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/ocirepository-source-v1.fields.txt index 0a58bcd8c0..ea3bbc6ed3 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/ocirepository-source-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/ocirepository-source-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.toolkit.fluxcd.io/v1 kind enum=OCIRepository metadata.name (required) @@ -8,11 +8,11 @@ spec.certSecretRef # CertSecretRef can be given the name of a Secret co spec.certSecretRef.name (required) # Name of the referent. spec.ignore # Ignore overrides the set of excluded patterns in the .sourceignore format (which is the same as .gitignore). If not provided, a default will be used, consult the documentation for your version to find out what those are. spec.insecure # Insecure allows connecting to a non-TLS HTTP container registry. -spec.interval (required) pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Interval at which the OCIRepository URL is checked for updates. This interval is approximate and may be subject to jitter to ensure efficient use of resources. +spec.interval pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Interval at which the OCIRepository URL is checked for updates. This interval is approximate and may be subject to jitter to ensure efficient use of resources. spec.layerSelector # LayerSelector specifies which layer should be extracted from the OCI artifact. When not specified, the first layer found in the artifact is selected. spec.layerSelector.mediaType # MediaType specifies the OCI media type of the layer which should be extracted from the OCI Artifact. The first layer matching this type is selected. spec.layerSelector.operation enum=extract|copy # Operation specifies how the selected layer should be processed. By default, the layer compressed content is extracted to storage. When the operation is set to 'copy', the layer compressed content is persisted to storage as it is. -spec.provider enum=generic|aws|azure|gcp default="generic" # The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. When not specified, defaults to 'generic'. +spec.provider enum=generic|aws|azure|gcp # The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. When not specified, defaults to 'generic'. spec.proxySecretRef # ProxySecretRef specifies the Secret containing the proxy configuration to use while communicating with the container registry. spec.proxySecretRef.name (required) # Name of the referent. spec.ref # The OCI reference to pull and monitor for changes, defaults to the latest tag. @@ -22,10 +22,10 @@ spec.ref.semverFilter # SemverFilter is a regex pattern to filter the t spec.ref.tag # Tag is the image tag to pull, defaults to latest. spec.secretRef # SecretRef contains the secret name containing the registry login credentials to resolve image metadata. The secret must be of type kubernetes.io/dockerconfigjson. spec.secretRef.name (required) # Name of the referent. -spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the image pull if the service account has attached pull secrets. For more information: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account +spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the image pull, either with the pull secrets attached to the service account or with an object identity. For more information about object identity: https://fluxcd.io/flux/integrations/object-identity/ For more information about image pull secrets: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account spec.suspend # This flag tells the controller to suspend the reconciliation of this source. -spec.timeout default="60s" pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" # The timeout for remote OCI Repository operations like pulling, defaults to 60s. -spec.url (required) pattern="^oci://.*$" # URL is a reference to an OCI artifact repository hosted on a remote container registry. +spec.timeout pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" # The timeout for remote OCI Repository operations like pulling, defaults to 60s. +spec.url pattern="^oci://.*$" # URL is a reference to an OCI artifact repository hosted on a remote container registry. spec.verify # Verify contains the secret name containing the trusted public keys used to verify the signature and specifies which provider to use to check whether OCI image is authentic. spec.verify.matchOIDCIdentity <[]object> # MatchOIDCIdentity specifies the identity matching criteria to use while verifying an OCI artifact which was signed using Cosign keyless signing. The artifact's identity is deemed to be verified if any of the specified matchers match against the identity. spec.verify.matchOIDCIdentity[].issuer (required) # Issuer specifies the regex pattern to match against to verify the OIDC issuer in the Fulcio certificate. The pattern must be a valid Go regular expression. @@ -57,4 +57,5 @@ status.observedIgnore # ObservedIgnore is the observed exclusion patter status.observedLayerSelector # ObservedLayerSelector is the observed layer selector used for constructing the source artifact. status.observedLayerSelector.mediaType # MediaType specifies the OCI media type of the layer which should be extracted from the OCI Artifact. The first layer matching this type is selected. status.observedLayerSelector.operation enum=extract|copy # Operation specifies how the selected layer should be processed. By default, the layer compressed content is extracted to storage. When the operation is set to 'copy', the layer compressed content is persisted to storage as it is. +status.sourceVerificationFingerprint # SourceVerificationFingerprint is the fingerprint of the verification material used to verify the signature of the current Artifact. It is used to detect changes to the verification policy, such as a key rotation, that require the current revision to be verified again. status.url # URL is the download link for the artifact output of the last OCI Repository sync. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/provider-notification-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/provider-notification-v1.fields.txt new file mode 100644 index 0000000000..562a162e80 --- /dev/null +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/provider-notification-v1.fields.txt @@ -0,0 +1,20 @@ +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 +apiVersion enum=notification.toolkit.fluxcd.io/v1 +kind enum=Provider +metadata.name (required) +metadata.namespace (required) +spec # ProviderSpec defines the desired state of the Provider. +spec.address max=2048 # Address specifies the endpoint, in a generic sense, to where alerts are sent. What kind of endpoint depends on the specific Provider type being used. For the generic Provider, for example, this is an HTTP/S address. For other Provider types this could be a project ID or a namespace. +spec.certSecretRef # CertSecretRef specifies the Secret containing TLS certificates for secure communication. Supported configurations: - CA-only: Server authentication (provide ca.crt only) - mTLS: Mutual authentication (provide ca.crt + tls.crt + tls.key) - Client-only: Client authentication with system CA (provide tls.crt + tls.key only) Legacy keys "caFile", "certFile", "keyFile" are supported but deprecated. Use "ca.crt", "tls.crt", "tls.key" instead. +spec.certSecretRef.name (required) # Name of the referent. +spec.channel max=2048 # Channel specifies the destination channel where events should be posted. +spec.commitStatusExpr # CommitStatusExpr is a CEL expression that evaluates to a string value that can be used to generate a custom commit status message for use with eligible Provider types (github, gitlab, gitea, bitbucketserver, bitbucket, azuredevops). Supported variables are: event, provider, and alert. +spec.proxySecretRef # ProxySecretRef specifies the Secret containing the proxy configuration for this Provider. The Secret should contain an 'address' key with the HTTP/S address of the proxy server. Optional 'username' and 'password' keys can be provided for proxy authentication. +spec.proxySecretRef.name (required) # Name of the referent. +spec.secretRef # SecretRef specifies the Secret containing the authentication credentials for this Provider. +spec.secretRef.name (required) # Name of the referent. +spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate with cloud provider services through object identity. This enables multi-tenant authentication without storing static credentials. Supported provider types: azureeventhub, azuredevops, googlepubsub When specified, the controller will: 1. Create an OIDC token for the specified ServiceAccount 2. Exchange it for cloud provider credentials via STS 3. Use the obtained credentials for API authentication When unspecified, the controller's workload identity is used (single-tenant). An error is thrown if static credentials are also defined in SecretRef. +spec.suspend # Suspend tells the controller to suspend subsequent events handling for this Provider. +spec.timeout pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" # Timeout for sending alerts to the Provider. +spec.type (required) enum=slack|discord|msteams|rocket|generic|generic-hmac|github|gitlab|gitea|giteapullrequestcomment|bitbucketserver|bitbucket|azuredevops|googlechat|googlepubsub|webex|sentry|azureeventhub|telegram|lark|matrix|opsgenie|alertmanager|grafana|githubdispatch|githubpullrequestcomment|gitlabmergerequestcomment|pagerduty|datadog|nats|zulip|otel|zoom|incident.io|mastodon # Type specifies which Provider implementation to use. +spec.username max=2048 # Username specifies the name under which events are posted. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/provider-notification-v1beta3.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/provider-notification-v1beta3.fields.txt index 2b31bc4621..5f55c15674 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/provider-notification-v1beta3.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/provider-notification-v1beta3.fields.txt @@ -1,5 +1,5 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 -apiVersion enum=notification.toolkit.fluxcd.io/v1beta3 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 +apiVersion enum=notification.toolkit.fluxcd.io/v1beta3 (deprecated) # v1beta3 Provider is deprecated, upgrade to v1 kind enum=Provider metadata.name (required) metadata.namespace (required) @@ -15,8 +15,8 @@ spec.proxySecretRef # ProxySecretRef specifies the Secret containing th spec.proxySecretRef.name (required) # Name of the referent. spec.secretRef # SecretRef specifies the Secret containing the authentication credentials for this Provider. spec.secretRef.name (required) # Name of the referent. -spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate with cloud provider services through workload identity. This enables multi-tenant authentication without storing static credentials. Supported provider types: azureeventhub, azuredevops, googlepubsub When specified, the controller will: 1. Create an OIDC token for the specified ServiceAccount 2. Exchange it for cloud provider credentials via STS 3. Use the obtained credentials for API authentication When unspecified, controller-level authentication is used (single-tenant). An error is thrown if static credentials are also defined in SecretRef. This field requires the ObjectLevelWorkloadIdentity feature gate to be enabled. +spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate with cloud provider services through workload identity. This enables multi-tenant authentication without storing static credentials. Supported provider types: azureeventhub, azuredevops, googlepubsub When specified, the controller will: 1. Create an OIDC token for the specified ServiceAccount 2. Exchange it for cloud provider credentials via STS 3. Use the obtained credentials for API authentication When unspecified, controller-level authentication is used (single-tenant). An error is thrown if static credentials are also defined in SecretRef. spec.suspend # Suspend tells the controller to suspend subsequent events handling for this Provider. spec.timeout pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" # Timeout for sending alerts to the Provider. -spec.type (required) enum=slack|discord|msteams|rocket|generic|generic-hmac|github|gitlab|gitea|giteapullrequestcomment|bitbucketserver|bitbucket|azuredevops|googlechat|googlepubsub|webex|sentry|azureeventhub|telegram|lark|matrix|opsgenie|alertmanager|grafana|githubdispatch|githubpullrequestcomment|gitlabmergerequestcomment|pagerduty|datadog|nats|zulip|otel # Type specifies which Provider implementation to use. +spec.type (required) enum=slack|discord|msteams|rocket|generic|generic-hmac|github|gitlab|gitea|giteapullrequestcomment|bitbucketserver|bitbucket|azuredevops|googlechat|googlepubsub|webex|sentry|azureeventhub|telegram|lark|matrix|opsgenie|alertmanager|grafana|githubdispatch|githubpullrequestcomment|gitlabmergerequestcomment|pagerduty|datadog|nats|zulip|otel|zoom|incident.io # Type specifies which Provider implementation to use. spec.username max=2048 # Username specifies the name under which events are posted. diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/receiver-notification-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/receiver-notification-v1.fields.txt index 65b28bd4d6..fb381503e5 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/receiver-notification-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/receiver-notification-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=notification.toolkit.fluxcd.io/v1 kind enum=Receiver metadata.name (required) diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/resourceset-fluxcd-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/resourceset-fluxcd-v1.fields.txt index ab0cf5172f..ec45be7f0c 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/resourceset-fluxcd-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/resourceset-fluxcd-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux Operator v0.58.1 https://github.com/controlplaneio-fluxcd/flux-operator +# schema source: Flux Operator v0.62.0 https://github.com/controlplaneio-fluxcd/flux-operator apiVersion enum=fluxcd.controlplane.io/v1 kind enum=ResourceSet metadata.name (required) diff --git a/.agents/skills/gitops-cluster-debug/assets/schemas/resourcesetinputprovider-fluxcd-v1.fields.txt b/.agents/skills/gitops-cluster-debug/assets/schemas/resourcesetinputprovider-fluxcd-v1.fields.txt index edd3e0fd43..8c9b7f1749 100644 --- a/.agents/skills/gitops-cluster-debug/assets/schemas/resourcesetinputprovider-fluxcd-v1.fields.txt +++ b/.agents/skills/gitops-cluster-debug/assets/schemas/resourcesetinputprovider-fluxcd-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux Operator v0.58.1 https://github.com/controlplaneio-fluxcd/flux-operator +# schema source: Flux Operator v0.62.0 https://github.com/controlplaneio-fluxcd/flux-operator apiVersion enum=fluxcd.controlplane.io/v1 kind enum=ResourceSetInputProvider metadata.name (required) @@ -32,7 +32,7 @@ spec.selectors[].matchExpressions[].values <[]string> # values is an array of st spec.selectors[].matchLabels # matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. spec.selectors[].name # Name selects a single ExternalArtifact by metadata.name. This field is mutually exclusive with matchLabels and matchExpressions. spec.selectors[].namespace # Namespace scopes ExternalArtifact discovery. When empty, ExternalArtifacts are listed in the ResourceSetInputProvider namespace. When set to "*", ExternalArtifacts are listed across all namespaces by omitting the namespace option from List(). Otherwise, ExternalArtifacts are listed only in the specified namespace. -spec.serviceAccountName # ServiceAccountName specifies the name of the Kubernetes ServiceAccount used for authentication with AWS, Azure or GCP services through workload identity federation features. If not specified, the authentication for these cloud providers will use the ServiceAccount of the operator (or any other environment authentication configuration). +spec.serviceAccountName # ServiceAccountName specifies the name of the Kubernetes ServiceAccount used for authentication with external services using object identity. If not specified, the default object identity ServiceAccount configured with the --default-object-identity-service-account flag or the DEFAULT_OBJECT_IDENTITY_SERVICE_ACCOUNT environment variable is used. This field can also be set for the ExternalArtifact type, where it is used only for impersonation and its annotations are ignored. For a complete guide to the ServiceAccount annotations used for object identity, including the spiffe credential provider, see: https://fluxcd.io/flux/integrations/object-identity/ spec.skip # Skip defines whether we need to skip input provider response updates. spec.skip.labels <[]string> # Labels specifies list of labels to skip input provider response when any of the label conditions matched. When prefixed with !, input provider response will be skipped if it does not have this label. spec.type (required) enum=Static|GitHubBranch|GitHubTag|GitHubPullRequest|GitLabBranch|GitLabTag|GitLabMergeRequest|GitLabEnvironment|AzureDevOpsBranch|AzureDevOpsTag|AzureDevOpsPullRequest|AWSCodeCommitBranch|AWSCodeCommitTag|AWSCodeCommitPullRequest|GiteaBranch|GiteaTag|GiteaPullRequest|OCIArtifactTag|ACRArtifactTag|ECRArtifactTag|GARArtifactTag|ExternalService|ExternalArtifact # Type specifies the type of the input provider. diff --git a/.agents/skills/gitops-cluster-debug/evals/evals.json b/.agents/skills/gitops-cluster-debug/evals/evals.json index f68484b3d4..fb90f1707f 100644 --- a/.agents/skills/gitops-cluster-debug/evals/evals.json +++ b/.agents/skills/gitops-cluster-debug/evals/evals.json @@ -1,55 +1,77 @@ { "skill_name": "gitops-cluster-debug", - "note": "These evals require a live Kubernetes cluster with Flux Operator and the flux-operator-mcp server running. They serve as documentation for expected skill behavior.", + "note": "These evals need a live cluster running Flux Operator and Flux 2.10 with the scenarios from tests/gitops-cluster-debug/scenarios.yaml applied, and the flux-operator-mcp server (v0.60+) running with --read-only. Executors get only the MCP tools plus local file tools; they have no kubectl access to the cluster.", "evals": [ { "id": 1, "prompt": "Check the Flux installation health on the current cluster and provide a status report.", - "expected_output": "A report showing the Flux Operator status, FluxInstance readiness, controller deployment health, installed Flux version, and a summary from the FluxReport.", + "expected_output": "A report showing the Flux Operator and FluxInstance status, the Flux version and components, controller health, and the Flux resources that are not ready across the cluster.", "files": [], "expectations": [ - "Calls get_flux_instance to check the Flux Operator status", - "Reports the FluxInstance Ready condition and any issues", - "Lists all Flux controller deployments and their status", - "Reports the installed Flux distribution version", - "Summarizes the FluxReport resource counts and conditions", - "If controllers are unhealthy, checks controller pod logs", - "Produces a structured report with summary and recommendations" + "Calls get_flux_instance to check the Flux Operator and FluxInstance status", + "Reports the installed Flux distribution version (v2.10.0) and that the FluxInstance is Ready", + "Lists the Flux controller deployments and their status", + "Names the failing Kustomization tenant-a/apps and the failing GitRepository tenant-a/tenant-a", + "Names the failing HelmRelease default/podinfo", + "Produces a structured report with a summary and recommendations" ] }, { "id": 2, - "prompt": "Debug the failing Kustomization 'apps' in the 'flux-system' namespace.", - "expected_output": "A root cause analysis identifying that the Kustomization fails because its source GitRepository has an authentication error, with recommendations to fix the Git credentials.", + "prompt": "Debug the failing Kustomization 'apps' in the 'tenant-a' namespace.", + "expected_output": "A root cause analysis identifying that the Kustomization has no artifact because its GitRepository tenant-a fails to clone with an authentication error, with recommendations to fix the Git credentials in the git-auth Secret.", "files": [], "expectations": [ - "Calls get_flux_instance to check the kustomize-controller status", - "Calls get_kubernetes_api_versions to verify the Kustomization apiVersion", - "Gets the Kustomization resource and analyzes its status conditions and events", - "Identifies the sourceRef pointing to a GitRepository", - "Gets the GitRepository resource and finds the FetchFailed condition", - "Identifies the authentication error as the root cause", - "Checks if the referenced secretRef Secret exists and has the expected keys", - "Produces a root cause analysis report with the dependency chain", - "Recommends fixing the Git credentials in the referenced Secret" + "Gets the Kustomization and reports its Ready condition (source artifact not found)", + "Identifies the sourceRef GitRepository tenant-a and gets it", + "Identifies the GitRepository authentication failure (invalid username or token) as the root cause", + "Checks that the referenced Secret git-auth exists and reports its key names (username, password)", + "Produces a root cause analysis report with the dependency chain GitRepository -> Kustomization", + "Recommends replacing the credentials in the git-auth Secret with a valid token (or GitHub App) and reconciling the source" ] }, { "id": 3, "prompt": "Debug the failing HelmRelease 'podinfo' in the 'default' namespace.", - "expected_output": "A root cause analysis identifying that the HelmRelease upgrade failed with managed Deployment pods in ImagePullBackOff due to a non-existent container image tag.", + "expected_output": "A root cause analysis identifying that the HelmRelease install fails because the podinfo Deployment pods are in ImagePullBackOff for the non-existent image tag 6.99.0-hotfix set in the HelmRelease values.", "files": [], "expectations": [ - "Calls get_flux_instance to check the helm-controller status", - "Calls get_kubernetes_api_versions to verify the HelmRelease apiVersion", - "Gets the HelmRelease resource and analyzes its status conditions and events", - "Identifies the chart source from chartRef or sourceRef", - "Gets the source resource and verifies it is ready", - "Checks the HelmRelease inventory for managed resources", - "Gets managed Deployments and finds pods in ImagePullBackOff", - "Analyzes pod events to identify the image pull error", - "Produces a root cause analysis tracing from HelmRelease to Deployment to Pod", - "Recommends fixing the container image reference in the HelmRelease values" + "Gets the HelmRelease and analyzes its status conditions (install failed or retrying)", + "Identifies the chart source OCIRepository default/podinfo and reports it as ready", + "Gets the managed podinfo Deployment or its pods from the release inventory", + "Finds the pods in ErrImagePull/ImagePullBackOff from events or pod status", + "Identifies the non-existent image tag 6.99.0-hotfix as the root cause", + "Traces the tag to spec.values.image.tag in the HelmRelease", + "Recommends fixing image.tag in the HelmRelease values (in Git) to an existing tag" + ] + }, + { + "id": 4, + "prompt": "Pods of the 'orders' deployment in the 'shop' namespace keep crashing. Find out what deploys it through GitOps and why it crashes.", + "expected_output": "Traces the Deployment to the ResourceSet shop/shop-services, finds CrashLoopBackOff/BackOff events, reads the container logs showing DB_PASSWORD is not set, and recommends adding DB_PASSWORD (from a Secret) in the ResourceSet template.", + "files": [], + "expectations": [ + "Calls trace_kubernetes_resource on the orders Deployment (or one of its pods)", + "Identifies the ResourceSet shop/shop-services as the Flux object that deploys the Deployment", + "Calls get_kubernetes_events for the orders workload and reports the BackOff / CrashLoopBackOff warnings", + "Calls get_kubernetes_logs with kind Deployment (not a pod name looked up first)", + "Identifies from the logs that the app exits because DB_PASSWORD is not set", + "Notes that the orders-config ConfigMap provides DB_HOST/DB_PORT/DB_NAME but no DB_PASSWORD", + "Recommends adding DB_PASSWORD from a Secret in the ResourceSet template (not editing the live Deployment)" + ] + }, + { + "id": 5, + "prompt": "I edited the podinfo manifests in {FIXTURE:tests/gitops-cluster-debug/podinfo-change} (this directory is deployed by the Flux Kustomization 'podinfo' in the 'web' namespace). Before I commit, tell me exactly what this change will do on the cluster.", + "expected_output": "Builds the directory, diffs it against the cluster with the web/podinfo Kustomization as owner, and reports the Deployment memory limit change, the HPA maxReplicas change and that the Service web/podinfo will be deleted (pruned).", + "files": ["tests/gitops-cluster-debug/podinfo-change"], + "expectations": [ + "Builds the manifests locally (kustomize build or equivalent) and passes the complete build output", + "Calls diff_kubernetes_manifest with owner Kustomization web/podinfo (owner_kind/owner_name/owner_namespace or flux_object)", + "Reports the Deployment update: memory limit 512Mi -> 256Mi", + "Reports the HorizontalPodAutoscaler update: maxReplicas 4 -> 8", + "Reports that the Service web/podinfo will be deleted because prune is enabled", + "Does not modify the cluster or the local files" ] } ] diff --git a/.agents/skills/gitops-cluster-debug/references/flux-crds.md b/.agents/skills/gitops-cluster-debug/references/flux-crds.md index 34ed3ce1d7..1e469510a5 100644 --- a/.agents/skills/gitops-cluster-debug/references/flux-crds.md +++ b/.agents/skills/gitops-cluster-debug/references/flux-crds.md @@ -220,6 +220,7 @@ Note: OCI HelmRepositories have no status conditions. **Key spec fields**: - `.spec.chartRef` / `.spec.chart.spec.sourceRef` — Chart source reference +- `.spec.chart.kind: OCIRepository` (Flux 2.10+) — `.spec.chart.spec` is an inline OCIRepository spec (`url`, `ref`); the controller creates and owns an OCIRepository named `-`, reported in `.status.helmChart` as `OCIRepository//` (event `OCIRepositoryCreated`). Debug that OCIRepository like any other source - `.spec.interval` — Reconciliation interval - `.spec.values` — Inline Helm values - `.spec.valuesFrom` — Values from ConfigMaps/Secrets @@ -242,18 +243,21 @@ Note: OCI HelmRepositories have no status conditions. ## Notification Controller -### Provider (`notification.toolkit.fluxcd.io/v1beta3`) +### Provider (`notification.toolkit.fluxcd.io/v1`) **Purpose**: Represents a notification service (Slack, MS Teams, GitHub, etc.). **Key spec fields**: - `.spec.type` — Provider type (slack, msteams, github, generic, etc.) - `.spec.address` — Webhook URL or API endpoint -- `.spec.secretRef` — Secret with authentication token +- `.spec.secretRef` — Secret with credentials (`address`, `token`, `username`, `password`, `headers`) +- `.spec.proxySecretRef` — Secret with proxy `address`; replaces `.spec.proxy` (removed in v1) +- `.spec.certSecretRef` — TLS data (`ca.crt`, `tls.crt`, `tls.key`) -Note: Providers have no status conditions. +Note: Providers have no status conditions. `v1beta3` is deprecated in Flux 2.10 (warning +`v1beta3 Provider is deprecated, upgrade to v1`); `v1` drops `.spec.proxy` and `.spec.interval`. -### Alert (`notification.toolkit.fluxcd.io/v1beta3`) +### Alert (`notification.toolkit.fluxcd.io/v1`) **Purpose**: Configures events to be forwarded to notification providers. @@ -263,6 +267,7 @@ Note: Providers have no status conditions. - `.spec.eventSeverity` — Minimum severity to forward (info, error) Note: Alerts have no status conditions. +`v1beta3` is deprecated in Flux 2.10; `v1` drops `.spec.summary` (use `.spec.eventMetadata.summary`). ### Receiver (`notification.toolkit.fluxcd.io/v1`) diff --git a/.agents/skills/gitops-cluster-debug/references/troubleshooting.md b/.agents/skills/gitops-cluster-debug/references/troubleshooting.md index 135e0b9db2..0fc2f1cc3a 100644 --- a/.agents/skills/gitops-cluster-debug/references/troubleshooting.md +++ b/.agents/skills/gitops-cluster-debug/references/troubleshooting.md @@ -31,6 +31,30 @@ Common failure patterns and debugging procedures for Flux on Kubernetes clusters - OOMKilled (increase memory limits in FluxInstance kustomize patches) - Incompatible CRD version (controller binary doesn't match installed CRDs) - Corrupt cache or storage (delete the pod to force fresh start) +- Unsupported Kubernetes version (Flux 2.10 requires Kubernetes 1.35 or later) + +### Object identity credentials fail (Flux 2.10+) + +**Symptoms**: Sources, Providers, image or applier objects with `.spec.serviceAccountName` fail auth +(cloud `.spec.provider`, `generic` with `credential.auth.fluxcd.io/*` ServiceAccount annotations, or +`kubeConfig.configMapRef`) — typically right after upgrading to 2.10; errors mention `serviceaccounts/token` or forbidden. + +**Common causes**: +- **Missing token RBAC**: Flux 2.10 default RBAC no longer grants `create` on `serviceaccounts/token`. Bind a ClusterRole with that permission to the controller ServiceAccounts (or set FluxInstance `.spec.cluster.objectIdentityRBAC: true`). +- **Incomplete annotations**: `generic` ServiceAccount tokens need both `credential.auth.fluxcd.io/provider: kubernetes` and `credential.auth.fluxcd.io/type: jwt`; one without the other is an error, and they can't be combined with `imagePullSecrets`. +- **Lockdown default SA**: With the object identity lockdown (`--default-service-account`, `multitenantObjectIdentity`), objects without `serviceAccountName` use the tenant's default SA, not the controller identity. +- **`spiffe` provider**: Requires the SPIFFE Workload API socket plus `--spiffe-broker-endpoint` and `--spiffe-broker-id` flags on the controller. + +### Inter-controller mTLS failures (SPIFFE, Flux 2.10+) + +**Symptoms**: Kustomizations/HelmReleases fail to fetch artifacts while the source is `Ready`, or +events stop reaching notification-controller, after `--authorized-*-spiffe-id` flags were added. + +**Diagnosis**: mTLS is enabled per traffic type by the presence of a flag, on both sides. Check that the +peer's flag is also set (e.g. `--authorized-artifact-client-spiffe-id` on source-controller pairs with +`--authorized-artifact-server-spiffe-id` on kustomize/helm-controller), that each flag holds the **peer's** SPIFFE ID +exactly as issued by the SPIFFE runtime, that `SPIFFE_ENDPOINT_SOCKET` and the socket mount exist on every +controller, and that the Services expose port 443 (`https`). ## Source Failures @@ -169,6 +193,12 @@ notification-controller logs, not object status. - **Event filtered**: Alert `.spec.eventSeverity: error` drops info events; `.spec.eventSources` doesn't match the resource kind/name/namespace producing the event. - **Provider auth/address error**: Wrong or expired token in the `secretRef`, wrong webhook `address` — look for HTTP 401/404/timeout errors in controller logs. - **Wrong provider type**: `.spec.type` doesn't match the receiving service's expected payload format. +- **Secret keys rejected after upgrading to Flux 2.10** (applies to `v1beta3` objects too, the controller reads `v1`): + - a `proxy` key in the `secretRef` Secret is rejected — move it to a Secret referenced by `.spec.proxySecretRef`; + - commit status Providers (`github`, `gitlab`, `gitea`, `bitbucket`, `bitbucketserver`, `azuredevops`) fail when the `secretRef` Secret holds TLS data and `.spec.certSecretRef` is unset; + - `azureeventhub` fails when its Secret has a `token` key (static JWT auth removed; use SAS `address` or object identity); + - `bitbucket` rejects `:` tokens — use a Bitbucket Cloud API token. +- **Alert summary or Provider proxy gone after upgrade**: `v1` dropped Alert `.spec.summary` and Provider `.spec.proxy`/`.spec.interval`; the API server drops them when objects are served or written at the `v1` storage version, with no error. Restore with `.spec.eventMetadata.summary` and `.spec.proxySecretRef`. Warnings like `v1beta3 Alert is deprecated, upgrade to v1` mean manifests in Git still use `v1beta3` — run `flux migrate -f .`. ### Receiver not triggering diff --git a/.agents/skills/gitops-knowledge/SKILL.md b/.agents/skills/gitops-knowledge/SKILL.md index 12d26cb0c4..42ef805401 100644 --- a/.agents/skills/gitops-knowledge/SKILL.md +++ b/.agents/skills/gitops-knowledge/SKILL.md @@ -4,9 +4,9 @@ description: | license: Apache-2.0 metadata: github-path: skills/gitops-knowledge - github-ref: refs/tags/v0.3.0 + github-ref: refs/tags/v0.4.0 github-repo: https://github.com/fluxcd/agent-skills - github-tree-sha: d2ac2832df36d71727c39e1740db43760180d215 + github-tree-sha: 51871054237119b83bedda9df029a69b0a647d1e internal: true name: gitops-knowledge --- @@ -59,7 +59,7 @@ The field index for each CRD is `assets/schemas/--.fields. | ArtifactGenerator | source.extensions.fluxcd.io/v1beta1 | source-watcher | `references/sources.md` | | Kustomization | kustomize.toolkit.fluxcd.io/v1 | kustomize-controller | `references/kustomization.md` | | HelmRelease | helm.toolkit.fluxcd.io/v2 | helm-controller | `references/helmrelease.md` | -| Provider, Alert | notification.toolkit.fluxcd.io/v1beta3 | notification-controller | `references/notifications.md` | +| Provider, Alert | notification.toolkit.fluxcd.io/v1 | notification-controller | `references/notifications.md` | | Receiver | notification.toolkit.fluxcd.io/v1 | notification-controller | `references/notifications.md` | | ImageRepository, ImagePolicy | image.toolkit.fluxcd.io/v1 | image-reflector-controller | `references/image-automation.md` | | ImageUpdateAutomation | image.toolkit.fluxcd.io/v1 | image-automation-controller | `references/image-automation.md` | @@ -69,7 +69,7 @@ The field index for each CRD is `assets/schemas/--.fields. | Repository structure, monorepo vs multi-repo, OCI-based fleet management | `references/repo-patterns.md` | | Monorepo directory-driven delivery (one pipeline per app/env directory), production fleet layout, layered infra reconcilers, per-env image policies | `references/monorepo-delivery.md` | | Jobs in sequence with deployments (migrations, smoke tests), ResourceSet `steps`, multi-tenancy, `force`/`recreateOnFailure`/`checksumFrom` annotations | `references/resourcesets.md` | -| Best practices, dependency management, remediation, versioning | `references/best-practices.md` | +| Best practices, dependency management, remediation, versioning, SPIFFE mTLS, object identity | `references/best-practices.md` | | Gitless GitOps, Flux OCI artifacts, `flux push artifact`, registry-based delivery | `references/gitless-gitops.md` | | Gitless image automation (ResourceSet + OCIArtifactTag) | `references/gitless-image-automation.md` | | Flux CLI and plugins: `flux schema` discover/validate/extract, local rendering with `flux build` and `flux operator build`, overlay debugging | `references/flux-cli.md` | @@ -198,7 +198,8 @@ spec: ``` For HTTPS Helm repositories use `HelmRepository` + `HelmRelease` with `spec.chart.spec` -(`chart`, `version: "3.x"`, `sourceRef`) instead of `chartRef` — see `references/helmrelease.md`. +(`chart`, `version: "3.x"`, `sourceRef`) instead of `chartRef`. For an OCI chart owned by one HelmRelease, +2.10+ also allows `spec.chart.kind: OCIRepository` — see `references/helmrelease.md`. ### 3. FluxInstance with OCI Sync (Gitless GitOps) @@ -253,7 +254,7 @@ and the `reconcileEvery` annotation — load `references/resourcesets.md`. ### 6. Notifications -`Provider` + `Alert` (`v1beta3`) for outgoing notifications, `Receiver` (`v1`) for incoming +`Provider` + `Alert` (`v1`) for outgoing notifications, `Receiver` (`v1`) for incoming webhooks. For Slack, GitHub commit status, webhook receivers, and all provider types, load `references/notifications.md`. @@ -264,7 +265,7 @@ load `references/notifications.md`. - Go templates `{{ }}` are only used in ImageUpdateAutomation `.spec.git.commit.messageTemplate` **Mutual exclusivity:** -- HelmRelease: `spec.chart.spec` and `spec.chartRef` are mutually exclusive +- HelmRelease: `spec.chart` and `spec.chartRef` are mutually exclusive - FluxInstance: only one per cluster, must be named `flux` **HelmRelease strategy fields:** diff --git a/.agents/skills/gitops-knowledge/assets/schemas/alert-notification-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/alert-notification-v1.fields.txt new file mode 100644 index 0000000000..4cad134b74 --- /dev/null +++ b/.agents/skills/gitops-knowledge/assets/schemas/alert-notification-v1.fields.txt @@ -0,0 +1,19 @@ +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 +apiVersion enum=notification.toolkit.fluxcd.io/v1 +kind enum=Alert +metadata.name (required) +metadata.namespace (required) +spec # AlertSpec defines an alerting rule for events involving a list of objects. +spec.eventMetadata # EventMetadata adds metadata to events. Sources, from lowest to highest precedence: `event.toolkit.fluxcd.io/` annotations on the involved object, Alert `.spec.eventMetadata`, and controller-defined `.toolkit.fluxcd.io/` event metadata. Higher precedence wins; conflicts produce an info log and a Warning Event. See the Alert API docs (Event metadata section). +spec.eventSeverity enum=info|error default="info" # EventSeverity specifies how to filter events based on severity. If set to 'info' no events will be filtered. +spec.eventSources <[]object> (required) # EventSources specifies how to filter events based on the involved object kind, name and namespace. +spec.eventSources[].apiVersion # API version of the referent +spec.eventSources[].kind (required) enum=Bucket|GitRepository|Kustomization|HelmRelease|HelmChart|HelmRepository|ImageRepository|ImagePolicy|ImageUpdateAutomation|OCIRepository|ArtifactGenerator|ExternalArtifact|FluxInstance|ResourceSet|ResourceSetInputProvider # Kind of the referent +spec.eventSources[].matchLabels # MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. MatchLabels requires the name to be set to `*`. +spec.eventSources[].name (required) min=1 max=253 # Name of the referent If multiple resources are targeted `*` may be set. +spec.eventSources[].namespace min=1 max=253 # Namespace of the referent +spec.exclusionList <[]string> # ExclusionList specifies a list of Golang regular expressions to be used for excluding messages. +spec.inclusionList <[]string> # InclusionList specifies a list of Golang regular expressions to be used for including messages. +spec.providerRef (required) # ProviderRef specifies which Provider this Alert should use. +spec.providerRef.name (required) # Name of the referent. +spec.suspend # Suspend tells the controller to suspend subsequent events handling for this Alert. diff --git a/.agents/skills/gitops-knowledge/assets/schemas/alert-notification-v1beta3.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/alert-notification-v1beta3.fields.txt index d77f4a99da..6673ce4b00 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/alert-notification-v1beta3.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/alert-notification-v1beta3.fields.txt @@ -1,5 +1,5 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 -apiVersion enum=notification.toolkit.fluxcd.io/v1beta3 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 +apiVersion enum=notification.toolkit.fluxcd.io/v1beta3 (deprecated) # v1beta3 Alert is deprecated, upgrade to v1 kind enum=Alert metadata.name (required) metadata.namespace (required) diff --git a/.agents/skills/gitops-knowledge/assets/schemas/artifactgenerator-source-v1beta1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/artifactgenerator-source-v1beta1.fields.txt index 06c4ee4f78..31b74c312c 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/artifactgenerator-source-v1beta1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/artifactgenerator-source-v1beta1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.extensions.fluxcd.io/v1beta1 kind enum=ArtifactGenerator metadata.name (required) @@ -8,15 +8,32 @@ spec.artifacts <[]object> (required) min=1 max=1000 # OutputArtifacts is a list spec.artifacts[].copy <[]object> (required) min=1 # Copy defines a list of copy operations to perform from the sources to the generated artifact. The copy operations are performed in the order they are listed with existing files being overwritten by later copy operations. spec.artifacts[].copy[].exclude <[]string> max=100 # Exclude specifies a list of glob patterns to exclude files and dirs matched by the 'From' field. Patterns are matched against paths relative to the source alias root or to the non-glob prefix of 'From'. Patterns without a separator (e.g. "*.md") match the file name at any depth. spec.artifacts[].copy[].from (required) pattern="^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)/(.*)$" min=1 max=1024 # From specifies the source (by alias) and the glob pattern to match files. The format is "@/". When pathPattern is set, the path may use capture placeholders such as "{app}". +spec.artifacts[].copy[].optional # Optional, when set to true, allows the copy operation to silently skip when the source path or glob pattern matches no files. When false (default), the reconciliation fails with an error if no files are matched. spec.artifacts[].copy[].strategy enum=Overwrite|Merge|Extract # Strategy specifies the copy strategy to use. 'Overwrite' will overwrite existing files in the destination. 'Merge' is for merging YAML files using Helm values merge strategy. 'Extract' is for extracting the contents of tarball archives (.tar.gz, .tgz) When using glob patterns, non-tarball files are silently skipped. For single file sources, the file must be a tarball or an error is returned. Directories are not supported. If not specified, defaults to 'Overwrite'. spec.artifacts[].copy[].to (required) pattern="^@artifact/([^/]{0,1}|[^./][^/]|[.][^./]|[^/]{3,})(/([^/]{0,1}|[^./][^/]|[.][^./]|[^/]{3,}))*$" min=1 max=1024 # To specifies the destination path within the artifact. The format is "@artifact/path", the alias "artifact" refers to the root path of the generated artifact. When pathPattern is set, the path may use capture placeholders such as "{app}". -spec.artifacts[].name (required) min=1 max=253 # Name is the name of the generated artifact. When pathPattern is set, this field may use capture placeholders such as "{app}". +spec.artifacts[].inputsFrom pattern="^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)/(.*)$" min=1 max=1024 # InputsFrom specifies a source path to a YAML file whose contents are exported in the ExternalArtifact .status.exportedInputs field. The format is "@/", where references a source or "artifact" for the generated artifact itself. When pathPattern is set, the path may use capture placeholders such as "{module}". +spec.artifacts[].name (required) max=1024 # Name is the name of the generated artifact. When pathPattern is set, this field may use capture placeholders such as "{app}". The maximum length accommodates capture placeholders; the effective limits are enforced by the CEL validation when pathPattern is not set. +spec.artifacts[].namespace max=1024 # Namespace is the namespace of the generated artifact. If not provided, defaults to the same namespace as the ArtifactGenerator. When pathPattern is set, this field may use capture placeholders such as "{app}". The credentials used to reconcile the artifact are described in .spec.serviceAccountName: an explicit ServiceAccount applies to every generated artifact, while the --default-service-account flag only applies to artifacts in a namespace other than the ArtifactGenerator namespace. The maximum length accommodates capture placeholders; the effective limits are enforced by the CEL validation when pathPattern is not set. spec.artifacts[].originRevision pattern="^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)$" max=64 # OriginRevision is used to set the 'org.opencontainers.image.revision' annotation on the generated artifact metadata. If specified, it must point to an existing source alias in the format "@". If the referenced source has an origin revision (e.g. a Git commit SHA), it will be used to set the annotation on the generated artifact. If the referenced source does not have an origin revision, the field is ignored. spec.artifacts[].revision pattern="^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)$" max=64 # Revision is the revision of the generated artifact. If specified, it must point to an existing source alias in the format "@". If not specified, the revision is automatically set to the digest of the artifact content. spec.commonMetadata # CommonMetadata specifies the common labels and annotations that are applied to all resources. Any existing label or annotation will be overridden if its key matches a common one. spec.commonMetadata.annotations # Annotations to be added to the object's metadata. spec.commonMetadata.labels # Labels to be added to the object's metadata. +spec.managedNamespaces # ManagedNamespaces defines how the controller manages the namespaces targeted by the generated artifacts. When omitted, the target namespaces are unmanaged: they must already exist and are left untouched. +spec.managedNamespaces.allowedNames <[]string> (required) min=1 # AllowedNames is a list of CEL expressions that define the set of namespaces the ArtifactGenerator agrees to manage. Each expression receives the namespace name through the 'ns' string variable and must return a boolean. A namespace is managed only when at least one expression returns true. The 'default', 'kube-system', 'kube-public' and 'flux-system' namespaces are always rejected, regardless of the expressions. +spec.managedNamespaces.metadata # Metadata defines how the metadata of the desired namespaces is built, on top of .spec.commonMetadata. +spec.managedNamespaces.metadata.from <[]object> # From is a list of metadata operations applied in order to the desired namespaces, on top of .spec.commonMetadata and .fromSource. +spec.managedNamespaces.metadata.from[].annotations # Annotations to be applied to the namespace. +spec.managedNamespaces.metadata.from[].labels # Labels to be applied to the namespace. +spec.managedNamespaces.metadata.from[].namespace (required) pattern="^(\\*|[a-z0-9]([-a-z0-9]*[a-z0-9])?)$" max=63 # Namespace is the name of the desired namespace the metadata applies to, or '*' to apply the metadata to all desired namespaces. +spec.managedNamespaces.metadata.from[].strategy (required) enum=Reset|Override|Merge # Strategy specifies how the labels and annotations are applied. 'Reset' clears all the existing labels and annotations before applying the ones defined in the operation (fields that are not set clear the corresponding metadata), 'Override' merges the ones defined in the operation into the existing values, overriding existing keys, while 'Merge' merges only the absent keys, preserving existing values. +spec.managedNamespaces.metadata.fromSource # FromSource sources namespace metadata from a NamespaceMetadata file inside a source artifact. +spec.managedNamespaces.metadata.fromSource.allowedAnnotations # AllowedAnnotations is a schema for the annotations that the NamespaceMetadata file is allowed to set. Each key is an annotation key and each value is a CEL expression that receives the annotation value through the 'value' string variable and must return a boolean. Annotations whose key is not present in this map are ignored, while annotations whose value does not satisfy the respective expression are rejected. The expressions are compiled, so a malformed expression or one that does not return a boolean fails validation at the start of the reconciliation. +spec.managedNamespaces.metadata.fromSource.allowedLabels # AllowedLabels is a schema for the labels that the NamespaceMetadata file is allowed to set. Each key is a label key and each value is a CEL expression that receives the label value through the 'value' string variable and must return a boolean. Labels whose key is not present in this map are ignored, while labels whose value does not satisfy the respective expression are rejected. The expressions are compiled, so a malformed expression or one that does not return a boolean fails validation at the start of the reconciliation. +spec.managedNamespaces.metadata.fromSource.path (required) pattern="^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)/(.*)$" min=1 max=1024 # Path is the path to the NamespaceMetadata file inside a source artifact, in the format "@/". When pathPattern is set, the path may use capture placeholders such as "{namespace}". Only namespace-level captures are allowed, so that every artifact targeting a namespace resolves to the same file. +spec.managedNamespaces.prune (required) # Prune specifies whether the controller deletes managed namespaces that are no longer targeted by any generated artifact, or when the ArtifactGenerator is deleted. spec.pathPattern pattern="^@([a-z0-9]([a-z0-9_-]*[a-z0-9])?)/(.*)$" max=1024 # PathPattern specifies a directory traversal pattern to match within the sources. The format is "@/". Named captures in the pattern (e.g. "{app}") can be used as placeholders in OutputArtifacts fields. +spec.serviceAccountName pattern="^[a-z0-9]([-a-z0-9]*[a-z0-9])?$" min=1 max=63 # ServiceAccountName is the name of the ServiceAccount used to authorize the reconciliation of the generated ExternalArtifacts and the managed Namespaces. The name is resolved in the ArtifactGenerator namespace. When specified, the controller checks this ServiceAccount with SubjectAccessReview for every namespace targeted by the generated ExternalArtifacts, including the ArtifactGenerator namespace, and its RBAC bindings determine the namespaces in which they can be created, updated and deleted. When not specified, the controller uses its own credentials for ExternalArtifacts in the ArtifactGenerator namespace, and the ServiceAccount configured with the --default-service-account flag (when set) for artifacts targeting another namespace. Namespace management (.spec.managedNamespaces) always requires a ServiceAccount for authorization, so either this field or the --default-service-account flag must be set; otherwise the reconciliation fails with a terminal error. The controller performs the namespace operations with its own credentials. spec.sources <[]object> (required) min=1 max=1000 # Sources is a list of references to the Flux source-controller resources that will be used to generate the artifact. spec.sources[].alias (required) pattern="^[a-z0-9]([a-z0-9_-]*[a-z0-9])?$" max=63 # Alias of the source within the ArtifactGenerator context. The alias must be unique per ArtifactGenerator, and must consist of lower case alphanumeric characters, underscores, and hyphens. It must start and end with an alphanumeric character. spec.sources[].kind (required) enum=Bucket|GitRepository|OCIRepository|HelmChart|ExternalArtifact # Kind of the source. @@ -30,10 +47,11 @@ status.conditions[].observedGeneration format=int64 min=0 # observedGe status.conditions[].reason (required) pattern="^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$" min=1 max=1024 # reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. status.conditions[].status (required) enum=True|False|Unknown # status of the condition, one of True, False, Unknown. status.conditions[].type (required) pattern="^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$" max=316 # type of condition in CamelCase or in foo.example.com/CamelCase. -status.inventory <[]object> # Inventory contains the list of generated ExternalArtifact references. -status.inventory[].digest (required) # Digest of the referent artifact. -status.inventory[].filename (required) # Filename is the name of the artifact file. -status.inventory[].name (required) # Name of the referent artifact. -status.inventory[].namespace (required) # Namespace of the referent artifact. +status.inventory <[]object> # Inventory contains the list of objects managed by the ArtifactGenerator, such as the generated ExternalArtifacts and the managed Namespaces. +status.inventory[].digest (required) # Digest of the referent object. For generated artifacts this is the artifact content digest; for managed namespaces this is a digest of the metadata applied by the controller. +status.inventory[].filename # Filename is the name of the artifact file. +status.inventory[].kind enum=ExternalArtifact|Namespace # Kind is the kind of the referent object. +status.inventory[].name (required) # Name of the referent object. +status.inventory[].namespace # Namespace of the referent object. Empty for cluster-scoped objects. status.lastHandledReconcileAt # LastHandledReconcileAt holds the value of the most recent reconcile request value, so a change of the annotation value can be detected. status.observedSourcesDigest # ObservedSourcesDigest is a hash representing the current state of all the sources referenced by the ArtifactGenerator. diff --git a/.agents/skills/gitops-knowledge/assets/schemas/bucket-source-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/bucket-source-v1.fields.txt index 5ee36407aa..429e7e9f25 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/bucket-source-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/bucket-source-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.toolkit.fluxcd.io/v1 kind enum=Bucket metadata.name (required) @@ -18,7 +18,7 @@ spec.proxySecretRef.name (required) # Name of the referent. spec.region # Region of the Endpoint where the BucketName is located in. spec.secretRef # SecretRef specifies the Secret containing authentication credentials for the Bucket. spec.secretRef.name (required) # Name of the referent. -spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the bucket. This field is only supported for the 'gcp' and 'aws' providers. For more information about workload identity: https://fluxcd.io/flux/components/source/buckets/#workload-identity +spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the bucket. This field is only supported for the 'gcp' and 'aws' providers. For more information about object identity: https://fluxcd.io/flux/integrations/object-identity/ spec.sts # STS specifies the required configuration to use a Security Token Service for fetching temporary credentials to authenticate in a Bucket provider. This field is only supported for the `aws` and `generic` providers. spec.sts.certSecretRef # CertSecretRef can be given the name of a Secret containing either or both of - a PEM-encoded client certificate (`tls.crt`) and private key (`tls.key`); - a PEM-encoded CA certificate (`ca.crt`) and whichever are supplied, will be used for connecting to the STS endpoint. The client cert and key are useful if you are authenticating with a certificate; the CA cert is useful if you are using a self-signed server certificate. The Secret must be of type `Opaque` or `kubernetes.io/tls`. This field is only supported for the `ldap` provider. spec.sts.certSecretRef.name (required) # Name of the referent. diff --git a/.agents/skills/gitops-knowledge/assets/schemas/externalartifact-source-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/externalartifact-source-v1.fields.txt index 6eee8a4a4e..3a791085c5 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/externalartifact-source-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/externalartifact-source-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.toolkit.fluxcd.io/v1 kind enum=ExternalArtifact metadata.name (required) @@ -25,3 +25,4 @@ status.conditions[].observedGeneration format=int64 min=0 # observedGe status.conditions[].reason (required) pattern="^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$" min=1 max=1024 # reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. status.conditions[].status (required) enum=True|False|Unknown # status of the condition, one of True, False, Unknown. status.conditions[].type (required) pattern="^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$" max=316 # type of condition in CamelCase or in foo.example.com/CamelCase. +status.exportedInputs # ExportedInputs holds a map of structured data optionally extracted from the source resource. It may be used, for example, by downstream consumers such as templating engines like ResourceSet to consume these inputs for implementing templating logic. diff --git a/.agents/skills/gitops-knowledge/assets/schemas/fluxinstance-fluxcd-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/fluxinstance-fluxcd-v1.fields.txt index bbb35b72f9..abedae5b9a 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/fluxinstance-fluxcd-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/fluxinstance-fluxcd-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux Operator v0.58.1 https://github.com/controlplaneio-fluxcd/flux-operator +# schema source: Flux Operator v0.62.0 https://github.com/controlplaneio-fluxcd/flux-operator apiVersion enum=fluxcd.controlplane.io/v1 kind enum=FluxInstance metadata.name (required) @@ -7,13 +7,15 @@ spec # FluxInstanceSpec defines the desired state of FluxInstance spec.cluster # Cluster holds the specification of the Kubernetes cluster. spec.cluster.domain default="cluster.local" # Domain is the cluster domain used for generating the FQDN of services. Defaults to 'cluster.local'. spec.cluster.multitenant default=false # Multitenant enables the multitenancy lockdown. Defaults to false. -spec.cluster.multitenantWorkloadIdentity default=false # MultitenantWorkloadIdentity enables the multitenancy lockdown for workload identity. Defaults to false. +spec.cluster.multitenantObjectIdentity default=false # MultitenantObjectIdentity enables the multitenancy lockdown for object identity. Defaults to false. +spec.cluster.multitenantWorkloadIdentity default=false # MultitenantWorkloadIdentity is now legacy. Legacy: Use MultitenantObjectIdentity instead. spec.cluster.networkPolicy default=true # NetworkPolicy restricts network access to the current namespace. Defaults to true. -spec.cluster.objectLevelWorkloadIdentity # ObjectLevelWorkloadIdentity enables the feature gate required for object-level workload identity. This feature is only available in Flux v2.6.0 and later. +spec.cluster.objectIdentityRBAC # ObjectIdentityRBAC configures the RBAC required for object identity using Kubernetes service account tokens. Object identity is the new name of the upstream Flux object-level workload identity feature. In Flux v2.6.0 to v2.9.x this enables the ObjectLevelWorkloadIdentity feature gate and leaves the RBAC for creating service account tokens in place. When disabled, the operator removes that RBAC from the Flux controllers' ClusterRole. Starting with Flux v2.10.0, the ObjectLevelWorkloadIdentity feature gate is retired and no longer changes behavior, so the operator no longer passes it to the controllers. Starting with Flux v2.10.0, the RBAC for creating service account tokens is removed from the Flux distribution, and this field controls whether the operator adds it. This feature is only available in Flux v2.6.0 and later. +spec.cluster.objectLevelWorkloadIdentity # ObjectLevelWorkloadIdentity is now legacy. Legacy: Use ObjectIdentityRBAC instead. spec.cluster.size enum=small|medium|large # Size defines the vertical scaling profile of the Flux controllers. The size is used to determine the concurrency and CPU/Memory limits for the Flux controllers. Accepted values are: 'small', 'medium' and 'large'. -spec.cluster.tenantDefaultDecryptionServiceAccount # TenantDefaultDecryptionServiceAccount is the name of the service account to use as default for kustomize-controller SOPS decryption when the multitenant lockdown for workload identity is enabled. Defaults to the 'default' service account from the tenant namespace. -spec.cluster.tenantDefaultKubeConfigServiceAccount # TenantDefaultKubeConfigServiceAccount is the name of the service account to use as default for kustomize-controller and helm-controller remote cluster access via spec.kubeConfig.configMapRef when the multitenant lockdown for workload identity is enabled. Defaults to the 'default' service account from the tenant namespace. -spec.cluster.tenantDefaultServiceAccount # TenantDefaultServiceAccount is the name of the service account to use as default when the multitenant lockdown is enabled, for kustomize-controller and helm-controller. This field will also be used for multitenant workload identity lockdown for source-controller, notification-controller, image-reflector-controller and image-automation-controller. Defaults to the 'default' service account from the tenant namespace. +spec.cluster.tenantDefaultDecryptionServiceAccount # TenantDefaultDecryptionServiceAccount is the name of the service account to use as default for kustomize-controller SOPS decryption when the multitenant lockdown for object identity is enabled. Defaults to the 'default' service account from the tenant namespace. +spec.cluster.tenantDefaultKubeConfigServiceAccount # TenantDefaultKubeConfigServiceAccount is the name of the service account to use as default for kustomize-controller and helm-controller remote cluster access via spec.kubeConfig.configMapRef when the multitenant lockdown for object identity is enabled. Defaults to the 'default' service account from the tenant namespace. +spec.cluster.tenantDefaultServiceAccount # TenantDefaultServiceAccount is the name of the service account to use as default when the multitenant lockdown is enabled, for kustomize-controller and helm-controller. This field will also be used for multitenant object identity lockdown for source-controller, notification-controller, image-reflector-controller and image-automation-controller. Defaults to the 'default' service account from the tenant namespace. spec.cluster.type enum=kubernetes|openshift|aws|azure|gcp default="kubernetes" # Type specifies the distro of the Kubernetes cluster. Defaults to 'kubernetes'. spec.commonMetadata # CommonMetadata specifies the common labels and annotations that are applied to all resources. Any existing label or annotation will be overridden if its key matches a common one. spec.commonMetadata.annotations # Annotations to be added to the object's metadata. @@ -42,6 +44,20 @@ spec.sharding # Sharding holds the specification of the sharding config spec.sharding.key default="sharding.fluxcd.io/key" # Key is the label key used to shard the resources. spec.sharding.shards <[]string> (required) min=1 # Shards is the list of shard names. spec.sharding.storage enum=ephemeral|persistent # Storage defines if the source-controller shards should use an emptyDir or a persistent volume claim for storage. Accepted values are 'ephemeral' or 'persistent', defaults to 'ephemeral'. When set to 'persistent', the '.spec.storage' field must be set. +spec.spiffe # SPIFFE holds the configuration for the SPIFFE integration. When set, the operator configures the Flux controllers to use the SPIFFE Workload API and optionally enables object identity and mTLS between the controllers. The flux-operator pod must also be configured with the same Workload API and, when used, Broker API settings, but does not need the inter-controller flags. +spec.spiffe.brokerAPI # BrokerAPI holds the configuration for the SPIFFE Broker API. When set, enables the object-level SPIFFE features. +spec.spiffe.brokerAPI.endpoint (required) pattern="^[!-~]+$" min=1 max=1024 # Endpoint is the address of the SPIFFE Broker API endpoint, e.g. 'dns:///spiffe-broker.example.com:443'. The flux-operator pod accepts the same --spiffe-broker-endpoint flag as the Flux controllers. For OLM installations, the endpoint can be set with the SPIFFE_BROKER_ENDPOINT environment variable. +spec.spiffe.brokerAPI.ids <[]string> (required) min=1 max=64 # IDs is the list of SPIFFE IDs or SPIFFE ID prefixes authorized for the SPIFFE Broker API endpoint. SPIFFE IDs ending with a slash are treated as prefixes. The flux-operator pod accepts the same repeatable --spiffe-broker-id flag as the Flux controllers. For OLM installations, the IDs can be set with the SPIFFE_BROKER_IDS environment variable as a comma-separated list. +spec.spiffe.mtls # MTLS holds the configuration for mTLS between the Flux controllers. The flux-operator reads the controller SPIFFE IDs from .status.spiffe. +spec.spiffe.mtls.componentIDTemplate (required) pattern="^spiffe://[a-z0-9._-]{1,255}(?:/(?:[a-zA-Z0-9_-]|[.][a-zA-Z0-9_-]|[{]component[}])[a-zA-Z0-9._-]*(?:[{]component[}][a-zA-Z0-9._-]*)*)+(?:/)?$" max=2048 # ComponentIDTemplate is the SPIFFE ID template for the Flux controllers. The '{component}' placeholder is replaced with the name of each installed component. A trailing slash indicates a SPIFFE ID prefix. The flux-operator ID is the SPIFFE ID of the operator's X.509-SVID, or this template with 'flux-operator' when the operator has no Workload API source. The flux-operator ID is always added to notification-controller as an authorized notifier, and to source-controller and source-watcher as an authorized artifact client for the Web UI artifact downloads. For a standalone Web UI, use ExtraArtifactClients and ExtraNotifiers. +spec.spiffe.mtls.enabled (required) # Enabled enables mTLS between the Flux controllers. +spec.spiffe.mtls.extraArtifactClients <[]string> max=64 # ExtraArtifactClients is a list of additional SPIFFE IDs added to source-controller and source-watcher as authorized artifact clients, e.g. the standalone Web UI or the Flux MCP Server. +spec.spiffe.mtls.extraArtifactServers <[]string> max=64 # ExtraArtifactServers is a list of additional SPIFFE IDs added to kustomize-controller, helm-controller and source-watcher as authorized artifact servers, e.g. an external source controller. +spec.spiffe.mtls.extraNotifiers <[]string> max=64 # ExtraNotifiers is a list of additional SPIFFE IDs added to notification-controller as authorized notifiers, e.g. the standalone Web UI or the Flux MCP Server. +spec.spiffe.mtls.receivers <[]string> max=64 # Receivers is the list of SPIFFE IDs of external Ingress or Gateway controllers authorized to send webhook requests to notification-controller. Setting at least one ID makes the receiver accept only SPIFFE mTLS clients. +spec.spiffe.workloadAPI (required) # WorkloadAPI holds the configuration for the SPIFFE Workload API. It is required for enabling any of the SPIFFE features and is used to render the go-spiffe environment variable and the SPIFFE CSI volume. +spec.spiffe.workloadAPI.csiDriver pattern="^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?)*$" min=1 max=63 # CSIDriver is the name of the SPIFFE CSI driver used to mount the Workload API socket into the Flux controller pods. When set, the operator mounts the CSI volume at /spiffe-workload-api and the endpoint must be a unix socket under that path. When omitted, no CSI volume is configured. +spec.spiffe.workloadAPI.endpoint (required) pattern="^(?:unix:(?:///[!$&->@-~]+|/[!$&-.0->@-~][!$&->@-~]*)|tcp://(?:[0-9]{1,3}(?:\\.[0-9]{1,3}){3}|\\[[0-9a-fA-F:.]+\\]):[0-9]{1,5})$" min=1 max=1024 # Endpoint is the address of the SPIFFE Workload API endpoint, in the form 'unix:///', 'unix:/' or 'tcp://:', e.g. 'unix:///spiffe-workload-api/agent.sock'. The flux-operator pod must be configured with the same endpoint through the SPIFFE_ENDPOINT_SOCKET environment variable. spec.storage # Storage holds the specification of the source-controller persistent volume claim. spec.storage.class (required) # Class is the storage class to use for the PVC. spec.storage.size (required) # Size is the size of the PVC. @@ -85,3 +101,8 @@ status.lastArtifactRevision # LastArtifactRevision is the digest of the status.lastAttemptedRevision # LastAttemptedRevision is the version and digest of the distribution config that was last attempted to reconcile. status.lastHandledForceAt # LastHandledForceAt holds the value of the most recent force request value, so a change of the annotation value can be detected. status.lastHandledReconcileAt # LastHandledReconcileAt holds the value of the most recent reconcile request value, so a change of the annotation value can be detected. +status.spiffe # SPIFFE holds the SPIFFE settings of the last applied distribution. +status.spiffe.mtls # MTLS holds the applied mTLS settings. +status.spiffe.mtls.componentIDTemplate # ComponentIDTemplate is the SPIFFE ID template of the Flux controllers. +status.spiffe.mtls.enabled (required) # Enabled is true when the Flux controllers were deployed with mTLS. +status.spiffe.mtls.extraArtifactServers <[]string> # ExtraArtifactServers is the list of additional SPIFFE IDs authorized as artifact servers. diff --git a/.agents/skills/gitops-knowledge/assets/schemas/fluxreport-fluxcd-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/fluxreport-fluxcd-v1.fields.txt index 02e2afb175..71d1348cbf 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/fluxreport-fluxcd-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/fluxreport-fluxcd-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux Operator v0.58.1 https://github.com/controlplaneio-fluxcd/flux-operator +# schema source: Flux Operator v0.62.0 https://github.com/controlplaneio-fluxcd/flux-operator apiVersion enum=fluxcd.controlplane.io/v1 kind enum=FluxReport metadata.name (required) diff --git a/.agents/skills/gitops-knowledge/assets/schemas/gitrepository-source-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/gitrepository-source-v1.fields.txt index 6258cfba93..0ac953dae4 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/gitrepository-source-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/gitrepository-source-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.toolkit.fluxcd.io/v1 kind enum=GitRepository metadata.name (required) @@ -66,4 +66,5 @@ status.observedInclude[].repository.name (required) # Name of the refer status.observedInclude[].toPath # ToPath specifies the path to copy contents to, defaults to the name of the GitRepositoryRef. status.observedRecurseSubmodules # ObservedRecurseSubmodules is the observed resource submodules configuration used to produce the current Artifact. status.observedSparseCheckout <[]string> # ObservedSparseCheckout is the observed list of directories used to produce the current Artifact. +status.sourceVerificationFingerprint # SourceVerificationFingerprint is the fingerprint of the public keys used to verify the signature of the Git object(s) for the current Artifact. It is used to detect changes to the verification policy, such as a key rotation, that require the current revision to be verified again. status.sourceVerificationMode # SourceVerificationMode is the last used verification mode indicating which Git object(s) have been verified. diff --git a/.agents/skills/gitops-knowledge/assets/schemas/helmchart-source-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/helmchart-source-v1.fields.txt index 3996a99426..3af821dbda 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/helmchart-source-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/helmchart-source-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.toolkit.fluxcd.io/v1 kind enum=HelmChart metadata.name (required) diff --git a/.agents/skills/gitops-knowledge/assets/schemas/helmrelease-helm-v2.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/helmrelease-helm-v2.fields.txt index dc5a6ccf13..e22f151f50 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/helmrelease-helm-v2.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/helmrelease-helm-v2.fields.txt @@ -1,29 +1,56 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=helm.toolkit.fluxcd.io/v2 kind enum=HelmRelease metadata.name (required) metadata.namespace (required) spec # HelmReleaseSpec defines the desired state of a Helm release. -spec.chart # Chart defines the template of the v1.HelmChart that should be created for this HelmRelease. +spec.chart # Chart defines the template of the source object that should be created for this HelmRelease. The Kind field determines whether a sourcev1.HelmChart or sourcev1.OCIRepository is created. +spec.chart.kind enum=HelmChart|OCIRepository # Kind is the kind of the source object generated from this template. Valid values: - HelmChart (default): generates a source.toolkit.fluxcd.io/v1 HelmChart from the HelmChartSpec-compatible fields under .spec.chart.spec. In particular, .spec.chart.spec.chart and .spec.chart.spec.sourceRef are required. - OCIRepository: generates a source.toolkit.fluxcd.io/v1 OCIRepository from the OCIRepositorySpec fields under .spec.chart.spec. In particular, .spec.chart.spec.url is required, and .spec.chart.spec.interval defaults to .spec.interval (interval is required in a plain OCIRepository). Use OCIRepository for charts hosted in OCI registries; use HelmChart for HelmRepository, GitRepository or Bucket sources. spec.chart.metadata # ObjectMeta holds the template for metadata like labels and annotations. spec.chart.metadata.annotations # Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ spec.chart.metadata.labels # Map of string keys and values that can be used to organize and categorize (scope and select) objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ -spec.chart.spec (required) # Spec holds the template for the v1.HelmChartSpec for this HelmRelease. -spec.chart.spec.chart (required) min=1 max=2048 # The name or path the Helm chart is available at in the SourceRef. +spec.chart.spec (required) # Spec holds the spec of the object generated for this HelmRelease. +spec.chart.spec.certSecretRef # CertSecretRef can be given the name of a Secret containing either or both of - a PEM-encoded client certificate (`tls.crt`) and private key (`tls.key`); - a PEM-encoded CA certificate (`ca.crt`) and whichever are supplied, will be used for connecting to the registry. The client cert and key are useful if you are authenticating with a certificate; the CA cert is useful if you are using a self-signed server certificate. The Secret must be of type `Opaque` or `kubernetes.io/tls`. +spec.chart.spec.certSecretRef.name (required) # Name of the referent. +spec.chart.spec.chart min=1 max=2048 # The name or path the Helm chart is available at in the SourceRef. +spec.chart.spec.ignore # Ignore overrides the set of excluded patterns in the .sourceignore format (which is the same as .gitignore). If not provided, a default will be used, consult the documentation for your version to find out what those are. spec.chart.spec.ignoreMissingValuesFiles # IgnoreMissingValuesFiles controls whether to silently ignore missing values files rather than failing. -spec.chart.spec.interval pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Interval at which to check the v1.Source for updates. Defaults to 'HelmReleaseSpec.Interval'. -spec.chart.spec.reconcileStrategy enum=ChartVersion|Revision default="ChartVersion" # Determines what enables the creation of a new artifact. Valid values are ('ChartVersion', 'Revision'). See the documentation of the values for an explanation on their behavior. Defaults to ChartVersion when omitted. -spec.chart.spec.sourceRef (required) # The name and namespace of the v1.Source the chart is available at. +spec.chart.spec.insecure # Insecure allows connecting to a non-TLS HTTP container registry. +spec.chart.spec.interval pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Interval at which the OCIRepository URL is checked for updates. This interval is approximate and may be subject to jitter to ensure efficient use of resources. +spec.chart.spec.layerSelector # LayerSelector specifies which layer should be extracted from the OCI artifact. When not specified, the first layer found in the artifact is selected. +spec.chart.spec.layerSelector.mediaType # MediaType specifies the OCI media type of the layer which should be extracted from the OCI Artifact. The first layer matching this type is selected. +spec.chart.spec.layerSelector.operation enum=extract|copy # Operation specifies how the selected layer should be processed. By default, the layer compressed content is extracted to storage. When the operation is set to 'copy', the layer compressed content is persisted to storage as it is. +spec.chart.spec.provider enum=generic|aws|azure|gcp # The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. When not specified, defaults to 'generic'. +spec.chart.spec.proxySecretRef # ProxySecretRef specifies the Secret containing the proxy configuration to use while communicating with the container registry. +spec.chart.spec.proxySecretRef.name (required) # Name of the referent. +spec.chart.spec.reconcileStrategy enum=ChartVersion|Revision # Determines what enables the creation of a new artifact. Valid values are ('ChartVersion', 'Revision'). See the documentation of the values for an explanation on their behavior. Defaults to ChartVersion when omitted. +spec.chart.spec.ref # The OCI reference to pull and monitor for changes, defaults to the latest tag. +spec.chart.spec.ref.digest # Digest is the image digest to pull, takes precedence over SemVer. The value should be in the format 'sha256:'. +spec.chart.spec.ref.semver # SemVer is the range of tags to pull selecting the latest within the range, takes precedence over Tag. +spec.chart.spec.ref.semverFilter # SemverFilter is a regex pattern to filter the tags within the SemVer range. +spec.chart.spec.ref.tag # Tag is the image tag to pull, defaults to latest. +spec.chart.spec.secretRef # SecretRef contains the secret name containing the registry login credentials to resolve image metadata. The secret must be of type kubernetes.io/dockerconfigjson. +spec.chart.spec.secretRef.name (required) # Name of the referent. +spec.chart.spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the image pull, either with the pull secrets attached to the service account or with an object identity. For more information about object identity: https://fluxcd.io/flux/integrations/object-identity/ For more information about image pull secrets: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account +spec.chart.spec.sourceRef # The name and namespace of the v1.Source the chart is available at. spec.chart.spec.sourceRef.apiVersion # APIVersion of the referent. spec.chart.spec.sourceRef.kind (required) enum=HelmRepository|GitRepository|Bucket # Kind of the referent. spec.chart.spec.sourceRef.name (required) min=1 max=253 # Name of the referent. spec.chart.spec.sourceRef.namespace min=1 max=63 # Namespace of the referent. +spec.chart.spec.suspend # This flag tells the controller to suspend the reconciliation of this source. +spec.chart.spec.timeout pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" # The timeout for remote OCI Repository operations like pulling, defaults to 60s. +spec.chart.spec.url pattern="^oci://.*$" # URL is a reference to an OCI artifact repository hosted on a remote container registry. spec.chart.spec.valuesFiles <[]string> # Alternative list of values files to use as the chart values (values.yaml is not included by default), expected to be a relative path in the SourceRef. Values files are merged in the order of this list with the last file overriding the first. Ignored when omitted. -spec.chart.spec.verify # Verify contains the secret name containing the trusted public keys used to verify the signature and specifies which provider to use to check whether OCI image is authentic. This field is only supported for OCI sources. Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified. -spec.chart.spec.verify.provider (required) enum=cosign|notation default="cosign" # Provider specifies the technology used to sign the OCI Helm chart. +spec.chart.spec.verify # Verify contains the secret name containing the trusted public keys used to verify the signature and specifies which provider to use to check whether OCI image is authentic. +spec.chart.spec.verify.matchOIDCIdentity <[]object> # MatchOIDCIdentity specifies the identity matching criteria to use while verifying an OCI artifact which was signed using Cosign keyless signing. The artifact's identity is deemed to be verified if any of the specified matchers match against the identity. +spec.chart.spec.verify.matchOIDCIdentity[].issuer (required) # Issuer specifies the regex pattern to match against to verify the OIDC issuer in the Fulcio certificate. The pattern must be a valid Go regular expression. +spec.chart.spec.verify.matchOIDCIdentity[].subject (required) # Subject specifies the regex pattern to match against to verify the identity subject in the Fulcio certificate. The pattern must be a valid Go regular expression. +spec.chart.spec.verify.provider (required) enum=cosign|notation default="cosign" # Provider specifies the technology used to sign the OCI Artifact. spec.chart.spec.verify.secretRef # SecretRef specifies the Kubernetes Secret containing the trusted public keys. spec.chart.spec.verify.secretRef.name (required) # Name of the referent. -spec.chart.spec.version default="*" # Version semver expression, ignored for charts from v1.GitRepository and v1beta2.Bucket sources. Defaults to latest when omitted. +spec.chart.spec.verify.trustedRootSecretRef # TrustedRootSecretRef specifies the Kubernetes Secret containing a Sigstore trusted_root.json file. This enables verification against self-hosted Sigstore infrastructure (custom Fulcio CA, self-hosted Rekor instance). The Secret must contain a key named "trusted_root.json". +spec.chart.spec.verify.trustedRootSecretRef.name (required) # Name of the referent. +spec.chart.spec.version # Version semver expression, ignored for charts from v1.GitRepository and v1beta2.Bucket sources. Defaults to latest when omitted i.e. to '*'. spec.chartRef # ChartRef holds a reference to a source controller resource containing the Helm chart artifact. spec.chartRef.apiVersion # APIVersion of the referent. spec.chartRef.kind (required) enum=OCIRepository|HelmChart|ExternalArtifact # Kind of the referent. @@ -75,8 +102,8 @@ spec.install.strategy.name (required) enum=RemediateOnFailure|RetryOnFa spec.install.strategy.retryInterval pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # RetryInterval is the interval at which to retry a failed install. Can be used only when Name is set to RetryOnFailure. Defaults to '5m'. spec.install.timeout pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Timeout is the time to wait for any individual Kubernetes operation (like Jobs for hooks) during the performance of a Helm install action. Defaults to 'HelmReleaseSpec.Timeout'. spec.interval (required) pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Interval at which to reconcile the Helm release. -spec.kubeConfig # KubeConfig for reconciling the HelmRelease on a remote cluster. When used in combination with HelmReleaseSpec.ServiceAccountName, forces the controller to act on behalf of that Service Account at the target cluster. If the --default-service-account flag is set, its value will be used as a controller level fallback for when HelmReleaseSpec.ServiceAccountName is empty. -spec.kubeConfig.configMapRef # ConfigMapRef holds an optional name of a ConfigMap that contains the following keys: - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or `generic`. Required. - `cluster`: the fully qualified resource name of the Kubernetes cluster in the cloud provider API. Not used by the `generic` provider. Required when one of `address` or `ca.crt` is not set. - `address`: the address of the Kubernetes API server. Required for `generic`. For the other providers, if not specified, the first address in the cluster resource will be used, and if specified, it must match one of the addresses in the cluster resource. If audiences is not set, will be used as the audience for the `generic` provider. - `ca.crt`: the optional PEM-encoded CA certificate for the Kubernetes API server. If not set, the controller will use the CA certificate from the cluster resource. - `audiences`: the optional audiences as a list of line-break-separated strings for the Kubernetes ServiceAccount token. Defaults to the `address` for the `generic` provider, or to specific values for the other providers depending on the provider. - `serviceAccountName`: the optional name of the Kubernetes ServiceAccount in the same namespace that should be used for authentication. If not specified, the controller ServiceAccount will be used. Mutually exclusive with SecretRef. +spec.kubeConfig # KubeConfig for reconciling the HelmRelease on a remote cluster. When used in combination with HelmReleaseSpec.ServiceAccountName, forces the controller to act on behalf of that Service Account at the target cluster. If the --default-service-account flag is set, its value will be used as the default for HelmReleaseSpec.ServiceAccountName when it is empty. +spec.kubeConfig.configMapRef # ConfigMapRef holds an optional name of a ConfigMap that contains the following keys: - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or `generic`. Required. - `cluster`: the fully qualified resource name of the Kubernetes cluster in the cloud provider API. Not used by the `generic` provider. Required when one of `address` or `ca.crt` is not set. - `address`: the address of the Kubernetes API server. Required for `generic`. For the other providers, if not specified, the first address in the cluster resource will be used, and if specified, it must match one of the addresses in the cluster resource. If audiences is not set, will be used as the audience for the `generic` provider. - `ca.crt`: the optional PEM-encoded CA certificate for the Kubernetes API server. If not set, the controller will use the CA certificate from the cluster resource. - `serviceAccountName`: the optional name of the Kubernetes ServiceAccount in the same namespace that should be used for authentication. If not specified, the controller ServiceAccount will be used. - `audiences`: the optional audiences as a list of string separated by commas and/or whitespaces/newlines for the Kubernetes ServiceAccount token. Defaults to the `address` for the `generic` provider, or to specific values for the other providers depending on the provider. Mutually exclusive with SecretRef. spec.kubeConfig.configMapRef.name (required) # Name of the referent. spec.kubeConfig.secretRef # SecretRef holds an optional name of a secret that contains a key with the kubeconfig file as the value. If no key is set, the key will default to 'value'. Mutually exclusive with ConfigMapRef. It is recommended that the kubeconfig is self-contained, and the secret is regularly updated if credentials such as a cloud-access-token expire. Cloud specific `cmd-path` auth helpers will not function without adding binaries and credentials to the Pod that is responsible for reconciling Kubernetes resources. Supported only for the generic provider. spec.kubeConfig.secretRef.key # Key in the Secret, when not specified an implementation-specific default key is used. @@ -170,7 +197,7 @@ status.conditions[].reason (required) pattern="^[A-Za-z]([A-Za-z0-9_,:] status.conditions[].status (required) enum=True|False|Unknown # status of the condition, one of True, False, Unknown. status.conditions[].type (required) pattern="^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$" max=316 # type of condition in CamelCase or in foo.example.com/CamelCase. status.failures format=int64 # Failures is the reconciliation failure count against the latest desired state. It is reset after a successful reconciliation. -status.helmChart # HelmChart is the namespaced name of the HelmChart resource created by the controller for the HelmRelease. +status.helmChart # HelmChart is the namespaced name of the HelmChart resource created by the controller for the HelmRelease, in the format '/', or the typed and namespaced name of the OCIRepository resource, in the format '//'. status.history <[]object> # History holds the history of Helm releases performed for this HelmRelease up to the last successfully completed release. status.history[].action # Action is the action that resulted in this snapshot being created. status.history[].apiVersion # APIVersion is the API version of the Snapshot. When the calculation method of the Digest field is changed, this field will be used to distinguish between the old and new methods. diff --git a/.agents/skills/gitops-knowledge/assets/schemas/helmrepository-source-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/helmrepository-source-v1.fields.txt index 5d226215a2..2bb7c9c93d 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/helmrepository-source-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/helmrepository-source-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.toolkit.fluxcd.io/v1 kind enum=HelmRepository metadata.name (required) diff --git a/.agents/skills/gitops-knowledge/assets/schemas/imagepolicy-image-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/imagepolicy-image-v1.fields.txt index 0e3de7db0b..b95b122f13 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/imagepolicy-image-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/imagepolicy-image-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=image.toolkit.fluxcd.io/v1 kind enum=ImagePolicy metadata.name (required) diff --git a/.agents/skills/gitops-knowledge/assets/schemas/imagerepository-image-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/imagerepository-image-v1.fields.txt index 58faf50750..3dc106e760 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/imagerepository-image-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/imagerepository-image-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=image.toolkit.fluxcd.io/v1 kind enum=ImageRepository metadata.name (required) @@ -18,7 +18,7 @@ spec.proxySecretRef # ProxySecretRef specifies the Secret containing th spec.proxySecretRef.name (required) # Name of the referent. spec.secretRef # SecretRef can be given the name of a secret containing credentials to use for the image registry. The secret should be created with `kubectl create secret docker-registry`, or the equivalent. spec.secretRef.name (required) # Name of the referent. -spec.serviceAccountName max=253 # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the image pull if the service account has attached pull secrets. +spec.serviceAccountName max=253 # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the image pull, either with the pull secrets attached to the service account or with an object identity. For more information about object identity: https://fluxcd.io/flux/integrations/object-identity/ spec.suspend # This flag tells the controller to suspend subsequent image scans. It does not apply to already started scans. Defaults to false. spec.timeout pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" # Timeout for image scanning. Defaults to 'Interval' duration. status default={"observedGeneration":-1} # ImageRepositoryStatus defines the observed state of ImageRepository diff --git a/.agents/skills/gitops-knowledge/assets/schemas/imageupdateautomation-image-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/imageupdateautomation-image-v1.fields.txt index 8ecadb202c..5a3798045a 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/imageupdateautomation-image-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/imageupdateautomation-image-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=image.toolkit.fluxcd.io/v1 kind enum=ImageUpdateAutomation metadata.name (required) @@ -27,6 +27,7 @@ spec.git.push.branch # Branch specifies that commits should be pushed t spec.git.push.options # Options specifies the push options that are sent to the Git server when performing a push operation. For details, see: https://git-scm.com/docs/git-push#Documentation/git-push.txt---push-optionltoptiongt spec.git.push.refspec pattern="^$|^[^+:]" # Refspec specifies the Git Refspec to use for a push operation. If both Branch and Refspec are provided, then the commit is pushed to the branch and also using the specified refspec. Deletion refspecs and refspecs prefixed with '+' are not supported. For more details about Git Refspecs, see: https://git-scm.com/book/en/v2/Git-Internals-The-Refspec spec.interval (required) pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Interval gives an lower bound for how often the automation run should be attempted. +spec.policyChangeDelay pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # PolicyChangeDelay delays the run triggered by ImagePolicy changes, so that image updates arriving within the delay are committed together. If PolicySelector is also set, only changes to the selected policies trigger a run. By default, the automation runs as soon as a policy changes. spec.policySelector # PolicySelector allows to filter applied policies based on labels. By default includes all policies in namespace. spec.policySelector.matchExpressions <[]object> # matchExpressions is a list of label selector requirements. The requirements are ANDed. spec.policySelector.matchExpressions[].key (required) # key is the label key that the selector applies to. diff --git a/.agents/skills/gitops-knowledge/assets/schemas/kustomization-kustomize-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/kustomization-kustomize-v1.fields.txt index 4cd60c6c65..d9d2eb8d9d 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/kustomization-kustomize-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/kustomization-kustomize-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=kustomize.toolkit.fluxcd.io/v1 kind enum=Kustomization metadata.name (required) @@ -48,8 +48,8 @@ spec.images[].name (required) # Name is a tag-less image name. spec.images[].newName # NewName is the value used to replace the original name. spec.images[].newTag # NewTag is the value used to replace the original tag. spec.interval (required) pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # The interval at which to reconcile the Kustomization. This interval is approximate and may be subject to jitter to ensure efficient use of resources. -spec.kubeConfig # The KubeConfig for reconciling the Kustomization on a remote cluster. When used in combination with KustomizationSpec.ServiceAccountName, forces the controller to act on behalf of that Service Account at the target cluster. If the --default-service-account flag is set, its value will be used as a controller level fallback for when KustomizationSpec.ServiceAccountName is empty. -spec.kubeConfig.configMapRef # ConfigMapRef holds an optional name of a ConfigMap that contains the following keys: - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or `generic`. Required. - `cluster`: the fully qualified resource name of the Kubernetes cluster in the cloud provider API. Not used by the `generic` provider. Required when one of `address` or `ca.crt` is not set. - `address`: the address of the Kubernetes API server. Required for `generic`. For the other providers, if not specified, the first address in the cluster resource will be used, and if specified, it must match one of the addresses in the cluster resource. If audiences is not set, will be used as the audience for the `generic` provider. - `ca.crt`: the optional PEM-encoded CA certificate for the Kubernetes API server. If not set, the controller will use the CA certificate from the cluster resource. - `audiences`: the optional audiences as a list of line-break-separated strings for the Kubernetes ServiceAccount token. Defaults to the `address` for the `generic` provider, or to specific values for the other providers depending on the provider. - `serviceAccountName`: the optional name of the Kubernetes ServiceAccount in the same namespace that should be used for authentication. If not specified, the controller ServiceAccount will be used. Mutually exclusive with SecretRef. +spec.kubeConfig # The KubeConfig for reconciling the Kustomization on a remote cluster. When used in combination with KustomizationSpec.ServiceAccountName, forces the controller to act on behalf of that Service Account at the target cluster. If the --default-service-account flag is set, its value will be used as the default for KustomizationSpec.ServiceAccountName when it is empty. +spec.kubeConfig.configMapRef # ConfigMapRef holds an optional name of a ConfigMap that contains the following keys: - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or `generic`. Required. - `cluster`: the fully qualified resource name of the Kubernetes cluster in the cloud provider API. Not used by the `generic` provider. Required when one of `address` or `ca.crt` is not set. - `address`: the address of the Kubernetes API server. Required for `generic`. For the other providers, if not specified, the first address in the cluster resource will be used, and if specified, it must match one of the addresses in the cluster resource. If audiences is not set, will be used as the audience for the `generic` provider. - `ca.crt`: the optional PEM-encoded CA certificate for the Kubernetes API server. If not set, the controller will use the CA certificate from the cluster resource. - `serviceAccountName`: the optional name of the Kubernetes ServiceAccount in the same namespace that should be used for authentication. If not specified, the controller ServiceAccount will be used. - `audiences`: the optional audiences as a list of string separated by commas and/or whitespaces/newlines for the Kubernetes ServiceAccount token. Defaults to the `address` for the `generic` provider, or to specific values for the other providers depending on the provider. Mutually exclusive with SecretRef. spec.kubeConfig.configMapRef.name (required) # Name of the referent. spec.kubeConfig.secretRef # SecretRef holds an optional name of a secret that contains a key with the kubeconfig file as the value. If no key is set, the key will default to 'value'. Mutually exclusive with ConfigMapRef. It is recommended that the kubeconfig is self-contained, and the secret is regularly updated if credentials such as a cloud-access-token expire. Cloud specific `cmd-path` auth helpers will not function without adding binaries and credentials to the Pod that is responsible for reconciling Kubernetes resources. Supported only for the generic provider. spec.kubeConfig.secretRef.key # Key in the Secret, when not specified an implementation-specific default key is used. diff --git a/.agents/skills/gitops-knowledge/assets/schemas/ocirepository-source-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/ocirepository-source-v1.fields.txt index 0a58bcd8c0..ea3bbc6ed3 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/ocirepository-source-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/ocirepository-source-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=source.toolkit.fluxcd.io/v1 kind enum=OCIRepository metadata.name (required) @@ -8,11 +8,11 @@ spec.certSecretRef # CertSecretRef can be given the name of a Secret co spec.certSecretRef.name (required) # Name of the referent. spec.ignore # Ignore overrides the set of excluded patterns in the .sourceignore format (which is the same as .gitignore). If not provided, a default will be used, consult the documentation for your version to find out what those are. spec.insecure # Insecure allows connecting to a non-TLS HTTP container registry. -spec.interval (required) pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Interval at which the OCIRepository URL is checked for updates. This interval is approximate and may be subject to jitter to ensure efficient use of resources. +spec.interval pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$" # Interval at which the OCIRepository URL is checked for updates. This interval is approximate and may be subject to jitter to ensure efficient use of resources. spec.layerSelector # LayerSelector specifies which layer should be extracted from the OCI artifact. When not specified, the first layer found in the artifact is selected. spec.layerSelector.mediaType # MediaType specifies the OCI media type of the layer which should be extracted from the OCI Artifact. The first layer matching this type is selected. spec.layerSelector.operation enum=extract|copy # Operation specifies how the selected layer should be processed. By default, the layer compressed content is extracted to storage. When the operation is set to 'copy', the layer compressed content is persisted to storage as it is. -spec.provider enum=generic|aws|azure|gcp default="generic" # The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. When not specified, defaults to 'generic'. +spec.provider enum=generic|aws|azure|gcp # The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. When not specified, defaults to 'generic'. spec.proxySecretRef # ProxySecretRef specifies the Secret containing the proxy configuration to use while communicating with the container registry. spec.proxySecretRef.name (required) # Name of the referent. spec.ref # The OCI reference to pull and monitor for changes, defaults to the latest tag. @@ -22,10 +22,10 @@ spec.ref.semverFilter # SemverFilter is a regex pattern to filter the t spec.ref.tag # Tag is the image tag to pull, defaults to latest. spec.secretRef # SecretRef contains the secret name containing the registry login credentials to resolve image metadata. The secret must be of type kubernetes.io/dockerconfigjson. spec.secretRef.name (required) # Name of the referent. -spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the image pull if the service account has attached pull secrets. For more information: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account +spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate the image pull, either with the pull secrets attached to the service account or with an object identity. For more information about object identity: https://fluxcd.io/flux/integrations/object-identity/ For more information about image pull secrets: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account spec.suspend # This flag tells the controller to suspend the reconciliation of this source. -spec.timeout default="60s" pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" # The timeout for remote OCI Repository operations like pulling, defaults to 60s. -spec.url (required) pattern="^oci://.*$" # URL is a reference to an OCI artifact repository hosted on a remote container registry. +spec.timeout pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" # The timeout for remote OCI Repository operations like pulling, defaults to 60s. +spec.url pattern="^oci://.*$" # URL is a reference to an OCI artifact repository hosted on a remote container registry. spec.verify # Verify contains the secret name containing the trusted public keys used to verify the signature and specifies which provider to use to check whether OCI image is authentic. spec.verify.matchOIDCIdentity <[]object> # MatchOIDCIdentity specifies the identity matching criteria to use while verifying an OCI artifact which was signed using Cosign keyless signing. The artifact's identity is deemed to be verified if any of the specified matchers match against the identity. spec.verify.matchOIDCIdentity[].issuer (required) # Issuer specifies the regex pattern to match against to verify the OIDC issuer in the Fulcio certificate. The pattern must be a valid Go regular expression. @@ -57,4 +57,5 @@ status.observedIgnore # ObservedIgnore is the observed exclusion patter status.observedLayerSelector # ObservedLayerSelector is the observed layer selector used for constructing the source artifact. status.observedLayerSelector.mediaType # MediaType specifies the OCI media type of the layer which should be extracted from the OCI Artifact. The first layer matching this type is selected. status.observedLayerSelector.operation enum=extract|copy # Operation specifies how the selected layer should be processed. By default, the layer compressed content is extracted to storage. When the operation is set to 'copy', the layer compressed content is persisted to storage as it is. +status.sourceVerificationFingerprint # SourceVerificationFingerprint is the fingerprint of the verification material used to verify the signature of the current Artifact. It is used to detect changes to the verification policy, such as a key rotation, that require the current revision to be verified again. status.url # URL is the download link for the artifact output of the last OCI Repository sync. diff --git a/.agents/skills/gitops-knowledge/assets/schemas/provider-notification-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/provider-notification-v1.fields.txt new file mode 100644 index 0000000000..562a162e80 --- /dev/null +++ b/.agents/skills/gitops-knowledge/assets/schemas/provider-notification-v1.fields.txt @@ -0,0 +1,20 @@ +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 +apiVersion enum=notification.toolkit.fluxcd.io/v1 +kind enum=Provider +metadata.name (required) +metadata.namespace (required) +spec # ProviderSpec defines the desired state of the Provider. +spec.address max=2048 # Address specifies the endpoint, in a generic sense, to where alerts are sent. What kind of endpoint depends on the specific Provider type being used. For the generic Provider, for example, this is an HTTP/S address. For other Provider types this could be a project ID or a namespace. +spec.certSecretRef # CertSecretRef specifies the Secret containing TLS certificates for secure communication. Supported configurations: - CA-only: Server authentication (provide ca.crt only) - mTLS: Mutual authentication (provide ca.crt + tls.crt + tls.key) - Client-only: Client authentication with system CA (provide tls.crt + tls.key only) Legacy keys "caFile", "certFile", "keyFile" are supported but deprecated. Use "ca.crt", "tls.crt", "tls.key" instead. +spec.certSecretRef.name (required) # Name of the referent. +spec.channel max=2048 # Channel specifies the destination channel where events should be posted. +spec.commitStatusExpr # CommitStatusExpr is a CEL expression that evaluates to a string value that can be used to generate a custom commit status message for use with eligible Provider types (github, gitlab, gitea, bitbucketserver, bitbucket, azuredevops). Supported variables are: event, provider, and alert. +spec.proxySecretRef # ProxySecretRef specifies the Secret containing the proxy configuration for this Provider. The Secret should contain an 'address' key with the HTTP/S address of the proxy server. Optional 'username' and 'password' keys can be provided for proxy authentication. +spec.proxySecretRef.name (required) # Name of the referent. +spec.secretRef # SecretRef specifies the Secret containing the authentication credentials for this Provider. +spec.secretRef.name (required) # Name of the referent. +spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate with cloud provider services through object identity. This enables multi-tenant authentication without storing static credentials. Supported provider types: azureeventhub, azuredevops, googlepubsub When specified, the controller will: 1. Create an OIDC token for the specified ServiceAccount 2. Exchange it for cloud provider credentials via STS 3. Use the obtained credentials for API authentication When unspecified, the controller's workload identity is used (single-tenant). An error is thrown if static credentials are also defined in SecretRef. +spec.suspend # Suspend tells the controller to suspend subsequent events handling for this Provider. +spec.timeout pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" # Timeout for sending alerts to the Provider. +spec.type (required) enum=slack|discord|msteams|rocket|generic|generic-hmac|github|gitlab|gitea|giteapullrequestcomment|bitbucketserver|bitbucket|azuredevops|googlechat|googlepubsub|webex|sentry|azureeventhub|telegram|lark|matrix|opsgenie|alertmanager|grafana|githubdispatch|githubpullrequestcomment|gitlabmergerequestcomment|pagerduty|datadog|nats|zulip|otel|zoom|incident.io|mastodon # Type specifies which Provider implementation to use. +spec.username max=2048 # Username specifies the name under which events are posted. diff --git a/.agents/skills/gitops-knowledge/assets/schemas/provider-notification-v1beta3.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/provider-notification-v1beta3.fields.txt index 2b31bc4621..5f55c15674 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/provider-notification-v1beta3.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/provider-notification-v1beta3.fields.txt @@ -1,5 +1,5 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 -apiVersion enum=notification.toolkit.fluxcd.io/v1beta3 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 +apiVersion enum=notification.toolkit.fluxcd.io/v1beta3 (deprecated) # v1beta3 Provider is deprecated, upgrade to v1 kind enum=Provider metadata.name (required) metadata.namespace (required) @@ -15,8 +15,8 @@ spec.proxySecretRef # ProxySecretRef specifies the Secret containing th spec.proxySecretRef.name (required) # Name of the referent. spec.secretRef # SecretRef specifies the Secret containing the authentication credentials for this Provider. spec.secretRef.name (required) # Name of the referent. -spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate with cloud provider services through workload identity. This enables multi-tenant authentication without storing static credentials. Supported provider types: azureeventhub, azuredevops, googlepubsub When specified, the controller will: 1. Create an OIDC token for the specified ServiceAccount 2. Exchange it for cloud provider credentials via STS 3. Use the obtained credentials for API authentication When unspecified, controller-level authentication is used (single-tenant). An error is thrown if static credentials are also defined in SecretRef. This field requires the ObjectLevelWorkloadIdentity feature gate to be enabled. +spec.serviceAccountName # ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate with cloud provider services through workload identity. This enables multi-tenant authentication without storing static credentials. Supported provider types: azureeventhub, azuredevops, googlepubsub When specified, the controller will: 1. Create an OIDC token for the specified ServiceAccount 2. Exchange it for cloud provider credentials via STS 3. Use the obtained credentials for API authentication When unspecified, controller-level authentication is used (single-tenant). An error is thrown if static credentials are also defined in SecretRef. spec.suspend # Suspend tells the controller to suspend subsequent events handling for this Provider. spec.timeout pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$" # Timeout for sending alerts to the Provider. -spec.type (required) enum=slack|discord|msteams|rocket|generic|generic-hmac|github|gitlab|gitea|giteapullrequestcomment|bitbucketserver|bitbucket|azuredevops|googlechat|googlepubsub|webex|sentry|azureeventhub|telegram|lark|matrix|opsgenie|alertmanager|grafana|githubdispatch|githubpullrequestcomment|gitlabmergerequestcomment|pagerduty|datadog|nats|zulip|otel # Type specifies which Provider implementation to use. +spec.type (required) enum=slack|discord|msteams|rocket|generic|generic-hmac|github|gitlab|gitea|giteapullrequestcomment|bitbucketserver|bitbucket|azuredevops|googlechat|googlepubsub|webex|sentry|azureeventhub|telegram|lark|matrix|opsgenie|alertmanager|grafana|githubdispatch|githubpullrequestcomment|gitlabmergerequestcomment|pagerduty|datadog|nats|zulip|otel|zoom|incident.io # Type specifies which Provider implementation to use. spec.username max=2048 # Username specifies the name under which events are posted. diff --git a/.agents/skills/gitops-knowledge/assets/schemas/receiver-notification-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/receiver-notification-v1.fields.txt index 65b28bd4d6..fb381503e5 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/receiver-notification-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/receiver-notification-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux v2.9.4 https://github.com/fluxcd/flux2 +# schema source: Flux v2.10.0 https://github.com/fluxcd/flux2 apiVersion enum=notification.toolkit.fluxcd.io/v1 kind enum=Receiver metadata.name (required) diff --git a/.agents/skills/gitops-knowledge/assets/schemas/resourceset-fluxcd-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/resourceset-fluxcd-v1.fields.txt index ab0cf5172f..ec45be7f0c 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/resourceset-fluxcd-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/resourceset-fluxcd-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux Operator v0.58.1 https://github.com/controlplaneio-fluxcd/flux-operator +# schema source: Flux Operator v0.62.0 https://github.com/controlplaneio-fluxcd/flux-operator apiVersion enum=fluxcd.controlplane.io/v1 kind enum=ResourceSet metadata.name (required) diff --git a/.agents/skills/gitops-knowledge/assets/schemas/resourcesetinputprovider-fluxcd-v1.fields.txt b/.agents/skills/gitops-knowledge/assets/schemas/resourcesetinputprovider-fluxcd-v1.fields.txt index edd3e0fd43..8c9b7f1749 100644 --- a/.agents/skills/gitops-knowledge/assets/schemas/resourcesetinputprovider-fluxcd-v1.fields.txt +++ b/.agents/skills/gitops-knowledge/assets/schemas/resourcesetinputprovider-fluxcd-v1.fields.txt @@ -1,4 +1,4 @@ -# schema source: Flux Operator v0.58.1 https://github.com/controlplaneio-fluxcd/flux-operator +# schema source: Flux Operator v0.62.0 https://github.com/controlplaneio-fluxcd/flux-operator apiVersion enum=fluxcd.controlplane.io/v1 kind enum=ResourceSetInputProvider metadata.name (required) @@ -32,7 +32,7 @@ spec.selectors[].matchExpressions[].values <[]string> # values is an array of st spec.selectors[].matchLabels # matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. spec.selectors[].name # Name selects a single ExternalArtifact by metadata.name. This field is mutually exclusive with matchLabels and matchExpressions. spec.selectors[].namespace # Namespace scopes ExternalArtifact discovery. When empty, ExternalArtifacts are listed in the ResourceSetInputProvider namespace. When set to "*", ExternalArtifacts are listed across all namespaces by omitting the namespace option from List(). Otherwise, ExternalArtifacts are listed only in the specified namespace. -spec.serviceAccountName # ServiceAccountName specifies the name of the Kubernetes ServiceAccount used for authentication with AWS, Azure or GCP services through workload identity federation features. If not specified, the authentication for these cloud providers will use the ServiceAccount of the operator (or any other environment authentication configuration). +spec.serviceAccountName # ServiceAccountName specifies the name of the Kubernetes ServiceAccount used for authentication with external services using object identity. If not specified, the default object identity ServiceAccount configured with the --default-object-identity-service-account flag or the DEFAULT_OBJECT_IDENTITY_SERVICE_ACCOUNT environment variable is used. This field can also be set for the ExternalArtifact type, where it is used only for impersonation and its annotations are ignored. For a complete guide to the ServiceAccount annotations used for object identity, including the spiffe credential provider, see: https://fluxcd.io/flux/integrations/object-identity/ spec.skip # Skip defines whether we need to skip input provider response updates. spec.skip.labels <[]string> # Labels specifies list of labels to skip input provider response when any of the label conditions matched. When prefixed with !, input provider response will be skipped if it does not have this label. spec.type (required) enum=Static|GitHubBranch|GitHubTag|GitHubPullRequest|GitLabBranch|GitLabTag|GitLabMergeRequest|GitLabEnvironment|AzureDevOpsBranch|AzureDevOpsTag|AzureDevOpsPullRequest|AWSCodeCommitBranch|AWSCodeCommitTag|AWSCodeCommitPullRequest|GiteaBranch|GiteaTag|GiteaPullRequest|OCIArtifactTag|ACRArtifactTag|ECRArtifactTag|GARArtifactTag|ExternalService|ExternalArtifact # Type specifies the type of the input provider. diff --git a/.agents/skills/gitops-knowledge/evals/evals.json b/.agents/skills/gitops-knowledge/evals/evals.json index 12ed8643c1..8607072f5e 100644 --- a/.agents/skills/gitops-knowledge/evals/evals.json +++ b/.agents/skills/gitops-knowledge/evals/evals.json @@ -46,11 +46,11 @@ { "id": 3, "prompt": "Set up Flux notifications for our production cluster. I need: (1) Slack alerts for all errors across all Kustomizations and HelmReleases, (2) GitHub commit status updates on our repo https://github.com/acme-corp/infra for the 'infra' Kustomization so we can see deploy status on commits, (3) a GitHub webhook Receiver that triggers immediate reconciliation of the 'infra' Kustomization on push events. Give me the Provider, Alert, Receiver, and Secret manifests for all three.", - "expected_output": "Two Providers (one Slack type, one GitHub type), two Alerts using notification.toolkit.fluxcd.io/v1beta3, and a Receiver using notification.toolkit.fluxcd.io/v1. Slack provider uses secretRef for webhook URL. GitHub provider uses address field for repo URL. Receiver type is 'github' with a secretRef for webhook validation.", + "expected_output": "Two Providers (one Slack type, one GitHub type), two Alerts, all using notification.toolkit.fluxcd.io/v1, and a Receiver using notification.toolkit.fluxcd.io/v1. Slack provider uses secretRef for webhook URL. GitHub provider uses address field for repo URL. Receiver type is 'github' with a secretRef for webhook validation.", "files": [], "expectations": [ - "All Provider resources use apiVersion notification.toolkit.fluxcd.io/v1beta3 (not v1 or v1beta2)", - "All Alert resources use apiVersion notification.toolkit.fluxcd.io/v1beta3 (not v1 or v1beta2)", + "All Provider resources use apiVersion notification.toolkit.fluxcd.io/v1 (not the deprecated v1beta3 or v1beta2)", + "All Alert resources use apiVersion notification.toolkit.fluxcd.io/v1 (not the deprecated v1beta3 or v1beta2)", "The Slack Provider spec.type is 'slack' (not 'Slack')", "The Slack Provider has a secretRef pointing to a Secret", "The Slack Secret has a 'token' key in stringData for the bot token", @@ -155,10 +155,10 @@ "expected_output": "An OCIRepository (source.toolkit.fluxcd.io/v1) for the chart with layerSelector for the Helm media type and verify.provider cosign plus verify.trustedRootSecretRef pointing at 'sigstore-trusted-root'. A HelmRelease (helm.toolkit.fluxcd.io/v2) using chartRef, waitStrategy.name 'poller', postRenderStrategy 'nohooks', a postRenderers kustomize patch for the sidecar, and a valuesFrom entry referencing the 'podinfo-config' ConfigMap with valuesKey 'allowedHosts', targetPath config.allowedHosts, and literal: true. A second OCIRepository plus a Kustomization (kustomize.toolkit.fluxcd.io/v1) into the 'platform' namespace with spec.ignore excluding /spec/replicas on the Deployment and spec.prune set.", "files": [], "expectations": [ - "The chart OCIRepository uses apiVersion source.toolkit.fluxcd.io/v1 with url starting oci:// and a Helm chart layerSelector (mediaType 'application/vnd.cncf.helm.chart.content.v1.tar+gzip', operation 'copy')", + "The chart source is an OCIRepository with url starting oci:// that selects the Helm chart layer: either a source.toolkit.fluxcd.io/v1 OCIRepository with layerSelector (mediaType 'application/vnd.cncf.helm.chart.content.v1.tar+gzip', operation 'copy'), or a HelmRelease spec.chart.kind: OCIRepository template (Flux 2.10+), where that layerSelector is the default", "The chart OCIRepository spec.verify.provider is 'cosign'", "The chart OCIRepository spec.verify.trustedRootSecretRef.name is 'sigstore-trusted-root' (custom Sigstore root for air-gapped keyless verification)", - "The HelmRelease uses apiVersion helm.toolkit.fluxcd.io/v2 and references the chart via spec.chartRef (not spec.chart.spec)", + "The HelmRelease uses apiVersion helm.toolkit.fluxcd.io/v2 and sources the chart from the OCIRepository, via spec.chartRef or spec.chart.kind: OCIRepository (not a HelmChart generated from chart.spec.sourceRef)", "The HelmRelease spec.waitStrategy.name is 'poller' (not 'legacy')", "The HelmRelease spec.postRenderStrategy is 'nohooks' (so hooks are not sent to post-renderers)", "The HelmRelease spec.postRenderers contains a kustomize patch injecting the Istio sidecar", @@ -265,6 +265,26 @@ "Every kustomization.yaml directory under the tree builds successfully with kustomize (LoadRestrictionsNone) and the rendered output passes flux schema validate after variable substitution", "The report states that kustomize builds and schema validation were run as verification" ] + }, + { + "id": 15, + "prompt": "We just upgraded to Flux 2.10. Give me the manifests for three things: (1) deploy podinfo from oci://ghcr.io/stefanprodan/charts/podinfo (semver >=6.0.0) into the apps namespace as a single HelmRelease that manages its own chart source, I don't want a separate OCIRepository object to maintain; (2) send Flux errors and recoveries for all HelmReleases and Kustomizations in flux-system to our incident.io HTTP alert source (config id 01JABCDEF) so incidents open and auto-resolve; (3) a GitRepository for https://github.com/acme-corp/fleet that authenticates with our GitHub App using its client ID Iv23liABCDEF and installation owner acme-corp, we don't want to use the numeric app ID.", + "expected_output": "A HelmRelease (helm.toolkit.fluxcd.io/v2) with spec.chart.kind: OCIRepository and an inline OCIRepository spec (url, ref.semver), no separate OCIRepository and no chartRef. A Provider and Alert in notification.toolkit.fluxcd.io/v1 with type incident.io, a Secret with address and token, and eventSeverity info so resolved events are sent. A GitRepository with provider: github and a Secret using githubAppClientID, githubAppInstallationOwner and githubAppPrivateKey, without githubAppID.", + "files": [], + "expectations": [ + "The HelmRelease uses apiVersion helm.toolkit.fluxcd.io/v2 and sets spec.chart.kind: OCIRepository", + "The HelmRelease spec.chart.spec.url is oci://ghcr.io/stefanprodan/charts/podinfo", + "The HelmRelease spec.chart.spec.ref.semver selects versions >=6.0.0 (equivalent semver ranges are acceptable)", + "No standalone OCIRepository object and no spec.chartRef are used for podinfo, and spec.chart.spec does not set chart, sourceRef or version", + "The Provider uses apiVersion notification.toolkit.fluxcd.io/v1 with spec.type: incident.io", + "The incident.io Provider references a Secret holding both an address (https://api.incident.io/v2/alert_events/http/01JABCDEF) and a token", + "The Alert uses apiVersion notification.toolkit.fluxcd.io/v1 and does not set the removed spec.summary field", + "The Alert uses eventSeverity: info (or omits it, which defaults to info), not error, so recovery events resolve the incident", + "The Alert eventSources include HelmRelease and Kustomization with name '*'", + "The GitRepository uses apiVersion source.toolkit.fluxcd.io/v1 with spec.provider: github and a secretRef", + "The GitHub App Secret sets githubAppClientID: Iv23liABCDEF, githubAppInstallationOwner: acme-corp and githubAppPrivateKey", + "The GitHub App Secret does not set githubAppID (exactly one of githubAppID or githubAppClientID is allowed)" + ] } ] } diff --git a/.agents/skills/gitops-knowledge/references/best-practices.md b/.agents/skills/gitops-knowledge/references/best-practices.md index becc5ac5cb..eb684bdc03 100644 --- a/.agents/skills/gitops-knowledge/references/best-practices.md +++ b/.agents/skills/gitops-knowledge/references/best-practices.md @@ -79,6 +79,46 @@ Prescriptive guidance for production Flux deployments with Flux Operator. the Flux Operator itself via Flux (operator manages itself pattern). - **Cosign verification:** Add Cosign verification patches to the FluxInstance for the sync OCIRepository to verify artifact signatures. +- **Object identity (Flux 2.10+):** set `cluster.objectIdentityRBAC: true` when objects use + object identity (`serviceAccountName` for cloud or `kubernetes` provider auth) — the 2.10 distribution + no longer grants `serviceaccounts/token` create. Add `cluster.multitenantObjectIdentity: true` + to force tenants onto object identity. Both need a Flux Operator release with 2.10 support. + +## SPIFFE: Inter-Controller mTLS and Object Identity (RFC-0014, Flux 2.10+) + +Opt-in, configured only through controller env vars and flags (no CRD fields or feature gates). +With Flux Operator, apply them as FluxInstance `spec.kustomize.patches` on the controller +Deployments; with bootstrap, as patches in `flux-system/kustomization.yaml`. + +- **Prerequisite:** a SPIFFE runtime (e.g. SPIRE) deployed *before* Flux — `flux bootstrap` does + not install it; the Flux Operator bootstrap Terraform module can. Each controller needs the + Workload API socket: env `SPIFFE_ENDPOINT_SOCKET=unix:///spiffe-workload-api/` plus a + volume mount, e.g. a CSI volume (`driver: csi.spiffe.io`, `readOnly: true`) at `/spiffe-workload-api`. +- **Inter-controller mTLS:** each traffic type is enabled by passing at least one of its repeatable + flags, each taking the authorized peer's SPIFFE ID: + +| Flag | Set on | +|------|--------| +| `--authorized-artifact-client-spiffe-id` | source-controller, source-watcher (artifact servers) | +| `--authorized-artifact-server-spiffe-id` | kustomize-controller, helm-controller, source-watcher (artifact clients) | +| `--authorized-notifier-spiffe-id` | notification-controller (event server) | +| `--authorized-event-server-spiffe-id` | all controllers except notification-controller | +| `--authorized-receiver-spiffe-id` | notification-controller (ingress/gateway peer of the webhook receiver) | +| `--authorized-kube-apiserver-spiffe-id` | all controllers (optional) | + + The source-controller, source-watcher, notification-controller and webhook-receiver Services + expose port `443` (`https`); clients rewrite artifact URLs to HTTPS in memory, so + `.status.artifact.url` is unchanged. +- **Object identity via `spiffe`:** set `--spiffe-broker-endpoint=dns:///..svc.cluster.local:443` + and one or more `--spiffe-broker-id=spiffe:///` (trailing `/` = prefix) on the + controllers, then annotate the object's ServiceAccount with + `credential.auth.fluxcd.io/provider: spiffe` and `credential.auth.fluxcd.io/type: jwt` (JWT-SVID). + GCP also needs `gcp.auth.fluxcd.io/workload-identity-provider`; AWS can set + `aws.auth.fluxcd.io/sts-endpoint`. Tenant isolation is up to the SPIFFE runtime issuing + namespaced SPIFFE IDs. Object identity basics are in `references/kustomization.md`. +- **Deferred to Flux 2.11:** `credential.auth.fluxcd.io/type: x509` (AWS IAM Roles Anywhere, GCP + WIF with X.509), the `spiffe.mtls.fluxcd.io/server-ids` annotation, and the `dockerhub` + provider with `dockerhub.auth.fluxcd.io/oidc-connection-id`. Don't generate these for 2.10. ## Operational Excellence diff --git a/.agents/skills/gitops-knowledge/references/flux-cli.md b/.agents/skills/gitops-knowledge/references/flux-cli.md index 2de2ac5363..dbab044a2a 100644 --- a/.agents/skills/gitops-knowledge/references/flux-cli.md +++ b/.agents/skills/gitops-knowledge/references/flux-cli.md @@ -11,7 +11,7 @@ need schema validation, when a Kustomize overlay or ResourceSet must be rendered debugged locally, or when users ask about the `flux schema` plugin, `flux build`, `flux envsubst`, or `flux-operator build`. -**Contents:** [Plugin Setup](#plugin-setup) | [Repository Discovery](#repository-discovery-with-flux-schema-discover) | [The Authoring Control Loop](#the-authoring-control-loop-with-flux-schema-validate) | [Schemas for Custom CRDs](#schemas-for-custom-crds) | [Rendering Manifests Locally](#rendering-manifests-locally) | [Debugging a Failing Overlay](#debugging-a-failing-overlay) | [When Tools Are Missing](#when-tools-are-missing) +**Contents:** [Plugin Setup](#plugin-setup) | [Repository Discovery](#repository-discovery-with-flux-schema-discover) | [The Authoring Control Loop](#the-authoring-control-loop-with-flux-schema-validate) | [Schemas for Custom CRDs](#schemas-for-custom-crds) | [Rendering Manifests Locally](#rendering-manifests-locally) | [Debugging a Failing Overlay](#debugging-a-failing-overlay) | [Cluster Commands](#cluster-commands-and-flux-210-changes) | [When Tools Are Missing](#when-tools-are-missing) ## Plugin Setup @@ -195,6 +195,41 @@ instead of reasoning about the YAML in the abstract: Each step isolates one layer (Kustomize syntax → Flux transformations → schema correctness), so the first failing step tells you which layer holds the bug. +## Cluster Commands and Flux 2.10 Changes + +These need cluster access, except `flux migrate -f` and `--export`. Flux 2.10 CLI (`flux check` requires Kubernetes >= 1.35): + +```bash +# kubectl-style TYPE/NAME args in get, reconcile, suspend, resume, export and delete. +# Short names: hr, ks, gitrepo, ocirepo, helmrepo, hc, ea, ag, imgrepo, imgpol, iua, alert-provider +flux get hr/podinfo +flux reconcile kustomizations podinfo # plural/short names in the space form +flux reconcile gitrepositories.source.toolkit.fluxcd.io/podinfo +flux get ks frontend backend # multiple names (older CLIs used only the first) +flux suspend gitrepo/podinfo gitrepo/flux-system + +# ArtifactGenerator (source-watcher) +flux suspend artifact generator podinfo # or: flux suspend ag/podinfo +flux resume artifact generator podinfo # resume requests a reconcile and waits +flux reconcile artifact generator frontend backend + +# Migrate manifests to the latest APIs (Alert/Provider v1beta3 -> v1); also strips fields +# dropped in v1 (Alert spec.summary, Provider spec.proxy/interval) with a warning per field +flux migrate -f . --dry-run +flux migrate -f . + +# Batch image updates into one commit (sets ImageUpdateAutomation spec.policyChangeDelay) +flux create image update apps --policy-change-delay=2m ... + +# GitHub App auth by client ID instead of app ID (writes the githubAppClientID key) +flux create secret githubapp app-auth --app-client-id="" \ + --app-installation-id="" --app-private-key=./private-key.pem --export +``` + +`flux create image policy` now rejects more than one of `--select-semver`, `--select-alpha`, +`--select-numeric`. HelmReleases with `spec.chart.kind: OCIRepository` work with +`get --show-source`, `reconcile --with-source`, `trace` and `events`. + ## When Tools Are Missing These commands are force multipliers, not hard requirements. If `flux`, a plugin, or diff --git a/.agents/skills/gitops-knowledge/references/flux-operator.md b/.agents/skills/gitops-knowledge/references/flux-operator.md index 1dc4539bd5..707c50247d 100644 --- a/.agents/skills/gitops-knowledge/references/flux-operator.md +++ b/.agents/skills/gitops-knowledge/references/flux-operator.md @@ -123,7 +123,7 @@ spec: | Field | Type | Description | |-------|------|-------------| -| `distribution.version` | string | Semver range (`2.x`, `2.8.x`) or exact version | +| `distribution.version` | string | Semver range (`2.x`, `2.10.x`) or exact version | | `distribution.registry` | string | Container registry (e.g., `ghcr.io/fluxcd`) | | `distribution.variant` | string | `upstream-alpine`, `enterprise-alpine`, `enterprise-distroless`, `enterprise-distroless-fips` | | `distribution.artifact` | string | OCI artifact URL with distribution manifests | @@ -149,9 +149,16 @@ Optional components: | `cluster.size` | string | `medium` | Affects controller resource limits and concurrency | | `cluster.multitenant` | bool | false | Enable multi-tenancy lockdown | | `cluster.tenantDefaultServiceAccount` | string | `default` | Default SA for tenant reconcilers when multitenant lockdown is enabled and the field is omitted | +| `cluster.objectIdentityRBAC` | bool | false | Object identity with SA tokens. Flux 2.10+: adds the `serviceaccounts/token` create RBAC the distribution no longer ships (2.6–2.9: enables the feature gate). Replaces legacy `objectLevelWorkloadIdentity` | +| `cluster.multitenantObjectIdentity` | bool | false | Multi-tenancy lockdown for object identity (default SA for source, notification and image controllers; requires `objectIdentityRBAC: true`). Replaces legacy `multitenantWorkloadIdentity` | +| `cluster.tenantDefaultDecryptionServiceAccount` | string | `default` | Default SA for SOPS decryption under the object identity lockdown | +| `cluster.tenantDefaultKubeConfigServiceAccount` | string | `default` | Default SA for remote cluster access (`kubeConfig.configMapRef`) under the object identity lockdown | | `cluster.networkPolicy` | bool | true | Restrict network access to Flux controllers | | `cluster.domain` | string | `cluster.local` | Kubernetes cluster domain | +`objectIdentityRBAC` and `multitenantObjectIdentity` need Flux Operator v0.62.0 +or later; older operators only accept the legacy names. Set either the new or the legacy name, never both. + ### Cluster Sizing | Size | Concurrency | CPU Limit | Memory Limit | Use Case | diff --git a/.agents/skills/gitops-knowledge/references/helmrelease.md b/.agents/skills/gitops-knowledge/references/helmrelease.md index 27e0115b64..f9eb248eb2 100644 --- a/.agents/skills/gitops-knowledge/references/helmrelease.md +++ b/.agents/skills/gitops-knowledge/references/helmrelease.md @@ -93,11 +93,38 @@ spec: namespace: cert-manager # optional, for cross-namespace ``` -These are **mutually exclusive** — use one or the other, never both. +**Option C — `spec.chart` with `kind: OCIRepository`** (Flux 2.10+, auto-creates an OCIRepository): +```yaml +spec: + interval: 10m + chart: + kind: OCIRepository # default is HelmChart (Option A) + spec: # inline OCIRepository spec + interval: 10m # defaults to .spec.interval + url: oci://ghcr.io/stefanprodan/charts/podinfo + ref: + semver: ">= 6.0.0" # pick the version here, not in chart.spec.version + values: + replicaCount: 2 +``` + +`chart.spec` takes the OCIRepository fields (`url` (required), `ref`, `layerSelector`, `verify`, +`provider`, `secretRef`, `certSecretRef`, `serviceAccountName`, `interval`). The HelmChart-only +fields are rejected: `chart`, `sourceRef`, `version` (other than `*`), `reconcileStrategy` (other than `ChartVersion`), +`valuesFiles`, `ignoreMissingValuesFiles`. `layerSelector` defaults to the Helm chart layer +(`application/vnd.cncf.helm.chart.content.v1.tar+gzip`, `copy`). The controller creates the +OCIRepository in the HelmRelease namespace, named `-`, and reports it in +`.status.helmChart` as `OCIRepository//`. + +`spec.chart` (Options A and C) and `spec.chartRef` (Option B) are **mutually exclusive** — use one or the other, never both. **When to use which:** - `chart.spec` with HelmRepository: Traditional HTTPS Helm repos (e.g., Bitnami) -- `chartRef` with OCIRepository: OCI registries (recommended — supports Cosign verification) +- `chartRef` with OCIRepository: OCI registries (recommended — supports Cosign verification); the + OCIRepository can be shared by several HelmReleases +- `chart.kind: OCIRepository`: OCI chart owned by one HelmRelease — the chart version (`ref`) and + `values` change in one atomic edit, avoiding upgrade failures from values that don't match the new + chart; requires Flux 2.10+ - `chart.spec` with GitRepository: Charts stored alongside application code ## Key Spec Fields @@ -308,7 +335,7 @@ Control how Helm manages CRDs: | Value | Install | Upgrade | Description | |-------|---------|---------|-------------| -| `Create` | Install CRDs | Skip CRDs | Default — create on install, leave on upgrade | +| `Create` | Install CRDs | Create new CRDs only | Default for install and upgrade — create missing CRDs, never update existing ones | | `Skip` | Skip CRDs | Skip CRDs | Never touch CRDs (manage separately) | | `CreateReplace` | Install CRDs | Replace CRDs | Create and update CRDs (use with caution) | diff --git a/.agents/skills/gitops-knowledge/references/image-automation.md b/.agents/skills/gitops-knowledge/references/image-automation.md index e702f0e276..575271d11e 100644 --- a/.agents/skills/gitops-knowledge/references/image-automation.md +++ b/.agents/skills/gitops-knowledge/references/image-automation.md @@ -45,6 +45,7 @@ spec: | `interval` | duration | yes | Scan interval | | `provider` | string | no | Registry auth provider: `generic` (default), `aws`, `azure`, `gcp` | | `secretRef.name` | string | no | Secret of type `kubernetes.io/dockerconfigjson` for auth | +| `serviceAccountName` | string | no | ServiceAccount for object identity (cloud providers) or its `imagePullSecrets`; with `generic`, a ServiceAccount token (see below) | | `exclusionList` | array | no | Regex patterns — matching tags are excluded from results | | `insecure` | bool | no | Allow HTTP (non-TLS) connections | | `suspend` | bool | no | Pause scanning | @@ -53,7 +54,27 @@ spec: - `aws` — uses IRSA/pod identity for ECR authentication - `azure` — uses workload identity for ACR authentication - `gcp` — uses workload identity for GAR/GCR authentication -- `generic` — uses `secretRef` with dockerconfigjson +- `generic` — uses `secretRef` with dockerconfigjson, or (Flux 2.10+) a Kubernetes + ServiceAccount token for registries that trust the cluster's OIDC issuer: + +```yaml +spec: + provider: generic + serviceAccountName: registry-puller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: registry-puller + annotations: + credential.auth.fluxcd.io/provider: kubernetes # required together with type + credential.auth.fluxcd.io/type: jwt + credential.auth.fluxcd.io/audiences: registry.example.com # optional, defaults to the registry host + credential.auth.fluxcd.io/username: flux # optional, switches Bearer to Basic auth +``` + +The annotations can't be combined with `imagePullSecrets`, and since Flux 2.10 the controller +needs a ClusterRole granting `create` on `serviceaccounts/token` (no longer in the default RBAC). ## ImagePolicy @@ -210,6 +231,7 @@ spec: | `git.commit.messageTemplate` | string | no | Go template for commit message | | `git.commit.signingKey.secretRef.name` | string | no | Secret with an OpenPGP or SSH key to sign the commit | | `git.push.branch` | string | no | Branch to push to (enables PR workflow) | +| `policyChangeDelay` | duration | no | Wait after an ImagePolicy change so close updates land in one commit (Flux 2.10+) | | `update.path` | string | no | Directory to scan for image markers (default: repository root) | | `update.strategy` | string | no | `Setters` (default) | | `suspend` | bool | no | Pause automation | @@ -228,6 +250,13 @@ spec: This creates/updates a branch with the image changes. Set up a CI workflow or manual process to create PRs from this branch and merge into main. +### Batching Updates + +`spec.policyChangeDelay` (e.g. `2m`, CLI: `flux create image update --policy-change-delay=2m`) +delays the run triggered by an ImagePolicy change, so images released together go into one +commit. The delay starts at the first change and isn't extended by later ones; interval, spec, +source and manual reconciles run immediately and replace the pending run. + ### Signed Commits Sign the automation commits with an OpenPGP or SSH key so the pushed commits carry a @@ -259,6 +288,20 @@ Available template data: - `.Changed.Objects` — map of resource to changes - `.Changed.Objects[].OldValue` — previous image reference - `.Changed.Objects[].NewValue` — new image reference +- `.Changed.Summary` — one line per change, sorted and deduplicated, e.g. + `ghcr.io/org/app tag 1.2.0 -> 1.2.1` (Flux 2.10+) + +```yaml +spec: + git: + commit: + messageTemplate: | + Update container images + + {{ .Changed.Summary }} +``` + +For a bulleted list: `{{ with .Changed.Summary }}{{ . | replace "\n" "\n- " | printf "- %s" }}{{ end }}`. ## Image Policy Markers diff --git a/.agents/skills/gitops-knowledge/references/kustomization.md b/.agents/skills/gitops-knowledge/references/kustomization.md index 4f8e50a7a1..05f28705ee 100644 --- a/.agents/skills/gitops-knowledge/references/kustomization.md +++ b/.agents/skills/gitops-knowledge/references/kustomization.md @@ -183,19 +183,58 @@ feature gate required. This covers: - **Cloud KMS** (AWS KMS, GCP KMS, Azure Key Vault) via the controller's cloud workload identity, and - **Vault / OpenBao** via the Kubernetes auth method, using the kustomize-controller's SA token. -Setting `decryption.serviceAccountName` switches authentication from controller-level to -**object-level** — the named per-Kustomization ServiceAccount is used instead (e.g. for -multi-tenancy). This requires the `ObjectLevelWorkloadIdentity` feature gate on kustomize-controller: +Setting `decryption.serviceAccountName` switches authentication from the controller's identity +to **object identity**: the named per-Kustomization ServiceAccount is used instead (e.g. for +multi-tenancy). Since Flux 2.10 object identity is GA and always on; the old +`ObjectLevelWorkloadIdentity` feature gate is retired (setting it has no effect). ```yaml spec: decryption: provider: sops - serviceAccountName: tenant-sa # object-level identity; needs ObjectLevelWorkloadIdentity gate + serviceAccountName: tenant-sa # object identity +``` + +**Object identity (Flux 2.10+).** The same model applies to every API with a `serviceAccountName` +for external auth (sources, image repositories, notification Providers, `kubeConfig.configMapRef`): + +- The ServiceAccount's annotations select the credential provider: + `credential.auth.fluxcd.io/provider: kubernetes` (TokenRequest API JWT) or `spiffe` + (JWT-SVID from the SPIFFE Broker API), always together with `credential.auth.fluxcd.io/type: jwt`. + Optional: `credential.auth.fluxcd.io/audiences`, `.../expiration` (kubernetes only), and + `.../username` (only OCIRepository/ImageRepository with the `generic` provider). + Cloud SAs keep using `eks.amazonaws.com/role-arn`, `azure.workload.identity/client-id` + + `azure.workload.identity/tenant-id`, `iam.gke.io/gcp-service-account`. +- The Flux 2.10 distribution **no longer grants** `create` on `serviceaccounts/token` to the + controllers. Any object identity (`serviceAccountName` with the `kubernetes` provider or a cloud + provider: aws/azure/gcp) requires binding a ClusterRole with that verb to the controller ServiceAccounts (with Flux Operator, set `spec.cluster.objectIdentityRBAC: true`). +- Remote clusters: the `kubeConfig` ConfigMap's legacy `audiences` key cannot be combined with the + annotations; use `credential.auth.fluxcd.io/audiences`. +- Multi-tenancy lockdown (forces tenants onto object identity): `--default-service-account` on + source-, notification-, image-reflector- and image-automation-controller; + `--default-kubeconfig-service-account` on kustomize- and helm-controller; + `--default-decryption-service-account` on kustomize-controller. Point them at `default`, a SA + with no identity configured (Flux Operator: `spec.cluster.multitenantObjectIdentity: true`). + +**OpenBao/Vault transit engine (Flux 2.10+).** Instead of the `--sops-vault-configmap` controller +flag, annotate the decryption ServiceAccount (the two cannot be combined): + +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: sops-decrypter + namespace: apps + annotations: + credential.auth.fluxcd.io/provider: kubernetes # or spiffe + credential.auth.fluxcd.io/type: jwt + credential.auth.fluxcd.io/audiences: https://openbao.example.com + transit-engine.auth.fluxcd.io/login-path: auth/jwt/login + transit-engine.auth.fluxcd.io/role: sops ``` For Vault/OpenBao specifically, the authentication precedence is: a static `sops.vault-token` -in the `secretRef` Secret **>** the Kubernetes auth method (controller or object-level SA) **>** +in the `secretRef` Secret **>** the Kubernetes/SPIFFE JWT auth (controller or object identity) **>** a global `VAULT_TOKEN` environment variable patched onto the controller Deployment. ## Health Checks diff --git a/.agents/skills/gitops-knowledge/references/monorepo-delivery.md b/.agents/skills/gitops-knowledge/references/monorepo-delivery.md index f093d8f544..623f344808 100644 --- a/.agents/skills/gitops-knowledge/references/monorepo-delivery.md +++ b/.agents/skills/gitops-knowledge/references/monorepo-delivery.md @@ -45,8 +45,8 @@ as they are created, updated or deleted. ## Prerequisites -Flux **v2.9.0 or later** with the `source-watcher` component enabled on the `FluxInstance` -(see `references/flux-operator.md` for the full spec): +Flux **v2.9.0 or later** (v2.10.0+ for cross-namespace artifacts and managed tenant namespaces) with +the `source-watcher` component enabled on the `FluxInstance` (see `references/flux-operator.md`): ```yaml spec: @@ -570,6 +570,57 @@ same tenant identity. Note the production layout above uses `multitenant: false` cross-namespace references; a locked-down variant keeps each tenant's artifacts, provider and ResourceSet in the tenant namespace. +### Cross-Namespace Artifacts and Tenant Namespaces (Flux 2.10+) + +source-watcher v2.3 (Flux 2.10) lets one ArtifactGenerator in a shared namespace publish each +tenant's `ExternalArtifact` into the tenant's namespace, and optionally create the namespaces: + +```yaml +apiVersion: source.extensions.fluxcd.io/v1beta1 +kind: ArtifactGenerator +metadata: + name: tenants + namespace: flux-system +spec: + serviceAccountName: tenant-artifacts # authorizes the work via SubjectAccessReview + managedNamespaces: # opt-in namespace provisioning + allowedNames: + - "ns.startsWith('tenant-')" # CEL over `ns`; default/kube-*/flux-system always rejected + prune: true # deletes the WHOLE namespace when the dir is removed + sources: + - alias: repo + kind: GitRepository + name: my-monorepo + pathPattern: "@repo/tenants/{tenant}" + artifacts: + - name: "{tenant}" + namespace: "{tenant}" # captures are lowercased; must be a valid namespace + copy: + - from: "@repo/tenants/{tenant}/**" + to: "@artifact/" +``` + +- `artifacts[].namespace` targets another namespace. The controller checks with + SubjectAccessReview that `spec.serviceAccountName` (resolved in the generator's namespace) may + `get`/`list`/`create`/`patch`/`delete` `externalartifacts` (and `patch` `externalartifacts/status`) + in every target namespace, then acts with its own credentials — no impersonation RBAC. +- Without `serviceAccountName`, in-namespace artifacts use the controller's credentials; + cross-namespace ones use the `--default-service-account` flag's SA (or the controller's when + unset). On multi-tenant clusters set `--default-service-account` on source-watcher. +- `managedNamespaces` requires `serviceAccountName` or `--default-service-account`. Both that + authorizing ServiceAccount (checked via SubjectAccessReview) and the `flux-system/source-watcher` + ServiceAccount need a ClusterRole with `get`/`create`/`patch`/`delete` on `namespaces` (not granted + by default; namespace verbs are cluster-scoped). Existing namespaces are adopted. Namespace metadata + comes from `commonMetadata`, then `managedNamespaces.metadata.fromSource` (a `NamespaceMetadata` + file in the repo, filtered by `allowedLabels`/`allowedAnnotations` CEL over `value`), then + `metadata.from[]` (`strategy: Reset|Override|Merge`, `namespace: |*`). Protect a namespace + from pruning with the `source.extensions.fluxcd.io/prune: Disabled` annotation. +- Only enable `prune` when the generator fully owns the namespaces; it wipes anything else in them. + +Other source-watcher v2.3 additions: `copy[].optional: true` skips copy operations that match no +files instead of failing, and the `source.extensions.fluxcd.io/reconcileEvery: 10m` annotation +sets the generator's reconcile interval. + ## Operations ```shell diff --git a/.agents/skills/gitops-knowledge/references/notifications.md b/.agents/skills/gitops-knowledge/references/notifications.md index 9c89a44b5e..b7be518890 100644 --- a/.agents/skills/gitops-knowledge/references/notifications.md +++ b/.agents/skills/gitops-knowledge/references/notifications.md @@ -6,16 +6,22 @@ target or source. **Contents:** [Provider](#provider) | [Alert](#alert) | [Receiver](#receiver) | [Common Patterns](#common-patterns) +**Flux 2.10:** `Provider` and `Alert` are GA at `notification.toolkit.fluxcd.io/v1`; `v1beta3` is +deprecated (still served). `v1` drops Alert `spec.summary` (use `spec.eventMetadata.summary`), +Provider `spec.proxy` (use `spec.proxySecretRef`) and Provider `spec.interval` (no replacement). +`flux migrate -f .` bumps manifests to `v1` and removes those fields. The Event payload sent to +`generic` webhooks gains `relatedObject` and `action` fields. + ## Provider -`apiVersion: notification.toolkit.fluxcd.io/v1beta3` +`apiVersion: notification.toolkit.fluxcd.io/v1` Defines an external notification service that Alert resources route events to. ### Canonical YAML — Microsoft Teams ```yaml -apiVersion: notification.toolkit.fluxcd.io/v1beta3 +apiVersion: notification.toolkit.fluxcd.io/v1 kind: Provider metadata: name: msteams @@ -49,6 +55,8 @@ stringData: | `rocket` | `address` (webhook URL) | — | Rocket.Chat (type is `rocket`, not `rocketchat`) | | `lark` | `address` (webhook URL) | — | | | `webex` | `token` | — | Channel is room ID | +| `zoom` | `address` (incoming webhook URL) + `token` (verification token) | — | Zoom Team Chat | +| `mastodon` | `token` (access token, `write:statuses` scope) + `address` (server root URL, e.g. `https://mastodon.social`) | — | `v1` only; statuses truncated to 500 chars | **Alerting and monitoring platforms:** @@ -60,13 +68,14 @@ stringData: | `datadog` | `token` (API key) | DataDog endpoint | | | `opsgenie` | `token` (API key) | OpsGenie endpoint | | | `pagerduty` | — (none required) | `https://events.pagerduty.com` | Integration routing key set in `spec.channel`, not a secret | +| `incident.io` | `address` (`https://api.incident.io/v2/alert_events/http/`) + `token` (API token) | — | Type is `incident.io`. Errors fire, other events resolve — keep the Alert at `eventSeverity: info` so alerts auto-resolve | **Event streaming:** | Type | Secret Field | Address | Notes | |------|-------------|---------|-------| | `googlepubsub` | `token` (JSON key) | — | Channel is topic ID | -| `azureeventhub` | `address` (SAS connection string, SAS auth only) | hub name in `spec.address` | `spec.channel` = Event Hubs namespace; `spec.address` = hub name. Managed identity uses `spec.channel`/`spec.address` directly | +| `azureeventhub` | `address` (SAS connection string, SAS auth only) | hub name in `spec.address` | `spec.channel` = Event Hubs namespace; `spec.address` = hub name. Object identity (`spec.serviceAccountName`) or the controller's workload identity uses `spec.channel`/`spec.address` directly. A `token` key fails (static JWT auth removed in 2.10) | | `nats` | `creds` / `nkey` / `username`+`password` (priority order) | NATS server URL | Channel is subject | **Git commit status:** @@ -76,7 +85,7 @@ stringData: | `github` | `token` (PAT or app token) | — | Sets commit status on PRs | | `gitlab` | `token` (access token) | GitLab URL | Sets pipeline status | | `gitea` | `token` | Gitea URL | | -| `bitbucket` | `token` | — | Bitbucket Cloud | +| `bitbucket` | `token` (Bitbucket Cloud API token, scopes `read:repository:bitbucket` + `write:repository:bitbucket`) | — | Bitbucket Cloud; `:` no longer works | | `bitbucketserver` | `token` | Bitbucket Server URL | | | `azuredevops` | `token` | Azure DevOps URL | | @@ -95,20 +104,23 @@ stringData: | `address` | string | API endpoint URL (some providers use secret instead) | | `channel` | string | Channel, room ID, or topic | | `username` | string | Bot username for display | -| `secretRef.name` | string | Secret with credentials | -| `certSecretRef.name` | string | Secret with custom TLS CA certificate | +| `secretRef.name` | string | Secret with credentials — keys `address`, `token`, `username`, `password`, `headers` (a `proxy` key is rejected) | +| `certSecretRef.name` | string | Secret with `ca.crt` (and `tls.crt`/`tls.key` for mTLS); TLS data is read only from here, not from `secretRef` | +| `proxySecretRef.name` | string | Secret with proxy `address` and optional `username`/`password` (replaces `spec.proxy`) | +| `serviceAccountName` | string | Object identity for `azureeventhub`, `azuredevops`, `googlepubsub`; unset falls back to the controller's workload identity | +| `timeout` | duration | Timeout for the whole delivery (default `15s`) | | `suspend` | bool | Pause the provider | ## Alert -`apiVersion: notification.toolkit.fluxcd.io/v1beta3` +`apiVersion: notification.toolkit.fluxcd.io/v1` Routes Flux events to a Provider based on source, severity, and content filters. ### Canonical YAML ```yaml -apiVersion: notification.toolkit.fluxcd.io/v1beta3 +apiVersion: notification.toolkit.fluxcd.io/v1 kind: Alert metadata: name: slack-alert @@ -189,8 +201,12 @@ spec: environment: production cluster: prod-eu-1 team: platform + summary: "Production cluster" # replaces the removed spec.summary ``` +Precedence, lowest to highest: `event.toolkit.fluxcd.io/` annotations on the source object, +then `spec.eventMetadata`, then controller-set metadata. + ## Receiver `apiVersion: notification.toolkit.fluxcd.io/v1` @@ -296,7 +312,7 @@ The `req` object exposes the webhook payload fields and `res` provides the resou `type: generic-oidc` authenticates incoming requests with a signed OIDC/JWT bearer token instead of a shared HMAC secret — no webhook secret to provision or rotate. The controller verifies the token's signature, expiry, and audience against the provider whose `issuerURL` -matches the token's `iss` claim, then evaluates optional CEL `validations` against the claims. +matches the token's `iss` claim, then evaluates the provider's CEL `validations` against the claims. Ideal for callers that already have a workload identity token (CI runners, cloud services): ```yaml @@ -314,16 +330,18 @@ spec: audience: flux-notification-controller # expected 'aud' claim (defaults to 'notification-controller') validations: # only accept tokens from a specific repo's workflows - - "claims.repository == 'my-org/my-app'" + - expression: "claims.repository == 'my-org/my-app'" + message: "token must be issued for my-org/my-app" resources: - apiVersion: source.toolkit.fluxcd.io/v1 kind: OCIRepository name: my-app ``` -`validations` are CEL booleans over `claims` (the token claims); the request is accepted only -if all pass. `variables` can define named CEL expressions exposed as `vars.` for reuse -inside validations. No `secretRef` is needed for `generic-oidc`. +`validations` is required (at least one): each item has a CEL boolean `expression` over `claims` +(the token claims) and a `message` returned to the caller when it is false; the request is +accepted only if all pass. `variables` (`name` + `expression`) define named CEL expressions +exposed as `vars.` for reuse inside validations. No `secretRef` is needed for `generic-oidc`. ## Common Patterns @@ -331,7 +349,7 @@ inside validations. No `secretRef` is needed for `generic-oidc`. ```yaml # Provider + Alert for error-only Slack notifications using Slack Bot API -apiVersion: notification.toolkit.fluxcd.io/v1beta3 +apiVersion: notification.toolkit.fluxcd.io/v1 kind: Provider metadata: name: slack-bot @@ -343,7 +361,7 @@ spec: secretRef: name: slack-bot-token --- -apiVersion: notification.toolkit.fluxcd.io/v1beta3 +apiVersion: notification.toolkit.fluxcd.io/v1 kind: Alert metadata: name: all-failures @@ -363,7 +381,7 @@ spec: ```yaml # Show deploy status on GitHub PRs/commits -apiVersion: notification.toolkit.fluxcd.io/v1beta3 +apiVersion: notification.toolkit.fluxcd.io/v1 kind: Provider metadata: name: github-status @@ -374,7 +392,7 @@ spec: secretRef: name: github-token --- -apiVersion: notification.toolkit.fluxcd.io/v1beta3 +apiVersion: notification.toolkit.fluxcd.io/v1 kind: Alert metadata: name: github-status diff --git a/.agents/skills/gitops-knowledge/references/resourcesets.md b/.agents/skills/gitops-knowledge/references/resourcesets.md index dff973a965..f52a708f98 100644 --- a/.agents/skills/gitops-knowledge/references/resourcesets.md +++ b/.agents/skills/gitops-knowledge/references/resourcesets.md @@ -6,6 +6,11 @@ ResourceSet generates Kubernetes resources from a matrix of input values using a approach. It is the primary mechanism for multi-tenant orchestration, fleet management, and self-service platforms. +For monorepos where each tenant is a directory, Flux 2.10 also lets an ArtifactGenerator publish +per-tenant `ExternalArtifact`s into tenant namespaces and provision those namespaces +(`spec.managedNamespaces`); an `ExternalArtifact` provider then feeds the ResourceSet. See +`references/monorepo-delivery.md` (Cross-Namespace Artifacts and Tenant Namespaces). + **Contents:** [Canonical YAML](#canonical-yaml) | [Key Spec Fields](#key-spec-fields) | [Template Syntax](#template-syntax) | [Testing ResourceSets Locally](#testing-resourcesets-locally) | [Input Strategies](#input-strategies) | [Dependencies](#dependencies) | [Step-Based Reconciliation](#step-based-reconciliation) (Jobs before/after a deploy) | [Advanced Features](#advanced-features) (annotations, `copyFrom`, `checksumFrom`) | [Built-in Input Fields](#built-in-input-fields) | [ResourceSetInputProvider](#resourcesetinputprovider) | [Use Cases](#use-cases) ## Canonical YAML diff --git a/.agents/skills/gitops-knowledge/references/sources.md b/.agents/skills/gitops-knowledge/references/sources.md index 6db9bc280f..c5c03920ad 100644 --- a/.agents/skills/gitops-knowledge/references/sources.md +++ b/.agents/skills/gitops-knowledge/references/sources.md @@ -74,7 +74,19 @@ stringData: known_hosts: github.com ssh-ed25519 AAAA... ``` -For GitHub App — Secret with `githubAppID`, `githubAppPrivateKey` and `githubAppInstallationID` or `githubAppInstallationOwner`. +For GitHub App (`spec.provider: github`) — Secret with `githubAppPrivateKey`, exactly one of +`githubAppID` or `githubAppClientID` (Flux 2.10+), and exactly one of `githubAppInstallationID` or +`githubAppInstallationOwner` (optional `githubAppBaseURL` for GitHub Enterprise): +```yaml +stringData: + githubAppClientID: "" # or githubAppID: "", never both + githubAppInstallationOwner: my-org + githubAppPrivateKey: | + -----BEGIN RSA PRIVATE KEY----- + ... +``` +CLI: `flux create secret githubapp --app-client-id= --app-installation-owner= --app-private-key=./key.pem --export` +(or `--app-id` for the numeric App ID). ## OCIRepository @@ -112,15 +124,43 @@ spec: | `ref.digest` | string | Exact digest (`sha256:...`) | | `secretRef.name` | string | Secret of type `kubernetes.io/dockerconfigjson` | | `certSecretRef.name` | string | Secret with TLS CA and client certs for mTLS auth | -| `provider` | string | Cloud OIDC provider for keyless auth: `aws`, `azure`, `gcp` | +| `provider` | string | `generic` (default), or cloud OIDC provider for keyless auth: `aws`, `azure`, `gcp` | | `layerSelector.mediaType` | string | Filter OCI layers by media type | | `layerSelector.operation` | string | `extract` (default) or `copy` | | `verify.provider` | string | Signature verification: `cosign` or `notation` | | `verify.matchOIDCIdentity` | array | OIDC issuer/subject patterns for keyless verification | | `verify.trustedRootSecretRef.name` | string | Secret with a custom Sigstore `trusted_root.json` — verify against self-hosted Fulcio CA / Rekor (air-gapped keyless) | -| `serviceAccountName` | string | Service account for image pull (uses imagePullSecrets) | +| `serviceAccountName` | string | Service account for image pull: object identity for cloud providers, its `imagePullSecrets`, or a ServiceAccount token with `generic` (see below) | | `insecure` | bool | Allow HTTP (non-TLS) connections | +**ServiceAccount token auth for `generic` registries (Flux 2.10+):** for registries that trust +the cluster's OIDC issuer, the controller sends a short-lived Kubernetes ServiceAccount token +instead of a static pull secret. No new spec fields — annotate the ServiceAccount: + +```yaml +spec: + provider: generic + serviceAccountName: registry-puller +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: registry-puller + namespace: apps + annotations: + credential.auth.fluxcd.io/provider: kubernetes # required together with type + credential.auth.fluxcd.io/type: jwt + credential.auth.fluxcd.io/audiences: registry.example.com # optional, defaults to the registry host + credential.auth.fluxcd.io/username: flux # optional, token sent as Basic password instead of Bearer + credential.auth.fluxcd.io/expiration: 10m # optional +``` + +Setting only one of `provider`/`type` is an error, and the annotations can't be combined with +`imagePullSecrets`. Object identity with the `kubernetes` provider needs the Flux controllers to +create ServiceAccount tokens: since Flux 2.10 the default RBAC no longer grants `create` on +`serviceaccounts/token`, so bind a ClusterRole with that permission to the controller +ServiceAccounts. + **Fetching Helm charts from OCI registries:** When an OCI registry stores Helm charts, use `layerSelector` to extract the chart layer: diff --git a/.agents/skills/gitops-knowledge/references/web-ui.md b/.agents/skills/gitops-knowledge/references/web-ui.md index b2e9f9dc29..f0fe3b6313 100644 --- a/.agents/skills/gitops-knowledge/references/web-ui.md +++ b/.agents/skills/gitops-knowledge/references/web-ui.md @@ -296,7 +296,7 @@ web: ### Audit Notifications to Slack ```yaml -apiVersion: notification.toolkit.fluxcd.io/v1beta3 +apiVersion: notification.toolkit.fluxcd.io/v1 kind: Alert metadata: name: web-actions-audit