Unverified Commit ff504cd8 authored by Kubernetes Prow Robot's avatar Kubernetes Prow Robot Committed by GitHub

Merge pull request #73681 from kwiesmueller/feature-serverside-apply

strip selected fields from managedFields
parents f9684998 9082cac4
...@@ -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