1
16
17 package internal
18
19 import (
20 "fmt"
21 "reflect"
22 "time"
23
24 "k8s.io/apimachinery/pkg/api/meta"
25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26 "k8s.io/apimachinery/pkg/runtime"
27 "k8s.io/apimachinery/pkg/runtime/schema"
28 "k8s.io/klog/v2"
29 "sigs.k8s.io/structured-merge-diff/v4/merge"
30 )
31
32
33
34
35 const DefaultMaxUpdateManagers int = 10
36
37
38
39 const DefaultTrackOnCreateProbability float32 = 1
40
41 var atMostEverySecond = NewAtMostEvery(time.Second)
42
43
44
45 type FieldManager struct {
46 fieldManager Manager
47 subresource string
48 }
49
50
51
52 func NewFieldManager(f Manager, subresource string) *FieldManager {
53 return &FieldManager{fieldManager: f, subresource: subresource}
54 }
55
56
57 func NewDefaultFieldManager(f Manager, typeConverter TypeConverter, objectConverter runtime.ObjectConvertor, objectCreater runtime.ObjectCreater, kind schema.GroupVersionKind, subresource string) *FieldManager {
58 return NewFieldManager(
59 NewVersionCheckManager(
60 NewLastAppliedUpdater(
61 NewLastAppliedManager(
62 NewProbabilisticSkipNonAppliedManager(
63 NewCapManagersManager(
64 NewBuildManagerInfoManager(
65 NewManagedFieldsUpdater(
66 NewStripMetaManager(f),
67 ), kind.GroupVersion(), subresource,
68 ), DefaultMaxUpdateManagers,
69 ), objectCreater, DefaultTrackOnCreateProbability,
70 ), typeConverter, objectConverter, kind.GroupVersion(),
71 ),
72 ), kind,
73 ), subresource,
74 )
75 }
76
77 func decodeLiveOrNew(liveObj, newObj runtime.Object, ignoreManagedFieldsFromRequestObject bool) (Managed, error) {
78 liveAccessor, err := meta.Accessor(liveObj)
79 if err != nil {
80 return nil, err
81 }
82
83
84
85 if ignoreManagedFieldsFromRequestObject {
86 return emptyManagedFieldsOnErr(DecodeManagedFields(liveAccessor.GetManagedFields()))
87 }
88
89
90
91 newAccessor, err := meta.Accessor(newObj)
92 if err != nil {
93 return nil, err
94 }
95
96 if isResetManagedFields(newAccessor.GetManagedFields()) {
97 return NewEmptyManaged(), nil
98 }
99
100
101
102
103 managed, err := DecodeManagedFields(newAccessor.GetManagedFields())
104 if err != nil || len(managed.Fields()) == 0 {
105 return emptyManagedFieldsOnErr(DecodeManagedFields(liveAccessor.GetManagedFields()))
106 }
107 return managed, nil
108 }
109
110 func emptyManagedFieldsOnErr(managed Managed, err error) (Managed, error) {
111 if err != nil {
112 return NewEmptyManaged(), nil
113 }
114 return managed, nil
115 }
116
117
118
119
120 func (f *FieldManager) Update(liveObj, newObj runtime.Object, manager string) (object runtime.Object, err error) {
121
122
123 isSubresource := f.subresource != ""
124 managed, err := decodeLiveOrNew(liveObj, newObj, isSubresource)
125 if err != nil {
126 return newObj, nil
127 }
128
129 RemoveObjectManagedFields(newObj)
130
131 if object, managed, err = f.fieldManager.Update(liveObj, newObj, managed, manager); err != nil {
132 return nil, err
133 }
134
135 if err = EncodeObjectManagedFields(object, managed); err != nil {
136 return nil, fmt.Errorf("failed to encode managed fields: %v", err)
137 }
138
139 return object, nil
140 }
141
142
143
144
145 func (f *FieldManager) UpdateNoErrors(liveObj, newObj runtime.Object, manager string) runtime.Object {
146 obj, err := f.Update(liveObj, newObj, manager)
147 if err != nil {
148 atMostEverySecond.Do(func() {
149 ns, name := "unknown", "unknown"
150 if accessor, err := meta.Accessor(newObj); err == nil {
151 ns = accessor.GetNamespace()
152 name = accessor.GetName()
153 }
154
155 klog.ErrorS(err, "[SHOULD NOT HAPPEN] failed to update managedFields", "versionKind",
156 newObj.GetObjectKind().GroupVersionKind(), "namespace", ns, "name", name)
157 })
158
159
160 RemoveObjectManagedFields(newObj)
161 return newObj
162 }
163 return obj
164 }
165
166
167
168
169 func isResetManagedFields(managedFields []metav1.ManagedFieldsEntry) bool {
170 if len(managedFields) == 0 {
171 return managedFields != nil
172 }
173
174 if len(managedFields) == 1 {
175 return reflect.DeepEqual(managedFields[0], metav1.ManagedFieldsEntry{})
176 }
177
178 return false
179 }
180
181
182
183 func (f *FieldManager) Apply(liveObj, appliedObj runtime.Object, manager string, force bool) (object runtime.Object, err error) {
184
185 accessor, err := meta.Accessor(liveObj)
186 if err != nil {
187 return nil, fmt.Errorf("couldn't get accessor: %v", err)
188 }
189
190
191 managed, err := DecodeManagedFields(accessor.GetManagedFields())
192 if err != nil {
193 return nil, fmt.Errorf("failed to decode managed fields: %v", err)
194 }
195
196 object, managed, err = f.fieldManager.Apply(liveObj, appliedObj, managed, manager, force)
197 if err != nil {
198 if conflicts, ok := err.(merge.Conflicts); ok {
199 return nil, NewConflictError(conflicts)
200 }
201 return nil, err
202 }
203
204 if err = EncodeObjectManagedFields(object, managed); err != nil {
205 return nil, fmt.Errorf("failed to encode managed fields: %v", err)
206 }
207
208 return object, nil
209 }
210
View as plain text