provider.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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. // /*
  14. // Licensed under the Apache License, Version 2.0 (the "License");
  15. // you may not use this file except in compliance with the License.
  16. // You may obtain a copy of the License at
  17. //
  18. // https://www.apache.org/licenses/LICENSE-2.0
  19. //
  20. // Unless required by applicable law or agreed to in writing, software
  21. // distributed under the License is distributed on an "AS IS" BASIS,
  22. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23. // See the License for the specific language governing permissions and
  24. // limitations under the License.
  25. // */
  26. package github
  27. import (
  28. "context"
  29. "errors"
  30. "fmt"
  31. "sigs.k8s.io/controller-runtime/pkg/client"
  32. "sigs.k8s.io/controller-runtime/pkg/webhook/admission"
  33. esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
  34. )
  35. const (
  36. errUnexpectedStoreSpec = "unexpected store spec"
  37. errInvalidStoreSpec = "invalid store spec"
  38. errInvalidStoreProv = "invalid store provider"
  39. errInvalidGithubProv = "invalid github provider"
  40. errInvalidStore = "invalid store"
  41. errInvalidProvider = "invalid provider"
  42. )
  43. type Provider struct {
  44. }
  45. var _ esv1.Provider = &Provider{}
  46. func init() {
  47. esv1.Register(&Provider{}, &esv1.SecretStoreProvider{
  48. Github: &esv1.GithubProvider{},
  49. }, esv1.MaintenanceStatusMaintained)
  50. }
  51. // Capabilities return the provider supported capabilities (ReadOnly, WriteOnly, ReadWrite).
  52. func (p *Provider) Capabilities() esv1.SecretStoreCapabilities {
  53. return esv1.SecretStoreWriteOnly
  54. }
  55. // NewClient constructs a new secrets client based on the provided store.
  56. func (p *Provider) NewClient(ctx context.Context, store esv1.GenericStore, kube client.Client, namespace string) (esv1.SecretsClient, error) {
  57. return newClient(ctx, store, kube, namespace)
  58. }
  59. func newClient(ctx context.Context, store esv1.GenericStore, kube client.Client, namespace string) (esv1.SecretsClient, error) {
  60. provider, err := getProvider(store)
  61. if err != nil {
  62. return nil, err
  63. }
  64. g := &Client{
  65. crClient: kube,
  66. store: store,
  67. namespace: namespace,
  68. provider: provider,
  69. storeKind: store.GetObjectKind().GroupVersionKind().Kind,
  70. }
  71. g.getSecretFn = g.orgGetSecretFn
  72. g.getPublicKeyFn = g.orgGetPublicKeyFn
  73. g.createOrUpdateFn = g.orgCreateOrUpdateSecret
  74. g.listSecretsFn = g.orgListSecretsFn
  75. g.deleteSecretFn = g.orgDeleteSecretsFn
  76. client, err := g.AuthWithPrivateKey(ctx)
  77. if err != nil {
  78. return nil, fmt.Errorf("could not get private key: %w", err)
  79. }
  80. g.baseClient = *client.Actions
  81. if provider.Repository != "" {
  82. g.getSecretFn = g.repoGetSecretFn
  83. g.getPublicKeyFn = g.repoGetPublicKeyFn
  84. g.createOrUpdateFn = g.repoCreateOrUpdateSecret
  85. g.listSecretsFn = g.repoListSecretsFn
  86. g.deleteSecretFn = g.repoDeleteSecretsFn
  87. if provider.Environment != "" {
  88. // For environment to work, we need the repository ID instead of its name.
  89. repository, _, err := client.Repositories.Get(ctx, g.provider.Organization, g.provider.Repository)
  90. if err != nil {
  91. return nil, fmt.Errorf("error fetching repository: %w", err)
  92. }
  93. g.repoID = repository.GetID()
  94. g.getSecretFn = g.envGetSecretFn
  95. g.getPublicKeyFn = g.envGetPublicKeyFn
  96. g.createOrUpdateFn = g.envCreateOrUpdateSecret
  97. g.listSecretsFn = g.envListSecretsFn
  98. g.deleteSecretFn = g.envDeleteSecretsFn
  99. }
  100. }
  101. return g, nil
  102. }
  103. func getProvider(store esv1.GenericStore) (*esv1.GithubProvider, error) {
  104. spc := store.GetSpec()
  105. if spc == nil || spc.Provider.Github == nil {
  106. return nil, errors.New(errUnexpectedStoreSpec)
  107. }
  108. return spc.Provider.Github, nil
  109. }
  110. func (p *Provider) ValidateStore(store esv1.GenericStore) (admission.Warnings, error) {
  111. if store == nil {
  112. return nil, errors.New(errInvalidStore)
  113. }
  114. spc := store.GetSpec()
  115. if spc == nil {
  116. return nil, errors.New(errInvalidStoreSpec)
  117. }
  118. if spc.Provider == nil {
  119. return nil, errors.New(errInvalidStoreProv)
  120. }
  121. prov := spc.Provider.Github
  122. if prov == nil {
  123. return nil, errors.New(errInvalidGithubProv)
  124. }
  125. return nil, nil
  126. }