Compare commits

...

294 Commits

Author SHA1 Message Date
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
129 changed files with 8177 additions and 4229 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.17.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.17.0 h1:KVMDyJQj1NYCsppsFUkbJGMnKxsqJVpnKBFolHf/q8E=
github.com/fluxcd/pkg/apis/meta v1.17.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,7 +67,6 @@ type AlertStatus struct {
}
// +genclient
// +genclient:Namespaced
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:deprecatedversion:warning="v1beta1 Alert is deprecated, upgrade to v1beta3"

View File

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

View File

@ -97,7 +97,6 @@ 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"

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,60 @@ 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).
// ServiceAccountName is the name of the service account used to
// authenticate with services from cloud providers. An error is thrown if a
// static credential is also defined inside the Secret referenced by the
// SecretRef.
// +optional
ServiceAccountName string `json:"serviceAccountName,omitempty"`
// CertSecretRef specifies the Secret containing TLS certificates
// for secure communication.
//
// Note: Support for the `caFile` key has
// been deprecated.
// 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
@ -32,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
@ -49,7 +54,8 @@ spec:
properties:
eventSeverity:
default: info
description: Filter events based on severity, defaults to ('info').
description: |-
Filter events based on severity, defaults to ('info').
If set to 'info' no events will be filtered.
enum:
- info
@ -58,8 +64,9 @@ spec:
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
description: |-
CrossNamespaceObjectReference contains enough information to let you locate the
typed referenced object at cluster level
properties:
apiVersion:
description: API version of the referent
@ -81,11 +88,10 @@ 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.
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
@ -98,6 +104,7 @@ spec:
minLength: 1
type: string
required:
- kind
- name
type: object
type: array
@ -120,8 +127,9 @@ spec:
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.
description: |-
This flag tells the controller to suspend subsequent events dispatching.
Defaults to false.
type: boolean
required:
- eventSources
@ -134,43 +142,35 @@ spec:
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 }"
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
@ -185,10 +185,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
@ -228,14 +224,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 +247,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 +292,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 +316,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 +345,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 +361,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 +404,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 +416,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 +441,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 +464,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 +509,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 +533,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 +557,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
@ -32,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
@ -51,7 +56,8 @@ spec:
pattern: ^(http|https)://
type: string
certSecretRef:
description: CertSecretRef can be given the name of a secret containing
description: |-
CertSecretRef can be given the name of a secret containing
a PEM-encoded CA certificate (`caFile`)
properties:
name:
@ -68,7 +74,8 @@ spec:
pattern: ^(http|https)://
type: string
secretRef:
description: Secret reference containing the provider webhook URL
description: |-
Secret reference containing the provider webhook URL
using "address" as data key
properties:
name:
@ -78,8 +85,9 @@ spec:
- name
type: object
suspend:
description: This flag tells the controller to suspend subsequent
events handling. Defaults to false.
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.
@ -123,43 +131,35 @@ spec:
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 }"
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
@ -174,10 +174,6 @@ spec:
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
--- Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
@ -217,14 +213,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 +233,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 +270,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 +281,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 +334,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 +377,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 +389,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 +414,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 +434,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 +464,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 +509,17 @@ spec:
required:
- name
type: object
serviceAccountName:
description: |-
ServiceAccountName is the name of the service account used to
authenticate with services from cloud providers. An error is thrown if a
static credential is also defined inside the Secret referenced by the
SecretRef.
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 +563,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

@ -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,21 @@ 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 service account used to
authenticate with services from cloud providers. An error is thrown if a
static credential is also defined inside the Secret referenced by the
SecretRef.</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 +392,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 +414,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 +545,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 +596,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 +671,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 +709,21 @@ 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 service account used to
authenticate with services from cloud providers. An error is thrown if a
static credential is also defined inside the Secret referenced by the
SecretRef.</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 +733,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 +755,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
@ -713,7 +812,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

View File

