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
Disallow legacy hostNetwork together with non-default provider #13693
Conversation
|
f0ef161
to
1513efe
Compare
a12fcfb
to
b3e0b74
Compare
d9aef18
to
210e2a1
Compare
This looks good. Let's also add a validating admission policy to reflect this in With that set, it should mean that k8s won't let you set |
210e2a1
to
26e3ab6
Compare
64d94eb
to
a02473d
Compare
02e5703
to
127d5dd
Compare
@BlaineEXE wrote:
Thanks for this hint! I found the place in the code. I will soon update the PR accordingly |
729d9b3
to
75b15fc
Compare
@BlaineEXE wrote:
I think I have now added what you suggested. And added the updated crds resulting from that. I guess now it "just" need some testing ... |
75b15fc
to
1f643d1
Compare
ff38153
to
ff2e341
Compare
pkg/apis/ceph.rook.io/v1/types.go
Outdated
@@ -2316,6 +2316,7 @@ type SSSDSidecarAdditionalFile struct { | |||
|
|||
// NetworkSpec for Ceph includes backward compatibility code | |||
// +kubebuilder:validation:XValidation:message="at least one network selector must be specified when using multus",rule="!has(self.provider) || (self.provider != 'multus' || (self.provider == 'multus' && size(self.selectors) > 0))" | |||
// +kubebuilder:validation:XValidation:message="the legacy hostNetwork setting can only be set if the network.provider is set to the empty string",rule="(self.hostNetwork != true) || (self.provider == '')" |
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 had to look up CEL documentation to learn that we do need has()
statements when JSON omitempty
is used.
The expression here is failing because it does not allow the empty-omitted case to succeed. The expression must be modified to allow !has(self.hostNetwork)
to be interpreted the same as self.hostNetwork == false
.
Ditto for !has(self.provider)
being interpreted the same as self.provider == ""
.
Please also use self.hostNetwork == false
instead of self.hostNetwork != true
. ==
is always easier to read than !=
.
The parens surrounding the statements between ||
are also unnecessary and don't improve legibility. Let's remove those before final merge.
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.
Also, I certainly find that sometimes the required logic needed to explain to VAPs when to pass validation can be hard to grok. I imagine this may be the case for you as well.
I have been finding it easier to mentally write out the failure case and then use DeMorgan's Laws to get the inverse expression. I learned this in school, but I'm not sure how common it is in other curriculums.
For example, the failure case is has(self.hostNetwork) && self.hostNetwork == true && has(self.provider) && self.provider != ""
. The inverse of this is !(<the whole previous expression>)
, and then DeMorgan's Laws allow simplifying the expression into ||
statements.
FWIW, this is also often how I go about reading/interpreting the existing validation statements. I find it easier to mentally grasp the failure cases.
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.
done
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.
@BlaineEXE thanks fore the detailed explanation above! I agree with everything you wrote. fwiw, application of Boolean algebra and de Morgan's law is how I originally arrived at the rule I initially had in the code (involving ||
instead of &&
.
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 these latest updates, the CI looks a lot better. One failing check looks unrelated.
Locally everything builds and deploys fine. got cluster-test.yaml
to deploy to status HEALTH_OK
! 🎉
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 inverse of the "failure case" expression I mentioned would be this:
!has(self.hostNetwork) || self.hostNetwork == false || !has(self.provider) || self.provider == ""
Note that I am using == false
as the inverse of == true
and == ""
as the inverse of != ""
to reduce the statement's layers to their simplest boolean algebra forms.
09f4032
to
7bb2723
Compare
4166dfb
to
c7689c6
Compare
pkg/apis/ceph.rook.io/v1/types.go
Outdated
@@ -2316,6 +2316,7 @@ type SSSDSidecarAdditionalFile struct { | |||
|
|||
// NetworkSpec for Ceph includes backward compatibility code | |||
// +kubebuilder:validation:XValidation:message="at least one network selector must be specified when using multus",rule="!has(self.provider) || (self.provider != 'multus' || (self.provider == 'multus' && size(self.selectors) > 0))" | |||
// +kubebuilder:validation:XValidation:message="the legacy hostNetwork setting can only be set if the network.provider is set to the empty string",rule="!has(self.hostNetwork) || !has(self.provider)" |
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.
rule="!has(self.hostNetwork) || !has(self.provider)
-> rule="has(self.hostNetwork) && !has(self.provider)" might be this
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.
@parth-gr wrote:
rule="!has(self.hostNetwork) || !has(self.provider) -> rule="has(self.hostNetwork) && !has(self.provider)" might be this
Actually no: We want to prevent hostNetwork from being set together with a non-empty provider, so the rule has to be this:
!(has(self.hostNetwork) && has(self.provider))
which Boolean algebra simplifies to:
!has(self.hostNetwork) || !has(self.provider)
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.
It is actually even more complex since we do need to check the values in addition to using has()
I'll update shortly.
Signed-off-by: Michael Adam <obnox@samba.org>
c7689c6
to
fb7ebd0
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.
Looks good, but please squash the commits into one. It's fine to leave the first (ci: add "network" to the allowed commit message prefixes
) commit separate if you like.
@BlaineEXE wrote:
Thanks! I'll do the squashing tomorrow |
Fixes: rook#13692 Since the introduction of the "host" network provider, the legacy "hostNetwork" setting is intended to be used only in combination with the default network provider (""), but the code did not enforce this. This change adds the required validation checks to throw errors in invalid constellations. These checks are added both in the operator's input validation code and as kubernetes x-validation admission policies in the Cepcluster CRD. Signed-off-by: Michael Adam <obnox@samba.org>
fb7ebd0
to
25aa15e
Compare
I actually already did it now 😬 |
Disallow legacy hostNetwork together with non-default provider (backport #13693)
Description of changes:
Since the introduction of the "host" network provider, the legacy
"hostNetwork" setting is intended to be used only in combination with
the default network provider (""), but originally, the code did not enforce this.
Issue resolved by this Pull Request:
Resolves #13692
Checklist: