Skip to content

Commit

Permalink
chore: refactor/centralise secretKeyRef usage
Browse files Browse the repository at this point in the history
Signed-off-by: Moritz Johner <beller.moritz@googlemail.com>
  • Loading branch information
moolen committed Jan 13, 2024
1 parent 04bccc5 commit 6dbe631
Show file tree
Hide file tree
Showing 37 changed files with 290 additions and 750 deletions.
4 changes: 2 additions & 2 deletions apis/externalsecrets/v1beta1/secretstore_conjur_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ type ConjurProvider struct {

type ConjurAuth struct {
// +optional
Apikey *ConjurApikey `json:"apikey,omitempty"`
APIKey *ConjurAPIKey `json:"apikey,omitempty"`
// +optional
Jwt *ConjurJWT `json:"jwt,omitempty"`
}

type ConjurApikey struct {
type ConjurAPIKey struct {
Account string `json:"account"`
UserRef *esmeta.SecretKeySelector `json:"userRef"`
APIKeyRef *esmeta.SecretKeySelector `json:"apiKeyRef"`
Expand Down
14 changes: 7 additions & 7 deletions apis/externalsecrets/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/generator/gcr/gcr.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (g *Generator) generate(
ts, err := tokenSource(ctx, esv1beta1.GCPSMAuth{
SecretRef: (*esv1beta1.GCPSMAuthSecretRef)(res.Spec.Auth.SecretRef),
WorkloadIdentity: (*esv1beta1.GCPWorkloadIdentity)(res.Spec.Auth.WorkloadIdentity),
}, res.Spec.ProjectID, false, kube, namespace)
}, res.Spec.ProjectID, "", kube, namespace)
if err != nil {
return nil, err
}
Expand All @@ -81,7 +81,7 @@ func (g *Generator) generate(
}, nil
}

type tokenSourceFunc func(ctx context.Context, auth esv1beta1.GCPSMAuth, projectID string, isClusterKind bool, kube client.Client, namespace string) (oauth2.TokenSource, error)
type tokenSourceFunc func(ctx context.Context, auth esv1beta1.GCPSMAuth, projectID string, storeKind string, kube client.Client, namespace string) (oauth2.TokenSource, error)

func parseSpec(data []byte) (*genv1alpha1.GCRAccessToken, error) {
var spec genv1alpha1.GCRAccessToken
Expand Down
2 changes: 1 addition & 1 deletion pkg/generator/gcr/gcr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TestGenerate(t *testing.T) {
"foo": []byte("bar"),
},
}).Build(),
fakeTokenSource: func(ctx context.Context, auth v1beta1.GCPSMAuth, projectID string, isClusterKind bool, kube client.Client, namespace string) (oauth2.TokenSource, error) {
fakeTokenSource: func(ctx context.Context, auth v1beta1.GCPSMAuth, projectID string, storeKind string, kube client.Client, namespace string) (oauth2.TokenSource, error) {
return oauth2.StaticTokenSource(&oauth2.Token{
AccessToken: "1234",
Expiry: time.Unix(5555, 0),
Expand Down
20 changes: 11 additions & 9 deletions pkg/provider/akeyless/akeyless.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,12 +426,14 @@ func (a *akeylessBase) getCACertPool(provider *esv1beta1.AkeylessProvider) (*x50
}
ok := caCertPool.AppendCertsFromPEM(pem)
if !ok {
return nil, fmt.Errorf("failed to append cabundle")
return nil, fmt.Errorf("failed to append caBundle")
}
}

if provider.CAProvider != nil && a.storeKind == esv1beta1.ClusterSecretStoreKind && provider.CAProvider.Namespace == nil {
return nil, fmt.Errorf("missing namespace on CAProvider secret")
if provider.CAProvider != nil &&
a.storeKind == esv1beta1.ClusterSecretStoreKind &&
provider.CAProvider.Namespace == nil {
return nil, fmt.Errorf("missing namespace on caProvider secret")
}

if provider.CAProvider != nil {
Expand All @@ -444,7 +446,7 @@ func (a *akeylessBase) getCACertPool(provider *esv1beta1.AkeylessProvider) (*x50
case esv1beta1.CAProviderTypeConfigMap:
cert, err = a.getCertFromConfigMap(provider)
default:
err = fmt.Errorf("unknown caprovider type: %s", provider.CAProvider.Type)
err = fmt.Errorf("unknown CAProvider type: %s", provider.CAProvider.Type)
}

if err != nil {
Expand All @@ -456,7 +458,7 @@ func (a *akeylessBase) getCACertPool(provider *esv1beta1.AkeylessProvider) (*x50
}
ok := caCertPool.AppendCertsFromPEM(pem)
if !ok {
return nil, fmt.Errorf("failed to append cabundle")
return nil, fmt.Errorf("failed to append caBundle")
}
}
return caCertPool, nil
Expand All @@ -473,12 +475,12 @@ func (a *akeylessBase) getCertFromSecret(provider *esv1beta1.AkeylessProvider) (
}

ctx := context.Background()
res, err := a.secretKeyRef(ctx, &secretRef)
cert, err := utils.ResolveSecretKeyRef(ctx, a.kube, a.storeKind, a.namespace, &secretRef)
if err != nil {
return nil, err
}

return []byte(res), nil
return []byte(cert), nil
}

func (a *akeylessBase) getCertFromConfigMap(provider *esv1beta1.AkeylessProvider) ([]byte, error) {
Expand All @@ -494,12 +496,12 @@ func (a *akeylessBase) getCertFromConfigMap(provider *esv1beta1.AkeylessProvider
ctx := context.Background()
err := a.kube.Get(ctx, objKey, configMapRef)
if err != nil {
return nil, fmt.Errorf("failed to get caprovider secret %s: %w", objKey.Name, err)
return nil, fmt.Errorf("failed to get caProvider secret %s: %w", objKey.Name, err)
}

val, ok := configMapRef.Data[provider.CAProvider.Key]
if !ok {
return nil, fmt.Errorf("failed to get caprovider configmap %s -> %s", objKey.Name, provider.CAProvider.Key)
return nil, fmt.Errorf("failed to get caProvider configMap %s -> %s", objKey.Name, provider.CAProvider.Key)
}

return []byte(val), nil
Expand Down
32 changes: 4 additions & 28 deletions pkg/provider/akeyless/akeyless_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (

esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
"github.com/external-secrets/external-secrets/pkg/utils"
)

var apiErr akeyless.GenericOpenAPIError
Expand Down Expand Up @@ -335,7 +336,7 @@ func (a *akeylessBase) getK8SServiceAccountJWT(ctx context.Context, kubernetesAu
tokenRef = kubernetesAuth.SecretRef.DeepCopy()
tokenRef.Key = "token"
}
jwt, err := a.secretKeyRef(ctx, tokenRef)
jwt, err := utils.ResolveSecretKeyRef(ctx, a.kube, a.storeKind, a.namespace, tokenRef)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -363,7 +364,7 @@ func (a *akeylessBase) getJWTFromServiceAccount(ctx context.Context, serviceAcco
return "", fmt.Errorf(errGetKubeSASecrets, ref.Name)
}
for _, tokenRef := range serviceAccount.Secrets {
retval, err := a.secretKeyRef(ctx, &esmeta.SecretKeySelector{
token, err := utils.ResolveSecretKeyRef(ctx, a.kube, a.storeKind, a.namespace, &esmeta.SecretKeySelector{
Name: tokenRef.Name,
Namespace: &ref.Namespace,
Key: "token",
Expand All @@ -372,36 +373,11 @@ func (a *akeylessBase) getJWTFromServiceAccount(ctx context.Context, serviceAcco
continue
}

return retval, nil
return token, nil
}
return "", fmt.Errorf(errGetKubeSANoToken, ref.Name)
}

func (a *akeylessBase) secretKeyRef(ctx context.Context, secretRef *esmeta.SecretKeySelector) (string, error) {
secret := &corev1.Secret{}
ref := types.NamespacedName{
Namespace: a.namespace,
Name: secretRef.Name,
}
if (a.storeKind == esv1beta1.ClusterSecretStoreKind) &&
(secretRef.Namespace != nil) {
ref.Namespace = *secretRef.Namespace
}
err := a.kube.Get(ctx, ref, secret)
if err != nil {
return "", fmt.Errorf(errGetKubeSecret, ref.Name, err)
}

keyBytes, ok := secret.Data[secretRef.Key]
if !ok {
return "", fmt.Errorf(errSecretKeyFmt, secretRef.Key)
}

value := string(keyBytes)
valueStr := strings.TrimSpace(value)
return valueStr, nil
}

func (a *akeylessBase) getJWTfromServiceAccountToken(ctx context.Context, serviceAccountRef esmeta.ServiceAccountSelector, additionalAud []string, expirationSeconds int64) (string, error) {
audiences := serviceAccountRef.Audiences
if len(additionalAud) > 0 {
Expand Down
55 changes: 9 additions & 46 deletions pkg/provider/alibaba/kms.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"github.com/avast/retry-go/v4"
"github.com/tidwall/gjson"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
kclient "sigs.k8s.io/controller-runtime/pkg/client"

esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
Expand All @@ -39,7 +38,8 @@ const (
errUninitalizedAlibabaProvider = "provider Alibaba is not initialized"
errInvalidClusterStoreMissingAKIDNamespace = "invalid ClusterStore, missing AccessKeyID namespace"
errInvalidClusterStoreMissingSKNamespace = "invalid ClusterStore, missing namespace"
errFetchAKIDSecret = "could not fetch AccessKeyID secret: %w"
errFetchAccessKeyID = "could not fetch AccessKeyID secret: %w"
errFetchAccessKeySecret = "could not fetch AccessKeyID secret: %w"
errMissingSAK = "missing AccessSecretKey"
errMissingAKID = "missing AccessKeyID"
)
Expand Down Expand Up @@ -222,54 +222,17 @@ func newAccessKeyAuth(ctx context.Context, kube kclient.Client, store esv1beta1.
storeSpec := store.GetSpec()
alibabaSpec := storeSpec.Provider.Alibaba
storeKind := store.GetObjectKind().GroupVersionKind().Kind

credentialsSecret := &corev1.Secret{}
credentialsSecretName := alibabaSpec.Auth.SecretRef.AccessKeyID.Name
if credentialsSecretName == "" {
return nil, fmt.Errorf(errAlibabaCredSecretName)
}
objectKey := types.NamespacedName{
Name: credentialsSecretName,
Namespace: namespace,
}

// only ClusterStore is allowed to set namespace (and then it's required)
if storeKind == esv1beta1.ClusterSecretStoreKind {
if alibabaSpec.Auth.SecretRef.AccessKeyID.Namespace == nil {
return nil, fmt.Errorf(errInvalidClusterStoreMissingAKIDNamespace)
}
objectKey.Namespace = *alibabaSpec.Auth.SecretRef.AccessKeyID.Namespace
}

err := kube.Get(ctx, objectKey, credentialsSecret)
accessKeyID, err := utils.ResolveSecretKeyRef(ctx, kube, storeKind, namespace, &alibabaSpec.Auth.SecretRef.AccessKeyID)

Check failure on line 225 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / unit-tests

undefined: utils.ResolveSecretKeyRef

Check failure on line 225 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / publish-artifacts (Dockerfile, CGO_ENABLED=0, amd64 arm64 s390x, linux/amd64,linux/arm64,linux/s3... / Build and Publish

undefined: utils.ResolveSecretKeyRef

Check failure on line 225 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / publish-artifacts (Dockerfile.ubi, CGO_ENABLED=0 GOEXPERIMENT=boringcrypto, amd64, linux/amd64, -... / Build and Publish

undefined: utils.ResolveSecretKeyRef

Check failure on line 225 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / publish-artifacts (Dockerfile.ubi, CGO_ENABLED=0, amd64 arm64, linux/amd64,linux/arm64, -ubi) / Build and Publish

undefined: utils.ResolveSecretKeyRef
if err != nil {
return nil, fmt.Errorf(errFetchAKIDSecret, err)
}

objectKey = types.NamespacedName{
Name: alibabaSpec.Auth.SecretRef.AccessKeySecret.Name,
Namespace: namespace,
}
if storeKind == esv1beta1.ClusterSecretStoreKind {
if alibabaSpec.Auth.SecretRef.AccessKeySecret.Namespace == nil {
return nil, fmt.Errorf(errInvalidClusterStoreMissingSKNamespace)
}
objectKey.Namespace = *alibabaSpec.Auth.SecretRef.AccessKeySecret.Namespace
}

accessKeyID := credentialsSecret.Data[alibabaSpec.Auth.SecretRef.AccessKeyID.Key]
if (accessKeyID == nil) || (len(accessKeyID) == 0) {
return nil, fmt.Errorf(errMissingAKID)
return nil, fmt.Errorf(errFetchAccessKeyID, err)
}

accessKeySecret := credentialsSecret.Data[alibabaSpec.Auth.SecretRef.AccessKeySecret.Key]
if (accessKeySecret == nil) || (len(accessKeySecret) == 0) {
return nil, fmt.Errorf(errMissingSAK)
accessKeySecret, err := utils.ResolveSecretKeyRef(ctx, kube, storeKind, namespace, &alibabaSpec.Auth.SecretRef.AccessKeySecret)

Check failure on line 229 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / unit-tests

undefined: utils.ResolveSecretKeyRef

Check failure on line 229 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / publish-artifacts (Dockerfile, CGO_ENABLED=0, amd64 arm64 s390x, linux/amd64,linux/arm64,linux/s3... / Build and Publish

undefined: utils.ResolveSecretKeyRef

Check failure on line 229 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / publish-artifacts (Dockerfile.ubi, CGO_ENABLED=0 GOEXPERIMENT=boringcrypto, amd64, linux/amd64, -... / Build and Publish

undefined: utils.ResolveSecretKeyRef

Check failure on line 229 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / publish-artifacts (Dockerfile.ubi, CGO_ENABLED=0, amd64 arm64, linux/amd64,linux/arm64, -ubi) / Build and Publish

undefined: utils.ResolveSecretKeyRef
if err != nil {
return nil, fmt.Errorf(errFetchAccessKeySecret, err)
}

credentialConfig := &credential.Config{
AccessKeyId: utils.Ptr(string(accessKeyID)),
AccessKeySecret: utils.Ptr(string(accessKeySecret)),
AccessKeyId: utils.Ptr(accessKeyID),

Check failure on line 234 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / unit-tests

cannot infer T (/home/runner/work/external-secrets/external-secrets/pkg/utils/utils.go:398:10)

Check failure on line 234 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / publish-artifacts (Dockerfile, CGO_ENABLED=0, amd64 arm64 s390x, linux/amd64,linux/arm64,linux/s3... / Build and Publish

cannot infer T (/home/runner/work/external-secrets/external-secrets/pkg/utils/utils.go:398:10)

Check failure on line 234 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / publish-artifacts (Dockerfile.ubi, CGO_ENABLED=0 GOEXPERIMENT=boringcrypto, amd64, linux/amd64, -... / Build and Publish

cannot infer T (/home/runner/work/external-secrets/external-secrets/pkg/utils/utils.go:398:10)

Check failure on line 234 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / publish-artifacts (Dockerfile.ubi, CGO_ENABLED=0, amd64 arm64, linux/amd64,linux/arm64, -ubi) / Build and Publish

cannot infer T (/home/runner/work/external-secrets/external-secrets/pkg/utils/utils.go:398:10)
AccessKeySecret: utils.Ptr(accessKeySecret),

Check failure on line 235 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / unit-tests

cannot infer T (/home/runner/work/external-secrets/external-secrets/pkg/utils/utils.go:398:10)

Check failure on line 235 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / publish-artifacts (Dockerfile, CGO_ENABLED=0, amd64 arm64 s390x, linux/amd64,linux/arm64,linux/s3... / Build and Publish

cannot infer T (/home/runner/work/external-secrets/external-secrets/pkg/utils/utils.go:398:10)

Check failure on line 235 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / publish-artifacts (Dockerfile.ubi, CGO_ENABLED=0 GOEXPERIMENT=boringcrypto, amd64, linux/amd64, -... / Build and Publish

cannot infer T (/home/runner/work/external-secrets/external-secrets/pkg/utils/utils.go:398:10)

Check failure on line 235 in pkg/provider/alibaba/kms.go

View workflow job for this annotation

GitHub Actions / publish-artifacts (Dockerfile.ubi, CGO_ENABLED=0, amd64 arm64, linux/amd64,linux/arm64, -ubi) / Build and Publish

cannot infer T (/home/runner/work/external-secrets/external-secrets/pkg/utils/utils.go:398:10)
Type: utils.Ptr("access_key"),
ConnectTimeout: utils.Ptr(30),
Timeout: utils.Ptr(60),
Expand Down
54 changes: 11 additions & 43 deletions pkg/provider/aws/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"github.com/external-secrets/external-secrets/pkg/cache"
"github.com/external-secrets/external-secrets/pkg/feature"
"github.com/external-secrets/external-secrets/pkg/provider/aws/util"
"github.com/external-secrets/external-secrets/pkg/utils"
)

// Config contains configuration to create a new AWS provider.
Expand Down Expand Up @@ -98,11 +99,11 @@ func New(ctx context.Context, store esv1beta1.GenericStore, kube client.Client,
}
}

// use credentials from sercretRef
// use credentials from secretRef
secretRef := prov.Auth.SecretRef
if secretRef != nil {
log.V(1).Info("using credentials from secretRef")
creds, err = credsFromSecretRef(ctx, prov.Auth, isClusterKind, kube, namespace)
creds, err = credsFromSecretRef(ctx, prov.Auth, store.GetKind(), kube, namespace)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -176,11 +177,11 @@ func NewGeneratorSession(ctx context.Context, auth esv1beta1.AWSAuth, role, regi
}
}

// use credentials from sercretRef
// use credentials from secretRef
secretRef := auth.SecretRef
if secretRef != nil {
log.V(1).Info("using credentials from secretRef")
creds, err = credsFromSecretRef(ctx, auth, false, kube, namespace)
creds, err = credsFromSecretRef(ctx, auth, "", kube, namespace)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -211,55 +212,22 @@ func NewGeneratorSession(ctx context.Context, auth esv1beta1.AWSAuth, role, regi
// construct a aws.Credentials object
// The namespace of the external secret is used if the ClusterSecretStore does not specify a namespace (referentAuth)
// If the ClusterSecretStore defines a namespace it will take precedence.
func credsFromSecretRef(ctx context.Context, auth esv1beta1.AWSAuth, isClusterKind bool, kube client.Client, namespace string) (*credentials.Credentials, error) {
ke := client.ObjectKey{
Name: auth.SecretRef.AccessKeyID.Name,
Namespace: namespace,
}
if isClusterKind && auth.SecretRef.AccessKeyID.Namespace != nil {
ke.Namespace = *auth.SecretRef.AccessKeyID.Namespace
}
akSecret := v1.Secret{}
err := kube.Get(ctx, ke, &akSecret)
if err != nil {
return nil, fmt.Errorf(errFetchAKIDSecret, err)
}
ke = client.ObjectKey{
Name: auth.SecretRef.SecretAccessKey.Name,
Namespace: namespace,
}
if isClusterKind && auth.SecretRef.SecretAccessKey.Namespace != nil {
ke.Namespace = *auth.SecretRef.SecretAccessKey.Namespace
}
sakSecret := v1.Secret{}
err = kube.Get(ctx, ke, &sakSecret)
func credsFromSecretRef(ctx context.Context, auth esv1beta1.AWSAuth, storeKind string, kube client.Client, namespace string) (*credentials.Credentials, error) {
sak, err := utils.ResolveSecretKeyRef(ctx, kube, storeKind, namespace, &auth.SecretRef.SecretAccessKey)
if err != nil {
return nil, fmt.Errorf(errFetchSAKSecret, err)
}
sak := string(sakSecret.Data[auth.SecretRef.SecretAccessKey.Key])
aks := string(akSecret.Data[auth.SecretRef.AccessKeyID.Key])
if sak == "" {
return nil, fmt.Errorf(errMissingSAK)
}
if aks == "" {
return nil, fmt.Errorf(errMissingAKID)
aks, err := utils.ResolveSecretKeyRef(ctx, kube, storeKind, namespace, &auth.SecretRef.AccessKeyID)
if err != nil {
return nil, fmt.Errorf(errFetchAKIDSecret, err)
}

var sessionToken string
if auth.SecretRef.SessionToken != nil {
ke = client.ObjectKey{
Name: auth.SecretRef.SessionToken.Name,
Namespace: namespace,
}
if isClusterKind && auth.SecretRef.SessionToken.Namespace != nil {
ke.Namespace = *auth.SecretRef.SessionToken.Namespace
}
stSecret := v1.Secret{}
err = kube.Get(ctx, ke, &stSecret)
sessionToken, err = utils.ResolveSecretKeyRef(ctx, kube, storeKind, namespace, auth.SecretRef.SessionToken)
if err != nil {
return nil, fmt.Errorf(errFetchSTSecret, err)
}
sessionToken = string(stSecret.Data[auth.SecretRef.SessionToken.Key])
}

return credentials.NewStaticCredentials(aks, sak, sessionToken), err
Expand Down
2 changes: 1 addition & 1 deletion pkg/provider/aws/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ func TestNewSession(t *testing.T) {
Data: map[string][]byte{},
},
},
expectErr: "missing SecretAccessKey",
expectErr: "could not fetch SecretAccessKey secret: cannot find secret data for key: \"two\"",
},
{
name: "should not be able to access secrets from different namespace",
Expand Down

0 comments on commit 6dbe631

Please sign in to comment.