Compare commits

...

329 Commits
v1.2.4 ... main

Author SHA1 Message Date
Matheus Pimenta 8f77ed4981
Merge pull request #1808 from TerryHowe/harden-blob-test
fix: blob test cores if no error
2025-07-01 14:34:26 +01:00
Terry Howe 9c8d8c95e2
fix: blob test cores if no error
Co-authored-by: Matheus Pimenta <matheuscscp@gmail.com>
Signed-off-by: Terry Howe <terrylhowe@gmail.com>
2025-06-30 05:57:55 -06:00
Matheus Pimenta 32967c32c3
Merge pull request #1843 from fluxcd/pick-changelog-v1.6.2
Add changelog entry for v1.6.2
2025-06-27 11:21:54 +01:00
Matheus Pimenta 5ff9de8bb9
Add changelog entry for v1.6.2
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
(cherry picked from commit 55b45275a1)
2025-06-27 11:04:25 +01:00
Stefan Prodan 4dec4c28c0
Merge pull request #1839 from fluxcd/fix-ssh-host-key-sha2
Fix: Prioritize sha2-512 and sha2-256 for ssh-rsa host keys
2025-06-27 11:44:19 +03:00
Stefan Prodan 07ab3461dc
Fix: Prioritize sha2-512 and sha2-256 for ssh-rsa host keys
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-06-27 11:26:54 +03:00
Matheus Pimenta e37bd89d5e
Merge pull request #1835 from cappyzawa/refactor/simplify-oci-auth-error-handling
refactor: cleanup GetArtifactRegistryCredentials error handling
2025-06-21 14:32:50 +01:00
cappyzawa 738fb2b3a8
refactor: simplify OCI auth error handling
Update fluxcd/pkg/auth to v0.18.0 and remove unnecessary authenticator
nil check in Helm OCI repository authentication.

With fluxcd/pkg/auth v0.18.0, GetArtifactRegistryCredentials() returns
valid authenticator when error is nil, making the nil check redundant.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-06-21 22:21:51 +09:00
Matheus Pimenta 97c995b8c8
Merge pull request #1833 from fluxcd/pick-changelog-v1.6.1
Add changelog entry for v1.6.1
2025-06-13 17:21:04 +01:00
Matheus Pimenta bcc0b84bd4
Add changelog entry for v1.6.1
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
(cherry picked from commit 7922d124e7)
2025-06-13 17:11:57 +01:00
Matheus Pimenta a5e476fce3
Merge pull request #1829 from fluxcd/fix-host-keys
Fix `knownhosts key mismatch` regression bug
2025-06-12 18:54:35 +01:00
Matheus Pimenta 5d5943fff0
Upgrade dependencies
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-06-12 18:02:44 +01:00
Matheus Pimenta 829b6a2104
Merge pull request #1825 from fluxcd/upgrade-auth
Upgrade dependencies
2025-06-09 17:43:41 +01:00
Matheus Pimenta 575d936c9b
Upgrade dependencies
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-06-09 17:07:52 +01:00
Matheus Pimenta 483dd69d1e
Merge pull request #1823 from zhaque44/update-reconciliation-tests
chore: adding more scenarios for processor_test.go
2025-06-07 14:49:14 +01:00
zhaque44 8a92986d5e adding scenarions for processor_test.go
Signed-off-by: zhaque44 <haque.zubair@gmail.com>

chg imports to be like main

Signed-off-by: zhaque44 <haque.zubair@gmail.com>
2025-06-07 08:39:34 -05:00
Stefan Prodan 71e6ca6b0a
Merge pull request #1819 from fluxcd/dependabot-up
Update dependabot config
2025-05-28 16:18:05 +03:00
Stefan Prodan 7fabea8f02
Update dependabot config
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-28 16:01:43 +03:00
Matheus Pimenta f2eaf74120
Merge pull request #1816 from fluxcd/update-labels
Add 1.6.x release label
2025-05-27 15:08:10 +01:00
Matheus Pimenta 1106cddce4
Add 1.6.x release label
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-27 14:16:49 +01:00
Matheus Pimenta 536ad96fab
Merge pull request #1814 from fluxcd/release/v1.6.x
Release/v1.6.x
2025-05-27 14:14:56 +01:00
Matheus Pimenta 83cb98615d
Merge pull request #1813 from fluxcd/release-v1.6.0
Release v1.6.0
2025-05-27 13:48:27 +01:00
Matheus Pimenta 465741e97a
Release v1.6.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-27 12:41:16 +01:00
Matheus Pimenta ac4afb3779
Add changelog entry for v1.6.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-27 12:39:52 +01:00
Matheus Pimenta 359d50d77e
Merge pull request #1811 from fluxcd/rfc-0010-docs
[RFC-0010] Link workload identity docs to complete guide
2025-05-27 09:46:26 +01:00
Matheus Pimenta d5552220a5
[RFC-0010] Link workload identity docs to complete guide
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-27 09:38:15 +01:00
Matheus Pimenta fdc84c7efa
Merge pull request #1812 from fluxcd/containerd-v1.7.27
Update containerd v1.7.27
2025-05-27 09:33:17 +01:00
Matheus Pimenta 71aa99e934
Fix flaky test
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-27 09:24:01 +01:00
Stefan Prodan 36e0d0dfca
Update containerd v1.7.27
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-27 09:16:15 +03:00
Stefan Prodan e98b89a5a0
Merge pull request #1794 from fluxcd/ocirepository-v1
Promote OCIRepository API to v1 (GA)
2025-05-27 08:42:21 +03:00
Stefan Prodan aadaf1c0aa
Remove deprecated status fields from OCIRepository v1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-27 08:29:44 +03:00
Stefan Prodan 34bb9862e6
Promote OCIRepository API to v1 (GA)
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-27 08:19:51 +03:00
Stefan Prodan 220044db74
Merge pull request #1800 from fluxcd/dependabot/github_actions/ci-b758b462f2
build(deps): bump the ci group across 1 directory with 4 updates
2025-05-26 10:05:22 +03:00
dependabot[bot] d205bd310f
build(deps): bump the ci group across 1 directory with 4 updates
Bumps the ci group with 4 updates in the / directory: [actions/setup-go](https://github.com/actions/setup-go), [docker/build-push-action](https://github.com/docker/build-push-action), [anchore/sbom-action](https://github.com/anchore/sbom-action) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `actions/setup-go` from 5.4.0 to 5.5.0
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](0aaccfd150...d35c59abb0)

Updates `docker/build-push-action` from 6.16.0 to 6.17.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](14487ce63c...1dc7386353)

Updates `anchore/sbom-action` from 0.19.0 to 0.20.0
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](9f73021414...e11c554f70)

Updates `github/codeql-action` from 3.28.16 to 3.28.17
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](28deaeda66...60168efe1c)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: 5.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/build-push-action
  dependency-version: 6.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-version: 0.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-version: 3.28.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-26 02:25:31 +00:00
Matheus Pimenta 7f83d3c049
Merge pull request #1810 from fluxcd/upgrade-deps
Update dependencies
2025-05-25 14:50:12 +01:00
Matheus Pimenta 15e2448578
Update dependencies
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-25 14:39:20 +01:00
Stefan Prodan 4aa31dcc21
Merge pull request #1806 from fluxcd/update-deps-1.6.0
Update dependencies
2025-05-23 16:47:29 +02:00
Stefan Prodan a05567e2bb
Update cosign to v2.5.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-23 17:34:32 +03:00
Stefan Prodan 26df08a633
Update controller-runtime to v0.21.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-23 17:29:01 +03:00
Matheus Pimenta 0d9ed5936f
Merge pull request #1802 from fluxcd/rfc-0010-feature-gate
[RFC-0010] Introduce feature gate
2025-05-23 07:59:19 +01:00
Matheus Pimenta aff9ebde96
[RFC-0010] Introduce feature gate
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-19 13:39:36 +01:00
Matheus Pimenta 0058004a83
Merge pull request #1796 from zhaque44/test-with-index
chore: Enhance Digester test coverage with edge case scenarios
2025-05-09 15:30:13 +01:00
zhaque44 bb4671cc0e set NewDigester back
Signed-off-by: zhaque44 <haque.zubair@gmail.com>
2025-05-08 19:19:08 -05:00
zhaque44 374e4ba495 rm unecessary scenarios
Signed-off-by: zhaque44 <haque.zubair@gmail.com>
2025-05-08 19:08:42 -05:00
zhaque44 15bbf61c50 fix new digester
Signed-off-by: zhaque44 <haque.zubair@gmail.com>
2025-05-08 19:05:06 -05:00
zhaque44 53578d8920 chore: Enhance Digester test coverage with edge case scenarios
Signed-off-by: zhaque44 <haque.zubair@gmail.com>
2025-05-08 18:54:05 -05:00
Matheus Pimenta e2538552af
Merge pull request #1790 from fluxcd/rfc-0010-oci
[RFC-0010] Introduce object-level workload identity for OCIRepository
2025-05-07 18:57:08 +01:00
Matheus Pimenta e128d3b795
[RFC-0010] Introduce object-level workload identity for container registry APIs
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-07 18:33:59 +01:00
Stefan Prodan 9f36f2943c
Merge pull request #1789 from fluxcd/upgrade-deps
Upgrade fluxcd/pkg cache, auth, git and gogit
2025-05-04 10:37:25 +03:00
Matheus Pimenta 2dde6bf536
Upgrade fluxcd/pkg cache, auth, git and gogit
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-03 15:47:39 +01:00
Matheus Pimenta a3f5db357b
Merge pull request #1788 from fluxcd/token-cache-default
Enable token cache by default
2025-05-03 12:23:15 +01:00
Matheus Pimenta 27d18b8dbe
Enable token cache by default
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-03 10:35:14 +01:00
Stefan Prodan 8b0726f49c
Merge pull request #1785 from fluxcd/semver-v3.3.0
Downgrade `Masterminds/semver` to v3.3.0
2025-04-29 15:46:23 +03:00
Stefan Prodan 5b1f0a6d71
Downgrade `Masterminds/semver` to v3.3.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-04-29 15:23:39 +03:00
Stefan Prodan 7b83ba8620
Merge pull request #1782 from fluxcd/dependabot/github_actions/ci-8bb20cbd96
build(deps): bump the ci group across 1 directory with 13 updates
2025-04-28 15:50:39 +03:00
dependabot[bot] 3888fca1bb
build(deps): bump the ci group across 1 directory with 13 updates
Bumps the ci group with 13 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [korthout/backport-action](https://github.com/korthout/backport-action) | `3.1.0` | `3.2.0` |
| [actions/setup-go](https://github.com/actions/setup-go) | `5.3.0` | `5.4.0` |
| [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) | `3.4.0` | `3.6.0` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3.9.0` | `3.10.0` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `6.13.0` | `6.16.0` |
| [docker/login-action](https://github.com/docker/login-action) | `3.3.0` | `3.4.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `5.6.1` | `5.7.0` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `3.8.0` | `3.8.2` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.18.0` | `0.19.0` |
| [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) | `6.1.0` | `6.3.0` |
| [slsa-framework/slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator) | `2.0.0` | `2.1.0` |
| [fossa-contrib/fossa-action](https://github.com/fossa-contrib/fossa-action) | `3.0.0` | `3.0.1` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.28.8` | `3.28.16` |



Updates `korthout/backport-action` from 3.1.0 to 3.2.0
- [Release notes](https://github.com/korthout/backport-action/releases)
- [Commits](be567af183...436145e922)

Updates `actions/setup-go` from 5.3.0 to 5.4.0
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](f111f3307d...0aaccfd150)

Updates `docker/setup-qemu-action` from 3.4.0 to 3.6.0
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](4574d27a47...29109295f8)

Updates `docker/setup-buildx-action` from 3.9.0 to 3.10.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](f7ce87c1d6...b5ca514318)

Updates `docker/build-push-action` from 6.13.0 to 6.16.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](ca877d9245...14487ce63c)

Updates `docker/login-action` from 3.3.0 to 3.4.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](9780b0c442...74a5d14239)

Updates `docker/metadata-action` from 5.6.1 to 5.7.0
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](369eb591f4...902fa8ec7d)

Updates `sigstore/cosign-installer` from 3.8.0 to 3.8.2
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](c56c2d3e59...3454372f43)

Updates `anchore/sbom-action` from 0.18.0 to 0.19.0
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](f325610c9f...9f73021414)

Updates `goreleaser/goreleaser-action` from 6.1.0 to 6.3.0
- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)
- [Commits](9ed2f89a66...9c156ee8a1)

Updates `slsa-framework/slsa-github-generator` from 2.0.0 to 2.1.0
- [Release notes](https://github.com/slsa-framework/slsa-github-generator/releases)
- [Changelog](https://github.com/slsa-framework/slsa-github-generator/blob/main/CHANGELOG.md)
- [Commits](https://github.com/slsa-framework/slsa-github-generator/compare/v2.0.0...v2.1.0)

Updates `fossa-contrib/fossa-action` from 3.0.0 to 3.0.1
- [Release notes](https://github.com/fossa-contrib/fossa-action/releases)
- [Changelog](https://github.com/fossa-contrib/fossa-action/blob/master/CHANGELOG.md)
- [Commits](cdc5065bcd...3d2ef181b1)

Updates `github/codeql-action` from 3.28.8 to 3.28.16
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](dd746615b3...28deaeda66)

---
updated-dependencies:
- dependency-name: korthout/backport-action
  dependency-version: 3.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: actions/setup-go
  dependency-version: 5.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/setup-qemu-action
  dependency-version: 3.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/setup-buildx-action
  dependency-version: 3.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/build-push-action
  dependency-version: 6.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/login-action
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/metadata-action
  dependency-version: 5.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: sigstore/cosign-installer
  dependency-version: 3.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-version: 0.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: goreleaser/goreleaser-action
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: slsa-framework/slsa-github-generator
  dependency-version: 2.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: fossa-contrib/fossa-action
  dependency-version: 3.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-version: 3.28.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 12:00:40 +00:00
Stefan Prodan 1ab0aba772
Merge pull request #1783 from fluxcd/k8s-1.33
Update to Kubernetes 1.33.0 and Go 1.24.0
2025-04-28 14:55:38 +03:00
Stefan Prodan 3c7812d387
Update to Kubernetes 1.33.0 and Go 1.24.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-04-28 14:10:47 +03:00
dipti-pai c7034978ee
Merge pull request #1774 from dipti-pai/git-sparse-checkout
Implement Sparse Checkout for `GitRepository`
2025-04-23 09:50:39 -07:00
Dipti Pai 61f9eb28fc Sparse Checkout Directories in GitRepositories.
- Add `.spec.sparseCheckout` and `.status.observedSparseCheckout` fields to `GitRepository`.
    - Add controller support to send the sparse checkout directories to go-git via pkg methods.
    - Use `.status/observedSparseCheckout` to detect drift in configuration.
    - Trim leading "./" in directory paths.
    - Validate spec configuration by checking directories specified in spec exist in the cloned repository after successful checkout
    - Add tests for testing the observed sparse checkout behavior.
    - Add docs describing the new fields.

Signed-off-by: Dipti Pai <diptipai89@outlook.com>
2025-04-23 09:30:10 -07:00
Stefan Prodan 034bc4962d
Merge pull request #1778 from fluxcd/git-mutual-tls
Add Mutual TLS support to `GitRepository`
2025-04-23 08:36:12 +03:00
Stefan Prodan 3214ccd11c
Add Git mTLS config to API docs
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-04-22 10:37:23 +03:00
Stefan Prodan b549fec2e7
Add tests for Git mutual TLS
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-04-22 10:28:00 +03:00
Stefan Prodan c1b32514a3
Update `fluxcd/pkg/git` to v0.26.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-04-22 10:12:49 +03:00
Stefan Prodan 2a839f8769
Renew testdata TLS certs
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-04-22 10:12:10 +03:00
Stefan Prodan 849b4de208
Merge pull request #1775 from fluxcd/helm-v3.17.3
Update dependencies to Helm v3.17.3
2025-04-11 12:15:23 +03:00
Stefan Prodan 0338a8e9ab
Update Helm to v3.17.3
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-04-09 22:42:28 +03:00
dipti-pai 414b7dbf95
Merge pull request #1754 from dipti-pai/move-github-pkg
Rename references to pkg/auth/github to pkg/git/github
2025-03-13 15:01:44 -07:00
Dipti Pai 560dc5bc5f Rename references to pkg/auth/github to pkg/git/github
Signed-off-by: Dipti Pai <diptipai89@outlook.com>
2025-03-13 13:53:18 -07:00
Matheus Pimenta 840bea6d67
Merge pull request #1745 from fluxcd/token-cache
Introduce token cache and use it for GitHub App tokens
2025-03-12 21:45:18 +00:00
Matheus Pimenta 9593041b53
Introduce token cache and use it for GitHub App tokens
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-03-12 14:45:48 +00:00
Matheus Pimenta 9dedcede9d
Merge pull request #1740 from zhaque44/cache-test-updates
chore: update cache_test.go (add cache exp test & cache delete test)
2025-03-03 10:33:06 +00:00
zhaque44 7a89359d27 add cache exp test & cache delete test
Signed-off-by: zhaque44 <haque.zubair@gmail.com>
2025-03-01 21:00:39 -06:00
Matheus Pimenta ba6d000437
Merge pull request #1729 from sneakernuts/main
minor updates to links and AAD reference
2025-02-28 19:29:09 +00:00
sneakernuts 1686832fc9 minor updates to links and AAD reference
Signed-off-by: sneakernuts <671942+sneakernuts@users.noreply.github.com>
2025-02-28 16:51:14 +00:00
dipti-pai 1cafc8ac0e
Merge pull request #1726 from dipti-pai/add-to-maintainers
Add Dipti Pai to maintainers
2025-02-27 09:24:35 -08:00
Dipti Pai 882908f933 Add Dipti Pai to maintainers
Signed-off-by: Dipti Pai <diptipai89@outlook.com>
2025-02-27 07:12:20 -08:00
Stefan Prodan 8e9e3a7d54
Merge pull request #1728 from fluxcd/dependabot/go_modules/go-deps-89d2d06eb1
build(deps): bump the go-deps group across 1 directory with 3 updates
2025-02-22 09:51:49 +02:00
dependabot[bot] 1939ffd40c
build(deps): bump the go-deps group across 1 directory with 3 updates
Bumps the go-deps group with 3 updates in the / directory: [github.com/minio/minio-go/v7](https://github.com/minio/minio-go), [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) and [github.com/sigstore/sigstore](https://github.com/sigstore/sigstore).


Updates `github.com/minio/minio-go/v7` from 7.0.86 to 7.0.87
- [Release notes](https://github.com/minio/minio-go/releases)
- [Commits](https://github.com/minio/minio-go/compare/v7.0.86...v7.0.87)

Updates `github.com/prometheus/client_golang` from 1.20.5 to 1.21.0
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.20.5...v1.21.0)

Updates `github.com/sigstore/sigstore` from 1.8.14 to 1.8.15
- [Release notes](https://github.com/sigstore/sigstore/releases)
- [Commits](https://github.com/sigstore/sigstore/compare/v1.8.14...v1.8.15)

---
updated-dependencies:
- dependency-name: github.com/minio/minio-go/v7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/sigstore/sigstore
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-21 02:45:16 +00:00
Stefan Prodan 847d55f8de
Merge pull request #1725 from fluxcd/build-no-cgo
Build controller without CGO
2025-02-20 11:31:59 +02:00
Stefan Prodan 53fd7a2ecd
Update repo for large repo test
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-02-20 10:28:24 +02:00
Stefan Prodan 0543dda4cd
Build controller without CGO
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-02-20 10:04:11 +02:00
Hidde Beydals 912feb4d8b
Merge pull request #1722 from fluxcd/dependabot/go_modules/go-deps-91ab6ef4fc 2025-02-17 15:16:04 +08:00
dependabot[bot] d293d4a0b7
build(deps): bump the go-deps group across 1 directory with 5 updates
Bumps the go-deps group with 3 updates in the / directory: [github.com/minio/minio-go/v7](https://github.com/minio/minio-go), [github.com/sigstore/sigstore](https://github.com/sigstore/sigstore) and [golang.org/x/oauth2](https://github.com/golang/oauth2).


Updates `github.com/minio/minio-go/v7` from 7.0.84 to 7.0.86
- [Release notes](https://github.com/minio/minio-go/releases)
- [Commits](https://github.com/minio/minio-go/compare/v7.0.84...v7.0.86)

Updates `github.com/sigstore/sigstore` from 1.8.12 to 1.8.14
- [Release notes](https://github.com/sigstore/sigstore/releases)
- [Commits](https://github.com/sigstore/sigstore/compare/v1.8.12...v1.8.14)

Updates `golang.org/x/crypto` from 0.32.0 to 0.33.0
- [Commits](https://github.com/golang/crypto/compare/v0.32.0...v0.33.0)

Updates `golang.org/x/oauth2` from 0.25.0 to 0.26.0
- [Commits](https://github.com/golang/oauth2/compare/v0.25.0...v0.26.0)

Updates `golang.org/x/sync` from 0.10.0 to 0.11.0
- [Commits](https://github.com/golang/sync/compare/v0.10.0...v0.11.0)

---
updated-dependencies:
- dependency-name: github.com/minio/minio-go/v7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/sigstore/sigstore
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: golang.org/x/oauth2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: golang.org/x/sync
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-17 02:28:18 +00:00
Matheus Pimenta 6952276d79
Merge pull request #1720 from fluxcd/update-labels
Add 1.5.x release label
2025-02-13 16:07:48 +00:00
Matheus Pimenta dcd0b862c2
Add 1.5.x release label
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-13 15:56:51 +00:00
Matheus Pimenta 9998214f61
Merge pull request #1719 from fluxcd/release/v1.5.x
Release/v1.5.x
2025-02-13 15:53:44 +00:00
Matheus Pimenta 301fc72714
Merge pull request #1718 from fluxcd/release-v1.5.0
Release v1.5.0
2025-02-13 15:29:10 +00:00
Matheus Pimenta 5f4bebaf23
Release v1.5.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-13 14:48:36 +00:00
Matheus Pimenta 428d0c5ab4
Add changelog entry for v1.5.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-13 14:47:24 +00:00
Matheus Pimenta c5046b839f
Merge pull request #1716 from fluxcd/upgrade-deps
Upgrade pkg/runtime
2025-02-11 12:06:00 +00:00
Matheus Pimenta 32e20898eb
Upgrade pkg/runtime
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-11 11:49:46 +00:00
Stefan Prodan d71bb70318
Merge pull request #1713 from fluxcd/dependabot/github_actions/ci-65554cb917
build(deps): bump the ci group across 1 directory with 11 updates
2025-02-09 17:48:45 +02:00
dependabot[bot] 8b061cfb79
build(deps): bump the ci group across 1 directory with 11 updates
Bumps the ci group with 11 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4.1.7` | `4.2.2` |
| [actions/setup-go](https://github.com/actions/setup-go) | `5.0.2` | `5.3.0` |
| [helm/kind-action](https://github.com/helm/kind-action) | `1.10.0` | `1.12.0` |
| [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) | `3.2.0` | `3.4.0` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3.6.1` | `3.9.0` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `6.7.0` | `6.13.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `5.5.1` | `5.6.1` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `3.6.0` | `3.8.0` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.17.2` | `0.18.0` |
| [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) | `6.0.0` | `6.1.0` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.26.4` | `3.28.8` |



Updates `actions/checkout` from 4.1.7 to 4.2.2
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](692973e3d9...11bd71901b)

Updates `actions/setup-go` from 5.0.2 to 5.3.0
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](0a12ed9d6a...f111f3307d)

Updates `helm/kind-action` from 1.10.0 to 1.12.0
- [Release notes](https://github.com/helm/kind-action/releases)
- [Commits](0025e74a8c...a1b0e39133)

Updates `docker/setup-qemu-action` from 3.2.0 to 3.4.0
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](49b3bc8e6b...4574d27a47)

Updates `docker/setup-buildx-action` from 3.6.1 to 3.9.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](988b5a0280...f7ce87c1d6)

Updates `docker/build-push-action` from 6.7.0 to 6.13.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](5cd11c3a4c...ca877d9245)

Updates `docker/metadata-action` from 5.5.1 to 5.6.1
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](8e5442c4ef...369eb591f4)

Updates `sigstore/cosign-installer` from 3.6.0 to 3.8.0
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](4959ce089c...c56c2d3e59)

Updates `anchore/sbom-action` from 0.17.2 to 0.18.0
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Changelog](https://github.com/anchore/sbom-action/blob/main/RELEASE.md)
- [Commits](61119d458a...f325610c9f)

Updates `goreleaser/goreleaser-action` from 6.0.0 to 6.1.0
- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)
- [Commits](286f3b13b1...9ed2f89a66)

Updates `github/codeql-action` from 3.26.4 to 3.28.8
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](f0f3afee80...dd746615b3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: helm/kind-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/metadata-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: goreleaser/goreleaser-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-07 02:16:07 +00:00
Stefan Prodan 70c482b311
Merge pull request #1709 from fluxcd/dependabot/go_modules/go-deps-cde8f11869
Update `fluxcd/pkg/oci` to 0.45.0
2025-01-31 15:32:02 +02:00
dependabot[bot] 307edb989e
build(deps): bump github.com/fluxcd/pkg/oci
Bumps the go-deps group with 1 update in the / directory: [github.com/fluxcd/pkg/oci](https://github.com/fluxcd/pkg).


Updates `github.com/fluxcd/pkg/oci` from 0.44.0 to 0.45.0
- [Commits](https://github.com/fluxcd/pkg/compare/oci/v0.44.0...oci/v0.45.0)

---
updated-dependencies:
- dependency-name: github.com/fluxcd/pkg/oci
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-31 13:18:20 +00:00
Stefan Prodan 74f2bc8ff4
Merge pull request #1708 from fluxcd/controller-runtime-v0.20.1
Update dependencies
2025-01-31 15:13:10 +02:00
Stefan Prodan 0e363c9f08
Update dependencies
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-01-31 15:02:27 +02:00
Stefan Prodan 529eee0ed1
Merge pull request #1705 from fluxcd/upgrade-runtime
Upgrade runtime
2025-01-10 15:57:20 +02:00
Matheus Pimenta 615bb912dd
Upgrade runtime
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-01-10 13:41:27 +00:00
Stefan Prodan fe5af75a3a
Merge pull request #1647 from dipti-pai/github-app-auth
[RFC-007] Implement GitHub app authentication for git repositories.
2025-01-09 20:20:52 +02:00
Sunny 1ed845928b gitrepo: Use new reason for provider misconfig
Introduce InvalidProviderConfigurationReason for Git provider github
related misconfiguration.

Add github provider related tests to check the status conditions reason.

Rearrange and modify a test case for getAuthOpts() for provider test
where a referred secret doesn't exist. This scenario is not specific to
any provider.

Signed-off-by: Sunny <github@darkowlzz.space>
2024-12-19 21:01:44 +00:00
Dipti Pai 9556a639c6 [RFC-007] Implement GitHub app authentication for git repositories.
- API change to add new `github` provider field in `GitRepository` spec.
- Controller change to use the GitHub authentication information specified in `.spec.secretRef` to create the auth options to authenticate to git repositories when the `provider` field is set to `github`,
- Tests for new `github` provider field
- Updated docs to use GitHub Apps for authentication in source-controller.

Signed-off-by: Dipti Pai <diptipai89@outlook.com>
2024-12-19 23:28:10 +05:30
Stefan Prodan fe7b1fecba
Merge pull request #1693 from fluxcd/k8s-1.32
Update dependencies to Kubernetes 1.32.0 and Go 1.23.0
2024-12-12 18:04:42 +02:00
Stefan Prodan 6f8f2e0435
Update dependencies to Kubernetes 1.32.0 and Go 1.23.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-12-12 16:36:02 +02:00
Stefan Prodan b392cdc094
Merge pull request #1686 from hasithsen/main
Remove deprecated object metrics
2024-12-11 23:28:10 +02:00
hasithsen 2b320409de feat: Remove deprecated object metrics from controllers fluxcd/flux2#5083
Signed-off-by: hasithsen <sen.hasith@gmail.com>
2024-12-12 00:02:25 +05:30
Stefan Prodan b5881fb4f6
Merge pull request #1689 from fluxcd/alpine-3.21
Update Alpine to 3.21 and xx to 1.6.1
2024-12-11 11:33:41 +02:00
Stefan Prodan 1cfb5d6c00
Update Alpine to 3.21 and xx to 1.6.1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-12-11 11:18:42 +02:00
Stefan Prodan 4d34b3f843
Merge pull request #1684 from fluxcd/fluxcd/pkg/git-v0.22.0
Update Git dependencies
2024-12-06 17:06:36 +02:00
Stefan Prodan 892e7ccab4
Update Git dependencies
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-12-06 16:51:45 +02:00
Matheus Pimenta af88ec2ba6
Merge pull request #1681 from fluxcd/matheuscscp-coremaintainer
Add @matheuscscp to core maintainers (remove from maintainers)
2024-12-05 12:17:58 +00:00
Matheus Pimenta 03c790ad7d Add @matheuscscp to core maintainers (remove from maintainers)
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-12-03 12:31:03 +00:00
Matheus Pimenta 3b6896fec1
Merge pull request #1679 from fluxcd/matheuscscp-affiliation
Update matheuscscp affiliation
2024-11-27 18:10:00 +00:00
Matheus Pimenta 5634a76190 Update matheuscscp affiliation
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-11-27 16:46:22 +00:00
Stefan Prodan 53868f7985
Merge pull request #1629 from fluxcd/pick-changelog-v1.4.1
Add changelog entry for v1.4.1
2024-09-26 19:52:16 +03:00
Sunny 24dcca83c1 Add changelog entry for v1.4.1
Signed-off-by: Sunny <github@darkowlzz.space>
2024-09-26 21:57:03 +05:30
Sunny 8baf4513f7
Merge pull request #1626 from fluxcd/git-no-provider-default
GitRepo: Remove provider default value from API
2024-09-26 21:12:12 +05:30
Sunny db42b07914 GitRepo: Remove provider default value from API
For backwards compatibility, remove the default value for GitRepository
provider. An empty provider value will still be considered as the
default provider.

Signed-off-by: Sunny <github@darkowlzz.space>
2024-09-26 15:13:29 +00:00
Stefan Prodan 1f150c552f
Merge pull request #1621 from fluxcd/backport-release-1.4.0
Add changelog entry for v1.4.0
2024-09-26 10:26:01 +03:00
Matheus Pimenta a9c287ea4d Release v1.4.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-09-26 02:33:35 +05:30
Matheus Pimenta e38d6c6855 Add changelog entry for v1.4.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-09-26 02:33:35 +05:30
Matheus Pimenta c4db49a3f4
Merge pull request #1622 from fluxcd/release-label
Add 1.4.x release label
2024-09-25 17:40:22 -03:00
Matheus Pimenta 02abea5362 Add 1.4.x release label
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-09-25 16:12:35 -03:00
Stefan Prodan 03889fecb1
Merge pull request #1618 from fluxcd/dependabot/go_modules/go-deps-a9e873101f
build(deps): bump the go-deps group across 1 directory with 3 updates
2024-09-25 09:43:11 +03:00
dependabot[bot] 32bc10cbd9
build(deps): bump the go-deps group across 1 directory with 3 updates
Bumps the go-deps group with 3 updates in the / directory: [github.com/minio/minio-go/v7](https://github.com/minio/minio-go), [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) and [google.golang.org/api](https://github.com/googleapis/google-api-go-client).


Updates `github.com/minio/minio-go/v7` from 7.0.76 to 7.0.77
- [Release notes](https://github.com/minio/minio-go/releases)
- [Commits](https://github.com/minio/minio-go/compare/v7.0.76...v7.0.77)

Updates `github.com/prometheus/client_golang` from 1.20.3 to 1.20.4
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.20.3...v1.20.4)

Updates `google.golang.org/api` from 0.197.0 to 0.198.0
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.197.0...v0.198.0)

---
updated-dependencies:
- dependency-name: github.com/minio/minio-go/v7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-25 02:32:15 +00:00
Stefan Prodan ccdd523e06
Merge pull request #1614 from fluxcd/k8s-1.31.1
Update dependencies to Kubernetes 1.31.1
2024-09-16 13:46:46 +03:00
Stefan Prodan 1e6ddbcc3a
Update dependencies to Kubernetes 1.31.1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-09-16 09:49:55 +03:00
Stefan Prodan 852394ee56
Merge pull request #1591 from dipti-pai/git-azure-oidc-auth
[RFC-0007] Enable Azure OIDC for Azure DevOps repositories
2024-09-16 09:41:06 +03:00
Dipti Pai 48417bdc8b Enable Azure OIDC for Azure DevOps Respository
- Add a new provider field to GitRepository API spec which can be set to azure to enable passwordless authentication to Azure DevOps repositories.

- API docs for new provider field and guidance to setup Azure environment with workload identity.

- Controller changes to set the provider options in git authoptions to fetch credential while cloning the repository.

- Add unit tests for testing provider

Signed-off-by: Dipti Pai <diptipai89@outlook.com>
2024-09-13 13:41:18 -07:00
Stefan Prodan 93253c70cf
Merge pull request #1610 from fluxcd/helm-3.16.0
Update Helm to v3.16.0
2024-09-13 09:48:24 +03:00
Stefan Prodan a5bdeb262b
Update Helm to v3.16.1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-09-12 19:56:28 +03:00
Stefan Prodan 58ef98c1b5
Update Helm to v3.16.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-09-12 14:45:27 +03:00
Stefan Prodan dd144ac942
Merge pull request #1607 from fluxcd/oci-oidc-proxy
OCIRepository: Configure proxy for OIDC auth
2024-09-11 18:57:58 +03:00
Stefan Prodan e3992568f5
OCIRepository: Configure proxy for OIDC auth
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-09-10 18:54:32 +03:00
Stefan Prodan cc1762b2e5
Update `fluxcd/pkg/oci` to v0.41.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-09-10 18:53:40 +03:00
Stefan Prodan 7318343e6c
Merge pull request #1603 from fluxcd/notation-go-1.2.0
Update `notaryproject/notation-go` to 1.2.1
2024-09-05 15:23:42 +03:00
Stefan Prodan ef2c356124
Update notation-go to v1.2.1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-09-05 15:09:58 +03:00
Stefan Prodan 225a452092
Update tests for notation 1.2
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-09-04 09:42:41 +03:00
Stefan Prodan 39c0c12410
Update docker to v27.2.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-09-04 09:42:03 +03:00
dependabot[bot] 0e8d794cfd
build(deps): bump the go-deps group across 1 directory with 8 updates
Bumps the go-deps group with 8 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [github.com/Masterminds/semver/v3](https://github.com/Masterminds/semver) | `3.2.1` | `3.3.0` |
| [github.com/minio/minio-go/v7](https://github.com/minio/minio-go) | `7.0.75` | `7.0.76` |
| [github.com/notaryproject/notation-core-go](https://github.com/notaryproject/notation-core-go) | `1.0.3` | `1.1.0` |
| [github.com/notaryproject/notation-go](https://github.com/notaryproject/notation-go) | `1.1.1` | `1.2.0` |
| [github.com/onsi/gomega](https://github.com/onsi/gomega) | `1.34.1` | `1.34.2` |
| [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) | `1.20.0` | `1.20.2` |
| [github.com/sigstore/sigstore](https://github.com/sigstore/sigstore) | `1.8.8` | `1.8.9` |
| [google.golang.org/api](https://github.com/googleapis/google-api-go-client) | `0.190.0` | `0.196.0` |



Updates `github.com/Masterminds/semver/v3` from 3.2.1 to 3.3.0
- [Release notes](https://github.com/Masterminds/semver/releases)
- [Changelog](https://github.com/Masterminds/semver/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Masterminds/semver/compare/v3.2.1...v3.3.0)

Updates `github.com/minio/minio-go/v7` from 7.0.75 to 7.0.76
- [Release notes](https://github.com/minio/minio-go/releases)
- [Commits](https://github.com/minio/minio-go/compare/v7.0.75...v7.0.76)

Updates `github.com/notaryproject/notation-core-go` from 1.0.3 to 1.1.0
- [Release notes](https://github.com/notaryproject/notation-core-go/releases)
- [Commits](https://github.com/notaryproject/notation-core-go/compare/v1.0.3...v1.1.0)

Updates `github.com/notaryproject/notation-go` from 1.1.1 to 1.2.0
- [Release notes](https://github.com/notaryproject/notation-go/releases)
- [Changelog](https://github.com/notaryproject/notation-go/blob/main/RELEASE_CHECKLIST.md)
- [Commits](https://github.com/notaryproject/notation-go/compare/v1.1.1...v1.2.0)

Updates `github.com/onsi/gomega` from 1.34.1 to 1.34.2
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.34.1...v1.34.2)

Updates `github.com/prometheus/client_golang` from 1.20.0 to 1.20.2
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.20.0...v1.20.2)

Updates `github.com/sigstore/sigstore` from 1.8.8 to 1.8.9
- [Release notes](https://github.com/sigstore/sigstore/releases)
- [Commits](https://github.com/sigstore/sigstore/compare/v1.8.8...v1.8.9)

Updates `google.golang.org/api` from 0.190.0 to 0.196.0
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.190.0...v0.196.0)

---
updated-dependencies:
- dependency-name: github.com/Masterminds/semver/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/minio/minio-go/v7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/notaryproject/notation-core-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/notaryproject/notation-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/prometheus/client_golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/sigstore/sigstore
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-04 02:52:43 +00:00
Stefan Prodan 53f7581a06
Merge pull request #1592 from fluxcd/bucket-v1-ga
Promote Bucket API to v1
2024-08-28 09:59:08 +03:00
Stefan Prodan 36a4889ea2
Alias Bucket providers from v1beta2 to v1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-08-27 17:16:14 +03:00
Stefan Prodan 2fa8c58d9f
Remove unused `accessFrom` field from Bucket v1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-08-24 11:43:54 +03:00
Stefan Prodan 297b5f1941
Update samples to Bucket v1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-08-23 14:34:27 +03:00
Stefan Prodan 5acef7b169
Add API docs for Bucket v1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-08-23 13:57:38 +03:00
Stefan Prodan cd48373d6c
Update controller-gen to v0.16.1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-08-23 13:42:28 +03:00
Stefan Prodan 5be0c53729
Promote Bucket API to v1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-08-23 13:25:57 +03:00
Stefan Prodan 823224ea0d
Merge pull request #1589 from fluxcd/new-bucket-provider-constants
Introduce Bucket provider constants with the common part as a prefix
2024-08-23 12:46:59 +03:00
Matheus Pimenta 02d492bc43 Introduce Bucket provider constants with the common part as a prefix
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-08-22 14:48:53 -03:00
Stefan Prodan b2f08f59d3
Merge pull request #1588 from fluxcd/dependabot/github_actions/ci-4516fd8e81
build(deps): bump the ci group across 1 directory with 3 updates
2024-08-22 18:57:30 +03:00
dependabot[bot] 29a40bc195
build(deps): bump the ci group across 1 directory with 3 updates
Bumps the ci group with 3 updates in the / directory: [korthout/backport-action](https://github.com/korthout/backport-action), [anchore/sbom-action](https://github.com/anchore/sbom-action) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `korthout/backport-action` from 3.0.2 to 3.1.0
- [Release notes](https://github.com/korthout/backport-action/releases)
- [Commits](bd410d37cd...be567af183)

Updates `anchore/sbom-action` from 0.17.1 to 0.17.2
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](ab9d16d4b4...61119d458a)

Updates `github/codeql-action` from 3.26.2 to 3.26.4
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](429e197704...f0f3afee80)

---
updated-dependencies:
- dependency-name: korthout/backport-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-22 11:55:56 +00:00
Matheus Pimenta 74e82d2467
Merge pull request #1585 from fluxcd/bucket-sts-endpoint-ldap
Add LDAP provider for Bucket STS API
2024-08-22 08:50:09 -03:00
Matheus Pimenta 10ac11314d Add LDAP provider for Bucket STS API
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-08-22 08:41:23 -03:00
Matheus Pimenta 7c4fdd5f36
Merge pull request #1536 from matheuscscp/ocirepo-proxy
Add proxy support for OCIRepository API
2024-08-15 11:11:07 -03:00
Matheus Pimenta 03a118a94c Add proxy support for OCIRepository API
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-08-15 10:29:57 -03:00
Stefan Prodan 145ed4a0bb
Merge pull request #1583 from fluxcd/cosign-v2.4.0
Update cosign to v2.4.0
2024-08-15 12:12:51 +03:00
Stefan Prodan cfccdb5491
Update cosign to v2.4.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-08-15 11:18:32 +03:00
Stefan Prodan 5b980f1d02
Merge pull request #1579 from fluxcd/dependabot/github_actions/ci-392b9cf7da
build(deps): bump github/codeql-action from 3.26.1 to 3.26.2 in the ci group
2024-08-15 10:34:30 +03:00
dependabot[bot] da32ec205f
build(deps): bump github/codeql-action in the ci group
Bumps the ci group with 1 update: [github/codeql-action](https://github.com/github/codeql-action).


Updates `github/codeql-action` from 3.26.1 to 3.26.2
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](29d86d22a3...429e197704)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-15 07:05:30 +00:00
Stefan Prodan 164e1a7c7d
Merge pull request #1582 from fluxcd/go-1.23
Build with Go 1.23
2024-08-15 10:03:29 +03:00
Stefan Prodan 4eaedd54b8
Build with Go 1.23
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-08-15 09:52:45 +03:00
Stefan Prodan d39592f7d9
Merge pull request #1578 from fluxcd/k8s-1.31
Update dependencies to Kubernetes v1.31.0
2024-08-15 09:48:34 +03:00
Stefan Prodan 93ad04b6c8
Update dependencies to Kubernetes v1.31.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-08-14 21:40:29 +03:00
Stefan Prodan 20c9d7f296
Merge pull request #1576 from fluxcd/dependabot/github_actions/ci-da4bee5f54
build(deps): bump the ci group across 1 directory with 9 updates
2024-08-14 21:04:59 +03:00
dependabot[bot] 87c564e1f0
build(deps): bump the ci group across 1 directory with 9 updates
Bumps the ci group with 9 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4.1.6` | `4.1.7` |
| [actions/setup-go](https://github.com/actions/setup-go) | `5.0.1` | `5.0.2` |
| [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) | `3.0.0` | `3.2.0` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3.3.0` | `3.6.1` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `5.4.0` | `6.7.0` |
| [docker/login-action](https://github.com/docker/login-action) | `3.2.0` | `3.3.0` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `3.5.0` | `3.6.0` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.16.0` | `0.17.1` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.25.8` | `3.26.1` |



Updates `actions/checkout` from 4.1.6 to 4.1.7
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](a5ac7e51b4...692973e3d9)

Updates `actions/setup-go` from 5.0.1 to 5.0.2
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](cdcb360436...0a12ed9d6a)

Updates `docker/setup-qemu-action` from 3.0.0 to 3.2.0
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](68827325e0...49b3bc8e6b)

Updates `docker/setup-buildx-action` from 3.3.0 to 3.6.1
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](d70bba72b1...988b5a0280)

Updates `docker/build-push-action` from 5.4.0 to 6.7.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](ca052bb54a...5cd11c3a4c)

Updates `docker/login-action` from 3.2.0 to 3.3.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](0d4c9c5ea7...9780b0c442)

Updates `sigstore/cosign-installer` from 3.5.0 to 3.6.0
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](59acb6260d...4959ce089c)

Updates `anchore/sbom-action` from 0.16.0 to 0.17.1
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](e8d2a6937e...ab9d16d4b4)

Updates `github/codeql-action` from 3.25.8 to 3.26.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](2e230e8fe0...29d86d22a3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: ci
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-14 02:39:26 +00:00
Matheus Pimenta e1ff038fca
Merge pull request #1568 from fluxcd/bucket-aws-proxy
Add proxy support for AWS S3 buckets
2024-08-11 21:51:52 +01:00
Matheus Pimenta 08fff6500a
Merge pull request #1567 from fluxcd/bucket-azure-proxy
Add proxy support for Azure buckets
2024-08-11 21:34:12 +01:00
Matheus Pimenta 625e672c7a Add proxy support for AWS S3 buckets
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-08-09 22:26:53 +01:00
Matheus Pimenta b6bd2abe2d Add proxy support for Azure buckets
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-08-09 22:17:06 +01:00
Sunny f494cf8574
Merge pull request #1574 from fluxcd/az-blob-int-visitobjects
azure-blob: Fix VisitObjects() in integration test
2024-08-10 00:43:20 +05:30
Sunny 0618f54717
azure-blob: Fix VisitObjects() in integration test
Signed-off-by: Sunny <github@darkowlzz.space>
2024-08-09 18:58:17 +00:00
Matheus Pimenta 67f6cba19d
Merge pull request #1565 from matheuscscp/bucket-gcp-proxy
Add proxy support for GCS buckets
2024-08-09 19:15:28 +01:00
Matheus Pimenta 31ed900a90 Add proxy support for GCS buckets
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-08-09 19:05:10 +01:00
Matheus Pimenta c41c2d6f09
Merge pull request #1552 from matheuscscp/bucket-sts-endpoint
Add support for AWS STS endpoint in the Bucket API
2024-08-08 22:20:36 +01:00
Matheus Pimenta 7536ab4b02 Add support for AWS STS endpoint in the Bucket API
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-08-08 16:35:01 +01:00
Sunny 218af573a3
Merge pull request #1516 from bb-Ricardo/main
Fix Helm index validation for Artifactory
2024-07-22 19:45:05 +05:30
ricardo.bartels@telekom.de a65f6fda92 mitigate issue with chart validation in Helm 3.14 #1515
Signed-off-by: ricardo.bartels@telekom.de <ricardo.bartels@telekom.de>
2024-07-19 20:07:29 +02:00
Sunny 58b4e6d719
Merge pull request #1550 from matheuscscp/fix-bucket-err-msg
Improve invalid proxy error message for Bucket API
2024-07-16 18:05:00 +05:30
Matheus Pimenta 8d19782683 Improve invalid proxy error message for Bucket API
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-07-16 09:57:31 +01:00
Matheus Pimenta 54cb2d8fd9
Merge pull request #1539 from matheuscscp/debug-dup-subcharts
Fix HelmChart local dependency resolution for name-based path
2024-07-10 15:01:30 +01:00
Matheus Pimenta d941101697 Fix HelmChart local dependency resolution for name-based path
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-07-10 12:09:59 +01:00
Stefan Prodan 8d8e7cc982
Merge pull request #1529 from octo/fix-conditions-usage
Fix incorrect use of format strings with the `conditions` package.
2024-07-05 17:14:46 +03:00
Florian Forster 277e5c1d55
Prefer `%s` over `%v` when formatting errors.
Signed-off-by: Florian Forster <fforster@gitlab.com>
2024-07-05 15:55:33 +02:00
Florian Forster fa3022443c
fix: Print `strings.Builder` by calling `String()` explicitly.
The `String()` method is only defined for the pointer receiver.

Signed-off-by: Florian Forster <fforster@gitlab.com>
2024-07-05 15:55:32 +02:00
Florian Forster 8be37ef1d2
Fix incorrect use of format strings with the `conditions` package.
Many of the functions in the `conditions` package accept a format string and
(optional) arguments, just like `fmt.Printf` and friends.

In many places, the code passed an error message as the format string, causing
it to be interpreted by the `fmt` package. This leads to issues when the
message contains percent signs, e.g. URL-encoded values.

Consider the following code:

```go
// internal/controller/ocirepository_controller.go
revision, err := r.getRevision(ref, opts)
if err != nil {
	e := serror.NewGeneric(
		fmt.Errorf("failed to determine artifact digest: %w", err),
		ociv1.OCIPullFailedReason,
	)
	conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
	return sreconcile.ResultEmpty, e
}
```

Since `getRevision()` includes the URL in the error message and the error
message is used as a format string, the resulting condition reads:

```
failed to determine artifact digest: GET https://gitlab.com/jwt/auth?scope=repository%!A(MISSING)fforster%!F(MISSING)<REDACTED>%!F(MISSING)k8s-resource-manifests%!A(MISSING)pull&service=container_registry: DENIED: access forbidden
```

This adds an explicit format string and shortens `e.Error()` and
`e.Err.Error()` to `e`, which yields the same output.

To the best of my knowledge, Go is safe from format string attacks. I **don't**
think this is a security vulnerability, but I'm also not a security expert.

Signed-off-by: Florian Forster <fforster@gitlab.com>
2024-07-05 15:55:31 +02:00
Stefan Prodan 3c0dda47d3
Merge pull request #1535 from matheuscscp/matheuscscp-maintainer
Add matheuscscp as maintainer
2024-07-05 09:30:10 +03:00
Matheus Pimenta b5d881357f Add matheuscscp as maintainer
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-07-03 15:33:53 +01:00
Stefan Prodan c7e8330442
Merge pull request #1500 from matheuscscp/bucket-generic-proxy
Add support for `.spec.proxySecretRef` for generic provider of Bucket API
2024-07-03 17:20:11 +03:00
Matheus Pimenta 4d9c87cf3f Add support for .spec.proxySecretRef for generic provider of Bucket API
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-07-03 15:10:47 +01:00
Stefan Prodan 59ad5a72ee
Merge pull request #1512 from fluxcd/gha-arm64
Run ARM64 tests on GitHub runners
2024-06-14 12:13:29 +03:00
Stefan Prodan 7e70497c6c
Run ARM64 tests on GitHub runners
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-06-14 11:41:44 +03:00
souleb 09575db5ca
Merge pull request #1490 from fluxcd/fix-1485
helm: Use the default transport pool to preserve proxy settings
2024-06-14 09:01:56 +02:00
Soule BA b310a851c7
Use the transport pool
If implemented, A transport from the pool with safe defaults will be used when creating an oci registry client.
This will enable using the proxy configuration.

Signed-off-by: Soule BA <bah.soule@gmail.com>
2024-06-14 08:50:33 +02:00
Stefan Prodan 7e69f0835b
Merge pull request #1507 from fluxcd/dependabot/github_actions/ci-e906b6679e
build(deps): bump the ci group across 1 directory with 7 updates
2024-06-11 09:44:20 +03:00
Stefan Prodan dc4b1c0ea9
Adapt config to GoRelease v2
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-06-11 09:35:42 +03:00
dependabot[bot] c3be752254
build(deps): bump the ci group across 1 directory with 7 updates
Bumps the ci group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4.1.4` | `4.1.6` |
| [korthout/backport-action](https://github.com/korthout/backport-action) | `2.5.0` | `3.0.2` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `5.3.0` | `5.4.0` |
| [docker/login-action](https://github.com/docker/login-action) | `3.1.0` | `3.2.0` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.15.11` | `0.16.0` |
| [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) | `5.0.0` | `6.0.0` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.25.3` | `3.25.8` |



Updates `actions/checkout` from 4.1.4 to 4.1.6
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](0ad4b8fada...a5ac7e51b4)

Updates `korthout/backport-action` from 2.5.0 to 3.0.2
- [Release notes](https://github.com/korthout/backport-action/releases)
- [Commits](ef20d86abc...bd410d37cd)

Updates `docker/build-push-action` from 5.3.0 to 5.4.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](2cdde995de...ca052bb54a)

Updates `docker/login-action` from 3.1.0 to 3.2.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](e92390c5fb...0d4c9c5ea7)

Updates `anchore/sbom-action` from 0.15.11 to 0.16.0
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](7ccf588e3c...e8d2a6937e)

Updates `goreleaser/goreleaser-action` from 5.0.0 to 6.0.0
- [Release notes](https://github.com/goreleaser/goreleaser-action/releases)
- [Commits](7ec5c2b0c6...286f3b13b1)

Updates `github/codeql-action` from 3.25.3 to 3.25.8
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](d39d31e687...2e230e8fe0)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: korthout/backport-action
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: ci
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: goreleaser/goreleaser-action
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-11 02:34:11 +00:00
Stefan Prodan 81b4dd0ea4
Merge pull request #1475 from matheuscscp/bucket-cert-secret
Add `.spec.certSecretRef` to Bucket API
2024-05-22 15:55:54 +03:00
Matheus Pimenta bc16734391 Add .certSecretRef for Bucket API
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-05-15 19:44:05 +01:00
Stefan Prodan b41c6532a7
Merge pull request #1479 from matheuscscp/new-release-label
Add 1.3.x release label
2024-05-08 17:07:07 +03:00
Matheus Pimenta 22ac6b2abc Add 1.3.x release label
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-05-08 14:27:28 +01:00
Stefan Prodan 7461ad9915
Merge pull request #1473 from fluxcd/release/v1.3.x
Housekeeping: merge `release/v1.3.x` back into `main`
2024-05-03 13:45:56 +03:00
Stefan Prodan a80a99b359
Merge pull request #1472 from fluxcd/release-v1.3.0
Release v1.3.0
2024-05-03 12:52:22 +03:00
Stefan Prodan 70901f8291
Release v1.3.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-03 12:34:15 +03:00
Stefan Prodan 05ab8b1dc5
Add changelog entry for v1.3.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-03 12:34:15 +03:00
Stefan Prodan c9bf16717a
Merge pull request #1298 from fluxcd/phony-build
Rename make target `build` to `manager`
2024-05-03 09:56:15 +03:00
Stefan Prodan cc3d495aa9
ci: Print controller logs after e2e run
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-03 09:38:14 +03:00
Sunny 0bd5b95c89
Rename make target `build` to `manager`
Due to the existence of a BUILD_DIR called `build` the `build` make
target never works. Rename the make target as `manager`, in alignment
with other makefiles in other repos and not conflict with the `build`
directory.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
2024-05-03 09:30:54 +03:00
Stefan Prodan edccfe9e65
Merge pull request #1470 from fluxcd/dependabot/github_actions/ci-b23e0286c6
build(deps): bump actions/setup-go from 5.0.0 to 5.0.1 in the ci group
2024-05-03 09:24:28 +03:00
dependabot[bot] 9ce2d61a00
build(deps): bump actions/setup-go from 5.0.0 to 5.0.1 in the ci group
Bumps the ci group with 1 update: [actions/setup-go](https://github.com/actions/setup-go).


Updates `actions/setup-go` from 5.0.0 to 5.0.1
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](0c52d547c9...cdcb360436)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-03 06:16:40 +00:00
Stefan Prodan 16eeeef535
Merge pull request #1469 from fluxcd/dependabot/go_modules/go-deps-4411c5bc33
build(deps): bump google.golang.org/api from 0.172.0 to 0.177.0 in the go-deps group across 1 directory
2024-05-03 09:13:24 +03:00
dependabot[bot] 8598b8dd25
build(deps): bump google.golang.org/api
Bumps the go-deps group with 1 update in the / directory: [google.golang.org/api](https://github.com/googleapis/google-api-go-client).


Updates `google.golang.org/api` from 0.172.0 to 0.177.0
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.172.0...v0.177.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-02 21:13:24 +00:00
Stefan Prodan cf750b57cb
Merge pull request #1428 from fluxcd/helm-ga
Promote Helm APIs to `source.toolkit.fluxcd.io/v1` (GA)
2024-05-03 00:11:36 +03:00
Stefan Prodan 31c4df4a8d
Deprecate v1beta1 APIs
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-02 19:40:15 +03:00
Stefan Prodan af6cfc4d61
Remove deprecated `valuesFile` from HelmChart v1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-02 16:54:42 +03:00
Stefan Prodan 522f57377b
Update samples to v1 APIs
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-02 16:45:30 +03:00
Stefan Prodan e72a645234
Update dependencies
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-02 16:35:39 +03:00
Stefan Prodan 0af6e16a5a
docs: Remove deprecated aad-pod-identity
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-02 16:23:00 +03:00
Stefan Prodan 0a7f66b0e3
docs: Add API spec for Helm v1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-02 16:19:48 +03:00
Stefan Prodan f85bc174e6
Promote Helm APIs to v1 (GA)
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-02 16:04:27 +03:00
Stefan Prodan 5fcae5c475
Merge pull request #1447 from isometry/feature/ignore-missing-values-files
Add `.spec.ignoreMissingValuesFiles` to HelmChart API
2024-05-02 15:12:32 +03:00
Robin Breathe 1e82cec48d
chore: address feedback
Signed-off-by: Robin Breathe <robin@isometry.net>
2024-05-02 12:10:05 +02:00
Robin Breathe 9b57d3bc52
chore: update tests
Signed-off-by: Robin Breathe <robin@isometry.net>
2024-05-02 08:21:23 +02:00
Robin Breathe 6d96ae1da4
fix: regenerate manifests
Signed-off-by: Robin Breathe <robin@isometry.net>
2024-05-01 12:34:43 +02:00
Robin Breathe b2702de944
doc: document ignoreMissingValuesFiles
Signed-off-by: Robin Breathe <robin@isometry.net>
2024-05-01 09:59:16 +02:00
Paulo Canilho bf97748339
feat: resolved values files are persisted to and retrieved from the [HelmChart.Status.ObservedValuesFiles] field
Signed-off-by: Paulo Canilho <paulo.canilho@nexthink.com>
2024-05-01 08:01:42 +02:00
Robin Breathe b84ab9e698
feat(HelmChartSpec): optionally ignore missing valuesFiles
Signed-off-by: Robin Breathe <robin@isometry.net>
2024-05-01 08:01:41 +02:00
Robin Breathe 0fe64864d4
fix: gracefully handle PATH with whitespace
Signed-off-by: Robin Breathe <robin@isometry.net>
2024-04-30 21:15:56 +02:00
Stefan Prodan 0e49343795
Merge pull request #1467 from fluxcd/dependabot/github_actions/ci-3daa6e97ec
build(deps): bump the ci group across 1 directory with 3 updates
2024-04-29 09:09:17 +03:00
dependabot[bot] 833dc26f60
build(deps): bump the ci group across 1 directory with 3 updates
Bumps the ci group with 3 updates in the / directory: [actions/checkout](https://github.com/actions/checkout), [anchore/sbom-action](https://github.com/anchore/sbom-action) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `actions/checkout` from 4.1.3 to 4.1.4
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](1d96c772d1...0ad4b8fada)

Updates `anchore/sbom-action` from 0.15.10 to 0.15.11
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](ab5d7b5f48...7ccf588e3c)

Updates `github/codeql-action` from 3.25.2 to 3.25.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](8f596b4ae3...d39d31e687)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-29 02:17:23 +00:00
Stefan Prodan 11470b20de
Merge pull request #1450 from fluxcd/kubernetes-1.30
Update dependencies to Kubernetes 1.30
2024-04-26 12:14:55 +03:00
Stefan Prodan 4f2d0af3de
ci: Enable dispatch for e2e tests
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-04-26 11:49:31 +03:00
Stefan Prodan e590863286
Update dependencies to Kubernetes 1.30
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-04-26 11:36:15 +03:00
Stefan Prodan 919e1c79a8
Merge pull request #1461 from fluxcd/dependabot/github_actions/ci-72bff0be84
build(deps): bump the ci group across 1 directory with 3 updates
2024-04-24 11:21:09 +03:00
dependabot[bot] 277a2d08de
build(deps): bump the ci group across 1 directory with 3 updates
Bumps the ci group with 3 updates in the / directory: [helm/kind-action](https://github.com/helm/kind-action), [slsa-framework/slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `helm/kind-action` from 1.9.0 to 1.10.0
- [Release notes](https://github.com/helm/kind-action/releases)
- [Commits](99576bfa6d...0025e74a8c)

Updates `slsa-framework/slsa-github-generator` from 1.10.0 to 2.0.0
- [Release notes](https://github.com/slsa-framework/slsa-github-generator/releases)
- [Changelog](https://github.com/slsa-framework/slsa-github-generator/blob/main/CHANGELOG.md)
- [Commits](https://github.com/slsa-framework/slsa-github-generator/compare/v1.10.0...v2.0.0)

Updates `github/codeql-action` from 3.25.1 to 3.25.2
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](c7f9125735...8f596b4ae3)

---
updated-dependencies:
- dependency-name: helm/kind-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: slsa-framework/slsa-github-generator
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-24 03:04:14 +00:00
souleb ec85f3af4c
Merge pull request #1457 from fluxcd/fix-1451
Bind cached helm index to the maximum index size
2024-04-22 18:59:43 +02:00
Soule BA b30404fff1
Bind cached helm index to the maximum index size
Signed-off-by: Soule BA <bah.soule@gmail.com>
2024-04-22 17:02:33 +02:00
Stefan Prodan cb8aab3172
Merge pull request #1455 from fluxcd/dependabot/github_actions/ci-cf88df92f9
build(deps): bump the ci group across 1 directory with 2 updates
2024-04-22 17:39:07 +03:00
dependabot[bot] 6a5be543c2
build(deps): bump the ci group across 1 directory with 2 updates
Bumps the ci group with 2 updates in the / directory: [actions/checkout](https://github.com/actions/checkout) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `actions/checkout` from 4.1.2 to 4.1.3
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](9bb56186c3...1d96c772d1)

Updates `github/codeql-action` from 3.24.10 to 3.25.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](4355270be1...c7f9125735)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-22 02:11:01 +00:00
Stefan Prodan 014365d0e1
Merge pull request #1412 from AustinAbro321/allow-insecure-registry-login
Helm: Allow insecure registry login
2024-04-18 17:35:39 +03:00
Austin Abro ab6d560002
allow insecure registry login
Signed-off-by: Austin Abro <AustinAbro321@gmail.com>

only add loginoptinsecure when already logging in

Signed-off-by: Austin Abro <AustinAbro321@gmail.com>

fix tests, move registry login options

Signed-off-by: Austin Abro <AustinAbro321@gmail.com>

cleaner code

Signed-off-by: Austin Abro <austinabro321@gmail.com>

change localhost to 127.0.0.1 in insecure suite test path

Signed-off-by: Austin Abro <austinabro321@gmail.com>

let myself run tests

Signed-off-by: Austin Abro <AustinAbro321@gmail.com>

allow myself to run tests

Signed-off-by: Austin Abro <AustinAbro321@gmail.com>

clearer error message in test

Signed-off-by: Austin Abro <AustinAbro321@gmail.com>

update test to reflect new behavior

Signed-off-by: Austin Abro <AustinAbro321@gmail.com>

undo test config changes

Signed-off-by: Austin Abro <AustinAbro321@gmail.com>

remove extra whitespace

Signed-off-by: Austin Abro <AustinAbro321@gmail.com>
2024-04-18 13:12:18 +00:00
Stefan Prodan 247cd7f1fa
Merge pull request #1442 from fluxcd/cosign-v2.2.4
Update dependencies to cosign v2.2.4
2024-04-11 10:29:30 +03:00
Stefan Prodan 6a2b26fcdf
Adapt GCS mock server for `cloud.google.com/go/storage v1.39.1`
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-04-11 10:04:43 +03:00
Stefan Prodan 4d29266821
Update dependencies to cosign v2.2.4
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-04-11 08:08:02 +03:00
Stefan Prodan 2330e69401
Merge pull request #1441 from fluxcd/dependabot/github_actions/ci-a93a267d32
build(deps): bump the ci group with 3 updates
2024-04-11 07:51:39 +03:00
dependabot[bot] c6779e47af
build(deps): bump the ci group with 3 updates
Bumps the ci group with 3 updates: [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action), [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `docker/setup-buildx-action` from 3.2.0 to 3.3.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](2b51285047...d70bba72b1)

Updates `sigstore/cosign-installer` from 3.4.0 to 3.5.0
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](e1523de757...59acb6260d)

Updates `github/codeql-action` from 3.24.9 to 3.24.10
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](1b1aada464...4355270be1)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-11 02:55:16 +00:00
Stefan Prodan 3074decfc6
Merge pull request #1434 from fluxcd/pick-changelog-v1.2.5
Add changelog entry for v1.2.5
2024-04-04 17:38:53 +03:00
Stefan Prodan 94018683fe
Add changelog entry for v1.2.5
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
(cherry picked from commit e34e0170a7)
2024-04-04 17:13:11 +03:00
Stefan Prodan 915d1a072a
Merge pull request #1430 from fluxcd/sanitze-bucker-errors
Sanitize URLs for bucket fetch error messages
2024-04-04 15:54:38 +03:00
Jagpreet Singh Tamber 5854dbee73
Sanitize URLs for bucket fetch error messages.
Co-authored-by: Jagpreet Singh Tamber <jagpreetstamber@gmail.com>
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-04-04 15:22:21 +03:00
Stefan Prodan 9a0f9af295
Merge pull request #1427 from fluxcd/fix-notation-tests
Generate unique names for notation secrets
2024-04-03 11:48:28 +03:00
Stefan Prodan 76b38f4a8e
Generate unique names for notation secrets
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-04-03 10:14:19 +03:00
Stefan Prodan c159f05403
Merge pull request #1422 from fluxcd/dependabot/github_actions/ci-f14ce248bb
build(deps): bump the ci group with 8 updates
2024-04-03 09:29:20 +03:00
dependabot[bot] e72200788c
build(deps): bump the ci group with 8 updates
Bumps the ci group with 8 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4.1.1` | `4.1.2` |
| [korthout/backport-action](https://github.com/korthout/backport-action) | `2.4.1` | `2.5.0` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3.0.0` | `3.2.0` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `5.1.0` | `5.3.0` |
| [docker/login-action](https://github.com/docker/login-action) | `3.0.0` | `3.1.0` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.15.8` | `0.15.10` |
| [slsa-framework/slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator) | `1.9.0` | `1.10.0` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.24.3` | `3.24.9` |


Updates `actions/checkout` from 4.1.1 to 4.1.2
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](b4ffde65f4...9bb56186c3)

Updates `korthout/backport-action` from 2.4.1 to 2.5.0
- [Release notes](https://github.com/korthout/backport-action/releases)
- [Commits](e8161d6a0d...ef20d86abc)

Updates `docker/setup-buildx-action` from 3.0.0 to 3.2.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](f95db51fdd...2b51285047)

Updates `docker/build-push-action` from 5.1.0 to 5.3.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](4a13e500e5...2cdde995de)

Updates `docker/login-action` from 3.0.0 to 3.1.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](343f7c4344...e92390c5fb)

Updates `anchore/sbom-action` from 0.15.8 to 0.15.10
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](b6a39da807...ab5d7b5f48)

Updates `slsa-framework/slsa-github-generator` from 1.9.0 to 1.10.0
- [Release notes](https://github.com/slsa-framework/slsa-github-generator/releases)
- [Changelog](https://github.com/slsa-framework/slsa-github-generator/blob/main/CHANGELOG.md)
- [Commits](https://github.com/slsa-framework/slsa-github-generator/compare/v1.9.0...v1.10.0)

Updates `github/codeql-action` from 3.24.3 to 3.24.9
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](379614612a...1b1aada464)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: korthout/backport-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: slsa-framework/slsa-github-generator
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-03 02:54:07 +00:00
Stefan Prodan f8c792bf1f
Merge pull request #1426 from fluxcd/dependabot/go_modules/go-deps-cdee554d87
build(deps): Update `google.golang.org/api` to 0.172.0
2024-04-02 17:38:06 +03:00
dependabot[bot] 58f7d223ec
build(deps): bump the go-deps group with 1 update
Bumps the go-deps group with 1 update: [google.golang.org/api](https://github.com/googleapis/google-api-go-client).


Updates `google.golang.org/api` from 0.163.0 to 0.172.0
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.163.0...v0.172.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-02 14:20:09 +00:00
Stefan Prodan 135dabe8e5
Merge pull request #1425 from fluxcd/go1.22
Update dependencies to Go 1.22 and Kubernetes 1.29.3
2024-04-02 17:16:54 +03:00
Stefan Prodan 827f579b14
Update dependencies to Go 1.22 and Kubernetes 1.29.3
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-04-02 16:52:10 +03:00
Stefan Prodan 3db4edeb27
Merge pull request #1378 from fluxcd/helm-v3.14.0
Update controller to Helm v3.14.2 and Kubernetes v1.29.0
2024-04-02 16:29:41 +03:00
Soule BA 51a7c72d4c
Update controller to Helm v3.14.2 and Kubernetes v1.29.0
Signed-off-by: Soule BA <bah.soule@gmail.com>
2024-04-02 15:00:52 +02:00
souleb 0c81d04c89
Merge pull request #1420 from fluxcd/fix-tests-race-condition
Fix the race condition happening in main
2024-03-29 18:36:00 +01:00
Soule BA 97bc896488
Fix the race condition happening in main
There is a race condition happening in main due to the mockdns resolver.
This is an attempt to fix it (cannot repoduce locally).

Signed-off-by: Soule BA <bah.soule@gmail.com>
2024-03-29 17:19:39 +01:00
souleb 74c5f99948
Merge pull request #1407 from fluxcd/add-semverfilter-to-ocirepo
Introduce a semVer filter in OCIRepository API
2024-03-29 10:25:58 +01:00
Soule BA 6d7189dbd1
adding an example for semverFilter in the the documentation
Signed-off-by: Soule BA <bah.soule@gmail.com>
2024-03-28 00:09:52 +01:00
Soule BA 10434e7e1f
Introduce a semver filter in OCIRepository
If implemented a semver filter regex can be declared in conjuction with
a semver range in the OCIRepository `spec.Reference`

Signed-off-by: Soule BA <bah.soule@gmail.com>
2024-03-28 00:09:51 +01:00
souleb 295fb73485
Merge pull request #1417 from fluxcd/switch-to-verify-ocirepo
Use the verify defined interface in OCIRepository
2024-03-27 09:55:49 +01:00
Soule BA 12fb25fec2
removing verifyImageSignatures method
Signed-off-by: Soule BA <bah.soule@gmail.com>
2024-03-26 21:53:32 +01:00
Soule BA 7f3df76ccc
Use the verify defined interface in OCIRepository
Signed-off-by: Soule BA <bah.soule@gmail.com>
2024-03-26 15:35:13 +01:00
souleb 55a2cdb9ae
Merge pull request #1075 from JasonTheDeveloper/feat/notation
feat(notation): add support for notation in HelmChart and OCIRepository configuration
2024-03-26 14:52:05 +01:00
JasonTheDeveloper 553945ab8e Add verification support for notation signed artifacts
Introduces a new verification provider `notation` to verify notation signed artifacts. Currently only cosign is supported and that is a problem if the end user utilises notation.

---------

Signed-off-by: Jason <jagoodse@microsoft.com>
Signed-off-by: JasonTheDeveloper <jagoodse@microsoft.com>
Signed-off-by: Jagpreet Singh Tamber <jagpreetstamber@gmail.com>
Co-authored-by: souleb <bah.soule@gmail.com>
Co-authored-by: Jagpreet Singh Tamber <jagpreetstamber@gmail.com>
Co-authored-by: Sunny <github@darkowlzz.space>
2024-03-26 21:32:23 +11:00
souleb 565f6ee039
Merge pull request #1399 from fluxcd/update-controller-gen-0.14
updating controller-gen to v0.14.0
2024-03-14 10:51:29 +01:00
Soule BA 4163f3f0a1
updating controller-gen to v0.14.0
Signed-off-by: Soule BA <bah.soule@gmail.com>
2024-03-12 14:19:58 +01:00
Stefan Prodan 4dd5b2996b
Merge pull request #1386 from gmolau/main
Remove `genclient:Namespaced` tag
2024-02-29 13:50:54 +00:00
Georg Molau b2bfba41b9 This tag isn't used by controller-tools, only `nonNamespaced` is.
Context: https://cloud-native.slack.com/archives/CLAJ40HV3/p1708794732147909

Tested by running `make generate` and verifying that there is no diff.

Signed-off-by: Georg Molau <georg.molau@gmail.com>
2024-02-27 22:24:01 +01:00
souleb eb19b1d407
Merge pull request #1376 from fluxcd/dependabot/github_actions/ci-8402f891f4
build(deps): bump the ci group with 6 updates
2024-02-22 10:36:58 +01:00
dependabot[bot] d4180987ef
build(deps): bump the ci group with 6 updates
Bumps the ci group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [helm/kind-action](https://github.com/helm/kind-action) | `1.8.0` | `1.9.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `5.5.0` | `5.5.1` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `3.3.0` | `3.4.0` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.15.6` | `0.15.8` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.23.2` | `3.24.3` |
| [EndBug/label-sync](https://github.com/endbug/label-sync) | `2.3.2` | `2.3.3` |


Updates `helm/kind-action` from 1.8.0 to 1.9.0
- [Release notes](https://github.com/helm/kind-action/releases)
- [Commits](dda0770415...99576bfa6d)

Updates `docker/metadata-action` from 5.5.0 to 5.5.1
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](dbef88086f...8e5442c4ef)

Updates `sigstore/cosign-installer` from 3.3.0 to 3.4.0
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](9614fae9e5...e1523de757)

Updates `anchore/sbom-action` from 0.15.6 to 0.15.8
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](c6aed38a43...b6a39da807)

Updates `github/codeql-action` from 3.23.2 to 3.24.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](b7bf0a3ed3...379614612a)

Updates `EndBug/label-sync` from 2.3.2 to 2.3.3
- [Release notes](https://github.com/endbug/label-sync/releases)
- [Commits](da00f2c11f...5207415819)

---
updated-dependencies:
- dependency-name: helm/kind-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/metadata-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: EndBug/label-sync
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-22 02:36:28 +00:00
Sunny 76db76cdf7
Merge pull request #1377 from fluxcd/chart-name-validations
Improve chart name validation
2024-02-21 17:07:16 +05:30
Sunny 84b30d1404
Improve chart name validation
Allow periods in the chart name and validate chart name before
packaging it.

Signed-off-by: Sunny <github@darkowlzz.space>
2024-02-20 14:27:57 +00:00
Stefan Prodan eff5a0784c
Merge pull request #1364 from fluxcd/pick-changelog-v1.2.4
Add changelog entry for v1.2.4
2024-02-01 16:32:46 +02:00
Sunny 9cf2d44d1f Add changelog entry for v1.2.4
Signed-off-by: Sunny <github@darkowlzz.space>
(cherry picked from commit 2a5732432c)
2024-02-01 19:30:08 +05:30
Stefan Prodan 169a92a2d5
Merge pull request #1361 from fluxcd/dependabot/go_modules/go-deps-cb47608b4d
build(deps): bump the go-deps group with 2 updates
2024-02-01 09:42:38 +02:00
dependabot[bot] 8f6fd92f46
build(deps): bump the go-deps group with 2 updates
Bumps the go-deps group with 2 updates: [github.com/sigstore/cosign/v2](https://github.com/sigstore/cosign) and [google.golang.org/api](https://github.com/googleapis/google-api-go-client).


Updates `github.com/sigstore/cosign/v2` from 2.2.2 to 2.2.3
- [Release notes](https://github.com/sigstore/cosign/releases)
- [Changelog](https://github.com/sigstore/cosign/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sigstore/cosign/compare/v2.2.2...v2.2.3)

Updates `google.golang.org/api` from 0.159.0 to 0.161.0
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.159.0...v0.161.0)

---
updated-dependencies:
- dependency-name: github.com/sigstore/cosign/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-01 07:35:29 +00:00
Stefan Prodan 323a2e3fb8
Merge pull request #1355 from fluxcd/dependabot/github_actions/ci-c0ab02bc06
build(deps): bump the ci group with 3 updates
2024-01-30 13:50:59 +02:00
dependabot[bot] aa56e64537
build(deps): bump the ci group with 3 updates
Bumps the ci group with 3 updates: [korthout/backport-action](https://github.com/korthout/backport-action), [anchore/sbom-action](https://github.com/anchore/sbom-action) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `korthout/backport-action` from 2.3.0 to 2.4.1
- [Release notes](https://github.com/korthout/backport-action/releases)
- [Commits](addffea45a...e8161d6a0d)

Updates `anchore/sbom-action` from 0.15.4 to 0.15.6
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](41f7a6c033...c6aed38a43)

Updates `github/codeql-action` from 3.23.1 to 3.23.2
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](0b21cf2492...b7bf0a3ed3)

---
updated-dependencies:
- dependency-name: korthout/backport-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-30 02:17:25 +00:00
Stefan Prodan 63f66a9ee0
Merge pull request #1352 from fluxcd/dependabot/go_modules/go-deps-782f7954e3
Update controller to Kubernetes 1.28.6
2024-01-29 15:13:21 +02:00
Stefan Prodan 2816a3b07e
Update API to Kubernetes v1.28.4
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-01-29 15:05:25 +02:00
dependabot[bot] 964bd008c2
build(deps): bump the go-deps group with 12 updates
Bumps the go-deps group with 12 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/fluxcd/cli-utils](https://github.com/fluxcd/cli-utils) | `0.36.0-flux.2` | `0.36.0-flux.3` |
| [github.com/fluxcd/pkg/apis/event](https://github.com/fluxcd/pkg) | `0.6.0` | `0.7.0` |
| [github.com/fluxcd/pkg/apis/meta](https://github.com/fluxcd/pkg) | `1.2.0` | `1.3.0` |
| [github.com/fluxcd/pkg/git](https://github.com/fluxcd/pkg) | `0.16.0` | `0.17.0` |
| [github.com/fluxcd/pkg/git/gogit](https://github.com/fluxcd/pkg) | `0.16.1` | `0.17.0` |
| [github.com/fluxcd/pkg/helmtestserver](https://github.com/fluxcd/pkg) | `0.15.0` | `0.16.0` |
| [github.com/fluxcd/pkg/oci](https://github.com/fluxcd/pkg) | `0.33.3` | `0.35.0` |
| [github.com/fluxcd/pkg/runtime](https://github.com/fluxcd/pkg) | `0.43.2` | `0.44.0` |
| [github.com/google/uuid](https://github.com/google/uuid) | `1.5.0` | `1.6.0` |
| [github.com/minio/minio-go/v7](https://github.com/minio/minio-go) | `7.0.65` | `7.0.66` |
| [github.com/sigstore/sigstore](https://github.com/sigstore/sigstore) | `1.7.6` | `1.8.1` |
| [google.golang.org/api](https://github.com/googleapis/google-api-go-client) | `0.153.0` | `0.159.0` |


Updates `github.com/fluxcd/cli-utils` from 0.36.0-flux.2 to 0.36.0-flux.3
- [Commits](https://github.com/fluxcd/cli-utils/compare/v0.36.0-flux.2...v0.36.0-flux.3)

Updates `github.com/fluxcd/pkg/apis/event` from 0.6.0 to 0.7.0
- [Commits](https://github.com/fluxcd/pkg/compare/git/v0.6.0...git/v0.7.0)

Updates `github.com/fluxcd/pkg/apis/meta` from 1.2.0 to 1.3.0
- [Commits](https://github.com/fluxcd/pkg/compare/apis/meta/v1.2.0...apis/meta/v1.3.0)

Updates `github.com/fluxcd/pkg/git` from 0.16.0 to 0.17.0
- [Commits](https://github.com/fluxcd/pkg/compare/git/v0.16.0...git/v0.17.0)

Updates `github.com/fluxcd/pkg/git/gogit` from 0.16.1 to 0.17.0
- [Commits](https://github.com/fluxcd/pkg/compare/ssa/v0.16.1...git/v0.17.0)

Updates `github.com/fluxcd/pkg/helmtestserver` from 0.15.0 to 0.16.0
- [Commits](https://github.com/fluxcd/pkg/compare/git/v0.15.0...git/v0.16.0)

Updates `github.com/fluxcd/pkg/oci` from 0.33.3 to 0.35.0
- [Commits](https://github.com/fluxcd/pkg/compare/oci/v0.33.3...oci/v0.35.0)

Updates `github.com/fluxcd/pkg/runtime` from 0.43.2 to 0.44.0
- [Commits](https://github.com/fluxcd/pkg/compare/runtime/v0.43.2...runtime/v0.44.0)

Updates `github.com/google/uuid` from 1.5.0 to 1.6.0
- [Release notes](https://github.com/google/uuid/releases)
- [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/uuid/compare/v1.5.0...v1.6.0)

Updates `github.com/minio/minio-go/v7` from 7.0.65 to 7.0.66
- [Release notes](https://github.com/minio/minio-go/releases)
- [Commits](https://github.com/minio/minio-go/compare/v7.0.65...v7.0.66)

Updates `github.com/sigstore/sigstore` from 1.7.6 to 1.8.1
- [Release notes](https://github.com/sigstore/sigstore/releases)
- [Commits](https://github.com/sigstore/sigstore/compare/v1.7.6...v1.8.1)

Updates `google.golang.org/api` from 0.153.0 to 0.159.0
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.153.0...v0.159.0)

---
updated-dependencies:
- dependency-name: github.com/fluxcd/cli-utils
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/fluxcd/pkg/apis/event
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/fluxcd/pkg/apis/meta
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/fluxcd/pkg/git
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/fluxcd/pkg/git/gogit
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/fluxcd/pkg/helmtestserver
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/fluxcd/pkg/oci
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/fluxcd/pkg/runtime
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/google/uuid
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/minio/minio-go/v7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/sigstore/sigstore
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-29 12:50:07 +00:00
Stefan Prodan 7d2affb0d6
Merge pull request #1351 from fluxcd/dependabot-ignore-cloud-sdk
dependabot: Ignore Cloud SDKs
2024-01-29 14:45:43 +02:00
Stefan Prodan 0c0b533367
dependabot: Ignore Cloud SDKs
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-01-29 14:41:49 +02:00
Stefan Prodan 9979603fe6
Merge pull request #1348 from fluxcd/dependabot-gomod
ci: Enable dependabot `gomod` updates
2024-01-29 14:20:12 +02:00
Stefan Prodan f47c85e492
ci: Enable dependabot `gomod` updates
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-01-26 20:28:49 +02:00
Stefan Prodan 6264713ac1
Merge pull request #1346 from fluxcd/distribution-up
Update OCI distribution to v3.0.0-alpha.1
2024-01-26 16:03:38 +02:00
Stefan Prodan acccf95b31
Update OCI distribution to v3.0.0-alpha.1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-01-26 14:51:03 +02:00
Stefan Prodan e1972b38fc
Merge pull request #1342 from fluxcd/dependabot/github_actions/ci-6640e13b03
build(deps): bump the ci group with 2 updates
2024-01-22 17:10:12 +02:00
dependabot[bot] 37ca30a142
build(deps): bump the ci group with 2 updates
Bumps the ci group with 2 updates: [anchore/sbom-action](https://github.com/anchore/sbom-action) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `anchore/sbom-action` from 0.15.3 to 0.15.4
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](c7f031d924...41f7a6c033)

Updates `github/codeql-action` from 3.23.0 to 3.23.1
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](e5f05b81d5...0b21cf2492)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-22 02:12:48 +00:00
Stefan Prodan 0b72483210
Merge pull request #1339 from fluxcd/dependabot/github_actions/ci-cbcf11c8df
build(deps): bump the ci group with 2 updates
2024-01-15 10:57:23 +02:00
dependabot[bot] f2056e09a4
build(deps): bump the ci group with 2 updates
Bumps the ci group with 2 updates: [anchore/sbom-action](https://github.com/anchore/sbom-action) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `anchore/sbom-action` from 0.15.2 to 0.15.3
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](719133684c...c7f031d924)

Updates `github/codeql-action` from 3.22.12 to 3.23.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](012739e508...e5f05b81d5)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-15 02:35:47 +00:00
Stefan Prodan 44d1823ec5
Merge pull request #1337 from fluxcd/dependabot/go_modules/github.com/cloudflare/circl-1.3.7
build(deps): bump github.com/cloudflare/circl from 1.3.6 to 1.3.7
2024-01-08 19:05:05 +02:00
dependabot[bot] 081ac045d1
build(deps): bump github.com/cloudflare/circl from 1.3.6 to 1.3.7
Bumps [github.com/cloudflare/circl](https://github.com/cloudflare/circl) from 1.3.6 to 1.3.7.
- [Release notes](https://github.com/cloudflare/circl/releases)
- [Commits](https://github.com/cloudflare/circl/compare/v1.3.6...v1.3.7)

---
updated-dependencies:
- dependency-name: github.com/cloudflare/circl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-08 16:55:12 +00:00
Stefan Prodan 18642dd2b8
Merge pull request #1335 from fluxcd/dependabot/github_actions/ci-e400a7320d
build(deps): bump the ci group with 5 updates
2024-01-08 09:41:37 +02:00
dependabot[bot] 5eb3c8525a
build(deps): bump the ci group with 5 updates
Bumps the ci group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [korthout/backport-action](https://github.com/korthout/backport-action) | `2.2.0` | `2.3.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `5.3.0` | `5.5.0` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `3.2.0` | `3.3.0` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.15.1` | `0.15.2` |
| [github/codeql-action](https://github.com/github/codeql-action) | `2.22.9` | `3.22.12` |


Updates `korthout/backport-action` from 2.2.0 to 2.3.0
- [Release notes](https://github.com/korthout/backport-action/releases)
- [Commits](b982d297e3...addffea45a)

Updates `docker/metadata-action` from 5.3.0 to 5.5.0
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](31cebacef4...dbef88086f)

Updates `sigstore/cosign-installer` from 3.2.0 to 3.3.0
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](1fc5bd396d...9614fae9e5)

Updates `anchore/sbom-action` from 0.15.1 to 0.15.2
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](5ecf649a41...719133684c)

Updates `github/codeql-action` from 2.22.9 to 3.22.12
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](c0d1daa7f7...012739e508)

---
updated-dependencies:
- dependency-name: korthout/backport-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: docker/metadata-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-08 02:13:29 +00:00
Stefan Prodan f8421712d9
Merge pull request #1332 from fluxcd/dependabot/go_modules/github.com/containerd/containerd-1.7.11
build(deps): bump github.com/containerd/containerd from 1.7.6 to 1.7.11
2024-01-02 16:17:19 +02:00
dependabot[bot] a4daddca57
build(deps): bump github.com/containerd/containerd from 1.7.6 to 1.7.11
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.7.6 to 1.7.11.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](https://github.com/containerd/containerd/compare/v1.7.6...v1.7.11)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-19 21:23:35 +00:00
Hidde Beydals 52c2d06615
Merge pull request #1331 from fluxcd/dependabot/go_modules/golang.org/x/crypto-0.17.0
build(deps): bump golang.org/x/crypto from 0.16.0 to 0.17.0
2023-12-19 09:36:48 +01:00
dependabot[bot] 4394296e88
build(deps): bump golang.org/x/crypto from 0.16.0 to 0.17.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.16.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.16.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-19 00:06:41 +00:00
Stefan Prodan 7edd864c2f
Merge pull request #1329 from fluxcd/pick-changelog-v1.2.3
Pick changelog v1.2.3
2023-12-14 17:24:47 +02:00
Sunny 08033ce9ea
Add changelog entry for v1.2.3
Signed-off-by: Sunny <darkowlzz@protonmail.com>
(cherry picked from commit 13aae50f08)
2023-12-14 20:52:55 +05:30
Sunny f1b53eb1e0
Merge pull request #1325 from fluxcd/update-helm
Update Helm to v3.13.3
2023-12-14 16:10:53 +05:30
Sunny 6e49175351 Update Helm to v3.13.3
Signed-off-by: Sunny <darkowlzz@protonmail.com>
2023-12-14 15:54:47 +05:30
Sunny 9a36e798d7
Merge pull request #1324 from fluxcd/remove-migration-event-log
helmrepo: Remove migration log/event
2023-12-14 15:54:19 +05:30
Sunny a242bdabed helmrepo: Remove migration log event
This will be logged/event emitted forever once in the lifecycle of
HelmRepository OCI object because all new objects have to remove the
.status.observedGeneration which is set to -1 by the API defaulting.
Better to perform the object conversion internally without any log or
event.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
2023-12-14 15:31:02 +05:30
Stefan Prodan 82b1381110
Merge pull request #1323 from fluxcd/pick-changelog-v1.2.2
Add changelog entry for v1.2.2
2023-12-11 15:19:49 +01:00
Hidde Beydals 26a6326ac3
Add changelog entry for v1.2.2
Signed-off-by: Hidde Beydals <hidde@hhh.computer>
(cherry picked from commit 0713a0269c)
2023-12-11 15:12:15 +01:00
Hidde Beydals a90a0ebf15
Merge pull request #1320 from fluxcd/update-pkgs-deps
Update fluxcd/pkg dependencies
2023-12-11 14:02:20 +01:00
Hidde Beydals ddaac2e25b
Update fluxcd/pkg dependencies
- github.com/fluxcd/pkg/git/gogit to v0.16.1
- github.com/fluxcd/pkg/oci to v0.33.3
- github.com/fluxcd/pkg/runtime to v0.43.2

Signed-off-by: Hidde Beydals <hidde@hhh.computer>
2023-12-11 13:53:22 +01:00
Hidde Beydals fec00f0584
Merge pull request #1317 from fluxcd/update-deps
Update dependencies
2023-12-11 11:02:05 +01:00
Hidde Beydals 3351d9f715
Update dependencies
- github.com/fluxcd/cli-utils to v0.36.0-flux.2
- github.com/fluxcd/pkg/oci to v0.33.2
- github.com/fluxcd/pkg/runtime to v0.43.1
- github.com/fluxcd/source-controller/api to v1.2.1
- github.com/go-git/go-git/v5 to v5.11.0

Signed-off-by: Hidde Beydals <hidde@hhh.computer>
2023-12-11 10:20:25 +01:00
Hidde Beydals c0e39ad348
api: update (indirect) dependencies
- github.com/go-logr/logr to v1.3.0
- golang.org/x/net to v0.19.0
- golang.org/x/text to v0.14.0
- k8s.io/klog/v2 to v2.110.1
- k8s.io/utils to v0.0.0-20231127182322-b307cd553661
- sigs.k8s.io/structured-merge-diff/v4 to v4.4.1

Signed-off-by: Hidde Beydals <hidde@hhh.computer>
2023-12-11 10:15:00 +01:00
Hidde Beydals ec145d4edf
Merge pull request #1315 from fluxcd/alpine-319
build: update Alpine to 3.19
2023-12-11 09:25:52 +01:00
Hidde Beydals ccae76f3ea
build: update Alpine to 3.19
Signed-off-by: Hidde Beydals <hidde@hhh.computer>
2023-12-11 09:18:21 +01:00
Hidde Beydals e7a1af96b8
Merge pull request #1311 from fluxcd/pick-changelog-v1.2.1
Add changelog entry for v1.2.1
2023-12-11 09:17:59 +01:00
Hidde Beydals 8d92bbbed2
Add changelog entry for v1.2.1
Signed-off-by: Hidde Beydals <hidde@hhh.computer>
(cherry picked from commit 13f43b8201)
2023-12-11 09:16:35 +01:00
Stefan Prodan 55b5e7d28d
Merge pull request #1313 from fluxcd/dependabot/github_actions/ci-72c9c0b121
build(deps): bump the ci group with 5 updates
2023-12-11 08:47:15 +01:00
dependabot[bot] 7af8651501
build(deps): bump the ci group with 5 updates
Bumps the ci group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [korthout/backport-action](https://github.com/korthout/backport-action) | `2.1.1` | `2.2.0` |
| [actions/setup-go](https://github.com/actions/setup-go) | `4.1.0` | `5.0.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `5.2.0` | `5.3.0` |
| [anchore/sbom-action](https://github.com/anchore/sbom-action) | `0.15.0` | `0.15.1` |
| [github/codeql-action](https://github.com/github/codeql-action) | `2.22.8` | `2.22.9` |


Updates `korthout/backport-action` from 2.1.1 to 2.2.0
- [Release notes](https://github.com/korthout/backport-action/releases)
- [Commits](08bafb375e...b982d297e3)

Updates `actions/setup-go` from 4.1.0 to 5.0.0
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](93397bea11...0c52d547c9)

Updates `docker/metadata-action` from 5.2.0 to 5.3.0
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](e6428a5c4e...31cebacef4)

Updates `anchore/sbom-action` from 0.15.0 to 0.15.1
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](fd74a6fb98...5ecf649a41)

Updates `github/codeql-action` from 2.22.8 to 2.22.9
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](407ffafae6...c0d1daa7f7)

---
updated-dependencies:
- dependency-name: korthout/backport-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: ci
- dependency-name: docker/metadata-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 02:25:47 +00:00
Hidde Beydals a83cb5cb78
Merge pull request #1308 from fluxcd/update-deps
Update dependencies
2023-12-08 09:30:29 +01:00
Hidde Beydals 4e6cef5075
Update dependencies
- github.com/sigstore/cosign/v2 to v2.2.2
- google.golang.org/api to v0.153.0

Signed-off-by: Hidde Beydals <hidde@hhh.computer>
2023-12-08 09:17:10 +01:00
Sanskar Jaiswal b983b1a084
Merge pull request #1307 from fluxcd/backport-release-v1.2.x-label
add `backport:release/v1.2.x` label
2023-12-06 12:34:00 +05:30
Sanskar Jaiswal e61d80cc1d
add `backport:release/v1.2.x` label
Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com>
2023-12-06 11:42:27 +05:30
Sanskar Jaiswal c9d5be8cef
Merge pull request #1306 from fluxcd/release/v1.2.x
Housekeeping: merge release/v1.2.x back into main
2023-12-05 22:52:09 +05:30
177 changed files with 22791 additions and 4558 deletions

View File

@ -1,16 +1,40 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
labels: ["dependencies"]
schedule:
interval: "monthly"
groups:
go-deps:
patterns:
- "*"
allow:
- dependency-type: "direct"
ignore:
# Cloud SDK are updated manually
- dependency-name: "cloud.google.com/*"
- dependency-name: "github.com/Azure/azure-sdk-for-go/*"
# Kubernetes deps are updated by fluxcd/pkg/runtime
- dependency-name: "k8s.io/*"
- dependency-name: "sigs.k8s.io/*"
- dependency-name: "github.com/go-logr/*"
# OCI deps are updated by fluxcd/pkg/oci
- dependency-name: "github.com/docker/*"
- dependency-name: "github.com/distribution/*"
- dependency-name: "github.com/google/go-containerregistry*"
- dependency-name: "github.com/opencontainers/*"
# Helm deps are updated by fluxcd/pkg/helmtestserver
- dependency-name: "helm.sh/helm/*"
# Flux APIs are updated at release time
- dependency-name: "github.com/fluxcd/source-controller/api"
- package-ecosystem: "github-actions"
directory: "/"
labels: ["area/ci", "dependencies"]
schedule:
# By default, this will be on a monday.
interval: "weekly"
groups:
# Group all updates together, so that they are all applied in a single PR.
# Grouped updates are currently in beta and is subject to change.
# xref: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#groups
ci:
patterns:
- "*"
schedule:
interval: "monthly"

15
.github/labels.yaml vendored
View File

@ -22,3 +22,18 @@
- name: backport:release/v1.1.x
description: To be backported to release/v1.1.x
color: '#ffd700'
- name: backport:release/v1.2.x
description: To be backported to release/v1.2.x
color: '#ffd700'
- name: backport:release/v1.3.x
description: To be backported to release/v1.3.x
color: '#ffd700'
- name: backport:release/v1.4.x
description: To be backported to release/v1.4.x
color: '#ffd700'
- name: backport:release/v1.5.x
description: To be backported to release/v1.5.x
color: '#ffd700'
- name: backport:release/v1.6.x
description: To be backported to release/v1.6.x
color: '#ffd700'

View File

@ -16,11 +16,11 @@ jobs:
if: github.event.pull_request.state == 'closed' && github.event.pull_request.merged && (github.event_name != 'labeled' || startsWith('backport:', github.event.label.name))
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Create backport PRs
uses: korthout/backport-action@08bafb375e6e9a9a2b53a744b987e5d81a133191 # v2.1.1
uses: korthout/backport-action@436145e922f9561fc5ea157ff406f21af2d6b363 # v3.2.0
# xref: https://github.com/korthout/backport-action#inputs
with:
# Use token to allow workflows to be triggered for the created PR

View File

@ -17,11 +17,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: 1.21.x
go-version: 1.24.x
cache-dependency-path: |
**/go.sum
**/go.mod

View File

@ -1,11 +1,11 @@
name: e2e
on:
workflow_dispatch:
pull_request:
paths-ignore:
- 'CHANGELOG.md'
- 'README.md'
- 'MAINTAINERS'
branches:
- 'main'
- 'release/**'
push:
branches:
- 'main'
@ -20,11 +20,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: 1.21.x
go-version: 1.24.x
cache-dependency-path: |
**/go.sum
**/go.mod
@ -34,11 +34,9 @@ jobs:
run: |
echo 'GO_TAGS=integration' >> $GITHUB_ENV
- name: Setup Kubernetes
uses: helm/kind-action@dda0770415bac9fc20092cacbc54aa298604d140 # v1.8.0
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
with:
version: v0.19.0
cluster_name: kind
node_image: kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6
- name: Setup Kustomize
uses: fluxcd/pkg/actions/kustomize@main
- name: Setup Helm
@ -48,45 +46,8 @@ jobs:
SKIP_COSIGN_VERIFICATION: true
CREATE_CLUSTER: false
run: make e2e
kind-linux-arm64:
# Hosted on Equinix
# Docs: https://github.com/fluxcd/flux2/tree/main/.github/runners
runs-on: [self-hosted, Linux, ARM64, equinix]
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with:
go-version: 1.21.x
cache-dependency-path: |
**/go.sum
**/go.mod
- name: Enable integration tests
# Only run integration tests for main and release branches
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')
run: |
echo 'GO_TAGS=integration' >> $GITHUB_ENV
- name: Prepare
id: prep
run: |
echo "CLUSTER=arm64-${GITHUB_SHA:0:7}-$(date +%s)" >> $GITHUB_OUTPUT
echo "CONTEXT=kind-arm64-${GITHUB_SHA:0:7}-$(date +%s)" >> $GITHUB_OUTPUT
- name: Setup Kubernetes Kind
run: |
kind create cluster --name ${{ steps.prep.outputs.CLUSTER }} --kubeconfig=/tmp/${{ steps.prep.outputs.CLUSTER }}
- name: Run e2e tests
env:
SKIP_COSIGN_VERIFICATION: true
KIND_CLUSTER_NAME: ${{ steps.prep.outputs.CLUSTER }}
KUBECONFIG: /tmp/${{ steps.prep.outputs.CLUSTER }}
CREATE_CLUSTER: false
BUILD_PLATFORM: linux/arm64
MINIO_TAG: RELEASE.2020-09-17T04-49-20Z-arm64
run: make e2e
- name: Cleanup
- name: Print controller logs
if: always()
continue-on-error: true
run: |
kind delete cluster --name ${{ steps.prep.outputs.CLUSTER }}
rm /tmp/${{ steps.prep.outputs.CLUSTER }}
kubectl -n source-system logs -l app=source-controller

View File

@ -15,16 +15,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup QEMU
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Setup Docker Buildx
id: buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
with:
buildkitd-flags: "--debug"
- name: Build multi-arch container image
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with:
push: false
builder: ${{ steps.buildx.outputs.name }}

View File

@ -29,7 +29,7 @@ jobs:
packages: write # for pushing and signing container images.
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Kustomize
uses: fluxcd/pkg/actions/kustomize@main
- name: Prepare
@ -42,24 +42,24 @@ jobs:
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
- name: Setup QEMU
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- name: Setup Docker Buildx
id: buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: Login to GitHub Container Registry
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: fluxcdbot
password: ${{ secrets.GHCR_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: fluxcdbot
password: ${{ secrets.DOCKER_FLUXCD_PASSWORD }}
- name: Generate images meta
id: meta
uses: docker/metadata-action@e6428a5c4e294a61438ed7f43155db912025b6b3 # v5.2.0
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
with:
images: |
fluxcd/${{ env.CONTROLLER }}
@ -68,7 +68,7 @@ jobs:
type=raw,value=${{ steps.prep.outputs.VERSION }}
- name: Publish images
id: build-push
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with:
sbom: true
provenance: true
@ -79,7 +79,7 @@ jobs:
platforms: linux/amd64,linux/arm/v7,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- uses: sigstore/cosign-installer@1fc5bd396d372bee37d608f955b336615edf79c8 # v3.2.0
- uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
- name: Sign images
env:
COSIGN_EXPERIMENTAL: 1
@ -92,14 +92,14 @@ jobs:
mkdir -p config/release
kustomize build ./config/crd > ./config/release/${{ env.CONTROLLER }}.crds.yaml
kustomize build ./config/manager > ./config/release/${{ env.CONTROLLER }}.deployment.yaml
- uses: anchore/sbom-action/download-syft@fd74a6fb98a204a1ad35bbfae0122c1a302ff88b # v0.15.0
- uses: anchore/sbom-action/download-syft@e11c554f704a0b820cbf8c51673f6945e0731532 # v0.20.0
- name: Create release and SBOM
id: run-goreleaser
if: startsWith(github.ref, 'refs/tags/v')
uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0
with:
version: latest
args: release --clean --skip-validate
args: release --clean --skip=validate
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Generate SLSA metadata
@ -123,7 +123,7 @@ jobs:
id-token: write # for creating OIDC tokens for signing.
contents: write # for uploading attestations to GitHub releases.
if: startsWith(github.ref, 'refs/tags/v')
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.9.0
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
with:
provenance-name: "provenance.intoto.jsonl"
base64-subjects: "${{ needs.release.outputs.hashes }}"
@ -136,7 +136,7 @@ jobs:
id-token: write # for creating OIDC tokens for signing.
packages: write # for uploading attestations.
if: startsWith(github.ref, 'refs/tags/v')
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
with:
image: ${{ needs.release.outputs.image_url }}
digest: ${{ needs.release.outputs.image_digest }}
@ -151,7 +151,7 @@ jobs:
id-token: write # for creating OIDC tokens for signing.
packages: write # for uploading attestations.
if: startsWith(github.ref, 'refs/tags/v')
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
with:
image: ghcr.io/${{ needs.release.outputs.image_url }}
digest: ${{ needs.release.outputs.image_digest }}

View File

@ -18,9 +18,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Run FOSSA scan and upload build data
uses: fossa-contrib/fossa-action@cdc5065bcdee31a32e47d4585df72d66e8e941c2 # v3.0.0
uses: fossa-contrib/fossa-action@3d2ef181b1820d6dcd1972f86a767d18167fa19b # v3.0.1
with:
# FOSSA Push-Only API Token
fossa-api-key: 5ee8bf422db1471e0bcf2bcb289185de
@ -31,22 +31,22 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: 1.21.x
go-version: 1.24.x
cache-dependency-path: |
**/go.sum
**/go.mod
- name: Initialize CodeQL
uses: github/codeql-action/init@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
languages: go
# xref: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# xref: https://codeql.github.com/codeql-query-help/go/
queries: security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8
uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18

View File

@ -17,8 +17,8 @@ jobs:
permissions:
issues: write
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: EndBug/label-sync@da00f2c11fdb78e4fae44adac2fdd713778ea3e8 # v2.3.2
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: EndBug/label-sync@52074158190acb45f3077f9099fea818aa43f97a # v2.3.3
with:
# Configuration file
config-file: |

View File

@ -1,12 +1,11 @@
name: tests
on:
workflow_dispatch:
pull_request:
paths-ignore:
- 'CHANGELOG.md'
- 'README.md'
- 'MAINTAINERS'
branches:
- 'main'
- 'release/**'
push:
branches:
- 'main'
@ -21,11 +20,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: 1.21.x
go-version: 1.24.x
cache-dependency-path: |
**/go.sum
**/go.mod
@ -37,31 +36,22 @@ jobs:
run: make test
test-linux-arm64:
# Hosted on Equinix
# Docs: https://github.com/fluxcd/flux2/tree/main/.github/runners
runs-on: [self-hosted, Linux, ARM64, equinix]
runs-on:
group: "ARM64"
if: github.actor != 'dependabot[bot]'
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: 1.21.x
go-version: 1.24.x
cache-dependency-path: |
**/go.sum
**/go.mod
- name: Run tests
env:
SKIP_COSIGN_VERIFICATION: true
TEST_AZURE_ACCOUNT_NAME: ${{ secrets.TEST_AZURE_ACCOUNT_NAME }}
TEST_AZURE_ACCOUNT_KEY: ${{ secrets.TEST_AZURE_ACCOUNT_KEY }}
# Temporarily disabling -race for arm64 as our GitHub action
# runners don't seem to like it. The race detection was tested
# on both Apple M1 and Linux arm64 with successful results.
#
# We should reenable go test -race for arm64 runners once the
# current issue is resolved.
GO_TEST_ARGS: ''
run: make test

View File

@ -2,11 +2,9 @@ name: verify
on:
pull_request:
paths-ignore:
- 'CHANGELOG.md'
- 'README.md'
- 'MAINTAINERS'
branches:
- 'main'
- 'release/**'
push:
branches:
- 'main'
@ -21,11 +19,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: 1.21.x
go-version: 1.24.x
cache-dependency-path: |
**/go.sum
**/go.mod

View File

@ -23,7 +23,7 @@ release:
To verify the images and their provenance (SLSA level 3), please see the [security documentation](https://fluxcd.io/flux/security/).
changelog:
skip: true
disable: true
checksum:
extra_files:

View File

@ -2,6 +2,404 @@
All notable changes to this project are documented in this file.
## 1.6.2
**Release date:** 2025-06-27
This patch release comes with a fix for `rsa-sha2-512` and `rsa-sha2-256` algorithms
not being prioritized for `ssh-rsa` host keys.
Fixes:
- Fix: Prioritize sha2-512 and sha2-256 for ssh-rsa host keys
[#1839](https://github.com/fluxcd/source-controller/pull/1839)
## 1.6.1
**Release date:** 2025-06-13
This patch release comes with a fix for the `knownhosts: key mismatch`
error in the `GitRepository` API when using SSH authentication, and
a fix for authentication with
[public ECR repositories](https://fluxcd.io/flux/integrations/aws/#for-amazon-public-elastic-container-registry)
in the `OCIRepository` API.
Fix:
- Fix authentication for public ECR
[#1825](https://github.com/fluxcd/source-controller/pull/1825)
- Fix `knownhosts key mismatch` regression bug
[#1829](https://github.com/fluxcd/source-controller/pull/1829)
## 1.6.0
**Release date:** 2025-05-27
This minor release promotes the OCIRepository API to GA, and comes with new features,
improvements and bug fixes.
### OCIRepository
The `OCIRepository` API has been promoted from `v1beta2` to `v1` (GA).
The `v1` API is backwards compatible with `v1beta2`.
OCIRepository API now supports object-level workload identity by setting
`.spec.provider` to one of `aws`, `azure`, or `gcp`, and setting
`.spec.serviceAccountName` to the name of a service account in the same
namespace that has been configured with appropriate cloud permissions.
For this feature to work, the controller feature gate
`ObjectLevelWorkloadIdentity` must be enabled. See a complete guide
[here](https://fluxcd.io/flux/integrations/).
OCIRepository API now caches registry credentials for cloud providers
by default. This behavior can be disabled or fine-tuned by adjusting the
token cache controller flags (see [docs](https://fluxcd.io/flux/components/source/options/)).
The token cache also exposes metrics that are documented
[here](https://fluxcd.io/flux/monitoring/metrics/#controller-metrics).
### GitRepository
GitRepository API now supports sparse checkout by setting a list
of directories in the `.spec.sparseCheckout` field. This allows
for optimizing the amount of data fetched from the Git repository.
GitRepository API now supports mTLS authentication for HTTPS Git repositories
by setting the fields `tls.crt`, `tls.key`, and `ca.crt` in the `.data` field
of the referenced Secret in `.spec.secretRef`.
GitRepository API now caches credentials for non-`generic` providers by default.
This behavior can be disabled or fine-tuned by adjusting the
token cache controller flags (see [docs](https://fluxcd.io/flux/components/source/options/)).
The token cache also exposes metrics that are documented
[here](https://fluxcd.io/flux/monitoring/metrics/#controller-metrics).
### General updates
In addition, the Kubernetes dependencies have been updated to v1.33 and
various other controller dependencies have been updated to their latest
version. The controller is now built with Go 1.24.
Fixes:
- Downgrade `Masterminds/semver` to v3.3.0
[#1785](https://github.com/fluxcd/source-controller/pull/1785)
Improvements:
- Promote OCIRepository API to v1 (GA)
[#1794](https://github.com/fluxcd/source-controller/pull/1794)
- [RFC-0010] Introduce object-level workload identity for container registry APIs and cache credentials
[#1790](https://github.com/fluxcd/source-controller/pull/1790)
[#1802](https://github.com/fluxcd/source-controller/pull/1802)
[#1811](https://github.com/fluxcd/source-controller/pull/1811)
- Implement Sparse Checkout for `GitRepository`
[#1774](https://github.com/fluxcd/source-controller/pull/1774)
- Add Mutual TLS support to `GitRepository`
[#1778](https://github.com/fluxcd/source-controller/pull/1778)
- Introduce token cache for `GitRepository`
[#1745](https://github.com/fluxcd/source-controller/pull/1745)
[#1788](https://github.com/fluxcd/source-controller/pull/1788)
[#1789](https://github.com/fluxcd/source-controller/pull/1789)
- Build controller without CGO
[#1725](https://github.com/fluxcd/source-controller/pull/1725)
- Various dependency updates
[#1812](https://github.com/fluxcd/source-controller/pull/1812)
[#1800](https://github.com/fluxcd/source-controller/pull/1800)
[#1810](https://github.com/fluxcd/source-controller/pull/1810)
[#1806](https://github.com/fluxcd/source-controller/pull/1806)
[#1782](https://github.com/fluxcd/source-controller/pull/1782)
[#1783](https://github.com/fluxcd/source-controller/pull/1783)
[#1775](https://github.com/fluxcd/source-controller/pull/1775)
[#1728](https://github.com/fluxcd/source-controller/pull/1728)
[#1722](https://github.com/fluxcd/source-controller/pull/1722)
## 1.5.0
**Release date:** 2025-02-13
This minor release comes with various bug fixes and improvements.
### GitRepository
The GitRepository API now supports authenticating through GitHub App
for GitHub repositories. See
[docs](https://fluxcd.io/flux/components/source/gitrepositories/#github).
In addition, the Kubernetes dependencies have been updated to v1.32.1, Helm has
been updated to v3.17.0 and various other controller dependencies have been
updated to their latest version.
Fixes:
- Remove deprecated object metrics from controllers
[#1686](https://github.com/fluxcd/source-controller/pull/1686)
Improvements:
- [RFC-007] Implement GitHub app authentication for git repositories.
[#1647](https://github.com/fluxcd/source-controller/pull/1647)
- Various dependency updates
[#1684](https://github.com/fluxcd/source-controller/pull/1684)
[#1689](https://github.com/fluxcd/source-controller/pull/1689)
[#1693](https://github.com/fluxcd/source-controller/pull/1693)
[#1705](https://github.com/fluxcd/source-controller/pull/1705)
[#1708](https://github.com/fluxcd/source-controller/pull/1708)
[#1709](https://github.com/fluxcd/source-controller/pull/1709)
[#1713](https://github.com/fluxcd/source-controller/pull/1713)
[#1716](https://github.com/fluxcd/source-controller/pull/1716)
## 1.4.1
**Release date:** 2024-09-26
This patch release comes with a fix to the `GitRepository` API to keep it
backwards compatible by removing the default value for `.spec.provider` field
when not set in the API. The controller will internally consider an empty value
for the provider as the `generic` provider.
Fix:
- GitRepo: Remove provider default value from API
[#1626](https://github.com/fluxcd/source-controller/pull/1626)
## 1.4.0
**Release date:** 2024-09-25
This minor release promotes the Bucket API to GA, and comes with new features,
improvements and bug fixes.
### Bucket
The `Bucket` API has been promoted from `v1beta2` to `v1` (GA).
The `v1` API is backwards compatible with `v1beta2`.
Bucket API now supports proxy through the field `.spec.proxySecretRef` and custom TLS client certificate and CA through the field `.spec.certSecretRef`.
Bucket API now also supports specifying a custom STS configuration through the field `.spec.sts`. This is currently only supported for the providers `generic` and `aws`. When specifying a custom STS configuration one must specify which STS provider to use. For the `generic` bucket provider we support the `ldap` STS provider, and for the `aws` bucket provider we support the `aws` STS provider. For the `aws` STS provider, one may use the default main STS endpoint, or the regional STS endpoints, or even an interface endpoint.
### OCIRepository
OCIRepository API now supports proxy through the field `.spec.proxySecretRef`.
**Warning**: Proxy is not supported for cosign keyless verification.
### GitRepository
GitRepository API now supports OIDC authentication for Azure DevOps repositories through the field `.spec.provider` using the value `azure`. See the docs for details [here](https://fluxcd.io/flux/components/source/gitrepositories/#provider).
In addition, the Kubernetes dependencies have been updated to v1.31.1, Helm has
been updated to v3.16.1 and various other controller dependencies have been
updated to their latest version. The controller is now built with Go 1.23.
Fixes:
- helm: Use the default transport pool to preserve proxy settings
[#1490](https://github.com/fluxcd/source-controller/pull/1490)
- Fix incorrect use of format strings with the conditions package.
[#1529](https://github.com/fluxcd/source-controller/pull/1529)
- Fix HelmChart local dependency resolution for name-based path
[#1539](https://github.com/fluxcd/source-controller/pull/1539)
- Fix Helm index validation for Artifactory
[#1516](https://github.com/fluxcd/source-controller/pull/1516)
Improvements:
- Promote Bucket API to v1
[#1592](https://github.com/fluxcd/source-controller/pull/1592)
- Add .spec.certSecretRef to Bucket API
[#1475](https://github.com/fluxcd/source-controller/pull/1475)
- Run ARM64 tests on GitHub runners
[#1512](https://github.com/fluxcd/source-controller/pull/1512)
- Add support for .spec.proxySecretRef for generic provider of Bucket API
[#1500](https://github.com/fluxcd/source-controller/pull/1500)
- Improve invalid proxy error message for Bucket API
[#1550](https://github.com/fluxcd/source-controller/pull/1550)
- Add support for AWS STS endpoint in the Bucket API
[#1552](https://github.com/fluxcd/source-controller/pull/1552)
- Add proxy support for GCS buckets
[#1565](https://github.com/fluxcd/source-controller/pull/1565)
- azure-blob: Fix VisitObjects() in integration test
[#1574](https://github.com/fluxcd/source-controller/pull/1574)
- Add proxy support for Azure buckets
[#1567](https://github.com/fluxcd/source-controller/pull/1567)
- Add proxy support for AWS S3 buckets
[#1568](https://github.com/fluxcd/source-controller/pull/1568)
- Add proxy support for OCIRepository API
[#1536](https://github.com/fluxcd/source-controller/pull/1536)
- Add LDAP provider for Bucket STS API
[#1585](https://github.com/fluxcd/source-controller/pull/1585)
- Introduce Bucket provider constants with the common part as a prefix
[#1589](https://github.com/fluxcd/source-controller/pull/1589)
- OCIRepository: Configure proxy for OIDC auth
[#1607](https://github.com/fluxcd/source-controller/pull/1607)
- [RFC-0007] Enable Azure OIDC for Azure DevOps repositories
[#1591](https://github.com/fluxcd/source-controller/pull/1591)
- Build with Go 1.23
[#1582](https://github.com/fluxcd/source-controller/pull/1582)
- Various dependency updates
[#1507](https://github.com/fluxcd/source-controller/pull/1507)
[#1576](https://github.com/fluxcd/source-controller/pull/1576)
[#1578](https://github.com/fluxcd/source-controller/pull/1578)
[#1579](https://github.com/fluxcd/source-controller/pull/1579)
[#1583](https://github.com/fluxcd/source-controller/pull/1583)
[#1588](https://github.com/fluxcd/source-controller/pull/1588)
[#1603](https://github.com/fluxcd/source-controller/pull/1603)
[#1610](https://github.com/fluxcd/source-controller/pull/1610)
[#1614](https://github.com/fluxcd/source-controller/pull/1614)
[#1618](https://github.com/fluxcd/source-controller/pull/1618)
## 1.3.0
**Release date:** 2024-05-03
This minor release promotes the Helm APIs to GA, and comes with new features,
improvements and bug fixes.
### HelmRepository
The `HelmRepository` API has been promoted from `v1beta2` to `v1` (GA).
The `v1` API is backwards compatible with `v1beta2`.
For `HelmRepository` of type `oci`, the `.spec.insecure` field allows connecting
over HTTP to an insecure non-TLS container registry.
To upgrade from `v1beta2`, after deploying the new CRD and controller,
set `apiVersion: source.toolkit.fluxcd.io/v1` in the YAML files that
contain `HelmRepository` definitions.
Bumping the API version in manifests can be done gradually.
It is advised not to delay this procedure as the beta versions will be removed after 6 months.
### HelmChart
The `HelmChart` API have been promoted from `v1beta2` to `v1` (GA).
The `v1` API is backwards compatible with `v1beta2`, with the exception
of the removal of the deprecated field `.spec.valuesFile` which was replaced with `spec.valuesFiles`.
The `HelmChart` API was extended with support for
[Notation signature verification](https://github.com/fluxcd/source-controller/blob/release/v1.3.x/docs/spec/v1/helmcharts.md#notation)
of Helm OCI charts.
A new optional field `.spec.ignoreMissingValuesFiles` has been added,
which allows the controller to ignore missing values files rather than failing to reconcile the `HelmChart`.
### OCIRepository
The `OCIRepository` API was extended with support for
[Notation signature verification](https://github.com/fluxcd/source-controller/blob/release/v1.3.x/docs/spec/v1beta2/ocirepositories.md#notation)
of OCI artifacts.
A new optional field `.spec.ref.semverFilter` has been added,
which allows the controller to filter the tags based on regular expressions
before applying the semver range. This allows
[picking the latest release candidate](https://github.com/fluxcd/source-controller/blob/release/v1.3.x/docs/spec/v1beta2/ocirepositories.md#semverfilter-example)
instead of the latest stable release.
In addition, the controller has been updated to Kubernetes v1.30.0,
Helm v3.14.4, and various other dependencies to their latest version
to patch upstream CVEs.
Improvements:
- Promote Helm APIs to `source.toolkit.fluxcd.io/v1` (GA)
[#1428](https://github.com/fluxcd/source-controller/pull/1428)
- Add `.spec.ignoreMissingValuesFiles` to HelmChart API
[#1447](https://github.com/fluxcd/source-controller/pull/1447)
- Implement `.spec.ref.semverFilter` in OCIRepository API
[#1407](https://github.com/fluxcd/source-controller/pull/1407)
- Helm: Allow insecure registry login
[#1412](https://github.com/fluxcd/source-controller/pull/1442)
- Add support for Notation verification to HelmChart and OCIRepository
[#1075](https://github.com/fluxcd/source-controller/pull/1075)
- Various dependency updates
[#1442](https://github.com/fluxcd/source-controller/pull/1442)
[#1450](https://github.com/fluxcd/source-controller/pull/1450)
[#1469](https://github.com/fluxcd/source-controller/pull/1469)
[#1378](https://github.com/fluxcd/source-controller/pull/1378)
Fixes:
- Bind cached helm index to the maximum index size
[#1457](https://github.com/fluxcd/source-controller/pull/1457)
- Remove `genclient:Namespaced` tag
[#1386](https://github.com/fluxcd/source-controller/pull/1386)
## 1.2.5
**Release date:** 2024-04-04
This patch release comes with improvements to the `HelmChart` name validation
and adds logging sanitization of connection error messages for `Bucket` sources.
Fixes:
- Improve chart name validation
[#1377](https://github.com/fluxcd/source-controller/pull/1377)
- Sanitize URLs for bucket fetch error messages
[#1430](https://github.com/fluxcd/source-controller/pull/1430)
Improvements:
- Update controller-gen to v0.14.0
[#1399](https://github.com/fluxcd/source-controller/pull/1399)
## 1.2.4
**Release date:** 2024-02-01
This patch release updates the Kubernetes dependencies to v1.28.6 and various
other dependencies to their latest version to patch upstream CVEs.
Improvements:
- Various dependency updates
[#1362](https://github.com/fluxcd/source-controller/pull/1362)
[#1357](https://github.com/fluxcd/source-controller/pull/1357)
[#1353](https://github.com/fluxcd/source-controller/pull/1353)
[#1347](https://github.com/fluxcd/source-controller/pull/1347)
[#1343](https://github.com/fluxcd/source-controller/pull/1343)
[#1340](https://github.com/fluxcd/source-controller/pull/1340)
[#1338](https://github.com/fluxcd/source-controller/pull/1338)
[#1336](https://github.com/fluxcd/source-controller/pull/1336)
[#1334](https://github.com/fluxcd/source-controller/pull/1334)
## 1.2.3
**Release date:** 2023-12-14
This patch release updates the controller's Helm dependency to v3.13.3.
Improvements:
- Update Helm to v3.13.3
[#1325](https://github.com/fluxcd/source-controller/pull/1325)
- helmrepo: Remove migration log/event
[#1324](https://github.com/fluxcd/source-controller/pull/1324)
## 1.2.2
**Release date:** 2023-12-11
This patch release addresses an issue with AWS ECR authentication introduced in
v1.2.0.
In addition, a variety of dependencies have been updated. Including an update
of the container base image to Alpine v3.19.
Fixes:
- Address issue with authenticating towards AWS ECR
[#1318](https://github.com/fluxcd/source-controller/pull/1318)
[#1321](https://github.com/fluxcd/source-controller/pull/1318)
Improvements:
- Update dependencies
[#1314](https://github.com/fluxcd/source-controller/pull/1314)
[#1318](https://github.com/fluxcd/source-controller/pull/1318)
[#1321](https://github.com/fluxcd/source-controller/pull/1321)
- build: update Alpine to 3.19
[#1316](https://github.com/fluxcd/source-controller/pull/1316)
## 1.2.1
**Release date:** 2023-12-08
This patch release ensures the controller is built with the latest Go `1.21.x`
release, to mitigate multiple security vulnerabilities which were published
shortly after the release of v1.2.0.
In addition, a small number of dependencies have been updated to their latest
version.
Improvements:
- Update dependencies
[#1309](https://github.com/fluxcd/source-controller/pull/1309)
## 1.2.0
**Release date:** 2023-12-05

View File

@ -24,7 +24,7 @@ If any of the above dependencies are not present on your system, the first invoc
## How to run the test suite
Prerequisites:
* Go >= 1.21
* Go >= 1.24
You can run the test suite by simply doing
@ -58,7 +58,7 @@ make run
### Building the container image
Set the name of the container image to be created from the source code. This will be used
Set the name of the container image to be created from the source code. This will be used
when building, pushing and referring to the image on YAML files:
```sh
@ -79,7 +79,7 @@ make docker-push
```
Alternatively, the three steps above can be done in a single line:
```sh
IMG=registry-path/source-controller TAG=latest BUILD_ARGS=--push \
make docker-build
@ -128,7 +128,8 @@ Create a `.vscode/launch.json` file:
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go"
"program": "${workspaceFolder}/main.go",
"args": ["--storage-adv-addr=:0", "--storage-path=${workspaceFolder}/bin/data"]
}
]
}

View File

@ -1,30 +1,16 @@
ARG BASE_VARIANT=alpine
ARG GO_VERSION=1.21
ARG XX_VERSION=1.3.0
ARG GO_VERSION=1.24
ARG XX_VERSION=1.6.1
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-${BASE_VARIANT} as gostable
FROM gostable AS go-linux
# Build-base consists of build platform dependencies and xx.
# These will be used at current arch to yield execute the cross compilations.
FROM go-${TARGETOS} AS build-base
RUN apk add --no-cache clang lld
# Docker buildkit multi-arch build requires golang alpine
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS builder
# Copy the build utilities.
COPY --from=xx / /
# build-go-mod can still be cached at build platform architecture.
FROM build-base as build
ARG TARGETPLATFORM
# Some dependencies have to installed
# for the target platform: https://github.com/tonistiigi/xx#go--cgo
RUN xx-apk add musl-dev gcc clang lld
# Configure workspace
WORKDIR /workspace
@ -46,28 +32,17 @@ COPY internal/ internal/
ARG TARGETPLATFORM
ARG TARGETARCH
# Reasons why CGO is in use:
# - The SHA1 implementation (sha1cd) used by go-git depends on CGO for
# performance reasons. See: https://github.com/pjbgf/sha1cd/issues/15
ENV CGO_ENABLED=1
# build without specifing the arch
ENV CGO_ENABLED=0
RUN xx-go build -trimpath -a -o source-controller main.go
RUN export CGO_LDFLAGS="-static -fuse-ld=lld" && \
xx-go build \
-ldflags "-s -w" \
-tags 'netgo,osusergo,static_build' \
-o /source-controller -trimpath main.go;
# Ensure that the binary was cross-compiled correctly to the target platform.
RUN xx-verify --static /source-controller
FROM alpine:3.18
FROM alpine:3.21
ARG TARGETPLATFORM
RUN apk --no-cache add ca-certificates \
&& update-ca-certificates
# Copy over binary from build
COPY --from=build /source-controller /usr/local/bin/
COPY --from=builder /workspace/source-controller /usr/local/bin/
USER 65534:65534
ENTRYPOINT [ "source-controller" ]

View File

@ -6,3 +6,5 @@ In additional to those listed below, this project shares maintainers
from the main Flux v2 git repository, as listed in
https://github.com/fluxcd/flux2/blob/main/MAINTAINERS
Dipti Pai, Microsoft <diptipai@microsoft.com> (github: @dipti-pai, slack: Dipti Pai)

View File

@ -38,7 +38,7 @@ FUZZ_TIME ?= 1m
GO_STATIC_FLAGS=-ldflags "-s -w" -tags 'netgo,osusergo,static_build$(addprefix ,,$(GO_TAGS))'
# API (doc) generation utilities
CONTROLLER_GEN_VERSION ?= v0.12.0
CONTROLLER_GEN_VERSION ?= v0.16.1
GEN_API_REF_DOCS_VERSION ?= e327d0730470cbd61b06300f81c5fcf91c23c113
# If gobin not set, create one on ./build and add to path.
@ -61,9 +61,10 @@ ifeq ($(shell uname -s),Darwin)
ENVTEST_ARCH=amd64
endif
all: build
all: manager
build: ## Build manager binary
# Build manager binary
manager: generate fmt vet
go build $(GO_STATIC_FLAGS) -o $(BUILD_DIR)/bin/manager main.go
KUBEBUILDER_ASSETS?="$(shell $(ENVTEST) --arch=$(ENVTEST_ARCH) use -i $(ENVTEST_KUBERNETES_VERSION) --bin-dir=$(ENVTEST_ASSETS_DIR) -p path)"
@ -114,12 +115,11 @@ manifests: controller-gen ## Generate manifests, e.g. CRD, RBAC, etc.
cd api; $(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role paths="./..." output:crd:artifacts:config="../config/crd/bases"
api-docs: gen-crd-api-reference-docs ## Generate API reference documentation
$(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1beta2 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/v1beta2/source.md
$(GEN_CRD_API_REFERENCE_DOCS) -api-dir=./api/v1 -config=./hack/api-docs/config.json -template-dir=./hack/api-docs/template -out-file=./docs/api/v1/source.md
tidy: ## Run go mod tidy
cd api; rm -f go.sum; go mod tidy -compat=1.20
rm -f go.sum; go mod tidy -compat=1.21
cd api; rm -f go.sum; go mod tidy -compat=1.24
rm -f go.sum; go mod tidy -compat=1.24
fmt: ## Run go fmt against code
go fmt ./...
@ -188,7 +188,7 @@ TMP_DIR=$$(mktemp -d) ;\
cd $$TMP_DIR ;\
go mod init tmp ;\
echo "Downloading $(2)" ;\
env -i bash -c "GOBIN=$(GOBIN) PATH=$(PATH) GOPATH=$(shell go env GOPATH) GOCACHE=$(shell go env GOCACHE) go install $(2)" ;\
env -i bash -c "GOBIN=$(GOBIN) PATH=\"$(PATH)\" GOPATH=$(shell go env GOPATH) GOCACHE=$(shell go env GOCACHE) go install $(2)" ;\
rm -rf $$TMP_DIR ;\
}
endef

12
PROJECT
View File

@ -7,9 +7,15 @@ resources:
- group: source
kind: GitRepository
version: v1beta2
- group: source
kind: HelmRepository
version: v1
- group: source
kind: HelmRepository
version: v1beta2
- group: source
kind: HelmChart
version: v1
- group: source
kind: HelmChart
version: v1beta2
@ -31,4 +37,10 @@ resources:
- group: source
kind: OCIRepository
version: v1beta2
- group: source
kind: Bucket
version: v1
- group: source
kind: OCIRepository
version: v1
version: "2"

View File

@ -16,18 +16,18 @@ and is a core component of the [GitOps toolkit](https://fluxcd.io/flux/component
## APIs
| Kind | API Version |
|---------------------------------------------------------|------------------------------------|
| [GitRepository](docs/spec/v1/gitrepositories.md) | `source.toolkit.fluxcd.io/v1` |
| [OCIRepository](docs/spec/v1beta2/ocirepositories.md) | `source.toolkit.fluxcd.io/v1beta2` |
| [HelmRepository](docs/spec/v1beta2/helmrepositories.md) | `source.toolkit.fluxcd.io/v1beta2` |
| [HelmChart](docs/spec/v1beta2/helmcharts.md) | `source.toolkit.fluxcd.io/v1beta2` |
| [Bucket](docs/spec/v1beta2/buckets.md) | `source.toolkit.fluxcd.io/v1beta2` |
| Kind | API Version |
|----------------------------------------------------|-------------------------------|
| [GitRepository](docs/spec/v1/gitrepositories.md) | `source.toolkit.fluxcd.io/v1` |
| [OCIRepository](docs/spec/v1/ocirepositories.md) | `source.toolkit.fluxcd.io/v1` |
| [HelmRepository](docs/spec/v1/helmrepositories.md) | `source.toolkit.fluxcd.io/v1` |
| [HelmChart](docs/spec/v1/helmcharts.md) | `source.toolkit.fluxcd.io/v1` |
| [Bucket](docs/spec/v1/buckets.md) | `source.toolkit.fluxcd.io/v1` |
## Features
* authenticates to sources (SSH, user/password, API token, Workload Identity)
* validates source authenticity (PGP, Cosign)
* validates source authenticity (PGP, Cosign, Notation)
* detects source changes based on update policies (semver)
* fetches resources on-demand and on-a-schedule
* packages the fetched resources into a well-known format (tar.gz, yaml)

View File

@ -1,32 +1,35 @@
module github.com/fluxcd/source-controller/api
go 1.20
go 1.24.0
require (
github.com/fluxcd/pkg/apis/acl v0.1.0
github.com/fluxcd/pkg/apis/meta v1.2.0
k8s.io/apimachinery v0.28.4
sigs.k8s.io/controller-runtime v0.16.3
github.com/fluxcd/pkg/apis/acl v0.7.0
github.com/fluxcd/pkg/apis/meta v1.12.0
k8s.io/apimachinery v0.33.0
sigs.k8s.io/controller-runtime v0.21.0
)
// Fix CVE-2022-28948
replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1
require (
github.com/go-logr/logr v1.2.4 // indirect
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/text v0.13.0 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/text v0.25.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

View File

@ -2,27 +2,31 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fluxcd/pkg/apis/acl v0.1.0 h1:EoAl377hDQYL3WqanWCdifauXqXbMyFuK82NnX6pH4Q=
github.com/fluxcd/pkg/apis/acl v0.1.0/go.mod h1:zfEZzz169Oap034EsDhmCAGgnWlcWmIObZjYMusoXS8=
github.com/fluxcd/pkg/apis/meta v1.2.0 h1:O766PzGAdMdQKybSflGL8oV0+GgCNIkdsxfalRyzeO8=
github.com/fluxcd/pkg/apis/meta v1.2.0/go.mod h1:fU/Az9AoVyIxC0oI4ihG0NVMNnvrcCzdEym3wxjIQsc=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/fluxcd/pkg/apis/acl v0.7.0 h1:dMhZJH+g6ZRPjs4zVOAN9vHBd1DcavFgcIFkg5ooOE0=
github.com/fluxcd/pkg/apis/acl v0.7.0/go.mod h1:uv7pXXR/gydiX4MUwlQa7vS8JONEDztynnjTvY3JxKQ=
github.com/fluxcd/pkg/apis/meta v1.12.0 h1:XW15TKZieC2b7MN8VS85stqZJOx+/b8jATQ/xTUhVYg=
github.com/fluxcd/pkg/apis/meta v1.12.0/go.mod h1:+son1Va60x2eiDcTwd7lcctbI6C+K3gM7R+ULmEq1SI=
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
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=
@ -32,15 +36,24 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -52,24 +65,26 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
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.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -79,21 +94,24 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM=
k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8=
k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk=
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4=
sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU=
k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM=
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ=
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro=
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

271
api/v1/bucket_types.go Normal file
View File

@ -0,0 +1,271 @@
/*
Copyright 2024 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 v1
import (
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fluxcd/pkg/apis/meta"
)
const (
// BucketKind is the string representation of a Bucket.
BucketKind = "Bucket"
)
const (
// BucketProviderGeneric for any S3 API compatible storage Bucket.
BucketProviderGeneric string = "generic"
// BucketProviderAmazon for an AWS S3 object storage Bucket.
// Provides support for retrieving credentials from the AWS EC2 service.
BucketProviderAmazon string = "aws"
// BucketProviderGoogle for a Google Cloud Storage Bucket.
// Provides support for authentication using a workload identity.
BucketProviderGoogle string = "gcp"
// BucketProviderAzure for an Azure Blob Storage Bucket.
// Provides support for authentication using a Service Principal,
// Managed Identity or Shared Key.
BucketProviderAzure string = "azure"
)
// BucketSpec specifies the required configuration to produce an Artifact for
// an object storage bucket.
// +kubebuilder:validation:XValidation:rule="self.provider == 'aws' || self.provider == 'generic' || !has(self.sts)", message="STS configuration is only supported for the 'aws' and 'generic' Bucket providers"
// +kubebuilder:validation:XValidation:rule="self.provider != 'aws' || !has(self.sts) || self.sts.provider == 'aws'", message="'aws' is the only supported STS provider for the 'aws' Bucket provider"
// +kubebuilder:validation:XValidation:rule="self.provider != 'generic' || !has(self.sts) || self.sts.provider == 'ldap'", message="'ldap' is the only supported STS provider for the 'generic' Bucket provider"
// +kubebuilder:validation:XValidation:rule="!has(self.sts) || self.sts.provider != 'aws' || !has(self.sts.secretRef)", message="spec.sts.secretRef is not required for the 'aws' STS provider"
// +kubebuilder:validation:XValidation:rule="!has(self.sts) || self.sts.provider != 'aws' || !has(self.sts.certSecretRef)", message="spec.sts.certSecretRef is not required for the 'aws' STS provider"
type BucketSpec struct {
// Provider of the object storage bucket.
// Defaults to 'generic', which expects an S3 (API) compatible object
// storage.
// +kubebuilder:validation:Enum=generic;aws;gcp;azure
// +kubebuilder:default:=generic
// +optional
Provider string `json:"provider,omitempty"`
// BucketName is the name of the object storage bucket.
// +required
BucketName string `json:"bucketName"`
// Endpoint is the object storage address the BucketName is located at.
// +required
Endpoint string `json:"endpoint"`
// STS specifies the required configuration to use a Security Token
// Service for fetching temporary credentials to authenticate in a
// Bucket provider.
//
// This field is only supported for the `aws` and `generic` providers.
// +optional
STS *BucketSTSSpec `json:"sts,omitempty"`
// Insecure allows connecting to a non-TLS HTTP Endpoint.
// +optional
Insecure bool `json:"insecure,omitempty"`
// Region of the Endpoint where the BucketName is located in.
// +optional
Region string `json:"region,omitempty"`
// Prefix to use for server-side filtering of files in the Bucket.
// +optional
Prefix string `json:"prefix,omitempty"`
// SecretRef specifies the Secret containing authentication credentials
// for the Bucket.
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
// CertSecretRef can be given the name of a Secret containing
// either or both of
//
// - a PEM-encoded client certificate (`tls.crt`) and private
// key (`tls.key`);
// - a PEM-encoded CA certificate (`ca.crt`)
//
// and whichever are supplied, will be used for connecting to the
// bucket. The client cert and key are useful if you are
// authenticating with a certificate; the CA cert is useful if
// you are using a self-signed server certificate. The Secret must
// be of type `Opaque` or `kubernetes.io/tls`.
//
// This field is only supported for the `generic` provider.
// +optional
CertSecretRef *meta.LocalObjectReference `json:"certSecretRef,omitempty"`
// ProxySecretRef specifies the Secret containing the proxy configuration
// to use while communicating with the Bucket server.
// +optional
ProxySecretRef *meta.LocalObjectReference `json:"proxySecretRef,omitempty"`
// Interval at which the Bucket Endpoint is checked for updates.
// This interval is approximate and may be subject to jitter to ensure
// efficient use of resources.
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
// +required
Interval metav1.Duration `json:"interval"`
// Timeout for fetch operations, defaults to 60s.
// +kubebuilder:default="60s"
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$"
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Ignore overrides the set of excluded patterns in the .sourceignore format
// (which is the same as .gitignore). If not provided, a default will be used,
// consult the documentation for your version to find out what those are.
// +optional
Ignore *string `json:"ignore,omitempty"`
// Suspend tells the controller to suspend the reconciliation of this
// Bucket.
// +optional
Suspend bool `json:"suspend,omitempty"`
}
// BucketSTSSpec specifies the required configuration to use a Security Token
// Service for fetching temporary credentials to authenticate in a Bucket
// provider.
type BucketSTSSpec struct {
// Provider of the Security Token Service.
// +kubebuilder:validation:Enum=aws;ldap
// +required
Provider string `json:"provider"`
// Endpoint is the HTTP/S endpoint of the Security Token Service from
// where temporary credentials will be fetched.
// +required
// +kubebuilder:validation:Pattern="^(http|https)://.*$"
Endpoint string `json:"endpoint"`
// SecretRef specifies the Secret containing authentication credentials
// for the STS endpoint. This Secret must contain the fields `username`
// and `password` and is supported only for the `ldap` provider.
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
// CertSecretRef can be given the name of a Secret containing
// either or both of
//
// - a PEM-encoded client certificate (`tls.crt`) and private
// key (`tls.key`);
// - a PEM-encoded CA certificate (`ca.crt`)
//
// and whichever are supplied, will be used for connecting to the
// STS endpoint. The client cert and key are useful if you are
// authenticating with a certificate; the CA cert is useful if
// you are using a self-signed server certificate. The Secret must
// be of type `Opaque` or `kubernetes.io/tls`.
//
// This field is only supported for the `ldap` provider.
// +optional
CertSecretRef *meta.LocalObjectReference `json:"certSecretRef,omitempty"`
}
// BucketStatus records the observed state of a Bucket.
type BucketStatus struct {
// ObservedGeneration is the last observed generation of the Bucket object.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
// Conditions holds the conditions for the Bucket.
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
// URL is the dynamic fetch link for the latest Artifact.
// It is provided on a "best effort" basis, and using the precise
// BucketStatus.Artifact data is recommended.
// +optional
URL string `json:"url,omitempty"`
// Artifact represents the last successful Bucket reconciliation.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
// ObservedIgnore is the observed exclusion patterns used for constructing
// the source artifact.
// +optional
ObservedIgnore *string `json:"observedIgnore,omitempty"`
meta.ReconcileRequestStatus `json:",inline"`
}
const (
// BucketOperationSucceededReason signals that the Bucket listing and fetch
// operations succeeded.
BucketOperationSucceededReason string = "BucketOperationSucceeded"
// BucketOperationFailedReason signals that the Bucket listing or fetch
// operations failed.
BucketOperationFailedReason string = "BucketOperationFailed"
)
// GetConditions returns the status conditions of the object.
func (in *Bucket) GetConditions() []metav1.Condition {
return in.Status.Conditions
}
// SetConditions sets the status conditions on the object.
func (in *Bucket) SetConditions(conditions []metav1.Condition) {
in.Status.Conditions = conditions
}
// GetRequeueAfter returns the duration after which the source must be reconciled again.
func (in *Bucket) GetRequeueAfter() time.Duration {
return in.Spec.Interval.Duration
}
// GetArtifact returns the latest artifact from the source if present in the status sub-resource.
func (in *Bucket) GetArtifact() *Artifact {
return in.Status.Artifact
}
// +genclient
// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Endpoint",type=string,JSONPath=`.spec.endpoint`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
// Bucket is the Schema for the buckets API.
type Bucket struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec BucketSpec `json:"spec,omitempty"`
// +kubebuilder:default={"observedGeneration":-1}
Status BucketStatus `json:"status,omitempty"`
}
// BucketList contains a list of Bucket objects.
// +kubebuilder:object:root=true
type BucketList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Bucket `json:"items"`
}
func init() {
SchemeBuilder.Register(&Bucket{}, &BucketList{})
}

View File

@ -108,4 +108,11 @@ const (
// PatchOperationFailedReason signals a failure in patching a kubernetes API
// object.
PatchOperationFailedReason string = "PatchOperationFailed"
// InvalidSTSConfigurationReason signals that the STS configurtion is invalid.
InvalidSTSConfigurationReason string = "InvalidSTSConfiguration"
// InvalidProviderConfigurationReason signals that the provider
// configuration is invalid.
InvalidProviderConfigurationReason string = "InvalidProviderConfiguration"
)

View File

@ -27,6 +27,18 @@ import (
const (
// GitRepositoryKind is the string representation of a GitRepository.
GitRepositoryKind = "GitRepository"
// GitProviderGeneric provides support for authentication using
// credentials specified in secretRef.
GitProviderGeneric string = "generic"
// GitProviderAzure provides support for authentication to azure
// repositories using Managed Identity.
GitProviderAzure string = "azure"
// GitProviderGitHub provides support for authentication to git
// repositories using GitHub App authentication
GitProviderGitHub string = "github"
)
const (
@ -80,6 +92,12 @@ type GitRepositorySpec struct {
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
// Provider used for authentication, can be 'azure', 'github', 'generic'.
// When not specified, defaults to 'generic'.
// +kubebuilder:validation:Enum=generic;azure;github
// +optional
Provider string `json:"provider,omitempty"`
// Interval at which the GitRepository URL is checked for updates.
// This interval is approximate and may be subject to jitter to ensure
// efficient use of resources.
@ -130,6 +148,12 @@ type GitRepositorySpec struct {
// should be included in the Artifact produced for this GitRepository.
// +optional
Include []GitRepositoryInclude `json:"include,omitempty"`
// SparseCheckout specifies a list of directories to checkout when cloning
// the repository. If specified, only these directories are included in the
// Artifact produced for this GitRepository.
// +optional
SparseCheckout []string `json:"sparseCheckout,omitempty"`
}
// GitRepositoryInclude specifies a local reference to a GitRepository which
@ -248,6 +272,11 @@ type GitRepositoryStatus struct {
// +optional
ObservedInclude []GitRepositoryInclude `json:"observedInclude,omitempty"`
// ObservedSparseCheckout is the observed list of directories used to
// produce the current Artifact.
// +optional
ObservedSparseCheckout []string `json:"observedSparseCheckout,omitempty"`
// SourceVerificationMode is the last used verification mode indicating
// which Git object(s) have been verified.
// +optional
@ -288,6 +317,14 @@ func (in *GitRepository) GetArtifact() *Artifact {
return in.Status.Artifact
}
// GetProvider returns the Git authentication provider.
func (v *GitRepository) GetProvider() string {
if v.Spec.Provider == "" {
return GitProviderGeneric
}
return v.Spec.Provider
}
// GetMode returns the declared GitVerificationMode, or a ModeGitHEAD default.
func (v *GitRepositoryVerification) GetMode() GitVerificationMode {
if v.Mode.Valid() {
@ -309,7 +346,6 @@ func (v *GitRepositoryVerification) VerifyTag() bool {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=gitrepo

227
api/v1/helmchart_types.go Normal file
View File

@ -0,0 +1,227 @@
/*
Copyright 2024 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 v1
import (
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fluxcd/pkg/apis/meta"
)
// HelmChartKind is the string representation of a HelmChart.
const HelmChartKind = "HelmChart"
// HelmChartSpec specifies the desired state of a Helm chart.
type HelmChartSpec struct {
// Chart is the name or path the Helm chart is available at in the
// SourceRef.
// +required
Chart string `json:"chart"`
// Version is the chart version semver expression, ignored for charts from
// GitRepository and Bucket sources. Defaults to latest when omitted.
// +kubebuilder:default:=*
// +optional
Version string `json:"version,omitempty"`
// SourceRef is the reference to the Source the chart is available at.
// +required
SourceRef LocalHelmChartSourceReference `json:"sourceRef"`
// Interval at which the HelmChart SourceRef is checked for updates.
// This interval is approximate and may be subject to jitter to ensure
// efficient use of resources.
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
// +required
Interval metav1.Duration `json:"interval"`
// ReconcileStrategy determines what enables the creation of a new artifact.
// Valid values are ('ChartVersion', 'Revision').
// See the documentation of the values for an explanation on their behavior.
// Defaults to ChartVersion when omitted.
// +kubebuilder:validation:Enum=ChartVersion;Revision
// +kubebuilder:default:=ChartVersion
// +optional
ReconcileStrategy string `json:"reconcileStrategy,omitempty"`
// ValuesFiles is an alternative list of values files to use as the chart
// values (values.yaml is not included by default), expected to be a
// relative path in the SourceRef.
// Values files are merged in the order of this list with the last file
// overriding the first. Ignored when omitted.
// +optional
ValuesFiles []string `json:"valuesFiles,omitempty"`
// IgnoreMissingValuesFiles controls whether to silently ignore missing values
// files rather than failing.
// +optional
IgnoreMissingValuesFiles bool `json:"ignoreMissingValuesFiles,omitempty"`
// Suspend tells the controller to suspend the reconciliation of this
// source.
// +optional
Suspend bool `json:"suspend,omitempty"`
// Verify contains the secret name containing the trusted public keys
// used to verify the signature and specifies which provider to use to check
// whether OCI image is authentic.
// This field is only supported when using HelmRepository source with spec.type 'oci'.
// Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified.
// +optional
Verify *OCIRepositoryVerification `json:"verify,omitempty"`
}
const (
// ReconcileStrategyChartVersion reconciles when the version of the Helm chart is different.
ReconcileStrategyChartVersion string = "ChartVersion"
// ReconcileStrategyRevision reconciles when the Revision of the source is different.
ReconcileStrategyRevision string = "Revision"
)
// LocalHelmChartSourceReference contains enough information to let you locate
// the typed referenced object at namespace level.
type LocalHelmChartSourceReference struct {
// APIVersion of the referent.
// +optional
APIVersion string `json:"apiVersion,omitempty"`
// Kind of the referent, valid values are ('HelmRepository', 'GitRepository',
// 'Bucket').
// +kubebuilder:validation:Enum=HelmRepository;GitRepository;Bucket
// +required
Kind string `json:"kind"`
// Name of the referent.
// +required
Name string `json:"name"`
}
// HelmChartStatus records the observed state of the HelmChart.
type HelmChartStatus struct {
// ObservedGeneration is the last observed generation of the HelmChart
// object.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
// ObservedSourceArtifactRevision is the last observed Artifact.Revision
// of the HelmChartSpec.SourceRef.
// +optional
ObservedSourceArtifactRevision string `json:"observedSourceArtifactRevision,omitempty"`
// ObservedChartName is the last observed chart name as specified by the
// resolved chart reference.
// +optional
ObservedChartName string `json:"observedChartName,omitempty"`
// ObservedValuesFiles are the observed value files of the last successful
// reconciliation.
// It matches the chart in the last successfully reconciled artifact.
// +optional
ObservedValuesFiles []string `json:"observedValuesFiles,omitempty"`
// Conditions holds the conditions for the HelmChart.
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
// URL is the dynamic fetch link for the latest Artifact.
// It is provided on a "best effort" basis, and using the precise
// BucketStatus.Artifact data is recommended.
// +optional
URL string `json:"url,omitempty"`
// Artifact represents the output of the last successful reconciliation.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
meta.ReconcileRequestStatus `json:",inline"`
}
const (
// ChartPullSucceededReason signals that the pull of the Helm chart
// succeeded.
ChartPullSucceededReason string = "ChartPullSucceeded"
// ChartPackageSucceededReason signals that the package of the Helm
// chart succeeded.
ChartPackageSucceededReason string = "ChartPackageSucceeded"
)
// GetConditions returns the status conditions of the object.
func (in HelmChart) GetConditions() []metav1.Condition {
return in.Status.Conditions
}
// SetConditions sets the status conditions on the object.
func (in *HelmChart) SetConditions(conditions []metav1.Condition) {
in.Status.Conditions = conditions
}
// GetRequeueAfter returns the duration after which the source must be
// reconciled again.
func (in HelmChart) GetRequeueAfter() time.Duration {
return in.Spec.Interval.Duration
}
// GetArtifact returns the latest artifact from the source if present in the
// status sub-resource.
func (in *HelmChart) GetArtifact() *Artifact {
return in.Status.Artifact
}
// GetValuesFiles returns a merged list of HelmChartSpec.ValuesFiles.
func (in *HelmChart) GetValuesFiles() []string {
return in.Spec.ValuesFiles
}
// +genclient
// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=hc
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Chart",type=string,JSONPath=`.spec.chart`
// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.spec.version`
// +kubebuilder:printcolumn:name="Source Kind",type=string,JSONPath=`.spec.sourceRef.kind`
// +kubebuilder:printcolumn:name="Source Name",type=string,JSONPath=`.spec.sourceRef.name`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
// HelmChart is the Schema for the helmcharts API.
type HelmChart struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec HelmChartSpec `json:"spec,omitempty"`
// +kubebuilder:default={"observedGeneration":-1}
Status HelmChartStatus `json:"status,omitempty"`
}
// HelmChartList contains a list of HelmChart objects.
// +kubebuilder:object:root=true
type HelmChartList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []HelmChart `json:"items"`
}
func init() {
SchemeBuilder.Register(&HelmChart{}, &HelmChartList{})
}

View File

@ -0,0 +1,228 @@
/*
Copyright 2024 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 v1
import (
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fluxcd/pkg/apis/acl"
"github.com/fluxcd/pkg/apis/meta"
)
const (
// HelmRepositoryKind is the string representation of a HelmRepository.
HelmRepositoryKind = "HelmRepository"
// HelmRepositoryURLIndexKey is the key used for indexing HelmRepository
// objects by their HelmRepositorySpec.URL.
HelmRepositoryURLIndexKey = ".metadata.helmRepositoryURL"
// HelmRepositoryTypeDefault is the default HelmRepository type.
// It is used when no type is specified and corresponds to a Helm repository.
HelmRepositoryTypeDefault = "default"
// HelmRepositoryTypeOCI is the type for an OCI repository.
HelmRepositoryTypeOCI = "oci"
)
// HelmRepositorySpec specifies the required configuration to produce an
// Artifact for a Helm repository index YAML.
type HelmRepositorySpec struct {
// URL of the Helm repository, a valid URL contains at least a protocol and
// host.
// +kubebuilder:validation:Pattern="^(http|https|oci)://.*$"
// +required
URL string `json:"url"`
// SecretRef specifies the Secret containing authentication credentials
// for the HelmRepository.
// For HTTP/S basic auth the secret must contain 'username' and 'password'
// fields.
// Support for TLS auth using the 'certFile' and 'keyFile', and/or 'caFile'
// keys is deprecated. Please use `.spec.certSecretRef` instead.
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
// CertSecretRef can be given the name of a Secret containing
// either or both of
//
// - a PEM-encoded client certificate (`tls.crt`) and private
// key (`tls.key`);
// - a PEM-encoded CA certificate (`ca.crt`)
//
// and whichever are supplied, will be used for connecting to the
// registry. The client cert and key are useful if you are
// authenticating with a certificate; the CA cert is useful if
// you are using a self-signed server certificate. The Secret must
// be of type `Opaque` or `kubernetes.io/tls`.
//
// It takes precedence over the values specified in the Secret referred
// to by `.spec.secretRef`.
// +optional
CertSecretRef *meta.LocalObjectReference `json:"certSecretRef,omitempty"`
// PassCredentials allows the credentials from the SecretRef to be passed
// on to a host that does not match the host as defined in URL.
// This may be required if the host of the advertised chart URLs in the
// index differ from the defined URL.
// Enabling this should be done with caution, as it can potentially result
// in credentials getting stolen in a MITM-attack.
// +optional
PassCredentials bool `json:"passCredentials,omitempty"`
// Interval at which the HelmRepository URL is checked for updates.
// This interval is approximate and may be subject to jitter to ensure
// efficient use of resources.
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
// +optional
Interval metav1.Duration `json:"interval,omitempty"`
// Insecure allows connecting to a non-TLS HTTP container registry.
// This field is only taken into account if the .spec.type field is set to 'oci'.
// +optional
Insecure bool `json:"insecure,omitempty"`
// Timeout is used for the index fetch operation for an HTTPS helm repository,
// and for remote OCI Repository operations like pulling for an OCI helm
// chart by the associated HelmChart.
// Its default value is 60s.
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$"
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Suspend tells the controller to suspend the reconciliation of this
// HelmRepository.
// +optional
Suspend bool `json:"suspend,omitempty"`
// AccessFrom specifies an Access Control List for allowing cross-namespace
// references to this object.
// NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092
// +optional
AccessFrom *acl.AccessFrom `json:"accessFrom,omitempty"`
// Type of the HelmRepository.
// When this field is set to "oci", the URL field value must be prefixed with "oci://".
// +kubebuilder:validation:Enum=default;oci
// +optional
Type string `json:"type,omitempty"`
// Provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'.
// This field is optional, and only taken into account if the .spec.type field is set to 'oci'.
// When not specified, defaults to 'generic'.
// +kubebuilder:validation:Enum=generic;aws;azure;gcp
// +kubebuilder:default:=generic
// +optional
Provider string `json:"provider,omitempty"`
}
// HelmRepositoryStatus records the observed state of the HelmRepository.
type HelmRepositoryStatus struct {
// ObservedGeneration is the last observed generation of the HelmRepository
// object.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
// Conditions holds the conditions for the HelmRepository.
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
// URL is the dynamic fetch link for the latest Artifact.
// It is provided on a "best effort" basis, and using the precise
// HelmRepositoryStatus.Artifact data is recommended.
// +optional
URL string `json:"url,omitempty"`
// Artifact represents the last successful HelmRepository reconciliation.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
meta.ReconcileRequestStatus `json:",inline"`
}
const (
// IndexationFailedReason signals that the HelmRepository index fetch
// failed.
IndexationFailedReason string = "IndexationFailed"
)
// GetConditions returns the status conditions of the object.
func (in HelmRepository) GetConditions() []metav1.Condition {
return in.Status.Conditions
}
// SetConditions sets the status conditions on the object.
func (in *HelmRepository) SetConditions(conditions []metav1.Condition) {
in.Status.Conditions = conditions
}
// GetRequeueAfter returns the duration after which the source must be
// reconciled again.
func (in HelmRepository) GetRequeueAfter() time.Duration {
if in.Spec.Interval.Duration != 0 {
return in.Spec.Interval.Duration
}
return time.Minute
}
// GetTimeout returns the timeout duration used for various operations related
// to this HelmRepository.
func (in HelmRepository) GetTimeout() time.Duration {
if in.Spec.Timeout != nil {
return in.Spec.Timeout.Duration
}
return time.Minute
}
// GetArtifact returns the latest artifact from the source if present in the
// status sub-resource.
func (in *HelmRepository) GetArtifact() *Artifact {
return in.Status.Artifact
}
// +genclient
// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=helmrepo
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="URL",type=string,JSONPath=`.spec.url`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
// HelmRepository is the Schema for the helmrepositories API.
type HelmRepository struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec HelmRepositorySpec `json:"spec,omitempty"`
// +kubebuilder:default={"observedGeneration":-1}
Status HelmRepositoryStatus `json:"status,omitempty"`
}
// HelmRepositoryList contains a list of HelmRepository objects.
// +kubebuilder:object:root=true
type HelmRepositoryList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []HelmRepository `json:"items"`
}
func init() {
SchemeBuilder.Register(&HelmRepository{}, &HelmRepositoryList{})
}

View File

@ -0,0 +1,296 @@
/*
Copyright 2025 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 v1
import (
"time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fluxcd/pkg/apis/meta"
)
const (
// OCIRepositoryKind is the string representation of an OCIRepository.
OCIRepositoryKind = "OCIRepository"
// OCIRepositoryPrefix is the prefix used for OCIRepository URLs.
OCIRepositoryPrefix = "oci://"
// GenericOCIProvider provides support for authentication using static credentials
// for any OCI compatible API such as Docker Registry, GitHub Container Registry,
// Docker Hub, Quay, etc.
GenericOCIProvider string = "generic"
// AmazonOCIProvider provides support for OCI authentication using AWS IRSA.
AmazonOCIProvider string = "aws"
// GoogleOCIProvider provides support for OCI authentication using GCP workload identity.
GoogleOCIProvider string = "gcp"
// AzureOCIProvider provides support for OCI authentication using a Azure Service Principal,
// Managed Identity or Shared Key.
AzureOCIProvider string = "azure"
// OCILayerExtract defines the operation type for extracting the content from an OCI artifact layer.
OCILayerExtract = "extract"
// OCILayerCopy defines the operation type for copying the content from an OCI artifact layer.
OCILayerCopy = "copy"
)
// OCIRepositorySpec defines the desired state of OCIRepository
type OCIRepositorySpec struct {
// URL is a reference to an OCI artifact repository hosted
// on a remote container registry.
// +kubebuilder:validation:Pattern="^oci://.*$"
// +required
URL string `json:"url"`
// The OCI reference to pull and monitor for changes,
// defaults to the latest tag.
// +optional
Reference *OCIRepositoryRef `json:"ref,omitempty"`
// LayerSelector specifies which layer should be extracted from the OCI artifact.
// When not specified, the first layer found in the artifact is selected.
// +optional
LayerSelector *OCILayerSelector `json:"layerSelector,omitempty"`
// The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'.
// When not specified, defaults to 'generic'.
// +kubebuilder:validation:Enum=generic;aws;azure;gcp
// +kubebuilder:default:=generic
// +optional
Provider string `json:"provider,omitempty"`
// SecretRef contains the secret name containing the registry login
// credentials to resolve image metadata.
// The secret must be of type kubernetes.io/dockerconfigjson.
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
// Verify contains the secret name containing the trusted public keys
// used to verify the signature and specifies which provider to use to check
// whether OCI image is authentic.
// +optional
Verify *OCIRepositoryVerification `json:"verify,omitempty"`
// ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate
// the image pull if the service account has attached pull secrets. For more information:
// https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account
// +optional
ServiceAccountName string `json:"serviceAccountName,omitempty"`
// CertSecretRef can be given the name of a Secret containing
// either or both of
//
// - a PEM-encoded client certificate (`tls.crt`) and private
// key (`tls.key`);
// - a PEM-encoded CA certificate (`ca.crt`)
//
// and whichever are supplied, will be used for connecting to the
// registry. The client cert and key are useful if you are
// authenticating with a certificate; the CA cert is useful if
// you are using a self-signed server certificate. The Secret must
// be of type `Opaque` or `kubernetes.io/tls`.
// +optional
CertSecretRef *meta.LocalObjectReference `json:"certSecretRef,omitempty"`
// ProxySecretRef specifies the Secret containing the proxy configuration
// to use while communicating with the container registry.
// +optional
ProxySecretRef *meta.LocalObjectReference `json:"proxySecretRef,omitempty"`
// Interval at which the OCIRepository URL is checked for updates.
// This interval is approximate and may be subject to jitter to ensure
// efficient use of resources.
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
// +required
Interval metav1.Duration `json:"interval"`
// The timeout for remote OCI Repository operations like pulling, defaults to 60s.
// +kubebuilder:default="60s"
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m))+$"
// +optional
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Ignore overrides the set of excluded patterns in the .sourceignore format
// (which is the same as .gitignore). If not provided, a default will be used,
// consult the documentation for your version to find out what those are.
// +optional
Ignore *string `json:"ignore,omitempty"`
// Insecure allows connecting to a non-TLS HTTP container registry.
// +optional
Insecure bool `json:"insecure,omitempty"`
// This flag tells the controller to suspend the reconciliation of this source.
// +optional
Suspend bool `json:"suspend,omitempty"`
}
// OCIRepositoryRef defines the image reference for the OCIRepository's URL
type OCIRepositoryRef struct {
// Digest is the image digest to pull, takes precedence over SemVer.
// The value should be in the format 'sha256:<HASH>'.
// +optional
Digest string `json:"digest,omitempty"`
// SemVer is the range of tags to pull selecting the latest within
// the range, takes precedence over Tag.
// +optional
SemVer string `json:"semver,omitempty"`
// SemverFilter is a regex pattern to filter the tags within the SemVer range.
// +optional
SemverFilter string `json:"semverFilter,omitempty"`
// Tag is the image tag to pull, defaults to latest.
// +optional
Tag string `json:"tag,omitempty"`
}
// OCILayerSelector specifies which layer should be extracted from an OCI Artifact
type OCILayerSelector struct {
// MediaType specifies the OCI media type of the layer
// which should be extracted from the OCI Artifact. The
// first layer matching this type is selected.
// +optional
MediaType string `json:"mediaType,omitempty"`
// Operation specifies how the selected layer should be processed.
// By default, the layer compressed content is extracted to storage.
// When the operation is set to 'copy', the layer compressed content
// is persisted to storage as it is.
// +kubebuilder:validation:Enum=extract;copy
// +optional
Operation string `json:"operation,omitempty"`
}
// OCIRepositoryStatus defines the observed state of OCIRepository
type OCIRepositoryStatus struct {
// ObservedGeneration is the last observed generation.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
// Conditions holds the conditions for the OCIRepository.
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
// URL is the download link for the artifact output of the last OCI Repository sync.
// +optional
URL string `json:"url,omitempty"`
// Artifact represents the output of the last successful OCI Repository sync.
// +optional
Artifact *Artifact `json:"artifact,omitempty"`
// ObservedIgnore is the observed exclusion patterns used for constructing
// the source artifact.
// +optional
ObservedIgnore *string `json:"observedIgnore,omitempty"`
// ObservedLayerSelector is the observed layer selector used for constructing
// the source artifact.
// +optional
ObservedLayerSelector *OCILayerSelector `json:"observedLayerSelector,omitempty"`
meta.ReconcileRequestStatus `json:",inline"`
}
const (
// OCIPullFailedReason signals that a pull operation failed.
OCIPullFailedReason string = "OCIArtifactPullFailed"
// OCILayerOperationFailedReason signals that an OCI layer operation failed.
OCILayerOperationFailedReason string = "OCIArtifactLayerOperationFailed"
)
// GetConditions returns the status conditions of the object.
func (in OCIRepository) GetConditions() []metav1.Condition {
return in.Status.Conditions
}
// SetConditions sets the status conditions on the object.
func (in *OCIRepository) SetConditions(conditions []metav1.Condition) {
in.Status.Conditions = conditions
}
// GetRequeueAfter returns the duration after which the OCIRepository must be
// reconciled again.
func (in OCIRepository) GetRequeueAfter() time.Duration {
return in.Spec.Interval.Duration
}
// GetArtifact returns the latest Artifact from the OCIRepository if present in
// the status sub-resource.
func (in *OCIRepository) GetArtifact() *Artifact {
return in.Status.Artifact
}
// GetLayerMediaType returns the media type layer selector if found in spec.
func (in *OCIRepository) GetLayerMediaType() string {
if in.Spec.LayerSelector == nil {
return ""
}
return in.Spec.LayerSelector.MediaType
}
// GetLayerOperation returns the layer selector operation (defaults to extract).
func (in *OCIRepository) GetLayerOperation() string {
if in.Spec.LayerSelector == nil || in.Spec.LayerSelector.Operation == "" {
return OCILayerExtract
}
return in.Spec.LayerSelector.Operation
}
// +genclient
// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=ocirepo
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="URL",type=string,JSONPath=`.spec.url`
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
// OCIRepository is the Schema for the ocirepositories API
type OCIRepository struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec OCIRepositorySpec `json:"spec,omitempty"`
// +kubebuilder:default={"observedGeneration":-1}
Status OCIRepositoryStatus `json:"status,omitempty"`
}
// OCIRepositoryList contains a list of OCIRepository
// +kubebuilder:object:root=true
type OCIRepositoryList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []OCIRepository `json:"items"`
}
func init() {
SchemeBuilder.Register(&OCIRepository{}, &OCIRepositoryList{})
}

View File

@ -0,0 +1,56 @@
/*
Copyright 2024 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 v1
import (
"github.com/fluxcd/pkg/apis/meta"
)
// OCIRepositoryVerification verifies the authenticity of an OCI Artifact
type OCIRepositoryVerification struct {
// Provider specifies the technology used to sign the OCI Artifact.
// +kubebuilder:validation:Enum=cosign;notation
// +kubebuilder:default:=cosign
Provider string `json:"provider"`
// SecretRef specifies the Kubernetes Secret containing the
// trusted public keys.
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
// MatchOIDCIdentity specifies the identity matching criteria to use
// while verifying an OCI artifact which was signed using Cosign keyless
// signing. The artifact's identity is deemed to be verified if any of the
// specified matchers match against the identity.
// +optional
MatchOIDCIdentity []OIDCIdentityMatch `json:"matchOIDCIdentity,omitempty"`
}
// OIDCIdentityMatch specifies options for verifying the certificate identity,
// i.e. the issuer and the subject of the certificate.
type OIDCIdentityMatch struct {
// Issuer specifies the regex pattern to match against to verify
// the OIDC issuer in the Fulcio certificate. The pattern must be a
// valid Go regular expression.
// +required
Issuer string `json:"issuer"`
// Subject specifies the regex pattern to match against to verify
// the identity subject in the Fulcio certificate. The pattern must
// be a valid Go regular expression.
// +required
Subject string `json:"subject"`
}

26
api/v1/sts_types.go Normal file
View File

@ -0,0 +1,26 @@
/*
Copyright 2024 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 v1
const (
// STSProviderAmazon represents the AWS provider for Security Token Service.
// Provides support for fetching temporary credentials from an AWS STS endpoint.
STSProviderAmazon string = "aws"
// STSProviderLDAP represents the LDAP provider for Security Token Service.
// Provides support for fetching temporary credentials from an LDAP endpoint.
STSProviderLDAP string = "ldap"
)

View File

@ -1,8 +1,7 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 2023 The Flux authors
Copyright 2024 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.
@ -22,6 +21,7 @@ limitations under the License.
package v1
import (
"github.com/fluxcd/pkg/apis/acl"
"github.com/fluxcd/pkg/apis/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@ -55,6 +55,169 @@ func (in *Artifact) DeepCopy() *Artifact {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Bucket) DeepCopyInto(out *Bucket) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Bucket.
func (in *Bucket) DeepCopy() *Bucket {
if in == nil {
return nil
}
out := new(Bucket)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Bucket) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BucketList) DeepCopyInto(out *BucketList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Bucket, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BucketList.
func (in *BucketList) DeepCopy() *BucketList {
if in == nil {
return nil
}
out := new(BucketList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *BucketList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BucketSTSSpec) DeepCopyInto(out *BucketSTSSpec) {
*out = *in
if in.SecretRef != nil {
in, out := &in.SecretRef, &out.SecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.CertSecretRef != nil {
in, out := &in.CertSecretRef, &out.CertSecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BucketSTSSpec.
func (in *BucketSTSSpec) DeepCopy() *BucketSTSSpec {
if in == nil {
return nil
}
out := new(BucketSTSSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BucketSpec) DeepCopyInto(out *BucketSpec) {
*out = *in
if in.STS != nil {
in, out := &in.STS, &out.STS
*out = new(BucketSTSSpec)
(*in).DeepCopyInto(*out)
}
if in.SecretRef != nil {
in, out := &in.SecretRef, &out.SecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.CertSecretRef != nil {
in, out := &in.CertSecretRef, &out.CertSecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.ProxySecretRef != nil {
in, out := &in.ProxySecretRef, &out.ProxySecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
out.Interval = in.Interval
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
*out = new(metav1.Duration)
**out = **in
}
if in.Ignore != nil {
in, out := &in.Ignore, &out.Ignore
*out = new(string)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BucketSpec.
func (in *BucketSpec) DeepCopy() *BucketSpec {
if in == nil {
return nil
}
out := new(BucketSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BucketStatus) DeepCopyInto(out *BucketStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(Artifact)
(*in).DeepCopyInto(*out)
}
if in.ObservedIgnore != nil {
in, out := &in.ObservedIgnore, &out.ObservedIgnore
*out = new(string)
**out = **in
}
out.ReconcileRequestStatus = in.ReconcileRequestStatus
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BucketStatus.
func (in *BucketStatus) DeepCopy() *BucketStatus {
if in == nil {
return nil
}
out := new(BucketStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GitRepository) DeepCopyInto(out *GitRepository) {
*out = *in
@ -184,6 +347,11 @@ func (in *GitRepositorySpec) DeepCopyInto(out *GitRepositorySpec) {
*out = make([]GitRepositoryInclude, len(*in))
copy(*out, *in)
}
if in.SparseCheckout != nil {
in, out := &in.SparseCheckout, &out.SparseCheckout
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitRepositorySpec.
@ -232,6 +400,11 @@ func (in *GitRepositoryStatus) DeepCopyInto(out *GitRepositoryStatus) {
*out = make([]GitRepositoryInclude, len(*in))
copy(*out, *in)
}
if in.ObservedSparseCheckout != nil {
in, out := &in.ObservedSparseCheckout, &out.ObservedSparseCheckout
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.SourceVerificationMode != nil {
in, out := &in.SourceVerificationMode, &out.SourceVerificationMode
*out = new(GitVerificationMode)
@ -265,3 +438,483 @@ func (in *GitRepositoryVerification) DeepCopy() *GitRepositoryVerification {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelmChart) DeepCopyInto(out *HelmChart) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChart.
func (in *HelmChart) DeepCopy() *HelmChart {
if in == nil {
return nil
}
out := new(HelmChart)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *HelmChart) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelmChartList) DeepCopyInto(out *HelmChartList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]HelmChart, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartList.
func (in *HelmChartList) DeepCopy() *HelmChartList {
if in == nil {
return nil
}
out := new(HelmChartList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *HelmChartList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelmChartSpec) DeepCopyInto(out *HelmChartSpec) {
*out = *in
out.SourceRef = in.SourceRef
out.Interval = in.Interval
if in.ValuesFiles != nil {
in, out := &in.ValuesFiles, &out.ValuesFiles
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Verify != nil {
in, out := &in.Verify, &out.Verify
*out = new(OCIRepositoryVerification)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartSpec.
func (in *HelmChartSpec) DeepCopy() *HelmChartSpec {
if in == nil {
return nil
}
out := new(HelmChartSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelmChartStatus) DeepCopyInto(out *HelmChartStatus) {
*out = *in
if in.ObservedValuesFiles != nil {
in, out := &in.ObservedValuesFiles, &out.ObservedValuesFiles
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(Artifact)
(*in).DeepCopyInto(*out)
}
out.ReconcileRequestStatus = in.ReconcileRequestStatus
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmChartStatus.
func (in *HelmChartStatus) DeepCopy() *HelmChartStatus {
if in == nil {
return nil
}
out := new(HelmChartStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelmRepository) DeepCopyInto(out *HelmRepository) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmRepository.
func (in *HelmRepository) DeepCopy() *HelmRepository {
if in == nil {
return nil
}
out := new(HelmRepository)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *HelmRepository) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelmRepositoryList) DeepCopyInto(out *HelmRepositoryList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]HelmRepository, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmRepositoryList.
func (in *HelmRepositoryList) DeepCopy() *HelmRepositoryList {
if in == nil {
return nil
}
out := new(HelmRepositoryList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *HelmRepositoryList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelmRepositorySpec) DeepCopyInto(out *HelmRepositorySpec) {
*out = *in
if in.SecretRef != nil {
in, out := &in.SecretRef, &out.SecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.CertSecretRef != nil {
in, out := &in.CertSecretRef, &out.CertSecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
out.Interval = in.Interval
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
*out = new(metav1.Duration)
**out = **in
}
if in.AccessFrom != nil {
in, out := &in.AccessFrom, &out.AccessFrom
*out = new(acl.AccessFrom)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmRepositorySpec.
func (in *HelmRepositorySpec) DeepCopy() *HelmRepositorySpec {
if in == nil {
return nil
}
out := new(HelmRepositorySpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelmRepositoryStatus) DeepCopyInto(out *HelmRepositoryStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(Artifact)
(*in).DeepCopyInto(*out)
}
out.ReconcileRequestStatus = in.ReconcileRequestStatus
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmRepositoryStatus.
func (in *HelmRepositoryStatus) DeepCopy() *HelmRepositoryStatus {
if in == nil {
return nil
}
out := new(HelmRepositoryStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *LocalHelmChartSourceReference) DeepCopyInto(out *LocalHelmChartSourceReference) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalHelmChartSourceReference.
func (in *LocalHelmChartSourceReference) DeepCopy() *LocalHelmChartSourceReference {
if in == nil {
return nil
}
out := new(LocalHelmChartSourceReference)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OCILayerSelector) DeepCopyInto(out *OCILayerSelector) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OCILayerSelector.
func (in *OCILayerSelector) DeepCopy() *OCILayerSelector {
if in == nil {
return nil
}
out := new(OCILayerSelector)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OCIRepository) DeepCopyInto(out *OCIRepository) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OCIRepository.
func (in *OCIRepository) DeepCopy() *OCIRepository {
if in == nil {
return nil
}
out := new(OCIRepository)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *OCIRepository) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OCIRepositoryList) DeepCopyInto(out *OCIRepositoryList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]OCIRepository, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OCIRepositoryList.
func (in *OCIRepositoryList) DeepCopy() *OCIRepositoryList {
if in == nil {
return nil
}
out := new(OCIRepositoryList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *OCIRepositoryList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OCIRepositoryRef) DeepCopyInto(out *OCIRepositoryRef) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OCIRepositoryRef.
func (in *OCIRepositoryRef) DeepCopy() *OCIRepositoryRef {
if in == nil {
return nil
}
out := new(OCIRepositoryRef)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OCIRepositorySpec) DeepCopyInto(out *OCIRepositorySpec) {
*out = *in
if in.Reference != nil {
in, out := &in.Reference, &out.Reference
*out = new(OCIRepositoryRef)
**out = **in
}
if in.LayerSelector != nil {
in, out := &in.LayerSelector, &out.LayerSelector
*out = new(OCILayerSelector)
**out = **in
}
if in.SecretRef != nil {
in, out := &in.SecretRef, &out.SecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.Verify != nil {
in, out := &in.Verify, &out.Verify
*out = new(OCIRepositoryVerification)
(*in).DeepCopyInto(*out)
}
if in.CertSecretRef != nil {
in, out := &in.CertSecretRef, &out.CertSecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.ProxySecretRef != nil {
in, out := &in.ProxySecretRef, &out.ProxySecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
out.Interval = in.Interval
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
*out = new(metav1.Duration)
**out = **in
}
if in.Ignore != nil {
in, out := &in.Ignore, &out.Ignore
*out = new(string)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OCIRepositorySpec.
func (in *OCIRepositorySpec) DeepCopy() *OCIRepositorySpec {
if in == nil {
return nil
}
out := new(OCIRepositorySpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OCIRepositoryStatus) DeepCopyInto(out *OCIRepositoryStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Artifact != nil {
in, out := &in.Artifact, &out.Artifact
*out = new(Artifact)
(*in).DeepCopyInto(*out)
}
if in.ObservedIgnore != nil {
in, out := &in.ObservedIgnore, &out.ObservedIgnore
*out = new(string)
**out = **in
}
if in.ObservedLayerSelector != nil {
in, out := &in.ObservedLayerSelector, &out.ObservedLayerSelector
*out = new(OCILayerSelector)
**out = **in
}
out.ReconcileRequestStatus = in.ReconcileRequestStatus
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OCIRepositoryStatus.
func (in *OCIRepositoryStatus) DeepCopy() *OCIRepositoryStatus {
if in == nil {
return nil
}
out := new(OCIRepositoryStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OCIRepositoryVerification) DeepCopyInto(out *OCIRepositoryVerification) {
*out = *in
if in.SecretRef != nil {
in, out := &in.SecretRef, &out.SecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.MatchOIDCIdentity != nil {
in, out := &in.MatchOIDCIdentity, &out.MatchOIDCIdentity
*out = make([]OIDCIdentityMatch, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OCIRepositoryVerification.
func (in *OCIRepositoryVerification) DeepCopy() *OCIRepositoryVerification {
if in == nil {
return nil
}
out := new(OCIRepositoryVerification)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OIDCIdentityMatch) DeepCopyInto(out *OIDCIdentityMatch) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCIdentityMatch.
func (in *OIDCIdentityMatch) DeepCopy() *OIDCIdentityMatch {
if in == nil {
return nil
}
out := new(OIDCIdentityMatch)
in.DeepCopyInto(out)
return out
}

View File

@ -193,9 +193,9 @@ func (in *Bucket) GetInterval() metav1.Duration {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta1 Bucket is deprecated, upgrade to v1"
// +kubebuilder:printcolumn:name="Endpoint",type=string,JSONPath=`.spec.endpoint`
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""

View File

@ -265,7 +265,6 @@ func (in *GitRepository) GetInterval() metav1.Duration {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=gitrepo
// +kubebuilder:subresource:status

View File

@ -231,10 +231,10 @@ func (in *HelmChart) GetValuesFiles() []string {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=hc
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta1 HelmChart is deprecated, upgrade to v1"
// +kubebuilder:printcolumn:name="Chart",type=string,JSONPath=`.spec.chart`
// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.spec.version`
// +kubebuilder:printcolumn:name="Source Kind",type=string,JSONPath=`.spec.sourceRef.kind`

View File

@ -181,10 +181,10 @@ func (in *HelmRepository) GetInterval() metav1.Duration {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=helmrepo
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta1 HelmRepository is deprecated, upgrade to v1"
// +kubebuilder:printcolumn:name="URL",type=string,JSONPath=`.spec.url`
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""

View File

@ -1,8 +1,7 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 2023 The Flux authors
Copyright 2024 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.

View File

@ -33,22 +33,48 @@ const (
)
const (
// BucketProviderGeneric for any S3 API compatible storage Bucket.
BucketProviderGeneric string = apiv1.BucketProviderGeneric
// BucketProviderAmazon for an AWS S3 object storage Bucket.
// Provides support for retrieving credentials from the AWS EC2 service.
BucketProviderAmazon string = apiv1.BucketProviderAmazon
// BucketProviderGoogle for a Google Cloud Storage Bucket.
// Provides support for authentication using a workload identity.
BucketProviderGoogle string = apiv1.BucketProviderGoogle
// BucketProviderAzure for an Azure Blob Storage Bucket.
// Provides support for authentication using a Service Principal,
// Managed Identity or Shared Key.
BucketProviderAzure string = apiv1.BucketProviderAzure
// GenericBucketProvider for any S3 API compatible storage Bucket.
GenericBucketProvider string = "generic"
//
// Deprecated: use BucketProviderGeneric.
GenericBucketProvider string = apiv1.BucketProviderGeneric
// AmazonBucketProvider for an AWS S3 object storage Bucket.
// Provides support for retrieving credentials from the AWS EC2 service.
AmazonBucketProvider string = "aws"
//
// Deprecated: use BucketProviderAmazon.
AmazonBucketProvider string = apiv1.BucketProviderAmazon
// GoogleBucketProvider for a Google Cloud Storage Bucket.
// Provides support for authentication using a workload identity.
GoogleBucketProvider string = "gcp"
//
// Deprecated: use BucketProviderGoogle.
GoogleBucketProvider string = apiv1.BucketProviderGoogle
// AzureBucketProvider for an Azure Blob Storage Bucket.
// Provides support for authentication using a Service Principal,
// Managed Identity or Shared Key.
AzureBucketProvider string = "azure"
//
// Deprecated: use BucketProviderAzure.
AzureBucketProvider string = apiv1.BucketProviderAzure
)
// BucketSpec specifies the required configuration to produce an Artifact for
// an object storage bucket.
// +kubebuilder:validation:XValidation:rule="self.provider == 'aws' || self.provider == 'generic' || !has(self.sts)", message="STS configuration is only supported for the 'aws' and 'generic' Bucket providers"
// +kubebuilder:validation:XValidation:rule="self.provider != 'aws' || !has(self.sts) || self.sts.provider == 'aws'", message="'aws' is the only supported STS provider for the 'aws' Bucket provider"
// +kubebuilder:validation:XValidation:rule="self.provider != 'generic' || !has(self.sts) || self.sts.provider == 'ldap'", message="'ldap' is the only supported STS provider for the 'generic' Bucket provider"
// +kubebuilder:validation:XValidation:rule="!has(self.sts) || self.sts.provider != 'aws' || !has(self.sts.secretRef)", message="spec.sts.secretRef is not required for the 'aws' STS provider"
// +kubebuilder:validation:XValidation:rule="!has(self.sts) || self.sts.provider != 'aws' || !has(self.sts.certSecretRef)", message="spec.sts.certSecretRef is not required for the 'aws' STS provider"
type BucketSpec struct {
// Provider of the object storage bucket.
// Defaults to 'generic', which expects an S3 (API) compatible object
@ -66,6 +92,14 @@ type BucketSpec struct {
// +required
Endpoint string `json:"endpoint"`
// STS specifies the required configuration to use a Security Token
// Service for fetching temporary credentials to authenticate in a
// Bucket provider.
//
// This field is only supported for the `aws` and `generic` providers.
// +optional
STS *BucketSTSSpec `json:"sts,omitempty"`
// Insecure allows connecting to a non-TLS HTTP Endpoint.
// +optional
Insecure bool `json:"insecure,omitempty"`
@ -83,6 +117,28 @@ type BucketSpec struct {
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
// CertSecretRef can be given the name of a Secret containing
// either or both of
//
// - a PEM-encoded client certificate (`tls.crt`) and private
// key (`tls.key`);
// - a PEM-encoded CA certificate (`ca.crt`)
//
// and whichever are supplied, will be used for connecting to the
// bucket. The client cert and key are useful if you are
// authenticating with a certificate; the CA cert is useful if
// you are using a self-signed server certificate. The Secret must
// be of type `Opaque` or `kubernetes.io/tls`.
//
// This field is only supported for the `generic` provider.
// +optional
CertSecretRef *meta.LocalObjectReference `json:"certSecretRef,omitempty"`
// ProxySecretRef specifies the Secret containing the proxy configuration
// to use while communicating with the Bucket server.
// +optional
ProxySecretRef *meta.LocalObjectReference `json:"proxySecretRef,omitempty"`
// Interval at which the Bucket Endpoint is checked for updates.
// This interval is approximate and may be subject to jitter to ensure
// efficient use of resources.
@ -116,6 +172,45 @@ type BucketSpec struct {
AccessFrom *acl.AccessFrom `json:"accessFrom,omitempty"`
}
// BucketSTSSpec specifies the required configuration to use a Security Token
// Service for fetching temporary credentials to authenticate in a Bucket
// provider.
type BucketSTSSpec struct {
// Provider of the Security Token Service.
// +kubebuilder:validation:Enum=aws;ldap
// +required
Provider string `json:"provider"`
// Endpoint is the HTTP/S endpoint of the Security Token Service from
// where temporary credentials will be fetched.
// +required
// +kubebuilder:validation:Pattern="^(http|https)://.*$"
Endpoint string `json:"endpoint"`
// SecretRef specifies the Secret containing authentication credentials
// for the STS endpoint. This Secret must contain the fields `username`
// and `password` and is supported only for the `ldap` provider.
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
// CertSecretRef can be given the name of a Secret containing
// either or both of
//
// - a PEM-encoded client certificate (`tls.crt`) and private
// key (`tls.key`);
// - a PEM-encoded CA certificate (`ca.crt`)
//
// and whichever are supplied, will be used for connecting to the
// STS endpoint. The client cert and key are useful if you are
// authenticating with a certificate; the CA cert is useful if
// you are using a self-signed server certificate. The Secret must
// be of type `Opaque` or `kubernetes.io/tls`.
//
// This field is only supported for the `ldap` provider.
// +optional
CertSecretRef *meta.LocalObjectReference `json:"certSecretRef,omitempty"`
}
// BucketStatus records the observed state of a Bucket.
type BucketStatus struct {
// ObservedGeneration is the last observed generation of the Bucket object.
@ -175,10 +270,9 @@ func (in *Bucket) GetArtifact() *apiv1.Artifact {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta2 Bucket is deprecated, upgrade to v1"
// +kubebuilder:printcolumn:name="Endpoint",type=string,JSONPath=`.spec.endpoint`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""

View File

@ -287,7 +287,6 @@ func (in *GitRepository) GetArtifact() *apiv1.Artifact {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=gitrepo
// +kubebuilder:subresource:status

View File

@ -23,6 +23,7 @@ import (
"github.com/fluxcd/pkg/apis/acl"
"github.com/fluxcd/pkg/apis/meta"
apiv1 "github.com/fluxcd/source-controller/api/v1"
)
@ -79,6 +80,11 @@ type HelmChartSpec struct {
// +deprecated
ValuesFile string `json:"valuesFile,omitempty"`
// IgnoreMissingValuesFiles controls whether to silently ignore missing values
// files rather than failing.
// +optional
IgnoreMissingValuesFiles bool `json:"ignoreMissingValuesFiles,omitempty"`
// Suspend tells the controller to suspend the reconciliation of this
// source.
// +optional
@ -96,7 +102,7 @@ type HelmChartSpec struct {
// This field is only supported when using HelmRepository source with spec.type 'oci'.
// Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified.
// +optional
Verify *OCIRepositoryVerification `json:"verify,omitempty"`
Verify *apiv1.OCIRepositoryVerification `json:"verify,omitempty"`
}
const (
@ -142,6 +148,12 @@ type HelmChartStatus struct {
// +optional
ObservedChartName string `json:"observedChartName,omitempty"`
// ObservedValuesFiles are the observed value files of the last successful
// reconciliation.
// It matches the chart in the last successfully reconciled artifact.
// +optional
ObservedValuesFiles []string `json:"observedValuesFiles,omitempty"`
// Conditions holds the conditions for the HelmChart.
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
@ -203,11 +215,10 @@ func (in *HelmChart) GetValuesFiles() []string {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=hc
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta2 HelmChart is deprecated, upgrade to v1"
// +kubebuilder:printcolumn:name="Chart",type=string,JSONPath=`.spec.chart`
// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.spec.version`
// +kubebuilder:printcolumn:name="Source Kind",type=string,JSONPath=`.spec.sourceRef.kind`

View File

@ -198,11 +198,10 @@ func (in *HelmRepository) GetArtifact() *apiv1.Artifact {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=helmrepo
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta2 HelmRepository is deprecated, upgrade to v1"
// +kubebuilder:printcolumn:name="URL",type=string,JSONPath=`.spec.url`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""

View File

@ -22,6 +22,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fluxcd/pkg/apis/meta"
apiv1 "github.com/fluxcd/source-controller/api/v1"
)
@ -89,7 +90,7 @@ type OCIRepositorySpec struct {
// used to verify the signature and specifies which provider to use to check
// whether OCI image is authentic.
// +optional
Verify *OCIRepositoryVerification `json:"verify,omitempty"`
Verify *apiv1.OCIRepositoryVerification `json:"verify,omitempty"`
// ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate
// the image pull if the service account has attached pull secrets. For more information:
@ -115,6 +116,11 @@ type OCIRepositorySpec struct {
// +optional
CertSecretRef *meta.LocalObjectReference `json:"certSecretRef,omitempty"`
// ProxySecretRef specifies the Secret containing the proxy configuration
// to use while communicating with the container registry.
// +optional
ProxySecretRef *meta.LocalObjectReference `json:"proxySecretRef,omitempty"`
// Interval at which the OCIRepository URL is checked for updates.
// This interval is approximate and may be subject to jitter to ensure
// efficient use of resources.
@ -157,6 +163,10 @@ type OCIRepositoryRef struct {
// +optional
SemVer string `json:"semver,omitempty"`
// SemverFilter is a regex pattern to filter the tags within the SemVer range.
// +optional
SemverFilter string `json:"semverFilter,omitempty"`
// Tag is the image tag to pull, defaults to latest.
// +optional
Tag string `json:"tag,omitempty"`
@ -179,41 +189,6 @@ type OCILayerSelector struct {
Operation string `json:"operation,omitempty"`
}
// OCIRepositoryVerification verifies the authenticity of an OCI Artifact
type OCIRepositoryVerification struct {
// Provider specifies the technology used to sign the OCI Artifact.
// +kubebuilder:validation:Enum=cosign
// +kubebuilder:default:=cosign
Provider string `json:"provider"`
// SecretRef specifies the Kubernetes Secret containing the
// trusted public keys.
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
// MatchOIDCIdentity specifies the identity matching criteria to use
// while verifying an OCI artifact which was signed using Cosign keyless
// signing. The artifact's identity is deemed to be verified if any of the
// specified matchers match against the identity.
// +optional
MatchOIDCIdentity []OIDCIdentityMatch `json:"matchOIDCIdentity,omitempty"`
}
// OIDCIdentityMatch specifies options for verifying the certificate identity,
// i.e. the issuer and the subject of the certificate.
type OIDCIdentityMatch struct {
// Issuer specifies the regex pattern to match against to verify
// the OIDC issuer in the Fulcio certificate. The pattern must be a
// valid Go regular expression.
// +required
Issuer string `json:"issuer"`
// Subject specifies the regex pattern to match against to verify
// the identity subject in the Fulcio certificate. The pattern must
// be a valid Go regular expression.
// +required
Subject string `json:"subject"`
}
// OCIRepositoryStatus defines the observed state of OCIRepository
type OCIRepositoryStatus struct {
// ObservedGeneration is the last observed generation.
@ -308,11 +283,10 @@ func (in *OCIRepository) GetLayerOperation() string {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=ocirepo
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta2 OCIRepository is deprecated, upgrade to v1"
// +kubebuilder:printcolumn:name="URL",type=string,JSONPath=`.spec.url`
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description=""

26
api/v1beta2/sts_types.go Normal file
View File

@ -0,0 +1,26 @@
/*
Copyright 2024 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 v1beta2
const (
// STSProviderAmazon represents the AWS provider for Security Token Service.
// Provides support for fetching temporary credentials from an AWS STS endpoint.
STSProviderAmazon string = "aws"
// STSProviderLDAP represents the LDAP provider for Security Token Service.
// Provides support for fetching temporary credentials from an LDAP endpoint.
STSProviderLDAP string = "ldap"
)

View File

@ -1,8 +1,7 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 2023 The Flux authors
Copyright 2024 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.
@ -117,13 +116,53 @@ func (in *BucketList) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BucketSpec) DeepCopyInto(out *BucketSpec) {
func (in *BucketSTSSpec) DeepCopyInto(out *BucketSTSSpec) {
*out = *in
if in.SecretRef != nil {
in, out := &in.SecretRef, &out.SecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.CertSecretRef != nil {
in, out := &in.CertSecretRef, &out.CertSecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BucketSTSSpec.
func (in *BucketSTSSpec) DeepCopy() *BucketSTSSpec {
if in == nil {
return nil
}
out := new(BucketSTSSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BucketSpec) DeepCopyInto(out *BucketSpec) {
*out = *in
if in.STS != nil {
in, out := &in.STS, &out.STS
*out = new(BucketSTSSpec)
(*in).DeepCopyInto(*out)
}
if in.SecretRef != nil {
in, out := &in.SecretRef, &out.SecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.CertSecretRef != nil {
in, out := &in.CertSecretRef, &out.CertSecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.ProxySecretRef != nil {
in, out := &in.ProxySecretRef, &out.ProxySecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
out.Interval = in.Interval
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
@ -467,7 +506,7 @@ func (in *HelmChartSpec) DeepCopyInto(out *HelmChartSpec) {
}
if in.Verify != nil {
in, out := &in.Verify, &out.Verify
*out = new(OCIRepositoryVerification)
*out = new(apiv1.OCIRepositoryVerification)
(*in).DeepCopyInto(*out)
}
}
@ -485,6 +524,11 @@ func (in *HelmChartSpec) DeepCopy() *HelmChartSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelmChartStatus) DeepCopyInto(out *HelmChartStatus) {
*out = *in
if in.ObservedValuesFiles != nil {
in, out := &in.ObservedValuesFiles, &out.ObservedValuesFiles
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]v1.Condition, len(*in))
@ -757,7 +801,7 @@ func (in *OCIRepositorySpec) DeepCopyInto(out *OCIRepositorySpec) {
}
if in.Verify != nil {
in, out := &in.Verify, &out.Verify
*out = new(OCIRepositoryVerification)
*out = new(apiv1.OCIRepositoryVerification)
(*in).DeepCopyInto(*out)
}
if in.CertSecretRef != nil {
@ -765,6 +809,11 @@ func (in *OCIRepositorySpec) DeepCopyInto(out *OCIRepositorySpec) {
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.ProxySecretRef != nil {
in, out := &in.ProxySecretRef, &out.ProxySecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
out.Interval = in.Interval
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
@ -825,43 +874,3 @@ func (in *OCIRepositoryStatus) DeepCopy() *OCIRepositoryStatus {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OCIRepositoryVerification) DeepCopyInto(out *OCIRepositoryVerification) {
*out = *in
if in.SecretRef != nil {
in, out := &in.SecretRef, &out.SecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.MatchOIDCIdentity != nil {
in, out := &in.MatchOIDCIdentity, &out.MatchOIDCIdentity
*out = make([]OIDCIdentityMatch, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OCIRepositoryVerification.
func (in *OCIRepositoryVerification) DeepCopy() *OCIRepositoryVerification {
if in == nil {
return nil
}
out := new(OCIRepositoryVerification)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OIDCIdentityMatch) DeepCopyInto(out *OIDCIdentityMatch) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDCIdentityMatch.
func (in *OIDCIdentityMatch) DeepCopy() *OIDCIdentityMatch {
if in == nil {
return nil
}
out := new(OIDCIdentityMatch)
in.DeepCopyInto(out)
return out
}

View File

@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.0
controller-gen.kubebuilder.io/version: v0.16.1
name: buckets.source.toolkit.fluxcd.io
spec:
group: source.toolkit.fluxcd.io
@ -14,6 +14,359 @@ spec:
singular: bucket
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.endpoint
name: Endpoint
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .status.conditions[?(@.type=="Ready")].status
name: Ready
type: string
- jsonPath: .status.conditions[?(@.type=="Ready")].message
name: Status
type: string
name: v1
schema:
openAPIV3Schema:
description: Bucket is the Schema for the buckets API.
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: |-
BucketSpec specifies the required configuration to produce an Artifact for
an object storage bucket.
properties:
bucketName:
description: BucketName is the name of the object storage bucket.
type: string
certSecretRef:
description: |-
CertSecretRef can be given the name of a Secret containing
either or both of
- a PEM-encoded client certificate (`tls.crt`) and private
key (`tls.key`);
- a PEM-encoded CA certificate (`ca.crt`)
and whichever are supplied, will be used for connecting to the
bucket. The client cert and key are useful if you are
authenticating with a certificate; the CA cert is useful if
you are using a self-signed server certificate. The Secret must
be of type `Opaque` or `kubernetes.io/tls`.
This field is only supported for the `generic` provider.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
endpoint:
description: Endpoint is the object storage address the BucketName
is located at.
type: string
ignore:
description: |-
Ignore overrides the set of excluded patterns in the .sourceignore format
(which is the same as .gitignore). If not provided, a default will be used,
consult the documentation for your version to find out what those are.
type: string
insecure:
description: Insecure allows connecting to a non-TLS HTTP Endpoint.
type: boolean
interval:
description: |-
Interval at which the Bucket Endpoint is checked for updates.
This interval is approximate and may be subject to jitter to ensure
efficient use of resources.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
prefix:
description: Prefix to use for server-side filtering of files in the
Bucket.
type: string
provider:
default: generic
description: |-
Provider of the object storage bucket.
Defaults to 'generic', which expects an S3 (API) compatible object
storage.
enum:
- generic
- aws
- gcp
- azure
type: string
proxySecretRef:
description: |-
ProxySecretRef specifies the Secret containing the proxy configuration
to use while communicating with the Bucket server.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
region:
description: Region of the Endpoint where the BucketName is located
in.
type: string
secretRef:
description: |-
SecretRef specifies the Secret containing authentication credentials
for the Bucket.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
sts:
description: |-
STS specifies the required configuration to use a Security Token
Service for fetching temporary credentials to authenticate in a
Bucket provider.
This field is only supported for the `aws` and `generic` providers.
properties:
certSecretRef:
description: |-
CertSecretRef can be given the name of a Secret containing
either or both of
- a PEM-encoded client certificate (`tls.crt`) and private
key (`tls.key`);
- a PEM-encoded CA certificate (`ca.crt`)
and whichever are supplied, will be used for connecting to the
STS endpoint. The client cert and key are useful if you are
authenticating with a certificate; the CA cert is useful if
you are using a self-signed server certificate. The Secret must
be of type `Opaque` or `kubernetes.io/tls`.
This field is only supported for the `ldap` provider.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
endpoint:
description: |-
Endpoint is the HTTP/S endpoint of the Security Token Service from
where temporary credentials will be fetched.
pattern: ^(http|https)://.*$
type: string
provider:
description: Provider of the Security Token Service.
enum:
- aws
- ldap
type: string
secretRef:
description: |-
SecretRef specifies the Secret containing authentication credentials
for the STS endpoint. This Secret must contain the fields `username`
and `password` and is supported only for the `ldap` provider.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
required:
- endpoint
- provider
type: object
suspend:
description: |-
Suspend tells the controller to suspend the reconciliation of this
Bucket.
type: boolean
timeout:
default: 60s
description: Timeout for fetch operations, defaults to 60s.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$
type: string
required:
- bucketName
- endpoint
- interval
type: object
x-kubernetes-validations:
- message: STS configuration is only supported for the 'aws' and 'generic'
Bucket providers
rule: self.provider == 'aws' || self.provider == 'generic' || !has(self.sts)
- message: '''aws'' is the only supported STS provider for the ''aws''
Bucket provider'
rule: self.provider != 'aws' || !has(self.sts) || self.sts.provider
== 'aws'
- message: '''ldap'' is the only supported STS provider for the ''generic''
Bucket provider'
rule: self.provider != 'generic' || !has(self.sts) || self.sts.provider
== 'ldap'
- message: spec.sts.secretRef is not required for the 'aws' STS provider
rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.secretRef)'
- message: spec.sts.certSecretRef is not required for the 'aws' STS provider
rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.certSecretRef)'
status:
default:
observedGeneration: -1
description: BucketStatus records the observed state of a Bucket.
properties:
artifact:
description: Artifact represents the last successful Bucket reconciliation.
properties:
digest:
description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$
type: string
lastUpdateTime:
description: |-
LastUpdateTime is the timestamp corresponding to the last update of the
Artifact.
format: date-time
type: string
metadata:
additionalProperties:
type: string
description: Metadata holds upstream information such as OCI annotations.
type: object
path:
description: |-
Path is the relative file path of the Artifact. It can be used to locate
the file in the root of the Artifact storage on the local file system of
the controller managing the Source.
type: string
revision:
description: |-
Revision is a human-readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.
type: string
size:
description: Size is the number of bytes in the file.
format: int64
type: integer
url:
description: |-
URL is the HTTP address of the Artifact as exposed by the controller
managing the Source. It can be used to retrieve the Artifact for
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- lastUpdateTime
- path
- revision
- url
type: object
conditions:
description: Conditions holds the conditions for the Bucket.
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
lastHandledReconcileAt:
description: |-
LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value
can be detected.
type: string
observedGeneration:
description: ObservedGeneration is the last observed generation of
the Bucket object.
format: int64
type: integer
observedIgnore:
description: |-
ObservedIgnore is the observed exclusion patterns used for constructing
the source artifact.
type: string
url:
description: |-
URL is the dynamic fetch link for the latest Artifact.
It is provided on a "best effort" basis, and using the precise
BucketStatus.Artifact data is recommended.
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
- additionalPrinterColumns:
- jsonPath: .spec.endpoint
name: Endpoint
@ -27,20 +380,27 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
deprecated: true
deprecationWarning: v1beta1 Bucket is deprecated, upgrade to v1
name: v1beta1
schema:
openAPIV3Schema:
description: Bucket is the Schema for the buckets API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@ -53,22 +413,21 @@ spec:
cross-namespace references to this object.
properties:
namespaceSelectors:
description: NamespaceSelectors is the list of namespace selectors
to which this ACL applies. Items in this list are evaluated
using a logical OR operation.
description: |-
NamespaceSelectors is the list of namespace selectors to which this ACL applies.
Items in this list are evaluated using a logical OR operation.
items:
description: NamespaceSelector selects the namespaces to which
this ACL applies. An empty map of MatchLabels matches all
namespaces in a cluster.
description: |-
NamespaceSelector selects the namespaces to which this ACL applies.
An empty map of MatchLabels matches all namespaces in a cluster.
properties:
matchLabels:
additionalProperties:
type: string
description: MatchLabels is a map of {key,value} pairs.
A single {key,value} in the matchLabels map is equivalent
to an element of matchExpressions, whose key field is
"key", the operator is "In", and the values array contains
only "value". The requirements are ANDed.
description: |-
MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
type: array
@ -82,10 +441,10 @@ spec:
description: The bucket endpoint address.
type: string
ignore:
description: Ignore overrides the set of excluded patterns in the
.sourceignore format (which is the same as .gitignore). If not provided,
a default will be used, consult the documentation for your version
to find out what those are.
description: |-
Ignore overrides the set of excluded patterns in the .sourceignore format
(which is the same as .gitignore). If not provided, a default will be used,
consult the documentation for your version to find out what those are.
type: string
insecure:
description: Insecure allows connecting to a non-TLS S3 HTTP endpoint.
@ -105,7 +464,8 @@ spec:
description: The bucket region.
type: string
secretRef:
description: The name of the secret containing authentication credentials
description: |-
The name of the secret containing authentication credentials
for the Bucket.
properties:
name:
@ -140,65 +500,60 @@ spec:
description: Checksum is the SHA256 checksum of the artifact.
type: string
lastUpdateTime:
description: LastUpdateTime is the timestamp corresponding to
the last update of this artifact.
description: |-
LastUpdateTime is the timestamp corresponding to the last update of this
artifact.
format: date-time
type: string
path:
description: Path is the relative file path of this artifact.
type: string
revision:
description: Revision is a human readable identifier traceable
in the origin source system. It can be a Git commit SHA, Git
tag, a Helm index timestamp, a Helm chart version, etc.
description: |-
Revision is a human readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm index timestamp, a Helm
chart version, etc.
type: string
url:
description: URL is the HTTP address of this artifact.
type: string
required:
- lastUpdateTime
- path
- url
type: object
conditions:
description: Conditions holds the conditions for the Bucket.
items:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
\n type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
// +listType=map // +listMapKey=type Conditions []metav1.Condition
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should be when
the underlying condition changed. If that is not known, then
using the time when the API field changed is acceptable.
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance, if .metadata.generation
is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the current
state of the instance.
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition. Producers
of specific condition types may define expected values and
meanings for this field, and whether the values are considered
a guaranteed API. The value should be a CamelCase string.
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
@ -213,10 +568,6 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@ -229,9 +580,10 @@ spec:
type: object
type: array
lastHandledReconcileAt:
description: LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value can
be detected.
description: |-
LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value
can be detected.
type: string
observedGeneration:
description: ObservedGeneration is the last observed generation.
@ -260,49 +612,57 @@ spec:
- jsonPath: .status.conditions[?(@.type=="Ready")].message
name: Status
type: string
deprecated: true
deprecationWarning: v1beta2 Bucket is deprecated, upgrade to v1
name: v1beta2
schema:
openAPIV3Schema:
description: Bucket is the Schema for the buckets API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: BucketSpec specifies the required configuration to produce
an Artifact for an object storage bucket.
description: |-
BucketSpec specifies the required configuration to produce an Artifact for
an object storage bucket.
properties:
accessFrom:
description: 'AccessFrom specifies an Access Control List for allowing
cross-namespace references to this object. NOTE: Not implemented,
provisional as of https://github.com/fluxcd/flux2/pull/2092'
description: |-
AccessFrom specifies an Access Control List for allowing cross-namespace
references to this object.
NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092
properties:
namespaceSelectors:
description: NamespaceSelectors is the list of namespace selectors
to which this ACL applies. Items in this list are evaluated
using a logical OR operation.
description: |-
NamespaceSelectors is the list of namespace selectors to which this ACL applies.
Items in this list are evaluated using a logical OR operation.
items:
description: NamespaceSelector selects the namespaces to which
this ACL applies. An empty map of MatchLabels matches all
namespaces in a cluster.
description: |-
NamespaceSelector selects the namespaces to which this ACL applies.
An empty map of MatchLabels matches all namespaces in a cluster.
properties:
matchLabels:
additionalProperties:
type: string
description: MatchLabels is a map of {key,value} pairs.
A single {key,value} in the matchLabels map is equivalent
to an element of matchExpressions, whose key field is
"key", the operator is "In", and the values array contains
only "value". The requirements are ANDed.
description: |-
MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
type: array
@ -312,23 +672,47 @@ spec:
bucketName:
description: BucketName is the name of the object storage bucket.
type: string
certSecretRef:
description: |-
CertSecretRef can be given the name of a Secret containing
either or both of
- a PEM-encoded client certificate (`tls.crt`) and private
key (`tls.key`);
- a PEM-encoded CA certificate (`ca.crt`)
and whichever are supplied, will be used for connecting to the
bucket. The client cert and key are useful if you are
authenticating with a certificate; the CA cert is useful if
you are using a self-signed server certificate. The Secret must
be of type `Opaque` or `kubernetes.io/tls`.
This field is only supported for the `generic` provider.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
endpoint:
description: Endpoint is the object storage address the BucketName
is located at.
type: string
ignore:
description: Ignore overrides the set of excluded patterns in the
.sourceignore format (which is the same as .gitignore). If not provided,
a default will be used, consult the documentation for your version
to find out what those are.
description: |-
Ignore overrides the set of excluded patterns in the .sourceignore format
(which is the same as .gitignore). If not provided, a default will be used,
consult the documentation for your version to find out what those are.
type: string
insecure:
description: Insecure allows connecting to a non-TLS HTTP Endpoint.
type: boolean
interval:
description: Interval at which the Bucket Endpoint is checked for
updates. This interval is approximate and may be subject to jitter
to ensure efficient use of resources.
description: |-
Interval at which the Bucket Endpoint is checked for updates.
This interval is approximate and may be subject to jitter to ensure
efficient use of resources.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
prefix:
@ -337,21 +721,20 @@ spec:
type: string
provider:
default: generic
description: Provider of the object storage bucket. Defaults to 'generic',
which expects an S3 (API) compatible object storage.
description: |-
Provider of the object storage bucket.
Defaults to 'generic', which expects an S3 (API) compatible object
storage.
enum:
- generic
- aws
- gcp
- azure
type: string
region:
description: Region of the Endpoint where the BucketName is located
in.
type: string
secretRef:
description: SecretRef specifies the Secret containing authentication
credentials for the Bucket.
proxySecretRef:
description: |-
ProxySecretRef specifies the Secret containing the proxy configuration
to use while communicating with the Bucket server.
properties:
name:
description: Name of the referent.
@ -359,9 +742,84 @@ spec:
required:
- name
type: object
region:
description: Region of the Endpoint where the BucketName is located
in.
type: string
secretRef:
description: |-
SecretRef specifies the Secret containing authentication credentials
for the Bucket.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
sts:
description: |-
STS specifies the required configuration to use a Security Token
Service for fetching temporary credentials to authenticate in a
Bucket provider.
This field is only supported for the `aws` and `generic` providers.
properties:
certSecretRef:
description: |-
CertSecretRef can be given the name of a Secret containing
either or both of
- a PEM-encoded client certificate (`tls.crt`) and private
key (`tls.key`);
- a PEM-encoded CA certificate (`ca.crt`)
and whichever are supplied, will be used for connecting to the
STS endpoint. The client cert and key are useful if you are
authenticating with a certificate; the CA cert is useful if
you are using a self-signed server certificate. The Secret must
be of type `Opaque` or `kubernetes.io/tls`.
This field is only supported for the `ldap` provider.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
endpoint:
description: |-
Endpoint is the HTTP/S endpoint of the Security Token Service from
where temporary credentials will be fetched.
pattern: ^(http|https)://.*$
type: string
provider:
description: Provider of the Security Token Service.
enum:
- aws
- ldap
type: string
secretRef:
description: |-
SecretRef specifies the Secret containing authentication credentials
for the STS endpoint. This Secret must contain the fields `username`
and `password` and is supported only for the `ldap` provider.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
required:
- endpoint
- provider
type: object
suspend:
description: Suspend tells the controller to suspend the reconciliation
of this Bucket.
description: |-
Suspend tells the controller to suspend the reconciliation of this
Bucket.
type: boolean
timeout:
default: 60s
@ -373,6 +831,22 @@ spec:
- endpoint
- interval
type: object
x-kubernetes-validations:
- message: STS configuration is only supported for the 'aws' and 'generic'
Bucket providers
rule: self.provider == 'aws' || self.provider == 'generic' || !has(self.sts)
- message: '''aws'' is the only supported STS provider for the ''aws''
Bucket provider'
rule: self.provider != 'aws' || !has(self.sts) || self.sts.provider
== 'aws'
- message: '''ldap'' is the only supported STS provider for the ''generic''
Bucket provider'
rule: self.provider != 'generic' || !has(self.sts) || self.sts.provider
== 'ldap'
- message: spec.sts.secretRef is not required for the 'aws' STS provider
rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.secretRef)'
- message: spec.sts.certSecretRef is not required for the 'aws' STS provider
rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.certSecretRef)'
status:
default:
observedGeneration: -1
@ -386,8 +860,9 @@ spec:
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$
type: string
lastUpdateTime:
description: LastUpdateTime is the timestamp corresponding to
the last update of the Artifact.
description: |-
LastUpdateTime is the timestamp corresponding to the last update of the
Artifact.
format: date-time
type: string
metadata:
@ -396,24 +871,25 @@ spec:
description: Metadata holds upstream information such as OCI annotations.
type: object
path:
description: Path is the relative file path of the Artifact. It
can be used to locate the file in the root of the Artifact storage
on the local file system of the controller managing the Source.
description: |-
Path is the relative file path of the Artifact. It can be used to locate
the file in the root of the Artifact storage on the local file system of
the controller managing the Source.
type: string
revision:
description: Revision is a human-readable identifier traceable
in the origin source system. It can be a Git commit SHA, Git
tag, a Helm chart version, etc.
description: |-
Revision is a human-readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.
type: string
size:
description: Size is the number of bytes in the file.
format: int64
type: integer
url:
description: URL is the HTTP address of the Artifact as exposed
by the controller managing the Source. It can be used to retrieve
the Artifact for consumption, e.g. by another controller applying
the Artifact contents.
description: |-
URL is the HTTP address of the Artifact as exposed by the controller
managing the Source. It can be used to retrieve the Artifact for
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- lastUpdateTime
@ -424,43 +900,35 @@ spec:
conditions:
description: Conditions holds the conditions for the Bucket.
items:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
\n type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
// +listType=map // +listMapKey=type Conditions []metav1.Condition
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should be when
the underlying condition changed. If that is not known, then
using the time when the API field changed is acceptable.
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance, if .metadata.generation
is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the current
state of the instance.
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition. Producers
of specific condition types may define expected values and
meanings for this field, and whether the values are considered
a guaranteed API. The value should be a CamelCase string.
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
@ -475,10 +943,6 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@ -491,9 +955,10 @@ spec:
type: object
type: array
lastHandledReconcileAt:
description: LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value can
be detected.
description: |-
LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value
can be detected.
type: string
observedGeneration:
description: ObservedGeneration is the last observed generation of
@ -501,17 +966,19 @@ spec:
format: int64
type: integer
observedIgnore:
description: ObservedIgnore is the observed exclusion patterns used
for constructing the source artifact.
description: |-
ObservedIgnore is the observed exclusion patterns used for constructing
the source artifact.
type: string
url:
description: URL is the dynamic fetch link for the latest Artifact.
It is provided on a "best effort" basis, and using the precise BucketStatus.Artifact
data is recommended.
description: |-
URL is the dynamic fetch link for the latest Artifact.
It is provided on a "best effort" basis, and using the precise
BucketStatus.Artifact data is recommended.
type: string
type: object
type: object
served: true
storage: true
storage: false
subresources:
status: {}

View File

@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.0
controller-gen.kubebuilder.io/version: v0.16.1
name: helmcharts.source.toolkit.fluxcd.io
spec:
group: source.toolkit.fluxcd.io
@ -16,6 +16,338 @@ spec:
singular: helmchart
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.chart
name: Chart
type: string
- jsonPath: .spec.version
name: Version
type: string
- jsonPath: .spec.sourceRef.kind
name: Source Kind
type: string
- jsonPath: .spec.sourceRef.name
name: Source Name
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .status.conditions[?(@.type=="Ready")].status
name: Ready
type: string
- jsonPath: .status.conditions[?(@.type=="Ready")].message
name: Status
type: string
name: v1
schema:
openAPIV3Schema:
description: HelmChart is the Schema for the helmcharts API.
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: HelmChartSpec specifies the desired state of a Helm chart.
properties:
chart:
description: |-
Chart is the name or path the Helm chart is available at in the
SourceRef.
type: string
ignoreMissingValuesFiles:
description: |-
IgnoreMissingValuesFiles controls whether to silently ignore missing values
files rather than failing.
type: boolean
interval:
description: |-
Interval at which the HelmChart SourceRef is checked for updates.
This interval is approximate and may be subject to jitter to ensure
efficient use of resources.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
reconcileStrategy:
default: ChartVersion
description: |-
ReconcileStrategy determines what enables the creation of a new artifact.
Valid values are ('ChartVersion', 'Revision').
See the documentation of the values for an explanation on their behavior.
Defaults to ChartVersion when omitted.
enum:
- ChartVersion
- Revision
type: string
sourceRef:
description: SourceRef is the reference to the Source the chart is
available at.
properties:
apiVersion:
description: APIVersion of the referent.
type: string
kind:
description: |-
Kind of the referent, valid values are ('HelmRepository', 'GitRepository',
'Bucket').
enum:
- HelmRepository
- GitRepository
- Bucket
type: string
name:
description: Name of the referent.
type: string
required:
- kind
- name
type: object
suspend:
description: |-
Suspend tells the controller to suspend the reconciliation of this
source.
type: boolean
valuesFiles:
description: |-
ValuesFiles is an alternative list of values files to use as the chart
values (values.yaml is not included by default), expected to be a
relative path in the SourceRef.
Values files are merged in the order of this list with the last file
overriding the first. Ignored when omitted.
items:
type: string
type: array
verify:
description: |-
Verify contains the secret name containing the trusted public keys
used to verify the signature and specifies which provider to use to check
whether OCI image is authentic.
This field is only supported when using HelmRepository source with spec.type 'oci'.
Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified.
properties:
matchOIDCIdentity:
description: |-
MatchOIDCIdentity specifies the identity matching criteria to use
while verifying an OCI artifact which was signed using Cosign keyless
signing. The artifact's identity is deemed to be verified if any of the
specified matchers match against the identity.
items:
description: |-
OIDCIdentityMatch specifies options for verifying the certificate identity,
i.e. the issuer and the subject of the certificate.
properties:
issuer:
description: |-
Issuer specifies the regex pattern to match against to verify
the OIDC issuer in the Fulcio certificate. The pattern must be a
valid Go regular expression.
type: string
subject:
description: |-
Subject specifies the regex pattern to match against to verify
the identity subject in the Fulcio certificate. The pattern must
be a valid Go regular expression.
type: string
required:
- issuer
- subject
type: object
type: array
provider:
default: cosign
description: Provider specifies the technology used to sign the
OCI Artifact.
enum:
- cosign
- notation
type: string
secretRef:
description: |-
SecretRef specifies the Kubernetes Secret containing the
trusted public keys.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
required:
- provider
type: object
version:
default: '*'
description: |-
Version is the chart version semver expression, ignored for charts from
GitRepository and Bucket sources. Defaults to latest when omitted.
type: string
required:
- chart
- interval
- sourceRef
type: object
status:
default:
observedGeneration: -1
description: HelmChartStatus records the observed state of the HelmChart.
properties:
artifact:
description: Artifact represents the output of the last successful
reconciliation.
properties:
digest:
description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$
type: string
lastUpdateTime:
description: |-
LastUpdateTime is the timestamp corresponding to the last update of the
Artifact.
format: date-time
type: string
metadata:
additionalProperties:
type: string
description: Metadata holds upstream information such as OCI annotations.
type: object
path:
description: |-
Path is the relative file path of the Artifact. It can be used to locate
the file in the root of the Artifact storage on the local file system of
the controller managing the Source.
type: string
revision:
description: |-
Revision is a human-readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.
type: string
size:
description: Size is the number of bytes in the file.
format: int64
type: integer
url:
description: |-
URL is the HTTP address of the Artifact as exposed by the controller
managing the Source. It can be used to retrieve the Artifact for
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- lastUpdateTime
- path
- revision
- url
type: object
conditions:
description: Conditions holds the conditions for the HelmChart.
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
lastHandledReconcileAt:
description: |-
LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value
can be detected.
type: string
observedChartName:
description: |-
ObservedChartName is the last observed chart name as specified by the
resolved chart reference.
type: string
observedGeneration:
description: |-
ObservedGeneration is the last observed generation of the HelmChart
object.
format: int64
type: integer
observedSourceArtifactRevision:
description: |-
ObservedSourceArtifactRevision is the last observed Artifact.Revision
of the HelmChartSpec.SourceRef.
type: string
observedValuesFiles:
description: |-
ObservedValuesFiles are the observed value files of the last successful
reconciliation.
It matches the chart in the last successfully reconciled artifact.
items:
type: string
type: array
url:
description: |-
URL is the dynamic fetch link for the latest Artifact.
It is provided on a "best effort" basis, and using the precise
BucketStatus.Artifact data is recommended.
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
- additionalPrinterColumns:
- jsonPath: .spec.chart
name: Chart
@ -38,20 +370,27 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
deprecated: true
deprecationWarning: v1beta1 HelmChart is deprecated, upgrade to v1
name: v1beta1
schema:
openAPIV3Schema:
description: HelmChart is the Schema for the helmcharts API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@ -63,22 +402,21 @@ spec:
cross-namespace references to this object.
properties:
namespaceSelectors:
description: NamespaceSelectors is the list of namespace selectors
to which this ACL applies. Items in this list are evaluated
using a logical OR operation.
description: |-
NamespaceSelectors is the list of namespace selectors to which this ACL applies.
Items in this list are evaluated using a logical OR operation.
items:
description: NamespaceSelector selects the namespaces to which
this ACL applies. An empty map of MatchLabels matches all
namespaces in a cluster.
description: |-
NamespaceSelector selects the namespaces to which this ACL applies.
An empty map of MatchLabels matches all namespaces in a cluster.
properties:
matchLabels:
additionalProperties:
type: string
description: MatchLabels is a map of {key,value} pairs.
A single {key,value} in the matchLabels map is equivalent
to an element of matchExpressions, whose key field is
"key", the operator is "In", and the values array contains
only "value". The requirements are ANDed.
description: |-
MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
type: array
@ -94,10 +432,11 @@ spec:
type: string
reconcileStrategy:
default: ChartVersion
description: Determines what enables the creation of a new artifact.
Valid values are ('ChartVersion', 'Revision'). See the documentation
of the values for an explanation on their behavior. Defaults to
ChartVersion when omitted.
description: |-
Determines what enables the creation of a new artifact. Valid values are
('ChartVersion', 'Revision').
See the documentation of the values for an explanation on their behavior.
Defaults to ChartVersion when omitted.
enum:
- ChartVersion
- Revision
@ -109,8 +448,9 @@ spec:
description: APIVersion of the referent.
type: string
kind:
description: Kind of the referent, valid values are ('HelmRepository',
'GitRepository', 'Bucket').
description: |-
Kind of the referent, valid values are ('HelmRepository', 'GitRepository',
'Bucket').
enum:
- HelmRepository
- GitRepository
@ -128,24 +468,26 @@ spec:
of this source.
type: boolean
valuesFile:
description: Alternative values file to use as the default chart values,
expected to be a relative path in the SourceRef. Deprecated in favor
of ValuesFiles, for backwards compatibility the file defined here
is merged before the ValuesFiles items. Ignored when omitted.
description: |-
Alternative values file to use as the default chart values, expected to
be a relative path in the SourceRef. Deprecated in favor of ValuesFiles,
for backwards compatibility the file defined here is merged before the
ValuesFiles items. Ignored when omitted.
type: string
valuesFiles:
description: Alternative list of values files to use as the chart
values (values.yaml is not included by default), expected to be
a relative path in the SourceRef. Values files are merged in the
order of this list with the last file overriding the first. Ignored
when omitted.
description: |-
Alternative list of values files to use as the chart values (values.yaml
is not included by default), expected to be a relative path in the SourceRef.
Values files are merged in the order of this list with the last file overriding
the first. Ignored when omitted.
items:
type: string
type: array
version:
default: '*'
description: The chart version semver expression, ignored for charts
from GitRepository and Bucket sources. Defaults to latest when omitted.
description: |-
The chart version semver expression, ignored for charts from GitRepository
and Bucket sources. Defaults to latest when omitted.
type: string
required:
- chart
@ -165,65 +507,60 @@ spec:
description: Checksum is the SHA256 checksum of the artifact.
type: string
lastUpdateTime:
description: LastUpdateTime is the timestamp corresponding to
the last update of this artifact.
description: |-
LastUpdateTime is the timestamp corresponding to the last update of this
artifact.
format: date-time
type: string
path:
description: Path is the relative file path of this artifact.
type: string
revision:
description: Revision is a human readable identifier traceable
in the origin source system. It can be a Git commit SHA, Git
tag, a Helm index timestamp, a Helm chart version, etc.
description: |-
Revision is a human readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm index timestamp, a Helm
chart version, etc.
type: string
url:
description: URL is the HTTP address of this artifact.
type: string
required:
- lastUpdateTime
- path
- url
type: object
conditions:
description: Conditions holds the conditions for the HelmChart.
items:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
\n type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
// +listType=map // +listMapKey=type Conditions []metav1.Condition
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should be when
the underlying condition changed. If that is not known, then
using the time when the API field changed is acceptable.
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance, if .metadata.generation
is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the current
state of the instance.
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition. Producers
of specific condition types may define expected values and
meanings for this field, and whether the values are considered
a guaranteed API. The value should be a CamelCase string.
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
@ -238,10 +575,6 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@ -254,9 +587,10 @@ spec:
type: object
type: array
lastHandledReconcileAt:
description: LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value can
be detected.
description: |-
LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value
can be detected.
type: string
observedGeneration:
description: ObservedGeneration is the last observed generation.
@ -293,20 +627,27 @@ spec:
- jsonPath: .status.conditions[?(@.type=="Ready")].message
name: Status
type: string
deprecated: true
deprecationWarning: v1beta2 HelmChart is deprecated, upgrade to v1
name: v1beta2
schema:
openAPIV3Schema:
description: HelmChart is the Schema for the helmcharts API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@ -314,27 +655,27 @@ spec:
description: HelmChartSpec specifies the desired state of a Helm chart.
properties:
accessFrom:
description: 'AccessFrom specifies an Access Control List for allowing
cross-namespace references to this object. NOTE: Not implemented,
provisional as of https://github.com/fluxcd/flux2/pull/2092'
description: |-
AccessFrom specifies an Access Control List for allowing cross-namespace
references to this object.
NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092
properties:
namespaceSelectors:
description: NamespaceSelectors is the list of namespace selectors
to which this ACL applies. Items in this list are evaluated
using a logical OR operation.
description: |-
NamespaceSelectors is the list of namespace selectors to which this ACL applies.
Items in this list are evaluated using a logical OR operation.
items:
description: NamespaceSelector selects the namespaces to which
this ACL applies. An empty map of MatchLabels matches all
namespaces in a cluster.
description: |-
NamespaceSelector selects the namespaces to which this ACL applies.
An empty map of MatchLabels matches all namespaces in a cluster.
properties:
matchLabels:
additionalProperties:
type: string
description: MatchLabels is a map of {key,value} pairs.
A single {key,value} in the matchLabels map is equivalent
to an element of matchExpressions, whose key field is
"key", the operator is "In", and the values array contains
only "value". The requirements are ANDed.
description: |-
MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
type: array
@ -342,21 +683,29 @@ spec:
- namespaceSelectors
type: object
chart:
description: Chart is the name or path the Helm chart is available
at in the SourceRef.
description: |-
Chart is the name or path the Helm chart is available at in the
SourceRef.
type: string
ignoreMissingValuesFiles:
description: |-
IgnoreMissingValuesFiles controls whether to silently ignore missing values
files rather than failing.
type: boolean
interval:
description: Interval at which the HelmChart SourceRef is checked
for updates. This interval is approximate and may be subject to
jitter to ensure efficient use of resources.
description: |-
Interval at which the HelmChart SourceRef is checked for updates.
This interval is approximate and may be subject to jitter to ensure
efficient use of resources.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
reconcileStrategy:
default: ChartVersion
description: ReconcileStrategy determines what enables the creation
of a new artifact. Valid values are ('ChartVersion', 'Revision').
See the documentation of the values for an explanation on their
behavior. Defaults to ChartVersion when omitted.
description: |-
ReconcileStrategy determines what enables the creation of a new artifact.
Valid values are ('ChartVersion', 'Revision').
See the documentation of the values for an explanation on their behavior.
Defaults to ChartVersion when omitted.
enum:
- ChartVersion
- Revision
@ -369,8 +718,9 @@ spec:
description: APIVersion of the referent.
type: string
kind:
description: Kind of the referent, valid values are ('HelmRepository',
'GitRepository', 'Bucket').
description: |-
Kind of the referent, valid values are ('HelmRepository', 'GitRepository',
'Bucket').
enum:
- HelmRepository
- GitRepository
@ -384,53 +734,57 @@ spec:
- name
type: object
suspend:
description: Suspend tells the controller to suspend the reconciliation
of this source.
description: |-
Suspend tells the controller to suspend the reconciliation of this
source.
type: boolean
valuesFile:
description: ValuesFile is an alternative values file to use as the
default chart values, expected to be a relative path in the SourceRef.
Deprecated in favor of ValuesFiles, for backwards compatibility
the file specified here is merged before the ValuesFiles items.
Ignored when omitted.
description: |-
ValuesFile is an alternative values file to use as the default chart
values, expected to be a relative path in the SourceRef. Deprecated in
favor of ValuesFiles, for backwards compatibility the file specified here
is merged before the ValuesFiles items. Ignored when omitted.
type: string
valuesFiles:
description: ValuesFiles is an alternative list of values files to
use as the chart values (values.yaml is not included by default),
expected to be a relative path in the SourceRef. Values files are
merged in the order of this list with the last file overriding the
first. Ignored when omitted.
description: |-
ValuesFiles is an alternative list of values files to use as the chart
values (values.yaml is not included by default), expected to be a
relative path in the SourceRef.
Values files are merged in the order of this list with the last file
overriding the first. Ignored when omitted.
items:
type: string
type: array
verify:
description: Verify contains the secret name containing the trusted
public keys used to verify the signature and specifies which provider
to use to check whether OCI image is authentic. This field is only
supported when using HelmRepository source with spec.type 'oci'.
Chart dependencies, which are not bundled in the umbrella chart
artifact, are not verified.
description: |-
Verify contains the secret name containing the trusted public keys
used to verify the signature and specifies which provider to use to check
whether OCI image is authentic.
This field is only supported when using HelmRepository source with spec.type 'oci'.
Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified.
properties:
matchOIDCIdentity:
description: MatchOIDCIdentity specifies the identity matching
criteria to use while verifying an OCI artifact which was signed
using Cosign keyless signing. The artifact's identity is deemed
to be verified if any of the specified matchers match against
the identity.
description: |-
MatchOIDCIdentity specifies the identity matching criteria to use
while verifying an OCI artifact which was signed using Cosign keyless
signing. The artifact's identity is deemed to be verified if any of the
specified matchers match against the identity.
items:
description: OIDCIdentityMatch specifies options for verifying
the certificate identity, i.e. the issuer and the subject
of the certificate.
description: |-
OIDCIdentityMatch specifies options for verifying the certificate identity,
i.e. the issuer and the subject of the certificate.
properties:
issuer:
description: Issuer specifies the regex pattern to match
against to verify the OIDC issuer in the Fulcio certificate.
The pattern must be a valid Go regular expression.
description: |-
Issuer specifies the regex pattern to match against to verify
the OIDC issuer in the Fulcio certificate. The pattern must be a
valid Go regular expression.
type: string
subject:
description: Subject specifies the regex pattern to match
against to verify the identity subject in the Fulcio certificate.
The pattern must be a valid Go regular expression.
description: |-
Subject specifies the regex pattern to match against to verify
the identity subject in the Fulcio certificate. The pattern must
be a valid Go regular expression.
type: string
required:
- issuer
@ -443,10 +797,12 @@ spec:
OCI Artifact.
enum:
- cosign
- notation
type: string
secretRef:
description: SecretRef specifies the Kubernetes Secret containing
the trusted public keys.
description: |-
SecretRef specifies the Kubernetes Secret containing the
trusted public keys.
properties:
name:
description: Name of the referent.
@ -459,9 +815,9 @@ spec:
type: object
version:
default: '*'
description: Version is the chart version semver expression, ignored
for charts from GitRepository and Bucket sources. Defaults to latest
when omitted.
description: |-
Version is the chart version semver expression, ignored for charts from
GitRepository and Bucket sources. Defaults to latest when omitted.
type: string
required:
- chart
@ -482,8 +838,9 @@ spec:
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$
type: string
lastUpdateTime:
description: LastUpdateTime is the timestamp corresponding to
the last update of the Artifact.
description: |-
LastUpdateTime is the timestamp corresponding to the last update of the
Artifact.
format: date-time
type: string
metadata:
@ -492,24 +849,25 @@ spec:
description: Metadata holds upstream information such as OCI annotations.
type: object
path:
description: Path is the relative file path of the Artifact. It
can be used to locate the file in the root of the Artifact storage
on the local file system of the controller managing the Source.
description: |-
Path is the relative file path of the Artifact. It can be used to locate
the file in the root of the Artifact storage on the local file system of
the controller managing the Source.
type: string
revision:
description: Revision is a human-readable identifier traceable
in the origin source system. It can be a Git commit SHA, Git
tag, a Helm chart version, etc.
description: |-
Revision is a human-readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.
type: string
size:
description: Size is the number of bytes in the file.
format: int64
type: integer
url:
description: URL is the HTTP address of the Artifact as exposed
by the controller managing the Source. It can be used to retrieve
the Artifact for consumption, e.g. by another controller applying
the Artifact contents.
description: |-
URL is the HTTP address of the Artifact as exposed by the controller
managing the Source. It can be used to retrieve the Artifact for
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- lastUpdateTime
@ -520,43 +878,35 @@ spec:
conditions:
description: Conditions holds the conditions for the HelmChart.
items:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
\n type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
// +listType=map // +listMapKey=type Conditions []metav1.Condition
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should be when
the underlying condition changed. If that is not known, then
using the time when the API field changed is acceptable.
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance, if .metadata.generation
is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the current
state of the instance.
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition. Producers
of specific condition types may define expected values and
meanings for this field, and whether the values are considered
a guaranteed API. The value should be a CamelCase string.
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
@ -571,10 +921,6 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@ -587,31 +933,44 @@ spec:
type: object
type: array
lastHandledReconcileAt:
description: LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value can
be detected.
description: |-
LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value
can be detected.
type: string
observedChartName:
description: ObservedChartName is the last observed chart name as
specified by the resolved chart reference.
description: |-
ObservedChartName is the last observed chart name as specified by the
resolved chart reference.
type: string
observedGeneration:
description: ObservedGeneration is the last observed generation of
the HelmChart object.
description: |-
ObservedGeneration is the last observed generation of the HelmChart
object.
format: int64
type: integer
observedSourceArtifactRevision:
description: ObservedSourceArtifactRevision is the last observed Artifact.Revision
description: |-
ObservedSourceArtifactRevision is the last observed Artifact.Revision
of the HelmChartSpec.SourceRef.
type: string
observedValuesFiles:
description: |-
ObservedValuesFiles are the observed value files of the last successful
reconciliation.
It matches the chart in the last successfully reconciled artifact.
items:
type: string
type: array
url:
description: URL is the dynamic fetch link for the latest Artifact.
It is provided on a "best effort" basis, and using the precise BucketStatus.Artifact
data is recommended.
description: |-
URL is the dynamic fetch link for the latest Artifact.
It is provided on a "best effort" basis, and using the precise
BucketStatus.Artifact data is recommended.
type: string
type: object
type: object
served: true
storage: true
storage: false
subresources:
status: {}

View File

@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.0
controller-gen.kubebuilder.io/version: v0.16.1
name: helmrepositories.source.toolkit.fluxcd.io
spec:
group: source.toolkit.fluxcd.io
@ -16,6 +16,308 @@ spec:
singular: helmrepository
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.url
name: URL
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
- jsonPath: .status.conditions[?(@.type=="Ready")].status
name: Ready
type: string
- jsonPath: .status.conditions[?(@.type=="Ready")].message
name: Status
type: string
name: v1
schema:
openAPIV3Schema:
description: HelmRepository is the Schema for the helmrepositories API.
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: |-
HelmRepositorySpec specifies the required configuration to produce an
Artifact for a Helm repository index YAML.
properties:
accessFrom:
description: |-
AccessFrom specifies an Access Control List for allowing cross-namespace
references to this object.
NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092
properties:
namespaceSelectors:
description: |-
NamespaceSelectors is the list of namespace selectors to which this ACL applies.
Items in this list are evaluated using a logical OR operation.
items:
description: |-
NamespaceSelector selects the namespaces to which this ACL applies.
An empty map of MatchLabels matches all namespaces in a cluster.
properties:
matchLabels:
additionalProperties:
type: string
description: |-
MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
type: array
required:
- namespaceSelectors
type: object
certSecretRef:
description: |-
CertSecretRef can be given the name of a Secret containing
either or both of
- a PEM-encoded client certificate (`tls.crt`) and private
key (`tls.key`);
- a PEM-encoded CA certificate (`ca.crt`)
and whichever are supplied, will be used for connecting to the
registry. The client cert and key are useful if you are
authenticating with a certificate; the CA cert is useful if
you are using a self-signed server certificate. The Secret must
be of type `Opaque` or `kubernetes.io/tls`.
It takes precedence over the values specified in the Secret referred
to by `.spec.secretRef`.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
insecure:
description: |-
Insecure allows connecting to a non-TLS HTTP container registry.
This field is only taken into account if the .spec.type field is set to 'oci'.
type: boolean
interval:
description: |-
Interval at which the HelmRepository URL is checked for updates.
This interval is approximate and may be subject to jitter to ensure
efficient use of resources.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
passCredentials:
description: |-
PassCredentials allows the credentials from the SecretRef to be passed
on to a host that does not match the host as defined in URL.
This may be required if the host of the advertised chart URLs in the
index differ from the defined URL.
Enabling this should be done with caution, as it can potentially result
in credentials getting stolen in a MITM-attack.
type: boolean
provider:
default: generic
description: |-
Provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'.
This field is optional, and only taken into account if the .spec.type field is set to 'oci'.
When not specified, defaults to 'generic'.
enum:
- generic
- aws
- azure
- gcp
type: string
secretRef:
description: |-
SecretRef specifies the Secret containing authentication credentials
for the HelmRepository.
For HTTP/S basic auth the secret must contain 'username' and 'password'
fields.
Support for TLS auth using the 'certFile' and 'keyFile', and/or 'caFile'
keys is deprecated. Please use `.spec.certSecretRef` instead.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
suspend:
description: |-
Suspend tells the controller to suspend the reconciliation of this
HelmRepository.
type: boolean
timeout:
description: |-
Timeout is used for the index fetch operation for an HTTPS helm repository,
and for remote OCI Repository operations like pulling for an OCI helm
chart by the associated HelmChart.
Its default value is 60s.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$
type: string
type:
description: |-
Type of the HelmRepository.
When this field is set to "oci", the URL field value must be prefixed with "oci://".
enum:
- default
- oci
type: string
url:
description: |-
URL of the Helm repository, a valid URL contains at least a protocol and
host.
pattern: ^(http|https|oci)://.*$
type: string
required:
- url
type: object
status:
default:
observedGeneration: -1
description: HelmRepositoryStatus records the observed state of the HelmRepository.
properties:
artifact:
description: Artifact represents the last successful HelmRepository
reconciliation.
properties:
digest:
description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$
type: string
lastUpdateTime:
description: |-
LastUpdateTime is the timestamp corresponding to the last update of the
Artifact.
format: date-time
type: string
metadata:
additionalProperties:
type: string
description: Metadata holds upstream information such as OCI annotations.
type: object
path:
description: |-
Path is the relative file path of the Artifact. It can be used to locate
the file in the root of the Artifact storage on the local file system of
the controller managing the Source.
type: string
revision:
description: |-
Revision is a human-readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.
type: string
size:
description: Size is the number of bytes in the file.
format: int64
type: integer
url:
description: |-
URL is the HTTP address of the Artifact as exposed by the controller
managing the Source. It can be used to retrieve the Artifact for
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- lastUpdateTime
- path
- revision
- url
type: object
conditions:
description: Conditions holds the conditions for the HelmRepository.
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
lastHandledReconcileAt:
description: |-
LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value
can be detected.
type: string
observedGeneration:
description: |-
ObservedGeneration is the last observed generation of the HelmRepository
object.
format: int64
type: integer
url:
description: |-
URL is the dynamic fetch link for the latest Artifact.
It is provided on a "best effort" basis, and using the precise
HelmRepositoryStatus.Artifact data is recommended.
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
- additionalPrinterColumns:
- jsonPath: .spec.url
name: URL
@ -29,20 +331,27 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
deprecated: true
deprecationWarning: v1beta1 HelmRepository is deprecated, upgrade to v1
name: v1beta1
schema:
openAPIV3Schema:
description: HelmRepository is the Schema for the helmrepositories API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@ -54,22 +363,21 @@ spec:
cross-namespace references to this object.
properties:
namespaceSelectors:
description: NamespaceSelectors is the list of namespace selectors
to which this ACL applies. Items in this list are evaluated
using a logical OR operation.
description: |-
NamespaceSelectors is the list of namespace selectors to which this ACL applies.
Items in this list are evaluated using a logical OR operation.
items:
description: NamespaceSelector selects the namespaces to which
this ACL applies. An empty map of MatchLabels matches all
namespaces in a cluster.
description: |-
NamespaceSelector selects the namespaces to which this ACL applies.
An empty map of MatchLabels matches all namespaces in a cluster.
properties:
matchLabels:
additionalProperties:
type: string
description: MatchLabels is a map of {key,value} pairs.
A single {key,value} in the matchLabels map is equivalent
to an element of matchExpressions, whose key field is
"key", the operator is "In", and the values array contains
only "value". The requirements are ANDed.
description: |-
MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
type: array
@ -80,18 +388,22 @@ spec:
description: The interval at which to check the upstream for updates.
type: string
passCredentials:
description: PassCredentials allows the credentials from the SecretRef
to be passed on to a host that does not match the host as defined
in URL. This may be required if the host of the advertised chart
URLs in the index differ from the defined URL. Enabling this should
be done with caution, as it can potentially result in credentials
getting stolen in a MITM-attack.
description: |-
PassCredentials allows the credentials from the SecretRef to be passed on to
a host that does not match the host as defined in URL.
This may be required if the host of the advertised chart URLs in the index
differ from the defined URL.
Enabling this should be done with caution, as it can potentially result in
credentials getting stolen in a MITM-attack.
type: boolean
secretRef:
description: The name of the secret containing authentication credentials
for the Helm repository. For HTTP/S basic auth the secret must contain
username and password fields. For TLS the secret must contain a
certFile and keyFile, and/or caFile fields.
description: |-
The name of the secret containing authentication credentials for the Helm
repository.
For HTTP/S basic auth the secret must contain username and
password fields.
For TLS the secret must contain a certFile and keyFile, and/or
caFile fields.
properties:
name:
description: Name of the referent.
@ -128,65 +440,60 @@ spec:
description: Checksum is the SHA256 checksum of the artifact.
type: string
lastUpdateTime:
description: LastUpdateTime is the timestamp corresponding to
the last update of this artifact.
description: |-
LastUpdateTime is the timestamp corresponding to the last update of this
artifact.
format: date-time
type: string
path:
description: Path is the relative file path of this artifact.
type: string
revision:
description: Revision is a human readable identifier traceable
in the origin source system. It can be a Git commit SHA, Git
tag, a Helm index timestamp, a Helm chart version, etc.
description: |-
Revision is a human readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm index timestamp, a Helm
chart version, etc.
type: string
url:
description: URL is the HTTP address of this artifact.
type: string
required:
- lastUpdateTime
- path
- url
type: object
conditions:
description: Conditions holds the conditions for the HelmRepository.
items:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
\n type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
// +listType=map // +listMapKey=type Conditions []metav1.Condition
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should be when
the underlying condition changed. If that is not known, then
using the time when the API field changed is acceptable.
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance, if .metadata.generation
is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the current
state of the instance.
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition. Producers
of specific condition types may define expected values and
meanings for this field, and whether the values are considered
a guaranteed API. The value should be a CamelCase string.
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
@ -201,10 +508,6 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@ -217,9 +520,10 @@ spec:
type: object
type: array
lastHandledReconcileAt:
description: LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value can
be detected.
description: |-
LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value
can be detected.
type: string
observedGeneration:
description: ObservedGeneration is the last observed generation.
@ -247,49 +551,57 @@ spec:
- jsonPath: .status.conditions[?(@.type=="Ready")].message
name: Status
type: string
deprecated: true
deprecationWarning: v1beta2 HelmRepository is deprecated, upgrade to v1
name: v1beta2
schema:
openAPIV3Schema:
description: HelmRepository is the Schema for the helmrepositories API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: HelmRepositorySpec specifies the required configuration to
produce an Artifact for a Helm repository index YAML.
description: |-
HelmRepositorySpec specifies the required configuration to produce an
Artifact for a Helm repository index YAML.
properties:
accessFrom:
description: 'AccessFrom specifies an Access Control List for allowing
cross-namespace references to this object. NOTE: Not implemented,
provisional as of https://github.com/fluxcd/flux2/pull/2092'
description: |-
AccessFrom specifies an Access Control List for allowing cross-namespace
references to this object.
NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092
properties:
namespaceSelectors:
description: NamespaceSelectors is the list of namespace selectors
to which this ACL applies. Items in this list are evaluated
using a logical OR operation.
description: |-
NamespaceSelectors is the list of namespace selectors to which this ACL applies.
Items in this list are evaluated using a logical OR operation.
items:
description: NamespaceSelector selects the namespaces to which
this ACL applies. An empty map of MatchLabels matches all
namespaces in a cluster.
description: |-
NamespaceSelector selects the namespaces to which this ACL applies.
An empty map of MatchLabels matches all namespaces in a cluster.
properties:
matchLabels:
additionalProperties:
type: string
description: MatchLabels is a map of {key,value} pairs.
A single {key,value} in the matchLabels map is equivalent
to an element of matchExpressions, whose key field is
"key", the operator is "In", and the values array contains
only "value". The requirements are ANDed.
description: |-
MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions, whose key field is "key", the
operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
type: array
@ -297,15 +609,22 @@ spec:
- namespaceSelectors
type: object
certSecretRef:
description: "CertSecretRef can be given the name of a Secret containing
either or both of \n - a PEM-encoded client certificate (`tls.crt`)
and private key (`tls.key`); - a PEM-encoded CA certificate (`ca.crt`)
\n and whichever are supplied, will be used for connecting to the
registry. The client cert and key are useful if you are authenticating
with a certificate; the CA cert is useful if you are using a self-signed
server certificate. The Secret must be of type `Opaque` or `kubernetes.io/tls`.
\n It takes precedence over the values specified in the Secret referred
to by `.spec.secretRef`."
description: |-
CertSecretRef can be given the name of a Secret containing
either or both of
- a PEM-encoded client certificate (`tls.crt`) and private
key (`tls.key`);
- a PEM-encoded CA certificate (`ca.crt`)
and whichever are supplied, will be used for connecting to the
registry. The client cert and key are useful if you are
authenticating with a certificate; the CA cert is useful if
you are using a self-signed server certificate. The Secret must
be of type `Opaque` or `kubernetes.io/tls`.
It takes precedence over the values specified in the Secret referred
to by `.spec.secretRef`.
properties:
name:
description: Name of the referent.
@ -314,30 +633,32 @@ spec:
- name
type: object
insecure:
description: Insecure allows connecting to a non-TLS HTTP container
registry. This field is only taken into account if the .spec.type
field is set to 'oci'.
description: |-
Insecure allows connecting to a non-TLS HTTP container registry.
This field is only taken into account if the .spec.type field is set to 'oci'.
type: boolean
interval:
description: Interval at which the HelmRepository URL is checked for
updates. This interval is approximate and may be subject to jitter
to ensure efficient use of resources.
description: |-
Interval at which the HelmRepository URL is checked for updates.
This interval is approximate and may be subject to jitter to ensure
efficient use of resources.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
passCredentials:
description: PassCredentials allows the credentials from the SecretRef
to be passed on to a host that does not match the host as defined
in URL. This may be required if the host of the advertised chart
URLs in the index differ from the defined URL. Enabling this should
be done with caution, as it can potentially result in credentials
getting stolen in a MITM-attack.
description: |-
PassCredentials allows the credentials from the SecretRef to be passed
on to a host that does not match the host as defined in URL.
This may be required if the host of the advertised chart URLs in the
index differ from the defined URL.
Enabling this should be done with caution, as it can potentially result
in credentials getting stolen in a MITM-attack.
type: boolean
provider:
default: generic
description: Provider used for authentication, can be 'aws', 'azure',
'gcp' or 'generic'. This field is optional, and only taken into
account if the .spec.type field is set to 'oci'. When not specified,
defaults to 'generic'.
description: |-
Provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'.
This field is optional, and only taken into account if the .spec.type field is set to 'oci'.
When not specified, defaults to 'generic'.
enum:
- generic
- aws
@ -345,11 +666,13 @@ spec:
- gcp
type: string
secretRef:
description: SecretRef specifies the Secret containing authentication
credentials for the HelmRepository. For HTTP/S basic auth the secret
must contain 'username' and 'password' fields. Support for TLS auth
using the 'certFile' and 'keyFile', and/or 'caFile' keys is deprecated.
Please use `.spec.certSecretRef` instead.
description: |-
SecretRef specifies the Secret containing authentication credentials
for the HelmRepository.
For HTTP/S basic auth the secret must contain 'username' and 'password'
fields.
Support for TLS auth using the 'certFile' and 'keyFile', and/or 'caFile'
keys is deprecated. Please use `.spec.certSecretRef` instead.
properties:
name:
description: Name of the referent.
@ -358,26 +681,30 @@ spec:
- name
type: object
suspend:
description: Suspend tells the controller to suspend the reconciliation
of this HelmRepository.
description: |-
Suspend tells the controller to suspend the reconciliation of this
HelmRepository.
type: boolean
timeout:
description: Timeout is used for the index fetch operation for an
HTTPS helm repository, and for remote OCI Repository operations
like pulling for an OCI helm chart by the associated HelmChart.
description: |-
Timeout is used for the index fetch operation for an HTTPS helm repository,
and for remote OCI Repository operations like pulling for an OCI helm
chart by the associated HelmChart.
Its default value is 60s.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$
type: string
type:
description: Type of the HelmRepository. When this field is set to "oci",
the URL field value must be prefixed with "oci://".
description: |-
Type of the HelmRepository.
When this field is set to "oci", the URL field value must be prefixed with "oci://".
enum:
- default
- oci
type: string
url:
description: URL of the Helm repository, a valid URL contains at least
a protocol and host.
description: |-
URL of the Helm repository, a valid URL contains at least a protocol and
host.
pattern: ^(http|https|oci)://.*$
type: string
required:
@ -397,8 +724,9 @@ spec:
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$
type: string
lastUpdateTime:
description: LastUpdateTime is the timestamp corresponding to
the last update of the Artifact.
description: |-
LastUpdateTime is the timestamp corresponding to the last update of the
Artifact.
format: date-time
type: string
metadata:
@ -407,24 +735,25 @@ spec:
description: Metadata holds upstream information such as OCI annotations.
type: object
path:
description: Path is the relative file path of the Artifact. It
can be used to locate the file in the root of the Artifact storage
on the local file system of the controller managing the Source.
description: |-
Path is the relative file path of the Artifact. It can be used to locate
the file in the root of the Artifact storage on the local file system of
the controller managing the Source.
type: string
revision:
description: Revision is a human-readable identifier traceable
in the origin source system. It can be a Git commit SHA, Git
tag, a Helm chart version, etc.
description: |-
Revision is a human-readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.
type: string
size:
description: Size is the number of bytes in the file.
format: int64
type: integer
url:
description: URL is the HTTP address of the Artifact as exposed
by the controller managing the Source. It can be used to retrieve
the Artifact for consumption, e.g. by another controller applying
the Artifact contents.
description: |-
URL is the HTTP address of the Artifact as exposed by the controller
managing the Source. It can be used to retrieve the Artifact for
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- lastUpdateTime
@ -435,43 +764,35 @@ spec:
conditions:
description: Conditions holds the conditions for the HelmRepository.
items:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
\n type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
// +listType=map // +listMapKey=type Conditions []metav1.Condition
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should be when
the underlying condition changed. If that is not known, then
using the time when the API field changed is acceptable.
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance, if .metadata.generation
is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the current
state of the instance.
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition. Producers
of specific condition types may define expected values and
meanings for this field, and whether the values are considered
a guaranteed API. The value should be a CamelCase string.
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
@ -486,10 +807,6 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@ -502,23 +819,26 @@ spec:
type: object
type: array
lastHandledReconcileAt:
description: LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value can
be detected.
description: |-
LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value
can be detected.
type: string
observedGeneration:
description: ObservedGeneration is the last observed generation of
the HelmRepository object.
description: |-
ObservedGeneration is the last observed generation of the HelmRepository
object.
format: int64
type: integer
url:
description: URL is the dynamic fetch link for the latest Artifact.
It is provided on a "best effort" basis, and using the precise HelmRepositoryStatus.Artifact
data is recommended.
description: |-
URL is the dynamic fetch link for the latest Artifact.
It is provided on a "best effort" basis, and using the precise
HelmRepositoryStatus.Artifact data is recommended.
type: string
type: object
type: object
served: true
storage: true
storage: false
subresources:
status: {}

View File

@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.12.0
controller-gen.kubebuilder.io/version: v0.16.1
name: ocirepositories.source.toolkit.fluxcd.io
spec:
group: source.toolkit.fluxcd.io
@ -29,20 +29,25 @@ spec:
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta2
name: v1
schema:
openAPIV3Schema:
description: OCIRepository is the Schema for the ocirepositories API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@ -50,15 +55,19 @@ spec:
description: OCIRepositorySpec defines the desired state of OCIRepository
properties:
certSecretRef:
description: "CertSecretRef can be given the name of a Secret containing
either or both of \n - a PEM-encoded client certificate (`tls.crt`)
and private key (`tls.key`); - a PEM-encoded CA certificate (`ca.crt`)
\n and whichever are supplied, will be used for connecting to the
registry. The client cert and key are useful if you are authenticating
with a certificate; the CA cert is useful if you are using a self-signed
server certificate. The Secret must be of type `Opaque` or `kubernetes.io/tls`.
\n Note: Support for the `caFile`, `certFile` and `keyFile` keys
have been deprecated."
description: |-
CertSecretRef can be given the name of a Secret containing
either or both of
- a PEM-encoded client certificate (`tls.crt`) and private
key (`tls.key`);
- a PEM-encoded CA certificate (`ca.crt`)
and whichever are supplied, will be used for connecting to the
registry. The client cert and key are useful if you are
authenticating with a certificate; the CA cert is useful if
you are using a self-signed server certificate. The Secret must
be of type `Opaque` or `kubernetes.io/tls`.
properties:
name:
description: Name of the referent.
@ -67,36 +76,39 @@ spec:
- name
type: object
ignore:
description: Ignore overrides the set of excluded patterns in the
.sourceignore format (which is the same as .gitignore). If not provided,
a default will be used, consult the documentation for your version
to find out what those are.
description: |-
Ignore overrides the set of excluded patterns in the .sourceignore format
(which is the same as .gitignore). If not provided, a default will be used,
consult the documentation for your version to find out what those are.
type: string
insecure:
description: Insecure allows connecting to a non-TLS HTTP container
registry.
type: boolean
interval:
description: Interval at which the OCIRepository URL is checked for
updates. This interval is approximate and may be subject to jitter
to ensure efficient use of resources.
description: |-
Interval at which the OCIRepository URL is checked for updates.
This interval is approximate and may be subject to jitter to ensure
efficient use of resources.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
layerSelector:
description: LayerSelector specifies which layer should be extracted
from the OCI artifact. When not specified, the first layer found
in the artifact is selected.
description: |-
LayerSelector specifies which layer should be extracted from the OCI artifact.
When not specified, the first layer found in the artifact is selected.
properties:
mediaType:
description: MediaType specifies the OCI media type of the layer
which should be extracted from the OCI Artifact. The first layer
matching this type is selected.
description: |-
MediaType specifies the OCI media type of the layer
which should be extracted from the OCI Artifact. The
first layer matching this type is selected.
type: string
operation:
description: Operation specifies how the selected layer should
be processed. By default, the layer compressed content is extracted
to storage. When the operation is set to 'copy', the layer compressed
content is persisted to storage as it is.
description: |-
Operation specifies how the selected layer should be processed.
By default, the layer compressed content is extracted to storage.
When the operation is set to 'copy', the layer compressed content
is persisted to storage as it is.
enum:
- extract
- copy
@ -104,34 +116,54 @@ spec:
type: object
provider:
default: generic
description: The provider used for authentication, can be 'aws', 'azure',
'gcp' or 'generic'. When not specified, defaults to 'generic'.
description: |-
The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'.
When not specified, defaults to 'generic'.
enum:
- generic
- aws
- azure
- gcp
type: string
proxySecretRef:
description: |-
ProxySecretRef specifies the Secret containing the proxy configuration
to use while communicating with the container registry.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
ref:
description: The OCI reference to pull and monitor for changes, defaults
to the latest tag.
description: |-
The OCI reference to pull and monitor for changes,
defaults to the latest tag.
properties:
digest:
description: Digest is the image digest to pull, takes precedence
over SemVer. The value should be in the format 'sha256:<HASH>'.
description: |-
Digest is the image digest to pull, takes precedence over SemVer.
The value should be in the format 'sha256:<HASH>'.
type: string
semver:
description: SemVer is the range of tags to pull selecting the
latest within the range, takes precedence over Tag.
description: |-
SemVer is the range of tags to pull selecting the latest within
the range, takes precedence over Tag.
type: string
semverFilter:
description: SemverFilter is a regex pattern to filter the tags
within the SemVer range.
type: string
tag:
description: Tag is the image tag to pull, defaults to latest.
type: string
type: object
secretRef:
description: SecretRef contains the secret name containing the registry
login credentials to resolve image metadata. The secret must be
of type kubernetes.io/dockerconfigjson.
description: |-
SecretRef contains the secret name containing the registry login
credentials to resolve image metadata.
The secret must be of type kubernetes.io/dockerconfigjson.
properties:
name:
description: Name of the referent.
@ -140,9 +172,10 @@ spec:
- name
type: object
serviceAccountName:
description: 'ServiceAccountName is the name of the Kubernetes ServiceAccount
used to authenticate the image pull if the service account has attached
pull secrets. For more information: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account'
description: |-
ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate
the image pull if the service account has attached pull secrets. For more information:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account
type: string
suspend:
description: This flag tells the controller to suspend the reconciliation
@ -155,35 +188,39 @@ spec:
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$
type: string
url:
description: URL is a reference to an OCI artifact repository hosted
description: |-
URL is a reference to an OCI artifact repository hosted
on a remote container registry.
pattern: ^oci://.*$
type: string
verify:
description: Verify contains the secret name containing the trusted
public keys used to verify the signature and specifies which provider
to use to check whether OCI image is authentic.
description: |-
Verify contains the secret name containing the trusted public keys
used to verify the signature and specifies which provider to use to check
whether OCI image is authentic.
properties:
matchOIDCIdentity:
description: MatchOIDCIdentity specifies the identity matching
criteria to use while verifying an OCI artifact which was signed
using Cosign keyless signing. The artifact's identity is deemed
to be verified if any of the specified matchers match against
the identity.
description: |-
MatchOIDCIdentity specifies the identity matching criteria to use
while verifying an OCI artifact which was signed using Cosign keyless
signing. The artifact's identity is deemed to be verified if any of the
specified matchers match against the identity.
items:
description: OIDCIdentityMatch specifies options for verifying
the certificate identity, i.e. the issuer and the subject
of the certificate.
description: |-
OIDCIdentityMatch specifies options for verifying the certificate identity,
i.e. the issuer and the subject of the certificate.
properties:
issuer:
description: Issuer specifies the regex pattern to match
against to verify the OIDC issuer in the Fulcio certificate.
The pattern must be a valid Go regular expression.
description: |-
Issuer specifies the regex pattern to match against to verify
the OIDC issuer in the Fulcio certificate. The pattern must be a
valid Go regular expression.
type: string
subject:
description: Subject specifies the regex pattern to match
against to verify the identity subject in the Fulcio certificate.
The pattern must be a valid Go regular expression.
description: |-
Subject specifies the regex pattern to match against to verify
the identity subject in the Fulcio certificate. The pattern must
be a valid Go regular expression.
type: string
required:
- issuer
@ -196,10 +233,12 @@ spec:
OCI Artifact.
enum:
- cosign
- notation
type: string
secretRef:
description: SecretRef specifies the Kubernetes Secret containing
the trusted public keys.
description: |-
SecretRef specifies the Kubernetes Secret containing the
trusted public keys.
properties:
name:
description: Name of the referent.
@ -228,8 +267,9 @@ spec:
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$
type: string
lastUpdateTime:
description: LastUpdateTime is the timestamp corresponding to
the last update of the Artifact.
description: |-
LastUpdateTime is the timestamp corresponding to the last update of the
Artifact.
format: date-time
type: string
metadata:
@ -238,24 +278,25 @@ spec:
description: Metadata holds upstream information such as OCI annotations.
type: object
path:
description: Path is the relative file path of the Artifact. It
can be used to locate the file in the root of the Artifact storage
on the local file system of the controller managing the Source.
description: |-
Path is the relative file path of the Artifact. It can be used to locate
the file in the root of the Artifact storage on the local file system of
the controller managing the Source.
type: string
revision:
description: Revision is a human-readable identifier traceable
in the origin source system. It can be a Git commit SHA, Git
tag, a Helm chart version, etc.
description: |-
Revision is a human-readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.
type: string
size:
description: Size is the number of bytes in the file.
format: int64
type: integer
url:
description: URL is the HTTP address of the Artifact as exposed
by the controller managing the Source. It can be used to retrieve
the Artifact for consumption, e.g. by another controller applying
the Artifact contents.
description: |-
URL is the HTTP address of the Artifact as exposed by the controller
managing the Source. It can be used to retrieve the Artifact for
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- lastUpdateTime
@ -266,43 +307,35 @@ spec:
conditions:
description: Conditions holds the conditions for the OCIRepository.
items:
description: "Condition contains details for one aspect of the current
state of this API Resource. --- This struct is intended for direct
use as an array at the field path .status.conditions. For example,
\n type FooStatus struct{ // Represents the observations of a
foo's current state. // Known .status.conditions.type are: \"Available\",
\"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
// +listType=map // +listMapKey=type Conditions []metav1.Condition
`json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: lastTransitionTime is the last time the condition
transitioned from one status to another. This should be when
the underlying condition changed. If that is not known, then
using the time when the API field changed is acceptable.
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: message is a human readable message indicating
details about the transition. This may be an empty string.
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: observedGeneration represents the .metadata.generation
that the condition was set based upon. For instance, if .metadata.generation
is currently 12, but the .status.conditions[x].observedGeneration
is 9, the condition is out of date with respect to the current
state of the instance.
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: reason contains a programmatic identifier indicating
the reason for the condition's last transition. Producers
of specific condition types may define expected values and
meanings for this field, and whether the values are considered
a guaranteed API. The value should be a CamelCase string.
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
@ -317,10 +350,6 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@ -332,43 +361,38 @@ spec:
- type
type: object
type: array
contentConfigChecksum:
description: "ContentConfigChecksum is a checksum of all the configurations
related to the content of the source artifact: - .spec.ignore -
.spec.layerSelector observed in .status.observedGeneration version
of the object. This can be used to determine if the content configuration
has changed and the artifact needs to be rebuilt. It has the format
of `<algo>:<checksum>`, for example: `sha256:<checksum>`. \n Deprecated:
Replaced with explicit fields for observed artifact content config
in the status."
type: string
lastHandledReconcileAt:
description: LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value can
be detected.
description: |-
LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value
can be detected.
type: string
observedGeneration:
description: ObservedGeneration is the last observed generation.
format: int64
type: integer
observedIgnore:
description: ObservedIgnore is the observed exclusion patterns used
for constructing the source artifact.
description: |-
ObservedIgnore is the observed exclusion patterns used for constructing
the source artifact.
type: string
observedLayerSelector:
description: ObservedLayerSelector is the observed layer selector
used for constructing the source artifact.
description: |-
ObservedLayerSelector is the observed layer selector used for constructing
the source artifact.
properties:
mediaType:
description: MediaType specifies the OCI media type of the layer
which should be extracted from the OCI Artifact. The first layer
matching this type is selected.
description: |-
MediaType specifies the OCI media type of the layer
which should be extracted from the OCI Artifact. The
first layer matching this type is selected.
type: string
operation:
description: Operation specifies how the selected layer should
be processed. By default, the layer compressed content is extracted
to storage. When the operation is set to 'copy', the layer compressed
content is persisted to storage as it is.
description: |-
Operation specifies how the selected layer should be processed.
By default, the layer compressed content is extracted to storage.
When the operation is set to 'copy', the layer compressed content
is persisted to storage as it is.
enum:
- extract
- copy
@ -384,3 +408,414 @@ spec:
storage: true
subresources:
status: {}
- additionalPrinterColumns:
- jsonPath: .spec.url
name: URL
type: string
- jsonPath: .status.conditions[?(@.type=="Ready")].status
name: Ready
type: string
- jsonPath: .status.conditions[?(@.type=="Ready")].message
name: Status
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
deprecated: true
deprecationWarning: v1beta2 OCIRepository is deprecated, upgrade to v1
name: v1beta2
schema:
openAPIV3Schema:
description: OCIRepository is the Schema for the ocirepositories API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: OCIRepositorySpec defines the desired state of OCIRepository
properties:
certSecretRef:
description: |-
CertSecretRef can be given the name of a Secret containing
either or both of
- a PEM-encoded client certificate (`tls.crt`) and private
key (`tls.key`);
- a PEM-encoded CA certificate (`ca.crt`)
and whichever are supplied, will be used for connecting to the
registry. The client cert and key are useful if you are
authenticating with a certificate; the CA cert is useful if
you are using a self-signed server certificate. The Secret must
be of type `Opaque` or `kubernetes.io/tls`.
Note: Support for the `caFile`, `certFile` and `keyFile` keys have
been deprecated.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
ignore:
description: |-
Ignore overrides the set of excluded patterns in the .sourceignore format
(which is the same as .gitignore). If not provided, a default will be used,
consult the documentation for your version to find out what those are.
type: string
insecure:
description: Insecure allows connecting to a non-TLS HTTP container
registry.
type: boolean
interval:
description: |-
Interval at which the OCIRepository URL is checked for updates.
This interval is approximate and may be subject to jitter to ensure
efficient use of resources.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
layerSelector:
description: |-
LayerSelector specifies which layer should be extracted from the OCI artifact.
When not specified, the first layer found in the artifact is selected.
properties:
mediaType:
description: |-
MediaType specifies the OCI media type of the layer
which should be extracted from the OCI Artifact. The
first layer matching this type is selected.
type: string
operation:
description: |-
Operation specifies how the selected layer should be processed.
By default, the layer compressed content is extracted to storage.
When the operation is set to 'copy', the layer compressed content
is persisted to storage as it is.
enum:
- extract
- copy
type: string
type: object
provider:
default: generic
description: |-
The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'.
When not specified, defaults to 'generic'.
enum:
- generic
- aws
- azure
- gcp
type: string
proxySecretRef:
description: |-
ProxySecretRef specifies the Secret containing the proxy configuration
to use while communicating with the container registry.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
ref:
description: |-
The OCI reference to pull and monitor for changes,
defaults to the latest tag.
properties:
digest:
description: |-
Digest is the image digest to pull, takes precedence over SemVer.
The value should be in the format 'sha256:<HASH>'.
type: string
semver:
description: |-
SemVer is the range of tags to pull selecting the latest within
the range, takes precedence over Tag.
type: string
semverFilter:
description: SemverFilter is a regex pattern to filter the tags
within the SemVer range.
type: string
tag:
description: Tag is the image tag to pull, defaults to latest.
type: string
type: object
secretRef:
description: |-
SecretRef contains the secret name containing the registry login
credentials to resolve image metadata.
The secret must be of type kubernetes.io/dockerconfigjson.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
serviceAccountName:
description: |-
ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate
the image pull if the service account has attached pull secrets. For more information:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account
type: string
suspend:
description: This flag tells the controller to suspend the reconciliation
of this source.
type: boolean
timeout:
default: 60s
description: The timeout for remote OCI Repository operations like
pulling, defaults to 60s.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$
type: string
url:
description: |-
URL is a reference to an OCI artifact repository hosted
on a remote container registry.
pattern: ^oci://.*$
type: string
verify:
description: |-
Verify contains the secret name containing the trusted public keys
used to verify the signature and specifies which provider to use to check
whether OCI image is authentic.
properties:
matchOIDCIdentity:
description: |-
MatchOIDCIdentity specifies the identity matching criteria to use
while verifying an OCI artifact which was signed using Cosign keyless
signing. The artifact's identity is deemed to be verified if any of the
specified matchers match against the identity.
items:
description: |-
OIDCIdentityMatch specifies options for verifying the certificate identity,
i.e. the issuer and the subject of the certificate.
properties:
issuer:
description: |-
Issuer specifies the regex pattern to match against to verify
the OIDC issuer in the Fulcio certificate. The pattern must be a
valid Go regular expression.
type: string
subject:
description: |-
Subject specifies the regex pattern to match against to verify
the identity subject in the Fulcio certificate. The pattern must
be a valid Go regular expression.
type: string
required:
- issuer
- subject
type: object
type: array
provider:
default: cosign
description: Provider specifies the technology used to sign the
OCI Artifact.
enum:
- cosign
- notation
type: string
secretRef:
description: |-
SecretRef specifies the Kubernetes Secret containing the
trusted public keys.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
required:
- provider
type: object
required:
- interval
- url
type: object
status:
default:
observedGeneration: -1
description: OCIRepositoryStatus defines the observed state of OCIRepository
properties:
artifact:
description: Artifact represents the output of the last successful
OCI Repository sync.
properties:
digest:
description: Digest is the digest of the file in the form of '<algorithm>:<checksum>'.
pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$
type: string
lastUpdateTime:
description: |-
LastUpdateTime is the timestamp corresponding to the last update of the
Artifact.
format: date-time
type: string
metadata:
additionalProperties:
type: string
description: Metadata holds upstream information such as OCI annotations.
type: object
path:
description: |-
Path is the relative file path of the Artifact. It can be used to locate
the file in the root of the Artifact storage on the local file system of
the controller managing the Source.
type: string
revision:
description: |-
Revision is a human-readable identifier traceable in the origin source
system. It can be a Git commit SHA, Git tag, a Helm chart version, etc.
type: string
size:
description: Size is the number of bytes in the file.
format: int64
type: integer
url:
description: |-
URL is the HTTP address of the Artifact as exposed by the controller
managing the Source. It can be used to retrieve the Artifact for
consumption, e.g. by another controller applying the Artifact contents.
type: string
required:
- lastUpdateTime
- path
- revision
- url
type: object
conditions:
description: Conditions holds the conditions for the OCIRepository.
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
contentConfigChecksum:
description: |-
ContentConfigChecksum is a checksum of all the configurations related to
the content of the source artifact:
- .spec.ignore
- .spec.layerSelector
observed in .status.observedGeneration version of the object. This can
be used to determine if the content configuration has changed and the
artifact needs to be rebuilt.
It has the format of `<algo>:<checksum>`, for example: `sha256:<checksum>`.
Deprecated: Replaced with explicit fields for observed artifact content
config in the status.
type: string
lastHandledReconcileAt:
description: |-
LastHandledReconcileAt holds the value of the most recent
reconcile request value, so a change of the annotation value
can be detected.
type: string
observedGeneration:
description: ObservedGeneration is the last observed generation.
format: int64
type: integer
observedIgnore:
description: |-
ObservedIgnore is the observed exclusion patterns used for constructing
the source artifact.
type: string
observedLayerSelector:
description: |-
ObservedLayerSelector is the observed layer selector used for constructing
the source artifact.
properties:
mediaType:
description: |-
MediaType specifies the OCI media type of the layer
which should be extracted from the OCI Artifact. The
first layer matching this type is selected.
type: string
operation:
description: |-
Operation specifies how the selected layer should be processed.
By default, the layer compressed content is extracted to storage.
When the operation is set to 'copy', the layer compressed content
is persisted to storage as it is.
enum:
- extract
- copy
type: string
type: object
url:
description: URL is the download link for the artifact output of the
last OCI Repository sync.
type: string
type: object
type: object
served: true
storage: false
subresources:
status: {}

View File

@ -6,4 +6,4 @@ resources:
images:
- name: fluxcd/source-controller
newName: fluxcd/source-controller
newTag: v1.2.0
newTag: v1.6.0

View File

@ -19,129 +19,19 @@ rules:
- get
- list
- watch
- apiGroups:
- ""
resources:
- serviceaccounts/token
verbs:
- create
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- buckets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- buckets/finalizers
verbs:
- create
- delete
- get
- patch
- update
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- buckets/status
verbs:
- get
- patch
- update
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- gitrepositories
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- gitrepositories/finalizers
verbs:
- create
- delete
- get
- patch
- update
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- gitrepositories/status
verbs:
- get
- patch
- update
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- helmcharts
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- helmcharts/finalizers
verbs:
- create
- delete
- get
- patch
- update
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- helmcharts/status
verbs:
- get
- patch
- update
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- helmrepositories
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- helmrepositories/finalizers
verbs:
- create
- delete
- get
- patch
- update
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- helmrepositories/status
verbs:
- get
- patch
- update
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- ocirepositories
verbs:
- create
@ -154,6 +44,10 @@ rules:
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- buckets/finalizers
- gitrepositories/finalizers
- helmcharts/finalizers
- helmrepositories/finalizers
- ocirepositories/finalizers
verbs:
- create
@ -164,6 +58,10 @@ rules:
- apiGroups:
- source.toolkit.fluxcd.io
resources:
- buckets/status
- gitrepositories/status
- helmcharts/status
- helmrepositories/status
- ocirepositories/status
verbs:
- get

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: Bucket
metadata:
name: bucket-sample

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: helmchart-git-sample

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: helmchart-sample-oci

View File

@ -1,11 +1,12 @@
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: helmchart-sample
spec:
chart: podinfo
version: '>=2.0.0 <3.0.0'
version: '6.x'
sourceRef:
kind: HelmRepository
name: helmrepository-sample
interval: 1m
ignoreMissingValuesFiles: true

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: helmrepository-sample-oci

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: helmrepository-sample

View File

@ -1,4 +1,4 @@
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: ocirepository-sample

View File

@ -1,5 +1,5 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
apiVersion: source.toolkit.fluxcd.io/v1
kind: Bucket
metadata:
name: podinfo

View File

@ -1,13 +1,10 @@
apiVersion: source.toolkit.fluxcd.io/v1beta1
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: large-repo
spec:
interval: 10m
timeout: 2m
url: https://github.com/hashgraph/hedera-mirror-node.git
url: https://github.com/nodejs/node.git
ref:
branch: main
ignore: |
/*
!/charts

View File

@ -1,5 +1,5 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
apiVersion: source.toolkit.fluxcd.io/v1
kind: Bucket
metadata:
name: charts
@ -13,7 +13,7 @@ spec:
secretRef:
name: minio-credentials
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: helmchart-bucket

View File

@ -0,0 +1,25 @@
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: podinfo-notation
spec:
url: oci://ghcr.io/stefanprodan/charts
type: "oci"
interval: 1m
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: podinfo-notation
spec:
chart: podinfo
sourceRef:
kind: HelmRepository
name: podinfo-notation
version: '6.6.0'
interval: 1m
verify:
provider: notation
secretRef:
name: notation-config

View File

@ -1,5 +1,5 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: podinfo
@ -8,7 +8,7 @@ spec:
type: "oci"
interval: 1m
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: podinfo
@ -20,7 +20,7 @@ spec:
version: '6.1.*'
interval: 1m
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: podinfo-keyless

View File

@ -1,5 +1,5 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: podinfo-deploy-signed-with-key

View File

@ -1,5 +1,5 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: podinfo-deploy-signed-with-keyless

View File

@ -0,0 +1,14 @@
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: podinfo-deploy-signed-with-notation
spec:
interval: 5m
url: oci://ghcr.io/stefanprodan/podinfo-deploy
ref:
semver: "6.6.x"
verify:
provider: notation
secretRef:
name: notation-config

File diff suppressed because it is too large Load Diff

View File

@ -114,6 +114,23 @@ string
</tr>
<tr>
<td>
<code>sts</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1beta2.BucketSTSSpec">
BucketSTSSpec
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>STS specifies the required configuration to use a Security Token
Service for fetching temporary credentials to authenticate in a
Bucket provider.</p>
<p>This field is only supported for the <code>aws</code> and <code>generic</code> providers.</p>
</td>
</tr>
<tr>
<td>
<code>insecure</code><br>
<em>
bool
@ -165,6 +182,47 @@ for the Bucket.</p>
</tr>
<tr>
<td>
<code>certSecretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
github.com/fluxcd/pkg/apis/meta.LocalObjectReference
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>CertSecretRef can be given the name of a Secret containing
either or both of</p>
<ul>
<li>a PEM-encoded client certificate (<code>tls.crt</code>) and private
key (<code>tls.key</code>);</li>
<li>a PEM-encoded CA certificate (<code>ca.crt</code>)</li>
</ul>
<p>and whichever are supplied, will be used for connecting to the
bucket. The client cert and key are useful if you are
authenticating with a certificate; the CA cert is useful if
you are using a self-signed server certificate. The Secret must
be of type <code>Opaque</code> or <code>kubernetes.io/tls</code>.</p>
<p>This field is only supported for the <code>generic</code> provider.</p>
</td>
</tr>
<tr>
<td>
<code>proxySecretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
github.com/fluxcd/pkg/apis/meta.LocalObjectReference
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>ProxySecretRef specifies the Secret containing the proxy configuration
to use while communicating with the Bucket server.</p>
</td>
</tr>
<tr>
<td>
<code>interval</code><br>
<em>
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Duration">
@ -660,6 +718,19 @@ is merged before the ValuesFiles items. Ignored when omitted.</p>
</tr>
<tr>
<td>
<code>ignoreMissingValuesFiles</code><br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>IgnoreMissingValuesFiles controls whether to silently ignore missing values
files rather than failing.</p>
</td>
</tr>
<tr>
<td>
<code>suspend</code><br>
<em>
bool
@ -691,8 +762,8 @@ NOTE: Not implemented, provisional as of <a href="https://github.com/fluxcd/flux
<td>
<code>verify</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1beta2.OCIRepositoryVerification">
OCIRepositoryVerification
<a href="https://pkg.go.dev/github.com/fluxcd/source-controller/api/v1#OCIRepositoryVerification">
github.com/fluxcd/source-controller/api/v1.OCIRepositoryVerification
</a>
</em>
</td>
@ -1109,8 +1180,8 @@ The secret must be of type kubernetes.io/dockerconfigjson.</p>
<td>
<code>verify</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1beta2.OCIRepositoryVerification">
OCIRepositoryVerification
<a href="https://pkg.go.dev/github.com/fluxcd/source-controller/api/v1#OCIRepositoryVerification">
github.com/fluxcd/source-controller/api/v1.OCIRepositoryVerification
</a>
</em>
</td>
@ -1164,6 +1235,21 @@ been deprecated.</p>
</tr>
<tr>
<td>
<code>proxySecretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
github.com/fluxcd/pkg/apis/meta.LocalObjectReference
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>ProxySecretRef specifies the Secret containing the proxy configuration
to use while communicating with the container registry.</p>
</td>
</tr>
<tr>
<td>
<code>interval</code><br>
<em>
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Duration">
@ -1369,6 +1455,94 @@ map[string]string
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1beta2.BucketSTSSpec">BucketSTSSpec
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1beta2.BucketSpec">BucketSpec</a>)
</p>
<p>BucketSTSSpec specifies the required configuration to use a Security Token
Service for fetching temporary credentials to authenticate in a Bucket
provider.</p>
<div class="md-typeset__scrollwrap">
<div class="md-typeset__table">
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>provider</code><br>
<em>
string
</em>
</td>
<td>
<p>Provider of the Security Token Service.</p>
</td>
</tr>
<tr>
<td>
<code>endpoint</code><br>
<em>
string
</em>
</td>
<td>
<p>Endpoint is the HTTP/S endpoint of the Security Token Service from
where temporary credentials will be fetched.</p>
</td>
</tr>
<tr>
<td>
<code>secretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
github.com/fluxcd/pkg/apis/meta.LocalObjectReference
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>SecretRef specifies the Secret containing authentication credentials
for the STS endpoint. This Secret must contain the fields <code>username</code>
and <code>password</code> and is supported only for the <code>ldap</code> provider.</p>
</td>
</tr>
<tr>
<td>
<code>certSecretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
github.com/fluxcd/pkg/apis/meta.LocalObjectReference
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>CertSecretRef can be given the name of a Secret containing
either or both of</p>
<ul>
<li>a PEM-encoded client certificate (<code>tls.crt</code>) and private
key (<code>tls.key</code>);</li>
<li>a PEM-encoded CA certificate (<code>ca.crt</code>)</li>
</ul>
<p>and whichever are supplied, will be used for connecting to the
STS endpoint. The client cert and key are useful if you are
authenticating with a certificate; the CA cert is useful if
you are using a self-signed server certificate. The Secret must
be of type <code>Opaque</code> or <code>kubernetes.io/tls</code>.</p>
<p>This field is only supported for the <code>ldap</code> provider.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1beta2.BucketSpec">BucketSpec
</h3>
<p>
@ -1425,6 +1599,23 @@ string
</tr>
<tr>
<td>
<code>sts</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1beta2.BucketSTSSpec">
BucketSTSSpec
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>STS specifies the required configuration to use a Security Token
Service for fetching temporary credentials to authenticate in a
Bucket provider.</p>
<p>This field is only supported for the <code>aws</code> and <code>generic</code> providers.</p>
</td>
</tr>
<tr>
<td>
<code>insecure</code><br>
<em>
bool
@ -1476,6 +1667,47 @@ for the Bucket.</p>
</tr>
<tr>
<td>
<code>certSecretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
github.com/fluxcd/pkg/apis/meta.LocalObjectReference
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>CertSecretRef can be given the name of a Secret containing
either or both of</p>
<ul>
<li>a PEM-encoded client certificate (<code>tls.crt</code>) and private
key (<code>tls.key</code>);</li>
<li>a PEM-encoded CA certificate (<code>ca.crt</code>)</li>
</ul>
<p>and whichever are supplied, will be used for connecting to the
bucket. The client cert and key are useful if you are
authenticating with a certificate; the CA cert is useful if
you are using a self-signed server certificate. The Secret must
be of type <code>Opaque</code> or <code>kubernetes.io/tls</code>.</p>
<p>This field is only supported for the <code>generic</code> provider.</p>
</td>
</tr>
<tr>
<td>
<code>proxySecretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
github.com/fluxcd/pkg/apis/meta.LocalObjectReference
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>ProxySecretRef specifies the Secret containing the proxy configuration
to use while communicating with the Bucket server.</p>
</td>
</tr>
<tr>
<td>
<code>interval</code><br>
<em>
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Duration">
@ -2329,6 +2561,19 @@ is merged before the ValuesFiles items. Ignored when omitted.</p>
</tr>
<tr>
<td>
<code>ignoreMissingValuesFiles</code><br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>IgnoreMissingValuesFiles controls whether to silently ignore missing values
files rather than failing.</p>
</td>
</tr>
<tr>
<td>
<code>suspend</code><br>
<em>
bool
@ -2360,8 +2605,8 @@ NOTE: Not implemented, provisional as of <a href="https://github.com/fluxcd/flux
<td>
<code>verify</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1beta2.OCIRepositoryVerification">
OCIRepositoryVerification
<a href="https://pkg.go.dev/github.com/fluxcd/source-controller/api/v1#OCIRepositoryVerification">
github.com/fluxcd/source-controller/api/v1.OCIRepositoryVerification
</a>
</em>
</td>
@ -2436,6 +2681,20 @@ resolved chart reference.</p>
</tr>
<tr>
<td>
<code>observedValuesFiles</code><br>
<em>
[]string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ObservedValuesFiles are the observed value files of the last successful
reconciliation.
It matches the chart in the last successfully reconciled artifact.</p>
</td>
</tr>
<tr>
<td>
<code>conditions</code><br>
<em>
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Condition">
@ -2938,6 +3197,18 @@ the range, takes precedence over Tag.</p>
</tr>
<tr>
<td>
<code>semverFilter</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>SemverFilter is a regex pattern to filter the tags within the SemVer range.</p>
</td>
</tr>
<tr>
<td>
<code>tag</code><br>
<em>
string
@ -3044,8 +3315,8 @@ The secret must be of type kubernetes.io/dockerconfigjson.</p>
<td>
<code>verify</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1beta2.OCIRepositoryVerification">
OCIRepositoryVerification
<a href="https://pkg.go.dev/github.com/fluxcd/source-controller/api/v1#OCIRepositoryVerification">
github.com/fluxcd/source-controller/api/v1.OCIRepositoryVerification
</a>
</em>
</td>
@ -3099,6 +3370,21 @@ been deprecated.</p>
</tr>
<tr>
<td>
<code>proxySecretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
github.com/fluxcd/pkg/apis/meta.LocalObjectReference
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>ProxySecretRef specifies the Secret containing the proxy configuration
to use while communicating with the container registry.</p>
</td>
</tr>
<tr>
<td>
<code>interval</code><br>
<em>
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Duration">
@ -3305,119 +3591,6 @@ github.com/fluxcd/pkg/apis/meta.ReconcileRequestStatus
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1beta2.OCIRepositoryVerification">OCIRepositoryVerification
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1beta2.HelmChartSpec">HelmChartSpec</a>,
<a href="#source.toolkit.fluxcd.io/v1beta2.OCIRepositorySpec">OCIRepositorySpec</a>)
</p>
<p>OCIRepositoryVerification verifies the authenticity of an OCI Artifact</p>
<div class="md-typeset__scrollwrap">
<div class="md-typeset__table">
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>provider</code><br>
<em>
string
</em>
</td>
<td>
<p>Provider specifies the technology used to sign the OCI Artifact.</p>
</td>
</tr>
<tr>
<td>
<code>secretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
github.com/fluxcd/pkg/apis/meta.LocalObjectReference
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>SecretRef specifies the Kubernetes Secret containing the
trusted public keys.</p>
</td>
</tr>
<tr>
<td>
<code>matchOIDCIdentity</code><br>
<em>
<a href="#source.toolkit.fluxcd.io/v1beta2.OIDCIdentityMatch">
[]OIDCIdentityMatch
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>MatchOIDCIdentity specifies the identity matching criteria to use
while verifying an OCI artifact which was signed using Cosign keyless
signing. The artifact&rsquo;s identity is deemed to be verified if any of the
specified matchers match against the identity.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1beta2.OIDCIdentityMatch">OIDCIdentityMatch
</h3>
<p>
(<em>Appears on:</em>
<a href="#source.toolkit.fluxcd.io/v1beta2.OCIRepositoryVerification">OCIRepositoryVerification</a>)
</p>
<p>OIDCIdentityMatch specifies options for verifying the certificate identity,
i.e. the issuer and the subject of the certificate.</p>
<div class="md-typeset__scrollwrap">
<div class="md-typeset__table">
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>issuer</code><br>
<em>
string
</em>
</td>
<td>
<p>Issuer specifies the regex pattern to match against to verify
the OIDC issuer in the Fulcio certificate. The pattern must be a
valid Go regular expression.</p>
</td>
</tr>
<tr>
<td>
<code>subject</code><br>
<em>
string
</em>
</td>
<td>
<p>Subject specifies the regex pattern to match against to verify
the identity subject in the Fulcio certificate. The pattern must
be a valid Go regular expression.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 id="source.toolkit.fluxcd.io/v1beta2.Source">Source
</h3>
<p>Source interface must be supported by all API types.

View File

@ -6,6 +6,10 @@ This is the v1 API specification for defining the desired state sources of Kuber
* Source kinds:
+ [GitRepository](gitrepositories.md)
+ [OCIRepository](ocirepositories.md)
+ [HelmRepository](helmrepositories.md)
+ [HelmChart](helmcharts.md)
+ [Bucket](buckets.md)
## Implementation

1385
docs/spec/v1/buckets.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -177,6 +177,31 @@ data:
ca.crt: <BASE64>
```
#### HTTPS Mutual TLS authentication
To authenticate towards a Git repository over HTTPS using mutual TLS,
the referenced Secret's `.data` should contain the following keys:
* `tls.crt` and `tls.key`, to specify the client certificate and private key used
for TLS client authentication. These must be used in conjunction, i.e.
specifying one without the other will lead to an error.
* `ca.crt`, to specify the CA certificate used to verify the server, which is
required if the server is using a self-signed certificate.
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: https-tls-certs
namespace: default
type: Opaque
data:
tls.crt: <BASE64>
tls.key: <BASE64>
ca.crt: <BASE64>
```
#### SSH authentication
To authenticate towards a Git repository over SSH, the referenced Secret is
@ -212,6 +237,153 @@ For password-protected SSH private keys, the password must be provided
via an additional `password` field in the secret. Flux CLI also supports
this via the `--password` flag.
### Provider
`.spec.provider` is an optional field that allows specifying an OIDC provider
used for authentication purposes.
Supported options are:
- `generic`
- `azure`
- `github`
When provider is not specified, it defaults to `generic` indicating that
mechanisms using `spec.secretRef` are used for authentication.
For a complete guide on how to set up authentication for cloud providers,
see the integration [docs](/flux/integrations/).
#### Azure
The `azure` provider can be used to authenticate to Azure DevOps repositories
automatically using Workload Identity.
##### Pre-requisites
- Ensure that your Azure DevOps Organization is
[connected](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/connect-organization-to-azure-ad?view=azure-devops)
to Microsoft Entra.
- Ensure Workload Identity is properly [set up on your
cluster](https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster#create-an-aks-cluster).
##### Configure Flux controller
- Create a managed identity to access Azure DevOps. Establish a federated
identity credential between the managed identity and the source-controller
service account. In the default installation, the source-controller service
account is located in the `flux-system` namespace with name
`source-controller`. Ensure the federated credential uses the correct
namespace and name of the source-controller service account. For more details,
please refer to this
[guide](https://azure.github.io/azure-workload-identity/docs/quick-start.html#6-establish-federated-identity-credential-between-the-identity-and-the-service-account-issuer--subject).
- Add the managed identity to the Azure DevOps organization as a user. Ensure
that the managed identity has the necessary permissions to access the Azure
DevOps repository as described
[here](https://learn.microsoft.com/en-us/azure/devops/integrate/get-started/authentication/service-principal-managed-identity?view=azure-devops#2-add-and-manage-service-principals-in-an-azure-devops-organization).
- Add the following patch to your bootstrap repository in
`flux-system/kustomization.yaml` file:
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gotk-components.yaml
- gotk-sync.yaml
patches:
- patch: |-
apiVersion: v1
kind: ServiceAccount
metadata:
name: source-controller
namespace: flux-system
annotations:
azure.workload.identity/client-id: <AZURE_CLIENT_ID>
labels:
azure.workload.identity/use: "true"
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: source-controller
namespace: flux-system
labels:
azure.workload.identity/use: "true"
spec:
template:
metadata:
labels:
azure.workload.identity/use: "true"
```
**Note:** When azure `provider` is used with `GitRepository`, the `.spec.url`
must follow this format:
```
https://dev.azure.com/{your-organization}/{your-project}/_git/{your-repository}
```
#### GitHub
The `github` provider can be used to authenticate to Git repositories using
[GitHub Apps](https://docs.github.com/en/apps/overview).
##### Pre-requisites
- [Register](https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app)
the GitHub App with the necessary permissions and [generate a private
key](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps)
for the app.
- [Install](https://docs.github.com/en/apps/using-github-apps/installing-your-own-github-app)
the app in the organization/account configuring access to the necessary
repositories.
##### Configure GitHub App secret
The GitHub App information is specified in `.spec.secretRef` in the format
specified below:
- Get the App ID from the app settings page at
`https://github.com/settings/apps/<app-name>`.
- Get the App Installation ID from the app installations page at
`https://github.com/settings/installations`. Click the installed app, the URL
will contain the installation ID
`https://github.com/settings/installations/<installation-id>`. For
organizations, the first part of the URL may be different, but it follows the
same pattern.
- The private key that was generated in the pre-requisites.
- (Optional) GitHub Enterprise Server users can set the base URL to
`http(s)://HOSTNAME/api/v3`.
```yaml
apiVersion: v1
kind: Secret
metadata:
name: github-sa
type: Opaque
stringData:
githubAppID: "<app-id>"
githubAppInstallationID: "<app-installation-id>"
githubAppPrivateKey: |
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
githubAppBaseURL: "<github-enterprise-api-url>" #optional, required only for GitHub Enterprise Server users
```
Alternatively, the Flux CLI can be used to automatically create the secret with
the github app authentication information.
```sh
flux create secret githubapp ghapp-secret \
--app-id=1 \
--app-installation-id=3 \
--app-private-key=~/private-key.pem
```
### Interval
`.spec.interval` is a required field that specifies the interval at which the
@ -446,6 +618,28 @@ list](#default-exclusions), and may overrule the [`.sourceignore` file
exclusions](#sourceignore-file). See [excluding files](#excluding-files)
for more information.
### Sparse checkout
`.spec.sparseCheckout` is an optional field to specify list of directories to
checkout when cloning the repository. If specified, only the specified directory
contents will be present in the artifact produced for this repository.
```yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: podinfo
namespace: default
spec:
interval: 5m
url: https://github.com/stefanprodan/podinfo
ref:
branch: master
sparseCheckout:
- charts
- kustomize
```
### Suspend
`.spec.suspend` is an optional field to suspend the reconciliation of a
@ -988,6 +1182,27 @@ status:
...
```
### Observed Sparse Checkout
The source-controller reports observed sparse checkout in the GitRepository's
`.status.observedSparseCheckout`. The observed sparse checkout is the latest
`.spec.sparseCheckout` value which resulted in a [ready
state](#ready-gitrepository), or stalled due to error it can not recover from
without human intervention. The value is the same as the [sparseCheckout in
spec](#sparse-checkout). It indicates the sparse checkout configuration used in
building the current artifact in storage. It is also used by the controller to
determine if an artifact needs to be rebuilt.
Example:
```yaml
status:
...
observedSparseCheckout:
- charts
- kustomize
...
```
### Source Verification Mode
The source-controller reports the Git object(s) it verified in the Git

865
docs/spec/v1/helmcharts.md Normal file
View File

@ -0,0 +1,865 @@
# Helm Charts
<!-- menuweight:50 -->
The `HelmChart` API defines a Source to produce an Artifact for a Helm chart
archive with a set of specific configurations.
## Example
The following is an example of a HelmChart. It fetches and/or packages a Helm
chart and exposes it as a tarball (`.tgz`) Artifact for the specified
configuration:
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: podinfo
namespace: default
spec:
interval: 5m0s
chart: podinfo
reconcileStrategy: ChartVersion
sourceRef:
kind: HelmRepository
name: podinfo
version: '5.*'
```
In the above example:
- A HelmChart named `podinfo` is created, indicated by the `.metadata.name`
field.
- The source-controller fetches the Helm chart every five minutes from the
`podinfo` HelmRepository source reference, indicated by the
`.spec.sourceRef.kind` and `.spec.sourceRef.name` fields.
- The fetched Helm chart version is the latest available chart
version in the range specified in `spec.version`. This version is also used as
Artifact revision, reported in-cluster in the `.status.artifact.revision`
field.
- When the current Helm Chart version differs from the latest available chart
in the version range, it is fetched and/or packaged as a new Artifact.
- The new Artifact is reported in the `.status.artifact` field.
You can run this example by saving the manifest into `helmchart.yaml`.
**Note:** HelmChart is usually used by the helm-controller. Based on the
HelmRelease configuration, an associated HelmChart is created by the
helm-controller.
1. Apply the resource on the cluster:
```sh
kubectl apply -f helmchart.yaml
```
2. Run `kubectl get helmchart` to see the HelmChart:
```console
NAME CHART VERSION SOURCE KIND SOURCE NAME AGE READY STATUS
podinfo podinfo 5.* HelmRepository podinfo 53s True pulled 'podinfo' chart with version '5.2.1'
```
3. Run `kubectl describe helmchart podinfo` to see the [Artifact](#artifact) and
[Conditions](#conditions) in the HelmChart's Status:
```console
Status:
Observed Source Artifact Revision: sha256:83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111
Artifact:
Digest: sha256:6c3cc3b955bce1686036ae6822ee2ca0ef6ecb994e3f2d19eaf3ec03dcba84b3
Last Update Time: 2022-02-13T11:24:10Z
Path: helmchart/default/podinfo/podinfo-5.2.1.tgz
Revision: 5.2.1
Size: 14166
URL: http://source-controller.flux-system.svc.cluster.local./helmchart/default/podinfo/podinfo-5.2.1.tgz
Conditions:
Last Transition Time: 2022-02-13T11:24:10Z
Message: pulled 'podinfo' chart with version '5.2.1'
Observed Generation: 1
Reason: ChartPullSucceeded
Status: True
Type: Ready
Last Transition Time: 2022-02-13T11:24:10Z
Message: pulled 'podinfo' chart with version '5.2.1'
Observed Generation: 1
Reason: ChartPullSucceeded
Status: True
Type: ArtifactInStorage
Observed Chart Name: podinfo
Observed Generation: 1
URL: http://source-controller.flux-system.svc.cluster.local./helmchart/default/podinfo/latest.tar.gz
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ChartPullSucceeded 2m51s source-controller pulled 'podinfo' chart with version '5.2.1'
```
## Writing a HelmChart spec
As with all other Kubernetes config, a HelmChart needs `apiVersion`, `kind`, and
`metadata` fields. The name of a HelmChart object must be a valid
[DNS subdomain name](https://kubernetes.io/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
A HelmChart also needs a
[`.spec` section](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status).
### Source reference
`.spec.sourceRef` is a required field that specifies a reference to the Source
the chart is available at.
Supported references are:
- [`HelmRepository`](helmrepositories.md)
- [`GitRepository`](gitrepositories.md)
- [`Bucket`](buckets.md)
Although there are three kinds of source references, there are only two
underlying implementations. The artifact building process for `GitRepository`
and `Bucket` are the same as they are already built source artifacts. In case
of `HelmRepository`, a chart is fetched and/or packaged based on the
configuration of the Helm chart.
For a `HelmChart` to be reconciled, the associated artifact in the source
reference must be ready. If the source artifact is not ready, the `HelmChart`
reconciliation is retried.
When the `metadata.generation` of the `HelmChart` don't match with the
`status.observedGeneration`, the chart is fetched from source and/or packaged.
If there's no `.spec.valuesFiles` specified, the chart is only fetched from the
source, and not packaged. If `.spec.valuesFiles` are specified, the chart is
fetched and packaged with the values files. When the `metadata.generation`
matches the `status.observedGeneration`, the chart is only fetched from source
or from the cache if available, and not packaged.
When using a `HelmRepository` source reference, the secret reference defined in
the Helm repository is used to fetch the chart.
The HelmChart reconciliation behavior varies depending on the source reference
kind, see [reconcile strategy](#reconcile-strategy).
The attributes of the generated artifact also varies depending on the source
reference kind, see [artifact](#artifact).
### Chart
`.spec.chart` is a required field that specifies the name or path the Helm chart
is available at in the [Source reference](#source-reference).
For `HelmRepository` Source reference, it'll be just the name of the chart.
```yaml
spec:
chart: podinfo
sourceRef:
name: podinfo
kind: HelmRepository
```
For `GitRepository` and `Bucket` Source reference, it'll be the path to the
Helm chart directory.
```yaml
spec:
chart: ./charts/podinfo
sourceRef:
name: podinfo
kind: <GitRepository|Bucket>
```
### Version
`.spec.version` is an optional field to specify the version of the chart in
semver. It is applicable only when the Source reference is a `HelmRepository`.
It is ignored for `GitRepository` and `Bucket` Source reference. It defaults to
the latest version of the chart with value `*`.
Version can be a fixed semver, minor or patch semver range of a specific
version (i.e. `4.0.x`) or any semver range (i.e. `>=4.0.0 <5.0.0`).
### Values files
`.spec.valuesFiles` is an optional field to specify an alternative list of
values files to use as the chart values (values.yaml). The file paths are
expected to be relative to the Source reference. Values files are merged in the
order of the list with the last file overriding the first. It is ignored when
omitted. When values files are specified, the chart is fetched and packaged
with the provided values.
```yaml
spec:
chart:
spec:
chart: podinfo
...
valuesFiles:
- values.yaml
- values-production.yaml
```
Values files also affect the generated artifact revision, see
[artifact](#artifact).
### Ignore missing values files
`.spec.ignoreMissingValuesFiles` is an optional field to specify whether missing
values files should be ignored rather than be considered errors. It defaults to
`false`.
When `.spec.valuesFiles` and `.spec.ignoreMissingValuesFiles` are specified,
the `.status.observedValuesFiles` field is populated with the list of values
files that were found and actually contributed to the packaged chart.
### Reconcile strategy
`.spec.reconcileStrategy` is an optional field to specify what enables the
creation of a new Artifact. Valid values are `ChartVersion` and `Revision`.
`ChartVersion` is used for creating a new artifact when the chart version
changes in a `HelmRepository`. `Revision` is used for creating a new artifact
when the source revision changes in a `GitRepository` or a `Bucket` Source. It
defaults to `ChartVersion`.
**Note:** If the reconcile strategy is `ChartVersion` and the source reference
is a `GitRepository` or a `Bucket`, no new chart artifact is produced on updates
to the source unless the `version` in `Chart.yaml` is incremented. To produce
new chart artifact on change in source revision, set the reconcile strategy to
`Revision`.
Reconcile strategy also affects the artifact version, see [artifact](#artifact)
for more details.
### Interval
`.spec.interval` is a required field that specifies the interval at which the
Helm Chart source must be checked for updates.
After successfully reconciling a HelmChart object, the source-controller
requeues the object for inspection after the specified interval. The value must
be in a [Go recognized duration string format](https://pkg.go.dev/time#ParseDuration),
e.g. `10m0s` to look at the source for updates every 10 minutes.
If the `.metadata.generation` of a resource changes (due to e.g. applying a
change to the spec), this is handled instantly outside the interval window.
**Note:** The controller can be configured to apply a jitter to the interval in
order to distribute the load more evenly when multiple HelmChart objects are set
up with the same interval. For more information, please refer to the
[source-controller configuration options](https://fluxcd.io/flux/components/source/options/).
### Suspend
`.spec.suspend` is an optional field to suspend the reconciliation of a
HelmChart. When set to `true`, the controller will stop reconciling the
HelmChart, and changes to the resource or the Helm chart Source will not result
in a new Artifact. When the field is set to `false` or removed, it will resume.
For practical information, see
[suspending and resuming](#suspending-and-resuming).
### Verification
**Note:** This feature is available only for Helm charts fetched from an OCI Registry.
`.spec.verify` is an optional field to enable the verification of [Cosign](https://github.com/sigstore/cosign) or [Notation](https://github.com/notaryproject/notation)
signatures. The field offers three subfields:
- `.provider`, to specify the verification provider. The supported options are `cosign` and `notation` at present.
- `.secretRef.name`, to specify a reference to a Secret in the same namespace as
the HelmChart, containing the public keys of trusted authors. For Notation this Secret should also include the [trust policy](https://github.com/notaryproject/specifications/blob/v1.0.0/specs/trust-store-trust-policy.md#trust-policy) in
addition to the CA certificate.
- `.matchOIDCIdentity`, to specify a list of OIDC identity matchers (only supported when using `cosign` as the verification provider). Please see
[Keyless verification](#keyless-verification) for more details.
#### Cosign
The `cosign` provider can be used to verify the signature of an OCI artifact using either a known public key or via the [Cosign Keyless](https://github.com/sigstore/cosign/blob/main/KEYLESS.md) procedure.
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: podinfo
spec:
verify:
provider: cosign
secretRef:
name: cosign-public-keys
```
When the verification succeeds, the controller adds a Condition with the
following attributes to the HelmChart's `.status.conditions`:
- `type: SourceVerified`
- `status: "True"`
- `reason: Succeeded`
##### Public keys verification
To verify the authenticity of HelmChart hosted in an OCI Registry, create a Kubernetes
secret with the Cosign public keys:
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: cosign-public-keys
type: Opaque
data:
key1.pub: <BASE64>
key2.pub: <BASE64>
```
Note that the keys must have the `.pub` extension for Flux to make use of them.
Flux will loop over the public keys and use them to verify a HelmChart's signature.
This allows for older HelmCharts to be valid as long as the right key is in the secret.
##### Keyless verification
For publicly available HelmCharts, which are signed using the
[Cosign Keyless](https://github.com/sigstore/cosign/blob/main/KEYLESS.md) procedure,
you can enable the verification by omitting the `.verify.secretRef` field.
To verify the identity's subject and the OIDC issuer present in the Fulcio
certificate, you can specify a list of OIDC identity matchers using
`.spec.verify.matchOIDCIdentity`. The matcher provides two required fields:
- `.issuer`, to specify a regexp that matches against the OIDC issuer.
- `.subject`, to specify a regexp that matches against the subject identity in
the certificate.
Both values should follow the [Go regular expression syntax](https://golang.org/s/re2syntax).
The matchers are evaluated in an OR fashion, i.e. the identity is deemed to be
verified if any one matcher successfully matches against the identity.
Example of verifying HelmCharts signed by the
[Cosign GitHub Action](https://github.com/sigstore/cosign-installer) with GitHub OIDC Token:
```yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: podinfo
spec:
interval: 5m
chart: podinfo
reconcileStrategy: ChartVersion
sourceRef:
kind: HelmRepository
name: podinfo
version: ">=6.1.6"
verify:
provider: cosign
matchOIDCIdentity:
- issuer: "^https://token.actions.githubusercontent.com$"
subject: "^https://github.com/stefanprodan/podinfo.*$"
```
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: podinfo
spec:
interval: 1m0s
url: oci://ghcr.io/stefanprodan/charts
type: "oci"
```
The controller verifies the signatures using the Fulcio root CA and the Rekor
instance hosted at [rekor.sigstore.dev](https://rekor.sigstore.dev/).
Note that keyless verification is an **experimental feature**, using
custom root CAs or self-hosted Rekor instances are not currently supported.
#### Notation
The `notation` provider can be used to verify the signature of an OCI artifact using known
trust policy and CA certificate.
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: podinfo
spec:
verify:
provider: notation
secretRef:
name: notation-config
```
When the verification succeeds, the controller adds a Condition with the
following attributes to the HelmChart's `.status.conditions`:
- `type: SourceVerified`
- `status: "True"`
- `reason: Succeeded`
To verify the authenticity of an OCI artifact, create a Kubernetes secret
containing Certificate Authority (CA) root certificates and the a `trust policy`
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: notation-config
type: Opaque
data:
certificate1.pem: <BASE64>
certificate2.crt: <BASE64>
trustpolicy.json: <BASE64>
```
Note that the CA certificates must have either `.pem` or `.crt` extension and your trust policy must
be named `trustpolicy.json` for Flux to make use of them.
For more information on the signing and verification process see [Signing and Verification Workflow](https://github.com/notaryproject/specifications/blob/v1.0.0/specs/signing-and-verification-workflow.md).
Flux will loop over the certificates and use them to verify an artifact's signature.
This allows for older artifacts to be valid as long as the right certificate is in the secret.
## Working with HelmCharts
### Triggering a reconcile
To manually tell the source-controller to reconcile a HelmChart outside the
[specified interval window](#interval), a HelmCHart can be annotated with
`reconcile.fluxcd.io/requestedAt: <arbitrary value>`. Annotating the resource
queues the object for reconciliation if the `<arbitrary-value>` differs from
the last value the controller acted on, as reported in
[`.status.lastHandledReconcileAt`](#last-handled-reconcile-at).
Using `kubectl`:
```sh
kubectl annotate --field-manager=flux-client-side-apply --overwrite helmchart/<chart-name> reconcile.fluxcd.io/requestedAt="$(date +%s)"
```
### Waiting for `Ready`
When a change is applied, it is possible to wait for the HelmChart to reach a
[ready state](#ready-helmchart) using `kubectl`:
```sh
kubectl wait helmchart/<chart-name> --for=condition=ready --timeout=1m
```
### Suspending and resuming
When you find yourself in a situation where you temporarily want to pause the
reconciliation of a HelmChart, you can suspend it using the
[`.spec.suspend` field](#suspend).
#### Suspend a HelmChart
In your YAML declaration:
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: <chart-name>
spec:
suspend: true
```
Using `kubectl`:
```sh
kubectl patch helmchart <chart-name> --field-manager=flux-client-side-apply -p '{\"spec\": {\"suspend\" : true }}'
```
**Note:** When a HelmChart has an Artifact and is suspended, and this
Artifact later disappears from the storage due to e.g. the source-controller
Pod being evicted from a Node, this will not be reflected in the
HelmChart's Status until it is resumed.
#### Resume a HelmChart
In your YAML declaration, comment out (or remove) the field:
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: <chart-name>
spec:
# suspend: true
```
**Note:** Setting the field value to `false` has the same effect as removing
it, but does not allow for "hot patching" using e.g. `kubectl` while practicing
GitOps; as the manually applied patch would be overwritten by the declared
state in Git.
Using `kubectl`:
```sh
kubectl patch helmchart <chart-name> --field-manager=flux-client-side-apply -p '{\"spec\" : {\"suspend\" : false }}'
```
### Debugging a HelmChart
There are several ways to gather information about a HelmChart for debugging
purposes.
#### Describe the HelmChart
Describing a HelmChart using `kubectl describe helmchart <chart-name>` displays
the latest recorded information for the resource in the `Status` and `Events`
sections:
```console
...
Status:
...
Conditions:
Last Transition Time: 2022-02-13T14:06:27Z
Message: invalid chart reference: failed to get chart version for remote reference: no 'podinfo' chart with version matching '9.*' found
Observed Generation: 3
Reason: InvalidChartReference
Status: True
Type: Stalled
Last Transition Time: 2022-02-13T14:06:27Z
Message: invalid chart reference: failed to get chart version for remote reference: no 'podinfo' chart with version matching '9.*' found
Observed Generation: 3
Reason: InvalidChartReference
Status: False
Type: Ready
Last Transition Time: 2022-02-13T14:06:27Z
Message: invalid chart reference: failed to get chart version for remote reference: no 'podinfo' chart with version matching '9.*' found
Observed Generation: 3
Reason: InvalidChartReference
Status: True
Type: FetchFailed
Last Handled Reconcile At: 1644759954
Observed Chart Name: podinfo
Observed Generation: 3
URL: http://source-controller.flux-system.svc.cluster.local./helmchart/default/podinfo/latest.tar.gz
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning InvalidChartReference 11s source-controller invalid chart reference: failed to get chart version for remote reference: no 'podinfo' chart with ver
sion matching '9.*' found
```
#### Trace emitted Events
To view events for specific HelmChart(s), `kubectl events` can be used in
combination with `--for` to list the Events for specific objects. For example,
running
```sh
kubectl events --for HelmChart/<chart-name>
```
lists
```console
LAST SEEN TYPE REASON OBJECT MESSAGE
22s Warning InvalidChartReference helmchart/<chart-name> invalid chart reference: failed to get chart version for remote reference: no 'podinfo' chart with version matching '9.*' found
2s Normal ChartPullSucceeded helmchart/<chart-name> pulled 'podinfo' chart with version '6.0.3'
2s Normal ArtifactUpToDate helmchart/<chart-name> artifact up-to-date with remote revision: '6.0.3'
```
Besides being reported in Events, the reconciliation errors are also logged by
the controller. The Flux CLI offer commands for filtering the logs for a
specific HelmChart, e.g. `flux logs --level=error --kind=HelmChart --name=<chart-name>`.
### Improving resource consumption by enabling the cache
When using a `HelmRepository` as Source for a `HelmChart`, the controller loads
the repository index in memory to find the latest version of the chart.
The controller can be configured to cache Helm repository indexes in memory.
The cache is used to avoid loading repository indexes for every `HelmChart`
reconciliation.
The following flags are provided to enable and configure the cache:
- `helm-cache-max-size`: The maximum size of the cache in number of indexes.
If `0`, then the cache is disabled.
- `helm-cache-ttl`: The TTL of an index in the cache.
- `helm-cache-purge-interval`: The interval at which the cache is purged of
expired items.
The caching strategy is to pull a repository index from the cache if it is
available, otherwise to load the index, retrieve and build the chart,
then cache the index. The cached index TTL is refreshed every time the
Helm repository index is loaded with the `helm-cache-ttl` value.
The cache is purged of expired items every `helm-cache-purge-interval`.
When the cache is full, no more items can be added to the cache, and the
source-controller will report a warning event instead.
In order to use the cache, set the related flags in the source-controller
Deployment config:
```yaml
spec:
containers:
- args:
- --watch-all-namespaces
- --log-level=info
- --log-encoding=json
- --enable-leader-election
- --storage-path=/data
- --storage-adv-addr=source-controller.$(RUNTIME_NAMESPACE).svc.cluster.local.
## Helm cache with up to 10 items, i.e. 10 indexes.
- --helm-cache-max-size=10
## TTL of an index is 1 hour.
- --helm-cache-ttl=1h
## Purge expired index every 10 minutes.
- --helm-cache-purge-interval=10m
```
## HelmChart Status
### Artifact
The HelmChart reports the last built chart as an Artifact object in the
`.status.artifact` of the resource.
The Artifact file is a gzip compressed TAR archive (`<chart-name>-<chart-version>.tgz`),
and can be retrieved in-cluster from the `.status.artifact.url` HTTP address.
#### Artifact example
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: <chart-name>
status:
artifact:
digest: sha256:e30b95a08787de69ffdad3c232d65cfb131b5b50c6fd44295f48a078fceaa44e
lastUpdateTime: "2022-02-10T18:53:47Z"
path: helmchart/<source-namespace>/<chart-name>/<chart-name>-<chart-version>.tgz
revision: 6.0.3
size: 14166
url: http://source-controller.flux-system.svc.cluster.local./helmchart/<source-namespace>/<chart-name>/<chart-name>-<chart-version>.tgz
```
When using a `HelmRepository` as the source reference and values files are
provided, the value of `status.artifact.revision` is the chart version combined
with the `HelmChart` object generation. For example, if the chart version is
`6.0.3` and the `HelmChart` object generation is `1`, the
`status.artifact.revision` value will be `6.0.3+1`.
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: <chart-name>
status:
artifact:
digest: sha256:ee68224ded207ebb18a8e9730cf3313fa6bc1f31e6d8d3943ab541113559bb52
lastUpdateTime: "2022-02-28T08:07:12Z"
path: helmchart/<source-namespace>/<chart-name>/<chart-name>-6.0.3+1.tgz
revision: 6.0.3+1
size: 14166
url: http://source-controller.flux-system.svc.cluster.local./helmchart/<source-namespace>/<chart-name>/<chart-name>-6.0.3+1.tgz
observedGeneration: 1
...
```
When using a `GitRepository` or a `Bucket` as the source reference and
`Revision` as the reconcile strategy, the value of `status.artifact.revision` is
the chart version combined with the first 12 characters of the revision of the
`GitRepository` or `Bucket`. For example if the chart version is `6.0.3` and the
revision of the `Bucket` is `4e5cbb7b97d00a8039b8810b90b922f4256fd3bd8f78b934b4892dae13f7ca87`,
the `status.artifact.revision` value will be `6.0.3+4e5cbb7b97d0`.
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmChart
metadata:
name: <chart-name>
status:
artifact:
digest: sha256:8d1f0ac3f4b0e8759a32180086f17ac87ca04e5d46c356e67f97e97616ef4718
lastUpdateTime: "2022-02-28T08:07:12Z"
path: helmchart/<source-namespace>/<chart-name>/<chart-name>-6.0.3+4e5cbb7b97d0.tgz
revision: 6.0.3+4e5cbb7b97d0
size: 14166
url: http://source-controller.flux-system.svc.cluster.local./helmchart/<source-namespace>/<chart-name>/<chart-name>-6.0.3+4e5cbb7b97d0.tgz
```
### Conditions
A HelmChart enters various states during its lifecycle, reflected as [Kubernetes
Conditions][typical-status-properties].
It can be [reconciling](#reconciling-helmchart) while fetching or building the
chart, it can be [ready](#ready-helmchart), it can
[fail during reconciliation](#failed-helmchart), or it can
[stall](#stalled-helmchart).
The HelmChart API is compatible with the [kstatus
specification][kstatus-spec],
and reports `Reconciling` and `Stalled` conditions where applicable to
provide better (timeout) support to solutions polling the HelmChart to become
`Ready`.
#### Reconciling HelmChart
The source-controller marks a HelmChart as _reconciling_ when one of the
following is true:
- There is no current Artifact for the HelmChart, or the reported Artifact is
determined to have disappeared from the storage.
- The generation of the HelmChart is newer than the [Observed
Generation](#observed-generation).
- The newly fetched Artifact revision differs from the current Artifact.
When the HelmChart is "reconciling", the `Ready` Condition status becomes
`Unknown` when the controller detects drift, and the controller adds a Condition
with the following attributes to the HelmChart's `.status.conditions`:
- `type: Reconciling`
- `status: "True"`
- `reason: Progressing` | `reason: ProgressingWithRetry`
If the reconciling state is due to a new version, it adds an additional
Condition with the following attributes:
- `type: ArtifactOutdated`
- `status: "True"`
- `reason: NewChart`
Both Conditions have a ["negative polarity"][typical-status-properties],
and are only present on the HelmChart while their status value is `"True"`.
#### Ready HelmChart
The source-controller marks a HelmChart as _ready_ when it has the following
characteristics:
- The HelmChart reports an [Artifact](#artifact).
- The reported Artifact exists in the controller's Artifact storage.
- The controller was able to fetch and build the Helm chart using the current
spec.
- The version/revision of the reported Artifact is up-to-date with the
latest version/revision of the Helm chart.
When the HelmChart is "ready", the controller sets a Condition with the
following attributes in the HelmChart's `.status.conditions`:
- `type: Ready`
- `status: "True"`
- `reason: Succeeded`
This `Ready` Condition will retain a status value of `"True"` until the
HelmChart is marked as [reconciling](#reconciling-helmchart), or e.g.
a [transient error](#failed-helmchart) occurs due to a temporary network issue.
When the HelmChart Artifact is archived in the controller's Artifact
storage, the controller sets a Condition with the following attributes in the
HelmChart's `.status.conditions`:
- `type: ArtifactInStorage`
- `status: "True"`
- `reason: Succeeded`
This `ArtifactInStorage` Condition will retain a status value of `"True"` until
the Artifact in the storage no longer exists.
#### Failed HelmChart
The source-controller may get stuck trying to produce an Artifact for a
HelmChart without completing. This can occur due to some of the following
factors:
- The Helm chart Source is temporarily unavailable.
- The credentials in the [Source reference](#source-reference) Secret are
invalid.
- The HelmChart spec contains a generic misconfiguration.
- A storage related failure when storing the artifact.
When this happens, the controller sets the `Ready` Condition status to `False`,
and adds a Condition with the following attributes to the HelmChart's
`.status.conditions`:
- `type: FetchFailed` | `type: StorageOperationFailed`
- `status: "True"`
- `reason: AuthenticationFailed` | `reason: StorageOperationFailed` | `reason: URLInvalid` | `reason: IllegalPath` | `reason: Failed`
This condition has a ["negative polarity"][typical-status-properties],
and is only present on the HelmChart while the status value is `"True"`.
There may be more arbitrary values for the `reason` field to provide accurate
reason for a condition.
While the HelmChart has this Condition, the controller will continue to
attempt to produce an Artifact for the resource with an exponential backoff,
until it succeeds and the HelmChart is marked as [ready](#ready-helmchart).
Note that a HelmChart can be [reconciling](#reconciling-helmchart)
while failing at the same time, for example due to a newly introduced
configuration issue in the HelmChart spec. When a reconciliation fails, the
`Reconciling` Condition reason would be `ProgressingWithRetry`. When the
reconciliation is performed again after the failure, the reason is updated to
`Progressing`.
#### Stalled HelmChart
The source-controller can mark a HelmChart as _stalled_ when it determines that
without changes to the spec, the reconciliation can not succeed.
For example because a HelmChart Version is set to a non-existing version.
When this happens, the controller sets the same Conditions as when it
[fails](#failed-helmchart), but adds another Condition with the following
attributes to the HelmChart's `.status.conditions`:
- `type: Stalled`
- `status: "True"`
- `reason: InvalidChartReference`
While the HelmChart has this Condition, the controller will not requeue the
resource any further, and will stop reconciling the resource until a change to
the spec is made.
### Observed Source Artifact Revision
The source-controller reports the revision of the last
[Source reference's](#source-reference) Artifact the current chart was fetched
from in the HelmChart's `.status.observedSourceArtifactRevision`. It is used to
keep track of the source artifact revision and detect when a new source
artifact is available.
### Observed Chart Name
The source-controller reports the last resolved chart name of the Artifact
for the [`.spec.chart` field](#chart) in the HelmChart's
`.status.observedChartName`. It is used to keep track of the chart and detect
when a new chart is found.
### Observed Generation
The source-controller reports an [observed generation][typical-status-properties]
in the HelmChart's `.status.observedGeneration`. The observed generation is the
latest `.metadata.generation` which resulted in either a [ready state](#ready-helmchart),
or stalled due to error it can not recover from without human
intervention.
### Last Handled Reconcile At
The source-controller reports the last `reconcile.fluxcd.io/requestedAt`
annotation value it acted on in the `.status.lastHandledReconcileAt` field.
For practical information about this field, see [triggering a
reconcile](#triggering-a-reconcile).
[typical-status-properties]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
[kstatus-spec]: https://github.com/kubernetes-sigs/cli-utils/tree/master/pkg/kstatus

View File

@ -0,0 +1,878 @@
# Helm Repositories
<!-- menuweight:40 -->
There are 2 [Helm repository types](#type) defined by the `HelmRepository` API:
- Helm HTTP/S repository, which defines a Source to produce an Artifact for a Helm
repository index YAML (`index.yaml`).
- OCI Helm repository, which defines a source that does not produce an Artifact.
It's a data container to store the information about the OCI repository that
can be used by [HelmChart](helmcharts.md) to access OCI Helm charts.
## Examples
### Helm HTTP/S repository
The following is an example of a HelmRepository. It creates a YAML (`.yaml`)
Artifact from the fetched Helm repository index (in this example the [podinfo
repository](https://github.com/stefanprodan/podinfo)):
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: podinfo
namespace: default
spec:
interval: 5m0s
url: https://stefanprodan.github.io/podinfo
```
In the above example:
- A HelmRepository named `podinfo` is created, indicated by the
`.metadata.name` field.
- The source-controller fetches the Helm repository index YAML every five
minutes from `https://stefanprodan.github.io/podinfo`, indicated by the
`.spec.interval` and `.spec.url` fields.
- The digest (algorithm defaults to SHA256) of the Helm repository index after
stable sorting the entries is used as Artifact revision, reported in-cluster
in the `.status.artifact.revision` field.
- When the current HelmRepository revision differs from the latest fetched
revision, it is stored as a new Artifact.
- The new Artifact is reported in the `.status.artifact` field.
You can run this example by saving the manifest into `helmrepository.yaml`.
1. Apply the resource on the cluster:
```sh
kubectl apply -f helmrepository.yaml
```
2. Run `kubectl get helmrepository` to see the HelmRepository:
```console
NAME URL AGE READY STATUS
podinfo https://stefanprodan.github.io/podinfo 4s True stored artifact for revision 'sha256:83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111'
```
3. Run `kubectl describe helmrepository podinfo` to see the [Artifact](#artifact)
and [Conditions](#conditions) in the HelmRepository's Status:
```console
...
Status:
Artifact:
Digest: sha256:83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111
Last Update Time: 2022-02-04T09:55:58Z
Path: helmrepository/default/podinfo/index-83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111.yaml
Revision: sha256:83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111
Size: 40898
URL: http://source-controller.flux-system.svc.cluster.local./helmrepository/default/podinfo/index-83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111.yaml
Conditions:
Last Transition Time: 2022-02-04T09:55:58Z
Message: stored artifact for revision 'sha256:83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111'
Observed Generation: 1
Reason: Succeeded
Status: True
Type: Ready
Last Transition Time: 2022-02-04T09:55:58Z
Message: stored artifact for revision 'sha256:83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111'
Observed Generation: 1
Reason: Succeeded
Status: True
Type: ArtifactInStorage
Observed Generation: 1
URL: http://source-controller.flux-system.svc.cluster.local./helmrepository/default/podinfo/index.yaml
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal NewArtifact 1m source-controller fetched index of size 30.88kB from 'https://stefanprodan.github.io/podinfo'
```
### Helm OCI repository
The following is an example of an OCI HelmRepository.
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: podinfo
namespace: default
spec:
type: "oci"
interval: 5m0s
url: oci://ghcr.io/stefanprodan/charts
```
In the above example:
- A HelmRepository named `podinfo` is created, indicated by the
`.metadata.name` field.
- A HelmChart that refers to this HelmRepository uses the URL in the `.spec.url`
field to access the OCI Helm chart.
**NOTE:** The `.spec.interval` field is only used by the `default` Helm
repository and is ignored for any value in `oci` Helm repository.
You can run this example by saving the manifest into `helmrepository.yaml`.
1. Apply the resource on the cluster:
```sh
kubectl apply -f helmrepository.yaml
```
2. Run `kubectl get helmrepository` to see the HelmRepository:
```console
NAME URL AGE READY STATUS
podinfo oci://ghcr.io/stefanprodan/charts 3m22s
```
Because the OCI Helm repository is a data container, there's nothing to report
for `READY` and `STATUS` columns above. The existence of the object can be
considered to be ready for use.
## Writing a HelmRepository spec
As with all other Kubernetes config, a HelmRepository needs `apiVersion`,
`kind`, and `metadata` fields. The name of a HelmRepository object must be a
valid [DNS subdomain name](https://kubernetes.io/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
A HelmRepository also needs a
[`.spec` section](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status).
### Type
`.spec.type` is an optional field that specifies the Helm repository type.
Possible values are `default` for a Helm HTTP/S repository, or `oci` for an OCI Helm repository.
### Provider
`.spec.provider` is an optional field that allows specifying an OIDC provider used
for authentication purposes.
Supported options are:
- `generic`
- `aws`
- `azure`
- `gcp`
The `generic` provider can be used for public repositories or when static credentials
are used for authentication. If you do not specify `.spec.provider`, it defaults
to `generic`.
**Note**: The provider field is supported only for Helm OCI repositories. The `spec.type`
field must be set to `oci`.
#### AWS
The `aws` provider can be used to authenticate automatically using the EKS worker
node IAM role or IAM Role for Service Accounts (IRSA), and by extension gain access
to ECR.
##### EKS Worker Node IAM Role
When the worker node IAM role has access to ECR, source-controller running on it
will also have access to ECR.
##### IAM Role for Service Accounts (IRSA)
When using IRSA to enable access to ECR, add the following patch to your bootstrap
repository, in the `flux-system/kustomization.yaml` file:
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gotk-components.yaml
- gotk-sync.yaml
patches:
- patch: |
apiVersion: v1
kind: ServiceAccount
metadata:
name: source-controller
annotations:
eks.amazonaws.com/role-arn: <role arn>
target:
kind: ServiceAccount
name: source-controller
```
Note that you can attach the AWS managed policy `arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly`
to the IAM role when using IRSA.
#### Azure
The `azure` provider can be used to authenticate automatically using Workload Identity and Kubelet Managed
Identity to gain access to ACR.
##### Kubelet Managed Identity
When the kubelet managed identity has access to ACR, source-controller running on
it will also have access to ACR.
**Note:** If you have more than one identity configured on the cluster, you have to specify which one to use
by setting the `AZURE_CLIENT_ID` environment variable in the source-controller deployment.
If you are running into further issues, please look at the
[troubleshooting guide](https://github.com/Azure/azure-sdk-for-go/blob/main/sdk/azidentity/TROUBLESHOOTING.md#azure-virtual-machine-managed-identity).
##### Azure Workload Identity
When using Workload Identity to enable access to ACR, add the following patch to
your bootstrap repository, in the `flux-system/kustomization.yaml` file:
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gotk-components.yaml
- gotk-sync.yaml
patches:
- patch: |-
apiVersion: v1
kind: ServiceAccount
metadata:
name: source-controller
namespace: flux-system
annotations:
azure.workload.identity/client-id: <AZURE_CLIENT_ID>
labels:
azure.workload.identity/use: "true"
- patch: |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: source-controller
namespace: flux-system
labels:
azure.workload.identity/use: "true"
spec:
template:
metadata:
labels:
azure.workload.identity/use: "true"
```
Ensure Workload Identity is properly set up on your cluster and the mutating webhook is installed.
Create an identity that has access to ACR. Next, establish
a federated identity between the source-controller ServiceAccount and the
identity. Patch the source-controller Deployment and ServiceAccount as shown in the patch
above. Please take a look at this [guide](https://azure.github.io/azure-workload-identity/docs/quick-start.html#6-establish-federated-identity-credential-between-the-identity-and-the-service-account-issuer--subject).
#### GCP
The `gcp` provider can be used to authenticate automatically using OAuth scopes or
Workload Identity, and by extension gain access to GCR or Artifact Registry.
##### Access Scopes
When the GKE nodes have the appropriate OAuth scope for accessing GCR and Artifact Registry,
source-controller running on it will also have access to them.
##### GKE Workload Identity
When using Workload Identity to enable access to GCR or Artifact Registry, add the
following patch to your bootstrap repository, in the `flux-system/kustomization.yaml`
file:
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gotk-components.yaml
- gotk-sync.yaml
patches:
- patch: |
apiVersion: v1
kind: ServiceAccount
metadata:
name: source-controller
annotations:
iam.gke.io/gcp-service-account: <identity-name>
target:
kind: ServiceAccount
name: source-controller
```
The Artifact Registry service uses the permission `artifactregistry.repositories.downloadArtifacts`
that is located under the Artifact Registry Reader role. If you are using Google Container Registry service,
the needed permission is instead `storage.objects.list` which can be bound as part
of the Container Registry Service Agent role. Take a look at [this guide](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity)
for more information about setting up GKE Workload Identity.
### Insecure
`.spec.insecure` is an optional field to allow connecting to an insecure (HTTP)
container registry server, if set to `true`. The default value is `false`,
denying insecure non-TLS connections when fetching Helm chart OCI artifacts.
**Note**: The insecure field is supported only for Helm OCI repositories.
The `spec.type` field must be set to `oci`.
### Interval
**Note:** This field is ineffectual for [OCI Helm
Repositories](#helm-oci-repository).
`.spec.interval` is a an optional field that specifies the interval which the
Helm repository index must be consulted at. When not set, the default value is
`1m`.
After successfully reconciling a HelmRepository object, the source-controller
requeues the object for inspection after the specified interval. The value
must be in a [Go recognized duration string format](https://pkg.go.dev/time#ParseDuration),
e.g. `10m0s` to fetch the HelmRepository index YAML every 10 minutes.
If the `.metadata.generation` of a resource changes (due to e.g. applying a
change to the spec), this is handled instantly outside the interval window.
**Note:** The controller can be configured to apply a jitter to the interval in
order to distribute the load more evenly when multiple HelmRepository objects
are set up with the same interval. For more information, please refer to the
[source-controller configuration options](https://fluxcd.io/flux/components/source/options/).
### URL
`.spec.url` is a required field that depending on the [type of the HelmRepository object](#type)
specifies the HTTP/S or OCI address of a Helm repository.
For OCI, the URL is expected to point to a registry repository, e.g. `oci://ghcr.io/fluxcd/source-controller`.
For Helm repositories which require authentication, see [Secret reference](#secret-reference).
### Timeout
**Note:** This field is not applicable to [OCI Helm
Repositories](#helm-oci-repository).
`.spec.timeout` is an optional field to specify a timeout for the fetch
operation. The value must be in a
[Go recognized duration string format](https://pkg.go.dev/time#ParseDuration),
e.g. `1m30s` for a timeout of one minute and thirty seconds. When not set, the
default value is `1m`.
### Secret reference
`.spec.secretRef.name` is an optional field to specify a name reference to a
Secret in the same namespace as the HelmRepository, containing authentication
credentials for the repository.
#### Basic access authentication
To authenticate towards a Helm repository using basic access authentication
(in other words: using a username and password), the referenced Secret is
expected to contain `.data.username` and `.data.password` values.
For example:
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: example
namespace: default
spec:
interval: 5m0s
url: https://example.com
secretRef:
name: example-user
---
apiVersion: v1
kind: Secret
metadata:
name: example-user
namespace: default
stringData:
username: "user-123456"
password: "pass-123456"
```
OCI Helm repository example:
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: podinfo
namespace: default
spec:
interval: 5m0s
url: oci://ghcr.io/my-user/my-private-repo
type: "oci"
secretRef:
name: oci-creds
---
apiVersion: v1
kind: Secret
metadata:
name: oci-creds
namespace: default
stringData:
username: "user-123456"
password: "pass-123456"
```
For OCI Helm repositories, Kubernetes secrets of type [kubernetes.io/dockerconfigjson](https://kubernetes.io/docs/concepts/configuration/secret/#secret-types) are also supported.
It is possible to create one such secret with `kubectl create secret docker-registry`
or using the Flux CLI:
```yaml
flux create secret oci ghcr-auth \
--url=ghcr.io \
--username=flux \
--password=${GITHUB_PAT}
```
**Warning:** Support for specifying TLS authentication data using this API has been
deprecated. Please use [`.spec.certSecretRef`](#cert-secret-reference) instead.
If the controller uses the secret specified by this field to configure TLS, then
a deprecation warning will be logged.
### Cert secret reference
`.spec.certSecretRef.name` is an optional field to specify a secret containing
TLS certificate data. The secret can contain the following keys:
* `tls.crt` and `tls.key`, to specify the client certificate and private key used
for TLS client authentication. These must be used in conjunction, i.e.
specifying one without the other will lead to an error.
* `ca.crt`, to specify the CA certificate used to verify the server, which is
required if the server is using a self-signed certificate.
If the server is using a self-signed certificate and has TLS client
authentication enabled, all three values are required.
The Secret should be of type `Opaque` or `kubernetes.io/tls`. All the files in
the Secret are expected to be [PEM-encoded][pem-encoding]. Assuming you have
three files; `client.key`, `client.crt` and `ca.crt` for the client private key,
client certificate and the CA certificate respectively, you can generate the
required Secret using the `flux create secret tls` command:
```sh
flux create secret tls --tls-key-file=client.key --tls-crt-file=client.crt --ca-crt-file=ca.crt
```
Example usage:
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: example
namespace: default
spec:
interval: 5m0s
url: https://example.com
certSecretRef:
name: example-tls
---
apiVersion: v1
kind: Secret
metadata:
name: example-tls
namespace: default
type: kubernetes.io/tls # or Opaque
data:
tls.crt: <BASE64>
tls.key: <BASE64>
# NOTE: Can be supplied without the above values
ca.crt: <BASE64>
```
### Pass credentials
`.spec.passCredentials` is an optional field to allow the credentials from the
[Secret reference](#secret-reference) to be passed on to a host that does not
match the host as defined in URL. This may for example be required if the host
advertised chart URLs in the index differ from the specified URL.
Enabling this should be done with caution, as it can potentially result in
credentials getting stolen in a man-in-the-middle attack. This feature only applies
to HTTP/S Helm repositories.
### Suspend
**Note:** This field is not applicable to [OCI Helm
Repositories](#helm-oci-repository).
`.spec.suspend` is an optional field to suspend the reconciliation of a
HelmRepository. When set to `true`, the controller will stop reconciling the
HelmRepository, and changes to the resource or the Helm repository index will
not result in a new Artifact. When the field is set to `false` or removed, it
will resume.
For practical information, see
[suspending and resuming](#suspending-and-resuming).
## Working with HelmRepositories
**Note:** This section does not apply to [OCI Helm
Repositories](#helm-oci-repository), being a data container, once created, they
are ready to used by [HelmCharts](helmcharts.md).
### Triggering a reconcile
To manually tell the source-controller to reconcile a HelmRepository outside the
[specified interval window](#interval), a HelmRepository can be annotated with
`reconcile.fluxcd.io/requestedAt: <arbitrary value>`. Annotating the resource
queues the object for reconciliation if the `<arbitrary-value>` differs from
the last value the controller acted on, as reported in
[`.status.lastHandledReconcileAt`](#last-handled-reconcile-at).
Using `kubectl`:
```sh
kubectl annotate --field-manager=flux-client-side-apply --overwrite helmrepository/<repository-name> reconcile.fluxcd.io/requestedAt="$(date +%s)"
```
Using `flux`:
```sh
flux reconcile source helm <repository-name>
```
### Waiting for `Ready`
When a change is applied, it is possible to wait for the HelmRepository to
reach a [ready state](#ready-helmrepository) using `kubectl`:
```sh
kubectl wait helmrepository/<repository-name> --for=condition=ready --timeout=1m
```
### Suspending and resuming
When you find yourself in a situation where you temporarily want to pause the
reconciliation of a HelmRepository, you can suspend it using the
[`.spec.suspend` field](#suspend).
#### Suspend a HelmRepository
In your YAML declaration:
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: <repository-name>
spec:
suspend: true
```
Using `kubectl`:
```sh
kubectl patch helmrepository <repository-name> --field-manager=flux-client-side-apply -p '{\"spec\": {\"suspend\" : true }}'
```
Using `flux`:
```sh
flux suspend source helm <repository-name>
```
**Note:** When a HelmRepository has an Artifact and is suspended, and this
Artifact later disappears from the storage due to e.g. the source-controller
Pod being evicted from a Node, this will not be reflected in the
HelmRepository's Status until it is resumed.
#### Resume a HelmRepository
In your YAML declaration, comment out (or remove) the field:
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: <repository-name>
spec:
# suspend: true
```
**Note:** Setting the field value to `false` has the same effect as removing
it, but does not allow for "hot patching" using e.g. `kubectl` while practicing
GitOps; as the manually applied patch would be overwritten by the declared
state in Git.
Using `kubectl`:
```sh
kubectl patch helmrepository <repository-name> --field-manager=flux-client-side-apply -p '{\"spec\" : {\"suspend\" : false }}'
```
Using `flux`:
```sh
flux resume source helm <repository-name>
```
### Debugging a HelmRepository
**Note:** This section does not apply to [OCI Helm
Repositories](#helm-oci-repository), being a data container, they are static
objects that don't require debugging if valid.
There are several ways to gather information about a HelmRepository for debugging
purposes.
#### Describe the HelmRepository
Describing a HelmRepository using `kubectl describe helmrepository <repository-name>`
displays the latest recorded information for the resource in the `Status` and
`Events` sections:
```console
...
Status:
...
Conditions:
Last Transition Time: 2022-02-04T13:41:56Z
Message: failed to construct Helm client: scheme "invalid" not supported
Observed Generation: 2
Reason: Failed
Status: True
Type: Stalled
Last Transition Time: 2022-02-04T13:41:56Z
Message: failed to construct Helm client: scheme "invalid" not supported
Observed Generation: 2
Reason: Failed
Status: False
Type: Ready
Last Transition Time: 2022-02-04T13:41:56Z
Message: failed to construct Helm client: scheme "invalid" not supported
Observed Generation: 2
Reason: Failed
Status: True
Type: FetchFailed
Observed Generation: 2
URL: http://source-controller.source-system.svc.cluster.local./helmrepository/default/podinfo/index.yaml
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Failed 6s source-controller failed to construct Helm client: scheme "invalid" not supported
```
#### Trace emitted Events
To view events for specific HelmRepository(s), `kubectl events` can be used in
combination with `--for` to list the Events for specific objects. For example,
running
```sh
kubectl events --for HelmRepository/<repository-name>
```
lists
```console
LAST SEEN TYPE REASON OBJECT MESSAGE
107s Warning Failed helmrepository/<repository-name> failed to construct Helm client: scheme "invalid" not supported
7s Normal NewArtifact helmrepository/<repository-name> fetched index of size 30.88kB from 'https://stefanprodan.github.io/podinfo'
3s Normal ArtifactUpToDate helmrepository/<repository-name> artifact up-to-date with remote revision: 'sha256:83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111'
```
Besides being reported in Events, the reconciliation errors are also logged by
the controller. The Flux CLI offer commands for filtering the logs for a
specific HelmRepository, e.g. `flux logs --level=error --kind=HelmRepository --name=<chart-name>`.
## HelmRepository Status
**Note:** This section does not apply to [OCI Helm
Repositories](#helm-oci-repository), they do not contain any information in the
status.
### Artifact
The HelmRepository reports the last fetched repository index as an Artifact
object in the `.status.artifact` of the resource.
The Artifact file is an exact copy of the Helm repository index YAML
(`index-<revision>.yaml`) as fetched, and can be retrieved in-cluster from the
`.status.artifact.url` HTTP address.
#### Artifact example
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: <repository-name>
status:
artifact:
digest: sha256:83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111
lastUpdateTime: "2022-02-04T09:55:58Z"
path: helmrepository/<namespace>/<repository-name>/index-83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111.yaml
revision: sha256:83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111
size: 40898
url: http://source-controller.flux-system.svc.cluster.local./helmrepository/<namespace>/<repository-name>/index-83a3c595163a6ff0333e0154c790383b5be441b9db632cb36da11db1c4ece111.yaml
```
### Conditions
A HelmRepository enters various states during its lifecycle, reflected as [Kubernetes
Conditions][typical-status-properties].
It can be [reconciling](#reconciling-helmrepository) while fetching the
repository index, it can be [ready](#ready-helmrepository), it can
[fail during reconciliation](#failed-helmrepository), or it can
[stall](#stalled-helmrepository).
The HelmRepository API is compatible with the [kstatus
specification][kstatus-spec],
and reports `Reconciling` and `Stalled` conditions where applicable to
provide better (timeout) support to solutions polling the HelmRepository to become
`Ready`.
#### Reconciling HelmRepository
The source-controller marks a HelmRepository as _reconciling_ when one of the following
is true:
- There is no current Artifact for the HelmRepository, or the reported Artifact
is determined to have disappeared from the storage.
- The generation of the HelmRepository is newer than the [Observed
Generation](#observed-generation).
- The newly fetched Artifact revision differs from the current Artifact.
When the HelmRepository is "reconciling", the `Ready` Condition status becomes
`Unknown` when the controller detects drift, and the controller adds a Condition
with the following attributes to the HelmRepository's `.status.conditions`:
- `type: Reconciling`
- `status: "True"`
- `reason: Progressing` | `reason: ProgressingWithRetry`
If the reconciling state is due to a new revision, it adds an additional
Condition with the following attributes:
- `type: ArtifactOutdated`
- `status: "True"`
- `reason: NewRevision`
Both Conditions have a ["negative polarity"][typical-status-properties],
and are only present on the HelmRepository while their status value is `"True"`.
#### Ready HelmRepository
The source-controller marks a HelmRepository as _ready_ when it has the following
characteristics:
- The HelmRepository reports an [Artifact](#artifact).
- The reported Artifact exists in the controller's Artifact storage.
- The controller was able to fetch the Helm repository index using the current
spec.
- The revision of the reported Artifact is up-to-date with the latest
revision of the Helm repository.
When the HelmRepository is "ready", the controller sets a Condition with the following
attributes in the HelmRepository's `.status.conditions`:
- `type: Ready`
- `status: "True"`
- `reason: Succeeded`
This `Ready` Condition will retain a status value of `"True"` until the
HelmRepository is marked as [reconciling](#reconciling-helmrepository), or e.g.
a [transient error](#failed-helmrepository) occurs due to a temporary network
issue.
When the HelmRepository Artifact is archived in the controller's Artifact
storage, the controller sets a Condition with the following attributes in the
HelmRepository's `.status.conditions`:
- `type: ArtifactInStorage`
- `status: "True"`
- `reason: Succeeded`
This `ArtifactInStorage` Condition will retain a status value of `"True"` until
the Artifact in the storage no longer exists.
#### Failed HelmRepository
The source-controller may get stuck trying to produce an Artifact for a
HelmRepository without completing. This can occur due to some of the following
factors:
- The Helm repository [URL](#url) is temporarily unavailable.
- The [Secret reference](#secret-reference) contains a reference to a
non-existing Secret.
- The credentials in the referenced Secret are invalid.
- The HelmRepository spec contains a generic misconfiguration.
- A storage related failure when storing the artifact.
When this happens, the controller sets the `Ready` Condition status to `False`,
and adds a Condition with the following attributes to the HelmRepository's
`.status.conditions`:
- `type: FetchFailed` | `type: StorageOperationFailed`
- `status: "True"`
- `reason: AuthenticationFailed` | `reason: IndexationFailed` | `reason: Failed`
This condition has a ["negative polarity"][typical-status-properties],
and is only present on the HelmRepository while the status value is `"True"`.
There may be more arbitrary values for the `reason` field to provide accurate
reason for a condition.
While the HelmRepository has this Condition, the controller will continue to
attempt to produce an Artifact for the resource with an exponential backoff,
until it succeeds and the HelmRepository is marked as [ready](#ready-helmrepository).
Note that a HelmRepository can be [reconciling](#reconciling-helmrepository)
while failing at the same time, for example due to a newly introduced
configuration issue in the HelmRepository spec. When a reconciliation fails, the
`Reconciling` Condition reason would be `ProgressingWithRetry`. When the
reconciliation is performed again after the failure, the reason is updated to
`Progressing`.
#### Stalled HelmRepository
The source-controller can mark a HelmRepository as _stalled_ when it determines
that without changes to the spec, the reconciliation can not succeed.
For example because a Helm repository URL with an unsupported protocol is
specified.
When this happens, the controller sets the same Conditions as when it
[fails](#failed-helmrepository), but adds another Condition with the following
attributes to the HelmRepository's
`.status.conditions`:
- `type: Stalled`
- `status: "True"`
- `reason: URLInvalid`
While the HelmRepository has this Condition, the controller will not requeue
the resource any further, and will stop reconciling the resource until a change
to the spec is made.
### Observed Generation
The source-controller reports an [observed generation][typical-status-properties]
in the HelmRepository's `.status.observedGeneration`. The observed generation is
the latest `.metadata.generation` which resulted in either a [ready state](#ready-helmrepository),
or stalled due to error it can not recover from without human intervention.
### Last Handled Reconcile At
The source-controller reports the last `reconcile.fluxcd.io/requestedAt`
annotation value it acted on in the `.status.lastHandledReconcileAt` field.
For practical information about this field, see [triggering a
reconcile](#triggering-a-reconcile).
[pem-encoding]: https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail
[typical-status-properties]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
[kstatus-spec]: https://github.com/kubernetes-sigs/cli-utils/tree/master/pkg/kstatus

File diff suppressed because it is too large Load Diff

View File

@ -749,6 +749,83 @@ HTTP endpoint requires enabling [`.spec.insecure`](#insecure).
Some endpoints require the specification of a [`.spec.region`](#region),
see [Provider](#provider) for more (provider specific) examples.
### STS
`.spec.sts` is an optional field for specifying the Security Token Service
configuration. A Security Token Service (STS) is a web service that issues
temporary security credentials. By adding this field, one may specify the
STS endpoint from where temporary credentials will be fetched.
This field is only supported for the `aws` and `generic` bucket [providers](#provider).
If using `.spec.sts`, the following fields are required:
- `.spec.sts.provider`, the Security Token Service provider. The only supported
option for the `generic` bucket provider is `ldap`. The only supported option
for the `aws` bucket provider is `aws`.
- `.spec.sts.endpoint`, the HTTP/S endpoint of the Security Token Service. In
the case of `aws` this can be `https://sts.amazonaws.com`, or a Regional STS
Endpoint, or an Interface Endpoint created inside a VPC. In the case of
`ldap` this must be the LDAP server endpoint.
When using the `ldap` provider, the following fields may also be specified:
- `.spec.sts.secretRef.name`, the name of the Secret containing the LDAP
credentials. The Secret must contain the following keys:
- `username`, the username to authenticate with.
- `password`, the password to authenticate with.
- `.spec.sts.certSecretRef.name`, the name of the Secret containing the
TLS configuration for communicating with the STS endpoint. The contents
of this Secret must follow the same structure of
[`.spec.certSecretRef.name`](#cert-secret-reference).
If [`.spec.proxySecretRef.name`](#proxy-secret-reference) is specified,
the proxy configuration will be used for commucating with the STS endpoint.
Example for the `ldap` provider:
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: Bucket
metadata:
name: example
namespace: example
spec:
interval: 5m
bucketName: example
provider: generic
endpoint: minio.example.com
sts:
provider: ldap
endpoint: https://ldap.example.com
secretRef:
name: ldap-credentials
certSecretRef:
name: ldap-tls
---
apiVersion: v1
kind: Secret
metadata:
name: ldap-credentials
namespace: example
type: Opaque
stringData:
username: <username>
password: <password>
---
apiVersion: v1
kind: Secret
metadata:
name: ldap-tls
namespace: example
type: kubernetes.io/tls # or Opaque
stringData:
tls.crt: <PEM-encoded cert>
tls.key: <PEM-encoded key>
ca.crt: <PEM-encoded cert>
```
### Bucket name
`.spec.bucketName` is a required field that specifies which object storage
@ -763,6 +840,100 @@ See [Provider](#provider) for more (provider specific) examples.
See [Provider](#provider) for more (provider specific) examples.
### Cert secret reference
`.spec.certSecretRef.name` is an optional field to specify a secret containing
TLS certificate data. The secret can contain the following keys:
* `tls.crt` and `tls.key`, to specify the client certificate and private key used
for TLS client authentication. These must be used in conjunction, i.e.
specifying one without the other will lead to an error.
* `ca.crt`, to specify the CA certificate used to verify the server, which is
required if the server is using a self-signed certificate.
If the server is using a self-signed certificate and has TLS client
authentication enabled, all three values are required.
The Secret should be of type `Opaque` or `kubernetes.io/tls`. All the files in
the Secret are expected to be [PEM-encoded][pem-encoding]. Assuming you have
three files; `client.key`, `client.crt` and `ca.crt` for the client private key,
client certificate and the CA certificate respectively, you can generate the
required Secret using the `flux create secret tls` command:
```sh
flux create secret tls minio-tls --tls-key-file=client.key --tls-crt-file=client.crt --ca-crt-file=ca.crt
```
If TLS client authentication is not required, you can generate the secret with:
```sh
flux create secret tls minio-tls --ca-crt-file=ca.crt
```
This API is only supported for the `generic` [provider](#provider).
Example usage:
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: Bucket
metadata:
name: example
namespace: example
spec:
interval: 5m
bucketName: example
provider: generic
endpoint: minio.example.com
certSecretRef:
name: minio-tls
---
apiVersion: v1
kind: Secret
metadata:
name: minio-tls
namespace: example
type: kubernetes.io/tls # or Opaque
stringData:
tls.crt: <PEM-encoded cert>
tls.key: <PEM-encoded key>
ca.crt: <PEM-encoded cert>
```
### Proxy secret reference
`.spec.proxySecretRef.name` is an optional field used to specify the name of a
Secret that contains the proxy settings for the object. These settings are used
for all the remote operations related to the Bucket.
The Secret can contain three keys:
- `address`, to specify the address of the proxy server. This is a required key.
- `username`, to specify the username to use if the proxy server is protected by
basic authentication. This is an optional key.
- `password`, to specify the password to use if the proxy server is protected by
basic authentication. This is an optional key.
Example:
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: http-proxy
type: Opaque
stringData:
address: http://proxy.com
username: mandalorian
password: grogu
```
Proxying can also be configured in the source-controller Deployment directly by
using the standard environment variables such as `HTTPS_PROXY`, `ALL_PROXY`, etc.
`.spec.proxySecretRef.name` takes precedence over all environment variables.
### Insecure
`.spec.insecure` is an optional field to allow connecting to an insecure (HTTP)

View File

@ -202,6 +202,16 @@ spec:
Values files also affect the generated artifact revision, see
[artifact](#artifact).
### Ignore missing values files
`.spec.ignoreMissingValuesFiles` is an optional field to specify whether missing
values files should be ignored rather than be considered errors. It defaults to
`false`.
When `.spec.valuesFiles` and `.spec.ignoreMissingValuesFiles` are specified,
the `.status.observedValuesFiles` field is populated with the list of values
files that were found and actually contributed to the packaged chart.
### Reconcile strategy
`.spec.reconcileStrategy` is an optional field to specify what enables the
@ -252,15 +262,20 @@ For practical information, see
**Note:** This feature is available only for Helm charts fetched from an OCI Registry.
`.spec.verify` is an optional field to enable the verification of [Cosign](https://github.com/sigstore/cosign)
`.spec.verify` is an optional field to enable the verification of [Cosign](https://github.com/sigstore/cosign) or [Notation](https://github.com/notaryproject/notation)
signatures. The field offers three subfields:
- `.provider`, to specify the verification provider. Only supports `cosign` at present.
- `.provider`, to specify the verification provider. The supported options are `cosign` and `notation` at present.
- `.secretRef.name`, to specify a reference to a Secret in the same namespace as
the HelmChart, containing the Cosign public keys of trusted authors.
- `.matchOIDCIdentity`, to specify a list of OIDC identity matchers. Please see
the HelmChart, containing the public keys of trusted authors. For Notation this Secret should also include the [trust policy](https://github.com/notaryproject/specifications/blob/v1.0.0/specs/trust-store-trust-policy.md#trust-policy) in
addition to the CA certificate.
- `.matchOIDCIdentity`, to specify a list of OIDC identity matchers (only supported when using `cosign` as the verification provider). Please see
[Keyless verification](#keyless-verification) for more details.
#### Cosign
The `cosign` provider can be used to verify the signature of an OCI artifact using either a known public key or via the [Cosign Keyless](https://github.com/sigstore/cosign/blob/main/KEYLESS.md) procedure.
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
@ -281,7 +296,7 @@ following attributes to the HelmChart's `.status.conditions`:
- `status: "True"`
- `reason: Succeeded`
#### Public keys verification
##### Public keys verification
To verify the authenticity of HelmChart hosted in an OCI Registry, create a Kubernetes
secret with the Cosign public keys:
@ -303,7 +318,7 @@ Note that the keys must have the `.pub` extension for Flux to make use of them.
Flux will loop over the public keys and use them to verify a HelmChart's signature.
This allows for older HelmCharts to be valid as long as the right key is in the secret.
#### Keyless verification
##### Keyless verification
For publicly available HelmCharts, which are signed using the
[Cosign Keyless](https://github.com/sigstore/cosign/blob/main/KEYLESS.md) procedure,
@ -362,6 +377,55 @@ instance hosted at [rekor.sigstore.dev](https://rekor.sigstore.dev/).
Note that keyless verification is an **experimental feature**, using
custom root CAs or self-hosted Rekor instances are not currently supported.
#### Notation
The `notation` provider can be used to verify the signature of an OCI artifact using known
trust policy and CA certificate.
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmChart
metadata:
name: podinfo
spec:
verify:
provider: notation
secretRef:
name: notation-config
```
When the verification succeeds, the controller adds a Condition with the
following attributes to the HelmChart's `.status.conditions`:
- `type: SourceVerified`
- `status: "True"`
- `reason: Succeeded`
To verify the authenticity of an OCI artifact, create a Kubernetes secret
containing Certificate Authority (CA) root certificates and the a `trust policy`
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: notation-config
type: Opaque
data:
certificate1.pem: <BASE64>
certificate2.crt: <BASE64>
trustpolicy.json: <BASE64>
```
Note that the CA certificates must have either `.pem` or `.crt` extension and your trust policy must
be named `trustpolicy.json` for Flux to make use of them.
For more information on the signing and verification process see [Signing and Verification Workflow](https://github.com/notaryproject/specifications/blob/v1.0.0/specs/signing-and-verification-workflow.md).
Flux will loop over the certificates and use them to verify an artifact's signature.
This allows for older artifacts to be valid as long as the right certificate is in the secret.
## Working with HelmCharts
### Triggering a reconcile

View File

@ -157,9 +157,8 @@ to the IAM role when using IRSA.
#### Azure
The `azure` provider can be used to authenticate automatically using Workload Identity, Kubelet Managed
Identity or Azure Active Directory pod-managed identity (aad-pod-identity),
and by extension gain access to ACR.
The `azure` provider can be used to authenticate automatically using Workload Identity and Kubelet Managed
Identity to gain access to ACR.
##### Kubelet Managed Identity
@ -215,41 +214,6 @@ a federated identity between the source-controller ServiceAccount and the
identity. Patch the source-controller Deployment and ServiceAccount as shown in the patch
above. Please take a look at this [guide](https://azure.github.io/azure-workload-identity/docs/quick-start.html#6-establish-federated-identity-credential-between-the-identity-and-the-service-account-issuer--subject).
##### Deprecated: AAD Pod Identity
**Note:** The AAD Pod Identity project will be archived in [September 2023](https://github.com/Azure/aad-pod-identity#-announcement),
and you are advised to use Workload Identity instead.
When using aad-pod-identity to enable access to ACR, add the following patch to
your bootstrap repository, in the `flux-system/kustomization.yaml` file:
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gotk-components.yaml
- gotk-sync.yaml
patches:
- patch: |
- op: add
path: /spec/template/metadata/labels/aadpodidbinding
value: <identity-name>
target:
kind: Deployment
name: source-controller
```
When using pod-managed identity on an AKS cluster, AAD Pod Identity
has to be used to give the `source-controller` pod access to the ACR.
To do this, you have to install `aad-pod-identity` on your cluster, create a managed identity
that has access to the container registry (this can also be the Kubelet identity
if it has `AcrPull` role assignment on the ACR), create an `AzureIdentity` and `AzureIdentityBinding`
that describe the managed identity and then label the `source-controller` deployment
with the name of the AzureIdentity as shown in the patch above. Please take a look
at [this guide](https://azure.github.io/aad-pod-identity/docs/) or
[this one](https://docs.microsoft.com/en-us/azure/aks/use-azure-ad-pod-identity)
if you want to use AKS pod-managed identities add-on that is in preview.
#### GCP
The `gcp` provider can be used to authenticate automatically using OAuth scopes
@ -279,7 +243,7 @@ patches:
target:
kind: ServiceAccount
name: source-controller
```
```
The Artifact Registry service uses the permission `artifactregistry.repositories.downloadArtifacts`
that is located under the Artifact Registry Reader role. If you are using
@ -366,6 +330,47 @@ data:
deprecated. If you have any Secrets using these keys and specified in an
OCIRepository, the controller will log a deprecation warning.
### Proxy secret reference
`.spec.proxySecretRef.name` is an optional field used to specify the name of a
Secret that contains the proxy settings for the object. These settings are used
for all the remote operations related to the OCIRepository.
The Secret can contain three keys:
- `address`, to specify the address of the proxy server. This is a required key.
- `username`, to specify the username to use if the proxy server is protected by
basic authentication. This is an optional key.
- `password`, to specify the password to use if the proxy server is protected by
basic authentication. This is an optional key.
Example:
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: http-proxy
type: Opaque
stringData:
address: http://proxy.com
username: mandalorian
password: grogu
```
Proxying can also be configured in the source-controller Deployment directly by
using the standard environment variables such as `HTTPS_PROXY`, `ALL_PROXY`, etc.
`.spec.proxySecretRef.name` takes precedence over all environment variables.
**Warning:** [Cosign](https://github.com/sigstore/cosign) *keyless*
[verification](#verification) is not supported for this API. If you
require cosign keyless verification to use a proxy you must use the
standard environment variables mentioned above. If you specify a
`proxySecretRef` the controller will simply send out the requests
needed for keyless verification without the associated object-level
proxy settings.
### Insecure
`.spec.insecure` is an optional field to allow connecting to an insecure (HTTP)
@ -441,6 +446,37 @@ spec:
This field takes precedence over [`.tag`](#tag-example).
#### SemverFilter example
`.spec.ref.semverFilter` is an optional field to specify a SemVer filter to apply
when fetching tags from the OCI repository. The filter is a regular expression
that is applied to the tags fetched from the repository. Only tags that match
the filter are considered for the semver range resolution.
**Note:** The filter is only taken into account when the `.spec.ref.semver` field
is set.
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: podinfo
namespace: default
spec:
interval: 5m0s
url: oci://ghcr.io/stefanprodan/manifests/podinfo
ref:
# SemVer comparisons using constraints without a prerelease comparator will skip prerelease versions.
# Adding a `-0` suffix to the semver range will include prerelease versions.
semver: ">= 6.1.x-0"
semverFilter: ".*-rc.*"
```
In the above example, the controller fetches tags from the `ghcr.io/stefanprodan/manifests/podinfo`
repository and filters them using the regular expression `.*-rc.*`. Only tags that
contain the `-rc` suffix are considered for the semver range resolution.
#### Digest example
To pull a specific digest, use `.spec.ref.digest`:
@ -454,7 +490,7 @@ metadata:
spec:
ref:
digest: "sha256:<SHA-value>"
```
```
This field takes precedence over all other fields.
@ -501,14 +537,23 @@ for more information.
### Verification
`.spec.verify` is an optional field to enable the verification of [Cosign](https://github.com/sigstore/cosign)
or [Notation](https://github.com/notaryproject/notation)
signatures. The field offers three subfields:
- `.provider`, to specify the verification provider. Only supports `cosign` at present.
- `.provider`, to specify the verification provider. The supported options are `cosign` and `notation` at present.
- `.secretRef.name`, to specify a reference to a Secret in the same namespace as
the OCIRepository, containing the Cosign public keys of trusted authors.
- `.matchOIDCIdentity`, to specify a list of OIDC identity matchers. Please see
the OCIRepository, containing the Cosign public keys of trusted authors. For Notation this Secret should also
include the [trust policy](https://github.com/notaryproject/specifications/blob/v1.0.0/specs/trust-store-trust-policy.md#trust-policy) in
addition to the CA certificate.
- `.matchOIDCIdentity`, to specify a list of OIDC identity matchers (only supported when using `cosign` as the
verification provider). Please see
[Keyless verification](#keyless-verification) for more details.
#### Cosign
The `cosign` provider can be used to verify the signature of an OCI artifact using either a known public key
or via the [Cosign Keyless](https://github.com/sigstore/cosign/blob/main/KEYLESS.md) procedure.
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
@ -529,7 +574,7 @@ following attributes to the OCIRepository's `.status.conditions`:
- `status: "True"`
- `reason: Succeeded`
#### Public keys verification
##### Public keys verification
To verify the authenticity of an OCI artifact, create a Kubernetes secret
with the Cosign public keys:
@ -551,7 +596,7 @@ Note that the keys must have the `.pub` extension for Flux to make use of them.
Flux will loop over the public keys and use them to verify an artifact's signature.
This allows for older artifacts to be valid as long as the right key is in the secret.
#### Keyless verification
##### Keyless verification
For publicly available OCI artifacts, which are signed using the
[Cosign Keyless](https://github.com/sigstore/cosign/blob/main/KEYLESS.md) procedure,
@ -593,6 +638,55 @@ instance hosted at [rekor.sigstore.dev](https://rekor.sigstore.dev/).
Note that keyless verification is an **experimental feature**, using
custom root CAs or self-hosted Rekor instances are not currently supported.
#### Notation
The `notation` provider can be used to verify the signature of an OCI artifact using known
trust policy and CA certificate.
```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: <repository-name>
spec:
verify:
provider: notation
secretRef:
name: notation-config
```
When the verification succeeds, the controller adds a Condition with the
following attributes to the OCIRepository's `.status.conditions`:
- `type: SourceVerified`
- `status: "True"`
- `reason: Succeeded`
To verify the authenticity of an OCI artifact, create a Kubernetes secret
containing Certificate Authority (CA) root certificates and the a `trust policy`
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: notation-config
type: Opaque
data:
certificate1.pem: <BASE64>
certificate2.crt: <BASE64>
trustpolicy.json: <BASE64>
```
Note that the CA certificates must have either `.pem` or `.crt` extension and your trust policy must
be named `trustpolicy.json` for Flux to make use of them.
For more information on the signing and verification process see [Signing and Verification Workflow](https://github.com/notaryproject/specifications/blob/v1.0.0/specs/signing-and-verification-workflow.md).
Flux will loop over the certificates and use them to verify an artifact's signature.
This allows for older artifacts to be valid as long as the right certificate is in the secret.
### Suspend
`.spec.suspend` is an optional field to suspend the reconciliation of a

543
go.mod
View File

@ -1,86 +1,98 @@
module github.com/fluxcd/source-controller
go 1.21
go 1.24.0
replace github.com/fluxcd/source-controller/api => ./api
// Pin semver to v3.3.0 to avoid breaking changes in v3.3.1
// xref: https://github.com/fluxcd/source-controller/issues/1738
replace github.com/Masterminds/semver/v3 => github.com/Masterminds/semver/v3 v3.3.0
// Replace digest lib to master to gather access to BLAKE3.
// xref: https://github.com/opencontainers/go-digest/pull/66
replace github.com/opencontainers/go-digest => github.com/opencontainers/go-digest v1.0.1-0.20220411205349-bde1400a84be
replace github.com/go-git/go-git/v5 => github.com/go-git/go-git/v5 v5.10.2-0.20231203195647-cec7da63ca04
require (
cloud.google.com/go/storage v1.35.1
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0
github.com/Masterminds/semver/v3 v3.2.1
github.com/cyphar/filepath-securejoin v0.2.4
github.com/distribution/distribution/v3 v3.0.0-20230821124843-59dd684cc897
github.com/docker/cli v24.0.7+incompatible
cloud.google.com/go/compute/metadata v0.6.0
cloud.google.com/go/storage v1.50.0
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0
github.com/Masterminds/semver/v3 v3.3.1
github.com/cyphar/filepath-securejoin v0.4.1
github.com/distribution/distribution/v3 v3.0.0
github.com/docker/cli v28.1.1+incompatible
github.com/docker/go-units v0.5.0
github.com/fluxcd/cli-utils v0.36.0-flux.1
github.com/fluxcd/pkg/apis/event v0.6.0
github.com/fluxcd/pkg/apis/meta v1.2.0
github.com/fluxcd/pkg/git v0.16.0
github.com/fluxcd/pkg/git/gogit v0.16.0
github.com/fluxcd/pkg/gittestserver v0.9.0
github.com/fluxcd/pkg/helmtestserver v0.15.0
github.com/fluxcd/pkg/lockedfile v0.1.0
github.com/fluxcd/pkg/masktoken v0.2.0
github.com/fluxcd/pkg/oci v0.33.1
github.com/fluxcd/pkg/runtime v0.43.0
github.com/fluxcd/pkg/sourceignore v0.4.0
github.com/fluxcd/pkg/ssh v0.10.0
github.com/fluxcd/pkg/tar v0.4.0
github.com/fluxcd/pkg/testserver v0.5.0
github.com/fluxcd/pkg/version v0.2.2
github.com/fluxcd/source-controller/api v1.2.0
github.com/foxcpp/go-mockdns v1.0.0
github.com/go-git/go-billy/v5 v5.5.0
github.com/go-git/go-git/v5 v5.10.1
github.com/go-logr/logr v1.3.0
github.com/google/go-containerregistry v0.17.0
github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20231202142526-55ffb0092afd
github.com/google/uuid v1.4.0
github.com/minio/minio-go/v7 v7.0.65
github.com/onsi/gomega v1.30.0
github.com/elazarl/goproxy v1.7.2
github.com/fluxcd/cli-utils v0.36.0-flux.13
github.com/fluxcd/pkg/apis/event v0.17.0
github.com/fluxcd/pkg/apis/meta v1.12.0
github.com/fluxcd/pkg/auth v0.18.0
github.com/fluxcd/pkg/cache v0.9.0
github.com/fluxcd/pkg/git v0.32.0
github.com/fluxcd/pkg/git/gogit v0.35.1
github.com/fluxcd/pkg/gittestserver v0.17.0
github.com/fluxcd/pkg/helmtestserver v0.24.0
github.com/fluxcd/pkg/lockedfile v0.6.0
github.com/fluxcd/pkg/masktoken v0.7.0
github.com/fluxcd/pkg/oci v0.49.0
github.com/fluxcd/pkg/runtime v0.60.0
github.com/fluxcd/pkg/sourceignore v0.12.0
github.com/fluxcd/pkg/ssh v0.19.0
github.com/fluxcd/pkg/tar v0.12.0
github.com/fluxcd/pkg/testserver v0.11.0
github.com/fluxcd/pkg/version v0.7.0
github.com/fluxcd/source-controller/api v1.6.0
github.com/foxcpp/go-mockdns v1.1.0
github.com/go-git/go-billy/v5 v5.6.2
github.com/go-git/go-git/v5 v5.16.2
github.com/go-logr/logr v1.4.2
github.com/google/go-containerregistry v0.20.5
github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20241111191718-6bce25ecf029
github.com/google/uuid v1.6.0
github.com/minio/minio-go/v7 v7.0.92
github.com/notaryproject/notation-core-go v1.3.0
github.com/notaryproject/notation-go v1.3.2
github.com/onsi/gomega v1.37.0
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/go-digest/blake3 v0.0.0-20231025023718-d50d2fec9c98
github.com/ory/dockertest/v3 v3.10.0
github.com/otiai10/copy v1.14.0
github.com/opencontainers/go-digest/blake3 v0.0.0-20240426182413-22b78e47854a
github.com/opencontainers/image-spec v1.1.1
github.com/ory/dockertest/v3 v3.12.0
github.com/otiai10/copy v1.14.1
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
github.com/prometheus/client_golang v1.17.0
github.com/sigstore/cosign/v2 v2.2.1
github.com/sigstore/sigstore v1.7.6
github.com/prometheus/client_golang v1.22.0
github.com/sigstore/cosign/v2 v2.5.0
github.com/sigstore/sigstore v1.9.1
github.com/sirupsen/logrus v1.9.3
github.com/spf13/pflag v1.0.5
golang.org/x/crypto v0.16.0
golang.org/x/sync v0.5.0
google.golang.org/api v0.152.0
github.com/spf13/pflag v1.0.6
golang.org/x/crypto v0.39.0
golang.org/x/oauth2 v0.30.0
golang.org/x/sync v0.15.0
google.golang.org/api v0.227.0
gotest.tools v2.2.0+incompatible
helm.sh/helm/v3 v3.13.2
k8s.io/api v0.28.4
k8s.io/apimachinery v0.28.4
k8s.io/client-go v0.28.4
k8s.io/utils v0.0.0-20231127182322-b307cd553661
sigs.k8s.io/controller-runtime v0.16.3
helm.sh/helm/v3 v3.17.3
k8s.io/api v0.33.0
k8s.io/apimachinery v0.33.0
k8s.io/client-go v0.33.0
k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e
oras.land/oras-go/v2 v2.5.0
sigs.k8s.io/controller-runtime v0.21.0
sigs.k8s.io/yaml v1.4.0
)
require (
cloud.google.com/go v0.110.10 // indirect
cloud.google.com/go/compute v1.23.3 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.5 // indirect
dario.cat/mergo v1.0.0 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0 // indirect
cel.dev/expr v0.19.1 // indirect
cloud.google.com/go v0.118.3 // indirect
cloud.google.com/go/auth v0.15.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
cloud.google.com/go/iam v1.4.1 // indirect
cloud.google.com/go/monitoring v1.24.0 // indirect
dario.cat/mergo v1.0.1 // indirect
github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/provider v0.14.0 // indirect
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.29 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect
@ -89,24 +101,19 @@ require (
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/DataDog/appsec-internal-go v1.0.0 // indirect
github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.1 // indirect
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.1 // indirect
github.com/DataDog/datadog-go/v5 v5.3.0 // indirect
github.com/DataDog/go-libddwaf v1.5.0 // indirect
github.com/DataDog/go-tuf v1.0.2-0.5.2 // indirect
github.com/DataDog/sketches-go v1.4.3 // indirect
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
github.com/BurntSushi/toml v1.4.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.49.0 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
github.com/Masterminds/squirrel v1.5.4 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20231012073058-a7379d079e0e // indirect
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d // indirect
github.com/ProtonMail/go-crypto v1.2.0 // indirect
github.com/ThalesIgnite/crypto11 v1.2.5 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect
github.com/alibabacloud-go/cr-20160607 v1.0.1 // indirect
@ -118,285 +125,301 @@ require (
github.com/alibabacloud-go/tea v1.2.1 // indirect
github.com/alibabacloud-go/tea-utils v1.4.5 // indirect
github.com/alibabacloud-go/tea-xml v1.1.3 // indirect
github.com/aliyun/credentials-go v1.3.1 // indirect
github.com/aliyun/credentials-go v1.3.2 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go-v2 v1.21.2 // indirect
github.com/aws/aws-sdk-go-v2/config v1.19.1 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.13.43 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 // indirect
github.com/aws/aws-sdk-go-v2/service/ecr v1.20.2 // indirect
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.23.2 // indirect
github.com/aws/smithy-go v1.15.0 // indirect
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8 // indirect
github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect
github.com/aws/aws-sdk-go-v2/config v1.29.14 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.67 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ecr v1.43.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.33.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect
github.com/aws/smithy-go v1.22.3 // indirect
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.9.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver v3.5.1+incompatible // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/bradleyfalzon/ghinstallation/v2 v2.15.0 // indirect
github.com/bshuster-repo/logrus-logstash-hook v1.0.0 // indirect
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd // indirect
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b // indirect
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 // indirect
github.com/buildkite/agent/v3 v3.58.0 // indirect
github.com/buildkite/interpolate v0.0.0-20200526001904-07f35b4ae251 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/buildkite/agent/v3 v3.95.1 // indirect
github.com/buildkite/go-pipeline v0.13.3 // indirect
github.com/buildkite/interpolate v0.1.5 // indirect
github.com/buildkite/roko v1.3.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/cloudflare/circl v1.3.6 // indirect
github.com/cloudflare/circl v1.6.1 // indirect
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 // indirect
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect
github.com/containerd/containerd v1.7.6 // indirect
github.com/containerd/continuity v0.4.2 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/coreos/go-oidc/v3 v3.7.0 // indirect
github.com/containerd/containerd v1.7.27 // indirect
github.com/containerd/continuity v0.4.5 // indirect
github.com/containerd/errdefs v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/platforms v0.2.1 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
github.com/coreos/go-oidc/v3 v3.14.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect
github.com/digitorus/timestamp v0.0.0-20230902153158-687734543647 // indirect
github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker v24.0.7+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/docker v28.1.1+incompatible // indirect
github.com/docker/docker-credential-helpers v0.9.3 // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/ebitengine/purego v0.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.7.0 // indirect
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
github.com/evanphx/json-patch v5.9.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fatih/color v1.17.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fluxcd/gitkit v0.6.0 // indirect
github.com/fluxcd/pkg/apis/acl v0.1.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/fluxcd/pkg/apis/acl v0.7.0 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
github.com/go-chi/chi v4.1.2+incompatible // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.1 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.4 // indirect
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
github.com/go-ldap/ldap/v3 v3.4.10 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.2.4 // indirect
github.com/go-openapi/analysis v0.21.4 // indirect
github.com/go-openapi/errors v0.20.4 // indirect
github.com/go-openapi/jsonpointer v0.20.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/loads v0.21.2 // indirect
github.com/go-openapi/runtime v0.26.0 // indirect
github.com/go-openapi/spec v0.20.9 // indirect
github.com/go-openapi/strfmt v0.21.7 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-openapi/validate v0.22.1 // indirect
github.com/go-piv/piv-go v1.11.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.15.5 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
github.com/go-openapi/analysis v0.23.0 // indirect
github.com/go-openapi/errors v0.22.1 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/loads v0.22.0 // indirect
github.com/go-openapi/runtime v0.28.0 // indirect
github.com/go-openapi/spec v0.21.0 // indirect
github.com/go-openapi/strfmt v0.23.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
github.com/go-openapi/validate v0.24.0 // indirect
github.com/go-piv/piv-go/v2 v2.3.0 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/gomodule/redigo v1.8.9 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/certificate-transparency-go v1.1.7 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/certificate-transparency-go v1.3.1 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20230516205744-dbecb1de8cfa // indirect
github.com/google/go-github/v55 v55.0.0 // indirect
github.com/google/go-github/v71 v71.0.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
github.com/gorilla/handlers v1.5.2 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
github.com/gowebpki/jcs v1.0.1 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.5 // indirect
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/in-toto/attestation v1.1.1 // indirect
github.com/in-toto/in-toto-golang v0.9.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmoiron/sqlx v1.3.5 // indirect
github.com/jmoiron/sqlx v1.4.0 // indirect
github.com/josharian/intern 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.17.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/lestrrat-go/blackmagic v1.0.2 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/httprc v1.0.4 // indirect
github.com/lestrrat-go/iter v1.0.2 // indirect
github.com/lestrrat-go/jwx/v2 v2.0.16 // indirect
github.com/lestrrat-go/option v1.0.1 // indirect
github.com/letsencrypt/boulder v0.0.0-20231026200631-000cd05d5491 // indirect
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/miekg/dns v1.1.55 // indirect
github.com/miekg/dns v1.1.58 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/minio/crc64nvme v1.0.1 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/sys/user v0.3.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/mozillazg/docker-credential-acr-helper v0.3.0 // indirect
github.com/mozillazg/docker-credential-acr-helper v0.4.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/notaryproject/notation-plugin-framework-go v1.0.0 // indirect
github.com/notaryproject/tspclient-go v1.0.0 // indirect
github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/oleiade/reflections v1.0.1 // indirect
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
github.com/opencontainers/runc v1.1.5 // indirect
github.com/oleiade/reflections v1.1.0 // indirect
github.com/opencontainers/runc v1.2.4 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/otiai10/mint v1.6.3 // indirect
github.com/pborman/uuid v1.2.1 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/philhofer/fwd v1.1.2 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
github.com/pjbgf/sha1cd v0.3.2 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.63.0 // indirect
github.com/prometheus/procfs v0.16.1 // 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
github.com/rivo/uniseg v0.4.4 // indirect
github.com/rs/xid v1.5.0 // indirect
github.com/rubenv/sql-migrate v1.5.2 // indirect
github.com/rs/xid v1.6.0 // indirect
github.com/rubenv/sql-migrate v1.7.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sagikazarmark/locafero v0.7.0 // indirect
github.com/sassoftware/relic v7.2.1+incompatible // indirect
github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect
github.com/segmentio/asm v1.2.0 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect
github.com/segmentio/ksuid v1.0.4 // indirect
github.com/sergi/go-diff v1.3.1 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/shibumi/go-pathspec v1.3.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sigstore/fulcio v1.4.3 // indirect
github.com/sigstore/rekor v1.3.3 // indirect
github.com/sigstore/timestamp-authority v1.2.0 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sigstore/fulcio v1.6.6 // indirect
github.com/sigstore/protobuf-specs v0.4.1 // indirect
github.com/sigstore/rekor v1.3.9 // indirect
github.com/sigstore/sigstore-go v0.7.1 // indirect
github.com/sigstore/timestamp-authority v1.2.5 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.10.0 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/viper v1.17.0 // indirect
github.com/spiffe/go-spiffe/v2 v2.1.6 // indirect
github.com/spf13/afero v1.12.0 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/spf13/cobra v1.9.1 // indirect
github.com/spf13/viper v1.20.1 // indirect
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
github.com/thales-e-security/pool v0.0.2 // indirect
github.com/theupdateframework/go-tuf v0.6.1 // indirect
github.com/tinylib/msgp v1.1.8 // indirect
github.com/theupdateframework/go-tuf v0.7.0 // indirect
github.com/theupdateframework/go-tuf/v2 v2.0.2 // indirect
github.com/tinylib/msgp v1.3.0 // indirect
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/transparency-dev/merkle v0.0.2 // indirect
github.com/vbatts/tar-split v0.11.5 // indirect
github.com/xanzy/go-gitlab v0.93.2 // indirect
github.com/vbatts/tar-split v0.12.1 // indirect
github.com/veraison/go-cose v1.3.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
github.com/zeebo/errs v1.3.0 // indirect
go.mongodb.org/mongo-driver v1.12.1 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel v1.19.0 // indirect
go.opentelemetry.io/otel/metric v1.19.0 // indirect
go.opentelemetry.io/otel/trace v1.19.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
go.step.sm/crypto v0.36.1 // indirect
go.uber.org/atomic v1.11.0 // indirect
github.com/zeebo/errs v1.4.0 // indirect
gitlab.com/gitlab-org/api/client-go v0.127.0 // indirect
go.mongodb.org/mongo-driver v1.14.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/bridges/prometheus v0.57.0 // indirect
go.opentelemetry.io/contrib/detectors/gcp v1.34.0 // indirect
go.opentelemetry.io/contrib/exporters/autoexport v0.57.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
go.opentelemetry.io/otel v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 // indirect
go.opentelemetry.io/otel/exporters/prometheus v0.54.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 // indirect
go.opentelemetry.io/otel/log v0.8.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
go.opentelemetry.io/otel/sdk/log v0.8.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.26.0 // indirect
go4.org/intern v0.0.0-20230525184215-6c62f75575cb // indirect
go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/oauth2 v0.14.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.16.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/time v0.11.0 // indirect
golang.org/x/tools v0.33.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/DataDog/dd-trace-go.v1 v1.56.1 // indirect
gopkg.in/evanphx/json-patch.v5 v5.6.0 // indirect
gopkg.in/go-jose/go-jose.v2 v2.6.1 // indirect
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
google.golang.org/grpc v1.71.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // 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
inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a // indirect
k8s.io/apiextensions-apiserver v0.28.4 // indirect
k8s.io/apiserver v0.28.4 // indirect
k8s.io/cli-runtime v0.28.4 // indirect
k8s.io/component-base v0.28.4 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e // indirect
k8s.io/kubectl v0.28.4 // indirect
oras.land/oras-go v1.2.4 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/api v0.15.0 // indirect
sigs.k8s.io/kustomize/kyaml v0.15.0 // indirect
sigs.k8s.io/release-utils v0.7.6 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
k8s.io/apiextensions-apiserver v0.33.0 // indirect
k8s.io/apiserver v0.33.0 // indirect
k8s.io/cli-runtime v0.33.0 // indirect
k8s.io/component-base v0.33.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
k8s.io/kubectl v0.33.0 // indirect
oras.land/oras-go v1.2.5 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/kustomize/api v0.19.0 // indirect
sigs.k8s.io/kustomize/kyaml v0.19.0 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/release-utils v0.11.1 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
)
retract v0.32.0 // Refers to incorrect ./api version.

1900
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
Copyright 2023 The Flux authors
Copyright 2024 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.

View File

@ -144,6 +144,12 @@ kubectl -n source-system apply -f "${ROOT_DIR}/config/testdata/helmchart-from-oc
kubectl -n source-system wait helmchart/podinfo --for=condition=ready --timeout=1m
kubectl -n source-system wait helmchart/podinfo-keyless --for=condition=ready --timeout=1m
kubectl -n source-system apply -f "${ROOT_DIR}/config/testdata/helmchart-from-oci/notation.yaml"
curl -sSLo notation.crt https://raw.githubusercontent.com/stefanprodan/podinfo/master/.notation/notation.crt
curl -sSLo trustpolicy.json https://raw.githubusercontent.com/stefanprodan/podinfo/master/.notation/trustpolicy.json
kubectl -n source-system create secret generic notation-config --from-file=notation.crt --from-file=trustpolicy.json --dry-run=client -o yaml | kubectl apply -f -
kubectl -n source-system wait helmchart/podinfo-notation --for=condition=ready --timeout=1m
echo "Run OCIRepository verify tests"
kubectl -n source-system apply -f "${ROOT_DIR}/config/testdata/ocirepository/signed-with-key.yaml"
kubectl -n source-system apply -f "${ROOT_DIR}/config/testdata/ocirepository/signed-with-keyless.yaml"
@ -152,3 +158,6 @@ kubectl -n source-system create secret generic cosign-key --from-file=cosign.pub
kubectl -n source-system wait ocirepository/podinfo-deploy-signed-with-key --for=condition=ready --timeout=1m
kubectl -n source-system wait ocirepository/podinfo-deploy-signed-with-keyless --for=condition=ready --timeout=1m
kubectl -n source-system apply -f "${ROOT_DIR}/config/testdata/ocirepository/signed-with-notation.yaml"
kubectl -n source-system wait ocirepository/podinfo-deploy-signed-with-notation --for=condition=ready --timeout=1m

View File

@ -85,3 +85,55 @@ func TestCache(t *testing.T) {
g.Expect(found).To(BeFalse())
g.Expect(item).To(BeNil())
}
func TestCacheExpiration(t *testing.T) {
g := NewWithT(t)
cache := New(10, 0)
key := "testKey"
value := "testValue"
expiration := 1 * time.Second
err := cache.Add(key, value, expiration)
g.Expect(err).ToNot(HaveOccurred())
newExpiration := 2 * time.Second
cache.SetExpiration(key, newExpiration)
actualExpiration := cache.GetExpiration(key)
g.Expect(actualExpiration).Should(BeNumerically("~", newExpiration, 100*time.Millisecond))
g.Expect(cache.HasExpired(key)).To(BeFalse())
time.Sleep(newExpiration + 100*time.Millisecond)
g.Expect(cache.HasExpired(key)).To(BeTrue())
g.Expect(cache.GetExpiration(key)).To(BeZero())
nonExistentKey := "nonExistent"
cache.SetExpiration(nonExistentKey, 1*time.Second)
g.Expect(cache.GetExpiration(nonExistentKey)).To(BeZero())
g.Expect(cache.HasExpired(nonExistentKey)).To(BeTrue())
}
func TestCacheDeleteClear(t *testing.T) {
g := NewWithT(t)
cache := New(3, 0)
err := cache.Add("key1", "value1", 0)
g.Expect(err).ToNot(HaveOccurred())
err = cache.Add("key2", "value2", 0)
g.Expect(err).ToNot(HaveOccurred())
err = cache.Add("key3", "value3", 0)
g.Expect(err).ToNot(HaveOccurred())
cache.Delete("key2")
_, found := cache.Get("key2")
g.Expect(found).To(BeFalse())
g.Expect(cache.ItemCount()).To(Equal(2))
cache.Clear()
g.Expect(cache.ItemCount()).To(Equal(0))
}

View File

@ -18,8 +18,10 @@ package controller
import (
"context"
stdtls "crypto/tls"
"errors"
"fmt"
"net/url"
"os"
"path/filepath"
"strings"
@ -32,13 +34,15 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
kuberecorder "k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/ratelimiter"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/runtime/conditions"
helper "github.com/fluxcd/pkg/runtime/controller"
@ -46,17 +50,15 @@ import (
"github.com/fluxcd/pkg/runtime/patch"
"github.com/fluxcd/pkg/runtime/predicates"
rreconcile "github.com/fluxcd/pkg/runtime/reconcile"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/sourceignore"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
bucketv1 "github.com/fluxcd/source-controller/api/v1beta2"
intdigest "github.com/fluxcd/source-controller/internal/digest"
serror "github.com/fluxcd/source-controller/internal/error"
"github.com/fluxcd/source-controller/internal/index"
sreconcile "github.com/fluxcd/source-controller/internal/reconcile"
"github.com/fluxcd/source-controller/internal/reconcile/summarize"
"github.com/fluxcd/source-controller/internal/tls"
"github.com/fluxcd/source-controller/pkg/azure"
"github.com/fluxcd/source-controller/pkg/gcp"
"github.com/fluxcd/source-controller/pkg/minio"
@ -75,7 +77,7 @@ import (
const maxConcurrentBucketFetches = 100
// bucketReadyCondition contains the information required to summarize a
// v1beta2.Bucket Ready Condition.
// v1.Bucket Ready Condition.
var bucketReadyCondition = summarize.Conditions{
Target: meta.ReadyCondition,
Owned: []string{
@ -115,7 +117,7 @@ var bucketFailConditions = []string{
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=buckets/finalizers,verbs=get;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
// BucketReconciler reconciles a v1beta2.Bucket object.
// BucketReconciler reconciles a v1.Bucket object.
type BucketReconciler struct {
client.Client
kuberecorder.EventRecorder
@ -128,7 +130,7 @@ type BucketReconciler struct {
}
type BucketReconcilerOptions struct {
RateLimiter ratelimiter.RateLimiter
RateLimiter workqueue.TypedRateLimiter[reconcile.Request]
}
// BucketProvider is an interface for fetching objects from a storage provider
@ -153,10 +155,10 @@ type BucketProvider interface {
Close(context.Context)
}
// bucketReconcileFunc is the function type for all the v1beta2.Bucket
// bucketReconcileFunc is the function type for all the v1.Bucket
// (sub)reconcile functions. The type implementations are grouped and
// executed serially to perform the complete reconcile of the object.
type bucketReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *bucketv1.Bucket, index *index.Digester, dir string) (sreconcile.Result, error)
type bucketReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.Bucket, index *index.Digester, dir string) (sreconcile.Result, error)
func (r *BucketReconciler) SetupWithManager(mgr ctrl.Manager) error {
return r.SetupWithManagerAndOptions(mgr, BucketReconcilerOptions{})
@ -166,7 +168,7 @@ func (r *BucketReconciler) SetupWithManagerAndOptions(mgr ctrl.Manager, opts Buc
r.patchOptions = getPatchOptions(bucketReadyCondition.Owned, r.ControllerName)
return ctrl.NewControllerManagedBy(mgr).
For(&bucketv1.Bucket{}).
For(&sourcev1.Bucket{}).
WithEventFilter(predicate.Or(predicate.GenerationChangedPredicate{}, predicates.ReconcileRequestedPredicate{})).
WithOptions(controller.Options{
RateLimiter: opts.RateLimiter,
@ -179,7 +181,7 @@ func (r *BucketReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
log := ctrl.LoggerFrom(ctx)
// Fetch the Bucket
obj := &bucketv1.Bucket{}
obj := &sourcev1.Bucket{}
if err := r.Get(ctx, req.NamespacedName, obj); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
@ -210,9 +212,7 @@ func (r *BucketReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
}
result, retErr = summarizeHelper.SummarizeAndPatch(ctx, obj, summarizeOpts...)
// Always record suspend, readiness and duration metrics.
r.Metrics.RecordSuspend(ctx, obj, obj.Spec.Suspend)
r.Metrics.RecordReadiness(ctx, obj)
// Always record duration metrics.
r.Metrics.RecordDuration(ctx, obj, start)
}()
@ -252,7 +252,7 @@ func (r *BucketReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
// reconcile iterates through the bucketReconcileFunc tasks for the
// object. It returns early on the first call that returns
// reconcile.ResultRequeue, or produces an error.
func (r *BucketReconciler) reconcile(ctx context.Context, sp *patch.SerialPatcher, obj *bucketv1.Bucket, reconcilers []bucketReconcileFunc) (sreconcile.Result, error) {
func (r *BucketReconciler) reconcile(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.Bucket, reconcilers []bucketReconcileFunc) (sreconcile.Result, error) {
oldObj := obj.DeepCopy()
rreconcile.ProgressiveStatus(false, obj, meta.ProgressingReason, "reconciliation in progress")
@ -283,7 +283,7 @@ func (r *BucketReconciler) reconcile(ctx context.Context, sp *patch.SerialPatche
fmt.Errorf("failed to create temporary working directory: %w", err),
sourcev1.DirCreationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
defer func() {
@ -323,7 +323,7 @@ func (r *BucketReconciler) reconcile(ctx context.Context, sp *patch.SerialPatche
}
// notify emits notification related to the reconciliation.
func (r *BucketReconciler) notify(ctx context.Context, oldObj, newObj *bucketv1.Bucket, index *index.Digester, res sreconcile.Result, resErr error) {
func (r *BucketReconciler) notify(ctx context.Context, oldObj, newObj *sourcev1.Bucket, index *index.Digester, res sreconcile.Result, resErr error) {
// Notify successful reconciliation for new artifact and recovery from any
// failure.
if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil {
@ -361,7 +361,7 @@ func (r *BucketReconciler) notify(ctx context.Context, oldObj, newObj *bucketv1.
// condition is added.
// The hostname of any URL in the Status of the object are updated, to ensure
// they match the Storage server hostname of current runtime.
func (r *BucketReconciler) reconcileStorage(ctx context.Context, sp *patch.SerialPatcher, obj *bucketv1.Bucket, _ *index.Digester, _ string) (sreconcile.Result, error) {
func (r *BucketReconciler) reconcileStorage(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.Bucket, _ *index.Digester, _ string) (sreconcile.Result, error) {
// Garbage collect previous advertised artifact(s) from storage
_ = r.garbageCollect(ctx, obj)
@ -399,7 +399,7 @@ func (r *BucketReconciler) reconcileStorage(ctx context.Context, sp *patch.Seria
if artifactMissing {
msg += ": disappeared from storage"
}
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, msg)
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "%s", msg)
conditions.Delete(obj, sourcev1.ArtifactInStorageCondition)
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
return sreconcile.ResultEmpty, serror.NewGeneric(err, sourcev1.PatchOperationFailedReason)
@ -418,59 +418,132 @@ func (r *BucketReconciler) reconcileStorage(ctx context.Context, sp *patch.Seria
// reconcileSource fetches the upstream bucket contents with the client for the
// given object's Provider, and returns the result.
// When a SecretRef is defined, it attempts to fetch the Secret before calling
// the provider. If this fails, it records v1beta2.FetchFailedCondition=True on
// the provider. If this fails, it records v1.FetchFailedCondition=True on
// the object and returns early.
func (r *BucketReconciler) reconcileSource(ctx context.Context, sp *patch.SerialPatcher, obj *bucketv1.Bucket, index *index.Digester, dir string) (sreconcile.Result, error) {
secret, err := r.getBucketSecret(ctx, obj)
func (r *BucketReconciler) reconcileSource(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.Bucket, index *index.Digester, dir string) (sreconcile.Result, error) {
secret, err := r.getSecret(ctx, obj.Spec.SecretRef, obj.GetNamespace())
if err != nil {
e := serror.NewGeneric(err, sourcev1.AuthenticationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
// Return error as the world as observed may change
return sreconcile.ResultEmpty, e
}
proxyURL, err := r.getProxyURL(ctx, obj)
if err != nil {
e := serror.NewGeneric(err, sourcev1.AuthenticationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
// Construct provider client
var provider BucketProvider
switch obj.Spec.Provider {
case bucketv1.GoogleBucketProvider:
case sourcev1.BucketProviderGoogle:
if err = gcp.ValidateSecret(secret); err != nil {
e := serror.NewGeneric(err, sourcev1.AuthenticationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
if provider, err = gcp.NewClient(ctx, secret); err != nil {
var opts []gcp.Option
if secret != nil {
opts = append(opts, gcp.WithSecret(secret))
}
if proxyURL != nil {
opts = append(opts, gcp.WithProxyURL(proxyURL))
}
if provider, err = gcp.NewClient(ctx, opts...); err != nil {
e := serror.NewGeneric(err, "ClientError")
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
case bucketv1.AzureBucketProvider:
case sourcev1.BucketProviderAzure:
if err = azure.ValidateSecret(secret); err != nil {
e := serror.NewGeneric(err, sourcev1.AuthenticationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
if provider, err = azure.NewClient(obj, secret); err != nil {
var opts []azure.Option
if secret != nil {
opts = append(opts, azure.WithSecret(secret))
}
if proxyURL != nil {
opts = append(opts, azure.WithProxyURL(proxyURL))
}
if provider, err = azure.NewClient(obj, opts...); err != nil {
e := serror.NewGeneric(err, "ClientError")
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
default:
if err = minio.ValidateSecret(secret); err != nil {
e := serror.NewGeneric(err, sourcev1.AuthenticationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
if provider, err = minio.NewClient(obj, secret); err != nil {
tlsConfig, err := r.getTLSConfig(ctx, obj.Spec.CertSecretRef, obj.GetNamespace(), obj.Spec.Endpoint)
if err != nil {
e := serror.NewGeneric(err, sourcev1.AuthenticationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
stsSecret, err := r.getSTSSecret(ctx, obj)
if err != nil {
e := serror.NewGeneric(err, sourcev1.AuthenticationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
stsTLSConfig, err := r.getSTSTLSConfig(ctx, obj)
if err != nil {
err := fmt.Errorf("failed to get STS TLS config: %w", err)
e := serror.NewGeneric(err, sourcev1.AuthenticationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
if sts := obj.Spec.STS; sts != nil {
if err := minio.ValidateSTSProvider(obj.Spec.Provider, sts); err != nil {
e := serror.NewStalling(err, sourcev1.InvalidSTSConfigurationReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
if _, err := url.Parse(sts.Endpoint); err != nil {
err := fmt.Errorf("failed to parse STS endpoint '%s': %w", sts.Endpoint, err)
e := serror.NewStalling(err, sourcev1.URLInvalidReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
if err := minio.ValidateSTSSecret(sts.Provider, stsSecret); err != nil {
e := serror.NewGeneric(err, sourcev1.AuthenticationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
}
var opts []minio.Option
if secret != nil {
opts = append(opts, minio.WithSecret(secret))
}
if tlsConfig != nil {
opts = append(opts, minio.WithTLSConfig(tlsConfig))
}
if proxyURL != nil {
opts = append(opts, minio.WithProxyURL(proxyURL))
}
if stsSecret != nil {
opts = append(opts, minio.WithSTSSecret(stsSecret))
}
if stsTLSConfig != nil {
opts = append(opts, minio.WithSTSTLSConfig(stsTLSConfig))
}
if provider, err = minio.NewClient(obj, opts...); err != nil {
e := serror.NewGeneric(err, "ClientError")
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
}
// Fetch etag index
if err = fetchEtagIndex(ctx, provider, obj, index, dir); err != nil {
e := serror.NewGeneric(err, bucketv1.BucketOperationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Error())
e := serror.NewGeneric(err, sourcev1.BucketOperationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -491,7 +564,7 @@ func (r *BucketReconciler) reconcileSource(ctx context.Context, sp *patch.Serial
message := fmt.Sprintf("new upstream revision '%s'", revision)
if obj.GetArtifact() != nil {
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", message)
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", "%s", message)
}
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "building artifact: %s", message)
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
@ -501,8 +574,8 @@ func (r *BucketReconciler) reconcileSource(ctx context.Context, sp *patch.Serial
}()
if err = fetchIndexFiles(ctx, provider, obj, index, dir); err != nil {
e := serror.NewGeneric(err, bucketv1.BucketOperationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Error())
e := serror.NewGeneric(err, sourcev1.BucketOperationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
}
@ -515,12 +588,12 @@ func (r *BucketReconciler) reconcileSource(ctx context.Context, sp *patch.Serial
// (Status) data on the object does not match the given.
//
// The inspection of the given data to the object is differed, ensuring any
// stale observations like v1beta2.ArtifactOutdatedCondition are removed.
// stale observations like v1.ArtifactOutdatedCondition are removed.
// If the given Artifact does not differ from the object's current, it returns
// early.
// On a successful archive, the Artifact in the Status of the object is set,
// and the symlink in the Storage is updated to its path.
func (r *BucketReconciler) reconcileArtifact(ctx context.Context, sp *patch.SerialPatcher, obj *bucketv1.Bucket, index *index.Digester, dir string) (sreconcile.Result, error) {
func (r *BucketReconciler) reconcileArtifact(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.Bucket, index *index.Digester, dir string) (sreconcile.Result, error) {
// Calculate revision
revision := index.Digest(intdigest.Canonical)
@ -554,14 +627,14 @@ func (r *BucketReconciler) reconcileArtifact(ctx context.Context, sp *patch.Seri
fmt.Errorf("failed to stat source path: %w", err),
sourcev1.StatOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
} else if !f.IsDir() {
e := serror.NewGeneric(
fmt.Errorf("source path '%s' is not a directory", dir),
sourcev1.InvalidPathReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -571,7 +644,7 @@ func (r *BucketReconciler) reconcileArtifact(ctx context.Context, sp *patch.Seri
fmt.Errorf("failed to create artifact directory: %w", err),
sourcev1.DirCreationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
unlock, err := r.Storage.Lock(artifact)
@ -589,7 +662,7 @@ func (r *BucketReconciler) reconcileArtifact(ctx context.Context, sp *patch.Seri
fmt.Errorf("unable to archive artifact to storage: %s", err),
sourcev1.ArchiveOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -613,7 +686,7 @@ func (r *BucketReconciler) reconcileArtifact(ctx context.Context, sp *patch.Seri
// reconcileDelete handles the deletion of the object.
// It first garbage collects all Artifacts for the object from the Storage.
// Removing the finalizer from the object if successful.
func (r *BucketReconciler) reconcileDelete(ctx context.Context, obj *bucketv1.Bucket) (sreconcile.Result, error) {
func (r *BucketReconciler) reconcileDelete(ctx context.Context, obj *sourcev1.Bucket) (sreconcile.Result, error) {
// Garbage collect the resource's artifacts
if err := r.garbageCollect(ctx, obj); err != nil {
// Return the error so we retry the failed garbage collection
@ -632,7 +705,7 @@ func (r *BucketReconciler) reconcileDelete(ctx context.Context, obj *bucketv1.Bu
// It removes all but the current Artifact from the Storage, unless the
// deletion timestamp on the object is set. Which will result in the
// removal of all Artifacts for the objects.
func (r *BucketReconciler) garbageCollect(ctx context.Context, obj *bucketv1.Bucket) error {
func (r *BucketReconciler) garbageCollect(ctx context.Context, obj *sourcev1.Bucket) error {
if !obj.DeletionTimestamp.IsZero() {
if deleted, err := r.Storage.RemoveAll(r.Storage.NewArtifactFor(obj.Kind, obj.GetObjectMeta(), "", "*")); err != nil {
return serror.NewGeneric(
@ -656,22 +729,22 @@ func (r *BucketReconciler) garbageCollect(ctx context.Context, obj *bucketv1.Buc
}
if len(delFiles) > 0 {
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, "GarbageCollectionSucceeded",
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)))
"garbage collected %d artifacts", len(delFiles))
return nil
}
}
return nil
}
// getBucketSecret attempts to fetch the Secret reference if specified on the
// obj. It returns any client error.
func (r *BucketReconciler) getBucketSecret(ctx context.Context, obj *bucketv1.Bucket) (*corev1.Secret, error) {
if obj.Spec.SecretRef == nil {
// getSecret attempts to fetch a Secret reference if specified. It returns any client error.
func (r *BucketReconciler) getSecret(ctx context.Context, secretRef *meta.LocalObjectReference,
namespace string) (*corev1.Secret, error) {
if secretRef == nil {
return nil, nil
}
secretName := types.NamespacedName{
Namespace: obj.GetNamespace(),
Name: obj.Spec.SecretRef.Name,
Namespace: namespace,
Name: secretRef.Name,
}
secret := &corev1.Secret{}
if err := r.Get(ctx, secretName, secret); err != nil {
@ -680,6 +753,68 @@ func (r *BucketReconciler) getBucketSecret(ctx context.Context, obj *bucketv1.Bu
return secret, nil
}
// getTLSConfig attempts to fetch a TLS configuration from the given
// Secret reference, namespace and endpoint.
func (r *BucketReconciler) getTLSConfig(ctx context.Context,
secretRef *meta.LocalObjectReference, namespace, endpoint string) (*stdtls.Config, error) {
certSecret, err := r.getSecret(ctx, secretRef, namespace)
if err != nil || certSecret == nil {
return nil, err
}
tlsConfig, _, err := tls.KubeTLSClientConfigFromSecret(*certSecret, endpoint)
if err != nil {
return nil, fmt.Errorf("failed to create TLS config: %w", err)
}
if tlsConfig == nil {
return nil, fmt.Errorf("certificate secret does not contain any TLS configuration")
}
return tlsConfig, nil
}
// getProxyURL attempts to fetch a proxy URL from the object's proxy secret
// reference.
func (r *BucketReconciler) getProxyURL(ctx context.Context, obj *sourcev1.Bucket) (*url.URL, error) {
namespace := obj.GetNamespace()
proxySecret, err := r.getSecret(ctx, obj.Spec.ProxySecretRef, namespace)
if err != nil || proxySecret == nil {
return nil, err
}
proxyData := proxySecret.Data
address, ok := proxyData["address"]
if !ok {
return nil, fmt.Errorf("invalid proxy secret '%s/%s': key 'address' is missing",
namespace, obj.Spec.ProxySecretRef.Name)
}
proxyURL, err := url.Parse(string(address))
if err != nil {
return nil, fmt.Errorf("failed to parse proxy address '%s': %w", address, err)
}
user, hasUser := proxyData["username"]
password, hasPassword := proxyData["password"]
if hasUser || hasPassword {
proxyURL.User = url.UserPassword(string(user), string(password))
}
return proxyURL, nil
}
// getSTSSecret attempts to fetch the secret from the object's STS secret
// reference.
func (r *BucketReconciler) getSTSSecret(ctx context.Context, obj *sourcev1.Bucket) (*corev1.Secret, error) {
if obj.Spec.STS == nil {
return nil, nil
}
return r.getSecret(ctx, obj.Spec.STS.SecretRef, obj.GetNamespace())
}
// getSTSTLSConfig attempts to fetch the certificate secret from the object's
// STS configuration.
func (r *BucketReconciler) getSTSTLSConfig(ctx context.Context, obj *sourcev1.Bucket) (*stdtls.Config, error) {
if obj.Spec.STS == nil {
return nil, nil
}
return r.getTLSConfig(ctx, obj.Spec.STS.CertSecretRef, obj.GetNamespace(), obj.Spec.STS.Endpoint)
}
// eventLogf records events, and logs at the same time.
//
// This log is different from the debug log in the EventRecorder, in the sense
@ -710,7 +845,7 @@ func (r *BucketReconciler) annotatedEventLogf(ctx context.Context,
// bucket using the given provider, while filtering them using .sourceignore
// rules. After fetching an object, the etag value in the index is updated to
// the current value to ensure accuracy.
func fetchEtagIndex(ctx context.Context, provider BucketProvider, obj *bucketv1.Bucket, index *index.Digester, tempDir string) error {
func fetchEtagIndex(ctx context.Context, provider BucketProvider, obj *sourcev1.Bucket, index *index.Digester, tempDir string) error {
ctxTimeout, cancel := context.WithTimeout(ctx, obj.Spec.Timeout.Duration)
defer cancel()
@ -728,7 +863,7 @@ func fetchEtagIndex(ctx context.Context, provider BucketProvider, obj *bucketv1.
path := filepath.Join(tempDir, sourceignore.IgnoreFile)
if _, err := provider.FGetObject(ctxTimeout, obj.Spec.BucketName, sourceignore.IgnoreFile, path); err != nil {
if !provider.ObjectIsNotFound(err) {
return err
return fmt.Errorf("failed to get Etag for '%s' object: %w", sourceignore.IgnoreFile, serror.SanitizeError(err))
}
}
ps, err := sourceignore.ReadIgnoreFile(path, nil)
@ -764,7 +899,7 @@ func fetchEtagIndex(ctx context.Context, provider BucketProvider, obj *bucketv1.
// using the given provider, and stores them into tempDir. It downloads in
// parallel, but limited to the maxConcurrentBucketFetches.
// Given an index is provided, the bucket is assumed to exist.
func fetchIndexFiles(ctx context.Context, provider BucketProvider, obj *bucketv1.Bucket, index *index.Digester, tempDir string) error {
func fetchIndexFiles(ctx context.Context, provider BucketProvider, obj *sourcev1.Bucket, index *index.Digester, tempDir string) error {
ctxTimeout, cancel := context.WithTimeout(ctx, obj.Spec.Timeout.Duration)
defer cancel()
@ -792,7 +927,7 @@ func fetchIndexFiles(ctx context.Context, provider BucketProvider, obj *bucketv1
index.Delete(k)
return nil
}
return fmt.Errorf("failed to get '%s' object: %w", k, err)
return fmt.Errorf("failed to get '%s' object: %w", k, serror.SanitizeError(err))
}
if t != etag {
index.Add(k, etag)

View File

@ -27,7 +27,7 @@ import (
"gotest.tools/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta2"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
"github.com/fluxcd/source-controller/internal/index"
)

File diff suppressed because it is too large Load Diff

View File

@ -27,12 +27,16 @@ import (
"time"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/fluxcd/pkg/auth"
authutils "github.com/fluxcd/pkg/auth/utils"
"github.com/fluxcd/pkg/git/github"
"github.com/fluxcd/pkg/runtime/logger"
"github.com/go-git/go-git/v5/plumbing/transport"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
kuberecorder "k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
"k8s.io/utils/ptr"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
@ -40,10 +44,11 @@ import (
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/ratelimiter"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/cache"
"github.com/fluxcd/pkg/git"
"github.com/fluxcd/pkg/git/gogit"
"github.com/fluxcd/pkg/git/repository"
@ -65,7 +70,7 @@ import (
)
// gitRepositoryReadyCondition contains the information required to summarize a
// v1beta2.GitRepository Ready Condition.
// v1.GitRepository Ready Condition.
var gitRepositoryReadyCondition = summarize.Conditions{
Target: meta.ReadyCondition,
Owned: []string{
@ -120,7 +125,7 @@ func getPatchOptions(ownedConditions []string, controllerName string) []patch.Op
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=gitrepositories/finalizers,verbs=get;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
// GitRepositoryReconciler reconciles a v1beta2.GitRepository object.
// GitRepositoryReconciler reconciles a v1.GitRepository object.
type GitRepositoryReconciler struct {
client.Client
kuberecorder.EventRecorder
@ -128,6 +133,7 @@ type GitRepositoryReconciler struct {
Storage *Storage
ControllerName string
TokenCache *cache.TokenCache
requeueDependency time.Duration
features map[string]bool
@ -137,11 +143,11 @@ type GitRepositoryReconciler struct {
type GitRepositoryReconcilerOptions struct {
DependencyRequeueInterval time.Duration
RateLimiter ratelimiter.RateLimiter
RateLimiter workqueue.TypedRateLimiter[reconcile.Request]
}
// gitRepositoryReconcileFunc is the function type for all the
// v1beta2.GitRepository (sub)reconcile functions.
// v1.GitRepository (sub)reconcile functions.
type gitRepositoryReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.GitRepository, commit *git.Commit, includes *artifactSet, dir string) (sreconcile.Result, error)
func (r *GitRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error {
@ -204,9 +210,7 @@ func (r *GitRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reques
}
result, retErr = summarizeHelper.SummarizeAndPatch(ctx, obj, summarizeOpts...)
// Always record suspend, readiness and duration metrics.
r.Metrics.RecordSuspend(ctx, obj, obj.Spec.Suspend)
r.Metrics.RecordReadiness(ctx, obj)
// Always record duration metrics.
r.Metrics.RecordDuration(ctx, obj, start)
}()
@ -279,7 +283,7 @@ func (r *GitRepositoryReconciler) reconcile(ctx context.Context, sp *patch.Seria
fmt.Errorf("failed to create temporary working directory: %w", err),
sourcev1.DirCreationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
defer func() {
@ -422,7 +426,7 @@ func (r *GitRepositoryReconciler) reconcileStorage(ctx context.Context, sp *patc
if artifactMissing {
msg += ": disappeared from storage"
}
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, msg)
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "%s", msg)
conditions.Delete(obj, sourcev1.ArtifactInStorageCondition)
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
return sreconcile.ResultEmpty, serror.NewGeneric(err, sourcev1.PatchOperationFailedReason)
@ -443,23 +447,23 @@ func (r *GitRepositoryReconciler) reconcileStorage(ctx context.Context, sp *patc
//
// The included repositories are fetched and their metadata are stored. In case
// one of the included repositories isn't ready, it records
// v1beta2.IncludeUnavailableCondition=True and returns early. When all the
// v1.IncludeUnavailableCondition=True and returns early. When all the
// included repositories are ready, it removes
// v1beta2.IncludeUnavailableCondition from the object.
// v1.IncludeUnavailableCondition from the object.
// When the included artifactSet differs from the current set in the Status of
// the object, it marks the object with v1beta2.ArtifactOutdatedCondition=True.
// the object, it marks the object with v1.ArtifactOutdatedCondition=True.
// The repository is cloned to the given dir, using the specified configuration
// to check out the reference. In case of an error during this process
// (including transient errors), it records v1beta2.FetchFailedCondition=True
// (including transient errors), it records v1.FetchFailedCondition=True
// and returns early.
// On a successful checkout, it removes v1beta2.FetchFailedCondition and
// On a successful checkout, it removes v1.FetchFailedCondition and
// compares the current revision of HEAD to the revision of the Artifact in the
// Status of the object. It records v1beta2.ArtifactOutdatedCondition=True when
// Status of the object. It records v1.ArtifactOutdatedCondition=True when
// they differ.
// If specified, the signature of the Git commit is verified. If the signature
// can not be verified or the verification fails, it records
// v1beta2.SourceVerifiedCondition=False and returns early. When successful,
// it records v1beta2.SourceVerifiedCondition=True.
// v1.SourceVerifiedCondition=False and returns early. When successful,
// it records v1.SourceVerifiedCondition=True.
// When all the above is successful, the given Commit pointer is set to the
// commit of the checked out Git repository.
//
@ -478,15 +482,16 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
}
var proxyOpts *transport.ProxyOptions
var proxyURL *url.URL
if obj.Spec.ProxySecretRef != nil {
var err error
proxyOpts, err = r.getProxyOpts(ctx, obj.Spec.ProxySecretRef.Name, obj.GetNamespace())
proxyOpts, proxyURL, err = r.getProxyOpts(ctx, obj.Spec.ProxySecretRef.Name, obj.GetNamespace())
if err != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to configure proxy options: %w", err),
sourcev1.AuthenticationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
// Return error as the world as observed may change
return sreconcile.ResultEmpty, e
}
@ -498,19 +503,14 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
fmt.Errorf("failed to parse url '%s': %w", obj.Spec.URL, err),
sourcev1.URLInvalidReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
authOpts, err := r.getAuthOpts(ctx, obj, *u)
authOpts, err := r.getAuthOpts(ctx, obj, *u, proxyURL)
if err != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to configure authentication options: %w", err),
sourcev1.AuthenticationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
// Return error as the world as observed may change
return sreconcile.ResultEmpty, e
return sreconcile.ResultEmpty, err
}
// Fetch the included artifact metadata.
@ -523,7 +523,7 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
if artifacts.Diff(obj.Status.IncludedArtifacts) {
message := "included artifacts differ from last observed includes"
if obj.Status.IncludedArtifacts != nil {
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "IncludeChange", message)
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "IncludeChange", "%s", message)
}
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "building artifact: %s", message)
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
@ -544,7 +544,7 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
fmt.Errorf("git repository is empty"),
"EmptyGitRepository",
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
// Assign the commit to the shared commit reference.
@ -588,6 +588,16 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
ctrl.LoggerFrom(ctx).V(logger.DebugLevel).Info("git repository checked out", "url", obj.Spec.URL, "revision", commitReference(obj, commit))
conditions.Delete(obj, sourcev1.FetchFailedCondition)
// Validate sparse checkout paths after successful checkout.
if err := r.validateSparseCheckoutPaths(ctx, obj, dir); err != nil {
e := serror.NewStalling(
fmt.Errorf("failed to sparse checkout directories : %w", err),
sourcev1.GitOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
// Verify commit signature
if result, err := r.verifySignature(ctx, obj, *commit); err != nil || result == sreconcile.ResultEmpty {
return result, err
@ -597,7 +607,7 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
if !obj.GetArtifact().HasRevision(commitReference(obj, commit)) {
message := fmt.Sprintf("new upstream revision '%s'", commitReference(obj, commit))
if obj.GetArtifact() != nil {
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", message)
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", "%s", message)
}
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "building artifact: %s", message)
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
@ -610,43 +620,155 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
// getProxyOpts fetches the secret containing the proxy settings, constructs a
// transport.ProxyOptions object using those settings and then returns it.
func (r *GitRepositoryReconciler) getProxyOpts(ctx context.Context, proxySecretName,
proxySecretNamespace string) (*transport.ProxyOptions, error) {
proxySecretNamespace string) (*transport.ProxyOptions, *url.URL, error) {
proxyData, err := r.getSecretData(ctx, proxySecretName, proxySecretNamespace)
if err != nil {
return nil, fmt.Errorf("failed to get proxy secret '%s/%s': %w", proxySecretNamespace, proxySecretName, err)
return nil, nil, fmt.Errorf("failed to get proxy secret '%s/%s': %w", proxySecretNamespace, proxySecretName, err)
}
address, ok := proxyData["address"]
b, ok := proxyData["address"]
if !ok {
return nil, fmt.Errorf("invalid proxy secret '%s/%s': key 'address' is missing", proxySecretNamespace, proxySecretName)
return nil, nil, fmt.Errorf("invalid proxy secret '%s/%s': key 'address' is missing", proxySecretNamespace, proxySecretName)
}
address := string(b)
username := string(proxyData["username"])
password := string(proxyData["password"])
proxyOpts := &transport.ProxyOptions{
URL: string(address),
Username: string(proxyData["username"]),
Password: string(proxyData["password"]),
URL: address,
Username: username,
Password: password,
}
return proxyOpts, nil
proxyURL, err := url.Parse(string(address))
if err != nil {
return nil, nil, fmt.Errorf("invalid address in proxy secret '%s/%s': %w", proxySecretNamespace, proxySecretName, err)
}
switch {
case username != "" && password == "":
proxyURL.User = url.User(username)
case username != "" && password != "":
proxyURL.User = url.UserPassword(username, password)
}
return proxyOpts, proxyURL, nil
}
// getAuthOpts fetches the secret containing the auth options (if specified),
// constructs a git.AuthOptions object using those options along with the provided
// URL and returns it.
func (r *GitRepositoryReconciler) getAuthOpts(ctx context.Context, obj *sourcev1.GitRepository, u url.URL) (*git.AuthOptions, error) {
func (r *GitRepositoryReconciler) getAuthOpts(ctx context.Context, obj *sourcev1.GitRepository,
u url.URL, proxyURL *url.URL) (*git.AuthOptions, error) {
var authData map[string][]byte
if obj.Spec.SecretRef != nil {
var err error
authData, err = r.getSecretData(ctx, obj.Spec.SecretRef.Name, obj.GetNamespace())
if err != nil {
return nil, fmt.Errorf("failed to get secret '%s/%s': %w", obj.GetNamespace(), obj.Spec.SecretRef.Name, err)
e := serror.NewGeneric(
fmt.Errorf("failed to get secret '%s/%s': %w", obj.GetNamespace(), obj.Spec.SecretRef.Name, err),
sourcev1.AuthenticationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return nil, e
}
}
// Configure authentication strategy to access the source
authOpts, err := git.NewAuthOptions(u, authData)
opts, err := git.NewAuthOptions(u, authData)
if err != nil {
return nil, err
e := serror.NewGeneric(
fmt.Errorf("failed to configure authentication options: %w", err),
sourcev1.AuthenticationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return nil, e
}
return authOpts, nil
// Configure provider authentication if specified.
var getCreds func() (*authutils.GitCredentials, error)
switch provider := obj.GetProvider(); provider {
case sourcev1.GitProviderAzure: // If AWS or GCP are added in the future they can be added here separated by a comma.
getCreds = func() (*authutils.GitCredentials, error) {
var opts []auth.Option
if r.TokenCache != nil {
involvedObject := cache.InvolvedObject{
Kind: sourcev1.GitRepositoryKind,
Name: obj.GetName(),
Namespace: obj.GetNamespace(),
Operation: cache.OperationReconcile,
}
opts = append(opts, auth.WithCache(*r.TokenCache, involvedObject))
}
if proxyURL != nil {
opts = append(opts, auth.WithProxyURL(*proxyURL))
}
return authutils.GetGitCredentials(ctx, provider, opts...)
}
case sourcev1.GitProviderGitHub:
// if provider is github, but secret ref is not specified
if obj.Spec.SecretRef == nil {
e := serror.NewStalling(
fmt.Errorf("secretRef with github app data must be specified when provider is set to github"),
sourcev1.InvalidProviderConfigurationReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return nil, e
}
getCreds = func() (*authutils.GitCredentials, error) {
var opts []github.OptFunc
if len(authData) > 0 {
opts = append(opts, github.WithAppData(authData))
}
if proxyURL != nil {
opts = append(opts, github.WithProxyURL(proxyURL))
}
if r.TokenCache != nil {
opts = append(opts, github.WithCache(r.TokenCache, sourcev1.GitRepositoryKind,
obj.GetName(), obj.GetNamespace(), cache.OperationReconcile))
}
username, password, err := github.GetCredentials(ctx, opts...)
if err != nil {
return nil, err
}
return &authutils.GitCredentials{
Username: username,
Password: password,
}, nil
}
default:
// analyze secret, if it has github app data, perhaps provider should have been github.
if appID := authData[github.AppIDKey]; len(appID) != 0 {
e := serror.NewStalling(
fmt.Errorf("secretRef '%s/%s' has github app data but provider is not set to github", obj.GetNamespace(), obj.Spec.SecretRef.Name),
sourcev1.InvalidProviderConfigurationReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return nil, e
}
}
if getCreds != nil {
creds, err := getCreds()
if err != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to configure authentication options: %w", err),
sourcev1.AuthenticationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return nil, e
}
opts.BearerToken = creds.BearerToken
opts.Username = creds.Username
opts.Password = creds.Password
}
return opts, nil
}
func (r *GitRepositoryReconciler) getSecretData(ctx context.Context, name, namespace string) (map[string][]byte, error) {
@ -665,7 +787,7 @@ func (r *GitRepositoryReconciler) getSecretData(ctx context.Context, name, names
// (Status) data on the object does not match the given.
//
// The inspection of the given data to the object is differed, ensuring any
// stale observations like v1beta2.ArtifactOutdatedCondition are removed.
// stale observations like v1.ArtifactOutdatedCondition are removed.
// If the given Artifact and/or artifactSet (includes) and observed artifact
// content config do not differ from the object's current, it returns early.
// Source ignore patterns are loaded, and the given directory is archived while
@ -703,14 +825,14 @@ func (r *GitRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pat
fmt.Errorf("failed to stat target artifact path: %w", err),
sourcev1.StatOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
} else if !f.IsDir() {
e := serror.NewGeneric(
fmt.Errorf("invalid target path: '%s' is not a directory", dir),
sourcev1.InvalidPathReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -720,7 +842,7 @@ func (r *GitRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pat
fmt.Errorf("failed to create artifact directory: %w", err),
sourcev1.DirCreationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
unlock, err := r.Storage.Lock(artifact)
@ -751,7 +873,7 @@ func (r *GitRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pat
fmt.Errorf("unable to archive artifact to storage: %w", err),
sourcev1.ArchiveOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -761,6 +883,7 @@ func (r *GitRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pat
obj.Status.ObservedIgnore = obj.Spec.Ignore
obj.Status.ObservedRecurseSubmodules = obj.Spec.RecurseSubmodules
obj.Status.ObservedInclude = obj.Spec.Include
obj.Status.ObservedSparseCheckout = obj.Spec.SparseCheckout
// Remove the deprecated symlink.
// TODO(hidde): remove 2 minor versions from introduction of v1.
@ -780,15 +903,15 @@ func (r *GitRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pat
}
// reconcileInclude reconciles the on the object specified
// v1beta2.GitRepositoryInclude list by copying their Artifact (sub)contents to
// v1.GitRepositoryInclude list by copying their Artifact (sub)contents to
// the specified paths in the given directory.
//
// When one of the includes is unavailable, it marks the object with
// v1beta2.IncludeUnavailableCondition=True and returns early.
// v1.IncludeUnavailableCondition=True and returns early.
// When the copy operations are successful, it removes the
// v1beta2.IncludeUnavailableCondition from the object.
// v1.IncludeUnavailableCondition from the object.
// When the composed artifactSet differs from the current set in the Status of
// the object, it marks the object with v1beta2.ArtifactOutdatedCondition=True.
// the object, it marks the object with v1.ArtifactOutdatedCondition=True.
func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context, sp *patch.SerialPatcher,
obj *sourcev1.GitRepository, _ *git.Commit, includes *artifactSet, dir string) (sreconcile.Result, error) {
@ -800,7 +923,7 @@ func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context, sp *patc
fmt.Errorf("path calculation for include '%s' failed: %w", incl.GitRepositoryRef.Name, err),
"IllegalPath",
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -821,7 +944,7 @@ func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context, sp *patc
fmt.Errorf("failed to copy '%s' include from %s to %s: %w", incl.GitRepositoryRef.Name, incl.GetFromPath(), incl.GetToPath(), err),
"CopyFailure",
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
}
@ -833,6 +956,7 @@ func (r *GitRepositoryReconciler) reconcileInclude(ctx context.Context, sp *patc
// performs a git checkout.
func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context, obj *sourcev1.GitRepository,
authOpts *git.AuthOptions, proxyOpts *transport.ProxyOptions, dir string, optimized bool) (*git.Commit, error) {
// Configure checkout strategy.
cloneOpts := repository.CloneConfig{
RecurseSubmodules: obj.Spec.RecurseSubmodules,
@ -845,7 +969,14 @@ func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context, obj *sourcev1
cloneOpts.SemVer = ref.SemVer
cloneOpts.RefName = ref.Name
}
if obj.Spec.SparseCheckout != nil {
// Trim any leading "./" in the directory paths since underlying go-git API does not honor them.
sparseCheckoutDirs := make([]string, len(obj.Spec.SparseCheckout))
for i, path := range obj.Spec.SparseCheckout {
sparseCheckoutDirs[i] = strings.TrimPrefix(path, "./")
}
cloneOpts.SparseCheckoutDirectories = sparseCheckoutDirs
}
// Only if the object has an existing artifact in storage, attempt to
// short-circuit clone operation. reconcileStorage has already verified
// that the artifact exists.
@ -872,7 +1003,7 @@ func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context, obj *sourcev1
fmt.Errorf("failed to create Git client: %w", err),
sourcev1.GitOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return nil, e
}
defer gitReader.Close()
@ -883,7 +1014,7 @@ func (r *GitRepositoryReconciler) gitCheckout(ctx context.Context, obj *sourcev1
fmt.Errorf("failed to checkout and determine revision: %w", err),
sourcev1.GitOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return nil, e
}
@ -902,7 +1033,7 @@ func (r *GitRepositoryReconciler) fetchIncludes(ctx context.Context, obj *source
"NotFound",
)
e.RequeueAfter = r.requeueDependency
conditions.MarkTrue(obj, sourcev1.IncludeUnavailableCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.IncludeUnavailableCondition, e.Reason, "%s", e)
return nil, e
}
@ -913,7 +1044,7 @@ func (r *GitRepositoryReconciler) fetchIncludes(ctx context.Context, obj *source
"NoArtifact",
)
e.RequeueAfter = r.requeueDependency
conditions.MarkTrue(obj, sourcev1.IncludeUnavailableCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.IncludeUnavailableCondition, e.Reason, "%s", e)
return nil, e
}
@ -929,10 +1060,10 @@ func (r *GitRepositoryReconciler) fetchIncludes(ctx context.Context, obj *source
// verifySignature verifies the signature of the given Git commit and/or its referencing tag
// depending on the verification mode specified on the object.
// If the signature can not be verified or the verification fails, it records
// v1beta2.SourceVerifiedCondition=False and returns.
// When successful, it records v1beta2.SourceVerifiedCondition=True.
// v1.SourceVerifiedCondition=False and returns.
// When successful, it records v1.SourceVerifiedCondition=True.
// If no verification mode is specified on the object, the
// v1beta2.SourceVerifiedCondition Condition is removed.
// v1.SourceVerifiedCondition Condition is removed.
func (r *GitRepositoryReconciler) verifySignature(ctx context.Context, obj *sourcev1.GitRepository, commit git.Commit) (sreconcile.Result, error) {
// Check if there is a commit verification is configured and remove any old
// observations if there is none
@ -953,7 +1084,7 @@ func (r *GitRepositoryReconciler) verifySignature(ctx context.Context, obj *sour
fmt.Errorf("PGP public keys secret error: %w", err),
"VerificationError",
)
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, e.Reason, e.Err.Error())
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -974,7 +1105,7 @@ func (r *GitRepositoryReconciler) verifySignature(ctx context.Context, obj *sour
errors.New("cannot verify tag object's signature if a tag reference is not specified"),
"InvalidVerificationMode",
)
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, err.Reason, err.Err.Error())
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, err.Reason, "%s", err)
return sreconcile.ResultEmpty, err
}
if !git.IsSignedTag(*tag) {
@ -985,7 +1116,7 @@ func (r *GitRepositoryReconciler) verifySignature(ctx context.Context, obj *sour
fmt.Errorf("cannot verify signature of tag '%s' since it is not signed", commit.ReferencingTag.String()),
"InvalidGitObject",
)
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, err.Reason, err.Err.Error())
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, err.Reason, "%s", err)
return sreconcile.ResultEmpty, err
}
@ -996,7 +1127,7 @@ func (r *GitRepositoryReconciler) verifySignature(ctx context.Context, obj *sour
fmt.Errorf("signature verification of tag '%s' failed: %w", tag.String(), err),
"InvalidTagSignature",
)
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, e.Reason, e.Err.Error())
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, e.Reason, "%s", e)
// Return error in the hope the secret changes
return sreconcile.ResultEmpty, e
}
@ -1012,7 +1143,7 @@ func (r *GitRepositoryReconciler) verifySignature(ctx context.Context, obj *sour
fmt.Errorf("signature verification of commit '%s' failed: %w", commit.Hash.String(), err),
"InvalidCommitSignature",
)
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, e.Reason, e.Err.Error())
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, e.Reason, "%s", e)
// Return error in the hope the secret changes
return sreconcile.ResultEmpty, e
}
@ -1027,8 +1158,8 @@ func (r *GitRepositoryReconciler) verifySignature(ctx context.Context, obj *sour
reason := meta.SucceededReason
mode := obj.Spec.Verification.GetMode()
obj.Status.SourceVerificationMode = &mode
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, reason, message.String())
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, reason, message.String())
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, reason, "%s", message.String())
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, reason, "%s", message.String())
return sreconcile.ResultSuccess, nil
}
@ -1045,6 +1176,10 @@ func (r *GitRepositoryReconciler) reconcileDelete(ctx context.Context, obj *sour
// Remove our finalizer from the list
controllerutil.RemoveFinalizer(obj, sourcev1.SourceFinalizer)
// Cleanup caches.
r.TokenCache.DeleteEventsForObject(sourcev1.GitRepositoryKind,
obj.GetName(), obj.GetNamespace(), cache.OperationReconcile)
// Stop reconciliation as the object is being deleted
return sreconcile.ResultEmpty, nil
}
@ -1078,7 +1213,7 @@ func (r *GitRepositoryReconciler) garbageCollect(ctx context.Context, obj *sourc
}
if len(delFiles) > 0 {
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, "GarbageCollectionSucceeded",
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)))
"garbage collected %d artifacts", len(delFiles))
return nil
}
}
@ -1118,6 +1253,14 @@ func gitContentConfigChanged(obj *sourcev1.GitRepository, includes *artifactSet)
if requiresVerification(obj) {
return true
}
if len(obj.Spec.SparseCheckout) != len(obj.Status.ObservedSparseCheckout) {
return true
}
for index, dir := range obj.Spec.SparseCheckout {
if dir != obj.Status.ObservedSparseCheckout[index] {
return true
}
}
// Convert artifactSet to index addressable artifacts and ensure that it and
// the included artifacts include all the include from the spec.
@ -1152,6 +1295,19 @@ func gitContentConfigChanged(obj *sourcev1.GitRepository, includes *artifactSet)
return false
}
// validateSparseCheckoutPaths checks if the sparse checkout paths exist in the cloned repository.
func (r *GitRepositoryReconciler) validateSparseCheckoutPaths(ctx context.Context, obj *sourcev1.GitRepository, dir string) error {
if obj.Spec.SparseCheckout != nil {
for _, path := range obj.Spec.SparseCheckout {
fullPath := filepath.Join(dir, path)
if _, err := os.Lstat(fullPath); err != nil {
return fmt.Errorf("sparse checkout dir '%s' does not exist in repository: %w", path, err)
}
}
}
return nil
}
// Returns true if both GitRepositoryIncludes are equal.
func gitRepositoryIncludeEqual(a, b sourcev1.GitRepositoryInclude) bool {
if a.GitRepositoryRef != b.GitRepositoryRef {

View File

@ -49,6 +49,7 @@ import (
kstatus "github.com/fluxcd/cli-utils/pkg/kstatus/status"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/git"
"github.com/fluxcd/pkg/git/github"
"github.com/fluxcd/pkg/gittestserver"
"github.com/fluxcd/pkg/runtime/conditions"
conditionscheck "github.com/fluxcd/pkg/runtime/conditions/check"
@ -385,6 +386,63 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new upstream revision 'master@sha1:<commit>'"),
},
},
{
name: "HTTPS with mutual TLS makes Reconciling=True",
protocol: "https",
server: options{
publicKey: tlsPublicKey,
privateKey: tlsPrivateKey,
ca: tlsCA,
},
secret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "mtls-certs",
},
Data: map[string][]byte{
"ca.crt": tlsCA,
"tls.crt": clientPublicKey,
"tls.key": clientPrivateKey,
},
},
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "mtls-certs"}
},
want: sreconcile.ResultSuccess,
assertConditions: []metav1.Condition{
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new upstream revision 'master@sha1:<commit>'"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new upstream revision 'master@sha1:<commit>'"),
},
},
{
name: "HTTPS with mutual TLS and invalid private key makes CheckoutFailed=True and returns error",
protocol: "https",
server: options{
publicKey: tlsPublicKey,
privateKey: tlsPrivateKey,
ca: tlsCA,
},
secret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "invalid-mtls-certs",
},
Data: map[string][]byte{
"ca.crt": tlsCA,
"tls.crt": clientPublicKey,
"tls.key": []byte("invalid"),
},
},
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "invalid-mtls-certs"}
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, meta.ProgressingReason, "foo")
},
wantErr: true,
assertConditions: []metav1.Condition{
*conditions.TrueCondition(sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "tls: failed to find any PEM data in key input"),
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "foo"),
},
},
{
name: "HTTPS with CAFile secret makes Reconciling=True",
protocol: "https",
@ -571,6 +629,50 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new upstream revision 'master@sha1:<commit>'"),
},
},
{
// This test is only for verifying the failure state when using
// provider auth. Protocol http is used for simplicity.
name: "github provider without secret ref makes FetchFailed=True",
protocol: "http",
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.Provider = sourcev1.GitProviderGitHub
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, meta.ProgressingReason, "foo")
},
want: sreconcile.ResultEmpty,
wantErr: true,
assertConditions: []metav1.Condition{
*conditions.TrueCondition(sourcev1.FetchFailedCondition, sourcev1.InvalidProviderConfigurationReason, "secretRef with github app data must be specified when provider is set to github"),
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "foo"),
},
},
{
// This test is only for verifying the failure state when using
// provider auth. Protocol http is used for simplicity.
name: "empty provider with github app data in secret makes FetchFailed=True",
protocol: "http",
secret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "github-app-secret",
},
Data: map[string][]byte{
github.AppIDKey: []byte("1111"),
},
},
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "github-app-secret"}
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, meta.ProgressingReason, "foo")
},
want: sreconcile.ResultEmpty,
wantErr: true,
assertConditions: []metav1.Condition{
*conditions.TrueCondition(sourcev1.FetchFailedCondition, sourcev1.InvalidProviderConfigurationReason, "secretRef '/github-app-secret' has github app data but provider is not set to github"),
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "foo"),
},
},
}
for _, tt := range tests {
@ -683,6 +785,136 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
}
}
func TestGitRepositoryReconciler_getAuthOpts_provider(t *testing.T) {
tests := []struct {
name string
url string
secret *corev1.Secret
beforeFunc func(obj *sourcev1.GitRepository)
wantErr string
}{
{
name: "azure provider",
url: "https://dev.azure.com/foo/bar/_git/baz",
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.Provider = sourcev1.GitProviderAzure
},
wantErr: "ManagedIdentityCredential",
},
{
name: "github provider with no secret ref",
url: "https://github.com/org/repo.git",
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.Provider = sourcev1.GitProviderGitHub
},
wantErr: "secretRef with github app data must be specified when provider is set to github",
},
{
name: "github provider with github app data in secret",
url: "https://example.com/org/repo",
secret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "githubAppSecret",
},
Data: map[string][]byte{
github.AppIDKey: []byte("123"),
github.AppInstallationIDKey: []byte("456"),
github.AppPrivateKey: []byte("abc"),
},
},
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.Provider = sourcev1.GitProviderGitHub
obj.Spec.SecretRef = &meta.LocalObjectReference{
Name: "githubAppSecret",
}
},
wantErr: "Key must be a PEM encoded PKCS1 or PKCS8 key",
},
{
name: "generic provider with github app data in secret",
url: "https://example.com/org/repo",
secret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "githubAppSecret",
},
Data: map[string][]byte{
github.AppIDKey: []byte("123"),
},
},
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.Provider = sourcev1.GitProviderGeneric
obj.Spec.SecretRef = &meta.LocalObjectReference{
Name: "githubAppSecret",
}
},
wantErr: "secretRef '/githubAppSecret' has github app data but provider is not set to github",
},
{
name: "generic provider",
url: "https://example.com/org/repo",
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.Provider = sourcev1.GitProviderGeneric
},
},
{
name: "secret ref defined for non existing secret",
url: "https://github.com/org/repo.git",
beforeFunc: func(obj *sourcev1.GitRepository) {
obj.Spec.SecretRef = &meta.LocalObjectReference{
Name: "authSecret",
}
},
wantErr: "failed to get secret '/authSecret': secrets \"authSecret\" not found",
},
{
url: "https://example.com/org/repo",
name: "no provider",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
clientBuilder := fakeclient.NewClientBuilder().
WithScheme(testEnv.GetScheme()).
WithStatusSubresource(&sourcev1.GitRepository{})
if tt.secret != nil {
clientBuilder.WithObjects(tt.secret)
}
obj := &sourcev1.GitRepository{}
r := &GitRepositoryReconciler{
EventRecorder: record.NewFakeRecorder(32),
Client: clientBuilder.Build(),
features: features.FeatureGates(),
patchOptions: getPatchOptions(gitRepositoryReadyCondition.Owned, "sc"),
}
url, err := url.Parse(tt.url)
g.Expect(err).ToNot(HaveOccurred())
if tt.beforeFunc != nil {
tt.beforeFunc(obj)
}
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
opts, err := r.getAuthOpts(ctx, obj, *url, nil)
if tt.wantErr != "" {
g.Expect(err).To(HaveOccurred())
g.Expect(err.Error()).To(ContainSubstring(tt.wantErr))
} else {
g.Expect(err).ToNot(HaveOccurred())
g.Expect(opts).ToNot(BeNil())
g.Expect(opts.BearerToken).To(BeEmpty())
g.Expect(opts.Username).To(BeEmpty())
g.Expect(opts.Password).To(BeEmpty())
}
})
}
}
func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T) {
g := NewWithT(t)
@ -2032,6 +2264,7 @@ func TestGitRepositoryReconciler_getProxyOpts(t *testing.T) {
secret string
err string
proxyOpts *transport.ProxyOptions
proxyURL *url.URL
}{
{
name: "non-existent secret",
@ -2051,16 +2284,22 @@ func TestGitRepositoryReconciler_getProxyOpts(t *testing.T) {
Username: "user",
Password: "pass",
},
proxyURL: &url.URL{
Scheme: "https",
Host: "example.com",
User: url.UserPassword("user", "pass"),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
opts, err := r.getProxyOpts(context.TODO(), tt.secret, "default")
opts, proxyURL, err := r.getProxyOpts(context.TODO(), tt.secret, "default")
if opts != nil {
g.Expect(err).ToNot(HaveOccurred())
g.Expect(opts).To(Equal(tt.proxyOpts))
g.Expect(proxyURL).To(Equal(tt.proxyURL))
} else {
g.Expect(err).To(HaveOccurred())
g.Expect(err.Error()).To(ContainSubstring(tt.err))
@ -2895,6 +3134,38 @@ func TestGitContentConfigChanged(t *testing.T) {
},
want: false,
},
{
name: "unobserved sparse checkout",
obj: sourcev1.GitRepository{
Spec: sourcev1.GitRepositorySpec{SparseCheckout: []string{"a/b/c", "x/y/z"}},
Status: sourcev1.GitRepositoryStatus{ObservedSparseCheckout: []string{"a/b/c"}},
},
want: true,
},
{
name: "unobserved case sensitive sparse checkout",
obj: sourcev1.GitRepository{
Spec: sourcev1.GitRepositorySpec{SparseCheckout: []string{"a/b/c", "x/y/Z"}},
Status: sourcev1.GitRepositoryStatus{ObservedSparseCheckout: []string{"a/b/c", "x/y/z"}},
},
want: true,
},
{
name: "observed sparse checkout",
obj: sourcev1.GitRepository{
Spec: sourcev1.GitRepositorySpec{SparseCheckout: []string{"a/b/c", "x/y/z"}},
Status: sourcev1.GitRepositoryStatus{ObservedSparseCheckout: []string{"a/b/c", "x/y/z"}},
},
want: false,
},
{
name: "observed sparse checkout with leading slash",
obj: sourcev1.GitRepository{
Spec: sourcev1.GitRepositorySpec{SparseCheckout: []string{"./a/b/c", "./x/y/z"}},
Status: sourcev1.GitRepositoryStatus{ObservedSparseCheckout: []string{"./a/b/c", "./x/y/z"}},
},
want: false,
},
{
name: "unobserved include",
obj: sourcev1.GitRepository{

View File

@ -19,6 +19,7 @@ package controller
import (
"context"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"net/url"
@ -29,6 +30,7 @@ import (
"time"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/notaryproject/notation-go/verifier/trustpolicy"
"github.com/opencontainers/go-digest"
"github.com/sigstore/cosign/v2/pkg/cosign"
helmgetter "helm.sh/helm/v3/pkg/getter"
@ -41,6 +43,7 @@ import (
"k8s.io/apimachinery/pkg/types"
kerrors "k8s.io/apimachinery/pkg/util/errors"
kuberecorder "k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
@ -48,7 +51,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/ratelimiter"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
@ -63,13 +65,14 @@ import (
"github.com/fluxcd/pkg/tar"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
helmv1 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/fluxcd/source-controller/internal/cache"
serror "github.com/fluxcd/source-controller/internal/error"
"github.com/fluxcd/source-controller/internal/helm/chart"
"github.com/fluxcd/source-controller/internal/helm/getter"
"github.com/fluxcd/source-controller/internal/helm/repository"
soci "github.com/fluxcd/source-controller/internal/oci"
scosign "github.com/fluxcd/source-controller/internal/oci/cosign"
"github.com/fluxcd/source-controller/internal/oci/notation"
sreconcile "github.com/fluxcd/source-controller/internal/reconcile"
"github.com/fluxcd/source-controller/internal/reconcile/summarize"
"github.com/fluxcd/source-controller/internal/util"
@ -151,32 +154,32 @@ func (r *HelmChartReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Man
}
type HelmChartReconcilerOptions struct {
RateLimiter ratelimiter.RateLimiter
RateLimiter workqueue.TypedRateLimiter[reconcile.Request]
}
// helmChartReconcileFunc is the function type for all the v1beta2.HelmChart
// helmChartReconcileFunc is the function type for all the v1.HelmChart
// (sub)reconcile functions. The type implementations are grouped and
// executed serially to perform the complete reconcile of the object.
type helmChartReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *helmv1.HelmChart, build *chart.Build) (sreconcile.Result, error)
type helmChartReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmChart, build *chart.Build) (sreconcile.Result, error)
func (r *HelmChartReconciler) SetupWithManagerAndOptions(ctx context.Context, mgr ctrl.Manager, opts HelmChartReconcilerOptions) error {
r.patchOptions = getPatchOptions(helmChartReadyCondition.Owned, r.ControllerName)
if err := mgr.GetCache().IndexField(ctx, &helmv1.HelmRepository{}, helmv1.HelmRepositoryURLIndexKey,
if err := mgr.GetCache().IndexField(ctx, &sourcev1.HelmRepository{}, sourcev1.HelmRepositoryURLIndexKey,
r.indexHelmRepositoryByURL); err != nil {
return fmt.Errorf("failed setting index fields: %w", err)
}
if err := mgr.GetCache().IndexField(ctx, &helmv1.HelmChart{}, sourcev1.SourceIndexKey,
if err := mgr.GetCache().IndexField(ctx, &sourcev1.HelmChart{}, sourcev1.SourceIndexKey,
r.indexHelmChartBySource); err != nil {
return fmt.Errorf("failed setting index fields: %w", err)
}
return ctrl.NewControllerManagedBy(mgr).
For(&helmv1.HelmChart{}, builder.WithPredicates(
For(&sourcev1.HelmChart{}, builder.WithPredicates(
predicate.Or(predicate.GenerationChangedPredicate{}, predicates.ReconcileRequestedPredicate{}),
)).
Watches(
&helmv1.HelmRepository{},
&sourcev1.HelmRepository{},
handler.EnqueueRequestsFromMapFunc(r.requestsForHelmRepositoryChange),
builder.WithPredicates(SourceRevisionChangePredicate{}),
).
@ -186,7 +189,7 @@ func (r *HelmChartReconciler) SetupWithManagerAndOptions(ctx context.Context, mg
builder.WithPredicates(SourceRevisionChangePredicate{}),
).
Watches(
&helmv1.Bucket{},
&sourcev1.Bucket{},
handler.EnqueueRequestsFromMapFunc(r.requestsForBucketChange),
builder.WithPredicates(SourceRevisionChangePredicate{}),
).
@ -201,7 +204,7 @@ func (r *HelmChartReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
log := ctrl.LoggerFrom(ctx)
// Fetch the HelmChart
obj := &helmv1.HelmChart{}
obj := &sourcev1.HelmChart{}
if err := r.Get(ctx, req.NamespacedName, obj); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
@ -233,9 +236,7 @@ func (r *HelmChartReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
}
result, retErr = summarizeHelper.SummarizeAndPatch(ctx, obj, summarizeOpts...)
// Always record suspend, readiness and duration metrics.
r.Metrics.RecordSuspend(ctx, obj, obj.Spec.Suspend)
r.Metrics.RecordReadiness(ctx, obj)
// Always record duration metrics.
r.Metrics.RecordDuration(ctx, obj, start)
}()
@ -275,7 +276,7 @@ func (r *HelmChartReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
// reconcile iterates through the helmChartReconcileFunc tasks for the
// object. It returns early on the first call that returns
// reconcile.ResultRequeue, or produces an error.
func (r *HelmChartReconciler) reconcile(ctx context.Context, sp *patch.SerialPatcher, obj *helmv1.HelmChart, reconcilers []helmChartReconcileFunc) (sreconcile.Result, error) {
func (r *HelmChartReconciler) reconcile(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmChart, reconcilers []helmChartReconcileFunc) (sreconcile.Result, error) {
oldObj := obj.DeepCopy()
rreconcile.ProgressiveStatus(false, obj, meta.ProgressingReason, "reconciliation in progress")
@ -328,7 +329,7 @@ func (r *HelmChartReconciler) reconcile(ctx context.Context, sp *patch.SerialPat
}
// notify emits notification related to the reconciliation.
func (r *HelmChartReconciler) notify(ctx context.Context, oldObj, newObj *helmv1.HelmChart, build *chart.Build, res sreconcile.Result, resErr error) {
func (r *HelmChartReconciler) notify(ctx context.Context, oldObj, newObj *sourcev1.HelmChart, build *chart.Build, res sreconcile.Result, resErr error) {
// Notify successful reconciliation for new artifact and recovery from any
// failure.
if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil {
@ -364,7 +365,7 @@ func (r *HelmChartReconciler) notify(ctx context.Context, oldObj, newObj *helmv1
// condition is added.
// The hostname of any URL in the Status of the object are updated, to ensure
// they match the Storage server hostname of current runtime.
func (r *HelmChartReconciler) reconcileStorage(ctx context.Context, sp *patch.SerialPatcher, obj *helmv1.HelmChart, _ *chart.Build) (sreconcile.Result, error) {
func (r *HelmChartReconciler) reconcileStorage(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmChart, _ *chart.Build) (sreconcile.Result, error) {
// Garbage collect previous advertised artifact(s) from storage
_ = r.garbageCollect(ctx, obj)
@ -402,7 +403,7 @@ func (r *HelmChartReconciler) reconcileStorage(ctx context.Context, sp *patch.Se
if artifactMissing {
msg += ": disappeared from storage"
}
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, msg)
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "%s", msg)
conditions.Delete(obj, sourcev1.ArtifactInStorageCondition)
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
return sreconcile.ResultEmpty, serror.NewGeneric(err, sourcev1.PatchOperationFailedReason)
@ -418,7 +419,7 @@ func (r *HelmChartReconciler) reconcileStorage(ctx context.Context, sp *patch.Se
return sreconcile.ResultSuccess, nil
}
func (r *HelmChartReconciler) reconcileSource(ctx context.Context, sp *patch.SerialPatcher, obj *helmv1.HelmChart, build *chart.Build) (_ sreconcile.Result, retErr error) {
func (r *HelmChartReconciler) reconcileSource(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmChart, build *chart.Build) (_ sreconcile.Result, retErr error) {
// Remove any failed verification condition.
// The reason is that a failing verification should be recalculated.
if conditions.IsFalse(obj, sourcev1.SourceVerifiedCondition) {
@ -432,7 +433,7 @@ func (r *HelmChartReconciler) reconcileSource(ctx context.Context, sp *patch.Ser
fmt.Errorf("failed to get source: %w", err),
"SourceUnavailable",
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
// Return Kubernetes client errors, but ignore others which can only be
// solved by a change in generation
@ -448,7 +449,7 @@ func (r *HelmChartReconciler) reconcileSource(ctx context.Context, sp *patch.Ser
// Assert source has an artifact
if s.GetArtifact() == nil || !r.Storage.ArtifactExist(*s.GetArtifact()) {
// Set the condition to indicate that the source has no artifact for all types except OCI HelmRepository
if helmRepo, ok := s.(*helmv1.HelmRepository); !ok || helmRepo.Spec.Type != helmv1.HelmRepositoryTypeOCI {
if helmRepo, ok := s.(*sourcev1.HelmRepository); !ok || helmRepo.Spec.Type != sourcev1.HelmRepositoryTypeOCI {
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, "NoSourceArtifact",
"no artifact available for %s source '%s'", obj.Spec.SourceRef.Kind, obj.Spec.SourceRef.Name)
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, "NoSourceArtifact",
@ -495,9 +496,9 @@ func (r *HelmChartReconciler) reconcileSource(ctx context.Context, sp *patch.Ser
// Perform the build for the chart source type
switch typedSource := s.(type) {
case *helmv1.HelmRepository:
case *sourcev1.HelmRepository:
return r.buildFromHelmRepository(ctx, obj, typedSource, build)
case *sourcev1.GitRepository, *helmv1.Bucket:
case *sourcev1.GitRepository, *sourcev1.Bucket:
return r.buildFromTarballArtifact(ctx, obj, *typedSource.GetArtifact(), build)
default:
// Ending up here should generally not be possible
@ -507,12 +508,12 @@ func (r *HelmChartReconciler) reconcileSource(ctx context.Context, sp *patch.Ser
}
// buildFromHelmRepository attempts to pull and/or package a Helm chart with
// the specified data from the v1beta2.HelmRepository and v1beta2.HelmChart
// the specified data from the v1.HelmRepository and v1.HelmChart
// objects.
// In case of a failure it records v1beta2.FetchFailedCondition on the chart
// In case of a failure it records v1.FetchFailedCondition on the chart
// object, and returns early.
func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *helmv1.HelmChart,
repo *helmv1.HelmRepository, b *chart.Build) (sreconcile.Result, error) {
func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *sourcev1.HelmChart,
repo *sourcev1.HelmRepository, b *chart.Build) (sreconcile.Result, error) {
// Used to login with the repository declared provider
ctxTimeout, cancel := context.WithTimeout(ctx, repo.GetTimeout())
defer cancel()
@ -528,7 +529,7 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
err,
sourcev1.AuthenticationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
if certsTmpDir != "" {
@ -545,7 +546,7 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
// Initialize the chart repository
var chartRepo repository.Downloader
switch repo.Spec.Type {
case helmv1.HelmRepositoryTypeOCI:
case sourcev1.HelmRepositoryTypeOCI:
if !helmreg.IsOCI(normalizedURL) {
err := fmt.Errorf("invalid OCI registry URL: %s", normalizedURL)
return chartRepoConfigErrorReturn(err, obj)
@ -561,7 +562,7 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
fmt.Errorf("failed to construct Helm client: %w", err),
meta.FailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -579,14 +580,14 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
provider := obj.Spec.Verify.Provider
verifiers, err = r.makeVerifiers(ctx, obj, *clientOpts)
if err != nil {
if obj.Spec.Verify.SecretRef == nil {
if obj.Spec.Verify.SecretRef == nil && obj.Spec.Verify.Provider == "cosign" {
provider = fmt.Sprintf("%s keyless", provider)
}
e := serror.NewGeneric(
fmt.Errorf("failed to verify the signature using provider '%s': %w", provider, err),
sourcev1.VerificationError,
)
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, e.Reason, e.Err.Error())
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
}
@ -617,7 +618,7 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
fmt.Errorf("failed to login to OCI registry: %w", err),
sourcev1.AuthenticationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
}
@ -660,8 +661,9 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
// Construct the chart builder with scoped configuration
cb := chart.NewRemoteBuilder(chartRepo)
opts := chart.BuildOptions{
ValuesFiles: obj.GetValuesFiles(),
Force: obj.Generation != obj.Status.ObservedGeneration,
ValuesFiles: obj.GetValuesFiles(),
IgnoreMissingValuesFiles: obj.Spec.IgnoreMissingValuesFiles,
Force: obj.Generation != obj.Status.ObservedGeneration,
// The remote builder will not attempt to download the chart if
// an artifact exists with the same name and version and `Force` is false.
// It will however try to verify the chart if `obj.Spec.Verify` is set, at every reconciliation.
@ -669,6 +671,7 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
}
if artifact := obj.GetArtifact(); artifact != nil {
opts.CachedChart = r.Storage.LocalPath(*artifact)
opts.CachedChartValuesFiles = obj.Status.ObservedValuesFiles
}
// Set the VersionMetadata to the object's Generation if ValuesFiles is defined
@ -689,11 +692,11 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
}
// buildFromTarballArtifact attempts to pull and/or package a Helm chart with
// the specified data from the v1beta2.HelmChart object and the given
// v1beta2.Artifact.
// In case of a failure it records v1beta2.FetchFailedCondition on the chart
// the specified data from the v1.HelmChart object and the given
// v1.Artifact.
// In case of a failure it records v1.FetchFailedCondition on the chart
// object, and returns early.
func (r *HelmChartReconciler) buildFromTarballArtifact(ctx context.Context, obj *helmv1.HelmChart, source sourcev1.Artifact, b *chart.Build) (sreconcile.Result, error) {
func (r *HelmChartReconciler) buildFromTarballArtifact(ctx context.Context, obj *sourcev1.HelmChart, source sourcev1.Artifact, b *chart.Build) (sreconcile.Result, error) {
// Create temporary working directory
tmpDir, err := util.TempDirForObj("", obj)
if err != nil {
@ -701,7 +704,7 @@ func (r *HelmChartReconciler) buildFromTarballArtifact(ctx context.Context, obj
fmt.Errorf("failed to create temporary working directory: %w", err),
sourcev1.DirCreationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
defer os.RemoveAll(tmpDir)
@ -713,7 +716,7 @@ func (r *HelmChartReconciler) buildFromTarballArtifact(ctx context.Context, obj
fmt.Errorf("failed to create directory to untar source into: %w", err),
sourcev1.DirCreationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -724,7 +727,7 @@ func (r *HelmChartReconciler) buildFromTarballArtifact(ctx context.Context, obj
fmt.Errorf("failed to open source artifact: %w", err),
sourcev1.ReadOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
if err = tar.Untar(f, sourceDir, tar.WithMaxUntarSize(-1)); err != nil {
@ -755,25 +758,27 @@ func (r *HelmChartReconciler) buildFromTarballArtifact(ctx context.Context, obj
// Configure builder options, including any previously cached chart
opts := chart.BuildOptions{
ValuesFiles: obj.GetValuesFiles(),
Force: obj.Generation != obj.Status.ObservedGeneration,
ValuesFiles: obj.GetValuesFiles(),
IgnoreMissingValuesFiles: obj.Spec.IgnoreMissingValuesFiles,
Force: obj.Generation != obj.Status.ObservedGeneration,
}
if artifact := obj.Status.Artifact; artifact != nil {
if artifact := obj.GetArtifact(); artifact != nil {
opts.CachedChart = r.Storage.LocalPath(*artifact)
opts.CachedChartValuesFiles = obj.Status.ObservedValuesFiles
}
// Configure revision metadata for chart build if we should react to revision changes
if obj.Spec.ReconcileStrategy == helmv1.ReconcileStrategyRevision {
if obj.Spec.ReconcileStrategy == sourcev1.ReconcileStrategyRevision {
rev := source.Revision
if obj.Spec.SourceRef.Kind == sourcev1.GitRepositoryKind {
rev = git.ExtractHashFromRevision(rev).String()
}
if obj.Spec.SourceRef.Kind == helmv1.BucketKind {
if obj.Spec.SourceRef.Kind == sourcev1.BucketKind {
if dig := digest.Digest(rev); dig.Validate() == nil {
rev = dig.Encoded()
}
}
if kind := obj.Spec.SourceRef.Kind; kind == sourcev1.GitRepositoryKind || kind == helmv1.BucketKind {
if kind := obj.Spec.SourceRef.Kind; kind == sourcev1.GitRepositoryKind || kind == sourcev1.BucketKind {
// The SemVer from the metadata is at times used in e.g. the label metadata for a resource
// in a chart, which has a limited length of 63 characters.
// To not fill most of this space with a full length SHA hex (40 characters for SHA-1, and
@ -815,12 +820,12 @@ func (r *HelmChartReconciler) buildFromTarballArtifact(ctx context.Context, obj
// (Status) data on the object does not match the given.
//
// The inspection of the given data to the object is differed, ensuring any
// stale observations like v1beta2.ArtifactOutdatedCondition are removed.
// stale observations like v1.ArtifactOutdatedCondition are removed.
// If the given Artifact does not differ from the object's current, it returns
// early.
// On a successful archive, the Artifact in the Status of the object is set,
// and the symlink in the Storage is updated to its path.
func (r *HelmChartReconciler) reconcileArtifact(ctx context.Context, _ *patch.SerialPatcher, obj *helmv1.HelmChart, b *chart.Build) (sreconcile.Result, error) {
func (r *HelmChartReconciler) reconcileArtifact(ctx context.Context, _ *patch.SerialPatcher, obj *sourcev1.HelmChart, b *chart.Build) (sreconcile.Result, error) {
// Without a complete chart build, there is little to reconcile
if !b.Complete() {
return sreconcile.ResultRequeue, nil
@ -830,7 +835,7 @@ func (r *HelmChartReconciler) reconcileArtifact(ctx context.Context, _ *patch.Se
defer func() {
if obj.Status.ObservedChartName == b.Name && obj.GetArtifact().HasRevision(b.Version) {
conditions.Delete(obj, sourcev1.ArtifactOutdatedCondition)
conditions.MarkTrue(obj, sourcev1.ArtifactInStorageCondition, reasonForBuild(b), b.Summary())
conditions.MarkTrue(obj, sourcev1.ArtifactInStorageCondition, reasonForBuild(b), "%s", b.Summary())
}
}()
@ -852,7 +857,7 @@ func (r *HelmChartReconciler) reconcileArtifact(ctx context.Context, _ *patch.Se
fmt.Errorf("failed to create artifact directory: %w", err),
sourcev1.DirCreationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
unlock, err := r.Storage.Lock(artifact)
@ -861,7 +866,7 @@ func (r *HelmChartReconciler) reconcileArtifact(ctx context.Context, _ *patch.Se
fmt.Errorf("failed to acquire lock for artifact: %w", err),
sourcev1.AcquireLockFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
defer unlock()
@ -872,13 +877,18 @@ func (r *HelmChartReconciler) reconcileArtifact(ctx context.Context, _ *patch.Se
fmt.Errorf("unable to copy Helm chart to storage: %w", err),
sourcev1.ArchiveOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
// Record it on the object
obj.Status.Artifact = artifact.DeepCopy()
obj.Status.ObservedChartName = b.Name
if obj.Spec.IgnoreMissingValuesFiles {
obj.Status.ObservedValuesFiles = b.ValuesFiles
} else {
obj.Status.ObservedValuesFiles = nil
}
// Update symlink on a "best effort" basis
symURL, err := r.Storage.Symlink(artifact, "latest.tar.gz")
@ -895,15 +905,15 @@ func (r *HelmChartReconciler) reconcileArtifact(ctx context.Context, _ *patch.Se
// getSource returns the v1beta1.Source for the given object, or an error describing why the source could not be
// returned.
func (r *HelmChartReconciler) getSource(ctx context.Context, obj *helmv1.HelmChart) (sourcev1.Source, error) {
func (r *HelmChartReconciler) getSource(ctx context.Context, obj *sourcev1.HelmChart) (sourcev1.Source, error) {
namespacedName := types.NamespacedName{
Namespace: obj.GetNamespace(),
Name: obj.Spec.SourceRef.Name,
}
var s sourcev1.Source
switch obj.Spec.SourceRef.Kind {
case helmv1.HelmRepositoryKind:
var repo helmv1.HelmRepository
case sourcev1.HelmRepositoryKind:
var repo sourcev1.HelmRepository
if err := r.Client.Get(ctx, namespacedName, &repo); err != nil {
return nil, err
}
@ -914,15 +924,15 @@ func (r *HelmChartReconciler) getSource(ctx context.Context, obj *helmv1.HelmCha
return nil, err
}
s = &repo
case helmv1.BucketKind:
var bucket helmv1.Bucket
case sourcev1.BucketKind:
var bucket sourcev1.Bucket
if err := r.Client.Get(ctx, namespacedName, &bucket); err != nil {
return nil, err
}
s = &bucket
default:
return nil, fmt.Errorf("unsupported source kind '%s', must be one of: %v", obj.Spec.SourceRef.Kind, []string{
helmv1.HelmRepositoryKind, sourcev1.GitRepositoryKind, helmv1.BucketKind})
sourcev1.HelmRepositoryKind, sourcev1.GitRepositoryKind, sourcev1.BucketKind})
}
return s, nil
}
@ -930,7 +940,7 @@ func (r *HelmChartReconciler) getSource(ctx context.Context, obj *helmv1.HelmCha
// reconcileDelete handles the deletion of the object.
// It first garbage collects all Artifacts for the object from the Storage.
// Removing the finalizer from the object if successful.
func (r *HelmChartReconciler) reconcileDelete(ctx context.Context, obj *helmv1.HelmChart) (sreconcile.Result, error) {
func (r *HelmChartReconciler) reconcileDelete(ctx context.Context, obj *sourcev1.HelmChart) (sreconcile.Result, error) {
// Garbage collect the resource's artifacts
if err := r.garbageCollect(ctx, obj); err != nil {
// Return the error so we retry the failed garbage collection
@ -949,7 +959,7 @@ func (r *HelmChartReconciler) reconcileDelete(ctx context.Context, obj *helmv1.H
// It removes all but the current Artifact from the Storage, unless the
// deletion timestamp on the object is set. Which will result in the
// removal of all Artifacts for the objects.
func (r *HelmChartReconciler) garbageCollect(ctx context.Context, obj *helmv1.HelmChart) error {
func (r *HelmChartReconciler) garbageCollect(ctx context.Context, obj *sourcev1.HelmChart) error {
if !obj.DeletionTimestamp.IsZero() {
if deleted, err := r.Storage.RemoveAll(r.Storage.NewArtifactFor(obj.Kind, obj.GetObjectMeta(), "", "*")); err != nil {
return serror.NewGeneric(
@ -973,7 +983,7 @@ func (r *HelmChartReconciler) garbageCollect(ctx context.Context, obj *helmv1.He
}
if len(delFiles) > 0 {
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, "GarbageCollectionSucceeded",
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)))
"garbage collected %d artifacts", len(delFiles))
return nil
}
}
@ -996,8 +1006,8 @@ func (r *HelmChartReconciler) namespacedChartRepositoryCallback(ctx context.Cont
if apierrs.ReasonForError(err) != metav1.StatusReasonUnknown {
return nil, err
}
obj = &helmv1.HelmRepository{
Spec: helmv1.HelmRepositorySpec{
obj = &sourcev1.HelmRepository{
Spec: sourcev1.HelmRepositorySpec{
URL: url,
Timeout: &metav1.Duration{Duration: 60 * time.Second},
},
@ -1085,13 +1095,13 @@ func (r *HelmChartReconciler) namespacedChartRepositoryCallback(ctx context.Cont
}
}
func (r *HelmChartReconciler) resolveDependencyRepository(ctx context.Context, url string, namespace string) (*helmv1.HelmRepository, error) {
func (r *HelmChartReconciler) resolveDependencyRepository(ctx context.Context, url string, namespace string) (*sourcev1.HelmRepository, error) {
listOpts := []client.ListOption{
client.InNamespace(namespace),
client.MatchingFields{helmv1.HelmRepositoryURLIndexKey: url},
client.MatchingFields{sourcev1.HelmRepositoryURLIndexKey: url},
client.Limit(1),
}
var list helmv1.HelmRepositoryList
var list sourcev1.HelmRepositoryList
err := r.Client.List(ctx, &list, listOpts...)
if err != nil {
return nil, fmt.Errorf("unable to retrieve HelmRepositoryList: %w", err)
@ -1103,7 +1113,7 @@ func (r *HelmChartReconciler) resolveDependencyRepository(ctx context.Context, u
}
func (r *HelmChartReconciler) indexHelmRepositoryByURL(o client.Object) []string {
repo, ok := o.(*helmv1.HelmRepository)
repo, ok := o.(*sourcev1.HelmRepository)
if !ok {
panic(fmt.Sprintf("Expected a HelmRepository, got %T", o))
}
@ -1115,7 +1125,7 @@ func (r *HelmChartReconciler) indexHelmRepositoryByURL(o client.Object) []string
}
func (r *HelmChartReconciler) indexHelmChartBySource(o client.Object) []string {
hc, ok := o.(*helmv1.HelmChart)
hc, ok := o.(*sourcev1.HelmChart)
if !ok {
panic(fmt.Sprintf("Expected a HelmChart, got %T", o))
}
@ -1123,7 +1133,7 @@ func (r *HelmChartReconciler) indexHelmChartBySource(o client.Object) []string {
}
func (r *HelmChartReconciler) requestsForHelmRepositoryChange(ctx context.Context, o client.Object) []reconcile.Request {
repo, ok := o.(*helmv1.HelmRepository)
repo, ok := o.(*sourcev1.HelmRepository)
if !ok {
ctrl.LoggerFrom(ctx).Error(fmt.Errorf("expected a HelmRepository, got %T", o), "failed to get requests for HelmRepository change")
return nil
@ -1134,9 +1144,9 @@ func (r *HelmChartReconciler) requestsForHelmRepositoryChange(ctx context.Contex
return nil
}
var list helmv1.HelmChartList
var list sourcev1.HelmChartList
if err := r.List(ctx, &list, client.MatchingFields{
sourcev1.SourceIndexKey: fmt.Sprintf("%s/%s", helmv1.HelmRepositoryKind, repo.Name),
sourcev1.SourceIndexKey: fmt.Sprintf("%s/%s", sourcev1.HelmRepositoryKind, repo.Name),
}); err != nil {
ctrl.LoggerFrom(ctx).Error(err, "failed to list HelmCharts for HelmRepository change")
return nil
@ -1164,7 +1174,7 @@ func (r *HelmChartReconciler) requestsForGitRepositoryChange(ctx context.Context
return nil
}
var list helmv1.HelmChartList
var list sourcev1.HelmChartList
if err := r.List(ctx, &list, client.MatchingFields{
sourcev1.SourceIndexKey: fmt.Sprintf("%s/%s", sourcev1.GitRepositoryKind, repo.Name),
}); err != nil {
@ -1182,7 +1192,7 @@ func (r *HelmChartReconciler) requestsForGitRepositoryChange(ctx context.Context
}
func (r *HelmChartReconciler) requestsForBucketChange(ctx context.Context, o client.Object) []reconcile.Request {
bucket, ok := o.(*helmv1.Bucket)
bucket, ok := o.(*sourcev1.Bucket)
if !ok {
ctrl.LoggerFrom(ctx).Error(fmt.Errorf("expected a Bucket, got %T", o),
"failed to get reconcile requests for Bucket change")
@ -1194,9 +1204,9 @@ func (r *HelmChartReconciler) requestsForBucketChange(ctx context.Context, o cli
return nil
}
var list helmv1.HelmChartList
var list sourcev1.HelmChartList
if err := r.List(ctx, &list, client.MatchingFields{
sourcev1.SourceIndexKey: fmt.Sprintf("%s/%s", helmv1.BucketKind, bucket.Name),
sourcev1.SourceIndexKey: fmt.Sprintf("%s/%s", sourcev1.BucketKind, bucket.Name),
}); err != nil {
ctrl.LoggerFrom(ctx).Error(err, "failed to list HelmCharts for Bucket change")
return nil
@ -1228,11 +1238,11 @@ func (r *HelmChartReconciler) eventLogf(ctx context.Context, obj runtime.Object,
}
// observeChartBuild records the observation on the given given build and error on the object.
func observeChartBuild(ctx context.Context, sp *patch.SerialPatcher, pOpts []patch.Option, obj *helmv1.HelmChart, build *chart.Build, err error) {
func observeChartBuild(ctx context.Context, sp *patch.SerialPatcher, pOpts []patch.Option, obj *sourcev1.HelmChart, build *chart.Build, err error) {
if build.HasMetadata() {
if build.Name != obj.Status.ObservedChartName || !obj.GetArtifact().HasRevision(build.Version) {
if obj.GetArtifact() != nil {
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewChart", build.Summary())
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewChart", "%s", build.Summary())
}
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "building artifact: %s", build.Summary())
if err := sp.Patch(ctx, obj, pOpts...); err != nil {
@ -1244,7 +1254,9 @@ func observeChartBuild(ctx context.Context, sp *patch.SerialPatcher, pOpts []pat
if build.Complete() {
conditions.Delete(obj, sourcev1.FetchFailedCondition)
conditions.Delete(obj, sourcev1.BuildFailedCondition)
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, meta.SucceededReason, fmt.Sprintf("verified signature of version %s", build.Version))
if build.VerifiedResult == soci.VerificationResultSuccess {
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, meta.SucceededReason, "verified signature of version %s", build.Version)
}
}
if obj.Spec.Verify == nil {
@ -1263,14 +1275,14 @@ func observeChartBuild(ctx context.Context, sp *patch.SerialPatcher, pOpts []pat
switch buildErr.Reason {
case chart.ErrChartMetadataPatch, chart.ErrValuesFilesMerge, chart.ErrDependencyBuild, chart.ErrChartPackage:
conditions.Delete(obj, sourcev1.FetchFailedCondition)
conditions.MarkTrue(obj, sourcev1.BuildFailedCondition, buildErr.Reason.Reason, buildErr.Error())
conditions.MarkTrue(obj, sourcev1.BuildFailedCondition, buildErr.Reason.Reason, "%s", buildErr)
case chart.ErrChartVerification:
conditions.Delete(obj, sourcev1.FetchFailedCondition)
conditions.MarkTrue(obj, sourcev1.BuildFailedCondition, buildErr.Reason.Reason, buildErr.Error())
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, sourcev1.VerificationError, buildErr.Error())
conditions.MarkTrue(obj, sourcev1.BuildFailedCondition, buildErr.Reason.Reason, "%s", buildErr)
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, sourcev1.VerificationError, "%s", buildErr)
default:
conditions.Delete(obj, sourcev1.BuildFailedCondition)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, buildErr.Reason.Reason, buildErr.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, buildErr.Reason.Reason, "%s", buildErr)
}
return
}
@ -1281,32 +1293,32 @@ func reasonForBuild(build *chart.Build) string {
return ""
}
if build.Packaged {
return helmv1.ChartPackageSucceededReason
return sourcev1.ChartPackageSucceededReason
}
return helmv1.ChartPullSucceededReason
return sourcev1.ChartPullSucceededReason
}
func chartRepoConfigErrorReturn(err error, obj *helmv1.HelmChart) (sreconcile.Result, error) {
func chartRepoConfigErrorReturn(err error, obj *sourcev1.HelmChart) (sreconcile.Result, error) {
switch err.(type) {
case *url.Error:
e := serror.NewStalling(
fmt.Errorf("invalid Helm repository URL: %w", err),
sourcev1.URLInvalidReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
default:
e := serror.NewStalling(
fmt.Errorf("failed to construct Helm client: %w", err),
meta.FailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
}
// makeVerifiers returns a list of verifiers for the given chart.
func (r *HelmChartReconciler) makeVerifiers(ctx context.Context, obj *helmv1.HelmChart, clientOpts getter.ClientOpts) ([]soci.Verifier, error) {
func (r *HelmChartReconciler) makeVerifiers(ctx context.Context, obj *sourcev1.HelmChart, clientOpts getter.ClientOpts) ([]soci.Verifier, error) {
var verifiers []soci.Verifier
verifyOpts := []remote.Option{}
@ -1318,26 +1330,27 @@ func (r *HelmChartReconciler) makeVerifiers(ctx context.Context, obj *helmv1.Hel
switch obj.Spec.Verify.Provider {
case "cosign":
defaultCosignOciOpts := []soci.Options{
soci.WithRemoteOptions(verifyOpts...),
defaultCosignOciOpts := []scosign.Options{
scosign.WithRemoteOptions(verifyOpts...),
}
// get the public keys from the given secret
if secretRef := obj.Spec.Verify.SecretRef; secretRef != nil {
certSecretName := types.NamespacedName{
verifySecret := types.NamespacedName{
Namespace: obj.Namespace,
Name: secretRef.Name,
}
var pubSecret corev1.Secret
if err := r.Get(ctx, certSecretName, &pubSecret); err != nil {
pubSecret, err := r.retrieveSecret(ctx, verifySecret)
if err != nil {
return nil, err
}
for k, data := range pubSecret.Data {
// search for public keys in the secret
if strings.HasSuffix(k, ".pub") {
verifier, err := soci.NewCosignVerifier(ctx, append(defaultCosignOciOpts, soci.WithPublicKey(data))...)
verifier, err := scosign.NewCosignVerifier(ctx, append(defaultCosignOciOpts, scosign.WithPublicKey(data))...)
if err != nil {
return nil, err
}
@ -1346,7 +1359,7 @@ func (r *HelmChartReconciler) makeVerifiers(ctx context.Context, obj *helmv1.Hel
}
if len(verifiers) == 0 {
return nil, fmt.Errorf("no public keys found in secret '%s'", certSecretName)
return nil, fmt.Errorf("no public keys found in secret '%s'", verifySecret.String())
}
return verifiers, nil
}
@ -1359,9 +1372,67 @@ func (r *HelmChartReconciler) makeVerifiers(ctx context.Context, obj *helmv1.Hel
SubjectRegExp: match.Subject,
})
}
defaultCosignOciOpts = append(defaultCosignOciOpts, soci.WithIdentities(identities))
defaultCosignOciOpts = append(defaultCosignOciOpts, scosign.WithIdentities(identities))
verifier, err := soci.NewCosignVerifier(ctx, defaultCosignOciOpts...)
verifier, err := scosign.NewCosignVerifier(ctx, defaultCosignOciOpts...)
if err != nil {
return nil, err
}
verifiers = append(verifiers, verifier)
return verifiers, nil
case "notation":
// get the public keys from the given secret
secretRef := obj.Spec.Verify.SecretRef
if secretRef == nil {
return nil, fmt.Errorf("verification secret cannot be empty: '%s'", obj.Name)
}
verifySecret := types.NamespacedName{
Namespace: obj.Namespace,
Name: secretRef.Name,
}
pubSecret, err := r.retrieveSecret(ctx, verifySecret)
if err != nil {
return nil, err
}
data, ok := pubSecret.Data[notation.DefaultTrustPolicyKey]
if !ok {
return nil, fmt.Errorf("'%s' not found in secret '%s'", notation.DefaultTrustPolicyKey, verifySecret.String())
}
var doc trustpolicy.Document
if err := json.Unmarshal(data, &doc); err != nil {
return nil, fmt.Errorf("error occurred while parsing %s: %w", notation.DefaultTrustPolicyKey, err)
}
var certs [][]byte
for k, data := range pubSecret.Data {
if strings.HasSuffix(k, ".crt") || strings.HasSuffix(k, ".pem") {
certs = append(certs, data)
}
}
if certs == nil {
return nil, fmt.Errorf("no certificates found in secret '%s'", verifySecret.String())
}
trustPolicy := notation.CleanTrustPolicy(&doc, ctrl.LoggerFrom(ctx))
defaultNotationOciOpts := []notation.Options{
notation.WithTrustPolicy(trustPolicy),
notation.WithRemoteOptions(verifyOpts...),
notation.WithAuth(clientOpts.Authenticator),
notation.WithKeychain(clientOpts.Keychain),
notation.WithInsecureRegistry(clientOpts.Insecure),
notation.WithLogger(ctrl.LoggerFrom(ctx)),
notation.WithRootCertificates(certs),
}
verifier, err := notation.NewNotationVerifier(defaultNotationOciOpts...)
if err != nil {
return nil, err
}
@ -1371,3 +1442,15 @@ func (r *HelmChartReconciler) makeVerifiers(ctx context.Context, obj *helmv1.Hel
return nil, fmt.Errorf("unsupported verification provider: %s", obj.Spec.Verify.Provider)
}
}
// retrieveSecret retrieves a secret from the specified namespace with the given secret name.
// It returns the retrieved secret and any error encountered during the retrieval process.
func (r *HelmChartReconciler) retrieveSecret(ctx context.Context, verifySecret types.NamespacedName) (corev1.Secret, error) {
var pubSecret corev1.Secret
if err := r.Get(ctx, verifySecret, &pubSecret); err != nil {
return corev1.Secret{}, err
}
return pubSecret, nil
}

File diff suppressed because it is too large Load Diff

View File

@ -32,12 +32,13 @@ import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
kuberecorder "k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/ratelimiter"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/apis/meta"
@ -49,7 +50,6 @@ import (
rreconcile "github.com/fluxcd/pkg/runtime/reconcile"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
helmv1 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/fluxcd/source-controller/internal/cache"
intdigest "github.com/fluxcd/source-controller/internal/digest"
serror "github.com/fluxcd/source-controller/internal/error"
@ -61,7 +61,7 @@ import (
)
// helmRepositoryReadyCondition contains the information required to summarize a
// v1beta2.HelmRepository Ready Condition.
// v1.HelmRepository Ready Condition.
var helmRepositoryReadyCondition = summarize.Conditions{
Target: meta.ReadyCondition,
Owned: []string{
@ -102,7 +102,7 @@ var helmRepositoryFailConditions = []string{
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=helmrepositories/finalizers,verbs=get;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
// HelmRepositoryReconciler reconciles a v1beta2.HelmRepository object.
// HelmRepositoryReconciler reconciles a v1.HelmRepository object.
type HelmRepositoryReconciler struct {
client.Client
kuberecorder.EventRecorder
@ -120,14 +120,14 @@ type HelmRepositoryReconciler struct {
}
type HelmRepositoryReconcilerOptions struct {
RateLimiter ratelimiter.RateLimiter
RateLimiter workqueue.TypedRateLimiter[reconcile.Request]
}
// helmRepositoryReconcileFunc is the function type for all the
// v1beta2.HelmRepository (sub)reconcile functions. The type implementations
// v1.HelmRepository (sub)reconcile functions. The type implementations
// are grouped and executed serially to perform the complete reconcile of the
// object.
type helmRepositoryReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *helmv1.HelmRepository, artifact *sourcev1.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error)
type helmRepositoryReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *sourcev1.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error)
func (r *HelmRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error {
return r.SetupWithManagerAndOptions(mgr, HelmRepositoryReconcilerOptions{})
@ -137,7 +137,7 @@ func (r *HelmRepositoryReconciler) SetupWithManagerAndOptions(mgr ctrl.Manager,
r.patchOptions = getPatchOptions(helmRepositoryReadyCondition.Owned, r.ControllerName)
return ctrl.NewControllerManagedBy(mgr).
For(&helmv1.HelmRepository{}).
For(&sourcev1.HelmRepository{}).
WithEventFilter(
predicate.And(
intpredicates.HelmRepositoryOCIMigrationPredicate{},
@ -155,7 +155,7 @@ func (r *HelmRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reque
log := ctrl.LoggerFrom(ctx)
// Fetch the HelmRepository
obj := &helmv1.HelmRepository{}
obj := &sourcev1.HelmRepository{}
if err := r.Get(ctx, req.NamespacedName, obj); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
@ -164,7 +164,7 @@ func (r *HelmRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reque
serialPatcher := patch.NewSerialPatcher(obj, r.Client)
// If it's of type OCI, migrate the object to static.
if obj.Spec.Type == helmv1.HelmRepositoryTypeOCI {
if obj.Spec.Type == sourcev1.HelmRepositoryTypeOCI {
return r.migrationToStatic(ctx, serialPatcher, obj)
}
@ -191,9 +191,7 @@ func (r *HelmRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reque
}
result, retErr = summarizeHelper.SummarizeAndPatch(ctx, obj, summarizeOpts...)
// Always record suspend, readiness and duration metrics.
r.Metrics.RecordSuspend(ctx, obj, obj.Spec.Suspend)
r.Metrics.RecordReadiness(ctx, obj)
// Always record duration metrics.
r.Metrics.RecordDuration(ctx, obj, start)
}()
@ -234,7 +232,7 @@ func (r *HelmRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// object. It returns early on the first call that returns
// reconcile.ResultRequeue, or produces an error.
func (r *HelmRepositoryReconciler) reconcile(ctx context.Context, sp *patch.SerialPatcher,
obj *helmv1.HelmRepository, reconcilers []helmRepositoryReconcileFunc) (sreconcile.Result, error) {
obj *sourcev1.HelmRepository, reconcilers []helmRepositoryReconcileFunc) (sreconcile.Result, error) {
oldObj := obj.DeepCopy()
rreconcile.ProgressiveStatus(false, obj, meta.ProgressingReason, "reconciliation in progress")
@ -287,7 +285,7 @@ func (r *HelmRepositoryReconciler) reconcile(ctx context.Context, sp *patch.Seri
}
// notify emits notification related to the reconciliation.
func (r *HelmRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *helmv1.HelmRepository, chartRepo *repository.ChartRepository, res sreconcile.Result, resErr error) {
func (r *HelmRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *sourcev1.HelmRepository, chartRepo *repository.ChartRepository, res sreconcile.Result, resErr error) {
// Notify successful reconciliation for new artifact and recovery from any
// failure.
if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil {
@ -331,7 +329,7 @@ func (r *HelmRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *h
// The hostname of any URL in the Status of the object are updated, to ensure
// they match the Storage server hostname of current runtime.
func (r *HelmRepositoryReconciler) reconcileStorage(ctx context.Context, sp *patch.SerialPatcher,
obj *helmv1.HelmRepository, _ *sourcev1.Artifact, _ *repository.ChartRepository) (sreconcile.Result, error) {
obj *sourcev1.HelmRepository, _ *sourcev1.Artifact, _ *repository.ChartRepository) (sreconcile.Result, error) {
// Garbage collect previous advertised artifact(s) from storage
_ = r.garbageCollect(ctx, obj)
@ -369,7 +367,7 @@ func (r *HelmRepositoryReconciler) reconcileStorage(ctx context.Context, sp *pat
if artifactMissing {
msg += ": disappeared from storage"
}
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, msg)
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "%s", msg)
conditions.Delete(obj, sourcev1.ArtifactInStorageCondition)
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
return sreconcile.ResultEmpty, serror.NewGeneric(err, sourcev1.PatchOperationFailedReason)
@ -386,15 +384,15 @@ func (r *HelmRepositoryReconciler) reconcileStorage(ctx context.Context, sp *pat
}
// reconcileSource attempts to fetch the Helm repository index using the
// specified configuration on the v1beta2.HelmRepository object.
// specified configuration on the v1.HelmRepository object.
//
// When the fetch fails, it records v1beta2.FetchFailedCondition=True and
// When the fetch fails, it records v1.FetchFailedCondition=True and
// returns early.
// If successful and the index is valid, any previous
// v1beta2.FetchFailedCondition is removed, and the repository.ChartRepository
// v1.FetchFailedCondition is removed, and the repository.ChartRepository
// pointer is set to the newly fetched index.
func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch.SerialPatcher,
obj *helmv1.HelmRepository, artifact *sourcev1.Artifact, chartRepo *repository.ChartRepository) (sreconcile.Result, error) {
obj *sourcev1.HelmRepository, artifact *sourcev1.Artifact, chartRepo *repository.ChartRepository) (sreconcile.Result, error) {
// Ensure it's not an OCI URL. API validation ensures that only
// http/https/oci scheme are allowed.
if strings.HasPrefix(obj.Spec.URL, helmreg.OCIScheme) {
@ -403,7 +401,7 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
fmt.Errorf("invalid Helm repository URL: %w", err),
sourcev1.URLInvalidReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -413,7 +411,7 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
fmt.Errorf("invalid Helm repository URL: %w", err),
sourcev1.URLInvalidReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -427,7 +425,7 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
err,
sourcev1.AuthenticationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
}
@ -441,14 +439,14 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
fmt.Errorf("invalid Helm repository URL: %w", err),
sourcev1.URLInvalidReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
default:
e := serror.NewStalling(
fmt.Errorf("failed to construct Helm client: %w", err),
meta.FailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
}
@ -459,7 +457,7 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
fmt.Errorf("failed to fetch Helm repository index: %w", err),
meta.FailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
// Coin flip on transient or persistent error, return error and hope for the best
return sreconcile.ResultEmpty, e
}
@ -483,9 +481,9 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
if err := chartRepo.LoadFromPath(); err != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to load Helm repository from index YAML: %w", err),
helmv1.IndexationFailedReason,
sourcev1.IndexationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
// Delete any stale failure observation
@ -496,16 +494,16 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
if revision.Validate() != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to calculate revision: %w", err),
helmv1.IndexationFailedReason,
sourcev1.IndexationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
// Mark observations about the revision on the object.
message := fmt.Sprintf("new index revision '%s'", revision)
if obj.GetArtifact() != nil {
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", message)
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", "%s", message)
}
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "building artifact: %s", message)
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
@ -526,12 +524,12 @@ func (r *HelmRepositoryReconciler) reconcileSource(ctx context.Context, sp *patc
// (Status) data on the object does not match the given.
//
// The inspection of the given data to the object is differed, ensuring any
// stale observations like v1beta2.ArtifactOutdatedCondition are removed.
// stale observations like v1.ArtifactOutdatedCondition are removed.
// If the given Artifact does not differ from the object's current, it returns
// early.
// On a successful archive, the Artifact in the Status of the object is set,
// and the symlink in the Storage is updated to its path.
func (r *HelmRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *patch.SerialPatcher, obj *helmv1.HelmRepository, artifact *sourcev1.Artifact, chartRepo *repository.ChartRepository) (sreconcile.Result, error) {
func (r *HelmRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *sourcev1.Artifact, chartRepo *repository.ChartRepository) (sreconcile.Result, error) {
// Set the ArtifactInStorageCondition if there's no drift.
defer func() {
if obj.GetArtifact().HasRevision(artifact.Revision) {
@ -560,7 +558,7 @@ func (r *HelmRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pa
fmt.Errorf("failed to create artifact directory: %w", err),
sourcev1.DirCreationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -581,7 +579,7 @@ func (r *HelmRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pa
fmt.Errorf("unable to get JSON index from chart repo: %w", err),
sourcev1.ArchiveOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
if err = r.Storage.Copy(artifact, bytes.NewBuffer(b)); err != nil {
@ -589,7 +587,7 @@ func (r *HelmRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pa
fmt.Errorf("unable to save artifact to storage: %w", err),
sourcev1.ArchiveOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -623,7 +621,7 @@ func (r *HelmRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pa
// reconcileDelete handles the deletion of the object.
// It first garbage collects all Artifacts for the object from the Storage.
// Removing the finalizer from the object if successful.
func (r *HelmRepositoryReconciler) reconcileDelete(ctx context.Context, obj *helmv1.HelmRepository) (sreconcile.Result, error) {
func (r *HelmRepositoryReconciler) reconcileDelete(ctx context.Context, obj *sourcev1.HelmRepository) (sreconcile.Result, error) {
// Garbage collect the resource's artifacts
if err := r.garbageCollect(ctx, obj); err != nil {
// Return the error so we retry the failed garbage collection
@ -651,8 +649,8 @@ func (r *HelmRepositoryReconciler) reconcileDelete(ctx context.Context, obj *hel
// - the deletion timestamp on the object is set
// - the obj.Spec.Type has changed and artifacts are not supported by the new type
// Which will result in the removal of all Artifacts for the objects.
func (r *HelmRepositoryReconciler) garbageCollect(ctx context.Context, obj *helmv1.HelmRepository) error {
if !obj.DeletionTimestamp.IsZero() || (obj.Spec.Type != "" && obj.Spec.Type != helmv1.HelmRepositoryTypeDefault) {
func (r *HelmRepositoryReconciler) garbageCollect(ctx context.Context, obj *sourcev1.HelmRepository) error {
if !obj.DeletionTimestamp.IsZero() || (obj.Spec.Type != "" && obj.Spec.Type != sourcev1.HelmRepositoryTypeDefault) {
if deleted, err := r.Storage.RemoveAll(r.Storage.NewArtifactFor(obj.Kind, obj.GetObjectMeta(), "", "*")); err != nil {
return serror.NewGeneric(
fmt.Errorf("garbage collection for deleted resource failed: %w", err),
@ -679,7 +677,7 @@ func (r *HelmRepositoryReconciler) garbageCollect(ctx context.Context, obj *helm
}
if len(delFiles) > 0 {
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, "GarbageCollectionSucceeded",
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)))
"garbage collected %d artifacts", len(delFiles))
return nil
}
}
@ -703,7 +701,7 @@ func (r *HelmRepositoryReconciler) eventLogf(ctx context.Context, obj runtime.Ob
}
// migrateToStatic is HelmRepository OCI migration to static object.
func (r *HelmRepositoryReconciler) migrationToStatic(ctx context.Context, sp *patch.SerialPatcher, obj *helmv1.HelmRepository) (result ctrl.Result, err error) {
func (r *HelmRepositoryReconciler) migrationToStatic(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository) (result ctrl.Result, err error) {
// Skip migration if suspended and not being deleted.
if obj.Spec.Suspend && obj.DeletionTimestamp.IsZero() {
return ctrl.Result{}, nil
@ -721,13 +719,11 @@ func (r *HelmRepositoryReconciler) migrationToStatic(ctx context.Context, sp *pa
}
// Delete finalizer and reset the status.
controllerutil.RemoveFinalizer(obj, sourcev1.SourceFinalizer)
obj.Status = helmv1.HelmRepositoryStatus{}
obj.Status = sourcev1.HelmRepositoryStatus{}
if err := sp.Patch(ctx, obj); err != nil {
return ctrl.Result{}, err
}
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, "Migration",
"removed artifact and finalizer to migrate to static HelmRepository of type OCI")
return ctrl.Result{}, nil
}

View File

@ -50,7 +50,6 @@ import (
"github.com/fluxcd/pkg/runtime/patch"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
helmv1 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/fluxcd/source-controller/internal/cache"
intdigest "github.com/fluxcd/source-controller/internal/digest"
"github.com/fluxcd/source-controller/internal/helm/getter"
@ -73,10 +72,10 @@ func TestHelmRepositoryReconciler_deleteBeforeFinalizer(t *testing.T) {
g.Expect(k8sClient.Delete(ctx, namespace)).NotTo(HaveOccurred())
})
helmrepo := &helmv1.HelmRepository{}
helmrepo := &sourcev1.HelmRepository{}
helmrepo.Name = "test-helmrepo"
helmrepo.Namespace = namespaceName
helmrepo.Spec = helmv1.HelmRepositorySpec{
helmrepo.Spec = sourcev1.HelmRepositorySpec{
Interval: metav1.Duration{Duration: interval},
URL: "https://example.com",
}
@ -109,12 +108,12 @@ func TestHelmRepositoryReconciler_Reconcile(t *testing.T) {
testServer.Start()
defer testServer.Stop()
origObj := &helmv1.HelmRepository{
origObj := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "helmrepository-reconcile-",
Namespace: "default",
},
Spec: helmv1.HelmRepositorySpec{
Spec: sourcev1.HelmRepositorySpec{
Interval: metav1.Duration{Duration: interval},
URL: testServer.URL(),
},
@ -175,7 +174,7 @@ func TestHelmRepositoryReconciler_Reconcile(t *testing.T) {
func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
tests := []struct {
name string
beforeFunc func(obj *helmv1.HelmRepository, storage *Storage) error
beforeFunc func(obj *sourcev1.HelmRepository, storage *Storage) error
want sreconcile.Result
wantErr bool
assertArtifact *sourcev1.Artifact
@ -184,7 +183,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
}{
{
name: "garbage collects",
beforeFunc: func(obj *helmv1.HelmRepository, storage *Storage) error {
beforeFunc: func(obj *sourcev1.HelmRepository, storage *Storage) error {
revisions := []string{"a", "b", "c", "d"}
for n := range revisions {
v := revisions[n]
@ -234,7 +233,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
},
{
name: "notices missing artifact in storage",
beforeFunc: func(obj *helmv1.HelmRepository, storage *Storage) error {
beforeFunc: func(obj *sourcev1.HelmRepository, storage *Storage) error {
obj.Status.Artifact = &sourcev1.Artifact{
Path: "/reconcile-storage/invalid.txt",
Revision: "d",
@ -253,7 +252,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
},
{
name: "notices empty artifact digest",
beforeFunc: func(obj *helmv1.HelmRepository, storage *Storage) error {
beforeFunc: func(obj *sourcev1.HelmRepository, storage *Storage) error {
f := "empty-digest.txt"
obj.Status.Artifact = &sourcev1.Artifact{
@ -284,7 +283,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
},
{
name: "notices artifact digest mismatch",
beforeFunc: func(obj *helmv1.HelmRepository, storage *Storage) error {
beforeFunc: func(obj *sourcev1.HelmRepository, storage *Storage) error {
f := "digest-mismatch.txt"
obj.Status.Artifact = &sourcev1.Artifact{
@ -315,7 +314,7 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
},
{
name: "updates hostname on diff from current",
beforeFunc: func(obj *helmv1.HelmRepository, storage *Storage) error {
beforeFunc: func(obj *sourcev1.HelmRepository, storage *Storage) error {
obj.Status.Artifact = &sourcev1.Artifact{
Path: "/reconcile-storage/hostname.txt",
Revision: "f",
@ -354,14 +353,14 @@ func TestHelmRepositoryReconciler_reconcileStorage(t *testing.T) {
r := &HelmRepositoryReconciler{
Client: fakeclient.NewClientBuilder().
WithScheme(testEnv.GetScheme()).
WithStatusSubresource(&helmv1.HelmRepository{}).
WithStatusSubresource(&sourcev1.HelmRepository{}).
Build(),
EventRecorder: record.NewFakeRecorder(32),
Storage: testStorage,
patchOptions: getPatchOptions(helmRepositoryReadyCondition.Owned, "sc"),
}
obj := &helmv1.HelmRepository{
obj := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "test-",
Generation: 1,
@ -421,8 +420,8 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
server options
url string
secret *corev1.Secret
beforeFunc func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest)
afterFunc func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository)
beforeFunc func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest)
afterFunc func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository)
want sreconcile.Result
wantErr bool
assertConditions []metav1.Condition
@ -440,7 +439,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
"ca.crt": tlsCA,
},
},
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Spec.CertSecretRef = &meta.LocalObjectReference{Name: "ca-file"}
},
assertConditions: []metav1.Condition{
@ -464,7 +463,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
"ca.crt": tlsCA,
},
},
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Spec.CertSecretRef = &meta.LocalObjectReference{Name: "ca-file"}
},
want: sreconcile.ResultSuccess,
@ -472,7 +471,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Revision).ToNot(BeEmpty())
@ -494,7 +493,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
"caFile": tlsCA,
},
},
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "ca-file"}
},
want: sreconcile.ResultSuccess,
@ -502,7 +501,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Revision).ToNot(BeEmpty())
@ -526,7 +525,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
},
Type: corev1.SecretTypeDockerConfigJson,
},
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "ca-file"}
},
want: sreconcile.ResultSuccess,
@ -534,7 +533,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Revision).ToNot(BeEmpty())
@ -548,7 +547,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Revision).ToNot(BeEmpty())
@ -570,7 +569,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
"password": []byte("1234"),
},
},
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "basic-auth"}
},
want: sreconcile.ResultSuccess,
@ -578,7 +577,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Revision).ToNot(BeEmpty())
@ -602,7 +601,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
},
Type: corev1.SecretTypeDockerConfigJson,
},
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "basic-auth"}
},
want: sreconcile.ResultSuccess,
@ -610,7 +609,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
t.Expect(artifact.Revision).ToNot(BeEmpty())
@ -632,7 +631,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
"ca.crt": []byte("invalid"),
},
},
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Spec.CertSecretRef = &meta.LocalObjectReference{Name: "invalid-ca"}
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
@ -643,7 +642,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
// No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil())
@ -653,7 +652,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
{
name: "Invalid URL makes FetchFailed=True and returns stalling error",
protocol: "http",
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Spec.URL = strings.ReplaceAll(obj.Spec.URL, "http://", "")
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
@ -665,7 +664,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
// No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil())
@ -675,7 +674,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
{
name: "Unsupported scheme makes FetchFailed=True and returns stalling error",
protocol: "http",
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Spec.URL = strings.ReplaceAll(obj.Spec.URL, "http://", "ftp://")
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
@ -687,7 +686,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
// No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil())
@ -697,7 +696,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
{
name: "Missing secret returns FetchFailed=True and returns error",
protocol: "http",
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "non-existing"}
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
@ -708,7 +707,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
// No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil())
@ -726,7 +725,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
"username": []byte("git"),
},
},
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Spec.SecretRef = &meta.LocalObjectReference{Name: "malformed-basic-auth"}
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
@ -737,7 +736,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
// No repo index due to fetch fail.
t.Expect(chartRepo.Path).To(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil())
@ -747,7 +746,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
{
name: "Stored index with same revision",
protocol: "http",
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Status.Artifact = &sourcev1.Artifact{
Revision: rev.String(),
}
@ -760,7 +759,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).To(BeNil())
@ -771,7 +770,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
{
name: "Stored index with different revision",
protocol: "http",
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Status.Artifact = &sourcev1.Artifact{
Revision: "80bb3dd67c63095d985850459834ea727603727a370079de90d221191d375a86",
}
@ -784,7 +783,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "building artifact: new index revision"),
*conditions.UnknownCondition(meta.ReadyCondition, meta.ProgressingReason, "building artifact: new index revision"),
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, chartRepo *repository.ChartRepository) {
t.Expect(chartRepo.Path).ToNot(BeEmpty())
t.Expect(chartRepo.Index).ToNot(BeNil())
@ -796,7 +795,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
{
name: "Existing artifact makes ArtifactOutdated=True",
protocol: "http",
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, rev digest.Digest) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, rev digest.Digest) {
obj.Status.Artifact = &sourcev1.Artifact{
Path: "some-path",
Revision: "some-rev",
@ -812,12 +811,12 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
}
for _, tt := range tests {
obj := &helmv1.HelmRepository{
obj := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "auth-strategy-",
Generation: 1,
},
Spec: helmv1.HelmRepositorySpec{
Spec: sourcev1.HelmRepositorySpec{
Interval: metav1.Duration{Duration: interval},
Timeout: &metav1.Duration{Duration: timeout},
},
@ -868,7 +867,7 @@ func TestHelmRepositoryReconciler_reconcileSource(t *testing.T) {
clientBuilder := fakeclient.NewClientBuilder().
WithScheme(testEnv.GetScheme()).
WithStatusSubresource(&helmv1.HelmRepository{})
WithStatusSubresource(&sourcev1.HelmRepository{})
if secret != nil {
clientBuilder.WithObjects(secret.DeepCopy())
@ -960,19 +959,19 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
tests := []struct {
name string
cache *cache.Cache
beforeFunc func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository)
afterFunc func(t *WithT, obj *helmv1.HelmRepository, cache *cache.Cache)
beforeFunc func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository)
afterFunc func(t *WithT, obj *sourcev1.HelmRepository, cache *cache.Cache)
want sreconcile.Result
wantErr bool
assertConditions []metav1.Condition
}{
{
name: "Archiving artifact to storage makes ArtifactInStorage=True and artifact is stored as JSON",
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
obj.Spec.Interval = metav1.Duration{Duration: interval}
},
want: sreconcile.ResultSuccess,
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, cache *cache.Cache) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, cache *cache.Cache) {
localPath := testStorage.LocalPath(*obj.GetArtifact())
b, err := os.ReadFile(localPath)
t.Expect(err).To(Not(HaveOccurred()))
@ -985,7 +984,7 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
{
name: "Archiving (loaded) artifact to storage adds to cache",
cache: cache.New(10, time.Minute),
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
index.Index = &repo.IndexFile{
APIVersion: "v1",
Generated: time.Now(),
@ -993,7 +992,7 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
obj.Spec.Interval = metav1.Duration{Duration: interval}
},
want: sreconcile.ResultSuccess,
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, cache *cache.Cache) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, cache *cache.Cache) {
i, ok := cache.Get(obj.GetArtifact().Path)
t.Expect(ok).To(BeTrue())
t.Expect(i).To(BeAssignableToTypeOf(&repo.IndexFile{}))
@ -1004,11 +1003,11 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
},
{
name: "Up-to-date artifact should not update status",
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
obj.Spec.Interval = metav1.Duration{Duration: interval}
obj.Status.Artifact = artifact.DeepCopy()
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, _ *cache.Cache) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, _ *cache.Cache) {
t.Expect(obj.Status.URL).To(BeEmpty())
},
want: sreconcile.ResultSuccess,
@ -1018,7 +1017,7 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
},
{
name: "Removes ArtifactOutdatedCondition after creating a new artifact",
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
obj.Spec.Interval = metav1.Duration{Duration: interval}
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "Foo", "")
},
@ -1029,10 +1028,10 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
},
{
name: "Creates latest symlink to the created artifact",
beforeFunc: func(t *WithT, obj *helmv1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
beforeFunc: func(t *WithT, obj *sourcev1.HelmRepository, artifact sourcev1.Artifact, index *repository.ChartRepository) {
obj.Spec.Interval = metav1.Duration{Duration: interval}
},
afterFunc: func(t *WithT, obj *helmv1.HelmRepository, _ *cache.Cache) {
afterFunc: func(t *WithT, obj *sourcev1.HelmRepository, _ *cache.Cache) {
localPath := testStorage.LocalPath(*obj.GetArtifact())
symlinkPath := filepath.Join(filepath.Dir(localPath), "index.yaml")
targetFile, err := os.Readlink(symlinkPath)
@ -1053,7 +1052,7 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
r := &HelmRepositoryReconciler{
Client: fakeclient.NewClientBuilder().
WithScheme(testEnv.GetScheme()).
WithStatusSubresource(&helmv1.HelmRepository{}).
WithStatusSubresource(&sourcev1.HelmRepository{}).
Build(),
EventRecorder: record.NewFakeRecorder(32),
Storage: testStorage,
@ -1062,16 +1061,16 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
patchOptions: getPatchOptions(helmRepositoryReadyCondition.Owned, "sc"),
}
obj := &helmv1.HelmRepository{
obj := &sourcev1.HelmRepository{
TypeMeta: metav1.TypeMeta{
Kind: helmv1.HelmRepositoryKind,
Kind: sourcev1.HelmRepositoryKind,
},
ObjectMeta: metav1.ObjectMeta{
GenerateName: "test-bucket-",
Generation: 1,
Namespace: "default",
},
Spec: helmv1.HelmRepositorySpec{
Spec: sourcev1.HelmRepositorySpec{
Timeout: &metav1.Duration{Duration: timeout},
URL: "https://example.com/index.yaml",
},
@ -1111,7 +1110,7 @@ func TestHelmRepositoryReconciler_reconcileArtifact(t *testing.T) {
func TestHelmRepositoryReconciler_reconcileSubRecs(t *testing.T) {
// Helper to build simple helmRepositoryReconcileFunc with result and error.
buildReconcileFuncs := func(r sreconcile.Result, e error) helmRepositoryReconcileFunc {
return func(ctx context.Context, sp *patch.SerialPatcher, obj *helmv1.HelmRepository, artifact *sourcev1.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error) {
return func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *sourcev1.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error) {
return r, e
}
}
@ -1166,11 +1165,11 @@ func TestHelmRepositoryReconciler_reconcileSubRecs(t *testing.T) {
{
name: "multiple object status conditions mutations",
reconcileFuncs: []helmRepositoryReconcileFunc{
func(ctx context.Context, sp *patch.SerialPatcher, obj *helmv1.HelmRepository, artifact *sourcev1.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error) {
func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *sourcev1.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error) {
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", "new index revision")
return sreconcile.ResultSuccess, nil
},
func(ctx context.Context, sp *patch.SerialPatcher, obj *helmv1.HelmRepository, artifact *sourcev1.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error) {
func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.HelmRepository, artifact *sourcev1.Artifact, repo *repository.ChartRepository) (sreconcile.Result, error) {
conditions.MarkTrue(obj, meta.ReconcilingCondition, meta.ProgressingReason, "creating artifact")
return sreconcile.ResultSuccess, nil
},
@ -1220,16 +1219,16 @@ func TestHelmRepositoryReconciler_reconcileSubRecs(t *testing.T) {
r := &HelmRepositoryReconciler{
Client: fakeclient.NewClientBuilder().
WithScheme(testEnv.GetScheme()).
WithStatusSubresource(&helmv1.HelmRepository{}).
WithStatusSubresource(&sourcev1.HelmRepository{}).
Build(),
patchOptions: getPatchOptions(helmRepositoryReadyCondition.Owned, "sc"),
}
obj := &helmv1.HelmRepository{
obj := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "test-",
Generation: tt.generation,
},
Status: helmv1.HelmRepositoryStatus{
Status: sourcev1.HelmRepositoryStatus{
ObservedGeneration: tt.observedGeneration,
},
}
@ -1254,13 +1253,13 @@ func TestHelmRepositoryReconciler_reconcileSubRecs(t *testing.T) {
func TestHelmRepositoryReconciler_statusConditions(t *testing.T) {
tests := []struct {
name string
beforeFunc func(obj *helmv1.HelmRepository)
beforeFunc func(obj *sourcev1.HelmRepository)
assertConditions []metav1.Condition
wantErr bool
}{
{
name: "positive conditions only",
beforeFunc: func(obj *helmv1.HelmRepository) {
beforeFunc: func(obj *sourcev1.HelmRepository) {
conditions.MarkTrue(obj, sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "stored artifact for revision")
},
assertConditions: []metav1.Condition{
@ -1271,7 +1270,7 @@ func TestHelmRepositoryReconciler_statusConditions(t *testing.T) {
},
{
name: "multiple failures",
beforeFunc: func(obj *helmv1.HelmRepository) {
beforeFunc: func(obj *sourcev1.HelmRepository) {
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.AuthenticationFailedReason, "failed to get secret")
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, sourcev1.DirCreationFailedReason, "failed to create directory")
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", "some error")
@ -1286,7 +1285,7 @@ func TestHelmRepositoryReconciler_statusConditions(t *testing.T) {
},
{
name: "mixed positive and negative conditions",
beforeFunc: func(obj *helmv1.HelmRepository) {
beforeFunc: func(obj *sourcev1.HelmRepository) {
conditions.MarkTrue(obj, sourcev1.ArtifactInStorageCondition, meta.SucceededReason, "stored artifact for revision")
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.AuthenticationFailedReason, "failed to get secret")
},
@ -1303,10 +1302,10 @@ func TestHelmRepositoryReconciler_statusConditions(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
obj := &helmv1.HelmRepository{
obj := &sourcev1.HelmRepository{
TypeMeta: metav1.TypeMeta{
Kind: helmv1.HelmRepositoryKind,
APIVersion: helmv1.GroupVersion.String(),
Kind: sourcev1.HelmRepositoryKind,
APIVersion: sourcev1.GroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "helmrepo",
@ -1316,7 +1315,7 @@ func TestHelmRepositoryReconciler_statusConditions(t *testing.T) {
clientBuilder := fakeclient.NewClientBuilder().
WithObjects(obj).
WithStatusSubresource(&helmv1.HelmRepository{})
WithStatusSubresource(&sourcev1.HelmRepository{})
c := clientBuilder.Build()
@ -1351,8 +1350,8 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
name string
res sreconcile.Result
resErr error
oldObjBeforeFunc func(obj *helmv1.HelmRepository)
newObjBeforeFunc func(obj *helmv1.HelmRepository)
oldObjBeforeFunc func(obj *sourcev1.HelmRepository)
newObjBeforeFunc func(obj *sourcev1.HelmRepository)
wantEvent string
}{
{
@ -1364,7 +1363,7 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
name: "new artifact with nil size",
res: sreconcile.ResultSuccess,
resErr: nil,
newObjBeforeFunc: func(obj *helmv1.HelmRepository) {
newObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: nil}
},
wantEvent: "Normal NewArtifact stored fetched index of unknown size",
@ -1373,7 +1372,7 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
name: "new artifact",
res: sreconcile.ResultSuccess,
resErr: nil,
newObjBeforeFunc: func(obj *helmv1.HelmRepository) {
newObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
},
wantEvent: "Normal NewArtifact stored fetched index of size",
@ -1382,12 +1381,12 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
name: "recovery from failure",
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *helmv1.HelmRepository) {
oldObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *helmv1.HelmRepository) {
newObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
@ -1397,12 +1396,12 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
name: "recovery and new artifact",
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *helmv1.HelmRepository) {
oldObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, sourcev1.GitOperationFailedReason, "fail")
conditions.MarkFalse(obj, meta.ReadyCondition, meta.FailedReason, "foo")
},
newObjBeforeFunc: func(obj *helmv1.HelmRepository) {
newObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "aaa", Digest: "bbb", Size: &aSize}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
@ -1412,11 +1411,11 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
name: "no updates",
res: sreconcile.ResultSuccess,
resErr: nil,
oldObjBeforeFunc: func(obj *helmv1.HelmRepository) {
oldObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
newObjBeforeFunc: func(obj *helmv1.HelmRepository) {
newObjBeforeFunc: func(obj *sourcev1.HelmRepository) {
obj.Status.Artifact = &sourcev1.Artifact{Revision: "xxx", Digest: "yyy", Size: &aSize}
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "ready")
},
@ -1428,7 +1427,7 @@ func TestHelmRepositoryReconciler_notify(t *testing.T) {
g := NewWithT(t)
recorder := record.NewFakeRecorder(32)
oldObj := &helmv1.HelmRepository{}
oldObj := &sourcev1.HelmRepository{}
newObj := oldObj.DeepCopy()
if tt.oldObjBeforeFunc != nil {
@ -1475,12 +1474,12 @@ func TestHelmRepositoryReconciler_ReconcileTypeUpdatePredicateFilter(t *testing.
testServer.Start()
defer testServer.Stop()
obj := &helmv1.HelmRepository{
obj := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "helmrepository-reconcile-",
Namespace: "default",
},
Spec: helmv1.HelmRepositorySpec{
Spec: sourcev1.HelmRepositorySpec{
Interval: metav1.Duration{Duration: interval},
URL: testServer.URL(),
},
@ -1524,7 +1523,7 @@ func TestHelmRepositoryReconciler_ReconcileTypeUpdatePredicateFilter(t *testing.
g.Expect(res.Status).To(Equal(kstatus.CurrentStatus))
// Switch to a OCI helm repository type
obj.Spec.Type = helmv1.HelmRepositoryTypeOCI
obj.Spec.Type = sourcev1.HelmRepositoryTypeOCI
obj.Spec.URL = fmt.Sprintf("oci://%s", testRegistryServer.registryHost)
oldGen := obj.GetGeneration()
@ -1564,12 +1563,12 @@ func TestHelmRepositoryReconciler_ReconcileSpecUpdatePredicateFilter(t *testing.
testServer.Start()
defer testServer.Stop()
obj := &helmv1.HelmRepository{
obj := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "helmrepository-reconcile-",
Namespace: "default",
},
Spec: helmv1.HelmRepositorySpec{
Spec: sourcev1.HelmRepositorySpec{
Interval: metav1.Duration{Duration: interval},
URL: testServer.URL(),
},
@ -1666,12 +1665,12 @@ func TestHelmRepositoryReconciler_InMemoryCaching(t *testing.T) {
g.Expect(err).ToNot(HaveOccurred())
defer func() { g.Expect(testEnv.Delete(ctx, ns)).To(Succeed()) }()
helmRepo := &helmv1.HelmRepository{
helmRepo := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "helmrepository-",
Namespace: ns.Name,
},
Spec: helmv1.HelmRepositorySpec{
Spec: sourcev1.HelmRepositorySpec{
URL: testServer.URL(),
},
}
@ -1725,7 +1724,7 @@ func TestHelmRepositoryReconciler_ociMigration(t *testing.T) {
g.Expect(testEnv.Cleanup(ctx, testns)).ToNot(HaveOccurred())
})
hr := &helmv1.HelmRepository{
hr := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("hr-%s", randStringRunes(5)),
Namespace: testns.Name,
@ -1736,8 +1735,8 @@ func TestHelmRepositoryReconciler_ociMigration(t *testing.T) {
// Migrates newly created object with finalizer.
hr.ObjectMeta.Finalizers = append(hr.ObjectMeta.Finalizers, "foo.bar", sourcev1.SourceFinalizer)
hr.Spec = helmv1.HelmRepositorySpec{
Type: helmv1.HelmRepositoryTypeOCI,
hr.Spec = sourcev1.HelmRepositorySpec{
Type: sourcev1.HelmRepositoryTypeOCI,
URL: "oci://foo/bar",
Interval: metav1.Duration{Duration: interval},
}

View File

@ -19,12 +19,15 @@ package controller
import (
"context"
cryptotls "crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"os"
"path/filepath"
"regexp"
"sort"
"strings"
"time"
@ -35,24 +38,21 @@ import (
"github.com/google/go-containerregistry/pkg/name"
gcrv1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/notaryproject/notation-go/verifier/trustpolicy"
"github.com/sigstore/cosign/v2/pkg/cosign"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
kuberecorder "k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
"k8s.io/utils/ptr"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/ratelimiter"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/auth"
"github.com/fluxcd/pkg/cache"
"github.com/fluxcd/pkg/oci"
"github.com/fluxcd/pkg/runtime/conditions"
helper "github.com/fluxcd/pkg/runtime/controller"
@ -63,11 +63,18 @@ import (
"github.com/fluxcd/pkg/sourceignore"
"github.com/fluxcd/pkg/tar"
"github.com/fluxcd/pkg/version"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/predicate"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
ociv1 "github.com/fluxcd/source-controller/api/v1beta2"
serror "github.com/fluxcd/source-controller/internal/error"
soci "github.com/fluxcd/source-controller/internal/oci"
scosign "github.com/fluxcd/source-controller/internal/oci/cosign"
"github.com/fluxcd/source-controller/internal/oci/notation"
sreconcile "github.com/fluxcd/source-controller/internal/reconcile"
"github.com/fluxcd/source-controller/internal/reconcile/summarize"
"github.com/fluxcd/source-controller/internal/tls"
@ -75,7 +82,7 @@ import (
)
// ociRepositoryReadyCondition contains the information required to summarize a
// v1beta2.OCIRepository Ready Condition.
// v1.OCIRepository Ready Condition.
var ociRepositoryReadyCondition = summarize.Conditions{
Target: meta.ReadyCondition,
Owned: []string{
@ -112,6 +119,8 @@ var ociRepositoryFailConditions = []string{
sourcev1.StorageOperationFailedCondition,
}
type filterFunc func(tags []string) ([]string, error)
type invalidOCIURLError struct {
err error
}
@ -120,12 +129,12 @@ func (e invalidOCIURLError) Error() string {
return e.err.Error()
}
// ociRepositoryReconcileFunc is the function type for all the v1beta2.OCIRepository
// ociRepositoryReconcileFunc is the function type for all the v1.OCIRepository
// (sub)reconcile functions. The type implementations are grouped and
// executed serially to perform the complete reconcile of the object.
type ociRepositoryReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *ociv1.OCIRepository, metadata *sourcev1.Artifact, dir string) (sreconcile.Result, error)
type ociRepositoryReconcileFunc func(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.OCIRepository, metadata *sourcev1.Artifact, dir string) (sreconcile.Result, error)
// OCIRepositoryReconciler reconciles a v1beta2.OCIRepository object
// OCIRepositoryReconciler reconciles a v1.OCIRepository object
type OCIRepositoryReconciler struct {
client.Client
helper.Metrics
@ -133,6 +142,7 @@ type OCIRepositoryReconciler struct {
Storage *Storage
ControllerName string
TokenCache *cache.TokenCache
requeueDependency time.Duration
patchOptions []patch.Option
@ -140,7 +150,7 @@ type OCIRepositoryReconciler struct {
type OCIRepositoryReconcilerOptions struct {
DependencyRequeueInterval time.Duration
RateLimiter ratelimiter.RateLimiter
RateLimiter workqueue.TypedRateLimiter[reconcile.Request]
}
// SetupWithManager sets up the controller with the Manager.
@ -154,7 +164,7 @@ func (r *OCIRepositoryReconciler) SetupWithManagerAndOptions(mgr ctrl.Manager, o
r.requeueDependency = opts.DependencyRequeueInterval
return ctrl.NewControllerManagedBy(mgr).
For(&ociv1.OCIRepository{}, builder.WithPredicates(
For(&sourcev1.OCIRepository{}, builder.WithPredicates(
predicate.Or(predicate.GenerationChangedPredicate{}, predicates.ReconcileRequestedPredicate{}),
)).
WithOptions(controller.Options{
@ -167,13 +177,14 @@ func (r *OCIRepositoryReconciler) SetupWithManagerAndOptions(mgr ctrl.Manager, o
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=ocirepositories/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=source.toolkit.fluxcd.io,resources=ocirepositories/finalizers,verbs=get;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
// +kubebuilder:rbac:groups="",resources=serviceaccounts/token,verbs=create
func (r *OCIRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, retErr error) {
start := time.Now()
log := ctrl.LoggerFrom(ctx)
// Fetch the OCIRepository
obj := &ociv1.OCIRepository{}
obj := &sourcev1.OCIRepository{}
if err := r.Get(ctx, req.NamespacedName, obj); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
@ -205,9 +216,7 @@ func (r *OCIRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reques
}
result, retErr = summarizeHelper.SummarizeAndPatch(ctx, obj, summarizeOpts...)
// Always record suspend, readiness and duration metrics.
r.Metrics.RecordSuspend(ctx, obj, obj.Spec.Suspend)
r.Metrics.RecordReadiness(ctx, obj)
// Always record duration metrics.
r.Metrics.RecordDuration(ctx, obj, start)
}()
@ -247,7 +256,7 @@ func (r *OCIRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reques
// reconcile iterates through the ociRepositoryReconcileFunc tasks for the
// object. It returns early on the first call that returns
// reconcile.ResultRequeue, or produces an error.
func (r *OCIRepositoryReconciler) reconcile(ctx context.Context, sp *patch.SerialPatcher, obj *ociv1.OCIRepository, reconcilers []ociRepositoryReconcileFunc) (sreconcile.Result, error) {
func (r *OCIRepositoryReconciler) reconcile(ctx context.Context, sp *patch.SerialPatcher, obj *sourcev1.OCIRepository, reconcilers []ociRepositoryReconcileFunc) (sreconcile.Result, error) {
oldObj := obj.DeepCopy()
rreconcile.ProgressiveStatus(false, obj, meta.ProgressingReason, "reconciliation in progress")
@ -279,7 +288,7 @@ func (r *OCIRepositoryReconciler) reconcile(ctx context.Context, sp *patch.Seria
fmt.Errorf("failed to create temporary working directory: %w", err),
sourcev1.DirCreationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
defer func() {
@ -319,10 +328,10 @@ func (r *OCIRepositoryReconciler) reconcile(ctx context.Context, sp *patch.Seria
}
// reconcileSource fetches the upstream OCI artifact metadata and content.
// If this fails, it records v1beta2.FetchFailedCondition=True on the object and returns early.
// If this fails, it records v1.FetchFailedCondition=True on the object and returns early.
func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch.SerialPatcher,
obj *ociv1.OCIRepository, metadata *sourcev1.Artifact, dir string) (sreconcile.Result, error) {
var auth authn.Authenticator
obj *sourcev1.OCIRepository, metadata *sourcev1.Artifact, dir string) (sreconcile.Result, error) {
var authenticator authn.Authenticator
ctxTimeout, cancel := context.WithTimeout(ctx, obj.Spec.Timeout.Duration)
defer cancel()
@ -342,35 +351,72 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
fmt.Errorf("failed to get credential: %w", err),
sourcev1.AuthenticationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
if _, ok := keychain.(soci.Anonymous); obj.Spec.Provider != ociv1.GenericOCIProvider && ok {
proxyURL, err := r.getProxyURL(ctx, obj)
if err != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to get proxy address: %w", err),
sourcev1.AuthenticationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
if _, ok := keychain.(soci.Anonymous); obj.Spec.Provider != "" && obj.Spec.Provider != sourcev1.GenericOCIProvider && ok {
var opts []auth.Option
if obj.Spec.ServiceAccountName != "" {
// Check object-level workload identity feature gate.
if !auth.IsObjectLevelWorkloadIdentityEnabled() {
const gate = auth.FeatureGateObjectLevelWorkloadIdentity
const msgFmt = "to use spec.serviceAccountName for provider authentication please enable the %s feature gate in the controller"
err := fmt.Errorf(msgFmt, gate)
return sreconcile.ResultEmpty, serror.NewStalling(err, meta.FeatureGateDisabledReason)
}
serviceAccount := client.ObjectKey{
Name: obj.Spec.ServiceAccountName,
Namespace: obj.GetNamespace(),
}
opts = append(opts, auth.WithServiceAccount(serviceAccount, r.Client))
}
if r.TokenCache != nil {
involvedObject := cache.InvolvedObject{
Kind: sourcev1.OCIRepositoryKind,
Name: obj.GetName(),
Namespace: obj.GetNamespace(),
Operation: cache.OperationReconcile,
}
opts = append(opts, auth.WithCache(*r.TokenCache, involvedObject))
}
if proxyURL != nil {
opts = append(opts, auth.WithProxyURL(*proxyURL))
}
var authErr error
auth, authErr = soci.OIDCAuth(ctxTimeout, obj.Spec.URL, obj.Spec.Provider)
if authErr != nil && !errors.Is(authErr, oci.ErrUnconfiguredProvider) {
authenticator, authErr = soci.OIDCAuth(ctxTimeout, obj.Spec.URL, obj.Spec.Provider, opts...)
if authErr != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to get credential from %s: %w", obj.Spec.Provider, authErr),
sourcev1.AuthenticationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
}
// Generate the transport for remote operations
transport, err := r.transport(ctx, obj)
transport, err := r.transport(ctx, obj, proxyURL)
if err != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to generate transport for '%s': %w", obj.Spec.URL, err),
sourcev1.AuthenticationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
opts := makeRemoteOptions(ctx, transport, keychain, auth)
opts := makeRemoteOptions(ctx, transport, keychain, authenticator)
// Determine which artifact revision to pull
ref, err := r.getArtifactRef(obj, opts)
@ -379,14 +425,14 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
e := serror.NewStalling(
fmt.Errorf("URL validation failed for '%s': %w", obj.Spec.URL, err),
sourcev1.URLInvalidReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
e := serror.NewGeneric(
fmt.Errorf("failed to determine the artifact tag for '%s': %w", obj.Spec.URL, err),
sourcev1.ReadOperationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -396,9 +442,9 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
if err != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to determine artifact digest: %w", err),
ociv1.OCIPullFailedReason,
sourcev1.OCIPullFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
metaArtifact := &sourcev1.Artifact{Revision: revision}
@ -409,7 +455,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
if !obj.GetArtifact().HasRevision(revision) {
message := fmt.Sprintf("new revision '%s' for '%s'", revision, ref)
if obj.GetArtifact() != nil {
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", message)
conditions.MarkTrue(obj, sourcev1.ArtifactOutdatedCondition, "NewRevision", "%s", message)
}
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "building artifact: %s", message)
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
@ -430,21 +476,23 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
conditions.GetObservedGeneration(obj, sourcev1.SourceVerifiedCondition) != obj.Generation ||
conditions.IsFalse(obj, sourcev1.SourceVerifiedCondition) {
err := r.verifySignature(ctx, obj, ref, opts...)
result, err := r.verifySignature(ctx, obj, ref, keychain, authenticator, transport, opts...)
if err != nil {
provider := obj.Spec.Verify.Provider
if obj.Spec.Verify.SecretRef == nil {
if obj.Spec.Verify.SecretRef == nil && obj.Spec.Verify.Provider == "cosign" {
provider = fmt.Sprintf("%s keyless", provider)
}
e := serror.NewGeneric(
fmt.Errorf("failed to verify the signature using provider '%s': %w", provider, err),
sourcev1.VerificationError,
)
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, e.Reason, e.Err.Error())
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, meta.SucceededReason, "verified signature of revision %s", revision)
if result == soci.VerificationResultSuccess {
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, meta.SucceededReason, "verified signature of revision %s", revision)
}
}
// Skip pulling if the artifact revision and the source configuration has
@ -459,9 +507,9 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
if err != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to pull artifact from '%s': %w", obj.Spec.URL, err),
ociv1.OCIPullFailedReason,
sourcev1.OCIPullFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -470,9 +518,9 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
if err != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to parse artifact manifest: %w", err),
ociv1.OCILayerOperationFailedReason,
sourcev1.OCILayerOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
metadata.Metadata = manifest.Annotations
@ -480,31 +528,31 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
// Extract the compressed content from the selected layer
blob, err := r.selectLayer(obj, img)
if err != nil {
e := serror.NewGeneric(err, ociv1.OCILayerOperationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
e := serror.NewGeneric(err, sourcev1.OCILayerOperationFailedReason)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
// Persist layer content to storage using the specified operation
switch obj.GetLayerOperation() {
case ociv1.OCILayerExtract:
case sourcev1.OCILayerExtract:
if err = tar.Untar(blob, dir, tar.WithMaxUntarSize(-1), tar.WithSkipSymlinks()); err != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to extract layer contents from artifact: %w", err),
ociv1.OCILayerOperationFailedReason,
sourcev1.OCILayerOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
case ociv1.OCILayerCopy:
case sourcev1.OCILayerCopy:
metadata.Path = fmt.Sprintf("%s.tgz", r.digestFromRevision(metadata.Revision))
file, err := os.Create(filepath.Join(dir, metadata.Path))
if err != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to create file to copy layer to: %w", err),
ociv1.OCILayerOperationFailedReason,
sourcev1.OCILayerOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
defer file.Close()
@ -513,17 +561,17 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
if err != nil {
e := serror.NewGeneric(
fmt.Errorf("failed to copy layer from artifact: %w", err),
ociv1.OCILayerOperationFailedReason,
sourcev1.OCILayerOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
default:
e := serror.NewGeneric(
fmt.Errorf("unsupported layer operation: %s", obj.GetLayerOperation()),
ociv1.OCILayerOperationFailedReason,
sourcev1.OCILayerOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -533,7 +581,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, sp *patch
// selectLayer finds the matching layer and returns its compressed contents.
// If no layer selector was provided, we pick the first layer from the OCI artifact.
func (r *OCIRepositoryReconciler) selectLayer(obj *ociv1.OCIRepository, image gcrv1.Image) (io.ReadCloser, error) {
func (r *OCIRepositoryReconciler) selectLayer(obj *sourcev1.OCIRepository, image gcrv1.Image) (io.ReadCloser, error) {
layers, err := image.Layers()
if err != nil {
return nil, fmt.Errorf("failed to parse artifact layers: %w", err)
@ -609,57 +657,64 @@ func (r *OCIRepositoryReconciler) digestFromRevision(revision string) string {
}
// verifySignature verifies the authenticity of the given image reference URL.
// It supports two different verification providers: cosign and notation.
// First, it tries to use a key if a Secret with a valid public key is provided.
// If not, it falls back to a keyless approach for verification.
func (r *OCIRepositoryReconciler) verifySignature(ctx context.Context, obj *ociv1.OCIRepository, ref name.Reference, opt ...remote.Option) error {
// If not, when using cosign it falls back to a keyless approach for verification.
// When notation is used, a trust policy is required to verify the image.
// The verification result is returned as a VerificationResult and any error encountered.
func (r *OCIRepositoryReconciler) verifySignature(ctx context.Context, obj *sourcev1.OCIRepository,
ref name.Reference, keychain authn.Keychain, auth authn.Authenticator,
transport *http.Transport, opt ...remote.Option) (soci.VerificationResult, error) {
ctxTimeout, cancel := context.WithTimeout(ctx, obj.Spec.Timeout.Duration)
defer cancel()
provider := obj.Spec.Verify.Provider
switch provider {
case "cosign":
defaultCosignOciOpts := []soci.Options{
soci.WithRemoteOptions(opt...),
defaultCosignOciOpts := []scosign.Options{
scosign.WithRemoteOptions(opt...),
}
// get the public keys from the given secret
if secretRef := obj.Spec.Verify.SecretRef; secretRef != nil {
certSecretName := types.NamespacedName{
verifySecret := types.NamespacedName{
Namespace: obj.Namespace,
Name: secretRef.Name,
}
var pubSecret corev1.Secret
if err := r.Get(ctxTimeout, certSecretName, &pubSecret); err != nil {
return err
pubSecret, err := r.retrieveSecret(ctxTimeout, verifySecret)
if err != nil {
return soci.VerificationResultFailed, err
}
signatureVerified := false
signatureVerified := soci.VerificationResultFailed
for k, data := range pubSecret.Data {
// search for public keys in the secret
if strings.HasSuffix(k, ".pub") {
verifier, err := soci.NewCosignVerifier(ctxTimeout, append(defaultCosignOciOpts, soci.WithPublicKey(data))...)
verifier, err := scosign.NewCosignVerifier(ctxTimeout, append(defaultCosignOciOpts, scosign.WithPublicKey(data))...)
if err != nil {
return err
return soci.VerificationResultFailed, err
}
signatures, _, err := verifier.VerifyImageSignatures(ctxTimeout, ref)
if err != nil {
result, err := verifier.Verify(ctxTimeout, ref)
if err != nil || result == soci.VerificationResultFailed {
continue
}
if signatures != nil {
signatureVerified = true
if result == soci.VerificationResultSuccess {
signatureVerified = result
break
}
}
}
if !signatureVerified {
return fmt.Errorf("no matching signatures were found for '%s'", ref)
if signatureVerified == soci.VerificationResultFailed {
return soci.VerificationResultFailed, fmt.Errorf("no matching signatures were found for '%s'", ref)
}
return nil
return soci.VerificationResultSuccess, nil
}
// if no secret is provided, try keyless verification
@ -672,35 +727,115 @@ func (r *OCIRepositoryReconciler) verifySignature(ctx context.Context, obj *ociv
SubjectRegExp: match.Subject,
})
}
defaultCosignOciOpts = append(defaultCosignOciOpts, soci.WithIdentities(identities))
defaultCosignOciOpts = append(defaultCosignOciOpts, scosign.WithIdentities(identities))
verifier, err := soci.NewCosignVerifier(ctxTimeout, defaultCosignOciOpts...)
verifier, err := scosign.NewCosignVerifier(ctxTimeout, defaultCosignOciOpts...)
if err != nil {
return err
return soci.VerificationResultFailed, err
}
signatures, _, err := verifier.VerifyImageSignatures(ctxTimeout, ref)
result, err := verifier.Verify(ctxTimeout, ref)
if err != nil {
return err
return soci.VerificationResultFailed, err
}
if len(signatures) > 0 {
return nil
if result == soci.VerificationResultFailed {
return soci.VerificationResultFailed, fmt.Errorf("no matching signatures were found for '%s'", ref)
}
return fmt.Errorf("no matching signatures were found for '%s'", ref)
return soci.VerificationResultSuccess, nil
case "notation":
// get the public keys from the given secret
secretRef := obj.Spec.Verify.SecretRef
if secretRef == nil {
return soci.VerificationResultFailed, fmt.Errorf("verification secret cannot be empty: '%s'", ref)
}
verifySecret := types.NamespacedName{
Namespace: obj.Namespace,
Name: secretRef.Name,
}
pubSecret, err := r.retrieveSecret(ctxTimeout, verifySecret)
if err != nil {
return soci.VerificationResultFailed, err
}
data, ok := pubSecret.Data[notation.DefaultTrustPolicyKey]
if !ok {
return soci.VerificationResultFailed, fmt.Errorf("'%s' not found in secret '%s'", notation.DefaultTrustPolicyKey, verifySecret.String())
}
var doc trustpolicy.Document
if err := json.Unmarshal(data, &doc); err != nil {
return soci.VerificationResultFailed, fmt.Errorf("error occurred while parsing %s: %w", notation.DefaultTrustPolicyKey, err)
}
var certs [][]byte
for k, data := range pubSecret.Data {
if strings.HasSuffix(k, ".crt") || strings.HasSuffix(k, ".pem") {
certs = append(certs, data)
}
}
if certs == nil {
return soci.VerificationResultFailed, fmt.Errorf("no certificates found in secret '%s'", verifySecret.String())
}
trustPolicy := notation.CleanTrustPolicy(&doc, ctrl.LoggerFrom(ctx))
defaultNotationOciOpts := []notation.Options{
notation.WithTrustPolicy(trustPolicy),
notation.WithRemoteOptions(opt...),
notation.WithAuth(auth),
notation.WithKeychain(keychain),
notation.WithInsecureRegistry(obj.Spec.Insecure),
notation.WithLogger(ctrl.LoggerFrom(ctx)),
notation.WithRootCertificates(certs),
notation.WithTransport(transport),
}
verifier, err := notation.NewNotationVerifier(defaultNotationOciOpts...)
if err != nil {
return soci.VerificationResultFailed, err
}
result, err := verifier.Verify(ctxTimeout, ref)
if err != nil {
return result, err
}
if result == soci.VerificationResultFailed {
return soci.VerificationResultFailed, fmt.Errorf("no matching signatures were found for '%s'", ref)
}
return result, nil
default:
return soci.VerificationResultFailed, fmt.Errorf("unsupported verification provider: %s", obj.Spec.Verify.Provider)
}
}
return nil
// retrieveSecret retrieves a secret from the specified namespace with the given secret name.
// It returns the retrieved secret and any error encountered during the retrieval process.
func (r *OCIRepositoryReconciler) retrieveSecret(ctx context.Context, verifySecret types.NamespacedName) (corev1.Secret, error) {
var pubSecret corev1.Secret
if err := r.Get(ctx, verifySecret, &pubSecret); err != nil {
return corev1.Secret{}, err
}
return pubSecret, nil
}
// parseRepository validates and extracts the repository URL.
func (r *OCIRepositoryReconciler) parseRepository(obj *ociv1.OCIRepository) (name.Repository, error) {
if !strings.HasPrefix(obj.Spec.URL, ociv1.OCIRepositoryPrefix) {
func (r *OCIRepositoryReconciler) parseRepository(obj *sourcev1.OCIRepository) (name.Repository, error) {
if !strings.HasPrefix(obj.Spec.URL, sourcev1.OCIRepositoryPrefix) {
return name.Repository{}, fmt.Errorf("URL must be in format 'oci://<domain>/<org>/<repo>'")
}
url := strings.TrimPrefix(obj.Spec.URL, ociv1.OCIRepositoryPrefix)
url := strings.TrimPrefix(obj.Spec.URL, sourcev1.OCIRepositoryPrefix)
options := []name.Option{}
if obj.Spec.Insecure {
@ -720,7 +855,7 @@ func (r *OCIRepositoryReconciler) parseRepository(obj *ociv1.OCIRepository) (nam
}
// getArtifactRef determines which tag or revision should be used and returns the OCI artifact FQN.
func (r *OCIRepositoryReconciler) getArtifactRef(obj *ociv1.OCIRepository, options []remote.Option) (name.Reference, error) {
func (r *OCIRepositoryReconciler) getArtifactRef(obj *sourcev1.OCIRepository, options []remote.Option) (name.Reference, error) {
repo, err := r.parseRepository(obj)
if err != nil {
return nil, invalidOCIURLError{err}
@ -732,7 +867,7 @@ func (r *OCIRepositoryReconciler) getArtifactRef(obj *ociv1.OCIRepository, optio
}
if obj.Spec.Reference.SemVer != "" {
return r.getTagBySemver(repo, obj.Spec.Reference.SemVer, options)
return r.getTagBySemver(repo, obj.Spec.Reference.SemVer, filterTags(obj.Spec.Reference.SemverFilter), options)
}
if obj.Spec.Reference.Tag != "" {
@ -745,19 +880,24 @@ func (r *OCIRepositoryReconciler) getArtifactRef(obj *ociv1.OCIRepository, optio
// getTagBySemver call the remote container registry, fetches all the tags from the repository,
// and returns the latest tag according to the semver expression.
func (r *OCIRepositoryReconciler) getTagBySemver(repo name.Repository, exp string, options []remote.Option) (name.Reference, error) {
func (r *OCIRepositoryReconciler) getTagBySemver(repo name.Repository, exp string, filter filterFunc, options []remote.Option) (name.Reference, error) {
tags, err := remote.List(repo, options...)
if err != nil {
return nil, err
}
validTags, err := filter(tags)
if err != nil {
return nil, err
}
constraint, err := semver.NewConstraint(exp)
if err != nil {
return nil, fmt.Errorf("semver '%s' parse error: %w", exp, err)
}
var matchingVersions []*semver.Version
for _, t := range tags {
for _, t := range validTags {
v, err := version.ParseVersion(t)
if err != nil {
continue
@ -779,7 +919,7 @@ func (r *OCIRepositoryReconciler) getTagBySemver(repo name.Repository, exp strin
// keychain generates the credential keychain based on the resource
// configuration. If no auth is specified a default keychain with
// anonymous access is returned
func (r *OCIRepositoryReconciler) keychain(ctx context.Context, obj *ociv1.OCIRepository) (authn.Keychain, error) {
func (r *OCIRepositoryReconciler) keychain(ctx context.Context, obj *sourcev1.OCIRepository) (authn.Keychain, error) {
pullSecretNames := sets.NewString()
// lookup auth secret
@ -823,16 +963,36 @@ func (r *OCIRepositoryReconciler) keychain(ctx context.Context, obj *ociv1.OCIRe
// transport clones the default transport from remote and when a certSecretRef is specified,
// the returned transport will include the TLS client and/or CA certificates.
func (r *OCIRepositoryReconciler) transport(ctx context.Context, obj *ociv1.OCIRepository) (*http.Transport, error) {
// If the insecure flag is set, the transport will skip the verification of the server's certificate.
// Additionally, if a proxy is specified, transport will use it.
func (r *OCIRepositoryReconciler) transport(ctx context.Context, obj *sourcev1.OCIRepository, proxyURL *url.URL) (*http.Transport, error) {
transport := remote.DefaultTransport.(*http.Transport).Clone()
tlsConfig, err := r.getTLSConfig(ctx, obj)
if err != nil {
return nil, err
}
if tlsConfig != nil {
transport.TLSClientConfig = tlsConfig
}
if proxyURL != nil {
transport.Proxy = http.ProxyURL(proxyURL)
}
return transport, nil
}
// getTLSConfig gets the TLS configuration for the transport based on the
// specified secret reference in the OCIRepository object, or the insecure flag.
func (r *OCIRepositoryReconciler) getTLSConfig(ctx context.Context, obj *sourcev1.OCIRepository) (*cryptotls.Config, error) {
if obj.Spec.CertSecretRef == nil || obj.Spec.CertSecretRef.Name == "" {
if obj.Spec.Insecure {
transport.TLSClientConfig = &cryptotls.Config{
return &cryptotls.Config{
InsecureSkipVerify: true,
}
}, nil
}
return transport, nil
return nil, nil
}
certSecretName := types.NamespacedName{
@ -858,9 +1018,42 @@ func (r *OCIRepositoryReconciler) transport(ctx context.Context, obj *ociv1.OCIR
Info("warning: specifying TLS auth data via `certFile`/`keyFile`/`caFile` is deprecated, please use `tls.crt`/`tls.key`/`ca.crt` instead")
}
}
transport.TLSClientConfig = tlsConfig
return transport, nil
return tlsConfig, nil
}
// getProxyURL gets the proxy configuration for the transport based on the
// specified proxy secret reference in the OCIRepository object.
func (r *OCIRepositoryReconciler) getProxyURL(ctx context.Context, obj *sourcev1.OCIRepository) (*url.URL, error) {
if obj.Spec.ProxySecretRef == nil || obj.Spec.ProxySecretRef.Name == "" {
return nil, nil
}
proxySecretName := types.NamespacedName{
Namespace: obj.Namespace,
Name: obj.Spec.ProxySecretRef.Name,
}
var proxySecret corev1.Secret
if err := r.Get(ctx, proxySecretName, &proxySecret); err != nil {
return nil, err
}
proxyData := proxySecret.Data
address, ok := proxyData["address"]
if !ok {
return nil, fmt.Errorf("invalid proxy secret '%s/%s': key 'address' is missing",
obj.Namespace, obj.Spec.ProxySecretRef.Name)
}
proxyURL, err := url.Parse(string(address))
if err != nil {
return nil, fmt.Errorf("failed to parse proxy address '%s': %w", address, err)
}
user, hasUser := proxyData["username"]
password, hasPassword := proxyData["password"]
if hasUser || hasPassword {
proxyURL.User = url.UserPassword(string(user), string(password))
}
return proxyURL, nil
}
// reconcileStorage ensures the current state of the storage matches the
@ -876,7 +1069,7 @@ func (r *OCIRepositoryReconciler) transport(ctx context.Context, obj *ociv1.OCIR
// The hostname of any URL in the Status of the object are updated, to ensure
// they match the Storage server hostname of current runtime.
func (r *OCIRepositoryReconciler) reconcileStorage(ctx context.Context, sp *patch.SerialPatcher,
obj *ociv1.OCIRepository, _ *sourcev1.Artifact, _ string) (sreconcile.Result, error) {
obj *sourcev1.OCIRepository, _ *sourcev1.Artifact, _ string) (sreconcile.Result, error) {
// Garbage collect previous advertised artifact(s) from storage
_ = r.garbageCollect(ctx, obj)
@ -914,7 +1107,7 @@ func (r *OCIRepositoryReconciler) reconcileStorage(ctx context.Context, sp *patc
if artifactMissing {
msg += ": disappeared from storage"
}
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, msg)
rreconcile.ProgressiveStatus(true, obj, meta.ProgressingReason, "%s", msg)
conditions.Delete(obj, sourcev1.ArtifactInStorageCondition)
if err := sp.Patch(ctx, obj, r.patchOptions...); err != nil {
return sreconcile.ResultEmpty, serror.NewGeneric(err, sourcev1.PatchOperationFailedReason)
@ -933,13 +1126,13 @@ func (r *OCIRepositoryReconciler) reconcileStorage(ctx context.Context, sp *patc
// (Status) data on the object does not match the given.
//
// The inspection of the given data to the object is differed, ensuring any
// stale observations like v1beta2.ArtifactOutdatedCondition are removed.
// stale observations like v1.ArtifactOutdatedCondition are removed.
// If the given Artifact does not differ from the object's current, it returns
// early.
// On a successful archive, the Artifact in the Status of the object is set,
// and the symlink in the Storage is updated to its path.
func (r *OCIRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *patch.SerialPatcher,
obj *ociv1.OCIRepository, metadata *sourcev1.Artifact, dir string) (sreconcile.Result, error) {
obj *sourcev1.OCIRepository, metadata *sourcev1.Artifact, dir string) (sreconcile.Result, error) {
// Create artifact
artifact := r.Storage.NewArtifactFor(obj.Kind, obj, metadata.Revision,
fmt.Sprintf("%s.tar.gz", r.digestFromRevision(metadata.Revision)))
@ -966,14 +1159,14 @@ func (r *OCIRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pat
fmt.Errorf("failed to stat source path: %w", err),
sourcev1.StatOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
} else if !f.IsDir() {
e := serror.NewGeneric(
fmt.Errorf("source path '%s' is not a directory", dir),
sourcev1.InvalidPathReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
@ -983,7 +1176,7 @@ func (r *OCIRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pat
fmt.Errorf("failed to create artifact directory: %w", err),
sourcev1.DirCreationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
unlock, err := r.Storage.Lock(artifact)
@ -996,13 +1189,13 @@ func (r *OCIRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pat
defer unlock()
switch obj.GetLayerOperation() {
case ociv1.OCILayerCopy:
case sourcev1.OCILayerCopy:
if err = r.Storage.CopyFromPath(&artifact, filepath.Join(dir, metadata.Path)); err != nil {
e := serror.NewGeneric(
fmt.Errorf("unable to copy artifact to storage: %w", err),
sourcev1.ArchiveOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
default:
@ -1024,7 +1217,7 @@ func (r *OCIRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pat
fmt.Errorf("unable to archive artifact to storage: %s", err),
sourcev1.ArchiveOperationFailedReason,
)
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, e.Err.Error())
conditions.MarkTrue(obj, sourcev1.StorageOperationFailedCondition, e.Reason, "%s", e)
return sreconcile.ResultEmpty, e
}
}
@ -1032,7 +1225,6 @@ func (r *OCIRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pat
// Record the observations on the object.
obj.Status.Artifact = artifact.DeepCopy()
obj.Status.Artifact.Metadata = metadata.Metadata
obj.Status.ContentConfigChecksum = "" // To be removed in the next API version.
obj.Status.ObservedIgnore = obj.Spec.Ignore
obj.Status.ObservedLayerSelector = obj.Spec.LayerSelector
@ -1052,7 +1244,7 @@ func (r *OCIRepositoryReconciler) reconcileArtifact(ctx context.Context, sp *pat
// reconcileDelete handles the deletion of the object.
// It first garbage collects all Artifacts for the object from the Storage.
// Removing the finalizer from the object if successful.
func (r *OCIRepositoryReconciler) reconcileDelete(ctx context.Context, obj *ociv1.OCIRepository) (sreconcile.Result, error) {
func (r *OCIRepositoryReconciler) reconcileDelete(ctx context.Context, obj *sourcev1.OCIRepository) (sreconcile.Result, error) {
// Garbage collect the resource's artifacts
if err := r.garbageCollect(ctx, obj); err != nil {
// Return the error so we retry the failed garbage collection
@ -1062,6 +1254,10 @@ func (r *OCIRepositoryReconciler) reconcileDelete(ctx context.Context, obj *ociv
// Remove our finalizer from the list
controllerutil.RemoveFinalizer(obj, sourcev1.SourceFinalizer)
// Cleanup caches.
r.TokenCache.DeleteEventsForObject(sourcev1.OCIRepositoryKind,
obj.GetName(), obj.GetNamespace(), cache.OperationReconcile)
// Stop reconciliation as the object is being deleted
return sreconcile.ResultEmpty, nil
}
@ -1071,7 +1267,7 @@ func (r *OCIRepositoryReconciler) reconcileDelete(ctx context.Context, obj *ociv
// It removes all but the current Artifact from the Storage, unless the
// deletion timestamp on the object is set. Which will result in the
// removal of all Artifacts for the objects.
func (r *OCIRepositoryReconciler) garbageCollect(ctx context.Context, obj *ociv1.OCIRepository) error {
func (r *OCIRepositoryReconciler) garbageCollect(ctx context.Context, obj *sourcev1.OCIRepository) error {
if !obj.DeletionTimestamp.IsZero() {
if deleted, err := r.Storage.RemoveAll(r.Storage.NewArtifactFor(obj.Kind, obj.GetObjectMeta(), "", "*")); err != nil {
return serror.NewGeneric(
@ -1095,7 +1291,7 @@ func (r *OCIRepositoryReconciler) garbageCollect(ctx context.Context, obj *ociv1
}
if len(delFiles) > 0 {
r.eventLogf(ctx, obj, eventv1.EventTypeTrace, "GarbageCollectionSucceeded",
fmt.Sprintf("garbage collected %d artifacts", len(delFiles)))
"garbage collected %d artifacts", len(delFiles))
return nil
}
}
@ -1119,7 +1315,7 @@ func (r *OCIRepositoryReconciler) eventLogf(ctx context.Context, obj runtime.Obj
}
// notify emits notification related to the reconciliation.
func (r *OCIRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *ociv1.OCIRepository, res sreconcile.Result, resErr error) {
func (r *OCIRepositoryReconciler) notify(ctx context.Context, oldObj, newObj *sourcev1.OCIRepository, res sreconcile.Result, resErr error) {
// Notify successful reconciliation for new artifact and recovery from any
// failure.
if resErr == nil && res == sreconcile.ResultSuccess && newObj.Status.Artifact != nil {
@ -1185,7 +1381,7 @@ type remoteOptions []remote.Option
// ociContentConfigChanged evaluates the current spec with the observations
// of the artifact in the status to determine if artifact content configuration
// has changed and requires rebuilding the artifact.
func ociContentConfigChanged(obj *ociv1.OCIRepository) bool {
func ociContentConfigChanged(obj *sourcev1.OCIRepository) bool {
if !ptr.Equal(obj.Spec.Ignore, obj.Status.ObservedIgnore) {
return true
}
@ -1200,7 +1396,7 @@ func ociContentConfigChanged(obj *ociv1.OCIRepository) bool {
// Returns true if both arguments are nil or both arguments
// dereference to the same value.
// Based on k8s.io/utils/pointer/pointer.go pointer value equality.
func layerSelectorEqual(a, b *ociv1.OCILayerSelector) bool {
func layerSelectorEqual(a, b *sourcev1.OCILayerSelector) bool {
if (a == nil) != (b == nil) {
return false
}
@ -1209,3 +1405,24 @@ func layerSelectorEqual(a, b *ociv1.OCILayerSelector) bool {
}
return *a == *b
}
func filterTags(filter string) filterFunc {
return func(tags []string) ([]string, error) {
if filter == "" {
return tags, nil
}
match, err := regexp.Compile(filter)
if err != nil {
return nil, err
}
validTags := []string{}
for _, tag := range tags {
if match.MatchString(tag) {
validTags = append(validTags, tag)
}
}
return validTags, nil
}
}

File diff suppressed because it is too large Load Diff

View File

@ -43,9 +43,9 @@ import (
"k8s.io/client-go/tools/record"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
"github.com/distribution/distribution/v3/configuration"
dcontext "github.com/distribution/distribution/v3/context"
dockerRegistry "github.com/distribution/distribution/v3/registry"
_ "github.com/distribution/distribution/v3/registry/auth/htpasswd"
_ "github.com/distribution/distribution/v3/registry/storage/driver/inmemory"
@ -56,7 +56,6 @@ import (
"github.com/fluxcd/pkg/testserver"
sourcev1 "github.com/fluxcd/source-controller/api/v1"
sourcev1beta2 "github.com/fluxcd/source-controller/api/v1beta2"
"github.com/fluxcd/source-controller/internal/cache"
// +kubebuilder:scaffold:imports
)
@ -157,19 +156,23 @@ func setupRegistryServer(ctx context.Context, workspaceDir string, opts registry
// mock DNS to map example.com to 127.0.0.1.
// This is required because Docker enforces HTTP if the registry
// is hosted on localhost/127.0.0.1.
server.registryHost = fmt.Sprintf("example.com:%d", port)
// Disable DNS server logging as it is extremely chatty.
dnsLog := log.Default()
dnsLog.SetOutput(io.Discard)
server.dnsServer, err = mockdns.NewServerWithLogger(map[string]mockdns.Zone{
"example.com.": {
A: []string{"127.0.0.1"},
},
}, dnsLog, false)
if err != nil {
return nil, err
if opts.withTLS {
server.registryHost = fmt.Sprintf("example.com:%d", port)
// Disable DNS server logging as it is extremely chatty.
dnsLog := log.Default()
dnsLog.SetOutput(io.Discard)
server.dnsServer, err = mockdns.NewServerWithLogger(map[string]mockdns.Zone{
"example.com.": {
A: []string{"127.0.0.1"},
},
}, dnsLog, false)
if err != nil {
return nil, err
}
server.dnsServer.PatchNet(net.DefaultResolver)
} else {
server.registryHost = fmt.Sprintf("127.0.0.1:%d", port)
}
server.dnsServer.PatchNet(net.DefaultResolver)
config.HTTP.Addr = fmt.Sprintf(":%d", port)
config.HTTP.DrainTimeout = time.Duration(10) * time.Second
@ -217,24 +220,22 @@ func setupRegistryServer(ctx context.Context, workspaceDir string, opts registry
// setup logger options
config.Log.AccessLog.Disabled = true
config.Log.Level = "error"
logger := logrus.New()
logger.SetOutput(io.Discard)
dcontext.SetDefaultLogger(logrus.NewEntry(logger))
logrus.SetOutput(io.Discard)
dockerRegistry, err := dockerRegistry.NewRegistry(ctx, config)
registry, err := dockerRegistry.NewRegistry(ctx, config)
if err != nil {
return nil, fmt.Errorf("failed to create docker registry: %w", err)
}
// init test client
client, err := helmreg.NewClient(clientOpts...)
helmClient, err := helmreg.NewClient(clientOpts...)
if err != nil {
return nil, fmt.Errorf("failed to create registry client: %s", err)
}
server.registryClient = client
server.registryClient = helmClient
// Start Docker registry
go dockerRegistry.ListenAndServe()
go registry.ListenAndServe()
return server, nil
}
@ -272,7 +273,6 @@ func TestMain(m *testing.M) {
initTestTLS()
utilruntime.Must(sourcev1.AddToScheme(scheme.Scheme))
utilruntime.Must(sourcev1beta2.AddToScheme(scheme.Scheme))
testEnv = testenv.New(
testenv.WithCRDPath(filepath.Join("..", "..", "config", "crd", "bases")),
@ -451,3 +451,8 @@ func randStringRunes(n int) string {
func int64p(i int64) *int64 {
return &i
}
func logOCIRepoStatus(t *testing.T, obj *sourcev1.OCIRepository) {
sts, _ := yaml.Marshal(obj.Status)
t.Log(string(sts))
}

View File

@ -1,5 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOH/u9dMcpVcZ0+X9Fc78dCTj8SHuXawhLjhu/ej64WToAoGCCqGSM49
AwEHoUQDQgAEruH/kPxtX3cyYR2G7TYmxLq6AHyzo/NGXc9XjGzdJutE2SQzn37H
dvSJbH+Lvqo9ik0uiJVRVdCYD1j7gNszGA==
MHcCAQEEICJFvVFVBSL0EteniBRfI9M1tm9Vmh9CKv7dhvZSqtV6oAoGCCqGSM49
AwEHoUQDQgAE+EGQ9wZw/XIbyCwu7wvbzoGhpE2KtZwSUXboPEAgacfaqfgdT92D
If9qYie8umbgUymQnnqN8fRnT/wqqdBLDg==
-----END EC PRIVATE KEY-----

View File

@ -1,9 +1,9 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIBIDCBxgIBADAZMRcwFQYDVQQDEw5leGFtcGxlLmNvbSBDQTBZMBMGByqGSM49
AgEGCCqGSM49AwEHA0IABK7h/5D8bV93MmEdhu02JsS6ugB8s6PzRl3PV4xs3Sbr
RNkkM59+x3b0iWx/i76qPYpNLoiVUVXQmA9Y+4DbMxigSzBJBgkqhkiG9w0BCQ4x
MIIBHzCBxgIBADAZMRcwFQYDVQQDEw5leGFtcGxlLmNvbSBDQTBZMBMGByqGSM49
AgEGCCqGSM49AwEHA0IABPhBkPcGcP1yG8gsLu8L286BoaRNirWcElF26DxAIGnH
2qn4HU/dgyH/amInvLpm4FMpkJ56jfH0Z0/8KqnQSw6gSzBJBgkqhkiG9w0BCQ4x
PDA6MDgGA1UdEQQxMC+CCWxvY2FsaG9zdIILZXhhbXBsZS5jb22CD3d3dy5leGFt
cGxlLmNvbYcEfwAAATAKBggqhkjOPQQDAgNJADBGAiEAkw85nyLhJssyCYsaFvRU
EErhu66xHPJug/nG50uV5OoCIQCUorrflOSxfChPeCe4xfwcPv7FpcCYbKVYtGzz
b34Wow==
cGxlLmNvbYcEfwAAATAKBggqhkjOPQQDAgNIADBFAiEA1PxOWSIrmLb5IeejHvfx
AkjpamR/GTLhSzXlGv1hCmsCIDSeZL2OF5R5k2v4giXiB6GUfmawykGkO2fIG1kq
5l5V
-----END CERTIFICATE REQUEST-----

View File

@ -1,11 +1,11 @@
-----BEGIN CERTIFICATE-----
MIIBhzCCAS2gAwIBAgIUdsAtiX3gN0uk7ddxASWYE/tdv0wwCgYIKoZIzj0EAwIw
GTEXMBUGA1UEAxMOZXhhbXBsZS5jb20gQ0EwHhcNMjAwNDE3MDgxODAwWhcNMjUw
NDE2MDgxODAwWjAZMRcwFQYDVQQDEw5leGFtcGxlLmNvbSBDQTBZMBMGByqGSM49
AgEGCCqGSM49AwEHA0IABK7h/5D8bV93MmEdhu02JsS6ugB8s6PzRl3PV4xs3Sbr
RNkkM59+x3b0iWx/i76qPYpNLoiVUVXQmA9Y+4DbMxijUzBRMA4GA1UdDwEB/wQE
AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQGyUiU1QEZiMAqjsnIYTwZ
4yp5wzAPBgNVHREECDAGhwR/AAABMAoGCCqGSM49BAMCA0gAMEUCIQDzdtvKdE8O
1+WRTZ9MuSiFYcrEz7Zne7VXouDEKqKEigIgM4WlbDeuNCKbqhqj+xZV0pa3rweb
OD8EjjCMY69RMO0=
MIIBiDCCAS2gAwIBAgIUCRPU/Fa1nIWlk7TUejHGI+WKJFAwCgYIKoZIzj0EAwIw
GTEXMBUGA1UEAxMOZXhhbXBsZS5jb20gQ0EwHhcNMjUwNDIyMDcwNTAwWhcNMzAw
NDIxMDcwNTAwWjAZMRcwFQYDVQQDEw5leGFtcGxlLmNvbSBDQTBZMBMGByqGSM49
AgEGCCqGSM49AwEHA0IABPhBkPcGcP1yG8gsLu8L286BoaRNirWcElF26DxAIGnH
2qn4HU/dgyH/amInvLpm4FMpkJ56jfH0Z0/8KqnQSw6jUzBRMA4GA1UdDwEB/wQE
AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS+cS2gBCfSCltLUMNY0kG2
mj9zEDAPBgNVHREECDAGhwR/AAABMAoGCCqGSM49BAMCA0kAMEYCIQC33kO/m+ab
i/2dlkg7hab4jCkFkxV3fWiOP0lbrLIMYQIhAPOcHeXmGE32apXKoZ6IfGJdMtz1
3bkHYeqNs2qtpQ/5
-----END CERTIFICATE-----

View File

@ -1,5 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEICpqb1p1TH98yoFXEEt6JmWc/Snb8NaYyz8jfTOVDBLOoAoGCCqGSM49
AwEHoUQDQgAERjzob4CCuyv+cYPyTYCPHwGuqSNGNuX3UGWpxvzwEqjYEWiePlOz
eJLk4DWaVX8CmVakNLsK/EHnBv9ErG7QYQ==
MHcCAQEEIFVLYwGEhqLW/WYnsA9om6cSxcgVsKnwIWXc34DF7LpwoAoGCCqGSM49
AwEHoUQDQgAE5H76We32W5cQq8DRJT+pteyh53GUBiI5IbM+qVWgsCIFJEaSJKgs
mv1H7c3NhP292Pgr6vdWJACLQHzmpsVpmg==
-----END EC PRIVATE KEY-----

View File

@ -1,8 +1,8 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIBHDCBwwIBADAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEG
CCqGSM49AwEHA0IABEY86G+Agrsr/nGD8k2Ajx8BrqkjRjbl91Blqcb88BKo2BFo
nj5Ts3iS5OA1mlV/AplWpDS7CvxB5wb/RKxu0GGgSzBJBgkqhkiG9w0BCQ4xPDA6
MIIBGzCBwwIBADAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEG
CCqGSM49AwEHA0IABOR++lnt9luXEKvA0SU/qbXsoedxlAYiOSGzPqlVoLAiBSRG
kiSoLJr9R+3NzYT9vdj4K+r3ViQAi0B85qbFaZqgSzBJBgkqhkiG9w0BCQ4xPDA6
MDgGA1UdEQQxMC+CCWxvY2FsaG9zdIILZXhhbXBsZS5jb22CD3d3dy5leGFtcGxl
LmNvbYcEfwAAATAKBggqhkjOPQQDAgNIADBFAiAHmtr9fDDx5eyFfY7r5m8xA4Wh
Jm+TB6/czvXRNNOKzAIhAN7ln6BpneEm2oqIBGqvfc3pETC6jdGJxCfYw+X+7von
LmNvbYcEfwAAATAKBggqhkjOPQQDAgNHADBEAiB0px2gw2ICFz26zAajtJyoNHl+
inOXY5ohtzP4ag+NXQIgAbjIsOUuQ7JT31DdI6yCVfO014hHawtEsdV4rxTrQMA=
-----END CERTIFICATE REQUEST-----

View File

@ -1,13 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB7DCCAZKgAwIBAgIUPJmKtZ6CfSxybx2BSsVS5EVun0swCgYIKoZIzj0EAwIw
GTEXMBUGA1UEAxMOZXhhbXBsZS5jb20gQ0EwHhcNMjMwNzE5MTExMzAwWhcNMzMw
NzE2MTExMzAwWjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEG
CCqGSM49AwEHA0IABEY86G+Agrsr/nGD8k2Ajx8BrqkjRjbl91Blqcb88BKo2BFo
nj5Ts3iS5OA1mlV/AplWpDS7CvxB5wb/RKxu0GGjgbowgbcwDgYDVR0PAQH/BAQD
MIIB7DCCAZKgAwIBAgIUPH5zyEsXoFMCMkZaM2s6YtnoQcgwCgYIKoZIzj0EAwIw
GTEXMBUGA1UEAxMOZXhhbXBsZS5jb20gQ0EwHhcNMjUwNDIyMDcwNTAwWhcNMzUw
NDIwMDcwNTAwWjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMGByqGSM49AgEG
CCqGSM49AwEHA0IABOR++lnt9luXEKvA0SU/qbXsoedxlAYiOSGzPqlVoLAiBSRG
kiSoLJr9R+3NzYT9vdj4K+r3ViQAi0B85qbFaZqjgbowgbcwDgYDVR0PAQH/BAQD
AgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAA
MB0GA1UdDgQWBBTgAyCQoH/EJqz/nY5DJa/uvWWshzAfBgNVHSMEGDAWgBQGyUiU
1QEZiMAqjsnIYTwZ4yp5wzA4BgNVHREEMTAvgglsb2NhbGhvc3SCC2V4YW1wbGUu
Y29tgg93d3cuZXhhbXBsZS5jb22HBH8AAAEwCgYIKoZIzj0EAwIDSAAwRQIgKSJH
YvhKiXcUUzRoL6FsXQeAlhemSg3lD9se+BhRF8ECIQDx2UpWFLDe5NOPqhrcR1Sd
haFriAG8eR1yD3u3nJvY6g==
MB0GA1UdDgQWBBTqud4vpysQdb1/5K3RoDXvBdQGgzAfBgNVHSMEGDAWgBS+cS2g
BCfSCltLUMNY0kG2mj9zEDA4BgNVHREEMTAvgglsb2NhbGhvc3SCC2V4YW1wbGUu
Y29tgg93d3cuZXhhbXBsZS5jb22HBH8AAAEwCgYIKoZIzj0EAwIDSAAwRQIhAM0u
Eo6u3BDtw5bezhLa/THDy4QT63ktpAff9i/QJOErAiAifOvW7n5ZTLjjSnJ+dCtr
Avtupcg1WLyryhliqtNKhg==
-----END CERTIFICATE-----

View File

@ -1,5 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIKQbEXV6nljOHMmPrWVWQ+JrAE5wsbE9iMhfY7wlJgXOoAoGCCqGSM49
AwEHoUQDQgAE+53oBGlrvVUTelSGYji8GNHVhVg8jOs1PeeLuXCIZjQmctHLFEq3
fE+mGxCL93MtpYzlwIWBf0m7pEGQre6bzg==
MHcCAQEEIH19RQir/x9wHNAvHITu7/3Y4ckQ3GsNyEGYF3/nalheoAoGCCqGSM49
AwEHoUQDQgAEvqlooNIpRmCjv9yBzjqoyXZvcU8zo9npYm3HPX7TReYetrkkJh/P
6a5NDJhnWemcj9iZdm2kGTE7MCgGi4mRog==
-----END EC PRIVATE KEY-----

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