Skip to content

Commit

Permalink
Deprecate 'generate openapi', add 'generate crds' (#2276)
Browse files Browse the repository at this point in the history
* Deprecate 'generate openapi', add 'generate crds'
  • Loading branch information
joelanford committed Dec 5, 2019
1 parent d147bb3 commit 7cc38cc
Show file tree
Hide file tree
Showing 23 changed files with 266 additions and 154 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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

Expand Down
21 changes: 10 additions & 11 deletions cmd/operator-sdk/add/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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=<kind> --api-version=<group/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/<group>/<version> then the command will not overwrite and return an
error.
Long: `operator-sdk add api --kind=<kind> --api-version=<group/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/<group>/<version> 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/<group>/<version>/zz_generated.{deepcopy,openapi}.go. CRD's are
generated, or updated if they exist for a particular group + version + kind,
under deploy/crds/<full group>_<resource>_crd.yaml; OpenAPI V3 validation YAML
pkg/apis/<group>/<version>/zz_generated.deepcopy.go. CRD's are generated,
or updated if they exist for a particular group + version + kind, under
deploy/crds/<full group>_<resource>_crd.yaml; OpenAPI V3 validation YAML
is generated as a 'validation' object. Generation can be disabled with the
--skip-generation flag.
Expand All @@ -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
Expand Down Expand Up @@ -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
}
}
Expand Down
1 change: 1 addition & 0 deletions cmd/operator-sdk/generate/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
49 changes: 49 additions & 0 deletions cmd/operator-sdk/generate/crds.go
Original file line number Diff line number Diff line change
@@ -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/<full group>_<resource>_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()
}
31 changes: 28 additions & 3 deletions cmd/operator-sdk/generate/openapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -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/<group>/<version> directories. Go code is generated under
pkg/apis/<group>/<version>/zz_generated.openapi.go. CRD's are generated, or
Expand All @@ -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/<group>/<version> -O zz_generated.openapi -p ./pkg/apis/<group>/<version> -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
}
81 changes: 81 additions & 0 deletions cmd/operator-sdk/internal/genutil/crds.go
Original file line number Diff line number Diff line change
@@ -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
}
33 changes: 0 additions & 33 deletions cmd/operator-sdk/internal/genutil/openapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -36,7 +35,6 @@ import (
func OpenAPIGen() error {
projutil.MustInProjectRoot()

absProjectPath := projutil.MustGetwd()
repoPkg := projutil.GetGoPkg()

gvMap, err := k8sutil.ParseGroupSubpackages(scaffold.ApisDir)
Expand All @@ -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
}
Expand Down
19 changes: 9 additions & 10 deletions doc/cli/operator-sdk_add_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ Adds a new api definition under pkg/apis

### Synopsis

operator-sdk add api --kind=<kind> --api-version=<group/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/<group>/<version> then the command will not overwrite and return an
error.
operator-sdk add api --kind=<kind> --api-version=<group/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/<group>/<version> 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/<group>/<version>/zz_generated.{deepcopy,openapi}.go. CRD's are
generated, or updated if they exist for a particular group + version + kind,
under deploy/crds/<full group>_<resource>_crd.yaml; OpenAPI V3 validation YAML
pkg/apis/<group>/<version>/zz_generated.deepcopy.go. CRD's are generated,
or updated if they exist for a particular group + version + kind, under
deploy/crds/<full group>_<resource>_crd.yaml; OpenAPI V3 validation YAML
is generated as a 'validation' object. Generation can be disabled with the
--skip-generation flag.

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion doc/cli/operator-sdk_generate.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

32 changes: 32 additions & 0 deletions doc/cli/operator-sdk_generate_crds.md
Original file line number Diff line number Diff line change
@@ -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/<full group>_<resource>_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

Loading

0 comments on commit 7cc38cc

Please sign in to comment.