From a7fe0f0283765e4970211f7227602e2caa4b3a57 Mon Sep 17 00:00:00 2001 From: Alexander Zielenski <351783+alexzielenski@users.noreply.github.com> Date: Wed, 24 Aug 2022 12:31:57 -0700 Subject: [PATCH] remove last applied configuration information --- .../client-go/util/csaupgrade/upgrade.go | 69 ++++++++++++++----- .../client-go/util/csaupgrade/upgrade_test.go | 39 +++-------- 2 files changed, 63 insertions(+), 45 deletions(-) diff --git a/staging/src/k8s.io/client-go/util/csaupgrade/upgrade.go b/staging/src/k8s.io/client-go/util/csaupgrade/upgrade.go index 372155a38db..d76eb68288c 100644 --- a/staging/src/k8s.io/client-go/util/csaupgrade/upgrade.go +++ b/staging/src/k8s.io/client-go/util/csaupgrade/upgrade.go @@ -7,8 +7,13 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) +const csaAnnotationName = "kubectl.kubernetes.io/last-applied-configuration" + +var csaAnnotationFieldSet = fieldpath.NewSet(fieldpath.MakePathOrDie("metadata", "annotations", csaAnnotationName)) + // Upgrades the Manager information for fields managed with CSA // Prepares fields owned by `csaManager` for 'Update' operations for use now // with the given `ssaManager` for `Apply` operations. @@ -60,37 +65,48 @@ func UpgradeManagedFields( entry.APIVersion == ssaManager.APIVersion }) + ssaFieldSet, err := fieldmanager.FieldsToSet(*ssaManager.FieldsV1) + if err != nil { + return nil, fmt.Errorf("failed to convert fields to set: %w", err) + } + + combinedFieldSet := &ssaFieldSet + + // Union the csa manager with the existing SSA manager if csaManagerExists { csaManager := managedFields[csaManagerIndex] - // Union the csa manager with the existing SSA manager - ssaFieldSet, err := fieldmanager.FieldsToSet(*ssaManager.FieldsV1) - if err != nil { - return nil, fmt.Errorf("failed to convert fields to set: %w", err) - } - csaFieldSet, err := fieldmanager.FieldsToSet(*csaManager.FieldsV1) if err != nil { return nil, fmt.Errorf("failed to convert fields to set: %w", err) } - combinedFieldSet := ssaFieldSet.Union(&csaFieldSet) - combinedFieldSetEncoded, err := fieldmanager.SetToFields(*combinedFieldSet) - if err != nil { - return nil, fmt.Errorf("failed to encode field set: %w", err) - } - - managedFields[ssaManagerIndex].FieldsV1 = &combinedFieldSetEncoded + combinedFieldSet = combinedFieldSet.Union(&csaFieldSet) } + + // Ensure that the resultant fieldset does not include the + // last applied annotation + combinedFieldSet = combinedFieldSet.Difference(csaAnnotationFieldSet) + + combinedFieldSetEncoded, err := fieldmanager.SetToFields(*combinedFieldSet) + if err != nil { + return nil, fmt.Errorf("failed to encode field set: %w", err) + } + + managedFields[ssaManagerIndex].FieldsV1 = &combinedFieldSetEncoded + } else { // SSA manager does not exist. Find the most recent matching CSA manager, // convert it to an SSA manager. // // (find first index, since managed fields are sorted so that most recent is // first in the list) - csaManagerIndex, csaManagerExists := findFirstIndex(managedFields, func(entry metav1.ManagedFieldsEntry) bool { - return entry.Manager == csaManagerName && entry.Operation == metav1.ManagedFieldsOperationUpdate && entry.Subresource == "" - }) + csaManagerIndex, csaManagerExists := findFirstIndex(managedFields, + func(entry metav1.ManagedFieldsEntry) bool { + return entry.Manager == csaManagerName && + entry.Operation == metav1.ManagedFieldsOperationUpdate && + entry.Subresource == "" + }) if !csaManagerExists { // There are no CSA managers that need to be converted. Nothing to do @@ -98,7 +114,22 @@ func UpgradeManagedFields( return obj, nil } + csaManager := managedFields[csaManagerIndex] + csaFieldSet, err := fieldmanager.FieldsToSet(*csaManager.FieldsV1) + if err != nil { + return nil, fmt.Errorf("failed to convert fields to set: %w", err) + } + + // Remove last applied configuration from owned fields, if necessary + csaFieldSet = *csaFieldSet.Difference(csaAnnotationFieldSet) + + csaFieldSetEncoded, err := fieldmanager.SetToFields(csaFieldSet) + if err != nil { + return nil, fmt.Errorf("failed to encode field set: %w", err) + } + // Convert the entry to apply operation + managedFields[csaManagerIndex].FieldsV1 = &csaFieldSetEncoded managedFields[csaManagerIndex].Operation = metav1.ManagedFieldsOperationApply managedFields[csaManagerIndex].Manager = ssaManagerName } @@ -116,6 +147,12 @@ func UpgradeManagedFields( return nil, fmt.Errorf("failed to get meta accessor for copied object: %w", err) } copiedAccessor.SetManagedFields(filteredManagers) + + // Wipe out CSA annotation if it exists + annotations := copiedAccessor.GetAnnotations() + delete(annotations, csaAnnotationName) + copiedAccessor.SetAnnotations(annotations) + return copied, nil } diff --git a/staging/src/k8s.io/client-go/util/csaupgrade/upgrade_test.go b/staging/src/k8s.io/client-go/util/csaupgrade/upgrade_test.go index 26bd0318e01..5af49e7442f 100644 --- a/staging/src/k8s.io/client-go/util/csaupgrade/upgrade_test.go +++ b/staging/src/k8s.io/client-go/util/csaupgrade/upgrade_test.go @@ -58,9 +58,7 @@ apiVersion: v1 data: {} kind: ConfigMap metadata: - annotations: - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"v1","data":{"key":"value","legacy":"unused"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"test","namespace":"default"}} + annotations: {} creationTimestamp: "2022-08-22T23:08:23Z" managedFields: - apiVersion: v1 @@ -71,9 +69,7 @@ metadata: f:key: {} f:legacy: {} f:metadata: - f:annotations: - .: {} - f:kubectl.kubernetes.io/last-applied-configuration: {} + f:annotations: {} manager: kubectl operation: Apply time: "2022-08-22T23:08:23Z" @@ -135,9 +131,7 @@ apiVersion: v1 data: {} kind: ConfigMap metadata: - annotations: - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"v1","data":{"key":"value","legacy":"unused"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"test","namespace":"default"}} + annotations: {} creationTimestamp: "2022-08-22T23:08:23Z" managedFields: - apiVersion: v1 @@ -148,9 +142,7 @@ metadata: f:key: {} f:legacy: {} f:metadata: - f:annotations: - .: {} - f:kubectl.kubernetes.io/last-applied-configuration: {} + f:annotations: {} manager: kubectl operation: Apply time: "2022-08-23T23:08:23Z" @@ -164,7 +156,7 @@ metadata: // CSA entry but no longer present in SSA entry, so it would not be pruned. // This shows that upgrading such an object results in correct behavior next // time SSA applier - // Expect final object to have all keys from both entries + // Expect final object to have unioned keys from both entries Name: "csa-combine-with-ssa-additional-keys", CSAManager: "kubectl-client-side-apply", SSAManager: "kubectl", @@ -213,9 +205,7 @@ apiVersion: v1 data: {} kind: ConfigMap metadata: - annotations: - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"v1","data":{"key":"value","legacy":"unused"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"test","namespace":"default"}} + annotations: {} creationTimestamp: "2022-08-22T23:08:23Z" managedFields: - apiVersion: v1 @@ -226,9 +216,7 @@ metadata: f:key: {} f:legacy: {} f:metadata: - f:annotations: - .: {} - f:kubectl.kubernetes.io/last-applied-configuration: {} + f:annotations: {} manager: kubectl operation: Apply time: "2022-08-23T23:08:23Z" @@ -319,9 +307,7 @@ apiVersion: v1 data: {} kind: ConfigMap metadata: - annotations: - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"v1","data":{"key":"value","legacy":"unused"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"test","namespace":"default"}} + annotations: {} creationTimestamp: "2022-08-22T23:08:23Z" managedFields: - apiVersion: v5 @@ -332,9 +318,7 @@ metadata: f:key: {} f:legacy: {} f:metadata: - f:annotations: - .: {} - f:kubectl.kubernetes.io/last-applied-configuration: {} + f:annotations: {} manager: kubectl operation: Apply time: "2022-08-23T23:08:23Z" @@ -425,9 +409,7 @@ apiVersion: v1 data: {} kind: ConfigMap metadata: - annotations: - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"v1","data":{"key":"value","legacy":"unused"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"test","namespace":"default"}} + annotations: {} creationTimestamp: "2022-08-22T23:08:23Z" managedFields: - apiVersion: v5 @@ -442,7 +424,6 @@ metadata: f:annotations: .: {} f:hello2: {} - f:kubectl.kubernetes.io/last-applied-configuration: {} manager: kubectl operation: Apply time: "2022-08-23T23:08:23Z"