Skip to content

Commit acb5e00

Browse files
authored
Merge pull request #38 from wallrj/kubebuilder-upgrade
Kubebuilder upgrade
2 parents 15d40eb + 778259c commit acb5e00

27 files changed

+435
-175
lines changed

.dockerignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file
2+
# Ignore build and test binaries.
3+
bin/
4+
testbin/
5+
build/

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*.so
77
*.dylib
88
bin
9+
testbin/*
10+
Dockerfile.cross
911

1012
# Test binary, build with `go test -c`
1113
*.test

Dockerfile

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Build the manager binary
22
FROM golang:1.20 as builder
3+
ARG TARGETOS
4+
ARG TARGETARCH
35

46
WORKDIR /workspace
57
# Copy the Go Modules manifests
@@ -14,9 +16,13 @@ COPY main.go main.go
1416
COPY api/ api/
1517
COPY internal/ internal/
1618

19+
# the GOARCH has not a default value to allow the binary be built according to the host where the command
20+
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
21+
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
22+
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
1723
ENV CGO_ENABLED=0
18-
ENV GOOS=linux
19-
ENV GOARCH=amd64
24+
ENV GOOS=${TARGETOS:-linux}
25+
ENV GOARCH=${TARGETARCH}
2026
ENV GO111MODULE=on
2127

2228
# Do an initial compilation before setting the version so that there is less to
@@ -36,5 +42,6 @@ RUN go build \
3642
FROM gcr.io/distroless/static:nonroot
3743
WORKDIR /
3844
COPY --from=builder /workspace/manager .
45+
USER 65532:65532
3946

4047
ENTRYPOINT ["/manager"]

Makefile

+156-94
Original file line numberDiff line numberDiff line change
@@ -14,133 +14,79 @@ DOCKER_IMAGE_NAME ?= cert-manager/sample-external-issuer/controller
1414
# Image URL to use all building/pushing image targets
1515
IMG ?= ${DOCKER_REGISTRY}/${DOCKER_IMAGE_NAME}:${VERSION}
1616

17-
# BIN is the directory where tools will be installed
18-
export BIN ?= ${CURDIR}/bin
19-
20-
OS := $(shell go env GOOS)
21-
ARCH := $(shell go env GOARCH)
22-
23-
# Kind
24-
KIND_VERSION := 0.18.0
25-
KIND := ${BIN}/kind-${KIND_VERSION}
26-
K8S_CLUSTER_NAME := sample-external-issuer-e2e
2717

2818
# cert-manager
2919
CERT_MANAGER_VERSION ?= 1.11.1
3020

31-
# Controller tools
32-
CONTROLLER_GEN_VERSION := 0.11.3
33-
CONTROLLER_GEN := ${BIN}/controller-gen
3421

3522
INSTALL_YAML ?= build/install.yaml
3623

3724
.PHONY: all
38-
all: manager
25+
all: build
3926

40-
# Run tests
41-
.PHONY: test
42-
test: generate fmt vet manifests
43-
go test ./... -coverprofile cover.out
27+
##@ General
4428

45-
# Build manager binary
46-
.PHONY: manager
47-
manager: generate fmt vet
48-
go build -o bin/manager main.go
29+
# The help target prints out all targets with their descriptions organized
30+
# beneath their categories. The categories are represented by '##@' and the
31+
# target descriptions by '##'. The awk commands is responsible for reading the
32+
# entire set of makefiles included in this invocation, looking for lines of the
33+
# file as xyz: ## something, and then pretty-format the target and help. Then,
34+
# if there's a line with ##@ something, that gets pretty-printed as a category.
35+
# More info on the usage of ANSI control characters for terminal formatting:
36+
# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
37+
# More info on the awk command:
38+
# http://linuxcommand.org/lc3_adv_awk.php
4939

50-
# Run against the configured Kubernetes cluster in ~/.kube/config
51-
.PHONY: run
52-
run: generate fmt vet manifests
53-
go run ./main.go
54-
55-
# Install CRDs into a cluster
56-
.PHONY: install
57-
install: manifests
58-
kustomize build config/crd | kubectl apply -f -
59-
60-
# Uninstall CRDs from a cluster
61-
.PHONY: uninstall
62-
uninstall: manifests
63-
kustomize build config/crd | kubectl delete -f -
64-
65-
# TODO(wallrj): .PHONY ensures that the install file is always regenerated,
66-
# because I this really depends on the checksum of the Docker image and all the
67-
# base Kustomize files.
68-
.PHONY: ${INSTALL_YAML}
69-
${INSTALL_YAML}:
70-
mkdir -p $(dir $@)
71-
rm -rf build/kustomize
72-
mkdir -p build/kustomize
73-
cd build/kustomize
74-
kustomize create --resources ../../config/default
75-
kustomize edit set image controller=${IMG}
76-
cd ${CURDIR}
77-
kustomize build build/kustomize > $@
40+
.PHONY: help
41+
help: ## Display this help.
42+
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
7843

79-
# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
80-
.PHONY: deploy
81-
deploy: ${INSTALL_YAML}
82-
kubectl apply -f ${INSTALL_YAML}
44+
##@ Development
8345

84-
# Generate manifests e.g. CRD, RBAC etc.
8546
.PHONY: manifests
86-
manifests: ${CONTROLLER_GEN}
87-
$(CONTROLLER_GEN) rbac:roleName=manager-role webhook crd paths="./..." output:crd:artifacts:config=config/crd/bases
47+
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
48+
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
49+
50+
.PHONY: generate
51+
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
52+
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
8853

89-
# Run go fmt against code
9054
.PHONY: fmt
91-
fmt:
55+
fmt: ## Run go fmt against code.
9256
go fmt ./...
9357

94-
# Run go vet against code
9558
.PHONY: vet
96-
vet:
59+
vet: ## Run go vet against code.
9760
go vet ./...
9861

99-
# Generate code
100-
generate: ${CONTROLLER_GEN}
101-
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."
102-
103-
# Build the docker image
104-
.PHONY: docker-build
105-
docker-build:
106-
docker build \
107-
--build-arg VERSION=$(VERSION) \
108-
--tag ${IMG} \
109-
--file Dockerfile \
110-
${CURDIR}
62+
.PHONY: test
63+
test: manifests generate fmt vet ## Run tests
64+
go test ./... -coverprofile cover.out
11165

112-
# Push the docker image
113-
.PHONY: docker-push
114-
docker-push:
115-
docker push ${IMG}
66+
##@ E2E testing
11667

117-
${CONTROLLER_GEN}: | ${BIN}
118-
GOBIN=${BIN} go install sigs.k8s.io/controller-tools/cmd/controller-gen@v${CONTROLLER_GEN_VERSION}
68+
K8S_CLUSTER_NAME := sample-external-issuer-e2e
11969

120-
# ==================================
121-
# E2E testing
122-
# ==================================
12370
.PHONY: kind-cluster
12471
kind-cluster: ## Use Kind to create a Kubernetes cluster for E2E tests
125-
kind-cluster: ${KIND}
72+
kind-cluster: kind
12673
${KIND} get clusters | grep ${K8S_CLUSTER_NAME} || ${KIND} create cluster --name ${K8S_CLUSTER_NAME}
12774

12875
.PHONY: kind-load
129-
kind-load: ## Load all the Docker images into Kind
76+
kind-load: kind ## Load all the Docker images into Kind
13077
${KIND} load docker-image --name ${K8S_CLUSTER_NAME} ${IMG}
13178

13279
.PHONY: kind-export-logs
133-
kind-export-logs:
80+
kind-export-logs: kind ## Export Kind logs
13481
${KIND} export logs --name ${K8S_CLUSTER_NAME} ${E2E_ARTIFACTS_DIRECTORY}
13582

136-
13783
.PHONY: deploy-cert-manager
13884
deploy-cert-manager: ## Deploy cert-manager in the configured Kubernetes cluster in ~/.kube/config
13985
kubectl apply --filename=https://github.com/cert-manager/cert-manager/releases/download/v${CERT_MANAGER_VERSION}/cert-manager.yaml
14086
kubectl wait --for=condition=Available --timeout=300s apiservice v1.cert-manager.io
14187

14288
.PHONY: e2e
143-
e2e:
89+
e2e: ## Run E2E tests
14490
kubectl apply --filename config/samples
14591

14692
kubectl wait --for=condition=Ready --timeout=5s issuers.sample-issuer.example.com issuer-sample
@@ -153,12 +99,128 @@ e2e:
15399

154100
kubectl delete --filename config/samples
155101

156-
# ==================================
157-
# Download: tools in ${BIN}
158-
# ==================================
159-
${BIN}:
160-
mkdir -p ${BIN}
102+
##@ Build
103+
104+
.PHONY: build
105+
build: manifests generate fmt vet ## Build manager binary
106+
go build -o bin/manager main.go
107+
108+
.PHONY: run
109+
run: manifests generate fmt vet ## Run a controller from your host.
110+
go run ./main.go
111+
112+
# If you wish built the manager image targeting other platforms you can use the --platform flag.
113+
# (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it.
114+
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
115+
.PHONY: docker-build
116+
docker-build: ## Build docker image with the manager.
117+
docker build \
118+
--build-arg VERSION=$(VERSION) \
119+
--tag ${IMG} \
120+
--file Dockerfile \
121+
${CURDIR}
122+
123+
# Push the docker image
124+
.PHONY: docker-push
125+
docker-push: ## Push docker image with the manager.
126+
docker push ${IMG}
127+
128+
# PLATFORMS defines the target platforms for the manager image be build to provide support to multiple
129+
# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
130+
# - able to use docker buildx . More info: https://docs.docker.com/build/buildx/
131+
# - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/
132+
# - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=<myregistry/image:<tag>> then the export will fail)
133+
# To properly provided solutions that supports more than one platform you should use this option.
134+
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
135+
.PHONY: docker-buildx
136+
docker-buildx: test ## Build and push docker image for the manager for cross-platform support
137+
# copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile
138+
sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
139+
- docker buildx create --name project-v3-builder
140+
docker buildx use project-v3-builder
141+
- docker buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross .
142+
- docker buildx rm project-v3-builder
143+
rm Dockerfile.cross
144+
145+
##@ Deployment
146+
147+
ifndef ignore-not-found
148+
ignore-not-found = false
149+
endif
150+
151+
.PHONY: install
152+
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
153+
$(KUSTOMIZE) build config/crd | kubectl apply -f -
154+
155+
.PHONY: uninstall
156+
uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
157+
$(KUSTOMIZE) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
158+
159+
# TODO(wallrj): .PHONY ensures that the install file is always regenerated,
160+
# because I this really depends on the checksum of the Docker image and all the
161+
# base Kustomize files.
162+
.PHONY: ${INSTALL_YAML}
163+
${INSTALL_YAML}: manifests kustomize
164+
mkdir -p $(dir $@)
165+
rm -rf build/kustomize
166+
mkdir -p build/kustomize
167+
cd build/kustomize
168+
$(KUSTOMIZE) create --resources ../../config/default
169+
$(KUSTOMIZE) edit set image controller=${IMG}
170+
cd ${CURDIR}
171+
$(KUSTOMIZE) build build/kustomize > $@
172+
173+
.PHONY: deploy
174+
deploy: ${INSTALL_YAML} ## Deploy controller to the K8s cluster specified in ~/.kube/config.
175+
kubectl apply -f ${INSTALL_YAML}
176+
177+
.PHONY: undeploy
178+
undeploy: ${INSTALL_YAML} ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
179+
kubectl delete -f ${INSTALL_YAML} --ignore-not-found=$(ignore-not-found)
180+
181+
##@ Build Dependencies
182+
183+
LOCAL_OS := $(shell go env GOOS)
184+
LOCAL_ARCH := $(shell go env GOARCH)
185+
186+
## Location to install dependencies to
187+
LOCALBIN ?= $(shell pwd)/bin
188+
$(LOCALBIN):
189+
mkdir -p $(LOCALBIN)
190+
191+
## Tool Binaries
192+
KUSTOMIZE ?= $(LOCALBIN)/kustomize
193+
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
194+
ENVTEST ?= $(LOCALBIN)/setup-envtest
195+
KIND ?= $(LOCALBIN)/kind
196+
197+
## Tool Versions
198+
KUSTOMIZE_VERSION ?= v3.8.7
199+
CONTROLLER_TOOLS_VERSION ?= v0.11.3
200+
KIND_VERSION := 0.18.0
161201

162-
${KIND}: ${BIN}
163-
curl -fsSL -o ${KIND} https://github.com/kubernetes-sigs/kind/releases/download/v${KIND_VERSION}/kind-${OS}-${ARCH}
202+
KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
203+
.PHONY: kustomize
204+
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading.
205+
$(KUSTOMIZE): $(LOCALBIN)
206+
@if test -x $(LOCALBIN)/kustomize && ! $(LOCALBIN)/kustomize version | grep -q $(KUSTOMIZE_VERSION); then \
207+
echo "$(LOCALBIN)/kustomize version is not expected $(KUSTOMIZE_VERSION). Removing it before installing."; \
208+
rm -rf $(LOCALBIN)/kustomize; \
209+
fi
210+
test -s $(LOCALBIN)/kustomize || { curl -Ss $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); }
211+
212+
.PHONY: controller-gen
213+
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. If wrong version is installed, it will be overwritten.
214+
$(CONTROLLER_GEN): $(LOCALBIN)
215+
test -s $(LOCALBIN)/controller-gen && $(LOCALBIN)/controller-gen --version | grep -q $(CONTROLLER_TOOLS_VERSION) || \
216+
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)
217+
218+
.PHONY: envtest
219+
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
220+
$(ENVTEST): $(LOCALBIN)
221+
test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
222+
223+
.PHONY: kind
224+
kind: $(LOCALBIN) ## Download Kind locally if necessary.
225+
curl -fsSL -o ${KIND} https://github.com/kubernetes-sigs/kind/releases/download/v${KIND_VERSION}/kind-${LOCAL_OS}-${LOCAL_ARCH}
164226
chmod +x ${KIND}

PROJECT

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1+
# Code generated by tool. DO NOT EDIT.
2+
# This file is used to track the info used to scaffold your project
3+
# and allow the plugins properly work.
4+
# More info: https://book.kubebuilder.io/reference/project-config.html
15
domain: example.com
6+
layout:
7+
- go.kubebuilder.io/v3
8+
projectName: sample-external-issuer
29
repo: github.com/cert-manager/sample-external-issuer
310
resources:
411
- group: sample-issuer
@@ -8,3 +15,4 @@ resources:
815
kind: ClusterIssuer
916
version: v1alpha1
1017
version: "2"
18+
version: "3"

README.md

+2-6
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ You will need the following command line tools installed on your PATH:
3737
* [Docker v17.03+](https://docs.docker.com/install/)
3838
* [Kind v0.18.0+](https://kind.sigs.k8s.io/docs/user/quick-start/)
3939
* [Kubectl v1.26.3+](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
40-
* [Kubebuilder v2.3.1+](https://book.kubebuilder.io/quick-start.html#installation)
40+
* [Kubebuilder v3.9.1+](https://book.kubebuilder.io/quick-start.html#installation)
4141
* [Kustomize v3.8.1+](https://kustomize.io/)
4242

4343
You may also want to read: the [Kubebuilder Book] and the [cert-manager Concepts Documentation] for further background
@@ -126,10 +126,6 @@ The values we pass to these commands specify the GVK (group, version, kind):
126126
These commands will have created some boilerplate files and directories: `api/` and `controllers/`,
127127
which we now need to edit as follows:
128128

129-
* `api/v1alpha1/{cluster}issuer_types.go`:
130-
Add [Kubebuilder CRD Markers](https://book.kubebuilder.io/reference/markers/crd.html) to allow modification of IssuerStatus
131-
as a [Status Subresource](https://book-v1.book.kubebuilder.io/basics/status_subresource.html): `// +kubebuilder:subresource:status`
132-
133129
* `api/v1alpha1/clusterissuer_types.go`:
134130
Remove the `ClusterIssuerSpec` and `ClusterIssuerStatus` and replace them with `IssuerSpec` and `IssuerStatus`.
135131
This is because both types of issuers share the same configuration and status reporting.
@@ -181,7 +177,7 @@ You will also need to add the cert-manager API types to the `Scheme`:
181177
```go
182178
func init() {
183179
...
184-
_ = cmapi.AddToScheme(scheme)
180+
utilruntime.Must(cmapi.AddToScheme(scheme))
185181
...
186182
}
187183
```

0 commit comments

Comments
 (0)