-
Notifications
You must be signed in to change notification settings - Fork 38.7k
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
Enable strict serializer in kube-proxy #82927
Enable strict serializer in kube-proxy #82927
Conversation
/assign @thockin |
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.
Nice job on this!
Here's my feedback:
cmd/kube-proxy/app/server_test.go
Outdated
@@ -279,35 +281,130 @@ nodePortAddresses: | |||
|
|||
// TestLoadConfigFailures tests failure modes for loadConfig() | |||
func TestLoadConfigFailures(t *testing.T) { | |||
duplicateKeyYAMLTemplate := `bindAddress: 0.0.0.0 | |||
bindAddress: 1.2.3.4 |
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 we could just represent the minimal config for these:
duplicateKeyYAMLTemplate := `bindAddress: 0.0.0.0
bindAddress: 1.2.3.4
clusterCIDR: "1.2.3.0/24"
configSyncPeriod: 15s
configSyncPeriod: 30s
kind: KubeProxyConfiguration`
Looking at the test runner, the apiVersion is appended to every test to reduce maintenance burden.
Being less specific about the fields make these strings easier to maintain.
There's already a happy path test for TestLoadConfig
It's possible to prepend some unrelated fields if a more robust test is desired, but this isn't a rigorous suite for the YAML parser.
WDYT?
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.
Yeah that's much cleaner. I provided a basicYAMLTemplate
which gets appended to in each tests accordingly.
cmd/kube-proxy/app/server_test.go
Outdated
{ | ||
name: "Duplicate fields", | ||
config: duplicateKeyYAMLTemplate, | ||
errFn: func(err error) bool { |
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.
This can change to:
errFn: kuberuntime.IsStrictDecodingError
That function contains a nil check, and it should already have been asserted an error exists before running it because of the nature of this range test.
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.
Fixed
cmd/kube-proxy/app/server_test.go
Outdated
}, | ||
{ | ||
name: "Bad config type test", | ||
config: "kind: KubeSchedulerConfiguration", | ||
expErr: "no kind", | ||
errFn: func(err error) bool { return err != nil }, |
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.
These functions can be omitted since the test will assert an error exists for every case.
Leaving the fields unspecified will result in a zero-value of nil
.
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.
Fixed
options := NewOptions() | ||
config := fmt.Sprintf("%s\n%s", version, tc.config) | ||
_, err := options.loadConfig([]byte(config)) | ||
if assert.Error(t, err, tc.name) { |
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.
Nice addition of t.Run
👍
We should keep this:
if assert.Error(t, err, tc.name) {
This whole test is about failures, so we assert that one should exist.
This is equivalent to if err != nil
. It protects us from operating on nil errors.
The sneaky benefit of using assert.Error
is that it will also fail the test if it is a nil error.
We can keep the old test behavior for string matching the error text.
To gate it, just check for the zero value ""
.
The gate is not strictly necessary since Contains will always pass with an empty string, but it's more clear.
We should also check that errFn != nil
before running it, otherwise go will
panic: runtime error: invalid memory address or nil pointer dereference
.
Gating this has the added benefit of making this errFn
optional as well.
Finally, we should use the assert library to maintain style.
ex:
t.Run(tc.name, func(t *testing.T) {
options := NewOptions()
config := fmt.Sprintf("%s\n%s", version, tc.config)
_, err := options.loadConfig([]byte(config))
if assert.Error(t, err, tc.name) {
if tc.expErr != "" {
assert.Contains(t, err.Error(), tc.expErr, tc.name)
}
if tc.errFn != nil {
assert.True(t, tc.errFn(err), tc.name)
}
}
})
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.
errFn
may be better named as checkFn
.
The verb/purpose is not "to error" but rather "to check and return a bool".
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 like it much better! I adjusted it accordingly
bef5f93
to
0c692fd
Compare
/retest |
/retest |
7addd7a
to
f9b152a
Compare
/retest |
/cc @caesarxuchao |
/assign |
/assign @caseydavenport @bowei @dcbw |
Thanks! /lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: obitech, 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 |
@@ -29,7 +29,7 @@ var ( | |||
Scheme = runtime.NewScheme() | |||
// Codecs provides methods for retrieving codecs and serializers for specific | |||
// versions and content types. | |||
Codecs = serializer.NewCodecFactory(Scheme) | |||
Codecs = serializer.NewCodecFactory(Scheme, serializer.EnableStrict) |
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.
@obitech I noticed this merged, did you plan to add a lenient path to this PR before then?
…rializer Enable strict serializer in kube-proxy
What type of PR is this?
/kind feature
What this PR does / why we need it:
With strict serializers enabled, an error will be thrown on things such as duplicate or unknown fields when parsing a YAML file. This will improve code quality of user's configuration files as it enforces a proper configuration file to be present when starting a component.
Which issue(s) this PR fixes:
Ref #82924
Special notes for your reviewer:
Does this PR introduce a user-facing change?:
Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:
/sig cluster-lifecycle
/sig api-machinery
/wg component-standard
/cc @mtaufen @stealthybox