client.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. Copyright © The ESO Authors
  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 store adapts v1 provider implementations to the v2 gRPC SecretStoreProvider interface.
  14. package store
  15. import (
  16. "context"
  17. corev1 "k8s.io/api/core/v1"
  18. esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
  19. pb "github.com/external-secrets/external-secrets/proto/provider"
  20. v2 "github.com/external-secrets/external-secrets/providers/v2/common"
  21. )
  22. // Client wraps a v2.Provider (gRPC client) and exposes it as an esv1.SecretsClient.
  23. // This allows v2 providers to be used with the existing client manager infrastructure.
  24. type Client struct {
  25. v2Provider v2.Provider
  26. providerRef *pb.ProviderReference
  27. compatibilityStore *pb.CompatibilityStore
  28. sourceNamespace string
  29. closeFunc func(context.Context) error
  30. }
  31. // Ensure Client implements SecretsClient interface.
  32. var _ esv1.SecretsClient = &Client{}
  33. // NewClient creates a new wrapper that adapts a v2.Provider to esv1.SecretsClient.
  34. func NewClient(v2Provider v2.Provider, providerRef *pb.ProviderReference, sourceNamespace string) esv1.SecretsClient {
  35. return NewClientWithCloser(v2Provider, providerRef, sourceNamespace, nil)
  36. }
  37. // NewClientWithCloser creates a provider-ref based wrapper with a custom close function.
  38. func NewClientWithCloser(v2Provider v2.Provider, providerRef *pb.ProviderReference, sourceNamespace string, closeFunc func(context.Context) error) esv1.SecretsClient {
  39. return &Client{
  40. v2Provider: v2Provider,
  41. providerRef: providerRef,
  42. sourceNamespace: sourceNamespace,
  43. closeFunc: closeFunc,
  44. }
  45. }
  46. // NewCompatibilityClient creates a compatibility-store based wrapper for runtimeRef reads.
  47. func NewCompatibilityClient(v2Provider v2.Provider, compatibilityStore *pb.CompatibilityStore, sourceNamespace string) esv1.SecretsClient {
  48. return NewCompatibilityClientWithCloser(v2Provider, compatibilityStore, sourceNamespace, nil)
  49. }
  50. // NewCompatibilityClientWithCloser creates a compatibility-store based wrapper with a custom close function.
  51. func NewCompatibilityClientWithCloser(v2Provider v2.Provider, compatibilityStore *pb.CompatibilityStore, sourceNamespace string, closeFunc func(context.Context) error) esv1.SecretsClient {
  52. return &Client{
  53. v2Provider: v2Provider,
  54. compatibilityStore: compatibilityStore,
  55. sourceNamespace: sourceNamespace,
  56. closeFunc: closeFunc,
  57. }
  58. }
  59. // GetSecret retrieves a single secret from the provider.
  60. func (w *Client) GetSecret(ctx context.Context, ref esv1.ExternalSecretDataRemoteRef) ([]byte, error) {
  61. return w.v2Provider.GetSecret(ctx, ref, w.providerRef, w.compatibilityStore, w.sourceNamespace)
  62. }
  63. // GetSecretMap retrieves a secret object and returns its key/value pairs.
  64. func (w *Client) GetSecretMap(ctx context.Context, ref esv1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
  65. return w.v2Provider.GetSecretMap(ctx, ref, w.providerRef, w.compatibilityStore, w.sourceNamespace)
  66. }
  67. // GetAllSecrets retrieves multiple secrets based on find criteria.
  68. func (w *Client) GetAllSecrets(ctx context.Context, find esv1.ExternalSecretFind) (map[string][]byte, error) {
  69. return w.v2Provider.GetAllSecrets(ctx, find, w.providerRef, w.compatibilityStore, w.sourceNamespace)
  70. }
  71. // PushSecret writes a secret to the provider.
  72. func (w *Client) PushSecret(ctx context.Context, secret *corev1.Secret, data esv1.PushSecretData) error {
  73. // Convert metadata from *apiextensionsv1.JSON to []byte
  74. var metadata []byte
  75. if data.GetMetadata() != nil {
  76. metadata = data.GetMetadata().Raw
  77. }
  78. // Convert esv1.PushSecretData to pb.PushSecretData
  79. pushSecretData := &pb.PushSecretData{
  80. RemoteKey: data.GetRemoteKey(),
  81. SecretKey: data.GetSecretKey(),
  82. Property: data.GetProperty(),
  83. Metadata: metadata,
  84. }
  85. return w.v2Provider.PushSecret(ctx, secret, pushSecretData, w.providerRef, w.compatibilityStore, w.sourceNamespace)
  86. }
  87. // DeleteSecret deletes a secret from the provider.
  88. func (w *Client) DeleteSecret(ctx context.Context, remoteRef esv1.PushSecretRemoteRef) error {
  89. // Convert esv1.PushSecretRemoteRef to pb.PushSecretRemoteRef
  90. pbRemoteRef := &pb.PushSecretRemoteRef{
  91. RemoteKey: remoteRef.GetRemoteKey(),
  92. Property: remoteRef.GetProperty(),
  93. }
  94. return w.v2Provider.DeleteSecret(ctx, pbRemoteRef, w.providerRef, w.compatibilityStore, w.sourceNamespace)
  95. }
  96. // SecretExists checks if a secret exists in the provider.
  97. func (w *Client) SecretExists(ctx context.Context, remoteRef esv1.PushSecretRemoteRef) (bool, error) {
  98. // Convert esv1.PushSecretRemoteRef to pb.PushSecretRemoteRef
  99. pbRemoteRef := &pb.PushSecretRemoteRef{
  100. RemoteKey: remoteRef.GetRemoteKey(),
  101. Property: remoteRef.GetProperty(),
  102. }
  103. return w.v2Provider.SecretExists(ctx, pbRemoteRef, w.providerRef, w.compatibilityStore, w.sourceNamespace)
  104. }
  105. // Validate checks if the provider is properly configured.
  106. func (w *Client) Validate() (esv1.ValidationResult, error) {
  107. if w.compatibilityStore != nil {
  108. if _, err := CompatibilityStoreToSyntheticStore(w.compatibilityStore); err != nil {
  109. return esv1.ValidationResultError, err
  110. }
  111. }
  112. err := w.v2Provider.Validate(context.Background(), w.providerRef, w.compatibilityStore, w.sourceNamespace)
  113. if err != nil {
  114. return esv1.ValidationResultError, err
  115. }
  116. return esv1.ValidationResultReady, nil
  117. }
  118. // Close cleans up any resources held by the provider client.
  119. func (w *Client) Close(ctx context.Context) error {
  120. if w.closeFunc != nil {
  121. return w.closeFunc(ctx)
  122. }
  123. return w.v2Provider.Close(ctx)
  124. }