Skip to content

Commit

Permalink
Merge pull request #132 from Liujingfang1/tmpcore
Browse files Browse the repository at this point in the history
Add support for creating core type controllers
  • Loading branch information
Phillip Wittrock committed May 14, 2018
2 parents b8eff8f + fe2d0f9 commit 391d011
Show file tree
Hide file tree
Showing 11 changed files with 275 additions and 34 deletions.
1 change: 1 addition & 0 deletions build/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export TEST_ASSET_ETCD=/tmp/kubebuilder/bin/etcd
kubebuilder init repo --domain sample.kubernetes.io
kubebuilder create resource --group insect --version v1beta1 --kind Bee
kubebuilder create resource --group insect --version v1beta1 --kind Wasp
kubebuilder create controller --group apps --version v1beta2 --kind Deployment --core-type

# Verify the controller-manager builds and the tests pass
go build ./cmd/...
Expand Down
41 changes: 40 additions & 1 deletion cmd/internal/codegen/parse/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ limitations under the License.
package parse

import (
"go/build"
"path/filepath"
"strings"
"os"
"bufio"

"github.com/golang/glog"

"github.com/kubernetes-sigs/kubebuilder/cmd/internal/codegen"
"github.com/pkg/errors"
Expand Down Expand Up @@ -114,6 +120,39 @@ func (b *APIs) parseDomain() {
comments := Comments(pkg.Comments)
b.Domain = comments.getTag("domain", "=")
if len(b.Domain) == 0 {
panic("Could not find string matching // +domain=.+ in apis/doc.go")
b.Domain = parseDomainFromFiles(b.context.Inputs)
if len(b.Domain) == 0 {
panic("Could not find string matching // +domain=.+ in apis/doc.go")
}
}
}

func parseDomainFromFiles(paths []string) string {
var domain string
for _, path := range paths {
if strings.HasSuffix(path, "pkg/apis") {
filePath := strings.Join([]string{build.Default.GOPATH, "src", path, "doc.go"}, "/")
lines := []string{}

file, err := os.Open(filePath)
if err != nil {
glog.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
if strings.HasPrefix(scanner.Text(), "//") {
lines = append(lines, strings.Replace(scanner.Text(), "// ", "", 1))
}
}
if err := scanner.Err(); err != nil {
glog.Fatal(err)
}

comments := Comments(lines)
domain = comments.getTag("domain", "=")
break
}
}
return domain
}
12 changes: 8 additions & 4 deletions cmd/kubebuilder-gen/internal/controllergen/inject.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,21 @@ func (d *injectGenerator) Imports(c *generator.Context) []string {

repo := d.Controllers[0].Repo
im := []string{
"time",
"github.com/kubernetes-sigs/kubebuilder/pkg/controller",
"k8s.io/client-go/rest",
repo + "/pkg/controller/sharedinformers",
repo + "/pkg/client/informers/externalversions",
repo + "/pkg/inject/args",
"rbacv1 \"k8s.io/api/rbac/v1\"",
"k8s.io/client-go/kubernetes/scheme",
"rscheme " + "\"" + repo + "/pkg/client/clientset/versioned/scheme\"",
}

if len(d.APIS.Groups) > 0 {
im = append(im, []string{
"time",
"k8s.io/client-go/kubernetes/scheme",
"rscheme " + "\"" + repo + "/pkg/client/clientset/versioned/scheme\""}...
)
}
// Import package for each controller
repos := map[string]string{}
for _, c := range d.Controllers {
Expand Down Expand Up @@ -100,7 +104,7 @@ func (d *injectGenerator) Finalize(context *generator.Context, w io.Writer) erro

var injectAPITemplate = `
func init() {
rscheme.AddToScheme(scheme.Scheme)
{{ $length := len .APIS.Groups }}{{if ne $length 0 }}rscheme.AddToScheme(scheme.Scheme){{ end }}
// Inject Informers
Inject = append(Inject, func(arguments args.InjectArgs) error {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package resource
package controller

import (
"fmt"
Expand All @@ -25,7 +25,20 @@ import (
"github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util"
)

func doController(dir string, args resourceTemplateArgs) bool {
type controllerTemplateArgs struct {
BoilerPlate string
Domain string
Group string
Version string
Kind string
Resource string
Repo string
PluralizedKind string
NonNamespacedKind bool
CoreType bool
}

func doController(dir string, args controllerTemplateArgs) bool {
path := filepath.Join(dir, "pkg", "controller", strings.ToLower(createutil.KindName), "controller.go")
fmt.Printf("\t%s\n", filepath.Join(
"pkg", "controller", strings.ToLower(createutil.KindName), "controller.go"))
Expand All @@ -42,11 +55,17 @@ import (
"github.com/kubernetes-sigs/kubebuilder/pkg/controller"
"github.com/kubernetes-sigs/kubebuilder/pkg/controller/types"
"k8s.io/client-go/tools/record"
{{if .CoreType}}
{{.Group}}{{.Version}}client "k8s.io/client-go/kubernetes/typed/{{.Group}}/{{.Version}}"
{{.Group}}{{.Version}}lister "k8s.io/client-go/listers/{{.Group}}/{{.Version}}"
{{.Group}}{{.Version}} "k8s.io/api/{{.Group}}/{{.Version}}"
{{.Group}}{{.Version}}informer "k8s.io/client-go/informers/{{.Group}}/{{.Version}}"
{{else}}
{{.Group}}{{.Version}}client "{{.Repo}}/pkg/client/clientset/versioned/typed/{{.Group}}/{{.Version}}"
{{.Group}}{{.Version}}lister "{{.Repo}}/pkg/client/listers/{{.Group}}/{{.Version}}"
{{.Group}}{{.Version}} "{{.Repo}}/pkg/apis/{{.Group}}/{{.Version}}"
{{.Group}}{{.Version}}informer "{{.Repo}}/pkg/client/informers/externalversions/{{.Group}}/{{.Version}}"
{{end}}
"{{.Repo}}/pkg/inject/args"
)
Expand All @@ -59,7 +78,7 @@ func (bc *{{.Kind}}Controller) Reconcile(k types.ReconcileKey) error {
log.Printf("Implement the Reconcile function on {{lower .Kind}}.{{.Kind}}Controller to reconcile %s\n", k.Name)
return nil
}
{{if .CoreType}}// +kubebuilder:informers:group={{ .Group }},version={{ .Version }},kind={{ .Kind }}{{end}}
// +kubebuilder:controller:group={{ .Group }},version={{ .Version }},kind={{ .Kind}},resource={{ .Resource }}
type {{.Kind}}Controller struct {
// INSERT ADDITIONAL FIELDS HERE
Expand All @@ -76,7 +95,8 @@ func ProvideController(arguments args.InjectArgs) (*controller.GenericController
// INSERT INITIALIZATIONS FOR ADDITIONAL FIELDS HERE
bc := &{{.Kind}}Controller{
{{lower .Kind}}Lister: arguments.ControllerManager.GetInformerProvider(&{{.Group}}{{.Version}}.{{.Kind}}{}).({{.Group}}{{.Version}}informer.{{.Kind}}Informer).Lister(),
{{lower .Kind}}client: arguments.Clientset.{{title .Group}}{{title .Version}}(),
{{if .CoreType}}{{lower .Kind}}client: arguments.KubernetesClientSet.{{title .Group}}{{title .Version}}(),{{else}}
{{lower .Kind}}client: arguments.Clientset.{{title .Group}}{{title .Version}}(),{{end}}
{{lower .Kind}}recorder: arguments.CreateRecorder("{{.Kind}}Controller"),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package resource
package controller

import (
"fmt"
Expand All @@ -25,7 +25,7 @@ import (
"github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util"
)

func doControllerTest(dir string, args resourceTemplateArgs) bool {
func doControllerTest(dir string, args controllerTemplateArgs) bool {
path := filepath.Join(dir, "pkg", "controller", strings.ToLower(createutil.KindName),
fmt.Sprintf("%s_suite_test.go",
strings.ToLower(createutil.KindName)))
Expand All @@ -52,16 +52,17 @@ import (
"github.com/kubernetes-sigs/kubebuilder/pkg/test"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"{{ .Repo }}/pkg/client/clientset/versioned"
{{if not .CoreType}}"{{ .Repo }}/pkg/client/clientset/versioned"{{end}}
"{{ .Repo }}/pkg/inject"
"{{ .Repo }}/pkg/inject/args"
)
var (
testenv *test.TestEnvironment
config *rest.Config
{{if not .CoreType}}
cs *versioned.Clientset
{{end}}
ks *kubernetes.Clientset
shutdown chan struct{}
ctrl *controller.GenericController
Expand All @@ -77,7 +78,9 @@ var _ = BeforeSuite(func() {
var err error
config, err = testenv.Start()
Expect(err).NotTo(HaveOccurred())
{{if not .CoreType}}
cs = versioned.NewForConfigOrDie(config)
{{end}}
ks = kubernetes.NewForConfigOrDie(config)
shutdown = make(chan struct{})
Expand Down Expand Up @@ -112,9 +115,13 @@ import (
"github.com/kubernetes-sigs/kubebuilder/pkg/controller/types"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
{{if .CoreType}}
. "k8s.io/api/{{.Group}}/{{.Version}}"
. "k8s.io/client-go/kubernetes/typed/{{.Group}}/{{.Version}}"
{{else}}
. "{{ .Repo }}/pkg/apis/{{ .Group }}/{{ .Version }}"
. "{{ .Repo }}/pkg/client/clientset/versioned/typed/{{ .Group }}/{{ .Version }}"
{{end}}
)
// EDIT THIS FILE!
Expand Down Expand Up @@ -153,7 +160,11 @@ var _ = Describe("{{ .Kind }} controller", func() {
}
// Create the instance
{{if .CoreType}}
client = ks.{{title .Group}}{{title .Version}}().{{ plural .Kind }}({{ if not .NonNamespacedKind }}"default"{{ end }})
{{else}}
client = cs.{{title .Group}}{{title .Version}}().{{ plural .Kind }}({{ if not .NonNamespacedKind }}"default"{{ end }})
{{end}}
_, err := client.Create(&instance)
Expect(err).ShouldNot(HaveOccurred())
Expand Down
113 changes: 113 additions & 0 deletions cmd/kubebuilder/create/controller/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
Copyright 2018 The Kubernetes 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 controller

import (
"fmt"
"log"
"os"

createutil "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util"
generatecmd "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/generate"
"github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util"
"github.com/markbates/inflect"
"github.com/spf13/cobra"
"strings"
)

type ControllerArguments struct {
nonNamespacedKind bool
generate bool
CoreType bool
}

func AddCreateController(cmd *cobra.Command) {
var c ControllerArguments

createControllerCmd := &cobra.Command{
Use: "controller",
Short: "Creates a controller for an API group, version and resource",
Long: `Creates a controller for an API group, version and resource.
Also creates:
- controller reconcile function
- tests for the controller
`,
Example: `# Create a controller for resource "Bee" in the "insect" group with version "v1beta"
kubebuilder create controller --group insect --version v1beta1 --kind Bee
# Create a controller for k8s core type "Deployment" in the "apps" group with version "v1beta2"
kubebuilder create controller --group apps --version v1beta2 --kind Deployment --core-type
`,
Run: c.RunCreateController,
}
createutil.RegisterResourceFlags(createControllerCmd)
createControllerCmd.Flags().BoolVar(&c.nonNamespacedKind, "non-namespaced", false, "if set, the API kind will be non namespaced")
createControllerCmd.Flags().BoolVar(&c.generate, "generate", true, "generate controller code")
createControllerCmd.Flags().BoolVar(&c.CoreType, "core-type", false, "generate controller for core type")
cmd.AddCommand(createControllerCmd)
}

func (c *ControllerArguments) RunCreateController(cmd *cobra.Command, args []string) {
if _, err := os.Stat("pkg"); err != nil {
log.Fatalf("could not find 'pkg' directory. must run kubebuilder init before creating controller")
}

util.GetDomain()
c.Validate()

cr := util.GetCopyright(createutil.Copyright)

fmt.Printf("Creating controller ...\n")
c.CreateController(cr)
if c.generate {
fmt.Printf("Generating code for new controller... " +
"Regenerate after editing controller files by running `kubebuilder generate clean; kubebuilder generate`.\n")
generatecmd.RunGenerate(cmd, args)
}
fmt.Printf("Next: Run the controller and create an instance with:\n" +
"$ GOBIN=${PWD}/bin go install ${PWD#$GOPATH/src/}/cmd/controller-manager\n" +
"$ bin/controller-manager --kubeconfig ~/.kube/config\n" +
"$ kubectl apply -f hack/sample/" + strings.ToLower(createutil.KindName) + ".yaml\n")
}

func (c *ControllerArguments) Validate() {
createutil.ValidateResourceFlags()
}

func (c *ControllerArguments) CreateController(boilerplate string) {
args := controllerTemplateArgs{
boilerplate,
util.Domain,
createutil.GroupName,
createutil.VersionName,
createutil.KindName,
createutil.ResourceName,
util.Repo,
inflect.NewDefaultRuleset().Pluralize(createutil.KindName),
c.nonNamespacedKind,
c.CoreType,
}

dir, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Edit your controller function...\n")
doController(dir, args)
doControllerTest(dir, args)
}
2 changes: 2 additions & 0 deletions cmd/kubebuilder/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package create

import (
"github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/config"
"github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/controller"
"github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/example"
"github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/resource"
"github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util"
Expand All @@ -41,6 +42,7 @@ func AddCreate(cmd *cobra.Command) {
resource.AddCreateResource(createCmd)
config.AddCreateConfig(createCmd)
example.AddCreateExample(createCmd)
controller.AddCreateController(createCmd)
}

func RunCreate(cmd *cobra.Command, args []string) {
Expand Down
10 changes: 4 additions & 6 deletions cmd/kubebuilder/create/resource/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import (
"fmt"
"log"
"os"

"strings"

controllerct "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/controller"
createutil "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/create/util"
generatecmd "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/generate"
"github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util"
Expand Down Expand Up @@ -113,13 +113,11 @@ func createResource(boilerplate string) {
doResourceTest(dir, args)

if controller {
fmt.Printf("Edit your controller function...\n")
doController(dir, args)
doControllerTest(dir, args)
fmt.Printf("Creating controller ...\n")
c := controllerct.ControllerArguments{CoreType: false}
c.CreateController(boilerplate)
}

//doDockerfile(filepath.Join(dir, "build"), args)
//doExample(dir, args)
fmt.Printf("Edit your sample resource instance...\n")
doSample(dir, args)
}
Loading

0 comments on commit 391d011

Please sign in to comment.