From b9ccd9c3cbbe39dfd1b74b753f2bbc0c21a0219f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20Wiesm=C3=BCller?= Date: Fri, 4 Jan 2019 17:52:17 +0100 Subject: [PATCH] add api error for apply conflicts and check in field manager --- .../apimachinery/pkg/api/errors/errors.go | 25 +++++++++++++++++++ .../handlers/fieldmanager/fieldmanager.go | 4 +++ 2 files changed, 29 insertions(+) diff --git a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go index e736a986140..73a80d7b4a5 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" + "sigs.k8s.io/structured-merge-diff/merge" ) const ( @@ -184,6 +185,30 @@ func NewConflict(qualifiedResource schema.GroupResource, name string, err error) }} } +// NewApplyConflict returns an error including details on the requests apply conflicts +func NewApplyConflict(conflicts merge.Conflicts, err error) *StatusError { + causes := make([]metav1.StatusCause, 0, len(conflicts)) + for i := range conflicts { + err := conflicts[i] + causes = append(causes, metav1.StatusCause{ + Type: metav1.CauseType("conflict"), + Message: err.Error(), + Field: err.Path.String(), + }) + } + + return &StatusError{ErrStatus: metav1.Status{ + Status: metav1.StatusFailure, + Code: http.StatusConflict, + Reason: metav1.StatusReasonConflict, + Details: &metav1.StatusDetails{ + // TODO: Get obj details here? + Causes: causes, + }, + Message: fmt.Sprintf("Apply failed with %d conflicts: %v", len(conflicts), err), + }} +} + // NewGone returns an error indicating the item no longer available at the server and no forwarding address is known. func NewGone(message string) *StatusError { return &StatusError{metav1.Status{ diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go index 4b093e70db0..e5846ced5db 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/fieldmanager.go @@ -19,6 +19,7 @@ package fieldmanager import ( "fmt" + "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal" @@ -136,6 +137,9 @@ func (f *FieldManager) Apply(liveObj runtime.Object, patch []byte, force bool) ( apiVersion := fieldpath.APIVersion(f.groupVersion.String()) newObjTyped, managed, err := f.updater.Apply(liveObjTyped, patchObjTyped, apiVersion, managed, applyManager, force) if err != nil { + if conflicts, ok := err.(merge.Conflicts); ok { + return nil, errors.NewApplyConflict(conflicts, err) + } return nil, err }