@@ -28,6 +28,12 @@ import (
28
28
"sigs.k8s.io/structured-merge-diff/fieldpath"
29
29
)
30
30
31
+ // Managed groups a fieldpath.ManagedFields together with the timestamps associated with each operation.
32
+ type Managed struct {
33
+ Fields fieldpath.ManagedFields
34
+ Times map [string ]* metav1.Time
35
+ }
36
+
31
37
// RemoveObjectManagedFields removes the ManagedFields from the object
32
38
// before we merge so that it doesn't appear in the ManagedFields
33
39
// recursively.
@@ -40,9 +46,9 @@ func RemoveObjectManagedFields(obj runtime.Object) {
40
46
}
41
47
42
48
// DecodeObjectManagedFields extracts and converts the objects ManagedFields into a fieldpath.ManagedFields.
43
- func DecodeObjectManagedFields (from runtime.Object ) (fieldpath. ManagedFields , error ) {
49
+ func DecodeObjectManagedFields (from runtime.Object ) (Managed , error ) {
44
50
if from == nil {
45
- return fieldpath. ManagedFields {}, nil
51
+ return Managed {}, nil
46
52
}
47
53
accessor , err := meta .Accessor (from )
48
54
if err != nil {
@@ -51,42 +57,44 @@ func DecodeObjectManagedFields(from runtime.Object) (fieldpath.ManagedFields, er
51
57
52
58
managed , err := decodeManagedFields (accessor .GetManagedFields ())
53
59
if err != nil {
54
- return nil , fmt .Errorf ("failed to convert managed fields from API: %v" , err )
60
+ return Managed {} , fmt .Errorf ("failed to convert managed fields from API: %v" , err )
55
61
}
56
62
return managed , err
57
63
}
58
64
59
65
// EncodeObjectManagedFields converts and stores the fieldpathManagedFields into the objects ManagedFields
60
- func EncodeObjectManagedFields (obj runtime.Object , fields fieldpath. ManagedFields ) error {
66
+ func EncodeObjectManagedFields (obj runtime.Object , managed Managed ) error {
61
67
accessor , err := meta .Accessor (obj )
62
68
if err != nil {
63
69
panic (fmt .Sprintf ("couldn't get accessor: %v" , err ))
64
70
}
65
71
66
- managed , err := encodeManagedFields (fields )
72
+ encodedManagedFields , err := encodeManagedFields (managed )
67
73
if err != nil {
68
74
return fmt .Errorf ("failed to convert back managed fields to API: %v" , err )
69
75
}
70
- accessor .SetManagedFields (managed )
76
+ accessor .SetManagedFields (encodedManagedFields )
71
77
72
78
return nil
73
79
}
74
80
75
81
// decodeManagedFields converts ManagedFields from the wire format (api format)
76
82
// to the format used by sigs.k8s.io/structured-merge-diff
77
- func decodeManagedFields (encodedManagedFields []metav1.ManagedFieldsEntry ) (managedFields fieldpath.ManagedFields , err error ) {
78
- managedFields = make (fieldpath.ManagedFields , len (encodedManagedFields ))
83
+ func decodeManagedFields (encodedManagedFields []metav1.ManagedFieldsEntry ) (managed Managed , err error ) {
84
+ managed .Fields = make (fieldpath.ManagedFields , len (encodedManagedFields ))
85
+ managed .Times = make (map [string ]* metav1.Time , len (encodedManagedFields ))
79
86
for _ , encodedVersionedSet := range encodedManagedFields {
80
87
manager , err := BuildManagerIdentifier (& encodedVersionedSet )
81
88
if err != nil {
82
- return nil , fmt .Errorf ("error decoding manager from %v: %v" , encodedVersionedSet , err )
89
+ return Managed {} , fmt .Errorf ("error decoding manager from %v: %v" , encodedVersionedSet , err )
83
90
}
84
- managedFields [manager ], err = decodeVersionedSet (& encodedVersionedSet )
91
+ managed . Fields [manager ], err = decodeVersionedSet (& encodedVersionedSet )
85
92
if err != nil {
86
- return nil , fmt .Errorf ("error decoding versioned set from %v: %v" , encodedVersionedSet , err )
93
+ return Managed {} , fmt .Errorf ("error decoding versioned set from %v: %v" , encodedVersionedSet , err )
87
94
}
95
+ managed .Times [manager ] = encodedVersionedSet .Time
88
96
}
89
- return managedFields , nil
97
+ return managed , nil
90
98
}
91
99
92
100
// BuildManagerIdentifier creates a manager identifier string from a ManagedFieldsEntry
@@ -96,11 +104,13 @@ func BuildManagerIdentifier(encodedManager *metav1.ManagedFieldsEntry) (manager
96
104
// Never include the fields in the manager identifier
97
105
encodedManagerCopy .Fields = nil
98
106
99
- // For appliers, don't include the APIVersion or Time in the manager identifier,
107
+ // Never include the time in the manager identifier
108
+ encodedManagerCopy .Time = nil
109
+
110
+ // For appliers, don't include the APIVersion in the manager identifier,
100
111
// so it will always have the same manager identifier each time it applied.
101
112
if encodedManager .Operation == metav1 .ManagedFieldsOperationApply {
102
113
encodedManagerCopy .APIVersion = ""
103
- encodedManagerCopy .Time = nil
104
114
}
105
115
106
116
// Use the remaining fields to build the manager identifier
@@ -126,21 +136,17 @@ func decodeVersionedSet(encodedVersionedSet *metav1.ManagedFieldsEntry) (version
126
136
127
137
// encodeManagedFields converts ManagedFields from the format used by
128
138
// sigs.k8s.io/structured-merge-diff to the wire format (api format)
129
- func encodeManagedFields (managedFields fieldpath.ManagedFields ) (encodedManagedFields []metav1.ManagedFieldsEntry , err error ) {
130
- // Sort the keys so a predictable order will be used.
131
- managers := []string {}
132
- for manager := range managedFields {
133
- managers = append (managers , manager )
134
- }
135
- sort .Strings (managers )
136
-
139
+ func encodeManagedFields (managed Managed ) (encodedManagedFields []metav1.ManagedFieldsEntry , err error ) {
137
140
encodedManagedFields = []metav1.ManagedFieldsEntry {}
138
- for _ , manager := range managers {
139
- versionedSet := managedFields [manager ]
141
+ for manager := range managed . Fields {
142
+ versionedSet := managed . Fields [manager ]
140
143
v , err := encodeManagerVersionedSet (manager , versionedSet )
141
144
if err != nil {
142
145
return nil , fmt .Errorf ("error encoding versioned set for %v: %v" , manager , err )
143
146
}
147
+ if t , ok := managed .Times [manager ]; ok {
148
+ v .Time = t
149
+ }
144
150
encodedManagedFields = append (encodedManagedFields , * v )
145
151
}
146
152
return sortEncodedManagedFields (encodedManagedFields )
0 commit comments