Reuse the existing provider e2e suite for the new V2 architecture, starting with the Kubernetes provider, and delete e2e/suites/v2 after its reusable logic has been migrated.
The target outcome is:
provider.test remains the single suite binary for provider e2e tests.e2e/suites/provider.provider.test for both legacy and V2 runs.test.e2e.v2 flow so it runs provider.test in V2 mode instead of v2.test.e2e/suites/provider/cases/kubernetes.e2e/suites/provider.ClusterProvider with AuthenticationScopeManifestNamespace.Add an environment-driven mode switch for the provider suite.
Suggested env var:
E2E_PROVIDER_MODE=legacy|v2Behavior:
legacyv2: install ESO with V2 enabled, create Provider/ClusterProvider CRDs, and enable the Kubernetes provider deploymentThis keeps the suite layout stable and avoids carrying e2e/suites/v2 as a parallel test hierarchy.
The V2 install logic currently proven in e2e/suites/v2/suite_test.go should be promoted into reusable addon mutators instead of staying in suite code.
Recommended shape:
e2e/framework/addonaddon.NewESO(...) for both legacy and V2e2e/framework/addon/eso_v2.go; either remove it later or repurpose it so there is only one supported installation pathSuggested mutators:
addon.WithV2Mode()addon.WithProviderNamespace("external-secrets-system")addon.WithV2Providers(...providers) or a narrower addon.WithKubernetesV2Provider()Minimum V2 Helm settings:
v2.enabled=truecrds.createProvider=truecrds.createClusterProvider=trueproviders.enabled=trueexternal-secrets-systemexternal-secretsThe main framework coupling today is that the default testcase builder assumes a namespaced SecretStore reference and no ref kind.
Add mode-aware defaults to framework.Framework so existing test tables can continue to build their manifests the same way.
Suggested new fields on framework.Framework:
DefaultSecretStoreRefKind stringDefaultPushSecretStoreRefKind stringDefaultPushSecretStoreRefAPIVersion stringProviderMode stringSet them in framework.New(...) based on E2E_PROVIDER_MODE:
DefaultSecretStoreRefKind = ""DefaultPushSecretStoreRefKind = ""DefaultSecretStoreRefKind = esv1.ProviderKindStrDefaultPushSecretStoreRefKind = esv1.ProviderKindStrUpdate default testcase creation in e2e/framework/testcase.go so:
makeDefaultExternalSecretTestCase() sets Spec.SecretStoreRef.Kind from framework defaultsmakeDefaultPushSecretTestCase() sets Spec.SecretStoreRefs[0].Kind from framework defaultsThis allows existing table-driven tests to reuse the same setup with no broad manifest rewrite.
e2e/suites/v2Anything that is reusable test infrastructure should move out of the v2 suite package before that package is deleted.
Recommended destination:
e2e/framework/v2 or similarHelpers to move first:
Likely source files:
e2e/suites/v2/helpers.goe2e/suites/v2/metrics_helpers.goAfter migration, provider cases should import only framework packages, never e2e/suites/v2.
Extend e2e/suites/provider/cases/kubernetes/provider.go so the provider setup can operate in both modes.
Recommended approach:
Provider as the abstraction used by the table testsSecretStore and ClusterSecretStoreKind=KubernetesKind=ProviderClusterProvider for the referent-auth equivalent pathRecommended structure:
BeforeEach() decides setupLegacy() vs setupV2()CreateStore() keeps legacy behaviorCreateStoreV2()CreateReferentStore() keeps legacy behaviorCreateReferentStoreV2()To minimize rewiring, keep the resource names aligned with what the table tests already expect.
For the default case in V2 mode:
Provider.Name = f.Namespace.NameProvider.Namespace = f.Namespace.NameExternalSecret.Spec.SecretStoreRef.Name remains untouched by tests and still resolves correctlyFor referent-auth cases in V2 mode:
ClusterProvider using the existing referent naming patternAuthenticationScopeManifestNamespaceToday the Kubernetes suite expresses referent auth by switching to ClusterSecretStore.
In V2, the semantic equivalent should be:
SecretStoreRef.Kind = ClusterProviderSecretStoreRef.Name = <referent-name>ClusterProvider.Spec.AuthenticationScope = ManifestNamespaceUpdate withReferentStore(...) so it branches by mode:
ClusterSecretStoreClusterProviderUse API constants where available:
esv1.ProviderKindStresv1.ClusterProviderKindStresv1.AuthenticationScopeManifestNamespaceThe V2 Kubernetes provider needs explicit RBAC to read or write secrets in the target namespace.
For namespaced provider tests:
For referent/cluster-provider cases:
AuthenticationScopeManifestNamespace is used, bind the service account identity from the ExternalSecret/PushSecret namespaceThe plan should prefer one RBAC helper with explicit parameters over many ad-hoc copies.
Keep the existing table-driven assertions in:
e2e/suites/provider/cases/kubernetes/kubernetes.goThese should run in both modes, but V2 execution should be label-gated so we can migrate incrementally.
Recommended labeling:
kubernetes labelv2legacy label to the old suite bootstrap only if needed laterRecommended strategy:
Move the following test coverage into e2e/suites/provider/cases/kubernetes or a sibling under e2e/suites/provider:
Suggested placement:
e2e/suites/provider/cases/kubernetes/capabilities_v2_test.goe2e/suites/provider/cases/kubernetes/push_v2_test.goe2e/suites/provider/cases/kubernetes/metrics_v2_test.goe2e/suites/provider/cases/kubernetes/cluster_provider_v2_test.goGuideline:
kubernetes.goThe metrics coverage in e2e/suites/v2/metrics_test.go is useful and should remain, but it should be narrowed to Kubernetes-only assumptions for this first step.
First migration scope:
ProviderClusterProviderExternalSecret syncAvoid in the first pass:
test.e2e.v2 to run the provider suiteUpdate the E2E execution path so V2 uses the provider suite binary instead of v2.test.
Planned changes:
e2e/Makefile
provider-kubernetes for V2 initiallyTEST_SUITES="provider"E2E_PROVIDER_MODE=v2GINKGO_LABELS="v2"e2e/Dockerfile
ADD e2e/suites/v2/v2.test /v2.test once the old suite is goneTarget command shape:
GINKGO_LABELS="v2" E2E_PROVIDER_MODE="v2" TEST_SUITES="provider" ./run.sh
e2e/suites/v2 only after parity is reachedDeletion should happen only after:
e2e/suites/v2/suite_test.goe2e/suites/v2/helpers.goe2e/suites/v2/metrics_helpers.goe2e/suites/providertest.e2e.v2 no longer depends on v2.testAt that point remove:
e2e/suites/v2/v2.test build/copy pathe2e/suites/v2/suite_test.go into e2e/framework/addon.Provider refs.test.e2e.v2 to run provider.test.e2e/suites/v2 and remove v2.test packaging.The migration is complete when all of the following are true:
make test.e2e still runs the legacy provider suite unchanged.make test.e2e.v2 runs provider.test with E2E_PROVIDER_MODE=v2.Provider / ClusterProvider resources.e2e/suites/provider.e2e/suites/v2 is deleted.v2.test.e2e/framework/addon/eso_v2.go appears to describe a second installation approach; keeping both active will create drift. Consolidate on the Helm-mutation path.ClusterProvider resources are cluster-scoped and must be cleaned up carefully to avoid cross-test leakage.E2E_PROVIDER_MODE.AuthenticationScopeManifestNamespace is the intended equivalent.