-
Notifications
You must be signed in to change notification settings - Fork 256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make LossLessDefaulter selective to only prevent dropping fields outside of schema. #3186
Conversation
✅ Deploy Preview for kubernetes-sigs-kueue canceled.
|
229669d
to
cc5bd04
Compare
/cc @alculquicondor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this extension is quite complex and we need much better test coverage, optimally 100%, including cases like removing from a slice (for example to drop a condition).
It is essential piece of code for correctness of webhooks so as a bailout mechanism, in case of an issue, I would like to consider a construction parameter to control this selective behavior. Such as "AllowRemovingSchemaFields".
cc5bd04
to
965e0a8
Compare
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: mbobrovskyi The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Maybe I'm missing something but an alternative (slightly hacky) can be to overwrite the Raw object before the actual defaulter is called. Something like: import (
"context"
+ "encoding/json"
+ "net/http"
- jsonpatch "gomodules.xyz/jsonpatch/v2"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)
@@ -29,11 +30,15 @@ import (
func WithLosslessDefaulter(scheme *runtime.Scheme, obj runtime.Object, defaulter admission.CustomDefaulter) admission.Handler {
return &losslessDefaulter{
Handler: admission.WithCustomDefaulter(scheme, obj, defaulter).Handler,
+ obj: obj.DeepCopyObject(),
+ decoder: admission.NewDecoder(scheme),
}
}
type losslessDefaulter struct {
admission.Handler
+ obj runtime.Object
+ decoder admission.Decoder
}
// Handle handles admission requests, **dropping** remove operations from patches produced by controller-runtime.
@@ -43,18 +48,14 @@ type losslessDefaulter struct {
// released CRDs.
// Dropping the "remove" operations is safe because Kueue's job mutators never remove fields.
func (h *losslessDefaulter) Handle(ctx context.Context, req admission.Request) admission.Response {
- response := h.Handler.Handle(ctx, req)
- if response.Allowed {
- var patches []jsonpatch.Operation
- for _, p := range response.Patches {
- if p.Operation != "remove" {
- patches = append(patches, p)
- }
- }
- if len(patches) == 0 {
- response.PatchType = nil
- }
- response.Patches = patches
+ o := h.obj.DeepCopyObject()
+ if err := h.decoder.Decode(req, o); err != nil {
+ return admission.Errored(http.StatusBadRequest, err)
}
- return response
+ marshalled, err := json.Marshal(o)
+ if err != nil {
+ return admission.Errored(http.StatusInternalServerError, err)
+ }
+ req.Object.Raw = marshalled
+ return h.Handler.Handle(ctx, req)
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe fieldExistsByJSONPath(object interface{}, path string)
and friends can be moved in pkg/util/api
.
if len(pathParts) < 2 { | ||
return false | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: maybe add a comment explaining why < 2
return true | ||
} | ||
|
||
switch fv.Kind() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should also check for maps
I'm not sure about that, maybe @alculquicondor can you think of some pros & cons of the alternative? |
I did find some discussions about that an the probability to generate invalid patches. |
We already discussed it here #3186 (comment) and take a decision to keep it on the same package. |
/close Due to found better solution #3194. |
@mbobrovskyi: Closed this PR. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
/reopen Due to #3194 (comment). |
@mbobrovskyi: Reopened this PR. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
bc26d4e
to
ac7821f
Compare
/close Due to very hard to handle inline object and Unmarshal methods. |
@mbobrovskyi: Closed this PR. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
What type of PR is this?
/kind feature
What this PR does / why we need it:
Make
LossLessDefaulter
selective to only prevent dropping fields outside of schema.Which issue(s) this PR fixes:
Fixes #3174
Special notes for your reviewer:
For more information see:
Does this PR introduce a user-facing change?