Skip to content

Commit 1902414

Browse files
author
Eric Abramov
committed
⚠️ admission responses with raw Status
If a custom webhook validator returns a metav1.Status object as the error, the validation handler will build an admission response with this Status object as is, instead of building a new Status object based on err.Error() This might be considered as a breaking change since the behaviour of the validation handler is going to be slightly different from what the users might expect based on the previous version of the code
1 parent d12bb87 commit 1902414

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

pkg/webhook/admission/response.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,17 @@ func ValidationResponse(allowed bool, reason string) Response {
8080
return resp
8181
}
8282

83+
// ValidationResponseFromStatus returns a response for admitting a request with provided Status object.
84+
func ValidationResponseFromStatus(allowed bool, status *metav1.Status) Response {
85+
resp := Response{
86+
AdmissionResponse: admissionv1beta1.AdmissionResponse{
87+
Allowed: allowed,
88+
Result: status,
89+
},
90+
}
91+
return resp
92+
}
93+
8394
// PatchResponseFromRaw takes 2 byte arrays and returns a new response with json patch.
8495
// The original object should be passed in as raw bytes to avoid the roundtripping problem
8596
// described in https://github.com/kubernetes-sigs/kubebuilder/issues/510.

pkg/webhook/admission/validator.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import (
2121
"net/http"
2222

2323
"k8s.io/api/admission/v1beta1"
24+
"k8s.io/apimachinery/pkg/api/errors"
25+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2426
"k8s.io/apimachinery/pkg/runtime"
2527
)
2628

@@ -67,7 +69,13 @@ func (h *validatingHandler) Handle(ctx context.Context, req Request) Response {
6769
}
6870

6971
err = obj.ValidateCreate()
72+
7073
if err != nil {
74+
75+
isStatusError, status := isStatusError(&err)
76+
if isStatusError {
77+
return ValidationResponseFromStatus(false, status)
78+
}
7179
return Denied(err.Error())
7280
}
7381
}
@@ -85,7 +93,12 @@ func (h *validatingHandler) Handle(ctx context.Context, req Request) Response {
8593
}
8694

8795
err = obj.ValidateUpdate(oldObj)
96+
8897
if err != nil {
98+
isStatusError, status := isStatusError(&err)
99+
if isStatusError {
100+
return ValidationResponseFromStatus(false, status)
101+
}
89102
return Denied(err.Error())
90103
}
91104
}
@@ -100,9 +113,22 @@ func (h *validatingHandler) Handle(ctx context.Context, req Request) Response {
100113

101114
err = obj.ValidateDelete()
102115
if err != nil {
116+
isStatusError, status := isStatusError(&err)
117+
if isStatusError {
118+
return ValidationResponseFromStatus(false, status)
119+
}
103120
return Denied(err.Error())
104121
}
105122
}
106123

107124
return Allowed("")
108125
}
126+
127+
func isStatusError(err *error) (bool, *metav1.Status) {
128+
statusError, isStatusError := (*err).(*errors.StatusError)
129+
if isStatusError {
130+
return true, &statusError.ErrStatus
131+
}
132+
133+
return false, nil
134+
}

0 commit comments

Comments
 (0)