github.com/argoproj/argo-cd/v3@v3.2.1/test/e2e/cluster_generator_test.go (about)

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