diff --git a/CHANGELOG.md b/CHANGELOG.md index 79663b6d39f..b0dc48153b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Support for vars in top level ansible watches. ([#2147](https://github.com/operator-framework/operator-sdk/pull/2147)) - Support for `"ansible.operator-sdk/verbosity"` annotation on Custom Resources watched by Ansible based operators to override verbosity on an individual resource. ([#2102](https://github.com/operator-framework/operator-sdk/pull/2102)) - Support for relative helm chart paths in the Helm operator's watches.yaml file. ([#2287](https://github.com/operator-framework/operator-sdk/pull/2287)) +- New `operator-sdk generate crds` subcommand, which generates CRDs from Go types. ([#2276](https://github.com/operator-framework/operator-sdk/pull/2276)) ### Changed - Upgrade minimal Ansible version in the init projects from `2.4` to `2.6`. ([#2107](https://github.com/operator-framework/operator-sdk/pull/2107)) @@ -17,6 +18,7 @@ - Replace Role verb `"*"` with list of verb strings in generated files so the Role is compatible with OpenShift and Kubernetes. ([#2175](https://github.com/operator-framework/operator-sdk/pull/2175)) ### Deprecated +- Deprecated the `operator-sdk generate openapi` command. CRD generation is still supported with `operator-sdk generate crds`. It is now recommended to use [openapi-gen](https://github.com/kubernetes/kube-openapi/tree/master/cmd/openapi-gen) directly for OpenAPI code generation. The `generate openapi` subcommand will be removed in a future release. ([#2276](https://github.com/operator-framework/operator-sdk/pull/2276)) ### Removed diff --git a/cmd/operator-sdk/add/api.go b/cmd/operator-sdk/add/api.go index fcbd8ce109e..b4e4b20af8f 100644 --- a/cmd/operator-sdk/add/api.go +++ b/cmd/operator-sdk/add/api.go @@ -40,17 +40,17 @@ func newAddApiCmd() *cobra.Command { apiCmd := &cobra.Command{ Use: "api", Short: "Adds a new api definition under pkg/apis", - Long: `operator-sdk add api --kind= --api-version= creates the -api definition for a new custom resource under pkg/apis. This command must be -run from the project root directory. If the api already exists at -pkg/apis// then the command will not overwrite and return an -error. + Long: `operator-sdk add api --kind= --api-version= creates +the api definition for a new custom resource under pkg/apis. This command +must be run from the project root directory. If the api already exists at +pkg/apis// then the command will not overwrite and return +an error. -By default, this command runs Kubernetes deepcopy and OpenAPI V3 generators on +By default, this command runs Kubernetes deepcopy and CRD generators on tagged types in all paths under pkg/apis. Go code is generated under -pkg/apis///zz_generated.{deepcopy,openapi}.go. CRD's are -generated, or updated if they exist for a particular group + version + kind, -under deploy/crds/__crd.yaml; OpenAPI V3 validation YAML +pkg/apis///zz_generated.deepcopy.go. CRD's are generated, +or updated if they exist for a particular group + version + kind, under +deploy/crds/__crd.yaml; OpenAPI V3 validation YAML is generated as a 'validation' object. Generation can be disabled with the --skip-generation flag. @@ -67,7 +67,6 @@ Example: ├── register.go ├── appservice_types.go ├── zz_generated.deepcopy.go - ├── zz_generated.openapi.go $ tree deploy/crds ├── deploy/crds/app.example.com_v1alpha1_appservice_cr.yaml ├── deploy/crds/app.example.com_appservices_crd.yaml @@ -143,7 +142,7 @@ func apiRun(cmd *cobra.Command, args []string) error { } // Generate a validation spec for the new CRD. - if err := genutil.OpenAPIGen(); err != nil { + if err := genutil.CRDGen(); err != nil { return err } } diff --git a/cmd/operator-sdk/generate/cmd.go b/cmd/operator-sdk/generate/cmd.go index d574ecc7c99..b8bea95e55c 100644 --- a/cmd/operator-sdk/generate/cmd.go +++ b/cmd/operator-sdk/generate/cmd.go @@ -25,6 +25,7 @@ func NewCmd() *cobra.Command { Long: `The operator-sdk generate command invokes specific generator to generate code as needed.`, } cmd.AddCommand(newGenerateK8SCmd()) + cmd.AddCommand(newGenerateCRDsCmd()) cmd.AddCommand(newGenerateOpenAPICmd()) return cmd } diff --git a/cmd/operator-sdk/generate/crds.go b/cmd/operator-sdk/generate/crds.go new file mode 100644 index 00000000000..901d2fc127b --- /dev/null +++ b/cmd/operator-sdk/generate/crds.go @@ -0,0 +1,49 @@ +// Copyright 2019 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package generate + +import ( + "fmt" + + "github.com/operator-framework/operator-sdk/cmd/operator-sdk/internal/genutil" + "github.com/spf13/cobra" +) + +func newGenerateCRDsCmd() *cobra.Command { + return &cobra.Command{ + Use: "crds", + Short: "Generates CRDs for API's", + Long: `generate crds generates CRDs or updates them if they exist, +under deploy/crds/__crd.yaml; OpenAPI +V3 validation YAML is generated as a 'validation' object. + +Example: + + $ operator-sdk generate crds + $ tree deploy/crds + ├── deploy/crds/app.example.com_v1alpha1_appservice_cr.yaml + ├── deploy/crds/app.example.com_appservices_crd.yaml +`, + RunE: crdsFunc, + } +} + +func crdsFunc(cmd *cobra.Command, args []string) error { + if len(args) != 0 { + return fmt.Errorf("command %s doesn't accept any arguments", cmd.CommandPath()) + } + + return genutil.CRDGen() +} diff --git a/cmd/operator-sdk/generate/openapi.go b/cmd/operator-sdk/generate/openapi.go index b6fe7b4f7bb..44fab37ef04 100644 --- a/cmd/operator-sdk/generate/openapi.go +++ b/cmd/operator-sdk/generate/openapi.go @@ -23,8 +23,9 @@ import ( func newGenerateOpenAPICmd() *cobra.Command { return &cobra.Command{ - Use: "openapi", - Short: "Generates OpenAPI specs for API's", + Hidden: true, + Use: "openapi", + Short: "Generates OpenAPI specs for API's", Long: `generate openapi generates OpenAPI validation specs in Go from tagged types in all pkg/apis// directories. Go code is generated under pkg/apis///zz_generated.openapi.go. CRD's are generated, or @@ -48,10 +49,34 @@ Example: } } +const deprecationTemplate = "\033[1;36m%s\033[0m" + func openAPIFunc(cmd *cobra.Command, args []string) error { + fmt.Printf(deprecationTemplate, `[Deprecation notice] The 'operator-sdk generate openapi' command is deprecated! + + - To generate CRDs, use 'operator-sdk generate crds'. + - To generate Go OpenAPI code, use 'openapi-gen'. For example: + + # Build the latest openapi-gen from source + which ./bin/openapi-gen > /dev/null || go build -o ./bin/openapi-gen k8s.io/kube-openapi/cmd/openapi-gen + + # Run openapi-gen for each of your API group/version packages + ./bin/openapi-gen --logtostderr=true -o "" -i ./pkg/apis// -O zz_generated.openapi -p ./pkg/apis// -h ./hack/boilerplate.go.txt -r "-" + +`) + if len(args) != 0 { return fmt.Errorf("command %s doesn't accept any arguments", cmd.CommandPath()) } - return genutil.OpenAPIGen() + fs := []func() error{ + genutil.OpenAPIGen, + genutil.CRDGen, + } + for _, f := range fs { + if err := f(); err != nil { + return err + } + } + return nil } diff --git a/cmd/operator-sdk/internal/genutil/crds.go b/cmd/operator-sdk/internal/genutil/crds.go new file mode 100644 index 00000000000..fad4bea8a8b --- /dev/null +++ b/cmd/operator-sdk/internal/genutil/crds.go @@ -0,0 +1,81 @@ +// Copyright 2018 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package genutil + +import ( + "fmt" + "path/filepath" + "strings" + + "github.com/operator-framework/operator-sdk/internal/scaffold" + "github.com/operator-framework/operator-sdk/internal/scaffold/input" + "github.com/operator-framework/operator-sdk/internal/util/k8sutil" + "github.com/operator-framework/operator-sdk/internal/util/projutil" + + log "github.com/sirupsen/logrus" +) + +// CRDGen generates CRDs for all APIs in pkg/apis. +func CRDGen() error { + projutil.MustInProjectRoot() + + absProjectPath := projutil.MustGetwd() + repoPkg := projutil.GetGoPkg() + + gvMap, err := k8sutil.ParseGroupSubpackages(scaffold.ApisDir) + if err != nil { + return fmt.Errorf("failed to parse group versions: (%v)", err) + } + gvb := &strings.Builder{} + for g, vs := range gvMap { + gvb.WriteString(fmt.Sprintf("%s:%v, ", g, vs)) + } + + log.Infof("Running CRD generation for Custom Resource group versions: [%v]\n", gvb.String()) + + s := &scaffold.Scaffold{} + cfg := &input.Config{ + Repo: repoPkg, + AbsProjectPath: absProjectPath, + ProjectName: filepath.Base(absProjectPath), + } + crds, err := k8sutil.GetCRDs(scaffold.CRDsDir) + if err != nil { + return err + } + for _, crd := range crds { + g, v, k := crd.Spec.Group, crd.Spec.Version, crd.Spec.Names.Kind + if v == "" { + if len(crd.Spec.Versions) != 0 { + v = crd.Spec.Versions[0].Name + } else { + return fmt.Errorf("crd of group %s kind %s has no version", g, k) + } + } + r, err := scaffold.NewResource(g+"/"+v, k) + if err != nil { + return err + } + err = s.Execute(cfg, + &scaffold.CRD{Resource: r, IsOperatorGo: projutil.IsOperatorGo()}, + ) + if err != nil { + return err + } + } + + log.Info("CRD generation complete.") + return nil +} diff --git a/cmd/operator-sdk/internal/genutil/openapi.go b/cmd/operator-sdk/internal/genutil/openapi.go index 989583adb38..57006a9e890 100644 --- a/cmd/operator-sdk/internal/genutil/openapi.go +++ b/cmd/operator-sdk/internal/genutil/openapi.go @@ -22,7 +22,6 @@ import ( "strings" "github.com/operator-framework/operator-sdk/internal/scaffold" - "github.com/operator-framework/operator-sdk/internal/scaffold/input" "github.com/operator-framework/operator-sdk/internal/util/k8sutil" "github.com/operator-framework/operator-sdk/internal/util/projutil" @@ -36,7 +35,6 @@ import ( func OpenAPIGen() error { projutil.MustInProjectRoot() - absProjectPath := projutil.MustGetwd() repoPkg := projutil.GetGoPkg() gvMap, err := k8sutil.ParseGroupSubpackages(scaffold.ApisDir) @@ -57,37 +55,6 @@ func OpenAPIGen() error { return err } - s := &scaffold.Scaffold{} - cfg := &input.Config{ - Repo: repoPkg, - AbsProjectPath: absProjectPath, - ProjectName: filepath.Base(absProjectPath), - } - crds, err := k8sutil.GetCRDs(scaffold.CRDsDir) - if err != nil { - return err - } - for _, crd := range crds { - g, v, k := crd.Spec.Group, crd.Spec.Version, crd.Spec.Names.Kind - if v == "" { - if len(crd.Spec.Versions) != 0 { - v = crd.Spec.Versions[0].Name - } else { - return fmt.Errorf("crd of group %s kind %s has no version", g, k) - } - } - r, err := scaffold.NewResource(g+"/"+v, k) - if err != nil { - return err - } - err = s.Execute(cfg, - &scaffold.CRD{Resource: r, IsOperatorGo: projutil.IsOperatorGo()}, - ) - if err != nil { - return err - } - } - log.Info("Code-generation complete.") return nil } diff --git a/doc/cli/operator-sdk_add_api.md b/doc/cli/operator-sdk_add_api.md index 09ec1cbf185..bc68d84d3f4 100644 --- a/doc/cli/operator-sdk_add_api.md +++ b/doc/cli/operator-sdk_add_api.md @@ -4,17 +4,17 @@ Adds a new api definition under pkg/apis ### Synopsis -operator-sdk add api --kind= --api-version= creates the -api definition for a new custom resource under pkg/apis. This command must be -run from the project root directory. If the api already exists at -pkg/apis// then the command will not overwrite and return an -error. +operator-sdk add api --kind= --api-version= creates +the api definition for a new custom resource under pkg/apis. This command +must be run from the project root directory. If the api already exists at +pkg/apis// then the command will not overwrite and return +an error. -By default, this command runs Kubernetes deepcopy and OpenAPI V3 generators on +By default, this command runs Kubernetes deepcopy and CRD generators on tagged types in all paths under pkg/apis. Go code is generated under -pkg/apis///zz_generated.{deepcopy,openapi}.go. CRD's are -generated, or updated if they exist for a particular group + version + kind, -under deploy/crds/__crd.yaml; OpenAPI V3 validation YAML +pkg/apis///zz_generated.deepcopy.go. CRD's are generated, +or updated if they exist for a particular group + version + kind, under +deploy/crds/__crd.yaml; OpenAPI V3 validation YAML is generated as a 'validation' object. Generation can be disabled with the --skip-generation flag. @@ -31,7 +31,6 @@ Example: ├── register.go ├── appservice_types.go ├── zz_generated.deepcopy.go - ├── zz_generated.openapi.go $ tree deploy/crds ├── deploy/crds/app.example.com_v1alpha1_appservice_cr.yaml ├── deploy/crds/app.example.com_appservices_crd.yaml diff --git a/doc/cli/operator-sdk_generate.md b/doc/cli/operator-sdk_generate.md index cf1bef810e2..1f2c7a8228d 100644 --- a/doc/cli/operator-sdk_generate.md +++ b/doc/cli/operator-sdk_generate.md @@ -15,6 +15,6 @@ The operator-sdk generate command invokes specific generator to generate code as ### SEE ALSO * [operator-sdk](operator-sdk.md) - An SDK for building operators with ease +* [operator-sdk generate crds](operator-sdk_generate_crds.md) - Generates CRDs for API's * [operator-sdk generate k8s](operator-sdk_generate_k8s.md) - Generates Kubernetes code for custom resource -* [operator-sdk generate openapi](operator-sdk_generate_openapi.md) - Generates OpenAPI specs for API's diff --git a/doc/cli/operator-sdk_generate_crds.md b/doc/cli/operator-sdk_generate_crds.md new file mode 100644 index 00000000000..85005d70227 --- /dev/null +++ b/doc/cli/operator-sdk_generate_crds.md @@ -0,0 +1,32 @@ +## operator-sdk generate crds + +Generates CRDs for API's + +### Synopsis + +generate crds generates CRDs or updates them if they exist, +under deploy/crds/__crd.yaml; OpenAPI +V3 validation YAML is generated as a 'validation' object. + +Example: + + $ operator-sdk generate crds + $ tree deploy/crds + ├── deploy/crds/app.example.com_v1alpha1_appservice_cr.yaml + ├── deploy/crds/app.example.com_appservices_crd.yaml + + +``` +operator-sdk generate crds [flags] +``` + +### Options + +``` + -h, --help help for crds +``` + +### SEE ALSO + +* [operator-sdk generate](operator-sdk_generate.md) - Invokes specific generator + diff --git a/doc/cli/operator-sdk_generate_openapi.md b/doc/cli/operator-sdk_generate_openapi.md deleted file mode 100644 index 2f6354a3f70..00000000000 --- a/doc/cli/operator-sdk_generate_openapi.md +++ /dev/null @@ -1,40 +0,0 @@ -## operator-sdk generate openapi - -Generates OpenAPI specs for API's - -### Synopsis - -generate openapi generates OpenAPI validation specs in Go from tagged types -in all pkg/apis// directories. Go code is generated under -pkg/apis///zz_generated.openapi.go. CRD's are generated, or -updated if they exist for a particular group + version + kind, under -deploy/crds/__crd.yaml; OpenAPI V3 validation YAML -is generated as a 'validation' object. - -Example: - - $ operator-sdk generate openapi - $ tree pkg/apis - pkg/apis/ - └── app - └── v1alpha1 - ├── zz_generated.openapi.go - $ tree deploy/crds - ├── deploy/crds/app.example.com_v1alpha1_appservice_cr.yaml - ├── deploy/crds/app.example.com_appservices_crd.yaml - - -``` -operator-sdk generate openapi [flags] -``` - -### Options - -``` - -h, --help help for openapi -``` - -### SEE ALSO - -* [operator-sdk generate](operator-sdk_generate.md) - Invokes specific generator - diff --git a/doc/operator-scope.md b/doc/operator-scope.md index ccdecedc7f3..646646f43be 100644 --- a/doc/operator-scope.md +++ b/doc/operator-scope.md @@ -131,7 +131,6 @@ This scope is ideal for the cases where an instance(CR) of some Kind(CRD) will b // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Memcached is the Schema for the memcacheds API - // +k8s:openapi-gen=true // +kubebuilder:resource:path=memcacheds,scope=Cluster type Memcached struct { metav1.TypeMeta `json:",inline"` @@ -141,7 +140,7 @@ This scope is ideal for the cases where an instance(CR) of some Kind(CRD) will b Status MemcachedStatus `json:"status,omitempty"` } ``` -- Execute the command `operator-sdk generate openapi`, then you should be able to check that the CRD was updated with the cluster scope as in the following example: +- Execute the command `operator-sdk generate crds`, then you should be able to check that the CRD was updated with the cluster scope as in the following example: * `deploy/crds/cache.example.com_memcacheds_crd.yaml` ```YAML diff --git a/doc/sdk-cli-reference.md b/doc/sdk-cli-reference.md index d3a3acfe2a9..3bdca9aa648 100644 --- a/doc/sdk-cli-reference.md +++ b/doc/sdk-cli-reference.md @@ -134,6 +134,21 @@ pkg/apis/app/v1alpha1/ ### openapi +> **DEPRECATED** +> +> The `operator-sdk generate openapi` command is deprecated +> - To generate CRDs, use 'operator-sdk generate crds'. +> - To generate Go OpenAPI code, use 'openapi-gen'. For example: +> +> ```console +> # Build the latest openapi-gen from source +> which ./bin/openapi-gen > /dev/null || go build -o ./bin/openapi-gen k8s.io/kube-openapi/cmd/openapi-gen +> +> # Run openapi-gen for each of your API group/version packages +> ./bin/openapi-gen --logtostderr=true -o "" -i ./pkg/apis// -O zz_generated.openapi -p ./pkg/apis// -h ./hack/boilerplate.go.txt -r "-" +> ``` + + Runs the [kube-openapi][openapi-code-generator] OpenAPIv3 code generator for all Custom Resource Definition (CRD) API tagged fields under `pkg/apis/...`. **Note**: This command must be run every time a tagged API struct or struct field for a custom resource type is updated. @@ -145,7 +160,7 @@ $ tree pkg/apis/app/v1alpha1/ pkg/apis/app/v1alpha1/ ├── appservice_types.go ├── doc.go -├── register.go +└── register.go $ operator-sdk generate openapi INFO[0000] Running OpenAPI code-generation for Custom Resource group versions: [app:[v1alpha1], ] @@ -160,6 +175,31 @@ pkg/apis/app/v1alpha1/ └── zz_generated.openapi.go ``` +### crds + +Runs CRD generation (based on controller-tools) for APIs under `pkg/apis/...`. + +**Note**: This command must be run every time a tagged API struct or struct field for a custom resource type is updated. + +#### Example + +```console +$ tree pkg/apis/app/v1alpha1/ +pkg/apis/app/v1alpha1/ +├── appservice_types.go +├── doc.go +└── register.go + +$ operator-sdk generate crds +INFO[0000] Running CRD generation for Custom Resource group versions: [app:[v1alpha1], ] +INFO[0001] Created deploy/crds/app.example.com_appservices_crd.yaml +INFO[0001] CRD generation complete. + +$ tree deploy/crds/ +deploy/crds +└── app.example.com_appservices_crd.yaml +``` + ## olm-catalog Parent command for all OLM Catalog related commands. diff --git a/doc/user-guide.md b/doc/user-guide.md index e69089e05c4..6552d35228e 100644 --- a/doc/user-guide.md +++ b/doc/user-guide.md @@ -86,13 +86,10 @@ type MemcachedSpec struct { } type MemcachedStatus struct { // Nodes are the names of the memcached pods - // +listType=set Nodes []string `json:"nodes"` } ``` -**NOTE:** Comment directives, such as +listType=set, are necessary in certain situations to avoid API rule violations when generating OpenAPI files. See https://godoc.org/k8s.io/kube-openapi/pkg/idl to learn more. - After modifying the `*_types.go` file always run the following command to update the generated code for that resource type: ```sh @@ -101,7 +98,7 @@ $ operator-sdk generate k8s ### OpenAPI validation -OpenAPIv3 schemas are added to CRD manifests in the `spec.validation` block when the manifests are generated. This validation block allows Kubernetes to validate the properties in a Memcached Custom Resource when it is created or updated. Additionally a `pkg/apis///zz_generated.openapi.go` file is generated containing the Go representation of this validation block if the `+k8s:openapi-gen=true` annotation is present above the kind type declaration (present by default). This auto-generated code is your Go kind type's OpenAPI model, from which you can create a full OpenAPI spec and generate a client. Check out [this issue comment][openapi-details] for steps on how to do so. +OpenAPIv3 schemas are added to CRD manifests in the `spec.validation` block when the manifests are generated. This validation block allows Kubernetes to validate the properties in a Memcached Custom Resource when it is created or updated. Markers (annotations) are available to configure validations for your API. These markers will always have a `+kubebuilder:validation` prefix. For example, adding an enum type specification can be done by adding the following marker: @@ -112,14 +109,12 @@ type Alias string Usage of markers in API code is discussed in the kubebuilder [CRD generation][generating-crd] and [marker][markers] documentation. A full list of OpenAPIv3 validation markers can be found [here][crd-markers]. -To update the OpenAPI validation section in the CRD `deploy/crds/cache.example.com_memcacheds_crd.yaml`, run the following command: +To update the CRD `deploy/crds/cache.example.com_memcacheds_crd.yaml`, run the following command: ```console -$ operator-sdk generate openapi +$ operator-sdk generate crds ``` -**Note:** You may see errors like "API rule violation" when running the above command. For information on these errors see the [API rules][api-rules] documentation - An example of the generated YAML is as follows: ```YAML @@ -136,7 +131,6 @@ spec: To learn more about OpenAPI v3.0 validation schemas in Custom Resource Definitions, refer to the [Kubernetes Documentation][doc-validation-schema]. -[openapi-details]: https://github.com/kubernetes/kube-openapi/issues/13#issuecomment-337719430 [doc-validation-schema]: https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#specifying-a-structural-schema [generating-crd]: https://book.kubebuilder.io/reference/generating-crd.html [markers]: https://book.kubebuilder.io/reference/markers.html diff --git a/doc/user/migrating-existing-apis.md b/doc/user/migrating-existing-apis.md index bd6e37eaa11..3800cf86cac 100644 --- a/doc/user/migrating-existing-apis.md +++ b/doc/user/migrating-existing-apis.md @@ -25,7 +25,6 @@ pkg/apis/ ├── register.go ├── shared.go ├── zz_generated.deepcopy.go - ├── zz_generated.openapi.go ``` Relevant files: @@ -71,13 +70,11 @@ pkg/apis/ | ├── register.go | ├── shared.go | ├── zz_generated.deepcopy.go - | ├── zz_generated.openapi.go └── v2 # new version dir with source files for v2 ├── catalogsourceconfig_types.go ├── doc.go ├── register.go ├── zz_generated.deepcopy.go - ├── zz_generated.openapi.go ``` In addition to creating a new API version, the command creates an `addtoscheme_operators_v2.go` file that exposes an `AddToScheme()` function for registering `v2.CatalogSourceConfig` and `v2.CatalogSourceConfigList`. @@ -198,12 +195,12 @@ You can now run `operator-sdk generate k8s` to generate deepcopy code for the mi ### Updating CustomResourceDefinition manifests and generating OpenAPI code -Now that we've migrated all Go types to their destination packages, we must update the corresponding CustomResourceDefinition (CRD) manifests in `deploy/crds` and generate [OpenAPI][openapi-gen] validation source. +Now that we've migrated all Go types to their destination packages, we must update the corresponding CustomResourceDefinition (CRD) manifests in `deploy/crds`. Doing so can be as simple as running the following command: ```console -$ operator-sdk generate openapi +$ operator-sdk generate crds ``` This command will automatically update all CRD manifests. @@ -216,7 +213,7 @@ Kubernetes 1.11+ supports CRD [`spec.versions`][crd-versions] and `spec.version` **Note**: `` is the full group name of your CRD while `` is the last subdomain of ``, ex. `foo.bar.com` vs `foo`. `` is the plural lower-case of CRD `Kind` specified at `spec.names.plural`. -**Note:** If your operator does not have custom data manually added to its CRD's, you can skip to the [following section](#golang-api-migrations-types-and-commonalities); `operator-sdk generate openapi` will handle CRD updates in that case. +**Note:** If your operator does not have custom data manually added to its CRD's, you can skip to the [following section](#golang-api-migrations-types-and-commonalities); `operator-sdk generate crds` will handle CRD updates in that case. Upgrading from `spec.version` to `spec.versions` will be demonstrated using the following CRD manifest example: @@ -388,7 +385,7 @@ Each case is different; one may require many more changes than others. However, 1. Copying code from one Go package to another, ex. from `v1` to `v2` and `shared`. 1. Changing import paths in project Go source files to those of new packages. 1. Updating CRD manifests. - - In many cases, having sufficient [code annotations][kubebuilder-api-annotations] and running `operator-sdk generate openapi` will be enough. + - In many cases, having sufficient [code annotations][kubebuilder-api-annotations] and running `operator-sdk generate crds` will be enough. The Go toolchain can be your friend here too. Running `go vet ./...` can tell you what import paths require changing and what type instantiations are using fields incorrectly. @@ -403,7 +400,6 @@ TODO [k8s-versioning]:https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-versioning [deepcopy-gen]:https://godoc.org/k8s.io/gengo/examples/deepcopy-gen [client-gen]:https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/generating-clientset.md -[openapi-gen]:https://github.com/kubernetes/kube-openapi [controller-tools]:https://github.com/kubernetes-sigs/controller-tools [crd-versions]:https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning/ [crd-conv]:https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning/#webhook-conversion diff --git a/hack/generate/gen-test-framework.sh b/hack/generate/gen-test-framework.sh index 37ffc1090b5..c35cdb0eccd 100755 --- a/hack/generate/gen-test-framework.sh +++ b/hack/generate/gen-test-framework.sh @@ -21,7 +21,4 @@ go mod tidy # Run gen commands ../../build/operator-sdk generate k8s -# TODO(camilamacedo86): remove this when the openapi gen be set to false and it no longer is generated -# The following file is gen by openapi but it has not been committed in order to allow we clone and call the test locally in any path. -trap_add 'rm pkg/apis/cache/v1alpha1/zz_generated.openapi.go' EXIT -../../build/operator-sdk generate openapi +../../build/operator-sdk generate crds diff --git a/hack/tests/scaffolding/scaffold-memcached.go b/hack/tests/scaffolding/scaffold-memcached.go index f587316b80d..0eaa59d5f8a 100644 --- a/hack/tests/scaffolding/scaffold-memcached.go +++ b/hack/tests/scaffolding/scaffold-memcached.go @@ -148,8 +148,7 @@ func main() { for lineNum, line := range memcachedTypesFileLines { if strings.Contains(string(line), "type MemcachedStatus struct {") { - memcachedTypesFileLinesIntermediate := append(memcachedTypesFileLines[:lineNum+1], []byte("\t// +listType=set")) - memcachedTypesFileLinesIntermediate = append(memcachedTypesFileLinesIntermediate, []byte("\tNodes []string `json:\"nodes\"`")) + memcachedTypesFileLinesIntermediate := append(memcachedTypesFileLines[:lineNum+1], []byte("\tNodes []string `json:\"nodes\"`")) memcachedTypesFileLines = append(memcachedTypesFileLinesIntermediate, memcachedTypesFileLines[lineNum+3:]...) break } @@ -169,21 +168,12 @@ func main() { log.Fatalf("Error: %v\nCommand Output: %s\n", err, string(cmdOut)) } - log.Print("Generating openapi") - cmdOut, err = exec.Command("operator-sdk", "generate", "openapi").CombinedOutput() + log.Print("Generating CRDs") + cmdOut, err = exec.Command("operator-sdk", "generate", "crds").CombinedOutput() if err != nil { log.Fatalf("Error: %v\nCommand Output: %s\n", err, string(cmdOut)) } - // TODO(camilamacedo86) Move this test to a unit test in - // `cmd/operator-sdk/internal/genutil/`. Unit tests are - // faster and are run more often during development, so it - // would be an improvement to implement this test there. - log.Print("Checking API rule violations") - if strings.Contains(string(cmdOut), "API rule violation") { - log.Fatalf("Error: %v\nCommand Output: %s\n", "API rule violations :", string(cmdOut)) - } - log.Print("Pulling new dependencies with go mod") cmdOut, err = exec.Command("go", "build", "./...").CombinedOutput() if err != nil { diff --git a/internal/scaffold/types.go b/internal/scaffold/types.go index 7ce675a0822..e6b0b325c64 100644 --- a/internal/scaffold/types.go +++ b/internal/scaffold/types.go @@ -52,7 +52,6 @@ import ( // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. // {{.Resource.Kind}}Spec defines the desired state of {{.Resource.Kind}} -// +k8s:openapi-gen=true type {{.Resource.Kind}}Spec struct { // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster // Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file @@ -60,7 +59,6 @@ type {{.Resource.Kind}}Spec struct { } // {{.Resource.Kind}}Status defines the observed state of {{.Resource.Kind}} -// +k8s:openapi-gen=true type {{.Resource.Kind}}Status struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster // Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file @@ -70,7 +68,6 @@ type {{.Resource.Kind}}Status struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // {{.Resource.Kind}} is the Schema for the {{ .Resource.Resource }} API -// +k8s:openapi-gen=true // +kubebuilder:subresource:status // +kubebuilder:resource:path={{.Resource.Resource}},scope=Namespaced type {{.Resource.Kind}} struct { diff --git a/internal/scaffold/types_test.go b/internal/scaffold/types_test.go index b1b30aa26f4..daf54f4e2c5 100644 --- a/internal/scaffold/types_test.go +++ b/internal/scaffold/types_test.go @@ -47,7 +47,6 @@ import ( // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. // AppServiceSpec defines the desired state of AppService -// +k8s:openapi-gen=true type AppServiceSpec struct { // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster // Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file @@ -55,7 +54,6 @@ type AppServiceSpec struct { } // AppServiceStatus defines the observed state of AppService -// +k8s:openapi-gen=true type AppServiceStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster // Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file @@ -65,7 +63,6 @@ type AppServiceStatus struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // AppService is the Schema for the appservices API -// +k8s:openapi-gen=true // +kubebuilder:subresource:status // +kubebuilder:resource:path=appservices,scope=Namespaced type AppService struct { diff --git a/pkg/apis/scorecard/v1alpha1/types.go b/pkg/apis/scorecard/v1alpha1/types.go index 3390898a53e..a2c0ebb42c4 100644 --- a/pkg/apis/scorecard/v1alpha1/types.go +++ b/pkg/apis/scorecard/v1alpha1/types.go @@ -35,7 +35,6 @@ const ( ) // ScorecardSuiteResult contains the combined results of a suite of tests. -// +k8s:openapi-gen=true type ScorecardSuiteResult struct { // Name is the name of the test suite Name string `json:"name"` @@ -61,7 +60,6 @@ type ScorecardSuiteResult struct { } // ScorecardTestResult contains the results of an individual scorecard test. -// +k8s:openapi-gen=true type ScorecardTestResult struct { // State is the final state of the test State State `json:"state"` @@ -84,7 +82,6 @@ type ScorecardTestResult struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ScorecardOutput is the schema for the scorecard API -// +k8s:openapi-gen=true type ScorecardOutput struct { metav1.TypeMeta `json:",inline"` // +optional diff --git a/pkg/apis/scorecard/v1alpha2/types.go b/pkg/apis/scorecard/v1alpha2/types.go index a7c1dd4fb78..5fc6e6f7157 100644 --- a/pkg/apis/scorecard/v1alpha2/types.go +++ b/pkg/apis/scorecard/v1alpha2/types.go @@ -33,7 +33,6 @@ const ( ) // ScorecardTestResult contains the results of an individual scorecard test. -// +k8s:openapi-gen=true type ScorecardTestResult struct { // Name is the name of the test Name string `json:"name"` @@ -52,7 +51,6 @@ type ScorecardTestResult struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ScorecardOutput is the schema for the scorecard API -// +k8s:openapi-gen=true type ScorecardOutput struct { metav1.TypeMeta `json:",inline"` // +optional diff --git a/test/test-framework/pkg/apis/cache/v1alpha1/memcached_types.go b/test/test-framework/pkg/apis/cache/v1alpha1/memcached_types.go index 51561c2b469..40c0dfabab5 100644 --- a/test/test-framework/pkg/apis/cache/v1alpha1/memcached_types.go +++ b/test/test-framework/pkg/apis/cache/v1alpha1/memcached_types.go @@ -22,24 +22,20 @@ import ( // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. // MemcachedSpec defines the desired state of Memcached -// +k8s:openapi-gen=true type MemcachedSpec struct { // Size is the size of the memcached deployment Size int32 `json:"size"` } // MemcachedStatus defines the observed state of Memcached -// +k8s:openapi-gen=true type MemcachedStatus struct { // Nodes are the names of the memcached pods - // +listType=set Nodes []string `json:"nodes"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Memcached is the Schema for the memcacheds API -// +k8s:openapi-gen=true // +kubebuilder:subresource:status // +kubebuilder:resource:path=memcacheds,scope=Namespaced type Memcached struct { diff --git a/test/test-framework/pkg/apis/cache/v1alpha1/memcachedrs_types.go b/test/test-framework/pkg/apis/cache/v1alpha1/memcachedrs_types.go index 7f739964447..0aad90a3265 100644 --- a/test/test-framework/pkg/apis/cache/v1alpha1/memcachedrs_types.go +++ b/test/test-framework/pkg/apis/cache/v1alpha1/memcachedrs_types.go @@ -22,15 +22,12 @@ import ( // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. // MemcachedRSSpec defines the desired state of MemcachedRS -// +k8s:openapi-gen=true type MemcachedRSSpec struct { NumNodes int32 `json:"numNodes"` } // MemcachedRSStatus defines the observed state of MemcachedRS -// +k8s:openapi-gen=true type MemcachedRSStatus struct { - // +listType=set NodeList []string `json:"nodeList"` Test bool `json:"test"` } @@ -38,7 +35,6 @@ type MemcachedRSStatus struct { // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // MemcachedRS is the Schema for the memcachedrs API -// +k8s:openapi-gen=true // +kubebuilder:subresource:status // +kubebuilder:resource:path=memcachedrs,scope=Namespaced type MemcachedRS struct {