-
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
kubeadm: enable strict config unmarhaling #70901
kubeadm: enable strict config unmarhaling #70901
Conversation
@@ -242,7 +242,6 @@ func TestMigrate(t *testing.T) { | |||
# This is intentionally testing an old API version and the old kind naming and making sure the output is correct | |||
apiVersion: kubeadm.k8s.io/v1alpha3 | |||
kind: InitConfiguration | |||
kubernetesVersion: v1.12.0 |
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.
some of these _test changes are bugs in our test config data..
cmd/kubeadm/app/util/config/testdata/conversion/master/v1alpha3.yaml
Outdated
Show resolved
Hide resolved
e298aa7
to
ff6bbe2
Compare
updated the PR. |
ff6bbe2
to
ce663f3
Compare
/hold |
f4eea43
to
d1d27ef
Compare
/retest |
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.
@neolit123 thanks for this PR!
As you are saying this change has potential implications and so I would like it to be discussed at sig level.
My personal first impression about this is that I would like kubeadm to be aligned with kubernetes, and that this change is kind of risky at this stage of the cycle
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 the general idea. I see a couple things however:
- I don't like the idea of imposing this on component configs (Kube-Proxy and Kubelet). Technically speaking, this validation should be done on their side and we should simply invoke their code to pre-validate things. Ideally, this should be done centrally like you suggested in [WIP] runtime/serializer: use DisallowUnknownFields for the json-iter config #70839 . I am not convinced, that we should single handedly impose restrictions in other people's configs.
- Missing tests for
InitConfiguration
. We need those in the spirit ofClusterConfiguration
.
cmd/kubeadm/app/util/config/testdata/validation/invalid_duplicate_field_mastercfg.yaml
Outdated
Show resolved
Hide resolved
cmd/kubeadm/app/util/config/testdata/validation/invalid_duplicate_field_nodecfg.yaml
Outdated
Show resolved
Hide resolved
cmd/kubeadm/app/util/config/testdata/validation/invalid_unknown_field_mastercfg.yaml
Outdated
Show resolved
Hide resolved
cmd/kubeadm/app/util/config/testdata/validation/invalid_unknown_field_nodecfg.yaml
Outdated
Show resolved
Hide resolved
api machinery will not enable strict unmarshaling for the core codecs. i will have office hours agenda on this. the change on the kubeadm side will always be risky, due to users having typos or duplicate fields in production YAMLs.
70839 is not going to happen. i just did it to see how many bogus YAML documents will fail the CI and there are quite a few all over the project. i do agree about kubeproxy and kubelet not being our responsibility, but the maintainers are not going to do it anytime in the future. given kubeadm is a tool for the end user it feels to me that we have to do it now, even if temporary. /assign @timothysc |
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.
We'll
/hold
until group consensus.
d1d27ef
to
e4b48bb
Compare
"sigs.k8s.io/yaml" | ||
) | ||
|
||
var localScheme = runtime.NewScheme() |
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 reason for this localscheme is that i cannot find a way to obtain external empty objects from our schemes such as:
&kubeadmapiv1beta1.ClusterConfiguration{}
in the case of: constants.ClusterConfigurationKind
and kubeadmapiv1alpha3.SchemeGroupVersion
@fabriziopandini @rosti @timothysc please advise.
is there a magical way to convert from GroupVersionKind to such an external empty object for our already registered config types including component configs?
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.
@neolit123 Isn't this one working for you?
var Scheme = runtime.NewScheme() |
73a0546
to
5552c66
Compare
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'll do a more thorough review tomorrow. Hope the suggestion works.
"sigs.k8s.io/yaml" | ||
) | ||
|
||
var localScheme = runtime.NewScheme() |
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.
@neolit123 Isn't this one working for you?
var Scheme = runtime.NewScheme() |
5552c66
to
2473bba
Compare
iface, err = componentconfigs.Scheme.New(gvk) | ||
if err != nil { | ||
err := errors.Errorf("unknown configuration %#v for scheme definitions in %q and %q", | ||
gvk, scheme.Scheme.Name(), componentconfigs.Scheme.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.
after the suggestion by @rosti this was greatly simplified and the init function was removed. 🎉
what this is doing is to check if a certain GVK exists in our kubeadm configs and if it doesn't it checks the component configs.
if it's missing for both it outputs such an error:
W1116 02:17:13.388274 30409 strict.go:47] unknown configuration schema.GroupVersionKind{Group:"kubeproxy.config.k8s.io", Version:"v1alpha1", Kind:"KubeProxyConfiguration1"} for scheme definitions "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme/scheme.go:31" and "k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs/scheme.go:28"
@timothysc please let me know if you want me to further amend the error output.
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.
thx @neolit123 !
/lgtm
/approve
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: neolit123, timothysc 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 |
/hold cancel |
/test pull-kubernetes-e2e-gce-100-performance |
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.
LGTM, thanks, but some small cleanup notes
// VerifyUnmarshalStrict takes a YAML byte slice and a GroupVersionKind and verifies if the YAML | ||
// schema is known and if it unmarshals with strict mode. | ||
// | ||
// TODO(neolit123): The returned error here is currently ignored everywhere and a klog warning is thrown instead. |
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.
Why don't you run klog if err != nil
on the caller side instead?
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 did this to contain the klog messages in one location.
otherwise i have to copy them two times - one for init and one for join config.
func VerifyUnmarshalStrict(bytes []byte, gvk schema.GroupVersionKind) error { | ||
|
||
var ( | ||
iface interface{} |
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: this isn't needed, just use :=
on first invocation instead
} | ||
err = VerifyUnmarshalStrict(bytes, gvk) | ||
if (err != nil) != test.expectedError { | ||
t.Errorf("expected error %v, got %v, error: %v", err != nil, test.expectedError, err) |
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 managed to flip "got" and "expected" here..
What type of PR is this?
/kind bug
What this PR does / why we need it:
EDITED
my PR here has the potential to break the whole k8s:
#70839
so instead this kubeadm localized PR can be used, which enables YAML field validation outside of codecs.
Which issue(s) this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close the issue(s) when PR gets merged):Fixes kubernetes/kubeadm#1066
Special notes for your reviewer:
NONE
Does this PR introduce a user-facing change?:
/assign @fabriziopandini @rosti
/priority important-longterm
cc @kubernetes/sig-cluster-lifecycle-pr-reviews
cc @luxas @dims