-
Notifications
You must be signed in to change notification settings - Fork 53
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
Check presence and match of fields in CRD and CSV in bundle #41
Check presence and match of fields in CRD and CSV in bundle #41
Conversation
/cc @kevinrizza @awgreene |
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 work @jeremylinlin
tests/test_files/bundles/verification/crdmissingkindfield.invalid.bundle.yaml
Show resolved
Hide resolved
500032d
to
6aef00d
Compare
/cc @awgreene @kevinrizza |
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 work on this. I just had one small comment, otherwise looks great.
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.
Please address the comments.
6aef00d
to
4628bfa
Compare
/cc @kevinrizza @awgreene |
/lgtm |
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.
Great work on this! Mostly nit-picks on style, I think some logs need additional info as well
operatorcourier/validate.py
Outdated
self._log_error("crd apiVersion not defined.") | ||
valid = False | ||
for crd_required_nested_field in self.crd_required_nested_fields: | ||
valid &= self._crd_fields_validation(crd_required_nested_field.split('.'), |
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: Any benefit of using this oneliner over an if statement? It's already long enough to spread two lines
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.
Actually using an if statement will also make the line exceed 90 chars. I think the line is long mainly because the long and descriptive method and variable names.
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.
Please be aware, that &=
is a bitwise operator. But it seems this code intends to do a boolean operation, so probably
valid = valid and crd_field_valid
would better express the intention here.
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.
Hi @csomh, thanks for the comment. I have updated this.
operatorcourier/validate.py
Outdated
if root_field == 'metadata' and 'name' in yaml_dict['metadata']: | ||
logging.info("Evaluating crd %s", yaml_dict['metadata']['name']) | ||
if root_field not in yaml_dict: | ||
self._log_error("crd %s not defined.", field_string) |
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: Can this also print the name of the crd in question? Or is that covered by previous if statement?
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.
Or is that covered by previous if statement?
Yes.
Can this also print the name of the crd in question?
This actually prints out the (nested) field that is missing in the CRD. See this test case as an example. I have updated the log message to make it less confusing.
operatorcourier/validate.py
Outdated
"spec.customresourcedefinitions.") | ||
valid = False | ||
elif csvOwnedCrd["name"] not in crdList: | ||
self._log_error("custom resource definition referenced in csv " |
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.
Can this print the name of the CRD that doesn't match?
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.
Can the CRD name also be added to the other error logs here as well?
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.
Actually I didn't change much logic in those if statements except making the code less indented.
Can this print the name of the CRD that doesn't match?
Sure I can do that.
Can the CRD name also be added to the other error logs here as well?
I can but that will require some additional nested if
checks to make sure csvOwnedCrd["name"]
exists and is valid. Do you want me to do that?
operatorcourier/validate.py
Outdated
valid = False | ||
|
||
for crd in bundleData[self.crdKey]: | ||
if 'name' not in csvOwnedCrd or not \ |
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 if statement is kinda long, and I'm not sure what it's checking for: Are we continuing if the name doesn't exist or if it does exist?
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 continue to check field matches only if the name in both CRD and CSV exists, and they match.
e4c3841
to
3f168f9
Compare
3f168f9
to
25af109
Compare
operatorcourier/validate.py
Outdated
|
||
for crd in bundleData[self.crdKey]: | ||
if 'name' not in csvOwnedCrd or not \ | ||
self._crd_fields_validation(['metadata', 'name'], crd, '') \ |
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.
If a CRD in the bundle doesn't have a name, should that also log as an error?
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.
Hi @SamiSousa, thanks for the review. Yes, but I believe this should be covered in previous checks.
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.
That check is for the CRD in the CSV, rather than the CRD from the bundle directly.
operator-courier/operatorcourier/validate.py
Line 166 in 25af109
crdList = [] |
On this line the
crdList
is created. Should this be used in this for loop?
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, for each type we should have a list of fields we check. The fact that they happen to be checked in other places by code that compares those fields to other fields shouldn't be relevant. I think part of the problem is that adding this required fields list crd_required_nested_fields
makes the code hard to read.
Perhaps instead we should either do that everywhere for every type, or not create that abstraction at all. Either way, it actually seems outside the scope of this pr. Can we revert it?
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.
@kevinrizza Without this abstraction we will need to introduce even more nested if
s just to check the presence of nested fields. These are already checked in CRD checks but we need to do it again to make sure the field in the yaml we compare against csvOwnedCrd actually exists.
Maybe after this PR I can apply this abstraction for checks in all types? And this hopefully can reduce the nested levels like this that can be found in multiple places in this file.
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.
Your intuition about nested if
s is good in the general case, but I think in this case it makes the code more clear. If we abstract away certain steps but only in certain cases, it makes the code hard to reason about.
Additionally, I think ultimately implementing a change like the one described here is probably the better long term approach: #39
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.
@kevinrizza That seems really cool and should be the better way to do it. For this particular PR, what are the changes you want me to make? Should I remove this abstraction and replace it with nested if
s 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.
@jeremylinlin yes, and please ensure that any of the checks were doing before are no longer removed.
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.
/cc @kevinrizza @SamiSousa Updated.
25af109
to
08caa95
Compare
- Check if the following fields in CRD matches that in CSV in bundle - `CRD.spec.names.plural`.`CRD.spec.group` == `CSV.spec.crd.owned.name` - `CRD.spec.names.kind` == `CSV.spec.crd.owned.kind` - `CRD.spec.version` == `CSV.spec.crd.owned.version` - Check the presence of all above fields in the bundle
08caa95
to
85d79bc
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.
/lgtm
if csvOwnedCrd['name'] != crd['metadata']['name']: | ||
continue | ||
|
||
if 'kind' in csvOwnedCrd: |
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 is much easier to read. 🤓
/lgtm |
CRD.spec.names.plural
.CRD.spec.group
==CSV.spec.crd.owned.name
CRD.spec.names.kind
==CSV.spec.crd.owned.kind
CRD.spec.version
==CSV.spec.crd.owned.version