Skip to content

Commit

Permalink
feat: add push secret to e2e tests (external-secrets#3017)
Browse files Browse the repository at this point in the history
* feat: add push secret to e2e tests

Signed-off-by: Gergely Brautigam <[email protected]>

* finally, a fully working example for an e2e flow with push secret

Signed-off-by: Gergely Brautigam <[email protected]>

* fix value field duplication issue

Signed-off-by: Gergely Brautigam <[email protected]>

---------

Signed-off-by: Gergely Brautigam <[email protected]>
  • Loading branch information
Skarlso authored Feb 12, 2024
1 parent c00d90d commit e726087
Show file tree
Hide file tree
Showing 168 changed files with 424 additions and 89 deletions.
1 change: 1 addition & 0 deletions apis/externalsecrets/v1beta1/externalsecret_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 v1beta1

import (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 v1beta1

import (
Expand Down
1 change: 1 addition & 0 deletions apis/externalsecrets/v1beta1/provider_schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 v1beta1

import (
Expand Down
1 change: 1 addition & 0 deletions cmd/certcontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ 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 cmd

import (
Expand Down
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ 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 cmd

import (
Expand Down
1 change: 1 addition & 0 deletions cmd/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ 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 cmd

import (
Expand Down
1 change: 1 addition & 0 deletions e2e/framework/addon/addon.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 (
Expand Down
1 change: 1 addition & 0 deletions e2e/framework/addon/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ 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 (
Expand Down
1 change: 1 addition & 0 deletions e2e/framework/addon/eso.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 (
Expand Down
1 change: 1 addition & 0 deletions e2e/framework/addon/eso_argocd_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ 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 (
Expand Down
1 change: 1 addition & 0 deletions e2e/framework/addon/eso_flux_helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ 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 (
Expand Down
1 change: 1 addition & 0 deletions e2e/framework/addon/helmserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ 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 (
Expand Down
1 change: 1 addition & 0 deletions e2e/framework/addon/uninstall_eso_crds.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 (
Expand Down
3 changes: 2 additions & 1 deletion e2e/framework/addon/vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 (
Expand All @@ -33,7 +34,7 @@ import (
vault "github.com/hashicorp/vault/api"

// nolint
ginkgo "github.com/onsi/ginkgo/v2"
"github.com/onsi/ginkgo/v2"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

Expand Down
1 change: 1 addition & 0 deletions e2e/framework/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 framework

import (
Expand Down
1 change: 1 addition & 0 deletions e2e/framework/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 log

import (
Expand Down
152 changes: 113 additions & 39 deletions e2e/framework/testcase.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 framework

import (
Expand All @@ -31,13 +32,16 @@ var TargetSecretName = "target-secret"

// TestCase contains the test infra to run a table driven test.
type TestCase struct {
Framework *Framework
ExternalSecret *esv1beta1.ExternalSecret
ExternalSecretV1Alpha1 *esv1alpha1.ExternalSecret
AdditionalObjects []client.Object
Secrets map[string]SecretEntry
ExpectedSecret *v1.Secret
AfterSync func(SecretStoreProvider, *v1.Secret)
Framework *Framework
ExternalSecret *esv1beta1.ExternalSecret
ExternalSecretV1Alpha1 *esv1alpha1.ExternalSecret
PushSecret *esv1alpha1.PushSecret
PushSecretSource *v1.Secret
AdditionalObjects []client.Object
Secrets map[string]SecretEntry
ExpectedSecret *v1.Secret
AfterSync func(SecretStoreProvider, *v1.Secret)
VerifyPushSecretOutcome func(ps *esv1alpha1.PushSecret, pushClient esv1beta1.SecretsClient)
}

type SecretEntry struct {
Expand All @@ -52,64 +56,114 @@ type SecretStoreProvider interface {
DeleteSecret(key string)
}

// TableFunc returns the main func that runs a TestCase in a table driven test.
func TableFunc(f *Framework, prov SecretStoreProvider) func(...func(*TestCase)) {
// TableFuncWithExternalSecret returns the main func that runs a TestCase in a table driven test.
func TableFuncWithExternalSecret(f *Framework, prov SecretStoreProvider) func(...func(*TestCase)) {
return func(tweaks ...func(*TestCase)) {
var err error

// make default test case
// and apply customization to it
tc := makeDefaultTestCase(f)
tc := makeDefaultExternalSecretTestCase(f)
for _, tweak := range tweaks {
tweak(tc)
}

// create secrets & defer delete
var deferRemoveKeys []string
for k, v := range tc.Secrets {
key := k
prov.CreateSecret(key, v)
defer func() {
prov.DeleteSecret(key)
}()
deferRemoveKeys = append(deferRemoveKeys, key)
}

// create v1alpha1 external secret, if provided
if tc.ExternalSecretV1Alpha1 != nil {
err = tc.Framework.CRClient.Create(context.Background(), tc.ExternalSecretV1Alpha1)
Expect(err).ToNot(HaveOccurred())
} else if tc.ExternalSecret != nil {
// create v1beta1 external secret otherwise
err = tc.Framework.CRClient.Create(context.Background(), tc.ExternalSecret)
Expect(err).ToNot(HaveOccurred())
}
if tc.AdditionalObjects != nil {
for _, obj := range tc.AdditionalObjects {
err = tc.Framework.CRClient.Create(context.Background(), obj)
Expect(err).ToNot(HaveOccurred())
defer func() {
for _, k := range deferRemoveKeys {
prov.DeleteSecret(k)
}
}
}()

// create v1alpha1 external secret, if provided
createProvidedExternalSecret(tc)

// create additional objects
generateAdditionalObjects(tc)

// in case target name is empty
if tc.ExternalSecret != nil && tc.ExternalSecret.Spec.Target.Name == "" {
TargetSecretName = tc.ExternalSecret.ObjectMeta.Name
}

// wait for Kind=Secret to have the expected data
if tc.ExpectedSecret != nil {
secret, err := tc.Framework.WaitForSecretValue(tc.Framework.Namespace.Name, TargetSecretName, tc.ExpectedSecret)
if err != nil {
f.printESDebugLogs(tc.ExternalSecret.Name, tc.ExternalSecret.Namespace)
log.Logf("Did not match. Expected: %+v, Got: %+v", tc.ExpectedSecret, secret)
}
executeAfterSync(tc, f, prov)
}
}

func executeAfterSync(tc *TestCase, f *Framework, prov SecretStoreProvider) {
if tc.ExpectedSecret != nil {
secret, err := tc.Framework.WaitForSecretValue(tc.Framework.Namespace.Name, TargetSecretName, tc.ExpectedSecret)
if err != nil {
f.printESDebugLogs(tc.ExternalSecret.Name, tc.ExternalSecret.Namespace)
log.Logf("Did not match. Expected: %+v, Got: %+v", tc.ExpectedSecret, secret)
}

Expect(err).ToNot(HaveOccurred())
tc.AfterSync(prov, secret)
} else {
tc.AfterSync(prov, nil)
}
}

func generateAdditionalObjects(tc *TestCase) {
if tc.AdditionalObjects != nil {
for _, obj := range tc.AdditionalObjects {
err := tc.Framework.CRClient.Create(context.Background(), obj)
Expect(err).ToNot(HaveOccurred())
}
}
}

func createProvidedExternalSecret(tc *TestCase) {
if tc.ExternalSecretV1Alpha1 != nil {
err := tc.Framework.CRClient.Create(context.Background(), tc.ExternalSecretV1Alpha1)
Expect(err).ToNot(HaveOccurred())
} else if tc.ExternalSecret != nil {
// create v1beta1 external secret otherwise
err := tc.Framework.CRClient.Create(context.Background(), tc.ExternalSecret)
Expect(err).ToNot(HaveOccurred())
}
}

// TableFuncWithPushSecret returns the main func that runs a TestCase in a table driven test for push secrets.
func TableFuncWithPushSecret(f *Framework, prov SecretStoreProvider, pushClient esv1beta1.SecretsClient) func(...func(*TestCase)) {
return func(tweaks ...func(*TestCase)) {
var err error

// make default test case
// and apply customization to it
tc := makeDefaultPushSecretTestCase(f)
for _, tweak := range tweaks {
tweak(tc)
}

if tc.PushSecretSource != nil {
err := tc.Framework.CRClient.Create(context.Background(), tc.PushSecretSource)
Expect(err).ToNot(HaveOccurred())
}

// create v1alpha1 push secret, if provided
if tc.PushSecret != nil {
// create v1beta1 external secret otherwise
err = tc.Framework.CRClient.Create(context.Background(), tc.PushSecret)
Expect(err).ToNot(HaveOccurred())
tc.AfterSync(prov, secret)
} else {
tc.AfterSync(prov, nil)
}

// additional objects
generateAdditionalObjects(tc)

// Run verification on the secret that push secret created or not.
tc.VerifyPushSecretOutcome(tc.PushSecret, pushClient)
}
}

func makeDefaultTestCase(f *Framework) *TestCase {
func makeDefaultExternalSecretTestCase(f *Framework) *TestCase {
return &TestCase{
AfterSync: func(ssp SecretStoreProvider, s *v1.Secret) {},
Framework: f,
Expand All @@ -130,3 +184,23 @@ func makeDefaultTestCase(f *Framework) *TestCase {
},
}
}

func makeDefaultPushSecretTestCase(f *Framework) *TestCase {
return &TestCase{
Framework: f,
PushSecret: &esv1alpha1.PushSecret{
ObjectMeta: metav1.ObjectMeta{
Name: "e2e-ps",
Namespace: f.Namespace.Name,
},
Spec: esv1alpha1.PushSecretSpec{
RefreshInterval: &metav1.Duration{Duration: time.Second * 5},
SecretStoreRefs: []esv1alpha1.PushSecretStoreRef{
{
Name: f.Namespace.Name,
},
},
},
},
}
}
1 change: 1 addition & 0 deletions e2e/framework/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 util

import (
Expand Down
3 changes: 2 additions & 1 deletion e2e/suites/argocd/argocd.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ 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 (
Expand All @@ -28,7 +29,7 @@ var _ = Describe("argocd", Label("argocd"), func() {
f := framework.New("argocd")
prov := fake.NewProvider(f)

DescribeTable("sync secrets", framework.TableFunc(f, prov),
DescribeTable("sync secrets", framework.TableFuncWithExternalSecret(f, prov),
Entry(common.SimpleDataSync(f)),
Entry(common.JSONDataFromSync(f)),
Entry(common.SSHKeySync(f)),
Expand Down
1 change: 1 addition & 0 deletions e2e/suites/argocd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ 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 (
Expand Down
1 change: 1 addition & 0 deletions e2e/suites/argocd/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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 (
Expand Down
3 changes: 2 additions & 1 deletion e2e/suites/flux/flux.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ 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 (
Expand All @@ -28,7 +29,7 @@ var _ = Describe("flux", Label("flux"), func() {
f := framework.New("flux")
prov := fake.NewProvider(f)

DescribeTable("sync secrets", framework.TableFunc(f, prov),
DescribeTable("sync secrets", framework.TableFuncWithExternalSecret(f, prov),
Entry(common.SimpleDataSync(f)),
Entry(common.JSONDataFromSync(f)),
Entry(common.SSHKeySync(f)),
Expand Down
Loading

0 comments on commit e726087

Please sign in to comment.