Files
paralus/pkg/controller/util/patch.go
nirav-rafay c66bdc25cd restructure rcloud-base as a single base controller (#37)
* restructure rcloud-base as a single base controller
* updated master.rest
* moved sentry from internal to pkg as it is used by relay
* removing unused rpc and it's dependencies
* Fix usermgmt tests
* Don't redefine variables in rest file
Co-authored-by: Abin Simon <abin.simon@rafay.co>
2022-03-03 17:59:06 +05:30

96 lines
3.0 KiB
Go

package util
import (
"fmt"
clusterv2 "github.com/RafaySystems/rcloud-base/proto/types/controller"
apixv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"github.com/RafaySystems/rcloud-base/pkg/controller/scheme"
jp "github.com/evanphx/json-patch"
"k8s.io/apimachinery/pkg/runtime/schema"
jmp "k8s.io/apimachinery/pkg/util/jsonmergepatch"
mp "k8s.io/apimachinery/pkg/util/mergepatch"
sp "k8s.io/apimachinery/pkg/util/strategicpatch"
)
var knownMergePatchGroups = func() map[string]struct{} {
return map[string]struct{}{
clusterv2.GroupVersion.Group: {},
apixv1.GroupName: {},
}
}()
func isKnowMergePatchGroup(gvk schema.GroupVersionKind) bool {
if _, ok := knownMergePatchGroups[gvk.Group]; ok {
return true
}
return false
}
// IsStrategicMergePatch returns true if gvk is present in the registerd scheme
func IsStrategicMergePatch(gvk schema.GroupVersionKind) bool {
return scheme.Scheme.Recognizes(gvk) && !isKnowMergePatchGroup(gvk)
}
// CreateStrategicMergePatch creates strategic merge patch for original and modified
func CreateStrategicMergePatch(gvk schema.GroupVersionKind, original, current, modified []byte) ([]byte, error) {
obj, err := scheme.Scheme.New(gvk)
if err != nil {
return nil, fmt.Errorf("unable to create new k8s object %s", err)
}
var patchMeta sp.PatchMetaFromStruct
patchMeta, err = sp.NewPatchMetaFromStruct(obj)
if err != nil {
err = fmt.Errorf("unable to lookup patch meta %s", err.Error())
return nil, err
}
ret, err := sp.CreateThreeWayMergePatch(original, modified, current, patchMeta, true,
mp.RequireKeyUnchanged("apiVersion"),
mp.RequireKeyUnchanged("kind"),
mp.RequireMetadataKeyUnchanged("name"))
if err != nil {
err = fmt.Errorf("unable to create strategic merge patch %s", err.Error())
}
return ret, err
}
// ApplyStrategicMergePatch applies strategic merge patch on orginal
func ApplyStrategicMergePatch(gvk schema.GroupVersionKind, original, patch []byte) ([]byte, error) {
obj, err := scheme.Scheme.New(gvk)
if err != nil {
return nil, fmt.Errorf("unable to create new k8s object %s", err)
}
fb, err := sp.StrategicMergePatch(original, patch, obj)
if err != nil {
return nil, fmt.Errorf("unable to strategic merge patch %s", err.Error())
}
return fb, nil
}
// CreateJSONMergePatch creates JSON merge patch between original, current and modified
func CreateJSONMergePatch(original, current, modified []byte) ([]byte, error) {
ret, err := jmp.CreateThreeWayJSONMergePatch(original, modified, current,
mp.RequireKeyUnchanged("apiVersion"),
mp.RequireKeyUnchanged("kind"),
mp.RequireMetadataKeyUnchanged("name"))
if err != nil {
err = fmt.Errorf("unable to create json merge patch %s", err.Error())
}
return ret, err
}
// ApplyJSONMergePatch applies JSON merge patch onto the original document
func ApplyJSONMergePatch(original, patch []byte) ([]byte, error) {
fb, err := jp.MergePatch(original, patch)
if err != nil {
return nil, fmt.Errorf("unable to json merge patch %s", err.Error())
}
return fb, nil
}