parser.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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 templating
  13. import (
  14. "context"
  15. "encoding/json"
  16. "fmt"
  17. "strings"
  18. v1 "k8s.io/api/core/v1"
  19. "k8s.io/apimachinery/pkg/types"
  20. "sigs.k8s.io/controller-runtime/pkg/client"
  21. esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
  22. "github.com/external-secrets/external-secrets/pkg/template"
  23. )
  24. const fieldOwnerTemplate = "externalsecrets.external-secrets.io/%v"
  25. var (
  26. errTplCMMissingKey = "error in configmap %s: missing key %s"
  27. errTplSecMissingKey = "error in secret %s: missing key %s"
  28. errExecTpl = "could not execute template: %w"
  29. )
  30. type Parser struct {
  31. Exec template.ExecFunc
  32. DataMap map[string][]byte
  33. Client client.Client
  34. TargetSecret *v1.Secret
  35. }
  36. func (p *Parser) MergeConfigMap(ctx context.Context, namespace string, tpl esv1beta1.TemplateFrom) error {
  37. if tpl.ConfigMap == nil {
  38. return nil
  39. }
  40. var cm v1.ConfigMap
  41. err := p.Client.Get(ctx, types.NamespacedName{
  42. Name: tpl.ConfigMap.Name,
  43. Namespace: namespace,
  44. }, &cm)
  45. if err != nil {
  46. return err
  47. }
  48. for _, k := range tpl.ConfigMap.Items {
  49. val, ok := cm.Data[k.Key]
  50. out := make(map[string][]byte)
  51. if !ok {
  52. return fmt.Errorf(errTplCMMissingKey, tpl.ConfigMap.Name, k.Key)
  53. }
  54. switch k.TemplateAs {
  55. case esv1beta1.TemplateScopeValues:
  56. out[k.Key] = []byte(val)
  57. case esv1beta1.TemplateScopeKeysAndValues:
  58. out[val] = []byte(val)
  59. }
  60. err = p.Exec(out, p.DataMap, k.TemplateAs, tpl.Target, p.TargetSecret)
  61. if err != nil {
  62. return err
  63. }
  64. }
  65. return nil
  66. }
  67. func (p *Parser) MergeSecret(ctx context.Context, namespace string, tpl esv1beta1.TemplateFrom) error {
  68. if tpl.Secret == nil {
  69. return nil
  70. }
  71. var sec v1.Secret
  72. err := p.Client.Get(ctx, types.NamespacedName{
  73. Name: tpl.Secret.Name,
  74. Namespace: namespace,
  75. }, &sec)
  76. if err != nil {
  77. return err
  78. }
  79. for _, k := range tpl.Secret.Items {
  80. val, ok := sec.Data[k.Key]
  81. if !ok {
  82. return fmt.Errorf(errTplSecMissingKey, tpl.Secret.Name, k.Key)
  83. }
  84. out := make(map[string][]byte)
  85. switch k.TemplateAs {
  86. case esv1beta1.TemplateScopeValues:
  87. out[k.Key] = val
  88. case esv1beta1.TemplateScopeKeysAndValues:
  89. out[string(val)] = val
  90. }
  91. err = p.Exec(out, p.DataMap, k.TemplateAs, tpl.Target, p.TargetSecret)
  92. if err != nil {
  93. return err
  94. }
  95. }
  96. return nil
  97. }
  98. func (p *Parser) MergeLiteral(_ context.Context, tpl esv1beta1.TemplateFrom) error {
  99. if tpl.Literal == nil {
  100. return nil
  101. }
  102. out := make(map[string][]byte)
  103. out[*tpl.Literal] = []byte(*tpl.Literal)
  104. return p.Exec(out, p.DataMap, esv1beta1.TemplateScopeKeysAndValues, tpl.Target, p.TargetSecret)
  105. }
  106. func (p *Parser) MergeTemplateFrom(ctx context.Context, namespace string, template *esv1beta1.ExternalSecretTemplate) error {
  107. if template == nil {
  108. return nil
  109. }
  110. for _, tpl := range template.TemplateFrom {
  111. err := p.MergeConfigMap(ctx, namespace, tpl)
  112. if err != nil {
  113. return err
  114. }
  115. err = p.MergeSecret(ctx, namespace, tpl)
  116. if err != nil {
  117. return err
  118. }
  119. err = p.MergeLiteral(ctx, tpl)
  120. if err != nil {
  121. return err
  122. }
  123. }
  124. return nil
  125. }
  126. func (p *Parser) MergeMap(tplMap map[string]string, target esv1beta1.TemplateTarget) error {
  127. byteMap := make(map[string][]byte)
  128. for k, v := range tplMap {
  129. byteMap[k] = []byte(v)
  130. }
  131. err := p.Exec(byteMap, p.DataMap, esv1beta1.TemplateScopeValues, target, p.TargetSecret)
  132. if err != nil {
  133. return fmt.Errorf(errExecTpl, err)
  134. }
  135. return nil
  136. }
  137. func GetManagedAnnotationKeys(secret *v1.Secret, fieldOwner string) ([]string, error) {
  138. return getManagedFieldKeys(secret, fieldOwner, func(fields map[string]interface{}) []string {
  139. metadataFields, exists := fields["f:metadata"]
  140. if !exists {
  141. return nil
  142. }
  143. mf, ok := metadataFields.(map[string]interface{})
  144. if !ok {
  145. return nil
  146. }
  147. annotationFields, exists := mf["f:annotations"]
  148. if !exists {
  149. return nil
  150. }
  151. af, ok := annotationFields.(map[string]interface{})
  152. if !ok {
  153. return nil
  154. }
  155. var keys []string
  156. for k := range af {
  157. keys = append(keys, k)
  158. }
  159. return keys
  160. })
  161. }
  162. func GetManagedLabelKeys(secret *v1.Secret, fieldOwner string) ([]string, error) {
  163. return getManagedFieldKeys(secret, fieldOwner, func(fields map[string]interface{}) []string {
  164. metadataFields, exists := fields["f:metadata"]
  165. if !exists {
  166. return nil
  167. }
  168. mf, ok := metadataFields.(map[string]interface{})
  169. if !ok {
  170. return nil
  171. }
  172. labelFields, exists := mf["f:labels"]
  173. if !exists {
  174. return nil
  175. }
  176. lf, ok := labelFields.(map[string]interface{})
  177. if !ok {
  178. return nil
  179. }
  180. var keys []string
  181. for k := range lf {
  182. keys = append(keys, k)
  183. }
  184. return keys
  185. })
  186. }
  187. func getManagedFieldKeys(
  188. secret *v1.Secret,
  189. fieldOwner string,
  190. process func(fields map[string]interface{}) []string,
  191. ) ([]string, error) {
  192. fqdn := fmt.Sprintf(fieldOwnerTemplate, fieldOwner)
  193. var keys []string
  194. for _, v := range secret.ObjectMeta.ManagedFields {
  195. if v.Manager != fqdn {
  196. continue
  197. }
  198. fields := make(map[string]interface{})
  199. err := json.Unmarshal(v.FieldsV1.Raw, &fields)
  200. if err != nil {
  201. return nil, fmt.Errorf("error unmarshaling managed fields: %w", err)
  202. }
  203. for _, key := range process(fields) {
  204. if key == "." {
  205. continue
  206. }
  207. keys = append(keys, strings.TrimPrefix(key, "f:"))
  208. }
  209. }
  210. return keys, nil
  211. }