Repository: rancher/fleet
Pull request #2440 (2024-05-17 14:33:11)

[Forward v0.10]. Support for Azure DevOps Webhook for gitRepos using SSH URL

Forward port of: https://github.com/rancher/gitjob/pull/446
Refers to: https://github.com/rancher/fleet/issues/2352



Patch:
diff --git a/pkg/webhook/webhook.go b/pkg/webhook/webhook.go
index 88e09d64..71d4e57e 100644
--- a/pkg/webhook/webhook.go
+++ b/pkg/webhook/webhook.go
@@ -199,7 +199,9 @@ func (w *Webhook) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
 			w.logAndReturn(rw, err)
 			return
 		}
-		regexpStr := `(?i)(http://|https://|\w+@|ssh://(\w+@)?)` + u.Hostname() + "(:[0-9]+|)[:/]" + u.Path[1:] + "(\\.git)?"
+		path := strings.Replace(u.Path[1:], "/_git/", "(/_git)?/", 1)
+		regexpStr := `(?i)(http://|https://|\w+@|ssh://(\w+@)?|git@(ssh\.)?)` + u.Hostname() +
+			"(:[0-9]+|)[:/](v\\d/)?" + path + "(\\.git)?"
 		repoRegexp, err := regexp.Compile(regexpStr)
 		if err != nil {
 			w.logAndReturn(rw, err)


Test patch:
diff --git a/pkg/webhook/webhook_test.go b/pkg/webhook/webhook_test.go
index 5fe44d2a..1b9bf64b 100644
--- a/pkg/webhook/webhook_test.go
+++ b/pkg/webhook/webhook_test.go
@@ -90,6 +90,52 @@ func TestAzureDevopsWebhook(t *testing.T) {
 	}
 }
 
+func TestAzureDevopsWebhookWithSSHURL(t *testing.T) {
+	const (
+		commit            = "f00c3a181697bb3829a6462e931c7456bbed557b"
+		gitRepoURL        = "git@ssh.dev.azure.com:v3/fleet/git-test/git-test"
+		responseRemoteURL = "https://dev.azure.com/fleet/git-test/_git/git-test"
+	)
+
+	gitRepo := &v1alpha1.GitRepo{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: "test",
+		},
+		Spec: v1alpha1.GitRepoSpec{
+			Repo:   gitRepoURL,
+			Branch: "main",
+		},
+	}
+	scheme := runtime.NewScheme()
+	err := v1alpha1.AddToScheme(scheme)
+	if err != nil {
+		t.Errorf("unexpected error %v", err)
+	}
+	client := cfake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(gitRepo).WithStatusSubresource(gitRepo).Build()
+	w := &Webhook{client: client}
+	w.azureDevops, _ = azuredevops.New()
+	jsonBody := []byte(`{"subscriptionId":"xxx","notificationId":1,"id":"xxx","eventType":"git.push","publisherId":"tfs","message":{"text":"commit pushed","html":"commit pushed"},"detailedMessage":{"text":"pushed a commit to git-test"},"resource":{"commits":[{"commitId":"` + commit + `","author":{"name":"fleet","email":"fleet@suse.com","date":"2024-01-05T10:16:56Z"},"committer":{"name":"fleet","email":"fleet@suse.com","date":"2024-01-05T10:16:56Z"},"comment":"test commit","url":"https://dev.azure.com/fleet/_apis/git/repositories/xxx/commits/f00c3a181697bb3829a6462e931c7456bbed557b"}],"refUpdates":[{"name":"refs/heads/main","oldObjectId":"135f8a827edae980466f72eef385881bb4e158d8","newObjectId":"` + commit + `"}],"repository":{"id":"xxx","name":"git-test","url":"https://dev.azure.com/fleet/_apis/git/repositories/xxx","project":{"id":"xxx","name":"git-test","url":"https://dev.azure.com/fleet/_apis/projects/xxx","state":"wellFormed","visibility":"unchanged","lastUpdateTime":"0001-01-01T00:00:00"},"defaultBranch":"refs/heads/main","remoteUrl":"` + responseRemoteURL + `"},"pushedBy":{"displayName":"Fleet","url":"https://spsprodneu1.vssps.visualstudio.com/xxx/_apis/Identities/xxx","_links":{"avatar":{"href":"https://dev.azure.com/fleet/_apis/GraphProfile/MemberAvatars/msa.xxxx"}},"id":"xxx","uniqueName":"fleet@suse.com","imageUrl":"https://dev.azure.com/fleet/_api/_common/identityImage?id=xxx","descriptor":"xxxx"},"pushId":22,"date":"2024-01-05T10:17:18.735088Z","url":"https://dev.azure.com/fleet/_apis/git/repositories/xxx/pushes/22","_links":{"self":{"href":"https://dev.azure.com/fleet/_apis/git/repositories/xxx/pushes/22"},"repository":{"href":"https://dev.azure.com/fleet/xxx/_apis/git/repositories/xxx"},"commits":{"href":"https://dev.azure.com/fleet/_apis/git/repositories/xxx/pushes/22/commits"},"pusher":{"href":"https://spsprodneu1.vssps.visualstudio.com/xxx/_apis/Identities/xxx"},"refs":{"href":"https://dev.azure.com/fleet/xxx/_apis/git/repositories/xxx/refs/heads/main"}}},"resourceVersion":"1.0","resourceContainers":{"collection":{"id":"xxx","baseUrl":"https://dev.azure.com/fleet/"},"account":{"id":"ec365173-fce3-4dfc-8fc2-950f0b5728b1","baseUrl":"https://dev.azure.com/fleet/"},"project":{"id":"xxx","baseUrl":"https://dev.azure.com/fleet/"}},"createdDate":"2024-01-05T10:17:26.0098694Z"}`)
+	bodyReader := bytes.NewReader(jsonBody)
+	req, err := http.NewRequest(http.MethodPost, responseRemoteURL, bodyReader)
+	if err != nil {
+		t.Errorf("unexpected err %v", err)
+	}
+	h := http.Header{}
+	h.Add("X-Vss-Activityid", "xxx")
+	req.Header = h
+
+	w.ServeHTTP(&responseWriter{}, req)
+
+	updatedGitRepo := &v1alpha1.GitRepo{}
+	err = client.Get(context.TODO(), types.NamespacedName{Name: gitRepo.Name, Namespace: gitRepo.Namespace}, updatedGitRepo)
+	if err != nil {
+		t.Errorf("unexpected err %v", err)
+	}
+	if updatedGitRepo.Status.Commit != commit {
+		t.Errorf("expected commit %v, but got %v", commit, updatedGitRepo.Status.Commit)
+	}
+}
+
 type responseWriter struct{}
 
 func (r *responseWriter) Header() http.Header {