Skip to content

Commit ca99961

Browse files
authored
Merge pull request #1037 from fluxcd/ssa-migrate-managed-fields
ssa: Add helper function to migrate the apiVersion on managed fields
2 parents edd6c51 + 18da908 commit ca99961

2 files changed

Lines changed: 54 additions & 25 deletions

File tree

ssa/manager_apply.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ func (m *ResourceManager) cleanupMetadata(ctx context.Context,
340340
return false, nil
341341
}
342342
existingObject := object.DeepCopy()
343-
var patches []jsonPatch
343+
var patches []JSONPatch
344344

345345
if len(opts.Annotations) > 0 {
346346
patches = append(patches, PatchRemoveAnnotations(existingObject, opts.Annotations)...)

ssa/patch.go

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,25 @@ import (
2929

3030
const managedFieldsPath = "/metadata/managedFields"
3131

32-
// jsonPatch defines a patch as specified by RFC 6902
32+
// JSONPatch defines a patch as specified by RFC 6902
3333
// https://www.rfc-editor.org/rfc/rfc6902
34-
type jsonPatch struct {
34+
type JSONPatch struct {
3535
Operation string `json:"op"`
3636
Path string `json:"path"`
3737
Value []metav1.ManagedFieldsEntry `json:"value,omitempty"`
3838
}
3939

40-
// newPatchRemove returns a jsonPatch for removing the specified path.
41-
func newPatchRemove(path string) jsonPatch {
42-
return jsonPatch{
40+
// NewPatchRemove returns a JSONPatch for removing the specified path.
41+
func NewPatchRemove(path string) JSONPatch {
42+
return JSONPatch{
4343
Operation: "remove",
4444
Path: path,
4545
}
4646
}
4747

48-
// newPatchRemove returns a jsonPatch for removing the specified path.
49-
func newPatchReplace(path string, value []metav1.ManagedFieldsEntry) jsonPatch {
50-
return jsonPatch{
48+
// NewPatchReplace returns a JSONPatch for replacing the specified path with the given value.
49+
func NewPatchReplace(path string, value []metav1.ManagedFieldsEntry) JSONPatch {
50+
return JSONPatch{
5151
Operation: "replace",
5252
Path: path,
5353
Value: value,
@@ -79,11 +79,11 @@ func matchFieldManager(entry metav1.ManagedFieldsEntry, manager FieldManager) bo
7979
return strings.HasPrefix(entry.Manager, manager.Name)
8080
}
8181

82-
// PatchRemoveFieldsManagers returns a jsonPatch array for removing managers with matching name or prefix.
83-
func PatchRemoveFieldsManagers(object *unstructured.Unstructured, managers []FieldManager) []jsonPatch {
82+
// PatchRemoveFieldsManagers returns a JSONPatch array for removing managers with matching name or prefix.
83+
func PatchRemoveFieldsManagers(object *unstructured.Unstructured, managers []FieldManager) []JSONPatch {
8484
objEntries := object.GetManagedFields()
8585

86-
var patches []jsonPatch
86+
var patches []JSONPatch
8787
entries := make([]metav1.ManagedFieldsEntry, 0, len(objEntries))
8888
for _, entry := range objEntries {
8989
exclude := false
@@ -106,12 +106,12 @@ func PatchRemoveFieldsManagers(object *unstructured.Unstructured, managers []Fie
106106
entries = append(entries, metav1.ManagedFieldsEntry{})
107107
}
108108

109-
return append(patches, newPatchReplace(managedFieldsPath, entries))
109+
return append(patches, NewPatchReplace(managedFieldsPath, entries))
110110
}
111111

112-
// PatchReplaceFieldsManagers returns a jsonPatch array for replacing the managers with matching
112+
// PatchReplaceFieldsManagers returns a JSONPatch array for replacing the managers with matching
113113
// name and operation type with the specified manager name and an apply operation.
114-
func PatchReplaceFieldsManagers(object *unstructured.Unstructured, managers []FieldManager, name string) ([]jsonPatch, error) {
114+
func PatchReplaceFieldsManagers(object *unstructured.Unstructured, managers []FieldManager, name string) ([]JSONPatch, error) {
115115
objEntries := object.GetManagedFields()
116116

117117
var prevManagedFields metav1.ManagedFieldsEntry
@@ -124,7 +124,7 @@ func PatchReplaceFieldsManagers(object *unstructured.Unstructured, managers []Fi
124124
}
125125
}
126126

127-
var patches []jsonPatch
127+
var patches []JSONPatch
128128
entries := make([]metav1.ManagedFieldsEntry, 0, len(objEntries))
129129
edited := false
130130

@@ -167,7 +167,36 @@ each_entry:
167167
}
168168

169169
entries = append(entries, prevManagedFields)
170-
return append(patches, newPatchReplace(managedFieldsPath, entries)), nil
170+
return append(patches, NewPatchReplace(managedFieldsPath, entries)), nil
171+
}
172+
173+
// PatchMigrateToVersion returns a JSONPatch array for replacing the existing apiVersion in the
174+
// managed fields with the specified apiVersion.
175+
func PatchMigrateToVersion(object *unstructured.Unstructured, apiVersion string) ([]JSONPatch, error) {
176+
objEntries := object.GetManagedFields()
177+
178+
// Early return if no managed fields
179+
if len(objEntries) == 0 {
180+
return nil, nil
181+
}
182+
183+
entries := make([]metav1.ManagedFieldsEntry, 0, len(objEntries))
184+
changed := false
185+
186+
for _, entry := range objEntries {
187+
if entry.APIVersion != apiVersion {
188+
entry.APIVersion = apiVersion
189+
changed = true
190+
}
191+
entries = append(entries, entry)
192+
}
193+
194+
// No changes needed
195+
if !changed {
196+
return nil, nil
197+
}
198+
199+
return []JSONPatch{NewPatchReplace(managedFieldsPath, entries)}, nil
171200
}
172201

173202
func mergeManagedFieldsV1(prevField *metav1.FieldsV1, newField *metav1.FieldsV1) (*metav1.FieldsV1, error) {
@@ -202,27 +231,27 @@ func mergeManagedFieldsV1(prevField *metav1.FieldsV1, newField *metav1.FieldsV1)
202231
return &mergedField, nil
203232
}
204233

205-
// PatchRemoveAnnotations returns a jsonPatch array for removing annotations with matching keys.
206-
func PatchRemoveAnnotations(object *unstructured.Unstructured, keys []string) []jsonPatch {
207-
var patches []jsonPatch
234+
// PatchRemoveAnnotations returns a JSONPatch array for removing annotations with matching keys.
235+
func PatchRemoveAnnotations(object *unstructured.Unstructured, keys []string) []JSONPatch {
236+
var patches []JSONPatch
208237
annotations := object.GetAnnotations()
209238
for _, key := range keys {
210239
if _, ok := annotations[key]; ok {
211240
path := fmt.Sprintf("/metadata/annotations/%s", strings.ReplaceAll(key, "/", "~1"))
212-
patches = append(patches, newPatchRemove(path))
241+
patches = append(patches, NewPatchRemove(path))
213242
}
214243
}
215244
return patches
216245
}
217246

218-
// PatchRemoveLabels returns a jsonPatch array for removing labels with matching keys.
219-
func PatchRemoveLabels(object *unstructured.Unstructured, keys []string) []jsonPatch {
220-
var patches []jsonPatch
247+
// PatchRemoveLabels returns a JSONPatch array for removing labels with matching keys.
248+
func PatchRemoveLabels(object *unstructured.Unstructured, keys []string) []JSONPatch {
249+
var patches []JSONPatch
221250
labels := object.GetLabels()
222251
for _, key := range keys {
223252
if _, ok := labels[key]; ok {
224253
path := fmt.Sprintf("/metadata/labels/%s", strings.ReplaceAll(key, "/", "~1"))
225-
patches = append(patches, newPatchRemove(path))
254+
patches = append(patches, NewPatchRemove(path))
226255
}
227256
}
228257
return patches

0 commit comments

Comments
 (0)