diff --git a/api/v1beta1/provider_types.go b/api/v1beta1/provider_types.go index c3fc15635..609c00c91 100644 --- a/api/v1beta1/provider_types.go +++ b/api/v1beta1/provider_types.go @@ -32,6 +32,14 @@ type ProviderSpec struct { // +required Type string `json:"type"` + // A string to prepend to the identifier of a commit status. + // Example use-case: a single object (kustomization/k8s-gitops) + // is deployed to multiple clusters. Specifying this (e.g., to + // the name of the cluster) ensures that the notification controllers + // on each cluster don't overwrite each others' commit statuses. + // +optional + CommitStatusPrefix string `json:"commitStatusPrefix,omitempty"` + // Alert channel for this provider // +optional Channel string `json:"channel,omitempty"` diff --git a/config/crd/bases/notification.toolkit.fluxcd.io_providers.yaml b/config/crd/bases/notification.toolkit.fluxcd.io_providers.yaml index e756564ce..aae305497 100644 --- a/config/crd/bases/notification.toolkit.fluxcd.io_providers.yaml +++ b/config/crd/bases/notification.toolkit.fluxcd.io_providers.yaml @@ -63,6 +63,13 @@ spec: channel: description: Alert channel for this provider type: string + commitStatusPrefix: + description: 'A string to prepend to the identifier of a commit status. + Example use-case: a single object (kustomization/k8s-gitops) is + deployed to multiple clusters. Specifying this (e.g., to the name + of the cluster) ensures that the notification controllers on each + cluster don''t overwrite each others'' commit statuses.' + type: string proxy: description: HTTP/S address of the proxy pattern: ^(http|https):// diff --git a/docs/api/notification.md b/docs/api/notification.md index 8260850ba..bdbb4ab52 100644 --- a/docs/api/notification.md +++ b/docs/api/notification.md @@ -237,6 +237,22 @@ string +commitStatusPrefix
+ +string + + + +(Optional) +

A string to prepend to the identifier of a commit status. +Example use-case: a single object (kustomization/k8s-gitops) +is deployed to multiple clusters. Specifying this (e.g., to +the name of the cluster) ensures that the notification controllers +on each cluster don’t overwrite each others’ commit statuses.

+ + + + channel
string @@ -742,6 +758,22 @@ string +commitStatusPrefix
+ +string + + + +(Optional) +

A string to prepend to the identifier of a commit status. +Example use-case: a single object (kustomization/k8s-gitops) +is deployed to multiple clusters. Specifying this (e.g., to +the name of the cluster) ensures that the notification controllers +on each cluster don’t overwrite each others’ commit statuses.

+ + + + channel
string diff --git a/internal/notifier/util.go b/internal/notifier/util.go index 631467f94..922304bfe 100644 --- a/internal/notifier/util.go +++ b/internal/notifier/util.go @@ -46,7 +46,16 @@ func parseGitAddress(s string) (string, string, error) { } func formatNameAndDescription(event events.Event) (string, string) { - name := fmt.Sprintf("%v/%v", event.InvolvedObject.Kind, event.InvolvedObject.Name) + kind, name := event.InvolvedObject.Kind, event.InvolvedObject.Name + commitStatusPrefix, ok := event.Metadata["commitStatusPrefix"] + if ok && commitStatusPrefix != "" { + // This adds additional information to the identifier of a commit status so that, + // for example, notification controllers deployed on multiple clusters hosting + // the same resource kind/name don't overwrite each others' commit statuses. + name = fmt.Sprintf("%v/%v/%v", commitStatusPrefix, kind, name) + } else { + name = fmt.Sprintf("%v/%v", kind, name) + } name = strings.ToLower(name) desc := strings.Join(splitCamelcase(event.Reason), " ") desc = strings.ToLower(desc) diff --git a/internal/notifier/util_test.go b/internal/notifier/util_test.go index 397d0f8a6..6eb4d75ed 100644 --- a/internal/notifier/util_test.go +++ b/internal/notifier/util_test.go @@ -25,16 +25,33 @@ import ( ) func TestUtil_NameAndDescription(t *testing.T) { - event := events.Event{ + var event events.Event + var name, desc string + + event = events.Event{ InvolvedObject: v1.ObjectReference{ Kind: "Kustomization", Name: "gitops-system", }, Reason: "ApplySucceeded", } - name, desc := formatNameAndDescription(event) + name, desc = formatNameAndDescription(event) require.Equal(t, "kustomization/gitops-system", name) require.Equal(t, "apply succeeded", desc) + + event = events.Event{ + InvolvedObject: v1.ObjectReference{ + Kind: "Kustomization", + Name: "gitops-system", + }, + Reason: "ApplySucceeded", + Metadata: map[string]string{ + "commitStatusPrefix": "im-a-cluster", + }, + } + name, desc = formatNameAndDescription(event) + require.Equal(t, "im-a-cluster/kustomization/gitops-system", name) + require.Equal(t, "apply succeeded", desc) } func TestUtil_ParseRevision(t *testing.T) { diff --git a/internal/server/event_handlers.go b/internal/server/event_handlers.go index 7c2d326e3..c698e047b 100644 --- a/internal/server/event_handlers.go +++ b/internal/server/event_handlers.go @@ -259,6 +259,16 @@ func (s *EventServer) handleEvent() func(w http.ResponseWriter, r *http.Request) } } + if provider.Spec.CommitStatusPrefix != "" { + if notification.Metadata == nil { + notification.Metadata = map[string]string{ + "commitStatusPrefix": provider.Spec.CommitStatusPrefix, + } + } else { + notification.Metadata["commitStatusPrefix"] = provider.Spec.CommitStatusPrefix + } + } + go func(n notifier.Interface, e events.Event) { if err := n.Post(e); err != nil { err = redactTokenFromError(err, token)