kudobuilder / kudo

Kubernetes Universal Declarative Operator (KUDO)
https://kudo.dev
Apache License 2.0
1.17k stars 103 forks source link

Unexpected handling of integer/long parameters #1779

Open bearpaws opened 3 years ago

bearpaws commented 3 years ago

What happened: Defined a parameter of type integer with a default value:

- name: MY_PARAM
  default: 432000000
  type: integer

Packaging the operator resulted in this error:

parameter "MY_PARAM" has an invalid default value:
type is "integer" but format of %!s(float64=4.32e+08) is invalid

Changed the type to long which solved the first error. But when the param is used in a template:

myParam={{ .Params.MY_PARAM }}

It is rendered as:

myParam=4.32e+08

Same thing happens when trying this:

myParam={{ .Params.MY_PARAM | toString }}

What you expected to happen: The default value of an integer parameter should not be parsed as a float.

When rendering an integer or long, it should not be formatted using scientific notation.

How to reproduce it (as minimally and precisely as possible):

  1. Define a param of type integer with a valid default value
  2. Reference the param in a template.
  3. Build the operator: kubectl-kudo package create ./operator --destination /tmp

Anything else we need to know?: It's not clear if integer/long types are actually supported.

The docs show only array and map types: https://kudo.dev/docs/developing-operators/parameters.html#declaring-parameters

Yet this KEP (https://github.com/kudobuilder/kudo/issues/988) has been completed and kudo allows integer and long params to be defined.

Environment:

ANeumann82 commented 3 years ago

I'm pretty sure this is a yaml-problem. Please try using a string as the default:

- name: MY_PARAM
  default: "432000000"
  type: integer

Yaml (as json) do not really support >32bit integers, you have to quote them as strings. Blame JavaScript for it ;)

bearpaws commented 3 years ago

The value I tested with is a valid 32-bit integer (432,000,000).

ANeumann82 commented 3 years ago

Good point. After looking into it, it's a go Problem. Go's default formatting uses scientific formatting sometimes, for some reason. See https://stackoverflow.com/questions/41159492/format-float-in-golang-html-template

We now could pre-format the value before rendering the template, but the issue is, some users might need access to the raw value.

The only solution I see for now is to use custom formatting:

{{printf "%.2f" .Params.MY_PARAM}}

Which is kind of annoying, or to use quotes around the Parameter default value, which would prevent the yaml parser to parse this as a number.

ANeumann82 commented 3 years ago

Oh, and there is no type "long" in KUDO - In the linked PR I added validation that would throw a validation error.

Type integer is actually correct and includes 32 and 64bit long integers. And these should be rendered correctly without explicit formatting.