Repository: argoproj/argo-cd
Pull request #6034 (2021-04-14 16:45:37)

fix: Bitbucket server webhook fails on diagnostics:ping (#6029)
Signed-off-by: Marcel Hoyer <m.hoyer@cid.com>

Checklist:

* [x] Either ~(a) I've created an [enhancement proposal](https://github.com/argoproj/argo-cd/issues/new/choose) and discussed it with the community~, (b) this is a bug fix, ~or (c) this does not need to be in the release notes~.
* [x] The title of the PR states what changed and the related issues number (used for the release note).
* [x] I've included "Closes [ISSUE #]" or "Fixes [ISSUE #]" in the description to automatically close the associated issue.
* [ ] ~I've updated both the CLI and UI to expose my feature, or I plan to submit a second PR with them.~
* [ ] ~Does this PR require documentation updates?~
* [ ] ~I've updated documentation as required by this PR.~
* [ ] ~Optional. My organization is added to USERS.md.~
* [x] I have signed off all my commits as required by [DCO](https://github.com/argoproj/argoproj/tree/master/community#contributing-to-argo)
* [x] I have written unit and/or e2e tests for my change. PRs without these are unlikely to be merged.
* [x] My build is green ([troubleshooting builds](https://argo-cd.readthedocs.io/en/latest/developer-guide/ci/)). 

Fixes [#6029]

codecov[bot]: # [Codecov](https://codecov.io/gh/argoproj/argo-cd/pull/6034?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj) Report
> Merging [#6034](https://codecov.io/gh/argoproj/argo-cd/pull/6034?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj) (488e2b2) into [master](https://codecov.io/gh/argoproj/argo-cd/commit/8fd6f13855b26062b2a70709c1fd265a748ce167?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj) (8fd6f13) will **increase** coverage by `0.01%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/argoproj/argo-cd/pull/6034/graphs/tree.svg?width=650&height=150&src=pr&token=kf5kwuegwE&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj)](https://codecov.io/gh/argoproj/argo-cd/pull/6034?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj)

```diff
@@            Coverage Diff             @@
##           master    #6034      +/-   ##
==========================================
+ Coverage   40.93%   40.95%   +0.01%     
==========================================
  Files         147      147              
  Lines       19661    19661              
==========================================
+ Hits         8049     8052       +3     
+ Misses      10508    10506       -2     
+ Partials     1104     1103       -1     
```


| [Impacted Files](https://codecov.io/gh/argoproj/argo-cd/pull/6034?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj) | Coverage Δ | |
|---|---|---|
| [util/webhook/webhook.go](https://codecov.io/gh/argoproj/argo-cd/pull/6034/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj#diff-dXRpbC93ZWJob29rL3dlYmhvb2suZ28=) | `66.09% <100.00%> (+1.72%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/argoproj/argo-cd/pull/6034?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/argoproj/argo-cd/pull/6034?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj). Last update [8fd6f13...488e2b2](https://codecov.io/gh/argoproj/argo-cd/pull/6034?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=argoproj).


Patch:
diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go
index 11bc40539..6caec6f81 100644
--- a/reposerver/repository/repository.go
+++ b/reposerver/repository/repository.go
@@ -459,6 +459,48 @@ func getHelmRepos(repositories []*v1alpha1.Repository) []helm.HelmRepository {
 	return repos
 }
 
+type dependencies struct {
+	Dependencies []repositories `yaml:"dependencies"`
+}
+
+type repositories struct {
+	Repository string `yaml:"repository"`
+}
+
+func getHelmDependencyRepos(appPath string) ([]*v1alpha1.Repository, error) {
+	repos := make([]*v1alpha1.Repository, 0)
+	f, err := ioutil.ReadFile(fmt.Sprintf("%s/%s", appPath, "Chart.yaml"))
+	if err != nil {
+		return nil, err
+	}
+
+	d := &dependencies{}
+	if err = yaml.Unmarshal(f, d); err != nil {
+		return nil, err
+	}
+
+	for _, r := range d.Dependencies {
+		if u, err := url.Parse(r.Repository); err == nil && u.Scheme == "https" {
+			repo := &v1alpha1.Repository{
+				Repo: r.Repository,
+				Name: u.Host,
+			}
+			repos = append(repos, repo)
+		}
+	}
+
+	return repos, nil
+}
+
+func repoExists(repo string, repos []*v1alpha1.Repository) bool {
+	for _, r := range repos {
+		if repo == r.Repo {
+			return true
+		}
+	}
+	return false
+}
+
 func isConcurrencyAllowed(appPath string) bool {
 	if _, err := os.Stat(path.Join(appPath, allowConcurrencyFile)); err == nil {
 		return true
@@ -586,11 +628,23 @@ func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclie
 	for i, j := range templateOpts.SetFile {
 		templateOpts.SetFile[i] = env.Envsubst(j)
 	}
-	h, err := helm.NewHelmApp(appPath, getHelmRepos(q.Repos), isLocal, version)
 
+	repos, err := getHelmDependencyRepos(appPath)
+	if err != nil {
+		return nil, err
+	}
+
+	for _, r := range repos {
+		if !repoExists(r.Repo, q.Repos) {
+			q.Repos = append(q.Repos, r)
+		}
+	}
+
+	h, err := helm.NewHelmApp(appPath, getHelmRepos(q.Repos), isLocal, version)
 	if err != nil {
 		return nil, err
 	}
+
 	defer h.Dispose()
 	err = h.Init()
 	if err != nil {
diff --git a/util/webhook/webhook.go b/util/webhook/webhook.go
index cd2019cc8..c8269f0e0 100644
--- a/util/webhook/webhook.go
+++ b/util/webhook/webhook.go
@@ -341,7 +341,7 @@ func (a *ArgoCDWebhookHandler) Handler(w http.ResponseWriter, r *http.Request) {
 	case r.Header.Get("X-Hook-UUID") != "":
 		payload, err = a.bitbucket.Parse(r, bitbucket.RepoPushEvent)
 	case r.Header.Get("X-Event-Key") != "":
-		payload, err = a.bitbucketserver.Parse(r, bitbucketserver.RepositoryReferenceChangedEvent)
+		payload, err = a.bitbucketserver.Parse(r, bitbucketserver.RepositoryReferenceChangedEvent, bitbucketserver.DiagnosticsPingEvent)
 	default:
 		log.Debug("Ignoring unknown webhook event")
 		http.Error(w, "Unknown webhook event", http.StatusBadRequest)


Test patch:
diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go
index bf2a366c0..5302c3bd8 100644
--- a/reposerver/repository/repository_test.go
+++ b/reposerver/repository/repository_test.go
@@ -1480,3 +1480,14 @@ func TestTestRepoOCI(t *testing.T) {
 	assert.Error(t, err)
 	assert.Equal(t, "OCI Helm repository URL should include hostname and port only", err.Error())
 }
+
+func Test_getHelmDependencyRepos(t *testing.T) {
+	repo1 := "https://charts.bitnami.com/bitnami"
+	repo2 := "https://eventstore.github.io/EventStore.Charts"
+
+	repos, err := getHelmDependencyRepos("../../util/helm/testdata/dependency")
+	assert.NoError(t, err)
+	assert.Equal(t, len(repos), 2)
+	assert.Equal(t, repos[0].Repo, repo1)
+	assert.Equal(t, repos[1].Repo, repo2)
+}
diff --git a/util/webhook/webhook_test.go b/util/webhook/webhook_test.go
index 54b8f01a6..a16392b22 100644
--- a/util/webhook/webhook_test.go
+++ b/util/webhook/webhook_test.go
@@ -85,6 +85,20 @@ func TestBitbucketServerRepositoryReferenceChangedEvent(t *testing.T) {
 	hook.Reset()
 }
 
+func TestBitbucketServerRepositoryDiagnosticPingEvent(t *testing.T) {
+	hook := test.NewGlobal()
+	h := NewMockHandler()
+	eventJSON := "{\"test\": true}"
+	req := httptest.NewRequest("POST", "/api/webhook", bytes.NewBufferString(eventJSON))
+	req.Header.Set("X-Event-Key", "diagnostics:ping")
+	w := httptest.NewRecorder()
+	h.Handler(w, req)
+	assert.Equal(t, w.Code, http.StatusOK)
+	expectedLogResult := "Ignoring webhook event"
+	assert.Equal(t, expectedLogResult, hook.LastEntry().Message)
+	hook.Reset()
+}
+
 func TestGogsPushEvent(t *testing.T) {
 	hook := test.NewGlobal()
 	h := NewMockHandler()