sigs.k8s.io/cluster-api-provider-azure@v1.14.3/Makefile (about)

     1  # Copyright 2018 The Kubernetes Authors.
     2  #
     3  # Licensed under the Apache License, Version 2.0 (the "License");
     4  # you may not use this file except in compliance with the License.
     5  # You may obtain a copy of the License at
     6  #
     7  #     http://www.apache.org/licenses/LICENSE-2.0
     8  #
     9  # Unless required by applicable law or agreed to in writing, software
    10  # distributed under the License is distributed on an "AS IS" BASIS,
    11  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  # See the License for the specific language governing permissions and
    13  # limitations under the License.
    14  
    15  # If you update this file, please follow
    16  # https://suva.sh/en/writings/well-documented-makefiles
    17  
    18  # Ensure Make is run with bash shell as some syntax below is bash-specific
    19  SHELL:=/usr/bin/env bash
    20  
    21  .DEFAULT_GOAL:=help
    22  
    23  GOPATH  := $(shell go env GOPATH)
    24  GOARCH  := $(shell go env GOARCH)
    25  GOOS    := $(shell go env GOOS)
    26  GOPROXY := $(shell go env GOPROXY)
    27  ifeq ($(GOPROXY),)
    28  GOPROXY := https://proxy.golang.org
    29  endif
    30  export GOPROXY
    31  
    32  # Active module mode, as we use go modules to manage dependencies
    33  export GO111MODULE=on
    34  
    35  # Kubebuilder.
    36  export KUBEBUILDER_ENVTEST_KUBERNETES_VERSION ?= 1.29.0
    37  export KUBEBUILDER_CONTROLPLANE_START_TIMEOUT ?= 60s
    38  export KUBEBUILDER_CONTROLPLANE_STOP_TIMEOUT ?= 60s
    39  
    40  # This option is for running docker manifest command
    41  export DOCKER_CLI_EXPERIMENTAL := enabled
    42  
    43  # curl retries
    44  CURL_RETRIES=3
    45  
    46  # Directories.
    47  ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
    48  TOOLS_DIR := hack/tools
    49  TOOLS_BIN_DIR := $(abspath $(TOOLS_DIR)/bin)
    50  TEMPLATES_DIR := $(ROOT_DIR)/templates
    51  BIN_DIR := $(abspath $(ROOT_DIR)/bin)
    52  EXP_DIR := exp
    53  GO_INSTALL = ./scripts/go_install.sh
    54  E2E_DATA_DIR ?= $(ROOT_DIR)/test/e2e/data
    55  KUBETEST_CONF_PATH ?= $(abspath $(E2E_DATA_DIR)/kubetest/conformance.yaml)
    56  KUBETEST_WINDOWS_CONFIG ?= upstream-windows.yaml
    57  KUBETEST_WINDOWS_CONF_PATH ?= $(abspath $(E2E_DATA_DIR)/kubetest/$(KUBETEST_WINDOWS_CONFIG))
    58  KUBETEST_REPO_LIST_PATH ?= $(abspath $(E2E_DATA_DIR)/kubetest/)
    59  AZURE_TEMPLATES := $(E2E_DATA_DIR)/infrastructure-azure
    60  ADDONS_DIR := templates/addons
    61  CONVERSION_VERIFIER := $(TOOLS_BIN_DIR)/conversion-verifier
    62  
    63  # use the project local tool binaries first
    64  export PATH := $(TOOLS_BIN_DIR):$(PATH)
    65  
    66  # set --output-base used for conversion-gen which needs to be different for in GOPATH and outside GOPATH dev
    67  ifneq ($(abspath $(ROOT_DIR)),$(GOPATH)/src/sigs.k8s.io/cluster-api-provider-azure)
    68    OUTPUT_BASE := --output-base=$(ROOT_DIR)
    69  endif
    70  
    71  # Binaries.
    72  CONTROLLER_GEN_VER := v0.13.0
    73  CONTROLLER_GEN_BIN := controller-gen
    74  CONTROLLER_GEN := $(TOOLS_BIN_DIR)/$(CONTROLLER_GEN_BIN)-$(CONTROLLER_GEN_VER)
    75  
    76  CONVERSION_GEN_VER := v0.28.0
    77  CONVERSION_GEN_BIN := conversion-gen
    78  CONVERSION_GEN := $(TOOLS_BIN_DIR)/$(CONVERSION_GEN_BIN)-$(CONVERSION_GEN_VER)
    79  
    80  ENVSUBST_VER := $(shell go list -m -f '{{.Version}}' github.com/drone/envsubst/v2)
    81  ENVSUBST_BIN := envsubst
    82  ENVSUBST := $(TOOLS_BIN_DIR)/$(ENVSUBST_BIN)-$(ENVSUBST_VER)
    83  
    84  GOLANGCI_LINT_VER := v1.55.2
    85  GOLANGCI_LINT_BIN := golangci-lint
    86  GOLANGCI_LINT := $(TOOLS_BIN_DIR)/$(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VER)
    87  
    88  KUSTOMIZE_VER := v4.5.2
    89  KUSTOMIZE_BIN := kustomize
    90  KUSTOMIZE := $(TOOLS_BIN_DIR)/$(KUSTOMIZE_BIN)-$(KUSTOMIZE_VER)
    91  
    92  MOCKGEN_VER := v0.4.0
    93  MOCKGEN_BIN := mockgen
    94  MOCKGEN := $(TOOLS_BIN_DIR)/$(MOCKGEN_BIN)-$(MOCKGEN_VER)
    95  
    96  RELEASE_NOTES_VER := v0.16.5-0.20240205193526-59cb6e852feb
    97  RELEASE_NOTES_BIN := release-notes
    98  RELEASE_NOTES := $(TOOLS_BIN_DIR)/$(RELEASE_NOTES_BIN)-$(RELEASE_NOTES_VER)
    99  
   100  KPROMO_VER := v4.0.4
   101  KPROMO_BIN := kpromo
   102  KPROMO := $(TOOLS_BIN_DIR)/$(KPROMO_BIN)-$(KPROMO_VER)
   103  
   104  GO_APIDIFF_VER := v0.7.0
   105  GO_APIDIFF_BIN := go-apidiff
   106  GO_APIDIFF := $(TOOLS_BIN_DIR)/$(GO_APIDIFF_BIN)
   107  
   108  GINKGO_VER := $(shell go list -m -f '{{.Version}}' github.com/onsi/ginkgo/v2)
   109  GINKGO_BIN := ginkgo
   110  GINKGO := $(TOOLS_BIN_DIR)/$(GINKGO_BIN)-$(GINKGO_VER)
   111  
   112  KUBECTL_VER := v1.28.4
   113  KUBECTL_BIN := kubectl
   114  KUBECTL := $(TOOLS_BIN_DIR)/$(KUBECTL_BIN)-$(KUBECTL_VER)
   115  
   116  HELM_VER := v3.14.4
   117  HELM_BIN := helm
   118  HELM := $(TOOLS_BIN_DIR)/$(HELM_BIN)-$(HELM_VER)
   119  
   120  YQ_VER := v4.35.2
   121  YQ_BIN := yq
   122  YQ :=  $(TOOLS_BIN_DIR)/$(YQ_BIN)-$(YQ_VER)
   123  
   124  KIND_VER := $(shell go list -m -f '{{.Version}}' sigs.k8s.io/kind)
   125  KIND_BIN := kind
   126  KIND :=  $(TOOLS_BIN_DIR)/$(KIND_BIN)-$(KIND_VER)
   127  
   128  CODESPELL_VER := 2.2.6
   129  CODESPELL_BIN := codespell
   130  CODESPELL_DIST_DIR := codespell_dist
   131  CODESPELL := $(TOOLS_BIN_DIR)/$(CODESPELL_DIST_DIR)/$(CODESPELL_BIN)
   132  
   133  SETUP_ENVTEST_VER := v0.0.0-20231012212722-e25aeebc7846
   134  SETUP_ENVTEST_BIN := setup-envtest
   135  SETUP_ENVTEST := $(abspath $(TOOLS_BIN_DIR)/$(SETUP_ENVTEST_BIN)-$(SETUP_ENVTEST_VER))
   136  SETUP_ENVTEST_PKG := sigs.k8s.io/controller-runtime/tools/setup-envtest
   137  
   138  KUBEBUILDER_ASSETS ?= $(shell $(SETUP_ENVTEST) use --use-env -p path $(KUBEBUILDER_ENVTEST_KUBERNETES_VERSION))
   139  
   140  # Define Docker related variables. Releases should modify and double check these vars.
   141  ifeq (,$(shell command -v gcloud))
   142      REGISTRY ?= gcr.io/$(shell gcloud config get-value project)
   143  else
   144      REGISTRY ?= localhost:5000
   145  endif
   146  STAGING_REGISTRY := gcr.io/k8s-staging-cluster-api-azure
   147  PROD_REGISTRY := registry.k8s.io/cluster-api-azure
   148  IMAGE_NAME ?= cluster-api-azure-controller
   149  CONTROLLER_IMG ?= $(REGISTRY)/$(IMAGE_NAME)
   150  TAG ?= dev
   151  ARCH ?= $(GOARCH)
   152  ALL_ARCH = amd64 arm arm64 ppc64le s390x
   153  
   154  # Allow overriding manifest generation destination directory
   155  MANIFEST_ROOT ?= config
   156  CRD_ROOT ?= $(MANIFEST_ROOT)/crd/bases
   157  WEBHOOK_ROOT ?= $(MANIFEST_ROOT)/webhook
   158  RBAC_ROOT ?= $(MANIFEST_ROOT)/rbac
   159  ASO_CRDS_PATH := $(MANIFEST_ROOT)/aso/crds.yaml
   160  ASO_VERSION := v2.5.0
   161  ASO_CRDS := resourcegroups.resources.azure.com natgateways.network.azure.com managedclusters.containerservice.azure.com managedclustersagentpools.containerservice.azure.com bastionhosts.network.azure.com virtualnetworks.network.azure.com virtualnetworkssubnets.network.azure.com privateendpoints.network.azure.com fleetsmembers.containerservice.azure.com extensions.kubernetesconfiguration.azure.com
   162  
   163  # Allow overriding the imagePullPolicy
   164  PULL_POLICY ?= Always
   165  
   166  # Allow overriding the e2e configurations
   167  GINKGO_FOCUS ?= \[REQUIRED\]
   168  GINKGO_SKIP ?=
   169  GINKGO_NODES ?= 3
   170  GINKGO_NOCOLOR ?= false
   171  GINKGO_ARGS ?=
   172  ARTIFACTS ?= $(ROOT_DIR)/_artifacts
   173  E2E_CONF_FILE ?= $(ROOT_DIR)/test/e2e/config/azure-dev.yaml
   174  E2E_CONF_FILE_ENVSUBST := $(ROOT_DIR)/test/e2e/config/azure-dev-envsubst.yaml
   175  SKIP_CLEANUP ?= false
   176  SKIP_LOG_COLLECTION ?= false
   177  # @sonasingh46: Skip creating mgmt cluster for ci as workload identity needs kind cluster
   178  # to be created with extra mounts for key pairs which is not yet supported
   179  # by existing e2e framework. A mgmt cluster(kind) is created as part of e2e suite
   180  # that meets workload identity pre-requisites.
   181  SKIP_CREATE_MGMT_CLUSTER ?= true
   182  WIN_REPO_URL ?=
   183  
   184  # Build time versioning details.
   185  LDFLAGS := $(shell hack/version.sh)
   186  
   187  CLUSTER_TEMPLATE ?= cluster-template.yaml
   188  
   189  export KIND_CLUSTER_NAME ?= capz
   190  
   191  ## --------------------------------------
   192  ## Binaries
   193  ## --------------------------------------
   194  
   195  ##@ Binaries:
   196  
   197  .PHONY: binaries
   198  binaries: manager ## Builds all binaries.
   199  
   200  .PHONY: manager
   201  manager: ## Build manager binary.
   202  	go build -ldflags "$(LDFLAGS)" -o $(BIN_DIR)/manager .
   203  
   204  ## --------------------------------------
   205  ## Cleanup / Verification
   206  ## --------------------------------------
   207  
   208  ##@ Cleanup / Verification:
   209  
   210  .PHONY: clean
   211  clean: ## Remove bin and kubeconfigs.
   212  	$(MAKE) clean-bin
   213  	$(MAKE) clean-temporary
   214  
   215  .PHONY: clean-bin
   216  clean-bin: ## Remove all generated binaries.
   217  	rm -rf bin
   218  	rm -rf hack/tools/bin
   219  
   220  .PHONY: clean-temporary
   221  clean-temporary: ## Remove all temporary files and folders.
   222  	rm -f minikube.kubeconfig
   223  	rm -f kubeconfig
   224  	rm -f *.kubeconfig
   225  
   226  .PHONY: clean-release
   227  clean-release: clean-release-git ## Remove the release folder.
   228  	rm -rf $(RELEASE_DIR)
   229  
   230  .PHONY: clean-release-git
   231  clean-release-git: ## Restores the git files usually modified during a release
   232  	git restore ./*manager_image_patch.yaml ./*manager_pull_policy.yaml
   233  
   234  APIDIFF_OLD_COMMIT ?= $(shell git rev-parse origin/main)
   235  
   236  .PHONY: apidiff
   237  apidiff: $(GO_APIDIFF) ## Check for API differences.
   238  	$(GO_APIDIFF) $(APIDIFF_OLD_COMMIT)
   239  
   240  .PHONY: format-tiltfile
   241  format-tiltfile: ## Format the Tiltfile.
   242  	./hack/verify-starlark.sh fix
   243  
   244  .PHONY: verify
   245  verify: verify-boilerplate verify-modules verify-gen verify-shellcheck verify-conversions verify-tiltfile verify-codespell ## Run "verify-boilerplate", "verify-modules", "verify-gen", "verify-shellcheck", "verify-conversions", "verify-tiltfile" "verify-codespell" rules.
   246  
   247  .PHONY: verify-boilerplate
   248  verify-boilerplate: ## Verify boilerplate header.
   249  	./hack/verify-boilerplate.sh
   250  
   251  .PHONY: verify-modules
   252  verify-modules: modules ## Verify go.sum go.mod are the latest.
   253  	@if !(git diff --quiet HEAD -- go.sum go.mod $(TOOLS_DIR)/go.sum $(TOOLS_DIR)/go.mod); then \
   254  		echo "go module files are out of date"; exit 1; \
   255  	fi
   256  
   257  .PHONY: verify-gen
   258  verify-gen: generate ## Verify generated files are the latest.
   259  	@if !(git diff --quiet HEAD); then \
   260  		git diff; echo "generated files are out of date, run make generate"; exit 1; \
   261  	fi
   262  
   263  .PHONY: verify-shellcheck
   264  verify-shellcheck: ## Verify shell files are passing lint.
   265  	./hack/verify-shellcheck.sh
   266  
   267  .PHONY: verify-conversions
   268  verify-conversions: $(CONVERSION_VERIFIER)  ## Verifies expected API conversion are in place.
   269  	$(CONVERSION_VERIFIER)
   270  
   271  .PHONY: verify-tiltfile
   272  verify-tiltfile: ## Verify Tiltfile format.
   273  	./hack/verify-starlark.sh
   274  
   275  .PHONY: verify-codespell
   276  verify-codespell: codespell ## Verify codespell.
   277  	@$(CODESPELL) $(ROOT_DIR) --ignore-words=$(ROOT_DIR)/.codespellignore --skip="*.git,*_artifacts,*.sum,$(ROOT_DIR)/docs/book/bookout,$(ROOT_DIR)/hack/tools/bin/codespell_dist"
   278  
   279  ## --------------------------------------
   280  ## Development
   281  ## --------------------------------------
   282  
   283  ##@ Development:
   284  
   285  .PHONY: install-tools # populate hack/tools/bin
   286  install-tools: $(ENVSUBST) $(KUSTOMIZE) $(KUBECTL) $(HELM) $(GINKGO) $(KIND)
   287  
   288  .PHONY: create-management-cluster
   289  create-management-cluster: $(KUSTOMIZE) $(ENVSUBST) $(KUBECTL) $(KIND) ## Create a management cluster.
   290  	# Create kind management cluster.
   291  	$(MAKE) kind-create
   292  
   293  	# Install cert manager and wait for availability
   294  	./hack/install-cert-manager.sh
   295  
   296  	# Create secret for AzureClusterIdentity
   297  	./hack/create-identity-secret.sh
   298  
   299  	# Create customized cloud provider configs
   300  	./hack/create-custom-cloud-provider-config.sh
   301  
   302  	# Deploy CAPI
   303  	timeout --foreground 300 bash -c "until curl --retry $(CURL_RETRIES) -sSL https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.6.4/cluster-api-components.yaml | $(ENVSUBST) | $(KUBECTL) apply -f -; do sleep 5; done"
   304  
   305  	# Deploy CAAPH
   306  	timeout --foreground 300 bash -c "until curl --retry $(CURL_RETRIES) -sSL https://github.com/kubernetes-sigs/cluster-api-addon-provider-helm/releases/download/v0.1.0-alpha.10/addon-components.yaml | $(ENVSUBST) | $(KUBECTL) apply -f -; do sleep 5; done"
   307  
   308  	# Deploy CAPZ
   309  	$(KIND) load docker-image $(CONTROLLER_IMG)-$(ARCH):$(TAG) --name=$(KIND_CLUSTER_NAME)
   310  	timeout --foreground 300 bash -c "until $(KUSTOMIZE) build config/default | $(ENVSUBST) | $(KUBECTL) apply -f - --server-side=true; do sleep 5; done"
   311  
   312  	# Wait for CAPI deployments
   313  	$(KUBECTL) wait --for=condition=Available --timeout=5m -n capi-system deployment -l cluster.x-k8s.io/provider=cluster-api
   314  	$(KUBECTL) wait --for=condition=Available --timeout=5m -n capi-kubeadm-bootstrap-system deployment -l cluster.x-k8s.io/provider=bootstrap-kubeadm
   315  	$(KUBECTL) wait --for=condition=Available --timeout=5m -n capi-kubeadm-control-plane-system deployment -l cluster.x-k8s.io/provider=control-plane-kubeadm
   316  
   317  	# Wait for CAAPH deployment
   318  	$(KUBECTL) wait --for=condition=Available --timeout=5m -n caaph-system deployment -l cluster.x-k8s.io/provider=helm
   319  
   320  	# Wait for the ClusterResourceSet CRD resource to be "installed" onto the mgmt cluster before installing CRS addons
   321  	timeout --foreground 300 bash -c "until $(KUBECTL) get clusterresourcesets -A; do sleep 3; done"
   322  
   323  	# install Windows Calico cluster resource set
   324  	timeout --foreground 300 bash -c "until $(KUBECTL) create configmap calico-windows-addon --from-file="$(ADDONS_DIR)/windows/calico" --dry-run=client -o yaml | kubectl apply -f -; do sleep 5; done"
   325  	timeout --foreground 300 bash -c "until $(KUBECTL) apply -f templates/addons/windows/calico-resource-set.yaml; do sleep 5; done"
   326  
   327  	# Wait for CAPZ deployments
   328  	$(KUBECTL) wait --for=condition=Available --timeout=5m -n capz-system deployment --all
   329  
   330  	# required sleep for when creating management and workload cluster simultaneously
   331  	# Wait for the core CRD resources to be "installed" onto the mgmt cluster before returning control
   332  	timeout --foreground 300 bash -c "until $(KUBECTL) get clusters -A; do sleep 3; done"
   333  	timeout --foreground 300 bash -c "until $(KUBECTL) get azureclusters -A; do sleep 3; done"
   334  	timeout --foreground 300 bash -c "until $(KUBECTL) get kubeadmcontrolplanes -A; do sleep 3; done"
   335  	@echo 'Set kubectl context to the kind management cluster by running "$(KUBECTL) config set-context kind-$(KIND_CLUSTER_NAME)"'
   336  
   337  .PHONY: create-workload-cluster
   338  create-workload-cluster: $(ENVSUBST) $(KUBECTL) ## Create a workload cluster.
   339  	# Create workload Cluster.
   340  	@if [ -f "$(TEMPLATES_DIR)/$(CLUSTER_TEMPLATE)" ]; then \
   341  		timeout --foreground 300 bash -c "until $(ENVSUBST) < $(TEMPLATES_DIR)/$(CLUSTER_TEMPLATE) | $(KUBECTL) apply -f -; do sleep 5; done"; \
   342  	elif [ -f "$(CLUSTER_TEMPLATE)" ]; then \
   343  		timeout --foreground 300 bash -c "until $(ENVSUBST) < "$(CLUSTER_TEMPLATE)" | $(KUBECTL) apply -f -; do sleep 5; done"; \
   344  	else \
   345  		timeout --foreground 300 bash -c "until curl --retry "$(CURL_RETRIES)" "$(CLUSTER_TEMPLATE)" | "$(ENVSUBST)" | $(KUBECTL) apply -f -; do sleep 5; done"; \
   346  	fi
   347  
   348  	# Wait for the kubeconfig to become available.
   349  	timeout --foreground 300 bash -c "while ! $(KUBECTL) get secrets | grep $(CLUSTER_NAME)-kubeconfig; do sleep 1; done"
   350  	# Get kubeconfig and store it locally.
   351  	$(KUBECTL) get secrets $(CLUSTER_NAME)-kubeconfig -o json | jq -r .data.value | base64 --decode > ./kubeconfig
   352  	$(KUBECTL) wait --for=condition=Ready --timeout=10m cluster "$(CLUSTER_NAME)"
   353  
   354  	@echo 'run "$(KUBECTL) --kubeconfig=./kubeconfig ..." to work with the new target cluster'
   355  
   356  .PHONY: create-cluster
   357  create-cluster: ## Create a workload development Kubernetes cluster on Azure in a kind management cluster.
   358  	EXP_CLUSTER_RESOURCE_SET=true \
   359  	EXP_MACHINE_POOL=true \
   360  	EXP_EDGEZONE=true \
   361  	$(MAKE) create-management-cluster \
   362  	create-workload-cluster
   363  
   364  .PHONY: delete-workload-cluster
   365  delete-workload-cluster: $(KUBECTL) ## Deletes the example workload Kubernetes cluster.
   366  	@echo 'Your Azure resources will now be deleted, this can take up to 20 minutes'
   367  	$(KUBECTL) delete cluster $(CLUSTER_NAME)
   368  
   369  ## --------------------------------------
   370  ## Docker
   371  ## --------------------------------------
   372  
   373  ##@ Docker:
   374  
   375  .PHONY: docker-pull-prerequisites
   376  docker-pull-prerequisites: ## Pull prerequisites for building controller-manager.
   377  	docker pull docker/dockerfile:1.4
   378  	docker pull docker.io/library/golang:1.20
   379  	docker pull gcr.io/distroless/static:latest
   380  
   381  .PHONY: docker-build
   382  docker-build: docker-pull-prerequisites ## Build the docker image for controller-manager.
   383  	DOCKER_BUILDKIT=1 docker build --build-arg goproxy=$(GOPROXY) --build-arg ARCH=$(ARCH) --build-arg ldflags="$(LDFLAGS)" . -t $(CONTROLLER_IMG)-$(ARCH):$(TAG)
   384  	$(MAKE) set-manifest-image MANIFEST_IMG=$(CONTROLLER_IMG)-$(ARCH) MANIFEST_TAG=$(TAG) TARGET_RESOURCE="./config/capz/manager_image_patch.yaml"
   385  	$(MAKE) set-manifest-pull-policy TARGET_RESOURCE="./config/capz/manager_pull_policy.yaml"
   386  
   387  .PHONY: docker-push
   388  docker-push: ## Push the docker image
   389  	docker push $(CONTROLLER_IMG)-$(ARCH):$(TAG)
   390  
   391  ## --------------------------------------
   392  ## Docker — All ARCH
   393  ## --------------------------------------
   394  
   395  ##@ Docker - All Arch:
   396  
   397  .PHONY: docker-build-all
   398  docker-build-all: $(addprefix docker-build-,$(ALL_ARCH)) ## Build all the architecture docker images.
   399  
   400  docker-build-%:
   401  	$(MAKE) ARCH=$* docker-build
   402  
   403  .PHONY: docker-push-all
   404  docker-push-all: $(addprefix docker-push-,$(ALL_ARCH)) ## Push all the architecture docker images.
   405  	$(MAKE) docker-push-manifest
   406  
   407  docker-push-%:
   408  	$(MAKE) ARCH=$* docker-push
   409  
   410  .PHONY: docker-push-manifest
   411  docker-push-manifest: ## Push the fat manifest docker image.
   412  	## Minimum docker version 18.06.0 is required for creating and pushing manifest images.
   413  	docker manifest create --amend $(CONTROLLER_IMG):$(TAG) $(shell echo $(ALL_ARCH) | sed -e "s~[^ ]*~$(CONTROLLER_IMG)\-&:$(TAG)~g")
   414  	@for arch in $(ALL_ARCH); do docker manifest annotate --arch $${arch} ${CONTROLLER_IMG}:${TAG} ${CONTROLLER_IMG}-$${arch}:${TAG}; done
   415  	docker manifest push --purge ${CONTROLLER_IMG}:${TAG}
   416  	MANIFEST_IMG=$(CONTROLLER_IMG) MANIFEST_TAG=$(TAG) $(MAKE) set-manifest-image
   417  	$(MAKE) set-manifest-pull-policy
   418  
   419  .PHONY: set-manifest-image
   420  set-manifest-image: ## Update kustomize image patch file for default resource.
   421  	$(info Updating kustomize image patch file for default resource)
   422  	sed -i'' -e 's@image: .*@image: '"${MANIFEST_IMG}:$(MANIFEST_TAG)"'@' ./config/capz/manager_image_patch.yaml
   423  
   424  .PHONY: set-manifest-pull-policy
   425  set-manifest-pull-policy: ## Update kustomize pull policy file for default resource.
   426  	$(info Updating kustomize pull policy file for default resource)
   427  	sed -i'' -e 's@imagePullPolicy: .*@imagePullPolicy: '"$(PULL_POLICY)"'@' ./config/capz/manager_pull_policy.yaml
   428  
   429  ## --------------------------------------
   430  ## Generate
   431  ## --------------------------------------
   432  
   433  ##@ Generate:
   434  
   435  .PHONY: generate
   436  generate: ## Generate go related targets, manifests, flavors, e2e-templates and addons.
   437  	$(MAKE) generate-go
   438  	$(MAKE) generate-manifests
   439  	$(MAKE) generate-flavors
   440  	$(MAKE) generate-e2e-templates
   441  	$(MAKE) generate-addons
   442  	$(MAKE) generate-aso-crds
   443  
   444  .PHONY: generate-go
   445  generate-go: $(CONTROLLER_GEN) $(MOCKGEN) $(CONVERSION_GEN) ## Runs Go related generate targets.
   446  	$(CONTROLLER_GEN) \
   447  		paths=./api/... \
   448  		paths=./$(EXP_DIR)/api/... \
   449  		object:headerFile=./hack/boilerplate/boilerplate.generatego.txt
   450  	go generate ./...
   451  
   452  .PHONY: generate-manifests
   453  generate-manifests: $(CONTROLLER_GEN) ## Generate manifests e.g. CRD, RBAC etc.
   454  	$(CONTROLLER_GEN) \
   455  		paths=./api/... \
   456  		paths=./$(EXP_DIR)/api/... \
   457  		crd:crdVersions=v1 \
   458  		rbac:roleName=manager-role \
   459  		output:crd:dir=$(CRD_ROOT) \
   460  		output:webhook:dir=$(WEBHOOK_ROOT) \
   461  		webhook
   462  	$(CONTROLLER_GEN) \
   463  		paths=./ \
   464  		paths=./controllers/... \
   465  		paths=./$(EXP_DIR)/controllers/... \
   466  		output:rbac:dir=$(RBAC_ROOT) \
   467  		rbac:roleName=manager-role
   468  
   469  .PHONY: generate-flavors ## Generate template flavors.
   470  generate-flavors: $(KUSTOMIZE) generate-addons
   471  	./hack/gen-flavors.sh
   472  
   473  .PHONY: generate-e2e-templates
   474  generate-e2e-templates: $(KUSTOMIZE) ## Generate Azure infrastructure templates for the v1beta1 CAPI test suite.
   475  	$(KUSTOMIZE) build $(AZURE_TEMPLATES)/v1beta1/cluster-template --load-restrictor LoadRestrictionsNone > $(AZURE_TEMPLATES)/v1beta1/cluster-template.yaml
   476  	$(KUSTOMIZE) build $(AZURE_TEMPLATES)/v1beta1/cluster-template-md-remediation --load-restrictor LoadRestrictionsNone > $(AZURE_TEMPLATES)/v1beta1/cluster-template-md-remediation.yaml
   477  	$(KUSTOMIZE) build $(AZURE_TEMPLATES)/v1beta1/cluster-template-kcp-remediation --load-restrictor LoadRestrictionsNone > $(AZURE_TEMPLATES)/v1beta1/cluster-template-kcp-remediation.yaml
   478  	$(KUSTOMIZE) build $(AZURE_TEMPLATES)/v1beta1/cluster-template-machine-pool --load-restrictor LoadRestrictionsNone > $(AZURE_TEMPLATES)/v1beta1/cluster-template-machine-pool.yaml
   479  	$(KUSTOMIZE) build $(AZURE_TEMPLATES)/v1beta1/cluster-template-node-drain --load-restrictor LoadRestrictionsNone > $(AZURE_TEMPLATES)/v1beta1/cluster-template-node-drain.yaml
   480  	$(KUSTOMIZE) build $(AZURE_TEMPLATES)/v1beta1/cluster-template-upgrades --load-restrictor LoadRestrictionsNone > $(AZURE_TEMPLATES)/v1beta1/cluster-template-upgrades.yaml
   481  	$(KUSTOMIZE) build $(AZURE_TEMPLATES)/v1beta1/cluster-template-kcp-scale-in --load-restrictor LoadRestrictionsNone > $(AZURE_TEMPLATES)/v1beta1/cluster-template-kcp-scale-in.yaml
   482  
   483  .PHONY: generate-addons
   484  generate-addons: fetch-calico-manifests ## Generate metric-server, calico, calico-ipv6, azure cni v1 addons.
   485  	$(KUSTOMIZE) build $(ADDONS_DIR)/metrics-server > $(ADDONS_DIR)/metrics-server/metrics-server.yaml
   486  	$(KUSTOMIZE) build $(ADDONS_DIR)/calico > $(ADDONS_DIR)/calico.yaml
   487  	$(KUSTOMIZE) build $(ADDONS_DIR)/calico-ipv6 > $(ADDONS_DIR)/calico-ipv6.yaml
   488  	$(KUSTOMIZE) build $(ADDONS_DIR)/calico-dual-stack > $(ADDONS_DIR)/calico-dual-stack.yaml
   489  	$(KUSTOMIZE) build $(ADDONS_DIR)/azure-cni-v1 > $(ADDONS_DIR)/azure-cni-v1.yaml
   490  
   491  .PHONY: generate-aso-crds
   492  # The yq command filters the list of all ASO CRDs to just the ones specified by ASO_CRDS.
   493  # The sed command changes '$$' to '$$$$' so once the CRDs get run through
   494  # envsubst, '$$$$' changes back to '$$' so ASO will not detect a diff and try to
   495  # update the CRDs for which we don't give it permission.
   496  generate-aso-crds: $(YQ)
   497  	curl -fSsL "https://github.com/Azure/azure-service-operator/releases/download/$(ASO_VERSION)/azureserviceoperator_customresourcedefinitions_$(ASO_VERSION).yaml" | \
   498  		$(YQ) e '. | select($(foreach name,$(ASO_CRDS),.metadata.name == "$(name)" or )false)' - | \
   499  		sed 's/\$$\$$/$$$$$$$$/g' \
   500  		> $(ASO_CRDS_PATH)
   501  
   502  # When updating this, make sure to also update the Windows image version in templates/addons/windows/calico.
   503  export CALICO_VERSION := v3.26.1
   504  # Where all downloaded Calico manifests are unpacked and stored.
   505  CALICO_RELEASES := $(ARTIFACTS)/calico
   506  # Path to manifests directory in a Calico release archive.
   507  CALICO_RELEASE_MANIFESTS_DIR := release-$(CALICO_VERSION)/manifests
   508  # Path where Calico manifests are stored which should be used for addons generation.
   509  CALICO_MANIFESTS_DIR := $(ARTIFACTS)/calico/$(CALICO_RELEASE_MANIFESTS_DIR)
   510  
   511  .PHONY: get-calico-version
   512  get-calico-version: ## Print the Calico version used for CNI in the repo.
   513  	@echo $(CALICO_VERSION)
   514  
   515  .PHONY: fetch-calico-manifests
   516  fetch-calico-manifests: $(CALICO_MANIFESTS_DIR) ## Get Calico release manifests and unzip them.
   517  	cp $(CALICO_MANIFESTS_DIR)/calico-vxlan.yaml $(ADDONS_DIR)/calico
   518  	cp $(CALICO_MANIFESTS_DIR)/calico-policy-only.yaml $(ADDONS_DIR)/calico-ipv6
   519  
   520  $(CALICO_MANIFESTS_DIR):
   521  	mkdir -p $(ARTIFACTS)/calico
   522  	@echo "Fetching Calico release manifests from release artifacts, this might take a minute..."
   523  	wget -qO- https://github.com/projectcalico/calico/releases/download/$(CALICO_VERSION)/release-$(CALICO_VERSION).tgz | tar xz --directory $(CALICO_RELEASES) $(CALICO_RELEASE_MANIFESTS_DIR)
   524  
   525  .PHONY: modules
   526  modules: ## Runs go mod tidy to ensure proper vendoring.
   527  	go mod tidy
   528  	pushd $(TOOLS_DIR) && go mod tidy; popd
   529  
   530  ## --------------------------------------
   531  ## Help
   532  ## --------------------------------------
   533  
   534  ##@ Help:
   535  
   536  help: ## Display this help.
   537  	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m<target>\033[0m\n"} /^[0-9a-zA-Z_-]+:.*?##/ { printf "  \033[36m%-25s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
   538  
   539  ## --------------------------------------
   540  ## Linting
   541  ## --------------------------------------
   542  
   543  ##@ Linting:
   544  
   545  .PHONY: lint
   546  lint: $(GOLANGCI_LINT) lint-latest ## Lint codebase.
   547  	$(GOLANGCI_LINT) run -v $(GOLANGCI_LINT_EXTRA_ARGS)
   548  
   549  .PHONY: lint-fix
   550  lint-fix: $(GOLANGCI_LINT) ## Lint the codebase and run auto-fixers if supported by the linter.
   551  	GOLANGCI_LINT_EXTRA_ARGS=--fix $(MAKE) lint
   552  
   553  lint-full: $(GOLANGCI_LINT) ## Run slower linters to detect possible issues.
   554  	$(GOLANGCI_LINT) run -v --fast=false
   555  
   556  .PHONY: lint-latest
   557  lint-latest:
   558  	./hack/lint-latest.sh
   559  
   560  ## --------------------------------------
   561  ## Release
   562  ## --------------------------------------
   563  
   564  ##@ Release:
   565  
   566  RELEASE_TAG ?= $(shell git describe --abbrev=0 2>/dev/null)
   567  # if the release tag contains a hyphen, treat it as a pre-release
   568  ifneq (,$(findstring -,$(RELEASE_TAG)))
   569      PRE_RELEASE=true
   570  endif
   571  FULL_VERSION := $(RELEASE_TAG:v%=%)
   572  MAJOR_VERSION := $(shell echo $(FULL_VERSION) | sed -E 's/^([0-9]+)\.([0-9]+)\.([0-9]+)$$/\1/')
   573  MINOR_VERSION := $(shell echo $(FULL_VERSION) | sed -E 's/^([0-9]+)\.([0-9]+)\.([0-9]+)$$/\2/')
   574  PATCH_VERSION := $(shell echo $(FULL_VERSION) | sed -E 's/^([0-9]+)\.([0-9]+)\.([0-9]+)$$/\3/')
   575  # if the release tag is a .0 version, use the main branch
   576  ifeq ($(PATCH_VERSION),0)
   577  	RELEASE_BRANCH ?= main
   578  else
   579  	RELEASE_BRANCH ?= release-$(MAJOR_VERSION).$(MINOR_VERSION)
   580  endif
   581  # the previous release tag, e.g., v0.3.9, excluding pre-release tags
   582  PREVIOUS_TAG ?= $(shell git tag --merged $(GIT_REMOTE_NAME)/$(RELEASE_BRANCH) -l | grep -E "^v[0-9]+\.[0-9]+\.[0-9]+$$" | sort -V | tail -n 1 2>/dev/null)
   583  START_SHA ?= $(shell git rev-list -n 1 $(PREVIOUS_TAG) 2>/dev/null)
   584  END_SHA ?= $(shell git rev-parse $(GIT_REMOTE_NAME)/$(RELEASE_BRANCH) 2>/dev/null)
   585  RELEASE_DIR ?= out
   586  RELEASE_NOTES_DIR := CHANGELOG
   587  GIT_REPO_NAME ?= cluster-api-provider-azure
   588  GIT_ORG_NAME ?= kubernetes-sigs
   589  GIT_REMOTE_NAME ?= upstream
   590  USER_FORK ?= $(shell git config --get remote.origin.url | cut -d/ -f4)
   591  IMAGE_REVIEWERS ?= $(shell ./hack/get-project-maintainers.sh)
   592  
   593  $(RELEASE_DIR):
   594  	mkdir -p $(RELEASE_DIR)/
   595  
   596  $(RELEASE_NOTES_DIR):
   597  	mkdir -p $(RELEASE_NOTES_DIR)/
   598  
   599  .PHONY: release
   600  release: clean-release  ## Builds and push container images using the latest git tag for the commit.
   601  	@if [ -z "${RELEASE_TAG}" ]; then echo "RELEASE_TAG is not set"; exit 1; fi
   602  	@if ! [ -z "$$(git status --porcelain)" ]; then echo "Your local git repository contains uncommitted changes, use git clean before proceeding."; exit 1; fi
   603  	git checkout "${RELEASE_TAG}"
   604  	# Set the manifest image to the production bucket.
   605  	$(MAKE) set-manifest-image MANIFEST_IMG=$(PROD_REGISTRY)/$(IMAGE_NAME) MANIFEST_TAG=$(RELEASE_TAG)
   606  	$(MAKE) set-manifest-pull-policy PULL_POLICY=IfNotPresent
   607  	$(MAKE) release-manifests
   608  	$(MAKE) release-templates
   609  	$(MAKE) release-metadata
   610  
   611  .PHONY: release-manifests
   612  release-manifests: $(KUSTOMIZE) $(RELEASE_DIR) ## Builds the manifests to publish with a release.
   613  	$(KUSTOMIZE) build config/default > $(RELEASE_DIR)/infrastructure-components.yaml
   614  
   615  .PHONY: release-templates
   616  release-templates: $(RELEASE_DIR)
   617  	cp templates/cluster-template* $(RELEASE_DIR)/
   618  
   619  .PHONY: release-metadata
   620  release-metadata: $(RELEASE_DIR)
   621  	cp metadata.yaml $(RELEASE_DIR)/metadata.yaml
   622  
   623  .PHONY: release-binary
   624  release-binary: $(RELEASE_DIR) ## Compile and build release binaries.
   625  	docker run \
   626  		--rm \
   627  		-e CGO_ENABLED=0 \
   628  		-e GOOS=$(GOOS) \
   629  		-e GOARCH=$(GOARCH) \
   630  		-v "$$(pwd):/workspace" \
   631  		-w /workspace \
   632  		golang:1.20 \
   633  		go build -a -ldflags '$(LDFLAGS) -extldflags "-static"' \
   634  		-o $(RELEASE_DIR)/$(notdir $(RELEASE_BINARY))-$(GOOS)-$(GOARCH) $(RELEASE_BINARY)
   635  
   636  .PHONY: release-staging
   637  release-staging: ## Builds and push container images to the staging bucket.
   638  	REGISTRY=$(STAGING_REGISTRY) $(MAKE) docker-build-all docker-push-all release-alias-tag
   639  
   640  RELEASE_ALIAS_TAG=$(PULL_BASE_REF)
   641  
   642  .PHONY: release-alias-tag
   643  release-alias-tag: ## Adds the tag to the last build tag.
   644  	gcloud container images add-tag $(CONTROLLER_IMG):$(TAG) $(CONTROLLER_IMG):$(RELEASE_ALIAS_TAG)
   645  
   646  .PHONY: release-notes
   647  release-notes: $(RELEASE_NOTES) $(RELEASE_NOTES_DIR) ## Generate/update release notes.
   648  	@echo "generating release notes from $(PREVIOUS_TAG) to $(RELEASE_TAG) with start sha $(START_SHA) and end sha $(END_SHA)"
   649  	@if [ -n "${PRE_RELEASE}" ]; then echo ":rotating_light: This is a RELEASE CANDIDATE. Use it only for testing purposes. If you find any bugs, file an [issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues/new)." > $(RELEASE_NOTES_DIR)/release-notes-$(RELEASE_TAG).md; \
   650  	else $(RELEASE_NOTES) --org $(GIT_ORG_NAME) --repo $(GIT_REPO_NAME) --branch $(RELEASE_BRANCH) --repo-path $(ROOT_DIR) --start-sha $(START_SHA) --end-sha $(END_SHA) --markdown-links true --output $(RELEASE_NOTES_DIR)/$(RELEASE_TAG).md --list-v2; \
   651  	sed 's/\[SIG Cluster Lifecycle\]//g' $(RELEASE_NOTES_DIR)/$(RELEASE_TAG).md > $(RELEASE_NOTES_DIR)/tmp-release-notes.md; \
   652  	cp $(RELEASE_NOTES_DIR)/tmp-release-notes.md $(RELEASE_NOTES_DIR)/$(RELEASE_TAG).md; \
   653  	rm -f $(RELEASE_NOTES_DIR)/tmp-release-notes.md; \
   654  	fi
   655  
   656  .PHONY: promote-images
   657  promote-images: $(KPROMO) ## Promote images.
   658  	$(KPROMO) pr --project cluster-api-azure --tag $(RELEASE_TAG) --reviewers "$(IMAGE_REVIEWERS)" --fork $(USER_FORK)
   659  
   660  ## --------------------------------------
   661  ## Testing
   662  ## --------------------------------------
   663  
   664  ##@ Testing:
   665  .PHONY: test
   666  test: generate lint go-test-race ## Run "generate", "lint" and "go-test-race" rules.
   667  
   668  .PHONY: go-test-race
   669  go-test-race: TEST_ARGS+= -race
   670  go-test-race: go-test ## Run go tests with the race detector enabled.
   671  
   672  .PHONY: go-test
   673  go-test: $(SETUP_ENVTEST) ## Run go tests.
   674  	KUBEBUILDER_ASSETS="$(KUBEBUILDER_ASSETS)" go test ./... $(TEST_ARGS)
   675  
   676  .PHONY: test-cover
   677  test-cover: TEST_ARGS+= -coverprofile coverage.out
   678  test-cover: test ## Run tests with code coverage and generate reports.
   679  	go tool cover -func=coverage.out -o coverage.txt
   680  	./hack/codecov-ignore.sh
   681  	go tool cover -html=coverage.out -o coverage.html
   682  
   683  .PHONY: kind-create-bootstrap
   684  kind-create-bootstrap: $(KUBECTL) ## Create capz kind bootstrap cluster.
   685  	export AZWI=$${AZWI:-true} KIND_CLUSTER_NAME=capz-e2e && ./scripts/kind-with-registry.sh
   686  
   687  ## --------------------------------------
   688  ## Security Scanning
   689  ## --------------------------------------
   690  
   691  .PHONY: verify-container-images
   692  verify-container-images: ## Verify container images
   693  	./hack/verify-container-images.sh
   694  
   695  ## --------------------------------------
   696  ## Tilt / Kind
   697  ## --------------------------------------
   698  
   699  ##@ Tilt / Kind:
   700  
   701  .PHONY: kind-create
   702  kind-create: $(KUBECTL) ## Create capz kind cluster if needed.
   703  	./scripts/kind-with-registry.sh
   704  
   705  .PHONY: tilt-up
   706  tilt-up: install-tools kind-create ## Start tilt and build kind cluster if needed.
   707  	CLUSTER_TOPOLOGY=true EXP_CLUSTER_RESOURCE_SET=true EXP_MACHINE_POOL=true EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION=true EXP_EDGEZONE=true tilt up
   708  
   709  .PHONY: delete-cluster
   710  delete-cluster: delete-workload-cluster  ## Deletes the example kind cluster "capz".
   711  	$(KIND) delete cluster --name=capz
   712  
   713  .PHONY: kind-reset
   714  kind-reset: $(KIND) ## Destroys the "capz" and "capz-e2e" kind clusters.
   715  	$(KIND) delete cluster --name=$(KIND_CLUSTER_NAME) || true
   716  	$(KIND) delete cluster --name=capz-e2e || true
   717  
   718  ## --------------------------------------
   719  ## Tooling Binaries
   720  ## --------------------------------------
   721  
   722  ##@ Tooling Binaries:
   723  
   724  conversion-verifier: $(CONVERSION_VERIFIER) go.mod go.sum ## Build a local copy of CAPI's conversion verifier.
   725  controller-gen: $(CONTROLLER_GEN) ## Build a local copy of controller-gen.
   726  conversion-gen: $(CONVERSION_GEN) ## Build a local copy of conversion-gen.
   727  envsubst: $(ENVSUBST) ## Build a local copy of envsubst.
   728  golangci-lint: $(GOLANGCI_LINT) ## Build a local copy of golang ci-lint.
   729  kustomize: $(KUSTOMIZE) ## Build a local copy of kustomize.
   730  mockgen: $(MOCKGEN) ## Build a local copy of mockgen.
   731  kpromo: $(KPROMO) ## Build a local copy of kpromo.
   732  release-notes: $(RELEASE_NOTES) ## Build a local copy of release notes.
   733  goapi-diff: $(GO_APIDIFF) ## Build a local copy of go api-diff.
   734  ginkgo: $(GINKGO) ## Build a local copy of ginkgo.
   735  kubectl: $(KUBECTL) ## Build a local copy of kubectl.
   736  helm: $(HELM) ## Build a local copy of helm.
   737  yq: $(YQ) ## Build a local copy of yq.
   738  kind: $(KIND) ## Build a local copy of kind.
   739  setup-envtest: $(SETUP_ENVTEST) ## Build a local copy of setup-envtest.
   740  codespell : $(CODESPELL) ## Build a local copy of codespell.
   741  
   742  $(CONVERSION_VERIFIER): go.mod
   743  	cd $(TOOLS_DIR); go build -tags=tools -o $@ sigs.k8s.io/cluster-api/hack/tools/conversion-verifier
   744  
   745  $(CONTROLLER_GEN): ## Build controller-gen from tools folder.
   746  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) sigs.k8s.io/controller-tools/cmd/controller-gen $(CONTROLLER_GEN_BIN) $(CONTROLLER_GEN_VER)
   747  
   748  $(CONVERSION_GEN): ## Build conversion-gen from tools folder.
   749  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) k8s.io/code-generator/cmd/conversion-gen $(CONVERSION_GEN_BIN) $(CONVERSION_GEN_VER)
   750  
   751  $(ENVSUBST): ## Build envsubst from tools folder.
   752  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) github.com/drone/envsubst/v2/cmd/envsubst $(ENVSUBST_BIN) $(ENVSUBST_VER)
   753  
   754  $(GOLANGCI_LINT): ## Build golangci-lint from tools folder.
   755  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) github.com/golangci/golangci-lint/cmd/golangci-lint $(GOLANGCI_LINT_BIN) $(GOLANGCI_LINT_VER)
   756  
   757  $(KUSTOMIZE): ## Build kustomize from tools folder.
   758  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) sigs.k8s.io/kustomize/kustomize/v4 $(KUSTOMIZE_BIN) $(KUSTOMIZE_VER)
   759  
   760  $(MOCKGEN): ## Build mockgen from tools folder.
   761  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) go.uber.org/mock/mockgen $(MOCKGEN_BIN) $(MOCKGEN_VER)
   762  
   763  $(KPROMO): ## Build kpromo from tools folder.
   764  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) sigs.k8s.io/promo-tools/v4/cmd/kpromo $(KPROMO_BIN) $(KPROMO_VER)
   765  
   766  $(RELEASE_NOTES): ## Build release notes from tools folder.
   767  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) k8s.io/release/cmd/release-notes $(RELEASE_NOTES_BIN) $(RELEASE_NOTES_VER)
   768  
   769  $(GO_APIDIFF): ## Build go-apidiff from tools folder.
   770  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) github.com/joelanford/go-apidiff $(GO_APIDIFF_BIN) $(GO_APIDIFF_VER)
   771  
   772  $(GINKGO): ## Build ginkgo from tools folder.
   773  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) github.com/onsi/ginkgo/v2/ginkgo $(GINKGO_BIN) $(GINKGO_VER)
   774  
   775  $(KUBECTL): ## Build kubectl from tools folder.
   776  	mkdir -p $(TOOLS_BIN_DIR)
   777  	rm -f "$(TOOLS_BIN_DIR)/$(KUBECTL_BIN)*"
   778  	curl --retry $(CURL_RETRIES) -fsL https://dl.k8s.io/release/$(KUBECTL_VER)/bin/$(GOOS)/$(GOARCH)/kubectl -o $(KUBECTL)
   779  	ln -sf $(KUBECTL) $(TOOLS_BIN_DIR)/$(KUBECTL_BIN)
   780  	chmod +x $(KUBECTL) $(TOOLS_BIN_DIR)/$(KUBECTL_BIN)
   781  
   782  $(HELM): ## Put helm into tools folder.
   783  	mkdir -p $(TOOLS_BIN_DIR)
   784  	rm -f "$(TOOLS_BIN_DIR)/$(HELM_BIN)*"
   785  	curl --retry $(CURL_RETRIES) -fsSL -o $(TOOLS_BIN_DIR)/get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
   786  	chmod 700 $(TOOLS_BIN_DIR)/get_helm.sh
   787  	USE_SUDO=false HELM_INSTALL_DIR=$(TOOLS_BIN_DIR) DESIRED_VERSION=$(HELM_VER) BINARY_NAME=$(HELM_BIN)-$(HELM_VER) $(TOOLS_BIN_DIR)/get_helm.sh
   788  	ln -sf $(HELM) $(TOOLS_BIN_DIR)/$(HELM_BIN)
   789  	rm -f $(TOOLS_BIN_DIR)/get_helm.sh
   790  
   791  $(KIND): ## Build kind into tools folder.
   792  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) sigs.k8s.io/kind $(KIND_BIN) $(KIND_VER)
   793  
   794  .PHONY: $(ENVSUBST_BIN)
   795  $(ENVSUBST_BIN): $(ENVSUBST)
   796  
   797  .PHONY: $(KUBECTL_BIN)
   798  $(KUBECTL_BIN): $(KUBECTL)
   799  
   800  .PHONY: $(HELM_BIN)
   801  $(HELM_BIN): $(HELM)
   802  
   803  .PHONY: $(GO_APIDIFF_BIN)
   804  $(GO_APIDIFF_BIN): $(GO_APIDIFF)
   805  
   806  $(YQ): ## Build yq from tools folder.
   807  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) github.com/mikefarah/yq/v4 $(YQ_BIN) $(YQ_VER)
   808  
   809  .PHONY: $(YQ_BIN)
   810  $(YQ_BIN): $(YQ) ## Building yq from the tools folder.
   811  
   812  .PHONY: $(KIND_BIN)
   813  $(KIND_BIN): $(KIND)
   814  
   815  .PHONY: $(SETUP_ENVTEST_BIN)
   816  $(SETUP_ENVTEST_BIN): $(SETUP_ENVTEST) ## Build a local copy of setup-envtest.
   817  
   818  $(SETUP_ENVTEST): # Build setup-envtest from tools folder.
   819  	GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(SETUP_ENVTEST_PKG) $(SETUP_ENVTEST_BIN) $(SETUP_ENVTEST_VER)
   820  
   821  $(CODESPELL): ## Build codespell from tools folder.
   822  	@which $(CODESPELL) >/dev/null || ( \
   823          mkdir -p $(TOOLS_BIN_DIR); \
   824          pip install --target=$(TOOLS_BIN_DIR)/$(CODESPELL_DIST_DIR) $(CODESPELL_BIN)==$(CODESPELL_VER); \
   825  		mv $(TOOLS_BIN_DIR)/$(CODESPELL_DIST_DIR)/bin/$(CODESPELL_BIN) $(TOOLS_BIN_DIR)/$(CODESPELL_DIST_DIR); \
   826  		rm -r $(TOOLS_BIN_DIR)/$(CODESPELL_DIST_DIR)/bin; \
   827      )
   828  
   829  include conformance.mk
   830  include e2e.mk