Skip to content

Commit

Permalink
pkg/plugin/v3: default to v1 CRDs and webhooks, with options to
Browse files Browse the repository at this point in the history
use v1beta1 via --crd-version and --webhook-version
  • Loading branch information
estroz committed Aug 19, 2020
1 parent 5c0b252 commit 5d98011
Show file tree
Hide file tree
Showing 65 changed files with 862 additions and 720 deletions.
10 changes: 2 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
# Makefile with some common workflow for dev, build and test
#
export GOPROXY?=https://proxy.golang.org/
CONTROLLER_GEN_BIN_PATH := $(shell which controller-gen)

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
Expand All @@ -44,18 +43,13 @@ build: ## Build the project locally
go build -o bin/kubebuilder ./cmd

.PHONY: install
install: ## Build and install the binary with the current source code. Use it to test your changes locally.
make build
install: build ## Build and install the binary with the current source code. Use it to test your changes locally.
cp ./bin/kubebuilder $(shell go env GOPATH)/bin/kubebuilder

##@ Development

.PHONY: generate
generate: ## Update/generate all mock data. You should run this commands to update the mock data after your changes.
# If exists, rremove the controller-gen installed locally. It ensures that the version which will be used
# is the version defined in the Makefile scaffolded.
- rm -rf $(CONTROLLER_GEN_BIN_PATH)
make generate-testdata
generate: generate-testdata
go mod tidy

.PHONY: generate-testdata
Expand Down
49 changes: 41 additions & 8 deletions generate_testdata.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.

set -e

source common.sh

build_kb() {
go build -o ./bin/kubebuilder sigs.k8s.io/kubebuilder/cmd
}

dirname_bin() {
echo "$(dirname $(command -v $1))"
}

