From db94027468b0a2e199e2a1c7db21d9dfbb1b5a34 Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Tue, 7 Jul 2020 18:51:21 +0100 Subject: [PATCH 1/2] cleanup: keeping sdk scaffolds centralized --- internal/plugins/golang/v2/api.go | 33 +--------- internal/plugins/golang/v2/init.go | 59 ++---------------- internal/util/plugins/makefile.go | 99 ++++++++++++++++++++++++++++++ internal/util/plugins/samples.go | 57 +++++++++++++++++ 4 files changed, 165 insertions(+), 83 deletions(-) create mode 100644 internal/util/plugins/makefile.go create mode 100644 internal/util/plugins/samples.go diff --git a/internal/plugins/golang/v2/api.go b/internal/plugins/golang/v2/api.go index 0af4da5382..27ca5278dc 100644 --- a/internal/plugins/golang/v2/api.go +++ b/internal/plugins/golang/v2/api.go @@ -15,21 +15,12 @@ package v2 import ( - "fmt" - "path/filepath" - "strings" - - "github.com/operator-framework/operator-sdk/internal/scaffold/kustomize" - "github.com/spf13/pflag" "sigs.k8s.io/kubebuilder/pkg/model/config" "sigs.k8s.io/kubebuilder/pkg/plugin" -) -// sampleKustomizationFragment is a template for samples/kustomization.yaml. -const sampleKustomizationFragment = `## This file is auto-generated, do not modify ## -resources: -` + utilplugins "github.com/operator-framework/operator-sdk/internal/util/plugins" +) type createAPIPlugin struct { plugin.CreateAPI @@ -63,23 +54,5 @@ func (p *createAPIPlugin) Run() error { // SDK plugin-specific scaffolds. func (p *createAPIPlugin) run() error { - - // Write CR paths to the samples' kustomization file. This file has a - // "do not modify" comment so it is safe to overwrite. - samplesKustomization := sampleKustomizationFragment - for _, gvk := range p.config.Resources { - samplesKustomization += fmt.Sprintf("- %s\n", makeCRFileName(gvk)) - } - kpath := filepath.Join("config", "samples") - if err := kustomize.Write(kpath, samplesKustomization); err != nil { - return err - } - - return nil -} - -// makeCRFileName returns a Custom Resource example file name in the same format -// as kubebuilder's CreateAPI plugin for a gvk. -func makeCRFileName(gvk config.GVK) string { - return fmt.Sprintf("%s_%s_%s.yaml", gvk.Group, gvk.Version, strings.ToLower(gvk.Kind)) + return utilplugins.WriteSamplesKustomization(p.config) } diff --git a/internal/plugins/golang/v2/init.go b/internal/plugins/golang/v2/init.go index 8dd7930e57..13b77c6305 100644 --- a/internal/plugins/golang/v2/init.go +++ b/internal/plugins/golang/v2/init.go @@ -16,11 +16,12 @@ package v2 import ( "fmt" - "io/ioutil" "github.com/spf13/pflag" "sigs.k8s.io/kubebuilder/pkg/model/config" "sigs.k8s.io/kubebuilder/pkg/plugin" + + utilplugins "github.com/operator-framework/operator-sdk/internal/util/plugins" ) type initPlugin struct { @@ -44,64 +45,16 @@ func (p *initPlugin) Run() error { return err } - // Update the scaffolded Makefile with operator-sdk recipes. - // TODO: rewrite this when plugins phase 2 is implemented. - if err := initUpdateMakefile("Makefile"); err != nil { - return fmt.Errorf("error updating Makefile: %v", err) - } - // Update plugin config section with this plugin's configuration. cfg := Config{} if err := p.config.EncodePluginConfig(pluginConfigKey, cfg); err != nil { return fmt.Errorf("error writing plugin config for %s: %v", pluginConfigKey, err) } - return nil + return p.run() } -// initUpdateMakefile updates a vanilla kubebuilder Makefile with operator-sdk recipes. -func initUpdateMakefile(filePath string) error { - makefileBytes, err := ioutil.ReadFile(filePath) - if err != nil { - return err - } - - // Prepend bundle variables. - makefileBytes = append([]byte(makefileBundleVarFragment), makefileBytes...) - // Append bundle recipes. - makefileBytes = append(makefileBytes, []byte(makefileBundleFragment)...) - makefileBytes = append(makefileBytes, []byte(makefileBundleBuildFragment)...) - - return ioutil.WriteFile(filePath, makefileBytes, 0644) +// SDK plugin-specific scaffolds. +func (p *initPlugin) run() error { + return utilplugins.UpdateMakefile(p.config) } - -// Makefile fragments to add to the base Makefile. -const ( - makefileBundleVarFragment = `# Current Operator version -VERSION ?= 0.0.1 -# Default bundle image tag -BUNDLE_IMG ?= controller-bundle:$(VERSION) -# Options for 'bundle-build' -ifneq ($(origin CHANNELS), undefined) -BUNDLE_CHANNELS := --channels=$(CHANNELS) -endif -ifneq ($(origin DEFAULT_CHANNEL), undefined) -BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL) -endif -BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) -` - - makefileBundleFragment = ` -# Generate bundle manifests and metadata, then validate generated files. -bundle: manifests - operator-sdk generate kustomize manifests -q - kustomize build config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) - operator-sdk bundle validate ./bundle -` - - makefileBundleBuildFragment = ` -# Build the bundle image. -bundle-build: - docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) . -` -) diff --git a/internal/util/plugins/makefile.go b/internal/util/plugins/makefile.go new file mode 100644 index 0000000000..3f22ef77f8 --- /dev/null +++ b/internal/util/plugins/makefile.go @@ -0,0 +1,99 @@ +// Copyright 2020 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. + +// TODO: rewrite this when plugins phase 2 is implemented. +package plugins + +import ( + "fmt" + "io/ioutil" + + "sigs.k8s.io/kubebuilder/pkg/model/config" + + "github.com/operator-framework/operator-sdk/internal/util/projutil" +) + +// UpdateMakefile modifies the project scaffolded by kubebuilder's Init plugin. +func UpdateMakefile(cfg *config.Config) error { + // Update the scaffolded Makefile with operator-sdk recipes. + if err := initUpdateMakefile("Makefile", cfg); err != nil { + return fmt.Errorf("error updating Makefile: %v", err) + } + return nil +} + +// initUpdateMakefile updates a vanilla kubebuilder Makefile with operator-sdk recipes. +func initUpdateMakefile(filePath string, cfg *config.Config) error { + makefileBytes, err := ioutil.ReadFile(filePath) + if err != nil { + return err + } + + // Prepend bundle variables. + makefileBytes = append([]byte(makefileBundleVarFragment), makefileBytes...) + + // Append bundle recipes. + operatorType := projutil.PluginKeyToOperatorType(cfg.Layout) + if operatorType == projutil.OperatorTypeGo { + makefileBytes = append(makefileBytes, []byte(makefileBundleFragmentGo)...) + } else { + // if is not go project then, has not the manifest target + makefileBytes = append(makefileBytes, []byte(makefileBundleFragmentNonGo)...) + } + + makefileBytes = append(makefileBytes, []byte(makefileBundleBuildFragment)...) + + return ioutil.WriteFile(filePath, makefileBytes, 0644) +} + +// Makefile fragments to add to the base Makefile. +const ( + makefileBundleVarFragment = `# Current Operator version +VERSION ?= 0.0.1 +# Default bundle image tag +BUNDLE_IMG ?= controller-bundle:$(VERSION) +# Options for 'bundle-build' +ifneq ($(origin CHANNELS), undefined) +BUNDLE_CHANNELS := --channels=$(CHANNELS) +endif +ifneq ($(origin DEFAULT_CHANNEL), undefined) +BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL) +endif +BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) + +.PHONY: bundle +` + + makefileBundleFragmentGo = ` +# Generate bundle manifests and metadata, then validate generated files. +bundle: manifests + operator-sdk generate kustomize manifests -q + $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) + operator-sdk bundle validate ./bundle +` + + makefileBundleFragmentNonGo = ` +# Generate bundle manifests and metadata, then validate generated files. +bundle: kustomize + operator-sdk generate kustomize manifests -q + $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) + operator-sdk bundle validate ./bundle +` + + makefileBundleBuildFragment = ` +# Build the bundle image. +bundle-build: + docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) . +` +) diff --git a/internal/util/plugins/samples.go b/internal/util/plugins/samples.go new file mode 100644 index 0000000000..71c3e187ab --- /dev/null +++ b/internal/util/plugins/samples.go @@ -0,0 +1,57 @@ +// Copyright 2020 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. + +// TODO: rewrite this when plugins phase 2 is implemented. +package plugins + +import ( + "fmt" + "path/filepath" + "strings" + + "sigs.k8s.io/kubebuilder/pkg/model/config" + + "github.com/operator-framework/operator-sdk/internal/scaffold/kustomize" +) + +// sampleKustomizationFragment is a template for samples/kustomization.yaml. +const sampleKustomizationFragment = `## This file is auto-generated, do not modify ## +resources: +` + +// WriteSamplesKustomization perform the SDK plugin-specific scaffolds. +func WriteSamplesKustomization(cfg *config.Config) error { + + // Write CR paths to the samples' kustomization file. This file has a + // "do not modify" comment so it is safe to overwrite. + samplesKustomization := sampleKustomizationFragment + for _, gvk := range cfg.Resources { + samplesKustomization += fmt.Sprintf("- %s\n", makeCRFileName(gvk)) + } + kpath := filepath.Join("config", "samples") + if err := kustomize.Write(kpath, samplesKustomization); err != nil { + return err + } + + return nil +} + +// todo(camilamacedo86): Now that we have the Kubebuilder scaffolding machinery included in our repo, we could make +// this an actual template that supports both file.Template and file.Inserter for init and create api, respectively. +// More info: https://github.com/operator-framework/operator-sdk/issues/3370 +// makeCRFileName returns a Custom Resource example file name in the same format +// as kubebuilder's CreateAPI plugin for a gvk. +func makeCRFileName(gvk config.GVK) string { + return fmt.Sprintf("%s_%s_%s.yaml", gvk.Group, gvk.Version, strings.ToLower(gvk.Kind)) +} From 6c408eb3c2c0ef0d0dd86b6cdd4e11f42bfb7528 Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Mon, 13 Jul 2020 20:17:49 +0100 Subject: [PATCH 2/2] suggestions applied --- internal/plugins/golang/v2/init.go | 7 ++++++- internal/util/plugins/makefile.go | 8 +++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/internal/plugins/golang/v2/init.go b/internal/plugins/golang/v2/init.go index 13b77c6305..1e00261d55 100644 --- a/internal/plugins/golang/v2/init.go +++ b/internal/plugins/golang/v2/init.go @@ -45,13 +45,18 @@ func (p *initPlugin) Run() error { return err } + // Update the scaffolded Makefile with operator-sdk recipes. + if err := p.run(); err != nil { + return err + } + // Update plugin config section with this plugin's configuration. cfg := Config{} if err := p.config.EncodePluginConfig(pluginConfigKey, cfg); err != nil { return fmt.Errorf("error writing plugin config for %s: %v", pluginConfigKey, err) } - return p.run() + return nil } // SDK plugin-specific scaffolds. diff --git a/internal/util/plugins/makefile.go b/internal/util/plugins/makefile.go index 3f22ef77f8..8b8550358c 100644 --- a/internal/util/plugins/makefile.go +++ b/internal/util/plugins/makefile.go @@ -45,10 +45,12 @@ func initUpdateMakefile(filePath string, cfg *config.Config) error { // Append bundle recipes. operatorType := projutil.PluginKeyToOperatorType(cfg.Layout) - if operatorType == projutil.OperatorTypeGo { + switch operatorType { + case projutil.OperatorTypeUnknown: + return fmt.Errorf("unsupported plugin key %q", cfg.Layout) + case projutil.OperatorTypeGo: makefileBytes = append(makefileBytes, []byte(makefileBundleFragmentGo)...) - } else { - // if is not go project then, has not the manifest target + default: makefileBytes = append(makefileBytes, []byte(makefileBundleFragmentNonGo)...) }