remove last applied configuration information

Kubernetes-commit: a7fe0f0283765e4970211f7227602e2caa4b3a57
This commit is contained in:
Alexander Zielenski 2022-08-24 12:31:57 -07:00 committed by Kubernetes Publisher
parent efe378914a
commit 089614c43e
2 changed files with 63 additions and 45 deletions

View File

@ -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
}

View File

@ -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"