apimachinery: add StringArrayOrString with json/yaml/proto marshaling#50625
apimachinery: add StringArrayOrString with json/yaml/proto marshaling#50625sttts wants to merge 2 commits intokubernetes:masterfrom
Conversation
ec99c77 to
c8566ca
Compare
c8566ca to
6116318
Compare
6116318 to
4181cf1
Compare
|
/retest |
| func (arraystr *StringArrayOrString) ArrayValue() []string { | ||
| if arraystr.Type == String { | ||
| if arraystr.StrVal == "" { | ||
| return nil |
There was a problem hiding this comment.
Why nil instead of a zero length slice?
| input string | ||
| result StringArrayOrStringHolder | ||
| }{ | ||
| {`{"val1": []}`, StringArrayOrStringHolder{SAOrS: FromString("")}}, |
There was a problem hiding this comment.
This surprised me. Serialized as an array, not a string?
There was a problem hiding this comment.
This surprised me. Serialized as an array, not a string?
Oh, unmarshal test
| input string | ||
| result StringArrayOrStringHolder | ||
| }{ | ||
| {`{"val1": []}`, StringArrayOrStringHolder{SAOrS: FromString("")}}, |
There was a problem hiding this comment.
Add a test unmarshalling an empty string please.
|
Request for an additional test. lgtm otherwise /approve no-issue |
4181cf1 to
194cd5f
Compare
|
Test added. |
|
/approve no-issue |
|
/lgtm @smarterclayton you should look. |
|
Another alternative is to say our "JSON Schema" differs slightly from the official spec, such as having to always use a string array in fields such as this, even if you only have one string (assuming there is no semantic difference between a string and an array with one entry). OpenAPI does this too; their docs explain the minor differences between OpenAPI Schema and the JSON Schema spec. The ability to exert such control over our own API was after all one of the justifications for importing the structs. If we wanted to match the spec 100%, it may have made more sense to just store the JSON Schema as a string. |
|
@sttts PR needs rebase |
|
@enisoc I am still not convinced that something like StringArrayOrString is bad. What are the issues that everybody expects? Short term in fact we could just fall back to "string only". This is what OpenAPI v3 does and we only support v3 now anyway. But IMO this is a very stupid restriction in the spec and I expect very much hat v3+ will support more than one type. But by that time we can reconsider. |
|
@sttts I was mostly just trying to give a hypothetical answer to the question, "What's the alternative?" I'm not familiar enough with the pain experienced with @smarterclayton You mentioned pain with OpenAPI. Were you referring to this thread? It seems like that issue will go away eventually when we switch to OpenAPI v3. |
We still don't have the type field as array in OpenAPI v3. We have dropped this now from our JSON Schema types. So the unmarshaler will complain if you try an array. If v4 finally adds arrays, we have to reconsider. |
We are on the other side of the problem: we offer the API, but our users won't be able to use an array for types. Actually, it's not |
|
Sorry if I'm creating confusion. I didn't mean to suggest that oneOf/anyOf could fix the problem faced by CRD validation. I was trying to say, if it's true that (1) the problem in that mailing list thread is the only known pain caused by IntOrString, and (2) the problem in that thread could be resolved by going to OpenAPI V3, then it would imply that there are actually no known, long-term problems with IntOrString. Therefore we would have no reason to suspect adding StringArrayOrString will cause long-term pain. |
|
@sttts We have absolutely no obligation to allow all of JSON / JSONSchema. The K8s API uses its own conventions, and even some of those we regret. Has anyone attempted to determine which features are exercised by the current K8s API surface? Are there any examples of StringArrayOrString in the K8s core v1 API? IIRC, we explicitly decided not to support that for command, for instance. We do have the problem that not all of the K8s API can be described by the current OpenAPI spec. At least that was true when I last checked. cc @mbohlool |
That's a good second view point. We use OpenAPI v3 to decribe kube's API (lower bound), but here we want to define the JSON Schema subset to specify APIs following the kube API conventions. Wondering whether we can derive any upper bound from the conventions we envisions also for user-provided CRDs. Sounds like a nice topic for bachelor thesis (hint!). kubeapi-lint. |
At least not from the spec point of view: |
|
|
Let me see if I understand the problem correctly. User provides a validation schema that we will use to validate CRs. We want them to be able to provide multiple types. Currently we support OpenAPI v3 schema in CRD validation, so they can do things like '{anyOf: [{type: "string"}, {type: "integer"}]}' but they can't do If the above is correct, what if we do a post-processing on the provided spec and convert Regarding |
|
@mbohlool we could do that transformation. But as we restrict ourselves to OpenAPI v3 now in CRD validation, the problem is no problem anymore. I.e. we don't need |
|
If we want common tooling, such as get, describe, schema validation, apply, etc., to work across built-in types and CRDs, then CRDs need to follow K8s API conventions, and the provided schema needs to support the same extensions we're adding for the built-in types. cc @pwittrock |
This is on the roadmap, together with a common definition namespace such that you can reference e.g. a PodSpec from a CRD. Would be great to get a proposal done for that early in the 1.9 dev cycle. |
|
Before looking in detail, let me say that IntOrString is terrible and we should not add more things like it :) |
|
Why do we need to represent the jsonschema in go types at all? Do we have go code that operates on it? Why not store it in a RawExtension type (i.e., just pass-through the json). |
|
On IntOrString: when we made it, we thought we were being nice to humans who were going to write yaml/json by hand directly. But in hindsight, I think it was not worth it. It confuses everyone who touches it. No type spec system represents it well, excepting OpenAPI3, which we don't use yet. Automation systems don't deal with it well, either, e.g. Google's Deployment Manager. It's especially confusing that "12" and 12 weren't the same thing for a while, but now I think they are, but "12%" still isn't. There was really no good reason not to make a struct {name, number} for port identification. An extra level in a yaml file really isn't a big deal. Basically, it violates the principle of least surprise for all the automation systems that have to deal with the API, without adding much benefit for users who are directly writing API objects. |
Automatic merge from submit-queue apiextensions: validation for customresources - [x] Add types for validation of CustomResources - [x] Fix conversion-gen: #49747 - [x] Fix defaulter-gen: kubernetes/gengo#61 - [x] Convert to OpenAPI types - [x] Validate CR using go-openapi - [x] Validate CRD Schema - [x] Add integration tests - [x] Fix round trip tests: #51204 - [x] Add custom fuzzer functions - [x] Add custom conversion functions - [x] Fix data race while updating CRD: #50098 - [x] Add feature gate for CustomResourceValidation - [x] Fix protobuf generation Proposal: kubernetes/community#708 Additional discussion: #49879, #50625 **Release note**: ```release-note Add validation for CustomResources via JSON Schema. ``` /cc @sttts @deads2k
|
this is no longer needed, correct? |
|
Correct. |
Automatic merge from submit-queue apiextensions: validation for customresources - [x] Add types for validation of CustomResources - [x] Fix conversion-gen: #49747 - [x] Fix defaulter-gen: kubernetes/gengo#61 - [x] Convert to OpenAPI types - [x] Validate CR using go-openapi - [x] Validate CRD Schema - [x] Add integration tests - [x] Fix round trip tests: #51204 - [x] Add custom fuzzer functions - [x] Add custom conversion functions - [x] Fix data race while updating CRD: #50098 - [x] Add feature gate for CustomResourceValidation - [x] Fix protobuf generation Proposal: kubernetes/community#708 Additional discussion: kubernetes/kubernetes#49879, kubernetes/kubernetes#50625 **Release note**: ```release-note Add validation for CustomResources via JSON Schema. ``` /cc @sttts @deads2k Kubernetes-commit: 4457e43e7b789586096bfb564330295cf0438e70
In analogy to
IntOrStringthis allows to have either a string or a string array in JSON/YAML/proto, needed by CRD validation #47263.