diff --git a/.gitignore b/.gitignore index ad5f5fdd40..523d047e10 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ kubectl-kyverno /release .DS_Store .tools +.gopath diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index cdd30ccdb6..802b34072b 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -362,7 +362,28 @@ We are using code generation tools to create the following portions of code: ### Generating kubernetes API client -TODO +Based on the [APIs golang code definitions](./api), you can generate the corresponding Kubernetes client by running: +```console +# generate clientset, listers and informers +make codegen-client-all +``` +or +```console +# generate clientset +make codegen-client-clientset +``` +or +```console +# generate listers +make codegen-client-listers +``` +or +```console +# generate informers +make codegen-client-informers +``` + +This will output generated files in the [/pkg/client](./pkg/client) package. ### Generating API deep copy functions diff --git a/Makefile b/Makefile index b872f2bb8c..53e8e690ba 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,10 @@ KIND := $(TOOLS_DIR)/kind KIND_VERSION := v0.14.0 CONTROLLER_GEN := $(TOOLS_DIR)/controller-gen CONTROLLER_GEN_VERSION := v0.9.1-0.20220629131006-1878064c4cdf +CLIENT_GEN := $(TOOLS_DIR)/client-gen +LISTER_GEN := $(TOOLS_DIR)/lister-gen +INFORMER_GEN := $(TOOLS_DIR)/informer-gen +CODE_GEN_VERSION := v0.19.0 GEN_CRD_API_REFERENCE_DOCS := $(TOOLS_DIR)/gen-crd-api-reference-docs GEN_CRD_API_REFERENCE_DOCS_VERSION := latest GO_ACC := $(TOOLS_DIR)/go-acc @@ -43,7 +47,7 @@ HELM_DOCS := $(TOOLS_DIR)/helm-docs HELM_DOCS_VERSION := v1.6.0 KO := $(TOOLS_DIR)/ko KO_VERSION := v0.12.0 -TOOLS := $(KIND) $(CONTROLLER_GEN) $(GEN_CRD_API_REFERENCE_DOCS) $(GO_ACC) $(KUSTOMIZE) $(GOIMPORTS) $(HELM_DOCS) $(KO) +TOOLS := $(KIND) $(CONTROLLER_GEN) $(CLIENT_GEN) $(LISTER_GEN) $(INFORMER_GEN) $(GEN_CRD_API_REFERENCE_DOCS) $(GO_ACC) $(KUSTOMIZE) $(GOIMPORTS) $(HELM_DOCS) $(KO) ifeq ($(GOOS), darwin) SED := gsed else @@ -56,6 +60,15 @@ $(KIND): $(CONTROLLER_GEN): @GOBIN=$(TOOLS_DIR) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_VERSION) +$(CLIENT_GEN): + @GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/client-gen@$(CODE_GEN_VERSION) + +$(LISTER_GEN): + @GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/lister-gen@$(CODE_GEN_VERSION) + +$(INFORMER_GEN): + @GOBIN=$(TOOLS_DIR) go install k8s.io/code-generator/cmd/informer-gen@$(CODE_GEN_VERSION) + $(GEN_CRD_API_REFERENCE_DOCS): @GOBIN=$(TOOLS_DIR) go install github.com/ahmetb/gen-crd-api-reference-docs@$(GEN_CRD_API_REFERENCE_DOCS_VERSION) @@ -286,12 +299,49 @@ docker-publish-all-dev: docker-publish-kyvernopre-dev docker-publish-kyverno-dev # CODEGEN # ########### +GOPATH_SHIM := ${PWD}/.gopath +PACKAGE_SHIM := $(GOPATH_SHIM)/src/$(PACKAGE) +OUT_PACKAGE := $(PACKAGE)/pkg/client +INPUT_DIRS := $(PACKAGE)/api/kyverno/v1,$(PACKAGE)/api/kyverno/v1beta1,$(PACKAGE)/api/kyverno/v1alpha2,$(PACKAGE)/api/policyreport/v1alpha2 +CLIENTSET_PACKAGE := $(OUT_PACKAGE)/clientset +LISTERS_PACKAGE := $(OUT_PACKAGE)/listers +INFORMERS_PACKAGE := $(OUT_PACKAGE)/informers + +$(GOPATH_SHIM): + @echo Create gopath shim... + @mkdir -p $(GOPATH_SHIM) + +.INTERMEDIATE: $(PACKAGE_SHIM) +$(PACKAGE_SHIM): $(GOPATH_SHIM) + @echo Create package shim... + @mkdir -p $(GOPATH_SHIM)/src/github.com/kyverno && ln -s -f ${PWD} $(PACKAGE_SHIM) + +.PHONY: codegen-client-clientset +codegen-client-clientset: $(PACKAGE_SHIM) $(CLIENT_GEN) ## Generate clientset + @echo Generate clientset... + @GOPATH=$(GOPATH_SHIM) $(CLIENT_GEN) --go-header-file ./scripts/boilerplate.go.txt --clientset-name versioned --output-package $(CLIENTSET_PACKAGE) --input-base "" --input $(INPUT_DIRS) + +.PHONY: codegen-client-listers +codegen-client-listers: $(PACKAGE_SHIM) $(LISTER_GEN) ## Generate listers + @echo Generate listers... + @GOPATH=$(GOPATH_SHIM) $(LISTER_GEN) --go-header-file ./scripts/boilerplate.go.txt --output-package $(LISTERS_PACKAGE) --input-dirs $(INPUT_DIRS) + +.PHONY: codegen-client-informers +codegen-client-informers: $(PACKAGE_SHIM) $(INFORMER_GEN) ## Generate informers + @echo Generate informers... + @GOPATH=$(GOPATH_SHIM) $(INFORMER_GEN) --go-header-file ./scripts/boilerplate.go.txt --output-package $(INFORMERS_PACKAGE) --input-dirs $(INPUT_DIRS) --versioned-clientset-package $(CLIENTSET_PACKAGE)/versioned --listers-package $(LISTERS_PACKAGE) + +.PHONY: codegen-client-all +codegen-client-all: codegen-client-clientset codegen-client-listers codegen-client-informers ## Generate clientset, listers and informers + .PHONY: codegen-crds-kyverno codegen-crds-kyverno: $(CONTROLLER_GEN) ## Generate Kyverno CRDs + @echo Generate kyverno crds... @$(CONTROLLER_GEN) crd paths=./api/kyverno/... crd:crdVersions=v1 output:dir=./config/crds .PHONY: codegen-crds-report codegen-crds-report: $(CONTROLLER_GEN) ## Generate policy reports CRDs + @echo Generate policy reports crds... @$(CONTROLLER_GEN) crd paths=./api/policyreport/... crd:crdVersions=v1 output:dir=./config/crds .PHONY: codegen-crds-all @@ -299,17 +349,19 @@ codegen-crds-all: codegen-crds-kyverno codegen-crds-report ## Generate all CRDs .PHONY: codegen-deepcopy-kyverno codegen-deepcopy-kyverno: $(CONTROLLER_GEN) $(GOIMPORTS) ## Generate Kyverno deep copy functions + @echo Generate kyverno deep copy functions... @$(CONTROLLER_GEN) object:headerFile="scripts/boilerplate.go.txt" paths="./api/kyverno/..." && $(GOIMPORTS) -w ./api/kyverno .PHONY: codegen-deepcopy-report codegen-deepcopy-report: $(CONTROLLER_GEN) $(GOIMPORTS) ## Generate policy reports deep copy functions + @echo Generate policy reports deep copy functions... @$(CONTROLLER_GEN) object:headerFile="scripts/boilerplate.go.txt" paths="./api/policyreport/..." && $(GOIMPORTS) -w ./api/policyreport .PHONY: codegen-deepcopy-all codegen-deepcopy-all: codegen-deepcopy-kyverno codegen-deepcopy-report ## Generate all deep copy functions .PHONY: codegen-all -codegen-all: codegen-deepcopy-all codegen-crds-all ## Generate all CRDs and deep copy functions +codegen-all: codegen-deepcopy-all codegen-crds-all codegen-client-all ## Generate clientset, listers, informers, all CRDs and deep copy functions ################################## # KYVERNO diff --git a/api/kyverno/v1/zz_generated.deepcopy.go b/api/kyverno/v1/zz_generated.deepcopy.go index 7a7f2e6581..5d08ca655e 100755 --- a/api/kyverno/v1/zz_generated.deepcopy.go +++ b/api/kyverno/v1/zz_generated.deepcopy.go @@ -2,6 +2,8 @@ // +build !ignore_autogenerated /* +Copyright 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 diff --git a/api/kyverno/v1alpha2/zz_generated.deepcopy.go b/api/kyverno/v1alpha2/zz_generated.deepcopy.go index a94a3d9338..2e80213c0e 100644 --- a/api/kyverno/v1alpha2/zz_generated.deepcopy.go +++ b/api/kyverno/v1alpha2/zz_generated.deepcopy.go @@ -2,6 +2,8 @@ // +build !ignore_autogenerated /* +Copyright 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 diff --git a/api/kyverno/v1beta1/zz_generated.deepcopy.go b/api/kyverno/v1beta1/zz_generated.deepcopy.go index 8fdb176a9f..ed4f1b2fd2 100644 --- a/api/kyverno/v1beta1/zz_generated.deepcopy.go +++ b/api/kyverno/v1beta1/zz_generated.deepcopy.go @@ -2,6 +2,8 @@ // +build !ignore_autogenerated /* +Copyright 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 diff --git a/api/policyreport/v1alpha2/zz_generated.deepcopy.go b/api/policyreport/v1alpha2/zz_generated.deepcopy.go index 4023b18f15..366791c030 100644 --- a/api/policyreport/v1alpha2/zz_generated.deepcopy.go +++ b/api/policyreport/v1alpha2/zz_generated.deepcopy.go @@ -2,6 +2,8 @@ // +build !ignore_autogenerated /* +Copyright 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 diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index 876339f7a9..5752ca53ba 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -25,11 +25,13 @@ import ( kyvernov1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha2" kyvernov1beta1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1beta1" wgpolicyk8sv1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/policyreport/v1alpha2" + discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" ) type Interface interface { + Discovery() discovery.DiscoveryInterface KyvernoV1() kyvernov1.KyvernoV1Interface KyvernoV1beta1() kyvernov1beta1.KyvernoV1beta1Interface KyvernoV1alpha2() kyvernov1alpha2.KyvernoV1alpha2Interface @@ -39,6 +41,7 @@ type Interface interface { // Clientset contains the clients for groups. Each group has exactly one // version included in a Clientset. type Clientset struct { + *discovery.DiscoveryClient kyvernoV1 *kyvernov1.KyvernoV1Client kyvernoV1beta1 *kyvernov1beta1.KyvernoV1beta1Client kyvernoV1alpha2 *kyvernov1alpha2.KyvernoV1alpha2Client @@ -65,6 +68,14 @@ func (c *Clientset) Wgpolicyk8sV1alpha2() wgpolicyk8sv1alpha2.Wgpolicyk8sV1alpha return c.wgpolicyk8sV1alpha2 } +// Discovery retrieves the DiscoveryClient +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + if c == nil { + return nil + } + return c.DiscoveryClient +} + // NewForConfig creates a new Clientset for the given config. // If config's RateLimiter is not set and QPS and Burst are acceptable, // NewForConfig will generate a rate-limiter in configShallowCopy. @@ -95,6 +106,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { return nil, err } + cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) + if err != nil { + return nil, err + } return &cs, nil } @@ -107,6 +122,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { cs.kyvernoV1alpha2 = kyvernov1alpha2.NewForConfigOrDie(c) cs.wgpolicyk8sV1alpha2 = wgpolicyk8sv1alpha2.NewForConfigOrDie(c) + cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) return &cs } @@ -118,5 +134,6 @@ func New(c rest.Interface) *Clientset { cs.kyvernoV1alpha2 = kyvernov1alpha2.New(c) cs.wgpolicyk8sV1alpha2 = wgpolicyk8sv1alpha2.New(c) + cs.DiscoveryClient = discovery.NewDiscoveryClient(c) return &cs } diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index cf3c1a08f4..a93604b6d1 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -43,14 +43,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{ // AddToScheme adds all types of this clientset into the given scheme. This allows composition // of clientsets, like in: // -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) // -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index 776190e352..9fbeaa98f0 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -43,14 +43,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{ // AddToScheme adds all types of this clientset into the given scheme. This allows composition // of clientsets, like in: // -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) // -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. diff --git a/scripts/boilerplate.go.txt b/scripts/boilerplate.go.txt index b4ede5d4b6..0926592d38 100644 --- a/scripts/boilerplate.go.txt +++ b/scripts/boilerplate.go.txt @@ -1,4 +1,6 @@ /* +Copyright 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 diff --git a/scripts/update-codegen.sh b/scripts/update-codegen.sh deleted file mode 100755 index 8fdc29c637..0000000000 --- a/scripts/update-codegen.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -set -o errexit -set -o nounset -set -o pipefail - -case "$(uname -s)" in - Linux*) linkutil=readlink;; - Darwin*) linkutil=greadlink;; - *) machine="UNKNOWN:${unameOut}" -esac - -# get nirmata root -NIRMATA_DIR=$(dirname ${BASH_SOURCE})/.. -NIRMATA_ROOT=$(${linkutil} -f ${NIRMATA_DIR}) - -# instructions to build project https://github.com/kyverno/kyverno/wiki/Building - -# get relative path to code generation script -CODEGEN_PKG="${GOPATH}/src/k8s.io/code-generator" - -# get relative path of nirmata -NIRMATA_PKG=${NIRMATA_ROOT#"${GOPATH}/src/"} - -# perform code generation -${CODEGEN_PKG}/generate-groups.sh \ - "client,informer,lister" \ - ${NIRMATA_PKG}/pkg/client \ - ${NIRMATA_PKG}/api \ - "kyverno:v1 kyverno:v1beta1 kyverno:v1alpha2 policyreport:v1alpha2"