Compare commits

...

319 Commits
v1.2.2 ... main

Author SHA1 Message Date
Matheus Pimenta d7cba67d48
Merge pull request #1160 from abhijith-darshan/feat/gh_app_tls
Add support for mTLS to GitHub App transport
2025-08-18 10:16:40 +01:00
abhijith-darshan 4eae0d34da
Add support for mTLS to GitHub App transport
This commit ensures that if GitHub app secret data contains ca.crt then a TLS config with user provided custom ca is used in the underlying HTTP transports. The ca.crt in GitHub App secretRef is ignored if certSecretRef is also provided.

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>

(chore): keep Makefile in sync with other controllers

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>

(chore): use proper func naming format

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>

(chore): revert Makefile changes

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>

(chore): add get secret helper

This commit creates a getSecret helper func which can be used to resolve secret. createNotifier re-uses this helper func to extract and pass secrets down to other methods

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>

(chore): adds tls test cases

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>

(chore): remove debug logs

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>

(chore): adds documentation

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>

(chore): update docs with mTLS info

Signed-off-by: abhijith-darshan <abhijith.darshan@hotmail.com>
2025-08-18 11:03:43 +02:00
Matheus Pimenta c2a0355a85
Merge pull request #1161 from cappyzawa/feat/default-service-account-flag
[RFC-0010] Add default-service-account for lockdown
2025-08-17 17:54:24 +01:00
cappyzawa 10a6172536
[RFC-0010] Add default-service-account for lockdown
Add --default-service-account flag for multi-tenant workload identity
lockdown support. This flag sets the default service account name to
be used when .spec.serviceAccountName is not specified in resources.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-08-18 01:44:25 +09:00
Matheus Pimenta 5bd63a94e4
Merge pull request #1158 from cappyzawa/remove-tlsconfig-servername-pinning
Remove TLS ServerName pinning in TLS config creation
2025-08-14 19:12:31 +01:00
cappyzawa 5be0d2b66c
Remove TLS ServerName pinning in TLS config creation
Updates pkg/runtime dependency to v0.80.0 which removes the need for
the insecure parameter in TLSConfigFromSecretRef. This change removes
the forced ServerName pinning behavior that was causing TLS verification
issues, allowing for more flexible certificate validation.

The TLS config creation now relies on the standard Go TLS verification
process without forcing specific ServerName values, improving
compatibility with various certificate configurations.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-08-15 02:44:18 +09:00
Stefan Prodan 81c25cf90e
Merge pull request #1157 from fluxcd/remove-v1beta1-api
Remove deprecated APIs in group `notification.toolkit.fluxcd.io/v1beta1`
2025-08-11 17:54:48 +03:00
Stefan Prodan 660e7d2aea
Remove deprecated APIs in group `notification.toolkit.fluxcd.io/v1beta1`
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-08-08 15:11:48 +03:00
Matheus Pimenta 4d1c5032d1
Merge pull request #1154 from cappyzawa/feat/google-pubsub-workload-identity
[RFC-0010] Add object-level workload identity support to Google Pub/Sub notifier
2025-08-02 23:42:24 +01:00
cappyzawa 039cd81a6f
docs: enhance workload identity documentation for providers
Add comprehensive workload identity documentation for both Google Pub/Sub and Azure DevOps providers.
Include controller-level and object-level authentication patterns with feature gate requirements
and setup instructions for multi-tenant environments.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-08-03 07:35:37 +09:00
cappyzawa 43b3104555
Add object-level workload identity support to Google Pub/Sub notifier
Add support for object-level GCP workload identity authentication to enable
individual Providers to authenticate using their own ServiceAccount without
needing to manage JSON credentials. This extends beyond the existing
controller-level workload identity that is automatically handled by
Google libraries.

The implementation maintains backward compatibility by prioritizing
JSON credentials when both authentication methods are available.
Proxy support is also added following the Azure DevOps pattern
for consistency across notifiers.

This change is part of the broader effort to support multi-tenant
workload identity across Flux controllers (RFC-0010).

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-08-03 07:35:37 +09:00
Matheus Pimenta eddaf14754
Merge pull request #1150 from cappyzawa/docs/mtls-documentation-unification
docs: improve mTLS documentation structure and visibility
2025-07-29 15:45:53 +01:00
cappyzawa c2d0f5ec98
docs: improve mTLS documentation structure and visibility
Reorganize Certificate secret reference section to prioritize mutual TLS
authentication discovery and reduce user friction. The previous structure
buried mTLS information within generic certificate documentation, causing
users to miss this important security feature.

Move provider compatibility validation before configuration examples to
prevent wasted effort with unsupported providers. Create dedicated sections
for mTLS and CA-only authentication with complete examples and clear
explanations of field requirements.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-07-29 23:28:34 +09:00
Matheus Pimenta 4cc3f62a26
Merge pull request #1152 from fluxcd/am-basic-auth
Introduce proper basic auth support for Alertmanager Provider
2025-07-28 11:43:38 +01:00
Matheus Pimenta 3e69e745a3
Introduce proper basic auth support for Alertmanager Provider
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-07-28 11:32:41 +01:00
Matheus Pimenta 5d49b42544
Merge pull request #1151 from fluxcd/watch-label
Introduce label selector for watching Secrets referenced in Receivers
2025-07-27 23:11:38 +01:00
Matheus Pimenta fd7385ba15
Introduce label selector for watching Secrets referenced in Receivers
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-07-27 20:08:00 +01:00
Matheus Pimenta 8f4c7b2ccf
Merge pull request #1148 from cappyzawa/feat/datadog-sentry-runtime-secrets-integration
Add mTLS support for DataDog and Sentry notifiers
2025-07-22 11:41:02 +01:00
cappyzawa 67c049d3c7
Add mTLS support for DataDog and Sentry notifiers
These notifiers were using x509.CertPool which only supports CA
certificates for server authentication. By migrating to tls.Config,
they now support mutual TLS authentication with client certificates.

This enables secure communication in enterprise environments that
require client certificate authentication, completing the runtime/secrets
migration for these remaining notifiers.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-07-22 14:23:12 +09:00
Matheus Pimenta 326c6bcf6e
Merge pull request #1147 from cappyzawa/pkg-runtime-v0.75.0-migration
Fix missing TLS ServerName in Provider notifications
2025-07-22 04:51:33 +01:00
cappyzawa f333296240
Fix missing TLS ServerName in Provider notifications
Updates pkg/runtime/secrets to v0.75.0 which adds targetURL and insecure
parameters to TLS functions. This resolves ServerName regression that
caused TLS handshake failures in virtual hosting environments.

The Provider API has no insecure field, so certificates are always
verified (insecure=false). This maintains secure-by-default behavior
and is consistent with the original pre-pkg/runtime/secrets implementation.

All 17+ notification providers automatically benefit from proper ServerName
setting through the centralized TLS configuration in createNotifier().

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-07-22 12:41:05 +09:00
Matheus Pimenta 4496c6e0f2
Merge pull request #1146 from cappyzawa/feat/git-notifiers-runtime-secrets-integration
Add mTLS support for git-based notifiers
2025-07-19 13:51:36 +01:00
cappyzawa 0c1801906a
Add mTLS support for git-based notifiers
Replace x509.CertPool with tls.Config across all Git-based notifiers
(GitHub, GitLab, Gitea, Bitbucket, Azure DevOps, GitHub Dispatch) to
enable mutual TLS authentication for enterprise environments.

Adopt runtime/secrets AuthMethodsFromSecret for standardized handling
of Bearer tokens, basic auth, and token auth while maintaining full
backward compatibility with existing Secret formats.

This unifies authentication processing across Git-based providers and
adds mTLS capability without changing API surface or breaking existing
deployments.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-07-19 08:31:47 +09:00
Matheus Pimenta 888412e8c5
Merge pull request #1145 from dipti-pai/ado-oidc-support
[RFC-0010] Azure OIDC integration updates for Azure DevOps and Azure EventHub
2025-07-18 16:16:09 +01:00
Dipti Pai dc8e92c119 Azure OIDC integration updates:
- Azure DevOps commit status update using Managed Identity.
- Migrate Azure Event Hubs to new ProducerClient (azeventhubs) sdk
- Unit Tests and doc update

Signed-off-by: Dipti Pai <diptipai89@outlook.com>
2025-07-18 07:58:13 -07:00
Matheus Pimenta a22d67edbb
Merge pull request #1141 from cappyzawa/feat/optional-address-field
Make address field optional for providers that generate URLs internally
2025-07-15 16:32:09 +01:00
cappyzawa 955d24142c
Make address field optional for providers that generate URLs internally
This change removes the generic address validation from event_handlers.go
that was preventing address-optional providers from functioning without
specifying a dummy address value. Some providers generate URLs internally
and don't require external address configuration.

This allows providers that generate URLs internally to work without
requiring dummy address values in the provider configuration.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-07-16 00:13:29 +09:00
Matheus Pimenta e8a909fac7
Merge pull request #1143 from fluxcd/upgrade-auth
Upgrade Kubernetes to 1.33.2
2025-07-14 17:06:13 +01:00
Matheus Pimenta febff88be7
Upgrade Kubernetes to 1.33.2
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-07-14 16:45:44 +01:00
Matheus Pimenta 5bea87e16b
Merge pull request #1142 from cappyzawa/fix/double-secret-fetch
Fix double secret fetching in BasicAuth processing
2025-07-10 11:50:12 +01:00
cappyzawa a8c2fc0759
Fix double secret fetching in BasicAuth processing
This commit addresses the performance issue where spec.secretRef
was being fetched twice - once in extractAuthFromSecret and again
in secrets.BasicAuthFromSecret. The fix moves BasicAuth processing
directly into extractAuthFromSecret using the already-fetched
secret data, eliminating the redundant API call.

This aligns with the special nature of spec.secretRef that contains
multiple authentication methods and follows the advice to not use
runtime/secrets for special requirements as discussed in flux2#5433.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-07-10 19:38:33 +09:00
Stefan Prodan 6e18c487d7
Merge pull request #1139 from cappyzawa/feat/basicauth-runtime-secrets
Unify BasicAuth processing using pkg/runtime/secrets
2025-07-10 11:05:01 +03:00
cappyzawa d1c85df902
Unify BasicAuth processing using pkg/runtime/secrets
This commit refactors the createNotifier function to use
pkg/runtime/secrets.BasicAuthFromSecret for standardized BasicAuth
handling while maintaining token-first authentication precedence.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-07-10 16:56:33 +09:00
Stefan Prodan 9e150256c7
Merge pull request #1140 from cappyzawa/feat/telegram-proxy-support
Add proxy support to Telegram notifier
2025-07-08 16:31:38 +03:00
cappyzawa e4160c509c
fixup! Add proxy support to Telegram notifier
Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-07-08 21:42:27 +09:00
cappyzawa fc4adfd030
Add proxy support to Telegram notifier
Replace shoutrrr with direct Telegram Bot API calls to enable proxy
configuration through postMessage function.

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-07-08 00:15:02 +09:00
Matheus Pimenta 3f4e962c83
Merge pull request #1137 from cappyzawa/feat/mtls-postmessage-notifiers
Add mTLS support for postMessage-based notifiers
2025-07-06 12:26:54 +01:00
cappyzawa 98ecf2de79
Add mTLS support for postMessage-based notifiers
- Implement mTLS support for 10 postMessage notifiers
- Unify constructor signatures with tlsConfig parameter
- Make TLSConfig field public for consistency
- Update factory functions and fuzz tests
- Add mTLS test cases
- Replace CertPool with TLSConfig using runtime/secrets

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-07-03 21:39:16 +09:00
Matheus Pimenta a3e6dd6a10
Merge pull request #1133 from cappyzawa/feat/proxy-secret-ref
Add ProxySecretRef field to Provider API
2025-06-27 15:57:40 +01:00
cappyzawa 8858332c27
Add ProxySecretRef field to Provider API
Introduce spec.proxySecretRef to enable secure proxy configuration
through dedicated Secrets. This provides a more secure alternative
to the deprecated spec.proxy field and secret proxy key.

The new field integrates with runtime/secrets for unified proxy
handling and maintains backward compatibility. Deprecation warnings
are implemented for existing proxy configuration methods.

Proxy priority: ProxySecretRef > secret proxy key > spec.proxy

Signed-off-by: cappyzawa <cappyzawa@gmail.com>
2025-06-27 23:31:02 +09:00
Stefan Prodan 2503bda903
Merge pull request #1128 from fluxcd/fix-docs-markdown
Fix links in provider API doc
2025-05-29 17:17:07 +03:00
Stefan Prodan fc126284ab
Fix links in provider API doc
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-29 17:09:54 +03:00
Stefan Prodan 8f207d65db
Merge pull request #1127 from fluxcd/dependabot-up
Update dependabot config
2025-05-28 16:17:48 +03:00
Stefan Prodan 61f24e3376
Update dependabot config
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-28 16:04:13 +03:00
Matheus Pimenta 3f4ba79594
Merge pull request #1123 from fluxcd/update-labels
Add 1.6.x release label
2025-05-28 08:30:32 +01:00
Matheus Pimenta d65c81d035
Add 1.6.x release label
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-28 08:23:38 +01:00
Matheus Pimenta 47b95d86a3
Merge pull request #1122 from fluxcd/release/v1.6.x
Release/v1.6.x
2025-05-27 17:29:48 +01:00
Matheus Pimenta 3a6de1fcef
Merge pull request #1121 from fluxcd/release-v1.6.0
Release v1.6.0
2025-05-27 15:26:44 +01:00
Matheus Pimenta a52f071bb9
Release v1.6.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-27 15:13:55 +01:00
Matheus Pimenta 0e0e912182
Add changelog entry for v1.6.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-27 15:12:52 +01:00
Matheus Pimenta 7383fe8be5
Merge pull request #1108 from larhauga/fix-crossnamespaceobjectref-maxlength
CrossNamespaceObjectReference: Fix MaxLength validation to k8s max 253 char
2025-05-27 10:44:16 +01:00
Lars Haugan 2284a0db5a
CrossNamespaceObjectReference: Fix MaxLength validation to kubernetes max size of 253
Signed-off-by: Lars Haugan <lars.haugan@sparebank1.no>
2025-05-27 10:34:25 +01:00
Stefan Prodan d32f5e26cc
Merge pull request #1101 from fluxcd/dependabot/github_actions/ci-4c7c75f92f
build(deps): bump the ci group across 1 directory with 14 updates
2025-05-27 12:22:33 +03:00
dependabot[bot] b416d68479
build(deps): bump the ci group across 1 directory with 14 updates
Bumps the ci group with 14 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` |
| [actions/cache](https://github.com/actions/cache) | `4.2.0` | `4.2.3` |
| [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` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `6.13.0` | `6.16.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 `actions/cache` from 4.2.0 to 4.2.3
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](1bd1e32a3b...5a3ec84eff)

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 `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 `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: actions/cache
  dependency-version: 4.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  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: docker/build-push-action
  dependency-version: 6.16.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-05-27 09:17:55 +00:00
Matheus Pimenta 3842f0c471
Merge pull request #1120 from fluxcd/rfc-0010-docs
[RFC-0010] Link workload identity docs to complete guide
2025-05-27 09:28:20 +01:00
Matheus Pimenta f2e2340807
[RFC-0010] Link workload identity docs to complete guide
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-26 23:42:01 +01:00
Matheus Pimenta 01dfe1208a
Merge pull request #1119 from fluxcd/upgrade-deps
Update dependencies
2025-05-25 16:58:51 +01:00
Matheus Pimenta 0464717037
Update dependencies
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-25 14:59:39 +01:00
Matheus Pimenta f3065c67b3
Merge pull request #1086 from ordovicia/fix-1048
Fix Slack `chat.postMessage` error handling
2025-05-24 14:44:39 +01:00
Hidehito Yabuuchi 882383e44c Fix Slack chat.postMessage error handling
Signed-off-by: Hidehito Yabuuchi <hdht.ybuc@gmail.com>
2025-05-24 18:23:45 +09:00
Stefan Prodan 8dd496a132
Merge pull request #1118 from fluxcd/controller-runtime-v0.21.0
Update controller-runtime to v0.21.0
2025-05-23 17:43:17 +02:00
Stefan Prodan de484cd447
Update controller-runtime to v0.21.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-05-23 18:28:14 +03:00
Matheus Pimenta b906831c5e
Merge pull request #1116 from fluxcd/rfc-0010-feature-gate
[RFC-0010] Introduce feature gate
2025-05-23 07:59:11 +01:00
Matheus Pimenta e95f8d5b38
[RFC-0010] Introduce feature gate
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-19 14:15:57 +01:00
Matheus Pimenta d78779e80b
Merge pull request #1113 from fluxcd/upgrade-deps
Upgrade fluxcd/pkg auth and git
2025-05-07 18:24:56 +01:00
Matheus Pimenta 637d55d0b9
Upgrade fluxcd/pkg auth and git
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-07 18:17:38 +01:00
Matheus Pimenta 99c6dbb70f
Merge pull request #1112 from fluxcd/fix-provider-state-machine
Reintroduce default state machine for Provider controller
2025-05-07 12:51:22 +01:00
Matheus Pimenta c32f9e1559
Reintroduce default state machine for Provider controller
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-05 22:00:46 +01:00
Matheus Pimenta f5ddc97108
Merge pull request #1106 from dipti-pai/azeventhub-mi-support
[RFC-0010] Implement managed identity support for Azure Event Hub provider
2025-05-05 20:39:45 +01:00
Dipti Pai 0beb3d02f7 Managed Identity support for Azure Event Hubs. Changes include -
- If authentication token is not specified in provider, attempt to get the token using workload identity.
= Add new field .spec.serviceAccountName to support multi-tenant workload identity as defined in RFC-0010 to use an identity with a service account other than the notification-controller.
- Use proxy to get the token if specified in provider spec.
- Cache the tokens if enabled in the notification controller options.
- If address has SAS connection string, use that for authentication, this takes priority over token-authentication
- If static JWT token is specified in the secret reference, use it for authentication, this takes priority over workload identity-acquired token.
- Update RBAC for notification-controller to be able to create service token requests.
- Add unit tests for the 3 authentication mechanisms (SAS, JWT, managed identity).
- Add documentation for using single-tenant and multi-tenant approaches of workload identity with azureeventhub provider.
- Add operation post to github helpers and provider controller for cache event metrics
- Enable token cache by default.

Signed-off-by: Dipti Pai <diptipai89@outlook.com>

review comments

Signed-off-by: Dipti Pai <diptipai89@outlook.com>

enable cache by default

Signed-off-by: Dipti Pai <diptipai89@outlook.com>
2025-05-05 12:03:52 -07:00
Matheus Pimenta 5dfaa1a5ef
Merge pull request #1109 from fluxcd/delete-cache-entries
Delete cache entries on provider object deletion
2025-05-02 13:09:11 +01:00
Matheus Pimenta 4d3a53ac86
Delete cache entries on provider object deletion
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-05-02 13:00:17 +01:00
Stefan Prodan 5b72532bb1
Merge pull request #1104 from fluxcd/k8s-1.33
Update to Kubernetes 1.33.0 and Go 1.24.0
2025-04-29 15:56:10 +03:00
Stefan Prodan 3f7486168e
Update to Kubernetes 1.33.0 and Go 1.24.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-04-29 15:45:24 +03:00
Stefan Prodan e970526b1e
Merge pull request #1087 from sdreger/geature/gitea-proxy-url
feat: add `proxyURL` support to Gitea notifier
2025-04-09 17:57:45 +03:00
Sergey Dreger 0338a311f4 feat: add 'proxyURL' support to Gitea notifier
Signed-off-by: Sergey Dreger <sergey.dreger@gmail.com>
2025-04-09 15:06:49 +03:00
Matheus Pimenta 671f7dd377
Merge pull request #1093 from fluxcd/proxy-log
Sanitize proxy error logging
2025-04-08 10:53:12 +01:00
Matheus Pimenta fdeab17bff
Sanitize proxy error logging
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-04-08 10:37:45 +01:00
Stefan Prodan f313afa287
Merge pull request #1084 from sdreger/bugfix/1083/gitea-tls-error
fix: pass 'certPool' to Gitea client on creation
2025-03-24 09:29:19 +02:00
Sergey Dreger 30d8d01687 fix: pass 'certPool' to Gitea client on creation
It is required when a custom CA is passed, otherwise the
gitea.NewClient() call will fail with the 'tls: failed to verify
certificate: x509: certificate signed by unknown authority' error.
Because the current version of Gitea SDK performs a call to the
'/api/v1/version' endpoint during a new client creation, so the
'certPool' must be passed when creating the client.

Resolves: #1083
Signed-off-by: Sergey Dreger <sergey.dreger@gmail.com>
2025-03-23 17:17:41 +02:00
Matheus Pimenta d62be26a3f
Merge pull request #1058 from dipti-pai/github-app-auth
[RFC-007] GitHub App authentication support for github and github-dispatch providers
2025-03-21 16:47:27 +00:00
Dipti Pai bc7166d419 [RFC-007] GitHub App authentication support for github and github-dispatch providers.
- Add providerOpts in notifier to configure authentication options for various providers.
- If token/password are not set to PAT, check if github app details are configured in secret and if found; authenticate using github-app by retrieving app installation token.
- If proxy is specified in the provider spec OR in the secret, configure github app authentication to fetch the installation token over the proxy.
- Add unit tests for providers.
- Update documentation describing the usage of github app authentication with the providers.
- Add token cache to notification controller to cache and re-use the tokens.

Signed-off-by: Dipti Pai <diptipai89@outlook.com>
2025-03-20 14:18:10 -07:00
Matheus Pimenta c476965793
Merge pull request #1077 from v1km4n/docs1063
Update docs to include Telegram forum configuration
2025-03-19 12:41:46 +00:00
Alexey Orlov 1a9858d725 updated docs to include telegram forum chat conf
Signed-off-by: Alexey Orlov <orlov.aa@selectel.com>
Signed-off-by: Alexey Orlov <v1km4n@ya.ru>
2025-03-19 15:15:34 +03:00
Matheus Pimenta e2eac40c33
Merge pull request #1068 from kathleenfrench/kfrench/provider-commit-expr
feat: support CEL string expressions for custom commit statuses in v1beta3 provider type
2025-03-18 19:08:26 +00:00
kathleen french 1967bc0c74 feat: support CEL expressions to construct commit statuses for v1beta3 provider types
Signed-off-by: kathleen french <kfrench@groq.com>
2025-03-14 08:53:55 -04:00
Matheus Pimenta 2763e548bd
Merge pull request #1045 from fluxcd/update-labels
Add 1.5.x release label
2025-02-13 16:05:48 +00:00
Matheus Pimenta cc51c36926
Add 1.5.x release label
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-13 15:55:06 +00:00
Matheus Pimenta 543a2b0da2
Merge pull request #1044 from fluxcd/release/v1.5.x
Release/v1.5.x
2025-02-13 15:52:30 +00:00
Matheus Pimenta 85d897c59d
Merge pull request #1043 from fluxcd/release-v1.5.0
Release v1.5.0
2025-02-13 15:28:56 +00:00
Matheus Pimenta ff00d11dae
Release v1.5.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-13 14:44:11 +00:00
Matheus Pimenta 2b3ccd7ddf
Add changelog entry for v1.5.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-13 14:44:10 +00:00
Stefan Prodan 384ae9889f
Merge pull request #1042 from fluxcd/dependabot/go_modules/go-deps-80f865df1d
build(deps): bump the go-deps group across 1 directory with 2 updates
2025-02-12 23:19:19 +02:00
dependabot[bot] 2295fcf8e2
build(deps): bump the go-deps group across 1 directory with 2 updates
Bumps the go-deps group with 2 updates in the / directory: [github.com/fluxcd/pkg/ssa](https://github.com/fluxcd/pkg) and [google.golang.org/api](https://github.com/googleapis/google-api-go-client).


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

Updates `google.golang.org/api` from 0.218.0 to 0.221.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.218.0...v0.221.0)

---
updated-dependencies:
- dependency-name: github.com/fluxcd/pkg/ssa
  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>
2025-02-12 20:25:11 +00:00
Matheus Pimenta b64453ba2f
Merge pull request #1041 from fluxcd/cel-fixes
Improvements after CEL resource filtering
2025-02-12 20:23:24 +00:00
Matheus Pimenta 3dc0b66390
Improvements after CEL resource filtering
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-12 16:46:59 +00:00
Matheus Pimenta 022b97cabe
Merge pull request #1040 from fluxcd/grafana-annotations
Add involved object reference as annotations for the grafana provider
2025-02-12 15:53:46 +00:00
Matheus Pimenta 7a34aee2bd
Add involved object reference as annotations for the grafana provider
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-12 14:10:13 +00:00
Matheus Pimenta 7e14e41f0f
Merge pull request #953 from swoehrl-mw/clarify-gitlab-provider-usage
Clarify gitlab notification provider usage
2025-02-12 12:22:17 +00:00
Sebastian Woehrl b72ecab696 Clarify gitlab provider usage
Currrent gitlab API does not accept project name for setting git commit
status, a project ID must be used.

Signed-off-by: Sebastian Woehrl <sebastian.woehrl@maibornwolff.de>
2025-02-12 11:57:51 +00:00
Matheus Pimenta 5df5b78783
Merge pull request #1039 from fluxcd/missing-return-statement
Fix add missing return statement and a few style issues
2025-02-12 11:57:28 +00:00
Matheus Pimenta c4eed6b243
Fix add missing return statement and a few style issues
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-12 11:17:50 +00:00
Matheus Pimenta 83ed0c59e5
Merge pull request #1037 from fluxcd/upgrade-deps
Upgrade pkg/runtime
2025-02-11 12:22:16 +00:00
Matheus Pimenta d52c41e0c4
Upgrade pkg/runtime
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-11 11:53:09 +00:00
Stefan Prodan 652d3d331e
Merge pull request #1036 from fluxcd/dependabot/go_modules/go-deps-58a8740459
build(deps): bump the go-deps group across 1 directory with 9 updates
2025-02-11 10:59:26 +02:00
dependabot[bot] 232e66c985
build(deps): bump the go-deps group across 1 directory with 9 updates
Bumps the go-deps group with 8 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [cloud.google.com/go/pubsub](https://github.com/googleapis/google-cloud-go) | `1.45.3` | `1.47.0` |
| [github.com/DataDog/datadog-api-client-go/v2](https://github.com/DataDog/datadog-api-client-go) | `2.34.0` | `2.35.0` |
| [github.com/fluxcd/pkg/ssa](https://github.com/fluxcd/pkg) | `0.44.0` | `0.45.0` |
| [github.com/google/cel-go](https://github.com/google/cel-go) | `0.23.1` | `0.23.2` |
| [github.com/nats-io/nats.go](https://github.com/nats-io/nats.go) | `1.38.0` | `1.39.0` |
| [gitlab.com/gitlab-org/api/client-go](https://gitlab.com/gitlab-org/api/client-go) | `0.121.0` | `0.122.0` |
| [golang.org/x/oauth2](https://github.com/golang/oauth2) | `0.25.0` | `0.26.0` |
| [golang.org/x/text](https://github.com/golang/text) | `0.21.0` | `0.22.0` |



Updates `cloud.google.com/go/pubsub` from 1.45.3 to 1.47.0
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/pubsub/v1.45.3...pubsub/v1.47.0)

Updates `github.com/DataDog/datadog-api-client-go/v2` from 2.34.0 to 2.35.0
- [Release notes](https://github.com/DataDog/datadog-api-client-go/releases)
- [Changelog](https://github.com/DataDog/datadog-api-client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/DataDog/datadog-api-client-go/compare/v2.34.0...v2.35.0)

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

Updates `github.com/google/cel-go` from 0.23.1 to 0.23.2
- [Release notes](https://github.com/google/cel-go/releases)
- [Commits](https://github.com/google/cel-go/compare/v0.23.1...v0.23.2)

Updates `github.com/nats-io/nats.go` from 1.38.0 to 1.39.0
- [Release notes](https://github.com/nats-io/nats.go/releases)
- [Commits](https://github.com/nats-io/nats.go/compare/v1.38.0...v1.39.0)

Updates `gitlab.com/gitlab-org/api/client-go` from 0.121.0 to 0.122.0
- [Release notes](https://gitlab.com/gitlab-org/api/client-go/tags)
- [Commits](https://gitlab.com/gitlab-org/api/client-go/compare/v0.121.0...v0.122.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/text` from 0.21.0 to 0.22.0
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.21.0...v0.22.0)

Updates `google.golang.org/api` from 0.211.0 to 0.218.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.211.0...v0.218.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/pubsub
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/DataDog/datadog-api-client-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/fluxcd/pkg/ssa
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/google/cel-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/nats-io/nats.go
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: gitlab.com/gitlab-org/api/client-go
  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/text
  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>
2025-02-11 08:41:55 +00:00
Stefan Prodan 2eb3c35ec3
Merge pull request #948 from bigkevmcd/cel-resource-filtering
Implement Receiver resource filtering with CEL
2025-02-11 10:39:28 +02:00
Kevin McDermott 28deef923f
Implement Receiver resource filtering with CEL
Signed-off-by: Kevin McDermott <bigkevmcd@gmail.com>
Co-authored-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-02-10 16:21:50 +00:00
Stefan Prodan 9b83efa21f
Merge pull request #1032 from fluxcd/dependabot/github_actions/ci-05f176d660
build(deps): bump the ci group across 1 directory with 3 updates
2025-02-09 11:42:55 +02:00
dependabot[bot] e68bc3b7e3
build(deps): bump the ci group across 1 directory with 3 updates
Bumps the ci group with 3 updates in the / directory: [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action), [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) and [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer).


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

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

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

---
updated-dependencies:
- 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: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-07 07:08:21 +00:00
Stefan Prodan f4001109db
Merge pull request #1027 from fluxcd/up-deps-api
Update API dependencies
2025-02-01 11:04:19 +02:00
Stefan Prodan ed7f6adac6
Update API dependencies
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2025-02-01 10:47:32 +02:00
Stefan Prodan dcbf4a7f73
Merge pull request #1025 from fluxcd/dependabot/github_actions/ci-fbaebe1433
build(deps): bump the ci group across 1 directory with 12 updates
2025-02-01 10:17:31 +02:00
dependabot[bot] b7cef8af24
build(deps): bump the ci group across 1 directory with 12 updates
Bumps the ci group with 12 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4.2.0` | `4.2.2` |
| [actions/setup-go](https://github.com/actions/setup-go) | `5.0.2` | `5.3.0` |
| [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) | `3.2.0` | `3.3.0` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3.6.1` | `3.8.0` |
| [actions/cache](https://github.com/actions/cache) | `4.0.2` | `4.2.0` |
| [helm/kind-action](https://github.com/helm/kind-action) | `1.10.0` | `1.12.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `5.5.1` | `5.6.1` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `6.7.0` | `6.13.0` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `3.6.0` | `3.7.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.9` | `3.28.8` |



Updates `actions/checkout` from 4.2.0 to 4.2.2
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](d632683dd7...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 `docker/setup-qemu-action` from 3.2.0 to 3.3.0
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](49b3bc8e6b...53851d1459)

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

Updates `actions/cache` from 4.0.2 to 4.2.0
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](0c45773b62...1bd1e32a3b)

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/metadata-action` from 5.5.1 to 5.6.1
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](8e5442c4ef...369eb591f4)

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 `sigstore/cosign-installer` from 3.6.0 to 3.7.0
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](4959ce089c...dc72c7d5c4)

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.9 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](461ef6c76d...dd746615b3)

---
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-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: actions/cache
  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/metadata-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: 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-01 07:49:38 +00:00
Stefan Prodan 1aea3c2275
Merge pull request #1023 from fluxcd/upgrade-deps
Update dependencies
2025-02-01 09:19:04 +02:00
Matheus Pimenta 7b8535bce0
Update dependencies
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-01-31 17:43:49 +00:00
Matheus Pimenta d9bb201c36
Merge pull request #1010 from mo-rieger/mrieger/1009
fix: adding of duplicate commit statuses in gitlab
2025-01-31 17:23:33 +00:00
Moritz Rieger 764123c6d3 fix: adding of duplicate commit statuses in gitlab
RESOLVES #1009

Signed-off-by: Moritz Rieger <moritz.rieger@exaring.de>
2025-01-31 09:00:27 +01:00
Matheus Pimenta 7ee7239ff3
Merge pull request #1022 from fluxcd/receiver
Enforce namespace check on receiver
2025-01-30 10:41:17 +00:00
Matheus Pimenta b362a258fe
Enforce namespace check on receiver
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-01-30 10:27:01 +00:00
Matheus Pimenta 8235026aa1
Merge pull request #1021 from d4rkfella/main
Add support for Bearer Token authentication to Provider `alertmanager`
2025-01-26 22:02:09 +00:00
Georgi Panov ecc3395615 Add support for Bearer Token authentication to Provider alertmanager
Signed-off-by: Georgi Panov <77702912+d4rkfella@users.noreply.github.com>
Signed-off-by: Darkfella91 <darkfella91@gmail.com>

Update alertmanager_test.go

Signed-off-by: Georgi Panov <77702912+d4rkfella@users.noreply.github.com>
Signed-off-by: Darkfella91 <darkfella91@gmail.com>

Update alertmanager_fuzz_test.go

Signed-off-by: Georgi Panov <77702912+d4rkfella@users.noreply.github.com>
Signed-off-by: Darkfella91 <darkfella91@gmail.com>

Update factory.go

Signed-off-by: Georgi Panov <77702912+d4rkfella@users.noreply.github.com>
Signed-off-by: Darkfella91 <darkfella91@gmail.com>

Update factory.go

Signed-off-by: Darkfella91 <darkfella91@gmail.com>

Fix a mistake with the last commit to update the docs

Signed-off-by: Darkfella91 <darkfella91@gmail.com>

Fix another formatting issue

Signed-off-by: Darkfella91 <darkfella91@gmail.com>

Screwed up my previous commit so implementing the suggested changes again and fixed formatting for the structs

Signed-off-by: Darkfella91 <darkfella91@gmail.com>

Tried to use better wording, to outline that authentication is optional

Signed-off-by: Darkfella91 <darkfella91@gmail.com>

Another small change to the explanation for bearer token authentication

Signed-off-by: Darkfella91 <darkfella91@gmail.com>

Fix incorrect article usage and the configured address example as suggested

Signed-off-by: Darkfella91 <darkfella91@gmail.com>
2025-01-26 23:43:03 +02:00
Matheus Pimenta fa7d9f260c
Merge pull request #1019 from fluxcd/origin-revision
Add subsection for Git providers supporting commit status updates
2025-01-23 11:22:08 +00:00
Matheus Pimenta 9dc18128c8
Add subsection for Git providers supporting commit status updates
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-01-23 10:33:56 +00:00
Matheus Pimenta a2eb8ea3be
Merge pull request #1018 from fluxcd/origin-revision
Add support for MetaOriginRevisionKey from the Event API
2025-01-21 08:53:15 +00:00
Matheus Pimenta e0b98ca519
Add support for MetaOriginRevisionKey from the Event API
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-01-21 08:28:31 +00:00
Matheus Pimenta 5469e2a1f0
Merge pull request #1017 from vflaux/teams_adaptive_cards_full_width
msteams notifier: adaptive cards full width
2025-01-15 11:06:32 +00:00
Valentin Flaux 56c5a5a4bc
msteams notifier: adaptive cards full width
Configure the adaptive card to expand and make full use of extra canvas
space in teams.

Signed-off-by: Valentin Flaux <38909103+vflaux@users.noreply.github.com>
2025-01-13 16:50:46 +01:00
Matheus Pimenta d455ac69fe
Merge pull request #1014 from fluxcd/rfc-0008
[RFC-0008] Custom Event Metadata from Annotations
2025-01-10 14:16:47 +00:00
Matheus Pimenta 939a16620f
[RFC-0008] Custom Event Metadata from Annotations
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2025-01-10 13:19:15 +00:00
Stefan Prodan 51db46dfee
Merge pull request #1016 from erikgb/gitlab-client-migration
Migrate to `gitlab.com/gitlab-org/api/client-go`
2025-01-09 11:21:50 +02:00
Erik Godding Boye f3438f7709
Migrate to gitlab.com/gitlab-org/api/client-go
Signed-off-by: Erik Godding Boye <egboye@gmail.com>
2025-01-03 13:36:13 +01:00
Stefan Prodan 8b1d9a1e0b
Merge pull request #1002 from fluxcd/k8s-1.32
Update dependencies to Kubernetes 1.32.0 and Go 1.23.0
2024-12-12 18:05:33 +02:00
Stefan Prodan a27f00191a
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:44:59 +02:00
Stefan Prodan 0667ba6629
Merge pull request #997 from hasithsen/main
Remove deprecated object metrics
2024-12-11 23:46:13 +02:00
hasithsen fb2adadc43 feat: Remove deprecated object metrics from controllers fluxcd/flux2#5083
Signed-off-by: hasithsen <sen.hasith@gmail.com>
2024-12-12 00:30:23 +05:30
Matheus Pimenta 276511a10a
Merge pull request #991 from fluxcd/matheuscscp-coremaintainer
Add @matheuscscp to core maintainers (remove from maintainers)
2024-12-05 12:18:17 +00:00
Matheus Pimenta effda518f4 Add @matheuscscp to core maintainers (remove from maintainers)
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-12-03 12:33:13 +00:00
Matheus Pimenta 632437c78e
Merge pull request #989 from fluxcd/matheuscscp-affiliation
Update matheuscscp affiliation
2024-11-27 18:10:53 +00:00
Matheus Pimenta e7a4503e51 Update matheuscscp affiliation
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-11-27 16:47:43 +00:00
Matheus Pimenta 2ebbf4803a
Merge pull request #937 from fluxcd/add-release-label
Add 1.4.x release label
2024-09-27 14:56:34 -03:00
Matheus Pimenta b6bdd3c2ce Add 1.4.x release label
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-09-27 14:41:37 -03:00
Matheus Pimenta 278fd67d9a
Merge pull request #938 from fluxcd/release/v1.4.x
Merge `release/v1.4.x` back to `main`
2024-09-27 14:40:45 -03:00
Matheus Pimenta 2525f2ce4e
Merge pull request #935 from fluxcd/release-v1.4.0
Release v1.4.0
2024-09-27 12:33:01 -03:00
Matheus Pimenta 52a4049be2 Release v1.4.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-09-27 15:34:18 +01:00
Matheus Pimenta 6fcfb6337c Add changelog entry for v1.4.0
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-09-27 11:27:23 -03:00
Stefan Prodan c43e6a93a6
Merge pull request #934 from fluxcd/go-github-v64
Update go-github to v63
2024-09-26 15:42:10 +03:00
Stefan Prodan b2ab2c2b07
Update go-github to v63
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-09-26 15:05:47 +03:00
Stefan Prodan 3acbe68075
Merge pull request #933 from fluxcd/dependabot/github_actions/ci-74c3fc3a14
build(deps): bump the ci group across 1 directory with 2 updates
2024-09-26 13:06:17 +03:00
dependabot[bot] 4997635afa
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.7 to 4.2.0
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](692973e3d9...d632683dd7)

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

---
updated-dependencies:
- dependency-name: actions/checkout
  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-09-26 08:14:56 +00:00
Stefan Prodan b4a9933f59
Merge pull request #932 from fluxcd/dependabot/go_modules/go-deps-d2f960fbdc
build(deps): bump the go-deps group across 1 directory with 7 updates
2024-09-26 11:02:04 +03:00
Stefan Prodan 519248ff29
Bump Go to 1.23.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-09-26 10:40:55 +03:00
Stefan Prodan 05be0bd5a1
Fix CDEvents example
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-09-26 10:40:37 +03:00
Sunny 3585b77c40 Fix CDEvents API usage and tests
Signed-off-by: Sunny <github@darkowlzz.space>
2024-09-25 23:31:05 +00:00
dependabot[bot] edb88c62fb
build(deps): bump the go-deps group across 1 directory with 7 updates
Bumps the go-deps group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [cloud.google.com/go/pubsub](https://github.com/googleapis/google-cloud-go) | `1.41.0` | `1.43.0` |
| [github.com/DataDog/datadog-api-client-go/v2](https://github.com/DataDog/datadog-api-client-go) | `2.29.0` | `2.30.0` |
| [github.com/cdevents/sdk-go](https://github.com/cdevents/sdk-go) | `0.3.2` | `0.4.1` |
| [github.com/getsentry/sentry-go](https://github.com/getsentry/sentry-go) | `0.28.1` | `0.29.0` |
| [github.com/slok/go-http-metrics](https://github.com/slok/go-http-metrics) | `0.12.0` | `0.13.0` |
| [github.com/xanzy/go-gitlab](https://github.com/xanzy/go-gitlab) | `0.107.0` | `0.109.0` |



Updates `cloud.google.com/go/pubsub` from 1.41.0 to 1.43.0
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/pubsub/v1.41.0...pubsub/v1.43.0)

Updates `github.com/DataDog/datadog-api-client-go/v2` from 2.29.0 to 2.30.0
- [Release notes](https://github.com/DataDog/datadog-api-client-go/releases)
- [Changelog](https://github.com/DataDog/datadog-api-client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/DataDog/datadog-api-client-go/compare/v2.29.0...v2.30.0)

Updates `github.com/cdevents/sdk-go` from 0.3.2 to 0.4.1
- [Release notes](https://github.com/cdevents/sdk-go/releases)
- [Changelog](https://github.com/cdevents/sdk-go/blob/main/.goreleaser.yaml)
- [Commits](https://github.com/cdevents/sdk-go/compare/v0.3.2...v0.4.1)

Updates `github.com/getsentry/sentry-go` from 0.28.1 to 0.29.0
- [Release notes](https://github.com/getsentry/sentry-go/releases)
- [Changelog](https://github.com/getsentry/sentry-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-go/compare/v0.28.1...v0.29.0)

Updates `github.com/slok/go-http-metrics` from 0.12.0 to 0.13.0
- [Release notes](https://github.com/slok/go-http-metrics/releases)
- [Changelog](https://github.com/slok/go-http-metrics/blob/master/CHANGELOG.md)
- [Commits](https://github.com/slok/go-http-metrics/compare/v0.12.0...v0.13.0)

Updates `github.com/xanzy/go-gitlab` from 0.107.0 to 0.109.0
- [Release notes](https://github.com/xanzy/go-gitlab/releases)
- [Changelog](https://github.com/xanzy/go-gitlab/blob/main/releases_test.go)
- [Commits](https://github.com/xanzy/go-gitlab/compare/v0.107.0...v0.109.0)

Updates `google.golang.org/api` from 0.192.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.192.0...v0.196.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/pubsub
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/DataDog/datadog-api-client-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/cdevents/sdk-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/getsentry/sentry-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/slok/go-http-metrics
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/xanzy/go-gitlab
  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-09-25 16:44:30 +00:00
Stefan Prodan 7d279b98f5
Merge pull request #931 from fluxcd/deps-update
Update fluxcd/pkg deps and k8s deps to 1.31.1
2024-09-25 19:42:21 +03:00
Sunny 7407570bee Update fluxcd/pkg and k8s deps to 1.31.1
Signed-off-by: Sunny <github@darkowlzz.space>
2024-09-25 14:54:23 +00:00
Stefan Prodan 46813c05b9
Merge pull request #925 from fluxcd/controller-gen-v0.16.1
Update controller-gen to v0.16.1
2024-09-13 12:50:45 +03:00
Stefan Prodan 7c15798aaa
Update controller-gen to v0.16.1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-09-13 10:39:03 +03:00
Matheus Pimenta 205cd17fb0
Merge pull request #920 from fluxcd/ms-adaptive-card-provider
Add MS Adaptive Card payload to `msteams` Provider
2024-09-12 11:16:18 -03:00
Matheus Pimenta e0cf7a1fc7 Add MS Adaptive Card payload to `msteams` Provider
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-09-12 11:00:51 -03:00
Stefan Prodan b81755d3f3
Merge pull request #841 from Kuzbekov/main
New flag to disable detailed metrics for path
2024-08-26 11:37:13 +03:00
Alexey Kuzbekov c85b1eb391
Change default behavior and naming
Signed-off-by: Alexey Kuzbekov <alexey@kuzbekov.me>
2024-08-24 15:29:29 +01:00
Alexey Kuzbekov ab58c812bd
New flag to disable detailed metrics for path
Flag detailed-metrics added to provide a way to disable exposing all accessed paths to the metrics and  prevent potential metrics cardinality explosion

Signed-off-by: Alexey Kuzbekov <alexey@kuzbekov.me>
2024-08-24 15:29:24 +01:00
Stefan Prodan 0871ad710a
Merge pull request #912 from fluxcd/dependabot/github_actions/ci-4516fd8e81
build(deps): bump the ci group across 1 directory with 3 updates
2024-08-22 13:02:56 +03:00
dependabot[bot] 42c2c79d2b
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 07:45:28 +00:00
Stefan Prodan 117bc7a91d
Merge pull request #903 from fluxcd/dependabot/github_actions/ci-3bac6ad11c
build(deps): bump the ci group across 1 directory with 8 updates
2024-08-15 16:36:07 +03:00
dependabot[bot] e6c53a0ae2
build(deps): bump the ci group across 1 directory with 8 updates
Bumps the ci group with 8 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [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/login-action](https://github.com/docker/login-action) | `3.2.0` | `3.3.0` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `6.2.0` | `6.7.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.11` | `3.26.2` |



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/login-action` from 3.2.0 to 3.3.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](0d4c9c5ea7...9780b0c442)

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

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.11 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](b611370bb5...429e197704)

---
updated-dependencies:
- 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/login-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: 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-15 13:02:48 +00:00
Stefan Prodan 478718ee48
Merge pull request #907 from fluxcd/go-1.23
Build with Go 1.23
2024-08-15 16:00:53 +03:00
Matheus Pimenta 7373cf4b62 Build with Go 1.23
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-08-15 09:36:36 -03:00
Matheus Pimenta d20a810652
Merge pull request #905 from fluxcd/upgrade-deps
Update dependencies to Kubernetes v1.31.0
2024-08-15 09:28:21 -03:00
Matheus Pimenta bd12728d0f Upgrade dependencies
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-08-15 09:03:03 -03:00
Max Jonas Werner 4e01193860
Merge pull request #894 from fluxcd/fix-telegram-test
Fix telegram test flake
2024-08-01 22:13:37 +02:00
Max Jonas Werner f9610afa8d
Fix telegram test flake
The test would sometimes fail because the metadata lines are built
from a map and map iteration order in Go is non-deterministic.
Therefore, the lines may be ordered differently between different test
runs.

Now, the test sorts the metadata lines of the telegram message so they
are always the same and only then verifies the expected output.

closes #867

Signed-off-by: Max Jonas Werner <max.werner@associmates.eu>
2024-08-01 15:50:58 +02:00
Stefan Prodan fa93b71722
Merge pull request #879 from octo/fix-conditions-usage
Fix incorrect use of format strings with the `conditions` package.
2024-07-12 10:51:45 +03:00
Florian Forster 1f4cdff23c
Fix incorrect use of format strings with the `conditions` package.
The `Mark…` 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 as a format string by the `fmt` package. This leads to
issues when the message contains percent signs, e.g. URL-encoded values.

This PR adds a format string and shortens `err.Error()` to `err`, which yields
the same output.

This change is identical in principle to fluxcd/source-controller#1529.

Signed-off-by: Florian Forster <fforster@gitlab.com>
2024-07-12 09:18:59 +02:00
Stefan Prodan 86f2a6d20f
Merge pull request #873 from ThomasDangleterre/stringdata-pat-github
docs: use `stringData` for secret of GitHub PAT
2024-07-09 12:15:13 +03:00
Thomas DANGLETERRE fd2df2cffe chore: set stringData for secret of github PAT in githubdispatch provider doc
Signed-off-by: Thomas DANGLETERRE <thomas.dangleterre@decathlon.com>
2024-07-09 10:42:28 +02:00
Stefan Prodan 48675f2426
Merge pull request #870 from matheuscscp/matheuscscp-maintainer
Add matheuscscp as maintainer
2024-07-05 09:30:31 +03:00
Matheus Pimenta 86b33d0f3c Add matheuscscp as maintainer
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-07-03 15:35:51 +01:00
Max Jonas Werner d9216e5c58
Merge pull request #866 from fluxcd/dependabot/github_actions/ci-6034f0241a
build(deps): bump github/codeql-action from 3.25.10 to 3.25.11 in the ci group
2024-07-01 09:28:09 +01:00
dependabot[bot] 84b8c037e9
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.25.10 to 3.25.11
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](23acc5c183...b611370bb5)

---
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-07-01 07:35:48 +00:00
souleb 39f345231f
Merge pull request #865 from fluxcd/dependabot/github_actions/ci-cb991c8081
build(deps): bump docker/build-push-action from 6.0.1 to 6.2.0 in the ci group across 1 directory
2024-06-27 15:31:28 +02:00
dependabot[bot] 9c4d43f32a
build(deps): bump docker/build-push-action
Bumps the ci group with 1 update in the / directory: [docker/build-push-action](https://github.com/docker/build-push-action).


Updates `docker/build-push-action` from 6.0.1 to 6.2.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](94f8f8c2ee...15560696de)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-27 08:01:32 +00:00
Max Jonas Werner a1cf5e0d43
Merge pull request #829 from hs1o/patch-1
telegram notifier should escape with metadata key
2024-06-25 10:29:49 +01:00
Max Jonas Werner e70166d5e3
Add test for telegram notifier
This test will make sure we're properly escaping the message and
constructing the URL correctly.

Signed-off-by: Max Jonas Werner <max.werner@associmates.eu>
2024-06-25 10:16:08 +02:00
hohohong 0f8ff3c0d8
telegram notifier should escape with metadata key
Signed-off-by: hohohong <github@m.hs1o.dev>
2024-06-25 10:16:08 +02:00
Max Jonas Werner b6037078a3
Merge pull request #857 from fluxcd/dependabot/go_modules/go-deps-278891ca24
build(deps): bump google.golang.org/api from 0.184.0 to 0.185.0 in the go-deps group
2024-06-21 18:04:06 +01:00
dependabot[bot] 5572c7fa04
build(deps): bump google.golang.org/api in the go-deps group
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.184.0 to 0.185.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.184.0...v0.185.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-06-21 07:25:12 +00:00
Max Jonas Werner ef7db0026b
Merge pull request #854 from fluxcd/dependabot/go_modules/go-deps-129d757b84
build(deps): bump the go-deps group across 1 directory with 10 updates
2024-06-20 18:39:34 +01:00
dependabot[bot] 7adf4f2c41
build(deps): bump the go-deps group across 1 directory with 10 updates
Bumps the go-deps group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [cloud.google.com/go/pubsub](https://github.com/googleapis/google-cloud-go) | `1.37.0` | `1.39.0` |
| [github.com/DataDog/datadog-api-client-go/v2](https://github.com/DataDog/datadog-api-client-go) | `2.25.0` | `2.26.0` |
| [github.com/getsentry/sentry-go](https://github.com/getsentry/sentry-go) | `0.27.0` | `0.28.1` |
| [github.com/hashicorp/go-retryablehttp](https://github.com/hashicorp/go-retryablehttp) | `0.7.5` | `0.7.7` |
| [github.com/ktrysmt/go-bitbucket](https://github.com/ktrysmt/go-bitbucket) | `0.9.79` | `0.9.80` |
| [github.com/nats-io/nats.go](https://github.com/nats-io/nats.go) | `1.34.1` | `1.36.0` |
| [github.com/xanzy/go-gitlab](https://github.com/xanzy/go-gitlab) | `0.104.0` | `0.105.0` |



Updates `cloud.google.com/go/pubsub` from 1.37.0 to 1.39.0
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/pubsub/v1.37.0...pubsub/v1.39.0)

Updates `github.com/DataDog/datadog-api-client-go/v2` from 2.25.0 to 2.26.0
- [Release notes](https://github.com/DataDog/datadog-api-client-go/releases)
- [Changelog](https://github.com/DataDog/datadog-api-client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/DataDog/datadog-api-client-go/compare/v2.25.0...v2.26.0)

Updates `github.com/getsentry/sentry-go` from 0.27.0 to 0.28.1
- [Release notes](https://github.com/getsentry/sentry-go/releases)
- [Changelog](https://github.com/getsentry/sentry-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-go/compare/v0.27.0...v0.28.1)

Updates `github.com/hashicorp/go-retryablehttp` from 0.7.5 to 0.7.7
- [Changelog](https://github.com/hashicorp/go-retryablehttp/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/go-retryablehttp/compare/v0.7.5...v0.7.7)

Updates `github.com/ktrysmt/go-bitbucket` from 0.9.79 to 0.9.80
- [Release notes](https://github.com/ktrysmt/go-bitbucket/releases)
- [Commits](https://github.com/ktrysmt/go-bitbucket/compare/v0.9.79...v0.9.80)

Updates `github.com/nats-io/nats.go` from 1.34.1 to 1.36.0
- [Release notes](https://github.com/nats-io/nats.go/releases)
- [Commits](https://github.com/nats-io/nats.go/compare/v1.34.1...v1.36.0)

Updates `github.com/xanzy/go-gitlab` from 0.104.0 to 0.105.0
- [Changelog](https://github.com/xanzy/go-gitlab/blob/main/releases_test.go)
- [Commits](https://github.com/xanzy/go-gitlab/compare/v0.104.0...v0.105.0)

Updates `golang.org/x/oauth2` from 0.20.0 to 0.21.0
- [Commits](https://github.com/golang/oauth2/compare/v0.20.0...v0.21.0)

Updates `golang.org/x/text` from 0.15.0 to 0.16.0
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.15.0...v0.16.0)

Updates `google.golang.org/api` from 0.177.0 to 0.184.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.177.0...v0.184.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/pubsub
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/DataDog/datadog-api-client-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/getsentry/sentry-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/hashicorp/go-retryablehttp
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/ktrysmt/go-bitbucket
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/nats-io/nats.go
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/xanzy/go-gitlab
  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/text
  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-06-20 17:20:49 +00:00
Max Jonas Werner c518265dae
Merge pull request #855 from fluxcd/dependabot/github_actions/ci-f2c4839187
build(deps): bump the ci group across 1 directory with 3 updates
2024-06-20 18:16:17 +01:00
dependabot[bot] 6240b16776
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), [docker/build-push-action](https://github.com/docker/build-push-action) and [github/codeql-action](https://github.com/github/codeql-action).


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 `docker/build-push-action` from 5.3.0 to 6.0.1
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](2cdde995de...94f8f8c2ee)

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

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: docker/build-push-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-19 08:04:32 +00:00
Stefan Prodan 3ae80f6475
Merge pull request #845 from fluxcd/dependabot/github_actions/ci-8595c0ecb0
build(deps): bump the ci group across 1 directory with 6 updates
2024-06-11 09:47:08 +03:00
Stefan Prodan 219f86fd11
Adapt config to GoRelease v2
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-06-11 09:33:07 +03:00
dependabot[bot] 129f60e6e6
build(deps): bump the ci group across 1 directory with 6 updates
Bumps the ci group with 6 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/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) | `2.13.4` | `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/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 2.13.4 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](cdcdbb5797...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/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-major
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-05 07:35:41 +00:00
Stefan Prodan 580497beeb
Merge pull request #823 from matheuscscp/new-release-label
Add 1.3.x release label
2024-05-08 17:07:14 +03:00
Matheus Pimenta f4e8df6360 Add 1.3.x release label
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2024-05-08 14:24:32 +01:00
Stefan Prodan eb62655b73
Merge pull request #818 from fluxcd/release/v1.3.x
Housekeeping: merge `release/v1.3.x` back into `main`
2024-05-06 16:11:52 +03:00
Stefan Prodan e0a1f00358
Merge pull request #817 from fluxcd/release-v1.3.0
Release v1.3.0
2024-05-06 14:57:33 +03:00
Stefan Prodan a8f81b3a00
Release v1.3.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-06 14:34:36 +03:00
Stefan Prodan 696f065673
Add changelog entry for v1.3.0
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-06 14:34:06 +03:00
Stefan Prodan 1b5dbd997a
Merge pull request #816 from fluxcd/dependabot/go_modules/go-deps-9d3f077bc0
build(deps): bump the go-deps group with 3 updates
2024-05-06 11:29:08 +03:00
dependabot[bot] 5bfdcc04fc
build(deps): bump the go-deps group with 3 updates
Bumps the go-deps group with 3 updates: [github.com/xanzy/go-gitlab](https://github.com/xanzy/go-gitlab), [golang.org/x/oauth2](https://github.com/golang/oauth2) and [golang.org/x/text](https://github.com/golang/text).


Updates `github.com/xanzy/go-gitlab` from 0.103.0 to 0.104.0
- [Changelog](https://github.com/xanzy/go-gitlab/blob/main/releases_test.go)
- [Commits](https://github.com/xanzy/go-gitlab/compare/v0.103.0...v0.104.0)

Updates `golang.org/x/oauth2` from 0.19.0 to 0.20.0
- [Commits](https://github.com/golang/oauth2/compare/v0.19.0...v0.20.0)

Updates `golang.org/x/text` from 0.14.0 to 0.15.0
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.14.0...v0.15.0)

---
updated-dependencies:
- dependency-name: github.com/xanzy/go-gitlab
  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/text
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-06 08:05:11 +00:00
Stefan Prodan 5f0f561ac0
Merge pull request #815 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-05 09:10:20 +03:00
dependabot[bot] 9a948c7290
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 07:15:11 +00:00
Stefan Prodan b2c799203d
Merge pull request #814 from fluxcd/update-apis
Update Helm APIs to `source.toolkit.fluxcd.io/v1` (GA)
2024-05-03 00:11:23 +03:00
Stefan Prodan 05abe0a9de
Update runtime dependencies
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-02 21:02:29 +03:00
Stefan Prodan 3aba5bbd39
Update Helm APIs to v1
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-05-02 21:00:30 +03:00
Stefan Prodan 35e2a0ebc0
Merge pull request #813 from fluxcd/dependabot/go_modules/go-deps-219a9f80f6
build(deps): bump the go-deps group across 1 directory with 2 updates
2024-05-01 10:38:51 +03:00
dependabot[bot] fd635f7dff
build(deps): bump the go-deps group across 1 directory with 2 updates
Bumps the go-deps group with 2 updates in the / directory: [github.com/onsi/gomega](https://github.com/onsi/gomega) and [google.golang.org/api](https://github.com/googleapis/google-api-go-client).


Updates `github.com/onsi/gomega` from 1.33.0 to 1.33.1
- [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.33.0...v1.33.1)

Updates `google.golang.org/api` from 0.176.1 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.176.1...v0.177.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  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-05-01 07:15:59 +00:00
souleb 838514c874
Merge pull request #811 from fluxcd/dependabot/github_actions/ci-df358fd3c4
build(deps): bump anchore/sbom-action from 0.15.10 to 0.15.11 in the ci group
2024-04-30 22:47:40 +02:00
dependabot[bot] b7b9a018e8
build(deps): bump anchore/sbom-action in the ci group
Bumps the ci group with 1 update: [anchore/sbom-action](https://github.com/anchore/sbom-action).


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

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-30 07:48:39 +00:00
Stefan Prodan c4835fbdbd
Merge pull request #810 from fluxcd/dependabot/go_modules/go-deps-152f4dbed8
build(deps): bump the go-deps group across 1 directory with 6 updates
2024-04-29 11:01:10 +03:00
dependabot[bot] 3407bf5486
build(deps): bump the go-deps group across 1 directory with 6 updates
Bumps the go-deps group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| code.gitea.io/sdk/gitea | `0.17.1` | `0.18.0` |
| [github.com/DataDog/datadog-api-client-go/v2](https://github.com/DataDog/datadog-api-client-go) | `2.24.0` | `2.25.0` |
| [github.com/ktrysmt/go-bitbucket](https://github.com/ktrysmt/go-bitbucket) | `0.9.77` | `0.9.79` |
| [github.com/onsi/gomega](https://github.com/onsi/gomega) | `1.32.0` | `1.33.0` |
| [github.com/xanzy/go-gitlab](https://github.com/xanzy/go-gitlab) | `0.102.0` | `0.103.0` |
| [google.golang.org/api](https://github.com/googleapis/google-api-go-client) | `0.172.0` | `0.176.1` |



Updates `code.gitea.io/sdk/gitea` from 0.17.1 to 0.18.0

Updates `github.com/DataDog/datadog-api-client-go/v2` from 2.24.0 to 2.25.0
- [Release notes](https://github.com/DataDog/datadog-api-client-go/releases)
- [Changelog](https://github.com/DataDog/datadog-api-client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/DataDog/datadog-api-client-go/compare/v2.24.0...v2.25.0)

Updates `github.com/ktrysmt/go-bitbucket` from 0.9.77 to 0.9.79
- [Release notes](https://github.com/ktrysmt/go-bitbucket/releases)
- [Commits](https://github.com/ktrysmt/go-bitbucket/compare/v0.9.77...v0.9.79)

Updates `github.com/onsi/gomega` from 1.32.0 to 1.33.0
- [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.32.0...v1.33.0)

Updates `github.com/xanzy/go-gitlab` from 0.102.0 to 0.103.0
- [Changelog](https://github.com/xanzy/go-gitlab/blob/main/releases_test.go)
- [Commits](https://github.com/xanzy/go-gitlab/compare/v0.102.0...v0.103.0)

Updates `google.golang.org/api` from 0.172.0 to 0.176.1
- [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.176.1)

---
updated-dependencies:
- dependency-name: code.gitea.io/sdk/gitea
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/DataDog/datadog-api-client-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/ktrysmt/go-bitbucket
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/xanzy/go-gitlab
  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-04-29 07:44:46 +00:00
Stefan Prodan 6d7913063d
Merge pull request #795 from tdemin/main
Alertmanager: Change timestamp label to .StartsAt
2024-04-29 09:30:55 +03:00
Timur Demin 531c5873e7 Alertmanager: Change timestamp label to .StartsAt
notification-controller posted all outgoing Alertmanager alerts with
"timestamp" label, effectively preventing grouping alerts related to the
same resource and forcing users to configure a separate alert receiver
with `send_resolved: false`.

This changes it to instead set "startsAt", which was previously set
(automatically by Alertmanager) to alert posting time. "endsAt" remains
unset, as we have no way of figuring that out but the reconciliation
interval of the resource that generated the alert, which can currently
only be found out by making a Kubernetes API round-trip.

Note that this requires users to adapt alert templates that relied on
.Labels.Timestamp.

Signed-off-by: Timur Demin <me@tdem.in>
2024-04-27 16:20:12 +05:00
Stefan Prodan cf2f554c11
Merge pull request #809 from fluxcd/kubernetes-1.30
Update dependencies to Kubernetes 1.30
2024-04-26 12:53:54 +03:00
Stefan Prodan d29f5f4919
Update dependencies to Kubernetes 1.30
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-04-26 12:33:21 +03:00
souleb f9c93e2952
Merge pull request #807 from fluxcd/dependabot/github_actions/ci-46f46a1c32
build(deps): bump the ci group across 1 directory with 3 updates
2024-04-25 10:17:34 +02:00
dependabot[bot] f5026a7443
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), [helm/kind-action](https://github.com/helm/kind-action) and [slsa-framework/slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator).


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

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)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- 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
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-25 07:32:57 +00:00
Stefan Prodan 678f374bc3
Merge pull request #747 from gdasson/fix_742
Add support for Bitbucket Context path
2024-04-23 17:16:49 +03:00
Gaurav Dasson 633e33bf4b Add support for Bitbucket Context path - Fix issue #742
Signed-off-by: Gaurav Dasson <gaurav.dasson@gmail.com>
2024-04-20 23:56:03 -05:00
souleb f22dd2bfff
Merge pull request #796 from al-lac/opsgenie-add-severity
Add severity to opsgenie alerts
2024-04-19 15:32:17 +02:00
al-lac 94ce6da0f2 Add severity to opsgenie Details payload
Co-authored-by: souleb <bah.soule@gmail.com>
Signed-off-by: al-lac <lackner.alex@gmail.com>
2024-04-19 14:36:35 +02:00
Stefan Prodan 0bea894c2e
Merge pull request #791 from fluxcd/dependabot/github_actions/ci-fd594e3a59
build(deps): bump the ci group with 2 updates
2024-04-11 12:24:47 +03:00
dependabot[bot] 857c11dd26
build(deps): bump the ci group with 2 updates
Bumps the ci group with 2 updates: [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) and [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer).


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)

---
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
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-11 07:53:45 +00:00
Stefan Prodan 2bac104a69
Merge pull request #790 from fluxcd/git-token-password
Use `password` as fallback for the Git provider `token` auth
2024-04-10 11:17:13 +03:00
Soule BA e3ae7c2d48
refactor notifier factory
Signed-off-by: Soule BA <bah.soule@gmail.com>
2024-04-09 22:21:11 +02:00
Stefan Prodan 952ccd000f
User the password as fallback for Git provider token auth
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-04-09 18:59:04 +03:00
Stefan Prodan 0106b53e02
Merge pull request #789 from fluxcd/sanitize-provider-data
Sanitize provider data loaded from secret
2024-04-09 18:54:19 +03:00
Stefan Prodan 6ba1a713fe
Sanitize provider data loaded from secret
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-04-09 18:35:01 +03:00
Stefan Prodan c6b89cd2d6
Merge pull request #787 from fluxcd/dependabot/go_modules/go-deps-f80f47cc43
build(deps): bump the go-deps group with 6 updates
2024-04-05 10:50:34 +03:00
dependabot[bot] e30844fe7b
build(deps): bump the go-deps group with 6 updates
Bumps the go-deps group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/fluxcd/cli-utils](https://github.com/fluxcd/cli-utils) | `0.36.0-flux.4` | `0.36.0-flux.5` |
| [github.com/fluxcd/pkg/runtime](https://github.com/fluxcd/pkg) | `0.45.0` | `0.46.0` |
| [github.com/fluxcd/pkg/ssa](https://github.com/fluxcd/pkg) | `0.37.0` | `0.38.0` |
| [github.com/nats-io/nats.go](https://github.com/nats-io/nats.go) | `1.34.0` | `1.34.1` |
| [github.com/xanzy/go-gitlab](https://github.com/xanzy/go-gitlab) | `0.101.0` | `0.102.0` |
| [golang.org/x/oauth2](https://github.com/golang/oauth2) | `0.18.0` | `0.19.0` |


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

Updates `github.com/fluxcd/pkg/runtime` from 0.45.0 to 0.46.0
- [Commits](https://github.com/fluxcd/pkg/compare/runtime/v0.45.0...runtime/v0.46.0)

Updates `github.com/fluxcd/pkg/ssa` from 0.37.0 to 0.38.0
- [Commits](https://github.com/fluxcd/pkg/compare/ssa/v0.37.0...ssa/v0.38.0)

Updates `github.com/nats-io/nats.go` from 1.34.0 to 1.34.1
- [Release notes](https://github.com/nats-io/nats.go/releases)
- [Commits](https://github.com/nats-io/nats.go/compare/v1.34.0...v1.34.1)

Updates `github.com/xanzy/go-gitlab` from 0.101.0 to 0.102.0
- [Changelog](https://github.com/xanzy/go-gitlab/blob/main/releases_test.go)
- [Commits](https://github.com/xanzy/go-gitlab/compare/v0.101.0...v0.102.0)

Updates `golang.org/x/oauth2` from 0.18.0 to 0.19.0
- [Commits](https://github.com/golang/oauth2/compare/v0.18.0...v0.19.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/runtime
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/fluxcd/pkg/ssa
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/nats-io/nats.go
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/xanzy/go-gitlab
  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
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-05 07:31:05 +00:00
Stefan Prodan 1fa1e28e33
Merge pull request #783 from fluxcd/dependabot/github_actions/ci-39c307716c
build(deps): bump the ci group with 12 updates
2024-04-02 17:27:38 +03:00
dependabot[bot] cb595180b1
build(deps): bump the ci group with 12 updates
Bumps the ci group with 12 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` |
| [actions/cache](https://github.com/actions/cache) | `4.0.0` | `4.0.2` |
| [helm/kind-action](https://github.com/helm/kind-action) | `1.8.0` | `1.9.0` |
| [docker/login-action](https://github.com/docker/login-action) | `3.0.0` | `3.1.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `5.5.0` | `5.5.1` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `5.1.0` | `5.3.0` |
| [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.7` | `0.15.10` |
| [slsa-framework/slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator) | `1.9.0` | `1.10.0` |
| [EndBug/label-sync](https://github.com/endbug/label-sync) | `2.3.2` | `2.3.3` |


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 `actions/cache` from 4.0.0 to 4.0.2
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](13aacd865c...0c45773b62)

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/login-action` from 3.0.0 to 3.1.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](343f7c4344...e92390c5fb)

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 `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 `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.7 to 0.15.10
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](767b08fd88...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 `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: 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: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: helm/kind-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: docker/metadata-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
- dependency-name: docker/build-push-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: slsa-framework/slsa-github-generator
  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-04-02 13:11:57 +00:00
Stefan Prodan 7659221a4a
Merge pull request #785 from fluxcd/go1.22
Update dependencies to Go 1.22 and Kubernetes 1.29.3
2024-04-02 16:10:01 +03:00
Stefan Prodan 08e74d5209
Update dependencies to Go 1.22 and Kubernetes 1.29.3
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-04-02 15:32:20 +03:00
Stefan Prodan 17adf69aeb
Merge pull request #772 from Nordix/cdevents-validation
[RFC-0006] Add CDEvent Receiver Support
2024-03-27 18:26:42 +02:00
adam b4949b6e05 Implement CDEvents Receiver
Signed-off-by: adamkenihan <adam.kenihan@est.tech>

Added CDEvents Receiver

Signed-off-by: adamkenihan <adam.kenihan@est.tech>

Added CDEvent Validation + Tests

Signed-off-by: adamkenihan <adam.kenihan@est.tech>

Small changes to CDEvent Receiver

Signed-off-by: adamkenihan <adam.kenihan@est.tech>

More CDEvents Tests and Docs added

Signed-off-by: adamkenihan <adam.kenihan@est.tech>

Adding imports to go.mod

Signed-off-by: adamkenihan <adam.kenihan@est.tech>

small changes + manifests and formatting

Signed-off-by: adamkenihan <adam.kenihan@est.tech>

Changing string compare to EqualFold

Signed-off-by: adamkenihan <adam.kenihan@est.tech>
2024-03-27 10:36:51 +00:00
Stefan Prodan 20eee15786
Merge pull request #776 from coding4food/734-fix-telegram-markup
Fix Telegram MarkdownV2 escaping
2024-03-25 12:50:08 +02:00
Anatoly Medvedkov bf918b9b3c Fix Telegram MarkdownV2 escaping
Current implementation was missing '*' symbol.

Signed-off-by: Anatoly Medvedkov <32126+coding4food@users.noreply.github.com>
2024-03-21 13:41:04 +03:00
souleb 440aad84b0
Merge pull request #763 from fluxcd/update-controllergen-0.14
Update controller-gen to v0.14.0
2024-03-12 16:10:37 +01:00
Soule BA c2302f8fed
Update controller-gen to v0.14.0
Also update to use GOBIN if it exist

Signed-off-by: Soule BA <bah.soule@gmail.com>
2024-03-12 15:01:35 +01:00
Stefan Prodan cd529f5588
Merge pull request #757 from fluxcd/api-docs-provider-timeout
Fix timeout propagation for alerts
2024-03-07 21:08:19 +02:00
Stefan Prodan aef940033c
Fix timout propagation for alerts
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-03-07 16:30:39 +02:00
Stefan Prodan 34a9099884
Add the Provider `.spec.timeout` field to the API docs
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-03-07 15:22:25 +02:00
Stefan Prodan e73db32382
Merge pull request #749 from gmolau/main
Remove `genclient:Namespaced` tag
2024-02-29 13:50:20 +00:00
Georg Molau b3e4bf2ad5 Remove `genclient:Namespaced` tag
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](mailto:georg.molau@gmail.com)
Signed-off-by: Georg Molau <georg.molau@gmail.com>
2024-02-27 22:23:51 +01:00
Sunny bd242e091c
Merge pull request #730 from fluxcd/pick-changelog-v1.2.4
Add changelog entry for v1.2.4
2024-02-01 20:01:44 +05:30
Sunny 36a83074f2 Add changelog entry for v1.2.4
Signed-off-by: Sunny <github@darkowlzz.space>
(cherry picked from commit be91fe2beb)
2024-02-01 19:38:49 +05:30
Stefan Prodan eceae7774f
Merge pull request #724 from fluxcd/dependabot/github_actions/ci-bfff10142b
build(deps): bump the ci group with 2 updates
2024-01-31 15:12:49 +02:00
dependabot[bot] edb771fa6c
build(deps): bump the ci group with 2 updates
Bumps the ci group with 2 updates: [korthout/backport-action](https://github.com/korthout/backport-action) and [anchore/sbom-action](https://github.com/anchore/sbom-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.7
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](41f7a6c033...767b08fd88)

---
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
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-31 13:05:55 +00:00
Stefan Prodan ee50f74164
Merge pull request #725 from fluxcd/dependabot/go_modules/go-deps-08706ae5bf
build(deps): bump the go-deps group with 2 updates
2024-01-31 14:11:27 +02:00
dependabot[bot] 6dafac748f
build(deps): bump the go-deps group with 2 updates
Bumps the go-deps group with 2 updates: [cloud.google.com/go/pubsub](https://github.com/googleapis/google-cloud-go) and [google.golang.org/api](https://github.com/googleapis/google-api-go-client).


Updates `cloud.google.com/go/pubsub` from 1.36.0 to 1.36.1
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/pubsub/v1.36.0...pubsub/v1.36.1)

Updates `google.golang.org/api` from 0.160.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.160.0...v0.161.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/pubsub
  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-01-31 08:05:35 +00:00
Stefan Prodan 333e6c3d07
Merge pull request #722 from fluxcd/fix-bitbucket-panic
Fix BitBucket status update panic
2024-01-30 16:27:22 +02:00
Stefan Prodan 32c59b2474
Fix BitBucket status update panic
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-01-30 15:23:38 +02:00
Stefan Prodan 681ad49b98
Merge pull request #720 from fluxcd/dependabot/go_modules/go-deps-5f4080d6cc
build(deps): bump the go-deps group with 1 update
2024-01-30 13:53:54 +02:00
dependabot[bot] 4e8bb2e4d5
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.159.0 to 0.160.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.160.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-01-30 07:58:21 +00:00
Stefan Prodan 8cedefd341
Merge pull request #717 from fluxcd/dependabot/go_modules/go-deps-3a14492254
Update controller to Kubernetes 1.28.6
2024-01-29 15:54:51 +02:00
Stefan Prodan 5ed66321a9
Update API to Kubernetes v1.28.6
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-01-29 15:39:57 +02:00
dependabot[bot] f325f774d8
build(deps): bump the go-deps group with 16 updates
Bumps the go-deps group with 16 updates:

| Package | From | To |
| --- | --- | --- |
| [cloud.google.com/go/pubsub](https://github.com/googleapis/google-cloud-go) | `1.33.0` | `1.36.0` |
| code.gitea.io/sdk/gitea | `0.17.0` | `0.17.1` |
| [github.com/Azure/azure-event-hubs-go/v3](https://github.com/Azure/azure-event-hubs-go) | `3.6.1` | `3.6.2` |
| [github.com/DataDog/datadog-api-client-go/v2](https://github.com/DataDog/datadog-api-client-go) | `2.19.0` | `2.21.0` |
| [github.com/PagerDuty/go-pagerduty](https://github.com/PagerDuty/go-pagerduty) | `1.7.0` | `1.8.0` |
| [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/runtime](https://github.com/fluxcd/pkg) | `0.43.2` | `0.44.0` |
| [github.com/fluxcd/pkg/ssa](https://github.com/fluxcd/pkg) | `0.35.0` | `0.36.0` |
| [github.com/getsentry/sentry-go](https://github.com/getsentry/sentry-go) | `0.25.0` | `0.26.0` |
| [github.com/ktrysmt/go-bitbucket](https://github.com/ktrysmt/go-bitbucket) | `0.9.73` | `0.9.74` |
| [github.com/nats-io/nats.go](https://github.com/nats-io/nats.go) | `1.31.0` | `1.32.0` |
| [github.com/xanzy/go-gitlab](https://github.com/xanzy/go-gitlab) | `0.95.1` | `0.96.0` |
| [google.golang.org/api](https://github.com/googleapis/google-api-go-client) | `0.157.0` | `0.159.0` |


Updates `cloud.google.com/go/pubsub` from 1.33.0 to 1.36.0
- [Release notes](https://github.com/googleapis/google-cloud-go/releases)
- [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-cloud-go/compare/pubsub/v1.33.0...pubsub/v1.36.0)

Updates `code.gitea.io/sdk/gitea` from 0.17.0 to 0.17.1

Updates `github.com/Azure/azure-event-hubs-go/v3` from 3.6.1 to 3.6.2
- [Release notes](https://github.com/Azure/azure-event-hubs-go/releases)
- [Changelog](https://github.com/Azure/azure-event-hubs-go/blob/master/changelog.md)
- [Commits](https://github.com/Azure/azure-event-hubs-go/compare/v3.6.1...v3.6.2)

Updates `github.com/DataDog/datadog-api-client-go/v2` from 2.19.0 to 2.21.0
- [Release notes](https://github.com/DataDog/datadog-api-client-go/releases)
- [Changelog](https://github.com/DataDog/datadog-api-client-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/DataDog/datadog-api-client-go/compare/v2.19.0...v2.21.0)

Updates `github.com/PagerDuty/go-pagerduty` from 1.7.0 to 1.8.0
- [Release notes](https://github.com/PagerDuty/go-pagerduty/releases)
- [Changelog](https://github.com/PagerDuty/go-pagerduty/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PagerDuty/go-pagerduty/compare/v1.7.0...v1.8.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/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/fluxcd/pkg/ssa` from 0.35.0 to 0.36.0
- [Commits](https://github.com/fluxcd/pkg/compare/oci/v0.35.0...ssa/v0.36.0)

Updates `github.com/getsentry/sentry-go` from 0.25.0 to 0.26.0
- [Release notes](https://github.com/getsentry/sentry-go/releases)
- [Changelog](https://github.com/getsentry/sentry-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-go/compare/v0.25.0...v0.26.0)

Updates `github.com/ktrysmt/go-bitbucket` from 0.9.73 to 0.9.74
- [Release notes](https://github.com/ktrysmt/go-bitbucket/releases)
- [Commits](https://github.com/ktrysmt/go-bitbucket/compare/v0.9.73...v0.9.74)

Updates `github.com/nats-io/nats.go` from 1.31.0 to 1.32.0
- [Release notes](https://github.com/nats-io/nats.go/releases)
- [Commits](https://github.com/nats-io/nats.go/compare/v1.31.0...v1.32.0)

Updates `github.com/xanzy/go-gitlab` from 0.95.1 to 0.96.0
- [Changelog](https://github.com/xanzy/go-gitlab/blob/main/releases_test.go)
- [Commits](https://github.com/xanzy/go-gitlab/compare/v0.95.1...v0.96.0)

Updates `google.golang.org/api` from 0.157.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.157.0...v0.159.0)

---
updated-dependencies:
- dependency-name: cloud.google.com/go/pubsub
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: code.gitea.io/sdk/gitea
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/Azure/azure-event-hubs-go/v3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/DataDog/datadog-api-client-go/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/PagerDuty/go-pagerduty
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- 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/runtime
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/fluxcd/pkg/ssa
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/getsentry/sentry-go
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/ktrysmt/go-bitbucket
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-deps
- dependency-name: github.com/nats-io/nats.go
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-deps
- dependency-name: github.com/xanzy/go-gitlab
  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 13:31:16 +00:00
Stefan Prodan bba04db89d
Merge pull request #716 from fluxcd/dependabot-ignore-logr
dependabot: Ignore `go-logr` package
2024-01-29 15:28:11 +02:00
Stefan Prodan c71a90e01a
dependabot: Ignore `go-logr` package
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-01-29 15:24:47 +02:00
Stefan Prodan 56120e9afc
Merge pull request #713 from fluxcd/dependabot-gomod
ci: Enable dependabot `gomod` updates
2024-01-29 15:13:01 +02:00
Stefan Prodan f455608bfd
ci: Enable dependabot `gomod` updates
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2024-01-26 20:38:53 +02:00
Sunny b816076657
Merge pull request #699 from piny940/fix/docs/v1beta3/providers
fix typo in docs/spec/v1beta3/providers.md
2024-01-26 20:37:28 +05:30
piny940 f5c0f6d33b fix typo in docs/spec/v1beta3/providers.md
Signed-off-by: piny940 <an.s.shoma@gmail.com>
2024-01-26 20:04:14 +05:30
Stefan Prodan d72c7df6a5
Merge pull request #711 from fluxcd/dependabot/github_actions/ci-1ce66589eb
build(deps): bump the ci group with 2 updates
2024-01-22 16:58:10 +02:00
dependabot[bot] b4deeb98be
build(deps): bump the ci group with 2 updates
Bumps the ci group with 2 updates: [actions/cache](https://github.com/actions/cache) and [anchore/sbom-action](https://github.com/anchore/sbom-action).


Updates `actions/cache` from 3.3.3 to 4.0.0
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](e12d46a63a...13aacd865c)

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

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: ci
- dependency-name: anchore/sbom-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 07:47:21 +00:00
Stefan Prodan 4df3ce451a
Merge pull request #710 from fluxcd/dependabot/github_actions/ci-425d4b0f20
build(deps): bump the ci group with 2 updates
2024-01-15 10:57:58 +02:00
dependabot[bot] 70b93d3f3d
build(deps): bump the ci group with 2 updates
Bumps the ci group with 2 updates: [actions/cache](https://github.com/actions/cache) and [anchore/sbom-action](https://github.com/anchore/sbom-action).


Updates `actions/cache` from 3.3.2 to 3.3.3
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](704facf57e...e12d46a63a)

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

---
updated-dependencies:
- dependency-name: actions/cache
  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
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-15 07:25:50 +00:00
Stefan Prodan ec61423cc5
Merge pull request #703 from radenui/fix/grafana-provider-remove-unsupported-character
fix(grafana-provider): replace ":" character in eventMetadata
2024-01-11 20:55:02 +02:00
Arthur ANDRIEU 5371d8a79d fix(grafana-provider): replace ":" character in eventMetadata
Signed-off-by: Arthur Andrieu  <arthur.andrieu@gmail.com>
2024-01-11 19:16:00 +01:00
Somtochi Onyekwere 071bf10fa3
Merge pull request #708 from fluxcd/update-maintainer-details
Update Somtochi's maintainer details
2024-01-09 20:13:06 +01:00
Somtochi Onyekwere d29d1f0804 change company
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
2024-01-09 19:48:47 +01:00
Somtochi Onyekwere 0d39d277d2 update Somtochi's maintainer details
Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
2024-01-09 19:46:59 +01:00
Stefan Prodan c368adbbcc
Merge pull request #706 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:08:22 +02:00
dependabot[bot] 69dfee9318
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:54:20 +00:00
Max Jonas Werner e7a241d777
Merge pull request #704 from fluxcd/dependabot/github_actions/ci-9edfa6747d
build(deps): bump the ci group with 2 updates
2024-01-08 08:53:07 +01:00
dependabot[bot] 8ce32f9553
build(deps): bump the ci group with 2 updates
Bumps the ci group with 2 updates: [docker/metadata-action](https://github.com/docker/metadata-action) and [anchore/sbom-action](https://github.com/anchore/sbom-action).


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

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

---
updated-dependencies:
- 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
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-08 07:33:03 +00:00
Sunny dcabd7c42b
Merge pull request #693 from fluxcd/update-old-api-versions
Remove old/incorrect API version usage
2023-12-19 19:12:21 +05:30
Sunny 5b152f583d Remove old/incorrect API version usage
- Update README.md to point to v1beta3 spec docs.
- Remove provider testdata which had old API version and is no longer
  used in any test.
- Update Provider v1beta2 spec docs to use Alert v1beta2.
- Update Provider v1beta3 spec docs to use v1beta3 API in all the
  code snippets.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
2023-12-19 18:25:16 +05:30
Hidde Beydals 0b48a065e3
Merge pull request #696 from fluxcd/dependabot/github_actions/ci-c99cc58ab6
build(deps): bump the ci group with 3 updates
2023-12-19 10:11:58 +01:00
dependabot[bot] a88f97eb44
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), [docker/metadata-action](https://github.com/docker/metadata-action) and [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer).


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.4.0
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](31cebacef4...9dc751fe24)

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

---
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
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-19 09:02:07 +00:00
Hidde Beydals 0bb0c6041c
Merge pull request #694 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:58:47 +01:00
dependabot[bot] 6ae9bb6fa7
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: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-19 00:06:31 +00:00
Sunny f9933507d0
Merge pull request #689 from fluxcd/pick-changelog-v1.2.3
Pick changelog v1.2.3
2023-12-14 19:59:49 +05:30
Sunny 20423eb80a Add changelog entry for v1.2.3
Signed-off-by: Sunny <darkowlzz@protonmail.com>
(cherry picked from commit 3289dbd35d)
2023-12-14 18:09:08 +05:30
Sunny a817cf91c1
Merge pull request #686 from fluxcd/exclude-token
Exclude eventv1.MetaTokenKey from event metadata
2023-12-14 14:20:30 +05:30
Sunny 68c38244cc Exclude eventv1.MetaTokenKey from event metadata
eventv1.MetaTokenKey is required to be considered in rate limiting but
it is only for internal use by flux components and should not be sent to
the alert provider. Remove eventv1.MetaTokenKey from the metadata of
event before processing the event for various matching alerts.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
2023-12-13 23:13:38 +05:30
Sunny 7834608f77
Merge pull request #683 from fluxcd/v1beta3-provider-interval
Add .spec.interval in v1beta3 Provider
2023-12-13 15:28:25 +05:30
Sunny 7f5eea0a2e Add .spec.interval in v1beta3 Provider
For backwards compatibility with v1beta2 Provider, add .spec.interval
with deprecation marker.
Interval was an optional field in v1beta2 with internal default. Only
the users who had explicitly set intervals would have encountered this
incompatibility error after upgrade.

Signed-off-by: Sunny <darkowlzz@protonmail.com>
2023-12-13 15:06:10 +05:30
Stefan Prodan 73e1965419
Merge pull request #682 from matheuscscp/fix-address-validation
Remove URL syntax validation for provider address entirely
2023-12-13 11:35:18 +02:00
Matheus Pimenta 143a0b3ee0 Remove URL syntax validation for provider address entirely
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
2023-12-12 19:01:31 +00:00
Hidde Beydals e48be82c89
Merge pull request #679 from fluxcd/pick-changelog-v1.2.2 2023-12-11 15:47:22 +01:00
Hidde Beydals 2a8ab214c9
Add changelog entry for v1.2.2
Signed-off-by: Hidde Beydals <hidde@hhh.computer>
(cherry picked from commit 9066a87e56)
2023-12-11 15:39:57 +01:00
Stefan Prodan ef5c602fb1
Merge pull request #676 from fluxcd/runtime-v0.43.2
Update dependencies
2023-12-11 14:42:52 +01:00
Stefan Prodan 74bd37a992
Update dependencies
- github.com/fluxcd/pkg/runtime v0.43.2
- github.com/fluxcd/cli-utils v0.36.0-flux.2
- github.com/xanzy/go-gitlab v0.95.1

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2023-12-11 15:28:02 +02:00
Hidde Beydals 52da6c48ca
Merge pull request #672 from fluxcd/dependabot/github_actions/ci-4167a8d32d
build(deps): bump the ci group with 1 update
2023-12-11 09:32:15 +01:00
dependabot[bot] 879f9576e2
build(deps): bump the ci group with 1 update
Bumps the ci group with 1 update: [actions/setup-go](https://github.com/actions/setup-go).

- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](93397bea11...0c52d547c9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-11 08:21:39 +00:00
Hidde Beydals 6ffb5f3f70
Merge pull request #673 from fluxcd/alpine-319
build: update Alpine to 3.19
2023-12-11 09:19:50 +01:00
Hidde Beydals 40ba471d6b
build: update Alpine to 3.19
Signed-off-by: Hidde Beydals <hidde@hhh.computer>
2023-12-11 09:04:49 +01:00
Hidde Beydals 791d34ef46
Merge pull request #671 from fluxcd/pick-changelog-v1.2.1
Add changelog entry for v1.2.1
2023-12-08 13:08:34 +01:00
Hidde Beydals 57c32c15be
Add changelog entry for v1.2.1
Signed-off-by: Hidde Beydals <hidde@hhh.computer>
(cherry picked from commit d5572c1e2f)
2023-12-08 12:03:27 +01:00
Hidde Beydals 9492ef1b96
Merge pull request #668 from fluxcd/update-deps
Update dependencies
2023-12-08 09:30:16 +01:00
Hidde Beydals b007f42139
Update dependencies
- github.com/ktrysmt/go-bitbucket to v0.9.73
- google.golang.org/api to v0.153.0

Signed-off-by: Hidde Beydals <hidde@hhh.computer>
2023-12-08 09:11:10 +01:00
Hidde Beydals 9f90225f04
Merge pull request #664 from hectorj2f/replace_go_module
Replace whilp/git-urls module by chainguard-dev/git-urls
2023-12-06 09:43:47 +01:00
Hector Fernandez 39a3853c5c replace whilp/git-urls module by chainguard-dev/git-urls
Signed-off-by: Hector Fernandez <hector@chainguard.dev>
2023-12-06 09:38:59 +01:00
Hidde Beydals cd51b02fdd
Merge pull request #663 from fluxcd/backport-release-v1.2.x-label
Add `backport:release/v1.2.x` label
2023-12-06 09:37:25 +01:00
Sunny c857eb65b3 Add backport:release/v1.2.x label
Signed-off-by: Sunny <darkowlzz@protonmail.com>
2023-12-06 09:22:16 +01:00
Hidde Beydals 46d54b024d
Merge pull request #665 from fluxcd/go-1.21
Update Go to 1.21.x
2023-12-06 09:20:18 +01:00
Hidde Beydals c8d287e9c3
Update `tonistiigi/xx` to 1.3.0
Signed-off-by: Hidde Beydals <hidde@hhh.computer>
2023-12-06 09:02:25 +01:00
Hidde Beydals f045217d70
Update Go to 1.21.x
As appears to be magically required by
`github.com/slok/go-http-metrics`.

Signed-off-by: Hidde Beydals <hidde@hhh.computer>
2023-12-06 09:02:25 +01:00
Hidde Beydals 5acc9a12a8
Merge pull request #662 from fluxcd/release-v1.2.x
Merge release/v1.2.x changes to main
2023-12-05 21:08:28 +01:00
Sunny f4f6cdc73b Release v1.2.0
Signed-off-by: Sunny <darkowlzz@protonmail.com>
2023-12-06 00:49:03 +05:30
Sunny 42870e46ce Add changelog entry for v1.2.0
Signed-off-by: Sunny <darkowlzz@protonmail.com>
2023-12-06 00:49:03 +05:30
Stefan Prodan fe333842be
Merge pull request #659 from fluxcd/dependabot/github_actions/ci-3e3005af3f
build(deps): bump the ci group with 3 updates
2023-12-05 16:29:55 +02:00
dependabot[bot] 29fb291738
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), [docker/metadata-action](https://github.com/docker/metadata-action) and [anchore/sbom-action](https://github.com/anchore/sbom-action).


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 `docker/metadata-action` from 5.0.0 to 5.3.0
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](96383f4557...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)

---
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: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ci
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-05 13:48:13 +00:00
136 changed files with 8755 additions and 4821 deletions

View File

@ -1,16 +1,30 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
labels: ["dependencies"]
schedule:
interval: "monthly"
groups:
go-deps:
patterns:
- "*"
allow:
- dependency-type: "direct"
ignore:
# Kubernetes deps are updated by fluxcd/pkg
- dependency-name: "k8s.io/*"
- dependency-name: "sigs.k8s.io/*"
- dependency-name: "github.com/go-logr/*"
# Flux APIs pkg are updated at release time
- dependency-name: "github.com/fluxcd/notification-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

@ -13,3 +13,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

@ -13,11 +13,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

@ -11,11 +11,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.20.x
go-version: 1.24.x
cache-dependency-path: |
**/go.sum
**/go.mod

View File

@ -12,14 +12,14 @@ 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
- name: Cache Docker layers
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
id: cache
with:
path: /tmp/.buildx-cache
@ -27,18 +27,16 @@ jobs:
restore-keys: |
${{ runner.os }}-buildx-ghcache-
- name: Setup Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: 1.20.x
go-version: 1.24.x
cache-dependency-path: |
**/go.sum
**/go.mod
- name: Setup Kubernetes
uses: helm/kind-action@dda0770415bac9fc20092cacbc54aa298604d140 # v1.8.0
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
with:
version: v0.20.0
cluster_name: kind
node_image: kindest/node:v1.27.3@sha256:3966ac761ae0136263ffdb6cfd4db23ef8a83cba8a463690e98317add2c9ba72
- name: Setup Kustomize
uses: fluxcd/pkg/actions/kustomize@main
- name: Run tests

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@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.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.20.x
go-version: 1.24.x
cache-dependency-path: |
**/go.sum
**/go.mod
- name: Initialize CodeQL
uses: github/codeql-action/init@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
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@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@cdcdbb579706841c47f7063dda365e292e5cad7a # v2.13.4
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

@ -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,388 @@
All notable changes to this project are documented in this file.
## 1.6.0
**Release date:** 2025-05-27
This minor release comes with various bug fixes and improvements.
### Provider
The `azureeventhub` provider now supports workload identity both
at the controller and object levels. For object level, the
`.spec.serviceAccountName` field can be set to the name of a
service account in the same namespace that was configured with
a Managed Identity.
For object level to work, the controller feature gate
`ObjectLevelWorkloadIdentity` must be enabled. See a complete guide
[here](https://fluxcd.io/flux/integrations/azure/).
The `github` and `githubdispatch` providers now support authenticating
with a GitHub App. See docs
[here](https://fluxcd.io/flux/components/notification/providers/#github)
and
[here](https://fluxcd.io/flux/components/notification/providers/#github-dispatch).
For commit status providers it is now possible to define a custom
status string by defining a CEL expression in the `.spec.commitStatusExpr`
field. The variables `event`, `alert` and `provider` are available
for the CEL expression. See
[docs](https://fluxcd.io/flux/components/notification/providers/#custom-commit-status-messages).
### 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:
- Fix Slack chat.postMessage error handling
[#1086](https://github.com/fluxcd/notification-controller/pull/1086)
- Fix pass 'certPool' to Gitea client on creation
[#1084](https://github.com/fluxcd/notification-controller/pull/1084)
- CrossNamespaceObjectReference: Fix MaxLength validation to kubernetes max size of 253
[#1108](https://github.com/fluxcd/notification-controller/pull/1108)
- Sanitize proxy error logging
[#1093](https://github.com/fluxcd/notification-controller/pull/1093)
Improvements:
- [RFC-0010] Workload Identity support for `azureeventhub` provider
[#1106](https://github.com/fluxcd/notification-controller/pull/1106)
[#1116](https://github.com/fluxcd/notification-controller/pull/1116)
[#1120](https://github.com/fluxcd/notification-controller/pull/1120)
[#1109](https://github.com/fluxcd/notification-controller/pull/1109)
[#1112](https://github.com/fluxcd/notification-controller/pull/1112)
- GitHub App authentication support for `github` and `githubdispatch`
[#1058](https://github.com/fluxcd/notification-controller/pull/1058)
- Support CEL expressions to construct commit statuses
[#1068](https://github.com/fluxcd/notification-controller/pull/1068)
- Add proxy support to `gitea` provider
[#1087](https://github.com/fluxcd/notification-controller/pull/1087)
- Various dependency updates
[#1101](https://github.com/fluxcd/notification-controller/pull/1101)
[#1119](https://github.com/fluxcd/notification-controller/pull/1119)
[#1118](https://github.com/fluxcd/notification-controller/pull/1118)
[#1113](https://github.com/fluxcd/notification-controller/pull/1113)
[#1104](https://github.com/fluxcd/notification-controller/pull/1104)
## 1.5.0
**Release date:** 2025-02-13
This minor release comes with various bug fixes and improvements.
### Alert
Now notification-controller also sends event metadata specified in Flux objects through
annotations. See [docs](https://fluxcd.io/flux/components/notification/alerts/#event-metadata-from-object-annotations).
Now notification-controller is also capable of updating Git commit statuses
from events about Kustomizations that consume OCIRepositories. See
[docs](https://fluxcd.io/flux/cheatsheets/oci-artifacts/#git-commit-status-updates).
### Receiver
The Receiver API now supports filtering the declared resources that
match a given Common Expression Language (CEL) expression. See
[docs](https://fluxcd.io/flux/components/notification/receivers/#filtering-reconciled-objects-with-cel).
In addition, the Kubernetes dependencies have been updated to v1.32.1 and
various other controller dependencies have been updated to their latest
version.
Fixes:
- Remove deprecated object metrics from controllers
[#997](https://github.com/fluxcd/notification-controller/pull/997)
- msteams notifier: adaptive cards full width
[#1017](https://github.com/fluxcd/notification-controller/pull/1017)
- fix: adding of duplicate commit statuses in gitlab
[#1010](https://github.com/fluxcd/notification-controller/pull/1010)
- Fix add missing return statement and a few style issues
[#1039](https://github.com/fluxcd/notification-controller/pull/1039)
Improvements:
- [RFC-0008] Custom Event Metadata from Annotations
[#1014](https://github.com/fluxcd/notification-controller/pull/1014)
- Add support for MetaOriginRevisionKey from the Event API
[#1018](https://github.com/fluxcd/notification-controller/pull/1018)
- Add subsection for Git providers supporting commit status updates
[#1019](https://github.com/fluxcd/notification-controller/pull/1019)
- Add support for Bearer Token authentication to Provider alertmanager
[#1021](https://github.com/fluxcd/notification-controller/pull/1021)
- Enforce namespace check on receiver
[#1022](https://github.com/fluxcd/notification-controller/pull/1022)
- Implement Receiver resource filtering with CEL
[#948](https://github.com/fluxcd/notification-controller/pull/948)
- Clarify gitlab provider usage
[#953](https://github.com/fluxcd/notification-controller/pull/953)
- Add involved object reference as annotations for the grafana provider
[#1040](https://github.com/fluxcd/notification-controller/pull/1040)
- Improvements after CEL resource filtering
[#1041](https://github.com/fluxcd/notification-controller/pull/1041)
- Various dependency updates
[#1002](https://github.com/fluxcd/notification-controller/pull/1002)
[#1016](https://github.com/fluxcd/notification-controller/pull/1016)
[#1023](https://github.com/fluxcd/notification-controller/pull/1023)
[#1025](https://github.com/fluxcd/notification-controller/pull/1025)
[#1027](https://github.com/fluxcd/notification-controller/pull/1027)
[#1032](https://github.com/fluxcd/notification-controller/pull/1032)
[#1036](https://github.com/fluxcd/notification-controller/pull/1036)
[#1037](https://github.com/fluxcd/notification-controller/pull/1037)
[#1042](https://github.com/fluxcd/notification-controller/pull/1042)
## 1.4.0
**Release date:** 2024-09-27
This minor release comes with various bug fixes and improvements.
MS Teams Provider has been updated to support MS Adaptive Card payloads.
This allows users to migrate from the deprecated
[Office 365 Connector for Incoming Webhooks](https://devblogs.microsoft.com/microsoft365dev/retirement-of-office-365-connectors-within-microsoft-teams/)
to the new [Microsoft Teams Incoming Webhooks with Workflows](https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498).
See the [Provider API documentation](https://fluxcd.io/flux/components/notification/providers/#microsoft-teams)
for more information. After getting the URL for the new Incoming Webhook Workflow,
update the secret used by the `msteams` Provider object with the new URL.
In addition, the Kubernetes dependencies have been updated to v1.31.1 and
various other controller dependencies have been updated to their latest
version. The controller is now built with Go 1.23.
Fixes:
- telegram notifier should escape with metadata key
[#829](https://github.com/fluxcd/notification-controller/pull/829)
- docs: use stringData for secret of GitHub PAT
[#873](https://github.com/fluxcd/notification-controller/pull/873)
- Fix incorrect use of format strings with the conditions package.
[#879](https://github.com/fluxcd/notification-controller/pull/879)
Improvements:
- New flag to disable detailed metrics for path
[#841](https://github.com/fluxcd/notification-controller/pull/841)
- Fix telegram test flake
[#894](https://github.com/fluxcd/notification-controller/pull/894)
- Build with Go 1.23
[#907](https://github.com/fluxcd/notification-controller/pull/907)
- Add MS Adaptive Card payload to msteams Provider
[#920](https://github.com/fluxcd/notification-controller/pull/920)
- Various dependency updates
[#845](https://github.com/fluxcd/notification-controller/pull/845)
[#855](https://github.com/fluxcd/notification-controller/pull/855)
[#854](https://github.com/fluxcd/notification-controller/pull/854)
[#857](https://github.com/fluxcd/notification-controller/pull/857)
[#865](https://github.com/fluxcd/notification-controller/pull/865)
[#866](https://github.com/fluxcd/notification-controller/pull/866)
[#905](https://github.com/fluxcd/notification-controller/pull/905)
[#903](https://github.com/fluxcd/notification-controller/pull/903)
[#912](https://github.com/fluxcd/notification-controller/pull/912)
[#925](https://github.com/fluxcd/notification-controller/pull/925)
[#931](https://github.com/fluxcd/notification-controller/pull/931)
[#932](https://github.com/fluxcd/notification-controller/pull/932)
[#933](https://github.com/fluxcd/notification-controller/pull/933)
[#934](https://github.com/fluxcd/notification-controller/pull/934)
## 1.3.0
**Release date:** 2024-05-06
This minor release comes with new features, improvements and bug fixes.
The `Receiver` API has been extended to support CDEvents,
for more information, please see the
[CDEvents Receiver API documentation](https://github.com/fluxcd/notification-controller/blob/release/v1.3.x/docs/spec/v1/receivers.md#cdevents).
Starting with this version, the controller allows grouping alerts for Alertmanager
by setting the `startsAt` label instead of `timestamp`. When sending alerts to
OpsGenie, the controller now sets the `severity` field to the alert's details.
In addition, the controller dependencies have been updated to Kubernetes v1.30
and controller-runtime v0.18. Various other dependencies have also been updated to
their latest version to patch upstream CVEs.
Lastly, the controller is now built with Go 1.22.
Improvements:
- Add CDEvent Receiver Support
[#772](https://github.com/fluxcd/notification-controller/pull/772)
- Add severity to opsgenie alerts
[#796](https://github.com/fluxcd/notification-controller/pull/796)
- Alertmanager: Change timestamp label to .StartsAt
[#795](https://github.com/fluxcd/notification-controller/pull/795)
- Use `password` as fallback for the Git provider `token` auth
[#790](https://github.com/fluxcd/notification-controller/pull/790)
- Add support for Bitbucket Context path
[#747](https://github.com/fluxcd/notification-controller/pull/747)
- Various dependency updates
[#816](https://github.com/fluxcd/notification-controller/pull/816)
[#814](https://github.com/fluxcd/notification-controller/pull/814)
[#813](https://github.com/fluxcd/notification-controller/pull/813)
[#810](https://github.com/fluxcd/notification-controller/pull/810)
[#809](https://github.com/fluxcd/notification-controller/pull/809)
[#787](https://github.com/fluxcd/notification-controller/pull/787)
[#783](https://github.com/fluxcd/notification-controller/pull/783)
[#763](https://github.com/fluxcd/notification-controller/pull/763)
Fixes:
- Sanitize provider data loaded from secret
[#789](https://github.com/fluxcd/notification-controller/pull/789)
- Fix timeout propagation for alerts
[#757](https://github.com/fluxcd/notification-controller/pull/757)
- Fix Telegram MarkdownV2 escaping
[#776](https://github.com/fluxcd/notification-controller/pull/776)
- Remove `genclient:Namespaced` tag
[#749](https://github.com/fluxcd/notification-controller/pull/749)
## 1.2.4
**Release date:** 2024-02-01
This patch release fixes various issues, updates the Kubernetes dependencies
to v1.28.6 and various other dependencies to their latest version to patch
upstream CVEs.
Improvements:
- Various dependency updates
[#727](https://github.com/fluxcd/notification-controller/pull/727)
[#726](https://github.com/fluxcd/notification-controller/pull/726)
[#721](https://github.com/fluxcd/notification-controller/pull/721)
[#718](https://github.com/fluxcd/notification-controller/pull/718)
[#707](https://github.com/fluxcd/notification-controller/pull/707)
[#695](https://github.com/fluxcd/notification-controller/pull/695)
Fixes:
- Fix BitBucket status update panic
[#722](https://github.com/fluxcd/notification-controller/pull/722)
- fix typo in docs/spec/v1beta3/providers.md
[#699](https://github.com/fluxcd/notification-controller/pull/699)
- fix(grafana-provider): replace ":" character in eventMetadata
[#703](https://github.com/fluxcd/notification-controller/pull/703)
- Remove old/incorrect API version usage
[#693](https://github.com/fluxcd/notification-controller/pull/693)
## 1.2.3
**Release date:** 2023-12-14
This patch release fixes various issues, most notably, the Provider v1beta3 API
backwards compatibility issue when `.spec.interval` was explicitly set in a
v1beta2 version of Provider.
Fixes:
- Exclude eventv1.MetaTokenKey from event metadata
[#686](https://github.com/fluxcd/notification-controller/pull/686)
- Add .spec.interval in v1beta3 Provider
[#683](https://github.com/fluxcd/notification-controller/pull/683)
- Remove URL syntax validation for provider address entirely
[#682](https://github.com/fluxcd/notification-controller/pull/682)
## 1.2.2
**Release date:** 2023-12-11
This patch releases updates a variety of dependencies, including an update of
the container base image to Alpine v3.19.
Improvements:
- build: update Alpine to 3.19
[#675](https://github.com/fluxcd/notification-controller/pull/675)
- Update dependencies
[#677](https://github.com/fluxcd/notification-controller/pull/677)
## 1.2.1
**Release date:** 2023-12-08
This patch release updates the Go version the controller is built with to
`1.21.x`, while mitigating recently published security vulnerabilities in the
`net/http` package.
In addition, it ensures static analyzers no longer detect a vulnerability in the
`whilp/git-urls` module by using `chainguard-dev/git-urls`. For which the
(potential) issue itself got already addressed internally in the [previous
v1.2.0 release](#120).
Lastly, a small number of dependencies got updated to their latest versions.
Improvements:
- Update Go to 1.21.x
[#666](https://github.com/fluxcd/notification-controller/pull/666)
- Replace whilp/git-urls module by chainguard-dev/git-urls
[#667](https://github.com/fluxcd/notification-controller/pull/667)
- Update dependencies
[#669](https://github.com/fluxcd/notification-controller/pull/669)
## 1.2.0
**Release date:** 2023-12-05
This minor release graduates the notification `Alert` and `Provider` APIs to
`v1beta3`. In addition, this version comes with alert Provider support for
[BitBucket
Server](https://github.com/fluxcd/notification-controller/blob/api/v1.2.0/docs/spec/v1beta3/providers.md#bitbucket-serverdata-center)
and
[NATS](https://github.com/fluxcd/notification-controller/blob/api/v1.2.0/docs/spec/v1beta3/providers.md#nats).
### `notification.toolkit.fluxcd.io/v1beta3`
After upgrading the controller to v1.2.0, please update the notification Custom
Resources for `Alert` and `Provider` in Git by replacing
`notification.toolkit.fluxcd.io/v1beta2` with
`notification.toolkit.fluxcd.io/v1beta3` in all the YAML manifests.
#### Static Alerts and Providers
The notification Alert and Provider API resources will become static objects
with configurations that will be used by the event handlers for processing the
respective incoming events. They will no longer be reconciled by a reconciler
and will not advertise any status. Once `Alerts` and `Providers` are created,
they can be considered ready. Users of
[kstatus](https://github.com/kubernetes-sigs/cli-utils/blob/master/pkg/kstatus/README.md)
shouldn't see any difference. Existing `Alerts` and `Providers` objects in
`v1beta2` API will undergo a one-time automatic migration to be converted into
static objects without any status.
#### Enhanced Alert events
The event handler will emit Kubernetes native events on the respective Alert
object for any relevant information, including failures due to any
misconfiguration.
Improvements:
- Add Provider for NATS Subject
[#651](https://github.com/fluxcd/notification-controller/pull/651)
- Cap provider address at 2048 bytes
[#654](https://github.com/fluxcd/notification-controller/pull/654)
- Refactor events and introduce v1beta3 API for Alert and Provider
[#540](https://github.com/fluxcd/notification-controller/pull/540)
- Add Bitbucket server/Bitbucket Data Center provider for git commit status
[#639](https://github.com/fluxcd/notification-controller/pull/639)
- Address miscellaneous issues throughout code base
[#627](https://github.com/fluxcd/notification-controller/pull/627)
- Update dependencies
[#609](https://github.com/fluxcd/notification-controller/pull/609)
[#612](https://github.com/fluxcd/notification-controller/pull/612)
[#613](https://github.com/fluxcd/notification-controller/pull/613)
[#617](https://github.com/fluxcd/notification-controller/pull/617)
[#621](https://github.com/fluxcd/notification-controller/pull/621)
[#623](https://github.com/fluxcd/notification-controller/pull/623)
[#628](https://github.com/fluxcd/notification-controller/pull/628)
[#629](https://github.com/fluxcd/notification-controller/pull/629)
[#632](https://github.com/fluxcd/notification-controller/pull/632)
[#635](https://github.com/fluxcd/notification-controller/pull/635)
[#637](https://github.com/fluxcd/notification-controller/pull/637)
[#641](https://github.com/fluxcd/notification-controller/pull/641)
[#643](https://github.com/fluxcd/notification-controller/pull/643)
[#646](https://github.com/fluxcd/notification-controller/pull/646)
[#648](https://github.com/fluxcd/notification-controller/pull/648)
[#652](https://github.com/fluxcd/notification-controller/pull/652)
[#656](https://github.com/fluxcd/notification-controller/pull/656)
[#657](https://github.com/fluxcd/notification-controller/pull/657)
Fixes:
- Fix README.md links to notification APIs
[#619](https://github.com/fluxcd/notification-controller/pull/619)
## 1.1.0
**Release date:** 2023-08-23

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.17
- Go >= 1.24
You can run the test suite by simply doing:

View File

@ -1,9 +1,9 @@
ARG GO_VERSION=1.20
ARG XX_VERSION=1.2.1
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}-alpine as builder
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS builder
# Copy the build utilities.
COPY --from=xx / /
@ -30,7 +30,7 @@ COPY internal/ internal/
ENV CGO_ENABLED=0
RUN xx-go build -trimpath -a -o notification-controller main.go
FROM alpine:3.18
FROM alpine:3.21
ARG TARGETPLATFORM

View File

@ -7,4 +7,6 @@ as listed in
https://github.com/fluxcd/flux2/blob/main/MAINTAINERS
Somtochi Onyekwere, Weaveworks <somtochi@weave.works> (github: @SomtochiAma, slack: somtoxhi)
In alphabetical order:
Somtochi Onyekwere, Independent <somtochionyekwere@gmail.com> (github: @somtochiama, slack: somtochiama)

View File

@ -2,14 +2,14 @@
IMG ?= fluxcd/notification-controller:latest
# Produce CRDs that work back to Kubernetes 1.16
CRD_OPTIONS ?= crd:crdVersions=v1
SOURCE_VER ?= v1.1.2
SOURCE_VER ?= v1.2.4
# Repository root based on Git metadata
REPOSITORY_ROOT := $(shell git rev-parse --show-toplevel)
BUILD_DIR := $(REPOSITORY_ROOT)/build
# API (doc) generation utilities
CONTROLLER_GEN_VERSION ?= v0.12.0
CONTROLLER_GEN_VERSION ?= v0.16.1
GEN_API_REF_DOCS_VERSION ?= e327d0730470cbd61b06300f81c5fcf91c23c113
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
@ -93,8 +93,8 @@ api-docs: gen-crd-api-reference-docs
# Run go mod tidy
tidy:
cd api; rm -f go.sum; go mod tidy -compat=1.20
rm -f go.sum; go mod tidy -compat=1.20
cd api; rm -f go.sum; go mod tidy -compat=1.24
rm -f go.sum; go mod tidy -compat=1.24
# Run go fmt against code
fmt:
@ -153,13 +153,13 @@ fuzz-native:
./tests/fuzz/native_go_run.sh
# Find or download controller-gen
CONTROLLER_GEN = $(shell pwd)/bin/controller-gen
CONTROLLER_GEN = $(GOBIN)/controller-gen
.PHONY: controller-gen
controller-gen: ## Download controller-gen locally if necessary.
$(call go-install-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION))
# Find or download gen-crd-api-reference-docs
GEN_CRD_API_REFERENCE_DOCS = $(shell pwd)/bin/gen-crd-api-reference-docs
GEN_CRD_API_REFERENCE_DOCS = $(GOBIN)/gen-crd-api-reference-docs
.PHONY: gen-crd-api-reference-docs
gen-crd-api-reference-docs:
$(call go-install-tool,$(GEN_CRD_API_REFERENCE_DOCS),github.com/ahmetb/gen-crd-api-reference-docs@$(GEN_API_REF_DOCS_VERSION))
@ -171,7 +171,7 @@ install-envtest: setup-envtest
mkdir -p ${ENVTEST_ASSETS_DIR}
$(ENVTEST) use $(ENVTEST_KUBERNETES_VERSION) --arch=$(ENVTEST_ARCH) --bin-dir=$(ENVTEST_ASSETS_DIR)
ENVTEST = $(shell pwd)/bin/setup-envtest
ENVTEST = $(GOBIN)/setup-envtest
.PHONY: envtest
setup-envtest: ## Download envtest-setup locally if necessary.
$(call go-install-tool,$(ENVTEST),sigs.k8s.io/controller-runtime/tools/setup-envtest@latest)
@ -185,7 +185,7 @@ TMP_DIR=$$(mktemp -d) ;\
cd $$TMP_DIR ;\
go mod init tmp ;\
echo "Downloading $(2)" ;\
GOBIN=$(PROJECT_DIR)/bin go install $(2) ;\
GOBIN=$(GOBIN) go install $(2) ;\
rm -rf $$TMP_DIR ;\
}
endef

View File

@ -7,7 +7,7 @@
[![release](https://img.shields.io/github/release/fluxcd/notification-controller/all.svg)](https://github.com/fluxcd/notification-controller/releases)
Event forwarder and notification dispatcher for the [GitOps Toolkit](https://fluxcd.io/flux/components/) controllers.
The notification-controller is an implementation of the [notification.toolkit.fluxcd.io](docs/spec/v1beta1/README.md)
The notification-controller is an implementation of the [notification.toolkit.fluxcd.io](docs/spec/v1beta3/README.md)
API based on the specifications described in the [RFC](docs/spec/README.md).
![overview](docs/diagrams/notification-controller-overview.png)

View File

@ -1,31 +1,35 @@
module github.com/fluxcd/notification-controller/api
go 1.20
go 1.24.0
require (
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/meta v1.18.0
k8s.io/apimachinery v0.33.2
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.3.0 // 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.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/text v0.27.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-20230726121419-3b25d923346b // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // 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.5.0 // indirect
)

View File

@ -2,26 +2,29 @@ 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/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.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/fluxcd/pkg/apis/meta v1.18.0 h1:ACHrMIjlcioE9GKS7NGk62KX4NshqNewr8sBwMcXABs=
github.com/fluxcd/pkg/apis/meta v1.18.0/go.mod h1:97l3hTwBpJbXBY+wetNbqrUsvES8B1jGioKcBUxmqd8=
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=
@ -31,17 +34,28 @@ 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=
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -51,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.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
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.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
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.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
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.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
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=
@ -78,21 +94,25 @@ 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-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/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.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
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.2 h1:IHFVhqg59mb8PJWTLi8m1mAoepkUNYmptHsV+Z1m5jY=
k8s.io/apimachinery v0.33.2/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/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ=
sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4=

View File

@ -40,13 +40,14 @@ const (
GCRReceiver string = "gcr"
NexusReceiver string = "nexus"
ACRReceiver string = "acr"
CDEventsReceiver string = "cdevents"
)
// ReceiverSpec defines the desired state of the Receiver.
type ReceiverSpec struct {
// Type of webhook sender, used to determine
// the validation procedure and payload deserialization.
// +kubebuilder:validation:Enum=generic;generic-hmac;github;gitlab;bitbucket;harbor;dockerhub;quay;gcr;nexus;acr
// +kubebuilder:validation:Enum=generic;generic-hmac;github;gitlab;bitbucket;harbor;dockerhub;quay;gcr;nexus;acr;cdevents
// +required
Type string `json:"type"`
@ -66,6 +67,16 @@ type ReceiverSpec struct {
// +required
Resources []CrossNamespaceObjectReference `json:"resources"`
// ResourceFilter is a CEL expression expected to return a boolean that is
// evaluated for each resource referenced in the Resources field when a
// webhook is received. If the expression returns false then the controller
// will not request a reconciliation for the resource.
// When the expression is specified the controller will parse it and mark
// the object as terminally failed if the expression is invalid or does not
// return a boolean.
// +optional
ResourceFilter string `json:"resourceFilter,omitempty"`
// SecretRef specifies the Secret containing the token used
// to validate the payload authenticity.
// +required
@ -122,7 +133,6 @@ func (in *Receiver) GetInterval() time.Duration {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status

View File

@ -31,13 +31,13 @@ type CrossNamespaceObjectReference struct {
// Name of the referent
// If multiple resources are targeted `*` may be set.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=53
// +kubebuilder:validation:MaxLength=253
// +required
Name string `json:"name"`
// Namespace of the referent
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=53
// +kubebuilder:validation:MaxLength=253
// +kubebuilder:validation:Optional
// +optional
Namespace string `json:"namespace,omitempty"`

View File

@ -1,5 +1,4 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 2023 The Flux authors

View File

@ -67,13 +67,8 @@ type AlertStatus struct {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta1 Alert is deprecated, upgrade to v1beta3"
// +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=""
// +kubebuilder:skipversion
// Alert is the Schema for the alerts API
type Alert struct {

View File

@ -15,6 +15,9 @@ limitations under the License.
*/
// Package v1beta1 contains API Schema definitions for the notification v1beta1 API group
//
// Deprecated: v1beta1 is no longer supported, use v1 and v1beta3 instead.
//
// +kubebuilder:object:generate=true
// +groupName=notification.toolkit.fluxcd.io
package v1beta1

View File

@ -110,13 +110,8 @@ type ProviderStatus struct {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta1 Provider is deprecated, upgrade to v1beta3"
// +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=""
// +kubebuilder:skipversion
// Provider is the Schema for the providers API
type Provider struct {

View File

@ -97,13 +97,8 @@ func (in *Receiver) SetConditions(conditions []metav1.Condition) {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta1 Receiver is deprecated, upgrade to v1"
// +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=""
// +kubebuilder:skipversion
// Receiver is the Schema for the receivers API
type Receiver struct {

View File

@ -1,5 +1,4 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 2023 The Flux authors

View File

@ -88,7 +88,6 @@ type AlertStatus struct {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta2 Alert is deprecated, upgrade to v1beta3"

View File

@ -131,7 +131,6 @@ type ProviderStatus struct {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta2 Provider is deprecated, upgrade to v1beta3"

View File

@ -129,7 +129,6 @@ func (in *Receiver) GetInterval() time.Duration {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta2 Receiver is deprecated, upgrade to v1"

View File

@ -1,5 +1,4 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 2023 The Flux authors

View File

@ -64,8 +64,11 @@ type AlertSpec struct {
ExclusionList []string `json:"exclusionList,omitempty"`
// Summary holds a short description of the impact and affected cluster.
// Deprecated: Use EventMetadata instead.
//
// +kubebuilder:validation:MaxLength:=255
// +optional
// +deprecated
Summary string `json:"summary,omitempty"`
// Suspend tells the controller to suspend subsequent
@ -75,7 +78,6 @@ type AlertSpec struct {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""

View File

@ -55,12 +55,22 @@ const (
)
// ProviderSpec defines the desired state of the Provider.
// +kubebuilder:validation:XValidation:rule="self.type == 'github' || self.type == 'gitlab' || self.type == 'gitea' || self.type == 'bitbucketserver' || self.type == 'bitbucket' || self.type == 'azuredevops' || !has(self.commitStatusExpr)", message="spec.commitStatusExpr is only supported for the 'github', 'gitlab', 'gitea', 'bitbucketserver', 'bitbucket', 'azuredevops' provider types"
type ProviderSpec struct {
// Type specifies which Provider implementation to use.
// +kubebuilder:validation:Enum=slack;discord;msteams;rocket;generic;generic-hmac;github;gitlab;gitea;bitbucketserver;bitbucket;azuredevops;googlechat;googlepubsub;webex;sentry;azureeventhub;telegram;lark;matrix;opsgenie;alertmanager;grafana;githubdispatch;pagerduty;datadog;nats
// +required
Type string `json:"type"`
// Interval at which to reconcile the Provider with its Secret references.
// Deprecated and not used in v1beta3.
//
// +kubebuilder:validation:Type=string
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ms|s|m|h))+$"
// +optional
// +deprecated
Interval *metav1.Duration `json:"interval,omitempty"`
// Channel specifies the destination channel where events should be posted.
// +kubebuilder:validation:MaxLength:=2048
// +optional
@ -87,33 +97,72 @@ type ProviderSpec struct {
Timeout *metav1.Duration `json:"timeout,omitempty"`
// Proxy the HTTP/S address of the proxy server.
// Deprecated: Use ProxySecretRef instead. Will be removed in v1.
// +kubebuilder:validation:Pattern="^(http|https)://.*$"
// +kubebuilder:validation:MaxLength:=2048
// +kubebuilder:validation:Optional
// +optional
Proxy string `json:"proxy,omitempty"`
// ProxySecretRef specifies the Secret containing the proxy configuration
// for this Provider. The Secret should contain an 'address' key with the
// HTTP/S address of the proxy server. Optional 'username' and 'password'
// keys can be provided for proxy authentication.
// +optional
ProxySecretRef *meta.LocalObjectReference `json:"proxySecretRef,omitempty"`
// SecretRef specifies the Secret containing the authentication
// credentials for this Provider.
// +optional
SecretRef *meta.LocalObjectReference `json:"secretRef,omitempty"`
// CertSecretRef specifies the Secret containing
// a PEM-encoded CA certificate (in the `ca.crt` key).
// +optional
// ServiceAccountName is the name of the Kubernetes ServiceAccount used to
// authenticate with cloud provider services through workload identity.
// This enables multi-tenant authentication without storing static credentials.
//
// Note: Support for the `caFile` key has
// been deprecated.
// Supported provider types: azureeventhub, azuredevops, googlepubsub
//
// When specified, the controller will:
// 1. Create an OIDC token for the specified ServiceAccount
// 2. Exchange it for cloud provider credentials via STS
// 3. Use the obtained credentials for API authentication
//
// When unspecified, controller-level authentication is used (single-tenant).
//
// An error is thrown if static credentials are also defined in SecretRef.
// This field requires the ObjectLevelWorkloadIdentity feature gate to be enabled.
//
// +optional
ServiceAccountName string `json:"serviceAccountName,omitempty"`
// CertSecretRef specifies the Secret containing TLS certificates
// for secure communication.
//
// Supported configurations:
// - CA-only: Server authentication (provide ca.crt only)
// - mTLS: Mutual authentication (provide ca.crt + tls.crt + tls.key)
// - Client-only: Client authentication with system CA (provide tls.crt + tls.key only)
//
// Legacy keys "caFile", "certFile", "keyFile" are supported but deprecated. Use "ca.crt", "tls.crt", "tls.key" instead.
//
// +optional
CertSecretRef *meta.LocalObjectReference `json:"certSecretRef,omitempty"`
// Suspend tells the controller to suspend subsequent
// events handling for this Provider.
// +optional
Suspend bool `json:"suspend,omitempty"`
// CommitStatusExpr is a CEL expression that evaluates to a string value
// that can be used to generate a custom commit status message for use
// with eligible Provider types (github, gitlab, gitea, bitbucketserver,
// bitbucket, azuredevops). Supported variables are: event, provider,
// and alert.
// +optional
CommitStatusExpr string `json:"commitStatusExpr,omitempty"`
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:storageversion
// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""

View File

@ -1,5 +1,4 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright 2023 The Flux authors
@ -187,11 +186,21 @@ func (in *ProviderList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ProviderSpec) DeepCopyInto(out *ProviderSpec) {
*out = *in
if in.Interval != nil {
in, out := &in.Interval, &out.Interval
*out = new(metav1.Duration)
**out = **in
}
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
*out = new(metav1.Duration)
**out = **in
}
if in.ProxySecretRef != nil {
in, out := &in.ProxySecretRef, &out.ProxySecretRef
*out = new(meta.LocalObjectReference)
**out = **in
}
if in.SecretRef != nil {
in, out := &in.SecretRef, &out.SecretRef
*out = new(meta.LocalObjectReference)

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: alerts.notification.toolkit.fluxcd.io
spec:
group: notification.toolkit.fluxcd.io
@ -14,202 +14,6 @@ spec:
singular: alert
scope: Namespaced
versions:
- additionalPrinterColumns:
- 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
deprecated: true
deprecationWarning: v1beta1 Alert is deprecated, upgrade to v1beta3
name: v1beta1
schema:
openAPIV3Schema:
description: Alert is the Schema for the alerts 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: AlertSpec defines an alerting rule for events involving a
list of objects
properties:
eventSeverity:
default: info
description: Filter events based on severity, defaults to ('info').
If set to 'info' no events will be filtered.
enum:
- info
- error
type: string
eventSources:
description: Filter events based on the involved objects.
items:
description: CrossNamespaceObjectReference contains enough information
to let you locate the typed referenced object at cluster level
properties:
apiVersion:
description: API version of the referent
type: string
kind:
description: Kind of the referent
enum:
- Bucket
- GitRepository
- Kustomization
- HelmRelease
- HelmChart
- HelmRepository
- ImageRepository
- ImagePolicy
- ImageUpdateAutomation
- OCIRepository
type: string
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
name:
description: Name of the referent
maxLength: 53
minLength: 1
type: string
namespace:
description: Namespace of the referent
maxLength: 53
minLength: 1
type: string
required:
- name
type: object
type: array
exclusionList:
description: A list of Golang regular expressions to be used for excluding
messages.
items:
type: string
type: array
providerRef:
description: Send events using this provider.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
summary:
description: Short description of the impact and affected cluster.
type: string
suspend:
description: This flag tells the controller to suspend subsequent
events dispatching. Defaults to false.
type: boolean
required:
- eventSources
- providerRef
type: object
status:
default:
observedGeneration: -1
description: AlertStatus defines the observed state of Alert
properties:
conditions:
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 }"
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.
--- 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
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
observedGeneration:
description: ObservedGeneration is the last observed generation.
format: int64
type: integer
type: object
type: object
served: true
storage: false
subresources:
status: {}
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
@ -228,14 +32,19 @@ spec:
description: Alert is the Schema for the alerts 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
@ -246,27 +55,30 @@ spec:
eventMetadata:
additionalProperties:
type: string
description: EventMetadata is an optional field for adding metadata
to events dispatched by the controller. This can be used for enhancing
the context of the event. If a field would override one already
present on the original event as generated by the emitter, then
the override doesn't happen, i.e. the original value is preserved,
and an info log is printed.
description: |-
EventMetadata is an optional field for adding metadata to events dispatched by the
controller. This can be used for enhancing the context of the event. If a field
would override one already present on the original event as generated by the emitter,
then the override doesn't happen, i.e. the original value is preserved, and an info
log is printed.
type: object
eventSeverity:
default: info
description: EventSeverity specifies how to filter events based on
severity. If set to 'info' no events will be filtered.
description: |-
EventSeverity specifies how to filter events based on severity.
If set to 'info' no events will be filtered.
enum:
- info
- error
type: string
eventSources:
description: EventSources specifies how to filter events based on
the involved object kind, name and namespace.
description: |-
EventSources specifies how to filter events based
on the involved object kind, name and namespace.
items:
description: CrossNamespaceObjectReference contains enough information
to let you locate the typed referenced object at cluster level
description: |-
CrossNamespaceObjectReference contains enough information to let you locate the
typed referenced object at cluster level
properties:
apiVersion:
description: API version of the referent
@ -288,21 +100,22 @@ spec:
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. MatchLabels requires the name to be set to `*`.
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.
MatchLabels requires the name to be set to `*`.
type: object
name:
description: Name of the referent If multiple resources are
targeted `*` may be set.
maxLength: 53
description: |-
Name of the referent
If multiple resources are targeted `*` may be set.
maxLength: 253
minLength: 1
type: string
namespace:
description: Namespace of the referent
maxLength: 53
maxLength: 253
minLength: 1
type: string
required:
@ -311,13 +124,15 @@ spec:
type: object
type: array
exclusionList:
description: ExclusionList specifies a list of Golang regular expressions
description: |-
ExclusionList specifies a list of Golang regular expressions
to be used for excluding messages.
items:
type: string
type: array
inclusionList:
description: InclusionList specifies a list of Golang regular expressions
description: |-
InclusionList specifies a list of Golang regular expressions
to be used for including messages.
items:
type: string
@ -338,8 +153,9 @@ spec:
maxLength: 255
type: string
suspend:
description: Suspend tells the controller to suspend subsequent events
handling for this Alert.
description: |-
Suspend tells the controller to suspend subsequent
events handling for this Alert.
type: boolean
required:
- eventSources
@ -353,43 +169,35 @@ spec:
conditions:
description: Conditions holds the conditions for the Alert.
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
@ -404,10 +212,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
@ -420,9 +224,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.
@ -444,14 +249,19 @@ spec:
description: Alert is the Schema for the alerts 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
@ -462,27 +272,30 @@ spec:
eventMetadata:
additionalProperties:
type: string
description: EventMetadata is an optional field for adding metadata
to events dispatched by the controller. This can be used for enhancing
the context of the event. If a field would override one already
present on the original event as generated by the emitter, then
the override doesn't happen, i.e. the original value is preserved,
and an info log is printed.
description: |-
EventMetadata is an optional field for adding metadata to events dispatched by the
controller. This can be used for enhancing the context of the event. If a field
would override one already present on the original event as generated by the emitter,
then the override doesn't happen, i.e. the original value is preserved, and an info
log is printed.
type: object
eventSeverity:
default: info
description: EventSeverity specifies how to filter events based on
severity. If set to 'info' no events will be filtered.
description: |-
EventSeverity specifies how to filter events based on severity.
If set to 'info' no events will be filtered.
enum:
- info
- error
type: string
eventSources:
description: EventSources specifies how to filter events based on
the involved object kind, name and namespace.
description: |-
EventSources specifies how to filter events based
on the involved object kind, name and namespace.
items:
description: CrossNamespaceObjectReference contains enough information
to let you locate the typed referenced object at cluster level
description: |-
CrossNamespaceObjectReference contains enough information to let you locate the
typed referenced object at cluster level
properties:
apiVersion:
description: API version of the referent
@ -504,21 +317,22 @@ spec:
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. MatchLabels requires the name to be set to `*`.
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.
MatchLabels requires the name to be set to `*`.
type: object
name:
description: Name of the referent If multiple resources are
targeted `*` may be set.
maxLength: 53
description: |-
Name of the referent
If multiple resources are targeted `*` may be set.
maxLength: 253
minLength: 1
type: string
namespace:
description: Namespace of the referent
maxLength: 53
maxLength: 253
minLength: 1
type: string
required:
@ -527,13 +341,15 @@ spec:
type: object
type: array
exclusionList:
description: ExclusionList specifies a list of Golang regular expressions
description: |-
ExclusionList specifies a list of Golang regular expressions
to be used for excluding messages.
items:
type: string
type: array
inclusionList:
description: InclusionList specifies a list of Golang regular expressions
description: |-
InclusionList specifies a list of Golang regular expressions
to be used for including messages.
items:
type: string
@ -549,13 +365,15 @@ spec:
- name
type: object
summary:
description: Summary holds a short description of the impact and affected
cluster.
description: |-
Summary holds a short description of the impact and affected cluster.
Deprecated: Use EventMetadata instead.
maxLength: 255
type: string
suspend:
description: Suspend tells the controller to suspend subsequent events
handling for this Alert.
description: |-
Suspend tells the controller to suspend subsequent
events handling for this Alert.
type: boolean
required:
- eventSources

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: providers.notification.toolkit.fluxcd.io
spec:
group: notification.toolkit.fluxcd.io
@ -14,191 +14,6 @@ spec:
singular: provider
scope: Namespaced
versions:
- additionalPrinterColumns:
- 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
deprecated: true
deprecationWarning: v1beta1 Provider is deprecated, upgrade to v1beta3
name: v1beta1
schema:
openAPIV3Schema:
description: Provider is the Schema for the providers 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: ProviderSpec defines the desired state of Provider
properties:
address:
description: HTTP/S webhook address of this provider
pattern: ^(http|https)://
type: string
certSecretRef:
description: CertSecretRef can be given the name of a secret containing
a PEM-encoded CA certificate (`caFile`)
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
channel:
description: Alert channel for this provider
type: string
proxy:
description: HTTP/S address of the proxy
pattern: ^(http|https)://
type: string
secretRef:
description: Secret reference containing the provider webhook URL
using "address" as data key
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
suspend:
description: This flag tells the controller to suspend subsequent
events handling. Defaults to false.
type: boolean
timeout:
description: Timeout for sending alerts to the provider.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$
type: string
type:
description: Type of provider
enum:
- slack
- discord
- msteams
- rocket
- generic
- generic-hmac
- github
- gitlab
- bitbucket
- azuredevops
- googlechat
- webex
- sentry
- azureeventhub
- telegram
- lark
- matrix
- opsgenie
- alertmanager
- grafana
- githubdispatch
type: string
username:
description: Bot username for this provider
type: string
required:
- type
type: object
status:
default:
observedGeneration: -1
description: ProviderStatus defines the observed state of Provider
properties:
conditions:
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 }"
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.
--- 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
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
observedGeneration:
description: ObservedGeneration is the last reconciled generation.
format: int64
type: integer
type: object
type: object
served: true
storage: false
subresources:
status: {}
- additionalPrinterColumns:
- jsonPath: .metadata.creationTimestamp
name: Age
@ -217,14 +32,19 @@ spec:
description: Provider is the Schema for the providers 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
@ -232,17 +52,20 @@ spec:
description: ProviderSpec defines the desired state of the Provider.
properties:
address:
description: Address specifies the endpoint, in a generic sense, to
where alerts are sent. What kind of endpoint depends on the specific
Provider type being used. For the generic Provider, for example,
this is an HTTP/S address. For other Provider types this could be
a project ID or a namespace.
description: |-
Address specifies the endpoint, in a generic sense, to where alerts are sent.
What kind of endpoint depends on the specific Provider type being used.
For the generic Provider, for example, this is an HTTP/S address.
For other Provider types this could be a project ID or a namespace.
maxLength: 2048
type: string
certSecretRef:
description: "CertSecretRef specifies the Secret containing a PEM-encoded
CA certificate (in the `ca.crt` key). \n Note: Support for the `caFile`
key has been deprecated."
description: |-
CertSecretRef specifies the Secret containing
a PEM-encoded CA certificate (in the `ca.crt` key).
Note: Support for the `caFile` key has
been deprecated.
properties:
name:
description: Name of the referent.
@ -266,7 +89,8 @@ spec:
pattern: ^(http|https)://.*$
type: string
secretRef:
description: SecretRef specifies the Secret containing the authentication
description: |-
SecretRef specifies the Secret containing the authentication
credentials for this Provider.
properties:
name:
@ -276,8 +100,9 @@ spec:
- name
type: object
suspend:
description: Suspend tells the controller to suspend subsequent events
handling for this Provider.
description: |-
Suspend tells the controller to suspend subsequent
events handling for this Provider.
type: boolean
timeout:
description: Timeout for sending alerts to the Provider.
@ -328,43 +153,35 @@ spec:
conditions:
description: Conditions holds the conditions for the Provider.
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
@ -379,10 +196,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
@ -395,9 +208,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 reconciled generation.
@ -419,14 +233,19 @@ spec:
description: Provider is the Schema for the providers 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
@ -434,17 +253,24 @@ spec:
description: ProviderSpec defines the desired state of the Provider.
properties:
address:
description: Address specifies the endpoint, in a generic sense, to
where alerts are sent. What kind of endpoint depends on the specific
Provider type being used. For the generic Provider, for example,
this is an HTTP/S address. For other Provider types this could be
a project ID or a namespace.
description: |-
Address specifies the endpoint, in a generic sense, to where alerts are sent.
What kind of endpoint depends on the specific Provider type being used.
For the generic Provider, for example, this is an HTTP/S address.
For other Provider types this could be a project ID or a namespace.
maxLength: 2048
type: string
certSecretRef:
description: "CertSecretRef specifies the Secret containing a PEM-encoded
CA certificate (in the `ca.crt` key). \n Note: Support for the `caFile`
key has been deprecated."
description: |-
CertSecretRef specifies the Secret containing TLS certificates
for secure communication.
Supported configurations:
- CA-only: Server authentication (provide ca.crt only)
- mTLS: Mutual authentication (provide ca.crt + tls.crt + tls.key)
- Client-only: Client authentication with system CA (provide tls.crt + tls.key only)
Legacy keys "caFile", "certFile", "keyFile" are supported but deprecated. Use "ca.crt", "tls.crt", "tls.key" instead.
properties:
name:
description: Name of the referent.
@ -457,13 +283,43 @@ spec:
should be posted.
maxLength: 2048
type: string
commitStatusExpr:
description: |-
CommitStatusExpr is a CEL expression that evaluates to a string value
that can be used to generate a custom commit status message for use
with eligible Provider types (github, gitlab, gitea, bitbucketserver,
bitbucket, azuredevops). Supported variables are: event, provider,
and alert.
type: string
interval:
description: |-
Interval at which to reconcile the Provider with its Secret references.
Deprecated and not used in v1beta3.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
proxy:
description: Proxy the HTTP/S address of the proxy server.
description: |-
Proxy the HTTP/S address of the proxy server.
Deprecated: Use ProxySecretRef instead. Will be removed in v1.
maxLength: 2048
pattern: ^(http|https)://.*$
type: string
proxySecretRef:
description: |-
ProxySecretRef specifies the Secret containing the proxy configuration
for this Provider. The Secret should contain an 'address' key with the
HTTP/S address of the proxy server. Optional 'username' and 'password'
keys can be provided for proxy authentication.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
secretRef:
description: SecretRef specifies the Secret containing the authentication
description: |-
SecretRef specifies the Secret containing the authentication
credentials for this Provider.
properties:
name:
@ -472,9 +328,28 @@ spec:
required:
- name
type: object
serviceAccountName:
description: |-
ServiceAccountName is the name of the Kubernetes ServiceAccount used to
authenticate with cloud provider services through workload identity.
This enables multi-tenant authentication without storing static credentials.
Supported provider types: azureeventhub, azuredevops, googlepubsub
When specified, the controller will:
1. Create an OIDC token for the specified ServiceAccount
2. Exchange it for cloud provider credentials via STS
3. Use the obtained credentials for API authentication
When unspecified, controller-level authentication is used (single-tenant).
An error is thrown if static credentials are also defined in SecretRef.
This field requires the ObjectLevelWorkloadIdentity feature gate to be enabled.
type: string
suspend:
description: Suspend tells the controller to suspend subsequent events
handling for this Provider.
description: |-
Suspend tells the controller to suspend subsequent
events handling for this Provider.
type: boolean
timeout:
description: Timeout for sending alerts to the Provider.
@ -518,6 +393,12 @@ spec:
required:
- type
type: object
x-kubernetes-validations:
- message: spec.commitStatusExpr is only supported for the 'github', 'gitlab',
'gitea', 'bitbucketserver', 'bitbucket', 'azuredevops' provider types
rule: self.type == 'github' || self.type == 'gitlab' || self.type ==
'gitea' || self.type == 'bitbucketserver' || self.type == 'bitbucket'
|| self.type == 'azuredevops' || !has(self.commitStatusExpr)
type: object
served: true
storage: true

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: receivers.notification.toolkit.fluxcd.io
spec:
group: notification.toolkit.fluxcd.io
@ -30,14 +30,19 @@ spec:
description: Receiver is the Schema for the receivers 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
@ -45,8 +50,9 @@ spec:
description: ReceiverSpec defines the desired state of the Receiver.
properties:
events:
description: Events specifies the list of event types to handle, e.g.
'push' for GitHub or 'Push Hook' for GitLab.
description: |-
Events specifies the list of event types to handle,
e.g. 'push' for GitHub or 'Push Hook' for GitLab.
items:
type: string
type: array
@ -56,11 +62,22 @@ spec:
Secret references.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
resourceFilter:
description: |-
ResourceFilter is a CEL expression expected to return a boolean that is
evaluated for each resource referenced in the Resources field when a
webhook is received. If the expression returns false then the controller
will not request a reconciliation for the resource.
When the expression is specified the controller will parse it and mark
the object as terminally failed if the expression is invalid or does not
return a boolean.
type: string
resources:
description: A list of resources to be notified about changes.
items:
description: CrossNamespaceObjectReference contains enough information
to let you locate the typed referenced object at cluster level
description: |-
CrossNamespaceObjectReference contains enough information to let you locate the
typed referenced object at cluster level
properties:
apiVersion:
description: API version of the referent
@ -82,21 +99,22 @@ spec:
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. MatchLabels requires the name to be set to `*`.
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.
MatchLabels requires the name to be set to `*`.
type: object
name:
description: Name of the referent If multiple resources are
targeted `*` may be set.
maxLength: 53
description: |-
Name of the referent
If multiple resources are targeted `*` may be set.
maxLength: 253
minLength: 1
type: string
namespace:
description: Namespace of the referent
maxLength: 53
maxLength: 253
minLength: 1
type: string
required:
@ -105,7 +123,8 @@ spec:
type: object
type: array
secretRef:
description: SecretRef specifies the Secret containing the token used
description: |-
SecretRef specifies the Secret containing the token used
to validate the payload authenticity.
properties:
name:
@ -115,12 +134,236 @@ spec:
- name
type: object
suspend:
description: Suspend tells the controller to suspend subsequent events
handling for this receiver.
description: |-
Suspend tells the controller to suspend subsequent
events handling for this receiver.
type: boolean
type:
description: Type of webhook sender, used to determine the validation
procedure and payload deserialization.
description: |-
Type of webhook sender, used to determine
the validation procedure and payload deserialization.
enum:
- generic
- generic-hmac
- github
- gitlab
- bitbucket
- harbor
- dockerhub
- quay
- gcr
- nexus
- acr
- cdevents
type: string
required:
- resources
- secretRef
- type
type: object
status:
default:
observedGeneration: -1
description: ReceiverStatus defines the observed state of the Receiver.
properties:
conditions:
description: Conditions holds the conditions for the Receiver.
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 Receiver object.
format: int64
type: integer
webhookPath:
description: |-
WebhookPath is the generated incoming webhook address in the format
of '/hook/sha256sum(token+name+namespace)'.
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
- additionalPrinterColumns:
- 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
deprecated: true
deprecationWarning: v1beta2 Receiver is deprecated, upgrade to v1
name: v1beta2
schema:
openAPIV3Schema:
description: Receiver is the Schema for the receivers 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: ReceiverSpec defines the desired state of the Receiver.
properties:
events:
description: |-
Events specifies the list of event types to handle,
e.g. 'push' for GitHub or 'Push Hook' for GitLab.
items:
type: string
type: array
interval:
description: Interval at which to reconcile the Receiver with its
Secret references.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
resources:
description: A list of resources to be notified about changes.
items:
description: |-
CrossNamespaceObjectReference contains enough information to let you locate the
typed referenced object at cluster level
properties:
apiVersion:
description: API version of the referent
type: string
kind:
description: Kind of the referent
enum:
- Bucket
- GitRepository
- Kustomization
- HelmRelease
- HelmChart
- HelmRepository
- ImageRepository
- ImagePolicy
- ImageUpdateAutomation
- OCIRepository
type: string
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.
MatchLabels requires the name to be set to `*`.
type: object
name:
description: |-
Name of the referent
If multiple resources are targeted `*` may be set.
maxLength: 253
minLength: 1
type: string
namespace:
description: Namespace of the referent
maxLength: 253
minLength: 1
type: string
required:
- kind
- name
type: object
type: array
secretRef:
description: |-
SecretRef specifies the Secret containing the token used
to validate the payload authenticity.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
suspend:
description: |-
Suspend tells the controller to suspend subsequent
events handling for this receiver.
type: boolean
type:
description: |-
Type of webhook sender, used to determine
the validation procedure and payload deserialization.
enum:
- generic
- generic-hmac
@ -147,43 +390,35 @@ spec:
conditions:
description: Conditions holds the conditions for the Receiver.
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
@ -198,10 +433,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
@ -214,432 +445,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.
type: string
observedGeneration:
description: ObservedGeneration is the last observed generation of
the Receiver object.
format: int64
type: integer
webhookPath:
description: WebhookPath is the generated incoming webhook address
in the format of '/hook/sha256sum(token+name+namespace)'.
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
- additionalPrinterColumns:
- 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
deprecated: true
deprecationWarning: v1beta1 Receiver is deprecated, upgrade to v1
name: v1beta1
schema:
openAPIV3Schema:
description: Receiver is the Schema for the receivers 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: ReceiverSpec defines the desired state of Receiver
properties:
events:
description: A list of events to handle, e.g. 'push' for GitHub or
'Push Hook' for GitLab.
items:
type: string
type: array
resources:
description: A list of resources to be notified about changes.
items:
description: CrossNamespaceObjectReference contains enough information
to let you locate the typed referenced object at cluster level
properties:
apiVersion:
description: API version of the referent
type: string
kind:
description: Kind of the referent
enum:
- Bucket
- GitRepository
- Kustomization
- HelmRelease
- HelmChart
- HelmRepository
- ImageRepository
- ImagePolicy
- ImageUpdateAutomation
- OCIRepository
type: string
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
name:
description: Name of the referent
maxLength: 53
minLength: 1
type: string
namespace:
description: Namespace of the referent
maxLength: 53
minLength: 1
type: string
required:
- name
type: object
type: array
secretRef:
description: Secret reference containing the token used to validate
the payload authenticity
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
suspend:
description: This flag tells the controller to suspend subsequent
events handling. Defaults to false.
type: boolean
type:
description: Type of webhook sender, used to determine the validation
procedure and payload deserialization.
enum:
- generic
- generic-hmac
- github
- gitlab
- bitbucket
- harbor
- dockerhub
- quay
- gcr
- nexus
- acr
type: string
required:
- resources
- type
type: object
status:
default:
observedGeneration: -1
description: ReceiverStatus defines the observed state of Receiver
properties:
conditions:
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 }"
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.
--- 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
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
observedGeneration:
description: ObservedGeneration is the last observed generation.
format: int64
type: integer
url:
description: Generated webhook URL in the format of '/hook/sha256sum(token+name+namespace)'.
type: string
type: object
type: object
served: true
storage: false
subresources:
status: {}
- additionalPrinterColumns:
- 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
deprecated: true
deprecationWarning: v1beta2 Receiver is deprecated, upgrade to v1
name: v1beta2
schema:
openAPIV3Schema:
description: Receiver is the Schema for the receivers 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: ReceiverSpec defines the desired state of the Receiver.
properties:
events:
description: Events specifies the list of event types to handle, e.g.
'push' for GitHub or 'Push Hook' for GitLab.
items:
type: string
type: array
interval:
description: Interval at which to reconcile the Receiver with its
Secret references.
pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$
type: string
resources:
description: A list of resources to be notified about changes.
items:
description: CrossNamespaceObjectReference contains enough information
to let you locate the typed referenced object at cluster level
properties:
apiVersion:
description: API version of the referent
type: string
kind:
description: Kind of the referent
enum:
- Bucket
- GitRepository
- Kustomization
- HelmRelease
- HelmChart
- HelmRepository
- ImageRepository
- ImagePolicy
- ImageUpdateAutomation
- OCIRepository
type: string
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. MatchLabels requires the name to be set to `*`.
type: object
name:
description: Name of the referent If multiple resources are
targeted `*` may be set.
maxLength: 53
minLength: 1
type: string
namespace:
description: Namespace of the referent
maxLength: 53
minLength: 1
type: string
required:
- kind
- name
type: object
type: array
secretRef:
description: SecretRef specifies the Secret containing the token used
to validate the payload authenticity.
properties:
name:
description: Name of the referent.
type: string
required:
- name
type: object
suspend:
description: Suspend tells the controller to suspend subsequent events
handling for this receiver.
type: boolean
type:
description: Type of webhook sender, used to determine the validation
procedure and payload deserialization.
enum:
- generic
- generic-hmac
- github
- gitlab
- bitbucket
- harbor
- dockerhub
- quay
- gcr
- nexus
- acr
type: string
required:
- resources
- type
type: object
status:
default:
observedGeneration: -1
description: ReceiverStatus defines the observed state of the Receiver.
properties:
conditions:
description: Conditions holds the conditions for the Receiver.
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 }"
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.
--- 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
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.
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
@ -647,13 +456,15 @@ spec:
format: int64
type: integer
url:
description: 'URL is the generated incoming webhook address in the
format of ''/hook/sha256sum(token+name+namespace)''. Deprecated:
Replaced by WebhookPath.'
description: |-
URL is the generated incoming webhook address in the format
of '/hook/sha256sum(token+name+namespace)'.
Deprecated: Replaced by WebhookPath.
type: string
webhookPath:
description: WebhookPath is the generated incoming webhook address
in the format of '/hook/sha256sum(token+name+namespace)'.
description: |-
WebhookPath is the generated incoming webhook address in the format
of '/hook/sha256sum(token+name+namespace)'.
type: string
type: object
type: object

View File

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

View File

@ -19,6 +19,12 @@ rules:
- get
- list
- watch
- apiGroups:
- ""
resources:
- serviceaccounts/token
verbs:
- create
- apiGroups:
- image.fluxcd.io
resources:
@ -39,29 +45,7 @@ rules:
- notification.toolkit.fluxcd.io
resources:
- alerts
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- notification.toolkit.fluxcd.io
resources:
- providers
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- notification.toolkit.fluxcd.io
resources:
- receivers
verbs:
- create
@ -83,53 +67,8 @@ rules:
- source.fluxcd.io
resources:
- buckets
verbs:
- get
- list
- patch
- update
- watch
- apiGroups:
- source.fluxcd.io
resources:
- buckets/status
verbs:
- get
- apiGroups:
- source.fluxcd.io
resources:
- gitrepositories
verbs:
- get
- list
- patch
- update
- watch
- apiGroups:
- source.fluxcd.io
resources:
- gitrepositories/status
verbs:
- get
- apiGroups:
- source.fluxcd.io
resources:
- helmrepositories
verbs:
- get
- list
- patch
- update
- watch
- apiGroups:
- source.fluxcd.io
resources:
- helmrepositories/status
verbs:
- get
- apiGroups:
- source.fluxcd.io
resources:
- ocirepositories
verbs:
- get
@ -140,6 +79,9 @@ rules:
- apiGroups:
- source.fluxcd.io
resources:
- buckets/status
- gitrepositories/status
- helmrepositories/status
- ocirepositories/status
verbs:
- get

View File

@ -1,8 +0,0 @@
---
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Provider
metadata:
name: status-defaults
spec:
type: generic

View File

@ -122,6 +122,24 @@ e.g. &lsquo;push&rsquo; for GitHub or &lsquo;Push Hook&rsquo; for GitLab.</p>
</tr>
<tr>
<td>
<code>resourceFilter</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ResourceFilter is a CEL expression expected to return a boolean that is
evaluated for each resource referenced in the Resources field when a
webhook is received. If the expression returns false then the controller
will not request a reconciliation for the resource.
When the expression is specified the controller will parse it and mark
the object as terminally failed if the expression is invalid or does not
return a boolean.</p>
</td>
</tr>
<tr>
<td>
<code>secretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
@ -321,6 +339,24 @@ e.g. &lsquo;push&rsquo; for GitHub or &lsquo;Push Hook&rsquo; for GitLab.</p>
</tr>
<tr>
<td>
<code>resourceFilter</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ResourceFilter is a CEL expression expected to return a boolean that is
evaluated for each resource referenced in the Resources field when a
webhook is received. If the expression returns false then the controller
will not request a reconciliation for the resource.
When the expression is specified the controller will parse it and mark
the object as terminally failed if the expression is invalid or does not
return a boolean.</p>
</td>
</tr>
<tr>
<td>
<code>secretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">

View File

@ -161,7 +161,8 @@ string
</td>
<td>
<em>(Optional)</em>
<p>Summary holds a short description of the impact and affected cluster.</p>
<p>Summary holds a short description of the impact and affected cluster.
Deprecated: Use EventMetadata instead.</p>
</td>
</tr>
<tr>
@ -254,6 +255,21 @@ string
</tr>
<tr>
<td>
<code>interval</code><br>
<em>
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Duration">
Kubernetes meta/v1.Duration
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Interval at which to reconcile the Provider with its Secret references.
Deprecated and not used in v1beta3.</p>
</td>
</tr>
<tr>
<td>
<code>channel</code><br>
<em>
string
@ -314,7 +330,25 @@ string
</td>
<td>
<em>(Optional)</em>
<p>Proxy the HTTP/S address of the proxy server.</p>
<p>Proxy the HTTP/S address of the proxy server.
Deprecated: Use ProxySecretRef instead. Will be removed in v1.</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
for this Provider. The Secret should contain an &lsquo;address&rsquo; key with the
HTTP/S address of the proxy server. Optional &lsquo;username&rsquo; and &lsquo;password&rsquo;
keys can be provided for proxy authentication.</p>
</td>
</tr>
<tr>
@ -334,6 +368,28 @@ credentials for this Provider.</p>
</tr>
<tr>
<td>
<code>serviceAccountName</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ServiceAccountName is the name of the Kubernetes ServiceAccount used to
authenticate with cloud provider services through workload identity.
This enables multi-tenant authentication without storing static credentials.</p>
<p>Supported provider types: azureeventhub, azuredevops, googlepubsub</p>
<p>When specified, the controller will:
1. Create an OIDC token for the specified ServiceAccount
2. Exchange it for cloud provider credentials via STS
3. Use the obtained credentials for API authentication</p>
<p>When unspecified, controller-level authentication is used (single-tenant).</p>
<p>An error is thrown if static credentials are also defined in SecretRef.
This field requires the ObjectLevelWorkloadIdentity feature gate to be enabled.</p>
</td>
</tr>
<tr>
<td>
<code>certSecretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
@ -343,10 +399,13 @@ github.com/fluxcd/pkg/apis/meta.LocalObjectReference
</td>
<td>
<em>(Optional)</em>
<p>CertSecretRef specifies the Secret containing
a PEM-encoded CA certificate (in the <code>ca.crt</code> key).</p>
<p>Note: Support for the <code>caFile</code> key has
been deprecated.</p>
<p>CertSecretRef specifies the Secret containing TLS certificates
for secure communication.</p>
<p>Supported configurations:
- CA-only: Server authentication (provide ca.crt only)
- mTLS: Mutual authentication (provide ca.crt + tls.crt + tls.key)
- Client-only: Client authentication with system CA (provide tls.crt + tls.key only)</p>
<p>Legacy keys &ldquo;caFile&rdquo;, &ldquo;certFile&rdquo;, &ldquo;keyFile&rdquo; are supported but deprecated. Use &ldquo;ca.crt&rdquo;, &ldquo;tls.crt&rdquo;, &ldquo;tls.key&rdquo; instead.</p>
</td>
</tr>
<tr>
@ -362,6 +421,22 @@ bool
events handling for this Provider.</p>
</td>
</tr>
<tr>
<td>
<code>commitStatusExpr</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>CommitStatusExpr is a CEL expression that evaluates to a string value
that can be used to generate a custom commit status message for use
with eligible Provider types (github, gitlab, gitea, bitbucketserver,
bitbucket, azuredevops). Supported variables are: event, provider,
and alert.</p>
</td>
</tr>
</table>
</td>
</tr>
@ -477,7 +552,8 @@ string
</td>
<td>
<em>(Optional)</em>
<p>Summary holds a short description of the impact and affected cluster.</p>
<p>Summary holds a short description of the impact and affected cluster.
Deprecated: Use EventMetadata instead.</p>
</td>
</tr>
<tr>
@ -527,6 +603,21 @@ string
</tr>
<tr>
<td>
<code>interval</code><br>
<em>
<a href="https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Duration">
Kubernetes meta/v1.Duration
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>Interval at which to reconcile the Provider with its Secret references.
Deprecated and not used in v1beta3.</p>
</td>
</tr>
<tr>
<td>
<code>channel</code><br>
<em>
string
@ -587,7 +678,25 @@ string
</td>
<td>
<em>(Optional)</em>
<p>Proxy the HTTP/S address of the proxy server.</p>
<p>Proxy the HTTP/S address of the proxy server.
Deprecated: Use ProxySecretRef instead. Will be removed in v1.</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
for this Provider. The Secret should contain an &lsquo;address&rsquo; key with the
HTTP/S address of the proxy server. Optional &lsquo;username&rsquo; and &lsquo;password&rsquo;
keys can be provided for proxy authentication.</p>
</td>
</tr>
<tr>
@ -607,6 +716,28 @@ credentials for this Provider.</p>
</tr>
<tr>
<td>
<code>serviceAccountName</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ServiceAccountName is the name of the Kubernetes ServiceAccount used to
authenticate with cloud provider services through workload identity.
This enables multi-tenant authentication without storing static credentials.</p>
<p>Supported provider types: azureeventhub, azuredevops, googlepubsub</p>
<p>When specified, the controller will:
1. Create an OIDC token for the specified ServiceAccount
2. Exchange it for cloud provider credentials via STS
3. Use the obtained credentials for API authentication</p>
<p>When unspecified, controller-level authentication is used (single-tenant).</p>
<p>An error is thrown if static credentials are also defined in SecretRef.
This field requires the ObjectLevelWorkloadIdentity feature gate to be enabled.</p>
</td>
</tr>
<tr>
<td>
<code>certSecretRef</code><br>
<em>
<a href="https://pkg.go.dev/github.com/fluxcd/pkg/apis/meta#LocalObjectReference">
@ -616,10 +747,13 @@ github.com/fluxcd/pkg/apis/meta.LocalObjectReference
</td>
<td>
<em>(Optional)</em>
<p>CertSecretRef specifies the Secret containing
a PEM-encoded CA certificate (in the <code>ca.crt</code> key).</p>
<p>Note: Support for the <code>caFile</code> key has
been deprecated.</p>
<p>CertSecretRef specifies the Secret containing TLS certificates
for secure communication.</p>
<p>Supported configurations:
- CA-only: Server authentication (provide ca.crt only)
- mTLS: Mutual authentication (provide ca.crt + tls.crt + tls.key)
- Client-only: Client authentication with system CA (provide tls.crt + tls.key only)</p>
<p>Legacy keys &ldquo;caFile&rdquo;, &ldquo;certFile&rdquo;, &ldquo;keyFile&rdquo; are supported but deprecated. Use &ldquo;ca.crt&rdquo;, &ldquo;tls.crt&rdquo;, &ldquo;tls.key&rdquo; instead.</p>
</td>
</tr>
<tr>
@ -635,6 +769,22 @@ bool
events handling for this Provider.</p>
</td>
</tr>
<tr>
<td>
<code>commitStatusExpr</code><br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>CommitStatusExpr is a CEL expression that evaluates to a string value
that can be used to generate a custom commit status message for use
with eligible Provider types (github, gitlab, gitea, bitbucketserver,
bitbucket, azuredevops). Supported variables are: event, provider,
and alert.</p>
</td>
</tr>
</tbody>
</table>
</div>

View File

@ -134,6 +134,7 @@ handle the incoming webhook request.
| [Nexus](#nexus) | `nexus` | ❌ |
| [Azure Container Registry](#acr) | `acr` | ❌ |
| [Google Container Registry](#gcr) | `gcr` | ❌ |
| [CDEvents](#cdevents) | `cdevents` | ✅ |
#### Generic
@ -613,6 +614,35 @@ spec:
name: webapp
```
#### CDEvents
When a Receiver's `.spec.type` is set to `cdevents`, the controller will respond to
a [CDEvent Event Payload](https://cdevents.dev/docs/). It will verify the CDEvent
using the [CDEvent Go-SDK](https://github.com/cdevents/sdk-go).
This type of receiver supports filtering using [Events](#events) by comparing the
`type` header to the list of events.
##### CDEvents example
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1
kind: Receiver
metadata:
name: cdevents-receiver
namespace: flux-system
spec:
type: cdevents
events:
- "dev.cdevents.change.merged"
secretRef:
name: receiver-token
resources:
- kind: GitRepository
name: webapp
```
### Events
`.spec.events` is an optional field to specify a list of webhook payload event
@ -670,6 +700,75 @@ resources:
**Note:** Cross-namespace references [can be disabled for security
reasons](#disabling-cross-namespace-selectors).
#### Filtering reconciled objects with CEL
To filter the resources that are reconciled you can use [Common Expression Language (CEL)](https://cel.dev/).
For example, to trigger `ImageRepositories` on notifications from [Google Artifact Registry](https://cloud.google.com/artifact-registry/docs/configure-notifications#examples) you can define the following receiver:
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1
kind: Receiver
metadata:
name: gar-receiver
namespace: apps
spec:
type: gcr
secretRef:
name: flux-gar-token
resources:
- apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
name: "*"
matchLabels:
registry: gar
```
This will trigger the reconciliation of all `ImageRepositories` with the label `registry: gar`.
But if you want to only notify `ImageRepository` resources that are referenced from the incoming hook you can use CEL to filter the resources.
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1
kind: Receiver
metadata:
name: gar-receiver
namespace: apps
spec:
type: gcr
secretRef:
name: flux-gar-token
resources:
- apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
name: "*"
matchLabels:
registry: gar
resourceFilter: 'req.tag.contains(res.metadata.name)'
```
If the body of the incoming hook looks like this:
```json
{
"action":"INSERT",
"digest":"us-east1-docker.pkg.dev/my-project/my-repo/hello-world@sha256:6ec128e26cd5...",
"tag":"us-east1-docker.pkg.dev/my-project/my-repo/hello-world:1.1"
}
```
This simple example would match `ImageRepositories` containing the name `hello-world`.
If you want to do more complex processing:
```yaml
resourceFilter: has(res.metadata.annotations) && req.tag.split('/').last().value().split(":").first().value() == res.metadata.annotations['update-image']
```
This would look for an annotation "update-image" on the resource, and match it to the `hello-world` part of the tag name.
**Note:** Currently the `resource` value in the CEL expression only provides the object metadata, this means you can access things like `res.metadata.labels`, `res.metadata.annotations` and `res.metadata.name`.
### Secret reference
`.spec.secretRef.name` is a required field to specify a name reference to a
@ -680,7 +779,7 @@ This token is used to salt the generated [webhook path](#webhook-path), and
depending on the Receiver [type](#supported-receiver-types), to verify the
authenticity of a request.
#### Secret example
Example:
```yaml
---
@ -694,6 +793,21 @@ stringData:
token: <random token>
```
To trigger a reconciliation of the Receiver when changes occur in
the referenced Secret, you can set the following label on the
Secret:
```yaml
metadata:
labels:
reconcile.fluxcd.io/watch: Enabled
```
An alternative to labeling every Secret is setting the
`--watch-configs-label-selector=owner!=helm` flag in
notification-controller, which allows watching all
Secrets except for Helm storage Secrets.
### Interval
`.spec.interval` is an optional field with a default of ten minutes that specifies
@ -713,7 +827,7 @@ When the field is set to `false` or removed, it will resume.
On multi-tenant clusters, platform admins can disable cross-namespace
references with the `--no-cross-namespace-refs=true` flag. When this flag is
set, Receivers can only refer to [Resources](#resources) in the same namespace
as the [Alert](alerts.md) object, preventing tenants from triggering
as the Receiver object, preventing tenants from triggering
reconciliations to another tenant's resources.
### Public Ingress considerations

View File

@ -368,7 +368,8 @@ and use `https://api.telegram.org/` as the api url.
--from-literal=address=https://api.telegram.org
```
Also note that `spec.channel` can be a unique identifier for the target chat
Also note that `spec.channel` can be a unique identifier for the target chat,
a unique identifier with the topic identifier for the forum chat
or username of the target channel (in the format @channelusername)
```yaml
@ -379,7 +380,7 @@ metadata:
namespace: flux-system
spec:
type: telegram
channel: "@fluxtest" # or "-1557265138" (channel id)
channel: "@fluxtest" # or "-1557265138" (channel id) or "-1552289257:1" (forum chat id with topic id)
secretRef:
name: telegram-token
```

View File

@ -447,7 +447,7 @@ metadata:
stringData:
token: <DataDog API Key>
---
apiVersion: notification.toolkit.fluxcd.io/v1beta1
apiVersion: notification.toolkit.fluxcd.io/v1beta2
kind: Alert
metadata:
name: datadog-info
@ -563,8 +563,9 @@ The Event will be formatted into a message string, with the metadata attached
as a list of key-value pairs.
The Provider's [Channel](#channel) is used to set the receiver of the message.
This can be a unique identifier (`-1234567890`) for the target chat, or
the username (`@username`) of the target channel.
This can be a unique identifier (`-1234567890`) for the target chat,
a unique identifier with the topic identifier (`-1234567890:1`) for the forum chat,
or the username (`@username`) of the target channel.
This Provider type does not support the configuration of a [proxy URL](#https-proxy)
or [TLS certificates](#tls-certificates).
@ -586,7 +587,7 @@ metadata:
spec:
type: telegram
address: https://api.telegram.org
channel: "@fluxcd" # or "-1557265138" (channel id)
channel: "@fluxcd" # or "-1557265138" (channel id) or "-1552289257:1" (forum chat id with topic id)
secretRef:
name: telegram-token
```
@ -1539,6 +1540,8 @@ kubectl create secret generic bb-server-token --from-literal=token=<token>
The HTTP access token must have `Repositories (Read/Write)` permission for
the repository specified in `.spec.address`.
**NOTE:** Please provide HTTPS clone URL in the `address` field of this provider. SSH URLs are not supported by this provider type.
#### Azure DevOps
When `.spec.type` is set to `azuredevops`, the referenced secret must contain a key called `token` with the value set to a

View File

@ -28,9 +28,13 @@ metadata:
name: slack
namespace: flux-system
spec:
summary: "Cluster addons impacted in us-east-2"
providerRef:
name: slack-bot
eventMetadata:
summary: Cluster addons impacted
env: prod
cluster: my-cluster
region: us-east-2
eventSeverity: error
eventSources:
- kind: GitRepository
@ -51,7 +55,7 @@ In the above example:
all GitRepositories and Kustomizations in the `flux-system` namespace.
- When an event with severity `error` is received, the controller posts
a message on Slack channel from `.spec.channel`,
containing the `summary` text and the reconciliation error.
containing the metadata and the reconciliation error.
You can run this example by saving the manifests into `slack-alerts.yaml`.
@ -78,10 +82,15 @@ An Alert also needs a
### Summary
`.spec.summary` is an optional field to specify a short description of the
impact and affected cluster.
`.spec.summary` is an optional field to specify a short description of the impact.
The summary max length can't be greater than 255 characters.
The summary max length can't be greater than 255 characters.
**Warning:** Support for `.spec.summary` has been deprecated and will be removed in
Alert API v1 GA. If you have any Alerts using this field, the controller will log a
deprecation warning. Please use [`.spec.eventMetadata.summary`](#event-metadata) or
[object annotations](#event-metadata-from-object-annotations) for defining alert
summary instead.
### Provider reference
@ -146,10 +155,11 @@ preventing tenants from subscribing to another tenant's events.
### Event metadata
`.spec.eventMetadata` is an optional field for adding metadata to events dispatched by
the controller. This can be used for enhancing the context of the event. If a field
would override one already present on the original event as generated by the emitter,
then the override doesn't happen, i.e. the original value is preserved, and an info
log is printed.
the controller. This can be used for enhancing the context of the event, e.g. with
cluster-level information.
For all the event metadata sources and their precedence order, please refer to
[Event metadata from object annotations](#event-metadata-from-object-annotations).
#### Example
@ -168,9 +178,68 @@ spec:
inclusionList:
- ".*succeeded.*"
eventMetadata:
app.kubernetes.io/env: "production"
app.kubernetes.io/cluster: "my-cluster"
app.kubernetes.io/region: "us-east-1"
env: production
cluster: my-cluster
region: us-east-1
```
### Event metadata from object annotations
Event metadata has four sources. They are listed below in order of precedence,
from lowest to highest:
1. User-defined metadata on Flux objects, set with the `event.toolkit.fluxcd.io/`
prefix in the keys of the object's `.metadata.annotations`.
2. User-defined metadata on the Alert object, set with [`.spec.eventMetadata`](#event-metadata).
3. User-defined summary on the Alert object, set with [`.spec.summary`](#summary) (deprecated, see docs).
4. Controller-defined metadata, set with the `<controller group>.toolkit.fluxcd.io/`
prefix in the metadata keys of the event payload.
If there are any metadata key conflicts between the sources, the higher
precedence source will override the lower precedence source, and a warning
log and Kubernetes event will be emitted.
#### Example
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
name: <name>
spec:
eventSources:
- kind: HelmRelease
name: '*'
eventMetadata:
env: production
cluster: my-cluster
region: us-east-1
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: my-webapp
annotations:
event.toolkit.fluxcd.io/summary: "my-webapp impacted. Playbook: <URL to playbook>"
event.toolkit.fluxcd.io/deploymentID: e076e315-5a48-41c3-81c8-8d8bdee7d74d
spec:
... # fields omitted for brevity
```
In the above example, the event payload dispatched by the controller will look like this
(most fields omitted for highlighting the metadata):
```json
{
"metadata": {
"env": "production",
"cluster": "my-cluster",
"region": "us-east-1",
"summary": "my-webapp impacted. Playbook: <URL to playbook>",
"deploymentID": "e076e315-5a48-41c3-81c8-8d8bdee7d74d"
}
}
```
### Event severity

File diff suppressed because it is too large Load Diff

286
go.mod
View File

@ -1,173 +1,205 @@
module github.com/fluxcd/notification-controller
go 1.20
go 1.24.0
replace github.com/fluxcd/notification-controller/api => ./api
require (
cloud.google.com/go/pubsub v1.33.0
code.gitea.io/sdk/gitea v0.17.0
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24
github.com/Azure/azure-amqp-common-go/v4 v4.2.0
github.com/Azure/azure-event-hubs-go/v3 v3.6.1
github.com/DataDog/datadog-api-client-go/v2 v2.19.0
github.com/PagerDuty/go-pagerduty v1.7.0
github.com/containrrr/shoutrrr v0.8.0
github.com/fluxcd/cli-utils v0.36.0-flux.1
github.com/fluxcd/notification-controller/api v1.1.0
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/masktoken v0.2.0
github.com/fluxcd/pkg/runtime v0.43.0
github.com/fluxcd/pkg/ssa v0.35.0
github.com/getsentry/sentry-go v0.25.0
github.com/go-logr/logr v1.3.0
github.com/google/go-github/v53 v53.2.0
github.com/hashicorp/go-retryablehttp v0.7.5
github.com/ktrysmt/go-bitbucket v0.9.72
cloud.google.com/go/pubsub v1.49.0
code.gitea.io/sdk/gitea v0.21.0
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1
github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs/v2 v2.0.0
github.com/DataDog/datadog-api-client-go/v2 v2.43.0
github.com/PagerDuty/go-pagerduty v1.8.0
github.com/cdevents/sdk-go v0.4.1
github.com/chainguard-dev/git-urls v1.0.2
github.com/elazarl/goproxy v1.7.2
github.com/fluxcd/cli-utils v0.36.0-flux.14
github.com/fluxcd/notification-controller/api v1.6.0
github.com/fluxcd/pkg/apis/event v0.18.0
github.com/fluxcd/pkg/apis/meta v1.18.0
github.com/fluxcd/pkg/auth v0.27.0
github.com/fluxcd/pkg/cache v0.10.0
github.com/fluxcd/pkg/git v0.35.0
github.com/fluxcd/pkg/masktoken v0.7.0
github.com/fluxcd/pkg/runtime v0.80.0
github.com/fluxcd/pkg/ssa v0.51.0
github.com/fluxcd/pkg/ssh v0.20.0
github.com/getsentry/sentry-go v0.34.1
github.com/go-logr/logr v1.4.3
github.com/google/cel-go v0.26.0
github.com/google/go-github/v64 v64.0.0
github.com/google/uuid v1.6.0
github.com/hashicorp/go-retryablehttp v0.7.8
github.com/ktrysmt/go-bitbucket v0.9.86
github.com/microsoft/azure-devops-go-api/azuredevops/v6 v6.0.1
github.com/nats-io/nats.go v1.31.0
github.com/onsi/gomega v1.30.0
github.com/sethvargo/go-limiter v0.7.2
github.com/slok/go-http-metrics v0.11.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
github.com/whilp/git-urls v1.0.0
github.com/xanzy/go-gitlab v0.94.0
golang.org/x/oauth2 v0.15.0
golang.org/x/text v0.14.0
google.golang.org/api v0.152.0
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
sigs.k8s.io/yaml v1.4.0
github.com/nats-io/nats.go v1.43.0
github.com/onsi/gomega v1.38.0
github.com/sethvargo/go-limiter v1.0.0
github.com/slok/go-http-metrics v0.13.0
github.com/spf13/pflag v1.0.7
github.com/stretchr/testify v1.10.0
gitlab.com/gitlab-org/api/client-go v0.137.0
golang.org/x/oauth2 v0.30.0
golang.org/x/text v0.27.0
google.golang.org/api v0.243.0
k8s.io/api v0.33.2
k8s.io/apimachinery v0.33.2
k8s.io/client-go v0.33.2
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
sigs.k8s.io/controller-runtime v0.21.0
sigs.k8s.io/yaml v1.5.0
)
// Fix CVE-2022-28948
replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1
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
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
github.com/Azure/go-amqp v1.0.0 // indirect
cel.dev/expr v0.24.0 // indirect
cloud.google.com/go v0.120.0 // indirect
cloud.google.com/go/auth v0.16.3 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/compute/metadata v0.7.0 // indirect
cloud.google.com/go/iam v1.5.2 // indirect
github.com/42wim/httpsig v1.2.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/containers/azcontainerregistry v0.2.3 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0 // indirect
github.com/Azure/go-amqp v1.4.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // 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
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
github.com/Azure/go-autorest/autorest/validation v0.3.1 // 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.4.2 // indirect
github.com/DataDog/zstd v1.5.2 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20231012073058-a7379d079e0e // indirect
github.com/ProtonMail/go-crypto v1.3.0 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/bradleyfalzon/ghinstallation/v2 v2.16.0 // indirect
github.com/carapace-sh/carapace-shlex v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/cloudflare/circl v1.3.6 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/cloudevents/sdk-go/v2 v2.15.2 // indirect
github.com/cloudflare/circl v1.6.1 // indirect
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/davidmz/go-pageant v1.0.2 // indirect
github.com/devigned/tab v0.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.7.0 // indirect
github.com/docker/cli v28.2.2+incompatible // indirect
github.com/docker/docker-credential-helpers v0.9.3 // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // 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/fluxcd/pkg/apis/acl v0.1.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fluxcd/pkg/apis/acl v0.7.0 // indirect
github.com/fluxcd/pkg/apis/kustomize v1.11.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.5 // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-fed/httpsig v1.1.0 // indirect
github.com/go-logr/zapr v1.2.4 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.21.1 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.22.0 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // 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/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-containerregistry v0.20.6 // indirect
github.com/google/go-github/v72 v72.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/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.4.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.1 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mailru/easyjson v0.9.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/moby/spdystream v0.2.0 // indirect
github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/term v0.5.0 // 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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nats-io/nkeys v0.4.6 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/nats-io/nkeys v0.4.11 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/package-url/packageurl-go v0.1.1 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.17.0 // 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.65.0 // indirect
github.com/prometheus/procfs v0.17.0 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/cobra v1.9.1 // indirect
github.com/stoewer/go-strcase v1.3.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
go.opentelemetry.io/otel v1.37.0 // indirect
go.opentelemetry.io/otel/metric v1.37.0 // indirect
go.opentelemetry.io/otel/trace v1.37.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.25.0 // indirect
golang.org/x/crypto v0.16.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/time v0.5.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/appengine v1.6.7 // 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/evanphx/json-patch.v5 v5.6.0 // indirect
go.uber.org/zap v1.27.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.40.0 // indirect
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/net v0.42.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.34.0 // indirect
golang.org/x/term v0.33.0 // indirect
golang.org/x/time v0.12.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250715232539-7130f93afb79 // indirect
google.golang.org/grpc v1.73.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/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-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
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/structured-merge-diff/v4 v4.4.1 // indirect
k8s.io/apiextensions-apiserver v0.33.2 // indirect
k8s.io/cli-runtime v0.33.2 // indirect
k8s.io/component-base v0.33.2 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect
k8s.io/kubectl v0.33.2 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/kustomize/api v0.20.0 // indirect
sigs.k8s.io/kustomize/kyaml v0.20.0 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
)

2094
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,6 @@ package controller
import (
"context"
corev1 "k8s.io/api/core/v1"
kuberecorder "k8s.io/client-go/tools/record"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
@ -28,12 +27,16 @@ import (
apiv1 "github.com/fluxcd/notification-controller/api/v1"
apiv1beta3 "github.com/fluxcd/notification-controller/api/v1beta3"
"github.com/fluxcd/pkg/cache"
"github.com/fluxcd/pkg/runtime/patch"
"github.com/fluxcd/notification-controller/internal/notifier"
)
// +kubebuilder:rbac:groups=notification.toolkit.fluxcd.io,resources=providers,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
// +kubebuilder:rbac:groups="",resources=events,verbs=create;patch
// +kubebuilder:rbac:groups="",resources=serviceaccounts/token,verbs=create
// ProviderReconciler reconciles a Provider object to migrate it to static
// Provider.
@ -41,40 +44,21 @@ type ProviderReconciler struct {
client.Client
kuberecorder.EventRecorder
ControllerName string
TokenCache *cache.TokenCache
}
func (r *ProviderReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&apiv1beta3.Provider{}, builder.WithPredicates(finalizerPredicate{})).
For(&apiv1beta3.Provider{}, builder.WithPredicates(providerPredicate{})).
Complete(r)
}
func (r *ProviderReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, retErr error) {
log := ctrl.LoggerFrom(ctx)
obj := &apiv1beta3.Provider{}
if err := r.Get(ctx, req.NamespacedName, obj); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// Early return if no migration is needed.
if !controllerutil.ContainsFinalizer(obj, apiv1.NotificationFinalizer) {
return ctrl.Result{}, nil
}
// Examine if the object is under deletion.
var delete bool
if !obj.ObjectMeta.DeletionTimestamp.IsZero() {
delete = true
}
// Skip if it's suspend and not being deleted.
if obj.Spec.Suspend && !delete {
log.Info("reconciliation is suspended for this object")
return ctrl.Result{}, nil
}
patcher, err := patch.NewHelper(obj, r.Client)
if err != nil {
return ctrl.Result{}, err
@ -86,11 +70,29 @@ func (r *ProviderReconciler) Reconcile(ctx context.Context, req ctrl.Request) (r
}
}()
// Remove the notification-controller finalizer.
controllerutil.RemoveFinalizer(obj, apiv1.NotificationFinalizer)
// Examine if the object is under deletion.
if !obj.ObjectMeta.DeletionTimestamp.IsZero() {
return r.reconcileDelete(obj)
}
log.Info("removed finalizer from Provider to migrate to static Provider")
r.Event(obj, corev1.EventTypeNormal, "Migration", "removed finalizer from Provider to migrate to static Provider")
// Add finalizer if it doesn't exist.
if !controllerutil.ContainsFinalizer(obj, apiv1.NotificationFinalizer) {
controllerutil.AddFinalizer(obj, apiv1.NotificationFinalizer)
}
return
}
// reconcileDelete handles the deletion of the object.
// It cleans up the caches and removes the finalizer.
func (r *ProviderReconciler) reconcileDelete(obj *apiv1beta3.Provider) (ctrl.Result, error) {
// Remove our finalizer from the list
controllerutil.RemoveFinalizer(obj, apiv1.NotificationFinalizer)
// Cleanup caches.
r.TokenCache.DeleteEventsForObject(apiv1beta3.ProviderKind,
obj.GetName(), obj.GetNamespace(), notifier.OperationPost)
// Stop reconciliation as the object is being deleted
return ctrl.Result{}, nil
}

View File

@ -52,61 +52,29 @@ func TestProviderReconciler(t *testing.T) {
}
providerKey := client.ObjectKeyFromObject(provider)
// Remove finalizer at create.
provider.ObjectMeta.Finalizers = append(provider.ObjectMeta.Finalizers, "foo.bar", apiv1.NotificationFinalizer)
// Create without finalizer.
provider.Spec = apiv1beta3.ProviderSpec{
Type: "slack",
Type: "generic",
}
g.Expect(testEnv.Create(ctx, provider)).ToNot(HaveOccurred())
// Should eventually have finalizer.
g.Eventually(func() bool {
_ = testEnv.Get(ctx, providerKey, provider)
return !controllerutil.ContainsFinalizer(provider, apiv1.NotificationFinalizer)
return controllerutil.ContainsFinalizer(provider, apiv1.NotificationFinalizer)
}, timeout, time.Second).Should(BeTrue())
// Remove finalizer at update.
// Remove finalizer.
patchHelper, err := patch.NewHelper(provider, testEnv.Client)
g.Expect(err).ToNot(HaveOccurred())
provider.ObjectMeta.Finalizers = append(provider.ObjectMeta.Finalizers, apiv1.NotificationFinalizer)
controllerutil.RemoveFinalizer(provider, apiv1.NotificationFinalizer)
g.Expect(patchHelper.Patch(ctx, provider)).ToNot(HaveOccurred())
// Should eventually have finalizer again.
g.Eventually(func() bool {
_ = testEnv.Get(ctx, providerKey, provider)
return !controllerutil.ContainsFinalizer(provider, apiv1.NotificationFinalizer)
}, timeout, time.Second).Should(BeTrue())
// Remove finalizer at delete.
patchHelper, err = patch.NewHelper(provider, testEnv.Client)
g.Expect(err).ToNot(HaveOccurred())
// Suspend the provider to prevent finalizer from getting removed.
// Ensure only flux finalizer is set to allow the object to be garbage
// collected at the end.
// NOTE: Suspending and updating finalizers are done separately here as
// doing them in a single patch results in flaky test where the finalizer
// update doesn't gets registered with the kube-apiserver, resulting in
// timeout waiting for finalizer to appear on the object below.
provider.Spec.Suspend = true
g.Expect(patchHelper.Patch(ctx, provider)).ToNot(HaveOccurred())
g.Eventually(func() bool {
_ = k8sClient.Get(ctx, providerKey, provider)
return provider.Spec.Suspend == true
}, timeout).Should(BeTrue())
patchHelper, err = patch.NewHelper(provider, testEnv.Client)
g.Expect(err).ToNot(HaveOccurred())
// Add finalizer and verify that finalizer exists on the object using a live
// client.
provider.ObjectMeta.Finalizers = []string{apiv1.NotificationFinalizer}
g.Expect(patchHelper.Patch(ctx, provider)).ToNot(HaveOccurred())
g.Eventually(func() bool {
_ = k8sClient.Get(ctx, providerKey, provider)
return controllerutil.ContainsFinalizer(provider, apiv1.NotificationFinalizer)
}, timeout).Should(BeTrue())
}, timeout, time.Second).Should(BeTrue())
// Delete the object and verify.
g.Expect(testEnv.Delete(ctx, provider)).ToNot(HaveOccurred())
@ -117,3 +85,85 @@ func TestProviderReconciler(t *testing.T) {
return false
}, timeout).Should(BeTrue())
}
func TestProviderReconciler_APIServerValidation(t *testing.T) {
tests := []struct {
name string
providerType string
commitStatusExpr string
err string
}{
{
name: "github provider types can create providers with commitStatusExpr",
providerType: "github",
commitStatusExpr: "event.metadata.namespace + '/' + event.metadata.name + '/' + provider.metadata.uid",
},
{
name: "gitlab provider types can create providers with commitStatusExpr",
providerType: "gitlab",
commitStatusExpr: "event.metadata.namespace + '/' + event.metadata.name + '/' + provider.metadata.uid",
},
{
name: "gitea provider types can create providers with commitStatusExpr",
providerType: "gitea",
commitStatusExpr: "event.metadata.namespace + '/' + event.metadata.name + '/' + provider.metadata.uid",
},
{
name: "bitbucketserver provider types can create providers with commitStatusExpr",
providerType: "bitbucketserver",
commitStatusExpr: "event.metadata.namespace + '/' + event.metadata.name + '/' + provider.metadata.uid",
},
{
name: "bitbucket provider types can create providers with commitStatusExpr",
providerType: "bitbucket",
commitStatusExpr: "event.metadata.namespace + '/' + event.metadata.name + '/' + provider.metadata.uid",
},
{
name: "azuredevops provider types can create providers with commitStatusExpr",
providerType: "azuredevops",
commitStatusExpr: "event.metadata.namespace + '/' + event.metadata.name + '/' + provider.metadata.uid",
},
{
name: "unsupported provider types cannot create providers with commitStatusExpr",
providerType: "slack",
commitStatusExpr: "event.metadata.namespace + '/' + event.metadata.name + '/' + provider.metadata.uid",
err: "spec.commitStatusExpr is only supported for the 'github', 'gitlab', 'gitea', 'bitbucketserver', 'bitbucket', 'azuredevops' provider types",
},
{
name: "github provider types can create providers without commitStatusExpr",
providerType: "github",
commitStatusExpr: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
obj := &apiv1beta3.Provider{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "provider-reconcile-",
Namespace: "default",
},
Spec: apiv1beta3.ProviderSpec{
Type: tt.providerType,
CommitStatusExpr: tt.commitStatusExpr,
},
}
err := testEnv.Create(ctx, obj)
if err == nil {
defer func() {
err := testEnv.Delete(ctx, obj)
g.Expect(err).ToNot(HaveOccurred())
}()
}
if tt.err != "" {
g.Expect(err.Error()).To(ContainSubstring(tt.err))
} else {
g.Expect(err).NotTo(HaveOccurred())
}
})
}
}

View File

@ -0,0 +1,48 @@
/*
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 controller
import (
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/event"
apiv1 "github.com/fluxcd/notification-controller/api/v1"
apiv1beta3 "github.com/fluxcd/notification-controller/api/v1beta3"
)
// providerPredicate implements predicate functions for the Provider API.
type providerPredicate struct{}
func (providerPredicate) Create(e event.CreateEvent) bool {
return !controllerutil.ContainsFinalizer(e.Object, apiv1.NotificationFinalizer)
}
func (providerPredicate) Update(e event.UpdateEvent) bool {
if e.ObjectNew == nil {
return false
}
return !controllerutil.ContainsFinalizer(e.ObjectNew, apiv1.NotificationFinalizer) ||
!e.ObjectNew.(*apiv1beta3.Provider).ObjectMeta.DeletionTimestamp.IsZero()
}
func (providerPredicate) Delete(e event.DeleteEvent) bool {
return false
}
func (providerPredicate) Generic(e event.GenericEvent) bool {
return !controllerutil.ContainsFinalizer(e.Object, apiv1.NotificationFinalizer)
}

View File

@ -26,13 +26,15 @@ 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"
"sigs.k8s.io/controller-runtime/pkg/controller"
"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"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/runtime/conditions"
@ -54,13 +56,20 @@ type ReceiverReconciler struct {
}
type ReceiverReconcilerOptions struct {
RateLimiter ratelimiter.RateLimiter
RateLimiter workqueue.TypedRateLimiter[reconcile.Request]
WatchConfigsPredicate predicate.Predicate
}
func (r *ReceiverReconciler) SetupWithManager(mgr ctrl.Manager) error {
return r.SetupWithManagerAndOptions(mgr, ReceiverReconcilerOptions{})
return r.SetupWithManagerAndOptions(mgr, ReceiverReconcilerOptions{
WatchConfigsPredicate: predicate.Not(predicate.Funcs{}),
})
}
const (
secretRefIndex = ".metadata.secretRef"
)
func (r *ReceiverReconciler) SetupWithManagerAndOptions(mgr ctrl.Manager, opts ReceiverReconcilerOptions) error {
// This index is used to list Receivers by their webhook path after the receiver server
// gets a request.
@ -68,16 +77,60 @@ func (r *ReceiverReconciler) SetupWithManagerAndOptions(mgr ctrl.Manager, opts R
server.WebhookPathIndexKey, server.IndexReceiverWebhookPath); err != nil {
return err
}
// Index receivers by the secret reference, so that we can enqueue
// Receiver requests when the referenced Secret is changed.
if err := mgr.GetFieldIndexer().IndexField(context.Background(), &apiv1.Receiver{},
secretRefIndex, func(obj client.Object) []string {
receiver := obj.(*apiv1.Receiver)
return []string{fmt.Sprintf("%s/%s", receiver.GetNamespace(), receiver.Spec.SecretRef.Name)}
}); err != nil {
}
return ctrl.NewControllerManagedBy(mgr).
For(&apiv1.Receiver{}, builder.WithPredicates(
predicate.Or(predicate.GenerationChangedPredicate{}, predicates.ReconcileRequestedPredicate{}),
)).
WatchesMetadata(
&corev1.Secret{},
handler.EnqueueRequestsFromMapFunc(r.enqueueRequestsForChangeOf),
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}, opts.WatchConfigsPredicate),
).
WithOptions(controller.Options{
RateLimiter: opts.RateLimiter,
}).
Complete(r)
}
// enqueueRequestsForChangeOf enqueues Receiver requests for changes in referenced Secret objects.
func (r *ReceiverReconciler) enqueueRequestsForChangeOf(ctx context.Context, obj client.Object) []reconcile.Request {
log := ctrl.LoggerFrom(ctx)
// List all Receivers that have the referenced Secret in their spec.
receivers := &apiv1.ReceiverList{}
if err := r.List(ctx, receivers, client.MatchingFields{
secretRefIndex: client.ObjectKeyFromObject(obj).String(),
}); err != nil {
log.Error(err, "failed to list Receivers for change of Secret",
"secretRef", map[string]string{
"name": obj.GetName(),
"namespace": obj.GetNamespace(),
})
return nil
}
requests := make([]reconcile.Request, 0, len(receivers.Items))
for _, receiver := range receivers.Items {
requests = append(requests, reconcile.Request{
NamespacedName: types.NamespacedName{
Name: receiver.Name,
Namespace: receiver.Namespace,
},
})
}
return requests
}
// +kubebuilder:rbac:groups=notification.toolkit.fluxcd.io,resources=receivers,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=notification.toolkit.fluxcd.io,resources=receivers/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=source.fluxcd.io,resources=buckets,verbs=get;list;watch;update;patch
@ -112,9 +165,7 @@ func (r *ReceiverReconciler) Reconcile(ctx context.Context, req ctrl.Request) (r
}
// Record Prometheus metrics.
r.Metrics.RecordReadiness(ctx, obj)
r.Metrics.RecordDuration(ctx, obj, reconcileStart)
r.Metrics.RecordSuspend(ctx, obj, obj.Spec.Suspend)
// Emit warning event if the reconciliation failed.
if retErr != nil {
@ -157,25 +208,40 @@ func (r *ReceiverReconciler) Reconcile(ctx context.Context, req ctrl.Request) (r
// reconcile steps through the actual reconciliation tasks for the object, it returns early on the first step that
// produces an error.
func (r *ReceiverReconciler) reconcile(ctx context.Context, obj *apiv1.Receiver) (ctrl.Result, error) {
log := ctrl.LoggerFrom(ctx)
if filter := obj.Spec.ResourceFilter; filter != "" {
if err := server.ValidateResourceFilter(filter); err != nil {
const msg = "Reconciliation failed terminally due to configuration error"
errMsg := fmt.Sprintf("%s: %v", msg, err)
conditions.MarkFalse(obj, meta.ReadyCondition, meta.InvalidCELExpressionReason, "%s", errMsg)
conditions.MarkStalled(obj, meta.InvalidCELExpressionReason, "%s", errMsg)
obj.Status.ObservedGeneration = obj.Generation
log.Error(err, msg)
r.Event(obj, corev1.EventTypeWarning, meta.InvalidCELExpressionReason, errMsg)
return ctrl.Result{}, nil
}
}
// Mark the resource as under reconciliation.
conditions.MarkReconciling(obj, meta.ProgressingReason, "Reconciliation in progress")
token, err := r.token(ctx, obj)
if err != nil {
conditions.MarkFalse(obj, meta.ReadyCondition, apiv1.TokenNotFoundReason, err.Error())
conditions.MarkFalse(obj, meta.ReadyCondition, apiv1.TokenNotFoundReason, "%s", err)
obj.Status.WebhookPath = ""
return ctrl.Result{Requeue: true}, err
return ctrl.Result{}, err
}
webhookPath := obj.GetWebhookPath(token)
msg := fmt.Sprintf("Receiver initialized for path: %s", webhookPath)
// Mark the resource as ready and set the webhook path in status.
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, msg)
conditions.MarkTrue(obj, meta.ReadyCondition, meta.SucceededReason, "%s", msg)
if obj.Status.WebhookPath != webhookPath {
obj.Status.WebhookPath = webhookPath
ctrl.LoggerFrom(ctx).Info(msg)
log.Info(msg)
}
return ctrl.Result{RequeueAfter: obj.GetInterval()}, nil

View File

@ -144,6 +144,45 @@ func TestReceiverReconciler_Reconcile(t *testing.T) {
g.Expect(resultR.Spec.Interval.Duration).To(BeIdenticalTo(10 * time.Minute))
})
t.Run("fails with invalid CEL resource filter", func(t *testing.T) {
g := NewWithT(t)
g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(receiver), resultR)).To(Succeed())
// Incomplete CEL expression
patch := []byte(`{"spec":{"resourceFilter":"has(res.metadata.annotations"}}`)
g.Expect(k8sClient.Patch(context.Background(), resultR, client.RawPatch(types.MergePatchType, patch))).To(Succeed())
g.Eventually(func() bool {
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(receiver), resultR)
return !conditions.IsReady(resultR)
}, timeout, time.Second).Should(BeTrue())
g.Expect(resultR.Status.ObservedGeneration).To(Equal(resultR.Generation))
g.Expect(conditions.GetReason(resultR, meta.ReadyCondition)).To(BeIdenticalTo(meta.InvalidCELExpressionReason))
g.Expect(conditions.GetMessage(resultR, meta.ReadyCondition)).To(ContainSubstring("annotations"))
g.Expect(conditions.Has(resultR, meta.StalledCondition)).To(BeTrue())
g.Expect(conditions.GetReason(resultR, meta.StalledCondition)).To(BeIdenticalTo(meta.InvalidCELExpressionReason))
g.Expect(conditions.GetObservedGeneration(resultR, meta.StalledCondition)).To(BeIdenticalTo(resultR.Generation))
})
t.Run("recovers when the CEL expression is valid", func(t *testing.T) {
g := NewWithT(t)
// Incomplete CEL expression
patch := []byte(`{"spec":{"resourceFilter":"has(res.metadata.annotations)"}}`)
g.Expect(k8sClient.Patch(context.Background(), resultR, client.RawPatch(types.MergePatchType, patch))).To(Succeed())
g.Eventually(func() bool {
_ = k8sClient.Get(context.Background(), client.ObjectKeyFromObject(receiver), resultR)
return conditions.IsReady(resultR)
}, timeout, time.Second).Should(BeTrue())
g.Expect(conditions.GetObservedGeneration(resultR, meta.ReadyCondition)).To(BeIdenticalTo(resultR.Generation))
g.Expect(resultR.Status.ObservedGeneration).To(BeIdenticalTo(resultR.Generation))
g.Expect(conditions.Has(resultR, meta.ReconcilingCondition)).To(BeFalse())
})
t.Run("fails with secret not found error", func(t *testing.T) {
g := NewWithT(t)
@ -239,7 +278,7 @@ func TestReceiverReconciler_EventHandler(t *testing.T) {
// Use the client from the manager as the server handler needs to list objects from the cache
// which the "live" k8s client does not have access to.
receiverServer := server.NewReceiverServer("127.0.0.1:56788", logf.Log, testEnv.GetClient())
receiverServer := server.NewReceiverServer("127.0.0.1:56788", logf.Log, testEnv.GetClient(), true, true)
receiverMdlw := middleware.New(middleware.Config{
Recorder: prommetrics.NewRecorder(prommetrics.Config{
Prefix: "gotk_receiver",

View File

@ -33,6 +33,7 @@ import (
"k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"github.com/fluxcd/cli-utils/pkg/kstatus/polling"
runtimeclient "github.com/fluxcd/pkg/runtime/client"
@ -40,6 +41,7 @@ import (
"github.com/fluxcd/pkg/runtime/metrics"
"github.com/fluxcd/pkg/runtime/testenv"
"github.com/fluxcd/pkg/ssa"
ssautil "github.com/fluxcd/pkg/ssa/utils"
apiv1 "github.com/fluxcd/notification-controller/api/v1"
apiv1b2 "github.com/fluxcd/notification-controller/api/v1beta2"
@ -81,9 +83,8 @@ func TestMain(m *testing.M) {
}
if err := (&ProviderReconciler{
Client: testEnv,
ControllerName: controllerName,
EventRecorder: testEnv.GetEventRecorderFor(controllerName),
Client: testEnv,
EventRecorder: testEnv.GetEventRecorderFor(controllerName),
}).SetupWithManager(testEnv); err != nil {
panic(fmt.Sprintf("Failed to start ProviderReconciler: %v", err))
}
@ -94,7 +95,8 @@ func TestMain(m *testing.M) {
ControllerName: controllerName,
EventRecorder: testEnv.GetEventRecorderFor(controllerName),
}).SetupWithManagerAndOptions(testEnv, ReceiverReconcilerOptions{
RateLimiter: controller.GetDefaultRateLimiter(),
RateLimiter: controller.GetDefaultRateLimiter(),
WatchConfigsPredicate: predicate.Not(predicate.Funcs{}),
}); err != nil {
panic(fmt.Sprintf("Failed to start ReceiverReconciler: %v", err))
}
@ -155,7 +157,7 @@ func readManifest(manifest, namespace string) (*unstructured.Unstructured, error
}
yml := fmt.Sprintf(string(data), namespace)
object, err := ssa.ReadObject(strings.NewReader(yml))
object, err := ssautil.ReadObject(strings.NewReader(yml))
if err != nil {
return nil, err
}

View File

@ -18,7 +18,10 @@ limitations under the License.
// and their default states.
package features
import feathelper "github.com/fluxcd/pkg/runtime/features"
import (
"github.com/fluxcd/pkg/auth"
feathelper "github.com/fluxcd/pkg/runtime/features"
)
const (
// CacheSecretsAndConfigMaps controls whether Secrets and ConfigMaps should
@ -35,6 +38,10 @@ var features = map[string]bool{
CacheSecretsAndConfigMaps: false,
}
func init() {
auth.SetFeatureGates(features)
}
// FeatureGates contains a list of all supported feature gates and
// their default values.
func FeatureGates() map[string]bool {

View File

@ -18,10 +18,13 @@ package notifier
import (
"context"
"crypto/x509"
"crypto/tls"
"encoding/json"
"fmt"
"net/url"
"time"
"github.com/hashicorp/go-retryablehttp"
"golang.org/x/text/cases"
"golang.org/x/text/language"
@ -29,27 +32,63 @@ import (
)
type Alertmanager struct {
URL string
ProxyURL string
CertPool *x509.CertPool
URL string
ProxyURL string
TLSConfig *tls.Config
Token string
Username string
Password string
}
type AlertManagerAlert struct {
Status string `json:"status"`
Labels map[string]string `json:"labels"`
Annotations map[string]string `json:"annotations"`
StartsAt AlertManagerTime `json:"startsAt"`
EndsAt AlertManagerTime `json:"endsAt,omitempty"`
}
func NewAlertmanager(hookURL string, proxyURL string, certPool *x509.CertPool) (*Alertmanager, error) {
// AlertManagerTime takes care of representing time.Time as RFC3339.
// See https://prometheus.io/docs/alerting/0.27/clients/
type AlertManagerTime time.Time
func (a AlertManagerTime) String() string {
return time.Time(a).Format(time.RFC3339)
}
func (a AlertManagerTime) MarshalJSON() ([]byte, error) {
return json.Marshal(a.String())
}
func (a *AlertManagerTime) UnmarshalJSON(jsonRepr []byte) error {
var serializedTime string
if err := json.Unmarshal(jsonRepr, &serializedTime); err != nil {
return err
}
t, err := time.Parse(time.RFC3339, serializedTime)
if err != nil {
return err
}
*a = AlertManagerTime(t)
return nil
}
func NewAlertmanager(hookURL string, proxyURL string, tlsConfig *tls.Config, token, user, pass string) (*Alertmanager, error) {
_, err := url.ParseRequestURI(hookURL)
if err != nil {
return nil, fmt.Errorf("invalid Alertmanager URL %s: '%w'", hookURL, err)
}
return &Alertmanager{
URL: hookURL,
ProxyURL: proxyURL,
CertPool: certPool,
URL: hookURL,
ProxyURL: proxyURL,
Token: token,
Username: user,
Password: pass,
TLSConfig: tlsConfig,
}, nil
}
@ -75,25 +114,54 @@ func (s *Alertmanager) Post(ctx context.Context, event eventv1.Event) error {
labels["alertname"] = "Flux" + event.InvolvedObject.Kind + cases.Title(language.Und).String(event.Reason)
labels["severity"] = event.Severity
labels["reason"] = event.Reason
labels["timestamp"] = event.Timestamp.String()
labels["kind"] = event.InvolvedObject.Kind
labels["name"] = event.InvolvedObject.Name
labels["namespace"] = event.InvolvedObject.Namespace
labels["reportingcontroller"] = event.ReportingController
// The best reasonable `endsAt` value would be multiplying
// InvolvedObject's reconciliation interval by 2 then adding that to
// `startsAt` (the next successful reconciliation would make sure
// the alert is cleared after the timeout). Due to
// event.InvolvedObject only containing the object reference (namely
// the GVKNN) best we can do is leave it unset up to Alertmanager's
// default `resolve_timeout`.
//
// https://prometheus.io/docs/alerting/0.27/configuration/#file-layout-and-global-settings
startsAt := AlertManagerTime(event.Timestamp.Time)
payload := []AlertManagerAlert{
{
Labels: labels,
Annotations: annotations,
Status: "firing",
StartsAt: startsAt,
},
}
err := postMessage(ctx, s.URL, s.ProxyURL, s.CertPool, payload)
var opts []postOption
if s.ProxyURL != "" {
opts = append(opts, withProxy(s.ProxyURL))
}
if s.TLSConfig != nil {
opts = append(opts, withTLSConfig(s.TLSConfig))
}
if s.Token != "" {
opts = append(opts, withRequestModifier(func(request *retryablehttp.Request) {
request.Header.Add("Authorization", "Bearer "+s.Token)
}))
}
if s.Username != "" && s.Password != "" {
opts = append(opts, withRequestModifier(func(request *retryablehttp.Request) {
request.SetBasicAuth(s.Username, s.Password)
}))
}
if err != nil {
if err := postMessage(ctx, s.URL, payload, opts...); err != nil {
return fmt.Errorf("postMessage failed: %w", err)
}
return nil
}

View File

@ -18,7 +18,7 @@ package notifier
import (
"context"
"crypto/x509"
"crypto/tls"
"fmt"
"io"
"net/http"
@ -43,10 +43,10 @@ func Fuzz_AlertManager(f *testing.F) {
}))
defer ts.Close()
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
var tlsConfig tls.Config
_ = fuzz.NewConsumer(seed).GenerateStruct(&tlsConfig)
alertmanager, err := NewAlertmanager(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", &cert)
alertmanager, err := NewAlertmanager(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", &tlsConfig, "", "", "")
if err != nil {
return
}

View File

@ -38,7 +38,7 @@ func TestAlertmanager_Post(t *testing.T) {
}))
defer ts.Close()
alertmanager, err := NewAlertmanager(ts.URL, "", nil)
alertmanager, err := NewAlertmanager(ts.URL, "", nil, "", "", "")
require.NoError(t, err)
err = alertmanager.Post(context.TODO(), testEvent())

View File

@ -19,16 +19,18 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"strings"
"github.com/microsoft/azure-devops-go-api/azuredevops/v6"
"github.com/microsoft/azure-devops-go-api/azuredevops/v6/git"
"sigs.k8s.io/controller-runtime/pkg/client"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/auth/azure"
"github.com/fluxcd/pkg/cache"
)
const genre string = "fluxcd"
@ -40,16 +42,23 @@ type azureDevOpsClient interface {
// AzureDevOps is an Azure DevOps notifier.
type AzureDevOps struct {
Project string
Repo string
ProviderUID string
Client azureDevOpsClient
Project string
Repo string
CommitStatus string
Client azureDevOpsClient
}
// NewAzureDevOps creates and returns a new AzureDevOps notifier.
func NewAzureDevOps(providerUID string, addr string, token string, certPool *x509.CertPool) (*AzureDevOps, error) {
func NewAzureDevOps(ctx context.Context, commitStatus string, addr string, token string,
tlsConfig *tls.Config, proxy, serviceAccountName, providerName, providerNamespace string,
tokenClient client.Client, tokenCache *cache.TokenCache) (*AzureDevOps, error) {
var err error
if len(token) == 0 {
return nil, errors.New("azure devops token cannot be empty")
// if token doesn't exist, try to create a new token using managed identity
token, err = newManagedIdentityToken(ctx, proxy, serviceAccountName, providerName, providerNamespace, azure.ScopeDevOps, tokenClient, tokenCache)
if err != nil {
return nil, fmt.Errorf("failed to acquire azure devops token: %w", err)
}
}
host, id, err := parseGitAddress(addr)
@ -57,6 +66,11 @@ func NewAzureDevOps(providerUID string, addr string, token string, certPool *x50
return nil, err
}
// this should never happen
if commitStatus == "" {
return nil, errors.New("commit status cannot be empty")
}
comp := strings.Split(id, "/")
if len(comp) != 4 {
return nil, fmt.Errorf("invalid repository id %q", id)
@ -67,20 +81,18 @@ func NewAzureDevOps(providerUID string, addr string, token string, certPool *x50
orgURL := fmt.Sprintf("%v/%v", host, org)
connection := azuredevops.NewPatConnection(orgURL, token)
if certPool != nil {
connection.TlsConfig = &tls.Config{
RootCAs: certPool,
}
if tlsConfig != nil {
connection.TlsConfig = tlsConfig
}
client := connection.GetClientByUrl(orgURL)
gitClient := &git.ClientImpl{
Client: *client,
}
return &AzureDevOps{
Project: proj,
Repo: repo,
ProviderUID: providerUID,
Client: gitClient,
Project: proj,
Repo: repo,
CommitStatus: commitStatus,
Client: gitClient,
}, nil
}
@ -91,7 +103,7 @@ func (a AzureDevOps) Post(ctx context.Context, event eventv1.Event) error {
return nil
}
revString, ok := event.Metadata[eventv1.MetaRevisionKey]
revString, ok := event.GetRevision()
if !ok {
return errors.New("missing revision metadata")
}
@ -108,7 +120,7 @@ func (a AzureDevOps) Post(ctx context.Context, event eventv1.Event) error {
g := commitStatusGenre(event)
_, desc := formatNameAndDescription(event)
id := generateCommitStatusID(a.ProviderUID, event)
id := a.CommitStatus
createArgs := git.CreateCommitStatusArgs{
Project: &a.Project,
RepositoryId: &a.Repo,

View File

@ -18,6 +18,7 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
@ -33,12 +34,12 @@ import (
const apiLocations = `{"count":0,"value":[{"area":"","id":"428dd4fb-fda5-4722-af02-9313b80305da","routeTemplate":"","resourceName":"","maxVersion":"6.0","minVersion":"5.0","releasedVersion":"6.0"}]}`
func Fuzz_AzureDevOps(f *testing.F) {
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "alakazam", "org/proj/_git/repo", "revision/dsa123a", "error", "", []byte{}, []byte(`{"count":1,"value":[{"state":"error","description":"","context":{"genre":"fluxcd","name":"/"}}]}`))
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "alakazam", "org/proj/_git/repo", "revision/dsa123a", "info", "", []byte{}, []byte(`{"count":1,"value":[{"state":"info","description":"","context":{"genre":"fluxcd","name":"/"}}]}`))
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "alakazam", "org/proj/_git/repo", "revision/dsa123a", "info", "", []byte{}, []byte(`{"count":0,"value":[]}`))
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "alakazam", "org/proj/_git/repo", "", "", "Progressing", []byte{}, []byte{})
f.Add("kustomization/gitops-system/0c9c2e41", "alakazam", "org/proj/_git/repo", "revision/dsa123a", "error", "", []byte{}, []byte(`{"count":1,"value":[{"state":"error","description":"","context":{"genre":"fluxcd","name":"/"}}]}`))
f.Add("kustomization/gitops-system/0c9c2e41", "alakazam", "org/proj/_git/repo", "revision/dsa123a", "info", "", []byte{}, []byte(`{"count":1,"value":[{"state":"info","description":"","context":{"genre":"fluxcd","name":"/"}}]}`))
f.Add("kustomization/gitops-system/0c9c2e41", "alakazam", "org/proj/_git/repo", "revision/dsa123a", "info", "", []byte{}, []byte(`{"count":0,"value":[]}`))
f.Add("kustomization/gitops-system/0c9c2e41", "alakazam", "org/proj/_git/repo", "", "", "Progressing", []byte{}, []byte{})
f.Fuzz(func(t *testing.T, uuid, token, urlSuffix, revision, severity, reason string, seed, response []byte) {
f.Fuzz(func(t *testing.T, commitStatus, token, urlSuffix, revision, severity, reason string, seed, response []byte) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.HasSuffix(r.URL.Path, "_apis") {
w.Write([]byte(apiLocations))
@ -54,7 +55,8 @@ func Fuzz_AzureDevOps(f *testing.F) {
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
azureDevOps, err := NewAzureDevOps(uuid, fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert)
tlsConfig := &tls.Config{RootCAs: &cert}
azureDevOps, err := NewAzureDevOps(context.TODO(), commitStatus, fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, tlsConfig, "", "", "", "", nil, nil)
if err != nil {
return
}

View File

@ -27,19 +27,24 @@ import (
)
func TestNewAzureDevOpsBasic(t *testing.T) {
a, err := NewAzureDevOps("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://dev.azure.com/foo/bar/_git/baz", "foo", nil)
a, err := NewAzureDevOps(context.TODO(), "kustomization/gitops-system/0c9c2e41", "https://dev.azure.com/foo/bar/_git/baz", "foo", nil, "", "", "", "", nil, nil)
assert.Nil(t, err)
assert.Equal(t, a.Project, "bar")
assert.Equal(t, a.Repo, "baz")
}
func TestNewAzureDevOpsInvalidUrl(t *testing.T) {
_, err := NewAzureDevOps("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://dev.azure.com/foo/bar/baz", "foo", nil)
_, err := NewAzureDevOps(context.TODO(), "kustomization/gitops-system/0c9c2e41", "https://dev.azure.com/foo/bar/baz", "foo", nil, "", "", "", "", nil, nil)
assert.NotNil(t, err)
}
func TestNewAzureDevOpsMissingToken(t *testing.T) {
_, err := NewAzureDevOps("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://dev.azure.com/foo/bar/baz", "", nil)
_, err := NewAzureDevOps(context.TODO(), "kustomization/gitops-system/0c9c2e41", "https://dev.azure.com/foo/bar/baz", "", nil, "", "", "", "", nil, nil)
assert.NotNil(t, err)
}
func TestNewAzureDevOpsEmptyCommitStatus(t *testing.T) {
_, err := NewAzureDevOps(context.TODO(), "", "https://dev.azure.com/foo/bar/_git/baz", "foo", nil, "", "", "", "", nil, nil)
assert.NotNil(t, err)
}
@ -100,6 +105,34 @@ func TestAzureDevOps_Post(t *testing.T) {
},
},
},
{
name: "event with origin revision",
event: eventv1.Event{
Severity: eventv1.EventSeverityInfo,
InvolvedObject: corev1.ObjectReference{
Kind: "Kustomization",
Name: "gitops-system",
},
Metadata: map[string]string{
eventv1.MetaRevisionKey: "main@sha1:69b59063470310ebbd88a9156325322a124e55a3",
eventv1.MetaOriginRevisionKey: "main@sha1:bd88a9156325322a124e55a369b59063470310eb",
},
Reason: "ApplySucceeded",
},
want: git.CreateCommitStatusArgs{
CommitId: strPtr("bd88a9156325322a124e55a369b59063470310eb"),
Project: strPtr("bar"),
RepositoryId: strPtr("baz"),
GitCommitStatusToCreate: &git.GitStatus{
Description: strPtr("apply succeeded"),
State: &git.GitStatusStateValues.Succeeded,
Context: &git.GitStatusContext{
Genre: strPtr("fluxcd"),
Name: strPtr("kustomization/gitops-system/0c9c2e41"),
},
},
},
},
{
name: "event with summary",
event: eventv1.Event{
@ -132,7 +165,7 @@ func TestAzureDevOps_Post(t *testing.T) {
for _, tt := range postTests {
t.Run(tt.name, func(t *testing.T) {
a, err := NewAzureDevOps("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://example.com/foo/bar/_git/baz", "foo", nil)
a, err := NewAzureDevOps(context.TODO(), "kustomization/gitops-system/0c9c2e41", "https://example.com/foo/bar/_git/baz", "foo", nil, "", "", "", "", nil, nil)
fakeClient := &fakeDevOpsClient{}
a.Client = fakeClient
assert.Nil(t, err)

View File

@ -17,37 +17,60 @@ import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
eventhub "github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventhubs/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
"github.com/Azure/azure-amqp-common-go/v4/auth"
eventhub "github.com/Azure/azure-event-hubs-go/v3"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/auth/azure"
"github.com/fluxcd/pkg/cache"
)
// AzureEventHub holds the eventhub client
type AzureEventHub struct {
Hub *eventhub.Hub
ProducerClient *eventhub.ProducerClient
}
// NewAzureEventHub creates a eventhub client
func NewAzureEventHub(endpointURL, token, eventHubNamespace string) (*AzureEventHub, error) {
var hub *eventhub.Hub
func NewAzureEventHub(ctx context.Context, endpointURL, token, eventHubNamespace, proxy,
serviceAccountName, providerName, providerNamespace string, tokenClient client.Client,
tokenCache *cache.TokenCache) (*AzureEventHub, error) {
var client *eventhub.ProducerClient
var err error
// token should only be defined if JWT is used
if token != "" {
hub, err = newJWTHub(endpointURL, token, eventHubNamespace)
if err := validateAuthOptions(endpointURL, token, serviceAccountName); err != nil {
return nil, fmt.Errorf("invalid authentication options: %v", err)
}
if isSASAuth(endpointURL) {
client, err = newSASHub(endpointURL)
if err != nil {
return nil, fmt.Errorf("failed to create a eventhub using JWT %v", err)
return nil, fmt.Errorf("failed to create a eventhub using SAS: %w", err)
}
} else {
hub, err = newSASHub(endpointURL)
// if token doesn't exist, try to create a new token using managed identity
if token == "" {
token, err = newManagedIdentityToken(ctx, proxy, serviceAccountName, providerName,
providerNamespace, azure.ScopeEventHubs, tokenClient, tokenCache)
if err != nil {
return nil, fmt.Errorf("failed to create a eventhub using managed identity: %w", err)
}
} else {
log.FromContext(ctx).Error(nil, "warning: static JWT authentication is deprecated and will be removed in the future, prefer workload identity: https://fluxcd.io/flux/components/notification/providers/#managed-identity")
}
client, err = newJWTHub(endpointURL, token, eventHubNamespace)
if err != nil {
return nil, fmt.Errorf("failed to create a eventhub using SAS %v", err)
return nil, fmt.Errorf("failed to create a eventhub using authentication token: %w", err)
}
}
return &AzureEventHub{
Hub: hub,
ProducerClient: client,
}, nil
}
@ -63,12 +86,22 @@ func (e *AzureEventHub) Post(ctx context.Context, event eventv1.Event) error {
return fmt.Errorf("unable to marshall event: %w", err)
}
err = e.Hub.Send(ctx, eventhub.NewEvent(eventBytes))
eventBatch, err := e.ProducerClient.NewEventDataBatch(ctx, nil)
if err != nil {
return fmt.Errorf("failed to create event data batch: %w", err)
}
err = eventBatch.AddEventData(&eventhub.EventData{Body: eventBytes}, nil)
if err != nil {
return fmt.Errorf("failed to add event data to batch: %w", err)
}
err = e.ProducerClient.SendEventDataBatch(ctx, eventBatch, nil)
if err != nil {
return fmt.Errorf("failed to send msg: %w", err)
}
err = e.Hub.Close(ctx)
err = e.ProducerClient.Close(ctx)
if err != nil {
return fmt.Errorf("unable to close connection: %w", err)
}
@ -81,26 +114,24 @@ type PureJWT struct {
}
// NewJWTProvider create a pureJWT method
func NewJWTProvider(jwt string) *PureJWT {
func NewJWTProvider(jwt string) azcore.TokenCredential {
return &PureJWT{
jwt: jwt,
}
}
// GetToken uses a JWT token, we assume that we will get new tokens when needed, thus no Expiry defined
func (j *PureJWT) GetToken(uri string) (*auth.Token, error) {
return &auth.Token{
TokenType: auth.CBSTokenTypeJWT,
Token: j.jwt,
Expiry: "",
func (j *PureJWT) GetToken(ctx context.Context, options policy.TokenRequestOptions) (azcore.AccessToken, error) {
return azcore.AccessToken{
Token: j.jwt,
}, nil
}
// newJWTHub used when address is a JWT token
func newJWTHub(eventhubName, token, eventHubNamespace string) (*eventhub.Hub, error) {
func newJWTHub(eventhubName, token, eventHubNamespace string) (*eventhub.ProducerClient, error) {
provider := NewJWTProvider(token)
hub, err := eventhub.NewHub(eventHubNamespace, eventhubName, provider)
fullyQualifiedNamespace := ensureFullyQualifiedNamespace(eventHubNamespace)
hub, err := eventhub.NewProducerClient(fullyQualifiedNamespace, eventhubName, provider, nil)
if err != nil {
return nil, err
}
@ -108,11 +139,66 @@ func newJWTHub(eventhubName, token, eventHubNamespace string) (*eventhub.Hub, er
}
// newSASHub used when address is a SAS ConnectionString
func newSASHub(address string) (*eventhub.Hub, error) {
hub, err := eventhub.NewHubFromConnectionString(address)
func newSASHub(address string) (*eventhub.ProducerClient, error) {
client, err := eventhub.NewProducerClientFromConnectionString(address, "", nil)
if err != nil {
return nil, err
}
return hub, nil
return client, nil
}
// validateAuthOptions checks if the authentication options are valid
func validateAuthOptions(endpointURL, token, serviceAccountName string) error {
if endpointURL == "" {
return fmt.Errorf("endpoint URL cannot be empty")
}
if isSASAuth(endpointURL) {
if err := validateSASAuth(token, serviceAccountName); err != nil {
return err
}
} else if serviceAccountName != "" && token != "" {
return fmt.Errorf("serviceAccountName and jwt token authentication cannot be set at the same time")
}
return nil
}
// isSASAuth checks if the endpoint URL contains SAS authentication parameters
func isSASAuth(endpointURL string) bool {
return strings.Contains(endpointURL, "SharedAccessKey")
}
// validateSASAuth checks if SAS authentication is used correctly
func validateSASAuth(token, serviceAccountName string) error {
if serviceAccountName != "" {
return fmt.Errorf("serviceAccountName and SAS authentication cannot be set at the same time")
}
if token != "" {
return fmt.Errorf("jwt token and SAS authentication cannot be set at the same time")
}
return nil
}
// getEventHubSuffixFromAuthorityHost maps AZURE_AUTHORITY_HOST to the correct suffix
func getEventHubSuffixFromAuthorityHost() string {
authorityHost := os.Getenv("AZURE_AUTHORITY_HOST")
switch {
case strings.Contains(authorityHost, "chinacloudapi.cn"):
return ".servicebus.chinacloudapi.cn"
case strings.Contains(authorityHost, "microsoftonline.us"):
return ".servicebus.usgovcloudapi.net"
default:
return ".servicebus.windows.net"
}
}
// ensureFullyQualifiedNamespace appends suffix if not already present
func ensureFullyQualifiedNamespace(namespace string) string {
if strings.Contains(namespace, ".servicebus.") {
return namespace // already fully qualified
}
return namespace + getEventHubSuffixFromAuthorityHost()
}

View File

@ -0,0 +1,103 @@
/*
Copyright 2021 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 notifier
import (
"context"
"errors"
"testing"
"github.com/stretchr/testify/assert"
)
func TestNewAzureEventHub(t *testing.T) {
tests := []struct {
name string
endpointURL string
token string
eventHubNamespace string
serviceAccountName string
err error
}{
{
name: "JWT Authentication",
endpointURL: "azure-nc-eventhub",
token: "jwt-token",
eventHubNamespace: "namespace",
},
{
name: "SAS Authentication",
endpointURL: "Endpoint=sb://example.com/;SharedAccessKeyName=keyName;SharedAccessKey=key;EntityPath=eventhub",
token: "",
eventHubNamespace: "namespace",
},
{
name: "SAS Authentication without entity path",
endpointURL: "Endpoint=sb://example.com/;SharedAccessKeyName=keyName;SharedAccessKey=key",
token: "",
eventHubNamespace: "namespace",
err: errors.New("failed to create a eventhub using SAS: connection string does not contain an EntityPath. eventHub cannot be an empty string"),
},
{
name: "Default Azure Credential",
endpointURL: "azure-nc-eventhub",
token: "",
eventHubNamespace: "namespace",
err: errors.New("failed to create a eventhub using managed identity: failed to get token: failed to create provider access token for the controller: ManagedIdentityCredential: failed to authenticate a system assigned identity. The endpoint responded with {\"error\":\"invalid_request\",\"error_description\":\"Identity not found\"}"),
},
{
name: "SAS auth with serviceAccountName set",
endpointURL: "Endpoint=sb://example.com/;SharedAccessKeyName=keyName;SharedAccessKey=key;EntityPath=eventhub",
token: "",
serviceAccountName: "test-service-account",
eventHubNamespace: "namespace",
err: errors.New("invalid authentication options: serviceAccountName and SAS authentication cannot be set at the same time"),
},
{
name: "SAS auth with token set",
endpointURL: "Endpoint=sb://example.com/;SharedAccessKeyName=keyName;SharedAccessKey=key;EntityPath=eventhub",
token: "test-token",
eventHubNamespace: "namespace",
err: errors.New("invalid authentication options: jwt token and SAS authentication cannot be set at the same time"),
},
{
name: "token auth with serviceAccountName set",
endpointURL: "azure-nc-eventhub",
token: "test-token",
serviceAccountName: "test-service-account",
eventHubNamespace: "namespace",
err: errors.New("invalid authentication options: serviceAccountName and jwt token authentication cannot be set at the same time"),
},
{
name: "empty endpoint URL",
endpointURL: "",
token: "test-token",
eventHubNamespace: "namespace",
err: errors.New("invalid authentication options: endpoint URL cannot be empty"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client, err := NewAzureEventHub(context.TODO(), tt.endpointURL, tt.token, tt.eventHubNamespace, "", tt.serviceAccountName, "", "", nil, nil)
if tt.err != nil {
assert.Error(t, err)
assert.ErrorContains(t, err, tt.err.Error())
} else {
assert.NoError(t, err)
assert.NotNil(t, client)
}
})
}
}

View File

@ -0,0 +1,69 @@
/*
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 notifier
import (
"context"
"fmt"
"net/url"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/pkg/auth"
"github.com/fluxcd/pkg/auth/azure"
"github.com/fluxcd/pkg/cache"
"github.com/fluxcd/notification-controller/api/v1beta3"
)
// newManagedIdentityToken is used to attempt credential-free authentication.
func newManagedIdentityToken(ctx context.Context, proxy, serviceAccountName, providerName, providerNamespace, scope string, tokenClient client.Client, tokenCache *cache.TokenCache) (string, error) {
opts := []auth.Option{
auth.WithScopes(scope),
auth.WithClient(tokenClient),
auth.WithServiceAccountNamespace(providerNamespace),
}
if proxy != "" {
proxyURL, err := url.Parse(proxy)
if err != nil {
return "", fmt.Errorf("error parsing proxy URL: %w", err)
}
opts = append(opts, auth.WithProxyURL(*proxyURL))
}
if serviceAccountName != "" {
opts = append(opts, auth.WithServiceAccountName(serviceAccountName))
}
if tokenCache != nil {
involvedObject := cache.InvolvedObject{
Kind: v1beta3.ProviderKind,
Name: providerName,
Namespace: providerNamespace,
Operation: OperationPost,
}
opts = append(opts, auth.WithCache(*tokenCache, involvedObject))
}
token, err := auth.GetAccessToken(ctx, azure.Provider{}, opts...)
if err != nil {
return "", fmt.Errorf("failed to get token: %w", err)
}
return token.(*azure.Token).Token, nil
}

View File

@ -19,7 +19,6 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
@ -34,18 +33,23 @@ import (
// Bitbucket is a Bitbucket Server notifier.
type Bitbucket struct {
Owner string
Repo string
ProviderUID string
Client *bitbucket.Client
Owner string
Repo string
CommitStatus string
Client *bitbucket.Client
}
// NewBitbucket creates and returns a new Bitbucket notifier.
func NewBitbucket(providerUID string, addr string, token string, certPool *x509.CertPool) (*Bitbucket, error) {
func NewBitbucket(commitStatus string, addr string, token string, tlsConfig *tls.Config) (*Bitbucket, error) {
if len(token) == 0 {
return nil, errors.New("bitbucket token cannot be empty")
}
// this should never happen
if commitStatus == "" {
return nil, errors.New("commit status cannot be empty")
}
_, id, err := parseGitAddress(addr)
if err != nil {
return nil, err
@ -66,21 +70,19 @@ func NewBitbucket(providerUID string, addr string, token string, certPool *x509.
repo := comp[1]
client := bitbucket.NewBasicAuth(username, password)
if certPool != nil {
if tlsConfig != nil {
tr := &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
},
TLSClientConfig: tlsConfig,
}
hc := &http.Client{Transport: tr}
client.HttpClient = hc
}
return &Bitbucket{
Owner: owner,
Repo: repo,
ProviderUID: providerUID,
Client: client,
Owner: owner,
Repo: repo,
CommitStatus: commitStatus,
Client: client,
}, nil
}
@ -91,7 +93,7 @@ func (b Bitbucket) Post(ctx context.Context, event eventv1.Event) error {
return nil
}
revString, ok := event.Metadata[eventv1.MetaRevisionKey]
revString, ok := event.GetRevision()
if !ok {
return errors.New("missing revision metadata")
}
@ -105,7 +107,7 @@ func (b Bitbucket) Post(ctx context.Context, event eventv1.Event) error {
}
name, desc := formatNameAndDescription(event)
id := generateCommitStatusID(b.ProviderUID, event)
id := b.CommitStatus
// key has a limitation of 40 characters in bitbucket api
key := sha1String(id)

View File

@ -18,6 +18,7 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
@ -31,10 +32,10 @@ import (
)
func Fuzz_Bitbucket(f *testing.F) {
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "user:pass", "org/repo", "revision/dsa123a", "info", []byte{}, []byte(`{"state":"SUCCESSFUL","description":"","key":"","name":"","url":""}`))
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "user:pass", "org/repo", "revision/dsa123a", "error", []byte{}, []byte(`{}`))
f.Add("kustomization/gitops-system/0c9c2e41", "user:pass", "org/repo", "revision/dsa123a", "info", []byte{}, []byte(`{"state":"SUCCESSFUL","description":"","key":"","name":"","url":""}`))
f.Add("kustomization/gitops-system/0c9c2e41", "user:pass", "org/repo", "revision/dsa123a", "error", []byte{}, []byte(`{}`))
f.Fuzz(func(t *testing.T, uuid, token, urlSuffix, revision, severity string, seed, response []byte) {
f.Fuzz(func(t *testing.T, commitStatus, token, urlSuffix, revision, severity string, seed, response []byte) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.Copy(io.Discard, r.Body)
w.Write(response)
@ -45,7 +46,8 @@ func Fuzz_Bitbucket(f *testing.F) {
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
bitbucket, err := NewBitbucket(uuid, fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert)
tlsConfig := &tls.Config{RootCAs: &cert}
bitbucket, err := NewBitbucket(commitStatus, fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, tlsConfig)
if err != nil {
return
}

View File

@ -23,18 +23,24 @@ import (
)
func TestNewBitbucketBasic(t *testing.T) {
b, err := NewBitbucket("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://bitbucket.org/foo/bar", "foo:bar", nil)
b, err := NewBitbucket("kustomization/gitops-system/0c9c2e41", "https://bitbucket.org/foo/bar", "foo:bar", nil)
assert.Nil(t, err)
assert.Equal(t, b.Owner, "foo")
assert.Equal(t, b.Repo, "bar")
assert.Equal(t, b.CommitStatus, "kustomization/gitops-system/0c9c2e41")
}
func TestNewBitbucketEmptyCommitStatus(t *testing.T) {
_, err := NewBitbucket("", "https://bitbucket.org/foo/bar", "foo:bar", nil)
assert.NotNil(t, err)
}
func TestNewBitbucketInvalidUrl(t *testing.T) {
_, err := NewBitbucket("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://bitbucket.org/foo/bar/baz", "foo:bar", nil)
_, err := NewBitbucket("kustomization/gitops-system/0c9c2e41", "https://bitbucket.org/foo/bar/baz", "foo:bar", nil)
assert.NotNil(t, err)
}
func TestNewBitbucketInvalidToken(t *testing.T) {
_, err := NewBitbucket("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://bitbucket.org/foo/bar", "bar", nil)
_, err := NewBitbucket("kustomization/gitops-system/0c9c2e41", "https://bitbucket.org/foo/bar", "bar", nil)
assert.NotNil(t, err)
}

View File

@ -20,7 +20,6 @@ import (
"bytes"
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
@ -37,11 +36,9 @@ import (
// BitbucketServer is a notifier for BitBucket Server and Data Center.
type BitbucketServer struct {
ProjectKey string
RepositorySlug string
ProviderUID string
CommitStatus string
Url *url.URL
ProviderAddress string
Host string
Username string
Password string
Token string
@ -49,8 +46,10 @@ type BitbucketServer struct {
}
const (
bbServerEndPointTmpl = "/rest/api/latest/projects/%[1]s/repos/%[2]s/commits/%[3]s/builds"
bbServerEndPointCommitsTmpl = "%[1]s/rest/api/latest/projects/%[2]s/repos/%[3]s/commits"
bbServerEndPointBuildsTmpl = "%[1]s/builds"
bbServerGetBuildStatusQueryString = "key"
bbServerSourceCodeMgmtString = "/scm/"
)
type bbServerBuildStatus struct {
@ -81,25 +80,21 @@ type bbServerBuildStatusSetRequest struct {
}
// NewBitbucketServer creates and returns a new BitbucketServer notifier.
func NewBitbucketServer(providerUID string, addr string, token string, certPool *x509.CertPool, username string, password string) (*BitbucketServer, error) {
hst, id, err := parseBitbucketServerGitAddress(addr)
func NewBitbucketServer(commitStatus string, addr string, token string, tlsConfig *tls.Config, username string, password string) (*BitbucketServer, error) {
url, err := parseBitbucketServerGitAddress(addr)
if err != nil {
return nil, err
}
comp := strings.Split(id, "/")
if len(comp) != 2 {
return nil, fmt.Errorf("invalid repository id %q", id)
// this should never happen
if commitStatus == "" {
return nil, errors.New("commit status cannot be empty")
}
projectkey := comp[0]
reposlug := comp[1]
httpClient := retryablehttp.NewClient()
if certPool != nil {
if tlsConfig != nil {
httpClient.HTTPClient.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
},
TLSClientConfig: tlsConfig,
}
}
@ -114,10 +109,8 @@ func NewBitbucketServer(providerUID string, addr string, token string, certPool
}
return &BitbucketServer{
ProjectKey: projectkey,
RepositorySlug: reposlug,
ProviderUID: providerUID,
Host: hst,
CommitStatus: commitStatus,
Url: url,
ProviderAddress: addr,
Token: token,
Username: username,
@ -132,7 +125,7 @@ func (b BitbucketServer) Post(ctx context.Context, event eventv1.Event) error {
if event.HasReason(meta.ProgressingReason) {
return nil
}
revString, ok := event.Metadata[eventv1.MetaRevisionKey]
revString, ok := event.GetRevision()
if !ok {
return errors.New("missing revision metadata")
}
@ -147,18 +140,18 @@ func (b BitbucketServer) Post(ctx context.Context, event eventv1.Event) error {
name, desc := formatNameAndDescription(event)
name = name + " [" + desc + "]" //Bitbucket server displays this data on browser. Thus adding description here.
id := generateCommitStatusID(b.ProviderUID, event)
id := b.CommitStatus
// key has a limitation of 40 characters in bitbucket api
key := sha1String(id)
u := b.Host + b.createApiPath(rev)
dupe, err := b.duplicateBitbucketServerStatus(ctx, rev, state, name, desc, id, key, u)
u := b.Url.JoinPath(b.createBuildPath(rev)).String()
dupe, err := b.duplicateBitbucketServerStatus(ctx, state, name, desc, key, u)
if err != nil {
return fmt.Errorf("could not get existing commit status: %w", err)
}
if !dupe {
_, err = b.postBuildStatus(ctx, rev, state, name, desc, id, key, u)
_, err = b.postBuildStatus(ctx, state, name, desc, key, u)
if err != nil {
return fmt.Errorf("could not post build status: %w", err)
}
@ -178,9 +171,9 @@ func (b BitbucketServer) state(severity string) (string, error) {
}
}
func (b BitbucketServer) duplicateBitbucketServerStatus(ctx context.Context, rev, state, name, desc, id, key, u string) (bool, error) {
func (b BitbucketServer) duplicateBitbucketServerStatus(ctx context.Context, state, name, desc, key, u string) (bool, error) {
// Prepare request object
req, err := b.prepareCommonRequest(ctx, u, nil, http.MethodGet, key, rev)
req, err := b.prepareCommonRequest(ctx, u, nil, http.MethodGet)
if err != nil {
return false, fmt.Errorf("could not check duplicate commit status: %w", err)
}
@ -192,10 +185,10 @@ func (b BitbucketServer) duplicateBitbucketServerStatus(ctx context.Context, rev
// Make a GET call
d, err := b.Client.Do(req)
if err != nil && d.StatusCode != http.StatusNotFound {
if err != nil {
return false, fmt.Errorf("failed api call to check duplicate commit status: %w", err)
}
if isError(d) && d.StatusCode != http.StatusNotFound {
if d != nil && isError(d) && d.StatusCode != http.StatusNotFound {
defer d.Body.Close()
return false, fmt.Errorf("failed api call to check duplicate commit status: %d - %s", d.StatusCode, http.StatusText(d.StatusCode))
}
@ -219,7 +212,7 @@ func (b BitbucketServer) duplicateBitbucketServerStatus(ctx context.Context, rev
return false, nil
}
func (b BitbucketServer) postBuildStatus(ctx context.Context, rev, state, name, desc, id, key, url string) (*http.Response, error) {
func (b BitbucketServer) postBuildStatus(ctx context.Context, state, name, desc, key, url string) (*http.Response, error) {
//Prepare json body
j := &bbServerBuildStatusSetRequest{
Key: key,
@ -235,7 +228,7 @@ func (b BitbucketServer) postBuildStatus(ctx context.Context, rev, state, name,
}
//Prepare request
req, err := b.prepareCommonRequest(ctx, url, p, http.MethodPost, key, rev)
req, err := b.prepareCommonRequest(ctx, url, p, http.MethodPost)
if err != nil {
return nil, fmt.Errorf("failed preparing request for post build commit status: %w", err)
}
@ -257,21 +250,46 @@ func (b BitbucketServer) postBuildStatus(ctx context.Context, rev, state, name,
return resp, nil
}
func (b BitbucketServer) createApiPath(rev string) string {
return fmt.Sprintf(bbServerEndPointTmpl, b.ProjectKey, b.RepositorySlug, rev)
func (b BitbucketServer) createBuildPath(rev string) string {
return fmt.Sprintf(bbServerEndPointBuildsTmpl, rev)
}
func parseBitbucketServerGitAddress(s string) (string, string, error) {
host, id, err := parseGitAddress(s)
func parseBitbucketServerGitAddress(s string) (*url.URL, error) {
u, err := url.Parse(s)
if err != nil {
return "", "", fmt.Errorf("could not parse git address: %w", err)
return nil, fmt.Errorf("could not parse git address: %w", err)
}
//Remove "scm/" --> https://community.atlassian.com/t5/Bitbucket-questions/remote-url-in-Bitbucket-server-what-does-scm-represent-is-it/qaq-p/2060987
id = strings.TrimPrefix(id, "scm/")
return host, id, nil
if u.Scheme != "http" && u.Scheme != "https" {
return nil, fmt.Errorf("could not parse git address: unsupported scheme type in address: %s. Must be http or https", u.Scheme)
}
idWithContext := strings.TrimSuffix(u.Path, ".git")
// /scm/ is always part of http/https clone urls : https://community.atlassian.com/t5/Bitbucket-questions/remote-url-in-Bitbucket-server-what-does-scm-represent-is-it/qaq-p/2060987
lastIndex := strings.LastIndex(idWithContext, bbServerSourceCodeMgmtString)
if lastIndex < 0 {
return nil, fmt.Errorf("could not parse git address: supplied provider address is not http(s) git clone url")
}
// Handle context scenarios --> https://confluence.atlassian.com/bitbucketserver/change-bitbucket-s-context-path-776640153.html
cntxtPath := idWithContext[:lastIndex] // Context path is anything that comes before last /scm/
id := idWithContext[lastIndex+len(bbServerSourceCodeMgmtString):] // Remove last `/scm/` from id as it is not used in API calls
comp := strings.Split(id, "/")
if len(comp) != 2 {
return nil, fmt.Errorf("could not parse git address: invalid repository id %q", id)
}
projectkey := comp[0]
reposlug := comp[1]
// Update the path till commits endpoint. The final builds endpoint would be added in Post function.
u.Path = fmt.Sprintf(bbServerEndPointCommitsTmpl, cntxtPath, projectkey, reposlug)
return u, nil
}
func (b BitbucketServer) prepareCommonRequest(ctx context.Context, path string, body io.Reader, method string, key, rev string) (*retryablehttp.Request, error) {
func (b BitbucketServer) prepareCommonRequest(ctx context.Context, path string, body io.Reader, method string) (*retryablehttp.Request, error) {
req, err := retryablehttp.NewRequestWithContext(ctx, method, path, body)
if err != nil {
return nil, fmt.Errorf("could not prepare request: %w", err)

View File

@ -20,6 +20,7 @@ import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"testing"
@ -33,33 +34,91 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestNewBitbucketServerBasic(t *testing.T) {
b, err := NewBitbucketServer("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://example.com:7990/scm/projectfoo/repobar.git", "", nil, "dummyuser", "testpassword")
func TestNewBitbucketServerBasicNoContext(t *testing.T) {
b, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/scm/projectfoo/repobar.git", "", nil, "dummyuser", "testpassword")
assert.Nil(t, err)
assert.Equal(t, b.Username, "dummyuser")
assert.Equal(t, b.Password, "testpassword")
assert.Equal(t, b.Url.Scheme, "https")
assert.Equal(t, b.Url.Host, "example.com:7990")
}
func TestNewBitbucketServerBasicWithContext(t *testing.T) {
b, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/context/scm/projectfoo/repobar.git", "", nil, "dummyuser", "testpassword")
assert.Nil(t, err)
assert.Equal(t, b.Username, "dummyuser")
assert.Equal(t, b.Password, "testpassword")
assert.Equal(t, b.Url.Scheme, "https")
assert.Equal(t, b.Url.Host, "example.com:7990")
}
func TestBitbucketServerApiPathNoContext(t *testing.T) {
b, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/scm/projectfoo/repobar.git", "", nil, "dummyuser", "testpassword")
assert.Nil(t, err)
u := b.Url.JoinPath(b.createBuildPath("00151b98e303e19610378e6f1c49e31e5e80cd3b")).String()
assert.Equal(t, u, "https://example.com:7990/rest/api/latest/projects/projectfoo/repos/repobar/commits/00151b98e303e19610378e6f1c49e31e5e80cd3b/builds")
}
func TestBitbucketServerApiPathOneWordContext(t *testing.T) {
b, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/context1/scm/projectfoo/repobar.git", "", nil, "dummyuser", "testpassword")
assert.Nil(t, err)
u := b.Url.JoinPath(b.createBuildPath("00151b98e303e19610378e6f1c49e31e5e80cd3b")).String()
assert.Equal(t, u, "https://example.com:7990/context1/rest/api/latest/projects/projectfoo/repos/repobar/commits/00151b98e303e19610378e6f1c49e31e5e80cd3b/builds")
}
func TestBitbucketServerApiPathMultipleWordContext(t *testing.T) {
b, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/context1/context2/context3/scm/projectfoo/repobar.git", "", nil, "dummyuser", "testpassword")
assert.Nil(t, err)
u := b.Url.JoinPath(b.createBuildPath("00151b98e303e19610378e6f1c49e31e5e80cd3b")).String()
assert.Equal(t, u, "https://example.com:7990/context1/context2/context3/rest/api/latest/projects/projectfoo/repos/repobar/commits/00151b98e303e19610378e6f1c49e31e5e80cd3b/builds")
}
func TestBitbucketServerApiPathOneWordScmInContext(t *testing.T) {
b, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/scm/scm/projectfoo/repobar.git", "", nil, "dummyuser", "testpassword")
assert.Nil(t, err)
u := b.Url.JoinPath(b.createBuildPath("00151b98e303e19610378e6f1c49e31e5e80cd3b")).String()
assert.Equal(t, u, "https://example.com:7990/scm/rest/api/latest/projects/projectfoo/repos/repobar/commits/00151b98e303e19610378e6f1c49e31e5e80cd3b/builds")
}
func TestBitbucketServerApiPathMultipleWordScmInContext(t *testing.T) {
b, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/scm/context2/scm/scm/projectfoo/repobar.git", "", nil, "dummyuser", "testpassword")
assert.Nil(t, err)
u := b.Url.JoinPath(b.createBuildPath("00151b98e303e19610378e6f1c49e31e5e80cd3b")).String()
assert.Equal(t, u, "https://example.com:7990/scm/context2/scm/rest/api/latest/projects/projectfoo/repos/repobar/commits/00151b98e303e19610378e6f1c49e31e5e80cd3b/builds")
}
func TestBitbucketServerApiPathScmAlreadyRemovedInInput(t *testing.T) {
_, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/context1/context2/context3/projectfoo/repobar.git", "", nil, "dummyuser", "testpassword")
assert.NotNil(t, err)
assert.Equal(t, err.Error(), "could not parse git address: supplied provider address is not http(s) git clone url")
}
func TestBitbucketServerSshAddress(t *testing.T) {
_, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "ssh://git@mybitbucket:2222/ap/fluxcd-sandbox.git", "", nil, "", "")
assert.NotNil(t, err)
assert.Equal(t, err.Error(), "could not parse git address: unsupported scheme type in address: ssh. Must be http or https")
}
func TestNewBitbucketServerToken(t *testing.T) {
b, err := NewBitbucketServer("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://example.com:7990/scm/projectfoo/repobar.git", "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP", nil, "", "")
b, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/scm/projectfoo/repobar.git", "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP", nil, "", "")
assert.Nil(t, err)
assert.Equal(t, b.Token, "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP")
}
func TestNewBitbucketServerInvalidCreds(t *testing.T) {
_, err := NewBitbucketServer("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://example.com:7990/scm/projectfoo/repobar.git", "", nil, "", "")
_, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/scm/projectfoo/repobar.git", "", nil, "", "")
assert.NotNil(t, err)
assert.Equal(t, err.Error(), "invalid credentials, expected to be one of username/password or API Token")
}
func TestNewBitbucketServerInvalidRepo(t *testing.T) {
_, err := NewBitbucketServer("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://example.com:7990/scm/projectfoo/repobar/invalid.git", "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP", nil, "", "")
_, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/scm/projectfoo/repobar/invalid.git", "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP", nil, "", "")
assert.NotNil(t, err)
assert.Equal(t, err.Error(), "invalid repository id \"projectfoo/repobar/invalid\"")
assert.Equal(t, err.Error(), "could not parse git address: invalid repository id \"projectfoo/repobar/invalid\"")
}
func TestPostBitbucketServerMissingRevision(t *testing.T) {
b, err := NewBitbucketServer("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://example.com:7990/scm/projectfoo/repobar.git", "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP", nil, "", "")
b, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/scm/projectfoo/repobar.git", "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP", nil, "", "")
assert.Nil(t, err)
//Validate missing revision
@ -70,8 +129,14 @@ func TestPostBitbucketServerMissingRevision(t *testing.T) {
assert.Equal(t, err.Error(), "missing revision metadata")
}
func TestNewBitbucketServerEmptyCommitStatus(t *testing.T) {
_, err := NewBitbucketServer("", "https://example.com:7990/scm/projectfoo/repobar.git", "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP", nil, "", "")
assert.NotNil(t, err)
assert.Equal(t, err.Error(), "commit status cannot be empty")
}
func TestPostBitbucketServerBadCommitHash(t *testing.T) {
b, err := NewBitbucketServer("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://example.com:7990/scm/projectfoo/repobar.git", "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP", nil, "", "")
b, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/scm/projectfoo/repobar.git", "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP", nil, "", "")
assert.Nil(t, err)
//Validate extract commit hash
@ -84,7 +149,7 @@ func TestPostBitbucketServerBadCommitHash(t *testing.T) {
}
func TestPostBitbucketServerBadBitbucketState(t *testing.T) {
b, err := NewBitbucketServer("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://example.com:7990/scm/projectfoo/repobar.git", "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP", nil, "", "")
b, err := NewBitbucketServer("kustomization/gitops-system/0c9c2e41", "https://example.com:7990/scm/projectfoo/repobar.git", "BBDC-ODIxODYxMzIyNzUyOttorMjO059P2rYTb6EH7mP", nil, "", "")
assert.Nil(t, err)
//Validate conversion to bitbucket state
@ -123,13 +188,14 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
password string
token string
event eventv1.Event
provideruid string
commitStatus string
key string
uriHash string
}{
{
name: "Validate Token Auth ",
token: "goodtoken",
provideruid: "0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a",
name: "Validate Token Auth ",
token: "goodtoken",
commitStatus: "kustomization/gitops-system/0c9c2e41",
headers: map[string]string{
"Authorization": "Bearer goodtoken",
"x-atlassian-token": "no-check",
@ -138,15 +204,30 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
event: generateTestEventKustomization("info", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}),
key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("info", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}))),
key: sha1String("kustomization/gitops-system/0c9c2e41"),
uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
},
{
name: "Validate Basic Auth and Post State=Successful",
username: "hello",
password: "password",
provideruid: "0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a",
name: "Event with origin revision",
token: "goodtoken",
commitStatus: "kustomization/gitops-system/0c9c2e41",
headers: map[string]string{
"Authorization": "Bearer goodtoken",
"x-atlassian-token": "no-check",
"x-requested-with": "XMLHttpRequest",
},
event: generateTestEventKustomization("info", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
eventv1.MetaOriginRevisionKey: "main@sha1:e7c17dd8b8384bbc84b7e7385394cb7f48332b2d",
}),
key: sha1String("kustomization/gitops-system/0c9c2e41"),
uriHash: "e7c17dd8b8384bbc84b7e7385394cb7f48332b2d",
},
{
name: "Validate Basic Auth and Post State=Successful",
username: "hello",
password: "password",
commitStatus: "kustomization/gitops-system/0c9c2e41",
headers: map[string]string{
"Authorization": "Basic " + base64.StdEncoding.EncodeToString([]byte("hello"+":"+"password")),
"x-atlassian-token": "no-check",
@ -155,15 +236,14 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
event: generateTestEventKustomization("info", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}),
key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("info", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}))),
key: sha1String("kustomization/gitops-system/0c9c2e41"),
uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
},
{
name: "Validate Post State=Failed",
username: "hello",
password: "password",
provideruid: "0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a",
name: "Validate Post State=Failed",
username: "hello",
password: "password",
commitStatus: "kustomization/gitops-system/0c9c2e41",
headers: map[string]string{
"Authorization": "Basic " + base64.StdEncoding.EncodeToString([]byte("hello"+":"+"password")),
"x-atlassian-token": "no-check",
@ -172,9 +252,8 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
event: generateTestEventKustomization("error", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}),
key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("error", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}))),
key: sha1String("kustomization/gitops-system/0c9c2e41"),
uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
},
{
name: "Fail if bad json response in existing commit status",
@ -182,7 +261,7 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
errorString: "could not get existing commit status: could not unmarshal json response body for duplicate commit status: unexpected end of JSON input",
username: "hello",
password: "password",
provideruid: "0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a",
commitStatus: "kustomization/gitops-system/0c9c2e41",
headers: map[string]string{
"Authorization": "Basic " + base64.StdEncoding.EncodeToString([]byte("hello"+":"+"password")),
"x-atlassian-token": "no-check",
@ -191,9 +270,8 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
event: generateTestEventKustomization("error", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}),
key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("error", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}))),
key: sha1String("kustomization/gitops-system/0c9c2e41"),
uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
},
{
name: "Fail if status code is non-200 in existing commit status",
@ -201,7 +279,7 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
errorString: "could not get existing commit status: failed api call to check duplicate commit status: 400 - Bad Request",
username: "hello",
password: "password",
provideruid: "0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a",
commitStatus: "kustomization/gitops-system/0c9c2e41",
headers: map[string]string{
"Authorization": "Basic " + base64.StdEncoding.EncodeToString([]byte("hello"+":"+"password")),
"x-atlassian-token": "no-check",
@ -210,9 +288,8 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
event: generateTestEventKustomization("error", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}),
key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("error", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}))),
key: sha1String("kustomization/gitops-system/0c9c2e41"),
uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
},
{
name: "Bad post- Unauthorized",
@ -220,7 +297,7 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
errorString: "could not post build status: could not post build commit status: 401 - Unauthorized",
username: "hello",
password: "password",
provideruid: "0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a",
commitStatus: "kustomization/gitops-system/0c9c2e41",
headers: map[string]string{
"Authorization": "Basic " + base64.StdEncoding.EncodeToString([]byte("hello"+":"+"password")),
"x-atlassian-token": "no-check",
@ -229,15 +306,14 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
event: generateTestEventKustomization("error", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}),
key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("error", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}))),
key: sha1String("kustomization/gitops-system/0c9c2e41"),
uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
},
{
name: "Validate duplicate commit status successful match",
username: "hello",
password: "password",
provideruid: "0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a",
name: "Validate duplicate commit status successful match",
username: "hello",
password: "password",
commitStatus: "kustomization/gitops-system/0c9c2e41",
headers: map[string]string{
"Authorization": "Basic " + base64.StdEncoding.EncodeToString([]byte("hello"+":"+"password")),
"x-atlassian-token": "no-check",
@ -246,9 +322,8 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
event: generateTestEventKustomization("info", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}),
key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("info", map[string]string{
eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
}))),
key: sha1String("kustomization/gitops-system/0c9c2e41"),
uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738",
},
}
@ -262,7 +337,8 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
}
// Validate URI
require.Equal(t, r.URL.Path, "/rest/api/latest/projects/projectfoo/repos/repobar/commits/5394cb7f48332b2de7c17dd8b8384bbc84b7e738/builds")
path := fmt.Sprintf("/rest/api/latest/projects/projectfoo/repos/repobar/commits/%s/builds", tt.uriHash)
require.Equal(t, r.URL.Path, path)
// Validate Get Build Status call
if r.Method == http.MethodGet {
@ -281,7 +357,7 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
jsondata, _ := json.Marshal(&bbServerBuildStatus{
Name: name,
Description: desc,
Key: sha1String(generateCommitStatusID(tt.provideruid, tt.event)),
Key: sha1String(tt.commitStatus),
State: "SUCCESSFUL",
Url: "https://example.com:7990/scm/projectfoo/repobar.git",
})
@ -364,7 +440,7 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) {
}
}))
defer ts.Close()
c, err := NewBitbucketServer(tt.provideruid, ts.URL+"/scm/projectfoo/repobar.git", tt.token, nil, tt.username, tt.password)
c, err := NewBitbucketServer(tt.commitStatus, ts.URL+"/scm/projectfoo/repobar.git", tt.token, nil, tt.username, tt.password)
require.NoError(t, err)
err = c.Post(context.TODO(), tt.event)
if tt.testFailReason == "" {

View File

@ -19,91 +19,130 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"net/url"
"runtime"
"time"
"github.com/hashicorp/go-retryablehttp"
)
type requestOptFunc func(*retryablehttp.Request)
type postOptions struct {
proxy string
tlsConfig *tls.Config
requestModifier func(*retryablehttp.Request)
responseValidator func(statusCode int, body []byte) error
}
func postMessage(ctx context.Context, address, proxy string, certPool *x509.CertPool, payload interface{}, reqOpts ...requestOptFunc) error {
httpClient := retryablehttp.NewClient()
if certPool != nil {
httpClient.HTTPClient.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
},
}
}
type postOption func(*postOptions)
if proxy != "" {
proxyURL, err := url.Parse(proxy)
if err != nil {
return fmt.Errorf("unable to parse proxy URL '%s', error: %w", proxy, err)
}
var tlsConfig *tls.Config
if certPool != nil {
tlsConfig = &tls.Config{
RootCAs: certPool,
func postMessage(ctx context.Context, address string, payload interface{}, opts ...postOption) error {
options := &postOptions{
// Default validateResponse function verifies that the response status code is 200, 202 or 201.
responseValidator: func(statusCode int, body []byte) error {
if statusCode == http.StatusOK ||
statusCode == http.StatusAccepted ||
statusCode == http.StatusCreated {
return nil
}
}
httpClient.HTTPClient.Transport = &http.Transport{
Proxy: http.ProxyURL(proxyURL),
TLSClientConfig: tlsConfig,
DialContext: (&net.Dialer{
Timeout: 15 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1,
}
return fmt.Errorf("request failed with status code %d, %s", statusCode, string(body))
},
}
httpClient.HTTPClient.Timeout = 15 * time.Second
httpClient.RetryWaitMin = 2 * time.Second
httpClient.RetryWaitMax = 30 * time.Second
httpClient.RetryMax = 4
httpClient.Logger = nil
for _, o := range opts {
o(options)
}
httpClient, err := newHTTPClient(options)
if err != nil {
return err
}
data, err := json.Marshal(payload)
if err != nil {
return fmt.Errorf("marshalling notification payload failed: %w", err)
}
req, err := retryablehttp.NewRequest(http.MethodPost, address, data)
req, err := retryablehttp.NewRequestWithContext(ctx, http.MethodPost, address, data)
if err != nil {
return fmt.Errorf("failed to create a new request: %w", err)
}
if ctx != nil {
req = req.WithContext(ctx)
}
req.Header.Set("Content-Type", "application/json")
for _, o := range reqOpts {
o(req)
if options.requestModifier != nil {
options.requestModifier(req)
}
resp, err := httpClient.Do(req)
if err != nil {
return fmt.Errorf("failed to execute request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusAccepted && resp.StatusCode != http.StatusCreated {
b, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("unable to read response body, %s", err)
}
return fmt.Errorf("request failed with status code %d, %s", resp.StatusCode, string(b))
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %w", err)
}
if err := options.responseValidator(resp.StatusCode, body); err != nil {
return fmt.Errorf("request failed: %w", err)
}
return nil
}
func withProxy(proxy string) postOption {
return func(opts *postOptions) {
opts.proxy = proxy
}
}
func withTLSConfig(tlsConfig *tls.Config) postOption {
return func(opts *postOptions) {
opts.tlsConfig = tlsConfig
}
}
func withRequestModifier(reqModifier func(*retryablehttp.Request)) postOption {
return func(opts *postOptions) {
opts.requestModifier = reqModifier
}
}
func withResponseValidator(respValidator func(statusCode int, body []byte) error) postOption {
return func(opts *postOptions) {
opts.responseValidator = respValidator
}
}
func newHTTPClient(opts *postOptions) (*retryablehttp.Client, error) {
httpClient := retryablehttp.NewClient()
transport := httpClient.HTTPClient.Transport.(*http.Transport)
if opts.tlsConfig != nil {
transport.TLSClientConfig = opts.tlsConfig
}
if opts.proxy != "" {
proxyURL, err := url.Parse(opts.proxy)
if err != nil {
return nil, fmt.Errorf("unable to parse proxy URL: %w", err)
}
transport.Proxy = http.ProxyURL(proxyURL)
}
// Disable the timeout for the HTTP client,
// as we set the provider timeout on the context.
httpClient.HTTPClient.Timeout = 0
httpClient.RetryWaitMin = 2 * time.Second
httpClient.RetryWaitMax = 30 * time.Second
httpClient.RetryMax = 4
httpClient.Logger = nil
return httpClient, nil
}

View File

@ -18,14 +18,19 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/hashicorp/go-retryablehttp"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -44,10 +49,21 @@ func Test_postMessage(t *testing.T) {
require.Equal(t, "success", payload["status"])
}))
defer ts.Close()
err := postMessage(context.Background(), ts.URL, "", nil, map[string]string{"status": "success"})
err := postMessage(context.Background(), ts.URL, map[string]string{"status": "success"})
require.NoError(t, err)
}
func Test_postMessage_timeout(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(2 * time.Second)
}))
defer ts.Close()
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
err := postMessage(ctx, ts.URL, map[string]string{"status": "success"})
require.Error(t, err, "context deadline exceeded")
}
func Test_postSelfSignedCert(t *testing.T) {
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
b, err := io.ReadAll(r.Body)
@ -65,10 +81,43 @@ func Test_postSelfSignedCert(t *testing.T) {
require.NoError(t, err)
certpool := x509.NewCertPool()
certpool.AddCert(cert)
err = postMessage(context.Background(), ts.URL, "", certpool, map[string]string{"status": "success"})
tlsConfig := &tls.Config{RootCAs: certpool}
err = postMessage(context.Background(), ts.URL, map[string]string{"status": "success"}, withTLSConfig(tlsConfig))
require.NoError(t, err)
}
func Test_postMessage_requestModifier(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) {
require.Equal(t, "Bearer token", r.Header.Get("Authorization"))
}))
defer ts.Close()
err := postMessage(context.Background(), ts.URL, map[string]string{"status": "success"}, withRequestModifier(func(req *retryablehttp.Request) {
req.Header.Set("Authorization", "Bearer token")
}))
require.NoError(t, err)
}
func Test_postMessage_responseValidator(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Default response validator determines success, but the custom validator below will determine failure .
w.WriteHeader(http.StatusOK)
w.Write([]byte("error: bad request"))
}))
defer ts.Close()
err := postMessage(context.Background(), ts.URL, map[string]string{"status": "success"})
require.NoError(t, err)
err = postMessage(context.Background(), ts.URL, map[string]string{"status": "success"}, withResponseValidator(func(_ int, body []byte) error {
if strings.HasPrefix(string(body), "error:") {
return errors.New(string(body))
}
return nil
}))
require.ErrorContains(t, err, "request failed: error: bad request")
}
func testEvent() eventv1.Event {
return eventv1.Event{
InvolvedObject: corev1.ObjectReference{

View File

@ -19,7 +19,6 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"net/http"
"net/url"
@ -41,7 +40,7 @@ type DataDog struct {
// url: The DataDog API endpoint to use. Examples: https://api.datadoghq.com, https://api.datadoghq.eu, etc.
// token: The DataDog API key (not the application key).
// headers: A map of extra tags to add to the event
func NewDataDog(address string, proxyUrl string, certPool *x509.CertPool, token string) (*DataDog, error) {
func NewDataDog(address string, proxyUrl string, tlsConfig *tls.Config, token string) (*DataDog, error) {
conf := datadog.NewConfiguration()
if token == "" {
@ -56,7 +55,7 @@ func NewDataDog(address string, proxyUrl string, certPool *x509.CertPool, token
conf.Host = baseUrl.Host
conf.Scheme = baseUrl.Scheme
if proxyUrl != "" || certPool != nil {
if proxyUrl != "" || tlsConfig != nil {
transport := &http.Transport{}
if proxyUrl != "" {
@ -68,10 +67,8 @@ func NewDataDog(address string, proxyUrl string, certPool *x509.CertPool, token
transport.Proxy = http.ProxyURL(proxy)
}
if certPool != nil {
transport.TLSClientConfig = &tls.Config{
RootCAs: certPool,
}
if tlsConfig != nil {
transport.TLSClientConfig = tlsConfig
}
conf.HTTPClient = &http.Client{

View File

@ -2,6 +2,7 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"io"
"net/http"
@ -33,7 +34,8 @@ func Fuzz_DataDog(f *testing.F) {
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
dd, err := NewDataDog(ts.URL, "", &cert, apiKey)
tlsConfig := &tls.Config{RootCAs: &cert}
dd, err := NewDataDog(ts.URL, "", tlsConfig, apiKey)
if err != nil {
return
}

View File

@ -90,8 +90,12 @@ func (s *Discord) Post(ctx context.Context, event eventv1.Event) error {
payload.Attachments = []SlackAttachment{a}
err := postMessage(ctx, s.URL, s.ProxyURL, nil, payload)
if err != nil {
var opts []postOption
if s.ProxyURL != "" {
opts = append(opts, withProxy(s.ProxyURL))
}
if err := postMessage(ctx, s.URL, payload, opts...); err != nil {
return fmt.Errorf("postMessage failed: %w", err)
}

View File

@ -17,114 +17,341 @@ limitations under the License.
package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/pkg/cache"
apiv1 "github.com/fluxcd/notification-controller/api/v1beta3"
)
type Factory struct {
URL string
ProxyURL string
Username string
Channel string
Token string
Headers map[string]string
CertPool *x509.CertPool
Password string
ProviderUID string
var (
// notifiers is a map of notifier names to factory functions.
notifiers = notifierMap{
// GenericProvider is the default notifier
apiv1.GenericProvider: genericNotifierFunc,
apiv1.GenericHMACProvider: genericHMACNotifierFunc,
apiv1.SlackProvider: slackNotifierFunc,
apiv1.DiscordProvider: discordNotifierFunc,
apiv1.RocketProvider: rocketNotifierFunc,
apiv1.MSTeamsProvider: msteamsNotifierFunc,
apiv1.GoogleChatProvider: googleChatNotifierFunc,
apiv1.GooglePubSubProvider: googlePubSubNotifierFunc,
apiv1.WebexProvider: webexNotifierFunc,
apiv1.SentryProvider: sentryNotifierFunc,
apiv1.AzureEventHubProvider: azureEventHubNotifierFunc,
apiv1.TelegramProvider: telegramNotifierFunc,
apiv1.LarkProvider: larkNotifierFunc,
apiv1.Matrix: matrixNotifierFunc,
apiv1.OpsgenieProvider: opsgenieNotifierFunc,
apiv1.AlertManagerProvider: alertmanagerNotifierFunc,
apiv1.GrafanaProvider: grafanaNotifierFunc,
apiv1.PagerDutyProvider: pagerDutyNotifierFunc,
apiv1.DataDogProvider: dataDogNotifierFunc,
apiv1.NATSProvider: natsNotifierFunc,
apiv1.GitHubProvider: gitHubNotifierFunc,
apiv1.GitHubDispatchProvider: gitHubDispatchNotifierFunc,
apiv1.GitLabProvider: gitLabNotifierFunc,
apiv1.GiteaProvider: giteaNotifierFunc,
apiv1.BitbucketServerProvider: bitbucketServerNotifierFunc,
apiv1.BitbucketProvider: bitbucketNotifierFunc,
apiv1.AzureDevOpsProvider: azureDevOpsNotifierFunc,
}
)
// notifierMap is a map of provider names to notifier factory functions
type notifierMap map[string]factoryFunc
// factoryFunc is a factory function that creates a new notifier
type factoryFunc func(opts notifierOptions) (Interface, error)
type notifierOptions struct {
Context context.Context
URL string
ProxyURL string
Username string
Channel string
Token string
Headers map[string]string
// CertPool is kept for Git platform providers (GitHub, GitLab, etc.) that use third-party SDKs.
// TODO: Remove this field once all notifiers support client certificate authentication via TLSConfig.
CertPool *x509.CertPool
TLSConfig *tls.Config
Password string
CommitStatus string
ProviderName string
ProviderNamespace string
SecretData map[string][]byte
ServiceAccountName string
TokenCache *cache.TokenCache
TokenClient client.Client
}
func NewFactory(url string,
proxy string,
username string,
channel string,
token string,
headers map[string]string,
certPool *x509.CertPool,
password string,
providerUID string) *Factory {
type Factory struct {
notifierOptions
}
// Option represents a functional option for configuring a notifier.
type Option func(*notifierOptions)
// WithProxyURL sets the proxy URL for the notifier.
func WithProxyURL(url string) Option {
return func(o *notifierOptions) {
o.ProxyURL = url
}
}
// WithUsername sets the username for the notifier.
func WithUsername(username string) Option {
return func(o *notifierOptions) {
o.Username = username
}
}
// WithChannel sets the channel for the notifier.
func WithChannel(channel string) Option {
return func(o *notifierOptions) {
o.Channel = channel
}
}
// WithToken sets the token for the notifier.
func WithToken(token string) Option {
return func(o *notifierOptions) {
o.Token = token
}
}
// WithHeaders sets the headers for the notifier.
func WithHeaders(headers map[string]string) Option {
return func(o *notifierOptions) {
o.Headers = headers
}
}
// WithCertPool sets the certificate pool for the notifier.
func WithCertPool(certPool *x509.CertPool) Option {
return func(o *notifierOptions) {
o.CertPool = certPool
}
}
// WithTLSConfig sets the TLS configuration for the notifier.
func WithTLSConfig(tlsConfig *tls.Config) Option {
return func(o *notifierOptions) {
o.TLSConfig = tlsConfig
}
}
// WithPassword sets the password for the notifier.
func WithPassword(password string) Option {
return func(o *notifierOptions) {
o.Password = password
}
}
// WithCommitStatus sets the custom commit status for the notifier.
func WithCommitStatus(commitStatus string) Option {
return func(o *notifierOptions) {
o.CommitStatus = commitStatus
}
}
// WithProviderName sets the provider name for the notifier.
func WithProviderName(name string) Option {
return func(o *notifierOptions) {
o.ProviderName = name
}
}
// WithProviderNamespace sets the provider namespace for the notifier.
func WithProviderNamespace(namespace string) Option {
return func(o *notifierOptions) {
o.ProviderNamespace = namespace
}
}
// WithSecretData sets the secret data for the notifier.
func WithSecretData(data map[string][]byte) Option {
return func(o *notifierOptions) {
o.SecretData = data
}
}
// WithTokenCache sets the token cache for the notifier.
func WithTokenCache(cache *cache.TokenCache) Option {
return func(o *notifierOptions) {
o.TokenCache = cache
}
}
// WithTokenClient sets the token client for the notifier.
func WithTokenClient(kubeClient client.Client) Option {
return func(o *notifierOptions) {
o.TokenClient = kubeClient
}
}
// WithServiceAccount sets the service account for the notifier.
func WithServiceAccount(serviceAccountName string) Option {
return func(o *notifierOptions) {
o.ServiceAccountName = serviceAccountName
}
}
// WithURL sets the webhook URL for the notifier.
func WithURL(url string) Option {
return func(o *notifierOptions) {
o.URL = url
}
}
// NewFactory creates a new notifier factory with optional configurations.
func NewFactory(ctx context.Context, opts ...Option) *Factory {
options := notifierOptions{
Context: ctx,
}
for _, opt := range opts {
opt(&options)
}
return &Factory{
URL: url,
ProxyURL: proxy,
Channel: channel,
Username: username,
Token: token,
Headers: headers,
CertPool: certPool,
Password: password,
ProviderUID: providerUID,
notifierOptions: options,
}
}
func (f Factory) Notifier(provider string) (Interface, error) {
if f.URL == "" {
return &NopNotifier{}, nil
notifier, ok := notifiers[provider]
if !ok {
return nil, fmt.Errorf("provider %s not supported", provider)
}
var n Interface
var err error
switch provider {
case apiv1.GenericProvider:
n, err = NewForwarder(f.URL, f.ProxyURL, f.Headers, f.CertPool, nil)
case apiv1.GenericHMACProvider:
n, err = NewForwarder(f.URL, f.ProxyURL, f.Headers, f.CertPool, []byte(f.Token))
case apiv1.SlackProvider:
n, err = NewSlack(f.URL, f.ProxyURL, f.Token, f.CertPool, f.Username, f.Channel)
case apiv1.DiscordProvider:
n, err = NewDiscord(f.URL, f.ProxyURL, f.Username, f.Channel)
case apiv1.RocketProvider:
n, err = NewRocket(f.URL, f.ProxyURL, f.CertPool, f.Username, f.Channel)
case apiv1.MSTeamsProvider:
n, err = NewMSTeams(f.URL, f.ProxyURL, f.CertPool)
case apiv1.GitHubProvider:
n, err = NewGitHub(f.ProviderUID, f.URL, f.Token, f.CertPool)
case apiv1.GitHubDispatchProvider:
n, err = NewGitHubDispatch(f.URL, f.Token, f.CertPool)
case apiv1.GitLabProvider:
n, err = NewGitLab(f.ProviderUID, f.URL, f.Token, f.CertPool)
case apiv1.GiteaProvider:
n, err = NewGitea(f.ProviderUID, f.URL, f.Token, f.CertPool)
case apiv1.BitbucketServerProvider:
n, err = NewBitbucketServer(f.ProviderUID, f.URL, f.Token, f.CertPool, f.Username, f.Password)
case apiv1.BitbucketProvider:
n, err = NewBitbucket(f.ProviderUID, f.URL, f.Token, f.CertPool)
case apiv1.AzureDevOpsProvider:
n, err = NewAzureDevOps(f.ProviderUID, f.URL, f.Token, f.CertPool)
case apiv1.GoogleChatProvider:
n, err = NewGoogleChat(f.URL, f.ProxyURL)
case apiv1.GooglePubSubProvider:
n, err = NewGooglePubSub(f.URL, f.Channel, f.Token, f.Headers)
case apiv1.WebexProvider:
n, err = NewWebex(f.URL, f.ProxyURL, f.CertPool, f.Channel, f.Token)
case apiv1.SentryProvider:
n, err = NewSentry(f.CertPool, f.URL, f.Channel)
case apiv1.AzureEventHubProvider:
n, err = NewAzureEventHub(f.URL, f.Token, f.Channel)
case apiv1.TelegramProvider:
n, err = NewTelegram(f.Channel, f.Token)
case apiv1.LarkProvider:
n, err = NewLark(f.URL)
case apiv1.Matrix:
n, err = NewMatrix(f.URL, f.Token, f.Channel, f.CertPool)
case apiv1.OpsgenieProvider:
n, err = NewOpsgenie(f.URL, f.ProxyURL, f.CertPool, f.Token)
case apiv1.AlertManagerProvider:
n, err = NewAlertmanager(f.URL, f.ProxyURL, f.CertPool)
case apiv1.GrafanaProvider:
n, err = NewGrafana(f.URL, f.ProxyURL, f.Token, f.CertPool, f.Username, f.Password)
case apiv1.PagerDutyProvider:
n, err = NewPagerDuty(f.URL, f.ProxyURL, f.CertPool, f.Channel)
case apiv1.DataDogProvider:
n, err = NewDataDog(f.URL, f.ProxyURL, f.CertPool, f.Token)
case apiv1.NATSProvider:
n, err = NewNATS(f.URL, f.Channel, f.Username, f.Password)
default:
err = fmt.Errorf("provider %s not supported", provider)
}
if err != nil {
n = &NopNotifier{}
}
return n, err
return notifier(f.notifierOptions)
}
func genericNotifierFunc(opts notifierOptions) (Interface, error) {
return NewForwarder(opts.URL, opts.ProxyURL, opts.Headers, opts.TLSConfig, nil)
}
func genericHMACNotifierFunc(opts notifierOptions) (Interface, error) {
return NewForwarder(opts.URL, opts.ProxyURL, opts.Headers, opts.TLSConfig, []byte(opts.Token))
}
func slackNotifierFunc(opts notifierOptions) (Interface, error) {
return NewSlack(opts.URL, opts.ProxyURL, opts.Token, opts.TLSConfig, opts.Username, opts.Channel)
}
func discordNotifierFunc(opts notifierOptions) (Interface, error) {
return NewDiscord(opts.URL, opts.ProxyURL, opts.Username, opts.Channel)
}
func rocketNotifierFunc(opts notifierOptions) (Interface, error) {
return NewRocket(opts.URL, opts.ProxyURL, opts.TLSConfig, opts.Username, opts.Channel)
}
func msteamsNotifierFunc(opts notifierOptions) (Interface, error) {
return NewMSTeams(opts.URL, opts.ProxyURL, opts.TLSConfig)
}
func googleChatNotifierFunc(opts notifierOptions) (Interface, error) {
return NewGoogleChat(opts.URL, opts.ProxyURL)
}
func googlePubSubNotifierFunc(opts notifierOptions) (Interface, error) {
return NewGooglePubSub(&opts)
}
func webexNotifierFunc(opts notifierOptions) (Interface, error) {
return NewWebex(opts.URL, opts.ProxyURL, opts.TLSConfig, opts.Channel, opts.Token)
}
func sentryNotifierFunc(opts notifierOptions) (Interface, error) {
return NewSentry(opts.TLSConfig, opts.URL, opts.Channel)
}
func azureEventHubNotifierFunc(opts notifierOptions) (Interface, error) {
return NewAzureEventHub(opts.Context, opts.URL, opts.Token, opts.Channel, opts.ProxyURL, opts.ServiceAccountName, opts.ProviderName, opts.ProviderNamespace, opts.TokenClient, opts.TokenCache)
}
func telegramNotifierFunc(opts notifierOptions) (Interface, error) {
return NewTelegram(opts.ProxyURL, opts.Channel, opts.Token)
}
func larkNotifierFunc(opts notifierOptions) (Interface, error) {
return NewLark(opts.URL)
}
func matrixNotifierFunc(opts notifierOptions) (Interface, error) {
return NewMatrix(opts.URL, opts.Token, opts.Channel, opts.TLSConfig)
}
func opsgenieNotifierFunc(opts notifierOptions) (Interface, error) {
return NewOpsgenie(opts.URL, opts.ProxyURL, opts.TLSConfig, opts.Token)
}
func alertmanagerNotifierFunc(opts notifierOptions) (Interface, error) {
return NewAlertmanager(opts.URL, opts.ProxyURL, opts.TLSConfig, opts.Token, opts.Username, opts.Password)
}
func grafanaNotifierFunc(opts notifierOptions) (Interface, error) {
return NewGrafana(opts.URL, opts.ProxyURL, opts.Token, opts.TLSConfig, opts.Username, opts.Password)
}
func pagerDutyNotifierFunc(opts notifierOptions) (Interface, error) {
return NewPagerDuty(opts.URL, opts.ProxyURL, opts.TLSConfig, opts.Channel)
}
func dataDogNotifierFunc(opts notifierOptions) (Interface, error) {
return NewDataDog(opts.URL, opts.ProxyURL, opts.TLSConfig, opts.Token)
}
func natsNotifierFunc(opts notifierOptions) (Interface, error) {
return NewNATS(opts.URL, opts.Channel, opts.Username, opts.Password)
}
func gitHubNotifierFunc(opts notifierOptions) (Interface, error) {
if opts.Token == "" && opts.Password != "" {
opts.Token = opts.Password
}
return NewGitHub(opts.CommitStatus, opts.URL, opts.Token, opts.TLSConfig, opts.ProxyURL, opts.ProviderName, opts.ProviderNamespace, opts.SecretData, opts.TokenCache)
}
func gitHubDispatchNotifierFunc(opts notifierOptions) (Interface, error) {
if opts.Token == "" && opts.Password != "" {
opts.Token = opts.Password
}
return NewGitHubDispatch(opts.URL, opts.Token, opts.TLSConfig, opts.ProxyURL, opts.ProviderName, opts.ProviderNamespace, opts.SecretData, opts.TokenCache)
}
func gitLabNotifierFunc(opts notifierOptions) (Interface, error) {
if opts.Token == "" && opts.Password != "" {
opts.Token = opts.Password
}
return NewGitLab(opts.CommitStatus, opts.URL, opts.Token, opts.TLSConfig)
}
func giteaNotifierFunc(opts notifierOptions) (Interface, error) {
if opts.Token == "" && opts.Password != "" {
opts.Token = opts.Password
}
return NewGitea(opts.CommitStatus, opts.URL, opts.ProxyURL, opts.Token, opts.TLSConfig)
}
func bitbucketServerNotifierFunc(opts notifierOptions) (Interface, error) {
return NewBitbucketServer(opts.CommitStatus, opts.URL, opts.Token, opts.TLSConfig, opts.Username, opts.Password)
}
func bitbucketNotifierFunc(opts notifierOptions) (Interface, error) {
return NewBitbucket(opts.CommitStatus, opts.URL, opts.Token, opts.TLSConfig)
}
func azureDevOpsNotifierFunc(opts notifierOptions) (Interface, error) {
return NewAzureDevOps(opts.Context, opts.CommitStatus, opts.URL, opts.Token,
opts.TLSConfig, opts.ProxyURL, opts.ServiceAccountName, opts.ProviderName,
opts.ProviderNamespace, opts.TokenClient, opts.TokenCache)
}

View File

@ -20,7 +20,7 @@ import (
"context"
"crypto/hmac"
"crypto/sha256"
"crypto/x509"
"crypto/tls"
"encoding/json"
"fmt"
"net/url"
@ -37,14 +37,14 @@ const NotificationHeader = "gotk-component"
// Forwarder is an implementation of the notification Interface that posts the
// body as an HTTP request using an optional proxy.
type Forwarder struct {
URL string
ProxyURL string
Headers map[string]string
CertPool *x509.CertPool
HMACKey []byte
URL string
ProxyURL string
Headers map[string]string
TLSConfig *tls.Config
HMACKey []byte
}
func NewForwarder(hookURL string, proxyURL string, headers map[string]string, certPool *x509.CertPool, hmacKey []byte) (*Forwarder, error) {
func NewForwarder(hookURL string, proxyURL string, headers map[string]string, tlsConfig *tls.Config, hmacKey []byte) (*Forwarder, error) {
if _, err := url.ParseRequestURI(hookURL); err != nil {
return nil, fmt.Errorf("invalid hook URL %s: %w", hookURL, err)
}
@ -54,11 +54,11 @@ func NewForwarder(hookURL string, proxyURL string, headers map[string]string, ce
}
return &Forwarder{
URL: hookURL,
ProxyURL: proxyURL,
Headers: headers,
CertPool: certPool,
HMACKey: hmacKey,
URL: hookURL,
ProxyURL: proxyURL,
Headers: headers,
HMACKey: hmacKey,
TLSConfig: tlsConfig,
}, nil
}
@ -77,18 +77,28 @@ func (f *Forwarder) Post(ctx context.Context, event eventv1.Event) error {
}
sig = fmt.Sprintf("sha256=%s", sign(eventJSON, f.HMACKey))
}
err := postMessage(ctx, f.URL, f.ProxyURL, f.CertPool, event, func(req *retryablehttp.Request) {
req.Header.Set(NotificationHeader, event.ReportingController)
for key, val := range f.Headers {
req.Header.Set(key, val)
}
if sig != "" {
req.Header.Set("X-Signature", sig)
}
})
if err != nil {
opts := []postOption{
withRequestModifier(func(req *retryablehttp.Request) {
req.Header.Set(NotificationHeader, event.ReportingController)
for key, val := range f.Headers {
req.Header.Set(key, val)
}
if sig != "" {
req.Header.Set("X-Signature", sig)
}
}),
}
if f.ProxyURL != "" {
opts = append(opts, withProxy(f.ProxyURL))
}
if f.TLSConfig != nil {
opts = append(opts, withTLSConfig(f.TLSConfig))
}
if err := postMessage(ctx, f.URL, event, opts...); err != nil {
return fmt.Errorf("postMessage failed: %w", err)
}
return nil
}

View File

@ -18,7 +18,7 @@ package notifier
import (
"context"
"crypto/x509"
"crypto/tls"
"fmt"
"io"
"net/http"
@ -41,13 +41,13 @@ func Fuzz_Forwarder(f *testing.F) {
}))
defer ts.Close()
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
var tlsConfig tls.Config
_ = fuzz.NewConsumer(seed).GenerateStruct(&tlsConfig)
header := make(map[string]string)
_ = fuzz.NewConsumer(seed).FuzzMap(&header)
forwarder, err := NewForwarder(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", header, &cert, hmacKey)
forwarder, err := NewForwarder(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", header, &tlsConfig, hmacKey)
if err != nil {
return
}

View File

@ -19,7 +19,6 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"net/http"
@ -34,22 +33,27 @@ import (
)
type Gitea struct {
BaseURL string
Token string
Owner string
Repo string
ProviderUID string
Client *gitea.Client
Debug bool
BaseURL string
Token string
Owner string
Repo string
CommitStatus string
Client *gitea.Client
Debug bool
}
var _ Interface = &Gitea{}
func NewGitea(providerUID string, addr string, token string, certPool *x509.CertPool) (*Gitea, error) {
func NewGitea(commitStatus string, addr string, proxyURL string, token string, tlsConfig *tls.Config) (*Gitea, error) {
if len(token) == 0 {
return nil, errors.New("gitea token cannot be empty")
}
// this should never happen
if commitStatus == "" {
return nil, errors.New("commit status cannot be empty")
}
host, id, err := parseGitAddress(addr)
if err != nil {
return nil, fmt.Errorf("failed parsing Git URL: %w", err)
@ -64,33 +68,37 @@ func NewGitea(providerUID string, addr string, token string, certPool *x509.Cert
return nil, fmt.Errorf("invalid repository id %q", id)
}
client, err := gitea.NewClient(host, gitea.SetToken(token))
tr := &http.Transport{}
if tlsConfig != nil {
tr.TLSClientConfig = tlsConfig
}
if proxyURL != "" {
parsedProxyURL, err := url.Parse(proxyURL)
if err != nil {
return nil, errors.New("invalid proxy URL")
}
tr.Proxy = http.ProxyURL(parsedProxyURL)
}
client, err := gitea.NewClient(host, gitea.SetToken(token), gitea.SetHTTPClient(&http.Client{Transport: tr}))
if err != nil {
return nil, fmt.Errorf("failed creating Gitea client: %w", err)
}
if certPool != nil {
tr := &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
},
}
client.SetHTTPClient(&http.Client{Transport: tr})
}
return &Gitea{
BaseURL: host,
Token: token,
Owner: idComponents[0],
Repo: idComponents[1],
ProviderUID: providerUID,
Client: client,
Debug: os.Getenv("NOTIFIER_GITEA_DEBUG") == "true",
BaseURL: host,
Token: token,
Owner: idComponents[0],
Repo: idComponents[1],
CommitStatus: commitStatus,
Client: client,
Debug: os.Getenv("NOTIFIER_GITEA_DEBUG") == "true",
}, nil
}
func (g *Gitea) Post(ctx context.Context, event eventv1.Event) error {
revString, ok := event.Metadata[eventv1.MetaRevisionKey]
revString, ok := event.GetRevision()
if !ok {
return errors.New("missing revision metadata")
}
@ -104,7 +112,7 @@ func (g *Gitea) Post(ctx context.Context, event eventv1.Event) error {
}
_, desc := formatNameAndDescription(event)
id := generateCommitStatusID(g.ProviderUID, event)
id := g.CommitStatus
status := gitea.CreateStatusOption{
State: state,

View File

@ -18,7 +18,10 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
testproxy "github.com/fluxcd/notification-controller/tests/proxy"
"net/http"
"net/http/httptest"
"testing"
@ -31,10 +34,20 @@ import (
"github.com/stretchr/testify/assert"
)
// newTestServer returns an HTTP server mimicking parts of Gitea's API so that tests don't
// newTestHTTPServer returns an HTTP server mimicking parts of Gitea's API so that tests don't
// need to rely on 3rd-party components to be available (like the try.gitea.io server).
func newTestServer(t *testing.T) *httptest.Server {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
func newTestHTTPServer(t *testing.T) *httptest.Server {
return httptest.NewServer(newGiteaStubHandler(t))
}
// newTestHTTPSServer returns an HTTPS server mimicking parts of Gitea's API so that tests don't
// need to rely on 3rd-party components to be available (like the try.gitea.io server).
func newTestHTTPSServer(t *testing.T) *httptest.Server {
return httptest.NewTLSServer(newGiteaStubHandler(t))
}
func newGiteaStubHandler(t *testing.T) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/v1/version":
fmt.Fprintf(w, `{"version":"1.18.3"}`)
@ -42,18 +55,79 @@ func newTestServer(t *testing.T) *httptest.Server {
fmt.Fprintf(w, "[]")
case "/api/v1/repos/foo/bar/statuses/69b59063470310ebbd88a9156325322a124e55a3":
fmt.Fprintf(w, "{}")
case "/api/v1/repos/foo/bar/commits/8a9156325322a124e55a369b59063470310ebbd8/statuses":
fmt.Fprintf(w, "[]")
case "/api/v1/repos/foo/bar/statuses/8a9156325322a124e55a369b59063470310ebbd8":
fmt.Fprintf(w, "{}")
default:
t.Logf("unknown %s request at %s", r.Method, r.URL.Path)
}
}))
return srv
})
}
func TestNewGiteaBasic(t *testing.T) {
srv := newTestServer(t)
srv := newTestHTTPServer(t)
defer srv.Close()
g, err := NewGitea("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", srv.URL+"/foo/bar", "foobar", nil)
g, err := NewGitea("kustomization/gitops-system/0c9c2e41", srv.URL+"/foo/bar", "", "foobar", nil)
assert.NoError(t, err)
assert.Equal(t, g.Owner, "foo")
assert.Equal(t, g.Repo, "bar")
assert.Equal(t, g.BaseURL, srv.URL)
}
func TestNewGiteaWithCertPool(t *testing.T) {
srv := newTestHTTPSServer(t)
defer srv.Close()
certPool := x509.NewCertPool()
certPool.AddCert(srv.Certificate())
tlsConfig := &tls.Config{RootCAs: certPool}
g, err := NewGitea("kustomization/gitops-system/0c9c2e41", srv.URL+"/foo/bar", "", "foobar", tlsConfig)
assert.NoError(t, err)
assert.Equal(t, g.Owner, "foo")
assert.Equal(t, g.Repo, "bar")
assert.Equal(t, g.BaseURL, srv.URL)
}
func TestNewGiteaNoCertificate(t *testing.T) {
srv := newTestHTTPSServer(t)
defer srv.Close()
certPool := x509.NewCertPool()
tlsConfig := &tls.Config{RootCAs: certPool}
_, err := NewGitea("kustomization/gitops-system/0c9c2e41", srv.URL+"/foo/bar", "", "foobar", tlsConfig)
assert.Error(t, err)
assert.ErrorContains(t, err, "tls: failed to verify certificate: x509: certificate signed by unknown authority")
}
func TestNewGiteaWithProxyURL(t *testing.T) {
srv := newTestHTTPServer(t)
defer srv.Close()
proxyAddr, _ := testproxy.New(t)
proxyURL := fmt.Sprintf("http://%s", proxyAddr)
g, err := NewGitea("kustomization/gitops-system/0c9c2e41", srv.URL+"/foo/bar", proxyURL, "foobar", nil)
assert.NoError(t, err)
assert.Equal(t, g.Owner, "foo")
assert.Equal(t, g.Repo, "bar")
assert.Equal(t, g.BaseURL, srv.URL)
}
func TestNewGiteaWithProxyURLAndCertPool(t *testing.T) {
srv := newTestHTTPSServer(t)
defer srv.Close()
certPool := x509.NewCertPool()
certPool.AddCert(srv.Certificate())
tlsConfig := &tls.Config{RootCAs: certPool}
proxyAddr, _ := testproxy.New(t)
proxyURL := fmt.Sprintf("http://%s", proxyAddr)
g, err := NewGitea("kustomization/gitops-system/0c9c2e41", srv.URL+"/foo/bar", proxyURL, "foobar", tlsConfig)
assert.NoError(t, err)
assert.Equal(t, g.Owner, "foo")
assert.Equal(t, g.Repo, "bar")
@ -61,44 +135,88 @@ func TestNewGiteaBasic(t *testing.T) {
}
func TestNewGiteaInvalidUrl(t *testing.T) {
srv := newTestServer(t)
srv := newTestHTTPServer(t)
defer srv.Close()
_, err := NewGitea("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", srv.URL+"/foo/bar/baz", "foobar", nil)
_, err := NewGitea("kustomization/gitops-system/0c9c2e41", srv.URL+"/foo/bar/baz", "", "foobar", nil)
assert.ErrorContains(t, err, "invalid repository id")
}
func TestNewGiteaInvalidProxyUrl(t *testing.T) {
_, err := NewGitea("kustomization/gitops-system/0c9c2e41", "/foo/bar", "wrong\nURL", "foobar", nil)
assert.ErrorContains(t, err, "invalid proxy URL")
}
func TestNewGiteaEmptyToken(t *testing.T) {
srv := newTestServer(t)
srv := newTestHTTPServer(t)
defer srv.Close()
_, err := NewGitea("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", srv.URL+"/foo/bar", "", nil)
_, err := NewGitea("kustomization/gitops-system/0c9c2e41", srv.URL+"/foo/bar", "", "", nil)
assert.ErrorContains(t, err, "gitea token cannot be empty")
}
func TestGitea_Post(t *testing.T) {
srv := newTestServer(t)
func TestNewGiteaEmptyCommitStatus(t *testing.T) {
srv := newTestHTTPServer(t)
defer srv.Close()
g, err := NewGitea("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", srv.URL+"/foo/bar", "foobar", nil)
_, err := NewGitea("", srv.URL+"/foo/bar", "", "foobar", nil)
assert.ErrorContains(t, err, "commit status cannot be empty")
}
func TestGitea_Post(t *testing.T) {
srv := newTestHTTPServer(t)
defer srv.Close()
g, err := NewGitea("kustomization/gitops-system/0c9c2e41", srv.URL+"/foo/bar", "", "foobar", nil)
assert.Nil(t, err)
event := eventv1.Event{
InvolvedObject: corev1.ObjectReference{
Kind: "Kustomization",
Namespace: "flux-system",
Name: "podinfo-repo",
for _, tt := range []struct {
name string
event eventv1.Event
}{
{
name: "revision key",
event: eventv1.Event{
InvolvedObject: corev1.ObjectReference{
Kind: "Kustomization",
Namespace: "flux-system",
Name: "podinfo-repo",
},
Severity: "info",
Timestamp: metav1.Time{
Time: time.Now(),
},
Metadata: map[string]string{
eventv1.MetaRevisionKey: "main@sha1:69b59063470310ebbd88a9156325322a124e55a3",
},
Message: "Service/podinfo/podinfo configured",
Reason: "",
},
},
Severity: "info",
Timestamp: metav1.Time{
Time: time.Now(),
{
name: "origin revision key",
event: eventv1.Event{
InvolvedObject: corev1.ObjectReference{
Kind: "Kustomization",
Namespace: "flux-system",
Name: "podinfo-repo",
},
Severity: "info",
Timestamp: metav1.Time{
Time: time.Now(),
},
Metadata: map[string]string{
eventv1.MetaRevisionKey: "main@sha1:69b59063470310ebbd88a9156325322a124e55a3",
eventv1.MetaOriginRevisionKey: "main@sha1:8a9156325322a124e55a369b59063470310ebbd8",
},
Message: "Service/podinfo/podinfo configured",
Reason: "",
},
},
Metadata: map[string]string{
eventv1.MetaRevisionKey: "main@sha1:69b59063470310ebbd88a9156325322a124e55a3",
},
Message: "Service/podinfo/podinfo configured",
Reason: "",
} {
t.Run(tt.name, func(t *testing.T) {
err := g.Post(context.Background(), tt.event)
assert.NoError(t, err)
})
}
err = g.Post(context.Background(), event)
assert.NoError(t, err)
}

View File

@ -19,73 +19,43 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"net/http"
"net/url"
"strings"
"github.com/google/go-github/v53/github"
"golang.org/x/oauth2"
"github.com/google/go-github/v64/github"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/cache"
)
type GitHub struct {
Owner string
Repo string
ProviderUID string
Client *github.Client
Owner string
Repo string
CommitStatus string
Client *github.Client
}
func NewGitHub(providerUID string, addr string, token string, certPool *x509.CertPool) (*GitHub, error) {
if len(token) == 0 {
return nil, errors.New("github token cannot be empty")
func NewGitHub(commitStatus string, addr string, token string, tlsConfig *tls.Config,
proxyURL string, providerName string, providerNamespace string, secretData map[string][]byte,
tokenCache *cache.TokenCache) (*GitHub, error) {
// this should never happen
if commitStatus == "" {
return nil, errors.New("commit status cannot be empty")
}
host, id, err := parseGitAddress(addr)
repoInfo, err := getRepoInfoAndGithubClient(addr, token, tlsConfig,
proxyURL, providerName, providerNamespace, secretData, tokenCache)
if err != nil {
return nil, err
}
baseUrl, err := url.Parse(host)
if err != nil {
return nil, err
}
comp := strings.Split(id, "/")
if len(comp) != 2 {
return nil, fmt.Errorf("invalid repository id %q", id)
}
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})
tc := oauth2.NewClient(context.Background(), ts)
client := github.NewClient(tc)
if baseUrl.Host != "github.com" {
if certPool != nil {
tr := &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
},
}
hc := &http.Client{Transport: tr}
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, hc)
tc = oauth2.NewClient(ctx, ts)
}
client, err = github.NewEnterpriseClient(host, host, tc)
if err != nil {
return nil, fmt.Errorf("could not create enterprise GitHub client: %v", err)
}
}
return &GitHub{
Owner: comp[0],
Repo: comp[1],
ProviderUID: providerUID,
Client: client,
Owner: repoInfo.owner,
Repo: repoInfo.repo,
CommitStatus: commitStatus,
Client: repoInfo.client,
}, nil
}
@ -96,7 +66,7 @@ func (g *GitHub) Post(ctx context.Context, event eventv1.Event) error {
return nil
}
revString, ok := event.Metadata[eventv1.MetaRevisionKey]
revString, ok := event.GetRevision()
if !ok {
return errors.New("missing revision metadata")
}
@ -110,7 +80,7 @@ func (g *GitHub) Post(ctx context.Context, event eventv1.Event) error {
}
_, desc := formatNameAndDescription(event)
id := generateCommitStatusID(g.ProviderUID, event)
id := g.CommitStatus
status := &github.RepoStatus{
State: &state,
Context: &id,

View File

@ -19,18 +19,13 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"strings"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/cache"
"github.com/google/go-github/v53/github"
"golang.org/x/oauth2"
"github.com/google/go-github/v64/github"
)
type GitHubDispatch struct {
@ -39,51 +34,20 @@ type GitHubDispatch struct {
Client *github.Client
}
func NewGitHubDispatch(addr string, token string, certPool *x509.CertPool) (*GitHubDispatch, error) {
if len(token) == 0 {
return nil, errors.New("github token cannot be empty")
}
func NewGitHubDispatch(addr string, token string, tlsConfig *tls.Config, proxyURL string,
providerName string, providerNamespace string, secretData map[string][]byte,
tokenCache *cache.TokenCache) (*GitHubDispatch, error) {
host, id, err := parseGitAddress(addr)
repoInfo, err := getRepoInfoAndGithubClient(addr, token, tlsConfig,
proxyURL, providerName, providerNamespace, secretData, tokenCache)
if err != nil {
return nil, err
}
baseUrl, err := url.Parse(host)
if err != nil {
return nil, err
}
comp := strings.Split(id, "/")
if len(comp) != 2 {
return nil, fmt.Errorf("invalid repository id %q", id)
}
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})
tc := oauth2.NewClient(context.Background(), ts)
client := github.NewClient(tc)
if baseUrl.Host != "github.com" {
if certPool != nil {
tr := &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
},
}
hc := &http.Client{Transport: tr}
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, hc)
tc = oauth2.NewClient(ctx, ts)
}
client, err = github.NewEnterpriseClient(host, host, tc)
if err != nil {
return nil, fmt.Errorf("could not create enterprise GitHub client: %v", err)
}
}
return &GitHubDispatch{
Owner: comp[0],
Repo: comp[1],
Client: client,
Owner: repoInfo.owner,
Repo: repoInfo.repo,
Client: repoInfo.client,
}, nil
}

View File

@ -18,6 +18,7 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
@ -46,7 +47,8 @@ func Fuzz_GitHub_Dispatch(f *testing.F) {
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
dispatch, err := NewGitHubDispatch(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert)
tlsConfig := &tls.Config{RootCAs: &cert}
dispatch, err := NewGitHubDispatch(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, tlsConfig, "", "", "", nil, nil)
if err != nil {
return
}

View File

@ -18,16 +18,23 @@ package notifier
import (
"context"
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
authgithub "github.com/fluxcd/pkg/git/github"
"github.com/fluxcd/pkg/ssh"
)
func TestNewGitHubDispatchBasic(t *testing.T) {
g, err := NewGitHubDispatch("https://github.com/foo/bar", "foobar", nil)
g, err := NewGitHubDispatch("https://github.com/foo/bar", "foobar", nil, "", "", "", nil, nil)
assert.Nil(t, err)
assert.Equal(t, g.Owner, "foo")
assert.Equal(t, g.Repo, "bar")
@ -35,7 +42,7 @@ func TestNewGitHubDispatchBasic(t *testing.T) {
}
func TestNewEnterpriseGitHubDispatchBasic(t *testing.T) {
g, err := NewGitHubDispatch("https://foobar.com/foo/bar", "foobar", nil)
g, err := NewGitHubDispatch("https://foobar.com/foo/bar", "foobar", nil, "", "", "", nil, nil)
assert.Nil(t, err)
assert.Equal(t, g.Owner, "foo")
assert.Equal(t, g.Repo, "bar")
@ -43,17 +50,98 @@ func TestNewEnterpriseGitHubDispatchBasic(t *testing.T) {
}
func TestNewGitHubDispatchInvalidUrl(t *testing.T) {
_, err := NewGitHubDispatch("https://github.com/foo/bar/baz", "foobar", nil)
_, err := NewGitHubDispatch("https://github.com/foo/bar/baz", "foobar", nil, "", "", "", nil, nil)
assert.NotNil(t, err)
}
func TestNewGitHubDispatchEmptyToken(t *testing.T) {
_, err := NewGitHubDispatch("https://github.com/foo/bar", "", nil)
_, err := NewGitHubDispatch("https://github.com/foo/bar", "", nil, "", "", "", nil, nil)
assert.NotNil(t, err)
}
func TestNewGithubDispatchProvider(t *testing.T) {
appID := "123"
installationID := "456"
kp, _ := ssh.GenerateKeyPair(ssh.RSA_4096)
expiresAt := time.Now().UTC().Add(time.Hour)
for _, tt := range []struct {
name string
secretData map[string][]byte
wantErr error
}{
{
name: "nil provider, no token",
wantErr: errors.New("github token or github app details must be specified"),
},
{
name: "provider with no github options",
secretData: map[string][]byte{},
wantErr: errors.New("github token or github app details must be specified"),
},
{
name: "provider with missing app ID in options ",
secretData: map[string][]byte{
"githubAppInstallationID": []byte(installationID),
"githubAppPrivateKey": kp.PrivateKey,
},
wantErr: errors.New("github token or github app details must be specified"),
},
{
name: "provider with missing app installation ID in options ",
secretData: map[string][]byte{
"githubAppID": []byte(appID),
"githubAppPrivateKey": kp.PrivateKey,
},
wantErr: errors.New("app installation ID must be provided to use github app authentication"),
},
{
name: "provider with missing app private key in options ",
secretData: map[string][]byte{
"githubAppID": []byte(appID),
"githubAppInstallationID": []byte(installationID),
},
wantErr: errors.New("private key must be provided to use github app authentication"),
},
{
name: "provider with complete app authentication information",
secretData: map[string][]byte{
"githubAppID": []byte(appID),
"githubAppInstallationID": []byte(installationID),
"githubAppPrivateKey": kp.PrivateKey,
},
},
} {
t.Run(tt.name, func(t *testing.T) {
handler := func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
var response []byte
var err error
response, err = json.Marshal(&authgithub.AppToken{Token: "access-token", ExpiresAt: expiresAt})
assert.Nil(t, err)
w.Write(response)
}
srv := httptest.NewServer(http.HandlerFunc(handler))
t.Cleanup(func() {
srv.Close()
})
if len(tt.secretData) > 0 {
tt.secretData["githubAppBaseURL"] = []byte(srv.URL)
}
_, err := NewGitHubDispatch("https://github.com/foo/bar", "", nil, "", "foo", "bar", tt.secretData, nil)
if tt.wantErr != nil {
assert.NotNil(t, err)
assert.Equal(t, tt.wantErr, err)
} else {
assert.Nil(t, err)
}
})
}
}
func TestGitHubDispatch_PostUpdate(t *testing.T) {
githubDispatch, err := NewGitHubDispatch("https://github.com/foo/bar", "foobar", nil)
githubDispatch, err := NewGitHubDispatch("https://github.com/foo/bar", "foobar", nil, "", "", "", nil, nil)
require.NoError(t, err)
event := testEvent()

View File

@ -18,6 +18,7 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
@ -30,14 +31,14 @@ import (
)
func Fuzz_GitHub(f *testing.F) {
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "token", "org/repo", "revision/abce1", "error", "", []byte{}, []byte(`[{"context":"/","state":"failure","description":""}]`))
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{"context":"/","state":"success","description":""}]`))
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{"context":"/","state":"failure","description":""}]`))
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{"context":"/"}]`))
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{}]`))
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "token", "org/repo", "revision/abce1", "info", "Progressing", []byte{}, []byte{})
f.Add("kustomization/gitops-system/0c9c2e41", "token", "org/repo", "revision/abce1", "error", "", []byte{}, []byte(`[{"context":"/","state":"failure","description":""}]`))
f.Add("kustomization/gitops-system/0c9c2e41", "token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{"context":"/","state":"success","description":""}]`))
f.Add("kustomization/gitops-system/0c9c2e41", "token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{"context":"/","state":"failure","description":""}]`))
f.Add("kustomization/gitops-system/0c9c2e41", "token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{"context":"/"}]`))
f.Add("kustomization/gitops-system/0c9c2e41", "token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{}]`))
f.Add("kustomization/gitops-system/0c9c2e41", "token", "org/repo", "revision/abce1", "info", "Progressing", []byte{}, []byte{})
f.Fuzz(func(t *testing.T, uuid, token, urlSuffix, revision, severity, reason string, seed, response []byte) {
f.Fuzz(func(t *testing.T, commitStatus, token, urlSuffix, revision, severity, reason string, seed, response []byte) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write(response)
io.Copy(io.Discard, r.Body)
@ -48,7 +49,8 @@ func Fuzz_GitHub(f *testing.F) {
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
github, err := NewGitHub(uuid, fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert)
tlsConfig := &tls.Config{RootCAs: &cert}
github, err := NewGitHub(commitStatus, fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, tlsConfig, "", "foo", "bar", nil, nil)
if err != nil {
return
}

View File

@ -0,0 +1,134 @@
/*
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 notifier
import (
"context"
"crypto/tls"
"errors"
"fmt"
"net/http"
"net/url"
"strings"
gogithub "github.com/google/go-github/v64/github"
"golang.org/x/oauth2"
"github.com/fluxcd/pkg/cache"
"github.com/fluxcd/pkg/git/github"
"github.com/fluxcd/notification-controller/api/v1beta3"
)
// repoInfo is an internal type encapsulating owner, repo and client
type repoInfo struct {
owner string
repo string
client *gogithub.Client
}
// getGitHubAppOptions constructs the github app authentication options.
func getGitHubAppOptions(providerName, providerNamespace, proxy string,
secretData map[string][]byte, tokenCache *cache.TokenCache) ([]github.OptFunc, error) {
githubOpts := []github.OptFunc{
github.WithAppData(secretData),
}
if len(githubOpts) > 0 && proxy != "" {
proxyURL, err := url.Parse(proxy)
if err != nil {
return nil, fmt.Errorf("error parsing proxy URL '%s': %w", proxy, err)
}
githubOpts = append(githubOpts, github.WithProxyURL(proxyURL))
}
if len(githubOpts) > 0 && tokenCache != nil {
githubOpts = append(githubOpts, github.WithCache(tokenCache,
v1beta3.ProviderKind, providerName, providerNamespace, OperationPost))
}
return githubOpts, nil
}
// getRepoInfoAndGithubClient gets the github client and repository info used by Github and GithubDispatch providers
func getRepoInfoAndGithubClient(addr string, token string, tlsConfig *tls.Config,
proxyURL string, providerName string, providerNamespace string,
secretData map[string][]byte, tokenCache *cache.TokenCache) (*repoInfo, error) {
if len(token) == 0 {
if _, ok := secretData[github.KeyAppID]; !ok {
return nil, errors.New("github token or github app details must be specified")
}
githubOpts, err := getGitHubAppOptions(providerName, providerNamespace, proxyURL, secretData, tokenCache)
if err != nil {
return nil, err
}
if tlsConfig != nil {
// add TLS config to get installation token
githubOpts = append(githubOpts, github.WithTLSConfig(tlsConfig))
}
client, err := github.New(githubOpts...)
if err != nil {
return nil, err
}
appToken, err := client.GetToken(context.Background())
if err != nil {
return nil, err
}
token = appToken.Token
}
host, id, err := parseGitAddress(addr)
if err != nil {
return nil, err
}
comp := strings.Split(id, "/")
if len(comp) != 2 {
return nil, fmt.Errorf("invalid repository id %q", id)
}
baseUrl, err := url.Parse(host)
if err != nil {
return nil, err
}
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})
tc := oauth2.NewClient(context.Background(), ts)
client := gogithub.NewClient(tc)
if baseUrl.Host != "github.com" {
if tlsConfig != nil {
tr := &http.Transport{
TLSClientConfig: tlsConfig,
}
hc := &http.Client{Transport: tr}
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, hc)
tc = oauth2.NewClient(ctx, ts)
}
client, err = gogithub.NewClient(tc).WithEnterpriseURLs(host, host)
if err != nil {
return nil, fmt.Errorf("could not create enterprise GitHub client: %v", err)
}
}
return &repoInfo{comp[0], comp[1], client}, nil
}

View File

@ -17,38 +17,134 @@ limitations under the License.
package notifier
import (
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/google/go-github/v53/github"
authgithub "github.com/fluxcd/pkg/git/github"
"github.com/fluxcd/pkg/ssh"
"github.com/google/go-github/v64/github"
"github.com/stretchr/testify/assert"
)
func TestNewGitHubBasic(t *testing.T) {
g, err := NewGitHub("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://github.com/foo/bar", "foobar", nil)
g, err := NewGitHub("kustomization/gitops-system/0c9c2e41", "https://github.com/foo/bar", "foobar", nil, "", "", "", nil, nil)
assert.Nil(t, err)
assert.Equal(t, g.Owner, "foo")
assert.Equal(t, g.Repo, "bar")
assert.Equal(t, g.Client.BaseURL.Host, "api.github.com")
assert.Equal(t, g.CommitStatus, "kustomization/gitops-system/0c9c2e41")
}
func TestNewEmterpriseGitHubBasic(t *testing.T) {
g, err := NewGitHub("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://foobar.com/foo/bar", "foobar", nil)
g, err := NewGitHub("kustomization/gitops-system/0c9c2e41", "https://foobar.com/foo/bar", "foobar", nil, "", "", "", nil, nil)
assert.Nil(t, err)
assert.Equal(t, g.Owner, "foo")
assert.Equal(t, g.Repo, "bar")
assert.Equal(t, g.Client.BaseURL.Host, "foobar.com")
assert.Equal(t, g.CommitStatus, "kustomization/gitops-system/0c9c2e41")
}
func TestNewGitHubInvalidUrl(t *testing.T) {
_, err := NewGitHub("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://github.com/foo/bar/baz", "foobar", nil)
_, err := NewGitHub("kustomization/gitops-system/0c9c2e41", "https://github.com/foo/bar/baz", "foobar", nil, "", "", "", nil, nil)
assert.NotNil(t, err)
}
func TestNewGitHubEmptyToken(t *testing.T) {
_, err := NewGitHub("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://github.com/foo/bar", "", nil)
_, err := NewGitHub("kustomization/gitops-system/0c9c2e41", "https://github.com/foo/bar", "", nil, "", "", "", nil, nil)
assert.NotNil(t, err)
}
func TestNewGitHubEmptyCommitStatus(t *testing.T) {
_, err := NewGitHub("", "https://github.com/foo/bar", "foobar", nil, "", "", "", nil, nil)
assert.NotNil(t, err)
}
func TestNewGithubProvider(t *testing.T) {
appID := "123"
installationID := "456"
kp, _ := ssh.GenerateKeyPair(ssh.RSA_4096)
expiresAt := time.Now().UTC().Add(time.Hour)
for _, tt := range []struct {
name string
secretData map[string][]byte
wantErr error
}{
{
name: "nil provider, no token",
wantErr: errors.New("github token or github app details must be specified"),
},
{
name: "provider with no github options",
secretData: map[string][]byte{},
wantErr: errors.New("github token or github app details must be specified"),
},
{
name: "provider with missing app ID in options ",
secretData: map[string][]byte{
"githubAppInstallationID": []byte(installationID),
"githubAppPrivateKey": kp.PrivateKey,
},
wantErr: errors.New("github token or github app details must be specified"),
},
{
name: "provider with missing app installation ID in options ",
secretData: map[string][]byte{
"githubAppID": []byte(appID),
"githubAppPrivateKey": kp.PrivateKey,
},
wantErr: errors.New("app installation ID must be provided to use github app authentication"),
},
{
name: "provider with missing app private key in options ",
secretData: map[string][]byte{
"githubAppID": []byte(appID),
"githubAppInstallationID": []byte(installationID),
},
wantErr: errors.New("private key must be provided to use github app authentication"),
},
{
name: "provider with complete app authentication information",
secretData: map[string][]byte{
"githubAppID": []byte(appID),
"githubAppInstallationID": []byte(installationID),
"githubAppPrivateKey": kp.PrivateKey,
},
},
} {
t.Run(tt.name, func(t *testing.T) {
handler := func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
var response []byte
var err error
response, err = json.Marshal(&authgithub.AppToken{Token: "access-token", ExpiresAt: expiresAt})
assert.Nil(t, err)
w.Write(response)
}
srv := httptest.NewServer(http.HandlerFunc(handler))
t.Cleanup(func() {
srv.Close()
})
if len(tt.secretData) > 0 {
tt.secretData["githubAppBaseURL"] = []byte(srv.URL)
}
_, err := NewGitHub("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://github.com/foo/bar", "", nil, "", "foo", "bar", tt.secretData, nil)
if tt.wantErr != nil {
assert.NotNil(t, err)
assert.Equal(t, tt.wantErr, err)
} else {
assert.Nil(t, err)
}
})
}
}
func TestDuplicateGithubStatus(t *testing.T) {
assert := assert.New(t)

View File

@ -19,24 +19,23 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"net/http"
"github.com/xanzy/go-gitlab"
gitlab "gitlab.com/gitlab-org/api/client-go"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/apis/meta"
)
type GitLab struct {
Id string
ProviderUID string
Client *gitlab.Client
Id string
CommitStatus string
Client *gitlab.Client
}
func NewGitLab(providerUID string, addr string, token string, certPool *x509.CertPool) (*GitLab, error) {
func NewGitLab(commitStatus string, addr string, token string, tlsConfig *tls.Config) (*GitLab, error) {
if len(token) == 0 {
return nil, errors.New("gitlab token cannot be empty")
}
@ -46,12 +45,15 @@ func NewGitLab(providerUID string, addr string, token string, certPool *x509.Cer
return nil, err
}
// this should never happen
if commitStatus == "" {
return nil, errors.New("commit status cannot be empty")
}
opts := []gitlab.ClientOptionFunc{gitlab.WithBaseURL(host)}
if certPool != nil {
if tlsConfig != nil {
tr := &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
},
TLSClientConfig: tlsConfig,
}
hc := &http.Client{Transport: tr}
opts = append(opts, gitlab.WithHTTPClient(hc))
@ -62,9 +64,9 @@ func NewGitLab(providerUID string, addr string, token string, certPool *x509.Cer
}
gitlab := &GitLab{
Id: id,
ProviderUID: providerUID,
Client: client,
Id: id,
CommitStatus: commitStatus,
Client: client,
}
return gitlab, nil
@ -77,7 +79,7 @@ func (g *GitLab) Post(ctx context.Context, event eventv1.Event) error {
return nil
}
revString, ok := event.Metadata[eventv1.MetaRevisionKey]
revString, ok := event.GetRevision()
if !ok {
return errors.New("missing revision metadata")
}
@ -91,7 +93,7 @@ func (g *GitLab) Post(ctx context.Context, event eventv1.Event) error {
}
_, desc := formatNameAndDescription(event)
id := generateCommitStatusID(g.ProviderUID, event)
id := g.CommitStatus
status := &gitlab.CommitStatus{
Name: id,
SHA: rev,
@ -99,7 +101,9 @@ func (g *GitLab) Post(ctx context.Context, event eventv1.Event) error {
Description: desc,
}
getOpt := &gitlab.GetCommitStatusesOptions{}
getOpt := &gitlab.GetCommitStatusesOptions{
Name: &status.Name,
}
statuses, _, err := g.Client.Commits.GetCommitStatuses(g.Id, rev, getOpt, gitlab.WithContext(ctx))
if err != nil {
return fmt.Errorf("unable to list commit status: %s", err)

View File

@ -18,6 +18,7 @@ package notifier
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
@ -30,12 +31,12 @@ import (
)
func Fuzz_GitLab(f *testing.F) {
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "token", "org/repo", "revision/abce1", "error", "", []byte{}, []byte(`[{"sha":"abce1","status":"failed","name":"/","description":""}]`))
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{"sha":"abce1","status":"failed","name":"/","description":""}]`))
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "token", "org/repo", "revision/abce1", "info", "Progressing", []byte{}, []byte{})
f.Add("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[]`))
f.Add("kustomization/gitops-system/0c9c2e41", "token", "org/repo", "revision/abce1", "error", "", []byte{}, []byte(`[{"sha":"abce1","status":"failed","name":"/","description":""}]`))
f.Add("kustomization/gitops-system/0c9c2e41", "token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[{"sha":"abce1","status":"failed","name":"/","description":""}]`))
f.Add("kustomization/gitops-system/0c9c2e41", "token", "org/repo", "revision/abce1", "info", "Progressing", []byte{}, []byte{})
f.Add("kustomization/gitops-system/0c9c2e41", "token", "org/repo", "revision/abce1", "info", "", []byte{}, []byte(`[]`))
f.Fuzz(func(t *testing.T, uuid, token, urlSuffix, revision, severity, reason string, seed, response []byte) {
f.Fuzz(func(t *testing.T, commitStatus, token, urlSuffix, revision, severity, reason string, seed, response []byte) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write(response)
io.Copy(io.Discard, r.Body)
@ -46,7 +47,8 @@ func Fuzz_GitLab(f *testing.F) {
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
gitLab, err := NewGitLab(uuid, fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert)
tlsConfig := &tls.Config{RootCAs: &cert}
gitLab, err := NewGitLab(commitStatus, fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, tlsConfig)
if err != nil {
return
}

View File

@ -23,25 +23,31 @@ import (
)
func TestNewGitLabBasic(t *testing.T) {
g, err := NewGitLab("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://gitlab.com/foo/bar", "foobar", nil)
g, err := NewGitLab("kustomization/gitops-system/0c9c2e41", "https://gitlab.com/foo/bar", "foobar", nil)
assert.Nil(t, err)
assert.Equal(t, g.Id, "foo/bar")
assert.Equal(t, g.CommitStatus, "kustomization/gitops-system/0c9c2e41")
}
func TestNewGitLabSubgroups(t *testing.T) {
g, err := NewGitLab("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://gitlab.com/foo/bar/baz", "foobar", nil)
g, err := NewGitLab("kustomization/gitops-system/0c9c2e41", "https://gitlab.com/foo/bar/baz", "foobar", nil)
assert.Nil(t, err)
assert.Equal(t, g.Id, "foo/bar/baz")
}
func TestNewGitLabSelfHosted(t *testing.T) {
g, err := NewGitLab("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://example.com/foo/bar", "foo:bar", nil)
g, err := NewGitLab("kustomization/gitops-system/0c9c2e41", "https://example.com/foo/bar", "foo:bar", nil)
assert.Nil(t, err)
assert.Equal(t, g.Id, "foo/bar")
assert.Equal(t, g.Client.BaseURL().Host, "example.com")
}
func TestNewGitLabEmptyToken(t *testing.T) {
_, err := NewGitLab("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", "https://gitlab.com/foo/bar", "", nil)
_, err := NewGitLab("kustomization/gitops-system/0c9c2e41", "https://gitlab.com/foo/bar", "", nil)
assert.NotNil(t, err)
}
func TestNewGitLabEmptyCommitStatus(t *testing.T) {
_, err := NewGitLab("", "https://gitlab.com/foo/bar", "foobar", nil)
assert.NotNil(t, err)
}

View File

@ -142,8 +142,12 @@ func (s *GoogleChat) Post(ctx context.Context, event eventv1.Event) error {
Cards: []GoogleChatCard{card},
}
err := postMessage(ctx, s.URL, s.ProxyURL, nil, payload)
if err != nil {
var opts []postOption
if s.ProxyURL != "" {
opts = append(opts, withProxy(s.ProxyURL))
}
if err := postMessage(ctx, s.URL, payload, opts...); err != nil {
return fmt.Errorf("postMessage failed: %w", err)
}

View File

@ -0,0 +1,73 @@
/*
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 notifier
import (
"context"
"fmt"
"net/url"
"google.golang.org/api/option"
"github.com/fluxcd/pkg/auth"
"github.com/fluxcd/pkg/auth/gcp"
"github.com/fluxcd/pkg/cache"
"github.com/fluxcd/notification-controller/api/v1beta3"
)
// buildGCPClientOptions builds client options for GCP services.
// Authentication precedence: JSON credentials take priority over workload identity.
func buildGCPClientOptions(ctx context.Context, opts notifierOptions) ([]option.ClientOption, error) {
var clientOpts []option.ClientOption
if opts.Token != "" {
clientOpts = append(clientOpts, option.WithCredentialsJSON([]byte(opts.Token)))
} else {
authOpts := []auth.Option{
auth.WithClient(opts.TokenClient),
auth.WithServiceAccountNamespace(opts.ProviderNamespace),
}
if opts.TokenCache != nil {
involvedObject := cache.InvolvedObject{
Kind: v1beta3.ProviderKind,
Name: opts.ProviderName,
Namespace: opts.ProviderNamespace,
Operation: OperationPost,
}
authOpts = append(authOpts, auth.WithCache(*opts.TokenCache, involvedObject))
}
if opts.ServiceAccountName != "" {
authOpts = append(authOpts, auth.WithServiceAccountName(opts.ServiceAccountName))
}
if opts.ProxyURL != "" {
proxyURL, err := url.Parse(opts.ProxyURL)
if err != nil {
return nil, fmt.Errorf("error parsing proxy URL: %w", err)
}
authOpts = append(authOpts, auth.WithProxyURL(*proxyURL))
}
tokenSource := gcp.NewTokenSource(ctx, authOpts...)
clientOpts = append(clientOpts, option.WithTokenSource(tokenSource))
}
return clientOpts, nil
}

View File

@ -23,7 +23,6 @@ import (
"fmt"
"cloud.google.com/go/pubsub"
"google.golang.org/api/option"
kerrors "k8s.io/apimachinery/pkg/util/errors"
"sigs.k8s.io/controller-runtime/pkg/log"
@ -33,18 +32,13 @@ import (
type (
// GooglePubSub holds a Google Pub/Sub client and target topic.
GooglePubSub struct {
topicID string
attrs map[string]string
topicName string
client interface {
publish(ctx context.Context, topicID string, eventPayload []byte, attrs map[string]string) (serverID string, err error)
publish(ctx context.Context, eventPayload []byte) error
}
}
googlePubSubClient struct {
projectID string
jsonCreds []byte
opts *notifierOptions
}
)
@ -52,33 +46,16 @@ type (
var _ Interface = &GooglePubSub{}
// NewGooglePubSub creates a Google Pub/Sub client tied to a specific
// project and topic.
//
// The jsonCreds parameter is optional, and if len(jsonCreds) == 0 then the
// automatic authentication methods of the Google libraries will take place,
// and therefore methods like Workload Identity will be automatically attempted.
//
// The attrs paramter is optional, and if len(attrs) == 0 then no attributes will
// be added to the Pub/Sub message.
func NewGooglePubSub(projectID, topicID, jsonCreds string, attrs map[string]string) (*GooglePubSub, error) {
if projectID == "" {
// project and topic using the provided client options.
func NewGooglePubSub(opts *notifierOptions) (*GooglePubSub, error) {
if opts.URL == "" {
return nil, errors.New("GCP project ID cannot be empty")
}
if topicID == "" {
if opts.Channel == "" {
return nil, errors.New("GCP Pub/Sub topic ID cannot be empty")
}
if len(attrs) == 0 {
attrs = nil
}
return &GooglePubSub{
topicID: topicID,
attrs: attrs,
topicName: fmt.Sprintf("projects/%s/topics/%s", projectID, topicID),
client: &googlePubSubClient{
projectID: projectID,
jsonCreds: []byte(jsonCreds),
},
}, nil
client := &googlePubSubClient{opts}
return &GooglePubSub{client}, nil
}
// Post posts Flux events to a Google Pub/Sub topic.
@ -93,28 +70,21 @@ func (g *GooglePubSub) Post(ctx context.Context, event eventv1.Event) error {
return fmt.Errorf("error json-marshaling event: %w", err)
}
serverID, err := g.client.publish(ctx, g.topicID, eventPayload, g.attrs)
if err != nil {
return fmt.Errorf("error publishing event to topic %s: %w", g.topicName, err)
}
// debug log
log.FromContext(ctx).V(1).Info("Event published to GCP Pub/Sub topic",
"topic", g.topicName,
"server message id", serverID)
return nil
return g.client.publish(ctx, eventPayload)
}
func (g *googlePubSubClient) publish(ctx context.Context, topicID string, eventPayload []byte, attrs map[string]string) (serverID string, err error) {
var opts []option.ClientOption
if len(g.jsonCreds) > 0 {
opts = append(opts, option.WithCredentialsJSON(g.jsonCreds))
}
var client *pubsub.Client
client, err = pubsub.NewClient(ctx, g.projectID, opts...)
func (g *googlePubSubClient) publish(ctx context.Context, eventPayload []byte) error {
projectID := g.opts.URL
topicID := g.opts.Channel
// Build client.
opts, err := buildGCPClientOptions(ctx, *g.opts)
if err != nil {
return
return err
}
client, err := pubsub.NewClient(ctx, projectID, opts...)
if err != nil {
return err
}
defer func() {
if closeErr := client.Close(); closeErr != nil {
@ -125,12 +95,28 @@ func (g *googlePubSubClient) publish(ctx context.Context, topicID string, eventP
}
}
}()
serverID, err = client.
// Publish the event to the topic.
attrs := g.opts.Headers
if len(attrs) == 0 {
attrs = nil
}
topic := fmt.Sprintf("projects/%s/topics/%s", projectID, topicID)
serverID, err := client.
Topic(topicID).
Publish(ctx, &pubsub.Message{
Data: eventPayload,
Attributes: attrs,
}).
Get(ctx)
return
if err != nil {
return fmt.Errorf("error publishing to GCP Pub/Sub topic %s: %w", topic, err)
}
// Emit debug log.
log.FromContext(ctx).V(1).Info("Event published to GCP Pub/Sub topic",
"topic", topic,
"server message id", serverID)
return nil
}

View File

@ -19,7 +19,6 @@ package notifier
import (
"context"
"errors"
"fmt"
"testing"
. "github.com/onsi/gomega"
@ -29,15 +28,10 @@ import (
func TestNewGooglePubSub(t *testing.T) {
tests := []struct {
name string
projectID string
topicID string
jsonCreds string
attrs map[string]string
expectedErr error
expectedTopicName string
expectedJSONCreds []byte
expectedAttrs map[string]string
name string
projectID string
topicID string
expectedErr error
}{
{
name: "empty project ID is not allowed",
@ -50,61 +44,18 @@ func TestNewGooglePubSub(t *testing.T) {
topicID: "",
expectedErr: errors.New("GCP Pub/Sub topic ID cannot be empty"),
},
{
name: "topic name is stored properly",
projectID: "project-id",
topicID: "topic-id",
expectedTopicName: "projects/project-id/topics/topic-id",
},
{
name: "json creds are stored properly",
projectID: "project-id",
topicID: "topic-id",
expectedTopicName: "projects/project-id/topics/topic-id",
jsonCreds: "json credentials",
expectedJSONCreds: []byte("json credentials"),
},
{
name: "non-empty attributes are stored properly",
projectID: "project-id",
topicID: "topic-id",
expectedTopicName: "projects/project-id/topics/topic-id",
attrs: map[string]string{"foo": "bar"},
expectedAttrs: map[string]string{"foo": "bar"},
},
{
name: "empty attributes are stored properly",
projectID: "project-id",
topicID: "topic-id",
expectedTopicName: "projects/project-id/topics/topic-id",
attrs: map[string]string{},
expectedAttrs: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)
provider, err := NewGooglePubSub(&notifierOptions{
URL: tt.projectID,
Channel: tt.topicID,
})
provider, err := NewGooglePubSub(tt.projectID, tt.topicID, tt.jsonCreds, tt.attrs)
if tt.expectedErr != nil {
g.Expect(err).To(Equal(tt.expectedErr))
g.Expect(provider).To(BeNil())
} else {
g.Expect(err).To(BeNil())
g.Expect(provider).NotTo(BeNil())
g.Expect(provider.topicID).To(Equal(tt.topicID))
g.Expect(provider.attrs).To(Equal(tt.expectedAttrs))
g.Expect(provider.topicName).To(Equal(tt.expectedTopicName))
g.Expect(provider.client).NotTo(BeNil())
client := provider.client.(*googlePubSubClient)
g.Expect(client).NotTo(BeNil())
g.Expect(client.projectID).To(Equal(tt.projectID))
g.Expect(client.jsonCreds).To(Equal(tt.expectedJSONCreds))
}
g.Expect(err).To(Equal(tt.expectedErr))
g.Expect(provider).To(BeNil())
})
}
}
@ -124,14 +75,11 @@ type googlePubSubPostTestCase struct {
g *WithT
}
func (tt *googlePubSubPostTestCase) publish(ctx context.Context, topicID string, eventPayload []byte, attrs map[string]string) (serverID string, err error) {
func (tt *googlePubSubPostTestCase) publish(ctx context.Context, eventPayload []byte) error {
tt.g.THelper()
tt.publishExecuted = true
tt.g.Expect(topicID).To(Equal(tt.topicID))
tt.g.Expect(string(eventPayload)).To(Equal(tt.expectedEventPayload))
tt.g.Expect(attrs).To(Equal(tt.attrs))
// serverID is only used in a debug log for now, there's no way to assert it
return "", tt.publishErr
return tt.publishErr
}
func TestGooglePubSubPost(t *testing.T) {
@ -152,11 +100,11 @@ func TestGooglePubSubPost(t *testing.T) {
publishShouldExecute: false,
},
{
name: "publish error is wrapped and relayed",
name: "publish error is relayed",
expectedEventPayload: `{"involvedObject":{},"severity":"","timestamp":null,"message":"","reason":"","reportingController":""}`,
topicName: "projects/projectID/topics/topicID",
publishErr: errors.New("publish error"),
expectedErr: fmt.Errorf("error publishing event to topic projects/projectID/topics/topicID: %w", errors.New("publish error")),
expectedErr: errors.New("publish error"),
publishShouldExecute: true,
},
{
@ -174,10 +122,7 @@ func TestGooglePubSubPost(t *testing.T) {
tt.g = g
topic := &GooglePubSub{
client: tt,
topicID: tt.topicID,
attrs: tt.attrs,
topicName: tt.topicName,
client: tt,
}
err := topic.Post(context.Background(), tt.event)

View File

@ -18,7 +18,7 @@ package notifier
import (
"context"
"crypto/x509"
"crypto/tls"
"fmt"
"net/url"
"strings"
@ -28,15 +28,15 @@ import (
)
type Grafana struct {
URL string
Token string
ProxyURL string
CertPool *x509.CertPool
Username string
Password string
URL string
Token string
ProxyURL string
TLSConfig *tls.Config
Username string
Password string
}
// GraphiteAnnotation represents a Grafana API annotation in Graphite format
// GraphitePayload represents a Grafana API annotation in Graphite format
type GraphitePayload struct {
When int64 `json:"when"` //optional unix timestamp (ms)
Text string `json:"text"`
@ -44,19 +44,19 @@ type GraphitePayload struct {
}
// NewGrafana validates the Grafana URL and returns a Grafana object
func NewGrafana(URL string, proxyURL string, token string, certPool *x509.CertPool, username string, password string) (*Grafana, error) {
func NewGrafana(URL string, proxyURL string, token string, tlsConfig *tls.Config, username string, password string) (*Grafana, error) {
_, err := url.ParseRequestURI(URL)
if err != nil {
return nil, fmt.Errorf("invalid Grafana URL %s", URL)
}
return &Grafana{
URL: URL,
ProxyURL: proxyURL,
Token: token,
CertPool: certPool,
Username: username,
Password: password,
URL: URL,
ProxyURL: proxyURL,
Token: token,
Username: username,
Password: password,
TLSConfig: tlsConfig,
}, nil
}
@ -71,23 +71,37 @@ func (g *Grafana) Post(ctx context.Context, event eventv1.Event) error {
// add tag to filter on grafana
sfields = append(sfields, "flux", event.ReportingController)
for k, v := range event.Metadata {
sfields = append(sfields, fmt.Sprintf("%s: %s", k, v))
key := strings.ReplaceAll(k, ":", "|")
value := strings.ReplaceAll(v, ":", "|")
sfields = append(sfields, fmt.Sprintf("%s: %s", key, value))
}
sfields = append(sfields, fmt.Sprintf("kind: %s", event.InvolvedObject.Kind))
sfields = append(sfields, fmt.Sprintf("name: %s", event.InvolvedObject.Name))
sfields = append(sfields, fmt.Sprintf("namespace: %s", event.InvolvedObject.Namespace))
payload := GraphitePayload{
When: event.Timestamp.Unix(),
Text: fmt.Sprintf("%s/%s.%s", strings.ToLower(event.InvolvedObject.Kind), event.InvolvedObject.Name, event.InvolvedObject.Namespace),
Tags: sfields,
}
err := postMessage(ctx, g.URL, g.ProxyURL, g.CertPool, payload, func(request *retryablehttp.Request) {
if (g.Username != "" && g.Password != "") && g.Token == "" {
request.Header.Add("Authorization", "Basic "+basicAuth(g.Username, g.Password))
}
if g.Token != "" {
request.Header.Add("Authorization", "Bearer "+g.Token)
}
})
if err != nil {
opts := []postOption{
withRequestModifier(func(req *retryablehttp.Request) {
if (g.Username != "" && g.Password != "") && g.Token == "" {
req.Header.Add("Authorization", "Basic "+basicAuth(g.Username, g.Password))
}
if g.Token != "" {
req.Header.Add("Authorization", "Bearer "+g.Token)
}
}),
}
if g.ProxyURL != "" {
opts = append(opts, withProxy(g.ProxyURL))
}
if g.TLSConfig != nil {
opts = append(opts, withTLSConfig(g.TLSConfig))
}
if err := postMessage(ctx, g.URL, payload, opts...); err != nil {
return fmt.Errorf("postMessage failed: %w", err)
}
return nil

View File

@ -18,7 +18,7 @@ package notifier
import (
"context"
"crypto/x509"
"crypto/tls"
"fmt"
"io"
"net/http"
@ -43,10 +43,10 @@ func Fuzz_Grafana(f *testing.F) {
}))
defer ts.Close()
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
var tlsConfig tls.Config
_ = fuzz.NewConsumer(seed).GenerateStruct(&tlsConfig)
grafana, err := NewGrafana(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", token, &cert, username, password)
grafana, err := NewGrafana(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", token, &tlsConfig, username, password)
if err != nil {
return
}

View File

@ -41,6 +41,9 @@ func TestGrafana_Post(t *testing.T) {
require.Equal(t, "flux", payload.Tags[0])
require.Equal(t, "source-controller", payload.Tags[1])
require.Equal(t, "test: metadata", payload.Tags[2])
require.Equal(t, "kind: GitRepository", payload.Tags[3])
require.Equal(t, "name: webapp", payload.Tags[4])
require.Equal(t, "namespace: gitops-system", payload.Tags[5])
}))
defer ts.Close()

View File

@ -109,5 +109,5 @@ func (l *Lark) Post(ctx context.Context, event eventv1.Event) error {
Card: card,
}
return postMessage(ctx, l.URL, "", nil, payload)
return postMessage(ctx, l.URL, payload)
}

View File

@ -3,7 +3,7 @@ package notifier
import (
"context"
"crypto/sha1"
"crypto/x509"
"crypto/tls"
"encoding/json"
"fmt"
"net/http"
@ -15,10 +15,10 @@ import (
)
type Matrix struct {
Token string
URL string
RoomId string
CertPool *x509.CertPool
Token string
URL string
RoomId string
TLSConfig *tls.Config
}
type MatrixPayload struct {
@ -26,17 +26,17 @@ type MatrixPayload struct {
MsgType string `json:"msgtype"`
}
func NewMatrix(serverURL, token, roomId string, certPool *x509.CertPool) (*Matrix, error) {
func NewMatrix(serverURL, token, roomId string, tlsConfig *tls.Config) (*Matrix, error) {
_, err := url.ParseRequestURI(serverURL)
if err != nil {
return nil, fmt.Errorf("invalid Matrix homeserver URL %s: '%w'", serverURL, err)
}
return &Matrix{
URL: serverURL,
RoomId: roomId,
Token: token,
CertPool: certPool,
URL: serverURL,
RoomId: roomId,
Token: token,
TLSConfig: tlsConfig,
}, nil
}
@ -65,11 +65,17 @@ func (m *Matrix) Post(ctx context.Context, event eventv1.Event) error {
MsgType: "m.text",
}
err = postMessage(ctx, fullURL, "", m.CertPool, payload, func(request *retryablehttp.Request) {
request.Method = http.MethodPut
request.Header.Add("Authorization", "Bearer "+m.Token)
})
if err != nil {
opts := []postOption{
withRequestModifier(func(req *retryablehttp.Request) {
req.Method = http.MethodPut
req.Header.Add("Authorization", "Bearer "+m.Token)
}),
}
if m.TLSConfig != nil {
opts = append(opts, withTLSConfig(m.TLSConfig))
}
if err := postMessage(ctx, fullURL, payload, opts...); err != nil {
return fmt.Errorf("postMessage failed: %w", err)
}

View File

@ -2,7 +2,7 @@ package notifier
import (
"context"
"crypto/x509"
"crypto/tls"
"fmt"
"io"
"net/http"
@ -27,10 +27,10 @@ func Fuzz_Matrix(f *testing.F) {
}))
defer ts.Close()
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
var tlsConfig tls.Config
_ = fuzz.NewConsumer(seed).GenerateStruct(&tlsConfig)
matrix, err := NewMatrix(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, roomId, &cert)
matrix, err := NewMatrix(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, roomId, &tlsConfig)
if err != nil {
return
}

View File

@ -1,29 +0,0 @@
/*
Copyright 2020 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 notifier
import (
"context"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
)
type NopNotifier struct{}
func (n *NopNotifier) Post(ctx context.Context, event eventv1.Event) error {
return nil
}

View File

@ -22,6 +22,9 @@ import (
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
)
// OperationPost is the operation name used in cache event metrics
const OperationPost = "post"
type Interface interface {
Post(ctx context.Context, event eventv1.Event) error
}

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