Skip to content
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

fix(crd-generator): default values for CRD fields can be numeric or boolean #6666

Merged
merged 1 commit into from
Nov 27, 2024

Conversation

manusa
Copy link
Member

@manusa manusa commented Nov 26, 2024

Description

Fixes #6654

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change
  • Chore (non-breaking change which doesn't affect codebase;
    test, version modification, documentation, etc.)

Checklist

  • Code contributed by me aligns with current project license: Apache 2.0
  • I Added CHANGELOG entry regarding this change
  • I have implemented unit tests to cover my changes
  • I have added/updated the javadocs and other documentation accordingly
  • No new bugs, code smells, etc. in SonarCloud report
  • I tested my code in Kubernetes
  • I tested my code in OpenShift

Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@manusa manusa added this to the 7.0.0 milestone Nov 27, 2024 — with automated-tasks
@manusa manusa merged commit bee2f01 into fabric8io:main Nov 27, 2024
21 of 22 checks passed
@manusa manusa deleted the fix/invalid-crd-default branch November 27, 2024 05:20
Copy link
Member

@andreaTP andreaTP left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this @manusa !
I asked a couple of questions but it looks like a great start!

@@ -42,6 +42,15 @@ public class AnnotatedSpec {
private String defaultValue;
@Default("my-value2")
private String defaultValue2;
@JsonProperty(defaultValue = "true")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens when the two annotations contain different values?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a precedence test for this, you can check it out ;)
JsonProperty takes precedence since AFAIR the other annotation will eventually be removed or deprecated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIR the other annotation will eventually be removed or deprecated

oh, really? I'm surprised!

Should this behavior be documented? somewhere

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have really no idea, I deduced this from this TODO comment:

I thought this had been discussed, but maybe not.

TBH this is the first time I'm actually looking into the CRD generator, up until now I had been delegating any task related to the CRD generator to you folks. So I might be disconnected.

In any case, a deprecation would happen in 7.x and not in 7.0.0

assertThat(JsonSchema.from(ClassInTest.class).getProperties())
.extracting("defaultValueForInt._default")
.asInstanceOf(InstanceOfAssertFactories.type(JsonNode.class))
.isInstanceOf(LongNode.class)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little surprised this is a LongNode

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has to do with the Number parser which considers this to be of long precision.
It really doesn't matter, since what we want is the number to be considered a number and not a String.
Of course, there must be corner cases such as users declaring a field of type in and setting a default value of 999999999999999999999. My expectation is that the cluster won't accept that CRD.
We could try and consider those corner cases, but if we introduce validations for the default values too, the complexity will be kind of crazy for such a simple feature.

Fixing this is just a matter of using the specific parser for the target type. i.e. adding more if-else clauses.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good enough for me, if we get any complaints over this we should remember to add checks for the boundaries (i.e. Integer.MAX_VALUE) etc.

.asInstanceOf(InstanceOfAssertFactories.type(JsonNode.class))
.isInstanceOf(LongNode.class)
.extracting(JsonNode::asLong)
.isEqualTo(1337L);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to also generate the resulting YAML file?

I'm interested in checking the L and d suffixes

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The suffixes here I added them to highlight that these values are equal to the expected type, to make it clear that a long is a long and a double is not a double.
How it renders in the CRD is not about how the value is stored in a JsonNode, but how the serializer deals with those. Basically they'll be rendered as any other number in a JSON->YAML document.

There's also an approval test modified that you can check:

defaultBoolean:
default: true
type: "boolean"
defaultInt:
default: 1337
type: "integer"
defaultInteger:
default: 1337
type: "integer"
defaultValue:
default: "my-value"
type: "string"

I noticed that I didn't add a specific test for doubles, but the expected value should be an unquoted number with a . in case it has decimals.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Invalid CRD with when no string default value is used
3 participants