Skip to content

Commit

Permalink
cmd: keep openapi with deprecation and instructions for migrating
Browse files Browse the repository at this point in the history
  • Loading branch information
joelanford committed Dec 3, 2019
1 parent 920bd3b commit 9dc62c2
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 7 deletions.
6 changes: 2 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### Added
- 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))
- 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 @@ -13,12 +14,9 @@
- Replace in the Ansible based operators module tests `k8s_info` for `k8s_facts` which is deprecated. ([#2168](https://github.com/operator-framework/operator-sdk/issues/2168))
- Upgrade the Ansible version from `2.8` to `2.9` on the Ansible based operators image. ([#2168](https://github.com/operator-framework/operator-sdk/issues/2168))
- Updated CRD generation for non-Go operators to use valid structural schema. ([#2275](https://github.com/operator-framework/operator-sdk/issues/2275))
- **Breaking change:** Renamed `operator-sdk generate openapi` to `operator-sdk generate crds`. ([#2276](https://github.com/operator-framework/operator-sdk/pull/2276))

### Deprecated

### Removed
- Removed generation of `zz_generated.openapi.go` files during `operator-sdk generate openapi`. ([#2276](https://github.com/operator-framework/operator-sdk/pull/2276))
- 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))

### Bug Fixes
- Fix issue faced in the Ansible based operators when `jmespath` queries are used because it was not installed. ([#2252](https://github.com/operator-framework/operator-sdk/pull/2252))
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 @@ -26,5 +26,6 @@ func NewCmd() *cobra.Command {
}
cmd.AddCommand(newGenerateK8SCmd())
cmd.AddCommand(newGenerateCRDsCmd())
cmd.AddCommand(newGenerateOpenAPICmd())
return cmd
}
82 changes: 82 additions & 0 deletions cmd/operator-sdk/generate/openapi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// 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 newGenerateOpenAPICmd() *cobra.Command {
return &cobra.Command{
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
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.
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
`,
RunE: openAPIFunc,
}
}

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())
}

fs := []func() error{
genutil.OpenAPIGen,
genutil.CRDGen,
}
for _, f := range fs {
if err := f(); err != nil {
return err
}
}
return nil
}
99 changes: 99 additions & 0 deletions cmd/operator-sdk/internal/genutil/openapi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// 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 (
"flag"
"fmt"
"os"
"path/filepath"
"strings"

"github.com/operator-framework/operator-sdk/internal/scaffold"
"github.com/operator-framework/operator-sdk/internal/util/k8sutil"
"github.com/operator-framework/operator-sdk/internal/util/projutil"

"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
generatorargs "k8s.io/kube-openapi/cmd/openapi-gen/args"
"k8s.io/kube-openapi/pkg/generators"
)

// OpenAPIGen generates OpenAPI validation specs for all CRD's in dirs.
func OpenAPIGen() error {
projutil.MustInProjectRoot()

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 OpenAPI code-generation for Custom Resource group versions: [%v]\n", gvb.String())

apisPkg := filepath.Join(repoPkg, scaffold.ApisDir)
fqApis := k8sutil.CreateFQAPIs(apisPkg, gvMap)
f := func(a string) error { return openAPIGen(a, fqApis) }
if err = generateWithHeaderFile(f); err != nil {
return err
}

log.Info("Code-generation complete.")
return nil
}

func openAPIGen(hf string, fqApis []string) error {
wd, err := os.Getwd()
if err != nil {
return err
}
if err := flag.Set("logtostderr", "true"); err != nil {
return err
}
for _, api := range fqApis {
api = filepath.FromSlash(api)
// Use relative API path so the generator writes to the correct path.
apiPath := "." + string(filepath.Separator) + api[strings.Index(api, scaffold.ApisDir):]
args, cargs := generatorargs.NewDefaults()
// Ignore default output base and set our own output path.
args.OutputBase = ""
// openapi-gen already generates a "do not edit" comment.
args.GeneratedByCommentTemplate = ""
args.InputDirs = []string{apiPath}
args.OutputFileBaseName = "zz_generated.openapi"
args.OutputPackagePath = filepath.Join(wd, apiPath)
args.GoHeaderFilePath = hf
// Print API rule violations to stdout
cargs.ReportFilename = "-"
if err := generatorargs.Validate(args); err != nil {
return errors.Wrap(err, "openapi-gen argument validation error")
}

err := args.Execute(
generators.NameSystems(),
generators.DefaultNameSystem(),
generators.Packages,
)
if err != nil {
return errors.Wrap(err, "openapi-gen generator error")
}
}
return nil
}
47 changes: 45 additions & 2 deletions doc/sdk-cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,49 @@ pkg/apis/app/v1alpha1/
└── zz_generated.deepcopy.go
```

### 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/<group>/<version> -O zz_generated.openapi -p ./pkg/apis/<group>/<version> -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.
#### Example
```console
$ tree pkg/apis/app/v1alpha1/
pkg/apis/app/v1alpha1/
├── appservice_types.go
├── doc.go
└── register.go
$ operator-sdk generate openapi
INFO[0000] Running OpenAPI code-generation for Custom Resource group versions: [app:[v1alpha1], ]
INFO[0001] Created deploy/crds/app.example.com_appservices_crd.yaml
INFO[0001] Code-generation complete.
$ tree pkg/apis/app/v1alpha1/
pkg/apis/app/v1alpha1/
├── appservice_types.go
├── doc.go
├── register.go
└── zz_generated.openapi.go
```
### crds

Runs CRD generation (based on controller-tools) for APIs under `pkg/apis/...`.
Expand All @@ -145,7 +188,7 @@ $ tree pkg/apis/app/v1alpha1/
pkg/apis/app/v1alpha1/
├── appservice_types.go
├── doc.go
── register.go
── register.go

$ operator-sdk generate crds
INFO[0000] Running CRD generation for Custom Resource group versions: [app:[v1alpha1], ]
Expand All @@ -154,7 +197,7 @@ INFO[0001] CRD generation complete.

$ tree deploy/crds/
deploy/crds
── app.example.com_appservices_crd.yaml
── app.example.com_appservices_crd.yaml
```

## olm-catalog
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ require (
k8s.io/gengo v0.0.0-20191010091904-7fa3014cb28f
k8s.io/helm v2.16.1+incompatible
k8s.io/klog v1.0.0
k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d // indirect
k8s.io/kube-openapi v0.0.0-20190918143330-0270cf2f1c1d
k8s.io/kube-state-metrics v1.7.2
k8s.io/kubectl v0.0.0
k8s.io/kubernetes v1.16.2
Expand Down

0 comments on commit 9dc62c2

Please sign in to comment.