writer.go 2.4 KB

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