Skip to content

Commit 7cc38cc

Browse files
authored
Deprecate 'generate openapi', add 'generate crds' (#2276)
* Deprecate 'generate openapi', add 'generate crds'
1 parent d147bb3 commit 7cc38cc

23 files changed

+266
-154
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- Support for vars in top level ansible watches. ([#2147](https://github.com/operator-framework/operator-sdk/pull/2147))
55
- 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))
66
- Support for relative helm chart paths in the Helm operator's watches.yaml file. ([#2287](https://github.com/operator-framework/operator-sdk/pull/2287))
7+
- New `operator-sdk generate crds` subcommand, which generates CRDs from Go types. ([#2276](https://github.com/operator-framework/operator-sdk/pull/2276))
78

89
### Changed
910
- 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 @@
1718
- 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))
1819

1920
### Deprecated
21+
- 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))
2022

2123
### Removed
2224

cmd/operator-sdk/add/api.go

+10-11
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,17 @@ func newAddApiCmd() *cobra.Command {
4040
apiCmd := &cobra.Command{
4141
Use: "api",
4242
Short: "Adds a new api definition under pkg/apis",
43-
Long: `operator-sdk add api --kind=<kind> --api-version=<group/version> creates the
44-
api definition for a new custom resource under pkg/apis. This command must be
45-
run from the project root directory. If the api already exists at
46-
pkg/apis/<group>/<version> then the command will not overwrite and return an
47-
error.
43+
Long: `operator-sdk add api --kind=<kind> --api-version=<group/version> creates
44+
the api definition for a new custom resource under pkg/apis. This command
45+
must be run from the project root directory. If the api already exists at
46+
pkg/apis/<group>/<version> then the command will not overwrite and return
47+
an error.
4848
49-
By default, this command runs Kubernetes deepcopy and OpenAPI V3 generators on
49+
By default, this command runs Kubernetes deepcopy and CRD generators on
5050
tagged types in all paths under pkg/apis. Go code is generated under
51-
pkg/apis/<group>/<version>/zz_generated.{deepcopy,openapi}.go. CRD's are
52-
generated, or updated if they exist for a particular group + version + kind,
53-
under deploy/crds/<full group>_<resource>_crd.yaml; OpenAPI V3 validation YAML
51+
pkg/apis/<group>/<version>/zz_generated.deepcopy.go. CRD's are generated,
52+
or updated if they exist for a particular group + version + kind, under
53+
deploy/crds/<full group>_<resource>_crd.yaml; OpenAPI V3 validation YAML
5454
is generated as a 'validation' object. Generation can be disabled with the
5555
--skip-generation flag.
5656
@@ -67,7 +67,6 @@ Example:
6767
├── register.go
6868
├── appservice_types.go
6969
├── zz_generated.deepcopy.go
70-
├── zz_generated.openapi.go
7170
$ tree deploy/crds
7271
├── deploy/crds/app.example.com_v1alpha1_appservice_cr.yaml
7372
├── deploy/crds/app.example.com_appservices_crd.yaml
@@ -143,7 +142,7 @@ func apiRun(cmd *cobra.Command, args []string) error {
143142
}
144143

145144
// Generate a validation spec for the new CRD.
146-
if err := genutil.OpenAPIGen(); err != nil {
145+
if err := genutil.CRDGen(); err != nil {
147146
return err
148147
}
149148
}

cmd/operator-sdk/generate/cmd.go

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ func NewCmd() *cobra.Command {
2525
Long: `The operator-sdk generate command invokes specific generator to generate code as needed.`,
2626
}
2727
cmd.AddCommand(newGenerateK8SCmd())
28+
cmd.AddCommand(newGenerateCRDsCmd())
2829
cmd.AddCommand(newGenerateOpenAPICmd())
2930
return cmd
3031
}

cmd/operator-sdk/generate/crds.go

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2019 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package generate
16+
17+
import (
18+
"fmt"
19+
20+
"github.com/operator-framework/operator-sdk/cmd/operator-sdk/internal/genutil"
21+
"github.com/spf13/cobra"
22+
)
23+
24+
func newGenerateCRDsCmd() *cobra.Command {
25+
return &cobra.Command{
26+
Use: "crds",
27+
Short: "Generates CRDs for API's",
28+
Long: `generate crds generates CRDs or updates them if they exist,
29+
under deploy/crds/<full group>_<resource>_crd.yaml; OpenAPI
30+
V3 validation YAML is generated as a 'validation' object.
31+
32+
Example:
33+
34+
$ operator-sdk generate crds
35+
$ tree deploy/crds
36+
├── deploy/crds/app.example.com_v1alpha1_appservice_cr.yaml
37+
├── deploy/crds/app.example.com_appservices_crd.yaml
38+
`,
39+
RunE: crdsFunc,
40+
}
41+
}
42+
43+
func crdsFunc(cmd *cobra.Command, args []string) error {
44+
if len(args) != 0 {
45+
return fmt.Errorf("command %s doesn't accept any arguments", cmd.CommandPath())
46+
}
47+
48+
return genutil.CRDGen()
49+
}

cmd/operator-sdk/generate/openapi.go

+28-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ import (
2323

2424
func newGenerateOpenAPICmd() *cobra.Command {
2525
return &cobra.Command{
26-
Use: "openapi",
27-
Short: "Generates OpenAPI specs for API's",
26+
Hidden: true,
27+
Use: "openapi",
28+
Short: "Generates OpenAPI specs for API's",
2829
Long: `generate openapi generates OpenAPI validation specs in Go from tagged types
2930
in all pkg/apis/<group>/<version> directories. Go code is generated under
3031
pkg/apis/<group>/<version>/zz_generated.openapi.go. CRD's are generated, or
@@ -48,10 +49,34 @@ Example:
4849
}
4950
}
5051

52+
const deprecationTemplate = "\033[1;36m%s\033[0m"
53+
5154
func openAPIFunc(cmd *cobra.Command, args []string) error {
55+
fmt.Printf(deprecationTemplate, `[Deprecation notice] The 'operator-sdk generate openapi' command is deprecated!
56+
57+
- To generate CRDs, use 'operator-sdk generate crds'.
58+
- To generate Go OpenAPI code, use 'openapi-gen'. For example:
59+
60+
# Build the latest openapi-gen from source
61+
which ./bin/openapi-gen > /dev/null || go build -o ./bin/openapi-gen k8s.io/kube-openapi/cmd/openapi-gen
62+
63+
# Run openapi-gen for each of your API group/version packages
64+
./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 "-"
65+
66+
`)
67+
5268
if len(args) != 0 {
5369
return fmt.Errorf("command %s doesn't accept any arguments", cmd.CommandPath())
5470
}
5571

56-
return genutil.OpenAPIGen()
72+
fs := []func() error{
73+
genutil.OpenAPIGen,
74+
genutil.CRDGen,
75+
}
76+
for _, f := range fs {
77+
if err := f(); err != nil {
78+
return err
79+
}
80+
}
81+
return nil
5782
}
+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright 2018 The Operator-SDK Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package genutil
16+
17+
import (
18+
"fmt"
19+
"path/filepath"
20+
"strings"
21+
22+
"github.com/operator-framework/operator-sdk/internal/scaffold"
23+
"github.com/operator-framework/operator-sdk/internal/scaffold/input"
24+
"github.com/operator-framework/operator-sdk/internal/util/k8sutil"
25+
"github.com/operator-framework/operator-sdk/internal/util/projutil"
26+
27+
log "github.com/sirupsen/logrus"
28+
)
29+
30+
// CRDGen generates CRDs for all APIs in pkg/apis.
31+
func CRDGen() error {
32+
projutil.MustInProjectRoot()
33+
34+
absProjectPath := projutil.MustGetwd()
35+
repoPkg := projutil.GetGoPkg()
36+
37+
gvMap, err := k8sutil.ParseGroupSubpackages(scaffold.ApisDir)
38+
if err != nil {
39+
return fmt.Errorf("failed to parse group versions: (%v)", err)
40+
}
41+
gvb := &strings.Builder{}
42+
for g, vs := range gvMap {
43+
gvb.WriteString(fmt.Sprintf("%s:%v, ", g, vs))
44+
}
45+
46+
log.Infof("Running CRD generation for Custom Resource group versions: [%v]\n", gvb.String())
47+
48+
s := &scaffold.Scaffold{}
49+
cfg := &input.Config{
50+
Repo: repoPkg,
51+
AbsProjectPath: absProjectPath,
52+
ProjectName: filepath.Base(absProjectPath),
53+
}
54+
crds, err := k8sutil.GetCRDs(scaffold.CRDsDir)
55+
if err != nil {
56+
return err
57+
}
58+
for _, crd := range crds {
59+
g, v, k := crd.Spec.Group, crd.Spec.Version, crd.Spec.Names.Kind
60+
if v == "" {
61+
if len(crd.Spec.Versions) != 0 {
62+
v = crd.Spec.Versions[0].Name
63+
} else {
64+
return fmt.Errorf("crd of group %s kind %s has no version", g, k)
65+
}
66+
}
67+
r, err := scaffold.NewResource(g+"/"+v, k)
68+
if err != nil {
69+
return err
70+
}
71+
err = s.Execute(cfg,
72+
&scaffold.CRD{Resource: r, IsOperatorGo: projutil.IsOperatorGo()},
73+
)
74+
if err != nil {
75+
return err
76+
}
77+
}
78+
79+
log.Info("CRD generation complete.")
80+
return nil
81+
}

cmd/operator-sdk/internal/genutil/openapi.go

-33
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"strings"
2323

2424
"github.com/operator-framework/operator-sdk/internal/scaffold"
25-
"github.com/operator-framework/operator-sdk/internal/scaffold/input"
2625
"github.com/operator-framework/operator-sdk/internal/util/k8sutil"
2726
"github.com/operator-framework/operator-sdk/internal/util/projutil"
2827

@@ -36,7 +35,6 @@ import (
3635
func OpenAPIGen() error {
3736
projutil.MustInProjectRoot()
3837

39-
absProjectPath := projutil.MustGetwd()
4038
repoPkg := projutil.GetGoPkg()
4139

4240
gvMap, err := k8sutil.ParseGroupSubpackages(scaffold.ApisDir)
@@ -57,37 +55,6 @@ func OpenAPIGen() error {
5755
return err
5856
}
5957

60-
s := &scaffold.Scaffold{}
61-
cfg := &input.Config{
62-
Repo: repoPkg,
63-
AbsProjectPath: absProjectPath,
64-
ProjectName: filepath.Base(absProjectPath),
65-
}
66-
crds, err := k8sutil.GetCRDs(scaffold.CRDsDir)
67-
if err != nil {
68-
return err
69-
}
70-
for _, crd := range crds {
71-
g, v, k := crd.Spec.Group, crd.Spec.Version, crd.Spec.Names.Kind
72-
if v == "" {
73-
if len(crd.Spec.Versions) != 0 {
74-
v = crd.Spec.Versions[0].Name
75-
} else {
76-
return fmt.Errorf("crd of group %s kind %s has no version", g, k)
77-
}
78-
}
79-
r, err := scaffold.NewResource(g+"/"+v, k)
80-
if err != nil {
81-
return err
82-
}
83-
err = s.Execute(cfg,
84-
&scaffold.CRD{Resource: r, IsOperatorGo: projutil.IsOperatorGo()},
85-
)
86-
if err != nil {
87-
return err
88-
}
89-
}
90-
9158
log.Info("Code-generation complete.")
9259
return nil
9360
}

doc/cli/operator-sdk_add_api.md

+9-10
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ Adds a new api definition under pkg/apis
44

55
### Synopsis
66

7-
operator-sdk add api --kind=<kind> --api-version=<group/version> creates the
8-
api definition for a new custom resource under pkg/apis. This command must be
9-
run from the project root directory. If the api already exists at
10-
pkg/apis/<group>/<version> then the command will not overwrite and return an
11-
error.
7+
operator-sdk add api --kind=<kind> --api-version=<group/version> creates
8+
the api definition for a new custom resource under pkg/apis. This command
9+
must be run from the project root directory. If the api already exists at
10+
pkg/apis/<group>/<version> then the command will not overwrite and return
11+
an error.
1212

13-
By default, this command runs Kubernetes deepcopy and OpenAPI V3 generators on
13+
By default, this command runs Kubernetes deepcopy and CRD generators on
1414
tagged types in all paths under pkg/apis. Go code is generated under
15-
pkg/apis/<group>/<version>/zz_generated.{deepcopy,openapi}.go. CRD's are
16-
generated, or updated if they exist for a particular group + version + kind,
17-
under deploy/crds/<full group>_<resource>_crd.yaml; OpenAPI V3 validation YAML
15+
pkg/apis/<group>/<version>/zz_generated.deepcopy.go. CRD's are generated,
16+
or updated if they exist for a particular group + version + kind, under
17+
deploy/crds/<full group>_<resource>_crd.yaml; OpenAPI V3 validation YAML
1818
is generated as a 'validation' object. Generation can be disabled with the
1919
--skip-generation flag.
2020

@@ -31,7 +31,6 @@ Example:
3131
├── register.go
3232
├── appservice_types.go
3333
├── zz_generated.deepcopy.go
34-
├── zz_generated.openapi.go
3534
$ tree deploy/crds
3635
├── deploy/crds/app.example.com_v1alpha1_appservice_cr.yaml
3736
├── deploy/crds/app.example.com_appservices_crd.yaml

doc/cli/operator-sdk_generate.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ The operator-sdk generate command invokes specific generator to generate code as
1515
### SEE ALSO
1616

1717
* [operator-sdk](operator-sdk.md) - An SDK for building operators with ease
18+
* [operator-sdk generate crds](operator-sdk_generate_crds.md) - Generates CRDs for API's
1819
* [operator-sdk generate k8s](operator-sdk_generate_k8s.md) - Generates Kubernetes code for custom resource
19-
* [operator-sdk generate openapi](operator-sdk_generate_openapi.md) - Generates OpenAPI specs for API's
2020

doc/cli/operator-sdk_generate_crds.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## operator-sdk generate crds
2+
3+
Generates CRDs for API's
4+
5+
### Synopsis
6+
7+
generate crds generates CRDs or updates them if they exist,
8+
under deploy/crds/<full group>_<resource>_crd.yaml; OpenAPI
9+
V3 validation YAML is generated as a 'validation' object.
10+
11+
Example:
12+
13+
$ operator-sdk generate crds
14+
$ tree deploy/crds
15+
├── deploy/crds/app.example.com_v1alpha1_appservice_cr.yaml
16+
├── deploy/crds/app.example.com_appservices_crd.yaml
17+
18+
19+
```
20+
operator-sdk generate crds [flags]
21+
```
22+
23+
### Options
24+
25+
```
26+
-h, --help help for crds
27+
```
28+
29+
### SEE ALSO
30+
31+
* [operator-sdk generate](operator-sdk_generate.md) - Invokes specific generator
32+

0 commit comments

Comments
 (0)