diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index afdfa61822344..3a596a9552d70 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -374,7 +374,7 @@ jobs: ARGOCD_E2E_K3S: "true" ARGOCD_IN_CI: "true" ARGOCD_E2E_APISERVER_PORT: "8088" - ARGOCD_APPLICATION_NAMESPACES: "argocd-e2e-external" + ARGOCD_APPLICATION_NAMESPACES: "argocd-e2e-external,argocd-e2e-external-2" ARGOCD_SERVER: "127.0.0.1:8088" GITHUB_TOKEN: ${{ secrets.E2E_TEST_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} GITLAB_TOKEN: ${{ secrets.E2E_TEST_GITLAB_TOKEN }} diff --git a/Makefile b/Makefile index 4d245b9bf15b5..d4df041fa58e1 100644 --- a/Makefile +++ b/Makefile @@ -438,6 +438,7 @@ start-e2e: test-tools-image start-e2e-local: mod-vendor-local dep-ui-local cli-local kubectl create ns argocd-e2e || true kubectl create ns argocd-e2e-external || true + kubectl create ns argocd-e2e-external-2 || true kubectl config set-context --current --namespace=argocd-e2e kustomize build test/manifests/base | kubectl apply -f - kubectl apply -f https://raw.githubusercontent.com/open-cluster-management/api/a6845f2ebcb186ec26b832f60c988537a58f3859/cluster/v1alpha1/0000_04_clusters.open-cluster-management.io_placementdecisions.crd.yaml @@ -458,8 +459,8 @@ start-e2e-local: mod-vendor-local dep-ui-local cli-local ARGOCD_ZJWT_FEATURE_FLAG=always \ ARGOCD_IN_CI=$(ARGOCD_IN_CI) \ BIN_MODE=$(ARGOCD_BIN_MODE) \ - ARGOCD_APPLICATION_NAMESPACES=argocd-e2e-external \ - ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES=argocd-e2e-external \ + ARGOCD_APPLICATION_NAMESPACES=argocd-e2e-external,argocd-e2e-external-2 \ + ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES=argocd-e2e-external,argocd-e2e-external-2 \ ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS=http://127.0.0.1:8341,http://127.0.0.1:8342,http://127.0.0.1:8343,http://127.0.0.1:8344 \ ARGOCD_E2E_TEST=true \ goreman -f $(ARGOCD_PROCFILE) start ${ARGOCD_START} diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index 385d476752aef..be73c81ca0c3f 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -734,7 +734,7 @@ func (r *ApplicationSetReconciler) createInCluster(ctx context.Context, logCtx * func (r *ApplicationSetReconciler) getCurrentApplications(_ context.Context, applicationSet argov1alpha1.ApplicationSet) ([]argov1alpha1.Application, error) { // TODO: Should this use the context param? var current argov1alpha1.ApplicationList - err := r.Client.List(context.Background(), ¤t, client.MatchingFields{".metadata.controller": applicationSet.Name}) + err := r.Client.List(context.Background(), ¤t, client.MatchingFields{".metadata.controller": applicationSet.Name}, client.InNamespace(applicationSet.Namespace)) if err != nil { return nil, fmt.Errorf("error retrieving applications: %w", err) diff --git a/test/e2e/applicationset_test.go b/test/e2e/applicationset_test.go index f56f9f552e9f6..2fef0ace55583 100644 --- a/test/e2e/applicationset_test.go +++ b/test/e2e/applicationset_test.go @@ -53,6 +53,8 @@ var ( func TestSimpleListGeneratorExternalNamespace(t *testing.T) { + var externalNamespace = string(utils.ArgoCDExternalNamespace) + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", @@ -60,7 +62,7 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) { }, ObjectMeta: metav1.ObjectMeta{ Name: "my-cluster-guestbook", - Namespace: utils.ArgoCDExternalNamespace, + Namespace: externalNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, Spec: argov1alpha1.ApplicationSpec{ @@ -82,10 +84,10 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) { Given(t). // Create a ListGenerator-based ApplicationSet When(). - SwitchToExternalNamespace(). - CreateNamespace(utils.ArgoCDExternalNamespace).Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). + CreateNamespace(externalNamespace).Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ Name: "simple-list-generator-external", - Namespace: utils.ArgoCDExternalNamespace, + Namespace: externalNamespace, }, Spec: v1alpha1.ApplicationSetSpec{ GoTemplate: true, @@ -151,6 +153,191 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) { } +func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) { + + var externalNamespace = string(utils.ArgoCDExternalNamespace) + var externalNamespace2 = string(utils.ArgoCDExternalNamespace2) + + expectedApp := argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: externalNamespace, + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + } + + expectedAppExternalNamespace2 := argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: externalNamespace2, + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + } + + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application + + Given(t). + // Create a ListGenerator-based ApplicationSet + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). + CreateNamespace(externalNamespace2).Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ + Name: "simple-list-generator-external", + Namespace: externalNamespace2, + }, + Spec: v1alpha1.ApplicationSetSpec{ + GoTemplate: true, + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "{{.url}}", + Namespace: "guestbook", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + List: &v1alpha1.ListGenerator{ + Elements: []apiextensionsv1.JSON{{ + Raw: []byte(`{"cluster": "my-cluster","url": "https://kubernetes.default.svc"}`), + }}, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). + CreateNamespace(externalNamespace).Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ + Name: "simple-list-generator-external", + Namespace: externalNamespace, + }, + Spec: v1alpha1.ApplicationSetSpec{ + GoTemplate: true, + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "{{.url}}", + Namespace: "guestbook", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + List: &v1alpha1.ListGenerator{ + Elements: []apiextensionsv1.JSON{{ + Raw: []byte(`{"cluster": "my-cluster","url": "https://kubernetes.default.svc"}`), + }}, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). + Then(). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). + Then(). + // Update the ApplicationSet template namespace, and verify it updates the Applications + When(). + And(func() { + expectedAppNewNamespace = expectedApp.DeepCopy() + expectedAppNewNamespace.Spec.Destination.Namespace = "guestbook2" + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). + Then(). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). + Then(). + // Update the metadata fields in the appset template, and make sure it propagates to the apps + When(). + And(func() { + expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy() + expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"} + expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{ + "label-key": "label-value", + } + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} + appset.Spec.Template.Labels = map[string]string{ + "label-key": "label-value", + } + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). + + // verify the ApplicationSet status conditions were set correctly + Expect(ApplicationSetHasConditions("simple-list-generator-external", ExpectedConditions)). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). + Then(). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). + Then(). + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewMetadata})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). + Then(). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). + When(). + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppExternalNamespace2})) +} + func TestSimpleListGenerator(t *testing.T) { expectedApp := argov1alpha1.Application{ diff --git a/test/e2e/cluster_generator_test.go b/test/e2e/cluster_generator_test.go index 7cac40aa569fb..1d5699e23503d 100644 --- a/test/e2e/cluster_generator_test.go +++ b/test/e2e/cluster_generator_test.go @@ -18,6 +18,8 @@ import ( func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) { + var externalNamespace = string(utils.ArgoCDExternalNamespace) + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", @@ -25,7 +27,7 @@ func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) { }, ObjectMeta: metav1.ObjectMeta{ Name: "cluster1-guestbook", - Namespace: utils.ArgoCDExternalNamespace, + Namespace: externalNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, Spec: argov1alpha1.ApplicationSpec{ @@ -49,8 +51,8 @@ func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) { // Create a ClusterGenerator-based ApplicationSet When(). CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc"). - SwitchToExternalNamespace(). - CreateNamespace(utils.ArgoCDExternalNamespace). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). + CreateNamespace(externalNamespace). Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ Name: "simple-cluster-generator", }, diff --git a/test/e2e/clusterdecisiongenerator_e2e_test.go b/test/e2e/clusterdecisiongenerator_e2e_test.go index 97d1327fe0331..5f0d6ff6ae3c7 100644 --- a/test/e2e/clusterdecisiongenerator_e2e_test.go +++ b/test/e2e/clusterdecisiongenerator_e2e_test.go @@ -19,6 +19,8 @@ var tenSec = int64(10) func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { + var externalNamespace = string(utils.ArgoCDExternalNamespace) + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", @@ -26,7 +28,7 @@ func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { }, ObjectMeta: metav1.ObjectMeta{ Name: "cluster1-guestbook", - Namespace: utils.ArgoCDExternalNamespace, + Namespace: externalNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, Spec: argov1alpha1.ApplicationSpec{ @@ -61,8 +63,8 @@ func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { CreatePlacementDecisionConfigMap("my-configmap"). CreatePlacementDecision("my-placementdecision"). StatusUpdatePlacementDecision("my-placementdecision", clusterList). - CreateNamespace(utils.ArgoCDExternalNamespace). - SwitchToExternalNamespace(). + CreateNamespace(externalNamespace). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ Name: "simple-cluster-generator", }, diff --git a/test/e2e/fixture/applicationsets/actions.go b/test/e2e/fixture/applicationsets/actions.go index 78878bcc24cbc..0b167c2b1a734 100644 --- a/test/e2e/fixture/applicationsets/actions.go +++ b/test/e2e/fixture/applicationsets/actions.go @@ -64,14 +64,14 @@ func (a *Actions) Then() *Consequences { return &Consequences{a.context, a} } -func (a *Actions) SwitchToExternalNamespace() *Actions { - a.context.useExternalNamespace = true - log.Infof("switched to external namespace: %s", utils.ArgoCDExternalNamespace) +func (a *Actions) SwitchToExternalNamespace(namespace utils.ExternalNamespace) *Actions { + a.context.switchToNamespace = namespace + log.Infof("switched to external namespace: %s", namespace) return a } func (a *Actions) SwitchToArgoCDNamespace() *Actions { - a.context.useExternalNamespace = false + a.context.switchToNamespace = "" log.Infof("switched to argocd namespace: %s", utils.ArgoCDNamespace) return a } @@ -216,8 +216,13 @@ func (a *Actions) Create(appSet v1alpha1.ApplicationSet) *Actions { var appSetClientSet dynamic.ResourceInterface - if a.context.useExternalNamespace { - appSetClientSet = fixtureClient.ExternalAppSetClientset + if a.context.switchToNamespace != "" { + externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[utils.ExternalNamespace(a.context.switchToNamespace)] + if !found { + a.lastOutput, a.lastError = "", fmt.Errorf("No external clientset found for %s", a.context.switchToNamespace) + return a + } + appSetClientSet = externalAppSetClientset } else { appSetClientSet = fixtureClient.AppSetClientset } @@ -390,8 +395,13 @@ func (a *Actions) Delete() *Actions { var appSetClientSet dynamic.ResourceInterface - if a.context.useExternalNamespace { - appSetClientSet = fixtureClient.ExternalAppSetClientset + if a.context.switchToNamespace != "" { + externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[utils.ExternalNamespace(a.context.switchToNamespace)] + if !found { + a.lastOutput, a.lastError = "", fmt.Errorf("No external clientset found for %s", a.context.switchToNamespace) + return a + } + appSetClientSet = externalAppSetClientset } else { appSetClientSet = fixtureClient.AppSetClientset } @@ -413,8 +423,12 @@ func (a *Actions) get() (*v1alpha1.ApplicationSet, error) { var appSetClientSet dynamic.ResourceInterface - if a.context.useExternalNamespace { - appSetClientSet = fixtureClient.ExternalAppSetClientset + if a.context.switchToNamespace != "" { + externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[utils.ExternalNamespace(a.context.switchToNamespace)] + if !found { + return nil, fmt.Errorf("No external clientset found for %s", a.context.switchToNamespace) + } + appSetClientSet = externalAppSetClientset } else { appSetClientSet = fixtureClient.AppSetClientset } @@ -460,8 +474,13 @@ func (a *Actions) Update(toUpdate func(*v1alpha1.ApplicationSet)) *Actions { var appSetClientSet dynamic.ResourceInterface - if a.context.useExternalNamespace { - appSetClientSet = fixtureClient.ExternalAppSetClientset + if a.context.switchToNamespace != "" { + externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[utils.ExternalNamespace(a.context.switchToNamespace)] + if !found { + a.lastOutput, a.lastError = "", fmt.Errorf("No external clientset found for %s", a.context.switchToNamespace) + return a + } + appSetClientSet = externalAppSetClientset } else { appSetClientSet = fixtureClient.AppSetClientset } diff --git a/test/e2e/fixture/applicationsets/consequences.go b/test/e2e/fixture/applicationsets/consequences.go index 2672b58fe9317..db614f3cf3075 100644 --- a/test/e2e/fixture/applicationsets/consequences.go +++ b/test/e2e/fixture/applicationsets/consequences.go @@ -77,8 +77,8 @@ func (c *Consequences) app(name string) *v1alpha1.Application { func (c *Consequences) apps() []v1alpha1.Application { var namespace string - if c.context.useExternalNamespace { - namespace = utils.ArgoCDExternalNamespace + if c.context.switchToNamespace != "" { + namespace = string(c.context.switchToNamespace) } else { namespace = fixture.TestNamespace() } @@ -100,8 +100,8 @@ func (c *Consequences) applicationSet(applicationSetName string) *v1alpha1.Appli var appSetClientSet dynamic.ResourceInterface - if c.context.useExternalNamespace { - appSetClientSet = fixtureClient.ExternalAppSetClientset + if c.context.switchToNamespace != "" { + appSetClientSet = fixtureClient.ExternalAppSetClientsets[c.context.switchToNamespace] } else { appSetClientSet = fixtureClient.AppSetClientset } diff --git a/test/e2e/fixture/applicationsets/context.go b/test/e2e/fixture/applicationsets/context.go index d2a0479a62aee..c10b2c99bfe5f 100644 --- a/test/e2e/fixture/applicationsets/context.go +++ b/test/e2e/fixture/applicationsets/context.go @@ -4,6 +4,7 @@ import ( "testing" "time" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" ) @@ -12,9 +13,9 @@ type Context struct { t *testing.T // name is the ApplicationSet's name, created by a Create action - name string - namespace string - useExternalNamespace bool + name string + namespace string + switchToNamespace utils.ExternalNamespace } func Given(t *testing.T) *Context { diff --git a/test/e2e/fixture/applicationsets/utils/fixture.go b/test/e2e/fixture/applicationsets/utils/fixture.go index b81a8875498a0..0074fe76bf5c8 100644 --- a/test/e2e/fixture/applicationsets/utils/fixture.go +++ b/test/e2e/fixture/applicationsets/utils/fixture.go @@ -25,15 +25,21 @@ import ( "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/errors" ) +type ExternalNamespace string + const ( // ArgoCDNamespace is the namespace into which Argo CD and ApplicationSet controller are deployed, // and in which Application resources should be created. ArgoCDNamespace = "argocd-e2e" // ArgoCDExternalNamespace is an external namespace to test additional namespaces - ArgoCDExternalNamespace = "argocd-e2e-external" + ArgoCDExternalNamespace ExternalNamespace = "argocd-e2e-external" + + // ArgoCDExternalNamespace2 is an external namespace to test additional namespaces + ArgoCDExternalNamespace2 ExternalNamespace = "argocd-e2e-external-2" // ApplicationsResourcesNamespace is the namespace into which temporary resources (such as Deployments/Pods/etc) // can be deployed, such as using it as the target namespace in an Application resource. @@ -54,11 +60,11 @@ var ( // E2EFixtureK8sClient contains Kubernetes clients initialized from local k8s configuration type E2EFixtureK8sClient struct { - KubeClientset kubernetes.Interface - DynamicClientset dynamic.Interface - AppClientset appclientset.Interface - AppSetClientset dynamic.ResourceInterface - ExternalAppSetClientset dynamic.ResourceInterface + KubeClientset kubernetes.Interface + DynamicClientset dynamic.Interface + AppClientset appclientset.Interface + AppSetClientset dynamic.ResourceInterface + ExternalAppSetClientsets map[ExternalNamespace]dynamic.ResourceInterface } func GetEnvWithDefault(envName, defaultValue string) string { @@ -91,7 +97,11 @@ func GetE2EFixtureK8sClient() *E2EFixtureK8sClient { } internalClientVars.AppSetClientset = internalClientVars.DynamicClientset.Resource(v1alpha1.SchemeGroupVersion.WithResource("applicationsets")).Namespace(TestNamespace()) - internalClientVars.ExternalAppSetClientset = internalClientVars.DynamicClientset.Resource(v1alpha1.SchemeGroupVersion.WithResource("applicationsets")).Namespace(ArgoCDExternalNamespace) + internalClientVars.ExternalAppSetClientsets = map[ExternalNamespace]dynamic.ResourceInterface{ + ArgoCDExternalNamespace: internalClientVars.DynamicClientset.Resource(v1alpha1.SchemeGroupVersion.WithResource("applicationsets")).Namespace(string(ArgoCDExternalNamespace)), + ArgoCDExternalNamespace2: internalClientVars.DynamicClientset.Resource(v1alpha1.SchemeGroupVersion.WithResource("applicationsets")).Namespace(string(ArgoCDExternalNamespace2)), + } + }) return internalClientVars } @@ -112,9 +122,15 @@ func EnsureCleanState(t *testing.T) { } // Delete the argocd-e2e-external namespace, if it exists - err2 := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), ArgoCDExternalNamespace, v1.DeleteOptions{PropagationPolicy: &policy}) + err2 := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), string(ArgoCDExternalNamespace), v1.DeleteOptions{PropagationPolicy: &policy}) if err2 != nil && !strings.Contains(err2.Error(), "not found") { // 'not found' error is expected - CheckError(err) + CheckError(err2) + } + + // Delete the argocd-e2e-external namespace, if it exists + err3 := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), string(ArgoCDExternalNamespace2), v1.DeleteOptions{PropagationPolicy: &policy}) + if err3 != nil && !strings.Contains(err3.Error(), "not found") { // 'not found' error is expected + CheckError(err3) } // delete resources @@ -177,6 +193,15 @@ func EnsureCleanState(t *testing.T) { func waitForExpectedClusterState() error { fixtureClient := GetE2EFixtureK8sClient() + + SetProjectSpec(fixtureClient, "default", v1alpha1.AppProjectSpec{ + OrphanedResources: nil, + SourceRepos: []string{"*"}, + Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "*"}}, + ClusterResourceWhitelist: []v1.GroupKind{{Group: "*", Kind: "*"}}, + SourceNamespaces: []string{string(ArgoCDExternalNamespace), string(ArgoCDExternalNamespace2)}, + }) + // Wait up to 60 seconds for all the ApplicationSets to delete if err := waitForSuccess(func() error { list, err := fixtureClient.AppSetClientset.List(context.Background(), v1.ListOptions{}) @@ -210,56 +235,45 @@ func waitForExpectedClusterState() error { } // Wait up to 120 seconds for namespace to not exist - if err := waitForSuccess(func() error { - _, err := fixtureClient.KubeClientset.CoreV1().Namespaces().Get(context.Background(), ApplicationsResourcesNamespace, v1.GetOptions{}) - - msg := "" - - if err == nil { - msg = fmt.Sprintf("namespace '%s' still exists, after delete", ApplicationsResourcesNamespace) - } - - if msg == "" && err != nil && strings.Contains(err.Error(), "not found") { - // Success is an error containing 'applicationset-e2e' not found. - return nil - } - - if msg == "" { - msg = err.Error() + for _, namespace := range []string{string(ApplicationsResourcesNamespace), string(ArgoCDExternalNamespace), string(ArgoCDExternalNamespace2)} { + // Wait up to 120 seconds for namespace to not exist + if err := waitForSuccess(func() error { + return cleanUpNamespace(fixtureClient, namespace) + }, time.Now().Add(120*time.Second)); err != nil { + return err } - - return fmt.Errorf(msg) - - }, time.Now().Add(120*time.Second)); err != nil { - return err } - // Wait up to 120 seconds for namespace to not exist - if err := waitForSuccess(func() error { - _, err := fixtureClient.KubeClientset.CoreV1().Namespaces().Get(context.Background(), ArgoCDExternalNamespace, v1.GetOptions{}) + return nil +} - msg := "" +func SetProjectSpec(fixtureClient *E2EFixtureK8sClient, project string, spec v1alpha1.AppProjectSpec) { + proj, err := fixtureClient.AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Get(context.Background(), project, v1.GetOptions{}) + errors.CheckError(err) + proj.Spec = spec + _, err = fixtureClient.AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Update(context.Background(), proj, v1.UpdateOptions{}) + errors.CheckError(err) +} - if err == nil { - msg = fmt.Sprintf("namespace '%s' still exists, after delete", ArgoCDExternalNamespace) - } +func cleanUpNamespace(fixtureClient *E2EFixtureK8sClient, namespace string) error { + _, err := fixtureClient.KubeClientset.CoreV1().Namespaces().Get(context.Background(), namespace, v1.GetOptions{}) - if msg == "" && err != nil && strings.Contains(err.Error(), "not found") { - // Success is an error containing 'applicationset-e2e' not found. - return nil - } + msg := "" - if msg == "" { - msg = err.Error() - } + if err == nil { + msg = fmt.Sprintf("namespace '%s' still exists, after delete", namespace) + } - return fmt.Errorf(msg) + if msg == "" && err != nil && strings.Contains(err.Error(), "not found") { + // Success is an error containing 'applicationset-e2e' not found. + return nil + } - }, time.Now().Add(120*time.Second)); err != nil { - return err + if msg == "" { + msg = err.Error() } - return nil + return fmt.Errorf(msg) } // waitForSuccess waits for the condition to return a non-error value.