diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go index 885330d965b..2360ff41e1e 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go @@ -132,7 +132,8 @@ func (f *FieldManager) Update(liveObj, newObj runtime.Object, manager string) (r return nil, fmt.Errorf("failed to build manager identifier: %v", err) } - managed, err = f.updater.Update(liveObjTyped, newObjTyped, apiVersion, managed, manager) + // TODO(apelisse) use the first return value when unions are implemented + _, managed, err = f.updater.Update(liveObjTyped, newObjTyped, apiVersion, managed, manager) if err != nil { return nil, fmt.Errorf("failed to update ManagedFields: %v", err) } @@ -247,6 +248,7 @@ func (f *FieldManager) buildManagerInfo(prefix string, operation metav1.ManagedF var stripSet = fieldpath.NewSet( fieldpath.MakePathOrDie("apiVersion"), fieldpath.MakePathOrDie("kind"), + fieldpath.MakePathOrDie("metadata"), fieldpath.MakePathOrDie("metadata", "name"), fieldpath.MakePathOrDie("metadata", "namespace"), fieldpath.MakePathOrDie("metadata", "creationTimestamp"), @@ -265,9 +267,11 @@ func (f *FieldManager) stripFields(managed fieldpath.ManagedFields, manager stri 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() { + newSet := vs.Set.Difference(stripSet) + if newSet.Empty() { delete(managed, manager) + } else { + managed[manager] = &fieldpath.VersionedSet{Set: newSet, APIVersion: vs.APIVersion, Applied: vs.Applied} } } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go index 929f1e79a7b..ff4022c8863 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/gvkparser.go @@ -35,12 +35,13 @@ type gvkParser struct { parser typed.Parser } -func (p *gvkParser) Type(gvk schema.GroupVersionKind) typed.ParseableType { +func (p *gvkParser) Type(gvk schema.GroupVersionKind) *typed.ParseableType { typeName, ok := p.gvks[gvk] if !ok { return nil } - return p.parser.Type(typeName) + t := p.parser.Type(typeName) + return &t } func newGVKParser(models proto.Models) (*gvkParser, error) { diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/managedfields.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/managedfields.go index 741918fdda4..7f7685c420b 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/managedfields.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/managedfields.go @@ -42,7 +42,7 @@ func RemoveObjectManagedFields(obj runtime.Object) { // DecodeObjectManagedFields extracts and converts the objects ManagedFields into a fieldpath.ManagedFields. func DecodeObjectManagedFields(from runtime.Object) (fieldpath.ManagedFields, error) { if from == nil { - return make(map[string]*fieldpath.VersionedSet), nil + return fieldpath.ManagedFields{}, nil } accessor, err := meta.Accessor(from) if err != nil { @@ -75,7 +75,7 @@ func EncodeObjectManagedFields(obj runtime.Object, fields fieldpath.ManagedField // decodeManagedFields converts ManagedFields from the wire format (api format) // to the format used by sigs.k8s.io/structured-merge-diff func decodeManagedFields(encodedManagedFields []metav1.ManagedFieldsEntry) (managedFields fieldpath.ManagedFields, err error) { - managedFields = make(map[string]*fieldpath.VersionedSet, len(encodedManagedFields)) + managedFields = make(fieldpath.ManagedFields, len(encodedManagedFields)) for _, encodedVersionedSet := range encodedManagedFields { manager, err := BuildManagerIdentifier(&encodedVersionedSet) if err != nil { @@ -113,12 +113,6 @@ func BuildManagerIdentifier(encodedManager *metav1.ManagedFieldsEntry) (manager } func decodeVersionedSet(encodedVersionedSet *metav1.ManagedFieldsEntry) (versionedSet *fieldpath.VersionedSet, err error) { - versionedSet = &fieldpath.VersionedSet{} - versionedSet.APIVersion = fieldpath.APIVersion(encodedVersionedSet.APIVersion) - if encodedVersionedSet.Operation == metav1.ManagedFieldsOperationApply { - versionedSet.Applied = true - } - fields := metav1.Fields{} if encodedVersionedSet.Fields != nil { fields = *encodedVersionedSet.Fields @@ -127,8 +121,7 @@ func decodeVersionedSet(encodedVersionedSet *metav1.ManagedFieldsEntry) (version if err != nil { return nil, fmt.Errorf("error decoding set: %v", err) } - versionedSet.Set = &set - return versionedSet, nil + return &fieldpath.VersionedSet{Set: &set, APIVersion: fieldpath.APIVersion(encodedVersionedSet.APIVersion), Applied: encodedVersionedSet.Operation == metav1.ManagedFieldsOperationApply}, nil } // encodeManagedFields converts ManagedFields from the format used by diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter.go index f275c9f2d88..c9e329d65c4 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter.go @@ -31,9 +31,9 @@ import ( // TypeConverter allows you to convert from runtime.Object to // typed.TypedValue and the other way around. type TypeConverter interface { - ObjectToTyped(runtime.Object) (typed.TypedValue, error) - YAMLToTyped([]byte) (typed.TypedValue, error) - TypedToObject(typed.TypedValue) (runtime.Object, error) + ObjectToTyped(runtime.Object) (*typed.TypedValue, error) + YAMLToTyped([]byte) (*typed.TypedValue, error) + TypedToObject(*typed.TypedValue) (runtime.Object, error) } // DeducedTypeConverter is a TypeConverter for CRDs that don't have a @@ -50,22 +50,22 @@ type DeducedTypeConverter struct{} var _ TypeConverter = DeducedTypeConverter{} // ObjectToTyped converts an object into a TypedValue with a "deduced type". -func (DeducedTypeConverter) ObjectToTyped(obj runtime.Object) (typed.TypedValue, error) { +func (DeducedTypeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) { u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) if err != nil { return nil, err } - return typed.DeducedParseableType{}.FromUnstructured(u) + return typed.DeducedParseableType.FromUnstructured(u) } // YAMLToTyped parses a yaml object into a TypedValue with a "deduced type". -func (DeducedTypeConverter) YAMLToTyped(from []byte) (typed.TypedValue, error) { - return typed.DeducedParseableType{}.FromYAML(typed.YAMLObject(from)) +func (DeducedTypeConverter) YAMLToTyped(from []byte) (*typed.TypedValue, error) { + return typed.DeducedParseableType.FromYAML(typed.YAMLObject(from)) } // TypedToObject transforms the typed value into a runtime.Object. That // is not specific to deduced type. -func (DeducedTypeConverter) TypedToObject(value typed.TypedValue) (runtime.Object, error) { +func (DeducedTypeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) { return valueToObject(value.AsValue()) } @@ -86,7 +86,7 @@ func NewTypeConverter(models proto.Models) (TypeConverter, error) { return &typeConverter{parser: parser}, nil } -func (c *typeConverter) ObjectToTyped(obj runtime.Object) (typed.TypedValue, error) { +func (c *typeConverter) ObjectToTyped(obj runtime.Object) (*typed.TypedValue, error) { u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) if err != nil { return nil, err @@ -99,7 +99,7 @@ func (c *typeConverter) ObjectToTyped(obj runtime.Object) (typed.TypedValue, err return t.FromUnstructured(u) } -func (c *typeConverter) YAMLToTyped(from []byte) (typed.TypedValue, error) { +func (c *typeConverter) YAMLToTyped(from []byte) (*typed.TypedValue, error) { unstructured := &unstructured.Unstructured{Object: map[string]interface{}{}} if err := yaml.Unmarshal(from, &unstructured.Object); err != nil { @@ -114,7 +114,7 @@ func (c *typeConverter) YAMLToTyped(from []byte) (typed.TypedValue, error) { return t.FromYAML(typed.YAMLObject(string(from))) } -func (c *typeConverter) TypedToObject(value typed.TypedValue) (runtime.Object, error) { +func (c *typeConverter) TypedToObject(value *typed.TypedValue) (runtime.Object, error) { return valueToObject(value.AsValue()) } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter_test.go index a29e25c8541..700abb90c50 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/typeconverter_test.go @@ -222,7 +222,7 @@ spec: b.ResetTimer() b.ReportAllocs() - var r typed.TypedValue + var r *typed.TypedValue for i := 0; i < b.N; i++ { var err error r, err = tc.ObjectToTyped(obj) @@ -230,5 +230,5 @@ spec: b.Fatalf("Failed to convert object to typed: %v", err) } } - result = r + result = *r } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter.go index 5f567837a5c..340c8985a6a 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/versionconverter.go @@ -60,7 +60,7 @@ func NewCRDVersionConverter(t TypeConverter, o runtime.ObjectConvertor, h schema } // Convert implements sigs.k8s.io/structured-merge-diff/merge.Converter -func (v *versionConverter) Convert(object typed.TypedValue, version fieldpath.APIVersion) (typed.TypedValue, error) { +func (v *versionConverter) Convert(object *typed.TypedValue, version fieldpath.APIVersion) (*typed.TypedValue, error) { // Convert the smd typed value to a kubernetes object. objectToConvert, err := v.typeConverter.TypedToObject(object) if err != nil {