mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
package patch
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/rancher/wrangler/pkg/gvk"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
|
"k8s.io/client-go/kubernetes/scheme"
|
|
)
|
|
|
|
var (
|
|
patchCache = map[schema.GroupVersionKind]patchCacheEntry{}
|
|
patchCacheLock = sync.Mutex{}
|
|
)
|
|
|
|
type patchCacheEntry struct {
|
|
patchType types.PatchType
|
|
lookup strategicpatch.LookupPatchMeta
|
|
}
|
|
|
|
func isJSONPatch(patch []byte) bool {
|
|
// a JSON patch is a list
|
|
return len(patch) > 0 && patch[0] == '['
|
|
}
|
|
|
|
func GetPatchStyle(original, patch []byte) (types.PatchType, strategicpatch.LookupPatchMeta, error) {
|
|
if isJSONPatch(patch) {
|
|
return types.JSONPatchType, nil, nil
|
|
}
|
|
gvk, ok, err := gvk.Detect(original)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
if !ok {
|
|
return types.MergePatchType, nil, nil
|
|
}
|
|
return GetMergeStyle(gvk)
|
|
}
|
|
|
|
func GetMergeStyle(gvk schema.GroupVersionKind) (types.PatchType, strategicpatch.LookupPatchMeta, error) {
|
|
var (
|
|
patchType types.PatchType
|
|
lookupPatchMeta strategicpatch.LookupPatchMeta
|
|
)
|
|
|
|
patchCacheLock.Lock()
|
|
entry, ok := patchCache[gvk]
|
|
patchCacheLock.Unlock()
|
|
|
|
if ok {
|
|
return entry.patchType, entry.lookup, nil
|
|
}
|
|
|
|
versionedObject, err := scheme.Scheme.New(gvk)
|
|
|
|
if runtime.IsNotRegisteredError(err) {
|
|
patchType = types.MergePatchType
|
|
} else if err != nil {
|
|
return patchType, nil, err
|
|
} else {
|
|
patchType = types.StrategicMergePatchType
|
|
lookupPatchMeta, err = strategicpatch.NewPatchMetaFromStruct(versionedObject)
|
|
if err != nil {
|
|
return patchType, nil, err
|
|
}
|
|
}
|
|
|
|
patchCacheLock.Lock()
|
|
patchCache[gvk] = patchCacheEntry{
|
|
patchType: patchType,
|
|
lookup: lookupPatchMeta,
|
|
}
|
|
patchCacheLock.Unlock()
|
|
|
|
return patchType, lookupPatchMeta, nil
|
|
}
|