github.com/argoproj/argo-cd/v2@v2.10.5/test/e2e/clusterdecisiongenerator_e2e_test.go (about) 1 package e2e 2 3 import ( 4 "testing" 5 6 "github.com/argoproj/argo-cd/v2/test/e2e/fixture" 7 8 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 9 10 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" 11 argov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" 12 . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets" 13 "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" 14 15 "github.com/argoproj/argo-cd/v2/pkg/apis/application" 16 ) 17 18 var tenSec = int64(10) 19 20 func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { 21 22 var externalNamespace = string(utils.ArgoCDExternalNamespace) 23 24 expectedApp := argov1alpha1.Application{ 25 TypeMeta: metav1.TypeMeta{ 26 Kind: "Application", 27 APIVersion: "argoproj.io/v1alpha1", 28 }, 29 ObjectMeta: metav1.ObjectMeta{ 30 Name: "cluster1-guestbook", 31 Namespace: externalNamespace, 32 Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, 33 }, 34 Spec: argov1alpha1.ApplicationSpec{ 35 Project: "default", 36 Source: &argov1alpha1.ApplicationSource{ 37 RepoURL: "https://github.com/argoproj/argocd-example-apps.git", 38 TargetRevision: "HEAD", 39 Path: "guestbook", 40 }, 41 Destination: argov1alpha1.ApplicationDestination{ 42 Name: "cluster1", 43 Namespace: "guestbook", 44 }, 45 }, 46 } 47 48 var expectedAppNewNamespace *argov1alpha1.Application 49 var expectedAppNewMetadata *argov1alpha1.Application 50 51 clusterList := []interface{}{ 52 map[string]interface{}{ 53 "clusterName": "cluster1", 54 "reason": "argotest", 55 }, 56 } 57 58 Given(t). 59 // Create a ClusterGenerator-based ApplicationSet 60 When(). 61 CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc"). 62 CreatePlacementRoleAndRoleBinding(). 63 CreatePlacementDecisionConfigMap("my-configmap"). 64 CreatePlacementDecision("my-placementdecision"). 65 StatusUpdatePlacementDecision("my-placementdecision", clusterList). 66 CreateNamespace(externalNamespace). 67 SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). 68 Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ 69 Name: "simple-cluster-generator", 70 }, 71 Spec: v1alpha1.ApplicationSetSpec{ 72 Template: v1alpha1.ApplicationSetTemplate{ 73 ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, 74 Spec: argov1alpha1.ApplicationSpec{ 75 Project: "default", 76 Source: &argov1alpha1.ApplicationSource{ 77 RepoURL: "https://github.com/argoproj/argocd-example-apps.git", 78 TargetRevision: "HEAD", 79 Path: "guestbook", 80 }, 81 Destination: argov1alpha1.ApplicationDestination{ 82 Name: "{{clusterName}}", 83 // Server: "{{server}}", 84 Namespace: "guestbook", 85 }, 86 }, 87 }, 88 Generators: []v1alpha1.ApplicationSetGenerator{ 89 { 90 ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{ 91 ConfigMapRef: "my-configmap", 92 Name: "my-placementdecision", 93 }, 94 }, 95 }, 96 }, 97 }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). 98 99 // Update the ApplicationSet template namespace, and verify it updates the Applications 100 When(). 101 And(func() { 102 expectedAppNewNamespace = expectedApp.DeepCopy() 103 expectedAppNewNamespace.Spec.Destination.Namespace = "guestbook2" 104 }). 105 Update(func(appset *v1alpha1.ApplicationSet) { 106 appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" 107 }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). 108 109 // Update the metadata fields in the appset template, and make sure it propagates to the apps 110 When(). 111 And(func() { 112 expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy() 113 expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"} 114 expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{ 115 "label-key": "label-value", 116 } 117 }). 118 Update(func(appset *v1alpha1.ApplicationSet) { 119 appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} 120 appset.Spec.Template.Labels = map[string]string{ 121 "label-key": "label-value", 122 } 123 }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). 124 125 // Delete the ApplicationSet, and verify it deletes the Applications 126 When(). 127 Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewNamespace})) 128 } 129 130 func TestSimpleClusterDecisionResourceGenerator(t *testing.T) { 131 132 expectedApp := argov1alpha1.Application{ 133 TypeMeta: metav1.TypeMeta{ 134 Kind: application.ApplicationKind, 135 APIVersion: "argoproj.io/v1alpha1", 136 }, 137 ObjectMeta: metav1.ObjectMeta{ 138 Name: "cluster1-guestbook", 139 Namespace: fixture.TestNamespace(), 140 Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, 141 }, 142 Spec: argov1alpha1.ApplicationSpec{ 143 Project: "default", 144 Source: &argov1alpha1.ApplicationSource{ 145 RepoURL: "https://github.com/argoproj/argocd-example-apps.git", 146 TargetRevision: "HEAD", 147 Path: "guestbook", 148 }, 149 Destination: argov1alpha1.ApplicationDestination{ 150 Name: "cluster1", 151 Namespace: "guestbook", 152 }, 153 }, 154 } 155 156 var expectedAppNewNamespace *argov1alpha1.Application 157 var expectedAppNewMetadata *argov1alpha1.Application 158 159 clusterList := []interface{}{ 160 map[string]interface{}{ 161 "clusterName": "cluster1", 162 "reason": "argotest", 163 }, 164 } 165 166 Given(t). 167 // Create a ClusterGenerator-based ApplicationSet 168 When(). 169 CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc"). 170 CreatePlacementRoleAndRoleBinding(). 171 CreatePlacementDecisionConfigMap("my-configmap"). 172 CreatePlacementDecision("my-placementdecision"). 173 StatusUpdatePlacementDecision("my-placementdecision", clusterList). 174 Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ 175 Name: "simple-cluster-generator", 176 }, 177 Spec: v1alpha1.ApplicationSetSpec{ 178 Template: v1alpha1.ApplicationSetTemplate{ 179 ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, 180 Spec: argov1alpha1.ApplicationSpec{ 181 Project: "default", 182 Source: &argov1alpha1.ApplicationSource{ 183 RepoURL: "https://github.com/argoproj/argocd-example-apps.git", 184 TargetRevision: "HEAD", 185 Path: "guestbook", 186 }, 187 Destination: argov1alpha1.ApplicationDestination{ 188 Name: "{{clusterName}}", 189 // Server: "{{server}}", 190 Namespace: "guestbook", 191 }, 192 }, 193 }, 194 Generators: []v1alpha1.ApplicationSetGenerator{ 195 { 196 ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{ 197 ConfigMapRef: "my-configmap", 198 Name: "my-placementdecision", 199 }, 200 }, 201 }, 202 }, 203 }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). 204 205 // Update the ApplicationSet template namespace, and verify it updates the Applications 206 When(). 207 And(func() { 208 expectedAppNewNamespace = expectedApp.DeepCopy() 209 expectedAppNewNamespace.Spec.Destination.Namespace = "guestbook2" 210 }). 211 Update(func(appset *v1alpha1.ApplicationSet) { 212 appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" 213 }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). 214 215 // Update the metadata fields in the appset template, and make sure it propagates to the apps 216 When(). 217 And(func() { 218 expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy() 219 expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"} 220 expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{"label-key": "label-value"} 221 }). 222 Update(func(appset *v1alpha1.ApplicationSet) { 223 appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} 224 appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} 225 }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). 226 227 // Delete the ApplicationSet, and verify it deletes the Applications 228 When(). 229 Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewNamespace})) 230 } 231 232 func TestSimpleClusterDecisionResourceGeneratorAddingCluster(t *testing.T) { 233 234 expectedAppTemplate := argov1alpha1.Application{ 235 TypeMeta: metav1.TypeMeta{ 236 Kind: application.ApplicationKind, 237 APIVersion: "argoproj.io/v1alpha1", 238 }, 239 ObjectMeta: metav1.ObjectMeta{ 240 Name: "{{name}}-guestbook", 241 Namespace: fixture.TestNamespace(), 242 Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, 243 }, 244 Spec: argov1alpha1.ApplicationSpec{ 245 Project: "default", 246 Source: &argov1alpha1.ApplicationSource{ 247 RepoURL: "https://github.com/argoproj/argocd-example-apps.git", 248 TargetRevision: "HEAD", 249 Path: "guestbook", 250 }, 251 Destination: argov1alpha1.ApplicationDestination{ 252 Name: "{{clusterName}}", 253 Namespace: "guestbook", 254 }, 255 }, 256 } 257 258 expectedAppCluster1 := *expectedAppTemplate.DeepCopy() 259 expectedAppCluster1.Spec.Destination.Name = "cluster1" 260 expectedAppCluster1.ObjectMeta.Name = "cluster1-guestbook" 261 262 expectedAppCluster2 := *expectedAppTemplate.DeepCopy() 263 expectedAppCluster2.Spec.Destination.Name = "cluster2" 264 expectedAppCluster2.ObjectMeta.Name = "cluster2-guestbook" 265 266 clusterList := []interface{}{ 267 map[string]interface{}{ 268 "clusterName": "cluster1", 269 "reason": "argotest", 270 }, 271 map[string]interface{}{ 272 "clusterName": "cluster2", 273 "reason": "argotest", 274 }, 275 } 276 277 Given(t). 278 // Create a ClusterGenerator-based ApplicationSet 279 When(). 280 CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc"). 281 CreatePlacementRoleAndRoleBinding(). 282 CreatePlacementDecisionConfigMap("my-configmap"). 283 CreatePlacementDecision("my-placementdecision"). 284 StatusUpdatePlacementDecision("my-placementdecision", clusterList). 285 Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ 286 Name: "simple-cluster-generator", 287 }, 288 Spec: v1alpha1.ApplicationSetSpec{ 289 Template: v1alpha1.ApplicationSetTemplate{ 290 ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, 291 Spec: argov1alpha1.ApplicationSpec{ 292 Project: "default", 293 Source: &argov1alpha1.ApplicationSource{ 294 RepoURL: "https://github.com/argoproj/argocd-example-apps.git", 295 TargetRevision: "HEAD", 296 Path: "guestbook", 297 }, 298 Destination: argov1alpha1.ApplicationDestination{ 299 Name: "{{clusterName}}", 300 // Server: "{{server}}", 301 Namespace: "guestbook", 302 }, 303 }, 304 }, 305 Generators: []v1alpha1.ApplicationSetGenerator{ 306 { 307 ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{ 308 ConfigMapRef: "my-configmap", 309 Name: "my-placementdecision", 310 RequeueAfterSeconds: &tenSec, 311 }, 312 }, 313 }, 314 }, 315 }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1})). 316 317 // Update the ApplicationSet template namespace, and verify it updates the Applications 318 When(). 319 CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc"). 320 Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). 321 322 // Delete the ApplicationSet, and verify it deletes the Applications 323 When(). 324 Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})) 325 } 326 327 func TestSimpleClusterDecisionResourceGeneratorDeletingClusterSecret(t *testing.T) { 328 329 expectedAppTemplate := argov1alpha1.Application{ 330 TypeMeta: metav1.TypeMeta{ 331 Kind: application.ApplicationKind, 332 APIVersion: "argoproj.io/v1alpha1", 333 }, 334 ObjectMeta: metav1.ObjectMeta{ 335 Name: "{{name}}-guestbook", 336 Namespace: fixture.TestNamespace(), 337 Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, 338 }, 339 Spec: argov1alpha1.ApplicationSpec{ 340 Project: "default", 341 Source: &argov1alpha1.ApplicationSource{ 342 RepoURL: "https://github.com/argoproj/argocd-example-apps.git", 343 TargetRevision: "HEAD", 344 Path: "guestbook", 345 }, 346 Destination: argov1alpha1.ApplicationDestination{ 347 Name: "{{name}}", 348 Namespace: "guestbook", 349 }, 350 }, 351 } 352 353 expectedAppCluster1 := *expectedAppTemplate.DeepCopy() 354 expectedAppCluster1.Spec.Destination.Name = "cluster1" 355 expectedAppCluster1.ObjectMeta.Name = "cluster1-guestbook" 356 357 expectedAppCluster2 := *expectedAppTemplate.DeepCopy() 358 expectedAppCluster2.Spec.Destination.Name = "cluster2" 359 expectedAppCluster2.ObjectMeta.Name = "cluster2-guestbook" 360 361 clusterList := []interface{}{ 362 map[string]interface{}{ 363 "clusterName": "cluster1", 364 "reason": "argotest", 365 }, 366 map[string]interface{}{ 367 "clusterName": "cluster2", 368 "reason": "argotest", 369 }, 370 } 371 372 Given(t). 373 // Create a ClusterGenerator-based ApplicationSet 374 When(). 375 CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc"). 376 CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc"). 377 CreatePlacementRoleAndRoleBinding(). 378 CreatePlacementDecisionConfigMap("my-configmap"). 379 CreatePlacementDecision("my-placementdecision"). 380 StatusUpdatePlacementDecision("my-placementdecision", clusterList). 381 Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ 382 Name: "simple-cluster-generator", 383 }, 384 Spec: v1alpha1.ApplicationSetSpec{ 385 Template: v1alpha1.ApplicationSetTemplate{ 386 ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, 387 Spec: argov1alpha1.ApplicationSpec{ 388 Project: "default", 389 Source: &argov1alpha1.ApplicationSource{ 390 RepoURL: "https://github.com/argoproj/argocd-example-apps.git", 391 TargetRevision: "HEAD", 392 Path: "guestbook", 393 }, 394 Destination: argov1alpha1.ApplicationDestination{ 395 Name: "{{clusterName}}", 396 // Server: "{{server}}", 397 Namespace: "guestbook", 398 }, 399 }, 400 }, 401 Generators: []v1alpha1.ApplicationSetGenerator{ 402 { 403 ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{ 404 ConfigMapRef: "my-configmap", 405 Name: "my-placementdecision", 406 RequeueAfterSeconds: &tenSec, 407 }, 408 }, 409 }, 410 }, 411 }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). 412 413 // Update the ApplicationSet template namespace, and verify it updates the Applications 414 When(). 415 DeleteClusterSecret("my-secret2"). 416 Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1})). 417 Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster2})). 418 419 // Delete the ApplicationSet, and verify it deletes the Applications 420 When(). 421 Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster1})) 422 } 423 424 func TestSimpleClusterDecisionResourceGeneratorDeletingClusterFromResource(t *testing.T) { 425 426 expectedAppTemplate := argov1alpha1.Application{ 427 TypeMeta: metav1.TypeMeta{ 428 Kind: application.ApplicationKind, 429 APIVersion: "argoproj.io/v1alpha1", 430 }, 431 ObjectMeta: metav1.ObjectMeta{ 432 Name: "{{name}}-guestbook", 433 Namespace: fixture.TestNamespace(), 434 Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, 435 }, 436 Spec: argov1alpha1.ApplicationSpec{ 437 Project: "default", 438 Source: &argov1alpha1.ApplicationSource{ 439 RepoURL: "https://github.com/argoproj/argocd-example-apps.git", 440 TargetRevision: "HEAD", 441 Path: "guestbook", 442 }, 443 Destination: argov1alpha1.ApplicationDestination{ 444 Name: "{{name}}", 445 Namespace: "guestbook", 446 }, 447 }, 448 } 449 450 expectedAppCluster1 := *expectedAppTemplate.DeepCopy() 451 expectedAppCluster1.Spec.Destination.Name = "cluster1" 452 expectedAppCluster1.ObjectMeta.Name = "cluster1-guestbook" 453 454 expectedAppCluster2 := *expectedAppTemplate.DeepCopy() 455 expectedAppCluster2.Spec.Destination.Name = "cluster2" 456 expectedAppCluster2.ObjectMeta.Name = "cluster2-guestbook" 457 458 clusterList := []interface{}{ 459 map[string]interface{}{ 460 "clusterName": "cluster1", 461 "reason": "argotest", 462 }, 463 map[string]interface{}{ 464 "clusterName": "cluster2", 465 "reason": "argotest", 466 }, 467 } 468 469 clusterListSmall := []interface{}{ 470 map[string]interface{}{ 471 "clusterName": "cluster1", 472 "reason": "argotest", 473 }, 474 } 475 476 Given(t). 477 // Create a ClusterGenerator-based ApplicationSet 478 When(). 479 CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc"). 480 CreateClusterSecret("my-secret2", "cluster2", "https://kubernetes.default.svc"). 481 CreatePlacementRoleAndRoleBinding(). 482 CreatePlacementDecisionConfigMap("my-configmap"). 483 CreatePlacementDecision("my-placementdecision"). 484 StatusUpdatePlacementDecision("my-placementdecision", clusterList). 485 Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ 486 Name: "simple-cluster-generator", 487 }, 488 Spec: v1alpha1.ApplicationSetSpec{ 489 Template: v1alpha1.ApplicationSetTemplate{ 490 ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{name}}-guestbook"}, 491 Spec: argov1alpha1.ApplicationSpec{ 492 Project: "default", 493 Source: &argov1alpha1.ApplicationSource{ 494 RepoURL: "https://github.com/argoproj/argocd-example-apps.git", 495 TargetRevision: "HEAD", 496 Path: "guestbook", 497 }, 498 Destination: argov1alpha1.ApplicationDestination{ 499 Name: "{{clusterName}}", 500 // Server: "{{server}}", 501 Namespace: "guestbook", 502 }, 503 }, 504 }, 505 Generators: []v1alpha1.ApplicationSetGenerator{ 506 { 507 ClusterDecisionResource: &v1alpha1.DuckTypeGenerator{ 508 ConfigMapRef: "my-configmap", 509 Name: "my-placementdecision", 510 RequeueAfterSeconds: &tenSec, 511 }, 512 }, 513 }, 514 }, 515 }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1, expectedAppCluster2})). 516 517 // Update the ApplicationSet template namespace, and verify it updates the Applications 518 When(). 519 StatusUpdatePlacementDecision("my-placementdecision", clusterListSmall). 520 Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppCluster1})). 521 Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster2})). 522 523 // Delete the ApplicationSet, and verify it deletes the Applications 524 When(). 525 Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppCluster1})) 526 }