@ -11,7 +11,7 @@ install or upgrade [Flagger](https://github.com/fluxcd/flagger).
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: slack-bot
@ -23,7 +23,7 @@ spec:
secretRef:
name: slack-bot-token
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
name: slack
@ -109,7 +109,9 @@ The supported alerting providers are:
| [WebEx](#webex) | `webex` |
| [NATS](#nats) | `nats` |
The supported providers for [Git commit status updates](#git-commit-status-updates) are:
#### Types supporting Git commit status updates
The providers supporting [Git commit status updates](#git-commit-status-updates) are:
| Provider | Type |
|--------------------------------------------------------------|-------------------|
@ -133,7 +135,7 @@ for example:
```json
{
"involvedObject": {
"apiVersion": "kustomize.toolkit.fluxcd.io/v1beta2",
"apiVersion": "kustomize.toolkit.fluxcd.io/v1",
"kind": "Kustomization",
"name": "webapp",
"namespace": "apps",
@ -282,7 +284,7 @@ field](https://api.slack.com/methods/chat.postMessage#arg_username) to the
payload, defaulting to the name of the reporting controller.
This Provider type supports the configuration of a [proxy URL](#https-proxy)
and/or [TLS certificates](#tls-certificates).
and/or [certificate secret reference](#certificate-secret-reference).
###### Slack example
@ -299,7 +301,7 @@ by adding the integration to each channel.
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: slack
@ -328,7 +330,7 @@ and a `slack` Provider with a [Secret reference](#address-example).
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: slack
@ -350,27 +352,30 @@ stringData:
##### Microsoft Teams
When `.spec.type` is set to `msteams`, the controller will send a payload for
an [Event](events.md#event-structure) to the provided Microsoft Teams [Address](#address).
an [Event](events.md#event-structure) to the provided [Address](#address). The address
may be a [Microsoft Teams Incoming Webhook Workflow](https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498), or
the deprecated [Office 365 Connector](https://devblogs.microsoft.com/microsoft365dev/retirement-of-office-365-connectors-within-microsoft-teams/).
The Event will be formatted into a Microsoft Teams
[connector message](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using#example-of-connector-message),
with the metadata attached as facts, and the involved object as summary.
**Note:** If the Address host contains the suffix `.webhook.office.com`, the controller will imply that
the backend is the deprecated Office 365 Connector and is expecting the Event in the [connector message](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using#example-of-connector-message) format. Otherwise, the controller will format the Event as a [Microsoft Adaptive Card](https://adaptivecards.io/explorer/) message.
In both cases the Event metadata is attached as facts, and the involved object as a summary/title.
The severity of the Event is used to set the color of the message.
This Provider type supports the configuration of a [proxy URL](#https-proxy)
and/or [TLS certificates](#tls-certificates), but lacks support for
and/or [certificate secret reference](#certificate-secret-reference), but lacks support for
configuring a [Channel](#channel). This can be configured during the
creation of the incoming webhook in Microsoft Teams.
creation of the Incoming Webhook Workflow in Microsoft Teams.
###### Microsoft Teams example
To configure a Provider for Microsoft Teams, create a Secret with [the
`address`](#address-example) set to the [webhook URL](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook#create-incoming-webhooks-1),
and a `msteams` Provider with a [Secret reference](#address-example).
`address`](#address-example) set to the [webhook URL](https://support.microsoft.com/en-us/office/create-incoming-webhooks-with-workflows-for-microsoft-teams-8ae491c7-0394-4861-ba59-055e33f75498),
and an `msteams` Provider with a [Secret reference](#secret-reference).
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: msteams
@ -386,7 +391,7 @@ metadata:
name: msteams-webhook
namespace: default
stringData:
address: "https://xxx.webhook.office.com/..."
address: https://prod-xxx.yyy.logic.azure.com:443/workflows/zzz/triggers/manual/paths/invoke?...
```
##### DataDog
@ -398,7 +403,7 @@ The Event will be formatted into a [DataDog Event](https://docs.datadoghq.com/ap
API endpoint of the provided DataDog [Address](#address).
This Provider type supports the configuration of a [proxy URL](#https-proxy)
and/or [TLS certificates](#tls-certificates).
and/or [certificate secret reference](#certificate-secret-reference).
The metadata of the Event is included in the DataDog event as extra tags.
@ -410,7 +415,7 @@ set to a [DataDog API key](https://docs.datadoghq.com/account_management/api-app
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: datadog
@ -429,7 +434,7 @@ metadata:
stringData:
token: <DataDog API Key>
---
apiVersion: notification.toolkit.fluxcd.io/v1beta1
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
name: datadog-info
@ -454,7 +459,7 @@ The Event will be formatted into a [Slack message](#slack) and send to the
`/slack` endpoint of the provided Discord [Address](#address).
This Provider type supports the configuration of a [proxy URL](#https-proxy)
and/or [TLS certificates](#tls-certificates), but lacks support for
and/or [certificate secret reference](#certificate-secret-reference), but lacks support for
configuring a [Channel](#channel). This can be configured [during the creation
of the address](https://discord.com/developers/docs/resources/webhook#create-webhook)
@ -466,7 +471,7 @@ and a `discord` Provider with a [Secret reference](#secret-reference).
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: discord
@ -502,7 +507,7 @@ The Provider's [Channel](#channel) is used to set the `environment` on the
Sentry client.
This Provider type supports the configuration of
[TLS certificates](#tls-certificates).
[certificate secret reference](#certificate-secret-reference).
###### Sentry example
@ -512,7 +517,7 @@ and a `sentry` Provider with a [Secret reference](#secret-reference).
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: sentry
@ -539,36 +544,37 @@ stringData:
##### Telegram
When `.spec.type` is set to `telegram`, the controller will send a payload for
an [Event](events.md#event-structure) to the provided Telegram [Address](#address).
an [Event](events.md#event-structure) to the Telegram Bot API.
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).
This Provider type does not support the configuration of a [certificate secret reference](#certificate-secret-reference).
**Note:** The Telegram provider always ignores the `address` field and uses the default
Telegram Bot API endpoint (`https://api.telegram.org`).
###### Telegram example
To configure a Provider for Telegram, create a Secret with [the `token`](#token-example)
obtained from [the BotFather](https://core.telegram.org/bots#how-do-i-create-a-bot),
and a `telegram` Provider with a [Secret reference](#secret-reference), and the
`address` set to `https://api.telegram.org`.
and a `telegram` Provider with a [Secret reference](#secret-reference).
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: telegram
namespace: default
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
```
@ -595,7 +601,7 @@ obtained from [the Matrix endpoint](https://matrix.org/docs/guides/client-server
and a `matrix` Provider with a [Secret reference](#secret-reference).
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: matrix
@ -617,7 +623,7 @@ The Event will be formatted into a [Lark Message card](https://open.larksuite.co
with the metadata written to the message string.
This Provider type does not support the configuration of a [proxy URL](#https-proxy)
or [TLS certificates](#tls-certificates).
or [certificate secret reference](#certificate-secret-reference).
###### Lark example
@ -626,7 +632,7 @@ obtained from [adding a bot to a group](https://open.larksuite.com/document/uAjL
and a `lark` Provider with a [Secret reference](#secret-reference).
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: lark
@ -654,7 +660,7 @@ The Event will be formatted into a [Slack message](#slack) and send as a
payload the provided Rocket [Address](#address).
This Provider type does support the configuration of a [proxy URL](#https-proxy)
and [TLS certificates](#tls-certificates).
and [certificate secret reference](#certificate-secret-reference).
###### Rocket example
@ -664,7 +670,7 @@ and a `rocket` Provider with a [Secret reference](#secret-reference).
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: rocket
@ -694,7 +700,7 @@ and a `googlechat` Provider with a [Secret reference](#secret-reference).
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: google
@ -736,7 +742,7 @@ You can optionally add [attributes](https://cloud.google.com/pubsub/docs/samples
to the Pub/Sub message using a [`headers` key in the referenced Secret](#http-headers-example).
This Provider type does not support the configuration of a [proxy URL](#https-proxy)
or [TLS certificates](#tls-certificates).
or [certificate secret reference](#certificate-secret-reference).
###### Google Pub/Sub with JSON Credentials and Custom Headers Example
@ -748,7 +754,7 @@ YAML string-to-string dictionary, and a `googlepubsub` Provider with the associa
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: googlepubsub-provider
@ -782,7 +788,7 @@ with the metadata added to the [`details` field](https://docs.opsgenie.com/docs/
as a list of key-value pairs.
This Provider type does support the configuration of a [proxy URL](#https-proxy)
and [TLS certificates](#tls-certificates).
and [certificate secret reference](#certificate-secret-reference).
###### Opsgenie example
@ -793,7 +799,7 @@ and a `opsgenie` Provider with a [Secret reference](#secret-reference) and the
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: opsgenie
@ -825,7 +831,7 @@ The provider will also send [Change Events](https://developer.pagerduty.com/api-
for `info` level `Severity`, which will be displayed in the PagerDuty service's timeline to track changes.
This Provider type supports the configuration of a [proxy URL](#https-proxy)
and [TLS certificates](#tls-certificates).
and [certificate secret reference](#certificate-secret-reference).
The [Channel](#channel) is used to set the routing key to send the event to the appropriate integration.
@ -842,7 +848,7 @@ When adding an integration for a service on PagerDuty, it is recommended to use
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: pagerduty
@ -857,7 +863,7 @@ only those sources you want to trigger an incident for that service. For example
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
name: my-service-pagerduty
@ -878,9 +884,10 @@ an [Event](events.md#event-structure) to the provided Prometheus Alertmanager
[Address](#address).
The Event will be formatted into a `firing` [Prometheus Alertmanager
alert](https://prometheus.io/docs/alerting/latest/notifications/#alert),
with the metadata added to the `labels` fields, and the `message` (and optional
`.metadata.summary`) added as annotations.
alert](https://prometheus.io/docs/alerting/latest/notifications/#alert), with
the metadata added to the `labels` fields, and the `message` (and optional
`.metadata.summary`) added as annotations. Event timestamp will be used to set
alert start time (`.StartsAt`).
In addition to the metadata from the Event, the following labels will be added:
@ -888,26 +895,43 @@ In addition to the metadata from the Event, the following labels will be added:
|-----------|------------------------------------------------------------------------------------------------------|
| alertname | The string Flux followed by the Kind and the reason for the event e.g `FluxKustomizationProgressing` |
| severity | The severity of the event (`error` or `info`) |
| timestamp | The timestamp of the event |
| reason | The machine readable reason for the objects transition into the current status |
| kind | The kind of the involved object associated with the event |
| name | The name of the involved object associated with the event |
| namespace | The namespace of the involved object associated with the event |
Note that due to the way other Flux controllers currently emit events, there's
no way for notification-controller to figure out the time the event ends to set
`.EndsAt` (a reasonable estimate being double the reconciliation interval of the
resource involved) that doesn't involve a Kubernetes API roundtrip. A
possible workaround could be setting
[`global.resolve_timeout`][am_config_global] to an interval large enough for
events to reoccur:
[am_config_global]: https://prometheus.io/docs/alerting/latest/configuration/#file-layout-and-global-settings
```yaml
global:
resolve_timeout: 1h
```
This Provider type does support the configuration of a [proxy URL](#https-proxy)
and [TLS certificates](#tls-certificates).
and [certificate secret reference](#certificate-secret-reference).
###### Prometheus Alertmanager example
To configure a Provider for Prometheus Alertmanager, create a Secret with [the
`address`](#address-example) set to the Prometheus Alertmanager [HTTP API
To configure a Provider for Prometheus Alertmanager, authentication can be done using either Basic Authentication or a Bearer Token.
Both methods are supported, but using authentication is optional based on your setup.
Basic Authentication:
Create a Secret with [the `address`](#address-example) set to the Prometheus Alertmanager [HTTP API
URL](https://prometheus.io/docs/alerting/latest/https/#http-traffic)
including Basic Auth credentials, and a `alertmanager` Provider with a [Secret
including Basic Auth credentials, and an `alertmanager` Provider with a [Secret
reference](#secret-reference).
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: alertmanager
@ -923,7 +947,33 @@ metadata:
name: alertmanager-address
namespace: default
stringData:
address: https://username:password@<alertmanager-url>/api/v2/alerts/"
address: https://<username>:<password>@<alertmanager-hostport>/api/v2/alerts/
```
Bearer Token Authentication:
Create a Secret with [the `token`](#token-example), and an `alertmanager` Provider with a [Secret
reference](#secret-reference) and the Prometheus Alertmanager [HTTP API
URL](https://prometheus.io/docs/alerting/latest/https/#http-traffic) set directly in the `.spec.address` field.
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: alertmanager
namespace: default
spec:
type: alertmanager
address: https://<alertmanager-hostport>/api/v2/alerts/
secretRef:
name: alertmanager-token
---
apiVersion: v1
kind: Secret
metadata:
name: alertmanager-token
namespace: default
stringData:
token: <token>
```
##### Webex
@ -938,7 +988,7 @@ The [Channel](#channel) is used to set the ID of the room to send the message
to.
This Provider type does support the configuration of a [proxy URL](#https-proxy)
and [TLS certificates](#tls-certificates).
and [certificate secret reference](#certificate-secret-reference).
###### Webex example
@ -953,7 +1003,7 @@ controller.
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: webex
@ -1047,7 +1097,7 @@ credentials for the provider API.
The Kubernetes secret can have any of the following keys:
- `address` - overrides `.spec.address`
- `proxy` - overrides `.spec.proxy`
- `proxy` - overrides `.spec.proxy` (deprecated, use `.spec.proxySecretRef` instead. **Support for this key will be removed in v1**)
- `token` - used for authentication
- `username` - overrides `.spec.username`
- `headers` - HTTP headers values included in the POST request
@ -1105,7 +1155,7 @@ stringData:
#### Proxy auth example
Some networks need to use an authenticated proxy to access external services.
Therefore, the proxy address can be stored as a secret to hide parameters like the username and password:
The recommended approach is to use `.spec.proxySecretRef` with a dedicated Secret:
```yaml
---
@ -1114,15 +1164,56 @@ kind: Secret
metadata:
name: my-provider-proxy
namespace: default
stringData:
address: "http://proxy_url:proxy_port"
username: "proxy_username"
password: "proxy_password"
```
**Legacy approach (deprecated):**
The proxy address can also be stored in the main secret to hide parameters like the username and password:
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: my-provider-proxy-legacy
namespace: default
stringData:
proxy: "http://username:password@proxy_url:proxy_port"
```
### TLS certificates
### Certificate secret reference
`.spec.certSecretRef` is an optional field to specify a name reference to a
Secret in the same namespace as the Provider, containing the TLS CA certificate.
The secret must be of type `kubernetes.io/tls` or `Opaque`.
Secret in the same namespace as the Provider, containing TLS certificates for
secure communication. The secret must be of type `kubernetes.io/tls` or `Opaque`.
#### Supported configurations
- **CA-only**: Server authentication (provide `ca.crt` only)
- **mTLS**: Client certificate authentication (provide `tls.crt` + `tls.key`, optionally with `ca.crt`)
#### Providers supporting client certificate authentication
The following webhook-based providers support client certificate authentication:
| Provider Type | Description |
|---------------------|--------------------------------|
| `alertmanager` | Prometheus Alertmanager |
| `discord` | Discord webhooks |
| `forwarder` | Generic forwarder |
| `grafana` | Grafana annotations API |
| `matrix` | Matrix rooms |
| `msteams` | Microsoft Teams |
| `opsgenie` | Opsgenie alerts |
| `pagerduty` | PagerDuty events |
| `rocket` | Rocket.Chat |
| `slack` | Slack API |
| `webex` | Webex messages |
Support for client certificate authentication is being expanded to additional providers over time.
#### Example
@ -1131,7 +1222,7 @@ using a self-signed TLS certificate, set the `ca.crt` like so:
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: my-webhook
@ -1160,10 +1251,25 @@ the controller will log a deprecation warning.
### HTTP/S proxy
`.spec.proxy` is an optional field to specify an HTTP/S proxy address.
**Warning:** This field is deprecated, use `.spec.proxySecretRef` instead. **Support for this field will be removed in v1.**
`.spec.proxySecretRef` is an optional field to specify a name reference to a
Secret in the same namespace as the Provider, containing the proxy configuration.
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.
If the proxy address contains sensitive information such as basic auth credentials, it is
recommended to store the proxy in the Kubernetes secret referenced by `.spec.secretRef.name`.
When the referenced Secret contains a `proxy` key, the `.spec.proxy` value is ignored.
recommended to use `.spec.proxySecretRef` instead of `.spec.proxy`.
When `.spec.proxySecretRef` is specified, both `.spec.proxy` and the `proxy` key from
`.spec.secretRef` are ignored.
### Timeout
`.spec.timeout` is an optional field to specify the timeout for the
HTTP/S request sent to the provider endpoint.
The value must be in a
[Go recognized duration string format](https://pkg.go.dev/time#ParseDuration),
e.g. `5m30s` for a timeout of five minutes and thirty seconds.
### Suspend
@ -1201,7 +1307,7 @@ kubectl create secret generic grafana-token \
Create a provider of type `grafana` and reference the `grafana-token` secret:
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: grafana
@ -1213,6 +1319,11 @@ spec:
name: grafana-token
```
Besides the tag `flux` and the tag containing the reporting controller (e.g. `source-controller`),
the event metadata is also included as tags of the form `${metadataKey}: ${metadataValue}`, and
the tags `kind: ${event.InvolvedObject.Kind}`, `name: ${event.InvolvedObject.Name}` and
`namespace: ${event.InvolvedObject.Namespace}` are also included.
### GitHub dispatch
The `githubdispatch` provider generates GitHub events of type
@ -1228,7 +1339,7 @@ The request includes the `event_type` and `client_payload` fields:
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: github-dispatch
@ -1237,14 +1348,16 @@ spec:
type: githubdispatch
address: https://github.com/stefanprodan/podinfo
secretRef:
name: api-token
name: auth-secret
```
The `address` is the address of your repository where you want to send webhooks to trigger GitHub workflows.
GitHub uses personal access tokens for authentication with its API:
GitHub uses [personal access tokens](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token)
or [GitHub app](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation)
for authentication with its API:
* [GitHub personal access token](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token)
#### GitHub personal access token
The provider requires a secret in the same format, with the personal access token as the value for the token key:
@ -1253,12 +1366,19 @@ The provider requires a secret in the same format, with the personal access toke
apiVersion: v1
kind: Secret
metadata:
name: api-token
name: auth-secret
namespace: default
data:
stringData:
token: <personal-access-tokens>
```
#### GitHub App
To use Github App authentication, make sure the GitHub App is registered and
installed with the necessary permissions and the github app secret is created as
described
[here](https://fluxcd.io/flux/components/source/gitrepositories/#github).
#### Setting up a GitHub workflow
To trigger a GitHub Actions workflow when a Flux Kustomization finishes reconciling,
@ -1293,7 +1413,7 @@ You can then create a flux kustomization resource for the app to have unique `ev
The kustomization manifest for app1/staging:
```yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
apiVersion: kustomize.toolkit.fluxcd.io/v1beta3
kind: Kustomization
metadata:
name: app1
@ -1306,7 +1426,7 @@ You would also like to know from the notification which cluster is being used fo
You can add the `spec.summary` field to the Flux alert configuration to mention the relevant cluster:
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
name: github-dispatch
@ -1321,7 +1441,7 @@ spec:
name: 'podinfo'
```
Now you can the trigger tests in the GitHub workflow for app1 in a staging cluster when
Now you can trigger the tests in the GitHub workflow for app1 in a staging cluster when
the app1 resources defined in `./app1/staging/` are reconciled by Flux:
```yaml
@ -1340,13 +1460,62 @@ jobs:
### Azure Event Hub
The Azure Event Hub supports two authentication methods, [JWT](https://docs.microsoft.com/en-us/azure/event-hubs/authenticate-application)
and [SAS](https://docs.microsoft.com/en-us/azure/event-hubs/authorize-access-shared-access-signature) based.
The Azure Event Hub provider supports the following authentication methods,
- [Managed
Identity](https://learn.microsoft.com/en-us/azure/event-hubs/authenticate-managed-identity)
- [JWT](https://docs.microsoft.com/en-us/azure/event-hubs/authenticate-application)
- [SAS](https://docs.microsoft.com/en-us/azure/event-hubs/authorize-access-shared-access-signature)
based.
#### Managed Identity
Managed identity authentication can be setup using Azure Workload identity.
##### Pre-requisites
- Ensure Workload Identity is properly [set up on your
cluster](https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster#create-an-aks-cluster).
##### Configure workload identity
- Create a managed identity to access Azure Event Hub.
- Grant the managed identity the necessary permissions to send events to Azure
Event hub as described
[here](https://learn.microsoft.com/en-us/azure/event-hubs/authenticate-managed-identity#to-assign-azure-roles-using-the-azure-portal).
- Establish a federated identity credential between the managed identity and the
service account to be used for authentication. Ensure the federated credential
uses the correct namespace and name of the service account. For more details,
please refer to this
[guide](https://azure.github.io/azure-workload-identity/docs/quick-start.html#6-establish-federated-identity-credential-between-the-identity-and-the-service-account-issuer--subject).
##### Single tenant approach
This approach uses the notification-controller service account for setting up
authentication.
- In the default installation, the notification-controller service account is
located in the `flux-system` namespace with name `notification-controller`.
- Configure workload identity with notification-controller as described in the
docs [here](/flux/installation/configuration/workload-identity/).
##### Multi-tenant approach
For multi-tenant clusters, set `.spec.serviceAccountName` of the provider to
the service account to be used for authentication. Ensure that the service
account has the
[annotations](https://learn.microsoft.com/en-us/azure/aks/workload-identity-overview?tabs=dotnet#service-account-annotations)
for the client-id and tenant-id of the managed identity.
For a complete guide on how to set up authentication for an Azure Event Hub,
see the integration [docs](/flux/integrations/azure/).
#### JWT based auth
In JWT we use 3 input values. Channel, token and address.
We perform the following translation to match we the data we need to communicate with Azure Event Hub.
In JWT we use 3 input values. Channel, token and address. We perform the
following translation to match we the data we need to communicate with Azure
Event Hub.
- channel = Azure Event Hub namespace
- address = Azure Event Hub name
@ -1354,7 +1523,7 @@ We perform the following translation to match we the data we need to communicate
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: azure
@ -1376,11 +1545,13 @@ stringData:
```
The controller doesn't take any responsibility for the JWT token to be updated.
You need to use a secondary tool to make sure that the token in the secret is renewed.
You need to use a secondary tool to make sure that the token in the secret is
renewed.
If you want to make a easy test assuming that you have setup a Azure Enterprise application and you called it
event-hub you can follow most of the bellow commands. You will need to provide the `client_secret` that you got
when generating the Azure Enterprise Application.
If you want to make a easy test assuming that you have setup a Azure Enterprise
application and you called it event-hub you can follow most of the bellow
commands. You will need to provide the `client_secret` that you got when
generating the Azure Enterprise Application.
```shell
export AZURE_CLIENT=$(az ad app list --filter "startswith(displayName,'event-hub')" --query '[].appId' |jq -r '.[0]')
@ -1403,7 +1574,7 @@ When using SAS auth, we only use the `address` field in the secret.
```yaml
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: azure
@ -1423,8 +1594,8 @@ stringData:
```
Assuming that you have created the Azure event hub and namespace you should be
able to use a similar command to get your connection string. This will give
you the default Root SAS, which is NOT supposed to be used in production.
able to use a similar command to get your connection string. This will give you
the default Root SAS, which is NOT supposed to be used in production.
```shell
az eventhubs namespace authorization-rule keys list --resource-group <rg-name> --namespace-name <namespace-name> --name RootManageSharedAccessKey -o tsv --query primaryConnectionString
@ -1450,7 +1621,7 @@ The following is an example of how to update the Git commit status for the GitHu
Flux was bootstrapped with `flux bootstrap github --owner=my-gh-org --repository=my-gh-repo`.
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: github-status
@ -1461,7 +1632,7 @@ spec:
secretRef:
name: github-token
---
apiVersion: notification.toolkit.fluxcd.io/v1beta2
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
name: github-status
@ -1476,10 +1647,16 @@ spec:
#### GitHub
When `.spec.type` is set to `github`, the referenced secret must contain a key called `token` with the value set to a
[GitHub personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token).
When `.spec.type` is set to `github`, the referenced secret can contain a
personal access token OR github app details.
The token must have permissions to update the commit status for the GitHub repository specified in `.spec.address`.
##### Personal Access Token
To use personal access tokens, the secret must contain a key called `token` with
the value set to a [GitHub personal access
token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token).
The token must have permissions to update the commit status for the GitHub
repository specified in `.spec.address`.
You can create the secret with `kubectl` like this:
@ -1487,12 +1664,21 @@ You can create the secret with `kubectl` like this:
kubectl create secret generic github-token --from-literal=token=<GITHUB-TOKEN>
```
##### GitHub App
To use [Github App
authentication](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation),
make sure the GitHub App is registered and installed with the necessary
permissions to update the commit status and the github app secret is created as
described
[here](https://fluxcd.io/flux/components/source/gitrepositories/#github).
#### GitLab
When `.spec.type` is set to `gitlab`, the referenced secret must contain a key called `token` with the value set to a
[GitLab personal access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html).
[GitLab personal access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html). If available group and project access tokens can also be used.
The token must have permissions to update the commit status for the GitLab repository specified in `.spec.address`.
The token must have permissions to update the commit status for the GitLab repository specified in `.spec.address` (grant it the `api` scope).
You can create the secret with `kubectl` like this:
@ -1500,6 +1686,10 @@ You can create the secret with `kubectl` like this:
kubectl create secret generic gitlab-token --from-literal=token=<GITLAB-TOKEN>
```
For gitlab.com and current self-hosted gitlab installations that support only the Gitlab v4 API you need to use the project ID in the address instead of the project name.
Use an address like `https://gitlab.com/1234` (with `1234` being the project ID).
You can find out the ID by opening the project in the browser and clicking on the three dot button in the top right corner. The menu that opens shows the project ID.
#### Gitea
When `.spec.type` is set to `gitea`, the referenced secret must contain a key called `token` with the value set to a
@ -1559,6 +1749,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
@ -1571,3 +1763,30 @@ You can create the secret with `kubectl` like this:
```shell
kubectl create secret generic azuredevops-token --from-literal=token=<AZURE-TOKEN>
```
#### Custom Commit Status Messages
Git providers supporting commit status updates can use a CEL expression to build a custom commit status message by setting the optional field `spec.commitStatusExpr`:
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
name: github-status
namespace: flux-system
spec:
type: github
address: https://github.com/my-gh-org/my-gh-repo
secretRef:
name: github-token
commitStatusExpr: "(event.involvedObject.kind + '/' + event.involvedObject.name + '/' + event.metadata.foo + '/' + provider.metadata.uid.split('-').first().value()).lowerAscii()"
```
The CEL expression can access the following variables:
- `event`: The Flux event object containing metadata about the reconciliation
- `provider`: The Provider object
- `alert`: The Alert object
If the `spec.commitStatusExpr` field is not specified, the notification-controller will use a default commit status message based on the involved object kind, name, and a truncated provider UID to generate a commit status (e.g. `kustomization/gitops-system/0c9c2e41`).
A useful tool for building and testing CEL expressions is the [CEL Playground](https://playcel.undistro.io/).

281
go.mod
View File

@ -1,173 +1,218 @@
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
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-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
github.com/Azure/azure-event-hubs-go/v3 v3.6.2
github.com/DataDog/datadog-api-client-go/v2 v2.42.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.17.0
github.com/fluxcd/pkg/auth v0.21.0
github.com/fluxcd/pkg/cache v0.10.0
github.com/fluxcd/pkg/git v0.34.0
github.com/fluxcd/pkg/masktoken v0.7.0
github.com/fluxcd/pkg/runtime v0.69.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.25.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.37.0
github.com/sethvargo/go-limiter v1.0.0
github.com/slok/go-http-metrics v0.13.0
github.com/spf13/pflag v1.0.6
github.com/stretchr/testify v1.10.0
gitlab.com/gitlab-org/api/client-go v0.134.0
golang.org/x/oauth2 v0.30.0
golang.org/x/text v0.27.0
google.golang.org/api v0.241.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.23.1 // indirect
cloud.google.com/go v0.120.0 // indirect
cloud.google.com/go/auth v0.16.2 // 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 v65.0.0+incompatible // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 // 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.3.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 v0.11.28 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.21 // 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.14.2 // 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/joho/godotenv v1.5.1 // 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.0 // 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.39.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.41.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-20250505200425-f936aa4a68b2 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // 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
)

2067
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,14 @@ 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/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,7 +55,7 @@ type ReceiverReconciler struct {
}
type ReceiverReconcilerOptions struct {
RateLimiter ratelimiter.RateLimiter
RateLimiter workqueue.TypedRateLimiter[reconcile.Request]
}
func (r *ReceiverReconciler) SetupWithManager(mgr ctrl.Manager) error {
@ -112,9 +113,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 +156,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

@ -40,6 +40,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 +82,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))
}
@ -155,7 +155,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,59 @@ import (
)
type Alertmanager struct {
URL string
ProxyURL string
CertPool *x509.CertPool
URL string
ProxyURL string
TLSConfig *tls.Config
Token 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 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,
TLSConfig: tlsConfig,
}, nil
}
@ -75,25 +110,49 @@ 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 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

@ -40,14 +40,14 @@ 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(commitStatus string, addr string, token string, certPool *x509.CertPool) (*AzureDevOps, error) {
if len(token) == 0 {
return nil, errors.New("azure devops token cannot be empty")
}
@ -57,6 +57,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)
@ -77,10 +82,10 @@ func NewAzureDevOps(providerUID string, addr string, token string, certPool *x50
Client: *client,
}
return &AzureDevOps{
Project: proj,
Repo: repo,
ProviderUID: providerUID,
Client: gitClient,
Project: proj,
Repo: repo,
CommitStatus: commitStatus,
Client: gitClient,
}, nil
}
@ -91,7 +96,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 +113,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

@ -33,12 +33,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 +54,7 @@ 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)
azureDevOps, err := NewAzureDevOps(commitStatus, fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert)
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("kustomization/gitops-system/0c9c2e41", "https://dev.azure.com/foo/bar/_git/baz", "foo", 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("kustomization/gitops-system/0c9c2e41", "https://dev.azure.com/foo/bar/baz", "foo", 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("kustomization/gitops-system/0c9c2e41", "https://dev.azure.com/foo/bar/baz", "", nil)
assert.NotNil(t, err)
}
func TestNewAzureDevOpsEmptyCommitStatus(t *testing.T) {
_, err := NewAzureDevOps("", "https://dev.azure.com/foo/bar/_git/baz", "foo", 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("kustomization/gitops-system/0c9c2e41", "https://example.com/foo/bar/_git/baz", "foo", nil)
fakeClient := &fakeDevOpsClient{}
a.Client = fakeClient
assert.Nil(t, err)

View File

@ -17,10 +17,20 @@ import (
"context"
"encoding/json"
"fmt"
"net/url"
"strings"
"github.com/Azure/azure-amqp-common-go/v4/auth"
azauth "github.com/Azure/azure-amqp-common-go/v4/auth"
eventhub "github.com/Azure/azure-event-hubs-go/v3"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/fluxcd/pkg/auth"
"github.com/fluxcd/pkg/auth/azure"
"github.com/fluxcd/pkg/cache"
"github.com/fluxcd/notification-controller/api/v1beta3"
)
// AzureEventHub holds the eventhub client
@ -29,21 +39,33 @@ type AzureEventHub struct {
}
// NewAzureEventHub creates a eventhub client
func NewAzureEventHub(endpointURL, token, eventHubNamespace string) (*AzureEventHub, error) {
func NewAzureEventHub(ctx context.Context, endpointURL, token, eventHubNamespace, proxy,
serviceAccountName, providerName, providerNamespace string, tokenClient client.Client,
tokenCache *cache.TokenCache) (*AzureEventHub, error) {
var hub *eventhub.Hub
var err error
// token should only be defined if JWT is used
if token != "" {
hub, err = newJWTHub(endpointURL, token, eventHubNamespace)
if err != nil {
return nil, fmt.Errorf("failed to create a eventhub using JWT %v", err)
}
} else {
if err := validateAuthOptions(endpointURL, token, serviceAccountName); err != nil {
return nil, fmt.Errorf("invalid authentication options: %v", err)
}
if isSASAuth(endpointURL) {
hub, err = newSASHub(endpointURL)
if err != nil {
return nil, fmt.Errorf("failed to create a eventhub using SAS %v", err)
}
} else {
// if token doesn't exist, try to create a new token using managed identity
if token == "" {
token, err = newManagedIdentityToken(ctx, proxy, serviceAccountName, providerName, providerNamespace, tokenClient, tokenCache)
if err != nil {
return nil, fmt.Errorf("failed to create a eventhub using managed identity %v", err)
}
}
hub, err = newJWTHub(endpointURL, token, eventHubNamespace)
if err != nil {
return nil, fmt.Errorf("failed to create a eventhub using authentication token %v", err)
}
}
return &AzureEventHub{
@ -88,9 +110,9 @@ func NewJWTProvider(jwt string) *PureJWT {
}
// 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,
func (j *PureJWT) GetToken(uri string) (*azauth.Token, error) {
return &azauth.Token{
TokenType: azauth.CBSTokenTypeJWT,
Token: j.jwt,
Expiry: "",
}, nil
@ -116,3 +138,75 @@ func newSASHub(address string) (*eventhub.Hub, error) {
return hub, nil
}
// newManagedIdentityToken is used to attempt credential-free authentication.
func newManagedIdentityToken(ctx context.Context, proxy, serviceAccountName, providerName,
providerNamespace string, tokenClient client.Client, tokenCache *cache.TokenCache) (string, error) {
opts := []auth.Option{auth.WithScopes(azure.ScopeEventHubs)}
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 != "" {
serviceAccount := types.NamespacedName{
Name: serviceAccountName,
Namespace: providerNamespace,
}
opts = append(opts, auth.WithServiceAccount(serviceAccount, tokenClient))
}
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 for azure event hub: %w", err)
}
return token.(*azure.Token).AccessToken.Token, 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
}

View File

@ -0,0 +1,96 @@
/*
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: "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 for azure event hub: 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.Equal(t, tt.err, err)
} else {
assert.NoError(t, err)
assert.NotNil(t, client)
}
})
}
}

View File

@ -34,18 +34,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, certPool *x509.CertPool) (*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
@ -77,10 +82,10 @@ func NewBitbucket(providerUID string, addr string, token string, certPool *x509.
}
return &Bitbucket{
Owner: owner,
Repo: repo,
ProviderUID: providerUID,
Client: client,
Owner: owner,
Repo: repo,
CommitStatus: commitStatus,
Client: client,
}, nil
}
@ -91,7 +96,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 +110,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

@ -31,10 +31,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 +45,7 @@ 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)
bitbucket, err := NewBitbucket(commitStatus, fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert)
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

@ -37,11 +37,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 +47,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,18 +81,16 @@ 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, certPool *x509.CertPool, 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 {
@ -114,10 +112,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 +128,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 +143,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 +174,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 +188,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 +215,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 +231,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 +253,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

@ -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,339 @@ 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.URL, opts.Channel, opts.Token, opts.Headers)
}
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.CertPool, 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)
}
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.CertPool, 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.CertPool, 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.CertPool, 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.CertPool)
}
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.CertPool)
}
func bitbucketServerNotifierFunc(opts notifierOptions) (Interface, error) {
return NewBitbucketServer(opts.CommitStatus, opts.URL, opts.Token, opts.CertPool, opts.Username, opts.Password)
}
func bitbucketNotifierFunc(opts notifierOptions) (Interface, error) {
return NewBitbucket(opts.CommitStatus, opts.URL, opts.Token, opts.CertPool)
}
func azureDevOpsNotifierFunc(opts notifierOptions) (Interface, error) {
return NewAzureDevOps(opts.CommitStatus, opts.URL, opts.Token, opts.CertPool)
}

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

@ -34,22 +34,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, certPool *x509.CertPool) (*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 +69,39 @@ 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 certPool != nil {
tr.TLSClientConfig = &tls.Config{
RootCAs: certPool,
}
}
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 +115,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,9 @@ package notifier
import (
"context"
"crypto/x509"
"fmt"
testproxy "github.com/fluxcd/notification-controller/tests/proxy"
"net/http"
"net/http/httptest"
"testing"
@ -31,10 +33,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 +54,76 @@ 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())
g, err := NewGitea("kustomization/gitops-system/0c9c2e41", srv.URL+"/foo/bar", "", "foobar", certPool)
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()
_, err := NewGitea("kustomization/gitops-system/0c9c2e41", srv.URL+"/foo/bar", "", "foobar", certPool)
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())
proxyAddr, _ := testproxy.New(t)
proxyURL := fmt.Sprintf("http://%s", proxyAddr)
g, err := NewGitea("kustomization/gitops-system/0c9c2e41", srv.URL+"/foo/bar", proxyURL, "foobar", certPool)
assert.NoError(t, err)
assert.Equal(t, g.Owner, "foo")
assert.Equal(t, g.Repo, "bar")
@ -61,44 +131,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

@ -18,74 +18,44 @@ 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, certPool *x509.CertPool,
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, certPool,
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

@ -18,19 +18,14 @@ 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, certPool *x509.CertPool, 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, certPool,
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

@ -46,7 +46,7 @@ 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)
dispatch, err := NewGitHubDispatch(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert, "", "", "", 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

@ -30,14 +30,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 +48,7 @@ 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)
github, err := NewGitHub(commitStatus, fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert, "", "foo", "bar", nil, nil)
if err != nil {
return
}

View File

@ -0,0 +1,132 @@
/*
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"
"crypto/x509"
"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, certPool *x509.CertPool,
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
}
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 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 = 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

@ -24,19 +24,19 @@ import (
"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, certPool *x509.CertPool) (*GitLab, error) {
if len(token) == 0 {
return nil, errors.New("gitlab token cannot be empty")
}
@ -46,6 +46,11 @@ 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 {
tr := &http.Transport{
@ -62,9 +67,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 +82,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 +96,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 +104,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

@ -30,12 +30,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 +46,7 @@ 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)
gitLab, err := NewGitLab(commitStatus, fmt.Sprintf("%s/%s", ts.URL, urlSuffix), token, &cert)
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

@ -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
}

View File

@ -18,7 +18,7 @@ package notifier
import (
"context"
"crypto/x509"
"crypto/tls"
"errors"
"fmt"
"net/url"
@ -28,10 +28,10 @@ import (
)
type Opsgenie struct {
URL string
ProxyURL string
CertPool *x509.CertPool
ApiKey string
URL string
ProxyURL string
TLSConfig *tls.Config
ApiKey string
}
type OpsgenieAlert struct {
@ -40,7 +40,7 @@ type OpsgenieAlert struct {
Details map[string]string `json:"details"`
}
func NewOpsgenie(hookURL string, proxyURL string, certPool *x509.CertPool, token string) (*Opsgenie, error) {
func NewOpsgenie(hookURL string, proxyURL string, tlsConfig *tls.Config, token string) (*Opsgenie, error) {
_, err := url.ParseRequestURI(hookURL)
if err != nil {
return nil, fmt.Errorf("invalid Opsgenie hook URL %s: '%w'", hookURL, err)
@ -51,10 +51,10 @@ func NewOpsgenie(hookURL string, proxyURL string, certPool *x509.CertPool, token
}
return &Opsgenie{
URL: hookURL,
ProxyURL: proxyURL,
CertPool: certPool,
ApiKey: token,
URL: hookURL,
ProxyURL: proxyURL,
ApiKey: token,
TLSConfig: tlsConfig,
}, nil
}
@ -65,18 +65,34 @@ func (s *Opsgenie) Post(ctx context.Context, event eventv1.Event) error {
return nil
}
var details = make(map[string]string)
if event.Metadata != nil {
details = event.Metadata
}
details["severity"] = event.Severity
payload := OpsgenieAlert{
Message: event.InvolvedObject.Kind + "/" + event.InvolvedObject.Name,
Description: event.Message,
Details: event.Metadata,
Details: details,
}
err := postMessage(ctx, s.URL, s.ProxyURL, s.CertPool, payload, func(req *retryablehttp.Request) {
req.Header.Set("Authorization", "GenieKey "+s.ApiKey)
})
opts := []postOption{
withRequestModifier(func(req *retryablehttp.Request) {
req.Header.Set("Authorization", "GenieKey "+s.ApiKey)
}),
}
if s.ProxyURL != "" {
opts = append(opts, withProxy(s.ProxyURL))
}
if s.TLSConfig != nil {
opts = append(opts, withTLSConfig(s.TLSConfig))
}
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"
@ -42,10 +42,10 @@ func Fuzz_OpsGenie(f *testing.F) {
}))
defer ts.Close()
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
var tlsConfig tls.Config
_ = fuzz.NewConsumer(seed).GenerateStruct(&tlsConfig)
opsgenie, err := NewOpsgenie(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", &cert, token)
opsgenie, err := NewOpsgenie(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", &tlsConfig, token)
if err != nil {
return
}

View File

@ -24,6 +24,7 @@ import (
"net/http/httptest"
"testing"
"github.com/fluxcd/pkg/apis/event/v1beta1"
"github.com/stretchr/testify/require"
)
@ -38,9 +39,32 @@ func TestOpsgenie_Post(t *testing.T) {
}))
defer ts.Close()
opsgenie, err := NewOpsgenie(ts.URL, "", nil, "token")
require.NoError(t, err)
tests := []struct {
name string
event func() v1beta1.Event
}{
{
name: "test event",
event: testEvent,
},
{
name: "test event with empty metadata",
event: func() v1beta1.Event {
events := testEvent()
events.Metadata = nil
return events
},
},
}
err = opsgenie.Post(context.TODO(), testEvent())
require.NoError(t, err)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
opsgenie, err := NewOpsgenie(ts.URL, "", nil, "token")
require.NoError(t, err)
err = opsgenie.Post(context.TODO(), tt.event())
require.NoError(t, err)
})
}
}

View File

@ -18,7 +18,7 @@ package notifier
import (
"context"
"crypto/x509"
"crypto/tls"
"fmt"
"net/url"
"time"
@ -33,10 +33,10 @@ type PagerDuty struct {
Endpoint string
RoutingKey string
ProxyURL string
CertPool *x509.CertPool
TLSConfig *tls.Config
}
func NewPagerDuty(endpoint string, proxyURL string, certPool *x509.CertPool, routingKey string) (*PagerDuty, error) {
func NewPagerDuty(endpoint string, proxyURL string, tlsConfig *tls.Config, routingKey string) (*PagerDuty, error) {
URL, err := url.ParseRequestURI(endpoint)
if err != nil {
return nil, fmt.Errorf("invalid PagerDuty endpoint URL %q: '%w'", endpoint, err)
@ -45,7 +45,7 @@ func NewPagerDuty(endpoint string, proxyURL string, certPool *x509.CertPool, rou
Endpoint: URL.Scheme + "://" + URL.Host,
RoutingKey: routingKey,
ProxyURL: proxyURL,
CertPool: certPool,
TLSConfig: tlsConfig,
}, nil
}
@ -54,19 +54,36 @@ func (p *PagerDuty) Post(ctx context.Context, event eventv1.Event) error {
if event.HasMetadata(eventv1.MetaCommitStatusKey, eventv1.MetaCommitStatusUpdateValue) || event.HasReason(meta.ProgressingReason) {
return nil
}
e := toPagerDutyV2Event(event, p.RoutingKey)
err := postMessage(ctx, p.Endpoint+"/v2/enqueue", p.ProxyURL, p.CertPool, e)
if err != nil {
var opts []postOption
if p.ProxyURL != "" {
opts = append(opts, withProxy(p.ProxyURL))
}
if p.TLSConfig != nil {
opts = append(opts, withTLSConfig(p.TLSConfig))
}
if err := postMessage(
ctx,
p.Endpoint+"/v2/enqueue",
toPagerDutyV2Event(event, p.RoutingKey),
opts...,
); err != nil {
return fmt.Errorf("failed sending event: %w", err)
}
// Send a change event for info events
if event.Severity == eventv1.EventSeverityInfo {
ce := toPagerDutyChangeEvent(event, p.RoutingKey)
err = postMessage(ctx, p.Endpoint+"/v2/change/enqueue", p.ProxyURL, p.CertPool, ce)
if err != nil {
if err := postMessage(
ctx,
p.Endpoint+"/v2/change/enqueue",
toPagerDutyChangeEvent(event, p.RoutingKey),
opts...,
); err != nil {
return fmt.Errorf("failed sending change event: %w", err)
}
}
return nil
}

View File

@ -2,7 +2,7 @@ package notifier
import (
"context"
"crypto/x509"
"crypto/tls"
"io"
"net/http"
"net/http/httptest"
@ -32,10 +32,10 @@ func Fuzz_PagerDuty(f *testing.F) {
ts := httptest.NewServer(mux)
defer ts.Close()
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
var tlsConfig tls.Config
_ = fuzz.NewConsumer(seed).GenerateStruct(&tlsConfig)
pd, err := NewPagerDuty(ts.URL, "", &cert, routingKey)
pd, err := NewPagerDuty(ts.URL, "", &tlsConfig, routingKey)
if err != nil {
return
}

View File

@ -18,7 +18,7 @@ package notifier
import (
"context"
"crypto/x509"
"crypto/tls"
"fmt"
"net/url"
"strings"
@ -28,26 +28,26 @@ import (
// Rocket holds the hook URL
type Rocket struct {
URL string
ProxyURL string
Username string
Channel string
CertPool *x509.CertPool
URL string
ProxyURL string
Username string
Channel string
TLSConfig *tls.Config
}
// NewRocket validates the Rocket URL and returns a Rocket object
func NewRocket(hookURL string, proxyURL string, certPool *x509.CertPool, username string, channel string) (*Rocket, error) {
func NewRocket(hookURL string, proxyURL string, tlsConfig *tls.Config, username string, channel string) (*Rocket, error) {
_, err := url.ParseRequestURI(hookURL)
if err != nil {
return nil, fmt.Errorf("invalid Rocket hook URL %s: '%w'", hookURL, err)
}
return &Rocket{
Channel: channel,
URL: hookURL,
ProxyURL: proxyURL,
Username: username,
CertPool: certPool,
Channel: channel,
URL: hookURL,
ProxyURL: proxyURL,
Username: username,
TLSConfig: tlsConfig,
}, nil
}
@ -83,8 +83,15 @@ func (s *Rocket) Post(ctx context.Context, event eventv1.Event) error {
payload.Attachments = []SlackAttachment{a}
err := postMessage(ctx, s.URL, s.ProxyURL, s.CertPool, payload)
if err != nil {
var opts []postOption
if s.ProxyURL != "" {
opts = append(opts, withProxy(s.ProxyURL))
}
if s.TLSConfig != nil {
opts = append(opts, withTLSConfig(s.TLSConfig))
}
if err := postMessage(ctx, s.URL, payload, opts...); err != nil {
return fmt.Errorf("postMessage failed: %w", err)
}
return nil

View File

@ -18,7 +18,6 @@ package notifier
import (
"context"
"crypto/x509"
"fmt"
"io"
"net/http"
@ -42,10 +41,7 @@ func Fuzz_Rocket(f *testing.F) {
}))
defer ts.Close()
var cert x509.CertPool
_ = fuzz.NewConsumer(seed).GenerateStruct(&cert)
rocket, err := NewRocket(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", &cert, username, channel)
rocket, err := NewRocket(fmt.Sprintf("%s/%s", ts.URL, urlSuffix), "", nil, username, channel)
if err != nil {
return
}

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