writer.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package dynamic
  2. import (
  3. "context"
  4. "github.com/porter-dev/porter/internal/templater/utils"
  5. "github.com/porter-dev/porter/internal/templater"
  6. "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
  7. "k8s.io/apimachinery/pkg/runtime/schema"
  8. "k8s.io/client-go/dynamic"
  9. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  10. )
  11. // TemplateWriter satisfies the templater.TemplateWriter interface
  12. // by creating/updating dynamic k8s resources
  13. type TemplateWriter struct {
  14. // The object to read from, identified by its group-version-kind
  15. Object *Object
  16. Client dynamic.Interface
  17. // The resource that's being written to
  18. resource dynamic.ResourceInterface
  19. // The values to be written
  20. vals map[string]interface{}
  21. // The base values
  22. base map[string]interface{}
  23. }
  24. // NewDynamicTemplateWriter returns a dynamic TemplateWriter
  25. func NewDynamicTemplateWriter(
  26. client dynamic.Interface,
  27. obj *Object,
  28. base map[string]interface{},
  29. ) templater.TemplateWriter {
  30. w := &TemplateWriter{
  31. Object: obj,
  32. Client: client,
  33. base: base,
  34. }
  35. objRes := schema.GroupVersionResource{
  36. Group: w.Object.Group,
  37. Version: w.Object.Version,
  38. Resource: w.Object.Resource,
  39. }
  40. w.resource = w.Client.Resource(objRes).Namespace(w.Object.Namespace)
  41. return w
  42. }
  43. // Transform merges base configuration with vals
  44. func (w *TemplateWriter) Transform() error {
  45. w.vals = utils.CoalesceValues(w.base, w.vals)
  46. return nil
  47. }
  48. // Create creates a new dynamic resource, this must be registered with the API server
  49. func (w *TemplateWriter) Create(vals map[string]interface{}) (map[string]interface{}, error) {
  50. w.vals = vals
  51. err := w.Transform()
  52. if err != nil {
  53. return nil, err
  54. }
  55. create, err := w.resource.Create(context.TODO(), &unstructured.Unstructured{
  56. Object: w.vals,
  57. }, metav1.CreateOptions{})
  58. if err != nil {
  59. return nil, err
  60. }
  61. return create.Object, nil
  62. }
  63. // Update performs an update operation on a k8s resource. The resource must be
  64. // registered with the API server.
  65. func (w *TemplateWriter) Update(vals map[string]interface{}) (map[string]interface{}, error) {
  66. w.vals = vals
  67. err := w.Transform()
  68. if err != nil {
  69. return nil, err
  70. }
  71. update, err := w.resource.Update(context.TODO(), &unstructured.Unstructured{
  72. Object: w.vals,
  73. }, metav1.UpdateOptions{})
  74. if err != nil {
  75. return nil, err
  76. }
  77. return update.Object, nil
  78. }