fix ssa ownership

Signed-off-by: Austin Abro <austinabro321@gmail.com>
pull/31511/head
Austin Abro 11 months ago
parent 51a9bc5157
commit fc15c11a08
No known key found for this signature in database
GPG Key ID: 533C18822161094C

@ -1101,6 +1101,13 @@ func patchResourceServerSide(target *resource.Info, dryRun bool, forceConflicts
WithFieldManager(getManagedFieldsManager()). WithFieldManager(getManagedFieldsManager()).
WithFieldValidation(string(fieldValidationDirective)) WithFieldValidation(string(fieldValidationDirective))
// Kubernetes looks at the server side state when evaluating conflicts in field manager rather than the field manager field in the request
// therefore when using the Apply operation you cannot define managedFields in the body of the request that you submit
// This is according to https://kubernetes.io/docs/reference/using-api/server-side-apply/#apply-and-update
if u, ok := target.Object.(*unstructured.Unstructured); ok {
u.SetManagedFields(nil)
}
// Send the full object to be applied on the server side. // Send the full object to be applied on the server side.
data, err := runtime.Encode(unstructured.UnstructuredJSONScheme, target.Object) data, err := runtime.Encode(unstructured.UnstructuredJSONScheme, target.Object)
if err != nil { if err != nil {

@ -2183,3 +2183,71 @@ status:
require.Error(t, err) require.Error(t, err)
assert.Contains(t, err.Error(), "context canceled", "expected context canceled error, got: %v", err) assert.Contains(t, err.Error(), "context canceled", "expected context canceled error, got: %v", err)
} }
func TestPatchResourceServerSide_ClearsManagedFields(t *testing.T) {
// Test that managedFields are cleared before sending SSA request
podWithManagedFields := &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
"kind": "Pod",
"metadata": map[string]interface{}{
"name": "test-pod",
"namespace": "default",
"managedFields": []interface{}{
map[string]interface{}{
"manager": "kubectl",
"operation": "Apply",
"apiVersion": "v1",
},
},
},
"spec": map[string]interface{}{
"containers": []interface{}{
map[string]interface{}{
"name": "test",
"image": "nginx",
},
},
},
},
}
// Create a fake REST client that will receive the patch request
var patchedData []byte
fakeClient := &fake.RESTClient{
GroupVersion: schema.GroupVersion{Version: "v1"},
NegotiatedSerializer: scheme.Codecs.WithoutConversion(),
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
body, err := io.ReadAll(req.Body)
require.NoError(t, err)
patchedData = body
header := http.Header{}
header.Set("Content-Type", runtime.ContentTypeJSON)
return &http.Response{
StatusCode: http.StatusOK,
Header: header,
Body: io.NopCloser(bytes.NewReader(body)),
}, nil
}),
}
target := &resource.Info{
Name: "test-pod",
Namespace: "default",
Object: podWithManagedFields,
Mapping: &meta.RESTMapping{
Resource: schema.GroupVersionResource{Version: "v1", Resource: "pods"},
GroupVersionKind: schema.GroupVersionKind{Version: "v1", Kind: "Pod"},
Scope: meta.RESTScopeNamespace,
},
Client: fakeClient,
}
// Call patchResourceServerSide
err := patchResourceServerSide(target, false, false, FieldValidationDirectiveStrict)
require.NoError(t, err)
// Verify the patched data doesn't contain managedFields
assert.NotContains(t, string(patchedData), "managedFields", "patched data should not contain managedFields")
}

Loading…
Cancel
Save