Commit 9082cac4 authored by Kevin Wiesmüller's avatar Kevin Wiesmüller

strip selected fields from managedFields

refactor fieldstrip and update tests add checks and remove empty fields shorten test and check for nil manager fix gofmt panic on nil manager
parent f7c4389b
...@@ -51,6 +51,7 @@ func NewFieldManager(models openapiproto.Models, objectConverter runtime.ObjectC ...@@ -51,6 +51,7 @@ func NewFieldManager(models openapiproto.Models, objectConverter runtime.ObjectC
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &FieldManager{ return &FieldManager{
typeConverter: typeConverter, typeConverter: typeConverter,
objectConverter: objectConverter, objectConverter: objectConverter,
...@@ -130,6 +131,7 @@ func (f *FieldManager) Update(liveObj, newObj runtime.Object, manager string) (r ...@@ -130,6 +131,7 @@ func (f *FieldManager) Update(liveObj, newObj runtime.Object, manager string) (r
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to update ManagedFields: %v", err) return nil, fmt.Errorf("failed to update ManagedFields: %v", err)
} }
managed = f.stripFields(managed, manager)
if err := internal.EncodeObjectManagedFields(newObj, managed); err != nil { if err := internal.EncodeObjectManagedFields(newObj, managed); err != nil {
return nil, fmt.Errorf("failed to encode managed fields: %v", err) return nil, fmt.Errorf("failed to encode managed fields: %v", err)
...@@ -180,6 +182,7 @@ func (f *FieldManager) Apply(liveObj runtime.Object, patch []byte, force bool) ( ...@@ -180,6 +182,7 @@ func (f *FieldManager) Apply(liveObj runtime.Object, patch []byte, force bool) (
} }
return nil, err return nil, err
} }
managed = f.stripFields(managed, manager)
newObj, err := f.typeConverter.TypedToObject(newObjTyped) newObj, err := f.typeConverter.TypedToObject(newObjTyped)
if err != nil { if err != nil {
...@@ -223,3 +226,31 @@ func (f *FieldManager) buildManagerInfo(prefix string, operation metav1.ManagedF ...@@ -223,3 +226,31 @@ func (f *FieldManager) buildManagerInfo(prefix string, operation metav1.ManagedF
} }
return internal.BuildManagerIdentifier(&managerInfo) return internal.BuildManagerIdentifier(&managerInfo)
} }
// stripSet is the list of fields that should never be part of a mangedFields.
var stripSet = fieldpath.NewSet(
fieldpath.MakePathOrDie("apiVersion"),
fieldpath.MakePathOrDie("kind"),
fieldpath.MakePathOrDie("metadata", "name"),
fieldpath.MakePathOrDie("metadata", "namespace"),
fieldpath.MakePathOrDie("metadata", "creationTimestamp"),
fieldpath.MakePathOrDie("metadata", "selfLink"),
fieldpath.MakePathOrDie("metadata", "uid"),
fieldpath.MakePathOrDie("metadata", "resourceVersion"),
)
// stripFields removes a predefined set of paths found in typed from managed and returns the updated ManagedFields
func (f *FieldManager) stripFields(managed fieldpath.ManagedFields, manager string) fieldpath.ManagedFields {
vs, ok := managed[manager]
if ok {
if vs == nil {
panic(fmt.Sprintf("Found unexpected nil manager which should never happen: %s", manager))
}
vs.Set = vs.Set.Difference(stripSet)
if vs.Set.Empty() {
delete(managed, manager)
}
}
return managed
}
...@@ -223,7 +223,11 @@ func TestApplyManagedFields(t *testing.T) { ...@@ -223,7 +223,11 @@ func TestApplyManagedFields(t *testing.T) {
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",
"metadata": { "metadata": {
"name": "test-cm" "name": "test-cm",
"namespace": "default",
"labels": {
"test-label": "test"
}
}, },
"data": { "data": {
"key": "value" "key": "value"
...@@ -267,16 +271,19 @@ func TestApplyManagedFields(t *testing.T) { ...@@ -267,16 +271,19 @@ func TestApplyManagedFields(t *testing.T) {
"uid": "` + string(accessor.GetUID()) + `", "uid": "` + string(accessor.GetUID()) + `",
"resourceVersion": "` + accessor.GetResourceVersion() + `", "resourceVersion": "` + accessor.GetResourceVersion() + `",
"creationTimestamp": "` + accessor.GetCreationTimestamp().UTC().Format(time.RFC3339) + `", "creationTimestamp": "` + accessor.GetCreationTimestamp().UTC().Format(time.RFC3339) + `",
"labels": {
"test-label": "test"
},
"managedFields": [ "managedFields": [
{ {
"manager": "apply", "manager": "apply",
"operation": "Apply", "operation": "Apply",
"apiVersion": "v1", "apiVersion": "v1",
"fields": { "fields": {
"f:apiVersion": {},
"f:kind": {},
"f:metadata": { "f:metadata": {
"f:name": {} "f:labels": {
"f:test-label": {}
}
} }
} }
}, },
...@@ -302,3 +309,54 @@ func TestApplyManagedFields(t *testing.T) { ...@@ -302,3 +309,54 @@ func TestApplyManagedFields(t *testing.T) {
t.Fatalf("Expected:\n%v\nGot:\n%v", string(expected), string(actual)) t.Fatalf("Expected:\n%v\nGot:\n%v", string(expected), string(actual))
} }
} }
// TestApplyRemovesEmptyManagedFields there are no empty managers in managedFields
func TestApplyRemovesEmptyManagedFields(t *testing.T) {
defer utilfeaturetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.ServerSideApply, true)()
_, client, closeFn := setup(t)
defer closeFn()
obj := []byte(`{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": {
"name": "test-cm",
"namespace": "default"
}
}`)
_, err := client.CoreV1().RESTClient().Patch(types.ApplyPatchType).
Namespace("default").
Resource("configmaps").
Name("test-cm").
Body(obj).
Do().
Get()
if err != nil {
t.Fatalf("Failed to create object using Apply patch: %v", err)
}
_, err = client.CoreV1().RESTClient().Patch(types.ApplyPatchType).
Namespace("default").
Resource("configmaps").
Name("test-cm").
Body(obj).Do().Get()
if err != nil {
t.Fatalf("Failed to patch object: %v", err)
}
object, err := client.CoreV1().RESTClient().Get().Namespace("default").Resource("configmaps").Name("test-cm").Do().Get()
if err != nil {
t.Fatalf("Failed to retrieve object: %v", err)
}
accessor, err := meta.Accessor(object)
if err != nil {
t.Fatalf("Failed to get meta accessor: %v", err)
}
if managed := accessor.GetManagedFields(); managed != nil {
t.Fatalf("Object contains unexpected managedFields: %v", managed)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment