Skip to content

Commit

Permalink
Move to plugin model
Browse files Browse the repository at this point in the history
  • Loading branch information
justinsb committed Aug 15, 2019
1 parent e5ba947 commit f96bee5
Show file tree
Hide file tree
Showing 21 changed files with 543 additions and 231 deletions.
18 changes: 17 additions & 1 deletion cmd/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ import (
"log"
"os"
"os/exec"
"strings"

"github.com/spf13/cobra"
flag "github.com/spf13/pflag"

"sigs.k8s.io/kubebuilder/cmd/util"
"sigs.k8s.io/kubebuilder/pkg/scaffold"
"sigs.k8s.io/kubebuilder/pkg/scaffold/v1/resource"
"sigs.k8s.io/kubebuilder/plugins/addon"
)

type apiOptions struct {
Expand All @@ -37,6 +39,9 @@ type apiOptions struct {

// runMake indicates whether to run make or not after scaffolding APIs
runMake bool

// pattern indicates that we should use a plugin to build according to a pattern
pattern string
}

func (o *apiOptions) bindCmdFlags(cmd *cobra.Command) {
Expand All @@ -48,7 +53,7 @@ func (o *apiOptions) bindCmdFlags(cmd *cobra.Command) {
cmd.Flags().BoolVar(&o.apiScaffolder.DoController, "controller", true,
"if set, generate the controller without prompting the user")
o.controllerFlag = cmd.Flag("controller")
cmd.Flags().StringVar(&o.apiScaffolder.Pattern, "pattern", "",
cmd.Flags().StringVar(&o.pattern, "pattern", "",
"generates an API following an extension pattern (addon)")
o.apiScaffolder.Resource = resourceForFlags(cmd.Flags())
}
Expand All @@ -69,6 +74,17 @@ func resourceForFlags(f *flag.FlagSet) *resource.Resource {
func (o *apiOptions) runAddAPI() {
dieIfNoProject()

switch strings.ToLower(o.pattern) {
case "":
// Default pattern

case "addon":
o.apiScaffolder.Plugins = append(o.apiScaffolder.Plugins, &addon.Plugin{})

default:
log.Fatal("unknown pattern %q", o.pattern)
}

reader := bufio.NewReader(os.Stdin)
if !o.resourceFlag.Changed {
fmt.Println("Create Resource [y/n]")
Expand Down
5 changes: 4 additions & 1 deletion cmd/vendor_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"log"

"github.com/spf13/cobra"
"sigs.k8s.io/kubebuilder/pkg/model"
"sigs.k8s.io/kubebuilder/pkg/scaffold"
"sigs.k8s.io/kubebuilder/pkg/scaffold/input"
"sigs.k8s.io/kubebuilder/pkg/scaffold/project"
Expand All @@ -35,7 +36,9 @@ kubebuilder update vendor
`,
Run: func(cmd *cobra.Command, args []string) {
dieIfNoProject()
err := (&scaffold.Scaffold{}).Execute(input.Options{},
err := (&scaffold.Scaffold{}).Execute(
&model.Universe{},
input.Options{},
&project.GopkgToml{})
if err != nil {
log.Fatalf("error updating vendor dependecies %v", err)
Expand Down
5 changes: 4 additions & 1 deletion cmd/webhook_v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/spf13/cobra"
flag "github.com/spf13/pflag"

"sigs.k8s.io/kubebuilder/pkg/model"
"sigs.k8s.io/kubebuilder/pkg/scaffold"
"sigs.k8s.io/kubebuilder/pkg/scaffold/input"
"sigs.k8s.io/kubebuilder/pkg/scaffold/project"
Expand Down Expand Up @@ -68,7 +69,9 @@ This command is only available for v1 scaffolding project.
o.res.Resource = flect.Pluralize(strings.ToLower(o.res.Kind))
}

err = (&scaffold.Scaffold{}).Execute(input.Options{},
err = (&scaffold.Scaffold{}).Execute(
&model.Universe{},
input.Options{},
&manager.Webhook{},
&webhook.AdmissionHandler{Resource: o.res, Config: webhook.Config{Server: o.server, Type: o.webhookType, Operations: o.operations}},
&webhook.AdmissionWebhookBuilder{Resource: o.res, Config: webhook.Config{Server: o.server, Type: o.webhookType, Operations: o.operations}},
Expand Down
2 changes: 2 additions & 0 deletions cmd/webhook_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/gobuffalo/flect"
"github.com/spf13/cobra"

"sigs.k8s.io/kubebuilder/pkg/model"
"sigs.k8s.io/kubebuilder/pkg/scaffold"
"sigs.k8s.io/kubebuilder/pkg/scaffold/input"
"sigs.k8s.io/kubebuilder/pkg/scaffold/project"
Expand Down Expand Up @@ -82,6 +83,7 @@ You need to implement the conversion.Hub and conversion.Convertible interfaces f
Validating: o.validation,
}
err = (&scaffold.Scaffold{}).Execute(
&model.Universe{},
input.Options{},
webhookScaffolder,
)
Expand Down
55 changes: 55 additions & 0 deletions pkg/model/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package model

import (
"sigs.k8s.io/kubebuilder/pkg/scaffold/input"
)

type Universe struct {
Boilerplate string `json:"boilerplate,omitempty"`

Resource *Resource `json:"resource,omitempty"`

Files []*File `json:"files,omitempty"`
}

// TODO: Just use the resource type?
type Resource struct {
// Namespaced is true if the resource is namespaced
Namespaced bool `json:"namespaces,omitempty"`

// Group is the API Group. Does not contain the domain.
Group string `json:"group,omitempty"`

// Version is the API version - e.g. v1beta1
Version string `json:"version,omitempty"`

// Kind is the API Kind.
Kind string `json:"kind,omitempty"`

// Plural is the plural lowercase of Kind.
Plural string `json:"plural,omitempty"`

// Resource is the API Resource.
Resource string `json:"resource,omitempty"`

// ResourcePackage is the go package of the Resource
GoPackage string `json:"goPackage,omitempty"`

// GroupDomain is the Group + "." + Domain for the Resource
GroupDomain string `json:"groupDomain,omitempty"`
}

type File struct {
// Type is an identifier for the class of the generator
Type string `json:"type"`

// Path is the file to write
Path string `json:"path,omitempty"`

// Contents is the generated output
Contents string `json:"contents,omitempty"`

// TODO: Move input.IfExistsAction into model
// IfExistsAction determines what to do if the file exists
IfExistsAction input.IfExistsAction `json:"ifExistsAction,omitempty"`
}
70 changes: 32 additions & 38 deletions pkg/scaffold/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ import (
"path/filepath"
"strings"

"github.com/gobuffalo/flect"
"sigs.k8s.io/kubebuilder/pkg/model"
"sigs.k8s.io/kubebuilder/pkg/scaffold/input"
"sigs.k8s.io/kubebuilder/pkg/scaffold/pattern/addon"
"sigs.k8s.io/kubebuilder/pkg/scaffold/project"
"sigs.k8s.io/kubebuilder/pkg/scaffold/util"
"sigs.k8s.io/kubebuilder/pkg/scaffold/v1/controller"
resourcev1 "sigs.k8s.io/kubebuilder/pkg/scaffold/v1/resource"
resourcev2 "sigs.k8s.io/kubebuilder/pkg/scaffold/v2"
Expand All @@ -35,6 +37,9 @@ import (
type API struct {
scaffold *Scaffold

// Plugins is the list of plugins we should allow to transform our generated scaffolding
Plugins []Plugin

Resource *resourcev1.Resource

project *input.ProjectFile
Expand All @@ -44,16 +49,8 @@ type API struct {

// DoController indicates whether to scaffold controller files or not
DoController bool

// Pattern specifies an alternative style of generation
Pattern string
}

const (
// PatternAddon is the Pattern flag value that specifies the declarative addon operator pattern
PatternAddon = "addon"
)

// Validate validates whether API scaffold has correct bits to generate
// scaffolding for API.
func (api *API) Validate() error {
Expand All @@ -70,15 +67,6 @@ func (api *API) Validate() error {
return fmt.Errorf("missing kind information for resource")
}

switch api.Pattern {
case "":
// Default pattern - OK
case PatternAddon:
// Declarative addon operator pattern
default:
return fmt.Errorf("unknown pattern %q", api.Pattern)
}

return nil
}

Expand Down Expand Up @@ -108,6 +96,23 @@ func (api *API) Scaffold() error {
}
}

func (api *API) buildUniverse() *model.Universe {
resource := &model.Resource{
Namespaced: api.Resource.Namespaced,
Group: api.Resource.Group,
Version: api.Resource.Version,
Kind: api.Resource.Kind,
Resource: api.Resource.Resource,
Plural: flect.Pluralize(strings.ToLower(api.Resource.Kind)),
}

resource.GoPackage, resource.GroupDomain = util.GetResourceInfo(api.Resource, api.project.Repo, api.project.Domain)

return &model.Universe{
Resource: resource,
}
}

func (api *API) scaffoldV1() error {
r := api.Resource

Expand All @@ -117,7 +122,7 @@ func (api *API) scaffoldV1() error {
fmt.Println(filepath.Join("pkg", "apis", r.Group, r.Version,
fmt.Sprintf("%s_types_test.go", strings.ToLower(r.Kind))))

err := (&Scaffold{}).Execute(input.Options{},
err := (&Scaffold{}).Execute(api.buildUniverse(), input.Options{},
&resourcev1.Register{Resource: r},
&resourcev1.Types{Resource: r},
&resourcev1.VersionSuiteTest{Resource: r},
Expand All @@ -144,7 +149,7 @@ func (api *API) scaffoldV1() error {
fmt.Println(filepath.Join("pkg", "controller", strings.ToLower(r.Kind),
fmt.Sprintf("%s_controller_test.go", strings.ToLower(r.Kind))))

err := (&Scaffold{}).Execute(input.Options{},
err := (&Scaffold{}).Execute(api.buildUniverse(), input.Options{},
&controller.Controller{Resource: r},
&controller.AddController{Resource: r},
&controller.Test{Resource: r},
Expand Down Expand Up @@ -174,35 +179,23 @@ func (api *API) scaffoldV2() error {
Input: input.Input{
Path: filepath.Join("api", r.Version, fmt.Sprintf("%s_types.go", strings.ToLower(r.Kind))),
},
Resource: r,
Pattern: api.Pattern},
Resource: r},
&resourcev2.Group{Resource: r},
&resourcev2.CRDSample{Resource: r},
&crdv2.EnableWebhookPatch{Resource: r},
&crdv2.EnableCAInjectionPatch{Resource: r},
}

switch api.Pattern {
case "":
// Default pattern

case "addon":
// declarative addon operator
packageName := strings.ToLower(r.Kind)
files = append(files, &addon.ExampleManifest{PackageName: packageName})
files = append(files, &addon.ExampleChannel{})

default:
return fmt.Errorf("unknown pattern %q", api.Pattern)
scaffold := &Scaffold{
Plugins: api.Plugins,
}

err := (&Scaffold{}).Execute(input.Options{}, files...)
if err != nil {
if err := scaffold.Execute(api.buildUniverse(), input.Options{}, files...); err != nil {
return fmt.Errorf("error scaffolding APIs: %v", err)
}

crdKustomization := &crdv2.Kustomization{Resource: r}
err = (&Scaffold{}).Execute(
err := (&Scaffold{}).Execute(api.buildUniverse(),
input.Options{},
crdKustomization,
&crdv2.KustomizeConfig{},
Expand Down Expand Up @@ -235,9 +228,10 @@ func (api *API) scaffoldV2() error {
if api.DoController {
fmt.Println(filepath.Join("controllers", fmt.Sprintf("%s_controller.go", strings.ToLower(r.Kind))))

ctrlScaffolder := &resourcev2.Controller{Resource: r, Pattern: api.Pattern}
ctrlScaffolder := &resourcev2.Controller{Resource: r}
testsuiteScaffolder := &resourcev2.ControllerSuiteTest{Resource: r}
err := (&Scaffold{}).Execute(
api.buildUniverse(),
input.Options{},
testsuiteScaffolder,
ctrlScaffolder,
Expand Down
13 changes: 13 additions & 0 deletions pkg/scaffold/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"strings"

"sigs.k8s.io/kubebuilder/cmd/util"
"sigs.k8s.io/kubebuilder/pkg/model"
"sigs.k8s.io/kubebuilder/pkg/scaffold/input"
"sigs.k8s.io/kubebuilder/pkg/scaffold/project"
scaffoldv1 "sigs.k8s.io/kubebuilder/pkg/scaffold/v1"
Expand Down Expand Up @@ -77,6 +78,10 @@ func (p *V1Project) EnsureDependencies() (bool, error) {
return true, c.Run()
}

func (p *V1Project) buildUniverse() *model.Universe {
return &model.Universe{}
}

func (p *V1Project) Scaffold() error {
p.Project.Version = project.Version1

Expand All @@ -96,6 +101,7 @@ func (p *V1Project) Scaffold() error {
}

err = s.Execute(
p.buildUniverse(),
input.Options{ProjectPath: projectInput.Path, BoilerplatePath: bpInput.Path},
&p.Project,
&p.Boilerplate,
Expand All @@ -109,6 +115,7 @@ func (p *V1Project) Scaffold() error {

s = &Scaffold{}
return s.Execute(
p.buildUniverse(),
input.Options{ProjectPath: projectInput.Path, BoilerplatePath: bpInput.Path},
&project.GitIgnore{},
&project.KustomizeRBAC{},
Expand Down Expand Up @@ -147,6 +154,10 @@ func (p *V2Project) EnsureDependencies() (bool, error) {
return true, c.Run()
}

func (p *V2Project) buildUniverse() *model.Universe {
return &model.Universe{}
}

func (p *V2Project) Scaffold() error {
p.Project.Version = project.Version2

Expand All @@ -166,6 +177,7 @@ func (p *V2Project) Scaffold() error {
}

err = s.Execute(
p.buildUniverse(),
input.Options{ProjectPath: projectInput.Path, BoilerplatePath: bpInput.Path},
&p.Project,
&p.Boilerplate,
Expand All @@ -179,6 +191,7 @@ func (p *V2Project) Scaffold() error {

s = &Scaffold{}
return s.Execute(
p.buildUniverse(),
input.Options{ProjectPath: projectInput.Path, BoilerplatePath: bpInput.Path},
&project.GitIgnore{},
&scaffoldv2.KustomizeImagePatch{},
Expand Down
Loading

0 comments on commit f96bee5

Please sign in to comment.