|
| 1 | +package sequential |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "os" |
| 6 | + "path/filepath" |
| 7 | + |
| 8 | + . "github.com/onsi/ginkgo/v2" |
| 9 | + . "github.com/onsi/gomega" |
| 10 | + |
| 11 | + "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture" |
| 12 | + "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/argocd" |
| 13 | + fixtureUtils "github.com/redhat-developer/gitops-operator/test/openshift/e2e/ginkgo/fixture/utils" |
| 14 | + |
| 15 | + corev1 "k8s.io/api/core/v1" |
| 16 | + k8serrors "k8s.io/apimachinery/pkg/api/errors" |
| 17 | + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" |
| 18 | + "k8s.io/apimachinery/pkg/runtime/schema" |
| 19 | + "sigs.k8s.io/controller-runtime/pkg/client" |
| 20 | +) |
| 21 | + |
| 22 | +var _ = Describe("GitOps Operator Sequential E2E Tests", func() { |
| 23 | + |
| 24 | + Context("1-084_validate_prune_templates", func() { |
| 25 | + var ( |
| 26 | + k8sClient client.Client |
| 27 | + ctx context.Context |
| 28 | + ns *corev1.Namespace |
| 29 | + cleanupFunc func() |
| 30 | + ) |
| 31 | + |
| 32 | + BeforeEach(func() { |
| 33 | + fixture.EnsureSequentialCleanSlate() |
| 34 | + k8sClient, _ = fixtureUtils.GetE2ETestKubeClient() |
| 35 | + ctx = context.Background() |
| 36 | + |
| 37 | + ns, cleanupFunc = fixture.CreateRandomE2ETestNamespaceWithCleanupFunc() |
| 38 | + |
| 39 | + // permissions |
| 40 | + err := k8sClient.Get(ctx, client.ObjectKeyFromObject(ns), ns) |
| 41 | + Expect(err).ToNot(HaveOccurred()) |
| 42 | + |
| 43 | + if ns.Labels == nil { |
| 44 | + ns.Labels = make(map[string]string) |
| 45 | + } |
| 46 | + ns.Labels["argocd.argoproj.io/managed-by"] = "openshift-gitops" |
| 47 | + Expect(k8sClient.Update(ctx, ns)).To(Succeed()) |
| 48 | + }) |
| 49 | + |
| 50 | + AfterEach(func() { |
| 51 | + defer cleanupFunc() |
| 52 | + fixture.OutputDebugOnFail(ns) |
| 53 | + }) |
| 54 | + |
| 55 | + It("validates that resources with duplicate GVKs can be pruned successfully with local sync", func() { |
| 56 | + By("creating a temp dir for git repo") |
| 57 | + workDir, err := os.MkdirTemp("", "gitops-prune-test") |
| 58 | + Expect(err).ToNot(HaveOccurred()) |
| 59 | + DeferCleanup(func() { |
| 60 | + _ = os.RemoveAll(workDir) |
| 61 | + }) |
| 62 | + |
| 63 | + By("writing two OpenShift Templates (duplicate GVKs) to the working dir") |
| 64 | + template1 := `--- |
| 65 | +apiVersion: template.openshift.io/v1 |
| 66 | +kind: Template |
| 67 | +metadata: |
| 68 | + name: redis-template-gitops |
| 69 | + annotations: |
| 70 | + description: "Description" |
| 71 | + iconClass: "icon-redis" |
| 72 | + tags: "database,nosql" |
| 73 | +objects: |
| 74 | +- apiVersion: v1 |
| 75 | + kind: Pod |
| 76 | + metadata: |
| 77 | + name: redis-master |
| 78 | + spec: |
| 79 | + containers: |
| 80 | + - env: |
| 81 | + - name: REDIS_PASSWORD |
| 82 | + value: xyz1234s |
| 83 | + image: dockerfile/redis |
| 84 | + name: master |
| 85 | + ports: |
| 86 | + - containerPort: 6379 |
| 87 | + protocol: TCP |
| 88 | +parameters: |
| 89 | +- description: Password used for Redis authentication |
| 90 | + from: '[A-Z0-9]{8}' |
| 91 | + generate: expression |
| 92 | + name: REDIS_PASSWORD |
| 93 | +labels: |
| 94 | + redis: master |
| 95 | +` |
| 96 | + template2 := `--- |
| 97 | +apiVersion: template.openshift.io/v1 |
| 98 | +kind: Template |
| 99 | +metadata: |
| 100 | + name: redis-template-gitops2 |
| 101 | + annotations: |
| 102 | + description: "Description" |
| 103 | + iconClass: "icon-redis" |
| 104 | + tags: "database,nosql" |
| 105 | +objects: |
| 106 | +- apiVersion: v1 |
| 107 | + kind: Pod |
| 108 | + metadata: |
| 109 | + name: redis-master |
| 110 | + spec: |
| 111 | + containers: |
| 112 | + - env: |
| 113 | + - name: REDIS_PASSWORD |
| 114 | + value: xyz1234s |
| 115 | + image: dockerfile/redis |
| 116 | + name: master |
| 117 | + ports: |
| 118 | + - containerPort: 6379 |
| 119 | + protocol: TCP |
| 120 | +parameters: |
| 121 | +- description: Password used for Redis authentication |
| 122 | + from: '[A-Z0-9]{8}' |
| 123 | + generate: expression |
| 124 | + name: REDIS_PASSWORD |
| 125 | +labels: |
| 126 | + redis: master |
| 127 | +` |
| 128 | + err = os.WriteFile(filepath.Join(workDir, "app-template.yaml"), []byte(template1), 0600) |
| 129 | + Expect(err).ToNot(HaveOccurred()) |
| 130 | + |
| 131 | + err = os.WriteFile(filepath.Join(workDir, "app-template2.yaml"), []byte(template2), 0600) |
| 132 | + Expect(err).ToNot(HaveOccurred()) |
| 133 | + |
| 134 | + By("logging into the Argo CD CLI") |
| 135 | + err = argocd.LogInToDefaultArgoCDInstance() |
| 136 | + Expect(err).ToNot(HaveOccurred(), "Failed to login to Argo CD") |
| 137 | + |
| 138 | + By("creating an Argo CD Application configured to deploy the templates") |
| 139 | + appName := "app-kustomize-" + ns.Name |
| 140 | + app := &unstructured.Unstructured{} |
| 141 | + app.SetGroupVersionKind(schema.GroupVersionKind{Group: "argoproj.io", Version: "v1alpha1", Kind: "Application"}) |
| 142 | + app.SetName(appName) |
| 143 | + app.SetNamespace("openshift-gitops") |
| 144 | + |
| 145 | + // application spec |
| 146 | + Expect(unstructured.SetNestedField(app.Object, "default", "spec", "project")).To(Succeed()) |
| 147 | + Expect(unstructured.SetNestedField(app.Object, "file://"+workDir+".git", "spec", "source", "repoURL")).To(Succeed()) |
| 148 | + Expect(unstructured.SetNestedField(app.Object, ".", "spec", "source", "path")).To(Succeed()) |
| 149 | + Expect(unstructured.SetNestedField(app.Object, "HEAD", "spec", "source", "targetRevision")).To(Succeed()) |
| 150 | + Expect(unstructured.SetNestedField(app.Object, "https://kubernetes.default.svc", "spec", "destination", "server")).To(Succeed()) |
| 151 | + Expect(unstructured.SetNestedField(app.Object, ns.Name, "spec", "destination", "namespace")).To(Succeed()) |
| 152 | + Expect(unstructured.SetNestedStringSlice(app.Object, []string{"PruneLast=true"}, "spec", "syncPolicy", "syncOptions")).To(Succeed()) |
| 153 | + |
| 154 | + Expect(k8sClient.Create(ctx, app)).To(Succeed()) |
| 155 | + DeferCleanup(func() { |
| 156 | + _ = k8sClient.Delete(ctx, app) |
| 157 | + }) |
| 158 | + |
| 159 | + By("syncing the application using the local dir") |
| 160 | + out, err := argocd.RunArgoCDCLI("app", "sync", appName, "--local", workDir, "--timeout", "100") |
| 161 | + Expect(err).ToNot(HaveOccurred(), "Failed to sync app with local flag: %s", out) |
| 162 | + |
| 163 | + By("verifying both templates were created") |
| 164 | + tmplObj := &unstructured.Unstructured{} |
| 165 | + tmplObj.SetGroupVersionKind(schema.GroupVersionKind{Group: "template.openshift.io", Version: "v1", Kind: "Template"}) |
| 166 | + |
| 167 | + Eventually(func() error { |
| 168 | + return k8sClient.Get(ctx, client.ObjectKey{Name: "redis-template-gitops", Namespace: ns.Name}, tmplObj) |
| 169 | + }, "2m", "5s").Should(Succeed()) |
| 170 | + |
| 171 | + Eventually(func() error { |
| 172 | + return k8sClient.Get(ctx, client.ObjectKey{Name: "redis-template-gitops2", Namespace: ns.Name}, tmplObj) |
| 173 | + }, "2m", "5s").Should(Succeed()) |
| 174 | + |
| 175 | + By("deleting one template from the local source directory") |
| 176 | + err = os.Remove(filepath.Join(workDir, "app-template.yaml")) |
| 177 | + Expect(err).ToNot(HaveOccurred()) |
| 178 | + |
| 179 | + By("syncing the application again this time with the prune flag enabled") |
| 180 | + out, err = argocd.RunArgoCDCLI("app", "sync", appName, "--local", workDir, "--prune", "--timeout", "100") |
| 181 | + Expect(err).ToNot(HaveOccurred(), "Failed to sync and prune app: %s", out) |
| 182 | + |
| 183 | + By("verifying the deleted template was pruned from the cluster") |
| 184 | + Eventually(func() bool { |
| 185 | + err := k8sClient.Get(ctx, client.ObjectKey{Name: "redis-template-gitops", Namespace: ns.Name}, tmplObj) |
| 186 | + return k8serrors.IsNotFound(err) |
| 187 | + }, "2m", "5s").Should(BeTrue(), "Expected redis-template-gitops to be pruned, but it still exists") |
| 188 | + |
| 189 | + By("verifying the remaining template still exists") |
| 190 | + err = k8sClient.Get(ctx, client.ObjectKey{Name: "redis-template-gitops2", Namespace: ns.Name}, tmplObj) |
| 191 | + Expect(err).ToNot(HaveOccurred(), "Expected redis-template-gitops2 to still exist") |
| 192 | + }) |
| 193 | + }) |
| 194 | +}) |
0 commit comments