aggregator.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package remote
  2. import (
  3. "context"
  4. "errors"
  5. "log"
  6. "reflect"
  7. esapi "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
  8. v1 "github.com/external-secrets/external-secrets/apis/meta/v1"
  9. corev1 "k8s.io/api/core/v1"
  10. "k8s.io/apimachinery/pkg/runtime/schema"
  11. "k8s.io/apimachinery/pkg/types"
  12. "sigs.k8s.io/controller-runtime/pkg/client"
  13. "sigs.k8s.io/yaml"
  14. )
  15. type AggregateResult struct {
  16. SecretKeySelectors []v1.SecretKeySelector
  17. ServiceAccountSelectors []v1.ServiceAccountSelector
  18. CAProviders []esapi.CAProvider
  19. }
  20. func aggregateObjects(ctx context.Context, store esapi.GenericStore, kube client.Client, namespace string) ([]byte, error) {
  21. if store == nil {
  22. return nil, errors.New("store can not be nil")
  23. }
  24. res := &AggregateResult{}
  25. storeSpec := store.GetSpec()
  26. iterate(storeSpec.Provider, res)
  27. var objects []byte
  28. for _, sel := range res.SecretKeySelectors {
  29. var secret corev1.Secret
  30. key := types.NamespacedName{
  31. Name: sel.Name,
  32. Namespace: namespace,
  33. }
  34. if store.GetKind() == esapi.ClusterSecretStoreKind && sel.Namespace != nil {
  35. key.Namespace = *sel.Namespace
  36. }
  37. err := kube.Get(ctx, key, &secret)
  38. if err != nil {
  39. return nil, err
  40. }
  41. secret.SetGroupVersionKind(schema.GroupVersionKind{
  42. Kind: "Secret",
  43. Version: "v1",
  44. })
  45. secretBytes, err := yaml.Marshal(secret)
  46. if err != nil {
  47. return nil, err
  48. }
  49. objects = append(objects, secretBytes...)
  50. objects = append(objects, []byte("\n---\n")...)
  51. }
  52. return objects, nil
  53. }
  54. func iterate(data interface{}, res *AggregateResult) {
  55. if reflect.ValueOf(data).Kind() == reflect.Slice {
  56. d := reflect.ValueOf(data)
  57. for i := 0; i < d.Len(); i++ {
  58. val := d.Index(i)
  59. analyse(val, res)
  60. iterate(reflect.Indirect(d.Index(i)).Interface(), res)
  61. }
  62. } else if reflect.ValueOf(data).Kind() == reflect.Map {
  63. d := reflect.ValueOf(data)
  64. for _, k := range d.MapKeys() {
  65. typeOfValue := reflect.TypeOf(d.MapIndex(k).Interface()).Kind()
  66. if typeOfValue == reflect.Map || typeOfValue == reflect.Slice {
  67. val := d.MapIndex(k)
  68. analyse(val, res)
  69. iterate(reflect.Indirect(val).Interface(), res)
  70. } else {
  71. log.Printf("val not map or slice: %#v", typeOfValue)
  72. }
  73. }
  74. } else if reflect.ValueOf(data).Kind() == reflect.Pointer {
  75. originalValue := reflect.ValueOf(data).Elem()
  76. if !originalValue.IsValid() {
  77. return
  78. }
  79. iterate(reflect.Indirect(originalValue).Interface(), res)
  80. } else if reflect.ValueOf(data).Kind() == reflect.Struct {
  81. v := reflect.ValueOf(data)
  82. for _, f := range reflect.VisibleFields(v.Type()) {
  83. val := v.FieldByIndex(f.Index)
  84. analyse(val, res)
  85. vv := reflect.Indirect(val)
  86. if vv.IsValid() {
  87. iterate(vv.Interface(), res)
  88. }
  89. }
  90. }
  91. }
  92. func analyse(val reflect.Value, res *AggregateResult) {
  93. if val.Kind() == reflect.Pointer {
  94. originalValue := val.Elem()
  95. if !originalValue.IsValid() {
  96. return
  97. }
  98. analyse(reflect.Indirect(originalValue), res)
  99. return
  100. }
  101. secretSelT := reflect.TypeOf(v1.SecretKeySelector{})
  102. if val.Type().AssignableTo(secretSelT) {
  103. sel := val.Interface().(v1.SecretKeySelector)
  104. res.SecretKeySelectors = append(res.SecretKeySelectors, sel)
  105. return
  106. }
  107. serviceAccSelT := reflect.TypeOf(v1.ServiceAccountSelector{})
  108. if val.Type().AssignableTo(serviceAccSelT) {
  109. sel := val.Interface().(v1.ServiceAccountSelector)
  110. res.ServiceAccountSelectors = append(res.ServiceAccountSelectors, sel)
  111. return
  112. }
  113. caProviderT := reflect.TypeOf(esapi.CAProvider{})
  114. if val.Type().AssignableTo(caProviderT) {
  115. sel := val.Interface().(esapi.CAProvider)
  116. res.CAProviders = append(res.CAProviders, sel)
  117. return
  118. }
  119. // TODO: add more types that are of interest...
  120. }