provider.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. Licensed under the Apache License, Version 2.0 (the "License");
  3. you may not use this file except in compliance with the License.
  4. You may obtain a copy of the License at
  5. http://www.apache.org/licenses/LICENSE-2.0
  6. Unless required by applicable law or agreed to in writing, software
  7. distributed under the License is distributed on an "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. See the License for the specific language governing permissions and
  10. limitations under the License.
  11. */
  12. package grpc
  13. import (
  14. "context"
  15. "encoding/json"
  16. "errors"
  17. "fmt"
  18. "log"
  19. "time"
  20. pb "github.com/external-secrets/external-secrets/pkg/plugin/grpc"
  21. "google.golang.org/grpc"
  22. "google.golang.org/grpc/credentials/insecure"
  23. v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  24. "sigs.k8s.io/controller-runtime/pkg/client"
  25. esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
  26. )
  27. // https://github.com/external-secrets/external-secrets/issues/644
  28. var _ esv1beta1.SecretsClient = &GRPCSecretClient{}
  29. var _ esv1beta1.Provider = &Provider{}
  30. // Provider satisfies the provider interface.
  31. type Provider struct{}
  32. type GRPCSecretClient struct {
  33. kube client.Client
  34. store esv1beta1.GenericStore
  35. namespace string
  36. storeKind string
  37. conn *grpc.ClientConn
  38. pbClient pb.SecretsClientClient
  39. }
  40. func init() {
  41. esv1beta1.Register(&Provider{}, &esv1beta1.SecretStoreProvider{
  42. GRPC: &esv1beta1.GRPCProvider{},
  43. })
  44. }
  45. // Capabilities return the provider supported capabilities (ReadOnly, WriteOnly, ReadWrite).
  46. func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
  47. return esv1beta1.SecretStoreReadWrite
  48. }
  49. func (p *Provider) NewClient(_ context.Context, store esv1beta1.GenericStore, kube client.Client, namespace string) (esv1beta1.SecretsClient, error) {
  50. grpcClient := &GRPCSecretClient{
  51. kube: kube,
  52. store: store,
  53. namespace: namespace,
  54. storeKind: store.GetObjectKind().GroupVersionKind().Kind,
  55. }
  56. provider, err := getProvider(store)
  57. if err != nil {
  58. return nil, err
  59. }
  60. // Set up a connection to the server.
  61. grpcClient.conn, err = grpc.Dial(provider.URL, grpc.WithTransportCredentials(insecure.NewCredentials()))
  62. if err != nil {
  63. log.Fatalf("did not connect: %v", err)
  64. }
  65. grpcClient.pbClient = pb.NewSecretsClientClient(grpcClient.conn)
  66. return grpcClient, nil
  67. }
  68. func (p *Provider) ValidateStore(_ esv1beta1.GenericStore) error {
  69. return nil
  70. }
  71. func getProvider(store esv1beta1.GenericStore) (*esv1beta1.GRPCProvider, error) {
  72. spc := store.GetSpec()
  73. if spc == nil || spc.Provider == nil || spc.Provider.GRPC == nil {
  74. return nil, fmt.Errorf("missing store provider webhook")
  75. }
  76. return spc.Provider.GRPC, nil
  77. }
  78. func (w *GRPCSecretClient) DeleteSecret(_ context.Context, _ esv1beta1.PushRemoteRef) error {
  79. return fmt.Errorf("not implemented")
  80. }
  81. // Not Implemented PushSecret.
  82. func (w *GRPCSecretClient) PushSecret(_ context.Context, _ []byte, _ esv1beta1.PushRemoteRef) error {
  83. return fmt.Errorf("not implemented")
  84. }
  85. // Empty GetAllSecrets.
  86. func (w *GRPCSecretClient) GetAllSecrets(_ context.Context, _ esv1beta1.ExternalSecretFind) (map[string][]byte, error) {
  87. // TO be implemented
  88. return nil, fmt.Errorf("GetAllSecrets not implemented")
  89. }
  90. func (w *GRPCSecretClient) GetSecret(ctx context.Context, ref esv1beta1.ExternalSecretDataRemoteRef) ([]byte, error) {
  91. ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  92. defer cancel()
  93. store := esv1beta1.SecretStore{
  94. TypeMeta: v1.TypeMeta{
  95. APIVersion: esv1beta1.SchemeGroupVersion.String(),
  96. Kind: esv1beta1.SecretStoreKind,
  97. },
  98. Spec: esv1beta1.SecretStoreSpec{
  99. Provider: &esv1beta1.SecretStoreProvider{
  100. Webhook: &esv1beta1.WebhookProvider{
  101. URL: "http://httpbin.org/anything",
  102. },
  103. },
  104. },
  105. }
  106. storeBytes, err := json.Marshal(store)
  107. if err != nil {
  108. return nil, err
  109. }
  110. res, err := w.pbClient.GetSecret(ctx, &pb.GetSecretRequest{
  111. Store: storeBytes,
  112. Namespace: w.namespace,
  113. RemoteRef: &pb.RemoteRef{
  114. Key: ref.Key,
  115. Version: ref.Version,
  116. Property: ref.Property,
  117. MetadataPolicy: string(ref.MetadataPolicy),
  118. DecodingStrategy: string(ref.DecodingStrategy),
  119. ConversionStrategy: string(ref.ConversionStrategy),
  120. },
  121. })
  122. if err != nil {
  123. return nil, err
  124. }
  125. log.Printf("secret=%s, err=%s", string(res.Secret), res.Error)
  126. if res.Error != "" {
  127. return nil, errors.New(res.Error)
  128. }
  129. return res.Secret, nil
  130. }
  131. func (w *GRPCSecretClient) GetSecretMap(ctx context.Context, ref esv1beta1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
  132. return nil, fmt.Errorf("GetSecretMap not implemented")
  133. }
  134. func (w *GRPCSecretClient) Close(_ context.Context) error {
  135. return w.conn.Close()
  136. }
  137. func (w *GRPCSecretClient) Validate() (esv1beta1.ValidationResult, error) {
  138. return esv1beta1.ValidationResultReady, nil
  139. }