provider.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. Copyright © 2025 ESO Maintainer Team
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. https://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. // Package previder implements a secret store provider for Previder Vault.
  14. package previder
  15. import (
  16. "context"
  17. "errors"
  18. "fmt"
  19. previderclient "github.com/previder/vault-cli/pkg"
  20. corev1 "k8s.io/api/core/v1"
  21. "sigs.k8s.io/controller-runtime/pkg/client"
  22. "sigs.k8s.io/controller-runtime/pkg/webhook/admission"
  23. esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
  24. "github.com/external-secrets/external-secrets/runtime/esutils/resolvers"
  25. )
  26. const (
  27. errNotImplemented = "not implemented"
  28. )
  29. var _ esv1.Provider = &SecretManager{}
  30. // SecretManager implements the esv1.Provider interface for Previder Vault.
  31. type SecretManager struct {
  32. VaultClient previderclient.PreviderVaultClient
  33. TokenType string
  34. }
  35. // NewClient creates a new Previder Vault client.
  36. func (s *SecretManager) NewClient(ctx context.Context, store esv1.GenericStore, kube client.Client, namespace string) (esv1.SecretsClient, error) {
  37. if store == nil {
  38. return nil, fmt.Errorf("secret store not found: %v", "nil store")
  39. }
  40. storeSpec := store.GetSpec().Provider.Previder
  41. storeKind := store.GetObjectKind().GroupVersionKind().Kind
  42. accessToken, err := resolvers.SecretKeyRef(ctx, kube, storeKind, namespace, &storeSpec.Auth.SecretRef.AccessToken)
  43. if err != nil {
  44. return nil, fmt.Errorf(accessToken, err)
  45. }
  46. s.VaultClient, err = previderclient.NewVaultClient(storeSpec.BaseURI, accessToken)
  47. if err != nil {
  48. return nil, err
  49. }
  50. tokenInfo, err := s.VaultClient.GetTokenInfo()
  51. if err != nil {
  52. return nil, err
  53. }
  54. s.TokenType = tokenInfo.TokenType
  55. return s, nil
  56. }
  57. // ValidateStore validates the Previder Vault store configuration.
  58. func (s *SecretManager) ValidateStore(store esv1.GenericStore) (admission.Warnings, error) {
  59. storeSpec := store.GetSpec()
  60. previderSpec := storeSpec.Provider.Previder
  61. if previderSpec == nil {
  62. return nil, errors.New("missing Previder spec")
  63. }
  64. if previderSpec.Auth.SecretRef == nil {
  65. return nil, errors.New("missing Previder Auth SecretRef")
  66. }
  67. accessToken := previderSpec.Auth.SecretRef.AccessToken
  68. if accessToken.Name == "" {
  69. return nil, errors.New("missing Previder accessToken name")
  70. }
  71. if accessToken.Key == "" {
  72. return nil, errors.New("missing Previder accessToken key")
  73. }
  74. return nil, nil
  75. }
  76. // Capabilities returns the capabilities of the Previder Vault provider.
  77. func (s *SecretManager) Capabilities() esv1.SecretStoreCapabilities {
  78. return esv1.SecretStoreReadOnly
  79. }
  80. // GetSecret retrieves a secret from Previder Vault.
  81. func (s *SecretManager) GetSecret(_ context.Context, ref esv1.ExternalSecretDataRemoteRef) ([]byte, error) {
  82. secret, err := s.VaultClient.DecryptSecret(ref.Key)
  83. if err != nil {
  84. return nil, err
  85. }
  86. return []byte(secret.Secret), nil
  87. }
  88. // PushSecret is not implemented for Previder Vault.
  89. func (s *SecretManager) PushSecret(context.Context, *corev1.Secret, esv1.PushSecretData) error {
  90. return errors.New(errNotImplemented)
  91. }
  92. // DeleteSecret is not implemented for Previder Vault.
  93. func (s *SecretManager) DeleteSecret(context.Context, esv1.PushSecretRemoteRef) error {
  94. return errors.New(errNotImplemented)
  95. }
  96. // SecretExists is not implemented for Previder Vault.
  97. func (s *SecretManager) SecretExists(context.Context, esv1.PushSecretRemoteRef) (bool, error) {
  98. return false, errors.New(errNotImplemented)
  99. }
  100. // Validate checks if the Vault client can connect and retrieve secrets.
  101. func (s *SecretManager) Validate() (esv1.ValidationResult, error) {
  102. _, err := s.VaultClient.GetTokenInfo()
  103. if err != nil {
  104. return esv1.ValidationResultError, err
  105. }
  106. return esv1.ValidationResultReady, nil
  107. }
  108. // GetSecretMap retrieves a secret and returns it as a map with a single key-value pair.
  109. func (s *SecretManager) GetSecretMap(ctx context.Context, ref esv1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
  110. secrets, err := s.GetSecret(ctx, ref)
  111. if err != nil {
  112. return nil, err
  113. }
  114. secretData := make(map[string][]byte)
  115. secretData[ref.Key] = secrets
  116. return secretData, nil
  117. }
  118. // GetAllSecrets is not implemented for Previder Vault.
  119. func (s *SecretManager) GetAllSecrets(context.Context, esv1.ExternalSecretFind) (map[string][]byte, error) {
  120. return nil, errors.New(errNotImplemented)
  121. }
  122. // Close cleans up any resources held by the client.
  123. func (s *SecretManager) Close(context.Context) error {
  124. return nil
  125. }
  126. // NewProvider creates a new Provider instance.
  127. func NewProvider() esv1.Provider {
  128. return &SecretManager{}
  129. }
  130. // ProviderSpec returns the provider specification for registration.
  131. func ProviderSpec() *esv1.SecretStoreProvider {
  132. return &esv1.SecretStoreProvider{
  133. Previder: &esv1.PreviderProvider{},
  134. }
  135. }
  136. // MaintenanceStatus returns the maintenance status of the provider.
  137. func MaintenanceStatus() esv1.MaintenanceStatus {
  138. return esv1.MaintenanceStatusMaintained
  139. }