github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/kube/patch.go (about)

     1  package kube
     2  
     3  import (
     4  	"encoding/json"
     5  
     6  	"github.com/mattbaird/jsonpatch"
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  // PatchRow used to generate the patch JSON for patching
    11  type PatchRow struct {
    12  	Op    string      `json:"op"`
    13  	Path  string      `json:"path"`
    14  	Value interface{} `json:"value"`
    15  }
    16  
    17  // CreatePatchBytes creates a kubernetes PATCH block
    18  func CreatePatchBytes(op string, path string, value interface{}) ([]byte, error) {
    19  	payload := &PatchRow{
    20  		Op:    op,
    21  		Path:  path,
    22  		Value: value,
    23  	}
    24  	return json.Marshal(payload)
    25  }
    26  
    27  // PatchModifier is a function that is function that mutates an entity during JSON patch generation.
    28  // The function should modify the provided value, and can return an non-nil error if something goes wrong.
    29  type PatchModifier func(obj interface{}) error
    30  
    31  // BuildJSONPatch builds JSON patch data for an entity mutation, that can then be applied to K8S as a Patch update.
    32  // The mutation is applied via the supplied callback, which modifies the entity it is given. If the supplied
    33  // mutate method returns an error then the process is aborted and the error returned.
    34  func BuildJSONPatch(obj interface{}, mutate PatchModifier) ([]byte, error) {
    35  	// Get original JSON.
    36  	oJSON, err := json.Marshal(obj)
    37  	if err != nil {
    38  		return nil, errors.WithMessage(err, "marshalling original data")
    39  	}
    40  
    41  	err = mutate(obj)
    42  	if err != nil {
    43  		return nil, errors.WithMessage(err, "mutating entity")
    44  	}
    45  
    46  	// Get modified JSON & generate a PATCH to apply.
    47  	mJSON, err := json.Marshal(obj)
    48  	if err != nil {
    49  		return nil, errors.WithMessage(err, "marshalling modified data")
    50  	}
    51  	patch, err := jsonpatch.CreatePatch(oJSON, mJSON)
    52  	if err != nil {
    53  		return nil, errors.WithMessage(err, "generating patch data")
    54  	}
    55  	patchJSON, err := json.MarshalIndent(patch, "", "  ")
    56  	if err != nil {
    57  		return nil, errors.WithMessage(err, "marshalling patch data")
    58  	}
    59  
    60  	return patchJSON, nil
    61  }