diff --git a/.github/labels.yaml b/.github/labels.yaml index 5821ac39..e5fcef61 100644 --- a/.github/labels.yaml +++ b/.github/labels.yaml @@ -44,12 +44,12 @@ description: Feature request proposals in the RFC format color: '#D621C3' aliases: ['area/RFC'] +- name: backport:release/v2.5.x + description: To be backported to release/v2.5.x + color: '#ffd700' - name: backport:release/v2.6.x description: To be backported to release/v2.6.x color: '#ffd700' - name: backport:release/v2.7.x description: To be backported to release/v2.7.x color: '#ffd700' -- name: backport:release/v2.8.x - description: To be backported to release/v2.8.x - color: '#ffd700' diff --git a/.github/workflows/upgrade-fluxcd-pkg.yaml b/.github/workflows/upgrade-fluxcd-pkg.yaml index c96199d1..659fd30a 100644 --- a/.github/workflows/upgrade-fluxcd-pkg.yaml +++ b/.github/workflows/upgrade-fluxcd-pkg.yaml @@ -3,9 +3,6 @@ name: upgrade-fluxcd-pkg on: workflow_dispatch: -permissions: - contents: read - jobs: upgrade-fluxcd-pkg: uses: fluxcd/gha-workflows/.github/workflows/upgrade-fluxcd-pkg.yaml@v0.9.0 diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 9fe1a1b6..00000000 --- a/AGENTS.md +++ /dev/null @@ -1,151 +0,0 @@ -# AGENTS.md - -Guidance for AI coding assistants working in `fluxcd/flux2`. Read this file before making changes. - -## Contribution workflow for AI agents - -These rules come from [`fluxcd/flux2/CONTRIBUTING.md`](https://github.com/fluxcd/flux2/blob/main/CONTRIBUTING.md) and apply to every Flux repository. - -- **Do not add `Signed-off-by` or `Co-authored-by` trailers with your agent name.** Only a human can legally certify the DCO. -- **Disclose AI assistance** with an `Assisted-by` trailer naming your agent and model: - ```sh - git commit -s -m "Add support for X" --trailer "Assisted-by: /" - ``` - The `-s` flag adds the human's `Signed-off-by` from their git config — do not remove it. -- **Commit message format:** Subject in imperative mood ("Add feature X" instead of "Adding feature X"), capitalized, no trailing period, ≤50 characters. Body wrapped at 72 columns, explaining what and why. No `@mentions` or `#123` issue references in the commit — put those in the PR description. -- **Trim verbiage:** in PR descriptions, commit messages, and code comments. No marketing prose, no restating the diff, no emojis. -- **Rebase, don't merge:** Never merge `main` into the feature branch; rebase onto the latest `main` and push with `--force-with-lease`. Squash before merge when asked. -- **Pre-PR gate:** `make tidy fmt vet && make test` must pass and the working tree must be clean. -- **Flux is GA:** Backward compatibility is mandatory. Breaking changes to CLI flags, output format, or behavior will be rejected. Design additive changes. -- **Copyright:** All new `.go` files must begin with the header from `cmd/flux/main.go` (Apache 2.0). Update the year to the current year when copying. -- **Tests:** New features, improvements and fixes must have test coverage. Add unit tests in `cmd/flux/*_test.go` tagged `//go:build unit`. Follow the existing `cmdTestCase` + golden file patterns. Run tests locally before pushing. - -## Code quality - -Before submitting code, review your changes for the following: - -- **No secrets in logs or output.** Never surface auth tokens, passwords, deploy keys, or credential URLs in error messages, log lines, or CLI output. Bootstrap and source-secret commands handle sensitive material — take extra care. -- **No unchecked I/O.** Close HTTP response bodies, file handles, and tar readers in `defer` statements. Check and propagate errors from I/O operations. -- **No path traversal.** Validate and sanitize file paths extracted from archives or user input. Never `filepath.Join` with untrusted components without validation. -- **No command injection.** Do not shell out via `os/exec` for git, helm, or kustomize operations. Use the Go libraries already in use (`fluxcd/pkg/git`, `fluxcd/pkg/kustomize`, `fluxcd/pkg/ssa`). -- **No hardcoded defaults for security settings.** TLS verification must remain enabled by default. Git auth settings come from user-provided secrets. -- **Error handling.** Wrap errors with `%w` for chain inspection. Do not swallow errors silently. CLI errors must be actionable — tell the user what went wrong and how to fix it without leaking internal state. -- **Resource cleanup.** Ensure temporary files and directories (manifest staging, downloaded tarballs) are cleaned up on all code paths (success and error). Use `defer` and `t.TempDir()` in tests. -- **No panics.** Never use `panic` in runtime code paths. Return errors and let the CLI handle them gracefully. -- **Output discipline.** Machine-readable data (tables, YAML, JSON) goes to stdout via `rootCmd.OutOrStdout()`. Human-readable status messages go to stderr via the `stderrLogger`. -- **Minimal surface.** Keep new exported APIs in `pkg/` to the minimum needed. Every export is a backward-compatibility commitment. - -## Project overview - -flux2 is the Flux CLI (`flux` command) and distribution repository. It is **not** a controller — it consumes CRD APIs from six independent controller repos (source-controller, kustomize-controller, helm-controller, notification-controller, image-reflector-controller, image-automation-controller). It serves two purposes: - -1. **CLI tool** — a Cobra-based binary that installs Flux onto Kubernetes clusters, bootstraps GitOps pipelines, and manages all Flux CRD objects (create, get, export, reconcile, suspend, resume, delete, diff, build, etc.). -2. **Distribution hub** — it bundles the Kustomize manifests for all Flux controllers and releases them as `manifests.tar.gz` on GitHub. Those manifests are also compiled into the binary itself via `//go:embed`. - -## Repository layout - -- `cmd/flux/` — all CLI source. Single `main` package with one file per command or resource type. `main.go` defines the root cobra command with global flags. `manifests.embed.go` embeds the generated controller manifests via `//go:embed`. -- `internal/build/` — `flux build kustomization` logic (kustomize-based diff/build, SOPS secret masking). -- `internal/flags/` — custom `pflag.Value` types providing enum validation (e.g. `LogLevel`, `ECDSACurve`, `RSAKeyBits`, `PublicKeyAlgorithm`, `DecryptionProvider`). -- `internal/tree/` — tree-printing helper for `flux tree kustomization`. -- `internal/utils/` — shared helpers: `KubeClient`, `KubeConfig`, `NewScheme` (registers all controller API groups), `Apply` (SSA-based two-phase apply), `ExecKubectlCommand`, `ValidateComponents`. -- `pkg/bootstrap/` — bootstrap orchestration: `Run()`, `PlainGitBootstrapper`, `ProviderBootstrapper`. `provider/` has the git provider factory (GitHub, GitLab, Gitea, Bitbucket). -- `pkg/log/` — `Logger` interface (`Actionf`, `Generatef`, `Waitingf`, `Successf`, `Warningf`, `Failuref`). -- `pkg/manifestgen/` — manifest generation for install, sync, kustomization, and source secrets. -- `pkg/printers/` — specialized printers `TablePrinter` and `DyffPrinter`. -- `pkg/status/` — `StatusChecker` using `fluxcd/cli-utils` kstatus polling. -- `pkg/uninstall/` — `flux uninstall` logic. -- `manifests/` — Kustomize bases per controller, RBAC, network policies, CRD references, and `scripts/bundle.sh` which runs `kustomize build` to generate `cmd/flux/manifests/`. -- `tests/integration/` — cloud e2e tests (Azure/GCP) with their own `go.mod` and Terraform infrastructure. -- `rfcs/` — Request for Comments documents for major design proposals and changes. - -## CLI architecture - -Commands are Cobra-based, organized as parent + per-resource children: -- Group files (`create.go`, `get.go`, `reconcile.go`, etc.) register the parent subcommand. -- Per-resource files (`create_kustomization.go`, `get_helmrelease.go`, etc.) register children. - -Core interfaces in `cmd/flux/` enable generic command implementations: -- `adapter` / `copyable` / `listAdapter` — wrap controller API types for generic CRUD. -- `reconcilable` — annotate-and-poll pattern for triggering reconciliation. -- `summarisable` — generic table output for `get` commands. - -Each resource type (e.g. `kustomizationAdapter` in `kustomization.go`) wraps the controller API type and implements these interfaces. Follow this pattern when adding new resource support. - -Commands interact with the Kubernetes API via `internal/utils.KubeClient()` → `client.WithWatch`. `internal/utils.NewScheme()` registers all six controller API groups plus core k8s types. `internal/utils.Apply()` implements SSA-based two-phase apply (CRDs/Namespaces first, then remaining objects). - -## Manifest pipeline - -1. `manifests/bases//` contains a Kustomize base per controller referencing the controller's GitHub release for CRDs and deployment manifests. -2. `manifests/install/kustomization.yaml` assembles all bases plus RBAC and policies. -3. `manifests/scripts/bundle.sh` runs `kustomize build` on each base, writing output to `cmd/flux/manifests/` (not checked in — generated). -4. The Makefile `$(EMBEDDED_MANIFESTS_TARGET)` runs `bundle.sh` and creates a sentinel file `cmd/flux/.manifests.done`. -5. `cmd/flux/manifests.embed.go` uses `//go:embed manifests/*.yaml` to compile everything into the binary. - -When modifying `manifests/`, always run `make build` and verify the generated output before committing. Never hand-edit files under `cmd/flux/manifests/`. - -## Build, test, lint - -All targets in the root `Makefile`. Go version tracks `go.mod`. - -- `make tidy` — tidy the root module and `tests/integration/`. -- `make fmt` / `make vet` — run in the root module. -- `make build` — builds `bin/flux` (CGO disabled, version injected via ldflags). Depends on embedded manifests being generated. -- `make build-dev` — builds with `DEV_VERSION`. -- `make install` / `make install-dev` — `go install` or copy to `/usr/local/bin`. -- `make test` — unit tests with envtest: runs `tidy fmt vet install-envtest`, then `go test ./... -coverprofile cover.out --tags=unit $(TEST_ARGS)`. -- `make e2e` — e2e tests against a live cluster: `go test ./cmd/flux/... --tags=e2e -v -failfast`. -- `make test-with-kind` — sets up a kind cluster, runs e2e, tears it down. -- `make install-envtest` — downloads `setup-envtest` and fetches k8s binaries into `testbin/`. - -Run a single test: `make test TEST_ARGS='-run TestCreate -v'`. - -## Codegen and generated files - -Check `go.mod` and the `Makefile` for current dependency and tool versions. The main codegen pipeline is the manifest bundle: - -```sh -./manifests/scripts/bundle.sh -``` - -Generated files (never hand-edit): - -- `cmd/flux/manifests/*.yaml` — generated by `bundle.sh` from `manifests/` sources. -- `cmd/flux/.manifests.done` — sentinel file tracking bundle state. - -Bump `fluxcd/pkg/*` and controller `api` modules as a set. Run `make tidy` after any bump. - -## Conventions - -- Standard `gofmt`. All exported names need doc comments. -- **Command pattern:** follow the existing group-parent + per-resource-child cobra structure. New resources need an adapter type implementing `adapter`, `copyable`, and the relevant command interfaces (`reconcilable`, `summarisable`, etc.). -- **Output:** stderr for human status messages via `stderrLogger` (Unicode symbols: `►` action, `✔` success, `✗` failure, `◎` waiting, `⚠️` warning, `✚` generate). Stdout for machine-readable data (tables, YAML, JSON) via `rootCmd.OutOrStdout()`. -- **Global flags:** kubeconfig flags come from `k8s.io/cli-runtime/pkg/genericclioptions.ConfigFlags`. Client tuning comes from `fluxcd/pkg/runtime/client.Options`. `FLUX_SYSTEM_NAMESPACE` env var overrides the default namespace. -- **SSA apply:** always use `internal/utils.Apply()` (two-phase: CRDs/Namespaces first, then rest). Do not apply manifests directly via the k8s client. -- **Reconcile triggering:** patch `meta.ReconcileRequestAnnotation` with a timestamp, then poll with `kstatus.Compute()` until ready. See `reconcile.go`. -- **Error handling:** return errors from `RunE`. Use `*RequestError` with exit codes for actionable CLI errors. Exit code 1 = warning, anything else = failure. -- **Flags:** use `internal/flags/` custom `pflag.Value` types for enum flags (providers, algorithms, sources). Add new enum types there. - -## Testing - -Three test suites with build tags: - -- **Unit** (`//go:build unit`): lives in `cmd/flux/*_test.go`. Uses `controller-runtime/envtest` for an in-process fake k8s API. CRDs are loaded from `cmd/flux/manifests/` (embedded manifests). Pattern: `cmdTestCase{args: "...", assert: assertGoldenFile("testdata/...")}`. The `executeCommand()` helper captures stdout. -- **E2e** (`//go:build e2e`): lives in `cmd/flux/*_test.go`. Requires a live cluster via `TEST_KUBECONFIG`. `TestMain` runs `flux install` for setup and teardown. -- **Integration** (`//go:build integration`): lives in `tests/integration/` with its own `go.mod`. Uses Terraform-provisioned cloud clusters. - -Golden files live in `cmd/flux/testdata/`. Update them with `go test ./cmd/flux/... --tags=unit -update`. - -Run a single unit test: `make test TEST_ARGS='-run TestInstall -v'`. - -## Gotchas and non-obvious rules - -- The `cmd/flux/manifests/` directory is **generated, not checked in**. It is created by `manifests/scripts/bundle.sh` and embedded into the binary. `make build` and `make test` both trigger the bundle if the sentinel file is stale. -- `kustomize` must be on `PATH` for `bundle.sh` to work. If you see "command not found" errors during build, install kustomize. -- `internal/utils.NewScheme()` registers all six controller API groups. Adding support for a new CRD type means updating the scheme registration there. -- The `VERSION` constant is injected via `-ldflags` at build time. In dev builds it defaults to `0.0.0-dev.0`. The embedded manifest version check (`isEmbeddedVersion`) determines whether `flux install` uses compiled-in manifests or downloads from GitHub. -- `resetCmdArgs()` in tests is critical — Cobra persists flag state between test runs. Every test case must reset to avoid pollution. -- `executeCommand()` captures stdout only. Stderr output (from `stderrLogger`) is not captured in test assertions. If your command's output goes to the wrong stream, tests will silently pass with empty golden files. -- The `adapter` / `listAdapter` interfaces use type assertions internally. If you add a new resource type and forget to implement an interface method, you'll get a runtime panic in the generic command handler, not a compile error. Add interface compliance checks (`var _ reconcilable = ...`). -- Bootstrap commands create real Git commits and push to real repos. E2e tests for bootstrap need careful cleanup. Do not add bootstrap e2e tests without a corresponding teardown. -- `pkg/` packages are importable by external consumers (e.g. Terraform provider, other tools). Treat their exported surface as public API. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 25a5f8b1..abfc1bb9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,129 +1,154 @@ # Contributing -Flux is [Apache 2.0 licensed](https://github.com/fluxcd/flux2/blob/main/LICENSE) and accepts contributions via GitHub pull requests. -This document outlines the conventions to get your contribution accepted. -We gratefully welcome improvements to documentation as well as code contributions. +Flux is [Apache 2.0 licensed](https://github.com/fluxcd/flux2/blob/main/LICENSE) and +accepts contributions via GitHub pull requests. This document outlines +some of the conventions on to make it easier to get your contribution +accepted. -If you are new to the project, we recommend starting with documentation improvements or -small bug fixes to get familiar with the codebase and the contribution process. - -## Project Structure - -The Flux project consists of a set of Kubernetes controllers and tools that implement the GitOps pattern. -The main repositories in the Flux project are: - -- [fluxcd/flux2](https://github.com/fluxcd/flux2): The Flux distribution and command-line interface (CLI) -- [fluxcd/pkg](https://github.com/fluxcd/pkg): The GitOps Toolkit Go SDK for building Flux controllers and CLI plugins -- [fluxcd/source-controller](https://github.com/fluxcd/source-controller): Kubernetes operator for managing sources (Git, OCI and Helm repositories, S3-compatible Buckets) -- [fluxcd/source-watcher](https://github.com/fluxcd/source-watcher): Kubernetes operator for advanced source composition and decomposition patterns -- [fluxcd/kustomize-controller](https://github.com/fluxcd/kustomize-controller): Kubernetes operator for building GitOps pipelines with Kustomize -- [fluxcd/helm-controller](https://github.com/fluxcd/helm-controller): Kubernetes operator for lifecycle management of Helm releases -- [fluxcd/notification-controller](https://github.com/fluxcd/notification-controller): Kubernetes operator for handling inbound and outbound events (alerts and webhook receivers) -- [fluxcd/image-reflector-controller](https://github.com/fluxcd/image-reflector-controller): Kubernetes operator for scanning container registries for new image tags and digests -- [fluxcd/image-automation-controller](https://github.com/fluxcd/image-automation-controller): Kubernetes operator for patching container image tags and digests in Git repositories -- [fluxcd/website](https://github.com/fluxcd/website): The Flux documentation website accessible at - -## AI Coding Assistants Guidance - -Using AI Agents to help write your PR is acceptable, but as the author, you are responsible -for understanding the code and the documentation you submit. Please review all the AI-generated -content and make sure it follows the guidelines in this document before submitting your PR. - -All Flux repositories contain an `AGENTS.md` file. You must point your AI Agent to -`AGENTS.md` and ask it to follow the guidelines and conventions described there. - -Trim down the verbiage in the PR description, commit messages and code comments. -When engaging with Flux maintainers please refrain from using AI Agents to -generate responses, we want to talk to you, not to your AI Agent. - -AI Agents **must not** add `Signed-off-by` or `Co-authored-by` tags to the commit message. -Only humans can legally certify the Developer Certificate of Origin ([DCO](https://developercertificate.org/)). - -You should disclose the use of AI Agents in the description of your PR and -in the commit message using the `Assisted-by: AGENT_NAME/LLM_VERSION` tag. - -Adding the `Assisted-by` tag to the commit message can be done with: - -```sh -git commit -s -m "Your commit message" --trailer "Assisted-by: /" -``` - -**Note** that the `Signed-off-by` tag is set via the `-s` flag using your real name and email -(`user.name` and `user.email` must be set in Git config). - -Example of a commit message disclosing the use of AI assistance: - -```text -Add version info to plugin listing - -Add a version column to the `flux plugin list` table output and populate -it with the semantic version info extracted from the plugin's recipe file. -For plugins installed via symlinks, the version is set to `unknown`. - -Signed-off-by: Jane Doe -Assisted-by: copilot/gpt-5.4 -``` +We gratefully welcome improvements to issues and documentation as well as to +code. ## Certificate of Origin -By contributing to this project you agree to the Developer Certificate of Origin (DCO). -This document was created by the Linux Kernel community and is a simple statement that you, -as a contributor, have the legal right to make the contribution. +By contributing to this project you agree to the Developer Certificate of +Origin (DCO). This document was created by the Linux Kernel community and is a +simple statement that you, as a contributor, have the legal right to make the +contribution. -We require all commits to be signed. By signing off with your signature, you certify that you wrote -the patch or otherwise have the right to contribute the material by the rules of the [DCO](https://raw.githubusercontent.com/fluxcd/flux2/refs/heads/main/DCO): +We require all commits to be signed. By signing off with your signature, you +certify that you wrote the patch or otherwise have the right to contribute the +material by the rules of the [DCO](DCO): `Signed-off-by: Jane Doe ` -The signature must contain your real name (sorry, no pseudonyms or anonymous contributions). -If your `user.name` and `user.email` are set in your Git config, +The signature must contain your real name +(sorry, no pseudonyms or anonymous contributions) +If your `user.name` and `user.email` are configured in your Git config, you can sign your commit automatically with `git commit -s`. +## Communications + +For realtime communications we use Slack: To join the conversation, simply +join the [CNCF](https://slack.cncf.io/) Slack workspace and use the +[#flux-contributors](https://cloud-native.slack.com/messages/flux-contributors/) channel. + +To discuss ideas and specifications we use [Github +Discussions](https://github.com/fluxcd/flux2/discussions). + +For announcements we use a mailing list as well. Simply subscribe to +[flux-dev on cncf.io](https://lists.cncf.io/g/cncf-flux-dev) +to join the conversation (there you can also add calendar invites +to your Google calendar for our [Flux +meeting](https://docs.google.com/document/d/1l_M0om0qUEN_NNiGgpqJ2tvsF2iioHkaARDeh6b70B0/view)). + +## Understanding Flux and the GitOps Toolkit + +If you are entirely new to Flux and the GitOps Toolkit, +you might want to take a look at the [introductory talk and demo](https://www.youtube.com/watch?v=qQBtSkgl7tI). + +This project is composed of: + +- [flux2](https://github.com/fluxcd/flux2): The Flux CLI +- [source-controller](https://github.com/fluxcd/source-controller): Kubernetes operator for managing sources (Git, OCI and Helm repositories, S3-compatible Buckets) +- [source-watcher](https://github.com/fluxcd/source-watcher): Kubernetes operator for advanced source composition and decomposition patterns +- [kustomize-controller](https://github.com/fluxcd/kustomize-controller): Kubernetes operator for building GitOps pipelines with Kustomize +- [helm-controller](https://github.com/fluxcd/helm-controller): Kubernetes operator for building GitOps pipelines with Helm +- [notification-controller](https://github.com/fluxcd/notification-controller): Kubernetes operator for handling inbound and outbound events +- [image-reflector-controller](https://github.com/fluxcd/image-reflector-controller): Kubernetes operator for scanning container registries +- [image-automation-controller](https://github.com/fluxcd/image-automation-controller): Kubernetes operator for patches container image tags in Git + +### Understanding the code + +To get started with developing controllers, you might want to review +[our guide](https://fluxcd.io/flux/gitops-toolkit/source-watcher/) which +walks you through writing a short and concise controller that watches out +for source changes. + +## How to run the test suite + +Prerequisites: + +* go >= 1.26 +* kubectl >= 1.33 +* kustomize >= 5.0 + +Install the [controller-runtime/envtest](https://github.com/kubernetes-sigs/controller-runtime/tree/master/tools/setup-envtest) binaries with: + +```bash +make install-envtest +``` + +Then you can run the unit tests with: + +```bash +make test +``` + +After [installing Kubernetes kind](https://kind.sigs.k8s.io/docs/user/quick-start#installation) on your machine, +create a cluster for testing with: + +```bash +make setup-kind +``` + +Then you can run the end-to-end tests with: + +```bash +make e2e +``` + +When the output of the Flux CLI changes, to automatically update the golden +files used in the test, pass `-update` flag to the test as: + +```bash +make e2e TEST_ARGS="-update" +``` + +Since not all packages use golden files for testing, `-update` argument must be +passed only for the packages that use golden files. Use the variables +`TEST_PKG_PATH` for unit tests and `E2E_TEST_PKG_PATH` for e2e tests, to set the +path of the target test package: + +```bash +# Unit test +make test TEST_PKG_PATH="./cmd/flux" TEST_ARGS="-update" +# e2e test +make e2e E2E_TEST_PKG_PATH="./cmd/flux" TEST_ARGS="-update" +``` + +Teardown the e2e environment with: + +```bash +make cleanup-kind +``` + ## Acceptance policy These things will make a PR more likely to be accepted: -- Addressing an open issue, if one doesn't exist, please open an issue to discuss the problem and the proposed solution before submitting a PR. -- Flux is GA software and we are committed to maintaining backward compatibility. If your contribution introduces a breaking change, expect for your PR to be rejected. -- New code and tests must follow the conventions in the existing code and tests. All new code must have good test coverage and be well documented. -- All top-level Go code and exported names should have doc comments, as should non-trivial unexported type or function declarations. -- Before submitting a PR, make sure that your code is properly formatted by running `make tidy fmt vet` and that all tests are passing by running `make test`. +- a well-described requirement +- tests for new code +- tests for old code! +- new code and tests follow the conventions in old code and tests +- a good commit message (see below) +- all code must abide [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments) +- names should abide [What's in a name](https://talks.golang.org/2014/names.slide#1) +- code must build on both Linux and Darwin, via plain `go build` +- code should have appropriate test coverage and tests should be written + to work with `go test` In general, we will merge a PR once one maintainer has endorsed it. For substantial changes, more people may become involved, and you might get asked to resubmit the PR or divide the changes into more than one PR. -## Format of the Commit Message +### Format of the Commit Message -For the Flux project we prefer the following rules: +For the GitOps Toolkit controllers we prefer the following rules for good commit messages: -- Limit the subject to 50 characters, start with a capital letter and do not end with a period. -- Explain what and why in the body, if more than a trivial change; wrap it at 72 characters. -- Use the imperative mood in the subject line (e.g., "Add support for X" instead of "Added support for X" or "Adds support for X"). -- Do not include GitHub mentions to issues in the commit message, use the PR description instead (e.g., "Fixes #123" or "Closes #123"). -- Do not include GitHub mentions to accounts (e.g., `@username` or `@team`) within the commit message. +- Limit the subject to 50 characters and write as the continuation + of the sentence "If applied, this commit will ..." +- Explain what and why in the body, if more than a trivial change; + wrap it at 72 characters. -## Pull Request Process - -Fork the repository and create a new branch for your changes, do not commit directly to the `main` branch. -Once you have made your changes and committed them, push your branch to your fork and open a pull request -against the `main` branch of the Flux repository. - -During the review process, you may be asked to make changes to your PR. Add commits to address the feedback -without force pushing, as this will make it easier for reviewers to see the changes. -Before committing, make sure to run `make test` to ensure that your code will pass the CI checks. - -When the review process is complete, you will be asked to **squash** the commits and **rebase** your branch. -**Do not merge** the `main` branch into your branch, instead, rebase your branch on top of the latest `main` -branch after **syncing your fork** with the latest changes from the Flux repository. After rebasing, -you can push your branch with the `--force-with-lease` option to update the PR. - -## Communications - -For realtime communications we use Slack. To reach out to the Flux maintainers and contributors, -join the [CNCF](https://slack.cncf.io/) Slack workspace and use the [#flux-contributors](https://cloud-native.slack.com/messages/flux-contributors/) channel. -To discuss ideas and specifications we use [GitHub Discussions](https://github.com/fluxcd/flux2/discussions). - -For announcements, we use a mailing list as well. Subscribe to -[flux-dev on cncf.io](https://lists.cncf.io/g/cncf-flux-dev), there you can also add calendar invites -to your Google calendar for our [Flux dev meeting](https://docs.google.com/document/d/1l_M0om0qUEN_NNiGgpqJ2tvsF2iioHkaARDeh6b70B0/view). +The [following article](https://chris.beams.io/posts/git-commit/#seven-rules) +has some more helpful advice on documenting your work. diff --git a/cmd/flux/build_artifact.go b/cmd/flux/build_artifact.go index 1dd681f8..9da0ca0e 100644 --- a/cmd/flux/build_artifact.go +++ b/cmd/flux/build_artifact.go @@ -22,7 +22,6 @@ import ( "fmt" "io" "os" - "path/filepath" "strings" "github.com/spf13/cobra" @@ -49,10 +48,9 @@ from the given directory or a single manifest file.`, } type buildArtifactFlags struct { - output string - path string - ignorePaths []string - resolveSymlinks bool + output string + path string + ignorePaths []string } var excludeOCI = append(strings.Split(sourceignore.ExcludeVCS, ","), strings.Split(sourceignore.ExcludeExt, ",")...) @@ -63,7 +61,6 @@ func init() { buildArtifactCmd.Flags().StringVarP(&buildArtifactArgs.path, "path", "p", "", "Path to the directory where the Kubernetes manifests are located.") buildArtifactCmd.Flags().StringVarP(&buildArtifactArgs.output, "output", "o", "artifact.tgz", "Path to where the artifact tgz file should be written.") buildArtifactCmd.Flags().StringSliceVar(&buildArtifactArgs.ignorePaths, "ignore-paths", excludeOCI, "set paths to ignore in .gitignore format") - buildArtifactCmd.Flags().BoolVar(&buildArtifactArgs.resolveSymlinks, "resolve-symlinks", false, "resolve symlinks by copying their targets into the artifact") buildCmd.AddCommand(buildArtifactCmd) } @@ -88,15 +85,6 @@ func buildArtifactCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("invalid path '%s', must point to an existing directory or file", path) } - if buildArtifactArgs.resolveSymlinks { - resolved, cleanupDir, err := resolveSymlinks(path) - if err != nil { - return fmt.Errorf("resolving symlinks failed: %w", err) - } - defer os.RemoveAll(cleanupDir) - path = resolved - } - logger.Actionf("building artifact from %s", path) ociClient := oci.NewClient(oci.DefaultOptions()) @@ -108,141 +96,6 @@ func buildArtifactCmdRun(cmd *cobra.Command, args []string) error { return nil } -// resolveSymlinks creates a temporary directory with symlinks resolved to their -// real file contents. This allows building artifacts from symlink trees (e.g., -// those created by Nix) where the actual files live outside the source directory. -// It returns the resolved path and the temporary directory path for cleanup. -func resolveSymlinks(srcPath string) (string, string, error) { - absPath, err := filepath.Abs(srcPath) - if err != nil { - return "", "", err - } - - info, err := os.Stat(absPath) - if err != nil { - return "", "", err - } - - // For a single file, resolve the symlink and return the path to the - // copied file within the temp dir, preserving file semantics for callers. - if !info.IsDir() { - resolved, err := filepath.EvalSymlinks(absPath) - if err != nil { - return "", "", fmt.Errorf("resolving symlink for %s: %w", absPath, err) - } - tmpDir, err := os.MkdirTemp("", "flux-artifact-*") - if err != nil { - return "", "", err - } - dst := filepath.Join(tmpDir, filepath.Base(absPath)) - if err := copyFile(resolved, dst); err != nil { - os.RemoveAll(tmpDir) - return "", "", err - } - return dst, tmpDir, nil - } - - tmpDir, err := os.MkdirTemp("", "flux-artifact-*") - if err != nil { - return "", "", err - } - - visited := make(map[string]bool) - if err := copyDir(absPath, tmpDir, visited); err != nil { - os.RemoveAll(tmpDir) - return "", "", err - } - - return tmpDir, tmpDir, nil -} - -// copyDir recursively copies the contents of srcDir to dstDir, resolving any -// symlinks encountered along the way. The visited map tracks resolved real -// directory paths to detect and break symlink cycles. -func copyDir(srcDir, dstDir string, visited map[string]bool) error { - real, err := filepath.EvalSymlinks(srcDir) - if err != nil { - return fmt.Errorf("resolving symlink %s: %w", srcDir, err) - } - abs, err := filepath.Abs(real) - if err != nil { - return fmt.Errorf("getting absolute path for %s: %w", real, err) - } - if visited[abs] { - return nil // break the cycle - } - visited[abs] = true - defer delete(visited, abs) - entries, err := os.ReadDir(srcDir) - if err != nil { - return err - } - - for _, entry := range entries { - srcPath := filepath.Join(srcDir, entry.Name()) - dstPath := filepath.Join(dstDir, entry.Name()) - - // Resolve symlinks to get the real path and info. - realPath, err := filepath.EvalSymlinks(srcPath) - if err != nil { - return fmt.Errorf("resolving symlink %s: %w", srcPath, err) - } - realInfo, err := os.Stat(realPath) - if err != nil { - return fmt.Errorf("stat resolved path %s: %w", realPath, err) - } - - if realInfo.IsDir() { - if err := os.MkdirAll(dstPath, realInfo.Mode()); err != nil { - return err - } - // Recursively copy the resolved directory contents. - if err := copyDir(realPath, dstPath, visited); err != nil { - return err - } - continue - } - - if !realInfo.Mode().IsRegular() { - continue - } - - if err := copyFile(realPath, dstPath); err != nil { - return err - } - } - - return nil -} - -func copyFile(src, dst string) error { - srcInfo, err := os.Stat(src) - if err != nil { - return err - } - - in, err := os.Open(src) - if err != nil { - return err - } - defer in.Close() - - if err := os.MkdirAll(filepath.Dir(dst), 0o755); err != nil { - return err - } - - out, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, srcInfo.Mode()) - if err != nil { - return err - } - defer out.Close() - - if _, err := io.Copy(out, in); err != nil { - return err - } - return out.Close() -} - func saveReaderToFile(reader io.Reader) (string, error) { b, err := io.ReadAll(bufio.NewReader(reader)) if err != nil { diff --git a/cmd/flux/build_artifact_test.go b/cmd/flux/build_artifact_test.go index 88ac278f..ba84186c 100644 --- a/cmd/flux/build_artifact_test.go +++ b/cmd/flux/build_artifact_test.go @@ -18,7 +18,6 @@ package main import ( "os" - "path/filepath" "strings" "testing" @@ -69,149 +68,3 @@ data: } } - -func Test_resolveSymlinks(t *testing.T) { - g := NewWithT(t) - - // Create source directory with a real file - srcDir := t.TempDir() - realFile := filepath.Join(srcDir, "real.yaml") - g.Expect(os.WriteFile(realFile, []byte("apiVersion: v1\nkind: Namespace\nmetadata:\n name: test\n"), 0o644)).To(Succeed()) - - // Create a directory with symlinks pointing to files outside it - symlinkDir := t.TempDir() - symlinkFile := filepath.Join(symlinkDir, "linked.yaml") - g.Expect(os.Symlink(realFile, symlinkFile)).To(Succeed()) - - // Also add a regular file in the symlink dir - regularFile := filepath.Join(symlinkDir, "regular.yaml") - g.Expect(os.WriteFile(regularFile, []byte("apiVersion: v1\nkind: ConfigMap\n"), 0o644)).To(Succeed()) - - // Create a symlinked subdirectory - subDir := filepath.Join(srcDir, "subdir") - g.Expect(os.MkdirAll(subDir, 0o755)).To(Succeed()) - g.Expect(os.WriteFile(filepath.Join(subDir, "nested.yaml"), []byte("nested"), 0o644)).To(Succeed()) - g.Expect(os.Symlink(subDir, filepath.Join(symlinkDir, "linkeddir"))).To(Succeed()) - - // Resolve symlinks - resolved, cleanupDir, err := resolveSymlinks(symlinkDir) - g.Expect(err).To(BeNil()) - t.Cleanup(func() { os.RemoveAll(cleanupDir) }) - - // Verify the regular file was copied - content, err := os.ReadFile(filepath.Join(resolved, "regular.yaml")) - g.Expect(err).To(BeNil()) - g.Expect(string(content)).To(Equal("apiVersion: v1\nkind: ConfigMap\n")) - - // Verify the symlinked file was resolved and copied - content, err = os.ReadFile(filepath.Join(resolved, "linked.yaml")) - g.Expect(err).To(BeNil()) - g.Expect(string(content)).To(ContainSubstring("kind: Namespace")) - - // Verify that the resolved file is a regular file, not a symlink - info, err := os.Lstat(filepath.Join(resolved, "linked.yaml")) - g.Expect(err).To(BeNil()) - g.Expect(info.Mode().IsRegular()).To(BeTrue()) - - // Verify that the symlinked directory was resolved and its contents were copied - content, err = os.ReadFile(filepath.Join(resolved, "linkeddir", "nested.yaml")) - g.Expect(err).To(BeNil()) - g.Expect(string(content)).To(Equal("nested")) - - // Verify that the file inside the symlinked directory is a regular file - info, err = os.Lstat(filepath.Join(resolved, "linkeddir", "nested.yaml")) - g.Expect(err).To(BeNil()) - g.Expect(info.Mode().IsRegular()).To(BeTrue()) -} - -func Test_resolveSymlinks_singleFile(t *testing.T) { - g := NewWithT(t) - - // Create a real file - srcDir := t.TempDir() - realFile := filepath.Join(srcDir, "manifest.yaml") - g.Expect(os.WriteFile(realFile, []byte("kind: ConfigMap"), 0o644)).To(Succeed()) - - // Create a symlink to the real file - linkDir := t.TempDir() - linkFile := filepath.Join(linkDir, "link.yaml") - g.Expect(os.Symlink(realFile, linkFile)).To(Succeed()) - - // Resolve the single symlinked file - resolved, cleanupDir, err := resolveSymlinks(linkFile) - g.Expect(err).To(BeNil()) - t.Cleanup(func() { os.RemoveAll(cleanupDir) }) - - // The returned path should be a file, not a directory - info, err := os.Stat(resolved) - g.Expect(err).To(BeNil()) - g.Expect(info.IsDir()).To(BeFalse()) - - // Verify contents - content, err := os.ReadFile(resolved) - g.Expect(err).To(BeNil()) - g.Expect(string(content)).To(Equal("kind: ConfigMap")) -} - -func Test_resolveSymlinks_cycle(t *testing.T) { - g := NewWithT(t) - - // Create a directory with a symlink cycle: dir/link -> dir - dir := t.TempDir() - g.Expect(os.WriteFile(filepath.Join(dir, "file.yaml"), []byte("data"), 0o644)).To(Succeed()) - g.Expect(os.Symlink(dir, filepath.Join(dir, "cycle"))).To(Succeed()) - - // resolveSymlinks should not infinite-loop - resolved, cleanupDir, err := resolveSymlinks(dir) - g.Expect(err).To(BeNil()) - t.Cleanup(func() { os.RemoveAll(cleanupDir) }) - - // The file should be copied - content, err := os.ReadFile(filepath.Join(resolved, "file.yaml")) - g.Expect(err).To(BeNil()) - g.Expect(string(content)).To(Equal("data")) - - // The cycle directory should exist but not cause infinite nesting - _, err = os.Stat(filepath.Join(resolved, "cycle")) - g.Expect(err).To(BeNil()) - - // There should NOT be deeply nested cycle/cycle/cycle/... paths - _, err = os.Stat(filepath.Join(resolved, "cycle", "cycle", "cycle")) - g.Expect(os.IsNotExist(err)).To(BeTrue()) -} - -func Test_resolveSymlinks_multipleLinksSameTarget(t *testing.T) { - g := NewWithT(t) - - // Create source directory with a real file inside a dir - srcDir := t.TempDir() - targetDir := filepath.Join(srcDir, "target") - g.Expect(os.MkdirAll(targetDir, 0o755)).To(Succeed()) - g.Expect(os.WriteFile(filepath.Join(targetDir, "file.yaml"), []byte("data"), 0o644)).To(Succeed()) - - // Create a directory with multiple symlinks pointing to targetDir - symlinkDir := t.TempDir() - - // Link 1 - link1 := filepath.Join(symlinkDir, "link1") - g.Expect(os.Symlink(targetDir, link1)).To(Succeed()) - - // Link 2 - link2 := filepath.Join(symlinkDir, "link2") - g.Expect(os.Symlink(targetDir, link2)).To(Succeed()) - - // Resolve symlinks - resolved, cleanupDir, err := resolveSymlinks(symlinkDir) - g.Expect(err).To(BeNil()) - t.Cleanup(func() { os.RemoveAll(cleanupDir) }) - - // Verify link1 has the file - content, err := os.ReadFile(filepath.Join(resolved, "link1", "file.yaml")) - g.Expect(err).To(BeNil()) - g.Expect(string(content)).To(Equal("data")) - - // Verify link2 ALSO has the file - content2, err := os.ReadFile(filepath.Join(resolved, "link2", "file.yaml")) - g.Expect(err).To(BeNil()) - g.Expect(string(content2)).To(Equal("data")) -} diff --git a/cmd/flux/build_kustomization.go b/cmd/flux/build_kustomization.go index 5b337ef5..2000faac 100644 --- a/cmd/flux/build_kustomization.go +++ b/cmd/flux/build_kustomization.go @@ -72,7 +72,6 @@ type buildKsFlags struct { strictSubst bool recursive bool localSources map[string]string - inMemoryBuild bool } var buildKsArgs buildKsFlags @@ -86,8 +85,6 @@ func init() { "When enabled, the post build substitutions will fail if a var without a default value is declared in files but is missing from the input vars.") buildKsCmd.Flags().BoolVarP(&buildKsArgs.recursive, "recursive", "r", false, "Recursively build Kustomizations") buildKsCmd.Flags().StringToStringVar(&buildKsArgs.localSources, "local-sources", nil, "Comma-separated list of repositories in format: Kind/namespace/name=path") - buildKsCmd.Flags().BoolVar(&buildKsArgs.inMemoryBuild, "in-memory-build", true, - "Use in-memory filesystem during build.") buildCmd.AddCommand(buildKsCmd) } @@ -133,7 +130,6 @@ func buildKsCmdRun(cmd *cobra.Command, args []string) (err error) { build.WithStrictSubstitute(buildKsArgs.strictSubst), build.WithRecursive(buildKsArgs.recursive), build.WithLocalSources(buildKsArgs.localSources), - build.WithInMemoryBuild(buildKsArgs.inMemoryBuild), ) } else { builder, err = build.NewBuilder(name, buildKsArgs.path, @@ -144,7 +140,6 @@ func buildKsCmdRun(cmd *cobra.Command, args []string) (err error) { build.WithStrictSubstitute(buildKsArgs.strictSubst), build.WithRecursive(buildKsArgs.recursive), build.WithLocalSources(buildKsArgs.localSources), - build.WithInMemoryBuild(buildKsArgs.inMemoryBuild), ) } diff --git a/cmd/flux/build_kustomization_test.go b/cmd/flux/build_kustomization_test.go index 723fb40a..7b49506e 100644 --- a/cmd/flux/build_kustomization_test.go +++ b/cmd/flux/build_kustomization_test.go @@ -52,12 +52,6 @@ func TestBuildKustomization(t *testing.T) { resultFile: "./testdata/build-kustomization/podinfo-result.yaml", assertFunc: "assertGoldenTemplateFile", }, - { - name: "build podinfo (on-disk)", - args: "build kustomization podinfo --path ./testdata/build-kustomization/podinfo --in-memory-build=false", - resultFile: "./testdata/build-kustomization/podinfo-result.yaml", - assertFunc: "assertGoldenTemplateFile", - }, { name: "build podinfo without service", args: "build kustomization podinfo --path ./testdata/build-kustomization/delete-service", @@ -76,24 +70,12 @@ func TestBuildKustomization(t *testing.T) { resultFile: "./testdata/build-kustomization/podinfo-with-ignore-result.yaml", assertFunc: "assertGoldenTemplateFile", }, - { - name: "build ignore (on-disk)", - args: "build kustomization podinfo --path ./testdata/build-kustomization/ignore --ignore-paths \"!configmap.yaml,!secret.yaml\" --in-memory-build=false", - resultFile: "./testdata/build-kustomization/podinfo-with-ignore-result.yaml", - assertFunc: "assertGoldenTemplateFile", - }, { name: "build with recursive", args: "build kustomization podinfo --path ./testdata/build-kustomization/podinfo-with-my-app --recursive --local-sources GitRepository/default/podinfo=./testdata/build-kustomization", resultFile: "./testdata/build-kustomization/podinfo-with-my-app-result.yaml", assertFunc: "assertGoldenTemplateFile", }, - { - name: "build with recursive (on-disk)", - args: "build kustomization podinfo --path ./testdata/build-kustomization/podinfo-with-my-app --recursive --local-sources GitRepository/default/podinfo=./testdata/build-kustomization --in-memory-build=false", - resultFile: "./testdata/build-kustomization/podinfo-with-my-app-result.yaml", - assertFunc: "assertGoldenTemplateFile", - }, } tmpl := map[string]string{ @@ -163,12 +145,6 @@ spec: resultFile: "./testdata/build-kustomization/podinfo-result.yaml", assertFunc: "assertGoldenTemplateFile", }, - { - name: "build podinfo (on-disk)", - args: "build kustomization podinfo --kustomization-file " + tmpFile + " --path ./testdata/build-kustomization/podinfo --in-memory-build=false", - resultFile: "./testdata/build-kustomization/podinfo-result.yaml", - assertFunc: "assertGoldenTemplateFile", - }, { name: "build podinfo without service", args: "build kustomization podinfo --kustomization-file " + tmpFile + " --path ./testdata/build-kustomization/delete-service", @@ -199,18 +175,6 @@ spec: resultFile: "./testdata/build-kustomization/podinfo-with-my-app-result.yaml", assertFunc: "assertGoldenTemplateFile", }, - { - name: "build with recursive (on-disk)", - args: "build kustomization podinfo --kustomization-file " + tmpFile + " --path ./testdata/build-kustomization/podinfo-with-my-app --recursive --local-sources GitRepository/default/podinfo=./testdata/build-kustomization --in-memory-build=false", - resultFile: "./testdata/build-kustomization/podinfo-with-my-app-result.yaml", - assertFunc: "assertGoldenTemplateFile", - }, - { - name: "build with recursive in dry-run mode (on-disk)", - args: "build kustomization podinfo --kustomization-file " + tmpFile + " --path ./testdata/build-kustomization/podinfo-with-my-app --recursive --local-sources GitRepository/default/podinfo=./testdata/build-kustomization --in-memory-build=false --dry-run", - resultFile: "./testdata/build-kustomization/podinfo-with-my-app-result.yaml", - assertFunc: "assertGoldenTemplateFile", - }, } tmpl := map[string]string{ @@ -277,12 +241,6 @@ func TestBuildKustomizationPathNormalization(t *testing.T) { resultFile: "./testdata/build-kustomization/podinfo-result.yaml", assertFunc: "assertGoldenTemplateFile", }, - { - name: "build with absolute path (on-disk)", - args: "build kustomization podinfo --path " + absTestDataPath + " --in-memory-build=false", - resultFile: "./testdata/build-kustomization/podinfo-result.yaml", - assertFunc: "assertGoldenTemplateFile", - }, { name: "build with complex relative path (parent dir)", args: "build kustomization podinfo --path ./testdata/build-kustomization/../build-kustomization/podinfo", diff --git a/cmd/flux/create_kustomization.go b/cmd/flux/create_kustomization.go index 45740c34..a7ae93ab 100644 --- a/cmd/flux/create_kustomization.go +++ b/cmd/flux/create_kustomization.go @@ -136,9 +136,6 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error { if !strings.HasPrefix(kustomizationArgs.path.String(), "./") { return fmt.Errorf("path must begin with ./") } - if kustomizationArgs.source.Name == "" { - return fmt.Errorf("source is required") - } if !createArgs.export { logger.Generatef("generating Kustomization") diff --git a/cmd/flux/create_kustomization_test.go b/cmd/flux/create_kustomization_test.go deleted file mode 100644 index ee743816..00000000 --- a/cmd/flux/create_kustomization_test.go +++ /dev/null @@ -1,48 +0,0 @@ -//go:build unit -// +build unit - -/* -Copyright 2026 The Flux authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import "testing" - -func TestCreateKustomization(t *testing.T) { - tests := []struct { - name string - args string - assert assertFunc - }{ - { - // A user creating a kustomization without --source gets a confusing - // API-level error about spec.sourceRef.kind instead of a clear message. - name: "missing source", - args: "create kustomization my-app --path=./deploy --export", - assert: assertError("source is required"), - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - cmd := cmdTestCase{ - args: tt.args, - assert: tt.assert, - } - cmd.runTestCmd(t) - }) - } -} diff --git a/cmd/flux/create_receiver.go b/cmd/flux/create_receiver.go index 26000b2d..ad6436cf 100644 --- a/cmd/flux/create_receiver.go +++ b/cmd/flux/create_receiver.go @@ -30,7 +30,6 @@ import ( notificationv1 "github.com/fluxcd/notification-controller/api/v1" "github.com/fluxcd/pkg/apis/meta" - "github.com/fluxcd/flux2/v2/internal/flags" "github.com/fluxcd/flux2/v2/internal/utils" ) @@ -50,7 +49,7 @@ var createReceiverCmd = &cobra.Command{ } type receiverFlags struct { - receiverType flags.ReceiverType + receiverType string secretRef string events []string resources []string @@ -59,7 +58,7 @@ type receiverFlags struct { var receiverArgs receiverFlags func init() { - createReceiverCmd.Flags().Var(&receiverArgs.receiverType, "type", receiverArgs.receiverType.Description()) + createReceiverCmd.Flags().StringVar(&receiverArgs.receiverType, "type", "", "") createReceiverCmd.Flags().StringVar(&receiverArgs.secretRef, "secret-ref", "", "") createReceiverCmd.Flags().StringSliceVar(&receiverArgs.events, "event", []string{}, "also accepts comma-separated values") createReceiverCmd.Flags().StringSliceVar(&receiverArgs.resources, "resource", []string{}, "also accepts comma-separated values") @@ -110,7 +109,7 @@ func createReceiverCmdRun(cmd *cobra.Command, args []string) error { Labels: sourceLabels, }, Spec: notificationv1.ReceiverSpec{ - Type: receiverArgs.receiverType.String(), + Type: receiverArgs.receiverType, Events: receiverArgs.events, Resources: resources, SecretRef: meta.LocalObjectReference{ diff --git a/cmd/flux/create_secret.go b/cmd/flux/create_secret.go index 1a4cb025..376fd24f 100644 --- a/cmd/flux/create_secret.go +++ b/cmd/flux/create_secret.go @@ -56,22 +56,6 @@ func upsertSecret(ctx context.Context, kubeClient client.Client, secret corev1.S } existing.StringData = secret.StringData - if secret.Annotations != nil { - if existing.Annotations == nil { - existing.Annotations = make(map[string]string) - } - for k, v := range secret.Annotations { - existing.Annotations[k] = v - } - } - if secret.Labels != nil { - if existing.Labels == nil { - existing.Labels = make(map[string]string) - } - for k, v := range secret.Labels { - existing.Labels[k] = v - } - } if err := kubeClient.Update(ctx, &existing); err != nil { return err } diff --git a/cmd/flux/create_secret_receiver.go b/cmd/flux/create_secret_receiver.go deleted file mode 100644 index 50eafbea..00000000 --- a/cmd/flux/create_secret_receiver.go +++ /dev/null @@ -1,134 +0,0 @@ -/* -Copyright 2026 The Flux authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "context" - "fmt" - - "github.com/spf13/cobra" - corev1 "k8s.io/api/core/v1" - "sigs.k8s.io/yaml" - - notificationv1 "github.com/fluxcd/notification-controller/api/v1" - - "github.com/fluxcd/flux2/v2/internal/flags" - "github.com/fluxcd/flux2/v2/internal/utils" - "github.com/fluxcd/flux2/v2/pkg/manifestgen/sourcesecret" -) - -var createSecretReceiverCmd = &cobra.Command{ - Use: "receiver [name]", - Short: "Create or update a Kubernetes secret for a Receiver webhook", - Long: `The create secret receiver command generates a Kubernetes secret with -the token used for webhook payload validation and an annotation with the -computed webhook URL.`, - Example: ` # Create a receiver secret for a GitHub webhook - flux create secret receiver github-receiver \ - --namespace=my-namespace \ - --type=github \ - --hostname=flux.example.com \ - --export - - # Create a receiver secret for GCR with email claim - flux create secret receiver gcr-receiver \ - --namespace=my-namespace \ - --type=gcr \ - --hostname=flux.example.com \ - --email-claim=sa@project.iam.gserviceaccount.com \ - --export`, - RunE: createSecretReceiverCmdRun, -} - -type secretReceiverFlags struct { - receiverType flags.ReceiverType - token string - hostname string - emailClaim string - audienceClaim string -} - -var secretReceiverArgs secretReceiverFlags - -func init() { - createSecretReceiverCmd.Flags().Var(&secretReceiverArgs.receiverType, "type", secretReceiverArgs.receiverType.Description()) - createSecretReceiverCmd.Flags().StringVar(&secretReceiverArgs.token, "token", "", "webhook token used for payload validation and URL computation, auto-generated if not specified") - createSecretReceiverCmd.Flags().StringVar(&secretReceiverArgs.hostname, "hostname", "", "hostname for the webhook URL e.g. flux.example.com") - createSecretReceiverCmd.Flags().StringVar(&secretReceiverArgs.emailClaim, "email-claim", "", "IAM service account email, required for gcr type") - createSecretReceiverCmd.Flags().StringVar(&secretReceiverArgs.audienceClaim, "audience-claim", "", "custom OIDC token audience for gcr type, defaults to the webhook URL") - - createSecretCmd.AddCommand(createSecretReceiverCmd) -} - -func createSecretReceiverCmdRun(cmd *cobra.Command, args []string) error { - name := args[0] - - if secretReceiverArgs.receiverType == "" { - return fmt.Errorf("--type is required") - } - - if secretReceiverArgs.hostname == "" { - return fmt.Errorf("--hostname is required") - } - - if secretReceiverArgs.receiverType.String() == notificationv1.GCRReceiver && secretReceiverArgs.emailClaim == "" { - return fmt.Errorf("--email-claim is required for gcr receiver type") - } - - labels, err := parseLabels() - if err != nil { - return err - } - - opts := sourcesecret.Options{ - Name: name, - Namespace: *kubeconfigArgs.Namespace, - Labels: labels, - ReceiverType: secretReceiverArgs.receiverType.String(), - Token: secretReceiverArgs.token, - Hostname: secretReceiverArgs.hostname, - EmailClaim: secretReceiverArgs.emailClaim, - AudienceClaim: secretReceiverArgs.audienceClaim, - } - - secret, err := sourcesecret.GenerateReceiver(opts) - if err != nil { - return err - } - - if createArgs.export { - rootCmd.Println(secret.Content) - return nil - } - - ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout) - defer cancel() - kubeClient, err := utils.KubeClient(kubeconfigArgs, kubeclientOptions) - if err != nil { - return err - } - var s corev1.Secret - if err := yaml.Unmarshal([]byte(secret.Content), &s); err != nil { - return err - } - if err := upsertSecret(ctx, kubeClient, s); err != nil { - return err - } - - logger.Actionf("receiver secret '%s' created in '%s' namespace", name, *kubeconfigArgs.Namespace) - return nil -} diff --git a/cmd/flux/create_secret_receiver_test.go b/cmd/flux/create_secret_receiver_test.go deleted file mode 100644 index 383f2371..00000000 --- a/cmd/flux/create_secret_receiver_test.go +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright 2026 The Flux authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package main - -import ( - "testing" -) - -func TestCreateReceiverSecret(t *testing.T) { - tests := []struct { - name string - args string - assert assertFunc - }{ - { - name: "missing type", - args: "create secret receiver test-secret --token=t --hostname=h", - assert: assertError("--type is required"), - }, - { - name: "invalid type", - args: "create secret receiver test-secret --type=invalid --token=t --hostname=h", - assert: assertError("invalid argument \"invalid\" for \"--type\" flag: receiver type 'invalid' is not supported, must be one of: generic, generic-hmac, github, gitlab, bitbucket, harbor, dockerhub, quay, gcr, nexus, acr, cdevents"), - }, - { - name: "missing hostname", - args: "create secret receiver test-secret --type=github --token=t", - assert: assertError("--hostname is required"), - }, - { - name: "gcr missing email-claim", - args: "create secret receiver test-secret --type=gcr --token=t --hostname=h", - assert: assertError("--email-claim is required for gcr receiver type"), - }, - { - name: "github receiver secret", - args: "create secret receiver receiver-secret --type=github --token=test-token --hostname=flux.example.com --namespace=my-namespace --export", - assert: assertGoldenFile("testdata/create_secret/receiver/secret-receiver.yaml"), - }, - { - name: "gcr receiver secret", - args: "create secret receiver gcr-secret --type=gcr --token=test-token --hostname=flux.example.com --email-claim=sa@project.iam.gserviceaccount.com --namespace=my-namespace --export", - assert: assertGoldenFile("testdata/create_secret/receiver/secret-receiver-gcr.yaml"), - }, - { - name: "gcr receiver secret with custom audience", - args: "create secret receiver gcr-secret --type=gcr --token=test-token --hostname=flux.example.com --email-claim=sa@project.iam.gserviceaccount.com --audience-claim=https://custom.audience.example.com --namespace=my-namespace --export", - assert: assertGoldenFile("testdata/create_secret/receiver/secret-receiver-gcr-audience.yaml"), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - cmd := cmdTestCase{ - args: tt.args, - assert: tt.assert, - } - cmd.runTestCmd(t) - }) - } -} diff --git a/cmd/flux/diff_kustomization.go b/cmd/flux/diff_kustomization.go index bc8164f0..0480e293 100644 --- a/cmd/flux/diff_kustomization.go +++ b/cmd/flux/diff_kustomization.go @@ -62,7 +62,6 @@ type diffKsFlags struct { strictSubst bool recursive bool localSources map[string]string - inMemoryBuild bool } var diffKsArgs diffKsFlags @@ -76,8 +75,6 @@ func init() { "When enabled, the post build substitutions will fail if a var without a default value is declared in files but is missing from the input vars.") diffKsCmd.Flags().BoolVarP(&diffKsArgs.recursive, "recursive", "r", false, "Recursively diff Kustomizations") diffKsCmd.Flags().StringToStringVar(&diffKsArgs.localSources, "local-sources", nil, "Comma-separated list of repositories in format: Kind/namespace/name=path") - diffKsCmd.Flags().BoolVar(&diffKsArgs.inMemoryBuild, "in-memory-build", true, - "Use in-memory filesystem during build.") diffCmd.AddCommand(diffKsCmd) } @@ -116,7 +113,6 @@ func diffKsCmdRun(cmd *cobra.Command, args []string) error { build.WithRecursive(diffKsArgs.recursive), build.WithLocalSources(diffKsArgs.localSources), build.WithSingleKustomization(), - build.WithInMemoryBuild(diffKsArgs.inMemoryBuild), ) } else { builder, err = build.NewBuilder(name, diffKsArgs.path, @@ -128,7 +124,6 @@ func diffKsCmdRun(cmd *cobra.Command, args []string) error { build.WithRecursive(diffKsArgs.recursive), build.WithLocalSources(diffKsArgs.localSources), build.WithSingleKustomization(), - build.WithInMemoryBuild(diffKsArgs.inMemoryBuild), ) } diff --git a/cmd/flux/get_helmrelease.go b/cmd/flux/get_helmrelease.go index 08f88bd9..c5a4b67e 100644 --- a/cmd/flux/get_helmrelease.go +++ b/cmd/flux/get_helmrelease.go @@ -28,22 +28,13 @@ import ( helmv2 "github.com/fluxcd/helm-controller/api/v2" ) -type getHelmReleaseFlags struct { - showSource bool -} - -var getHrArgs getHelmReleaseFlags - var getHelmReleaseCmd = &cobra.Command{ Use: "helmreleases", Aliases: []string{"hr", "helmrelease"}, Short: "Get HelmRelease statuses", Long: "The get helmreleases command prints the statuses of the resources.", Example: ` # List all Helm releases and their status - flux get helmreleases - - # List all Helm releases with source information - flux get helmreleases --show-source`, + flux get helmreleases`, ValidArgsFunction: resourceNamesCompletionFunc(helmv2.GroupVersion.WithKind(helmv2.HelmReleaseKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ @@ -78,7 +69,6 @@ var getHelmReleaseCmd = &cobra.Command{ } func init() { - getHelmReleaseCmd.Flags().BoolVar(&getHrArgs.showSource, "show-source", false, "show the source reference for each helmrelease") getCmd.AddCommand(getHelmReleaseCmd) } @@ -89,45 +79,16 @@ func getHelmReleaseRevision(helmRelease helmv2.HelmRelease) string { return helmRelease.Status.LastAttemptedRevision } -func getHelmReleaseSource(item helmv2.HelmRelease) string { - if item.Spec.ChartRef != nil { - ns := item.Spec.ChartRef.Namespace - if ns == "" { - ns = item.GetNamespace() - } - return fmt.Sprintf("%s/%s/%s", - item.Spec.ChartRef.Kind, - ns, - item.Spec.ChartRef.Name) - } - ns := item.Spec.Chart.Spec.SourceRef.Namespace - if ns == "" { - ns = item.GetNamespace() - } - return fmt.Sprintf("%s/%s/%s", - item.Spec.Chart.Spec.SourceRef.Kind, - ns, - item.Spec.Chart.Spec.SourceRef.Name) -} - func (a helmReleaseListAdapter) summariseItem(i int, includeNamespace bool, includeKind bool) []string { item := a.Items[i] revision := getHelmReleaseRevision(item) status, msg := statusAndMessage(item.Status.Conditions) - row := nameColumns(&item, includeNamespace, includeKind) - if getHrArgs.showSource { - row = append(row, getHelmReleaseSource(item)) - } - return append(row, + return append(nameColumns(&item, includeNamespace, includeKind), revision, cases.Title(language.English).String(strconv.FormatBool(item.Spec.Suspend)), status, msg) } func (a helmReleaseListAdapter) headers(includeNamespace bool) []string { - headers := []string{"Name"} - if getHrArgs.showSource { - headers = append(headers, "Source") - } - headers = append(headers, "Revision", "Suspended", "Ready", "Message") + headers := []string{"Name", "Revision", "Suspended", "Ready", "Message"} if includeNamespace { headers = append([]string{"Namespace"}, headers...) } diff --git a/cmd/flux/get_kustomization.go b/cmd/flux/get_kustomization.go index 97a1d93b..a95ec655 100644 --- a/cmd/flux/get_kustomization.go +++ b/cmd/flux/get_kustomization.go @@ -30,22 +30,13 @@ import ( "github.com/fluxcd/flux2/v2/internal/utils" ) -type getKustomizationFlags struct { - showSource bool -} - -var getKsArgs getKustomizationFlags - var getKsCmd = &cobra.Command{ Use: "kustomizations", Aliases: []string{"ks", "kustomization"}, Short: "Get Kustomization statuses", Long: `The get kustomizations command prints the statuses of the resources.`, Example: ` # List all kustomizations and their status - flux get kustomizations - - # List all kustomizations with source information - flux get kustomizations --show-source`, + flux get kustomizations`, ValidArgsFunction: resourceNamesCompletionFunc(kustomizev1.GroupVersion.WithKind(kustomizev1.KustomizationKind)), RunE: func(cmd *cobra.Command, args []string) error { get := getCommand{ @@ -83,7 +74,6 @@ var getKsCmd = &cobra.Command{ } func init() { - getKsCmd.Flags().BoolVar(&getKsArgs.showSource, "show-source", false, "show the source reference for each kustomization") getCmd.AddCommand(getKsCmd) } @@ -93,27 +83,12 @@ func (a kustomizationListAdapter) summariseItem(i int, includeNamespace bool, in status, msg := statusAndMessage(item.Status.Conditions) revision = utils.TruncateHex(revision) msg = utils.TruncateHex(msg) - row := nameColumns(&item, includeNamespace, includeKind) - if getKsArgs.showSource { - sourceNs := item.Spec.SourceRef.Namespace - if sourceNs == "" { - sourceNs = item.GetNamespace() - } - row = append(row, fmt.Sprintf("%s/%s/%s", - item.Spec.SourceRef.Kind, - sourceNs, - item.Spec.SourceRef.Name)) - } - return append(row, + return append(nameColumns(&item, includeNamespace, includeKind), revision, cases.Title(language.English).String(strconv.FormatBool(item.Spec.Suspend)), status, msg) } func (a kustomizationListAdapter) headers(includeNamespace bool) []string { - headers := []string{"Name"} - if getKsArgs.showSource { - headers = append(headers, "Source") - } - headers = append(headers, "Revision", "Suspended", "Ready", "Message") + headers := []string{"Name", "Revision", "Suspended", "Ready", "Message"} if includeNamespace { headers = append([]string{"Namespace"}, headers...) } diff --git a/cmd/flux/main_test.go b/cmd/flux/main_test.go index 78159920..48c2549b 100644 --- a/cmd/flux/main_test.go +++ b/cmd/flux/main_test.go @@ -456,7 +456,6 @@ func resetCmdArgs() { secretGitArgs = NewSecretGitFlags() secretGitHubAppArgs = secretGitHubAppFlags{} secretProxyArgs = secretProxyFlags{} - secretReceiverArgs = secretReceiverFlags{} secretHelmArgs = secretHelmFlags{} secretTLSArgs = secretTLSFlags{} sourceBucketArgs = sourceBucketFlags{} diff --git a/cmd/flux/push_artifact.go b/cmd/flux/push_artifact.go index 237c2593..c37f0ef1 100644 --- a/cmd/flux/push_artifact.go +++ b/cmd/flux/push_artifact.go @@ -103,18 +103,17 @@ The command can read the credentials from '~/.docker/config.json' but they can a } type pushArtifactFlags struct { - path string - source string - revision string - creds string - provider flags.SourceOCIProvider - ignorePaths []string - annotations []string - output string - debug bool - reproducible bool - insecure bool - resolveSymlinks bool + path string + source string + revision string + creds string + provider flags.SourceOCIProvider + ignorePaths []string + annotations []string + output string + debug bool + reproducible bool + insecure bool } var pushArtifactArgs = newPushArtifactFlags() @@ -138,7 +137,6 @@ func init() { pushArtifactCmd.Flags().BoolVarP(&pushArtifactArgs.debug, "debug", "", false, "display logs from underlying library") pushArtifactCmd.Flags().BoolVar(&pushArtifactArgs.reproducible, "reproducible", false, "ensure reproducible image digests by setting the created timestamp to '1970-01-01T00:00:00Z'") pushArtifactCmd.Flags().BoolVar(&pushArtifactArgs.insecure, "insecure-registry", false, "allows artifacts to be pushed without TLS") - pushArtifactCmd.Flags().BoolVar(&pushArtifactArgs.resolveSymlinks, "resolve-symlinks", false, "resolve symlinks by copying their targets into the artifact") pushCmd.AddCommand(pushArtifactCmd) } @@ -185,15 +183,6 @@ func pushArtifactCmdRun(cmd *cobra.Command, args []string) error { return fmt.Errorf("invalid path '%s', must point to an existing directory or file: %w", path, err) } - if pushArtifactArgs.resolveSymlinks { - resolved, cleanupDir, err := resolveSymlinks(path) - if err != nil { - return fmt.Errorf("resolving symlinks failed: %w", err) - } - defer os.RemoveAll(cleanupDir) - path = resolved - } - annotations := map[string]string{} for _, annotation := range pushArtifactArgs.annotations { kv := strings.Split(annotation, "=") diff --git a/cmd/flux/reconcile.go b/cmd/flux/reconcile.go index 9f0787bd..ffdcce91 100644 --- a/cmd/flux/reconcile.go +++ b/cmd/flux/reconcile.go @@ -152,14 +152,7 @@ func reconciliationHandled(kubeClient client.Client, namespacedName types.Namesp return false, err } - switch result.Status { - case kstatus.CurrentStatus: - return true, nil - case kstatus.InProgressStatus: - return false, nil - default: - return false, fmt.Errorf("%s", result.Message) - } + return result.Status == kstatus.CurrentStatus, nil } } diff --git a/cmd/flux/resume.go b/cmd/flux/resume.go index e531ecee..fe23a411 100644 --- a/cmd/flux/resume.go +++ b/cmd/flux/resume.go @@ -126,17 +126,6 @@ func (resume resumeCommand) run(cmd *cobra.Command, args []string) error { resume.printMessage(reconcileResps) - // Return an error if any reconciliation failed - var failedCount int - for _, r := range reconcileResps { - if r.resumable != nil && r.err != nil { - failedCount++ - } - } - if failedCount > 0 { - return fmt.Errorf("reconciliation failed for %d %s(s)", failedCount, resume.kind) - } - return nil } diff --git a/cmd/flux/testdata/create_secret/receiver/secret-receiver-gcr-audience.yaml b/cmd/flux/testdata/create_secret/receiver/secret-receiver-gcr-audience.yaml deleted file mode 100644 index 9e52a56b..00000000 --- a/cmd/flux/testdata/create_secret/receiver/secret-receiver-gcr-audience.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -apiVersion: v1 -kind: Secret -metadata: - annotations: - notification.toolkit.fluxcd.io/webhook: https://flux.example.com/hook/6d6c55e9affb9d1e0d101ce604ae4270880ec1ff24d1bd2d928fcd64243d21a4 - name: gcr-secret - namespace: my-namespace -stringData: - audience: https://custom.audience.example.com - email: sa@project.iam.gserviceaccount.com - token: test-token - diff --git a/cmd/flux/testdata/create_secret/receiver/secret-receiver-gcr.yaml b/cmd/flux/testdata/create_secret/receiver/secret-receiver-gcr.yaml deleted file mode 100644 index ff4c88b4..00000000 --- a/cmd/flux/testdata/create_secret/receiver/secret-receiver-gcr.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -apiVersion: v1 -kind: Secret -metadata: - annotations: - notification.toolkit.fluxcd.io/webhook: https://flux.example.com/hook/6d6c55e9affb9d1e0d101ce604ae4270880ec1ff24d1bd2d928fcd64243d21a4 - name: gcr-secret - namespace: my-namespace -stringData: - audience: https://flux.example.com/hook/6d6c55e9affb9d1e0d101ce604ae4270880ec1ff24d1bd2d928fcd64243d21a4 - email: sa@project.iam.gserviceaccount.com - token: test-token - diff --git a/cmd/flux/testdata/create_secret/receiver/secret-receiver.yaml b/cmd/flux/testdata/create_secret/receiver/secret-receiver.yaml deleted file mode 100644 index f1f63759..00000000 --- a/cmd/flux/testdata/create_secret/receiver/secret-receiver.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -apiVersion: v1 -kind: Secret -metadata: - annotations: - notification.toolkit.fluxcd.io/webhook: https://flux.example.com/hook/106120121d366c2f67e93200f6c1dbe938235eb588daa5e8c0516d3a77ac1dee - name: receiver-secret - namespace: my-namespace -stringData: - token: test-token - diff --git a/docs/release/release-notes-template.md b/docs/release/release-notes-template.md index 5ad01f56..2a05d5c5 100644 --- a/docs/release/release-notes-template.md +++ b/docs/release/release-notes-template.md @@ -26,8 +26,6 @@ The following template can be used for the GitHub release page: -ℹ️ Please follow the [Upgrade Procedure for Flux v2.7+](https://github.com/fluxcd/flux2/discussions/5572) for a smooth upgrade from Flux v2.6 to the latest version. - ### Fixes and improvements @@ -38,7 +36,7 @@ The following template can be used for the GitHub release page: ## Components changelog -- -controller [v](https://github.com/fluxcd/-controller/blob//CHANGELOG.md) +- -controller [v](https://github.com/fluxcd/-controller/blob//CHANGELOG.md ## CLI changelog diff --git a/go.mod b/go.mod index 5563d076..cecd0b06 100644 --- a/go.mod +++ b/go.mod @@ -9,31 +9,31 @@ require ( github.com/Masterminds/semver/v3 v3.4.0 github.com/ProtonMail/go-crypto v1.3.0 github.com/cyphar/filepath-securejoin v0.6.1 - github.com/distribution/distribution/v3 v3.1.0 + github.com/distribution/distribution/v3 v3.0.0 github.com/fluxcd/cli-utils v0.37.2-flux.1 github.com/fluxcd/go-git-providers v0.26.0 github.com/fluxcd/helm-controller/api v1.5.3 github.com/fluxcd/image-automation-controller/api v1.1.1 github.com/fluxcd/image-reflector-controller/api v1.1.1 - github.com/fluxcd/kustomize-controller/api v1.8.3 - github.com/fluxcd/notification-controller/api v1.8.3 - github.com/fluxcd/pkg/apis/event v0.25.0 - github.com/fluxcd/pkg/apis/meta v1.26.0 - github.com/fluxcd/pkg/auth v0.40.0 - github.com/fluxcd/pkg/chartutil v1.23.0 + github.com/fluxcd/kustomize-controller/api v1.8.2 + github.com/fluxcd/notification-controller/api v1.8.2 + github.com/fluxcd/pkg/apis/event v0.24.1 + github.com/fluxcd/pkg/apis/meta v1.25.1 + github.com/fluxcd/pkg/auth v0.38.4 + github.com/fluxcd/pkg/chartutil v1.22.1 github.com/fluxcd/pkg/envsubst v1.5.0 - github.com/fluxcd/pkg/git v0.46.0 - github.com/fluxcd/pkg/kustomize v1.29.0 - github.com/fluxcd/pkg/oci v0.63.0 - github.com/fluxcd/pkg/runtime v0.103.0 + github.com/fluxcd/pkg/git v0.43.1 + github.com/fluxcd/pkg/kustomize v1.27.1 + github.com/fluxcd/pkg/oci v0.60.1 + github.com/fluxcd/pkg/runtime v0.100.4 github.com/fluxcd/pkg/sourceignore v0.17.0 - github.com/fluxcd/pkg/ssa v0.70.0 + github.com/fluxcd/pkg/ssa v0.67.3 github.com/fluxcd/pkg/ssh v0.24.0 github.com/fluxcd/pkg/tar v0.17.0 - github.com/fluxcd/pkg/version v0.14.0 - github.com/fluxcd/source-controller/api v1.8.2 + github.com/fluxcd/pkg/version v0.12.0 + github.com/fluxcd/source-controller/api v1.8.1 github.com/fluxcd/source-watcher/api/v2 v2.1.1 - github.com/go-git/go-git/v5 v5.17.1 + github.com/go-git/go-git/v5 v5.16.5 github.com/go-logr/logr v1.4.3 github.com/gonvenience/bunt v1.4.2 github.com/gonvenience/ytbx v1.4.7 @@ -50,9 +50,9 @@ require ( github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 github.com/spf13/cobra v1.10.2 github.com/theckman/yacspin v0.13.12 - golang.org/x/crypto v0.50.0 - golang.org/x/term v0.42.0 - golang.org/x/text v0.36.0 + golang.org/x/crypto v0.48.0 + golang.org/x/term v0.40.0 + golang.org/x/text v0.34.0 k8s.io/api v0.35.2 k8s.io/apiextensions-apiserver v0.35.2 k8s.io/apimachinery v0.35.2 @@ -102,7 +102,7 @@ require ( github.com/aws/smithy-go v1.24.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/bshuster-repo/logrus-logstash-hook v1.1.0 // indirect + github.com/bshuster-repo/logrus-logstash-hook v1.0.0 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect @@ -117,8 +117,8 @@ require ( github.com/distribution/reference v0.6.0 // indirect github.com/docker/cli v29.2.0+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker-credential-helpers v0.9.5 // indirect - github.com/docker/go-events v0.0.0-20250808211157-605354379745 // indirect + github.com/docker/docker-credential-helpers v0.9.3 // indirect + github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/emirpasic/gods v1.18.1 // indirect @@ -128,7 +128,7 @@ require ( github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fluxcd/pkg/apis/acl v0.9.0 // indirect - github.com/fluxcd/pkg/apis/kustomize v1.16.0 // indirect + github.com/fluxcd/pkg/apis/kustomize v1.15.1 // indirect github.com/fluxcd/pkg/cache v0.13.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect @@ -136,7 +136,7 @@ require ( github.com/go-errors/errors v1.5.1 // indirect github.com/go-fed/httpsig v1.1.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.8.0 // indirect + github.com/go-git/go-billy/v5 v5.7.0 // indirect github.com/go-ldap/ldap/v3 v3.4.10 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.21.1 // indirect @@ -159,7 +159,7 @@ require ( github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.8 // indirect @@ -171,7 +171,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kevinburke/ssh_config v1.4.0 // indirect - github.com/klauspost/compress v1.18.4 // indirect + github.com/klauspost/compress v1.18.1 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.9.0 // indirect @@ -200,7 +200,7 @@ require ( github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/otlptranslator v1.0.0 // indirect - github.com/prometheus/procfs v0.20.1 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 // indirect github.com/redis/go-redis/v9 v9.7.3 // indirect @@ -218,47 +218,47 @@ require ( github.com/xlab/treeprint v1.2.0 // indirect gitlab.com/gitlab-org/api/client-go v1.29.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/bridges/prometheus v0.67.0 // indirect - go.opentelemetry.io/contrib/exporters/autoexport v0.67.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect - go.opentelemetry.io/otel v1.43.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.65.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.19.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.43.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.43.0 // indirect - go.opentelemetry.io/otel/log v0.19.0 // indirect - go.opentelemetry.io/otel/metric v1.43.0 // indirect - go.opentelemetry.io/otel/sdk v1.43.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.19.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect - go.opentelemetry.io/otel/trace v1.43.0 // indirect - go.opentelemetry.io/proto/otlp v1.10.0 // indirect - go.yaml.in/yaml/v2 v2.4.4 // indirect + go.opentelemetry.io/contrib/bridges/prometheus v0.65.0 // indirect + go.opentelemetry.io/contrib/exporters/autoexport v0.65.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect + go.opentelemetry.io/otel v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.16.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.16.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/prometheus v0.62.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.16.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0 // indirect + go.opentelemetry.io/otel/log v0.16.0 // indirect + go.opentelemetry.io/otel/metric v1.40.0 // indirect + go.opentelemetry.io/otel/sdk v1.40.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.16.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect + go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.53.0 // indirect - golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.43.0 // indirect + golang.org/x/net v0.50.0 // indirect + golang.org/x/oauth2 v0.35.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.41.0 // indirect golang.org/x/time v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/api v0.261.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect - google.golang.org/grpc v1.80.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect + google.golang.org/grpc v1.78.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - helm.sh/helm/v4 v4.1.4 // indirect + helm.sh/helm/v4 v4.1.3 // indirect k8s.io/component-base v0.35.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect diff --git a/go.sum b/go.sum index 843d2366..e720c911 100644 --- a/go.sum +++ b/go.sum @@ -47,8 +47,6 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= -github.com/alicebob/miniredis/v2 v2.35.0 h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI= -github.com/alicebob/miniredis/v2 v2.35.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -93,8 +91,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bshuster-repo/logrus-logstash-hook v1.1.0 h1:o2FzZifLg+z/DN1OFmzTWzZZx/roaqt8IPZCIVco8r4= -github.com/bshuster-repo/logrus-logstash-hook v1.1.0/go.mod h1:Q2aXOe7rNuPgbBtPCOzYyWDvKX7+FpxE5sRdvcPoui0= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= +github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= @@ -140,18 +138,18 @@ github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454Wv github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/distribution/distribution/v3 v3.1.0 h1:u1v788HreKTLGdNY6s7px8Exgrs9mZ9UrCDjSrpCM8g= -github.com/distribution/distribution/v3 v3.1.0/go.mod h1:73BuF5/ziMHNVt7nnL1roYpH4Eg/FgUlKZm3WryIx/o= +github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM= +github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/cli v29.2.0+incompatible h1:9oBd9+YM7rxjZLfyMGxjraKBKE4/nVyvVfN4qNl9XRM= github.com/docker/cli v29.2.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY= -github.com/docker/docker-credential-helpers v0.9.5/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= -github.com/docker/go-events v0.0.0-20250808211157-605354379745 h1:yOn6Ze6IbYI/KAw2lw/83ELYvZh6hvsygTVkD0dzMC4= -github.com/docker/go-events v0.0.0-20250808211157-605354379745/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= +github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= github.com/elazarl/goproxy v1.8.0 h1:dt561rX7UAYMeFRLtzFx6uQGl2TpL1dr6uCG23nFQSY= @@ -182,48 +180,48 @@ github.com/fluxcd/image-automation-controller/api v1.1.1 h1:uiu7kjdVoW8/461HOemX github.com/fluxcd/image-automation-controller/api v1.1.1/go.mod h1:lkD/drkD6Wc+2SDjVj5KqfozEucTLFexWgby/5ft660= github.com/fluxcd/image-reflector-controller/api v1.1.1 h1:4Bj1abzVnjj8+b/293kNeFMRJc+y2wO8Z12ReZ/gA0w= github.com/fluxcd/image-reflector-controller/api v1.1.1/go.mod h1:j4JSIocL42HQ77Veg1t60sApOy+lng8/cbXHXGSnfi0= -github.com/fluxcd/kustomize-controller/api v1.8.3 h1:Ux9AAOY0lkP6FgRg5/b/ITvRSy8lz6VBBaZ9bXmTLmI= -github.com/fluxcd/kustomize-controller/api v1.8.3/go.mod h1:c/mUPIffDDLg1EicXCJtX4N/rc+z5Zh0e/CXjhd7Dyc= -github.com/fluxcd/notification-controller/api v1.8.3 h1:edYpC/t4pNw/KQur189SRC1XtFNU597ooDTCrW90Xmw= -github.com/fluxcd/notification-controller/api v1.8.3/go.mod h1:ozgJGQPy0dG5eOsLZlwAr6n0q/y6+TWd1fGOtavlXJA= +github.com/fluxcd/kustomize-controller/api v1.8.2 h1:LcFUjJccwNrhCo7pQBBneLAlHfZZcb58bWB2LnyFwag= +github.com/fluxcd/kustomize-controller/api v1.8.2/go.mod h1:c/mUPIffDDLg1EicXCJtX4N/rc+z5Zh0e/CXjhd7Dyc= +github.com/fluxcd/notification-controller/api v1.8.2 h1:TDrXohUC5Gh3BF+v2ux9/zEG1Ax8u49WDW+3Y6GiIEc= +github.com/fluxcd/notification-controller/api v1.8.2/go.mod h1:ozgJGQPy0dG5eOsLZlwAr6n0q/y6+TWd1fGOtavlXJA= github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA= github.com/fluxcd/pkg/apis/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4= -github.com/fluxcd/pkg/apis/event v0.25.0 h1:zdwytvDhG+fk+Ywl5DOtv7TklkrVgM21WHm1f+YhleE= -github.com/fluxcd/pkg/apis/event v0.25.0/go.mod h1:TlK8HWYrTwl0raqBRC+ROoNpYW5fdVnwcwOBOx5Kzw8= -github.com/fluxcd/pkg/apis/kustomize v1.16.0 h1:PhWXEhqQqsisIpwp1/wHvTvo+MO+GGzsBPoN0ZnRE3Y= -github.com/fluxcd/pkg/apis/kustomize v1.16.0/go.mod h1:IZOy4CCtR/hxMGb7erK1RfbGnczVv4/dRBoVD37AywI= -github.com/fluxcd/pkg/apis/meta v1.26.0 h1:dxP1FfBpTCYso6odzRcltVnnRuBb2VyhhgV0VX9YbUE= -github.com/fluxcd/pkg/apis/meta v1.26.0/go.mod h1:c7o6mJGLCMvNrfdinGZehkrdZuFT9vZdZNrn66DtVD0= -github.com/fluxcd/pkg/auth v0.40.0 h1:p6Kw6KH+z8oRqngKhmTt8ILKD/rC+8tP87a//kLZhi8= -github.com/fluxcd/pkg/auth v0.40.0/go.mod h1:Oq/hIEKUMTbL2bv5blf+EhC/jXXJLsOjIMtJj/AtG3Y= +github.com/fluxcd/pkg/apis/event v0.24.1 h1:TClVdn02aiq3sAl9BuzLjjTIxm3JJ83fJ9nchtBa4qg= +github.com/fluxcd/pkg/apis/event v0.24.1/go.mod h1:TlK8HWYrTwl0raqBRC+ROoNpYW5fdVnwcwOBOx5Kzw8= +github.com/fluxcd/pkg/apis/kustomize v1.15.1 h1:t9QZh+3ZS8EKmlxrnnbcKZcGTrg8FDvMF1T8BHMCuqI= +github.com/fluxcd/pkg/apis/kustomize v1.15.1/go.mod h1:IZOy4CCtR/hxMGb7erK1RfbGnczVv4/dRBoVD37AywI= +github.com/fluxcd/pkg/apis/meta v1.25.1 h1:WG1GIC/SOz0GjxT0uVuO6AMicQ3yFsk6bDozCnq+fto= +github.com/fluxcd/pkg/apis/meta v1.25.1/go.mod h1:c7o6mJGLCMvNrfdinGZehkrdZuFT9vZdZNrn66DtVD0= +github.com/fluxcd/pkg/auth v0.38.4 h1:xVsJ1rakUm5zS2tOKguZOQc5g6wLgCNxW2a9exidd4M= +github.com/fluxcd/pkg/auth v0.38.4/go.mod h1:KTXOh770ukcyQfC8NavEFzm110ORSQRan0v/kjzgFXs= github.com/fluxcd/pkg/cache v0.13.0 h1:MqtlgOwIVcGKKgV422e39O+KFSVMWuExKeRaMDBjJlk= github.com/fluxcd/pkg/cache v0.13.0/go.mod h1:0xRZ1hitrIFQ6pl68ke2wZLbIqA2VLzY78HpDo9DVxs= -github.com/fluxcd/pkg/chartutil v1.23.0 h1:ohstQEVnrBIbN85FGu83hnmAohLl0PdOoPlsM6+cjyI= -github.com/fluxcd/pkg/chartutil v1.23.0/go.mod h1:kFhmD6DwBgRsvC1ilINsomargMi2WbqvSndWQLikkLc= +github.com/fluxcd/pkg/chartutil v1.22.1 h1:ufI9LJ4d5T79h9ruBQRoRcSmuI/KkcwEqWdxu/9Xub8= +github.com/fluxcd/pkg/chartutil v1.22.1/go.mod h1:4/2mpNLyfox3uey++hG21AePPsMWekdhSWAtSdDiubQ= github.com/fluxcd/pkg/envsubst v1.5.0 h1:S07mo+MkGhptdHA4pRze5HPKlc8tHxKswNdcMZi1WDY= github.com/fluxcd/pkg/envsubst v1.5.0/go.mod h1:c3a8DYI855sZUubHFYQbjfjop6Wu4/zg1cLyf7SnCes= -github.com/fluxcd/pkg/git v0.46.0 h1:QMh0+ZzQ2jO6rIGj4ffR5trZ8g/cxvt8cVajReJ8Iyw= -github.com/fluxcd/pkg/git v0.46.0/go.mod h1:iHcIjx9c8zye3PQiajTJYxgOMRiy7WCs+hfLKDswpfI= -github.com/fluxcd/pkg/gittestserver v0.26.0 h1:+RZrCzFRsE+d5WaqAoqaPCEgcgv/jZp6+f7DS0+Ynb8= -github.com/fluxcd/pkg/gittestserver v0.26.0/go.mod h1:7fybYb0yej1fFNiF1ohs0Jr0XzyaZQ/cRh3AFEoCtuc= -github.com/fluxcd/pkg/kustomize v1.29.0 h1:B/5hr9wX6INwaQAZ6BGKVNvZm++A6qjgorUfoaBAwPw= -github.com/fluxcd/pkg/kustomize v1.29.0/go.mod h1:cW08mnngSP8MJYb6mDmMvxH8YjNATdiML0udb37dk+M= -github.com/fluxcd/pkg/oci v0.63.0 h1:ZPKTT2C+gWYjhP63xC76iTPdYE9w3ABcsDq77uhAgwo= -github.com/fluxcd/pkg/oci v0.63.0/go.mod h1:qMPz4njvm6hJzdyGSb8ydSqrapXxTQwJonxHIsdeXSQ= -github.com/fluxcd/pkg/runtime v0.103.0 h1:J5y5GPhWdkyqIUBlaI1FP2N02TtZmsjbWhhZubuTSFk= -github.com/fluxcd/pkg/runtime v0.103.0/go.mod h1:mbo2f3azo3yVQgm7XZGxQB6/2zvzQ5Wgtd8TjRRwwAw= +github.com/fluxcd/pkg/git v0.43.1 h1:lw29P44wueKzQk79KnYyvisfw//cxg0S4cDeTYx+Slo= +github.com/fluxcd/pkg/git v0.43.1/go.mod h1:3R/AjCe7ee7FqWcAG+2IiuJPOCxrGHF4SCGkuvKS6OQ= +github.com/fluxcd/pkg/gittestserver v0.25.1 h1:40Ridmy1xKxBM9ItDn012R4VKmaoDqzvGaC5g7xv+mw= +github.com/fluxcd/pkg/gittestserver v0.25.1/go.mod h1:7fybYb0yej1fFNiF1ohs0Jr0XzyaZQ/cRh3AFEoCtuc= +github.com/fluxcd/pkg/kustomize v1.27.1 h1:BLOBNLb2N5ObttZA8XJhZ2NqNY1ZjBqQtTpNlIx8/L4= +github.com/fluxcd/pkg/kustomize v1.27.1/go.mod h1:A2RQTe9woDPiwJDWFlkoP4oF9eX9DeXr89FEkKnSObk= +github.com/fluxcd/pkg/oci v0.60.1 h1:mT6WBX+MBIcczzEnw/W4cfXyt5JSRNhRoB/UnJ72K6M= +github.com/fluxcd/pkg/oci v0.60.1/go.mod h1:w2FGseUl3WGjwRMH/3h6MTI4gKahcBQtnGbn/TQVA34= +github.com/fluxcd/pkg/runtime v0.100.4 h1:rwvbeoeWN0BTJORJBISJJEkWn6DVfmWwynFl2GseWns= +github.com/fluxcd/pkg/runtime v0.100.4/go.mod h1:M6LjRJ1hIe2s6E2ykFfae1Xy/rLvOFQf2QquMKmN350= github.com/fluxcd/pkg/sourceignore v0.17.0 h1:Z72nruRMhC15zIEpWoDrAcJcJ1El6QDnP/aRDfE4WOA= github.com/fluxcd/pkg/sourceignore v0.17.0/go.mod h1:3e/VmYLId0pI/H5sK7W9Ibif+j0Ahns9RxNjDMtTTfY= -github.com/fluxcd/pkg/ssa v0.70.0 h1:IBylYPiTK1IEdCC2DvjKXIhwQcbd5VufXA9WS3zO+tE= -github.com/fluxcd/pkg/ssa v0.70.0/go.mod h1:6igtlt7/zF+nNFQpa5ZAkkvtpL6o36NRU39/PqqC+Bg= +github.com/fluxcd/pkg/ssa v0.67.3 h1:mjuhH5fNOYstkF6jB7EeaWmfnt5T272Cup8ZD9O8YBQ= +github.com/fluxcd/pkg/ssa v0.67.3/go.mod h1:6igtlt7/zF+nNFQpa5ZAkkvtpL6o36NRU39/PqqC+Bg= github.com/fluxcd/pkg/ssh v0.24.0 h1:hrPlxs0hhXf32DRqs68VbsXs0XfQMphyRVIk0rYYJa4= github.com/fluxcd/pkg/ssh v0.24.0/go.mod h1:xWammEqalrpurpcMiixJRXtynRQtBEoqheyU5F/vWrg= github.com/fluxcd/pkg/tar v0.17.0 h1:uNxbFXy8ly8C7fJ8D7w3rjTNJFrb4Hp1aY/30XkfvxY= github.com/fluxcd/pkg/tar v0.17.0/go.mod h1:b1xyIRYDD0ket4SV5u0UXYv+ZdN/O/HmIO5jZQdHQls= -github.com/fluxcd/pkg/version v0.14.0 h1:T3llSc8sUnsuFrW5ng2ePSfXwGXUKv0YG9QXf0ErhWw= -github.com/fluxcd/pkg/version v0.14.0/go.mod h1:YHdg/78kzf+kCqS+SqSOiUxum5AjxlixiqwpX6AUZB8= -github.com/fluxcd/source-controller/api v1.8.2 h1:i0/6BeNCn+zRfX+gKh4PsFF2NBzBhwXt0wPImVlZObg= -github.com/fluxcd/source-controller/api v1.8.2/go.mod h1:HgZ6NSH1cyOE2jRoNwln1xEwr9ETvrLeiy1o4O04vQM= +github.com/fluxcd/pkg/version v0.12.0 h1:MGbdbNf2D5wazMqAkNPn+Lh5j+oY0gxQJFTGyet5Hfc= +github.com/fluxcd/pkg/version v0.12.0/go.mod h1:YHdg/78kzf+kCqS+SqSOiUxum5AjxlixiqwpX6AUZB8= +github.com/fluxcd/source-controller/api v1.8.1 h1:49HiJF5mNEdZTwueQMRahTVts35B+xhN5CsuOAL9gQ0= +github.com/fluxcd/source-controller/api v1.8.1/go.mod h1:HgZ6NSH1cyOE2jRoNwln1xEwr9ETvrLeiy1o4O04vQM= github.com/fluxcd/source-watcher/api/v2 v2.1.1 h1:1LfT50ty+78MKKbschAZl28QbVqIyjaNq17KmW5wPJI= github.com/fluxcd/source-watcher/api/v2 v2.1.1/go.mod h1:6M1BzBGQRoIuSenSQlfJHwMVVobFPiNPxXqfN0IILc4= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= @@ -240,14 +238,14 @@ github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDzZG0= -github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY= +github.com/go-git/go-billy/v5 v5.7.0 h1:83lBUJhGWhYp0ngzCMSgllhUSuoHP1iEWYjsPl9nwqM= +github.com/go-git/go-billy/v5 v5.7.0/go.mod h1:/1IUejTKH8xipsAcdfcSAlUlo2J7lkYV8GTKxAT/L3E= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.17.1 h1:WnljyxIzSj9BRRUlnmAU35ohDsjRK0EKmL0evDqi5Jk= -github.com/go-git/go-git/v5 v5.17.1/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo= -github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= -github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s= +github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M= +github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= +github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-ldap/ldap/v3 v3.4.10 h1:ot/iwPOhfpNVgB1o+AVXljizWZ9JTp7YF5oeyONmcJU= github.com/go-ldap/ldap/v3 v3.4.10/go.mod h1:JXh4Uxgi40P6E9rdsYqpUtbW46D9UTjJ9QSwGRznplY= @@ -329,8 +327,8 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+ github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7/go.mod h1:lW34nIZuQ8UDPdkon5fmfp2l3+ZkQ2me/+oecHYLOII= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -380,8 +378,8 @@ github.com/kevinburke/ssh_config v1.4.0 h1:6xxtP5bZ2E4NF5tuQulISpTO2z8XbtH8cg1PW github.com/kevinburke/ssh_config v1.4.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= -github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= -github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= +github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -491,8 +489,8 @@ github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVR github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= -github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 h1:EaDatTxkdHG+U3Bk4EUr+DZ7fOGwTfezUiUJMaIcaho= github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5/go.mod h1:fyalQWdtzDBECAQFBJuQe5bzQ02jGd5Qcbgb97Flm7U= github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb27yVE+gIAfeqp8LUCc= @@ -510,7 +508,6 @@ github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= @@ -551,66 +548,64 @@ github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= -github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= gitlab.com/gitlab-org/api/client-go v1.29.0 h1:3KnF6vENry/9v9eVrnLi2OfBV0m/WSrwh3RcxgH/hkA= gitlab.com/gitlab-org/api/client-go v1.29.0/go.mod h1:6i3EZtC6gKiTTmDwp+f6r/Yi9OY4AaYubl5B3yXEdHE= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/bridges/prometheus v0.67.0 h1:dkBzNEAIKADEaFnuESzcXvpd09vxvDZsOjx11gjUqLk= -go.opentelemetry.io/contrib/bridges/prometheus v0.67.0/go.mod h1:Z5RIwRkZgauOIfnG5IpidvLpERjhTninpP1dTG2jTl4= -go.opentelemetry.io/contrib/exporters/autoexport v0.67.0 h1:4fnRcNpc6YFtG3zsFw9achKn3XgmxPxuMuqIL5rE8e8= -go.opentelemetry.io/contrib/exporters/autoexport v0.67.0/go.mod h1:qTvIHMFKoxW7HXg02gm6/Wofhq5p3Ib/A/NNt1EoBSQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= -go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= -go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 h1:Dn8rkudDzY6KV9dr/D/bTUuWgqDf9xe0rr4G2elrn0Y= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0/go.mod h1:gMk9F0xDgyN9M/3Ed5Y1wKcx/9mlU91NXY2SNq7RQuU= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 h1:HIBTQ3VO5aupLKjC90JgMqpezVXwFuq6Ryjn0/izoag= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0/go.mod h1:ji9vId85hMxqfvICA0Jt8JqEdrXaAkcpkI9HPXya0ro= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0 h1:8UQVDcZxOJLtX6gxtDt3vY2WTgvZqMQRzjsqiIHQdkc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0/go.mod h1:2lmweYCiHYpEjQ/lSJBYhj9jP1zvCvQW4BqL9dnT7FQ= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 h1:w1K+pCJoPpQifuVpsKamUdn9U0zM3xUziVOqsGksUrY= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0/go.mod h1:HBy4BjzgVE8139ieRI75oXm3EcDN+6GhD88JT1Kjvxg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 h1:88Y4s2C8oTui1LGM6bTWkw0ICGcOLCAI5l6zsD1j20k= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0/go.mod h1:Vl1/iaggsuRlrHf/hfPJPvVag77kKyvrLeD10kpMl+A= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 h1:RAE+JPfvEmvy+0LzyUA25/SGawPwIUbZ6u0Wug54sLc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0/go.mod h1:AGmbycVGEsRx9mXMZ75CsOyhSP6MFIcj/6dnG+vhVjk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 h1:3iZJKlCZufyRzPzlQhUIWVmfltrXuGyfjREgGP3UUjc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0/go.mod h1:/G+nUPfhq2e+qiXMGxMwumDrP5jtzU+mWN7/sjT2rak= -go.opentelemetry.io/otel/exporters/prometheus v0.65.0 h1:jOveH/b4lU9HT7y+Gfamf18BqlOuz2PWEvs8yM7Q6XE= -go.opentelemetry.io/otel/exporters/prometheus v0.65.0/go.mod h1:i1P8pcumauPtUI4YNopea1dhzEMuEqWP1xoUZDylLHo= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.19.0 h1:GJkybS+crDMdExT/BUNCEgfrmfboztcS6PhvSo88HKM= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.19.0/go.mod h1:NuAyxRYIG2lKX3YQkB+83StTxM7s52PUUkRRiC0wnYI= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.43.0 h1:TC+BewnDpeiAmcscXbGMfxkO+mwYUwE/VySwvw88PfA= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.43.0/go.mod h1:J/ZyF4vfPwsSr9xJSPyQ4LqtcTPULFR64KwTikGLe+A= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.43.0 h1:mS47AX77OtFfKG4vtp+84kuGSFZHTyxtXIN269vChY0= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.43.0/go.mod h1:PJnsC41lAGncJlPUniSwM81gc80GkgWJWr3cu2nKEtU= -go.opentelemetry.io/otel/log v0.19.0 h1:KUZs/GOsw79TBBMfDWsXS+KZ4g2Ckzksd1ymzsIEbo4= -go.opentelemetry.io/otel/log v0.19.0/go.mod h1:5DQYeGmxVIr4n0/BcJvF4upsraHjg6vudJJpnkL6Ipk= -go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= -go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= -go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= -go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= -go.opentelemetry.io/otel/sdk/log v0.19.0 h1:scYVLqT22D2gqXItnWiocLUKGH9yvkkeql5dBDiXyko= -go.opentelemetry.io/otel/sdk/log v0.19.0/go.mod h1:vFBowwXGLlW9AvpuF7bMgnNI95LiW10szrOdvzBHlAg= -go.opentelemetry.io/otel/sdk/log/logtest v0.19.0 h1:BEbF7ZBB6qQloV/Ub1+3NQoOUnVtcGkU3XX4Ws3GQfk= -go.opentelemetry.io/otel/sdk/log/logtest v0.19.0/go.mod h1:Lua81/3yM0wOmoHTokLj9y9ADeA02v1naRrVrkAZuKk= -go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= -go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= -go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= -go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= -go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= -go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.opentelemetry.io/contrib/bridges/prometheus v0.65.0 h1:I/7S/yWobR3QHFLqHsJ8QOndoiFsj1VgHpQiq43KlUI= +go.opentelemetry.io/contrib/bridges/prometheus v0.65.0/go.mod h1:jPF6gn3y1E+nozCAEQj3c6NZ8KY+tvAgSVfvoOJUFac= +go.opentelemetry.io/contrib/exporters/autoexport v0.65.0 h1:2gApdml7SznX9szEKFjKjM4qGcGSvAybYLBY319XG3g= +go.opentelemetry.io/contrib/exporters/autoexport v0.65.0/go.mod h1:0QqAGlbHXhmPYACG3n5hNzO5DnEqqtg4VcK5pr22RI0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.16.0 h1:ZVg+kCXxd9LtAaQNKBxAvJ5NpMf7LpvEr4MIZqb0TMQ= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.16.0/go.mod h1:hh0tMeZ75CCXrHd9OXRYxTlCAdxcXioWHFIpYw2rZu8= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.16.0 h1:djrxvDxAe44mJUrKataUbOhCKhR3F8QCyWucO16hTQs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.16.0/go.mod h1:dt3nxpQEiSoKvfTVxp3TUg5fHPLhKtbcnN3Z1I1ePD0= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.40.0 h1:NOyNnS19BF2SUDApbOKbDtWZ0IK7b8FJ2uAGdIWOGb0= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.40.0/go.mod h1:VL6EgVikRLcJa9ftukrHu/ZkkhFBSo1lzvdBC9CF1ss= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0 h1:9y5sHvAxWzft1WQ4BwqcvA+IFVUJ1Ya75mSAUnFEVwE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0/go.mod h1:eQqT90eR3X5Dbs1g9YSM30RavwLF725Ris5/XSXWvqE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 h1:DvJDOPmSWQHWywQS6lKL+pb8s3gBLOZUtw4N+mavW1I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0/go.mod h1:EtekO9DEJb4/jRyN4v4Qjc2yA7AtfCBuz2FynRUWTXs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 h1:wVZXIWjQSeSmMoxF74LzAnpVQOAFDo3pPji9Y4SOFKc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0/go.mod h1:khvBS2IggMFNwZK/6lEeHg/W57h/IX6J4URh57fuI40= +go.opentelemetry.io/otel/exporters/prometheus v0.62.0 h1:krvC4JMfIOVdEuNPTtQ0ZjCiXrybhv+uOHMfHRmnvVo= +go.opentelemetry.io/otel/exporters/prometheus v0.62.0/go.mod h1:fgOE6FM/swEnsVQCqCnbOfRV4tOnWPg7bVeo4izBuhQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.16.0 h1:ivlbaajBWJqhcCPniDqDJmRwj4lc6sRT+dCAVKNmxlQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.16.0/go.mod h1:u/G56dEKDDwXNCVLsbSrllB2o8pbtFLUC4HpR66r2dc= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0 h1:ZrPRak/kS4xI3AVXy8F7pipuDXmDsrO8Lg+yQjBLjw0= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.40.0/go.mod h1:3y6kQCWztq6hyW8Z9YxQDDm0Je9AJoFar2G0yDcmhRk= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0 h1:MzfofMZN8ulNqobCmCAVbqVL5syHw+eB2qPRkCMA/fQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.40.0/go.mod h1:E73G9UFtKRXrxhBsHtG00TB5WxX57lpsQzogDkqBTz8= +go.opentelemetry.io/otel/log v0.16.0 h1:DeuBPqCi6pQwtCK0pO4fvMB5eBq6sNxEnuTs88pjsN4= +go.opentelemetry.io/otel/log v0.16.0/go.mod h1:rWsmqNVTLIA8UnwYVOItjyEZDbKIkMxdQunsIhpUMes= +go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= +go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk/log v0.16.0 h1:e/b4bdlQwC5fnGtG3dlXUrNOnP7c8YLVSpSfEBIkTnI= +go.opentelemetry.io/otel/sdk/log v0.16.0/go.mod h1:JKfP3T6ycy7QEuv3Hj8oKDy7KItrEkus8XJE6EoSzw4= +go.opentelemetry.io/otel/sdk/log/logtest v0.16.0 h1:/XVkpZ41rVRTP4DfMgYv1nEtNmf65XPPyAdqV90TMy4= +go.opentelemetry.io/otel/sdk/log/logtest v0.16.0/go.mod h1:iOOPgQr5MY9oac/F5W86mXdeyWZGleIx3uXO98X2R6Y= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= +go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= +go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= +go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= +go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= -go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -624,15 +619,15 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= -golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= -golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -648,10 +643,10 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= -golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= -golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= -golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -661,8 +656,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -688,8 +683,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -699,8 +694,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= -golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -711,8 +706,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= -golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -721,23 +716,23 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= -golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/api v0.261.0 h1:3DoJ2GGibaCxNi1lhdScNMx9fTW87ujKHDgyHMMYdoA= google.golang.org/api v0.261.0/go.mod h1:nVH0ZK5C4tO0RdsMscleeTLY7I8m/Nt9IXxcXD2tfts= google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217 h1:GvESR9BIyHUahIb0NcTum6itIWtdoglGX+rnGxm2934= google.golang.org/genproto v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:yJ2HH4EHEDTd3JiLmhds6NkJ17ITVYOdV3m3VKOnws0= -google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA= -google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= -google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M= +google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -761,8 +756,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -helm.sh/helm/v4 v4.1.4 h1:zwTrNkalG4f7SYigRSdQnYrTj0QEz1qzetzAlYoDVSo= -helm.sh/helm/v4 v4.1.4/go.mod h1:5dSo8rRgn3OTkDAc/k0Ipw5/Q+BlqKIKZwa0XwSiINI= +helm.sh/helm/v4 v4.1.3 h1:Abfmb+oJUtxoaXDyB2Jhw1zRk3hT6aFfHta+AXb8Lno= +helm.sh/helm/v4 v4.1.3/go.mod h1:5dSo8rRgn3OTkDAc/k0Ipw5/Q+BlqKIKZwa0XwSiINI= k8s.io/api v0.35.2 h1:tW7mWc2RpxW7HS4CoRXhtYHSzme1PN1UjGHJ1bdrtdw= k8s.io/api v0.35.2/go.mod h1:7AJfqGoAZcwSFhOjcGM7WV05QxMMgUaChNfLTXDRE60= k8s.io/apiextensions-apiserver v0.35.2 h1:iyStXHoJZsUXPh/nFAsjC29rjJWdSgUmG1XpApE29c0= diff --git a/internal/build/build.go b/internal/build/build.go index 6f1b44c5..7deca47c 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -45,7 +45,6 @@ import ( kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" "github.com/fluxcd/pkg/kustomize" - buildfs "github.com/fluxcd/pkg/kustomize/filesys" runclient "github.com/fluxcd/pkg/runtime/client" ssautil "github.com/fluxcd/pkg/ssa/utils" "sigs.k8s.io/kustomize/kyaml/filesys" @@ -66,65 +65,6 @@ const ( var defaultTimeout = 80 * time.Second -// fsBackend controls how the kustomization manifest is generated -// and which filesystem is used for the kustomize build. -type fsBackend interface { - Generate(gen *kustomize.Generator, dirPath string) (filesys.FileSystem, string, kustomize.Action, error) - Cleanup(dirPath string, action kustomize.Action) error -} - -// onDiskFsBackend writes to the source directory. -type onDiskFsBackend struct{} - -func (onDiskFsBackend) Generate(gen *kustomize.Generator, dirPath string) (filesys.FileSystem, string, kustomize.Action, error) { - action, err := gen.WriteFile(dirPath, kustomize.WithSaveOriginalKustomization()) - if err != nil { - return nil, "", action, err - } - return filesys.MakeFsOnDisk(), dirPath, action, nil -} - -func (onDiskFsBackend) Cleanup(dirPath string, action kustomize.Action) error { - return kustomize.CleanDirectory(dirPath, action) -} - -// inMemoryFsBackend builds in an in-memory filesystem without modifying the source directory. -type inMemoryFsBackend struct{} - -func (inMemoryFsBackend) Generate(gen *kustomize.Generator, dirPath string) (filesys.FileSystem, string, kustomize.Action, error) { - manifest, kfilePath, action, err := gen.GenerateManifest(dirPath) - if err != nil { - return nil, "", action, err - } - - absDirPath, err := filepath.Abs(dirPath) - if err != nil { - return nil, "", action, fmt.Errorf("failed to resolve dirPath: %w", err) - } - absDirPath, err = filepath.EvalSymlinks(absDirPath) - if err != nil { - return nil, "", action, fmt.Errorf("failed to eval symlinks: %w", err) - } - - cwd, err := os.Getwd() - if err != nil { - return nil, "", action, fmt.Errorf("failed to get working directory: %w", err) - } - - diskFS, err := buildfs.MakeFsOnDiskSecure(cwd) - if err != nil { - return nil, "", action, fmt.Errorf("failed to create secure filesystem: %w", err) - } - fs := buildfs.MakeFsInMemory(diskFS) - - if err := fs.WriteFile(filepath.Join(absDirPath, filepath.Base(kfilePath)), manifest); err != nil { - return nil, "", action, err - } - return fs, absDirPath, action, nil -} - -func (inMemoryFsBackend) Cleanup(string, kustomize.Action) error { return nil } - // Builder builds yaml manifests // It retrieves the kustomization object from the k8s cluster // and overlays the manifests with the resources specified in the resourcesPath @@ -148,7 +88,6 @@ type Builder struct { localSources map[string]string // diff needs to handle kustomizations one by one singleKustomization bool - fsBackend fsBackend } // BuilderOptionFunc is a function that configures a Builder @@ -259,16 +198,6 @@ func WithLocalSources(localSources map[string]string) BuilderOptionFunc { } } -// WithInMemoryBuild sets the in-memory build backend -func WithInMemoryBuild(inMemoryBuild bool) BuilderOptionFunc { - return func(b *Builder) error { - if inMemoryBuild { - b.fsBackend = inMemoryFsBackend{} - } - return nil - } -} - // WithSingleKustomization sets the single kustomization field to true func WithSingleKustomization() BuilderOptionFunc { return func(b *Builder) error { @@ -294,14 +223,6 @@ func withSpinnerFrom(in *Builder) BuilderOptionFunc { } } -// withFsBackend sets the build backend -func withFsBackend(s fsBackend) BuilderOptionFunc { - return func(b *Builder) error { - b.fsBackend = s - return nil - } -} - // withKustomization sets the kustomization field func withKustomization(k *kustomizev1.Kustomization) BuilderOptionFunc { return func(b *Builder) error { @@ -337,10 +258,6 @@ func NewBuilder(name, resources string, opts ...BuilderOptionFunc) (*Builder, er b.timeout = defaultTimeout } - if b.fsBackend == nil { - b.fsBackend = onDiskFsBackend{} - } - if b.dryRun && b.kustomizationFile == "" && b.kustomization == nil { return nil, fmt.Errorf("kustomization file is required for dry-run") } @@ -461,9 +378,9 @@ func (b *Builder) build() (m resmap.ResMap, err error) { b.kustomization = k // generate kustomization.yaml if needed - buildFS, buildDir, action, er := b.generate(*k, b.resourcesPath) + action, er := b.generate(*k, b.resourcesPath) if er != nil { - errf := b.fsBackend.Cleanup(b.resourcesPath, action) + errf := kustomize.CleanDirectory(b.resourcesPath, action) err = fmt.Errorf("failed to generate kustomization.yaml: %w", fmt.Errorf("%v %v", er, errf)) return } @@ -471,14 +388,14 @@ func (b *Builder) build() (m resmap.ResMap, err error) { b.action = action defer func() { - errf := b.fsBackend.Cleanup(b.resourcesPath, b.action) + errf := b.Cancel() if err == nil { err = errf } }() // build the kustomization - m, err = b.do(ctx, *k, buildFS, buildDir) + m, err = b.do(ctx, *k, b.resourcesPath) if err != nil { return } @@ -519,7 +436,6 @@ func (b *Builder) kustomizationBuild(k *kustomizev1.Kustomization) ([]*unstructu WithRecursive(b.recursive), WithLocalSources(b.localSources), WithDryRun(b.dryRun), - withFsBackend(b.fsBackend), ) if err != nil { return nil, err @@ -574,10 +490,10 @@ func (b *Builder) unMarshallKustomization() (*kustomizev1.Kustomization, error) return k, nil } -func (b *Builder) generate(kustomization kustomizev1.Kustomization, dirPath string) (filesys.FileSystem, string, kustomize.Action, error) { +func (b *Builder) generate(kustomization kustomizev1.Kustomization, dirPath string) (kustomize.Action, error) { data, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&kustomization) if err != nil { - return nil, "", kustomize.UnchangedAction, err + return "", err } // a scanner will be used down the line to parse the list @@ -589,10 +505,12 @@ func (b *Builder) generate(kustomization kustomizev1.Kustomization, dirPath stri b.mu.Lock() defer b.mu.Unlock() - return b.fsBackend.Generate(gen, dirPath) + return gen.WriteFile(dirPath, kustomize.WithSaveOriginalKustomization()) } -func (b *Builder) do(ctx context.Context, kustomization kustomizev1.Kustomization, fs filesys.FileSystem, dirPath string) (resmap.ResMap, error) { +func (b *Builder) do(ctx context.Context, kustomization kustomizev1.Kustomization, dirPath string) (resmap.ResMap, error) { + fs := filesys.MakeFsOnDisk() + // acquire the lock b.mu.Lock() defer b.mu.Unlock() @@ -816,7 +734,12 @@ func (b *Builder) Cancel() error { b.mu.Lock() defer b.mu.Unlock() - return b.fsBackend.Cleanup(b.resourcesPath, b.action) + err := kustomize.CleanDirectory(b.resourcesPath, b.action) + if err != nil { + return err + } + + return nil } func (b *Builder) StartSpinner() error { diff --git a/internal/build/build_test.go b/internal/build/build_test.go index fa7ffff3..bf82513f 100644 --- a/internal/build/build_test.go +++ b/internal/build/build_test.go @@ -18,15 +18,12 @@ package build import ( "fmt" - "os" - "path/filepath" "strings" "testing" "time" kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1" "github.com/fluxcd/pkg/apis/meta" - "github.com/fluxcd/pkg/kustomize" "github.com/google/go-cmp/cmp" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -614,229 +611,3 @@ func Test_kustomizationPath(t *testing.T) { }) } } - -// chdirTemp changes to the given directory and restores the original on cleanup. -func chdirTemp(t *testing.T, dir string) { - t.Helper() - orig, err := os.Getwd() - if err != nil { - t.Fatal(err) - } - if err := os.Chdir(dir); err != nil { - t.Fatal(err) - } - t.Cleanup(func() { os.Chdir(orig) }) -} - -func Test_inMemoryFsBackend_Generate(t *testing.T) { - srcDir := t.TempDir() - chdirTemp(t, srcDir) - - kusYAML := `apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- configmap.yaml -` - cmYAML := `apiVersion: v1 -kind: ConfigMap -metadata: - name: test-cm -data: - key: value -` - if err := os.WriteFile(filepath.Join(srcDir, "kustomization.yaml"), []byte(kusYAML), 0o644); err != nil { - t.Fatalf("write: %v", err) - } - if err := os.WriteFile(filepath.Join(srcDir, "configmap.yaml"), []byte(cmYAML), 0o644); err != nil { - t.Fatalf("write: %v", err) - } - - // snapshot source dir - beforeFiles := map[string]string{} - filepath.Walk(srcDir, func(p string, info os.FileInfo, err error) error { - if err != nil || info.IsDir() { - return err - } - data, _ := os.ReadFile(p) - rel, _ := filepath.Rel(srcDir, p) - beforeFiles[rel] = string(data) - return nil - }) - - ks := unstructured.Unstructured{Object: map[string]interface{}{ - "apiVersion": "kustomize.toolkit.fluxcd.io/v1", - "kind": "Kustomization", - "metadata": map[string]interface{}{"name": "test", "namespace": "default"}, - "spec": map[string]interface{}{ - "targetNamespace": "my-ns", - }, - }} - gen := kustomize.NewGenerator(srcDir, ks) - - backend := inMemoryFsBackend{} - fs, dir, action, err := backend.Generate(gen, srcDir) - if err != nil { - t.Fatalf("Generate: %v", err) - } - - if action != kustomize.UnchangedAction { - t.Errorf("expected UnchangedAction, got %q", action) - } - - // kustomization.yaml should contain the merged targetNamespace - data, err := fs.ReadFile(filepath.Join(dir, "kustomization.yaml")) - if err != nil { - t.Fatalf("ReadFile kustomization.yaml: %v", err) - } - if !strings.Contains(string(data), "my-ns") { - t.Errorf("expected kustomization to contain targetNamespace, got:\n%s", data) - } - - // resource file should be readable from disk through the memory fs - data, err = fs.ReadFile(filepath.Join(dir, "configmap.yaml")) - if err != nil { - t.Fatalf("ReadFile configmap.yaml: %v", err) - } - if diff := cmp.Diff(string(data), cmYAML); diff != "" { - t.Errorf("configmap mismatch: (-got +want)%s", diff) - } - - // source directory must be unmodified - afterFiles := map[string]string{} - filepath.Walk(srcDir, func(p string, info os.FileInfo, err error) error { - if err != nil || info.IsDir() { - return err - } - data, _ := os.ReadFile(p) - rel, _ := filepath.Rel(srcDir, p) - afterFiles[rel] = string(data) - return nil - }) - if diff := cmp.Diff(afterFiles, beforeFiles); diff != "" { - t.Errorf("source directory was modified: (-got +want)%s", diff) - } -} - -func Test_inMemoryFsBackend_Generate_parentRef(t *testing.T) { - // tmpDir/ - // configmap.yaml (referenced as ../../configmap.yaml) - // overlay/sub/kustomization.yaml - tmpDir := t.TempDir() - chdirTemp(t, tmpDir) - - cmYAML := `apiVersion: v1 -kind: ConfigMap -metadata: - name: parent-cm -data: - key: value -` - if err := os.WriteFile(filepath.Join(tmpDir, "configmap.yaml"), []byte(cmYAML), 0o644); err != nil { - t.Fatalf("write: %v", err) - } - - overlayDir := filepath.Join(tmpDir, "overlay", "sub") - if err := os.MkdirAll(overlayDir, 0o755); err != nil { - t.Fatalf("mkdir: %v", err) - } - - kusYAML := `apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- ../../configmap.yaml -` - if err := os.WriteFile(filepath.Join(overlayDir, "kustomization.yaml"), []byte(kusYAML), 0o644); err != nil { - t.Fatalf("write: %v", err) - } - - ks := unstructured.Unstructured{Object: map[string]interface{}{ - "apiVersion": "kustomize.toolkit.fluxcd.io/v1", - "kind": "Kustomization", - "metadata": map[string]interface{}{"name": "test", "namespace": "default"}, - "spec": map[string]interface{}{ - "targetNamespace": "parent-ns", - }, - }} - gen := kustomize.NewGenerator(overlayDir, ks) - - backend := inMemoryFsBackend{} - fs, dir, _, err := backend.Generate(gen, overlayDir) - if err != nil { - t.Fatalf("Generate: %v", err) - } - - // ../../configmap.yaml must resolve through the disk layer - m, err := kustomize.Build(fs, dir) - if err != nil { - t.Fatalf("kustomize.Build failed (parent ref not resolved): %v", err) - } - - resources := m.Resources() - if len(resources) != 1 { - t.Fatalf("expected 1 resource, got %d", len(resources)) - } - if resources[0].GetName() != "parent-cm" { - t.Errorf("expected resource name parent-cm, got %s", resources[0].GetName()) - } - if resources[0].GetNamespace() != "parent-ns" { - t.Errorf("expected namespace parent-ns, got %s", resources[0].GetNamespace()) - } -} - -func Test_inMemoryFsBackend_Generate_outsideCwd(t *testing.T) { - // Two sibling temp dirs: one for the source tree, one as cwd. - // The kustomization references a file that exists on disk but is - // outside cwd, so the secure filesystem must reject it. - // - // parentDir/ - // outside/configmap.yaml (exists but outside cwd) - // cwd/overlay/kustomization.yaml (references ../../outside/configmap.yaml) - parentDir := t.TempDir() - - outsideDir := filepath.Join(parentDir, "outside") - if err := os.MkdirAll(outsideDir, 0o755); err != nil { - t.Fatal(err) - } - if err := os.WriteFile(filepath.Join(outsideDir, "configmap.yaml"), []byte(`apiVersion: v1 -kind: ConfigMap -metadata: - name: outside-cm -`), 0o644); err != nil { - t.Fatal(err) - } - - cwdDir := filepath.Join(parentDir, "cwd") - overlayDir := filepath.Join(cwdDir, "overlay") - if err := os.MkdirAll(overlayDir, 0o755); err != nil { - t.Fatal(err) - } - if err := os.WriteFile(filepath.Join(overlayDir, "kustomization.yaml"), []byte(`apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: -- ../../outside/configmap.yaml -`), 0o644); err != nil { - t.Fatal(err) - } - - // Set cwd to cwdDir so the secure root excludes outsideDir. - chdirTemp(t, cwdDir) - - ks := unstructured.Unstructured{Object: map[string]interface{}{ - "apiVersion": "kustomize.toolkit.fluxcd.io/v1", - "kind": "Kustomization", - "metadata": map[string]interface{}{"name": "test", "namespace": "default"}, - }} - gen := kustomize.NewGenerator(overlayDir, ks) - - backend := inMemoryFsBackend{} - fs, dir, _, err := backend.Generate(gen, overlayDir) - if err != nil { - t.Fatalf("Generate: %v", err) - } - - // Build must fail because the resource is outside the secure root. - _, err = kustomize.Build(fs, dir) - if err == nil { - t.Fatal("expected error when referencing resource outside cwd, got nil") - } -} diff --git a/internal/build/diff.go b/internal/build/diff.go index 8884e57f..4485dd0f 100644 --- a/internal/build/diff.go +++ b/internal/build/diff.go @@ -230,7 +230,6 @@ func (b *Builder) kustomizationDiff(kustomization *kustomizev1.Kustomization) (s WithRecursive(b.recursive), WithLocalSources(b.localSources), WithSingleKustomization(), - withFsBackend(b.fsBackend), ) if err != nil { return "", false, err diff --git a/internal/flags/receiver_type.go b/internal/flags/receiver_type.go deleted file mode 100644 index 42948b7a..00000000 --- a/internal/flags/receiver_type.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 2026 The Flux authors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package flags - -import ( - "fmt" - "strings" - - notificationv1 "github.com/fluxcd/notification-controller/api/v1" - - "github.com/fluxcd/flux2/v2/internal/utils" -) - -var supportedReceiverTypes = []string{ - notificationv1.GenericReceiver, - notificationv1.GenericHMACReceiver, - notificationv1.GitHubReceiver, - notificationv1.GitLabReceiver, - notificationv1.BitbucketReceiver, - notificationv1.HarborReceiver, - notificationv1.DockerHubReceiver, - notificationv1.QuayReceiver, - notificationv1.GCRReceiver, - notificationv1.NexusReceiver, - notificationv1.ACRReceiver, - notificationv1.CDEventsReceiver, -} - -type ReceiverType string - -func (r *ReceiverType) String() string { - return string(*r) -} - -func (r *ReceiverType) Set(str string) error { - if strings.TrimSpace(str) == "" { - return fmt.Errorf("no receiver type given, please specify %s", - r.Description()) - } - if !utils.ContainsItemString(supportedReceiverTypes, str) { - return fmt.Errorf("receiver type '%s' is not supported, must be one of: %s", - str, strings.Join(supportedReceiverTypes, ", ")) - } - *r = ReceiverType(str) - return nil -} - -func (r *ReceiverType) Type() string { - return strings.Join(supportedReceiverTypes, "|") -} - -func (r *ReceiverType) Description() string { - return "the receiver type" -} diff --git a/manifests/bases/kustomize-controller/kustomization.yaml b/manifests/bases/kustomize-controller/kustomization.yaml index 2ad41b16..f75f707d 100644 --- a/manifests/bases/kustomize-controller/kustomization.yaml +++ b/manifests/bases/kustomize-controller/kustomization.yaml @@ -1,8 +1,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: -- https://github.com/fluxcd/kustomize-controller/releases/download/v1.8.3/kustomize-controller.crds.yaml -- https://github.com/fluxcd/kustomize-controller/releases/download/v1.8.3/kustomize-controller.deployment.yaml +- https://github.com/fluxcd/kustomize-controller/releases/download/v1.8.2/kustomize-controller.crds.yaml +- https://github.com/fluxcd/kustomize-controller/releases/download/v1.8.2/kustomize-controller.deployment.yaml - account.yaml transformers: - labels.yaml diff --git a/manifests/bases/notification-controller/kustomization.yaml b/manifests/bases/notification-controller/kustomization.yaml index 344c9e29..71c3de84 100644 --- a/manifests/bases/notification-controller/kustomization.yaml +++ b/manifests/bases/notification-controller/kustomization.yaml @@ -1,8 +1,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: -- https://github.com/fluxcd/notification-controller/releases/download/v1.8.3/notification-controller.crds.yaml -- https://github.com/fluxcd/notification-controller/releases/download/v1.8.3/notification-controller.deployment.yaml +- https://github.com/fluxcd/notification-controller/releases/download/v1.8.2/notification-controller.crds.yaml +- https://github.com/fluxcd/notification-controller/releases/download/v1.8.2/notification-controller.deployment.yaml - account.yaml transformers: - labels.yaml diff --git a/manifests/bases/source-controller/kustomization.yaml b/manifests/bases/source-controller/kustomization.yaml index b2eef98d..eba59908 100644 --- a/manifests/bases/source-controller/kustomization.yaml +++ b/manifests/bases/source-controller/kustomization.yaml @@ -1,8 +1,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: -- https://github.com/fluxcd/source-controller/releases/download/v1.8.2/source-controller.crds.yaml -- https://github.com/fluxcd/source-controller/releases/download/v1.8.2/source-controller.deployment.yaml +- https://github.com/fluxcd/source-controller/releases/download/v1.8.1/source-controller.crds.yaml +- https://github.com/fluxcd/source-controller/releases/download/v1.8.1/source-controller.deployment.yaml - account.yaml transformers: - labels.yaml diff --git a/manifests/crds/kustomization.yaml b/manifests/crds/kustomization.yaml index 3f3f914e..c29dc4ec 100644 --- a/manifests/crds/kustomization.yaml +++ b/manifests/crds/kustomization.yaml @@ -1,10 +1,10 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: -- https://github.com/fluxcd/source-controller/releases/download/v1.8.2/source-controller.crds.yaml -- https://github.com/fluxcd/kustomize-controller/releases/download/v1.8.3/kustomize-controller.crds.yaml +- https://github.com/fluxcd/source-controller/releases/download/v1.8.1/source-controller.crds.yaml +- https://github.com/fluxcd/kustomize-controller/releases/download/v1.8.2/kustomize-controller.crds.yaml - https://github.com/fluxcd/helm-controller/releases/download/v1.5.3/helm-controller.crds.yaml -- https://github.com/fluxcd/notification-controller/releases/download/v1.8.3/notification-controller.crds.yaml +- https://github.com/fluxcd/notification-controller/releases/download/v1.8.2/notification-controller.crds.yaml - https://github.com/fluxcd/image-reflector-controller/releases/download/v1.1.1/image-reflector-controller.crds.yaml - https://github.com/fluxcd/image-automation-controller/releases/download/v1.1.1/image-automation-controller.crds.yaml - https://github.com/fluxcd/source-watcher/releases/download/v2.1.1/source-watcher.crds.yaml diff --git a/pkg/manifestgen/sourcesecret/options.go b/pkg/manifestgen/sourcesecret/options.go index 9fe7b49d..a226a4db 100644 --- a/pkg/manifestgen/sourcesecret/options.go +++ b/pkg/manifestgen/sourcesecret/options.go @@ -42,12 +42,6 @@ const ( KnownHostsSecretKey = "known_hosts" BearerTokenKey = "bearerToken" TrustPolicyKey = "trustpolicy.json" - TokenSecretKey = "token" - EmailSecretKey = "email" - AudienceSecretKey = "audience" - - // WebhookURLAnnotation is the annotation key for the computed webhook URL. - WebhookURLAnnotation = "notification.toolkit.fluxcd.io/webhook" // Deprecated: Replaced by CACrtSecretKey, but kept for backwards // compatibility with deprecated TLS flags. @@ -88,13 +82,6 @@ type Options struct { GitHubAppInstallationID string GitHubAppPrivateKey string GitHubAppBaseURL string - - // Receiver options - ReceiverType string - Token string - Hostname string - EmailClaim string - AudienceClaim string } type VerificationCrt struct { diff --git a/pkg/manifestgen/sourcesecret/sourcesecret.go b/pkg/manifestgen/sourcesecret/sourcesecret.go index 54cca4e8..709f8d01 100644 --- a/pkg/manifestgen/sourcesecret/sourcesecret.go +++ b/pkg/manifestgen/sourcesecret/sourcesecret.go @@ -18,10 +18,7 @@ package sourcesecret import ( "bytes" - "crypto/rand" - "crypto/sha256" "encoding/base64" - "encoding/hex" "encoding/json" "fmt" "net" @@ -263,59 +260,6 @@ func GenerateGitHubApp(options Options) (*manifestgen.Manifest, error) { return secretToManifest(secret, options) } -func GenerateReceiver(options Options) (*manifestgen.Manifest, error) { - token := options.Token - if token == "" { - b := make([]byte, 32) - if _, err := rand.Read(b); err != nil { - return nil, fmt.Errorf("failed to generate random token: %w", err) - } - token = hex.EncodeToString(b) - } - - if options.Hostname == "" { - return nil, fmt.Errorf("hostname is required") - } - - // Compute the webhook path using the same algorithm as notification-controller. - // See: github.com/fluxcd/notification-controller/api/v1.Receiver.GetWebhookPath - digest := sha256.Sum256([]byte(token + options.Name + options.Namespace)) - webhookPath := fmt.Sprintf("/hook/%x", digest) - webhookURL := fmt.Sprintf("https://%s%s", options.Hostname, webhookPath) - - secret := &corev1.Secret{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Secret", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: options.Name, - Namespace: options.Namespace, - Labels: options.Labels, - Annotations: map[string]string{ - WebhookURLAnnotation: webhookURL, - }, - }, - StringData: map[string]string{ - TokenSecretKey: token, - }, - } - - if options.ReceiverType == "gcr" { - if options.EmailClaim == "" { - return nil, fmt.Errorf("email-claim is required for gcr receiver type") - } - secret.StringData[EmailSecretKey] = options.EmailClaim - if options.AudienceClaim != "" { - secret.StringData[AudienceSecretKey] = options.AudienceClaim - } else { - secret.StringData[AudienceSecretKey] = webhookURL - } - } - - return secretToManifest(secret, options) -} - func LoadKeyPairFromPath(path, password string) (*ssh.KeyPair, error) { if path == "" { return nil, nil diff --git a/rfcs/0010-multi-tenant-workload-identity/README.md b/rfcs/0010-multi-tenant-workload-identity/README.md index 920e402e..9ed342d9 100644 --- a/rfcs/0010-multi-tenant-workload-identity/README.md +++ b/rfcs/0010-multi-tenant-workload-identity/README.md @@ -1,10 +1,15 @@ # RFC-0010 Multi-Tenant Workload Identity -**Status:** implemented +**Status:** implementable + + **Creation date:** 2025-02-22 -**Last update:** 2026-03-13 +**Last update:** 2025-04-29 ## Summary @@ -1415,11 +1420,10 @@ options to call `gcp.NewTokenSource()` and feed this token source to the `HelmRepository` and `HelmChart`, as well as for SOPS decryption in the `Kustomization` API and Azure Event Hubs in the `Provider` API. -* In Flux 2.7 object-level workload identity was introduced for all - the remaining APIs that support cloud providers, i.e. `Bucket`, - `GitRepository` and `ImageUpdateAutomation`, and also all the - remaining types for the `Provider` API, i.e. `azuredevops` and - `googlepubsub`. In addition, support for controller and - object-level workload identity was introduced for the - `Kustomization` and `HelmRelease` APIs for remote cluster - access. + + diff --git a/rfcs/0011-opentelemetry-tracing/README.md b/rfcs/0011-opentelemetry-tracing/README.md index 3dd5e851..768e05a4 100644 --- a/rfcs/0011-opentelemetry-tracing/README.md +++ b/rfcs/0011-opentelemetry-tracing/README.md @@ -1,10 +1,15 @@ # RFC-0011: OpenTelemetry Tracing -**Status:** implemented +**Status:** provisional + + **Creation date:** 2025-04-24 -**Last update:** 2026-03-13 +**Last update:** 2025-08-13 ## Summary The aim is to be able to collect traces via OpenTelemetry (OTel) across all Flux related objects, such as HelmReleases, Kustomizations and among others. These may be sent towards a tracing provider where may be potentially stored and visualized. Flux does not have any responsibility on storing and visualizing those, it keeps being completely stateless. Thereby, being seamless for the user, the implementation is going to be part of the already existing `Alert` API Type. Therefore, `EventSources` is going to discriminate the events belonging to the specific sources, which are going to be looked up to and send them out towards the `Provider` set. In this way, it could facilitate the observability and monitoring of Flux related objects. @@ -205,4 +210,9 @@ This design ensures trace continuity even in challenging distributed environment ## Implementation History -* RFC implemented and generally available in Flux [v2.7.0](https://github.com/fluxcd/flux2/releases/tag/v2.7.0) + diff --git a/rfcs/0012-external-artifact/README.md b/rfcs/0012-external-artifact/README.md index c8d21bbf..602c4918 100644 --- a/rfcs/0012-external-artifact/README.md +++ b/rfcs/0012-external-artifact/README.md @@ -1,10 +1,10 @@ # RFC-0012 External Artifact -**Status:** implemented +**Status:** provisional **Creation date:** 2025-04-08 -**Last update:** 2026-03-13 +**Last update:** 2025-09-03 ## Summary @@ -319,4 +319,9 @@ control the adoption of the `ExternalArtifact` feature in their clusters. ## Implementation History -* RFC implemented and generally available in Flux [v2.7.0](https://github.com/fluxcd/flux2/releases/tag/v2.7.0) + diff --git a/rfcs/0013-cli-plugin-system/README.md b/rfcs/0013-cli-plugin-system/README.md deleted file mode 100644 index 4d0cfeef..00000000 --- a/rfcs/0013-cli-plugin-system/README.md +++ /dev/null @@ -1,334 +0,0 @@ -# RFC-0013 Flux CLI Plugin System - -**Status:** implementable - -**Creation date:** 2026-03-30 - -**Last update:** 2026-04-13 - -## Summary - -This RFC proposes a plugin system for the Flux CLI that allows external CLI tools to be -discoverable and invocable as `flux ` subcommands. Plugins are installed from a -centralized catalog hosted on GitHub, with SHA-256 checksum verification and automatic -version updates. The design follows the established kubectl plugin pattern used across -the Kubernetes ecosystem. - -## Motivation - -The Flux CLI currently has no mechanism for extending its functionality with external tools. -Projects like [flux-operator](https://github.com/controlplaneio-fluxcd/flux-operator) and -[flux-local](https://github.com/allenporter/flux-local) provide complementary CLI tools -that users install and invoke separately. This creates a fragmented user experience where -Flux-related workflows require switching between multiple binaries with different flag -conventions and discovery mechanisms. - -The Kubernetes ecosystem has a proven model for CLI extensibility: kubectl plugins are -executables prefixed with `kubectl-` that can be discovered, installed via -[krew](https://krew.sigs.k8s.io/), and invoked as `kubectl `. This model has -been widely adopted and is well understood by Kubernetes users. - -### Goals - -- Allow external CLI tools to be invoked as `flux ` subcommands without modifying - the external binary. -- Provide a `flux plugin install` command to download plugins from a centralized catalog - with checksum verification. -- Support shell completion for plugin subcommands by delegating to the plugin's own - Cobra `__complete` command. -- Support plugins written as scripts (Python, Bash, etc.) via symlinks into the - plugin directory. -- Ensure built-in commands always take priority over plugins. -- Keep the plugin system lightweight with zero impact on non-plugin Flux commands. - -### Non-Goals - -- Plugin dependency management (plugins are standalone binaries). -- Cosign/SLSA signature verification (SHA-256 only in v1beta1; signatures can be added later). -- Automatic update checks on startup (users run `flux plugin update` explicitly). -- Private catalog authentication (users can use `$FLUXCD_PLUGIN_CATALOG` with TLS). -- Flag sharing between Flux and plugins (`--namespace`, `--context`, etc. are not - forwarded; plugins manage their own flags). - -## Proposal - -### Plugin Discovery - -Plugins are executables prefixed with `flux-` placed in a single plugin directory. -The `flux-` binary maps to the `flux ` command. For example, -`flux-operator` becomes `flux operator`. - -The default plugin directory is `~/.fluxcd/plugins/`. Users can override it with the -`FLUXCD_PLUGINS` environment variable. Only this single directory is scanned. - -When a plugin is discovered, it appears under a "Plugin Commands:" group in `flux --help`: - -``` -Plugin Commands: - operator Runs the operator plugin - -Additional Commands: - bootstrap Deploy Flux on a cluster the GitOps way. - ... -``` - -### Plugin Execution - -On macOS and Linux, `flux operator export report` replaces the current process with -`flux-operator export report` via `syscall.Exec`, matching kubectl's behavior. -On Windows, the plugin runs as a child process with full I/O passthrough. -All arguments after the plugin name are passed through verbatim with -`DisableFlagParsing: true`. - -### Shell Completion - -Shell completion is delegated to the plugin binary via Cobra's `__complete` protocol. -When the user types `flux operator get `, Flux runs -`flux-operator __complete get ""` and returns the results. This works automatically -for all Cobra-based plugins (like flux-operator). Non-Cobra plugins gracefully degrade -to no completions. - -### Plugin Catalog - -A dedicated GitHub repository ([fluxcd/plugins](https://github.com/fluxcd/plugins)) -serves as the plugin catalog. Each plugin has a YAML manifest: - -```yaml -apiVersion: cli.fluxcd.io/v1beta1 -kind: Plugin -name: operator -description: Flux Operator CLI -homepage: https://fluxoperator.dev/ -source: https://github.com/controlplaneio-fluxcd/flux-operator -bin: flux-operator -versions: - - version: 0.45.0 - platforms: - - os: darwin - arch: arm64 - url: https://github.com/.../flux-operator_0.45.0_darwin_arm64.tar.gz - checksum: sha256:cd85d5d84d264... - - os: linux - arch: amd64 - url: https://github.com/.../flux-operator_0.45.0_linux_amd64.tar.gz - checksum: sha256:96198da969096... - - os: windows - arch: amd64 - url: https://github.com/.../flux-operator_0.45.0_windows_amd64.zip - checksum: sha256:9712026094a5... -``` - -The plugin manifest includes metadata (name, description, homepage, source repo), the binary name -(`bin`), and a list of versions with platform-specific download URLs and checksums. - -The download URLs can point to one of the following formats: - -- An archive containing the binary (`tar`, `tar.gz` or `zip`), with the binary at the root of the archive. The binary name inside the archive must match the `bin` field in the manifest. -- An optional `extractPath` field can be specified in a `platforms` entry to override this default, either because the binary has a different name on this platform, or because it is nested in a subfolder rather than at the root of the archive. It accepts an absolute path to a file within the archive (e.g., `bin/flux-operator`). -- A direct binary URL. The binary is downloaded and saved without extraction. The `bin` field is used for naming the installed plugin, not for discovery in this case. -- Note that when the OS is Windows, the binary name is composed by appending `.exe` to the `bin` field (e.g., `flux-operator.exe`). - -The Flux Operator CLI detects if the URL points to an archive by checking the file extension. -If no extension is present, it checks the content type by probing for archive magic bytes after downloading the file. -If the content is not an archive, it treats it as a direct binary URL. - -A generated `catalog.yaml` (`PluginCatalog` kind) contains static metadata for all -plugins, enabling `flux plugin search` with a single HTTP fetch. - -### CLI Commands - -| Command | Description | -|---------|-------------| -| `flux plugin list` (alias: `ls`) | List installed plugins with versions and paths | -| `flux plugin install [@]` | Install a plugin from the catalog | -| `flux plugin uninstall ` | Remove a plugin binary and receipt | -| `flux plugin update [name]` | Update one or all installed plugins | -| `flux plugin search [query]` | Search the plugin catalog | - -### Install Flow - -1. Fetch `plugins/.yaml` from the catalog URL -2. Validate `apiVersion: cli.fluxcd.io/v1beta1` and `kind: Plugin` -3. Resolve version (latest if unspecified, or match `@version`) -4. Find platform entry matching `runtime.GOOS` / `runtime.GOARCH` -5. Download archive to temp file with SHA-256 checksum verification -6. Extract only the declared binary from the archive (tar.gz or zip), streaming - directly to disk without buffering in memory -7. Write binary to plugin directory as `flux-` (mode `0755`) -8. Write install receipt (`flux-.yaml`) recording version, platform, download URL, checksum and timestamp - -Install is idempotent -- reinstalling overwrites the binary and receipt. - -### Install Receipts - -When a plugin is installed via `flux plugin install`, a receipt file is written -next to the binary: - -```yaml -name: operator -version: "0.45.0" -installedAt: "2026-03-30T10:00:00Z" -platform: - os: darwin - arch: arm64 - url: https://github.com/.../flux-operator_0.45.0_darwin_arm64.tar.gz - checksum: sha256:cd85d5d84d264... -``` - -Receipts enable `flux plugin list` to show versions, `flux plugin update` to compare -installed vs. latest, and provenance tracking. Manually installed plugins (no receipt) -show `manual` in listings and are skipped by `flux plugin update`. - -### User Stories - -#### Flux User Installs a Plugin - -As a Flux user, I want to install the Flux Operator CLI as a plugin so that I can -manage Flux instances using `flux operator` instead of a separate `flux-operator` binary. - -```bash -flux plugin install operator -flux operator get instance -n flux-system -``` - -#### Flux User Updates Plugins - -As a Flux user, I want to update all my installed plugins to the latest versions -with a single command. - -```bash -flux plugin update -``` - -#### Flux User Symlinks a Python Plugin - -As a Flux user, I want to use [flux-local](https://github.com/allenporter/flux-local) -(a Python tool) as a Flux CLI plugin by symlinking it into the plugin directory. -Since flux-local is not a Go binary distributed via the catalog, I install it with -pip and register it manually. - -```bash -uv venv -source .venv/bin/activate -uv pip install flux-local -ln -s "$(pwd)/.venv/bin/flux-local" ~/.fluxcd/plugins/flux-local -flux local test -``` - -Manually symlinked plugins show `manual` in `flux plugin list` and are skipped by -`flux plugin update`. - -#### Flux User Discovers Available Plugins - -As a Flux user, I want to search for available plugins so that I can extend my -Flux CLI with community tools. - -```bash -flux plugin search -``` - -#### Plugin Author Publishes a Plugin - -As a plugin author, I want to submit my tool to the Flux plugin catalog so that -Flux users can install it with `flux plugin install `. - -1. Release binary with GoReleaser (produces tarballs/zips + checksums) -2. Submit a PR to `fluxcd/plugins` with `plugins/.yaml` -3. Subsequent releases are picked up by automated polling workflows - -Plugin authors are responsible for maintaining their plugin definitions in the catalog, -by responding to issues and approving PRs for updates. - -### Alternatives - -#### PATH-based Discovery (kubectl model) - -kubectl discovers plugins by scanning `$PATH` for `kubectl-*` executables. This is -simple but has drawbacks: - -- Scanning the entire PATH is slow on some systems -- No control over what's discoverable (any `flux-*` binary on PATH becomes a plugin) -- No install/update mechanism built in (requires a separate tool like krew) - -The single-directory approach is faster, more predictable, and integrates install/update -directly into the CLI. - -## Design Details - -### Package Structure - -``` -internal/plugin/ - discovery.go # Plugin dir scanning, DI-based Handler - completion.go # Shell completion via Cobra __complete protocol - exec_unix.go # syscall.Exec (//go:build !windows) - exec_windows.go # os/exec fallback (//go:build windows) - catalog.go # Catalog fetching, manifest parsing, version/platform resolution - install.go # Download, verify, extract, receipts - update.go # Compare receipts vs catalog, update check - -cmd/flux/ - plugin.go # Cobra command registration, all plugin subcommands -``` - -The `internal/plugin` package uses dependency injection (injectable `ReadDir`, `Stat`, -`GetEnv`, `HomeDir` on a `Handler` struct) for testability. Tests mock these functions -directly without filesystem fixtures. - -### Plugin Directory - -- **Default**: `~/.fluxcd/plugins/` -- auto-created by install/update commands - (best-effort, no error if filesystem is read-only). -- **Override**: `FLUXCD_PLUGINS` env var replaces the default directory path. - When set, the CLI does not auto-create the directory. - -### Startup Behavior - -`registerPlugins()` is called in `main()` before `rootCmd.Execute()`. It scans the -plugin directory and registers discovered plugins as Cobra subcommands. The scan is -lightweight (a single `ReadDir` call) and only occurs if the plugin directory exists. -Built-in commands always take priority. - -### Manifest Validation - -Both plugin manifests and the catalog are validated after fetching: - -- `apiVersion` must be `cli.fluxcd.io/v1beta1` -- `kind` must be `Plugin` or `PluginCatalog` respectively -- Checksum format is `:` (currently `sha256:...`), allowing future - algorithm migration without schema changes - -### Security Considerations - -- **Checksum verification**: All downloaded archives are verified against SHA-256 - checksums declared in the catalog manifest before extraction. -- **Path traversal protection**: Archive extraction guards against tar traversal. -- **Response size limits**: HTTP responses from the catalog are capped at 10 MiB to - prevent unbounded memory allocation from malicious servers. -- **No code execution during discovery**: Plugin directory scanning only reads directory - entries and file metadata. No plugin binary is executed during startup. -- **Retryable fetching**: All HTTP/S operations use automatic retries for transient network failures. - -### Catalog Repository CI - -The `fluxcd/plugins` repository includes CI workflows that: - -1. Validate plugin manifests on every PR (schema, name consistency, URL reachability, - checksum verification, binary presence in archives, no builtin collisions) -2. Regenerate `catalog.yaml` when plugins are added or removed -3. Automatically poll upstream repositories for new releases and create update PRs -4. Plugin authors have to agree to maintain their plugin's definition by responding to issues and approving PRs in the catalog repo. - -### Known Limitations (v1beta1) - -1. **No cosign/SLSA verification** -- SHA-256 only. Signature verification can be added later. -2. **No plugin dependencies** -- plugins are standalone binaries. -3. **No automatic update checks** -- users run `flux plugin update` explicitly. -4. **No private catalog auth** -- `$FLUXCD_PLUGIN_CATALOG` works for private URLs but no token injection. -5. **No version constraints** -- no `>=0.44.0` ranges. Exact version or latest only. -6. **Flag names differ between Flux and plugins** -- e.g., `--context` (flux) vs - `--kube-context` (flux-operator). This is a plugin concern, not a system concern. - -## Implementation History - -- **2026-03-30** PoC plugin catalog repository with example manifests and CI validation workflows available at [fluxcd/plugins](https://github.com/fluxcd/plugins). diff --git a/tests/integration/azure_test.go b/tests/integration/azure_test.go index c92f47f5..6c7cab14 100644 --- a/tests/integration/azure_test.go +++ b/tests/integration/azure_test.go @@ -19,10 +19,9 @@ package integration import ( "context" "fmt" - "log" "os" - azeventhubs "github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs/v2" + eventhub "github.com/Azure/azure-event-hubs-go/v3" "github.com/fluxcd/pkg/git" "github.com/fluxcd/test-infra/tftestenv" tfjson "github.com/hashicorp/terraform-json" @@ -149,47 +148,27 @@ func registryLoginACR(ctx context.Context, output map[string]*tfjson.StateOutput } func setupEventHubHandler(ctx context.Context, c chan []byte, eventHubSas string) (func(), error) { - consumerClient, err := azeventhubs.NewConsumerClientFromConnectionString(eventHubSas, "", azeventhubs.DefaultConsumerGroup, nil) + hub, err := eventhub.NewHubFromConnectionString(eventHubSas) if err != nil { return nil, err } - props, err := consumerClient.GetEventHubProperties(ctx, nil) + handler := func(ctx context.Context, event *eventhub.Event) error { + c <- event.Data + return nil + } + runtimeInfo, err := hub.GetRuntimeInformation(ctx) if err != nil { - consumerClient.Close(ctx) return nil, err } - - latest := true - partitionClient, err := consumerClient.NewPartitionClient(props.PartitionIDs[0], &azeventhubs.PartitionClientOptions{ - StartPosition: azeventhubs.StartPosition{Latest: &latest}, - }) + listenerHandler, err := hub.Receive(ctx, runtimeInfo.PartitionIDs[0], handler, eventhub.ReceiveWithLatestOffset()) if err != nil { - consumerClient.Close(ctx) return nil, err } - receiveCtx, cancel := context.WithCancel(ctx) - go func() { - for { - events, err := partitionClient.ReceiveEvents(receiveCtx, 1, nil) - if err != nil { - if receiveCtx.Err() != nil { - return - } - log.Printf("error receiving event hub events: %s\n", err) - return - } - for _, event := range events { - c <- event.Body - } - } - }() - closefn := func() { - cancel() - partitionClient.Close(ctx) - consumerClient.Close(ctx) + listenerHandler.Close(ctx) + hub.Close(ctx) } return closefn, nil diff --git a/tests/integration/gcp_test.go b/tests/integration/gcp_test.go index d33b566b..8d901dcb 100644 --- a/tests/integration/gcp_test.go +++ b/tests/integration/gcp_test.go @@ -24,7 +24,7 @@ import ( "os" "strings" - "cloud.google.com/go/pubsub/v2" + "cloud.google.com/go/pubsub" tfjson "github.com/hashicorp/terraform-json" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -159,7 +159,7 @@ func setupPubSubReceiver(ctx context.Context, c chan []byte, projectID string, t return nil, fmt.Errorf("error creating pubsub client: %s", err) } - sub := pubsubClient.Subscriber(topicID) + sub := pubsubClient.Subscription(topicID) go func() { err = sub.Receive(ctx, func(ctx context.Context, message *pubsub.Message) { c <- message.Data diff --git a/tests/integration/go.mod b/tests/integration/go.mod index 0f15b014..1c4561af 100644 --- a/tests/integration/go.mod +++ b/tests/integration/go.mod @@ -3,27 +3,27 @@ module github.com/fluxcd/flux2/tests/integration go 1.26.0 require ( - cloud.google.com/go/pubsub/v2 v2.0.0 - github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs/v2 v2.0.2 + cloud.google.com/go/pubsub v1.50.1 + github.com/Azure/azure-event-hubs-go/v3 v3.6.2 github.com/chainguard-dev/git-urls v1.0.2 github.com/fluxcd/helm-controller/api v1.4.5 github.com/fluxcd/image-automation-controller/api v1.0.4 github.com/fluxcd/image-reflector-controller/api v1.0.4 github.com/fluxcd/kustomize-controller/api v1.7.3 github.com/fluxcd/notification-controller/api v1.7.5 - github.com/fluxcd/pkg/apis/event v0.25.0 - github.com/fluxcd/pkg/apis/meta v1.26.0 - github.com/fluxcd/pkg/git v0.46.0 - github.com/fluxcd/pkg/runtime v0.103.0 + github.com/fluxcd/pkg/apis/event v0.24.1 + github.com/fluxcd/pkg/apis/meta v1.25.1 + github.com/fluxcd/pkg/git v0.43.1 + github.com/fluxcd/pkg/runtime v0.100.4 github.com/fluxcd/source-controller/api v1.7.4 github.com/fluxcd/test-infra/tftestenv v0.0.0-20250626232827-e0ca9c3f8d7b - github.com/go-git/go-git/v5 v5.17.2 + github.com/go-git/go-git/v5 v5.16.5 github.com/google/go-containerregistry v0.20.7 github.com/hashicorp/terraform-exec v0.24.0 github.com/hashicorp/terraform-json v0.27.2 github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5 github.com/onsi/gomega v1.39.0 - google.golang.org/grpc v1.79.3 + google.golang.org/grpc v1.77.0 k8s.io/api v0.35.2 k8s.io/apimachinery v0.35.2 k8s.io/client-go v0.35.2 @@ -36,20 +36,29 @@ require ( cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect cloud.google.com/go/iam v1.5.2 // indirect + cloud.google.com/go/pubsub/v2 v2.0.0 // indirect dario.cat/mergo v1.0.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect - github.com/Azure/go-amqp v1.5.0 // indirect + github.com/Azure/azure-amqp-common-go/v4 v4.2.0 // indirect + github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect + github.com/Azure/go-amqp v1.4.0 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest v0.11.30 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.24 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.1 // indirect + github.com/Azure/go-autorest/autorest/to v0.4.1 // indirect + github.com/Azure/go-autorest/autorest/validation v0.3.2 // indirect + github.com/Azure/go-autorest/logger v0.2.2 // indirect + github.com/Azure/go-autorest/tracing v0.6.1 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.3.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudflare/circl v1.6.3 // indirect github.com/containerd/stargz-snapshotter/estargz v0.18.1 // indirect github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/docker/cli v29.2.0+incompatible // indirect + github.com/devigned/tab v0.1.1 // indirect + github.com/docker/cli v29.0.3+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect @@ -57,17 +66,18 @@ require ( github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fluxcd/pkg/apis/acl v0.9.0 // indirect - github.com/fluxcd/pkg/apis/kustomize v1.16.0 // indirect + github.com/fluxcd/pkg/apis/kustomize v1.15.1 // indirect github.com/fluxcd/pkg/ssh v0.24.0 // indirect - github.com/fluxcd/pkg/version v0.14.0 // indirect + github.com/fluxcd/pkg/version v0.12.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.8.0 // indirect + github.com/go-git/go-billy/v5 v5.7.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.21.1 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.1 // indirect + github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/go-cmp v0.7.0 // indirect @@ -84,11 +94,13 @@ require ( github.com/hashicorp/hc-install v0.9.2 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/josharian/intern v1.0.0 // indirect + github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/klauspost/compress v1.18.1 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect @@ -104,35 +116,33 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/zclconf/go-cty v1.16.4 // indirect - go.einride.tech/aip v0.73.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.43.0 // indirect - go.opentelemetry.io/otel/metric v1.43.0 // indirect - go.opentelemetry.io/otel/trace v1.43.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.50.0 // indirect - golang.org/x/mod v0.34.0 // indirect - golang.org/x/net v0.53.0 // indirect - golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.43.0 // indirect - golang.org/x/term v0.42.0 // indirect - golang.org/x/text v0.36.0 // indirect + golang.org/x/crypto v0.47.0 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/term v0.39.0 // indirect + golang.org/x/text v0.33.0 // indirect golang.org/x/time v0.14.0 // indirect google.golang.org/api v0.247.0 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect google.golang.org/protobuf v1.36.10 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - gotest.tools/v3 v3.5.2 // indirect k8s.io/apiextensions-apiserver v0.35.2 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect diff --git a/tests/integration/go.sum b/tests/integration/go.sum index 8705ffe7..6b0e62eb 100644 --- a/tests/integration/go.sum +++ b/tests/integration/go.sum @@ -9,28 +9,53 @@ cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdB cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= +cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk= +cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8= +cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE= +cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY= +cloud.google.com/go/pubsub v1.50.1 h1:fzbXpPyJnSGvWXF1jabhQeXyxdbCIkXTpjXHy7xviBM= +cloud.google.com/go/pubsub v1.50.1/go.mod h1:6YVJv3MzWJUVdvQXG081sFvS0dWQOdnV+oTo++q/xFk= cloud.google.com/go/pubsub/v2 v2.0.0 h1:0qS6mRJ41gD1lNmM/vdm6bR7DQu6coQcVwD+VPf0Bz0= cloud.google.com/go/pubsub/v2 v2.0.0/go.mod h1:0aztFxNzVQIRSZ8vUr79uH2bS3jwLebwK6q1sgEub+E= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 h1:JXg2dwJUmPB9JmtVmdEB16APJ7jurfbY5jnfXpJoRMc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= -github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs/v2 v2.0.2 h1:EBiOwZYJUMsjLGJ9x0oNY6ADf+5915P/jhhVcn42KXc= -github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs/v2 v2.0.2/go.mod h1:NjuxmUsBJ0Ya9Xxjhjo06bj3/QB4C8z838I5S88UtQQ= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/eventhub/armeventhub v1.3.0 h1:4hGvxD72TluuFIXVr8f4XkKZfqAa7Pj61t0jmQ7+kes= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/eventhub/armeventhub v1.3.0/go.mod h1:TSH7DcFItwAufy0Lz+Ft2cyopExCpxbOxI5SkH4dRNo= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.3 h1:ZJJNFaQ86GVKQ9ehwqyAFE6pIfyicpuJ8IkVaPBc6/4= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.3/go.mod h1:URuDvhmATVKqHBH9/0nOiNKk0+YcwfQ3WkK5PqHKxc8= -github.com/Azure/go-amqp v1.5.0 h1:GRiQK1VhrNFbyx5VlmI6BsA1FCp27W5rb9kxOZScnTo= -github.com/Azure/go-amqp v1.5.0/go.mod h1:vZAogwdrkbyK3Mla8m/CxSc/aKdnTZ4IbPxl51Y5WZE= -github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs= -github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= +github.com/Azure/azure-amqp-common-go/v4 v4.2.0 h1:q/jLx1KJ8xeI8XGfkOWMN9XrXzAfVTkyvCxPvHCjd2I= +github.com/Azure/azure-amqp-common-go/v4 v4.2.0/go.mod h1:GD3m/WPPma+621UaU6KNjKEo5Hl09z86viKwQjTpV0Q= +github.com/Azure/azure-event-hubs-go/v3 v3.6.2 h1:7rNj1/iqS/i3mUKokA2n2eMYO72TB7lO7OmpbKoakKY= +github.com/Azure/azure-event-hubs-go/v3 v3.6.2/go.mod h1:n+ocYr9j2JCLYqUqz9eI+lx/TEAtL/g6rZzyTFSuIpc= +github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= +github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-amqp v1.4.0 h1:Xj3caqi4comOF/L1Uc5iuBxR/pB6KumejC01YQOqOR4= +github.com/Azure/go-amqp v1.4.0/go.mod h1:vZAogwdrkbyK3Mla8m/CxSc/aKdnTZ4IbPxl51Y5WZE= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.30 h1:iaZ1RGz/ALZtN5eq4Nr1SOFSlf2E4pDI3Tcsl+dZPVE= +github.com/Azure/go-autorest/autorest v0.11.30/go.mod h1:t1kpPIOpIVX7annvothKvb0stsrXa37i7b+xpmBW8Fs= +github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= +github.com/Azure/go-autorest/autorest/adal v0.9.24 h1:BHZfgGsGwdkHDyZdtQRQk1WeUdW0m2WPAwuHZwUi5i4= +github.com/Azure/go-autorest/autorest/adal v0.9.24/go.mod h1:7T1+g0PYFmACYW5LlG2fcoPiPlFHjClyRGL7dRlP5c8= +github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 h1:iM6UAvjR97ZIeR93qTcwpKNMpV+/FTWjwEbuPD495Tk= +github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= +github.com/Azure/go-autorest/autorest/azure/cli v0.3.1 h1:LXl088ZQlP0SBppGFsRZonW6hSvwgL5gRByMbvUbx8U= +github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/date v0.3.1 h1:o9Z8Jyt+VJJTCZ/UORishuHOusBwolhjokt9s5k8I4w= +github.com/Azure/go-autorest/autorest/date v0.3.1/go.mod h1:Dz/RDmXlfiFFS/eW+b/xMUSFs1tboPVy6UjgADToWDM= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= +github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= +github.com/Azure/go-autorest/autorest/to v0.4.1 h1:CxNHBqdzTr7rLtdrtb5CMjJcDut+WNGCVv7OmS5+lTc= +github.com/Azure/go-autorest/autorest/to v0.4.1/go.mod h1:EtaofgU4zmtvn1zT2ARsjRFdq9vXx0YWtmElwL+GZ9M= +github.com/Azure/go-autorest/autorest/validation v0.3.2 h1:myD3tcvs+Fk1bkJ1Xx7xidop4z4FWvWADiMGMXeVd2E= +github.com/Azure/go-autorest/autorest/validation v0.3.2/go.mod h1:4z7eU88lSINAB5XL8mhfPumiUdoAQo/c7qXwbsM8Zhc= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/logger v0.2.2 h1:hYqBsEBywrrOSW24kkOCXRcKfKhK76OzLTfF+MYDE2o= +github.com/Azure/go-autorest/logger v0.2.2/go.mod h1:I5fg9K52o+iuydlWfa9T5K6WFos9XYr9dYTFzpqgibw= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/Azure/go-autorest/tracing v0.6.1 h1:YUMSrC/CeD1ZnnXcNYU4a/fzsO35u2Fsful9L/2nyR0= +github.com/Azure/go-autorest/tracing v0.6.1/go.mod h1:/3EgjbsjraOqiicERAeu3m7/z0x1TzjQGAwDrJrXGkc= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= @@ -56,10 +81,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= -github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= -github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= -github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= +github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0= +github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4= github.com/containerd/stargz-snapshotter/estargz v0.18.1 h1:cy2/lpgBXDA3cDKSyEfNOFMA/c10O1axL69EU7iirO8= github.com/containerd/stargz-snapshotter/estargz v0.18.1/go.mod h1:ALIEqa7B6oVDsrF37GkGN20SuvG/pIMm7FwP7ZmRb0Q= github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE= @@ -68,8 +91,12 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/cli v29.2.0+incompatible h1:9oBd9+YM7rxjZLfyMGxjraKBKE4/nVyvVfN4qNl9XRM= -github.com/docker/cli v29.2.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/devigned/tab v0.1.1 h1:3mD6Kb1mUOYeLpJvTVSDwSg5ZsfSxfvxGRTxRsJsITA= +github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= +github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/docker/cli v29.0.3+incompatible h1:8J+PZIcF2xLd6h5sHPsp5pvvJA+Sr2wGQxHkRl53a1E= +github.com/docker/cli v29.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= @@ -83,12 +110,12 @@ github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FM github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= -github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= -github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= +github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM= +github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo= +github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4= -github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= @@ -109,22 +136,22 @@ github.com/fluxcd/notification-controller/api v1.7.5 h1:6CO5bKyjodiK9exQFOdBcz0X github.com/fluxcd/notification-controller/api v1.7.5/go.mod h1:IciwSg8Q0pVtdbsyDyEXx/MxBKWeagxAazpm64C8oCE= github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA= github.com/fluxcd/pkg/apis/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4= -github.com/fluxcd/pkg/apis/event v0.25.0 h1:zdwytvDhG+fk+Ywl5DOtv7TklkrVgM21WHm1f+YhleE= -github.com/fluxcd/pkg/apis/event v0.25.0/go.mod h1:TlK8HWYrTwl0raqBRC+ROoNpYW5fdVnwcwOBOx5Kzw8= -github.com/fluxcd/pkg/apis/kustomize v1.16.0 h1:PhWXEhqQqsisIpwp1/wHvTvo+MO+GGzsBPoN0ZnRE3Y= -github.com/fluxcd/pkg/apis/kustomize v1.16.0/go.mod h1:IZOy4CCtR/hxMGb7erK1RfbGnczVv4/dRBoVD37AywI= -github.com/fluxcd/pkg/apis/meta v1.26.0 h1:dxP1FfBpTCYso6odzRcltVnnRuBb2VyhhgV0VX9YbUE= -github.com/fluxcd/pkg/apis/meta v1.26.0/go.mod h1:c7o6mJGLCMvNrfdinGZehkrdZuFT9vZdZNrn66DtVD0= -github.com/fluxcd/pkg/git v0.46.0 h1:QMh0+ZzQ2jO6rIGj4ffR5trZ8g/cxvt8cVajReJ8Iyw= -github.com/fluxcd/pkg/git v0.46.0/go.mod h1:iHcIjx9c8zye3PQiajTJYxgOMRiy7WCs+hfLKDswpfI= -github.com/fluxcd/pkg/gittestserver v0.26.0 h1:+RZrCzFRsE+d5WaqAoqaPCEgcgv/jZp6+f7DS0+Ynb8= -github.com/fluxcd/pkg/gittestserver v0.26.0/go.mod h1:7fybYb0yej1fFNiF1ohs0Jr0XzyaZQ/cRh3AFEoCtuc= -github.com/fluxcd/pkg/runtime v0.103.0 h1:J5y5GPhWdkyqIUBlaI1FP2N02TtZmsjbWhhZubuTSFk= -github.com/fluxcd/pkg/runtime v0.103.0/go.mod h1:mbo2f3azo3yVQgm7XZGxQB6/2zvzQ5Wgtd8TjRRwwAw= +github.com/fluxcd/pkg/apis/event v0.24.1 h1:TClVdn02aiq3sAl9BuzLjjTIxm3JJ83fJ9nchtBa4qg= +github.com/fluxcd/pkg/apis/event v0.24.1/go.mod h1:TlK8HWYrTwl0raqBRC+ROoNpYW5fdVnwcwOBOx5Kzw8= +github.com/fluxcd/pkg/apis/kustomize v1.15.1 h1:t9QZh+3ZS8EKmlxrnnbcKZcGTrg8FDvMF1T8BHMCuqI= +github.com/fluxcd/pkg/apis/kustomize v1.15.1/go.mod h1:IZOy4CCtR/hxMGb7erK1RfbGnczVv4/dRBoVD37AywI= +github.com/fluxcd/pkg/apis/meta v1.25.1 h1:WG1GIC/SOz0GjxT0uVuO6AMicQ3yFsk6bDozCnq+fto= +github.com/fluxcd/pkg/apis/meta v1.25.1/go.mod h1:c7o6mJGLCMvNrfdinGZehkrdZuFT9vZdZNrn66DtVD0= +github.com/fluxcd/pkg/git v0.43.1 h1:lw29P44wueKzQk79KnYyvisfw//cxg0S4cDeTYx+Slo= +github.com/fluxcd/pkg/git v0.43.1/go.mod h1:3R/AjCe7ee7FqWcAG+2IiuJPOCxrGHF4SCGkuvKS6OQ= +github.com/fluxcd/pkg/gittestserver v0.25.1 h1:40Ridmy1xKxBM9ItDn012R4VKmaoDqzvGaC5g7xv+mw= +github.com/fluxcd/pkg/gittestserver v0.25.1/go.mod h1:7fybYb0yej1fFNiF1ohs0Jr0XzyaZQ/cRh3AFEoCtuc= +github.com/fluxcd/pkg/runtime v0.100.4 h1:rwvbeoeWN0BTJORJBISJJEkWn6DVfmWwynFl2GseWns= +github.com/fluxcd/pkg/runtime v0.100.4/go.mod h1:M6LjRJ1hIe2s6E2ykFfae1Xy/rLvOFQf2QquMKmN350= github.com/fluxcd/pkg/ssh v0.24.0 h1:hrPlxs0hhXf32DRqs68VbsXs0XfQMphyRVIk0rYYJa4= github.com/fluxcd/pkg/ssh v0.24.0/go.mod h1:xWammEqalrpurpcMiixJRXtynRQtBEoqheyU5F/vWrg= -github.com/fluxcd/pkg/version v0.14.0 h1:T3llSc8sUnsuFrW5ng2ePSfXwGXUKv0YG9QXf0ErhWw= -github.com/fluxcd/pkg/version v0.14.0/go.mod h1:YHdg/78kzf+kCqS+SqSOiUxum5AjxlixiqwpX6AUZB8= +github.com/fluxcd/pkg/version v0.12.0 h1:MGbdbNf2D5wazMqAkNPn+Lh5j+oY0gxQJFTGyet5Hfc= +github.com/fluxcd/pkg/version v0.12.0/go.mod h1:YHdg/78kzf+kCqS+SqSOiUxum5AjxlixiqwpX6AUZB8= github.com/fluxcd/source-controller/api v1.7.4 h1:+EOVnRA9LmLxOx7J273l7IOEU39m+Slt/nQGBy69ygs= github.com/fluxcd/source-controller/api v1.7.4/go.mod h1:ruf49LEgZRBfcP+eshl2n9SX1MfHayCcViAIGnZcaDY= github.com/fluxcd/test-infra/tftestenv v0.0.0-20250626232827-e0ca9c3f8d7b h1:FSPtvaVgL8azcyweqLmD71elAw4vozuXH/QvsJQ7tg0= @@ -137,12 +164,12 @@ github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDzZG0= -github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY= +github.com/go-git/go-billy/v5 v5.7.0 h1:83lBUJhGWhYp0ngzCMSgllhUSuoHP1iEWYjsPl9nwqM= +github.com/go-git/go-billy/v5 v5.7.0/go.mod h1:/1IUejTKH8xipsAcdfcSAlUlo2J7lkYV8GTKxAT/L3E= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.17.2 h1:B+nkdlxdYrvyFK4GPXVU8w1U+YkbsgciIR7f2sZJ104= -github.com/go-git/go-git/v5 v5.17.2/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo= +github.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s= +github.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -160,15 +187,15 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= -github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -226,10 +253,12 @@ github.com/hashicorp/terraform-json v0.27.2 h1:BwGuzM6iUPqf9JYM/Z4AF1OJ5VVJEEzoK github.com/hashicorp/terraform-json v0.27.2/go.mod h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= @@ -243,8 +272,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -255,6 +282,8 @@ github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5 h1:YH424zrwLTlyHS github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5/go.mod h1:PoGiBqKSQK1vIfQ+yVaFcGjDySHvym6FM1cNYnwzbrY= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -273,8 +302,6 @@ github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJw github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= github.com/pjbgf/sha1cd v0.4.0 h1:NXzbL1RvjTUi6kgYZCX3fPwwl27Q1LJndxtUDVfJGRY= github.com/pjbgf/sha1cd v0.4.0/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= -github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= -github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= @@ -314,6 +341,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4= @@ -322,6 +350,7 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.16.4 h1:QGXaag7/7dCzb+odlGrgr+YmYZFaOCMW6DEpS+UD1eE= github.com/zclconf/go-cty v1.16.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= go.einride.tech/aip v0.73.0 h1:bPo4oqBo2ZQeBKo4ZzLb1kxYXTY1ysJhpvQyfuGzvps= @@ -334,16 +363,16 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= -go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= -go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= -go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= -go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= -go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= -go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= -go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= -go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= -go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= @@ -354,32 +383,44 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= -golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= -golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= -golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= -golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -389,17 +430,30 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= -golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= -golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -407,8 +461,12 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= -golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= @@ -421,17 +479,17 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= -google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= +google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= +google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -458,8 +516,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= -gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.35.2 h1:tW7mWc2RpxW7HS4CoRXhtYHSzme1PN1UjGHJ1bdrtdw=