github.com/argoproj/argo-cd/v2@v2.10.5/test/e2e/project_management_test.go (about) 1 package e2e 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "strconv" 8 "strings" 9 "testing" 10 "time" 11 12 "github.com/stretchr/testify/assert" 13 "k8s.io/apimachinery/pkg/api/errors" 14 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 15 "k8s.io/apimachinery/pkg/fields" 16 "k8s.io/utils/pointer" 17 18 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" 19 "github.com/argoproj/argo-cd/v2/test/e2e/fixture" 20 "github.com/argoproj/argo-cd/v2/util/argo" 21 ) 22 23 func assertProjHasEvent(t *testing.T, a *v1alpha1.AppProject, message string, reason string) { 24 list, err := fixture.KubeClientset.CoreV1().Events(fixture.TestNamespace()).List(context.Background(), metav1.ListOptions{ 25 FieldSelector: fields.SelectorFromSet(map[string]string{ 26 "involvedObject.name": a.Name, 27 "involvedObject.uid": string(a.UID), 28 "involvedObject.namespace": fixture.TestNamespace(), 29 }).String(), 30 }) 31 assert.NoError(t, err) 32 33 for i := range list.Items { 34 event := list.Items[i] 35 if event.Reason == reason && strings.Contains(event.Message, message) { 36 return 37 } 38 } 39 t.Errorf("Unable to find event with reason=%s; message=%s", reason, message) 40 } 41 42 func TestProjectCreation(t *testing.T) { 43 fixture.EnsureCleanState(t) 44 45 projectName := "proj-" + fixture.Name() 46 _, err := fixture.RunCli("proj", "create", projectName, 47 "--description", "Test description", 48 "-d", "https://192.168.99.100:8443,default", 49 "-d", "https://192.168.99.100:8443,service", 50 "-s", "https://github.com/argoproj/argo-cd.git", 51 "--orphaned-resources") 52 assert.Nil(t, err) 53 54 proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 55 assert.NoError(t, err) 56 assert.Equal(t, projectName, proj.Name) 57 assert.Equal(t, 2, len(proj.Spec.Destinations)) 58 59 assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.Destinations[0].Server) 60 assert.Equal(t, "default", proj.Spec.Destinations[0].Namespace) 61 62 assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.Destinations[1].Server) 63 assert.Equal(t, "service", proj.Spec.Destinations[1].Namespace) 64 65 assert.Equal(t, 1, len(proj.Spec.SourceRepos)) 66 assert.Equal(t, "https://github.com/argoproj/argo-cd.git", proj.Spec.SourceRepos[0]) 67 68 assert.NotNil(t, proj.Spec.OrphanedResources) 69 assert.False(t, proj.Spec.OrphanedResources.IsWarn()) 70 71 assertProjHasEvent(t, proj, "create", argo.EventReasonResourceCreated) 72 73 // create a manifest with the same name to upsert 74 newDescription := "Upserted description" 75 proj.Spec.Description = newDescription 76 proj.ResourceVersion = "" 77 data, err := json.Marshal(proj) 78 stdinString := string(data) 79 assert.NoError(t, err) 80 81 // fail without upsert flag 82 _, err = fixture.RunCliWithStdin(stdinString, "proj", "create", 83 "-f", "-") 84 assert.Error(t, err) 85 86 // succeed with the upsert flag 87 _, err = fixture.RunCliWithStdin(stdinString, "proj", "create", 88 "-f", "-", "--upsert") 89 assert.NoError(t, err) 90 proj, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 91 assert.NoError(t, err) 92 assert.Equal(t, newDescription, proj.Spec.Description) 93 } 94 95 func TestProjectDeletion(t *testing.T) { 96 fixture.EnsureCleanState(t) 97 98 projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) 99 proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( 100 context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) 101 assert.NoError(t, err) 102 103 _, err = fixture.RunCli("proj", "delete", projectName) 104 assert.NoError(t, err) 105 106 _, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 107 assert.True(t, errors.IsNotFound(err)) 108 assertProjHasEvent(t, proj, "delete", argo.EventReasonResourceDeleted) 109 } 110 111 func TestSetProject(t *testing.T) { 112 fixture.EnsureCleanState(t) 113 114 projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) 115 _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( 116 context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) 117 assert.NoError(t, err) 118 119 _, err = fixture.RunCli("proj", "set", projectName, 120 "--description", "updated description", 121 "-d", "https://192.168.99.100:8443,default", 122 "-d", "https://192.168.99.100:8443,service", 123 "--orphaned-resources-warn=false") 124 assert.NoError(t, err) 125 126 proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 127 assert.NoError(t, err) 128 assert.Equal(t, projectName, proj.Name) 129 assert.Equal(t, 2, len(proj.Spec.Destinations)) 130 131 assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.Destinations[0].Server) 132 assert.Equal(t, "default", proj.Spec.Destinations[0].Namespace) 133 134 assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.Destinations[1].Server) 135 assert.Equal(t, "service", proj.Spec.Destinations[1].Namespace) 136 137 assert.NotNil(t, proj.Spec.OrphanedResources) 138 assert.False(t, proj.Spec.OrphanedResources.IsWarn()) 139 140 assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated) 141 } 142 143 func TestAddProjectDestination(t *testing.T) { 144 fixture.EnsureCleanState(t) 145 146 projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) 147 _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( 148 context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) 149 if err != nil { 150 t.Fatalf("Unable to create project %v", err) 151 } 152 153 _, err = fixture.RunCli("proj", "add-destination", projectName, 154 "https://192.168.99.100:8443", 155 "test1", 156 ) 157 158 if err != nil { 159 t.Fatalf("Unable to add project destination %v", err) 160 } 161 162 _, err = fixture.RunCli("proj", "add-destination", projectName, 163 "https://192.168.99.100:8443", 164 "test1", 165 ) 166 assert.Error(t, err) 167 assert.True(t, strings.Contains(err.Error(), "already defined")) 168 169 _, err = fixture.RunCli("proj", "add-destination", projectName, 170 "!*", 171 "test1", 172 ) 173 assert.Error(t, err) 174 assert.True(t, strings.Contains(err.Error(), "server has an invalid format, '!*'")) 175 176 _, err = fixture.RunCli("proj", "add-destination", projectName, 177 "https://192.168.99.100:8443", 178 "!*", 179 ) 180 assert.Error(t, err) 181 assert.True(t, strings.Contains(err.Error(), "namespace has an invalid format, '!*'")) 182 183 proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 184 assert.NoError(t, err) 185 assert.Equal(t, projectName, proj.Name) 186 assert.Equal(t, 1, len(proj.Spec.Destinations)) 187 188 assert.Equal(t, "https://192.168.99.100:8443", proj.Spec.Destinations[0].Server) 189 assert.Equal(t, "test1", proj.Spec.Destinations[0].Namespace) 190 assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated) 191 } 192 193 func TestAddProjectDestinationWithName(t *testing.T) { 194 fixture.EnsureCleanState(t) 195 196 projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) 197 _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( 198 context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) 199 if err != nil { 200 t.Fatalf("Unable to create project %v", err) 201 } 202 203 _, err = fixture.RunCli("proj", "add-destination", projectName, 204 "in-cluster", 205 "test1", 206 "--name", 207 ) 208 209 if err != nil { 210 t.Fatalf("Unable to add project destination %v", err) 211 } 212 213 proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 214 assert.NoError(t, err) 215 assert.Equal(t, projectName, proj.Name) 216 assert.Equal(t, 1, len(proj.Spec.Destinations)) 217 218 assert.Equal(t, "", proj.Spec.Destinations[0].Server) 219 assert.Equal(t, "in-cluster", proj.Spec.Destinations[0].Name) 220 assert.Equal(t, "test1", proj.Spec.Destinations[0].Namespace) 221 assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated) 222 } 223 224 func TestRemoveProjectDestination(t *testing.T) { 225 fixture.EnsureCleanState(t) 226 227 projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) 228 _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create(context.Background(), &v1alpha1.AppProject{ 229 ObjectMeta: metav1.ObjectMeta{Name: projectName}, 230 Spec: v1alpha1.AppProjectSpec{ 231 Destinations: []v1alpha1.ApplicationDestination{{ 232 Server: "https://192.168.99.100:8443", 233 Namespace: "test", 234 }}, 235 }, 236 }, metav1.CreateOptions{}) 237 238 if err != nil { 239 t.Fatalf("Unable to create project %v", err) 240 } 241 242 _, err = fixture.RunCli("proj", "remove-destination", projectName, 243 "https://192.168.99.100:8443", 244 "test", 245 ) 246 247 if err != nil { 248 t.Fatalf("Unable to remove project destination %v", err) 249 } 250 251 _, err = fixture.RunCli("proj", "remove-destination", projectName, 252 "https://192.168.99.100:8443", 253 "test1", 254 ) 255 assert.Error(t, err) 256 assert.Contains(t, err.Error(), "does not exist") 257 258 proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 259 if err != nil { 260 t.Fatalf("Unable to get project %v", err) 261 } 262 assert.Equal(t, projectName, proj.Name) 263 assert.Equal(t, 0, len(proj.Spec.Destinations)) 264 assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated) 265 } 266 267 func TestAddProjectSource(t *testing.T) { 268 fixture.EnsureCleanState(t) 269 270 projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) 271 _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( 272 context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) 273 if err != nil { 274 t.Fatalf("Unable to create project %v", err) 275 } 276 277 _, err = fixture.RunCli("proj", "add-source", projectName, "https://github.com/argoproj/argo-cd.git") 278 279 if err != nil { 280 t.Fatalf("Unable to add project source %v", err) 281 } 282 283 _, err = fixture.RunCli("proj", "add-source", projectName, "https://github.com/argoproj/argo-cd.git") 284 assert.Nil(t, err) 285 286 proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 287 assert.NoError(t, err) 288 assert.Equal(t, projectName, proj.Name) 289 assert.Equal(t, 1, len(proj.Spec.SourceRepos)) 290 291 assert.Equal(t, "https://github.com/argoproj/argo-cd.git", proj.Spec.SourceRepos[0]) 292 } 293 294 func TestRemoveProjectSource(t *testing.T) { 295 fixture.EnsureCleanState(t) 296 297 projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) 298 _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create(context.Background(), &v1alpha1.AppProject{ 299 ObjectMeta: metav1.ObjectMeta{Name: projectName}, 300 Spec: v1alpha1.AppProjectSpec{ 301 SourceRepos: []string{"https://github.com/argoproj/argo-cd.git"}, 302 }, 303 }, metav1.CreateOptions{}) 304 305 assert.NoError(t, err) 306 307 _, err = fixture.RunCli("proj", "remove-source", projectName, "https://github.com/argoproj/argo-cd.git") 308 309 assert.NoError(t, err) 310 311 _, err = fixture.RunCli("proj", "remove-source", projectName, "https://github.com/argoproj/argo-cd.git") 312 assert.NoError(t, err) 313 314 proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 315 assert.NoError(t, err) 316 assert.Equal(t, projectName, proj.Name) 317 assert.Equal(t, 0, len(proj.Spec.SourceRepos)) 318 assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated) 319 } 320 321 func TestUseJWTToken(t *testing.T) { 322 fixture.EnsureCleanState(t) 323 324 projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) 325 appName := "app-" + strconv.FormatInt(time.Now().Unix(), 10) 326 roleName := "roleTest" 327 testApp := &v1alpha1.Application{ 328 ObjectMeta: metav1.ObjectMeta{ 329 Name: appName, 330 }, 331 Spec: v1alpha1.ApplicationSpec{ 332 Source: &v1alpha1.ApplicationSource{ 333 RepoURL: fixture.RepoURL(fixture.RepoURLTypeFile), 334 Path: "guestbook", 335 }, 336 Destination: v1alpha1.ApplicationDestination{ 337 Server: v1alpha1.KubernetesInternalAPIServerAddr, 338 Namespace: fixture.TestNamespace(), 339 }, 340 Project: projectName, 341 }, 342 } 343 _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create(context.Background(), &v1alpha1.AppProject{ 344 ObjectMeta: metav1.ObjectMeta{Name: projectName}, 345 Spec: v1alpha1.AppProjectSpec{ 346 Destinations: []v1alpha1.ApplicationDestination{{ 347 Server: v1alpha1.KubernetesInternalAPIServerAddr, 348 Namespace: fixture.TestNamespace(), 349 }}, 350 SourceRepos: []string{"*"}, 351 }, 352 }, metav1.CreateOptions{}) 353 assert.Nil(t, err) 354 355 _, err = fixture.AppClientset.ArgoprojV1alpha1().Applications(fixture.TestNamespace()).Create(context.Background(), testApp, metav1.CreateOptions{}) 356 assert.NoError(t, err) 357 358 _, err = fixture.RunCli("proj", "role", "create", projectName, roleName) 359 assert.NoError(t, err) 360 361 roleGetResult, err := fixture.RunCli("proj", "role", "get", projectName, roleName) 362 assert.NoError(t, err) 363 assert.True(t, strings.HasSuffix(roleGetResult, "ID ISSUED-AT EXPIRES-AT")) 364 365 _, err = fixture.RunCli("proj", "role", "create-token", projectName, roleName) 366 assert.NoError(t, err) 367 368 for _, action := range []string{"get", "update", "sync", "create", "override", "*"} { 369 _, err = fixture.RunCli("proj", "role", "add-policy", projectName, roleName, "-a", action, "-o", "*", "-p", "allow") 370 assert.NoError(t, err) 371 } 372 373 newProj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 374 assert.NoError(t, err) 375 assert.Len(t, newProj.Status.JWTTokensByRole[roleName].Items, 1) 376 assert.ElementsMatch(t, newProj.Status.JWTTokensByRole[roleName].Items, newProj.Spec.Roles[0].JWTTokens) 377 378 roleGetResult, err = fixture.RunCli("proj", "role", "get", projectName, roleName) 379 assert.NoError(t, err) 380 assert.True(t, strings.Contains(roleGetResult, strconv.FormatInt(newProj.Status.JWTTokensByRole[roleName].Items[0].IssuedAt, 10))) 381 382 _, err = fixture.RunCli("proj", "role", "delete-token", projectName, roleName, strconv.FormatInt(newProj.Status.JWTTokensByRole[roleName].Items[0].IssuedAt, 10)) 383 assert.NoError(t, err) 384 newProj, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 385 assert.NoError(t, err) 386 assert.Nil(t, newProj.Status.JWTTokensByRole[roleName].Items) 387 assert.Nil(t, newProj.Spec.Roles[0].JWTTokens) 388 389 } 390 391 func TestAddOrphanedIgnore(t *testing.T) { 392 fixture.EnsureCleanState(t) 393 394 projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) 395 _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create( 396 context.Background(), &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: projectName}}, metav1.CreateOptions{}) 397 if err != nil { 398 t.Fatalf("Unable to create project %v", err) 399 } 400 401 _, err = fixture.RunCli("proj", "add-orphaned-ignore", projectName, 402 "group", 403 "kind", 404 "--name", 405 "name", 406 ) 407 408 if err != nil { 409 t.Fatalf("Unable to add resource to orphaned ignore %v", err) 410 } 411 412 _, err = fixture.RunCli("proj", "add-orphaned-ignore", projectName, 413 "group", 414 "kind", 415 "--name", 416 "name", 417 ) 418 assert.Error(t, err) 419 assert.True(t, strings.Contains(err.Error(), "already defined")) 420 421 proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 422 assert.NoError(t, err) 423 assert.Equal(t, projectName, proj.Name) 424 assert.Equal(t, 1, len(proj.Spec.OrphanedResources.Ignore)) 425 426 assert.Equal(t, "group", proj.Spec.OrphanedResources.Ignore[0].Group) 427 assert.Equal(t, "kind", proj.Spec.OrphanedResources.Ignore[0].Kind) 428 assert.Equal(t, "name", proj.Spec.OrphanedResources.Ignore[0].Name) 429 assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated) 430 } 431 432 func TestRemoveOrphanedIgnore(t *testing.T) { 433 fixture.EnsureCleanState(t) 434 435 projectName := "proj-" + strconv.FormatInt(time.Now().Unix(), 10) 436 _, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Create(context.Background(), &v1alpha1.AppProject{ 437 ObjectMeta: metav1.ObjectMeta{Name: projectName}, 438 Spec: v1alpha1.AppProjectSpec{ 439 OrphanedResources: &v1alpha1.OrphanedResourcesMonitorSettings{ 440 Warn: pointer.Bool(true), 441 Ignore: []v1alpha1.OrphanedResourceKey{{Group: "group", Kind: "kind", Name: "name"}}, 442 }, 443 }, 444 }, metav1.CreateOptions{}) 445 446 if err != nil { 447 t.Fatalf("Unable to create project %v", err) 448 } 449 450 _, err = fixture.RunCli("proj", "remove-orphaned-ignore", projectName, 451 "group", 452 "kind", 453 "--name", 454 "name", 455 ) 456 457 if err != nil { 458 t.Fatalf("Unable to remove resource from orphaned ignore list %v", err) 459 } 460 461 _, err = fixture.RunCli("proj", "remove-orphaned-ignore", projectName, 462 "group", 463 "kind", 464 "--name", 465 "name", 466 ) 467 assert.Error(t, err) 468 assert.Contains(t, err.Error(), "does not exist") 469 470 proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 471 if err != nil { 472 t.Fatalf("Unable to get project %v", err) 473 } 474 assert.Equal(t, projectName, proj.Name) 475 assert.Equal(t, 0, len(proj.Spec.OrphanedResources.Ignore)) 476 assertProjHasEvent(t, proj, "update", argo.EventReasonResourceUpdated) 477 } 478 479 func createAndConfigGlobalProject() error { 480 // Create global project 481 projectGlobalName := "proj-g-" + fixture.Name() 482 _, err := fixture.RunCli("proj", "create", projectGlobalName, 483 "--description", "Test description", 484 "-d", "https://192.168.99.100:8443,default", 485 "-d", "https://192.168.99.100:8443,service", 486 "-s", "https://github.com/argoproj/argo-cd.git", 487 "--orphaned-resources") 488 if err != nil { 489 return err 490 } 491 492 projGlobal, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectGlobalName, metav1.GetOptions{}) 493 if err != nil { 494 return err 495 } 496 497 projGlobal.Spec.NamespaceResourceBlacklist = []metav1.GroupKind{ 498 {Group: "", Kind: "Service"}, 499 } 500 501 projGlobal.Spec.NamespaceResourceWhitelist = []metav1.GroupKind{ 502 {Group: "", Kind: "Deployment"}, 503 } 504 505 projGlobal.Spec.ClusterResourceWhitelist = []metav1.GroupKind{ 506 {Group: "", Kind: "Job"}, 507 } 508 509 projGlobal.Spec.ClusterResourceBlacklist = []metav1.GroupKind{ 510 {Group: "", Kind: "Pod"}, 511 } 512 513 projGlobal.Spec.SyncWindows = v1alpha1.SyncWindows{} 514 win := &v1alpha1.SyncWindow{Kind: "deny", Schedule: "* * * * *", Duration: "1h", Applications: []string{"*"}} 515 projGlobal.Spec.SyncWindows = append(projGlobal.Spec.SyncWindows, win) 516 517 _, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Update(context.Background(), projGlobal, metav1.UpdateOptions{}) 518 if err != nil { 519 return err 520 } 521 522 // Configure global project settings 523 globalProjectsSettings := `data: 524 accounts.config-service: apiKey 525 globalProjects: | 526 - labelSelector: 527 matchExpressions: 528 - key: opt 529 operator: In 530 values: 531 - me 532 - you 533 projectName: %s` 534 535 _, err = fixture.Run("", "kubectl", "patch", "cm", "argocd-cm", 536 "-n", fixture.TestNamespace(), 537 "-p", fmt.Sprintf(globalProjectsSettings, projGlobal.Name)) 538 if err != nil { 539 return err 540 } 541 542 return nil 543 } 544 545 func TestGetVirtualProjectNoMatch(t *testing.T) { 546 fixture.EnsureCleanState(t) 547 err := createAndConfigGlobalProject() 548 assert.NoError(t, err) 549 550 // Create project which does not match global project settings 551 projectName := "proj-" + fixture.Name() 552 _, err = fixture.RunCli("proj", "create", projectName, 553 "--description", "Test description", 554 "-d", fmt.Sprintf("%s,*", v1alpha1.KubernetesInternalAPIServerAddr), 555 "-s", "*", 556 "--orphaned-resources") 557 assert.NoError(t, err) 558 559 proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 560 assert.NoError(t, err) 561 562 // Create an app belongs to proj project 563 _, err = fixture.RunCli("app", "create", fixture.Name(), "--repo", fixture.RepoURL(fixture.RepoURLTypeFile), 564 "--path", guestbookPath, "--project", proj.Name, "--dest-server", v1alpha1.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace()) 565 assert.NoError(t, err) 566 567 // Waiting for the app to be successfully created. 568 // Else the sync would fail to retrieve the app resources. 569 time.Sleep(time.Second * 2) 570 571 // App trying to sync a resource which is not blacked listed anywhere 572 _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", fmt.Sprintf("%v", 10)) 573 assert.NoError(t, err) 574 575 // app trying to sync a resource which is black listed by global project 576 _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", ":Service:guestbook-ui", "--timeout", fmt.Sprintf("%v", 10)) 577 assert.NoError(t, err) 578 579 } 580 581 func TestGetVirtualProjectMatch(t *testing.T) { 582 fixture.EnsureCleanState(t) 583 err := createAndConfigGlobalProject() 584 assert.NoError(t, err) 585 586 // Create project which matches global project settings 587 projectName := "proj-" + fixture.Name() 588 _, err = fixture.RunCli("proj", "create", projectName, 589 "--description", "Test description", 590 "-d", fmt.Sprintf("%s,*", v1alpha1.KubernetesInternalAPIServerAddr), 591 "-s", "*", 592 "--orphaned-resources") 593 assert.NoError(t, err) 594 595 proj, err := fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Get(context.Background(), projectName, metav1.GetOptions{}) 596 assert.NoError(t, err) 597 598 // Add a label to this project so that this project match global project selector 599 proj.Labels = map[string]string{"opt": "me"} 600 _, err = fixture.AppClientset.ArgoprojV1alpha1().AppProjects(fixture.TestNamespace()).Update(context.Background(), proj, metav1.UpdateOptions{}) 601 assert.NoError(t, err) 602 603 // Create an app belongs to proj project 604 _, err = fixture.RunCli("app", "create", fixture.Name(), "--repo", fixture.RepoURL(fixture.RepoURLTypeFile), 605 "--path", guestbookPath, "--project", proj.Name, "--dest-server", v1alpha1.KubernetesInternalAPIServerAddr, "--dest-namespace", fixture.DeploymentNamespace()) 606 assert.NoError(t, err) 607 608 // Waiting for the app to be successfully created. 609 // Else the sync would fail to retrieve the app resources. 610 time.Sleep(time.Second * 2) 611 612 // App trying to sync a resource which is not blacked listed anywhere 613 _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", "apps:Deployment:guestbook-ui", "--timeout", fmt.Sprintf("%v", 10)) 614 assert.Error(t, err) 615 assert.Contains(t, err.Error(), "blocked by sync window") 616 617 // app trying to sync a resource which is black listed by global project 618 _, err = fixture.RunCli("app", "sync", fixture.Name(), "--resource", ":Service:guestbook-ui", "--timeout", fmt.Sprintf("%v", 10)) 619 assert.Contains(t, err.Error(), "blocked by sync window") 620 621 }