Skip to content

Commit

Permalink
feat: add fieldoverrider
Browse files Browse the repository at this point in the history
Signed-off-by: sophie <yl5357@columbia.edu>
  • Loading branch information
sophiefeifeifeiya committed Sep 26, 2024
1 parent 4f7dc2c commit d79631c
Show file tree
Hide file tree
Showing 7 changed files with 744 additions and 5 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/emirpasic/gods v1.18.1
github.com/evanphx/json-patch/v5 v5.9.0
github.com/go-co-op/gocron v1.30.1
github.com/go-openapi/jsonpointer v0.20.2
github.com/gogo/protobuf v1.3.2
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.5.0
Expand Down Expand Up @@ -90,7 +91,6 @@ require (
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/swag v0.22.7 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
Expand Down
121 changes: 121 additions & 0 deletions pkg/util/overridemanager/overridemanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@ package overridemanager
import (
"context"
"encoding/json"
"fmt"
"reflect"
"sort"

jsonpatch "github.com/evanphx/json-patch/v5"
"github.com/go-openapi/jsonpointer"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/client-go/tools/record"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"

clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
Expand Down Expand Up @@ -280,6 +284,52 @@ func applyJSONPatch(obj *unstructured.Unstructured, overrides []overrideOption)
return err
}

// applyRawJSONPatch applies the override on to the given raw json object.
func applyRawJSONPatch(raw []byte, overrides []overrideOption) ([]byte, error) {
jsonPatchBytes, err := json.Marshal(overrides)
if err != nil {
return nil, err
}

patch, err := jsonpatch.DecodePatch(jsonPatchBytes)
if err != nil {
return nil, err
}

return patch.Apply(raw)
}

func applyRawYAMLPatch(raw []byte, overrides []overrideOption) ([]byte, error) {
rawJSON, err := yaml.YAMLToJSON(raw)
if err != nil {
klog.ErrorS(err, "Failed to convert yaml to json")
return nil, err
}

jsonPatchBytes, err := json.Marshal(overrides)
if err != nil {
return nil, err
}

patch, err := jsonpatch.DecodePatch(jsonPatchBytes)
if err != nil {
return nil, err
}

rawJSON, err = patch.Apply(rawJSON)
if err != nil {
return nil, err
}

rawYAML, err := yaml.JSONToYAML(rawJSON)
if err != nil {
klog.Errorf("Failed to convert json to yaml, error: %v", err)
return nil, err
}

return rawYAML, nil
}

// applyPolicyOverriders applies OverridePolicy/ClusterOverridePolicy overriders to target object
func applyPolicyOverriders(rawObj *unstructured.Unstructured, overriders policyv1alpha1.Overriders) error {
err := applyImageOverriders(rawObj, overriders.ImageOverrider)
Expand All @@ -300,6 +350,9 @@ func applyPolicyOverriders(rawObj *unstructured.Unstructured, overriders policyv
if err := applyAnnotationsOverriders(rawObj, overriders.AnnotationsOverrider); err != nil {
return err
}
if err := applyFieldOverriders(rawObj, overriders.FieldOverrider); err != nil {
return err
}
return applyJSONPatch(rawObj, parseJSONPatchesByPlaintext(overriders.Plaintext))
}

Expand Down Expand Up @@ -352,6 +405,50 @@ func applyArgsOverriders(rawObj *unstructured.Unstructured, argsOverriders []pol
return nil
}

func applyFieldOverriders(rawObj *unstructured.Unstructured, FieldOverriders []policyv1alpha1.FieldOverrider) error {
if len(FieldOverriders) == 0 {
return nil
}
for index := range FieldOverriders {
pointer, err := jsonpointer.New(FieldOverriders[index].FieldPath)
if err != nil {
klog.Errorf("Build jsonpointer with overrider's path err: %v", err)
return err
}
res, kind, err := pointer.Get(rawObj.Object)
if err != nil {
klog.Errorf("Get value by overrider's path err: %v", err)
return err
}
if kind != reflect.String {
errMsg := fmt.Sprintf("Get object's value by overrider's path(%s) is not string", FieldOverriders[index].FieldPath)
klog.Errorf(errMsg)
return fmt.Errorf(errMsg)
}
dataBytes := []byte(res.(string))
klog.V(4).Infof("Parsed JSON patches by FieldOverriders[%d](%+v)", index, FieldOverriders[index])
var appliedRawData []byte
if len(FieldOverriders[index].YAML) > 0 {
appliedRawData, err = applyRawYAMLPatch(dataBytes, parseYAMLPatchesByField(FieldOverriders[index].YAML))
if err != nil {
klog.Errorf("Error applying raw JSON patch: %v", err)
return err
}
} else if len(FieldOverriders[index].JSON) > 0 {
appliedRawData, err = applyRawJSONPatch(dataBytes, parseJSONPatchesByField(FieldOverriders[index].JSON))
if err != nil {
klog.Errorf("Error applying raw YAML patch: %v", err)
return err
}
}
_, err = pointer.Set(rawObj.Object, string(appliedRawData))
if err != nil {
return err
}
}
return nil
}

func parseJSONPatchesByPlaintext(overriders []policyv1alpha1.PlaintextOverrider) []overrideOption {
patches := make([]overrideOption, 0, len(overriders))
for i := range overriders {
Expand All @@ -363,3 +460,27 @@ func parseJSONPatchesByPlaintext(overriders []policyv1alpha1.PlaintextOverrider)
}
return patches
}

func parseYAMLPatchesByField(overriders []policyv1alpha1.YAMLPatchOperation) []overrideOption {
patches := make([]overrideOption, 0, len(overriders))
for i := range overriders {
patches = append(patches, overrideOption{
Op: string(overriders[i].Operator),
Path: overriders[i].SubPath,
Value: overriders[i].Value,
})
}
return patches
}

func parseJSONPatchesByField(overriders []policyv1alpha1.JSONPatchOperation) []overrideOption {
patches := make([]overrideOption, 0, len(overriders))
for i := range overriders {
patches = append(patches, overrideOption{
Op: string(overriders[i].Operator),
Path: overriders[i].SubPath,
Value: overriders[i].Value,
})
}
return patches
}
Loading

0 comments on commit d79631c

Please sign in to comment.