Browse Source

ArgoCD & Flux e2e suites (#1041)

* feat: add gitops suite

Signed-off-by: Moritz Johner <beller.moritz@googlemail.com>

* feat: add flux tests

Signed-off-by: Moritz Johner <beller.moritz@googlemail.com>

* fix: pin to v1.23 kubectl version to avoid invalid apiVersion issue

see: https://github.com/aws/aws-cli/issues/6920
Signed-off-by: Moritz Johner <beller.moritz@googlemail.com>

* Revert "fix: pin to v1.23 kubectl version to avoid invalid apiVersion issue"

This reverts commit 2f78226cdce1683a0255457b41199d10dd30509f.

Signed-off-by: Moritz Johner <beller.moritz@googlemail.com>
Moritz Johner 4 years ago
parent
commit
8e0a5b96c6
59 changed files with 1761 additions and 89 deletions
  1. 2 2
      .github/workflows/e2e-managed.yml
  2. 3 1
      .gitignore
  3. 1 1
      Makefile
  4. 4 2
      e2e/Dockerfile
  5. 2 1
      e2e/Makefile
  6. 7 6
      e2e/entrypoint.sh
  7. 1 1
      e2e/framework/addon/addon.go
  8. 12 0
      e2e/framework/addon/chart.go
  9. 28 1
      e2e/framework/addon/eso.go
  10. 144 0
      e2e/framework/addon/eso_argocd_application.go
  11. 166 0
      e2e/framework/addon/eso_flux_helm.go
  12. 99 0
      e2e/framework/addon/helmserver.go
  13. 45 0
      e2e/framework/addon/uninstall_eso_crds.go
  14. 0 9
      e2e/framework/framework.go
  15. 2 1
      e2e/framework/testcase.go
  16. 18 0
      e2e/framework/util/util.go
  17. 2 2
      e2e/run.sh
  18. 37 0
      e2e/suites/argocd/argocd.go
  19. 81 0
      e2e/suites/argocd/install.go
  20. 53 0
      e2e/suites/argocd/suite_test.go
  21. 37 0
      e2e/suites/flux/flux.go
  22. 79 0
      e2e/suites/flux/install.go
  23. 53 0
      e2e/suites/flux/suite_test.go
  24. 1 1
      e2e/suite/akeyless/akeyless.go
  25. 0 0
      e2e/suites/provider/cases/akeyless/provider.go
  26. 1 1
      e2e/suite/alibaba/alibaba.go
  27. 0 0
      e2e/suites/provider/cases/alibaba/provider.go
  28. 0 0
      e2e/suites/provider/cases/aws/common.go
  29. 0 0
      e2e/suites/provider/cases/aws/parameterstore/find_by_name.go
  30. 0 0
      e2e/suites/provider/cases/aws/parameterstore/find_by_tags.go
  31. 1 1
      e2e/suite/aws/parameterstore/parameterstore.go
  32. 2 2
      e2e/suite/aws/parameterstore/parameterstore_managed.go
  33. 1 1
      e2e/suite/aws/parameterstore/provider.go
  34. 1 1
      e2e/suite/aws/secretsmanager/provider.go
  35. 1 1
      e2e/suite/aws/secretsmanager/secretsmanager.go
  36. 2 2
      e2e/suite/aws/secretsmanager/secretsmanager_managed.go
  37. 0 0
      e2e/suites/provider/cases/azure/azure_cert.go
  38. 0 0
      e2e/suites/provider/cases/azure/azure_key.go
  39. 1 1
      e2e/suite/azure/azure_secret.go
  40. 5 3
      e2e/suite/azure/provider.go
  41. 1 1
      e2e/suite/common/common.go
  42. 0 8
      e2e/suite/common/find_by_name.go
  43. 0 8
      e2e/suite/common/find_by_tags.go
  44. 106 0
      e2e/suites/provider/cases/fake/provider.go
  45. 1 1
      e2e/suite/gcp/gcp.go
  46. 1 1
      e2e/suite/gcp/gcp_managed.go
  47. 0 0
      e2e/suites/provider/cases/gcp/provider.go
  48. 1 1
      e2e/suite/gitlab/gitlab.go
  49. 0 0
      e2e/suites/provider/cases/gitlab/provider.go
  50. 6 6
      e2e/suite/import.go
  51. 1 1
      e2e/suite/oracle/oracle.go
  52. 0 0
      e2e/suites/provider/cases/oracle/provider.go
  53. 0 0
      e2e/suites/provider/cases/template/provider.go
  54. 0 0
      e2e/suites/provider/cases/template/template.go
  55. 3 2
      e2e/suite/vault/provider.go
  56. 1 1
      e2e/suite/vault/vault.go
  57. 8 4
      e2e/e2e_test.go
  58. 81 7
      go.mod
  59. 659 7
      go.sum

+ 2 - 2
.github/workflows/e2e-managed.yml

@@ -191,8 +191,8 @@ jobs:
       run: |
         export PATH=$PATH:$(go env GOPATH)/bin
         PROVIDER=${{github.event.client_payload.slash_command.args.named.provider}}
-        go get github.com/onsi/ginkgo/v2/ginkgo
-        make test.e2e.managed GINKGO_LABELS="${PROVIDER}"
+        go install -mod=mod github.com/onsi/ginkgo/v2/ginkgo
+        make test.e2e.managed GINKGO_LABELS="${PROVIDER}" TEST_SUITES="provider"
 
     - name: Destroy TF
       if: always()

+ 3 - 1
.gitignore

@@ -20,7 +20,9 @@ deploy/charts/external-secrets/templates/crds/*.yaml
 
 site/
 e2e/k8s/deploy
-e2e/e2e.test
+e2e/suites/argocd/argocd.test
+e2e/suites/flux/flux.test
+e2e/suites/provider/provider.test
 
 # tf ignores
 # Local .terraform directories

+ 1 - 1
Makefile

@@ -82,7 +82,7 @@ license.check: golicenses.check
 	 grep -v -E '${LICENSES}' | \
 	 tr "," " " | awk '{print "Invalid License " $$3 " for dependency " $$1 }'|| ok=1; \
 	 if [[ $$ok -eq 1 ]]; then $(OK) dependencies are compliant; else $(FAIL); fi
-	 
+
 check-diff: reviewable ## Ensure branch is clean.
 	@$(INFO) checking that branch is clean
 	@test -z "$$(git status --porcelain)" || (echo "$$(git status --porcelain)" && $(FAIL))

+ 4 - 2
e2e/Dockerfile

@@ -1,7 +1,7 @@
 ARG GO_VERSION=1.17
 FROM golang:$GO_VERSION-buster as builder
 
-ENV KUBECTL_VERSION="v1.21.2"
+ENV KUBECTL_VERSION="v1.23.6"
 ENV HELM_VERSION="v3.7.1"
 
 RUN go get -u github.com/onsi/ginkgo/v2/ginkgo
@@ -24,7 +24,9 @@ COPY --from=builder /usr/local/bin/kubectl /usr/local/bin/
 COPY --from=builder /usr/local/bin/helm /usr/local/bin/
 
 COPY entrypoint.sh                  /entrypoint.sh
-COPY e2e.test                       /e2e.test
+COPY suites/provider/provider.test  /provider.test
+COPY suites/argocd/argocd.test      /argocd.test
+COPY suites/flux/flux.test          /flux.test
 COPY k8s                            /k8s
 
 CMD [ "/entrypoint.sh" ]

+ 2 - 1
e2e/Makefile

@@ -7,6 +7,7 @@ BUILD_ARGS     ?=
 
 export E2E_IMAGE_REGISTRY ?= ghcr.io/external-secrets/external-secrets-e2e
 export GINKGO_LABELS ?= !managed
+export TEST_SUITES ?= provider flux argocd
 
 start-kind: ## Start kind cluster
 	kind create cluster \
@@ -38,7 +39,7 @@ test.managed: e2e-image ## Run e2e tests against current kube context
 	./run.sh
 
 e2e-bin:
-	CGO_ENABLED=0 go run github.com/onsi/ginkgo/v2/ginkgo build .
+	CGO_ENABLED=0 go run github.com/onsi/ginkgo/v2/ginkgo build ./suites/...
 
 e2e-image: e2e-bin
 	-rm -rf ./k8s/deploy

+ 7 - 6
e2e/entrypoint.sh

@@ -41,10 +41,11 @@ ginkgo_args=(
   "-timeout=45m"
 )
 
-kubectl apply -f /k8s/deploy/crds
+for SUITE in ${TEST_SUITES}; do
+  echo -e "${BGREEN}Running suite ${SUITE} (LABELS=${GINKGO_LABELS})...${NC}"
+  ACK_GINKGO_RC=true ginkgo "${ginkgo_args[@]}" \
+    -label-filter="${GINKGO_LABELS}"            \
+    -nodes="${E2E_NODES}"                       \
+    /${SUITE}.test
+done
 
-echo -e "${BGREEN}Running e2e test suite (LABELS=${GINKGO_LABELS})...${NC}"
-ACK_GINKGO_RC=true ginkgo "${ginkgo_args[@]}" \
-  -label-filter="${GINKGO_LABELS}"            \
-  -nodes="${E2E_NODES}"                       \
-  /e2e.test

+ 1 - 1
e2e/framework/addon/addon.go

@@ -50,7 +50,7 @@ type Addon interface {
 func InstallGlobalAddon(addon Addon, cfg *Config) {
 	globalAddons = append(globalAddons, addon)
 
-	ginkgo.By("installing addon")
+	ginkgo.By("installing global addon")
 	err := addon.Setup(cfg)
 	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 

+ 12 - 0
e2e/framework/addon/chart.go

@@ -33,6 +33,7 @@ type HelmChart struct {
 	Repo         ChartRepo
 	Vars         []StringTuple
 	Values       []string
+	Args         []string
 
 	config *Config
 }
@@ -81,6 +82,8 @@ func (c *HelmChart) Install() error {
 		args = append(args, "--set", fmt.Sprintf("%s=%s", s.Key, s.Value))
 	}
 
+	args = append(args, c.Args...)
+
 	var sout, serr bytes.Buffer
 	log.Logf("installing chart with args: %+q", args)
 	cmd := exec.Command("helm", args...)
@@ -174,3 +177,12 @@ func (c *HelmChart) Logs() error {
 	}
 	return nil
 }
+
+func (c *HelmChart) HasVar(key, value string) bool {
+	for _, v := range c.Vars {
+		if v.Key == key && v.Value == value {
+			return true
+		}
+	}
+	return false
+}

+ 28 - 1
e2e/framework/addon/eso.go

@@ -24,6 +24,8 @@ type ESO struct {
 	*HelmChart
 }
 
+const installCRDsVar = "installCRDs"
+
 func NewESO(mutators ...MutationFunc) *ESO {
 	eso := &ESO{
 		&HelmChart{
@@ -60,7 +62,7 @@ func NewESO(mutators ...MutationFunc) *ESO {
 					Value: os.Getenv("VERSION"),
 				},
 				{
-					Key:   "installCRDs",
+					Key:   installCRDsVar,
 					Value: "false",
 				},
 			},
@@ -139,6 +141,19 @@ func WithControllerClass(class string) MutationFunc {
 	}
 }
 
+// By default ESO is installed without CRDs
+// when using WithCRDs() the CRDs will be installed before
+// and uninstalled after use.
+func WithCRDs() MutationFunc {
+	return func(eso *ESO) {
+		for i, v := range eso.HelmChart.Vars {
+			if v.Key == installCRDsVar {
+				eso.HelmChart.Vars[i].Value = "true"
+			}
+		}
+	}
+}
+
 func (l *ESO) Install() error {
 	By("Installing eso\n")
 	err := l.HelmChart.Install()
@@ -148,3 +163,15 @@ func (l *ESO) Install() error {
 
 	return nil
 }
+
+func (l *ESO) Uninstall() error {
+	By("Uninstalling eso")
+	err := l.HelmChart.Uninstall()
+	if err != nil {
+		return err
+	}
+	if l.HelmChart.HasVar(installCRDsVar, "true") {
+		return uninstallCRDs(l.config)
+	}
+	return nil
+}

+ 144 - 0
e2e/framework/addon/eso_argocd_application.go

@@ -0,0 +1,144 @@
+/*
+Copyright 2020 The cert-manager Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package addon
+
+import (
+	"bytes"
+	"context"
+	"crypto/tls"
+	"net/http"
+	"time"
+
+	argoapp "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
+	"github.com/onsi/ginkgo/v2"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/wait"
+)
+
+// HelmChart installs the specified Chart into the cluster.
+type ArgoCDApplication struct {
+	Name                 string
+	Namespace            string
+	DestinationNamespace string
+	HelmChart            string
+	HelmRepo             string
+	HelmRevision         string
+	HelmValues           string
+
+	config *Config
+}
+
+// Setup stores the config in an internal field
+// to get access to the k8s api in orderto fetch logs.
+func (c *ArgoCDApplication) Setup(cfg *Config) error {
+	c.config = cfg
+	return nil
+}
+
+// Install adds the chart repo and installs the helm chart.
+func (c *ArgoCDApplication) Install() error {
+	app := &argoapp.Application{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      c.Name,
+			Namespace: c.Namespace,
+			Annotations: map[string]string{
+				"argocd.argoproj.io/refresh": "hard",
+			},
+		},
+		Spec: argoapp.ApplicationSpec{
+			Project: "default",
+			SyncPolicy: &argoapp.SyncPolicy{
+				Automated: &argoapp.SyncPolicyAutomated{
+					Prune:    true,
+					SelfHeal: true,
+				},
+				SyncOptions: argoapp.SyncOptions{
+					"CreateNamespace=true",
+				},
+			},
+			Source: argoapp.ApplicationSource{
+				Chart:          c.HelmChart,
+				RepoURL:        c.HelmRepo,
+				TargetRevision: c.HelmRevision,
+				Helm: &argoapp.ApplicationSourceHelm{
+					ReleaseName: c.Name,
+					Values:      c.HelmValues,
+				},
+			},
+			Destination: argoapp.ApplicationDestination{
+				Server:    "https://kubernetes.default.svc",
+				Namespace: c.DestinationNamespace,
+			},
+		},
+	}
+	err := c.config.CRClient.Create(context.Background(), app)
+	if err != nil {
+		return err
+	}
+
+	// wait for app to become ready
+	err = wait.PollImmediate(time.Second*5, time.Minute*10, func() (bool, error) {
+		var app argoapp.Application
+		err := c.config.CRClient.Get(context.Background(), types.NamespacedName{
+			Name:      c.Name,
+			Namespace: c.Namespace,
+		}, &app)
+		if err != nil {
+			return false, nil
+		}
+		return app.Status.Sync.Status == argoapp.SyncStatusCodeSynced, nil
+	})
+	if err != nil {
+		return err
+	}
+
+	// we have to wait for the webhook to become ready
+	tr := &http.Transport{
+		// nolint:gosec
+		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+	}
+	client := &http.Client{Transport: tr}
+	return wait.PollImmediate(time.Second, time.Minute*5, func() (bool, error) {
+		const payload = `{"apiVersion": "apiextensions.k8s.io/v1","kind": "ConversionReview","request": {}}`
+		res, err := client.Post("https://external-secrets-webhook.external-secrets.svc.cluster.local/convert", "application/json", bytes.NewBufferString(payload))
+		if err != nil {
+			return false, nil
+		}
+		defer res.Body.Close()
+		ginkgo.GinkgoWriter.Printf("conversion res: %d", res.StatusCode)
+		return res.StatusCode == http.StatusOK, nil
+	})
+}
+
+// Uninstall removes the chart aswell as the repo.
+func (c *ArgoCDApplication) Uninstall() error {
+	err := c.config.CRClient.Delete(context.Background(), &argoapp.Application{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      c.Name,
+			Namespace: c.Namespace,
+		},
+	})
+	if err != nil {
+		return err
+	}
+	err = uninstallCRDs(c.config)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (c *ArgoCDApplication) Logs() error {
+	return nil
+}

+ 166 - 0
e2e/framework/addon/eso_flux_helm.go

@@ -0,0 +1,166 @@
+/*
+Copyright 2020 The cert-manager Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package addon
+
+import (
+	"bytes"
+	"context"
+	"crypto/tls"
+	"net/http"
+	"time"
+
+	fluxhelm "github.com/fluxcd/helm-controller/api/v2beta1"
+	"github.com/fluxcd/pkg/apis/meta"
+	fluxsrc "github.com/fluxcd/source-controller/api/v1beta2"
+	"github.com/onsi/ginkgo/v2"
+	v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/wait"
+)
+
+const fluxNamespace = "flux-system"
+
+// HelmChart installs the specified Chart into the cluster.
+type FluxHelmRelease struct {
+	Name            string
+	Namespace       string
+	TargetNamespace string
+	HelmChart       string
+	HelmRepo        string
+	HelmRevision    string
+	HelmValues      string
+
+	config *Config
+}
+
+// Setup stores the config in an internal field
+// to get access to the k8s api in orderto fetch logs.
+func (c *FluxHelmRelease) Setup(cfg *Config) error {
+	c.config = cfg
+	return nil
+}
+
+// Install adds the chart repo and installs the helm chart.
+func (c *FluxHelmRelease) Install() error {
+	app := &fluxsrc.HelmRepository{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      c.Name,
+			Namespace: fluxNamespace,
+		},
+		Spec: fluxsrc.HelmRepositorySpec{
+			URL: c.HelmRepo,
+		},
+	}
+	err := c.config.CRClient.Create(context.Background(), app)
+	if err != nil {
+		return err
+	}
+
+	hr := &fluxhelm.HelmRelease{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      c.Name,
+			Namespace: c.Namespace,
+		},
+		Spec: fluxhelm.HelmReleaseSpec{
+			ReleaseName:     c.Name,
+			TargetNamespace: c.TargetNamespace,
+			Values: &v1.JSON{
+				Raw: []byte(c.HelmValues),
+			},
+			Install: &fluxhelm.Install{
+				CreateNamespace: true,
+				Remediation: &fluxhelm.InstallRemediation{
+					Retries: -1,
+				},
+			},
+			Chart: fluxhelm.HelmChartTemplate{
+				Spec: fluxhelm.HelmChartTemplateSpec{
+					Version: c.HelmRevision,
+					Chart:   c.HelmChart,
+					SourceRef: fluxhelm.CrossNamespaceObjectReference{
+						Kind:      "HelmRepository",
+						Name:      c.Name,
+						Namespace: fluxNamespace,
+					},
+				},
+			},
+		},
+	}
+	err = c.config.CRClient.Create(context.Background(), hr)
+	if err != nil {
+		return err
+	}
+
+	// wait for app to become ready
+	err = wait.PollImmediate(time.Second*5, time.Minute*3, func() (bool, error) {
+		var hr fluxhelm.HelmRelease
+		err := c.config.CRClient.Get(context.Background(), types.NamespacedName{
+			Name:      c.Name,
+			Namespace: c.Namespace,
+		}, &hr)
+		if err != nil {
+			return false, nil
+		}
+		for _, cond := range hr.GetConditions() {
+			ginkgo.GinkgoWriter.Printf("check condition: %s=%s: %s\n", cond.Type, cond.Status, cond.Message)
+			if cond.Type == meta.ReadyCondition && cond.Status == metav1.ConditionTrue {
+				return true, nil
+			}
+		}
+		return false, nil
+	})
+	if err != nil {
+		return err
+	}
+
+	// we have to wait for the webhook to become ready
+	tr := &http.Transport{
+		// nolint:gosec
+		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+	}
+	client := &http.Client{Transport: tr}
+	return wait.PollImmediate(time.Second, time.Minute*5, func() (bool, error) {
+		const payload = `{"apiVersion": "apiextensions.k8s.io/v1","kind": "ConversionReview","request": {}}`
+		res, err := client.Post("https://external-secrets-webhook.external-secrets.svc.cluster.local/convert", "application/json", bytes.NewBufferString(payload))
+		if err != nil {
+			return false, nil
+		}
+		defer res.Body.Close()
+		ginkgo.GinkgoWriter.Printf("conversion res: %d", res.StatusCode)
+		return res.StatusCode == http.StatusOK, nil
+	})
+}
+
+// Uninstall removes the chart aswell as the repo.
+func (c *FluxHelmRelease) Uninstall() error {
+	err := c.config.CRClient.Delete(context.Background(), &fluxhelm.HelmRelease{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      c.Name,
+			Namespace: c.Namespace,
+		},
+	})
+	if err != nil {
+		return err
+	}
+	return c.config.CRClient.Delete(context.Background(), &fluxsrc.HelmRepository{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      c.Name,
+			Namespace: fluxNamespace,
+		},
+	})
+}
+
+func (c *FluxHelmRelease) Logs() error {
+	return nil
+}

+ 99 - 0
e2e/framework/addon/helmserver.go

@@ -0,0 +1,99 @@
+/*
+Copyright 2020 The cert-manager Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package addon
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"os"
+	"os/exec"
+
+	v1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/util/intstr"
+)
+
+type HelmServer struct {
+	ChartDir      string
+	ChartRevision string
+
+	config   *Config
+	srv      *http.Server
+	serveDir string
+}
+
+func (s *HelmServer) Setup(config *Config) error {
+	s.config = config
+	var err error
+	s.serveDir, err = os.MkdirTemp("", "e2e-helm")
+	if err != nil {
+		return err
+	}
+
+	// nolint:gosec
+	cmd := exec.Command("helm", "package", s.ChartDir, "--version", s.ChartRevision)
+	cmd.Dir = s.serveDir
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("unable to package helm chart: %w %s", err, string(out))
+	}
+
+	cmd = exec.Command("helm", "repo", "index", ".")
+	cmd.Dir = s.serveDir
+	out, err = cmd.CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("unable to create helm index: %w %s", err, string(out))
+	}
+
+	_, err = s.config.KubeClientSet.CoreV1().Services("default").Create(context.Background(), &v1.Service{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: "e2e-helmserver",
+		},
+		Spec: v1.ServiceSpec{
+			Selector: map[string]string{
+				// set via e2e/run.sh
+				"app": "eso-e2e",
+			},
+			Ports: []v1.ServicePort{
+				{
+					Name:       "http",
+					Port:       80,
+					TargetPort: intstr.FromInt(3000),
+				},
+			}},
+	}, metav1.CreateOptions{})
+	return err
+}
+
+func (s *HelmServer) Install() error {
+	fs := http.FileServer(http.Dir(s.serveDir))
+	http.Handle("/", fs)
+	s.srv = &http.Server{Addr: ":3000"}
+	go func() {
+		_ = s.srv.ListenAndServe()
+	}()
+	return nil
+}
+
+func (s *HelmServer) Logs() error {
+	return nil
+}
+
+func (s *HelmServer) Uninstall() error {
+	err := s.config.KubeClientSet.CoreV1().Services("default").Delete(context.Background(), "e2e-helmserver", metav1.DeleteOptions{})
+	if err != nil {
+		return err
+	}
+	return s.srv.Close()
+}

+ 45 - 0
e2e/framework/addon/uninstall_eso_crds.go

@@ -0,0 +1,45 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package addon
+
+import (
+	"context"
+
+	"github.com/onsi/ginkgo/v2"
+	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+func uninstallCRDs(cfg *Config) error {
+	ginkgo.By("Uninstalling eso CRDs")
+	for _, crdName := range []string{
+		"clusterexternalsecrets.external-secrets.io",
+		"clustersecretstores.external-secrets.io",
+		"externalsecrets.external-secrets.io",
+		"secretstores.external-secrets.io",
+	} {
+		crd := &apiextensionsv1.CustomResourceDefinition{
+			ObjectMeta: metav1.ObjectMeta{
+				Name: crdName,
+			},
+		}
+		err := cfg.CRClient.Delete(context.Background(), crd, &client.DeleteOptions{})
+		if err != nil && !apierrors.IsNotFound(err) {
+			return err
+		}
+	}
+	return nil
+}

+ 0 - 9
e2e/framework/framework.go

@@ -22,23 +22,14 @@ import (
 	. "github.com/onsi/gomega"
 	api "k8s.io/api/core/v1"
 	"k8s.io/client-go/kubernetes"
-	kscheme "k8s.io/client-go/kubernetes/scheme"
 	"k8s.io/client-go/rest"
 	crclient "sigs.k8s.io/controller-runtime/pkg/client"
 
-	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
-	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework/addon"
 	"github.com/external-secrets/external-secrets/e2e/framework/log"
 	"github.com/external-secrets/external-secrets/e2e/framework/util"
 )
 
-func init() {
-	_ = kscheme.AddToScheme(util.Scheme)
-	_ = esv1beta1.AddToScheme(util.Scheme)
-	_ = esv1alpha1.AddToScheme(util.Scheme)
-}
-
 type Framework struct {
 	BaseName string
 

+ 2 - 1
e2e/framework/testcase.go

@@ -15,6 +15,7 @@ package framework
 
 import (
 	"context"
+	"time"
 
 	//nolint
 	. "github.com/onsi/gomega"
@@ -93,7 +94,6 @@ func TableFunc(f *Framework, prov SecretStoreProvider) func(...func(*TestCase))
 		}
 
 		Expect(err).ToNot(HaveOccurred())
-
 		tc.AfterSync(prov, secret)
 	}
 }
@@ -108,6 +108,7 @@ func makeDefaultTestCase(f *Framework) *TestCase {
 				Namespace: f.Namespace.Name,
 			},
 			Spec: esv1beta1.ExternalSecretSpec{
+				RefreshInterval: &metav1.Duration{Duration: time.Second * 5},
 				SecretStoreRef: esv1beta1.SecretStoreRef{
 					Name: f.Namespace.Name,
 				},

+ 18 - 0
e2e/framework/util/util.go

@@ -21,9 +21,14 @@ import (
 	"os"
 	"time"
 
+	argoapp "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
+	fluxhelm "github.com/fluxcd/helm-controller/api/v2beta1"
+	fluxsrc "github.com/fluxcd/source-controller/api/v1beta2"
+
 	// nolint
 	. "github.com/onsi/ginkgo/v2"
 	v1 "k8s.io/api/core/v1"
+	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -34,10 +39,23 @@ import (
 	"k8s.io/client-go/tools/clientcmd"
 	"k8s.io/client-go/tools/remotecommand"
 	crclient "sigs.k8s.io/controller-runtime/pkg/client"
+
+	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 )
 
 var Scheme = runtime.NewScheme()
 
+func init() {
+	_ = scheme.AddToScheme(Scheme)
+	_ = esv1beta1.AddToScheme(Scheme)
+	_ = esv1alpha1.AddToScheme(Scheme)
+	_ = argoapp.AddToScheme(Scheme)
+	_ = fluxhelm.AddToScheme(Scheme)
+	_ = fluxsrc.AddToScheme(Scheme)
+	_ = apiextensionsv1.AddToScheme(Scheme)
+}
+
 const (
 	// How often to poll for conditions.
 	Poll = 2 * time.Second

+ 2 - 2
e2e/run.sh

@@ -45,14 +45,13 @@ until kubectl get secret | grep -q -e ^external-secrets-e2e-token; do \
   sleep 3; \
 done
 
-kubectl apply -f ${DIR}/k8s/deploy/crds
-
 echo -e "Starting the e2e test pod ${E2E_IMAGE_REGISTRY}:${VERSION}"
 
 kubectl run --rm \
   --attach \
   --restart=Never \
   --pod-running-timeout=5m \
+  --labels="app=eso-e2e" \
   --env="GINKGO_LABELS=${GINKGO_LABELS:-.*}" \
   --env="GCP_SM_SA_JSON=${GCP_SM_SA_JSON:-}" \
   --env="GCP_PROJECT_ID=${GCP_PROJECT_ID:-}" \
@@ -80,5 +79,6 @@ kubectl run --rm \
   --env="ORACLE_KEY=${ORACLE_KEY:-}" \
   --env="IMAGE_REGISTRY=${IMAGE_REGISTRY}" \
   --env="VERSION=${VERSION}" \
+  --env="TEST_SUITES=${TEST_SUITES}" \
   --overrides='{ "apiVersion": "v1", "spec":{"serviceAccountName": "external-secrets-e2e"}}' \
   e2e --image=${E2E_IMAGE_REGISTRY}:${VERSION}

+ 37 - 0
e2e/suites/argocd/argocd.go

@@ -0,0 +1,37 @@
+/*
+Copyright 2020 The cert-manager Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package argocd
+
+import (
+
+	// nolint
+	. "github.com/onsi/ginkgo/v2"
+
+	"github.com/external-secrets/external-secrets/e2e/framework"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/fake"
+)
+
+var _ = Describe("argocd", Label("argocd"), func() {
+	f := framework.New("argocd")
+	prov := fake.NewProvider(f)
+
+	DescribeTable("sync secrets", framework.TableFunc(f, prov),
+		Entry(common.SimpleDataSync(f)),
+		Entry(common.JSONDataFromSync(f)),
+		Entry(common.SSHKeySync(f)),
+		Entry(common.SyncWithoutTargetName(f)),
+		Entry(common.SyncV1Alpha1(f)),
+		Entry(common.DeletionPolicyDelete(f)),
+	)
+})

+ 81 - 0
e2e/suites/argocd/install.go

@@ -0,0 +1,81 @@
+/*
+Copyright 2020 The cert-manager Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package argocd
+
+import (
+	"fmt"
+	"os"
+
+	// nolint
+	. "github.com/onsi/ginkgo/v2"
+
+	"github.com/external-secrets/external-secrets/e2e/framework/addon"
+)
+
+const (
+	helmChartRevision = "0.0.0-e2e"
+)
+
+func installArgo(cfg *addon.Config) {
+	By("installing argocd")
+	addon.InstallGlobalAddon(&addon.HelmChart{
+		Namespace:    "argocd",
+		ReleaseName:  "argocd",
+		Chart:        "argo-cd/argo-cd",
+		ChartVersion: "3.35.4",
+		Repo: addon.ChartRepo{
+			Name: "argo-cd",
+			URL:  "https://argoproj.github.io/argo-helm",
+		},
+		Vars: []addon.StringTuple{
+			{
+				Key:   "controller.args.appResyncPeriod",
+				Value: "15",
+			},
+		},
+		Args: []string{"--create-namespace"},
+	}, cfg)
+}
+
+func installESO(cfg *addon.Config) {
+	By("installing helm http server")
+	repo := os.Getenv("IMAGE_REGISTRY")
+	tag := os.Getenv("VERSION")
+	addon.InstallGlobalAddon(&addon.HelmServer{
+		ChartDir:      "/k8s/deploy/charts/external-secrets",
+		ChartRevision: helmChartRevision,
+	}, cfg)
+
+	By("installing eso through argo app")
+	addon.InstallGlobalAddon(&addon.ArgoCDApplication{
+		Name:                 "external-secrets",
+		Namespace:            "argocd",
+		DestinationNamespace: "external-secrets",
+		HelmChart:            "external-secrets",
+		HelmRepo:             "http://e2e-helmserver.default.svc.cluster.local",
+		HelmRevision:         helmChartRevision,
+		HelmValues: fmt.Sprintf(`
+installCRDs: true
+image:
+  repository: %s
+  tag: %s
+webhook:
+  image:
+    repository: %s
+    tag: %s
+certController:
+  image:
+    repository: %s
+    tag: %s`, repo, tag, repo, tag, repo, tag),
+	}, cfg)
+}

+ 53 - 0
e2e/suites/argocd/suite_test.go

@@ -0,0 +1,53 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package argocd
+
+import (
+	"testing"
+
+	// nolint
+	. "github.com/onsi/ginkgo/v2"
+
+	// nolint
+	. "github.com/onsi/gomega"
+
+	"github.com/external-secrets/external-secrets/e2e/framework/addon"
+	"github.com/external-secrets/external-secrets/e2e/framework/util"
+)
+
+var _ = SynchronizedBeforeSuite(func() []byte {
+	cfg := &addon.Config{}
+	cfg.KubeConfig, cfg.KubeClientSet, cfg.CRClient = util.NewConfig()
+	installArgo(cfg)
+	installESO(cfg)
+	return nil
+}, func([]byte) {
+	// noop
+})
+
+var _ = SynchronizedAfterSuite(func() {
+	// noop
+}, func() {
+	By("Cleaning up global addons")
+	addon.UninstallGlobalAddons()
+	if CurrentSpecReport().Failed() {
+		addon.PrintLogs()
+	}
+})
+
+func TestE2E(t *testing.T) {
+	NewWithT(t)
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "external-secrets argocd e2e suite", Label("argocd"))
+}

+ 37 - 0
e2e/suites/flux/flux.go

@@ -0,0 +1,37 @@
+/*
+Copyright 2020 The cert-manager Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package flux
+
+import (
+
+	// nolint
+	. "github.com/onsi/ginkgo/v2"
+
+	"github.com/external-secrets/external-secrets/e2e/framework"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/fake"
+)
+
+var _ = Describe("flux", Label("flux"), func() {
+	f := framework.New("flux")
+	prov := fake.NewProvider(f)
+
+	DescribeTable("sync secrets", framework.TableFunc(f, prov),
+		Entry(common.SimpleDataSync(f)),
+		Entry(common.JSONDataFromSync(f)),
+		Entry(common.SSHKeySync(f)),
+		Entry(common.SyncWithoutTargetName(f)),
+		Entry(common.SyncV1Alpha1(f)),
+		Entry(common.DeletionPolicyDelete(f)),
+	)
+})

+ 79 - 0
e2e/suites/flux/install.go

@@ -0,0 +1,79 @@
+/*
+Copyright 2020 The cert-manager Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+    http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package flux
+
+import (
+	"fmt"
+	"os"
+	"os/exec"
+
+	// nolint
+	. "github.com/onsi/ginkgo/v2"
+
+	// nolint
+	. "github.com/onsi/gomega"
+
+	"github.com/external-secrets/external-secrets/e2e/framework/addon"
+)
+
+const (
+	helmChartRevision = "0.0.0-e2e"
+)
+
+func installFlux() {
+	By("installing flux")
+	fluxVersion := "v0.29.3"
+	url := fmt.Sprintf("https://github.com/fluxcd/flux2/releases/download/%s/install.yaml", fluxVersion)
+	cmd := exec.Command("kubectl", "apply", "-f", url)
+	out, err := cmd.CombinedOutput()
+	Expect(err).ToNot(HaveOccurred(), string(out))
+}
+
+func installESO(cfg *addon.Config) {
+	By("installing helm http server")
+	addon.InstallGlobalAddon(&addon.HelmServer{
+		ChartDir:      "/k8s/deploy/charts/external-secrets",
+		ChartRevision: helmChartRevision,
+	}, cfg)
+
+	By("installing eso through flux helmrelease app")
+	repo := os.Getenv("IMAGE_REGISTRY")
+	tag := os.Getenv("VERSION")
+	addon.InstallGlobalAddon(&addon.FluxHelmRelease{
+		Name:            "external-secrets",
+		Namespace:       "flux-system",
+		TargetNamespace: "external-secrets",
+		HelmChart:       "external-secrets",
+		HelmRepo:        "http://e2e-helmserver.default.svc.cluster.local",
+		HelmRevision:    helmChartRevision,
+		HelmValues: fmt.Sprintf(`{
+			"installCRDs": true,
+			"image": {
+			  "repository": "%s",
+			  "tag": "%s"
+			},
+			"webhook": {
+			  "image": {
+				"repository": "%s",
+				"tag": "%s"
+			  }
+			},
+			"certController": {
+			  "image": {
+				"repository": "%s",
+				"tag": "%s"
+			  }
+			}
+		  }`, repo, tag, repo, tag, repo, tag),
+	}, cfg)
+}

+ 53 - 0
e2e/suites/flux/suite_test.go

@@ -0,0 +1,53 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package flux
+
+import (
+	"testing"
+
+	// nolint
+	. "github.com/onsi/ginkgo/v2"
+
+	// nolint
+	. "github.com/onsi/gomega"
+
+	"github.com/external-secrets/external-secrets/e2e/framework/addon"
+	"github.com/external-secrets/external-secrets/e2e/framework/util"
+)
+
+var _ = SynchronizedBeforeSuite(func() []byte {
+	cfg := &addon.Config{}
+	cfg.KubeConfig, cfg.KubeClientSet, cfg.CRClient = util.NewConfig()
+	installFlux()
+	installESO(cfg)
+	return nil
+}, func([]byte) {
+	// noop
+})
+
+var _ = SynchronizedAfterSuite(func() {
+	// noop
+}, func() {
+	By("Cleaning up global addons")
+	addon.UninstallGlobalAddons()
+	if CurrentSpecReport().Failed() {
+		addon.PrintLogs()
+	}
+})
+
+func TestE2E(t *testing.T) {
+	NewWithT(t)
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "external-secrets flux e2e suite", Label("flux"))
+}

+ 1 - 1
e2e/suite/akeyless/akeyless.go

@@ -20,7 +20,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 
 	"github.com/external-secrets/external-secrets/e2e/framework"
-	"github.com/external-secrets/external-secrets/e2e/suite/common"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
 )
 
 var _ = Describe("[akeyless]", Label("akeyless"), func() {

e2e/suite/akeyless/provider.go → e2e/suites/provider/cases/akeyless/provider.go


+ 1 - 1
e2e/suite/alibaba/alibaba.go

@@ -20,7 +20,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 
 	"github.com/external-secrets/external-secrets/e2e/framework"
-	"github.com/external-secrets/external-secrets/e2e/suite/common"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
 )
 
 var _ = Describe("[alibaba]", Label("alibaba"), func() {

e2e/suite/alibaba/provider.go → e2e/suites/provider/cases/alibaba/provider.go


e2e/suite/aws/common.go → e2e/suites/provider/cases/aws/common.go


e2e/suite/aws/parameterstore/find_by_name.go → e2e/suites/provider/cases/aws/parameterstore/find_by_name.go


e2e/suite/aws/parameterstore/find_by_tags.go → e2e/suites/provider/cases/aws/parameterstore/find_by_tags.go


+ 1 - 1
e2e/suite/aws/parameterstore/parameterstore.go

@@ -20,7 +20,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 
 	"github.com/external-secrets/external-secrets/e2e/framework"
-	"github.com/external-secrets/external-secrets/e2e/suite/common"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
 )
 
 var _ = Describe("[aws] ", Label("aws", "parameterstore"), func() {

+ 2 - 2
e2e/suite/aws/parameterstore/parameterstore_managed.go

@@ -21,8 +21,8 @@ import (
 
 	"github.com/external-secrets/external-secrets/e2e/framework"
 	"github.com/external-secrets/external-secrets/e2e/framework/addon"
-	awscommon "github.com/external-secrets/external-secrets/e2e/suite/aws"
-	"github.com/external-secrets/external-secrets/e2e/suite/common"
+	awscommon "github.com/external-secrets/external-secrets/e2e/suites/provider/cases/aws"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
 )
 
 // here we use the global eso instance

+ 1 - 1
e2e/suite/aws/parameterstore/provider.go

@@ -36,7 +36,7 @@ import (
 	esmetav1 "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 	"github.com/external-secrets/external-secrets/e2e/framework/log"
-	common "github.com/external-secrets/external-secrets/e2e/suite/aws"
+	common "github.com/external-secrets/external-secrets/e2e/suites/provider/cases/aws"
 )
 
 type Provider struct {

+ 1 - 1
e2e/suite/aws/secretsmanager/provider.go

@@ -37,7 +37,7 @@ import (
 	esmetav1 "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 	"github.com/external-secrets/external-secrets/e2e/framework/log"
-	common "github.com/external-secrets/external-secrets/e2e/suite/aws"
+	common "github.com/external-secrets/external-secrets/e2e/suites/provider/cases/aws"
 )
 
 type Provider struct {

+ 1 - 1
e2e/suite/aws/secretsmanager/secretsmanager.go

@@ -20,7 +20,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 
 	"github.com/external-secrets/external-secrets/e2e/framework"
-	"github.com/external-secrets/external-secrets/e2e/suite/common"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
 )
 
 var _ = Describe("[aws] ", Label("aws", "secretsmanager"), func() {

+ 2 - 2
e2e/suite/aws/secretsmanager/secretsmanager_managed.go

@@ -21,8 +21,8 @@ import (
 
 	"github.com/external-secrets/external-secrets/e2e/framework"
 	"github.com/external-secrets/external-secrets/e2e/framework/addon"
-	awscommon "github.com/external-secrets/external-secrets/e2e/suite/aws"
-	"github.com/external-secrets/external-secrets/e2e/suite/common"
+	awscommon "github.com/external-secrets/external-secrets/e2e/suites/provider/cases/aws"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
 )
 
 // here we use the global eso instance

e2e/suite/azure/azure_cert.go → e2e/suites/provider/cases/azure/azure_cert.go


e2e/suite/azure/azure_key.go → e2e/suites/provider/cases/azure/azure_key.go


+ 1 - 1
e2e/suite/azure/azure_secret.go

@@ -18,7 +18,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 
 	"github.com/external-secrets/external-secrets/e2e/framework"
-	"github.com/external-secrets/external-secrets/e2e/suite/common"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
 )
 
 // keyvault type=secret should behave just like any other secret store.

+ 5 - 3
e2e/suite/azure/provider.go

@@ -33,6 +33,8 @@ import (
 	"github.com/external-secrets/external-secrets/e2e/framework"
 )
 
+const providerSecretName = "provider-secret"
+
 type azureProvider struct {
 	clientID     string
 	clientSecret string
@@ -179,7 +181,7 @@ func (s *azureProvider) DeleteCertificate(key string) {
 func (s *azureProvider) CreateSecretStore() {
 	azureCreds := &v1.Secret{
 		ObjectMeta: metav1.ObjectMeta{
-			Name:      "provider-secret",
+			Name:      providerSecretName,
 			Namespace: s.framework.Namespace.Name,
 		},
 		StringData: map[string]string{
@@ -202,11 +204,11 @@ func (s *azureProvider) CreateSecretStore() {
 					VaultURL: &s.vaultURL,
 					AuthSecretRef: &esv1beta1.AzureKVAuth{
 						ClientID: &esmeta.SecretKeySelector{
-							Name: "provider-secret",
+							Name: providerSecretName,
 							Key:  "client-id",
 						},
 						ClientSecret: &esmeta.SecretKeySelector{
-							Name: "provider-secret",
+							Name: providerSecretName,
 							Key:  "client-secret",
 						},
 					},

+ 1 - 1
e2e/suite/common/common.go

@@ -63,6 +63,7 @@ func SyncV1Alpha1(f *framework.Framework) (string, func(*framework.TestCase)) {
 				Namespace: f.Namespace.Name,
 			},
 			Spec: esv1alpha1.ExternalSecretSpec{
+				RefreshInterval: &metav1.Duration{Duration: time.Second * 5},
 				SecretStoreRef: esv1alpha1.SecretStoreRef{
 					Name: f.Namespace.Name,
 				},
@@ -578,7 +579,6 @@ func DeletionPolicyDelete(f *framework.Framework) (string, func(*framework.TestC
 			},
 		}
 
-		tc.ExternalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second * 5}
 		tc.ExternalSecret.Spec.Target.DeletionPolicy = esv1beta1.DeletionPolicyDelete
 		tc.ExternalSecret.Spec.Data = []esv1beta1.ExternalSecretData{
 			{

+ 0 - 8
e2e/suite/common/find_by_name.go

@@ -14,10 +14,8 @@ package common
 
 import (
 	"fmt"
-	"time"
 
 	v1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	esapi "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
@@ -44,9 +42,6 @@ func FindByName(f *framework.Framework) (string, func(*framework.TestCase)) {
 				secretKeyThree: []byte(secretValue),
 			},
 		}
-		// AWS Secrets Manager is eventually consistent
-		// specifying a low refresh interval avoids flaky tests
-		tc.ExternalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second * 5}
 		tc.ExternalSecret.Spec.DataFrom = []esapi.ExternalSecretDataFromRemoteRef{
 			{
 				Find: &esapi.ExternalSecretFind{
@@ -77,9 +72,6 @@ func FindByNameWithPath(f *framework.Framework) (string, func(*framework.TestCas
 				fmt.Sprintf("%s-three", f.Namespace.Name): []byte(secretValue),
 			},
 		}
-		// AWS Secrets Manager is eventually consistent
-		// specifying a low refresh interval avoids flaky tests
-		tc.ExternalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second * 5}
 		tc.ExternalSecret.Spec.DataFrom = []esapi.ExternalSecretDataFromRemoteRef{
 			{
 				Find: &esapi.ExternalSecretFind{

+ 0 - 8
e2e/suite/common/find_by_tags.go

@@ -14,10 +14,8 @@ package common
 
 import (
 	"fmt"
-	"time"
 
 	v1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	esapi "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
@@ -55,9 +53,6 @@ func FindByTag(f *framework.Framework) (string, func(*framework.TestCase)) {
 				fmt.Sprintf("e2e-find-name-%s-three", f.Namespace.Name): []byte(secretValue1),
 			},
 		}
-		// AWS Secrets Manager is eventually consistent
-		// specifying a low refresh interval avoids flaky tests
-		tc.ExternalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second * 5}
 		tc.ExternalSecret.Spec.DataFrom = []esapi.ExternalSecretDataFromRemoteRef{
 			{
 				Find: &esapi.ExternalSecretFind{
@@ -103,9 +98,6 @@ func FindByTagWithPath(f *framework.Framework) (string, func(*framework.TestCase
 				fmt.Sprintf("foobar-%s-three", f.Namespace.Name): []byte(secretValue),
 			},
 		}
-		// AWS Secrets Manager is eventually consistent
-		// specifying a low refresh interval avoids flaky tests
-		tc.ExternalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second * 5}
 		tc.ExternalSecret.Spec.DataFrom = []esapi.ExternalSecretDataFromRemoteRef{
 			{
 				Find: &esapi.ExternalSecretFind{

+ 106 - 0
e2e/suites/provider/cases/fake/provider.go

@@ -0,0 +1,106 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package fake
+
+import (
+	"context"
+	"encoding/json"
+
+	// nolint
+	. "github.com/onsi/ginkgo/v2"
+
+	// nolint
+	. "github.com/onsi/gomega"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	"github.com/external-secrets/external-secrets/e2e/framework"
+)
+
+type Provider struct {
+	framework *framework.Framework
+}
+
+func NewProvider(f *framework.Framework) *Provider {
+	prov := &Provider{
+		framework: f,
+	}
+	BeforeEach(prov.BeforeEach)
+	return prov
+}
+
+func (s *Provider) CreateSecret(key string, val framework.SecretEntry) {
+	var store esv1beta1.SecretStore
+	err := s.framework.CRClient.Get(context.Background(), types.NamespacedName{
+		Namespace: s.framework.Namespace.Name,
+		Name:      s.framework.Namespace.Name,
+	}, &store)
+	Expect(err).ToNot(HaveOccurred())
+	base := store.DeepCopy()
+
+	mapData := make(map[string]string)
+	_ = json.Unmarshal([]byte(val.Value), &mapData)
+	store.Spec.Provider.Fake.Data = append(store.Spec.Provider.Fake.Data, esv1beta1.FakeProviderData{
+		Key:      key,
+		Value:    val.Value,
+		ValueMap: mapData,
+	})
+	err = s.framework.CRClient.Patch(context.Background(), &store, client.MergeFrom(base))
+	Expect(err).ToNot(HaveOccurred())
+}
+
+func (s *Provider) BeforeEach() {
+	s.CreateStore()
+}
+
+func (s *Provider) DeleteSecret(key string) {
+	var store esv1beta1.SecretStore
+	err := s.framework.CRClient.Get(context.Background(), types.NamespacedName{
+		Namespace: s.framework.Namespace.Name,
+		Name:      s.framework.Namespace.Name,
+	}, &store)
+	Expect(err).ToNot(HaveOccurred())
+	base := store.DeepCopy()
+	data := make([]esv1beta1.FakeProviderData, 0)
+	for _, v := range store.Spec.Provider.Fake.Data {
+		if v.Key != key {
+			data = append(data, v)
+		}
+	}
+	store.Spec.Provider.Fake.Data = data
+	err = s.framework.CRClient.Patch(context.Background(), &store, client.MergeFrom(base))
+	Expect(err).ToNot(HaveOccurred())
+}
+
+func (s *Provider) CreateStore() {
+	// Create a secret store - change these values to match YAML
+	By("creating a secret store for credentials")
+	fakeStore := &esv1beta1.SecretStore{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      s.framework.Namespace.Name,
+			Namespace: s.framework.Namespace.Name,
+		},
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				Fake: &esv1beta1.FakeProvider{
+					Data: []esv1beta1.FakeProviderData{},
+				},
+			},
+		},
+	}
+	err := s.framework.CRClient.Create(context.Background(), fakeStore)
+	Expect(err).ToNot(HaveOccurred())
+}

+ 1 - 1
e2e/suite/gcp/gcp.go

@@ -26,7 +26,7 @@ import (
 	// nolint
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
-	"github.com/external-secrets/external-secrets/e2e/suite/common"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
 )
 
 // This test uses the global ESO.

+ 1 - 1
e2e/suite/gcp/gcp_managed.go

@@ -22,7 +22,7 @@ import (
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
 	"github.com/external-secrets/external-secrets/e2e/framework/addon"
-	"github.com/external-secrets/external-secrets/e2e/suite/common"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
 )
 
 const (

e2e/suite/gcp/provider.go → e2e/suites/provider/cases/gcp/provider.go


+ 1 - 1
e2e/suite/gitlab/gitlab.go

@@ -23,7 +23,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 
 	"github.com/external-secrets/external-secrets/e2e/framework"
-	"github.com/external-secrets/external-secrets/e2e/suite/common"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
 )
 
 var _ = Describe("[gitlab]", Label("gitlab"), func() {

e2e/suite/gitlab/provider.go → e2e/suites/provider/cases/gitlab/provider.go


+ 6 - 6
e2e/suite/import.go

@@ -16,10 +16,10 @@ package suite
 import (
 
 	// import different e2e test suites.
-	_ "github.com/external-secrets/external-secrets/e2e/suite/aws/parameterstore"
-	_ "github.com/external-secrets/external-secrets/e2e/suite/aws/secretsmanager"
-	_ "github.com/external-secrets/external-secrets/e2e/suite/azure"
-	_ "github.com/external-secrets/external-secrets/e2e/suite/gcp"
-	_ "github.com/external-secrets/external-secrets/e2e/suite/template"
-	_ "github.com/external-secrets/external-secrets/e2e/suite/vault"
+	_ "github.com/external-secrets/external-secrets/e2e/suites/provider/cases/aws/parameterstore"
+	_ "github.com/external-secrets/external-secrets/e2e/suites/provider/cases/aws/secretsmanager"
+	_ "github.com/external-secrets/external-secrets/e2e/suites/provider/cases/azure"
+	_ "github.com/external-secrets/external-secrets/e2e/suites/provider/cases/gcp"
+	_ "github.com/external-secrets/external-secrets/e2e/suites/provider/cases/template"
+	_ "github.com/external-secrets/external-secrets/e2e/suites/provider/cases/vault"
 )

+ 1 - 1
e2e/suite/oracle/oracle.go

@@ -18,7 +18,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 
 	"github.com/external-secrets/external-secrets/e2e/framework"
-	"github.com/external-secrets/external-secrets/e2e/suite/common"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
 )
 
 var _ = Describe("[oracle]", Label("oracle"), func() {

e2e/suite/oracle/provider.go → e2e/suites/provider/cases/oracle/provider.go


e2e/suite/template/provider.go → e2e/suites/provider/cases/template/provider.go


e2e/suite/template/template.go → e2e/suites/provider/cases/template/template.go


+ 3 - 2
e2e/suite/vault/provider.go

@@ -45,6 +45,7 @@ const (
 	appRoleAuthProviderName = "app-role-provider"
 	kvv1ProviderName        = "kv-v1-provider"
 	jwtProviderName         = "jwt-provider"
+	jwtProviderSecretName   = "jwt-provider-credentials"
 	jwtK8sProviderName      = "jwt-k8s-provider"
 	kubernetesProviderName  = "kubernetes-provider"
 )
@@ -237,7 +238,7 @@ func (s vaultProvider) CreateV1Store(v *addon.Vault, ns string) {
 func (s vaultProvider) CreateJWTStore(v *addon.Vault, ns string) {
 	vaultCreds := &v1.Secret{
 		ObjectMeta: metav1.ObjectMeta{
-			Name:      "jwt-provider",
+			Name:      jwtProviderSecretName,
 			Namespace: ns,
 		},
 		Data: map[string][]byte{
@@ -252,7 +253,7 @@ func (s vaultProvider) CreateJWTStore(v *addon.Vault, ns string) {
 			Path: v.JWTPath,
 			Role: v.JWTRole,
 			SecretRef: &esmeta.SecretKeySelector{
-				Name: "jwt-provider",
+				Name: jwtProviderSecretName,
 				Key:  "jwt",
 			},
 		},

+ 1 - 1
e2e/suite/vault/vault.go

@@ -21,7 +21,7 @@ import (
 
 	esapi "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/e2e/framework"
-	"github.com/external-secrets/external-secrets/e2e/suite/common"
+	"github.com/external-secrets/external-secrets/e2e/suites/provider/cases/common"
 )
 
 const (

+ 8 - 4
e2e/e2e_test.go

@@ -23,7 +23,7 @@ import (
 
 	"github.com/external-secrets/external-secrets/e2e/framework/addon"
 	"github.com/external-secrets/external-secrets/e2e/framework/util"
-	_ "github.com/external-secrets/external-secrets/e2e/suite"
+	_ "github.com/external-secrets/external-secrets/e2e/suites/provider/cases"
 )
 
 var _ = SynchronizedBeforeSuite(func() []byte {
@@ -31,12 +31,16 @@ var _ = SynchronizedBeforeSuite(func() []byte {
 	cfg.KubeConfig, cfg.KubeClientSet, cfg.CRClient = util.NewConfig()
 
 	By("installing eso")
-	addon.InstallGlobalAddon(addon.NewESO(), cfg)
+	addon.InstallGlobalAddon(addon.NewESO(addon.WithCRDs()), cfg)
 
 	return nil
-}, func([]byte) {})
+}, func([]byte) {
+	// noop
+})
 
-var _ = SynchronizedAfterSuite(func() {}, func() {
+var _ = SynchronizedAfterSuite(func() {
+	// noop
+}, func() {
 	By("Cleaning up global addons")
 	addon.UninstallGlobalAddons()
 	if CurrentSpecReport().Failed() {

+ 81 - 7
go.mod

@@ -3,9 +3,8 @@ module github.com/external-secrets/external-secrets
 go 1.17
 
 replace (
-	github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1 => ./apis/externalsecrets/v1alpha1
-	github.com/external-secrets/external-secrets/e2e/framework/log => ./e2e/framework/log
-	github.com/external-secrets/external-secrets/pkg/provider/gitlab => ./pkg/provider/gitlab
+	github.com/go-check/check => github.com/go-check/check v0.0.0-20180628173108-788fd7840127
+	github.com/go-test/deep => github.com/go-test/deep v1.0.4
 	k8s.io/api => k8s.io/api v0.23.0
 	k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.23.0
 	k8s.io/apimachinery => k8s.io/apimachinery v0.23.0
@@ -29,6 +28,7 @@ replace (
 	k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.23.0
 	k8s.io/metrics => k8s.io/metrics v0.23.0
 	k8s.io/mount-utils => k8s.io/mount-utils v0.23.0
+	k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.23.0
 	k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.23.0
 )
 
@@ -53,6 +53,7 @@ require (
 	github.com/aws/aws-sdk-go v1.44.19
 	github.com/crossplane/crossplane-runtime v0.15.1
 	github.com/go-logr/logr v1.2.3
+	github.com/go-test/deep v1.0.4 // indirect
 	github.com/golang-jwt/jwt/v4 v4.4.1
 	github.com/google/go-cmp v0.5.8
 	github.com/google/uuid v1.3.0
@@ -87,7 +88,7 @@ require (
 	k8s.io/apiextensions-apiserver v0.23.5
 	k8s.io/apimachinery v0.23.5
 	k8s.io/client-go v0.23.5
-	k8s.io/utils v0.0.0-20211116205334-6203023598ed
+	k8s.io/utils v0.0.0-20211208161948-7d6a63dca704
 	sigs.k8s.io/controller-runtime v0.11.2
 	sigs.k8s.io/controller-tools v0.8.0
 	software.sslmate.com/src/go-pkcs12 v0.0.0-20210415151418-c5206de65a78
@@ -96,7 +97,15 @@ require (
 require github.com/1Password/connect-sdk-go v1.2.0
 
 require (
+	github.com/argoproj/argo-cd/v2 v2.3.3
+	github.com/fluxcd/helm-controller/api v0.20.1
+	github.com/fluxcd/pkg/apis/meta v0.12.2
+	github.com/fluxcd/source-controller/api v0.24.1
+)
+
+require (
 	cloud.google.com/go/compute v1.6.0 // indirect
+	github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
 	github.com/Azure/go-autorest v14.2.0+incompatible // indirect
 	github.com/Azure/go-autorest/autorest/azure/cli v0.4.5 // indirect
 	github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
@@ -104,39 +113,70 @@ require (
 	github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
 	github.com/Azure/go-autorest/logger v0.2.1 // indirect
 	github.com/Azure/go-autorest/tracing v0.6.0 // indirect
+	github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect
 	github.com/Masterminds/semver/v3 v3.1.1 // indirect
 	github.com/PaesslerAG/gval v1.0.0 // indirect
+	github.com/PuerkitoBio/purell v1.1.1 // indirect
+	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
+	github.com/argoproj/gitops-engine v0.6.2 // indirect
+	github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0 // indirect
 	github.com/armon/go-metrics v0.3.10 // indirect
 	github.com/armon/go-radix v1.0.0 // indirect
 	github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/bombsimon/logrusr/v2 v2.0.1 // indirect
+	github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 // indirect
 	github.com/cenkalti/backoff/v3 v3.2.2 // indirect
 	github.com/cespare/xxhash/v2 v2.1.2 // indirect
+	github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d // indirect
+	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 	github.com/dimchansky/utfbom v1.1.1 // indirect
+	github.com/docker/distribution v2.7.1+incompatible // indirect
+	github.com/emicklei/go-restful v2.9.5+incompatible // indirect
+	github.com/emirpasic/gods v1.12.0 // indirect
 	github.com/evanphx/json-patch v4.12.0+incompatible // indirect
+	github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
+	github.com/fatih/camelcase v1.0.0 // indirect
 	github.com/fatih/color v1.13.0 // indirect
+	github.com/fluxcd/pkg/apis/acl v0.0.3 // indirect
+	github.com/fluxcd/pkg/apis/kustomize v0.3.3 // indirect
 	github.com/fsnotify/fsnotify v1.5.1 // indirect
+	github.com/fvbommel/sortorder v1.0.1 // indirect
 	github.com/ghodss/yaml v1.0.0 // indirect
+	github.com/go-errors/errors v1.0.1 // indirect
+	github.com/go-git/gcfg v1.5.0 // indirect
+	github.com/go-git/go-billy/v5 v5.0.0 // indirect
+	github.com/go-git/go-git/v5 v5.2.0 // indirect
 	github.com/go-logr/zapr v1.2.0 // indirect
 	github.com/go-openapi/errors v0.19.8 // indirect
+	github.com/go-openapi/jsonpointer v0.19.5 // indirect
+	github.com/go-openapi/jsonreference v0.19.5 // indirect
 	github.com/go-openapi/strfmt v0.21.2 // indirect
+	github.com/go-openapi/swag v0.19.14 // indirect
 	github.com/go-playground/locales v0.14.0 // indirect
 	github.com/go-playground/universal-translator v0.18.0 // indirect
+	github.com/go-redis/cache/v8 v8.4.2 // indirect
+	github.com/go-redis/redis/v8 v8.11.3 // indirect
 	github.com/go-stack/stack v1.8.0 // indirect
 	github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
 	github.com/gobuffalo/flect v0.2.3 // indirect
+	github.com/gobwas/glob v0.2.3 // indirect
 	github.com/goccy/go-json v0.9.6 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang-jwt/jwt v3.2.1+incompatible // indirect
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
+	github.com/google/btree v1.0.1 // indirect
+	github.com/google/go-github/v41 v41.0.0 // indirect
 	github.com/google/go-querystring v1.1.0 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
 	github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
+	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
 	github.com/googleapis/gnostic v0.5.5 // indirect
+	github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
 	github.com/hashicorp/errwrap v1.1.0 // indirect
 	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
 	github.com/hashicorp/go-hclog v1.1.0 // indirect
@@ -157,8 +197,14 @@ require (
 	github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
 	github.com/inconshreveable/mousetrap v1.0.0 // indirect
+	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
+	github.com/jonboulle/clockwork v0.2.2 // indirect
+	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
+	github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd // indirect
+	github.com/klauspost/compress v1.13.6 // indirect
 	github.com/kylelemons/godebug v1.1.0 // indirect
 	github.com/leodido/go-urn v1.2.1 // indirect
 	github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
@@ -166,42 +212,61 @@ require (
 	github.com/lestrrat-go/httpcc v1.0.1 // indirect
 	github.com/lestrrat-go/iter v1.0.1 // indirect
 	github.com/lestrrat-go/option v1.0.0 // indirect
+	github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
+	github.com/mailru/easyjson v0.7.6 // indirect
 	github.com/mattn/go-colorable v0.1.12 // indirect
 	github.com/mattn/go-isatty v0.0.14 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
 	github.com/mitchellh/copystructure v1.2.0 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/go-testing-interface v1.14.1 // indirect
+	github.com/mitchellh/go-wordwrap v1.0.0 // indirect
 	github.com/mitchellh/mapstructure v1.4.3 // indirect
 	github.com/mitchellh/reflectwalk v1.0.2 // indirect
 	github.com/moby/spdystream v0.2.0 // indirect
+	github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
 	github.com/oklog/run v1.1.0 // indirect
 	github.com/oklog/ulid v1.3.1 // indirect
+	github.com/opencontainers/go-digest v1.0.0 // indirect
 	github.com/opentracing/opentracing-go v1.2.0 // indirect
+	github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
+	github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
 	github.com/pierrec/lz4 v2.6.1+incompatible // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/prometheus/common v0.32.1 // indirect
 	github.com/prometheus/procfs v0.7.3 // indirect
+	github.com/robfig/cron v1.2.0 // indirect
+	github.com/russross/blackfriday v1.5.2 // indirect
 	github.com/russross/blackfriday/v2 v2.1.0 // indirect
 	github.com/ryanuber/go-glob v1.0.0 // indirect
+	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/shopspring/decimal v1.2.0 // indirect
+	github.com/sirupsen/logrus v1.8.1 // indirect
 	github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b // indirect
 	github.com/spf13/cast v1.4.1 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
-	github.com/stretchr/objx v0.2.0 // indirect
 	github.com/tidwall/match v1.1.1 // indirect
 	github.com/tidwall/pretty v1.2.0 // indirect
 	github.com/uber/jaeger-client-go v2.25.0+incompatible // indirect
 	github.com/uber/jaeger-lib v2.4.0+incompatible // indirect
+	github.com/vmihailenco/go-tinylfu v0.2.1 // indirect
+	github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect
+	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
+	github.com/xanzy/ssh-agent v0.2.1 // indirect
+	github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
 	go.mongodb.org/mongo-driver v1.7.5 // indirect
 	go.opencensus.io v0.23.0 // indirect
+	go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
 	go.uber.org/atomic v1.9.0 // indirect
 	go.uber.org/multierr v1.6.0 // indirect
+	golang.org/x/exp v0.0.0-20210901193431-a062eea981d2 // indirect
 	golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
 	golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect
+	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
 	golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
 	golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
 	golang.org/x/text v0.3.7 // indirect
@@ -215,13 +280,22 @@ require (
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/ini.v1 v1.66.2 // indirect
 	gopkg.in/square/go-jose.v2 v2.6.0 // indirect
+	gopkg.in/warnings.v0 v0.1.2 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
+	k8s.io/apiserver v0.23.1 // indirect
+	k8s.io/cli-runtime v0.23.1 // indirect
 	k8s.io/component-base v0.23.5 // indirect
-	k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c // indirect
+	k8s.io/component-helpers v0.23.1 // indirect
+	k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect
 	k8s.io/klog v0.3.0 // indirect
 	k8s.io/klog/v2 v2.30.0 // indirect
+	k8s.io/kube-aggregator v0.23.1 // indirect
 	k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
-	sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
+	k8s.io/kubectl v0.23.1 // indirect
+	k8s.io/kubernetes v1.23.1 // indirect
+	sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
+	sigs.k8s.io/kustomize/api v0.10.1 // indirect
+	sigs.k8s.io/kustomize/kyaml v0.13.0 // indirect
 	sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
 	sigs.k8s.io/yaml v1.3.0 // indirect
 )

File diff suppressed because it is too large
+ 659 - 7
go.sum