diff --git a/go.mod b/go.mod index dec38ff71..234e2a299 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/containrrr/shoutrrr v0.8.0 github.com/fluxcd/cli-utils v0.36.0-flux.11 github.com/fluxcd/notification-controller/api v1.4.0 - github.com/fluxcd/pkg/apis/event v0.13.0 + github.com/fluxcd/pkg/apis/event v0.15.0 github.com/fluxcd/pkg/apis/meta v1.9.0 github.com/fluxcd/pkg/git v0.23.0 github.com/fluxcd/pkg/masktoken v0.6.0 diff --git a/go.sum b/go.sum index c36dcb037..eabc747d3 100644 --- a/go.sum +++ b/go.sum @@ -142,8 +142,8 @@ github.com/fluxcd/cli-utils v0.36.0-flux.11 h1:W0y2uvCVkcE8bgV9jgoGSjzWbLFiNq1Aj github.com/fluxcd/cli-utils v0.36.0-flux.11/go.mod h1:WZ7xUpZbK+O6HBxA5UWqzWTLSSltdmj4wS1LstS5Dqs= github.com/fluxcd/pkg/apis/acl v0.5.0 h1:+ykKezgerKUlZwSYFUy03lPMOIAyWlqvMNNLIWWqOhk= github.com/fluxcd/pkg/apis/acl v0.5.0/go.mod h1:IVDZx3MAoDWjlLrJHMF9Z27huFuXAEQlnbWw0M6EcTs= -github.com/fluxcd/pkg/apis/event v0.13.0 h1:m5qHAhYIC0+mRFy5OC8FZxBVBGJM3qxJ/sEg2Vgx4T8= -github.com/fluxcd/pkg/apis/event v0.13.0/go.mod h1:aRK2AONnjjSNW61B6Iy3SW4YHozACntnJeGm3fFqDqA= +github.com/fluxcd/pkg/apis/event v0.15.0 h1:k1suqIfVxnhEeKlGkvlHAbOYXjY8wRixT/OZcIuakqA= +github.com/fluxcd/pkg/apis/event v0.15.0/go.mod h1:aRK2AONnjjSNW61B6Iy3SW4YHozACntnJeGm3fFqDqA= github.com/fluxcd/pkg/apis/meta v1.9.0 h1:wPgm7bWNJZ/ImS5GqikOxt362IgLPFBG73dZ27uWRiQ= github.com/fluxcd/pkg/apis/meta v1.9.0/go.mod h1:pMea8eEZcsFSI7ngRnTHFtDZk2CEZGgtrueNgI6Iu70= github.com/fluxcd/pkg/auth v0.2.0 h1:Df3pHGMDJjpr8AcGKgPvudXF3Lb3SuBlkAmhrkp7U1k= diff --git a/internal/notifier/azure_devops.go b/internal/notifier/azure_devops.go index d28e21617..ea7e0b80f 100644 --- a/internal/notifier/azure_devops.go +++ b/internal/notifier/azure_devops.go @@ -91,7 +91,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") } diff --git a/internal/notifier/azure_devops_test.go b/internal/notifier/azure_devops_test.go index 8a9a51435..6a15a9c38 100644 --- a/internal/notifier/azure_devops_test.go +++ b/internal/notifier/azure_devops_test.go @@ -100,6 +100,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{ diff --git a/internal/notifier/bitbucket.go b/internal/notifier/bitbucket.go index 393c7fca2..52ad1bb9e 100644 --- a/internal/notifier/bitbucket.go +++ b/internal/notifier/bitbucket.go @@ -91,7 +91,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") } diff --git a/internal/notifier/bitbucketserver.go b/internal/notifier/bitbucketserver.go index 98c299feb..532838eb8 100644 --- a/internal/notifier/bitbucketserver.go +++ b/internal/notifier/bitbucketserver.go @@ -123,7 +123,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") } diff --git a/internal/notifier/bitbucketserver_test.go b/internal/notifier/bitbucketserver_test.go index 5ce707d9c..98a2b7d35 100644 --- a/internal/notifier/bitbucketserver_test.go +++ b/internal/notifier/bitbucketserver_test.go @@ -20,6 +20,7 @@ import ( "context" "encoding/base64" "encoding/json" + "fmt" "io" "testing" @@ -183,6 +184,7 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) { event eventv1.Event provideruid string key string + uriHash string }{ { name: "Validate Token Auth ", @@ -199,6 +201,25 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) { key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("info", map[string]string{ eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }))), + uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738", + }, + { + name: "Event with origin revision", + token: "goodtoken", + provideruid: "0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", + 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(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("info", map[string]string{ + eventv1.MetaRevisionKey: "main@sha1:e7c17dd8b8384bbc84b7e7385394cb7f48332b2d", + }))), + uriHash: "e7c17dd8b8384bbc84b7e7385394cb7f48332b2d", }, { name: "Validate Basic Auth and Post State=Successful", @@ -216,6 +237,7 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) { key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("info", map[string]string{ eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }))), + uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }, { name: "Validate Post State=Failed", @@ -233,6 +255,7 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) { key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("error", map[string]string{ eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }))), + uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }, { name: "Fail if bad json response in existing commit status", @@ -252,6 +275,7 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) { key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("error", map[string]string{ eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }))), + uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }, { name: "Fail if status code is non-200 in existing commit status", @@ -271,6 +295,7 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) { key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("error", map[string]string{ eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }))), + uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }, { name: "Bad post- Unauthorized", @@ -290,6 +315,7 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) { key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("error", map[string]string{ eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }))), + uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }, { name: "Validate duplicate commit status successful match", @@ -307,6 +333,7 @@ func TestBitBucketServerPostValidateRequest(t *testing.T) { key: sha1String(generateCommitStatusID("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", generateTestEventKustomization("info", map[string]string{ eventv1.MetaRevisionKey: "main@sha1:5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }))), + uriHash: "5394cb7f48332b2de7c17dd8b8384bbc84b7e738", }, } @@ -320,7 +347,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 { diff --git a/internal/notifier/gitea.go b/internal/notifier/gitea.go index 69a605930..b73b988c3 100644 --- a/internal/notifier/gitea.go +++ b/internal/notifier/gitea.go @@ -90,7 +90,7 @@ func NewGitea(providerUID string, addr string, token string, certPool *x509.Cert } 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") } diff --git a/internal/notifier/gitea_test.go b/internal/notifier/gitea_test.go index 0279d7477..685a88644 100644 --- a/internal/notifier/gitea_test.go +++ b/internal/notifier/gitea_test.go @@ -42,6 +42,10 @@ 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) } @@ -83,22 +87,53 @@ func TestGitea_Post(t *testing.T) { g, err := NewGitea("0c9c2e41-d2f9-4f9b-9c41-bebc1984d67a", 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) } diff --git a/internal/notifier/github.go b/internal/notifier/github.go index 132cee061..56660ac1e 100644 --- a/internal/notifier/github.go +++ b/internal/notifier/github.go @@ -96,7 +96,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") } diff --git a/internal/notifier/gitlab.go b/internal/notifier/gitlab.go index 08a6c8597..25e9a9534 100644 --- a/internal/notifier/gitlab.go +++ b/internal/notifier/gitlab.go @@ -24,7 +24,7 @@ import ( "fmt" "net/http" - "gitlab.com/gitlab-org/api/client-go" + gitlab "gitlab.com/gitlab-org/api/client-go" eventv1 "github.com/fluxcd/pkg/apis/event/v1beta1" "github.com/fluxcd/pkg/apis/meta" @@ -77,7 +77,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") } diff --git a/internal/server/event_server.go b/internal/server/event_server.go index 0f78cce93..f7fe1b1da 100644 --- a/internal/server/event_server.go +++ b/internal/server/event_server.go @@ -233,9 +233,11 @@ func eventKeyFunc(r *http.Request) (string, error) { objectGroup := event.InvolvedObject.GetObjectKind().GroupVersionKind().Group + originRevisionKey := fmt.Sprintf("%s/%s", objectGroup, eventv1.MetaOriginRevisionKey) revisionKey := fmt.Sprintf("%s/%s", objectGroup, eventv1.MetaRevisionKey) - revision, ok := event.Metadata[revisionKey] - if ok { + if originRevision, ok := event.Metadata[originRevisionKey]; ok { + comps = append(comps, "revision="+originRevision) + } else if revision, ok := event.Metadata[revisionKey]; ok { comps = append(comps, "revision="+revision) } diff --git a/internal/server/event_server_test.go b/internal/server/event_server_test.go index ac1e327cc..cf3e50081 100644 --- a/internal/server/event_server_test.go +++ b/internal/server/event_server_test.go @@ -460,6 +460,51 @@ func TestEventKeyFunc(t *testing.T) { }, rateLimit: false, }, + { + involvedObject: corev1.ObjectReference{ + APIVersion: "kustomize.toolkit.fluxcd.io/v1", + Kind: "Kustomization", + Name: "4", + Namespace: "4", + }, + severity: eventv1.EventSeverityInfo, + message: "Health check passed", + metadata: map[string]string{ + fmt.Sprintf("%s/%s", "kustomize.toolkit.fluxcd.io", eventv1.MetaRevisionKey): "revA", + fmt.Sprintf("%s/%s", "kustomize.toolkit.fluxcd.io", eventv1.MetaOriginRevisionKey): "orev1", + }, + rateLimit: false, + }, + { + involvedObject: corev1.ObjectReference{ + APIVersion: "kustomize.toolkit.fluxcd.io/v1", + Kind: "Kustomization", + Name: "4", + Namespace: "4", + }, + severity: eventv1.EventSeverityInfo, + message: "Health check passed", + metadata: map[string]string{ + fmt.Sprintf("%s/%s", "kustomize.toolkit.fluxcd.io", eventv1.MetaRevisionKey): "revB", + fmt.Sprintf("%s/%s", "kustomize.toolkit.fluxcd.io", eventv1.MetaOriginRevisionKey): "orev1", + }, + rateLimit: true, + }, + { + involvedObject: corev1.ObjectReference{ + APIVersion: "kustomize.toolkit.fluxcd.io/v1", + Kind: "Kustomization", + Name: "4", + Namespace: "4", + }, + severity: eventv1.EventSeverityInfo, + message: "Health check passed", + metadata: map[string]string{ + fmt.Sprintf("%s/%s", "kustomize.toolkit.fluxcd.io", eventv1.MetaRevisionKey): "revB", + fmt.Sprintf("%s/%s", "kustomize.toolkit.fluxcd.io", eventv1.MetaOriginRevisionKey): "orev2", + }, + rateLimit: false, + }, { involvedObject: corev1.ObjectReference{ APIVersion: "kustomize.toolkit.fluxcd.io/v1",