-
Notifications
You must be signed in to change notification settings - Fork 39.4k
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
Don't call service Validate / Prepare hooks twice #95666
Conversation
/triage accepted |
b02d3d7
to
d1d41b9
Compare
6b46cb7
to
c738b46
Compare
@@ -810,3 +825,61 @@ func collectServiceNodePorts(service *api.Service) []int { | |||
} | |||
return servicePorts | |||
} | |||
|
|||
// nearlyNullStrategy does almost nothing, but makes the REST logic happy. |
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'm in deepwaters here, is mostly for learning purposes, so
in Create we call
if err := rest.BeforeCreate(rs.strategy, ctx, obj); err != nil {
with this nearlyNullStrategy
, and here it can call strategy.GenerateName()
kubernetes/staging/src/k8s.io/apiserver/pkg/registry/rest/create.go
Lines 91 to 93 in 2af52db
if len(objectMeta.GetGenerateName()) > 0 && len(objectMeta.GetName()) == 0 { | |
objectMeta.SetName(strategy.GenerateName(objectMeta.GetGenerateName())) | |
} |
but I don`t see that we implement it , is not needed?
or should we mock it too?
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.
GenerateName is implemented by names.SimpleNameGenerator which we embed in nearlyNullStrategy in NewREST() (pkg/registry/core/service/storage/rest.go). This was copied from the "real" strategy.
IIUIC with this change all allocators operations will be triggered without any validation, |
@aojea it's a good question. I don't THINK so (not any more than before anyway) |
I added more details on the flow to the PR description |
/retest |
I think that the tests that are failing are becuse this breaks current dual-stack, but that will be fixed later by Khal's PR ... EDIT duh, I saw that you've already talked #91824 (review) |
/retest |
pkg/registry/core/service/storage/rest_test.go is all wonky in light of this. @khenidak and I agreed to get his PR merged and then untangle this. /hold |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: thockin The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
As expected, when I rebase this on top of Kal's dual-stack, it breaks. Working some ideas |
// we have previously validated for ip correctness and if family exist it will match ip family | ||
// so the following is safe to do | ||
isIPv6 := netutil.IsIPv6String(ip) | ||
parsedIP := net.ParseIP(ip) |
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.
from the top of my head, I' m afraid that a wrong service with one valid IP and an invalid one, allocates the valid and fails later.
ClusterIPs: ["192.168.0.2","INVALID"]
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.
ic , we normalize and then parse, if something wrong parsing, return and validation catchs it later
👍
Thanks to @aojea for helping debug and adding a test. |
beee1d1
to
d880774
Compare
the testing around this is weak, I will look at boosting it as I figure what failed. |
To quote a master: "oof.. can't unsee" |
func (nearlyNullStrategy) PrepareForUpdate(_ context.Context, _, _ runtime.Object) { | ||
} | ||
|
||
func (nearlyNullStrategy) Validate(_ context.Context, _ runtime.Object) field.ErrorList { |
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.
@thockin the unit tests fail now because we no longer validate here
kubernetes/pkg/registry/core/service/strategy.go
Lines 125 to 130 in d01cc01
func (strategy svcStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList { | |
service := obj.(*api.Service) | |
allErrs := validation.ValidateServiceCreate(service) | |
allErrs = append(allErrs, validation.ValidateConditionalService(service, nil, strategy.ipFamilies)...) | |
return allErrs | |
} |
should we modify the test or the strategy?
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.
The testing here is ALL OVER THE PLACE. Before this change it tested with strategy, but strategy has its own tests. Some of the test in here only test validation, which also has its own tests. There are some general-looking (i.e. follows patterns) tests for the inner REST but the failing test are the outer rest.
So the question at hand is - should the UNIT TEST for the "outer" REST test all the way down into the inner REST? It never has. I can add strategy back in here, but it feels sketchy to be testing across packages that way. Or I can remove the validation-centric tests and just make this pass without strategy, then come back as we clean up the REST logic overall, which is where I am leaning.
When we used to validate before allocation. Now that we don't, we have to handle some extra cases in the allocation path. This also removes some REST tests that were just testing validation transitively and adjusts some other tests to be properly dual-stack. Testing on pkg/registry/core/service/storage needs an overhaul.
I expect it to pass tests now, even if I am unsatisfied with the testing overall... |
d880774
to
544e763
Compare
/retest |
/retest |
@thockin: The following tests failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. 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/test-infra repository. I understand the commands that are listed here. |
@thockin they pass now, I think that as next step we should identify the gaps or areas we find weak and open issues to track and start adding more coverage |
@thockin: PR needs rebase. 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/test-infra repository. |
Issues go stale after 90d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
Stale issues rot after 30d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-contributor-experience at kubernetes/community. |
Rotten issues close after 30d of inactivity. Send feedback to sig-contributor-experience at kubernetes/community. |
@fejta-bot: 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/test-infra repository. |
Service has an "outer" and "inner" REST handler. They use the same
strategy, but the outer calls into the inner, which caused Prepare and
Validate hooks to be called twice.
This change makes the "outer" strategy do nothing in those cases. One
net result of this is that the validation code can get a bit stricter,
since it will NEVER see a service before allocation. This is left for
later.
This whole mess can be simplified and flattened to a single REST layer,
which we can explore AFTER dual-stack merges
For posterity:
The "normal" flow seems to be:
Service (before this PR) does:
After this PR the flow is the same but the "outer" strategy is no-op:
/kind bug
/kind cleanup