#
# This function scaffolds test projects given a project name and
Expand All @@ -32,13 +33,12 @@ scaffold_test_project() {
local version=$2
local plugin=${3:-""}

testdata_dir=$(pwd)/testdata
local testdata_dir=$(pwd)/testdata
mkdir -p ./testdata/$project
rm -rf ./testdata/$project/*
pushd .
cd testdata/$project
kb=$testdata_dir/../bin/kubebuilder
oldgopath=$GOPATH
local kb=$testdata_dir/../bin/kubebuilder
# Set "--plugins $plugin" if $plugin is not null.
local plugin_flag="${plugin:+--plugins $plugin}"

Expand All @@ -51,8 +51,6 @@ scaffold_test_project() {
header_text "Starting to generate projects with version $version"
header_text "Generating $project"

export GO111MODULE=on
export PATH=$PATH:$(go env GOPATH)/bin
go mod init sigs.k8s.io/kubebuilder/testdata/$project # our repo autodetection will traverse up to the kb module if we don't do this

header_text "initializing $project ..."
Expand Down Expand Up @@ -91,16 +89,51 @@ scaffold_test_project() {
make all test
rm -f go.sum
rm -rf ./bin
export GOPATH=$oldgopath
# Remove $GOBIN so binaries are re-downloaded each time this function is called.
rm -rf "$GOBIN"
popd
}

set -e

build_kb

# Each project's Makefile will use binaries that already exist in $PATH instead of downloading them
# regardless of version, ex. controller-gen. Since tool versions may differ between plugin verions,
# set up the environment such that the correct tool versions are used for each test case.
header_text "Initializing temp Go environment"
gopath_old=$(go env GOPATH)
gobin_old=$(go env GOBIN)
gomodcache_old=$(go env GOMODCACHE)
path_old="$PATH"
gopath_new=$(mktemp -d)
declare -A env_list
env_list=(
[GO111MODULE]=on
# go v1.15+ has the GOMODCACHE variable, which is set such that existing local modules are used.
# If a lesser version is used, modules will be re-downloaded each time this script is invoked.
[GOMODCACHE]="${gomodcache_old:-${gopath_old}/pkg/mod}"
[GOPATH]="$gopath_new"
[GOBIN]="${gopath_new}/bin"
[PATH]="/usr/bin:$(dirname_bin make):$(dirname_bin go):${gopath_new}/bin"
)
for key in "${!env_list[@]}"; do
echo "$key=${env_list[$key]}"
export $key="${env_list[$key]}"
done

scaffold_test_project project-v2 2
scaffold_test_project project-v2-multigroup 2
scaffold_test_project project-v2-addon 2
scaffold_test_project project-v3 3-alpha go/v3-alpha
scaffold_test_project project-v3-multigroup 3-alpha go/v3-alpha
scaffold_test_project project-v3-addon 3-alpha go/v3-alpha

header_text "Cleaning up temp Go environment"

go clean -modcache
rm -rf "$gopath_new"
export GOPATH="$gopath_old"
export GOBIN="$gopath_old"
export GOMODCACHE="$gomodcache_old"
export PATH="$path_old"
9 changes: 8 additions & 1 deletion pkg/plugin/v3/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ type createAPIPlugin struct {

resource *resource.Options

// crdVersion determines which CRD version to configure the project with.
crdVersion string

// Check if we have to scaffold resource and/or controller
resourceFlag *pflag.Flag
controllerFlag *pflag.Flag
Expand Down Expand Up @@ -122,6 +125,8 @@ func (p *createAPIPlugin) BindFlags(fs *pflag.FlagSet) {
fs.StringVar(&p.resource.Group, "group", "", "resource Group")
fs.StringVar(&p.resource.Version, "version", "", "resource Version")
fs.BoolVar(&p.resource.Namespaced, "namespaced", true, "resource is namespaced")

fs.StringVar(&p.crdVersion, "crd-version", "v1", "CustomResourceDefinition version: [v1, v1beta1]")
}

func (p *createAPIPlugin) InjectConfig(c *config.Config) {
Expand Down Expand Up @@ -186,7 +191,9 @@ func (p *createAPIPlugin) GetScaffolder() (scaffold.Scaffolder, error) {

// Create the actual resource from the resource options
res := p.resource.NewResource(p.config, p.doResource)
return scaffolds.NewAPIScaffolder(p.config, string(bp), res, p.doResource, p.doController, plugins), nil
return scaffolds.NewAPIScaffolder(p.config, string(bp),
res, p.crdVersion, p.doResource, p.doController,
plugins), nil
}

func (p *createAPIPlugin) PostScaffold() error {
Expand Down
8 changes: 7 additions & 1 deletion pkg/plugin/v3/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ type initPlugin struct {
license string
owner string

// webhookVersion determines which webhook config version to configure the project with.
webhookVersion string

// flags
fetchDeps bool
skipGoVersionCheck bool
Expand Down Expand Up @@ -92,6 +95,9 @@ func (p *initPlugin) BindFlags(fs *pflag.FlagSet) {
"defaults to the go package of the current working directory.")
fs.StringVar(&p.config.Domain, "domain", "my.domain", "domain for groups")
fs.StringVar(&p.config.ProjectName, "project-name", "", "name of this project")

fs.StringVar(&p.webhookVersion, "webhook-version", "v1",
"{Mutating,Validating}WebhookConfiguration version: [v1, v1beta1]")
}

func (p *initPlugin) InjectConfig(c *config.Config) {
Expand Down Expand Up @@ -136,7 +142,7 @@ func (p *initPlugin) Validate() error {
}

func (p *initPlugin) GetScaffolder() (scaffold.Scaffolder, error) {
return scaffolds.NewInitScaffolder(p.config, p.license, p.owner), nil
return scaffolds.NewInitScaffolder(p.config, p.license, p.owner, p.webhookVersion), nil
}

func (p *initPlugin) PostScaffold() error {
Expand Down
11 changes: 8 additions & 3 deletions pkg/plugin/v3/scaffolds/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type apiScaffolder struct {
config *config.Config
boilerplate string
resource *resource.Resource
// crdVersion determines which version of CRD to scaffold: v1 (default) or v1beta1.
crdVersion string
// plugins is the list of plugins we should allow to transform our generated scaffolding
plugins []model.Plugin
// doResource indicates whether to scaffold API Resource or not
Expand All @@ -53,13 +55,16 @@ func NewAPIScaffolder(
config *config.Config,
boilerplate string,
res *resource.Resource,
crdVersion string,
doResource, doController bool,
plugins []model.Plugin,
) scaffold.Scaffolder {

return &apiScaffolder{
config: config,
boilerplate: boilerplate,
resource: res,
crdVersion: crdVersion,
plugins: plugins,
doResource: doResource,
doController: doController,
Expand Down Expand Up @@ -92,16 +97,16 @@ func (s *apiScaffolder) scaffold() error {
&samples.CRDSample{},
&rbac.CRDEditorRole{},
&rbac.CRDViewerRole{},
&crd.EnableWebhookPatch{},
&crd.EnableCAInjectionPatch{},
&crd.EnableWebhookPatch{CRDVersion: s.crdVersion},
&crd.EnableCAInjectionPatch{CRDVersion: s.crdVersion},
); err != nil {
return fmt.Errorf("error scaffolding APIs: %v", err)
}

if err := machinery.NewScaffold().Execute(
s.newUniverse(),
&crd.Kustomization{},
&crd.KustomizeConfig{},
&crd.KustomizeConfig{CRDVersion: s.crdVersion},
); err != nil {
return fmt.Errorf("error scaffolding kustomization: %v", err)
}
Expand Down
24 changes: 15 additions & 9 deletions pkg/plugin/v3/scaffolds/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const (
// ControllerRuntimeVersion is the kubernetes-sigs/controller-runtime version to be used in the project
ControllerRuntimeVersion = "v0.6.2"
// ControllerToolsVersion is the kubernetes-sigs/controller-tools version to be used in the project
ControllerToolsVersion = "v0.3.0"
ControllerToolsVersion = "v0.4.0"
// KustomizeVersion is the kubernetes-sigs/kustomize version to be used in the project
KustomizeVersion = "v3.5.4"

Expand All @@ -53,15 +53,21 @@ type initScaffolder struct {
boilerplatePath string
license string
owner string
// webhookVersion determines which version of webhook to scaffold: v1 (default) or v1beta1.
webhookVersion string
}

// NewInitScaffolder returns a new Scaffolder for project initialization operations
func NewInitScaffolder(config *config.Config, license, owner string) scaffold.Scaffolder {
func NewInitScaffolder(config *config.Config,
license, owner string,
webhookVersion string) scaffold.Scaffolder {

return &initScaffolder{
config: config,
boilerplatePath: filepath.Join("hack", "boilerplate.go.txt"),
license: license,
owner: owner,
webhookVersion: webhookVersion,
}
}

Expand Down Expand Up @@ -99,11 +105,15 @@ func (s *initScaffolder) scaffold() error {
return machinery.NewScaffold().Execute(
s.newUniverse(string(boilerplate)),
&templates.GitIgnore{},
&rbac.KustomizeRBAC{},
&rbac.AuthProxyRole{},
&rbac.AuthProxyRoleBinding{},
&kdefault.AuthProxyPatch{},
&rbac.AuthProxyService{},
&rbac.ManagerRoleBinding{},
&rbac.LeaderElectionRole{},
&rbac.LeaderElectionRoleBinding{},
&rbac.ClientClusterRole{},
&manager.Kustomization{},
&manager.Config{Image: imageName},
&templates.Main{},
&templates.GoMod{ControllerRuntimeVersion: ControllerRuntimeVersion},
Expand All @@ -116,16 +126,12 @@ func (s *initScaffolder) scaffold() error {
&templates.Dockerfile{},
&templates.DockerignoreFile{},
&kdefault.Kustomize{},
&kdefault.AuthProxyPatch{},
&kdefault.ManagerWebhookPatch{},
&rbac.ManagerRoleBinding{},
&rbac.LeaderElectionRole{},
&rbac.LeaderElectionRoleBinding{},
&rbac.KustomizeRBAC{},
&manager.Kustomization{},
&kdefault.InjectCAPatch{WebhookVersion: s.webhookVersion},
&webhook.Kustomization{},
&webhook.KustomizeConfigWebhook{},
&webhook.Service{},
&kdefault.InjectCAPatch{},
&prometheus.Kustomization{},
&prometheus.ServiceMonitor{},
&certmanager.CertManager{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func (r *{{ .Resource.Kind }}) SetupWebhookWithManager(mgr ctrl.Manager) error {

//nolint:lll
defaultingWebhookTemplate = `
// +kubebuilder:webhook:path=/mutate-{{ .GroupDomainWithDash }}-{{ .Resource.Version }}-{{ lower .Resource.Kind }},mutating=true,failurePolicy=fail,groups={{ .Resource.Domain }},resources={{ .Resource.Plural }},verbs=create;update,versions={{ .Resource.Version }},name=m{{ lower .Resource.Kind }}.kb.io
// +kubebuilder:webhook:path=/mutate-{{ .GroupDomainWithDash }}-{{ .Resource.Version }}-{{ lower .Resource.Kind }},mutating=true,failurePolicy=fail,sideEffects=None,groups={{ .Resource.Domain }},resources={{ .Resource.Plural }},verbs=create;update,versions={{ .Resource.Version }},name=m{{ lower .Resource.Kind }}.kb.io
var _ webhook.Defaulter = &{{ .Resource.Kind }}{}
Expand All @@ -112,7 +112,7 @@ func (r *{{ .Resource.Kind }}) Default() {
//nolint:lll
validatingWebhookTemplate = `
// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
// +kubebuilder:webhook:verbs=create;update,path=/validate-{{ .GroupDomainWithDash }}-{{ .Resource.Version }}-{{ lower .Resource.Kind }},mutating=false,failurePolicy=fail,groups={{ .Resource.Domain }},resources={{ .Resource.Plural }},versions={{ .Resource.Version }},name=v{{ lower .Resource.Kind }}.kb.io
// +kubebuilder:webhook:verbs=create;update,path=/validate-{{ .GroupDomainWithDash }}-{{ .Resource.Version }}-{{ lower .Resource.Kind }},mutating=false,failurePolicy=fail,sideEffects=None,groups={{ .Resource.Domain }},resources={{ .Resource.Plural }},versions={{ .Resource.Version }},name=v{{ lower .Resource.Kind }}.kb.io
var _ webhook.Validator = &{{ .Resource.Kind }}{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ var _ file.Template = &EnableCAInjectionPatch{}
type EnableCAInjectionPatch struct {
file.TemplateMixin
file.ResourceMixin

// Version of CRD patch to generate.
CRDVersion string
}

// SetTemplateDefaults implements input.Template
Expand All @@ -37,12 +40,28 @@ func (f *EnableCAInjectionPatch) SetTemplateDefaults() error {
}
f.Path = f.Resource.Replacer().Replace(f.Path)

f.TemplateBody = enableCAInjectionPatchTemplate
switch f.CRDVersion {
case v1beta1:
f.TemplateBody = enableCAInjectionPatchTemplatev1beta1
default:
f.TemplateBody = enableCAInjectionPatchTemplatev1
}

return nil
}

const enableCAInjectionPatchTemplate = `# The following patch adds a directive for certmanager to inject CA into the CRD
//nolint:lll
const enableCAInjectionPatchTemplatev1 = `# The following patch adds a directive for certmanager to inject CA into the CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
name: {{ .Resource.Plural }}.{{ .Resource.Domain }}
`

//nolint:lll
const enableCAInjectionPatchTemplatev1beta1 = `# The following patch adds a directive for certmanager to inject CA into the CRD
# CRD conversion requires k8s 1.13 or later.
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
Expand Down
Loading

0 comments on commit 5d98011

Please sign in to comment.