kubernetes / kube-openapi Goto Github PK
View Code? Open in Web Editor NEWKubernetes OpenAPI spec generation & serving
License: Apache License 2.0
Kubernetes OpenAPI spec generation & serving
License: Apache License 2.0
I'm not sure how difficult this would be, but it would be really handy if we could annotate each property that will force a replacement of the related resource.
For example, changing the .spec.affinity
field of a Pod will force a replacement. We've manually curated a list of the ones we've encountered here: https://github.com/pulumi/pulumi-kubernetes/blob/e9f9dda531c3b8cfff519fd438a01f878d5e271a/pkg/provider/diff.go
This list isn't authoritative, and it would be great if we had a real source of truth here.
https://travis-ci.org/kubernetes/kube-openapi/builds/539009857
travis-ci in this repo doesn't honor go module
go get: warning: modules disabled by GO111MODULE=auto in GOPATH/src;
ignoring go.mod;
instead of fetching the pinged commit, the CI fetches package from HEAD, which includes public interface change, and fails to compile
pkg/schemaconv/smd.go:235:5: unknown field 'DiscriminatedBy' in struct literal of type schema.UnionField
pkg/schemaconv/smd.go:254:3: a.Struct undefined (type *schema.Atom has no field or method Struct)
pkg/schemaconv/smd.go:254:14: undefined: schema.Struct
pkg/schemaconv/smd.go:258:4: a.Struct undefined (type *schema.Atom has no field or method Struct)
pkg/schemaconv/smd.go:271:3: a.Struct undefined (type *schema.Atom has no field or method Struct)
cc @apelisse
@mbohlool , is there an example on how to use this generator to generate/serve open api spec for CRDs from GO types?
From kubernetes-client/java#96, I am looking for ways to generate non-Go client for CRDs.
Any help is much appreciated!
The two annotations used to describe the topology of maps and structs, +mapType
and +structType
, should result in generating the equivalent openapi extensions (x-kubernetes-map-type
and x-kubernetes-struct-type
respectively). This is documented but not implemented at the moment.
/assign
(have a tiny PR in progress at the moment)
Found following issues in the README inside test/integration folder
go run ../../cmd/openapi-gen/openapi-gen.go -i "./testdata/listtype" -o pkg -p generated -O openapi_generated
pkg/generaged/openapi_generated.go
should have been created.It should be "pkg/generated/openapi_generated.go"
Write a full documentation on how to use Kube-OpenAPI.
/assign mbohlool
To prevent problems like this: #113 (comment)
When running the openapi-gen
code generator in the kubernetes/cluster-registry repo executed by the lines in this script, I see several could not import <some-package-import-path>
errors for dependencies that are located within the vendor directory of the repo. For example:
I1220 16:35:12.455910 9557 parse.go:418] type checker: /tmp/gopathnU5sCI0j/src/k8s.io/apimachinery/pkg/apis/meta/v1/micro_time.go:23:10: could not import k8s.io/kube-openapi/pkg/common (unable to import "k8s.io/kube-openapi/pkg/common": cannot find package "k8s.io/kube-openapi/pkg/common" in any of:
/usr/local/go/src/k8s.io/kube-openapi/pkg/common (from $GOROOT)
/tmp/gopathnU5sCI0j/src/k8s.io/kube-openapi/pkg/common (from $GOPATH))
The reason for these errors is that the type checker
seems to want the import located in the src directory of either the Go toolchain installation or the GOPATH.
Can we instead allow the tool to search a particular comma separated list of directories? This would allow one to specify the vendor directory within their repo to satisfy them all.
How to reproduce it:
To reproduce this, add --v=10
and possibly also --logtostderr
(or just look for the file /tmp/openapi-gen.*
) in the openapi-gen
step at: https://github.com/kubernetes/cluster-registry/blob/cc52bb00104bda72a2a14fdf49d71630e81c1fe8/hack/update-codegen.sh#L114-L120
to see all the errors.
I was wondering if 'kubectl explain' can be used to find out information about Custom Resources?
Based on my understanding of kube-openapi and 'kubectl explain' workflow, it seems to me that this is currently not possible. Is this correct understanding?
I have written up my analysis here:
https://medium.com/@cloudark/understanding-kubectl-explain-9d703396cc8
Could you take a look and let me know if it is correct?
cc: @sttts
Hi,
I'm interested in tackling kubernetes/kubernetes#8116 and kubernetes/kubernetes#24562. I understand that this project wishes to remain free of Kubernetes particularities, and I also see there's an attempt at integrating kube-openapi at kubernetes/kubernetes#55472.
So my question is if my end goal is to add enums to the generated swagger/openapi Json (or format regexp for Strings), should I start by adding the support to this project? Is this project intended to replace go-restful?
@apelisse @dims Please advise and will do accordingly.
Problem
While running github-actions CI, using go v.1.16, "go test" fails if GOPATH is not passed explicit to "go test"
Description
Pull Requests #226 , #232 and Issue #225 are related to this
Will close this issue if this not need to be tracked
Currently, the builder
package is tightly coupled with a 2017 version of go-restful
. This dependency is exposed in three places:
BuildOpenAPISpec
, which takes a slice of *restful.WebService
sGetOperationIDAndTags
function, which takes a *restful.Route
BuildAndRegisterOpenAPIVersionedService
It would be nice to be able to use this builder with newer versions of go-restful
, but also with other frameworks.
I propose taking ownership of the route interfaces and adding an adapter for the current version of go-restful
to support the transition. We could add more adapters in this repo, or 3rd parties could implement them elsewhere.
This would result in three breaking changes that I can see, with the two places the current dependency is exposed. Would this require a formal KEP?
list_type is only useful when writing, and writes to *List types (containing metav1.ListMeta) are not written to
currently, every list type has a lint violation exception in place because of this, and every API promotion adds a new violation
The go-restful Returns
directive says it's ok to use a nil interface value for the model
: https://godoc.org/github.com/emicklei/go-restful#RouteBuilder.Returns
But when I pass nil in (in this case while adding a new route to the K8s API server), it causes a nil pointer dereference in GetCanonicalTypeName
. I think this is because reflect.TypeOf
returns nil when given a nil interface, but we immediately call t.Kind()
without first checking if t
is nil:
Lines 93 to 94 in fd29a9f
I don't have time to context-switch to a PR to fix at the moment, but figured I'd report it in case someone else can.
ServiceServingCertSignerConfig
embeds metav1.TypeMeta
and configv1.GenericControllerConfig
: https://github.com/openshift/api/blob/master/servicecertsigner/v1alpha1/types.go#L15-L21
At the time, configv1.GenericControllerConfig
also embedded metav1.TypeMeta
, which led to:
func schema_openshift_api_servicecertsigner_v1alpha1_ServiceServingCertSignerConfig(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "ServiceServingCertSignerConfig provides information to configure a serving serving cert signing controller",
Properties: map[string]spec.Schema{
"kind": {
SchemaProps: spec.SchemaProps{
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
Type: []string{"string"},
Format: "",
},
},
"apiVersion": {
SchemaProps: spec.SchemaProps{
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources",
Type: []string{"string"},
Format: "",
},
},
"kind": {
SchemaProps: spec.SchemaProps{
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
Type: []string{"string"},
Format: "",
},
},
"apiVersion": {
SchemaProps: spec.SchemaProps{
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources",
Type: []string{"string"},
Format: "",
},
},
pkg/openapi/zz_generated.openapi.go:24107:6: duplicate key "kind" in map literal
pkg/openapi/zz_generated.openapi.go:24114:6: duplicate key "apiVersion" in map literal
we have an Go app that run as an Kubernetes initializer. It imports the following:
"k8s.io/client-go/tools/clientcmd"
"github.com/ghodss/yaml"
"k8s.io/api/apps/v1beta1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/strategicpatch"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
And then invokes 2 two merge this way:
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, v1beta1.Deployment{})
This works fine up till recently, where building the code failed with the following error:
../k8s.io/apimachinery/pkg/util/strategicpatch/meta.go:166:17: cannot use kindItem (type *kindItem) as type "k8s.io/kube-openapi/pkg/util/proto".SchemaVisitor in argument to s.Schema.Accept:
*kindItem does not implement "k8s.io/kube-openapi/pkg/util/proto".SchemaVisitor (missing VisitArbitrary method)
../k8s.io/apimachinery/pkg/util/strategicpatch/meta.go:181:17: cannot use sliceItem (type *sliceItem) as type "k8s.io/kube-openapi/pkg/util/proto".SchemaVisitor in argument to s.Schema.Accept:
*sliceItem does not implement "k8s.io/kube-openapi/pkg/util/proto".SchemaVisitor (missing VisitArbitrary method)
../k8s.io/apimachinery/pkg/util/strategicpatch/types.go:55:5: cannot use kindItem literal (type *kindItem) as type LookupPatchItem in assignment:
*kindItem does not implement LookupPatchItem (missing VisitArbitrary method)
../k8s.io/apimachinery/pkg/util/strategicpatch/types.go:79:28: cannot use item (type *kindItem) as type "k8s.io/kube-openapi/pkg/util/proto".SchemaVisitor in argument to schema.SubSchema().Accept:
*kindItem does not implement "k8s.io/kube-openapi/pkg/util/proto".SchemaVisitor (missing VisitArbitrary method)
../k8s.io/apimachinery/pkg/util/strategicpatch/types.go:118:5: cannot use sliceItem literal (type *sliceItem) as type LookupPatchItem in assignment:
*sliceItem does not implement LookupPatchItem (missing VisitArbitrary method)
../k8s.io/apimachinery/pkg/util/strategicpatch/types.go:146:28: cannot use item (type *sliceItem) as type "k8s.io/kube-openapi/pkg/util/proto".SchemaVisitor in argument to schema.SubSchema().Accept:
*sliceItem does not implement "k8s.io/kube-openapi/pkg/util/proto".SchemaVisitor (missing VisitArbitrary method)
../k8s.io/apimachinery/pkg/util/strategicpatch/types.go:169:18: cannot use item (type *sliceItem) as type "k8s.io/kube-openapi/pkg/util/proto".SchemaVisitor in argument to subschema.Accept:
*sliceItem does not implement "k8s.io/kube-openapi/pkg/util/proto".SchemaVisitor (missing VisitArbitrary method)
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.2.4
creationTimestamp: null
name: sampleapps.app.mydomain
spec:
group: app.mydomain
names:
kind: SampleApp
listKind: SampleAppList
plural: sampleapps
singular: sampleapp
scope: Namespaced
validation:
openAPIV3Schema:
description: SampleApp is the Schema for the sampleapps API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: SampleAppSpec defines the desired state of SampleApp
properties:
foo:
description: Foo is an example field of SampleApp. Edit SampleApp_types.go
to remove/update
type: string
type: object
status:
description: SampleAppStatus defines the observed state of SampleApp
type: object
type: object
version: v1
versions:
- name: v1
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []
All K8s subrepositories should have a CONTRIBUTING.md file, which at the minimum should point to https://github.com/kubernetes/community/blob/master/contributors/guide/README.md. Care should be taken that all information is in sync with the contributor guide.
Subrepositories may also have contributing guidelines specific to that repository. They should be explicitly documented and explained in the CONTRIBUTING.md
Ref kubernetes/kubernetes#92064 (comment)
Add a linter to catch listMapKey
(e.g. apiserverID) that mismatches actual field name (e.g. apiServerID).
The specific bug was merged with the API definition. It was detected when we actually serve the API and test server-side apply with non-empty payload
I am trying to generate OpenAPI Spec for some custom type definitions. There are no validation errors and openapi_generated.go is correctly generated. The custom type definition has a field whose type is apimachinery's v1.Time. When using builder.go to generate the JSON OpenAPI Spec, I am getting following error:
2019/04/07 12:00:08 ERROR: cannot find model definition for k8s.io/apimachinery/pkg/apis/meta/v1.Time. If you added a new type, you may need to add +k8s:openapi-gen=true to the package or type and run code-gen again
exit status 1
The vendor/k8s.io/apimachinery/pkg/apis/meta/v1/doc.go already has '+k8s:openapi-gen=true' set.
Is there a way to get around this issue?
In the Jaeger Operator, we have structs similar to this:
// +k8s:openapi-gen=true
type JaegerSpec struct {
// +optional
JaegerCommonSpec `json:",inline,omitempty"`
}
type JaegerQuerySpec struct {
// +optional
JaegerCommonSpec `json:",inline,omitempty"`
}
type JaegerCollectorSpec struct {
// +optional
JaegerCommonSpec `json:",inline,omitempty"`
}
// and a bunch of other types embedding the common spec
// +k8s:openapi-gen=true
type JaegerCommonSpec struct {
// +optional
Volumes []v1.Volume `json:"volumes,omitempty"`
// +optional
Affinity *v1.Affinity `json:"affinity,omitempty"`
// a bunch of other fields here...
}
Generating the CRD with the OpenAPI Schema generates a CRD with 1.3M:
$ ls -lah deploy/crds/jaegertracing.io_jaegers_crd.yaml
-rw-r--r--. 1 jpkroehling wheel 1,3M 29. Nov 16:56 deploy/crds/jaegertracing.io_jaegers_crd.yaml
Kubernetes, in turn, refuses this CRD:
The CustomResourceDefinition "jaegers.jaegertracing.io" is invalid: metadata.annotations: Too long: must have at most 262144 characters
Unfortunately, it looks like overriding the tag k8s:openapi-gen
to false
in the JaegerCommonSpec
type has no effect. Neither has overriding the tag at the property level, so, my request here is to allow properties to be skipped from the schema generation.
I noticed when validating a custom resource using the apiextensions NewSchemaValidator (which is using the SchemaValidator in this repo) that when a validation error occurs within a slice, the index of the slice is omitted from the fieldpath returned in the error.
YAML snippet:
spec:
dependsOn:
- provider: registry.upbound.io/crossplane/provider-aws
version: 1
Output:
spec.dependsOn.version in body must be of type string: "integer"
I looked into why this is happening by traversing through the recursive validation that is performed against the schema. When we get to a the sliceValidator
for spec.dependsOn
, it's Applies()
call returns true
, causing it to be run.
Looking good so far. When the validation actually runs, we get the length for the slice and construct a new SchemaValidator
that we will reuse to validate each item (just one item in this case).
When we first construct this nested SchemaValidator
we set the path to match the parent validator (spec.dependsOn
). This is not accurate though and needs to be updated on each iteration, so we call SetPath()
. After setting the path, we can see that the validator has the proper index appended (spec.dependsOn.0
).
Still looking good (though the format is a bit strange, more on this below). Unfortunately, the initial call to NewSchemaValidator()
is when each of its child validators are instantiated (e.g. formatValidator
, objectValidator
, etc.), and the subsequent call to SetPath()
updates the SchemaValidator
path, but none of the child validator paths (so now the SchemaValidator
has path spec.dependsOn.0
, but all child validators have path spec.dependsOn
). This can be observed when we iterate through each of the child validators and compare their path with the SchemaValidator
:
Unfortunately this means that if an error occurs anywhere in any descendant validator, the index of the slice is omitted from the field path (as seen at beginning of the ticket). I have also verified that this is happening in the API server validation (that consumes this repo):
Note: this example is using a different resource.
$ kubectl apply -f definition.yaml --validate=false
The CompositeResourceDefinition "compositepostgresqlinstances.database.example.org" is invalid: spec.versions.referenceable: Invalid value: "string": spec.versions.referenceable in body must be of type boolean: "string"
I imagine most users are not catching this because the client-side validation provides a more accurate error:
$ kubectl apply -f definition.yaml
error: error validating "definition.yaml": error validating data: ValidationError(CompositeResourceDefinition.spec.versions[0].referenceable): invalid type for io.crossplane.apiextensions.v1.CompositeResourceDefinition.spec.versions.referenceable: got "string", expected "boolean"; if you choose to ignore these errors, turn validation off with --validate=false
I would like to propose two changes, and I am happy to implement them:
SchemaValidator
SetPath()
The simplest fix is to set the path for all child validators when the path is set on SchemaValidator
. Though I believe there could be some more elegant handling of paths while performing this traversal, this does address the issue and is a lightweight change to fix this in the immediate term.
// SetPath sets the path for this schema validator
func (s *SchemaValidator) SetPath(path string) {
s.Path = path
for _, v := range s.validators {
v.SetPath(path)
}
}
I have verified that this works correctly:
spec.dependsOn.0.version in body must be of type string: "integer"
To be more aligned with client-side validation, and for a more generally accepted format, it would be great to represent that index of a slice as dependsOn[0]
instead of dependsOn.0
.
If both of these fixes sound reasonable to folks, I'll go ahead and open PRs to address.
/assign
/bug
As per the email sent to kubernetes-dev[1], please create a SECURITY_CONTACTS
file.
The template for the file can be found in the kubernetes-template repository[2].
A description for the file is in the steering-committee docs[3], you might need
to search that page for "Security Contacts".
Please feel free to ping me on the PR when you make it, otherwise I will see when
you close this issue. :)
Thanks so much, let me know if you have any questions.
(This issue was generated from a tool, apologies for any weirdness.)
[1] https://groups.google.com/forum/#!topic/kubernetes-dev/codeiIoQ6QE
[2] https://github.com/kubernetes/kubernetes-template-project/blob/master/SECURITY_CONTACTS
[3] https://github.com/kubernetes/community/blob/master/committee-steering/governance/sig-governance-template-short.md
Proto (and, it seems, json-schema) have a "required" concept, by which they mean that you cannot decode/deserialize an object that lacks the field.
Kubernetes has a required concept, by which we mean you cannot create an object if it lacks the field.
Fields that are "required" in the Kubernetes sense are NOT required in the proto/json-schema sense: There are valid uses of kubernetes resources that involve deliberately partially specified objects.
This is just an example of an attribute for which it's very important when it is checked.
I'll categorize the aspects of our system in these two buckets here, as I think of them.
Deserialization-time enforcement:
Validation-time enforcement:
#13
I made some attempts based on this problem, and finally generated the openapi spec of the CRD, but I also want to generate the openapi spec of the CRD status sub-resource. Do you have any suggestions?
@mbohlool @tamalsaha
Hi,
In github-actions ci, "go test" fails, unless a "mkdir $GOPATH/src/k8s.io" is done "$GOPATH/src" and "git clone" is executed under $GOPATH/src/k8s.io" .
But "go build" works without the above specific path. So I am assuming that some piece of code under $PROJECT_HOME/test needs looking into.
Details here #226
When trying to generate Open API spec for the provided sample testdata, I am getting following API validation error:
$ go run ../../cmd/openapi-gen/openapi-gen.go -i "./testdata/listtype" -o pkg -p generated -O openapi_generated
API rule violation: names_match,./testdata/listtype,AtomicList,Field
API rule violation: names_match,./testdata/listtype,Item,Port
API rule violation: names_match,./testdata/listtype,Item,Protocol
API rule violation: names_match,./testdata/listtype,MapList,Field
API rule violation: names_match,./testdata/listtype,Pod,spec
API rule violation: names_match,./testdata/listtype,SetList,Field
2018/07/23 17:46:45 OpenAPI code generation error: Failed executing generator: some packages had errors:
API rule violations exist
exit status 1
In order to get a working example I used following testdata, which works:
package listtype
// +k8s:openapi-gen=true
type Volume struct {
// Volume's name.
// Must be a DNS_LABEL and unique within the pod.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
Name string json:"name" protobuf:"bytes,1,opt,name=name"
// VolumeSource represents the location and type of the mounted volume.
// If not specified, the Volume is implied to be an EmptyDir.
// This implied behavior is deprecated and will be removed in a future version.
VolumeSource json:",inline" protobuf:"bytes,2,opt,name=volumeSource"
}
This is basically Type Volume copied from k8s.io/kubernetes/staging/src/k8s.io/api/core/v1/types.go
Line "// +k8s:openapi-gen=true" is added at the top as required by kube-openapi
when I run main.go, it throws the following error:
kube-openapi/test/integration/builder/main.go:95:22: unknown field 'ResponseDefinitions' in struct literal of type common.Config
https://github.com/kubernetes/kube-openapi/blob/master/pkg/generators/rules/idl_tag.go#L25
This code needs to make an exception for List types (served as a result of a LIST verb and never a target for a mutating operation).
If:
Metadata v1meta.ListMeta
sibling field ANDThen we should actually require that people NOT include a listType= annotation. (and ideally, suppress emitting the tag in the resulting openapi spec)
Why? Otherwise people have to add an exception for this, and I don't want people doing that for nothingburgers, it's bad karma.
Recently I encountered a bug that aggregator failed because an OpenAPI spec did not have a Path item (null pointer exception). We should make sure all nullable fields are accounted for in the aggregation.
ref:
kube-openapi/pkg/aggregator/aggregator.go
Line 145 in 39a7bf8
๐ just saw the project is still using travis-ci.org for CI, and I have to call out that Travis is going to shut it down on this May 31.
Feature request to allow types to register an Example (to be placed in Schema.Example
). It seems like what is currently done for custom types + formats would work (OpenAPISchemaType()
method registered on type).
I'd propose the method definition to be:
OpenAPISchemaExample() interface{}
The same method would probably work for v3 as well.
Another approach would be to use the WriteSample
and ReadSample
on the restful.Route
, if provided.
Would a PR for this be accepted?
I'd like to use kube-openapi with latest gnostic (0.5.x) but there is an incompatibility between yaml v2 used by kube-openapi and yaml v3 used by gnostic since version 0.5.0: google/gnostic#195
May you please update kube-openapi to use the latest gnostic (0.5.1)?
From @tamalsaha's issue kubernetes/kubernetes#62325 and @mbohlool's suggestion to open an issue in this repo (kubernetes/kubernetes#62325 (comment)),
Currently I generate CRD schema validation using a pipeline like below:
types.go ---(openapi-gen) ---> openapi_generated.go ---(crd-validation)---> crd.yaml
While this works, openapi-gen does not generate spec information for enums . We would like to see this supported.
[1] crd-validation: https://github.com/ant31/crd-validation
The error surfacing in this package should be self evident.
A self-contained system like Kubernetes which imports kube-openapi may use logging module (glog/klog) to do V-style logging. However this package don't have a good reason to use glog/klog, which interferes/makes assumption about logging mechanism used by downstream systems.
ref: #115
/good-first-issue
/help
Initially opened here kubernetes/kubernetes#97503 but I believe this improvement suggestion might be better here? This is about supporting parameters that support a list of values:
The "Protocol" parameter of a ContainerPort needs to be one of 'TCP', 'UDP', or 'SCTP' - as documented here
kubernetes/staging/src/k8s.io/api/core/v1/types.go
Line 1837 in ddf3eb5
// Protocol for port. Must be UDP, TCP, or SCTP.
However this restriction is not explicit in the generated OpenAPI file: https://raw.githubusercontent.com/kubernetes/kubernetes/ddf3eb5a1877338da806c2be15b53f456b6342c9/api/openapi-spec/swagger.json
There are a number of similar parameters which only accept a list of values - that restriction not being part of the generated OpenAPI file - "RestartPolicy" being another one.
This restricts the amount of validation that schema validators (such as Kubeval/Kubeconform) can do - and confuses users who would expect the tool to catch this kind of error.
OpenAPI does support enums though - is this a restriction of the tooling? It would be great to have these as part of the OpenAPI schema! pray
newest [email protected] used [email protected] only.
package "github.com/googleapis/gnostic/openapiv2" and "github.com/googleapis/gnostic/OpenAPIv2" was conflict.
It caused a big dependency problem.
Hi
With the current version of gnostic
we got the following message.
/private/var/tmp/_bazel_a13705/d47ee6d5190331e265fc3deb51db2812/external/bazel_gazelle/internal/go_repository.bzl:184:13: gazelle: gazelle: finding module path for import github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/apis_guru/apis_guru: exit status 1: go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/apis_guru/apis_guru latest
go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/apis_guru latest
go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples latest
go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator latest
go: finding github.com/googleapis/gnostic/plugins latest
can't load package: package github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/apis_guru/apis_guru: unknown import path "github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/apis_guru/apis_guru": cannot find module providing package github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/apis_guru/apis_guru
gazelle: finding module path for import github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/bookstore/bookstore: exit status 1: go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/bookstore/bookstore latest
go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/bookstore latest
go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples latest
go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator latest
go: finding github.com/googleapis/gnostic/plugins latest
can't load package: package github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/bookstore/bookstore: unknown import path "github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/bookstore/bookstore": cannot find module providing package github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/bookstore/bookstore
gazelle: finding module path for import github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/bookstore/bookstore: exit status 1: go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/bookstore/bookstore latest
go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/bookstore latest
go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples latest
go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator latest
go: finding github.com/googleapis/gnostic/plugins latest
can't load package: package github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/bookstore/bookstore: unknown import path "github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/bookstore/bookstore": cannot find module providing package github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/bookstore/bookstore
gazelle: finding module path for import github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/xkcd/xkcd: exit status 1: go: finding github.com/googleapis/gnostic/plugins/gnostic-go-generator/examples/v2.0/xkcd/xkcd latest
Related issue: kubernetes/client-go#636
We have a bunch of cases involving the composition of atomics that we don't yet test.
We need to define and test the behavior of all of them. Creating a grid out all possible combinations might be a good first step.
Here are a few we are aware of:
type Container struct {
Field AtomicMapTyperef
}
// +mapType=atomic
type AtomicMapTyperef map[string]string
type Container struct {
//+mapType=atomic
Field AtomicMapTyperef
}
type AtomicMapTyperef map[string]string
type Container struct {
//+listType=set
SetField []AtomicStruct
}
//+mapType=atomic
type AtomicStruct struct {
StringField string
}
type Container struct {
//+listType=map
//+listMapKey=name
ListField []ListItem
}
//+mapType=atomic
type ListItem struct {
Name string
AtomicStructField AtomicStruct
}
//+mapType=atomic
type AtomicStruct struct {
StringField string
}
type Container struct {
//+listType=map
//+listMapKey=atomicStructField
ListField []ListItem
}
//+mapType=atomic
type ListItem struct {
atomicStructField AtomicStruct
}
//+mapType=atomic
type AtomicStruct struct {
StringField string
}
In the current state, the generated OpenAPI document does not include all response types in operations, and those which are defined do not always include a schema.
For example:
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/io.k8s.api.core.v1.PodList"
}
},
"401": {
"description": "Unauthorized"
}
},
This is a problem because code generators cannot emit validation code or even just type signatures for functions sending requests.
Is there a reason this information is missing ?
We are using k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208
and facing API rule violation: list_type_missing
when the impl is as follows.
// Status of Nodes
Nodes []string `json:"nodes"`
So, we would like to know if is a bug or the expected behaviour? If it is a bug, could you help us by letting us know if it is solved already?
We could solve the validation issue by doing as follows.
// MemcachedStatus defines the observed state of Memcached
// +k8s:openapi-gen=true
type MemcachedStatus struct {
// Nodes are the names of the memcached pods
// +kubebuilder:validation:UniqueItems=true
Nodes PodList `json:"nodes"`
}
// PodList is a list of names of pods
type PodList struct {
Names []string
}
func NewPodList(value []string) PodList {
p := PodList{Names: value}
return p
}
Extra :
Following the others lbs/versions used with as well.
k8s.io/api => k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.0.0-20190409022649-727a075fdec8
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190404173353-6a84e37a896d
k8s.io/client-go => k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
k8s.io/cloud-provider => k8s.io/cloud-provider v0.0.0-20190409023720-1bc0c81fa51d
Hello! I've spent some time hacking on kubeval, and a separate, similar project called kubeconform. Both rely on JSON schemas generated from the Kubernetes Swagger file: https://github.com/instrumenta/kubernetes-json-schema . Rationale described by kubeval is that Go Tooling is not convenient to validate against OpenAPI schemas, whereas there is ample tooling for validating against JSON Schemas.
What is the relation between the pkg/validation/ module and go-swagger?
Can that module validate a Kubernetes manifest, using Kubernetes' Swagger file as schema?
Skipping the OpenAPI > JSON Schema conversion step would make tools like kubeval or kubeconform quite simpler and easier to maintain :) Note that I might be a bit confused with regard to the differences between Swagger, OpenAPI (2.0? 3.0?) and jsonschemas.
Thanks a lot!
I'm trying to use this library to generate the JSON openapi spec for the spark-on-k8s-operator, but I am running into an issue going from the generated models to the spec. Ultimately, I think root issue is a missing +k8s:openapi-gen=false
annotation in the kubernetes apimachinery module. Since those annotations are used by this library, I wanted to verify my proposed change here before submitting a PR there to kubernetes/kubernetes
.
Add the +k8s:openapi-gen=false
annotation to the InternalEvent
type defined in k8s apimachinery. Link to the actual type definition: type InternalEvent. Reference copied here for convenience:
// InternalEvent makes watch.Event versioned
// +protobuf=false
type InternalEvent watch.Event
To simplify the duplication of my issue, I've created the following Dockerfile.
# Initial portion of Dockerfile is copied from here: https://github.com/GoogleCloudPlatform/spark-on-k8s-operator/blob/master/Dockerfile
FROM golang:1.12.5-alpine as builder
ARG DEP_VERSION="0.5.3"
RUN apk add --no-cache bash git
ADD https://github.com/golang/dep/releases/download/v${DEP_VERSION}/dep-linux-amd64 /usr/bin/dep
RUN chmod +x /usr/bin/dep
# Get necessary go sources
RUN go get -u k8s.io/code-generator/cmd/openapi-gen
RUN go get -d github.com/GoogleCloudPlatform/spark-on-k8s-operator
# Get the dependencies and run openapi-gen to get the models
WORKDIR ${GOPATH}/src/github.com/GoogleCloudPlatform/spark-on-k8s-operator
RUN dep ensure
RUN go run ../../../k8s.io/code-generator/cmd/openapi-gen/main.go \
-i github.com/GoogleCloudPlatform/spark-on-k8s-operator/pkg/apis/sparkoperator.k8s.io/v1beta2/,k8s.io/api/core/v1,k8s.io/apimachinery/pkg/api/resource,k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/util/intstr,k8s.io/apimachinery/pkg/runtime \
-p github.com/GoogleCloudPlatform/spark-on-k8s-operator/pkg/apis/sparkoperator.k8s.io/v1beta2/ \
-h hack/custom-boilerplate.go.txt
# Change directories for ease of finding generated code.
WORKDIR pkg/apis/sparkoperator.k8s.io/v1beta2
ENTRYPOINT /bin/bash
After running docker build -t spark-on-k8s-operator:codegen
passing in the above Dockerfile, you can run docker run -it spark-on-k8s-operator:codegen
to get access to the openapi_generated.go
file in the initial directory after getting into the container.
Now that we have a shared set up, you can open openapi_generated.go
and inside, find one of the defined models:
func schema_pkg_apis_meta_v1_InternalEvent(ref common.ReferenceCallback) common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "InternalEvent makes watch.Event versioned",
Type: []string{"object"},
Properties: map[string]spec.Schema{
"Type": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
"Object": {
SchemaProps: spec.SchemaProps{
Description: "Object is:\n * If Type is Added or Modified: the new state of the object.\n * If Type is Deleted: the state of the object immediately before deletion.\n * If Type is Error: *api.Status is recommended; other types may make sense\n depending on context.",
Ref: ref("k8s.io/apimachinery/pkg/runtime.Object"),
},
},
},
Required: []string{"Type", "Object"},
},
},
Dependencies: []string{
"k8s.io/apimachinery/pkg/runtime.Object"},
}
}
It is problematic that the model specifies k8s.io/apimachinery/pkg/runtime.Object
as a dependency because runtime.Object is not annotated to be a part of the output of running openapi-gen. Because this dependency isn't defined within the generated output, I get the following error when I call the k8s.io/kube-openapi/pkg/builder.BuildOpenAPIDefinitionsForResources
method (defined in this project):
2019/09/20 12:55:31 ERROR: cannot find model definition for k8s.io/apimachinery/pkg/runtime.Object. If you added a new type, you may need to add +k8s:openapi-gen=true to the package or type and run code-gen again
exit status 1
I was able to get past this issue by going into the vendored file /go/src/github.com/GoogleCloudPlatform/spark-on-k8s-operator/vendor/k8s.io/apimachinery/pkg/apis/meta/v1/watch.go
, adding the proposed annotation, and then re-running the openapi-gen code. That change successfully removes the reference to InternalEvent
in the generated output, which removes the dependency on runtime.Object
, and then the subsequent call to BuildOpenAPIDefinitionsForResources
can complete successfully.
It seems to me that the most reasonable solution is to remove the InternalEvent
from the openapi-gen output considering that this type is excluded from protobuf generation, that it's name implies it'd be unnecessary in a client, and that the runtime.Object
is not new and is not annotated to be included in the openapi-gen output. However, I have not used this library before, and I am new to kubernetes code generation. It's possible that I'm not using this project correctly. Does it make sense to submit a PR to the kubernetes
project to add the annotation? Any help or direction here is greatly appreciated. Thanks!
This issue is moved from kubectl repo.
Since #10 is moving parsing code for openapi from the main repo to https://github.com/kubernetes/kube-openapi/, we need to verify that the full swagger openapi file can still be parsed.
This is just a reminder that we need to do that.
In other word, we need to add a test in the main repo that verifies that the parsing code can parse the openapi swagger.
I upgraded my dependencies for my operator using go get -u all
but now I receive the following error:
../../../../.go/pkg/mod/k8s.io/[email protected]/pkg/util/proto/document.go:24:2: case-insensitive import collision: "github.com/googleapis/gnostic/openapiv2" and "github.com/googleapis/gnostic/OpenAPIv2"
go.mod:
module github.com/...
go 1.14
require (
github.com/Azure/go-autorest/autorest v0.11.10 // indirect
github.com/Azure/go-autorest/autorest/to v0.4.0
github.com/evanphx/json-patch v4.9.0+incompatible // indirect
github.com/go-logr/logr v0.2.1 // indirect
github.com/google/go-cmp v0.5.2 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.1.2 // indirect
github.com/googleapis/gnostic v0.5.1 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/imdario/mergo v0.3.11 // indirect
github.com/json-iterator/go v1.1.10 // indirect
github.com/kr/pretty v0.2.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/nxadm/tail v1.4.5 // indirect
github.com/onsi/ginkgo v1.14.1 // indirect
github.com/onsi/gomega v1.10.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/stretchr/testify v1.6.1 // indirect
golang.org/x/net v0.0.0-20201009032441-dbdefad45b89 // indirect
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 // indirect
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634 // indirect
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e // indirect
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
k8s.io/api v0.19.2
k8s.io/apimachinery v0.19.2
k8s.io/client-go v0.0.0-20200214082307-e38a84523341
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.3.0 // indirect
k8s.io/kube-openapi v0.0.0-20200923155610-8b5066479488 // indirect
k8s.io/utils v0.0.0-20201005171033-6301aaf42dc7 // indirect
sigs.k8s.io/structured-merge-diff/v3 v3.0.0 // indirect
)
replace (
golang.org/x/sys => golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // pinned to release-branch.go1.13
golang.org/x/tools => golang.org/x/tools v0.0.0-20190821162956-65e3620a7ae7 // pinned to release-branch.go1.13
k8s.io/api => k8s.io/api v0.0.0-20200214081623-ecbd4af0fc33
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20200214081019-7490b3ed6e92
k8s.io/client-go => k8s.io/client-go v0.0.0-20200214082307-e38a84523341
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20200214080538-dc8f3adce97c
)
json-iterator just cut a new release to address incompatibilities with the current go development version (will be go1.18)
xref:
In my project, I will use the following command to generate deepcopy.
// Generate deepcopy for apis
//go:generate go run ../../vendor/k8s.io/code-generator/cmd/deepcopy-gen/main.go -O zz_generated.deepcopy -i ./... -h ../../hack/boilerplate.go.txt
// Generate openapi for apis
//go:generate go run ../../vendor/k8s.io/kube-openapi/cmd/openapi-gen/openapi-gen.go -O openapi_generated -i ./... -h ../../hack/boilerplate.go.txt
but if got error
go generate ./pkg/... ./cmd/...
2019/01/11 15:07:48 Arguments validation error: output package cannot be empty
exit status 1
pkg/apis/apis.go:20: running "go": exit status 1
make: *** [generate] Error 1
So I have to write a separate generate command for each package, I think it is necessary to have openapi-gen and deepcopy-gen have similar behavior, which can save a lot of unnecessary code.
//go:generate go run ../../vendor/k8s.io/kube-openapi/cmd/openapi-gen/openapi-gen.go -O openapi_generated -i ./devops/v1alpha2 -p github.com/runzexia/kubesphere-crd-sample/pkg/apis/devops/v1alpha2 -h ../../hack/boilerplate.go.txt
From @tamalsaha's issue kubernetes/kubernetes#62329 and @mbohlool's comment to create an issue in this repo (kubernetes/kubernetes#62329 (comment)),
Currently openapi-gen generated spec for intstr.IntOrString only allows string types. https://github.com/kubernetes/apimachinery/blob/5d4f0da8e5fde7cbadf8ab3ce5cfb76f86dd854e/pkg/util/intstr/intstr.go#L124 . This is incorrect and causes problem when used to generate CRD validation schema. I generate CRD schema validation using a pipeline like below:
types.go ---(openapi-gen) ---> openapi_generated.go ---(crd-validation)---> crd.yaml
One fix suggested by @sttts is to use schema like
{
"anyOf": [
{ "type": "string" },
{ "type": "number" }
]
}
But anyOf is not defined in v2 spec so can't be be returned from IntOrString.OpenAPIDefinition() method. But when CRD schema is generated one can update the auto generated schema for IntOrStr to fix this issue. For example: https://github.com/appscode/kutil/pull/133/files
[1] crd-validation: https://github.com/ant31/crd-validation
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.