Skip to content

Commit d3abf04

Browse files
committed
Merge branch 'master' into refactor/controller-runtime-v0.2.0
2 parents 3dcdc04 + f509fcd commit d3abf04

File tree

16 files changed

+139
-91
lines changed

16 files changed

+139
-91
lines changed

CHANGELOG.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,8 @@
22

33
### Added
44

5-
- Document new compile-time dependency `mercurial` in user-facing documentation. ([#1683](https://github.com/operator-framework/operator-sdk/pull/1683))
6-
- Adds new flag `--zap-time-encoding` to the flagset provided by `pkg/log/zap`. This flag configures the timestamp format produced by the zap logger. See the [logging doc](https://github.com/operator-framework/operator-sdk/blob/master/doc/user/logging.md) for more information. ([#1529](https://github.com/operator-framework/operator-sdk/pull/1529))
7-
85
### Changed
96

10-
- Make `ready` package idempotent. Now, a user can call `Set()` or `Unset()` to set the operator's readiness without knowing the current state. ([#1761](https://github.com/operator-framework/operator-sdk/pull/1761))
11-
127
### Breaking changes
138

149
- CSV config field `role-path` is now `role-paths` and takes a list of strings. Users can now specify multiple `Role` and `ClusterRole` manifests using `role-paths`. ([#1704](https://github.com/operator-framework/operator-sdk/pull/1704))
@@ -41,6 +36,21 @@
4136

4237
### Bug Fixes
4338

39+
- Configure the repo path correctly in `operator-sdk add crd` and prevent the command from running outside of an operator project. ([#1660](https://github.com/operator-framework/operator-sdk/pull/1660))
40+
41+
## v0.10.0
42+
43+
### Added
44+
45+
- Document new compile-time dependency `mercurial` in user-facing documentation. ([#1683](https://github.com/operator-framework/operator-sdk/pull/1683))
46+
- Adds new flag `--zap-time-encoding` to the flagset provided by `pkg/log/zap`. This flag configures the timestamp format produced by the zap logger. See the [logging doc](https://github.com/operator-framework/operator-sdk/blob/master/doc/user/logging.md) for more information. ([#1529](https://github.com/operator-framework/operator-sdk/pull/1529))
47+
48+
### Changed
49+
50+
- Make `ready` package idempotent. Now, a user can call `Set()` or `Unset()` to set the operator's readiness without knowing the current state. ([#1761](https://github.com/operator-framework/operator-sdk/pull/1761))
51+
52+
### Bug Fixes
53+
4454
- Check if `metadata.annotations['alm-examples']` is non-empty before creating contained CR manifests in the scorecard. ([#1789](https://github.com/operator-framework/operator-sdk/pull/1789))
4555
4656
## v0.9.0

cmd/operator-sdk/add/crd.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@ Generated CR filename: <project-name>/deploy/crds/<group>_<version>_<kind>_cr.y
5555
}
5656

5757
func crdFunc(cmd *cobra.Command, args []string) error {
58+
projutil.MustInProjectRoot()
59+
5860
cfg := &input.Config{
5961
AbsProjectPath: projutil.MustGetwd(),
62+
Repo: projutil.GetGoPkg(),
6063
}
6164
if len(args) != 0 {
6265
return fmt.Errorf("command %s doesn't accept any arguments", cmd.CommandPath())

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

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -15,72 +15,14 @@
1515
package genutil
1616

1717
import (
18-
"fmt"
1918
"io/ioutil"
2019
"os"
21-
"path"
22-
"path/filepath"
2320

2421
"github.com/operator-framework/operator-sdk/internal/pkg/scaffold"
2522

2623
log "github.com/sirupsen/logrus"
2724
)
2825

29-
// ParseGroupVersions parses the layout of pkg/apis to return a map of
30-
// API groups to versions.
31-
func parseGroupVersions() (map[string][]string, error) {
32-
gvs := make(map[string][]string)
33-
groups, err := ioutil.ReadDir(scaffold.ApisDir)
34-
if err != nil {
35-
return nil, fmt.Errorf("could not read pkg/apis directory to find api Versions: %v", err)
36-
}
37-
38-
for _, g := range groups {
39-
if g.IsDir() {
40-
groupDir := filepath.Join(scaffold.ApisDir, g.Name())
41-
versions, err := ioutil.ReadDir(groupDir)
42-
if err != nil {
43-
return nil, fmt.Errorf("could not read %s directory to find api Versions: %v", groupDir, err)
44-
}
45-
46-
gvs[g.Name()] = make([]string, 0)
47-
for _, v := range versions {
48-
if v.IsDir() {
49-
// Ignore directories that do not contain any files, so generators
50-
// do not get empty directories as arguments.
51-
verDir := filepath.Join(groupDir, v.Name())
52-
files, err := ioutil.ReadDir(verDir)
53-
if err != nil {
54-
return nil, fmt.Errorf("could not read %s directory to find api Versions: %v", verDir, err)
55-
}
56-
for _, f := range files {
57-
if !f.IsDir() && filepath.Ext(f.Name()) == ".go" {
58-
gvs[g.Name()] = append(gvs[g.Name()], filepath.ToSlash(v.Name()))
59-
break
60-
}
61-
}
62-
}
63-
}
64-
}
65-
}
66-
67-
if len(gvs) == 0 {
68-
return nil, fmt.Errorf("no groups or versions found in %s", scaffold.ApisDir)
69-
}
70-
return gvs, nil
71-
}
72-
73-
// createFQAPIs return a slice of all fully qualified pkg + groups + versions
74-
// of pkg and gvs in the format "pkg/groupA/v1".
75-
func createFQAPIs(pkg string, gvs map[string][]string) (apis []string) {
76-
for g, vs := range gvs {
77-
for _, v := range vs {
78-
apis = append(apis, path.Join(pkg, g, v))
79-
}
80-
}
81-
return apis
82-
}
83-
8426
// generateWithHeaderFile runs f with a header file path as an arguemnt.
8527
// If there is no project boilerplate.go.txt file, an empty header file is
8628
// created and its path passed as the argument.

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"strings"
2323

2424
"github.com/operator-framework/operator-sdk/internal/pkg/scaffold"
25+
"github.com/operator-framework/operator-sdk/internal/util/k8sutil"
2526
"github.com/operator-framework/operator-sdk/internal/util/projutil"
2627

2728
"github.com/pkg/errors"
@@ -37,7 +38,7 @@ func K8sCodegen() error {
3738

3839
repoPkg := projutil.GetGoPkg()
3940

40-
gvMap, err := parseGroupVersions()
41+
gvMap, err := k8sutil.ParseGroupSubpackages(scaffold.ApisDir)
4142
if err != nil {
4243
return fmt.Errorf("failed to parse group versions: (%v)", err)
4344
}
@@ -49,7 +50,7 @@ func K8sCodegen() error {
4950
log.Infof("Running deepcopy code-generation for Custom Resource group versions: [%v]\n", gvb.String())
5051

5152
apisPkg := filepath.Join(repoPkg, scaffold.ApisDir)
52-
fqApis := createFQAPIs(apisPkg, gvMap)
53+
fqApis := k8sutil.CreateFQAPIs(apisPkg, gvMap)
5354
f := func(a string) error { return deepcopyGen(a, fqApis) }
5455
if err = generateWithHeaderFile(f); err != nil {
5556
return err

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func OpenAPIGen() error {
3939
absProjectPath := projutil.MustGetwd()
4040
repoPkg := projutil.GetGoPkg()
4141

42-
gvMap, err := parseGroupVersions()
42+
gvMap, err := k8sutil.ParseGroupSubpackages(scaffold.ApisDir)
4343
if err != nil {
4444
return fmt.Errorf("failed to parse group versions: (%v)", err)
4545
}
@@ -51,7 +51,7 @@ func OpenAPIGen() error {
5151
log.Infof("Running OpenAPI code-generation for Custom Resource group versions: [%v]\n", gvb.String())
5252

5353
apisPkg := filepath.Join(repoPkg, scaffold.ApisDir)
54-
fqApis := createFQAPIs(apisPkg, gvMap)
54+
fqApis := k8sutil.CreateFQAPIs(apisPkg, gvMap)
5555
f := func(a string) error { return openAPIGen(a, fqApis) }
5656
if err = generateWithHeaderFile(f); err != nil {
5757
return err

cmd/operator-sdk/new/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ generates a skeletal app-operator application in $HOME/projects/example.com/app-
5757
newCmd.Flags().StringVar(&kind, "kind", "", "Kubernetes CustomResourceDefintion kind. (e.g AppService) - used with \"ansible\" or \"helm\" types")
5858
newCmd.Flags().StringVar(&operatorType, "type", "go", "Type of operator to initialize (choices: \"go\", \"ansible\" or \"helm\")")
5959
newCmd.Flags().StringVar(&depManager, "dep-manager", "modules", `Dependency manager the new project will use (choices: "dep", "modules")`)
60-
newCmd.Flags().StringVar(&repo, "repo", "", "Project repository path for Go operators. Used as the project's Go import path. This must be set if outside of $GOPATH/src with Go modules, and cannot be set if --dep-manager=dep")
60+
newCmd.Flags().StringVar(&repo, "repo", "", "Project repository path for Go operators. Used as the project's Go import path. This must be set if outside of $GOPATH/src with Go modules, and cannot be set if --dep-manager=dep (e.g. github.com/example-inc/my-opertor)")
6161
newCmd.Flags().BoolVar(&gitInit, "git-init", false, "Initialize the project directory as a git repository (default false)")
6262
newCmd.Flags().StringVar(&headerFile, "header-file", "", "Path to file containing headers for generated Go files. Copied to hack/boilerplate.go.txt")
6363
newCmd.Flags().BoolVar(&makeVendor, "vendor", false, "Use a vendor directory for dependencies. This flag only applies when --dep-manager=modules (the default)")

doc/sdk-cli-reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ you will need to rename it before running migrate or manually add it to your Doc
229229

230230
* `--dep-manager` string - Dependency manager the migrated project will use (choices: "dep", "modules") (default "modules")
231231
* `--header-file` string - Path to file containing headers for generated Go files. Copied to hack/boilerplate.go.txt
232-
* `--repo` string - Project repository path for Go operators. Used as the project's Go import path. This must be set if outside of `$GOPATH/src` with Go modules, and cannot be set if `--dep-manager=dep`
232+
* `--repo` string - Project repository path for Go operators. Used as the project's Go import path. This must be set if outside of `$GOPATH/src` with Go modules, and cannot be set if `--dep-manager=dep` (e.g. github.com/example-inc/my-opertor)
233233

234234
### Example
235235

doc/user/install-operator-sdk.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ $ brew install operator-sdk
1818

1919
```sh
2020
# Set the release version variable
21-
$ RELEASE_VERSION=v0.9.0
21+
$ RELEASE_VERSION=v0.10.0
2222
# Linux
2323
$ curl -OJL https://github.com/operator-framework/operator-sdk/releases/download/${RELEASE_VERSION}/operator-sdk-${RELEASE_VERSION}-x86_64-linux-gnu
2424
# macOS

internal/pkg/scaffold/ansible/gopkgtoml.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const gopkgTomlTmpl = `[[constraint]]
3939
name = "github.com/operator-framework/operator-sdk"
4040
# The version rule is used for a specific release and the master branch for in between releases.
4141
branch = "master" #osdk_branch_annotation
42-
# version = "=v0.9.0" #osdk_version_annotation
42+
# version = "=v0.10.0" #osdk_version_annotation
4343
4444
[[override]]
4545
name = "k8s.io/api"

internal/pkg/scaffold/gopkgtoml.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ required = [
8585
name = "github.com/operator-framework/operator-sdk"
8686
# The version rule is used for a specific release and the master branch for in between releases.
8787
branch = "master" #osdk_branch_annotation
88-
# version = "=v0.9.0" #osdk_version_annotation
88+
# version = "=v0.10.0" #osdk_version_annotation
8989
9090
[prune]
9191
go-tests = true

internal/pkg/scaffold/helm/gopkgtoml.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const gopkgTomlTmpl = `[[constraint]]
3939
name = "github.com/operator-framework/operator-sdk"
4040
# The version rule is used for a specific release and the master branch for in between releases.
4141
branch = "master" #osdk_branch_annotation
42-
# version = "=v0.9.0" #osdk_version_annotation
42+
# version = "=v0.10.0" #osdk_version_annotation
4343
4444
[[override]]
4545
name = "k8s.io/api"

internal/pkg/scaffold/olm-catalog/csv.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,16 +346,16 @@ func (s *CSV) updateCSVFromManifestFiles(cfg *CSVConfig, csv *olmapiv1alpha1.Clu
346346
scanner := yamlutil.NewYAMLScanner(yamlData)
347347
for scanner.Scan() {
348348
yamlSpec := scanner.Bytes()
349-
typemeta, err := k8sutil.GetTypeMetaFromBytes(yamlSpec)
349+
typeMeta, err := k8sutil.GetTypeMetaFromBytes(yamlSpec)
350350
if err != nil {
351351
return errors.Wrapf(err, "error getting type metadata from manifest %s", f)
352352
}
353-
found, err := store.AddToUpdater(yamlSpec, typemeta.Kind)
353+
found, err := store.AddToUpdater(yamlSpec, typeMeta.Kind)
354354
if err != nil {
355355
return errors.Wrapf(err, "error adding manifest %s to CSV updaters", f)
356356
}
357357
if !found {
358-
id := gvkID(typemeta.GroupVersionKind())
358+
id := gvkID(typeMeta.GroupVersionKind())
359359
if _, ok := otherSpecs[id]; !ok {
360360
otherSpecs[id] = make([][]byte, 0)
361361
}

internal/util/k8sutil/crd.go

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ import (
1818
"fmt"
1919
"io/ioutil"
2020
"os"
21+
"path"
2122
"path/filepath"
22-
"strings"
23+
"regexp"
2324

2425
yaml "github.com/ghodss/yaml"
26+
"github.com/pkg/errors"
2527
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
2628
)
2729

30+
// GetCRDs parses all CRD manifests in the directory crdsDir and all of its subdirectories.
2831
func GetCRDs(crdsDir string) ([]*apiextv1beta1.CustomResourceDefinition, error) {
2932
manifests, err := GetCRDManifestPaths(crdsDir)
3033
if err != nil {
@@ -45,6 +48,7 @@ func GetCRDs(crdsDir string) ([]*apiextv1beta1.CustomResourceDefinition, error)
4548
return crds, nil
4649
}
4750

51+
// GetCRDManifestPaths gets all CRD manifest paths in crdsDir and subdirs.
4852
func GetCRDManifestPaths(crdsDir string) (crdPaths []string, err error) {
4953
err = filepath.Walk(crdsDir, func(path string, info os.FileInfo, werr error) error {
5054
if werr != nil {
@@ -53,10 +57,98 @@ func GetCRDManifestPaths(crdsDir string) (crdPaths []string, err error) {
5357
if info == nil {
5458
return nil
5559
}
56-
if !info.IsDir() && strings.HasSuffix(path, "_crd.yaml") {
57-
crdPaths = append(crdPaths, path)
60+
if !info.IsDir() {
61+
b, err := ioutil.ReadFile(path)
62+
if err != nil {
63+
return errors.Wrapf(err, "error reading manifest %s", path)
64+
}
65+
typeMeta, err := GetTypeMetaFromBytes(b)
66+
if err != nil {
67+
return errors.Wrapf(err, "error getting kind from manifest %s", path)
68+
}
69+
if typeMeta.Kind == "CustomResourceDefinition" {
70+
crdPaths = append(crdPaths, path)
71+
}
5872
}
5973
return nil
6074
})
6175
return crdPaths, err
6276
}
77+
78+
// ParseGroupSubpackages parses the apisDir directory tree and returns a map of
79+
// all found API groups to subpackages.
80+
func ParseGroupSubpackages(apisDir string) (map[string][]string, error) {
81+
return parseGroupSubdirs(apisDir, false)
82+
}
83+
84+
// ParseGroupVersions parses the apisDir directory tree and returns a map of
85+
// all found API groups to versions.
86+
func ParseGroupVersions(apisDir string) (map[string][]string, error) {
87+
return parseGroupSubdirs(apisDir, true)
88+
}
89+
90+
// versionRegexp defines a kube-like version:
91+
// https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-versioning
92+
var versionRegexp = regexp.MustCompile("^v[1-9][0-9]*((alpha|beta)[1-9][0-9]*)?$")
93+
94+
// parseGroupSubdirs searches apisDir for all groups and potential version
95+
// subdirs directly beneath each group dir, and returns a map of each group
96+
// dir name to all children version dir names. If strictVersionMatch is true,
97+
// all potential version dir names must strictly match versionRegexp. If
98+
// false, all subdir names are considered valid.
99+
func parseGroupSubdirs(apisDir string, strictVersionMatch bool) (map[string][]string, error) {
100+
gvs := make(map[string][]string)
101+
groups, err := ioutil.ReadDir(apisDir)
102+
if err != nil {
103+
return nil, errors.Wrapf(err, "error reading directory %q to find API groups", apisDir)
104+
}
105+
106+
for _, g := range groups {
107+
if g.IsDir() {
108+
groupDir := filepath.Join(apisDir, g.Name())
109+
versions, err := ioutil.ReadDir(groupDir)
110+
if err != nil {
111+
return nil, errors.Wrapf(err, "error reading directory %q to find API versions", groupDir)
112+
}
113+
114+
gvs[g.Name()] = make([]string, 0)
115+
for _, v := range versions {
116+
if v.IsDir() {
117+
// Ignore directories that do not contain any files, so generators
118+
// do not get empty directories as arguments.
119+
verDir := filepath.Join(groupDir, v.Name())
120+
files, err := ioutil.ReadDir(verDir)
121+
if err != nil {
122+
return nil, errors.Wrapf(err, "error reading directory %q to find API source files", verDir)
123+
}
124+
for _, f := range files {
125+
if !f.IsDir() && filepath.Ext(f.Name()) == ".go" {
126+
// If strictVersionMatch is true, strictly check if v.Name()
127+
// is a Kubernetes API version.
128+
if !strictVersionMatch || versionRegexp.MatchString(v.Name()) {
129+
gvs[g.Name()] = append(gvs[g.Name()], v.Name())
130+
}
131+
break
132+
}
133+
}
134+
}
135+
}
136+
}
137+
}
138+
139+
if len(gvs) == 0 {
140+
return nil, fmt.Errorf("no groups or versions found in %s", apisDir)
141+
}
142+
return gvs, nil
143+
}
144+
145+
// CreateFQAPIs return a slice of all fully qualified pkg + groups + versions
146+
// of pkg and gvs in the format "pkg/groupA/v1".
147+
func CreateFQAPIs(pkg string, gvs map[string][]string) (apis []string) {
148+
for g, vs := range gvs {
149+
for _, v := range vs {
150+
apis = append(apis, path.Join(pkg, g, v))
151+
}
152+
}
153+
return apis
154+
}

0 commit comments

Comments
 (0)