Browse Source

Added support different type auth sources (#4877)

Signed-off-by: Ildar Valiullin <ivaliullin@MX2Y3.local>
Co-authored-by: Ildar Valiullin <ivaliullin@MX2Y3.local>
Co-authored-by: Gergely Brautigam <skarlso777@gmail.com>
preved911 7 months ago
parent
commit
8c5b10124e

+ 4 - 3
pkg/provider/yandex/certificatemanager/certificatemanager.go

@@ -38,8 +38,9 @@ func adaptInput(store esv1.GenericStore) (*common.SecretsClientInput, error) {
 	}
 	}
 	storeSpecYandexCertificateManager := storeSpec.Provider.YandexCertificateManager
 	storeSpecYandexCertificateManager := storeSpec.Provider.YandexCertificateManager
 
 
-	if storeSpecYandexCertificateManager.Auth.AuthorizedKey.Name == "" {
-		return nil, errors.New("invalid Yandex Certificate Manager SecretStore resource: missing AuthorizedKey Name")
+	var authorizedKey *esmeta.SecretKeySelector
+	if storeSpecYandexCertificateManager.Auth.AuthorizedKey.Name != "" {
+		authorizedKey = &storeSpecYandexCertificateManager.Auth.AuthorizedKey
 	}
 	}
 
 
 	var caCertificate *esmeta.SecretKeySelector
 	var caCertificate *esmeta.SecretKeySelector
@@ -49,7 +50,7 @@ func adaptInput(store esv1.GenericStore) (*common.SecretsClientInput, error) {
 
 
 	return &common.SecretsClientInput{
 	return &common.SecretsClientInput{
 		APIEndpoint:   storeSpecYandexCertificateManager.APIEndpoint,
 		APIEndpoint:   storeSpecYandexCertificateManager.APIEndpoint,
-		AuthorizedKey: storeSpecYandexCertificateManager.Auth.AuthorizedKey,
+		AuthorizedKey: authorizedKey,
 		CACertificate: caCertificate,
 		CACertificate: caCertificate,
 	}, nil
 	}, nil
 }
 }

+ 10 - 19
pkg/provider/yandex/certificatemanager/certificatemanager_test.go

