Do not add managed fields if a scale entry doesn't own replicas

This happens when a request changes the .status.replicas but not
.spec.replicas
This commit is contained in:
Andrea Nodari 2021-04-04 19:05:45 +02:00
parent 09649e58b5
commit 8e4b5c849b
3 changed files with 14 additions and 19 deletions

View File

@ -135,6 +135,9 @@ func (h *ScaleHandler) ToParent(scaleEntries []metav1.ManagedFieldsEntry) ([]met
} }
for manager, versionedSet := range scaleFields { for manager, versionedSet := range scaleFields {
if !versionedSet.Set().Has(replicasPathInScale) {
continue
}
newVersionedSet := fieldpath.NewVersionedSet( newVersionedSet := fieldpath.NewVersionedSet(
fieldpath.NewSet(h.mappings[h.groupVersion.String()]), fieldpath.NewSet(h.mappings[h.groupVersion.String()]),
fieldpath.APIVersion(h.groupVersion.String()), fieldpath.APIVersion(h.groupVersion.String()),

View File

@ -463,7 +463,7 @@ func TestTransformingManagedFieldsToParent(t *testing.T) {
Operation: metav1.ManagedFieldsOperationApply, Operation: metav1.ManagedFieldsOperationApply,
APIVersion: "apps/v1", APIVersion: "apps/v1",
FieldsType: "FieldsV1", FieldsType: "FieldsV1",
FieldsV1: &metav1.FieldsV1{Raw: []byte(`{"f:spec":{"f:replicas":{},"f:selector":{}}}`)}, FieldsV1: &metav1.FieldsV1{Raw: []byte(`{"f:spec":{"f:selector":{}}}`)},
}, },
}, },
subresource: []metav1.ManagedFieldsEntry{ subresource: []metav1.ManagedFieldsEntry{
@ -472,7 +472,7 @@ func TestTransformingManagedFieldsToParent(t *testing.T) {
Operation: metav1.ManagedFieldsOperationUpdate, Operation: metav1.ManagedFieldsOperationUpdate,
APIVersion: "autoscaling/v1", APIVersion: "autoscaling/v1",
FieldsType: "FieldsV1", FieldsType: "FieldsV1",
FieldsV1: &metav1.FieldsV1{Raw: []byte(`{"f:spec":{"f:another":{}}}`)}, FieldsV1: &metav1.FieldsV1{Raw: []byte(`{"f:status":{"f:replicas":{}}}`)},
Subresource: "scale", Subresource: "scale",
}, },
}, },
@ -484,14 +484,6 @@ func TestTransformingManagedFieldsToParent(t *testing.T) {
FieldsType: "FieldsV1", FieldsType: "FieldsV1",
FieldsV1: &metav1.FieldsV1{Raw: []byte(`{"f:spec":{"f:selector":{}}}`)}, FieldsV1: &metav1.FieldsV1{Raw: []byte(`{"f:spec":{"f:selector":{}}}`)},
}, },
{
Manager: "scale",
Operation: metav1.ManagedFieldsOperationUpdate,
APIVersion: "apps/v1",
FieldsType: "FieldsV1",
FieldsV1: &metav1.FieldsV1{Raw: []byte(`{"f:spec":{"f:replicas":{}}}`)},
Subresource: "scale",
},
}, },
}, },
{ {

View File

@ -97,7 +97,7 @@ func TestScaleAllResources(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Failed to create object using apply: %v", err) t.Fatalf("Failed to create object using apply: %v", err)
} }
obj := retrieveObject(t, client, test) obj := retrieveObject(t, client, test.path, test.resource)
assertReplicasValue(t, obj, 1) assertReplicasValue(t, obj, 1)
assertReplicasOwnership(t, obj, "apply_test") assertReplicasOwnership(t, obj, "apply_test")
@ -115,7 +115,7 @@ func TestScaleAllResources(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Failed to scale object: %v", err) t.Fatalf("Failed to scale object: %v", err)
} }
obj = retrieveObject(t, client, test) obj = retrieveObject(t, client, test.path, test.resource)
assertReplicasValue(t, obj, 5) assertReplicasValue(t, obj, 5)
assertReplicasOwnership(t, obj, "scale_test") assertReplicasOwnership(t, obj, "scale_test")
@ -145,7 +145,7 @@ func TestScaleAllResources(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Error force-updating: %v", err) t.Fatalf("Error force-updating: %v", err)
} }
obj = retrieveObject(t, client, test) obj = retrieveObject(t, client, test.path, test.resource)
assertReplicasValue(t, obj, 1) assertReplicasValue(t, obj, 1)
assertReplicasOwnership(t, obj, "apply_test") assertReplicasOwnership(t, obj, "apply_test")
@ -180,7 +180,7 @@ func TestScaleAllResources(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Error updating object by applying scale and forcing: %v ", err) t.Fatalf("Error updating object by applying scale and forcing: %v ", err)
} }
obj = retrieveObject(t, client, test) obj = retrieveObject(t, client, test.path, test.resource)
assertReplicasValue(t, obj, 17) assertReplicasValue(t, obj, 17)
assertReplicasOwnership(t, obj, "apply_scale") assertReplicasOwnership(t, obj, "apply_scale")
@ -197,7 +197,7 @@ func TestScaleAllResources(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Error replacing object: %v", err) t.Fatalf("Error replacing object: %v", err)
} }
obj = retrieveObject(t, client, test) obj = retrieveObject(t, client, test.path, test.resource)
assertReplicasValue(t, obj, 7) assertReplicasValue(t, obj, 7)
assertReplicasOwnership(t, obj, "replace_test") assertReplicasOwnership(t, obj, "replace_test")
@ -214,7 +214,7 @@ func TestScaleAllResources(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Error updating object: %v", err) t.Fatalf("Error updating object: %v", err)
} }
obj = retrieveObject(t, client, test) obj = retrieveObject(t, client, test.path, test.resource)
assertReplicasValue(t, obj, 7) assertReplicasValue(t, obj, 7)
assertReplicasOwnership(t, obj, "replace_test", "co_owning_test") assertReplicasOwnership(t, obj, "replace_test", "co_owning_test")
@ -231,7 +231,7 @@ func TestScaleAllResources(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Error scaling object: %v", err) t.Fatalf("Error scaling object: %v", err)
} }
obj = retrieveObject(t, client, test) obj = retrieveObject(t, client, test.path, test.resource)
assertReplicasValue(t, obj, 5) assertReplicasValue(t, obj, 5)
assertReplicasOwnership(t, obj, "scale_test") assertReplicasOwnership(t, obj, "scale_test")
}) })
@ -379,10 +379,10 @@ func validV1ReplicationController() string {
}` }`
} }
func retrieveObject(t *testing.T, client clientset.Interface, test scaleTest) *unstructured.Unstructured { func retrieveObject(t *testing.T, client clientset.Interface, prefix, resource string) *unstructured.Unstructured {
t.Helper() t.Helper()
urlPath := path.Join(test.path, "namespaces", "default", test.resource, "test") urlPath := path.Join(prefix, "namespaces", "default", resource, "test")
bytes, err := client.CoreV1().RESTClient().Get().AbsPath(urlPath).DoRaw(context.TODO()) bytes, err := client.CoreV1().RESTClient().Get().AbsPath(urlPath).DoRaw(context.TODO())
if err != nil { if err != nil {
t.Fatalf("Failed to retrieve object: %v", err) t.Fatalf("Failed to retrieve object: %v", err)