diff --git a/CHANGELOG.md b/CHANGELOG.md index 542964c834..40fc69a3f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Renamed `--docker-build-args` option to `--image-build-args` option for `build` subcommand, because this option can now be shared with other image build tools than docker when `--image-builder` option is specified. ([#1311](https://github.com/operator-framework/operator-sdk/pull/1311)) - Reduces Helm release information in CR status to only the release name and manifest and moves it from `status.conditions` to a new top-level `deployedRelease` field. ([#1309](https://github.com/operator-framework/operator-sdk/pull/1309)) - **WARNING**: Users with active CRs and releases who are upgrading their helm-based operator should upgrade to one based on v0.7.0 before upgrading further. Helm operators based on v0.8.0+ will not seamlessly transition release state to the persistent backend, and will instead uninstall and reinstall all managed releases. +- Go operator CRDs are overwritten when being regenerated by [`operator-sdk generate openapi`](https://github.com/operator-framework/operator-sdk/blob/master/doc/sdk-cli-reference.md#openapi). Users can now rely on `+kubebuilder` annotations in their API code, which provide access to most OpenAPIv3 [validation properties](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schema-object) (the full set will be supported in the near future, see [this PR](https://github.com/kubernetes-sigs/controller-tools/pull/190)) and [other CRD fields](https://book.kubebuilder.io/beyond_basics/generating_crd.html). ([#1278](https://github.com/operator-framework/operator-sdk/pull/1278)) ### Deprecated @@ -23,6 +24,7 @@ ### Bug Fixes - In Helm-based operators, when a custom resource with a failing release is reverted back to a working state, the `ReleaseFailed` condition is now correctly removed. ([#1321](https://github.com/operator-framework/operator-sdk/pull/1321)) +- [`operator-sdk generate openapi`](https://github.com/operator-framework/operator-sdk/blob/master/doc/sdk-cli-reference.md#openapi) no longer overwrites CRD values derived from `+kubebuilder` annotations in Go API code. See issues ([#1212](https://github.com/operator-framework/operator-sdk/issues/1212)) and ([#1323](https://github.com/operator-framework/operator-sdk/issues/1323)) for discussion. ([#1278](https://github.com/operator-framework/operator-sdk/pull/1278)) ## v0.7.0 diff --git a/Gopkg.lock b/Gopkg.lock index 8a9a2eb953..ee2c8cef51 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1698,7 +1698,7 @@ version = "v0.1.10" [[projects]] - digest = "1:d9b023a1f03e70736cedd89f6a0d700a298c73cedc1ad20c55275abcdc71fc50" + digest = "1:024781b25f1d15e78be60cc44842c092d3cda8d494f6c972e6f35707ac35419a" name = "sigs.k8s.io/controller-tools" packages = [ "pkg/crd/generator", @@ -1709,8 +1709,7 @@ "pkg/util", ] pruneopts = "NUT" - revision = "b8adde9bc6d7f3fba449d306613a9daed23676c8" - version = "v0.1.10" + revision = "9d55346c2bde73fb3326ac22eac2e5210a730207" [[projects]] digest = "1:8730e0150dfb2b7e173890c8b9868e7a273082ef8e39f4940e3506a481cf895c" diff --git a/Gopkg.toml b/Gopkg.toml index 477da1871a..ab5fc620fc 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -30,6 +30,12 @@ name = "sigs.k8s.io/controller-runtime" version = "=v0.1.10" +# This override revision has a fix that allows CRD unit tests to run correctly. +# Remove once v0.1.11 is released. +[[override]] + name = "sigs.k8s.io/controller-tools" + revision = "9d55346c2bde73fb3326ac22eac2e5210a730207" + [[constraint]] name = "github.com/sergi/go-diff" version = "1.0.0" diff --git a/internal/pkg/scaffold/crd.go b/internal/pkg/scaffold/crd.go index a0b0f253fb..31904cd99c 100644 --- a/internal/pkg/scaffold/crd.go +++ b/internal/pkg/scaffold/crd.go @@ -16,8 +16,6 @@ package scaffold import ( "fmt" - "io/ioutil" - "os" "path/filepath" "strings" "sync" @@ -41,6 +39,20 @@ type CRD struct { // IsOperatorGo is true when the operator is written in Go. IsOperatorGo bool + + once sync.Once + fs afero.Fs // For testing, ex. afero.NewMemMapFs() +} + +func (s *CRD) initFS(fs afero.Fs) { + s.once.Do(func() { + s.fs = fs + }) +} + +func (s *CRD) getFS() afero.Fs { + s.initFS(afero.NewOsFs()) + return s.fs } func (s *CRD) GetInput() (input.Input, error) { @@ -76,77 +88,78 @@ func initCache() { }) } -func (s *CRD) SetFS(_ afero.Fs) {} +var _ CustomRenderer = &CRD{} + +func (s *CRD) SetFS(fs afero.Fs) { s.initFS(fs) } func (s *CRD) CustomRender() ([]byte, error) { - i, _ := s.GetInput() - // controller-tools generates crd file names with no _crd.yaml suffix: - // __.yaml. - path := strings.Replace(filepath.Base(i.Path), "_crd.yaml", ".yaml", 1) - - // controller-tools' generators read and make crds for all apis in pkg/apis, - // so generate crds in a cached, in-memory fs to extract the data we need. - if s.IsOperatorGo && !cache.fileExists(path) { - g := &crdgenerator.Generator{ - RootPath: s.AbsProjectPath, - Domain: strings.SplitN(s.Resource.FullGroup, ".", 2)[1], - OutputDir: ".", - SkipMapValidation: false, - OutFs: cache, - } - if err := g.ValidateAndInitFields(); err != nil { - return nil, err - } - if err := g.Do(); err != nil { - return nil, err - } + i, err := s.GetInput() + if err != nil { + return nil, err } - dstCRD := newCRDForResource(s.Resource) - // Get our generated crd's from the in-memory fs. If it doesn't exist in the - // fs, the corresponding API does not exist yet, so scaffold a fresh crd - // without a validation spec. - // If the crd exists in the fs, and a local crd exists, append the validation - // spec. If a local crd does not exist, use the generated crd. - if _, err := cache.Stat(path); err != nil && !os.IsNotExist(err) { - return nil, err - } else if err == nil { + crd := &apiextv1beta1.CustomResourceDefinition{} + if s.IsOperatorGo { + // controller-tools generates crd file names with no _crd.yaml suffix: + // __.yaml. + path := strings.Replace(filepath.Base(i.Path), "_crd.yaml", ".yaml", 1) + + // controller-tools' generators read and make crds for all apis in pkg/apis, + // so generate crds in a cached, in-memory fs to extract the data we need. + if !cache.fileExists(path) { + g := &crdgenerator.Generator{ + RootPath: s.AbsProjectPath, + Domain: strings.SplitN(s.Resource.FullGroup, ".", 2)[1], + Repo: s.Repo, + OutputDir: ".", + SkipMapValidation: false, + OutFs: cache, + } + if err := g.ValidateAndInitFields(); err != nil { + return nil, err + } + if err := g.Do(); err != nil { + return nil, err + } + } + b, err := afero.ReadFile(cache, path) if err != nil { return nil, err } - dstCRD = &apiextv1beta1.CustomResourceDefinition{} - if err = yaml.Unmarshal(b, dstCRD); err != nil { + if err = yaml.Unmarshal(b, crd); err != nil { return nil, err } - val := dstCRD.Spec.Validation.DeepCopy() - - // If the crd exists at i.Path, append the validation spec to its crd spec. - if _, err := os.Stat(i.Path); err == nil { - cb, err := ioutil.ReadFile(i.Path) + // controller-tools does not set ListKind or Singular names. + setCRDNamesForResource(crd, s.Resource) + // Remove controller-tools default label. + delete(crd.Labels, "controller-tools.k8s.io") + } else { + // There are currently no commands to update CRD manifests for non-Go + // operators, so if a CRD manifests already exists for this gvk, this + // scaffold is a no-op. + path := filepath.Join(s.AbsProjectPath, i.Path) + if _, err = s.getFS().Stat(path); err == nil { + b, err := afero.ReadFile(s.getFS(), path) if err != nil { return nil, err } - if len(cb) > 0 { - dstCRD = &apiextv1beta1.CustomResourceDefinition{} - if err = yaml.Unmarshal(cb, dstCRD); err != nil { + if len(b) == 0 { + crd = newCRDForResource(s.Resource) + } else { + if err = yaml.Unmarshal(b, crd); err != nil { return nil, err } - dstCRD.Spec.Validation = val } } - // controller-tools does not set ListKind or Singular names. - dstCRD.Spec.Names = getCRDNamesForResource(s.Resource) - // Remove controller-tools default label. - delete(dstCRD.Labels, "controller-tools.k8s.io") } - addCRDSubresource(dstCRD) - addCRDVersions(dstCRD) - return k8sutil.GetObjectBytes(dstCRD) + + setCRDVersions(crd) + return k8sutil.GetObjectBytes(crd) } func newCRDForResource(r *Resource) *apiextv1beta1.CustomResourceDefinition { - return &apiextv1beta1.CustomResourceDefinition{ + crd := &apiextv1beta1.CustomResourceDefinition{ TypeMeta: metav1.TypeMeta{ APIVersion: "apiextensions.k8s.io/v1beta1", Kind: "CustomResourceDefinition", @@ -156,7 +169,6 @@ func newCRDForResource(r *Resource) *apiextv1beta1.CustomResourceDefinition { }, Spec: apiextv1beta1.CustomResourceDefinitionSpec{ Group: r.FullGroup, - Names: getCRDNamesForResource(r), Scope: apiextv1beta1.NamespaceScoped, Version: r.Version, Subresources: &apiextv1beta1.CustomResourceSubresources{ @@ -164,27 +176,26 @@ func newCRDForResource(r *Resource) *apiextv1beta1.CustomResourceDefinition { }, }, } + setCRDNamesForResource(crd, r) + return crd } -func getCRDNamesForResource(r *Resource) apiextv1beta1.CustomResourceDefinitionNames { - return apiextv1beta1.CustomResourceDefinitionNames{ - Kind: r.Kind, - ListKind: r.Kind + "List", - Plural: r.Resource, - Singular: r.LowerKind, +func setCRDNamesForResource(crd *apiextv1beta1.CustomResourceDefinition, r *Resource) { + if crd.Spec.Names.Kind == "" { + crd.Spec.Names.Kind = r.Kind } -} - -func addCRDSubresource(crd *apiextv1beta1.CustomResourceDefinition) { - if crd.Spec.Subresources == nil { - crd.Spec.Subresources = &apiextv1beta1.CustomResourceSubresources{} + if crd.Spec.Names.ListKind == "" { + crd.Spec.Names.ListKind = r.Kind + "List" + } + if crd.Spec.Names.Plural == "" { + crd.Spec.Names.Plural = r.Resource } - if crd.Spec.Subresources.Status == nil { - crd.Spec.Subresources.Status = &apiextv1beta1.CustomResourceSubresourceStatus{} + if crd.Spec.Names.Singular == "" { + crd.Spec.Names.Singular = r.LowerKind } } -func addCRDVersions(crd *apiextv1beta1.CustomResourceDefinition) { +func setCRDVersions(crd *apiextv1beta1.CustomResourceDefinition) { // crd.Version is deprecated, use crd.Versions instead. var crdVersions []apiextv1beta1.CustomResourceDefinitionVersion if crd.Spec.Version != "" { diff --git a/internal/pkg/scaffold/crd_test.go b/internal/pkg/scaffold/crd_test.go index 1f7cf95848..103bf04379 100644 --- a/internal/pkg/scaffold/crd_test.go +++ b/internal/pkg/scaffold/crd_test.go @@ -15,13 +15,14 @@ package scaffold import ( - "os" "path/filepath" - "strings" "testing" - "github.com/operator-framework/operator-sdk/internal/pkg/scaffold/input" + testutil "github.com/operator-framework/operator-sdk/internal/pkg/scaffold/internal/testutil" "github.com/operator-framework/operator-sdk/internal/util/diffutil" + "github.com/operator-framework/operator-sdk/internal/util/fileutil" + + "github.com/spf13/afero" ) func TestCRDGoProject(t *testing.T) { @@ -30,28 +31,18 @@ func TestCRDGoProject(t *testing.T) { t.Fatal(err) } s, buf := setupScaffoldAndWriter() - absPath, err := os.Getwd() + s.Fs = afero.NewMemMapFs() + cfg, err := setupTestFrameworkConfig() if err != nil { t.Fatal(err) } - // Set the project and repo paths to {abs}/test/test-framework, which - // contains pkg/apis for the memcached-operator. - tfDir := filepath.Join("test", "test-framework") - pkgIdx := strings.Index(absPath, "internal/pkg") - cfg := &input.Config{ - Repo: filepath.Join(absPath[strings.Index(absPath, "github.com"):pkgIdx], tfDir), - AbsProjectPath: filepath.Join(absPath[:pkgIdx], tfDir), - ProjectName: tfDir, - } - if err := os.Chdir(cfg.AbsProjectPath); err != nil { + + err = testutil.WriteOSPathToFS(afero.NewOsFs(), s.Fs, cfg.AbsProjectPath) + if err != nil { t.Fatal(err) } - defer func() { os.Chdir(absPath) }() - err = s.Execute(cfg, &CRD{ - Input: input.Input{Path: filepath.Join(tfDir, "cache_v1alpha1_memcached.yaml")}, - Resource: r, - IsOperatorGo: true, - }) + + err = s.Execute(cfg, &CRD{Resource: r, IsOperatorGo: true}) if err != nil { t.Fatalf("Failed to execute the scaffold: (%v)", err) } @@ -74,8 +65,6 @@ spec: plural: memcacheds singular: memcached scope: Namespaced - subresources: - status: {} validation: openAPIV3Schema: properties: @@ -118,13 +107,31 @@ spec: ` func TestCRDNonGoProject(t *testing.T) { + s, buf := setupScaffoldAndWriter() + s.Fs = afero.NewMemMapFs() + r, err := NewResource(appApiVersion, appKind) if err != nil { t.Fatal(err) } - s, buf := setupScaffoldAndWriter() - err = s.Execute(appConfig, &CRD{Resource: r}) + + crd := &CRD{Resource: r} + i, err := crd.GetInput() if err != nil { + t.Fatal(err) + } + cfg, err := setupTestFrameworkConfig() + if err != nil { + t.Fatal(err) + } + + path := filepath.Join(cfg.AbsProjectPath, i.Path) + err = afero.WriteFile(s.Fs, path, []byte(crdNonGoExp), fileutil.DefaultFileMode) + if err != nil { + t.Fatal(err) + } + + if err = s.Execute(cfg, crd); err != nil { t.Fatalf("Failed to execute the scaffold: (%v)", err) } @@ -134,6 +141,9 @@ func TestCRDNonGoProject(t *testing.T) { } } +// crdNonGoExp contains a simple validation block to make sure manually-added +// validation is not overwritten. Non-go projects don't have the luxury of +// kubebuilder annotations. const crdNonGoExp = `apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: @@ -148,6 +158,26 @@ spec: scope: Namespaced subresources: status: {} + validation: + openAPIV3Schema: + properties: + spec: + properties: + size: + format: int32 + type: integer + required: + - size + type: object + status: + properties: + nodes: + items: + type: string + type: array + required: + - nodes + type: object version: v1alpha1 versions: - name: v1alpha1 diff --git a/internal/pkg/scaffold/gopkgtoml.go b/internal/pkg/scaffold/gopkgtoml.go index 8d84475334..5aec04e196 100644 --- a/internal/pkg/scaffold/gopkgtoml.go +++ b/internal/pkg/scaffold/gopkgtoml.go @@ -62,7 +62,7 @@ required = [ [[override]] name = "sigs.k8s.io/controller-tools" - version = "=v0.1.8" + revision = "9d55346c2bde73fb3326ac22eac2e5210a730207" [[override]] name = "k8s.io/api" diff --git a/internal/pkg/scaffold/gopkgtoml_test.go b/internal/pkg/scaffold/gopkgtoml_test.go index b2f52e25cd..4f09bf12c3 100644 --- a/internal/pkg/scaffold/gopkgtoml_test.go +++ b/internal/pkg/scaffold/gopkgtoml_test.go @@ -60,7 +60,7 @@ required = [ [[override]] name = "sigs.k8s.io/controller-tools" - version = "=v0.1.8" + revision = "9d55346c2bde73fb3326ac22eac2e5210a730207" [[override]] name = "k8s.io/api" diff --git a/internal/pkg/scaffold/internal/testutil/test_util.go b/internal/pkg/scaffold/internal/testutil/test_util.go new file mode 100644 index 0000000000..70c96721fe --- /dev/null +++ b/internal/pkg/scaffold/internal/testutil/test_util.go @@ -0,0 +1,28 @@ +package test + +import ( + "os" + + "github.com/operator-framework/operator-sdk/internal/util/fileutil" + + "github.com/spf13/afero" +) + +func WriteOSPathToFS(fromFS, toFS afero.Fs, root string) error { + if _, err := fromFS.Stat(root); err != nil { + return err + } + return afero.Walk(fromFS, root, func(path string, info os.FileInfo, err error) error { + if err != nil || info == nil { + return err + } + if !info.IsDir() { + b, err := afero.ReadFile(fromFS, path) + if err != nil { + return err + } + return afero.WriteFile(toFS, path, b, fileutil.DefaultFileMode) + } + return nil + }) +} diff --git a/internal/pkg/scaffold/olm-catalog/csv_test.go b/internal/pkg/scaffold/olm-catalog/csv_test.go index b2e8cbdc8c..2a15794377 100644 --- a/internal/pkg/scaffold/olm-catalog/csv_test.go +++ b/internal/pkg/scaffold/olm-catalog/csv_test.go @@ -24,8 +24,8 @@ import ( "github.com/operator-framework/operator-sdk/internal/pkg/scaffold" "github.com/operator-framework/operator-sdk/internal/pkg/scaffold/input" + testutil "github.com/operator-framework/operator-sdk/internal/pkg/scaffold/internal/testutil" "github.com/operator-framework/operator-sdk/internal/util/diffutil" - "github.com/operator-framework/operator-sdk/internal/util/fileutil" "github.com/coreos/go-semver/semver" "github.com/ghodss/yaml" @@ -66,25 +66,6 @@ func TestCSVNew(t *testing.T) { } } -func writeOSPathToFS(fromFs, toFs afero.Fs, root string) error { - if _, err := fromFs.Stat(root); err != nil { - return err - } - return afero.Walk(fromFs, root, func(path string, info os.FileInfo, err error) error { - if err != nil || info == nil { - return err - } - if !info.IsDir() { - b, err := afero.ReadFile(fromFs, path) - if err != nil { - return err - } - return afero.WriteFile(toFs, path, b, fileutil.DefaultFileMode) - } - return nil - }) -} - func TestCSVFromOld(t *testing.T) { s := &scaffold.Scaffold{Fs: afero.NewMemMapFs()} projectName := "app-operator" @@ -92,7 +73,7 @@ func TestCSVFromOld(t *testing.T) { // Write all files in testdata/deploy to fs so manifests are present when // writing a new CSV. - if err := writeOSPathToFS(afero.NewOsFs(), s.Fs, testDeployDir); err != nil { + if err := testutil.WriteOSPathToFS(afero.NewOsFs(), s.Fs, testDeployDir); err != nil { t.Fatalf("Failed to write %s to in-memory test fs: (%v)", testDeployDir, err) } diff --git a/internal/pkg/scaffold/test_setup.go b/internal/pkg/scaffold/test_setup.go index d0e76dbc65..5212a137c9 100644 --- a/internal/pkg/scaffold/test_setup.go +++ b/internal/pkg/scaffold/test_setup.go @@ -19,6 +19,7 @@ import ( "io" "os" "path/filepath" + "strings" "github.com/operator-framework/operator-sdk/internal/pkg/scaffold/input" @@ -57,3 +58,20 @@ func setupScaffoldAndWriter() (*Scaffold, *bytes.Buffer) { }, }, buf } + +func setupTestFrameworkConfig() (*input.Config, error) { + absPath, err := os.Getwd() + if err != nil { + return nil, err + } + absPath = absPath[:strings.Index(absPath, "internal/pkg")] + tfDir := filepath.Join(absPath, "test", "test-framework") + + // Set the project and repo paths to {abs}/test/test-framework, which + // contains pkg/apis for the memcached-operator. + return &input.Config{ + Repo: tfDir[strings.Index(absPath, "github.com"):], + AbsProjectPath: tfDir, + ProjectName: filepath.Base(tfDir), + }, nil +} diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/generator/generator.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/generator/generator.go index dfbf152789..f8b98fd1d5 100644 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/generator/generator.go +++ b/vendor/sigs.k8s.io/controller-tools/pkg/crd/generator/generator.go @@ -38,6 +38,7 @@ import ( type Generator struct { RootPath string OutputDir string + Repo string Domain string Namespace string SkipMapValidation bool @@ -70,17 +71,20 @@ func (c *Generator) ValidateAndInitFields() error { } } - // Validate root path is under go src path - if !crdutil.IsUnderGoSrcPath(c.RootPath) { - return fmt.Errorf("command must be run from path under $GOPATH/src/") + // Validate PROJECT file if Domain or Repo are not set manually + if len(c.Domain) == 0 || len(c.Repo) == 0 { + if !crdutil.PathHasProjectFile(c.RootPath) { + return fmt.Errorf("PROJECT file missing in dir %s", c.RootPath) + } + } + + if len(c.Repo) == 0 { + c.Repo = crdutil.GetRepoFromProject(c.RootPath) } // If Domain is not explicitly specified, // try to search for PROJECT file as a basis. if len(c.Domain) == 0 { - if !crdutil.PathHasProjectFile(c.RootPath) { - return fmt.Errorf("PROJECT file missing in dir %s", c.RootPath) - } c.Domain = crdutil.GetDomainFromProject(c.RootPath) } @@ -106,13 +110,23 @@ func (c *Generator) Do() error { } // Switch working directory to root path. + wd, err := os.Getwd() + if err != nil { + return err + } if err := os.Chdir(c.RootPath); err != nil { return fmt.Errorf("failed switching working dir: %v", err) } + defer func() { + if err := os.Chdir(wd); err != nil { + log.Fatalf("Failed to switch back to original working dir: %v", err) + } + }() - if err := b.AddDirRecursive("./" + c.APIsPath); err != nil { + if err := b.AddDirRecursive(fmt.Sprintf("%s/%s", c.Repo, c.APIsPath)); err != nil { return fmt.Errorf("failed making a parser: %v", err) } + ctx, err := parse.NewContext(b) if err != nil { return fmt.Errorf("failed making a context: %v", err) @@ -185,7 +199,6 @@ func (c *Generator) belongsToAPIsPkg(t *types.Type) bool { } func (c *Generator) setAPIsPkg() error { - var err error if c.APIsPath == "" { c.APIsPath = "pkg/apis" } @@ -198,10 +211,7 @@ func (c *Generator) setAPIsPkg() error { return fmt.Errorf("error validating apis path %s: %v", apisPath, err) } - c.apisPkg, err = crdutil.DirToGoPkg(apisPath) - if err != nil { - return err - } + c.apisPkg = path.Join(c.Repo, c.APIsPath) } return nil } diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/crd/util/util.go b/vendor/sigs.k8s.io/controller-tools/pkg/crd/util/util.go index 821aab5d25..559e602278 100644 --- a/vendor/sigs.k8s.io/controller-tools/pkg/crd/util/util.go +++ b/vendor/sigs.k8s.io/controller-tools/pkg/crd/util/util.go @@ -89,7 +89,17 @@ func PathHasProjectFile(filePath string) bool { // GetDomainFromProject get domain information from the PROJECT file under the path. func GetDomainFromProject(rootPath string) string { - var domain string + return GetFieldFromProject("domain", rootPath) +} + +// GetRepoFromProject get domain information from the PROJECT file under the path. +func GetRepoFromProject(rootPath string) string { + return GetFieldFromProject("repo", rootPath) +} + +// GetFieldFromProject get field information from the PROJECT file under the path. +func GetFieldFromProject(fieldKey string, rootPath string) string { + var fieldVal string file, err := os.Open(path.Join(rootPath, "PROJECT")) if err != nil { @@ -103,15 +113,18 @@ func GetDomainFromProject(rootPath string) string { scanner := bufio.NewScanner(file) for scanner.Scan() { - if strings.HasPrefix(scanner.Text(), "domain:") { - domainInfo := strings.Split(scanner.Text(), ":") - if len(domainInfo) != 2 { - log.Fatalf("Unexpected domain info: %s", scanner.Text()) + if strings.HasPrefix(scanner.Text(), fmt.Sprintf("%s:", fieldKey)) { + fieldInfo := strings.Split(scanner.Text(), ":") + if len(fieldInfo) != 2 { + log.Fatalf("Unexpected %s info: %s", fieldKey, scanner.Text()) } - domain = strings.Replace(domainInfo[1], " ", "", -1) + fieldVal = strings.Replace(fieldInfo[1], " ", "", -1) break } } + if len(fieldVal) == 0 { + log.Fatalf("%s/PROJECT file is missing value for '%s'", rootPath, fieldKey) + } - return domain + return fieldVal } diff --git a/vendor/sigs.k8s.io/controller-tools/pkg/internal/codegen/types.go b/vendor/sigs.k8s.io/controller-tools/pkg/internal/codegen/types.go index ebfaf620d0..e4fda4c7e3 100644 --- a/vendor/sigs.k8s.io/controller-tools/pkg/internal/codegen/types.go +++ b/vendor/sigs.k8s.io/controller-tools/pkg/internal/codegen/types.go @@ -21,7 +21,7 @@ import ( rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/gengo/types"