@@ -47,6 +47,8 @@ const (
 func TestNewClient(t *testing.T) {
 func TestNewClient(t *testing.T) {
 	ctx := context.Background()
 	ctx := context.Background()
 	const namespace = "namespace"
 	const namespace = "namespace"
+	const authorizedKeySecretName = "authorizedKeySecretName"
+	const authorizedKeySecretKey = "authorizedKeySecretKey"
 
 
 	store := &esv1.SecretStore{
 	store := &esv1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 		ObjectMeta: metav1.ObjectMeta{
@@ -54,7 +56,14 @@ func TestNewClient(t *testing.T) {
 		},
 		},
 		Spec: esv1.SecretStoreSpec{
 		Spec: esv1.SecretStoreSpec{
 			Provider: &esv1.SecretStoreProvider{
 			Provider: &esv1.SecretStoreProvider{
-				YandexCertificateManager: &esv1.YandexCertificateManagerProvider{},
+				YandexCertificateManager: &esv1.YandexCertificateManagerProvider{
+					Auth: esv1.YandexCertificateManagerAuth{
+						AuthorizedKey: esmeta.SecretKeySelector{
+							Key:  authorizedKeySecretKey,
+							Name: authorizedKeySecretName,
+						},
+					},
+				},
 			},
 			},
 		},
 		},
 	}
 	}
@@ -63,24 +72,6 @@ func TestNewClient(t *testing.T) {
 
 
 	k8sClient := clientfake.NewClientBuilder().Build()
 	k8sClient := clientfake.NewClientBuilder().Build()
 	secretClient, err := provider.NewClient(context.Background(), store, k8sClient, namespace)
 	secretClient, err := provider.NewClient(context.Background(), store, k8sClient, namespace)
-	tassert.EqualError(t, err, errMissingKey)
-	tassert.Nil(t, secretClient)
-
-	store.Spec.Provider.YandexCertificateManager.Auth = esv1.YandexCertificateManagerAuth{}
-	secretClient, err = provider.NewClient(context.Background(), store, k8sClient, namespace)
-	tassert.EqualError(t, err, errMissingKey)
-	tassert.Nil(t, secretClient)
-
-	store.Spec.Provider.YandexCertificateManager.Auth.AuthorizedKey = esmeta.SecretKeySelector{}
-	secretClient, err = provider.NewClient(context.Background(), store, k8sClient, namespace)
-	tassert.EqualError(t, err, errMissingKey)
-	tassert.Nil(t, secretClient)
-
-	const authorizedKeySecretName = "authorizedKeySecretName"
-	const authorizedKeySecretKey = "authorizedKeySecretKey"
-	store.Spec.Provider.YandexCertificateManager.Auth.AuthorizedKey.Name = authorizedKeySecretName
-	store.Spec.Provider.YandexCertificateManager.Auth.AuthorizedKey.Key = authorizedKeySecretKey
-	secretClient, err = provider.NewClient(context.Background(), store, k8sClient, namespace)
 	tassert.EqualError(t, err, "cannot get Kubernetes secret \"authorizedKeySecretName\" from namespace \"namespace\": secrets \"authorizedKeySecretName\" not found")
 	tassert.EqualError(t, err, "cannot get Kubernetes secret \"authorizedKeySecretName\" from namespace \"namespace\": secrets \"authorizedKeySecretName\" not found")
 	tassert.Nil(t, secretClient)
 	tassert.Nil(t, secretClient)
 
 

+ 34 - 19
pkg/provider/yandex/common/provider.go

@@ -101,7 +101,7 @@ type IamToken struct {
 
 
 type SecretsClientInput struct {
 type SecretsClientInput struct {
 	APIEndpoint   string
 	APIEndpoint   string
-	AuthorizedKey esmeta.SecretKeySelector
+	AuthorizedKey *esmeta.SecretKeySelector
 	CACertificate *esmeta.SecretKeySelector
 	CACertificate *esmeta.SecretKeySelector
 }
 }
 
 
@@ -116,21 +116,24 @@ func (p *YandexCloudProvider) NewClient(ctx context.Context, store esv1.GenericS
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	key, err := resolvers.SecretKeyRef(
-		ctx,
-		kube,
-		store.GetKind(),
-		namespace,
-		&input.AuthorizedKey,
-	)
-	if err != nil {
-		return nil, err
-	}
+	var authorizedKey *iamkey.Key
+	if input.AuthorizedKey != nil {
+		key, err := resolvers.SecretKeyRef(
+			ctx,
+			kube,
+			store.GetKind(),
+			namespace,
+			input.AuthorizedKey,
+		)
+		if err != nil {
+			return nil, err
+		}
 
 
-	var authorizedKey iamkey.Key
-	err = json.Unmarshal([]byte(key), &authorizedKey)
-	if err != nil {
-		return nil, fmt.Errorf("unable to unmarshal authorized key: %w", err)
+		authorizedKey = &iamkey.Key{}
+		err = json.Unmarshal([]byte(key), authorizedKey)
+		if err != nil {
+			return nil, fmt.Errorf("unable to unmarshal authorized key: %w", err)
+		}
 	}
 	}
 
 
 	var caCertificateData []byte
 	var caCertificateData []byte
@@ -148,12 +151,12 @@ func (p *YandexCloudProvider) NewClient(ctx context.Context, store esv1.GenericS
 		caCertificateData = []byte(caCert)
 		caCertificateData = []byte(caCert)
 	}
 	}
 
 
-	secretGetter, err := p.getOrCreateSecretGetter(ctx, input.APIEndpoint, &authorizedKey, caCertificateData)
+	secretGetter, err := p.getOrCreateSecretGetter(ctx, input.APIEndpoint, authorizedKey, caCertificateData)
 	if err != nil {
 	if err != nil {
 		return nil, fmt.Errorf("failed to create Yandex.Cloud client: %w", err)
 		return nil, fmt.Errorf("failed to create Yandex.Cloud client: %w", err)
 	}
 	}
 
 
-	iamToken, err := p.getOrCreateIamToken(ctx, input.APIEndpoint, &authorizedKey, caCertificateData)
+	iamToken, err := p.getOrCreateIamToken(ctx, input.APIEndpoint, authorizedKey, caCertificateData)
 	if err != nil {
 	if err != nil {
 		return nil, fmt.Errorf("failed to create IAM token: %w", err)
 		return nil, fmt.Errorf("failed to create IAM token: %w", err)
 	}
 	}
@@ -183,14 +186,22 @@ func (p *YandexCloudProvider) getOrCreateIamToken(ctx context.Context, apiEndpoi
 
 
 	iamTokenKey := buildIamTokenKey(authorizedKey)
 	iamTokenKey := buildIamTokenKey(authorizedKey)
 	if iamToken, ok := p.iamTokenMap[iamTokenKey]; !ok || !p.isIamTokenUsable(iamToken) {
 	if iamToken, ok := p.iamTokenMap[iamTokenKey]; !ok || !p.isIamTokenUsable(iamToken) {
-		p.logger.Info("creating IAM token", "authorizedKeyId", authorizedKey.Id)
+		if authorizedKey != nil {
+			p.logger.Info("creating IAM token", "authorizedKeyId", authorizedKey.Id)
+		} else {
+			p.logger.Info("creating instance SA IAM token")
+		}
 
 
 		iamToken, err := p.newIamTokenFunc(ctx, apiEndpoint, authorizedKey, caCertificate)
 		iamToken, err := p.newIamTokenFunc(ctx, apiEndpoint, authorizedKey, caCertificate)
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
 
 
-		p.logger.Info("created IAM token", "authorizedKeyId", authorizedKey.Id, "expiresAt", iamToken.ExpiresAt)
+		if authorizedKey != nil {
+			p.logger.Info("created IAM token", "authorizedKeyId", authorizedKey.Id, "expiresAt", iamToken.ExpiresAt)
+		} else {
+			p.logger.Info("created instance SA IAM token", "expiresAt", iamToken.ExpiresAt)
+		}
 
 
 		p.iamTokenMap[iamTokenKey] = iamToken
 		p.iamTokenMap[iamTokenKey] = iamToken
 	}
 	}
@@ -203,6 +214,10 @@ func (p *YandexCloudProvider) isIamTokenUsable(iamToken *IamToken) bool {
 }
 }
 
 
 func buildIamTokenKey(authorizedKey *iamkey.Key) iamTokenKey {
 func buildIamTokenKey(authorizedKey *iamkey.Key) iamTokenKey {
+	if authorizedKey == nil {
+		return iamTokenKey{}
+	}
+
 	privateKeyHash := sha256.Sum256([]byte(authorizedKey.PrivateKey))
 	privateKeyHash := sha256.Sum256([]byte(authorizedKey.PrivateKey))
 	return iamTokenKey{
 	return iamTokenKey{
 		authorizedKey.GetId(),
 		authorizedKey.GetId(),

+ 9 - 3
pkg/provider/yandex/common/sdk.go

@@ -114,9 +114,15 @@ func tlsConfig(caCertificate []byte) (*tls.Config, error) {
 }
 }
 
 
 func buildSDK(ctx context.Context, apiEndpoint string, authorizedKey *iamkey.Key, tlsConfig *tls.Config) (*ycsdk.SDK, error) {
 func buildSDK(ctx context.Context, apiEndpoint string, authorizedKey *iamkey.Key, tlsConfig *tls.Config) (*ycsdk.SDK, error) {
-	creds, err := ycsdk.ServiceAccountKey(authorizedKey)
-	if err != nil {
-		return nil, err
+	var creds ycsdk.Credentials
+	if authorizedKey != nil {
+		var err error
+		creds, err = ycsdk.ServiceAccountKey(authorizedKey)
+		if err != nil {
+			return nil, err
+		}
+	} else {
+		creds = ycsdk.InstanceServiceAccount()
 	}
 	}
 
 
 	sdk, err := ycsdk.Build(ctx, ycsdk.Config{
 	sdk, err := ycsdk.Build(ctx, ycsdk.Config{

+ 4 - 3
pkg/provider/yandex/lockbox/lockbox.go

@@ -38,8 +38,9 @@ func adaptInput(store esv1.GenericStore) (*common.SecretsClientInput, error) {
 	}
 	}
 	storeSpecYandexLockbox := storeSpec.Provider.YandexLockbox
 	storeSpecYandexLockbox := storeSpec.Provider.YandexLockbox
 
 
-	if storeSpecYandexLockbox.Auth.AuthorizedKey.Name == "" {
-		return nil, errors.New("invalid Yandex Lockbox SecretStore resource: missing AuthorizedKey Name")
+	var authorizedKey *esmeta.SecretKeySelector
+	if storeSpecYandexLockbox.Auth.AuthorizedKey.Name != "" {
+		authorizedKey = &storeSpecYandexLockbox.Auth.AuthorizedKey
 	}
 	}
 
 
 	var caCertificate *esmeta.SecretKeySelector
 	var caCertificate *esmeta.SecretKeySelector
@@ -49,7 +50,7 @@ func adaptInput(store esv1.GenericStore) (*common.SecretsClientInput, error) {
 
 
 	return &common.SecretsClientInput{
 	return &common.SecretsClientInput{
 		APIEndpoint:   storeSpecYandexLockbox.APIEndpoint,
 		APIEndpoint:   storeSpecYandexLockbox.APIEndpoint,
-		AuthorizedKey: storeSpecYandexLockbox.Auth.AuthorizedKey,
+		AuthorizedKey: authorizedKey,
 		CACertificate: caCertificate,
 		CACertificate: caCertificate,
 	}, nil
 	}, nil
 }
 }

+ 10 - 19
pkg/provider/yandex/lockbox/lockbox_test.go

@@ -47,6 +47,8 @@ const (
 func TestNewClient(t *testing.T) {
 func TestNewClient(t *testing.T) {
 	ctx := context.Background()
 	ctx := context.Background()
 	const namespace = "namespace"
 	const namespace = "namespace"
+	const authorizedKeySecretName = "authorizedKeySecretName"
+	const authorizedKeySecretKey = "authorizedKeySecretKey"
 
 
 	store := &esv1.SecretStore{
 	store := &esv1.SecretStore{
 		ObjectMeta: metav1.ObjectMeta{
 		ObjectMeta: metav1.ObjectMeta{
@@ -54,7 +56,14 @@ func TestNewClient(t *testing.T) {
 		},
 		},
 		Spec: esv1.SecretStoreSpec{
 		Spec: esv1.SecretStoreSpec{
 			Provider: &esv1.SecretStoreProvider{
 			Provider: &esv1.SecretStoreProvider{
-				YandexLockbox: &esv1.YandexLockboxProvider{},
+				YandexLockbox: &esv1.YandexLockboxProvider{
+					Auth: esv1.YandexLockboxAuth{
+						AuthorizedKey: esmeta.SecretKeySelector{
+							Key:  authorizedKeySecretKey,
+							Name: authorizedKeySecretName,
+						},
+					},
+				},
 			},
 			},
 		},
 		},
 	}
 	}
@@ -63,24 +72,6 @@ func TestNewClient(t *testing.T) {
 
 
 	k8sClient := clientfake.NewClientBuilder().Build()
 	k8sClient := clientfake.NewClientBuilder().Build()
 	secretClient, err := provider.NewClient(context.Background(), store, k8sClient, namespace)
 	secretClient, err := provider.NewClient(context.Background(), store, k8sClient, namespace)
-	tassert.EqualError(t, err, errMissingKey)
-	tassert.Nil(t, secretClient)
-
-	store.Spec.Provider.YandexLockbox.Auth = esv1.YandexLockboxAuth{}
-	secretClient, err = provider.NewClient(context.Background(), store, k8sClient, namespace)
-	tassert.EqualError(t, err, errMissingKey)
-	tassert.Nil(t, secretClient)
-
-	store.Spec.Provider.YandexLockbox.Auth.AuthorizedKey = esmeta.SecretKeySelector{}
-	secretClient, err = provider.NewClient(context.Background(), store, k8sClient, namespace)
-	tassert.EqualError(t, err, errMissingKey)
-	tassert.Nil(t, secretClient)
-
-	const authorizedKeySecretName = "authorizedKeySecretName"
-	const authorizedKeySecretKey = "authorizedKeySecretKey"
-	store.Spec.Provider.YandexLockbox.Auth.AuthorizedKey.Name = authorizedKeySecretName
-	store.Spec.Provider.YandexLockbox.Auth.AuthorizedKey.Key = authorizedKeySecretKey
-	secretClient, err = provider.NewClient(context.Background(), store, k8sClient, namespace)
 	tassert.EqualError(t, err, "cannot get Kubernetes secret \"authorizedKeySecretName\" from namespace \"namespace\": secrets \"authorizedKeySecretName\" not found")
 	tassert.EqualError(t, err, "cannot get Kubernetes secret \"authorizedKeySecretName\" from namespace \"namespace\": secrets \"authorizedKeySecretName\" not found")
 	tassert.Nil(t, secretClient)
 	tassert.Nil(t, secretClient)