Skip to content
Permalink
Browse files

Switch v2 scaffolding to controller-tools 0.2.0

This switches the v2 scaffolding to make use of (the upcoming) controller-tools
v0.2.0, which has rewritten generators and a bundled deepcopy.  It's
currently using a prerelease version.  controller-tools is now consumed
as a binary, available via `go get` with modules turned on.
  • Loading branch information...
DirectXMan12 committed May 4, 2019
1 parent 7bf07e7 commit 612671c99a1aa6aaca1b7a4151a593bc48bf2a48
@@ -126,9 +126,6 @@ function fetch_tools {
curl -sL ${kb_tools_download_url} -o "$kb_tools_archive_path"
fi
tar -zvxf "$kb_tools_archive_path" -C "$tmp_root/"

header_text "fetching controller-gen from source (till it's packaged)"
GO111MODULE=on go get sigs.k8s.io/controller-tools/cmd/controller-gen@crdgeneratortmp
}

function build_kb {
@@ -58,7 +58,6 @@ scaffold_test_project() {
$kb create api --group policy --version v1beta1 --kind HealthCheckPolicy --example=false --controller=true --resource=true --namespaced=false --make=false
elif [ $version == "2" ]; then
export GO111MODULE=on
go get sigs.k8s.io/controller-tools/cmd/controller-gen@crdgeneratortmp
export PATH=$PATH:$(go env GOPATH)/bin
go mod init sigs.k8s.io/kubebuilder/testdata/project_v2 # our repo autodetection will traverse up to the kb module if we don't do this

@@ -148,18 +148,13 @@ func (api *API) scaffoldV2() error {

err := (&Scaffold{}).Execute(
input.Options{},
&resourcev2.ResourceDoc{
Input: input.Input{
Path: filepath.Join("api", r.Version, "doc.go"),
},
Resource: r},
&resourcev1.Types{
&resourcev2.Types{
Input: input.Input{
Path: filepath.Join("api", r.Version, fmt.Sprintf("%s_types.go", strings.ToLower(r.Kind))),
},
Resource: r},
&resourcev2.Group{Resource: r},
&resourcev1.CRDSample{Resource: r},
&resourcev2.CRDSample{Resource: r},
&crdv2.EnableWebhookPatch{Resource: r},
)
if err != nil {
@@ -188,11 +188,12 @@ func (p *V2Project) Scaffold() error {
&managerv2.Config{Image: imgName},
&scaffoldv2.Main{},
&scaffoldv2.GoMod{},
&scaffoldv2.Doc{},
&scaffoldv2.Makefile{Image: imgName},
&scaffoldv2.Dockerfile{},
&scaffoldv2.Kustomize{},
&scaffoldv2.ManagerWebhookPatch{},
&scaffoldv2.ManagerRoleBinding{},
&scaffoldv2.KustomizeRBAC{},
&managerv2.Kustomization{},
&webhook.Kustomization{},
&webhook.KustomizeConfigWebhook{},
@@ -29,7 +29,6 @@ import (

"golang.org/x/tools/imports"
yaml "gopkg.in/yaml.v2"
"sigs.k8s.io/controller-tools/pkg/util"
"sigs.k8s.io/kubebuilder/pkg/scaffold/input"
"sigs.k8s.io/kubebuilder/pkg/scaffold/project"
)
@@ -85,7 +85,7 @@ func (a *Controller) UpdateMain(path string) error {

reconcilerSetupCodeFragment := fmt.Sprintf(`err = (&controllers.%sReconciler{
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("%s-controller"),
Log: ctrl.Log.WithName("controllers").WithName("%s"),
}).SetupWithManager(mgr)
if err != nil {
setupLog.Error(err, "unable to create controller", "controller", "%s")
@@ -158,9 +158,10 @@ type {{ .Resource.Kind }}Reconciler struct {
// +kubebuilder:rbac:groups={{.GroupDomain}},resources={{ .Plural }},verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups={{.GroupDomain}},resources={{ .Plural }}/status,verbs=get;update;patch
func (r *{{ .Resource.Kind }}Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
_ = context.Background()
_ = r.Log.WithValues("{{ .Resource.Kind }}", req.NamespacedName)
_ = r.Log.WithValues("{{ .Resource.Kind | lower }}", req.NamespacedName)
// your logic here
@@ -36,7 +36,7 @@ type EnableWebhookPatch struct {
// GetInput implements input.File
func (p *EnableWebhookPatch) GetInput() (input.Input, error) {
if p.Path == "" {
p.Path = filepath.Join("config", "crds", "patches",
p.Path = filepath.Join("config", "crd", "patches",
fmt.Sprintf("webhook_in_%s.yaml", strings.ToLower(p.Resource.Kind)))
}
p.TemplateBody = enableWebhookPatchTemplate
@@ -21,6 +21,8 @@ import (
"path/filepath"
"strings"

"github.com/markbates/inflect"

"sigs.k8s.io/kubebuilder/pkg/scaffold/input"
"sigs.k8s.io/kubebuilder/pkg/scaffold/v1/resource"
"sigs.k8s.io/kubebuilder/pkg/scaffold/v2/internal"
@@ -44,7 +46,7 @@ type Kustomization struct {
// GetInput implements input.File
func (c *Kustomization) GetInput() (input.Input, error) {
if c.Path == "" {
c.Path = filepath.Join("config", "crds", "kustomization.yaml")
c.Path = filepath.Join("config", "crd", "kustomization.yaml")
}
c.TemplateBody = kustomizationTemplate
c.Input.IfExistsAction = input.Error
@@ -53,13 +55,16 @@ func (c *Kustomization) GetInput() (input.Input, error) {

func (c *Kustomization) Update() error {
if c.Path == "" {
c.Path = filepath.Join("config", "crds", "kustomization.yaml")
c.Path = filepath.Join("config", "crd", "kustomization.yaml")
}

kustomizeResourceCodeFragment := fmt.Sprintf(`- bases/%s_%s.yaml
`, c.Resource.Group, strings.ToLower(c.Resource.Kind))
kustomizePatchCodeFragment := fmt.Sprintf(`#- patches/webhook_in_%s.yaml
`, strings.ToLower(c.Resource.Kind))
// TODO(directxman12): not technically valid if something changes from the default
// (we'd need to parse the markers)
rs := inflect.NewDefaultRuleset()
plural := rs.Pluralize(strings.ToLower(c.Resource.Kind))

kustomizeResourceCodeFragment := fmt.Sprintf("- bases/%s.%s_%s.yaml\n", c.Resource.Group, c.Domain, plural)
kustomizePatchCodeFragment := fmt.Sprintf("#- patches/webhook_in_%s.yaml\n", plural)

return internal.InsertStringsInFile(c.Path,
kustomizeResourceScaffoldMarker, kustomizeResourceCodeFragment,
@@ -32,7 +32,7 @@ type KustomizeConfig struct {
// GetInput implements input.File
func (c *KustomizeConfig) GetInput() (input.Input, error) {
if c.Path == "" {
c.Path = filepath.Join("config", "crds", "kustomizeconfig.yaml")
c.Path = filepath.Join("config", "crd", "kustomizeconfig.yaml")
}
c.TemplateBody = kustomizeConfigTemplate
c.Input.IfExistsAction = input.Error
@@ -0,0 +1,62 @@
/*
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 v2

import (
"fmt"
"path/filepath"
"strings"

"sigs.k8s.io/kubebuilder/pkg/scaffold/input"
"sigs.k8s.io/kubebuilder/pkg/scaffold/v1/resource"
)

var _ input.File = &CRDSample{}

// CRDSample scaffolds a manifest for CRD sample.
type CRDSample struct {
input.Input

// Resource is a resource in the API group
Resource *resource.Resource
}

// GetInput implements input.File
func (c *CRDSample) GetInput() (input.Input, error) {
if c.Path == "" {
c.Path = filepath.Join("config", "samples", fmt.Sprintf(
"%s_%s_%s.yaml", c.Resource.Group, c.Resource.Version, strings.ToLower(c.Resource.Kind)))
}

c.IfExistsAction = input.Error
c.TemplateBody = crdSampleTemplate
return c.Input, nil
}

// Validate validates the values
func (c *CRDSample) Validate() error {
return c.Resource.Validate()
}

var crdSampleTemplate = `apiVersion: {{ .Resource.Group }}.{{ .Domain }}/{{ .Resource.Version }}
kind: {{ .Resource.Kind }}
metadata:
name: {{ lower .Resource.Kind }}-sample
spec:
# Add fields here
foo: bar
`
@@ -25,7 +25,7 @@ import (

var _ input.File = &Group{}

// Group scaffolds the pkg/apis/group/group.go
// Group scaffolds the api/<version>/groupversion_info.go
type Group struct {
input.Input

@@ -50,10 +50,7 @@ func (g *Group) Validate() error {
var groupTemplate = `{{ .Boilerplate }}
// Package {{.Resource.Version}} contains API Schema definitions for the {{ .Resource.Group }} {{.Resource.Version}} API group
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen={{ .Repo }}/pkg/apis/{{ .Resource.Group }}
// +k8s:defaulter-gen=TypeMeta
// +kubebuilder:object:generate=true
// +groupName={{ .Resource.Group }}.{{ .Domain }}
package {{ .Resource.Version }}
@@ -66,12 +66,12 @@ namePrefix: {{.Prefix}}-
# someName: someValue
bases:
- ../crds
- ../crd
- ../rbac
- ../manager
- ../webhook
# - ../webhook
# Comment the next line if you want to disable cert-manager
- ../certmanager
# - ../certmanager
patches:
- manager_image_patch.yaml
@@ -27,9 +27,6 @@ type Makefile struct {
input.Input
// Image is controller manager image name
Image string

// path for controller-tools pkg
ControllerToolsPath string
}

// GetInput implements input.File
@@ -40,9 +37,6 @@ func (c *Makefile) GetInput() (input.Input, error) {
if c.Image == "" {
c.Image = "controller:latest"
}
if c.ControllerToolsPath == "" {
c.ControllerToolsPath = "vendor/sigs.k8s.io/controller-tools"
}
c.TemplateBody = makefileTemplate
c.Input.IfExistsAction = input.Error
return c.Input, nil
@@ -51,8 +45,10 @@ func (c *Makefile) GetInput() (input.Input, error) {
var makefileTemplate = `
# Image URL to use all building/pushing image targets
IMG ?= {{ .Image }}
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
CRD_OPTIONS ?= "crd:trivialVersions=true"
all: test manager
all: manager
# Run tests
test: generate fmt vet manifests
@@ -68,34 +64,28 @@ run: generate fmt vet
# Install CRDs into a cluster
install: manifests
kubectl apply -f config/crds/bases
kubectl apply -f config/crd/bases
# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
deploy: manifests
kubectl apply -f config/crds/bases
kubectl apply -f config/crd/bases
kustomize build config/default | kubectl apply -f -
# Generate manifests e.g. CRD, RBAC etc.
manifests:
# TODO(droot): controller-gen will require fix to take new api-path as input, so disabling this for now
#
# go run {{ .ControllerToolsPath }}/cmd/controller-gen/main.go all --output-dir=config/crds/bases/
manifests: controller-gen
$(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./api/...;./controllers/..." output:crd:artifacts:config=config/crd/bases
# Run go fmt against code
fmt:
go fmt ./api/... ./controllers/...
go fmt ./...
# Run go vet against code
vet:
go vet ./api/... ./controllers/...
go vet ./...
# Generate code
generate:
ifndef GOPATH
$(error GOPATH not defined, please define GOPATH. Run "go help gopath" to learn more about GOPATH)
endif
go run ./vendor/k8s.io/code-generator/cmd/deepcopy-gen/main.go -O zz_generated.deepcopy --go-header-file ./hack/boilerplate.go.txt -i ./api/...
generate: controller-gen
$(CONTROLLER_GEN) object:headerFile=./hack/boilerplate.go.txt paths=./api/...
# Build the docker image
docker-build: test
@@ -106,4 +96,14 @@ docker-build: test
# Push the docker image
docker-push:
docker push ${IMG}
# find or download controller-gen
# download controller-gen if necessary
controller-gen:
ifeq (, $(shell which controller-gen))
go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.0-alpha.1
CONTROLLER_GEN=$(shell go env GOPATH)/bin/controller-gen
else
CONTROLLER_GEN=$(shell which controller-gen)
endif
`
@@ -43,17 +43,17 @@ var kustomizeManagerTemplate = `resources:
- manager.yaml
# the following config is for teaching kustomize how to do var substitution
vars:
- name: NAMESPACE
objref:
kind: Service
version: v1
name: webhook-service
fieldref:
fieldpath: metadata.namespace
- name: SERVICENAME
objref:
kind: Service
version: v1
name: webhook-service
# vars:
# - name: NAMESPACE
# objref:
# kind: Service
# version: v1
# name: webhook-service
# fieldref:
# fieldpath: metadata.namespace
# - name: SERVICENAME
# objref:
# kind: Service
# version: v1
# name: webhook-service
`
Oops, something went wrong.

0 comments on commit 612671c

Please sign in to comment.
You can’t perform that action at this time.