github.com/argoproj/argo-cd/v3@v3.2.1/applicationset/webhook/webhook_test.go (about) 1 package webhook 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "net/http" 8 "net/http/httptest" 9 "os" 10 "path/filepath" 11 "testing" 12 "time" 13 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/mock" 16 "github.com/stretchr/testify/require" 17 corev1 "k8s.io/api/core/v1" 18 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 19 "k8s.io/apimachinery/pkg/runtime" 20 kubefake "k8s.io/client-go/kubernetes/fake" 21 "sigs.k8s.io/controller-runtime/pkg/client" 22 "sigs.k8s.io/controller-runtime/pkg/client/fake" 23 24 apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 25 26 "github.com/argoproj/argo-cd/v3/applicationset/generators" 27 "github.com/argoproj/argo-cd/v3/applicationset/services/scm_provider" 28 "github.com/argoproj/argo-cd/v3/common" 29 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" 30 argosettings "github.com/argoproj/argo-cd/v3/util/settings" 31 ) 32 33 type generatorMock struct { 34 mock.Mock 35 } 36 37 func (g *generatorMock) GetTemplate(_ *v1alpha1.ApplicationSetGenerator) *v1alpha1.ApplicationSetTemplate { 38 return &v1alpha1.ApplicationSetTemplate{} 39 } 40 41 func (g *generatorMock) GenerateParams(_ *v1alpha1.ApplicationSetGenerator, _ *v1alpha1.ApplicationSet, _ client.Client) ([]map[string]any, error) { 42 return []map[string]any{}, nil 43 } 44 45 func (g *generatorMock) GetRequeueAfter(_ *v1alpha1.ApplicationSetGenerator) time.Duration { 46 d, _ := time.ParseDuration("10s") 47 return d 48 } 49 50 func TestWebhookHandler(t *testing.T) { 51 tt := []struct { 52 desc string 53 headerKey string 54 headerValue string 55 effectedAppSets []string 56 payloadFile string 57 expectedStatusCode int 58 expectedRefresh bool 59 }{ 60 { 61 desc: "WebHook from a GitHub repository via Commit", 62 headerKey: "X-GitHub-Event", 63 headerValue: "push", 64 payloadFile: "github-commit-event.json", 65 effectedAppSets: []string{"git-github", "git-github-ssh", "git-github-alt-ssh", "matrix-git-github", "merge-git-github", "matrix-scm-git-github", "matrix-nested-git-github", "merge-nested-git-github", "plugin", "matrix-pull-request-github-plugin"}, 66 expectedStatusCode: http.StatusOK, 67 expectedRefresh: true, 68 }, 69 { 70 desc: "WebHook from a GitHub repository via Commit shorthand", 71 headerKey: "X-GitHub-Event", 72 headerValue: "push", 73 payloadFile: "github-commit-event-feature-branch.json", 74 effectedAppSets: []string{"github-shorthand", "matrix-pull-request-github-plugin", "plugin"}, 75 expectedStatusCode: http.StatusOK, 76 expectedRefresh: true, 77 }, 78 { 79 desc: "WebHook from a GitHub repository via Commit to branch", 80 headerKey: "X-GitHub-Event", 81 headerValue: "push", 82 payloadFile: "github-commit-branch-event.json", 83 effectedAppSets: []string{"git-github", "git-github-ssh", "git-github-alt-ssh", "plugin", "matrix-pull-request-github-plugin"}, 84 expectedStatusCode: http.StatusOK, 85 expectedRefresh: true, 86 }, 87 { 88 desc: "WebHook from a GitHub ping event", 89 headerKey: "X-GitHub-Event", 90 headerValue: "ping", 91 payloadFile: "github-ping-event.json", 92 effectedAppSets: []string{"git-github", "git-github-ssh", "git-github-alt-ssh", "plugin"}, 93 expectedStatusCode: http.StatusOK, 94 expectedRefresh: false, 95 }, 96 { 97 desc: "WebHook from a GitLab repository via Commit", 98 headerKey: "X-Gitlab-Event", 99 headerValue: "Push Hook", 100 payloadFile: "gitlab-event.json", 101 effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin", "matrix-pull-request-github-plugin"}, 102 expectedStatusCode: http.StatusOK, 103 expectedRefresh: true, 104 }, 105 { 106 desc: "WebHook from a System Hook via Commit", 107 headerKey: "X-Gitlab-Event", 108 headerValue: "System Hook", 109 payloadFile: "gitlab-event.json", 110 effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin", "matrix-pull-request-github-plugin"}, 111 expectedStatusCode: http.StatusOK, 112 expectedRefresh: true, 113 }, 114 { 115 desc: "WebHook with an unknown event", 116 headerKey: "X-Random-Event", 117 headerValue: "Push Hook", 118 payloadFile: "gitlab-event.json", 119 effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin"}, 120 expectedStatusCode: http.StatusBadRequest, 121 expectedRefresh: false, 122 }, 123 { 124 desc: "WebHook with an invalid event", 125 headerKey: "X-Random-Event", 126 headerValue: "Push Hook", 127 payloadFile: "invalid-event.json", 128 effectedAppSets: []string{"git-gitlab", "git-gitlab-ssh", "git-gitlab-alt-ssh", "plugin"}, 129 expectedStatusCode: http.StatusBadRequest, 130 expectedRefresh: false, 131 }, 132 { 133 desc: "WebHook from a GitHub repository via pull_request opened event", 134 headerKey: "X-GitHub-Event", 135 headerValue: "pull_request", 136 payloadFile: "github-pull-request-opened-event.json", 137 effectedAppSets: []string{"pull-request-github", "matrix-pull-request-github", "matrix-scm-pull-request-github", "merge-pull-request-github", "plugin", "matrix-pull-request-github-plugin"}, 138 expectedStatusCode: http.StatusOK, 139 expectedRefresh: true, 140 }, 141 { 142 desc: "WebHook from a GitHub repository via pull_request assigned event", 143 headerKey: "X-GitHub-Event", 144 headerValue: "pull_request", 145 payloadFile: "github-pull-request-assigned-event.json", 146 effectedAppSets: []string{"pull-request-github", "matrix-pull-request-github", "matrix-scm-pull-request-github", "merge-pull-request-github", "plugin", "matrix-pull-request-github-plugin"}, 147 expectedStatusCode: http.StatusOK, 148 expectedRefresh: false, 149 }, 150 { 151 desc: "WebHook from a GitHub repository via pull_request labeled event", 152 headerKey: "X-GitHub-Event", 153 headerValue: "pull_request", 154 payloadFile: "github-pull-request-labeled-event.json", 155 effectedAppSets: []string{"pull-request-github", "matrix-pull-request-github", "matrix-scm-pull-request-github", "merge-pull-request-github", "plugin", "matrix-pull-request-github-plugin"}, 156 expectedStatusCode: http.StatusOK, 157 expectedRefresh: true, 158 }, 159 { 160 desc: "WebHook from a GitLab repository via open merge request event", 161 headerKey: "X-Gitlab-Event", 162 headerValue: "Merge Request Hook", 163 payloadFile: "gitlab-merge-request-open-event.json", 164 effectedAppSets: []string{"pull-request-gitlab", "plugin", "matrix-pull-request-github-plugin"}, 165 expectedStatusCode: http.StatusOK, 166 expectedRefresh: true, 167 }, 168 { 169 desc: "WebHook from a GitLab repository via approval merge request event", 170 headerKey: "X-Gitlab-Event", 171 headerValue: "Merge Request Hook", 172 payloadFile: "gitlab-merge-request-approval-event.json", 173 effectedAppSets: []string{"pull-request-gitlab", "plugin"}, 174 expectedStatusCode: http.StatusOK, 175 expectedRefresh: false, 176 }, 177 { 178 desc: "WebHook from a Azure DevOps repository via Commit", 179 headerKey: "X-Vss-Activityid", 180 headerValue: "Push Hook", 181 payloadFile: "azuredevops-push.json", 182 effectedAppSets: []string{"git-azure-devops", "plugin", "matrix-pull-request-github-plugin"}, 183 expectedStatusCode: http.StatusOK, 184 expectedRefresh: true, 185 }, 186 { 187 desc: "WebHook from a Azure DevOps repository via pull request event", 188 headerKey: "X-Vss-Activityid", 189 headerValue: "Pull Request Hook", 190 payloadFile: "azuredevops-pull-request.json", 191 effectedAppSets: []string{"pull-request-azure-devops", "plugin", "matrix-pull-request-github-plugin"}, 192 expectedStatusCode: http.StatusOK, 193 expectedRefresh: true, 194 }, 195 } 196 197 namespace := "test" 198 webhookParallelism := 10 199 fakeClient := newFakeClient(namespace) 200 scheme := runtime.NewScheme() 201 err := v1alpha1.AddToScheme(scheme) 202 require.NoError(t, err) 203 err = v1alpha1.AddToScheme(scheme) 204 require.NoError(t, err) 205 206 for _, test := range tt { 207 t.Run(test.desc, func(t *testing.T) { 208 fc := fake.NewClientBuilder().WithScheme(scheme).WithObjects( 209 fakeAppWithGitGenerator("git-github", namespace, "https://github.com/org/repo"), 210 fakeAppWithGitGenerator("git-github-copy", namespace, "https://github.com/org/repo-copy"), 211 fakeAppWithGitGenerator("git-github-ssh", namespace, "ssh://git@github.com/org/repo"), 212 fakeAppWithGitGenerator("git-github-alt-ssh", namespace, "ssh://git@ssh.github.com:443/org/repo"), 213 fakeAppWithGitGenerator("git-gitlab", namespace, "https://gitlab.com/group/name"), 214 fakeAppWithGitGenerator("git-gitlab-ssh", namespace, "ssh://git@gitlab.com/group/name"), 215 fakeAppWithGitGenerator("git-gitlab-alt-ssh", namespace, "ssh://git@altssh.gitlab.com:443/group/name"), 216 fakeAppWithGitGenerator("git-azure-devops", namespace, "https://dev.azure.com/fabrikam-fiber-inc/DefaultCollection/_git/Fabrikam-Fiber-Git"), 217 fakeAppWithGitGeneratorWithRevision("github-shorthand", namespace, "https://github.com/org/repo", "env/dev"), 218 fakeAppWithGithubPullRequestGenerator("pull-request-github", namespace, "CodErTOcat", "Hello-World"), 219 fakeAppWithGitlabPullRequestGenerator("pull-request-gitlab", namespace, "100500"), 220 fakeAppWithAzureDevOpsPullRequestGenerator("pull-request-azure-devops", namespace, "DefaultCollection", "Fabrikam"), 221 fakeAppWithPluginGenerator("plugin", namespace), 222 fakeAppWithMatrixAndGitGenerator("matrix-git-github", namespace, "https://github.com/org/repo"), 223 fakeAppWithMatrixAndPullRequestGenerator("matrix-pull-request-github", namespace, "Codertocat", "Hello-World"), 224 fakeAppWithMatrixAndScmWithGitGenerator("matrix-scm-git-github", namespace, "org"), 225 fakeAppWithMatrixAndScmWithPullRequestGenerator("matrix-scm-pull-request-github", namespace, "Codertocat"), 226 fakeAppWithMatrixAndNestedGitGenerator("matrix-nested-git-github", namespace, "https://github.com/org/repo"), 227 fakeAppWithMatrixAndPullRequestGeneratorWithPluginGenerator("matrix-pull-request-github-plugin", namespace, "coDErtoCat", "HeLLO-WorLD", "plugin-cm"), 228 fakeAppWithMergeAndGitGenerator("merge-git-github", namespace, "https://github.com/org/repo"), 229 fakeAppWithMergeAndPullRequestGenerator("merge-pull-request-github", namespace, "Codertocat", "Hello-World"), 230 fakeAppWithMergeAndNestedGitGenerator("merge-nested-git-github", namespace, "https://github.com/org/repo"), 231 ).Build() 232 set := argosettings.NewSettingsManager(t.Context(), fakeClient, namespace) 233 h, err := NewWebhookHandler(webhookParallelism, set, fc, mockGenerators()) 234 require.NoError(t, err) 235 236 req := httptest.NewRequest(http.MethodPost, "/api/webhook", http.NoBody) 237 req.Header.Set(test.headerKey, test.headerValue) 238 eventJSON, err := os.ReadFile(filepath.Join("testdata", test.payloadFile)) 239 require.NoError(t, err) 240 req.Body = io.NopCloser(bytes.NewReader(eventJSON)) 241 w := httptest.NewRecorder() 242 243 h.Handler(w, req) 244 close(h.queue) 245 h.Wait() 246 assert.Equal(t, test.expectedStatusCode, w.Code) 247 248 list := &v1alpha1.ApplicationSetList{} 249 err = fc.List(t.Context(), list) 250 require.NoError(t, err) 251 effectedAppSetsAsExpected := make(map[string]bool) 252 for _, appSetName := range test.effectedAppSets { 253 effectedAppSetsAsExpected[appSetName] = false 254 } 255 for i := range list.Items { 256 gotAppSet := &list.Items[i] 257 if _, isEffected := effectedAppSetsAsExpected[gotAppSet.Name]; isEffected { 258 expected, got := test.expectedRefresh, gotAppSet.RefreshRequired() 259 require.Equalf(t, expected, got, "unexpected RefreshRequired() for appset '%s' expect: %v got: %v", gotAppSet.Name, expected, got) 260 effectedAppSetsAsExpected[gotAppSet.Name] = true 261 } else { 262 assert.False(t, gotAppSet.RefreshRequired()) 263 } 264 } 265 for appSetName, checked := range effectedAppSetsAsExpected { 266 assert.True(t, checked, "appset %s not found", appSetName) 267 } 268 }) 269 } 270 } 271 272 func mockGenerators() map[string]generators.Generator { 273 // generatorMockList := generatorMock{} 274 generatorMockGit := &generatorMock{} 275 generatorMockPR := &generatorMock{} 276 generatorMockPlugin := &generatorMock{} 277 mockSCMProvider := &scm_provider.MockProvider{ 278 Repos: []*scm_provider.Repository{ 279 { 280 Organization: "myorg", 281 Repository: "repo1", 282 URL: "git@github.com:org/repo.git", 283 Branch: "main", 284 SHA: "0bc57212c3cbbec69d20b34c507284bd300def5b", 285 }, 286 { 287 Organization: "Codertocat", 288 Repository: "Hello-World", 289 URL: "git@github.com:Codertocat/Hello-World.git", 290 Branch: "main", 291 SHA: "59d0", 292 }, 293 }, 294 } 295 generatorMockSCM := generators.NewTestSCMProviderGenerator(mockSCMProvider) 296 297 terminalMockGenerators := map[string]generators.Generator{ 298 "List": generators.NewListGenerator(), 299 "Git": generatorMockGit, 300 "SCMProvider": generatorMockSCM, 301 "PullRequest": generatorMockPR, 302 "Plugin": generatorMockPlugin, 303 } 304 305 nestedGenerators := map[string]generators.Generator{ 306 "List": terminalMockGenerators["List"], 307 "Git": terminalMockGenerators["Git"], 308 "SCMProvider": terminalMockGenerators["SCMProvider"], 309 "PullRequest": terminalMockGenerators["PullRequest"], 310 "Plugin": terminalMockGenerators["Plugin"], 311 "Matrix": generators.NewMatrixGenerator(terminalMockGenerators), 312 "Merge": generators.NewMergeGenerator(terminalMockGenerators), 313 } 314 315 return map[string]generators.Generator{ 316 "List": terminalMockGenerators["List"], 317 "Git": terminalMockGenerators["Git"], 318 "SCMProvider": terminalMockGenerators["SCMProvider"], 319 "PullRequest": terminalMockGenerators["PullRequest"], 320 "Plugin": terminalMockGenerators["Plugin"], 321 "Matrix": generators.NewMatrixGenerator(nestedGenerators), 322 "Merge": generators.NewMergeGenerator(nestedGenerators), 323 } 324 } 325 326 func TestGenRevisionHasChanged(t *testing.T) { 327 type args struct { 328 gen *v1alpha1.GitGenerator 329 revision string 330 touchedHead bool 331 } 332 tests := []struct { 333 name string 334 args args 335 want bool 336 }{ 337 {name: "touchedHead", args: args{ 338 gen: &v1alpha1.GitGenerator{}, 339 revision: "main", 340 touchedHead: true, 341 }, want: true}, 342 {name: "didntTouchHead", args: args{ 343 gen: &v1alpha1.GitGenerator{}, 344 revision: "main", 345 touchedHead: false, 346 }, want: false}, 347 {name: "foundEqualShort", args: args{ 348 gen: &v1alpha1.GitGenerator{Revision: "dev"}, 349 revision: "dev", 350 touchedHead: true, 351 }, want: true}, 352 {name: "foundEqualLongGen", args: args{ 353 gen: &v1alpha1.GitGenerator{Revision: "refs/heads/dev"}, 354 revision: "dev", 355 touchedHead: true, 356 }, want: true}, 357 {name: "foundNotEqualLongGen", args: args{ 358 gen: &v1alpha1.GitGenerator{Revision: "refs/heads/dev"}, 359 revision: "main", 360 touchedHead: true, 361 }, want: false}, 362 {name: "foundNotEqualShort", args: args{ 363 gen: &v1alpha1.GitGenerator{Revision: "dev"}, 364 revision: "main", 365 touchedHead: false, 366 }, want: false}, 367 {name: "foundEqualTag", args: args{ 368 gen: &v1alpha1.GitGenerator{Revision: "v3.14.1"}, 369 revision: "v3.14.1", 370 touchedHead: false, 371 }, want: true}, 372 {name: "foundEqualTagLongGen", args: args{ 373 gen: &v1alpha1.GitGenerator{Revision: "refs/tags/v3.14.1"}, 374 revision: "v3.14.1", 375 touchedHead: false, 376 }, want: true}, 377 } 378 for _, tt := range tests { 379 t.Run(tt.name, func(t *testing.T) { 380 assert.Equalf(t, tt.want, genRevisionHasChanged(tt.args.gen, tt.args.revision, tt.args.touchedHead), "genRevisionHasChanged(%v, %v, %v)", tt.args.gen, tt.args.revision, tt.args.touchedHead) 381 }) 382 } 383 } 384 385 func fakeAppWithGitGenerator(name, namespace, repo string) *v1alpha1.ApplicationSet { 386 return &v1alpha1.ApplicationSet{ 387 ObjectMeta: metav1.ObjectMeta{ 388 Name: name, 389 Namespace: namespace, 390 }, 391 Spec: v1alpha1.ApplicationSetSpec{ 392 Generators: []v1alpha1.ApplicationSetGenerator{ 393 { 394 Git: &v1alpha1.GitGenerator{ 395 RepoURL: repo, 396 Revision: "master", 397 }, 398 }, 399 }, 400 }, 401 } 402 } 403 404 func fakeAppWithGitGeneratorWithRevision(name, namespace, repo, revision string) *v1alpha1.ApplicationSet { 405 appSet := fakeAppWithGitGenerator(name, namespace, repo) 406 appSet.Spec.Generators[0].Git.Revision = revision 407 return appSet 408 } 409 410 func fakeAppWithGitlabPullRequestGenerator(name, namespace, projectId string) *v1alpha1.ApplicationSet { 411 return &v1alpha1.ApplicationSet{ 412 ObjectMeta: metav1.ObjectMeta{ 413 Name: name, 414 Namespace: namespace, 415 }, 416 Spec: v1alpha1.ApplicationSetSpec{ 417 Generators: []v1alpha1.ApplicationSetGenerator{ 418 { 419 PullRequest: &v1alpha1.PullRequestGenerator{ 420 GitLab: &v1alpha1.PullRequestGeneratorGitLab{ 421 Project: projectId, 422 }, 423 }, 424 }, 425 }, 426 }, 427 } 428 } 429 430 func fakeAppWithGithubPullRequestGenerator(name, namespace, owner, repo string) *v1alpha1.ApplicationSet { 431 return &v1alpha1.ApplicationSet{ 432 ObjectMeta: metav1.ObjectMeta{ 433 Name: name, 434 Namespace: namespace, 435 }, 436 Spec: v1alpha1.ApplicationSetSpec{ 437 Generators: []v1alpha1.ApplicationSetGenerator{ 438 { 439 PullRequest: &v1alpha1.PullRequestGenerator{ 440 Github: &v1alpha1.PullRequestGeneratorGithub{ 441 Owner: owner, 442 Repo: repo, 443 }, 444 }, 445 }, 446 }, 447 }, 448 } 449 } 450 451 func fakeAppWithAzureDevOpsPullRequestGenerator(name, namespace, project, repo string) *v1alpha1.ApplicationSet { 452 return &v1alpha1.ApplicationSet{ 453 ObjectMeta: metav1.ObjectMeta{ 454 Name: name, 455 Namespace: namespace, 456 }, 457 Spec: v1alpha1.ApplicationSetSpec{ 458 Generators: []v1alpha1.ApplicationSetGenerator{ 459 { 460 PullRequest: &v1alpha1.PullRequestGenerator{ 461 AzureDevOps: &v1alpha1.PullRequestGeneratorAzureDevOps{ 462 Project: project, 463 Repo: repo, 464 }, 465 }, 466 }, 467 }, 468 }, 469 } 470 } 471 472 func fakeAppWithMatrixAndGitGenerator(name, namespace, repo string) *v1alpha1.ApplicationSet { 473 return &v1alpha1.ApplicationSet{ 474 ObjectMeta: metav1.ObjectMeta{ 475 Name: name, 476 Namespace: namespace, 477 }, 478 Spec: v1alpha1.ApplicationSetSpec{ 479 Generators: []v1alpha1.ApplicationSetGenerator{ 480 { 481 Matrix: &v1alpha1.MatrixGenerator{ 482 Generators: []v1alpha1.ApplicationSetNestedGenerator{ 483 { 484 List: &v1alpha1.ListGenerator{}, 485 }, 486 { 487 Git: &v1alpha1.GitGenerator{ 488 RepoURL: repo, 489 }, 490 }, 491 }, 492 }, 493 }, 494 }, 495 }, 496 } 497 } 498 499 func fakeAppWithMatrixAndPullRequestGenerator(name, namespace, owner, repo string) *v1alpha1.ApplicationSet { 500 return &v1alpha1.ApplicationSet{ 501 ObjectMeta: metav1.ObjectMeta{ 502 Name: name, 503 Namespace: namespace, 504 }, 505 Spec: v1alpha1.ApplicationSetSpec{ 506 Generators: []v1alpha1.ApplicationSetGenerator{ 507 { 508 Matrix: &v1alpha1.MatrixGenerator{ 509 Generators: []v1alpha1.ApplicationSetNestedGenerator{ 510 { 511 List: &v1alpha1.ListGenerator{}, 512 }, 513 { 514 PullRequest: &v1alpha1.PullRequestGenerator{ 515 Github: &v1alpha1.PullRequestGeneratorGithub{ 516 Owner: owner, 517 Repo: repo, 518 }, 519 }, 520 }, 521 }, 522 }, 523 }, 524 }, 525 }, 526 } 527 } 528 529 func fakeAppWithMatrixAndScmWithGitGenerator(name, namespace, owner string) *v1alpha1.ApplicationSet { 530 return &v1alpha1.ApplicationSet{ 531 ObjectMeta: metav1.ObjectMeta{ 532 Name: name, 533 Namespace: namespace, 534 }, 535 Spec: v1alpha1.ApplicationSetSpec{ 536 Generators: []v1alpha1.ApplicationSetGenerator{ 537 { 538 Matrix: &v1alpha1.MatrixGenerator{ 539 Generators: []v1alpha1.ApplicationSetNestedGenerator{ 540 { 541 SCMProvider: &v1alpha1.SCMProviderGenerator{ 542 CloneProtocol: "ssh", 543 Github: &v1alpha1.SCMProviderGeneratorGithub{ 544 Organization: owner, 545 }, 546 }, 547 }, 548 { 549 Git: &v1alpha1.GitGenerator{ 550 RepoURL: "{{ url }}", 551 }, 552 }, 553 }, 554 }, 555 }, 556 }, 557 }, 558 } 559 } 560 561 func fakeAppWithMatrixAndScmWithPullRequestGenerator(name, namespace, owner string) *v1alpha1.ApplicationSet { 562 return &v1alpha1.ApplicationSet{ 563 ObjectMeta: metav1.ObjectMeta{ 564 Name: name, 565 Namespace: namespace, 566 }, 567 Spec: v1alpha1.ApplicationSetSpec{ 568 Generators: []v1alpha1.ApplicationSetGenerator{ 569 { 570 Matrix: &v1alpha1.MatrixGenerator{ 571 Generators: []v1alpha1.ApplicationSetNestedGenerator{ 572 { 573 SCMProvider: &v1alpha1.SCMProviderGenerator{ 574 CloneProtocol: "https", 575 Github: &v1alpha1.SCMProviderGeneratorGithub{ 576 Organization: owner, 577 }, 578 }, 579 }, 580 { 581 PullRequest: &v1alpha1.PullRequestGenerator{ 582 Github: &v1alpha1.PullRequestGeneratorGithub{ 583 Owner: "{{ organization }}", 584 Repo: "{{ repository }}", 585 }, 586 }, 587 }, 588 }, 589 }, 590 }, 591 }, 592 }, 593 } 594 } 595 596 func fakeAppWithMatrixAndNestedGitGenerator(name, namespace, repo string) *v1alpha1.ApplicationSet { 597 return &v1alpha1.ApplicationSet{ 598 ObjectMeta: metav1.ObjectMeta{ 599 Name: name, 600 Namespace: namespace, 601 }, 602 Spec: v1alpha1.ApplicationSetSpec{ 603 Generators: []v1alpha1.ApplicationSetGenerator{ 604 { 605 Matrix: &v1alpha1.MatrixGenerator{ 606 Generators: []v1alpha1.ApplicationSetNestedGenerator{ 607 { 608 List: &v1alpha1.ListGenerator{}, 609 }, 610 { 611 Matrix: &apiextensionsv1.JSON{ 612 Raw: []byte(fmt.Sprintf(`{ 613 "Generators": [ 614 { 615 "List": { 616 "Elements": [ 617 { 618 "repository": "%s" 619 } 620 ] 621 } 622 }, 623 { 624 "Git": { 625 "RepoURL": "{{ repository }}" 626 } 627 } 628 ] 629 }`, repo)), 630 }, 631 }, 632 }, 633 }, 634 }, 635 }, 636 }, 637 } 638 } 639 640 func fakeAppWithMergeAndGitGenerator(name, namespace, repo string) *v1alpha1.ApplicationSet { 641 return &v1alpha1.ApplicationSet{ 642 ObjectMeta: metav1.ObjectMeta{ 643 Name: name, 644 Namespace: namespace, 645 }, 646 Spec: v1alpha1.ApplicationSetSpec{ 647 Generators: []v1alpha1.ApplicationSetGenerator{ 648 { 649 Merge: &v1alpha1.MergeGenerator{ 650 Generators: []v1alpha1.ApplicationSetNestedGenerator{ 651 { 652 Git: &v1alpha1.GitGenerator{ 653 RepoURL: repo, 654 }, 655 }, 656 }, 657 }, 658 }, 659 }, 660 }, 661 } 662 } 663 664 func fakeAppWithMergeAndPullRequestGenerator(name, namespace, owner, repo string) *v1alpha1.ApplicationSet { 665 return &v1alpha1.ApplicationSet{ 666 ObjectMeta: metav1.ObjectMeta{ 667 Name: name, 668 Namespace: namespace, 669 }, 670 Spec: v1alpha1.ApplicationSetSpec{ 671 Generators: []v1alpha1.ApplicationSetGenerator{ 672 { 673 Merge: &v1alpha1.MergeGenerator{ 674 Generators: []v1alpha1.ApplicationSetNestedGenerator{ 675 { 676 PullRequest: &v1alpha1.PullRequestGenerator{ 677 Github: &v1alpha1.PullRequestGeneratorGithub{ 678 Owner: owner, 679 Repo: repo, 680 }, 681 }, 682 }, 683 }, 684 }, 685 }, 686 }, 687 }, 688 } 689 } 690 691 func fakeAppWithMergeAndNestedGitGenerator(name, namespace, repo string) *v1alpha1.ApplicationSet { 692 return &v1alpha1.ApplicationSet{ 693 ObjectMeta: metav1.ObjectMeta{ 694 Name: name, 695 Namespace: namespace, 696 }, 697 Spec: v1alpha1.ApplicationSetSpec{ 698 Generators: []v1alpha1.ApplicationSetGenerator{ 699 { 700 Merge: &v1alpha1.MergeGenerator{ 701 MergeKeys: []string{ 702 "server", 703 }, 704 Generators: []v1alpha1.ApplicationSetNestedGenerator{ 705 { 706 List: &v1alpha1.ListGenerator{}, 707 }, 708 { 709 Merge: &apiextensionsv1.JSON{ 710 Raw: []byte(fmt.Sprintf(`{ 711 "MergeKeys": ["server"], 712 "Generators": [ 713 { 714 "List": {} 715 }, 716 { 717 "Git": { 718 "RepoURL": "%s" 719 } 720 } 721 ] 722 }`, repo)), 723 }, 724 }, 725 }, 726 }, 727 }, 728 }, 729 }, 730 } 731 } 732 733 func fakeAppWithPluginGenerator(name, namespace string) *v1alpha1.ApplicationSet { 734 return &v1alpha1.ApplicationSet{ 735 ObjectMeta: metav1.ObjectMeta{ 736 Name: name, 737 Namespace: namespace, 738 }, 739 Spec: v1alpha1.ApplicationSetSpec{ 740 Generators: []v1alpha1.ApplicationSetGenerator{ 741 { 742 Plugin: &v1alpha1.PluginGenerator{ 743 ConfigMapRef: v1alpha1.PluginConfigMapRef{ 744 Name: "test", 745 }, 746 }, 747 }, 748 }, 749 }, 750 } 751 } 752 753 func fakeAppWithMatrixAndPullRequestGeneratorWithPluginGenerator(name, namespace, owner, repo, configmapName string) *v1alpha1.ApplicationSet { 754 return &v1alpha1.ApplicationSet{ 755 ObjectMeta: metav1.ObjectMeta{ 756 Name: name, 757 Namespace: namespace, 758 }, 759 Spec: v1alpha1.ApplicationSetSpec{ 760 Generators: []v1alpha1.ApplicationSetGenerator{ 761 { 762 Matrix: &v1alpha1.MatrixGenerator{ 763 Generators: []v1alpha1.ApplicationSetNestedGenerator{ 764 { 765 PullRequest: &v1alpha1.PullRequestGenerator{ 766 Github: &v1alpha1.PullRequestGeneratorGithub{ 767 Owner: owner, 768 Repo: repo, 769 }, 770 }, 771 }, 772 { 773 Plugin: &v1alpha1.PluginGenerator{ 774 ConfigMapRef: v1alpha1.PluginConfigMapRef{ 775 Name: configmapName, 776 }, 777 }, 778 }, 779 }, 780 }, 781 }, 782 }, 783 }, 784 } 785 } 786 787 func newFakeClient(ns string) *kubefake.Clientset { 788 s := runtime.NewScheme() 789 s.AddKnownTypes(v1alpha1.SchemeGroupVersion, &v1alpha1.ApplicationSet{}) 790 return kubefake.NewClientset(&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "argocd-cm", Namespace: ns, Labels: map[string]string{ 791 "app.kubernetes.io/part-of": "argocd", 792 }}}, &corev1.Secret{ 793 ObjectMeta: metav1.ObjectMeta{ 794 Name: common.ArgoCDSecretName, 795 Namespace: ns, 796 Labels: map[string]string{ 797 "app.kubernetes.io/part-of": "argocd", 798 }, 799 }, 800 Data: map[string][]byte{ 801 "server.secretkey": nil, 802 }, 803 }) 804 }