1
0
Fork 0
mirror of https://github.com/external-secrets/external-secrets.git synced 2024-12-15 17:51:01 +00:00

chore: implement aws parameterstore e2e tests

Signed-off-by: Moritz Johner <beller.moritz@googlemail.com>
This commit is contained in:
Moritz Johner 2022-01-26 22:10:15 +01:00
parent 5a8df8cb18
commit 64589cddda
10 changed files with 512 additions and 179 deletions

97
e2e/suite/aws/common.go Normal file
View file

@ -0,0 +1,97 @@
/*
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 common
import (
"context"
// nolint
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
esmetav1 "github.com/external-secrets/external-secrets/apis/meta/v1"
"github.com/external-secrets/external-secrets/e2e/framework"
)
const (
WithReferencedIRSA = "with referenced IRSA"
WithMountedIRSA = "with mounted IRSA"
StaticCredentialsSecretName = "provider-secret"
)
func ReferencedIRSAStoreName(f *framework.Framework) string {
return "irsa-ref-" + f.Namespace.Name
}
func MountedIRSAStoreName(f *framework.Framework) string {
return "irsa-mounted-" + f.Namespace.Name
}
func UseClusterSecretStore(tc *framework.TestCase) {
tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.ClusterSecretStoreKind
tc.ExternalSecret.Spec.SecretStoreRef.Name = ReferencedIRSAStoreName(tc.Framework)
}
func UseMountedIRSAStore(tc *framework.TestCase) {
tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.SecretStoreKind
tc.ExternalSecret.Spec.SecretStoreRef.Name = MountedIRSAStoreName(tc.Framework)
}
// StaticStore is namespaced and references
// static credentials from a secret.
func SetupStaticStore(f *framework.Framework, kid, sak, region string, serviceType esv1alpha1.AWSServiceType) {
awsCreds := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: StaticCredentialsSecretName,
Namespace: f.Namespace.Name,
},
StringData: map[string]string{
"kid": kid,
"sak": sak,
},
}
err := f.CRClient.Create(context.Background(), awsCreds)
Expect(err).ToNot(HaveOccurred())
secretStore := &esv1alpha1.SecretStore{
ObjectMeta: metav1.ObjectMeta{
Name: f.Namespace.Name,
Namespace: f.Namespace.Name,
},
Spec: esv1alpha1.SecretStoreSpec{
Provider: &esv1alpha1.SecretStoreProvider{
AWS: &esv1alpha1.AWSProvider{
Service: serviceType,
Region: region,
Auth: esv1alpha1.AWSAuth{
SecretRef: &esv1alpha1.AWSAuthSecretRef{
AccessKeyID: esmetav1.SecretKeySelector{
Name: StaticCredentialsSecretName,
Key: "kid",
},
SecretAccessKey: esmetav1.SecretKeySelector{
Name: StaticCredentialsSecretName,
Key: "sak",
},
},
},
},
},
},
}
err = f.CRClient.Create(context.Background(), secretStore)
Expect(err).ToNot(HaveOccurred())
}

View file

@ -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 aws
import (
// nolint
. "github.com/onsi/ginkgo/v2"
"github.com/external-secrets/external-secrets/e2e/framework"
"github.com/external-secrets/external-secrets/e2e/suite/common"
)
var _ = Describe("[aws] ", Label("aws", "parameterstore"), func() {
f := framework.New("eso-aws-ps")
prov := NewFromEnv(f)
DescribeTable("sync secrets",
framework.TableFunc(f,
prov),
Entry(common.SimpleDataSync(f)),
Entry(common.NestedJSONWithGJSON(f)),
Entry(common.JSONDataFromSync(f)),
Entry(common.JSONDataWithProperty(f)),
Entry(common.JSONDataWithTemplate(f)),
Entry(common.DockerJSONConfig(f)),
Entry(common.DataPropertyDockerconfigJSON(f)),
Entry(common.SSHKeySync(f)),
Entry(common.SSHKeySyncDataProperty(f)),
Entry(common.SyncWithoutTargetName(f)),
Entry(common.JSONDataWithoutTargetName(f)),
)
})

View file

@ -0,0 +1,85 @@
/*
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 aws
import (
// nolint
. "github.com/onsi/ginkgo/v2"
"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"
)
// here we use the global eso instance
// that uses the service account in the default namespace
// which was created by terraform.
var _ = Describe("[awsmanaged] IRSA via referenced service account", Label("aws", "parameterstore", "managed"), func() {
f := framework.New("eso-aws-ps-managed")
prov := NewFromEnv(f)
// nolint
DescribeTable("sync secrets",
framework.TableFunc(f,
prov),
framework.Compose(awscommon.WithReferencedIRSA, f, common.SimpleDataSync, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.NestedJSONWithGJSON, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataFromSync, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataWithProperty, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataWithTemplate, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.DockerJSONConfig, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.DataPropertyDockerconfigJSON, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.SSHKeySync, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.SSHKeySyncDataProperty, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.SyncWithoutTargetName, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataWithoutTargetName, awscommon.UseClusterSecretStore),
)
})
// here we create a central eso instance in the default namespace
// that mounts the service account which was created by terraform.
var _ = Describe("[awsmanaged] with mounted IRSA", Label("aws", "parameterstore", "managed"), func() {
f := framework.New("eso-aws-ps-irsa-managed")
prov := NewFromEnv(f)
// each test case gets its own ESO instance
BeforeEach(func() {
f.Install(addon.NewESO(
addon.WithControllerClass(f.BaseName),
addon.WithServiceAccount(prov.ServiceAccountName),
addon.WithReleaseName(f.Namespace.Name),
addon.WithNamespace("default"),
))
})
// nolint
DescribeTable("sync secrets",
framework.TableFunc(f,
prov),
framework.Compose(awscommon.WithMountedIRSA, f, common.SimpleDataSync, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.NestedJSONWithGJSON, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataFromSync, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataWithProperty, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataWithTemplate, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.DockerJSONConfig, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.DataPropertyDockerconfigJSON, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.SSHKeySync, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.SSHKeySyncDataProperty, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.SyncWithoutTargetName, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataWithoutTargetName, awscommon.UseMountedIRSAStore),
)
})

View file

@ -0,0 +1,165 @@
/*
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 aws
import (
"context"
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ssm"
//nolint
. "github.com/onsi/ginkgo/v2"
// nolint
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
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"
)
type Provider struct {
ServiceAccountName string
ServiceAccountNamespace string
region string
client *ssm.SSM
framework *framework.Framework
}
func NewProvider(f *framework.Framework, kid, sak, region, saName, saNamespace string) *Provider {
sess, err := session.NewSessionWithOptions(session.Options{
Config: aws.Config{
Credentials: credentials.NewStaticCredentials(kid, sak, ""),
Region: aws.String(region),
},
})
if err != nil {
Fail(err.Error())
}
sm := ssm.New(sess)
prov := &Provider{
ServiceAccountName: saName,
ServiceAccountNamespace: saNamespace,
region: region,
client: sm,
framework: f,
}
BeforeEach(func() {
common.SetupStaticStore(f, kid, sak, region, esv1alpha1.AWSServiceParameterStore)
prov.SetupReferencedIRSAStore()
prov.SetupMountedIRSAStore()
})
AfterEach(func() {
// Cleanup ClusterSecretStore
err := prov.framework.CRClient.Delete(context.Background(), &esv1alpha1.ClusterSecretStore{
ObjectMeta: metav1.ObjectMeta{
Name: common.ReferencedIRSAStoreName(f),
},
})
Expect(err).ToNot(HaveOccurred())
})
return prov
}
func NewFromEnv(f *framework.Framework) *Provider {
kid := os.Getenv("AWS_ACCESS_KEY_ID")
sak := os.Getenv("AWS_SECRET_ACCESS_KEY")
region := "eu-west-1"
saName := os.Getenv("AWS_SA_NAME")
saNamespace := os.Getenv("AWS_SA_NAMESPACE")
return NewProvider(f, kid, sak, region, saName, saNamespace)
}
// CreateSecret creates a secret at the provider.
func (s *Provider) CreateSecret(key, val string) {
_, err := s.client.PutParameter(&ssm.PutParameterInput{
Name: aws.String(key),
Value: aws.String(val),
DataType: aws.String("text"),
Type: aws.String("String"),
})
Expect(err).ToNot(HaveOccurred())
}
// DeleteSecret deletes a secret at the provider.
func (s *Provider) DeleteSecret(key string) {
_, err := s.client.DeleteParameter(&ssm.DeleteParameterInput{
Name: aws.String(key),
})
Expect(err).ToNot(HaveOccurred())
}
// MountedIRSAStore is a SecretStore without auth config
// ESO relies on the pod-mounted ServiceAccount when using this store.
func (s *Provider) SetupMountedIRSAStore() {
secretStore := &esv1alpha1.SecretStore{
ObjectMeta: metav1.ObjectMeta{
Name: common.MountedIRSAStoreName(s.framework),
Namespace: s.framework.Namespace.Name,
},
Spec: esv1alpha1.SecretStoreSpec{
Provider: &esv1alpha1.SecretStoreProvider{
AWS: &esv1alpha1.AWSProvider{
Service: esv1alpha1.AWSServiceParameterStore,
Region: s.region,
Auth: esv1alpha1.AWSAuth{},
},
},
},
}
err := s.framework.CRClient.Create(context.Background(), secretStore)
Expect(err).ToNot(HaveOccurred())
}
// ReferncedIRSAStore is a ClusterStore
// that references a (IRSA-) ServiceAccount in the default namespace.
func (s *Provider) SetupReferencedIRSAStore() {
log.Logf("creating IRSA ClusterSecretStore %s", s.framework.Namespace.Name)
secretStore := &esv1alpha1.ClusterSecretStore{
ObjectMeta: metav1.ObjectMeta{
Name: common.ReferencedIRSAStoreName(s.framework),
},
}
_, err := controllerutil.CreateOrUpdate(context.Background(), s.framework.CRClient, secretStore, func() error {
secretStore.Spec.Provider = &esv1alpha1.SecretStoreProvider{
AWS: &esv1alpha1.AWSProvider{
Service: esv1alpha1.AWSServiceParameterStore,
Region: s.region,
Auth: esv1alpha1.AWSAuth{
JWTAuth: &esv1alpha1.AWSJWTAuth{
ServiceAccountRef: &esmetav1.ServiceAccountSelector{
Name: s.ServiceAccountName,
Namespace: &s.ServiceAccountNamespace,
},
},
},
},
}
return nil
})
Expect(err).ToNot(HaveOccurred())
}

View file

@ -29,7 +29,6 @@ import (
// nolint // nolint
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@ -37,24 +36,19 @@ import (
esmetav1 "github.com/external-secrets/external-secrets/apis/meta/v1" 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"
"github.com/external-secrets/external-secrets/e2e/framework/log" "github.com/external-secrets/external-secrets/e2e/framework/log"
common "github.com/external-secrets/external-secrets/e2e/suite/aws"
) )
type SMProvider struct { type Provider struct {
ServiceAccountName string ServiceAccountName string
ServiceAccountNamespace string ServiceAccountNamespace string
kid string
sak string
region string region string
client *secretsmanager.SecretsManager client *secretsmanager.SecretsManager
framework *framework.Framework framework *framework.Framework
} }
const ( func NewProvider(f *framework.Framework, kid, sak, region, saName, saNamespace string) *Provider {
staticCredentialsSecretName = "provider-secret"
)
func NewSMProvider(f *framework.Framework, kid, sak, region, saName, saNamespace string) *SMProvider {
sess, err := session.NewSessionWithOptions(session.Options{ sess, err := session.NewSessionWithOptions(session.Options{
Config: aws.Config{ Config: aws.Config{
Credentials: credentials.NewStaticCredentials(kid, sak, ""), Credentials: credentials.NewStaticCredentials(kid, sak, ""),
@ -65,18 +59,16 @@ func NewSMProvider(f *framework.Framework, kid, sak, region, saName, saNamespace
Fail(err.Error()) Fail(err.Error())
} }
sm := secretsmanager.New(sess) sm := secretsmanager.New(sess)
prov := &SMProvider{ prov := &Provider{
ServiceAccountName: saName, ServiceAccountName: saName,
ServiceAccountNamespace: saNamespace, ServiceAccountNamespace: saNamespace,
kid: kid,
sak: sak,
region: region, region: region,
client: sm, client: sm,
framework: f, framework: f,
} }
BeforeEach(func() { BeforeEach(func() {
prov.SetupStaticStore() common.SetupStaticStore(f, kid, sak, region, esv1alpha1.AWSServiceSecretsManager)
prov.SetupReferencedIRSAStore() prov.SetupReferencedIRSAStore()
prov.SetupMountedIRSAStore() prov.SetupMountedIRSAStore()
}) })
@ -85,7 +77,7 @@ func NewSMProvider(f *framework.Framework, kid, sak, region, saName, saNamespace
// Cleanup ClusterSecretStore // Cleanup ClusterSecretStore
err := prov.framework.CRClient.Delete(context.Background(), &esv1alpha1.ClusterSecretStore{ err := prov.framework.CRClient.Delete(context.Background(), &esv1alpha1.ClusterSecretStore{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: prov.ReferencedIRSAStoreName(), Name: common.ReferencedIRSAStoreName(f),
}, },
}) })
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
@ -94,17 +86,17 @@ func NewSMProvider(f *framework.Framework, kid, sak, region, saName, saNamespace
return prov return prov
} }
func NewFromEnv(f *framework.Framework) *SMProvider { func NewFromEnv(f *framework.Framework) *Provider {
kid := os.Getenv("AWS_ACCESS_KEY_ID") kid := os.Getenv("AWS_ACCESS_KEY_ID")
sak := os.Getenv("AWS_SECRET_ACCESS_KEY") sak := os.Getenv("AWS_SECRET_ACCESS_KEY")
region := "eu-west-1" region := "eu-west-1"
saName := os.Getenv("AWS_SA_NAME") saName := os.Getenv("AWS_SA_NAME")
saNamespace := os.Getenv("AWS_SA_NAMESPACE") saNamespace := os.Getenv("AWS_SA_NAMESPACE")
return NewSMProvider(f, kid, sak, region, saName, saNamespace) return NewProvider(f, kid, sak, region, saName, saNamespace)
} }
// CreateSecret creates a secret at the provider. // CreateSecret creates a secret at the provider.
func (s *SMProvider) CreateSecret(key, val string) { func (s *Provider) CreateSecret(key, val string) {
// we re-use some secret names throughout our test suite // we re-use some secret names throughout our test suite
// due to the fact that there is a short delay before the secret is actually deleted // due to the fact that there is a short delay before the secret is actually deleted
// we have to retry creating the secret // we have to retry creating the secret
@ -129,7 +121,7 @@ func (s *SMProvider) CreateSecret(key, val string) {
// DeleteSecret deletes a secret at the provider. // DeleteSecret deletes a secret at the provider.
// There may be a short delay between calling this function // There may be a short delay between calling this function
// and the removal of the secret on the provider side. // and the removal of the secret on the provider side.
func (s *SMProvider) DeleteSecret(key string) { func (s *Provider) DeleteSecret(key string) {
log.Logf("deleting secret %s", key) log.Logf("deleting secret %s", key)
_, err := s.client.DeleteSecret(&secretsmanager.DeleteSecretInput{ _, err := s.client.DeleteSecret(&secretsmanager.DeleteSecretInput{
SecretId: aws.String(key), SecretId: aws.String(key),
@ -140,10 +132,10 @@ func (s *SMProvider) DeleteSecret(key string) {
// MountedIRSAStore is a SecretStore without auth config // MountedIRSAStore is a SecretStore without auth config
// ESO relies on the pod-mounted ServiceAccount when using this store. // ESO relies on the pod-mounted ServiceAccount when using this store.
func (s *SMProvider) SetupMountedIRSAStore() { func (s *Provider) SetupMountedIRSAStore() {
secretStore := &esv1alpha1.SecretStore{ secretStore := &esv1alpha1.SecretStore{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: s.MountedIRSAStoreName(), Name: common.MountedIRSAStoreName(s.framework),
Namespace: s.framework.Namespace.Name, Namespace: s.framework.Namespace.Name,
}, },
Spec: esv1alpha1.SecretStoreSpec{ Spec: esv1alpha1.SecretStoreSpec{
@ -160,17 +152,13 @@ func (s *SMProvider) SetupMountedIRSAStore() {
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
} }
func (s *SMProvider) MountedIRSAStoreName() string {
return "irsa-mounted-" + s.framework.Namespace.Name
}
// ReferncedIRSAStore is a ClusterStore // ReferncedIRSAStore is a ClusterStore
// that references a (IRSA-) ServiceAccount in the default namespace. // that references a (IRSA-) ServiceAccount in the default namespace.
func (s *SMProvider) SetupReferencedIRSAStore() { func (s *Provider) SetupReferencedIRSAStore() {
log.Logf("creating IRSA ClusterSecretStore %s", s.framework.Namespace.Name) log.Logf("creating IRSA ClusterSecretStore %s", s.framework.Namespace.Name)
secretStore := &esv1alpha1.ClusterSecretStore{ secretStore := &esv1alpha1.ClusterSecretStore{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: s.ReferencedIRSAStoreName(), Name: common.ReferencedIRSAStoreName(s.framework),
}, },
} }
_, err := controllerutil.CreateOrUpdate(context.Background(), s.framework.CRClient, secretStore, func() error { _, err := controllerutil.CreateOrUpdate(context.Background(), s.framework.CRClient, secretStore, func() error {
@ -192,53 +180,3 @@ func (s *SMProvider) SetupReferencedIRSAStore() {
}) })
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
} }
func (s *SMProvider) ReferencedIRSAStoreName() string {
return "irsa-ref-" + s.framework.Namespace.Name
}
// StaticStore is namespaced and references
// static credentials from a secret.
func (s *SMProvider) SetupStaticStore() {
awsCreds := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: staticCredentialsSecretName,
Namespace: s.framework.Namespace.Name,
},
StringData: map[string]string{
"kid": s.kid,
"sak": s.sak,
},
}
err := s.framework.CRClient.Create(context.Background(), awsCreds)
Expect(err).ToNot(HaveOccurred())
secretStore := &esv1alpha1.SecretStore{
ObjectMeta: metav1.ObjectMeta{
Name: s.framework.Namespace.Name,
Namespace: s.framework.Namespace.Name,
},
Spec: esv1alpha1.SecretStoreSpec{
Provider: &esv1alpha1.SecretStoreProvider{
AWS: &esv1alpha1.AWSProvider{
Service: esv1alpha1.AWSServiceSecretsManager,
Region: s.region,
Auth: esv1alpha1.AWSAuth{
SecretRef: &esv1alpha1.AWSAuthSecretRef{
AccessKeyID: esmetav1.SecretKeySelector{
Name: staticCredentialsSecretName,
Key: "kid",
},
SecretAccessKey: esmetav1.SecretKeySelector{
Name: staticCredentialsSecretName,
Key: "sak",
},
},
},
},
},
},
}
err = s.framework.CRClient.Create(context.Background(), secretStore)
Expect(err).ToNot(HaveOccurred())
}

View file

@ -0,0 +1,85 @@
/*
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 aws
import (
// nolint
. "github.com/onsi/ginkgo/v2"
"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"
)
// here we use the global eso instance
// that uses the service account in the default namespace
// which was created by terraform.
var _ = Describe("[awsmanaged] IRSA via referenced service account", Label("aws", "secretsmanager", "managed"), func() {
f := framework.New("eso-aws-managed")
prov := NewFromEnv(f)
// nolint
DescribeTable("sync secretsmanager secrets",
framework.TableFunc(f,
prov),
framework.Compose(awscommon.WithReferencedIRSA, f, common.SimpleDataSync, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.NestedJSONWithGJSON, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataFromSync, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataWithProperty, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataWithTemplate, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.DockerJSONConfig, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.DataPropertyDockerconfigJSON, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.SSHKeySync, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.SSHKeySyncDataProperty, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.SyncWithoutTargetName, awscommon.UseClusterSecretStore),
framework.Compose(awscommon.WithReferencedIRSA, f, common.JSONDataWithoutTargetName, awscommon.UseClusterSecretStore),
)
})
// here we create a central eso instance in the default namespace
// that mounts the service account which was created by terraform.
var _ = Describe("[awsmanaged] with mounted IRSA", Label("aws", "secretsmanager", "managed"), func() {
f := framework.New("eso-aws-managed")
prov := NewFromEnv(f)
// each test case gets its own ESO instance
BeforeEach(func() {
f.Install(addon.NewESO(
addon.WithControllerClass(f.BaseName),
addon.WithServiceAccount(prov.ServiceAccountName),
addon.WithReleaseName(f.Namespace.Name),
addon.WithNamespace("default"),
))
})
// nolint
DescribeTable("sync secretsmanager secrets",
framework.TableFunc(f,
prov),
framework.Compose(awscommon.WithMountedIRSA, f, common.SimpleDataSync, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.NestedJSONWithGJSON, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataFromSync, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataWithProperty, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataWithTemplate, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.DockerJSONConfig, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.DataPropertyDockerconfigJSON, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.SSHKeySync, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.SSHKeySyncDataProperty, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.SyncWithoutTargetName, awscommon.UseMountedIRSAStore),
framework.Compose(awscommon.WithMountedIRSA, f, common.JSONDataWithoutTargetName, awscommon.UseMountedIRSAStore),
)
})

View file

@ -1,102 +0,0 @@
/*
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 aws
import (
// nolint
. "github.com/onsi/ginkgo/v2"
esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
"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"
)
const (
withReferencedIRSA = "with referenced IRSA"
withMountedIRSA = "with mounted IRSA"
)
// here we use the global eso instance
// that uses the service account in the default namespace
// which was created by terraform.
var _ = Describe("[awsmanaged] IRSA via referenced service account", Label("aws", "secretsmanager", "managed"), func() {
f := framework.New("eso-aws-managed")
prov := NewFromEnv(f)
DescribeTable("sync secrets",
framework.TableFunc(f,
prov),
framework.Compose(withReferencedIRSA, f, common.SimpleDataSync, useClusterSecretStore(prov)),
framework.Compose(withReferencedIRSA, f, common.NestedJSONWithGJSON, useClusterSecretStore(prov)),
framework.Compose(withReferencedIRSA, f, common.JSONDataFromSync, useClusterSecretStore(prov)),
framework.Compose(withReferencedIRSA, f, common.JSONDataWithProperty, useClusterSecretStore(prov)),
framework.Compose(withReferencedIRSA, f, common.JSONDataWithTemplate, useClusterSecretStore(prov)),
framework.Compose(withReferencedIRSA, f, common.DockerJSONConfig, useClusterSecretStore(prov)),
framework.Compose(withReferencedIRSA, f, common.DataPropertyDockerconfigJSON, useClusterSecretStore(prov)),
framework.Compose(withReferencedIRSA, f, common.SSHKeySync, useClusterSecretStore(prov)),
framework.Compose(withReferencedIRSA, f, common.SSHKeySyncDataProperty, useClusterSecretStore(prov)),
framework.Compose(withReferencedIRSA, f, common.SyncWithoutTargetName, useClusterSecretStore(prov)),
framework.Compose(withReferencedIRSA, f, common.JSONDataWithoutTargetName, useClusterSecretStore(prov)),
)
})
// here we create a central eso instance in the default namespace
// that mounts the service account which was created by terraform.
var _ = Describe("[awsmanaged] with mounted IRSA", Label("aws", "secretsmanager", "managed"), func() {
f := framework.New("eso-aws-managed")
prov := NewFromEnv(f)
// each test case gets its own ESO instance
BeforeEach(func() {
f.Install(addon.NewESO(
addon.WithControllerClass(f.BaseName),
addon.WithServiceAccount(prov.ServiceAccountName),
addon.WithReleaseName(f.Namespace.Name),
addon.WithNamespace("default"),
))
})
DescribeTable("sync secrets",
framework.TableFunc(f,
prov),
framework.Compose(withMountedIRSA, f, common.SimpleDataSync, useMountedIRSAStore(prov)),
framework.Compose(withMountedIRSA, f, common.NestedJSONWithGJSON, useMountedIRSAStore(prov)),
framework.Compose(withMountedIRSA, f, common.JSONDataFromSync, useMountedIRSAStore(prov)),
framework.Compose(withMountedIRSA, f, common.JSONDataWithProperty, useMountedIRSAStore(prov)),
framework.Compose(withMountedIRSA, f, common.JSONDataWithTemplate, useMountedIRSAStore(prov)),
framework.Compose(withMountedIRSA, f, common.DockerJSONConfig, useMountedIRSAStore(prov)),
framework.Compose(withMountedIRSA, f, common.DataPropertyDockerconfigJSON, useMountedIRSAStore(prov)),
framework.Compose(withMountedIRSA, f, common.SSHKeySync, useMountedIRSAStore(prov)),
framework.Compose(withMountedIRSA, f, common.SSHKeySyncDataProperty, useMountedIRSAStore(prov)),
framework.Compose(withMountedIRSA, f, common.SyncWithoutTargetName, useMountedIRSAStore(prov)),
framework.Compose(withMountedIRSA, f, common.JSONDataWithoutTargetName, useMountedIRSAStore(prov)),
)
})
func useClusterSecretStore(prov *SMProvider) func(*framework.TestCase) {
return func(tc *framework.TestCase) {
tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.ClusterSecretStoreKind
tc.ExternalSecret.Spec.SecretStoreRef.Name = prov.ReferencedIRSAStoreName()
}
}
func useMountedIRSAStore(prov *SMProvider) func(*framework.TestCase) {
return func(tc *framework.TestCase) {
tc.ExternalSecret.Spec.SecretStoreRef.Kind = esv1alpha1.SecretStoreKind
tc.ExternalSecret.Spec.SecretStoreRef.Name = prov.MountedIRSAStoreName()
}
}

View file

@ -16,7 +16,8 @@ package suite
import ( import (
// import different e2e test suites. // import different e2e test suites.
_ "github.com/external-secrets/external-secrets/e2e/suite/aws" _ "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/azure"
_ "github.com/external-secrets/external-secrets/e2e/suite/gcp" _ "github.com/external-secrets/external-secrets/e2e/suite/gcp"
_ "github.com/external-secrets/external-secrets/e2e/suite/vault" _ "github.com/external-secrets/external-secrets/e2e/suite/vault"

View file

@ -37,6 +37,25 @@ resource "aws_iam_role" "eso-e2e-irsa" {
"arn:aws:iam::aws:policy/SecretsManagerReadWrite" "arn:aws:iam::aws:policy/SecretsManagerReadWrite"
] ]
inline_policy {
name = "aws_ssm_parameterstore"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ssm:GetParameter",
"ssm:PutParameter",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
} }
resource "null_resource" "apply_sa" { resource "null_resource" "apply_sa" {