diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index e3a77772..81b92973 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -1,17 +1,20 @@ -# Update Go dependencies and GitHub Actions dependencies weekly. +# THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +# Edit https://github.com/cert-manager/makefile-modules/blob/main/modules/repository-base/base/.github/dependabot.yaml instead. + +# Update Go dependencies and GitHub Actions dependencies daily. version: 2 updates: - package-ecosystem: gomod directory: / schedule: - interval: weekly + interval: daily groups: all: patterns: ["*"] - package-ecosystem: github-actions directory: / schedule: - interval: weekly + interval: daily groups: all: patterns: ["*"] diff --git a/.github/workflows/debian-trust-package-release.yaml b/.github/workflows/debian-trust-package-release.yaml new file mode 100644 index 00000000..e14a799a --- /dev/null +++ b/.github/workflows/debian-trust-package-release.yaml @@ -0,0 +1,35 @@ +name: debian-trust-package-release +on: + push: + branches: ['main'] + paths: + - make/00_debian_version.mk + +jobs: + build_images: + runs-on: ubuntu-latest + + permissions: + contents: read # needed for checkout + packages: write # needed for push images + id-token: write # needed for keyless signing + + steps: + - uses: actions/checkout@v4 + + - uses: docker/login-action@v3 + with: + registry: quay.io + username: ${{ secrets.QUAY_USERNAME }} + password: ${{ secrets.QUAY_PASSWORD }} + + - uses: actions/setup-go@v4 + with: + go-version-file: go.mod + + - id: release + run: make release-debian-trust-package + + outputs: + RELEASE_OCI_MANAGER_IMAGE: ${{ steps.release.outputs.RELEASE_OCI_MANAGER_IMAGE }} + RELEASE_OCI_MANAGER_TAG: ${{ steps.release.outputs.RELEASE_OCI_MANAGER_TAG }} diff --git a/.github/workflows/debian-trust-package-upgrade.yaml b/.github/workflows/debian-trust-package-upgrade.yaml new file mode 100644 index 00000000..80e2d3a6 --- /dev/null +++ b/.github/workflows/debian-trust-package-upgrade.yaml @@ -0,0 +1,86 @@ +name: debian-trust-package-upgrade +concurrency: debian-trust-package-upgrade +on: + workflow_dispatch: {} + schedule: + - cron: '0 0 * * *' + +jobs: + debian-trust-package-upgrade: + runs-on: ubuntu-latest + + permissions: + contents: write + pull-requests: write + + env: + SOURCE_BRANCH: "${{ github.ref_name }}" + SELF_UPGRADE_BRANCH: "debian-trust-package-upgrade-${{ github.ref_name }}" + + steps: + - name: Fail if branch is not head of branch. + if: ${{ !startsWith(github.ref, 'refs/heads/') && env.SOURCE_BRANCH != '' && env.SELF_UPGRADE_BRANCH != '' }} + run: | + echo "This workflow should not be run on a non-branch-head." + exit 1 + + - uses: actions/checkout@v4 + + - id: go-version + run: | + make print-go-version >> "$GITHUB_OUTPUT" + + - uses: actions/setup-go@v5 + with: + go-version: ${{ steps.go-version.outputs.result }} + + - run: | + git checkout -B "$SELF_UPGRADE_BRANCH" + + - run: | + make -j upgrade-debian-trust-package-version + + - id: is-up-to-date + shell: bash + run: | + git_status=$(git status -s) + is_up_to_date="true" + if [ -n "$git_status" ]; then + is_up_to_date="false" + echo "The following changes will be committed:" + echo "$git_status" + fi + echo "result=$is_up_to_date" >> "$GITHUB_OUTPUT" + + - if: ${{ steps.is-up-to-date.outputs.result != 'true' }} + run: | + git config --global user.name "cert-manager-bot" + git config --global user.email "cert-manager-bot@users.noreply.github.com" + git add -A && git commit -m "BOT: run 'make upgrade-klone' and 'make generate'" --signoff + git push -f origin "$SELF_UPGRADE_BRANCH" + + - if: ${{ steps.is-up-to-date.outputs.result != 'true' }} + uses: actions/github-script@v7 + with: + script: | + const { repo, owner } = context.repo; + const pulls = await github.rest.pulls.list({ + owner: owner, + repo: repo, + head: owner + ':' + process.env.SELF_UPGRADE_BRANCH, + base: process.env.SOURCE_BRANCH, + state: 'open', + }); + + if (pulls.data.length < 1) { + await github.rest.pulls.create({ + title: '[CI] Merge ' + process.env.SELF_UPGRADE_BRANCH + ' into ' + process.env.SOURCE_BRANCH, + owner: owner, + repo: repo, + head: process.env.SELF_UPGRADE_BRANCH, + base: process.env.SOURCE_BRANCH, + body: [ + 'This PR is auto-generated to bump the Makefile modules.', + ].join('\n'), + }); + } diff --git a/.github/workflows/govulncheck.yaml b/.github/workflows/govulncheck.yaml new file mode 100644 index 00000000..405e8dec --- /dev/null +++ b/.github/workflows/govulncheck.yaml @@ -0,0 +1,28 @@ +# THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +# Edit https://github.com/cert-manager/makefile-modules/blob/main/modules/go/base/.github/workflows/govulncheck.yaml instead. + +# Run govulncheck at midnight every night on the main branch, +# to alert us to recent vulnerabilities which affect the Go code in this +# project. +name: govulncheck +on: + workflow_dispatch: {} + schedule: + - cron: '0 0 * * *' + +jobs: + govulncheck: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - id: go-version + run: | + make print-go-version >> "$GITHUB_OUTPUT" + + - uses: actions/setup-go@v5 + with: + go-version: ${{ steps.go-version.outputs.result }} + + - run: make verify-govulncheck diff --git a/.github/workflows/make-self-upgrade.yaml b/.github/workflows/make-self-upgrade.yaml new file mode 100644 index 00000000..93beedff --- /dev/null +++ b/.github/workflows/make-self-upgrade.yaml @@ -0,0 +1,90 @@ +# THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +# Edit https://github.com/cert-manager/makefile-modules/blob/main/modules/repository-base/base/.github/workflows/make-self-upgrade.yaml instead. + +name: make-self-upgrade +concurrency: make-self-upgrade +on: + workflow_dispatch: {} + schedule: + - cron: '0 0 * * *' + +jobs: + self_upgrade: + runs-on: ubuntu-latest + + permissions: + contents: write + pull-requests: write + + env: + SOURCE_BRANCH: "${{ github.ref_name }}" + SELF_UPGRADE_BRANCH: "self-upgrade-${{ github.ref_name }}" + + steps: + - name: Fail if branch is not head of branch. + if: ${{ !startsWith(github.ref, 'refs/heads/') && env.SOURCE_BRANCH != '' && env.SELF_UPGRADE_BRANCH != '' }} + run: | + echo "This workflow should not be run on a non-branch-head." + exit 1 + + - uses: actions/checkout@v4 + + - id: go-version + run: | + make print-go-version >> "$GITHUB_OUTPUT" + + - uses: actions/setup-go@v5 + with: + go-version: ${{ steps.go-version.outputs.result }} + + - run: | + git checkout -B "$SELF_UPGRADE_BRANCH" + + - run: | + make -j upgrade-klone + make -j generate + + - id: is-up-to-date + shell: bash + run: | + git_status=$(git status -s) + is_up_to_date="true" + if [ -n "$git_status" ]; then + is_up_to_date="false" + echo "The following changes will be committed:" + echo "$git_status" + fi + echo "result=$is_up_to_date" >> "$GITHUB_OUTPUT" + + - if: ${{ steps.is-up-to-date.outputs.result != 'true' }} + run: | + git config --global user.name "cert-manager-bot" + git config --global user.email "cert-manager-bot@users.noreply.github.com" + git add -A && git commit -m "BOT: run 'make upgrade-klone' and 'make generate'" --signoff + git push -f origin "$SELF_UPGRADE_BRANCH" + + - if: ${{ steps.is-up-to-date.outputs.result != 'true' }} + uses: actions/github-script@v7 + with: + script: | + const { repo, owner } = context.repo; + const pulls = await github.rest.pulls.list({ + owner: owner, + repo: repo, + head: owner + ':' + process.env.SELF_UPGRADE_BRANCH, + base: process.env.SOURCE_BRANCH, + state: 'open', + }); + + if (pulls.data.length < 1) { + await github.rest.pulls.create({ + title: '[CI] Merge ' + process.env.SELF_UPGRADE_BRANCH + ' into ' + process.env.SOURCE_BRANCH, + owner: owner, + repo: repo, + head: process.env.SELF_UPGRADE_BRANCH, + base: process.env.SOURCE_BRANCH, + body: [ + 'This PR is auto-generated to bump the Makefile modules.', + ].join('\n'), + }); + } diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 00000000..525016a2 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,84 @@ +name: release +on: + push: + tags: + - "v*" + +env: + VERSION: ${{ github.ref_name }} + +jobs: + build_images: + runs-on: ubuntu-latest + + permissions: + contents: read # needed for checkout + packages: write # needed for push images + id-token: write # needed for keyless signing + + steps: + - uses: actions/checkout@v4 + + - uses: docker/login-action@v3 + with: + registry: quay.io + username: ${{ secrets.QUAY_USERNAME }} + password: ${{ secrets.QUAY_PASSWORD }} + + - uses: actions/setup-go@v4 + with: + go-version-file: go.mod + + - id: release + run: make release + + - uses: actions/upload-artifact@v3 + with: + name: trust-manager-${{ env.VERSION }}.tgz + path: ${{ steps.release.outputs.RELEASE_HELM_CHART_TAR }} + + outputs: + RELEASE_OCI_MANAGER_IMAGE: ${{ steps.release.outputs.RELEASE_OCI_MANAGER_IMAGE }} + RELEASE_OCI_MANAGER_TAG: ${{ steps.release.outputs.RELEASE_OCI_MANAGER_TAG }} + RELEASE_OCI_PACKAGE_DEBIAN_IMAGE: ${{ steps.release.outputs.RELEASE_OCI_PACKAGE_DEBIAN_IMAGE }} + RELEASE_OCI_PACKAGE_DEBIAN_TAG: ${{ steps.release.outputs.RELEASE_OCI_PACKAGE_DEBIAN_TAG }} + RELEASE_HELM_CHART_NAME: ${{ steps.release.outputs.RELEASE_HELM_CHART_NAME }} + RELEASE_HELM_CHART_VERSION: ${{ steps.release.outputs.RELEASE_HELM_CHART_VERSION }} + + github_release: + runs-on: ubuntu-latest + + needs: build_images + + permissions: + contents: write # needed for creating a PR + pull-requests: write # needed for creating a PR + + steps: + - run: | + touch .notes-file + echo "OCI_MANAGER_IMAGE: ${{ needs.build_images.outputs.RELEASE_OCI_MANAGER_IMAGE }}" >> .notes-file + echo "OCI_MANAGER_TAG: ${{ needs.build_images.outputs.RELEASE_OCI_MANAGER_TAG }}" >> .notes-file + echo "OCI_PACKAGE_DEBIAN_IMAGE: ${{ needs.build_images.outputs.RELEASE_OCI_PACKAGE_DEBIAN_IMAGE }}" >> .notes-file + echo "OCI_PACKAGE_DEBIAN_TAG: ${{ needs.build_images.outputs.RELEASE_OCI_PACKAGE_DEBIAN_TAG }}" >> .notes-file + echo "HELM_CHART_NAME: ${{ needs.build_images.outputs.RELEASE_HELM_CHART_NAME }}" >> .notes-file + echo "HELM_CHART_VERSION: ${{ needs.build_images.outputs.RELEASE_HELM_CHART_VERSION }}" >> .notes-file + + - id: chart_download + uses: actions/download-artifact@v3 + with: + name: trust-manager-${{ env.VERSION }}.tgz + + - env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create "$VERSION" \ + --repo="$GITHUB_REPOSITORY" \ + --title="${GITHUB_REPOSITORY#*/} ${VERSION#v}" \ + --draft \ + --verify-tag \ + --notes-file .notes-file + + gh release upload "$VERSION" \ + --repo="$GITHUB_REPOSITORY" \ + "${{ steps.chart_download.outputs.download-path }}/trust-manager-$VERSION.tgz" diff --git a/.gitignore b/.gitignore index ed1f0c72..dea47876 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,31 @@ -/bin -/_artifacts -/.vscode -/.idea/ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin +testbin/* + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Kubernetes Generated files - skip generated files, except for vendored files +!vendor/**/zz_generated.* + +# editor and IDE paraphernalia +.idea +*.swp +*.swo +*~ + +_bin +_certs +_artifacts +.vscode + +# direnv files +.envrc diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 00000000..f3d10224 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,94 @@ +issues: + exclude-rules: + - linters: + - errcheck + - typecheck + - staticcheck + - gosimple + - contextcheck + - promlinter + - prealloc + - containedctx + - gci + - errorlint + - gosec + - unparam + - gocritic + - gofmt + - unconvert + - misspell + - mirror + - wastedassign + - ineffassign + - unused + - dupword + text: ".*" +linters: + # Explicitly define all enabled linters + disable-all: true + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - contextcheck + - decorder + - dogsled + - dupword + - durationcheck + - errcheck + - errchkjson + - errname + - execinquery + - exhaustive + - exportloopref + - forbidigo + - gci + - ginkgolinter + - gocheckcompilerdirectives + - gochecksumtype + - gocritic + - gofmt + - goheader + - goprintffuncname + - gosec + - gosimple + - gosmopolitan + - govet + - grouper + - importas + - ineffassign + - interfacebloat + - loggercheck + - makezero + - mirror + - misspell + - musttag + - nakedret + - nilerr + - nilnil + - noctx + - nosprintfhostport + - predeclared + - promlinter + - protogetter + - reassign + - sloglint + - staticcheck + - tagalign + - tenv + - testableexamples + - typecheck + - unconvert + - unparam + - unused + - usestdlibvars + - wastedassign +linters-settings: + gci: + sections: + - standard # Standard section: captures all standard packages. + - default # Default section: contains all imports that could not be matched to another section type. + - prefix(github.com/cert-manager/trust-manager) # Custom section: groups all imports with the specified Prefix. + - blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled. + - dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled. diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index f211f167..00000000 --- a/Dockerfile +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2021 The cert-manager 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. - -# Build the trust binary -FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.22 as builder - -ARG GOPROXY -ARG TARGETARCH - -WORKDIR /workspace -# Copy the Go Modules manifests -COPY go.mod go.mod -COPY go.sum go.sum - -# Copy build scripts -COPY Makefile Makefile -COPY make/ make/ - -# Copy the go source files -COPY cmd/ cmd/ -COPY pkg/ pkg/ -COPY hack/ hack/ - -RUN GOPROXY=$GOPROXY go mod download - -# Build -RUN make build-linux-$TARGETARCH - -FROM scratch - -ARG TARGETARCH - -LABEL description="trust-manager is an operator for distributing trust bundles across a Kubernetes cluster" - -WORKDIR / -USER 1001 -COPY --from=builder /workspace/bin/trust-manager-linux-$TARGETARCH /usr/bin/trust-manager - -ENTRYPOINT ["/usr/bin/trust-manager"] diff --git a/Makefile b/Makefile index cde6e5ff..6c5aa126 100644 --- a/Makefile +++ b/Makefile @@ -12,293 +12,105 @@ # See the License for the specific language governing permissions and # limitations under the License. +# THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +# Edit https://github.com/cert-manager/makefile-modules/blob/main/modules/repository-base/base/Makefile instead. + +# NOTE FOR DEVELOPERS: "How do the Makefiles work and how can I extend them?" +# +# Shared Makefile logic lives in the make/_shared/ directory. The source of truth for these files +# lies outside of this repository, eg. in the cert-manager/makefile-modules repository. +# +# Logic specific to this repository must be defined in the make/00_mod.mk and make/02_mod.mk files: +# - The make/00_mod.mk file is included first and contains variable definitions needed by +# the shared Makefile logic. +# - The make/02_mod.mk file is included later, it can make use of most of the shared targets +# defined in the make/_shared/ directory (all targets defined in 00_mod.mk and 01_mod.mk). +# This file should be used to define targets specific to this repository. + +################################## + +# Some modules build their dependencies from variables, we want these to be +# evalutated at the last possible moment. For this we use second expansion to +# re-evaluate the generate and verify targets a second time. +# +# See https://www.gnu.org/software/make/manual/html_node/Secondary-Expansion.html +.SECONDEXPANSION: + +# For details on some of these "prelude" settings, see: +# https://clarkgrubb.com/makefile-style-guide MAKEFLAGS += --warn-undefined-variables --no-builtin-rules SHELL := /usr/bin/env bash .SHELLFLAGS := -uo pipefail -c .DEFAULT_GOAL := help .DELETE_ON_ERROR: +.SUFFIXES: FORCE: -BINDIR ?= $(CURDIR)/bin - -ARCH ?= $(shell go env GOARCH) -OS ?= $(shell go env GOOS) - -HELM_VERSION ?= 3.12.3 -KUBEBUILDER_TOOLS_VERISON ?= 1.28.0 -KUBECTL_VERSION ?= 1.28.2 -YQ_VERSION ?= v4.40.5 -KIND_VERSION ?= $(shell grep "sigs.k8s.io/kind" go.mod | awk '{print $$NF}') -GINKGO_VERSION ?= $(shell grep "github.com/onsi/ginkgo/v2" go.mod | awk '{print $$NF}') -HELM_TOOL_VERSION ?= $(shell grep "github.com/cert-manager/helm-tool" hack/tools/go.mod | awk '{print $$NF}') -BOILERSUITE_VERSION ?= $(shell grep "github.com/cert-manager/boilersuite" hack/tools/go.mod | awk '{print $$NF}') -CONTROLLER_TOOLS_VERSION ?= $(shell grep "sigs.k8s.io/controller-tools" hack/tools/go.mod | awk '{print $$NF}') -CODE_GENERATOR_VERSION ?= $(shell grep "k8s.io/code-generator" hack/tools/go.mod | awk '{print $$NF}') - -IMAGE_PLATFORMS ?= linux/amd64,linux/arm64,linux/arm/v7,linux/ppc64le,linux/s390x - -RELEASE_VERSION ?= v0.9.0 - -BUILDX_BUILDER ?= trust-manager-builder - -CONTAINER_REGISTRY ?= quay.io/jetstack -CONTAINER_REGISTRY_API_URL ?= https://quay.io/v2/jetstack/cert-manager-package-debian/manifests - -GOPROXY ?= https://proxy.golang.org,direct - -GO_SOURCES := $(shell find . -name "*.go") go.mod go.sum - -CGO_ENABLED ?= 0 -GOEXPERIMENT ?= # empty by default - -CI ?= - -# can't use a comma in an argument to a make function, so define a variable instead -_COMMA := , - -include make/color.mk -include make/trust-manager-build.mk -include make/trust-package-debian.mk - -.PHONY: help -help: ## display this help - @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n\nTargets:\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST) - -.PHONY: all -all: depend generate test build image ## runs test, build and image - -.PHONY: test -test: lint unit-test integration-test ## test trust-manager, running linters, unit and integration tests - -.PHONY: unit-test -unit-test: ## runs unit tests, defined as any test which doesn't require external stup - go test -v ./pkg/... ./cmd/... - -.PHONY: integration-test -integration-test: | $(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON)/kube-apiserver $(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON)/etcd ## runs integration tests, defined as tests which require external setup (but not full end-to-end tests) - KUBEBUILDER_ASSETS=$(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON) go test -v ./test/integration/... - -.PHONY: lint -lint: vet verify-boilerplate - -# Run the supplied make target argument in a temporary workspace and diff the results. -verify-%: FORCE - ./hack/util/verify.sh $(MAKE) -s $* - -.PHONY: verify -verify: ## build, test and verify generate tagets -verify: depend build test -verify: verify-generate - -.PHONY: verify-boilerplate -verify-boilerplate: | $(BINDIR)/boilersuite-$(BOILERSUITE_VERSION)/boilersuite - $(BINDIR)/boilersuite-$(BOILERSUITE_VERSION)/boilersuite . - -.PHONY: vet -vet: - go vet ./... - -.PHONY: build -build: $(BINDIR)/trust-manager | $(BINDIR) ## build trust-manager for the host system architecture - -.PHONY: build-linux-amd64 build-linux-arm64 build-linux-ppc64le build-linux-arm build-linux-s390x -build-linux-amd64 build-linux-arm64 build-linux-ppc64le build-linux-arm build-linux-s390x: build-linux-%: $(BINDIR)/trust-manager-linux-% - -$(BINDIR)/trust-manager: $(GO_SOURCES) | $(BINDIR) - CGO_ENABLED=$(CGO_ENABLED) GOEXPERIMENT=$(GOEXPERIMENT) \ - go build -o $(BINDIR)/trust-manager ./cmd/trust-manager - -$(BINDIR)/trust-manager-linux-amd64 $(BINDIR)/trust-manager-linux-arm64 $(BINDIR)/trust-manager-linux-ppc64le $(BINDIR)/trust-manager-linux-arm $(BINDIR)/trust-manager-linux-s390x: $(BINDIR)/trust-manager-linux-%: $(GO_SOURCES) | $(BINDIR) - CGO_ENABLED=$(CGO_ENABLED) GOEXPERIMENT=$(GOEXPERIMENT) \ - GOOS=linux GOARCH=$* \ - go build -o $@ ./cmd/trust-manager - -.PHONY: generate -generate: depend generate-deepcopy generate-applyconfigurations generate-manifests generate-helm-docs generate-helm-schema - -.PHONY: generate-deepcopy -generate-deepcopy: ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. -generate-deepcopy: | $(BINDIR)/controller-tools-$(CONTROLLER_TOOLS_VERSION)/controller-gen - $(BINDIR)/controller-tools-$(CONTROLLER_TOOLS_VERSION)/controller-gen object:headerFile="hack/boilerplate/boilerplate.go.txt" paths="./..." - -GO_MODULE := $(shell go list -m) -API_DIRS := $(shell find pkg/apis -mindepth 2 -type d | sed "s|^|$(GO_MODULE)/|" | paste -sd "," -) - -.PHONY: generate-applyconfigurations -generate-applyconfigurations: ## Generate applyconfigurations to support typesafe SSA. -generate-applyconfigurations: | $(BINDIR)/code-generator-$(CODE_GENERATOR_VERSION)/applyconfiguration-gen - rm -rf pkg/applyconfigurations - @echo ">> generating pkg/applyconfigurations..." - $(BINDIR)/code-generator-$(CODE_GENERATOR_VERSION)/applyconfiguration-gen \ - --go-header-file hack/boilerplate/boilerplate.go.txt \ - --input-dirs "$(API_DIRS)" \ - --output-package "$(GO_MODULE)/pkg/applyconfigurations" \ - --trim-path-prefix "$(GO_MODULE)" \ - --output-base "." - -.PHONY: generate-manifests -generate-manifests: ## Generate CustomResourceDefinition objects. -generate-manifests: $(BINDIR)/controller-tools-$(CONTROLLER_TOOLS_VERSION)/controller-gen $(BINDIR)/yq-$(YQ_VERSION)/yq - ./hack/update-codegen.sh $^ - -# See wait-for-buildx.sh for an explanation of why it's needed -.PHONY: provision-buildx -provision-buildx: ## set up docker buildx for multiarch building; required for building images -ifeq ($(OS), linux) - # This step doesn't work on macOS and doesn't seem to be required (at least with docker desktop) - # It did seem to be needed in Linux, at least in certain configurations when running on amd64 - # TODO: it might be preferable to move away from docker buildx in the long term to avoid the dependency on Docker - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes +noop: # do nothing + +# Set empty value for MAKECMDGOALS to prevent the "warning: undefined variable 'MAKECMDGOALS'" +# warning from happening when running make without arguments +MAKECMDGOALS ?= + +################################## +# Host OS and architecture setup # +################################## + +# The reason we don't use "go env GOOS" or "go env GOARCH" is that the "go" +# binary may not be available in the PATH yet when the Makefiles are +# evaluated. HOST_OS and HOST_ARCH only support Linux, *BSD and macOS (M1 +# and Intel). +host_os := $(shell uname -s | tr A-Z a-z) +host_arch := $(shell uname -m) +HOST_OS ?= $(host_os) +HOST_ARCH ?= $(host_arch) + +ifeq (x86_64, $(HOST_ARCH)) + HOST_ARCH = amd64 +else ifeq (aarch64, $(HOST_ARCH)) + # linux reports the arm64 arch as aarch64 + HOST_ARCH = arm64 endif - docker buildx rm $(BUILDX_BUILDER) &>/dev/null || : - ./hack/wait-for-buildx.sh $(BUILDX_BUILDER) gone - docker buildx create --name $(BUILDX_BUILDER) --bootstrap --driver docker-container --platform $(IMAGE_PLATFORMS) - ./hack/wait-for-buildx.sh $(BUILDX_BUILDER) exists - docker buildx inspect --bootstrap --builder $(BUILDX_BUILDER) -.PHONY: image -image: trust-manager-save | $(BINDIR) ## build trust-manager container images targeting all supported platforms and save to disk. Requires `make provision-buildx` +################################## +# Git and versioning information # +################################## -.PHONY: local-images -local-images: trust-manager-load trust-package-debian-load ## build container images for only the local architecture and load into docker. Requires `make provision-buildx` +git_version := $(shell git describe --tags --always --match='v*' --abbrev=14 --dirty) +VERSION ?= $(git_version) +IS_PRERELEASE := $(shell git describe --tags --always --match='v*' --abbrev=0 | grep -q '-' && echo true || echo false) +GITCOMMIT := $(shell git rev-parse HEAD) +GITEPOCH := $(shell git show -s --format=%ct HEAD) -.PHONY: kind-load -kind-load: local-images | $(BINDIR)/kind-$(KIND_VERSION)/kind ## same as local-images but also run "kind load docker-image" - $(BINDIR)/kind-$(KIND_VERSION)/kind load docker-image \ - --name trust \ - $(CONTAINER_REGISTRY)/trust-manager:latest \ - $(CONTAINER_REGISTRY)/cert-manager-package-debian:latest$(DEBIAN_TRUST_PACKAGE_SUFFIX) +################################## +# Global variables and dirs # +################################## -.PHONY: chart -chart: | $(BINDIR)/helm-$(HELM_VERSION)/helm $(BINDIR)/chart - $(BINDIR)/helm-$(HELM_VERSION)/helm package --app-version=$(RELEASE_VERSION) --version=$(RELEASE_VERSION) --destination "$(BINDIR)/chart" ./deploy/charts/trust-manager +bin_dir := _bin -.PHONY: generate-helm-docs -generate-helm-docs: | $(BINDIR)/helm-tool-$(HELM_TOOL_VERSION)/helm-tool ## update Helm README, generated from other Helm files - ./hack/update-helm-tool.sh $(BINDIR)/helm-tool-$(HELM_TOOL_VERSION)/helm-tool +# The ARTIFACTS environment variable is set by the CI system to a directory +# where artifacts should be placed. These artifacts are then uploaded to a +# storage bucket by the CI system (https://docs.prow.k8s.io/docs/components/pod-utilities/). +# An example of such an artifact is a jUnit XML file containing test results. +# If the ARTIFACTS environment variable is not set, we default to a local +# directory in the _bin directory. +ARTIFACTS ?= $(bin_dir)/artifacts -.PHONY: generate-helm-schema -generate-helm-schema: | $(BINDIR)/helm-tool-$(HELM_TOOL_VERSION)/helm-tool ## update Helm README, generated from other Helm files - $(BINDIR)/helm-tool-$(HELM_TOOL_VERSION)/helm-tool schema -i ./deploy/charts/trust-manager/values.yaml | jq > ./deploy/charts/trust-manager/values.schema.json +$(bin_dir) $(ARTIFACTS) $(bin_dir)/scratch: + mkdir -p $@ .PHONY: clean -clean: ## clean up created files - rm -rf \ - $(BINDIR) \ - _artifacts - -.PHONY: demo -demo: ensure-kind kind-load ensure-cert-manager ensure-trust-manager $(BINDIR)/kubeconfig.yaml ## ensure a cluster ready for a smoke test or local testing - -.PHONY: smoke -smoke: demo | $(BINDIR)/ginkgo-$(GINKGO_VERSION)/ginkgo ## ensure local cluster exists, deploy trust-manager and run smoke tests - $(BINDIR)/ginkgo-$(GINKGO_VERSION)/ginkgo -procs 1 test/smoke/ -- --kubeconfig-path $(BINDIR)/kubeconfig.yaml - -$(BINDIR)/kubeconfig.yaml: ensure-ci-docker-network _FORCE test/kind-cluster.yaml | $(BINDIR)/kind-$(KIND_VERSION)/kind - @if $(BINDIR)/kind-$(KIND_VERSION)/kind get clusters | grep -q "^trust$$"; then \ - echo "cluster already exists, not trying to create"; \ - $(BINDIR)/kind-$(KIND_VERSION)/kind get kubeconfig --name trust > $@ && chmod 600 $@; \ - else \ - $(BINDIR)/kind-$(KIND_VERSION)/kind create cluster --config test/kind-cluster.yaml --kubeconfig $@ && chmod 600 $@; \ - echo -e "$(_RED)kind cluster 'trust' was created; to access it, pass '--kubeconfig $(BINDIR)/kubeconfig.yaml' to kubectl/helm$(_END)"; \ - sleep 2; \ - fi - -.PHONY: ensure-kind -ensure-kind: $(BINDIR)/kubeconfig.yaml ## create a trust-manager kind cluster, if one doesn't already exist - -.PHONY: ensure-cert-manager -ensure-cert-manager: ensure-kind $(BINDIR)/kubeconfig.yaml | $(BINDIR)/helm-$(HELM_VERSION)/helm ## ensure cert-manager is installed on cluster for testing - @if $(BINDIR)/helm-$(HELM_VERSION)/helm --kubeconfig $(BINDIR)/kubeconfig.yaml list --short --namespace cert-manager --selector name=cert-manager | grep -q cert-manager; then \ - echo "cert-manager already installed, not trying to reinstall"; \ - else \ - $(BINDIR)/helm-$(HELM_VERSION)/helm repo add jetstack https://charts.jetstack.io --force-update; \ - $(BINDIR)/helm-$(HELM_VERSION)/helm upgrade --kubeconfig $(BINDIR)/kubeconfig.yaml -i --create-namespace -n cert-manager cert-manager jetstack/cert-manager --set installCRDs=true --wait; \ - fi - -.PHONY: ensure-trust-manager -ensure-trust-manager: ensure-kind kind-load ensure-cert-manager | $(BINDIR)/helm-$(HELM_VERSION)/helm ## ensure trust-manager is available on cluster, built from local checkout - $(BINDIR)/helm-$(HELM_VERSION)/helm uninstall --kubeconfig $(BINDIR)/kubeconfig.yaml -n cert-manager trust-manager || : - $(BINDIR)/helm-$(HELM_VERSION)/helm upgrade --kubeconfig $(BINDIR)/kubeconfig.yaml -i -n cert-manager trust-manager deploy/charts/trust-manager/. \ - --set image.tag=latest \ - --set defaultPackageImage.tag=latest$(DEBIAN_TRUST_PACKAGE_SUFFIX) \ - --set app.logLevel=2 \ - --set secretTargets.enabled=true --set secretTargets.authorizedSecretsAll=true \ - --wait - -# When running in our CI environment the Docker network's subnet choice -# causees issues with routing. -# Creating a custom kind network gets around that problem. -.PHONY: ensure-ci-docker-network -ensure-ci-docker-network: -ifneq ($(strip $(CI)),) - @echo -e "$(_RED)Creating CI docker network$(_END); this will cause problems if you're not in CI" - @echo "To undo, run 'docker network rm kind'" - @sleep 2 - docker network create --driver=bridge --subnet=192.168.0.0/16 --gateway 192.168.0.1 kind || true - @# Sleep for 2s to avoid any races between docker's network subcommand and 'kind create' - @sleep 2 -endif - -.PHONY: build-validate-trust-package -build-validate-trust-package: $(BINDIR)/validate-trust-package - -$(BINDIR)/validate-trust-package: cmd/validate-trust-package/main.go pkg/fspkg/package.go | $(BINDIR) - CGO_ENABLED=0 go build -o $@ $< - -.PHONY: depend -depend: $(BINDIR)/controller-tools-$(CONTROLLER_TOOLS_VERSION)/controller-gen -depend: $(BINDIR)/code-generator-$(CODE_GENERATOR_VERSION)/applyconfiguration-gen -depend: $(BINDIR)/boilersuite-$(BOILERSUITE_VERSION)/boilersuite -depend: $(BINDIR)/kind-$(KIND_VERSION)/kind -depend: $(BINDIR)/helm-tool-$(HELM_TOOL_VERSION)/helm-tool -depend: $(BINDIR)/helm-$(HELM_VERSION)/helm -depend: $(BINDIR)/ginkgo-$(GINKGO_VERSION)/ginkgo -depend: $(BINDIR)/kubectl-$(KUBECTL_VERSION)/kubectl -depend: $(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON)/kube-apiserver -depend: $(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON)/etcd -depend: $(BINDIR)/yq-$(YQ_VERSION)/yq - -$(BINDIR)/controller-tools-$(CONTROLLER_TOOLS_VERSION)/controller-gen: | $(BINDIR)/controller-tools-$(CONTROLLER_TOOLS_VERSION) - cd hack/tools && go build -o $@ sigs.k8s.io/controller-tools/cmd/controller-gen - -$(BINDIR)/code-generator-$(CODE_GENERATOR_VERSION)/applyconfiguration-gen: | $(BINDIR)/code-generator-$(CODE_GENERATOR_VERSION) - cd hack/tools && go build -o $@ k8s.io/code-generator/cmd/applyconfiguration-gen - -$(BINDIR)/boilersuite-$(BOILERSUITE_VERSION)/boilersuite: | $(BINDIR)/boilersuite-$(BOILERSUITE_VERSION) - cd hack/tools && go build -o $@ github.com/cert-manager/boilersuite - -$(BINDIR)/kind-$(KIND_VERSION)/kind: | $(BINDIR)/kind-$(KIND_VERSION) - cd hack/tools && go build -o $@ sigs.k8s.io/kind - -$(BINDIR)/helm-tool-$(HELM_TOOL_VERSION)/helm-tool: | $(BINDIR)/helm-tool-$(HELM_TOOL_VERSION) - cd hack/tools && go build -o $@ github.com/cert-manager/helm-tool - -$(BINDIR)/helm-$(HELM_VERSION)/helm: $(BINDIR)/helm-$(HELM_VERSION)/helm-v$(HELM_VERSION)-$(OS)-$(ARCH).tar.gz | $(BINDIR) - tar xfO $< $(OS)-$(ARCH)/helm > $@ && chmod +x $@ - -$(BINDIR)/helm-$(HELM_VERSION)/helm-v$(HELM_VERSION)-$(OS)-$(ARCH).tar.gz: | $(BINDIR)/helm-$(HELM_VERSION) - curl -o $@ -LO "https://get.helm.sh/helm-v$(HELM_VERSION)-$(OS)-$(ARCH).tar.gz" - -$(BINDIR)/ginkgo-$(GINKGO_VERSION)/ginkgo: | $(BINDIR) - GOBIN=$(dir $@) go install github.com/onsi/ginkgo/v2/ginkgo@$(GINKGO_VERSION) - -$(BINDIR)/kubectl-$(KUBECTL_VERSION)/kubectl: | $(BINDIR)/kubectl-$(KUBECTL_VERSION) - curl -o $@ -L "https://storage.googleapis.com/kubernetes-release/release/v$(KUBECTL_VERSION)/bin/$(OS)/$(ARCH)/kubectl" && chmod +x $@ - -$(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON)/etcd: $(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON)/envtest-bins.tar.gz | $(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON) - tar xfO $< kubebuilder/bin/etcd > $@ && chmod +x $@ - -$(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON)/kube-apiserver: $(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON)/envtest-bins.tar.gz | $(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON) - tar xfO $< kubebuilder/bin/kube-apiserver > $@ && chmod +x $@ - -$(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON)/envtest-bins.tar.gz: | $(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON) - curl -sSL -o $@ "https://storage.googleapis.com/kubebuilder-tools/kubebuilder-tools-$(KUBEBUILDER_TOOLS_VERISON)-$(OS)-$(ARCH).tar.gz" - -$(BINDIR)/yq-$(YQ_VERSION)/yq: | $(BINDIR)/yq-$(YQ_VERSION) - curl -o $@ -L "https://github.com/mikefarah/yq/releases/download/$(YQ_VERSION)/yq_$(OS)_$(ARCH)" && chmod +x $@ - -$(BINDIR) $(BINDIR)/kubectl-$(KUBECTL_VERSION) $(BINDIR)/kubebuilder-$(KUBEBUILDER_TOOLS_VERISON) $(BINDIR)/chart $(BINDIR)/ginkgo-$(GINKGO_VERSION) $(BINDIR)/helm-$(HELM_VERSION) $(BINDIR)/helm-tool-$(HELM_TOOL_VERSION) $(BINDIR)/kind-$(KIND_VERSION) $(BINDIR)/boilersuite-$(BOILERSUITE_VERSION) $(BINDIR)/controller-tools-$(CONTROLLER_TOOLS_VERSION) $(BINDIR)/code-generator-$(CODE_GENERATOR_VERSION) $(BINDIR)/yq-$(YQ_VERSION): - @mkdir -p $@ - -_FORCE: +## Clean all temporary files +## @category [shared] Tools +clean: + rm -rf $(bin_dir) + +################################## +# Include all the Makefiles # +################################## + +-include make/00_mod.mk +-include make/_shared/*/00_mod.mk +-include make/_shared/*/01_mod.mk +-include make/02_mod.mk +-include make/_shared/*/02_mod.mk diff --git a/OWNERS b/OWNERS index 18b15f05..bfa90218 100644 --- a/OWNERS +++ b/OWNERS @@ -1,21 +1,7 @@ approvers: -- munnerz -- joshvanl -- wallrj -- jakexks -- maelvls -- irbekrm -- sgtcodfish -- inteon +- cm-maintainers - erikgb reviewers: -- munnerz -- joshvanl -- wallrj -- jakexks -- maelvls -- irbekrm -- sgtcodfish -- inteon +- cm-maintainers - erikgb - thatsmrtalbot \ No newline at end of file diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES new file mode 100644 index 00000000..10d1279a --- /dev/null +++ b/OWNERS_ALIASES @@ -0,0 +1,14 @@ +# THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +# Edit https://github.com/cert-manager/makefile-modules/blob/main/modules/repository-base/base/OWNERS_ALIASES instead. + +aliases: + cm-maintainers: + - munnerz + - joshvanl + - wallrj + - jakexks + - maelvls + - irbekrm + - sgtcodfish + - inteon + - thatsmrtalbot diff --git a/deploy/charts/trust-manager/templates/trust.cert-manager.io_bundles.yaml b/deploy/charts/trust-manager/templates/crd-trust.cert-manager.io_bundles.yaml similarity index 99% rename from deploy/charts/trust-manager/templates/trust.cert-manager.io_bundles.yaml rename to deploy/charts/trust-manager/templates/crd-trust.cert-manager.io_bundles.yaml index cc4aba60..799827d1 100644 --- a/deploy/charts/trust-manager/templates/trust.cert-manager.io_bundles.yaml +++ b/deploy/charts/trust-manager/templates/crd-trust.cert-manager.io_bundles.yaml @@ -42,9 +42,6 @@ spec: name: v1alpha1 schema: openAPIV3Schema: - type: object - required: - - spec properties: apiVersion: description: |- @@ -65,27 +62,18 @@ spec: type: object spec: description: Desired state of the Bundle resource. - type: object - required: - - sources - - target properties: sources: description: Sources is a set of references to data whose data will sync to the target. - type: array items: description: |- BundleSource is the set of sources whose data will be appended and synced to the BundleTarget in all Namespaces. - type: object properties: configMap: description: |- ConfigMap is a reference (by name) to a ConfigMap's `data` key, or to a list of ConfigMap's `data` key using label selector, in the trust Namespace. - type: object - required: - - key properties: key: description: Key is the key of the entry in the object's `data` field to be used. @@ -99,19 +87,13 @@ spec: description: |- Selector is the label selector to use to fetch a list of objects. Must not be set when `Name` is set. - type: object properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - type: array items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. - type: object - required: - - key - - operator properties: key: description: key is the label key that the selector applies to. @@ -127,20 +109,29 @@ spec: the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. - type: array items: type: string + type: array x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array x-kubernetes-list-type: atomic matchLabels: + additionalProperties: + type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object - additionalProperties: - type: string + type: object x-kubernetes-map-type: atomic + required: + - key + type: object inLine: description: InLine is a simple string to append as the source data. type: string @@ -148,9 +139,6 @@ spec: description: |- Secret is a reference (by name) to a Secret's `data` key, or to a list of Secret's `data` key using label selector, in the trust Namespace. - type: object - required: - - key properties: key: description: Key is the key of the entry in the object's `data` field to be used. @@ -164,19 +152,13 @@ spec: description: |- Selector is the label selector to use to fetch a list of objects. Must not be set when `Name` is set. - type: object properties: matchExpressions: description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - type: array items: description: |- A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. - type: object - required: - - key - - operator properties: key: description: key is the label key that the selector applies to. @@ -192,20 +174,29 @@ spec: the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. - type: array items: type: string + type: array x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array x-kubernetes-list-type: atomic matchLabels: + additionalProperties: + type: string description: |- matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object - additionalProperties: - type: string + type: object x-kubernetes-map-type: atomic + required: + - key + type: object useDefaultCAs: description: |- UseDefaultCAs, when true, requests the default CA bundle to be used as a source. @@ -217,114 +208,112 @@ spec: The version of the default CA package which is used for a Bundle is stored in the defaultCAPackageVersion field of the Bundle's status field. type: boolean + type: object + type: array target: description: Target is the target location in all namespaces to sync source data to. - type: object properties: additionalFormats: description: AdditionalFormats specifies any additional formats to write to the target - type: object properties: jks: description: |- JKS requests a JKS-formatted binary trust bundle to be written to the target. The bundle has "changeit" as the default password. For more information refer to this link https://cert-manager.io/docs/faq/#keystore-passwords - type: object - required: - - key properties: key: description: Key is the key of the entry in the object's `data` field to be used. type: string password: - description: Password for JKS trust store - type: string default: changeit + description: Password for JKS trust store maxLength: 128 minLength: 1 + type: string + required: + - key + type: object pkcs12: description: |- PKCS12 requests a PKCS12-formatted binary trust bundle to be written to the target. The bundle is by default created without a password. - type: object - required: - - key properties: key: description: Key is the key of the entry in the object's `data` field to be used. type: string password: - description: Password for PKCS12 trust store - type: string default: "" + description: Password for PKCS12 trust store maxLength: 128 + type: string + required: + - key + type: object + type: object configMap: description: |- ConfigMap is the target ConfigMap in Namespaces that all Bundle source data will be synced to. - type: object - required: - - key properties: key: description: Key is the key of the entry in the object's `data` field to be used. type: string + required: + - key + type: object namespaceSelector: description: |- NamespaceSelector will, if set, only sync the target resource in Namespaces which match the selector. - type: object properties: matchLabels: + additionalProperties: + type: string description: |- MatchLabels matches on the set of labels that must be present on a Namespace for the Bundle target to be synced there. type: object - additionalProperties: - type: string + type: object secret: description: |- Secret is the target Secret that all Bundle source data will be synced to. Using Secrets as targets is only supported if enabled at trust-manager startup. By default, trust-manager has no permissions for writing to secrets and can only read secrets in the trust namespace. - type: object - required: - - key properties: key: description: Key is the key of the entry in the object's `data` field to be used. type: string + required: + - key + type: object + type: object + required: + - sources + - target + type: object status: description: Status of the Bundle. This is set and managed automatically. - type: object properties: conditions: description: |- List of status conditions to indicate the status of the Bundle. Known condition types are `Bundle`. - type: array items: description: BundleCondition contains condition information for a Bundle. - type: object - required: - - lastTransitionTime - - reason - - status - - type properties: lastTransitionTime: description: |- LastTransitionTime is the timestamp corresponding to the last status change of this condition. - type: string format: date-time + type: string message: description: |- Message is a human-readable description of the details of the last transition, complementing reason. - type: string maxLength: 32768 + type: string observedGeneration: description: |- If set, this represents the .metadata.generation that the condition was @@ -332,31 +321,38 @@ spec: For instance, if .metadata.generation is currently 12, but the .status.condition[x].observedGeneration is 9, the condition is out of date with respect to the current state of the Bundle. - type: integer format: int64 minimum: 0 + type: integer reason: description: |- Reason is a brief machine-readable explanation for the condition's last transition. The value should be a CamelCase string. This field may not be empty. - type: string maxLength: 1024 minLength: 1 pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string status: description: Status of the condition, one of True, False, Unknown. - type: string enum: - "True" - "False" - Unknown + type: string type: description: Type of the condition, known values are (`Synced`). - type: string maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - reason + - status + - type + type: object + type: array x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map @@ -367,8 +363,12 @@ spec: source. This should only be set if useDefaultCAs was set to "true" on a source, and will be the same for the same version of a bundle with identical certificates. type: string + type: object + required: + - spec + type: object served: true storage: true subresources: status: {} -{{- end }} +{{- end }} \ No newline at end of file diff --git a/deploy/charts/trust-manager/templates/deployment.yaml b/deploy/charts/trust-manager/templates/deployment.yaml index c3da7be0..209bd6d5 100644 --- a/deploy/charts/trust-manager/templates/deployment.yaml +++ b/deploy/charts/trust-manager/templates/deployment.yaml @@ -66,7 +66,6 @@ spec: path: {{ .Values.app.readinessProbe.path }} initialDelaySeconds: 3 periodSeconds: 7 - command: ["trust-manager"] args: - "--log-level={{.Values.app.logLevel}}" - "--metrics-port={{.Values.app.metrics.port}}" diff --git a/deploy/charts/trust-manager/values.linter.exceptions b/deploy/charts/trust-manager/values.linter.exceptions new file mode 100644 index 00000000..e69de29b diff --git a/deploy/charts/trust-manager/values.schema.json b/deploy/charts/trust-manager/values.schema.json index c975df8b..fb6ffc83 100644 --- a/deploy/charts/trust-manager/values.schema.json +++ b/deploy/charts/trust-manager/values.schema.json @@ -1,9 +1,7 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", - "$ref": "#/$defs/helm-values", "$defs": { "helm-values": { - "type": "object", + "additionalProperties": false, "properties": { "affinity": { "$ref": "#/$defs/helm-values.affinity" @@ -66,15 +64,15 @@ "$ref": "#/$defs/helm-values.topologySpreadConstraints" } }, - "additionalProperties": false + "type": "object" }, "helm-values.affinity": { + "default": {}, "description": "Kubernetes Affinity. For more information, see [Affinity v1 core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#affinity-v1-core).\nFor example:\naffinity:\n nodeAffinity:\n requiredDuringSchedulingIgnoredDuringExecution:\n nodeSelectorTerms:\n - matchExpressions:\n - key: foo.bar.com/role\n operator: In\n values:\n - master", - "type": "object", - "default": {} + "type": "object" }, "helm-values.app": { - "type": "object", + "additionalProperties": false, "properties": { "logLevel": { "$ref": "#/$defs/helm-values.app.logLevel" @@ -101,15 +99,15 @@ "$ref": "#/$defs/helm-values.app.webhook" } }, - "additionalProperties": false + "type": "object" }, "helm-values.app.logLevel": { + "default": 1, "description": "The verbosity of trust-manager logging. This takes a value from 1-5, with the higher value being more verbose.", - "type": "number", - "default": 1 + "type": "number" }, "helm-values.app.metrics": { - "type": "object", + "additionalProperties": false, "properties": { "port": { "$ref": "#/$defs/helm-values.app.metrics.port" @@ -118,15 +116,15 @@ "$ref": "#/$defs/helm-values.app.metrics.service" } }, - "additionalProperties": false + "type": "object" }, "helm-values.app.metrics.port": { + "default": 9402, "description": "The port for exposing Prometheus metrics on 0.0.0.0 on path '/metrics'.", - "type": "number", - "default": 9402 + "type": "number" }, "helm-values.app.metrics.service": { - "type": "object", + "additionalProperties": false, "properties": { "enabled": { "$ref": "#/$defs/helm-values.app.metrics.service.enabled" @@ -138,15 +136,15 @@ "$ref": "#/$defs/helm-values.app.metrics.service.type" } }, - "additionalProperties": false + "type": "object" }, "helm-values.app.metrics.service.enabled": { + "default": true, "description": "Create a Service resource to expose the metrics endpoint.", - "type": "boolean", - "default": true + "type": "boolean" }, "helm-values.app.metrics.service.servicemonitor": { - "type": "object", + "additionalProperties": false, "properties": { "enabled": { "$ref": "#/$defs/helm-values.app.metrics.service.servicemonitor.enabled" @@ -164,50 +162,50 @@ "$ref": "#/$defs/helm-values.app.metrics.service.servicemonitor.scrapeTimeout" } }, - "additionalProperties": false + "type": "object" }, "helm-values.app.metrics.service.servicemonitor.enabled": { + "default": false, "description": "Create a Prometheus ServiceMonitor for trust-manager.", - "type": "boolean", - "default": false + "type": "boolean" }, "helm-values.app.metrics.service.servicemonitor.interval": { + "default": "10s", "description": "The interval to scrape the metrics.", - "type": "string", - "default": "10s" + "type": "string" }, "helm-values.app.metrics.service.servicemonitor.labels": { + "default": {}, "description": "Additional labels to add to the ServiceMonitor.", - "type": "object", - "default": {} + "type": "object" }, "helm-values.app.metrics.service.servicemonitor.prometheusInstance": { + "default": "default", "description": "Sets the value of the \"prometheus\" label on the ServiceMonitor. This is used so that separate Prometheus instances can select different ServiceMonitors using labels.", - "type": "string", - "default": "default" + "type": "string" }, "helm-values.app.metrics.service.servicemonitor.scrapeTimeout": { + "default": "5s", "description": "The timeout for a metrics scrape.", - "type": "string", - "default": "5s" + "type": "string" }, "helm-values.app.metrics.service.type": { + "default": "ClusterIP", "description": "The Service type to expose metrics.", - "type": "string", - "default": "ClusterIP" + "type": "string" }, "helm-values.app.podAnnotations": { + "default": {}, "description": "Pod annotations to add to trust-manager pods.", - "type": "object", - "default": {} + "type": "object" }, "helm-values.app.podLabels": { + "default": {}, "description": "Pod labels to add to trust-manager pods.", - "type": "object", - "default": {} + "type": "object" }, "helm-values.app.readinessProbe": { - "type": "object", + "additionalProperties": false, "properties": { "path": { "$ref": "#/$defs/helm-values.app.readinessProbe.path" @@ -216,48 +214,48 @@ "$ref": "#/$defs/helm-values.app.readinessProbe.port" } }, - "additionalProperties": false + "type": "object" }, "helm-values.app.readinessProbe.path": { + "default": "/readyz", "description": "The path on which to expose the trust-manager HTTP readiness probe using the default network interface.", - "type": "string", - "default": "/readyz" + "type": "string" }, "helm-values.app.readinessProbe.port": { + "default": 6060, "description": "The container port on which to expose the trust-manager HTTP readiness probe using the default network interface.", - "type": "number", - "default": 6060 + "type": "number" }, "helm-values.app.securityContext": { - "type": "object", + "additionalProperties": false, "properties": { "seccompProfileEnabled": { "$ref": "#/$defs/helm-values.app.securityContext.seccompProfileEnabled" } }, - "additionalProperties": false + "type": "object" }, "helm-values.app.securityContext.seccompProfileEnabled": { + "default": true, "description": "If false, disables the default seccomp profile, which might be required to run on certain platforms.", - "type": "boolean", - "default": true + "type": "boolean" }, "helm-values.app.trust": { - "type": "object", + "additionalProperties": false, "properties": { "namespace": { "$ref": "#/$defs/helm-values.app.trust.namespace" } }, - "additionalProperties": false + "type": "object" }, "helm-values.app.trust.namespace": { + "default": "cert-manager", "description": "The namespace used as the trust source. Note that the namespace _must_ exist before installing trust-manager.", - "type": "string", - "default": "cert-manager" + "type": "string" }, "helm-values.app.webhook": { - "type": "object", + "additionalProperties": false, "properties": { "host": { "$ref": "#/$defs/helm-values.app.webhook.host" @@ -278,25 +276,25 @@ "$ref": "#/$defs/helm-values.app.webhook.tls" } }, - "additionalProperties": false + "type": "object" }, "helm-values.app.webhook.host": { + "default": "0.0.0.0", "description": "Host that the webhook listens on.", - "type": "string", - "default": "0.0.0.0" + "type": "string" }, "helm-values.app.webhook.hostNetwork": { + "default": false, "description": "This value specifies if the app should be started in hostNetwork mode. It is required for use in some managed Kubernetes clusters (such as AWS EKS) with custom CNI.", - "type": "boolean", - "default": false + "type": "boolean" }, "helm-values.app.webhook.port": { + "default": 6443, "description": "Port that the webhook listens on.", - "type": "number", - "default": 6443 + "type": "number" }, "helm-values.app.webhook.service": { - "type": "object", + "additionalProperties": false, "properties": { "nodePort": { "$ref": "#/$defs/helm-values.app.webhook.service.nodePort" @@ -305,33 +303,33 @@ "$ref": "#/$defs/helm-values.app.webhook.service.type" } }, - "additionalProperties": false + "type": "object" }, "helm-values.app.webhook.service.nodePort": { "description": "The nodePort set on the Service used by the webhook.", "type": "number" }, "helm-values.app.webhook.service.type": { + "default": "ClusterIP", "description": "The type of Kubernetes Service used by the Webhook.", - "type": "string", - "default": "ClusterIP" + "type": "string" }, "helm-values.app.webhook.timeoutSeconds": { + "default": 5, "description": "Timeout of webhook HTTP request.", - "type": "number", - "default": 5 + "type": "number" }, "helm-values.app.webhook.tls": { - "type": "object", + "additionalProperties": false, "properties": { "approverPolicy": { "$ref": "#/$defs/helm-values.app.webhook.tls.approverPolicy" } }, - "additionalProperties": false + "type": "object" }, "helm-values.app.webhook.tls.approverPolicy": { - "type": "object", + "additionalProperties": false, "properties": { "certManagerNamespace": { "$ref": "#/$defs/helm-values.app.webhook.tls.approverPolicy.certManagerNamespace" @@ -343,30 +341,30 @@ "$ref": "#/$defs/helm-values.app.webhook.tls.approverPolicy.enabled" } }, - "additionalProperties": false + "type": "object" }, "helm-values.app.webhook.tls.approverPolicy.certManagerNamespace": { + "default": "cert-manager", "description": "The namespace in which cert-manager was installed. Only used if `app.webhook.tls.approverPolicy.enabled` is true.", - "type": "string", - "default": "cert-manager" + "type": "string" }, "helm-values.app.webhook.tls.approverPolicy.certManagerServiceAccount": { + "default": "cert-manager", "description": "The name of cert-manager's Service Account. Only used if `app.webhook.tls.approverPolicy.enabled` is true.", - "type": "string", - "default": "cert-manager" + "type": "string" }, "helm-values.app.webhook.tls.approverPolicy.enabled": { + "default": false, "description": "Whether to create an approver-policy CertificateRequestPolicy allowing auto-approval of the trust-manager webhook certificate. If you have approver-policy installed, you almost certainly want to enable this.", - "type": "boolean", - "default": false + "type": "boolean" }, "helm-values.commonLabels": { + "default": {}, "description": "Labels to apply to all resources", - "type": "object", - "default": {} + "type": "object" }, "helm-values.crds": { - "type": "object", + "additionalProperties": false, "properties": { "enabled": { "$ref": "#/$defs/helm-values.crds.enabled" @@ -375,20 +373,20 @@ "$ref": "#/$defs/helm-values.crds.keep" } }, - "additionalProperties": false + "type": "object" }, "helm-values.crds.enabled": { + "default": true, "description": "This option decides if the CRDs should be installed as part of the Helm installation.", - "type": "boolean", - "default": true + "type": "boolean" }, "helm-values.crds.keep": { + "default": true, "description": "This option makes it so that the \"helm.sh/resource-policy\": keep annotation is added to the CRD. This will prevent Helm from uninstalling the CRD when the Helm release is uninstalled. WARNING: when the CRDs are removed, all cert-manager custom resources\n(Certificates, Issuers, ...) will be removed too by the garbage collector.", - "type": "boolean", - "default": true + "type": "boolean" }, "helm-values.defaultPackage": { - "type": "object", + "additionalProperties": false, "properties": { "enabled": { "$ref": "#/$defs/helm-values.defaultPackage.enabled" @@ -397,20 +395,20 @@ "$ref": "#/$defs/helm-values.defaultPackage.resources" } }, - "additionalProperties": false + "type": "object" }, "helm-values.defaultPackage.enabled": { + "default": true, "description": "Whether to load the default trust package during pod initialization, and include it in main container args. This container enables the 'useDefaultCAs' source on Bundles.", - "type": "boolean", - "default": true + "type": "boolean" }, "helm-values.defaultPackage.resources": { + "default": {}, "description": "Kubernetes pod resource limits for default package init container.\n\nFor example:\nresources:\n limits:\n cpu: 100m\n memory: 128Mi\n requests:\n cpu: 100m\n memory: 128Mi", - "type": "object", - "default": {} + "type": "object" }, "helm-values.defaultPackageImage": { - "type": "object", + "additionalProperties": false, "properties": { "digest": { "$ref": "#/$defs/helm-values.defaultPackageImage.digest" @@ -428,50 +426,50 @@ "$ref": "#/$defs/helm-values.defaultPackageImage.tag" } }, - "additionalProperties": false + "type": "object" }, "helm-values.defaultPackageImage.digest": { "description": "Target image digest. Override any tag, if set.\nFor example:\ndigest: sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20", "type": "string" }, "helm-values.defaultPackageImage.pullPolicy": { + "default": "IfNotPresent", "description": "imagePullPolicy for the default package image.", - "type": "string", - "default": "IfNotPresent" + "type": "string" }, "helm-values.defaultPackageImage.registry": { "description": "Target image registry. This value is prepended to the target image repository, if set.\nFor example:\nregistry: quay.io\nrepository: jetstack/cert-manager-package-debian", "type": "string" }, "helm-values.defaultPackageImage.repository": { + "default": "quay.io/jetstack/cert-manager-package-debian", "description": "The repository for the default package image. This image enables the 'useDefaultCAs' source on Bundles.", - "type": "string", - "default": "quay.io/jetstack/cert-manager-package-debian" + "type": "string" }, "helm-values.defaultPackageImage.tag": { + "default": "20210119.0", "description": "Override the image tag of the default package image. If no value is set, the chart's appVersion is used.", - "type": "string", - "default": "20210119.0" + "type": "string" }, "helm-values.filterExpiredCertificates": { - "type": "object", + "additionalProperties": false, "properties": { "enabled": { "$ref": "#/$defs/helm-values.filterExpiredCertificates.enabled" } }, - "additionalProperties": false + "type": "object" }, "helm-values.filterExpiredCertificates.enabled": { + "default": false, "description": "Whether to filter expired certificates from the trust bundle.", - "type": "boolean", - "default": false + "type": "boolean" }, "helm-values.global": { "description": "Global values shared across all (sub)charts" }, "helm-values.image": { - "type": "object", + "additionalProperties": false, "properties": { "digest": { "$ref": "#/$defs/helm-values.image.digest" @@ -489,54 +487,54 @@ "$ref": "#/$defs/helm-values.image.tag" } }, - "additionalProperties": false + "type": "object" }, "helm-values.image.digest": { "description": "Target image digest. Override any tag, if set.\nFor example:\ndigest: sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20", "type": "string" }, "helm-values.image.pullPolicy": { + "default": "IfNotPresent", "description": "Kubernetes imagePullPolicy on Deployment.", - "type": "string", - "default": "IfNotPresent" + "type": "string" }, "helm-values.image.registry": { "description": "Target image registry. This value is prepended to the target image repository, if set.\nFor example:\nregistry: quay.io\nrepository: jetstack/trust-manager", "type": "string" }, "helm-values.image.repository": { + "default": "quay.io/jetstack/trust-manager", "description": "Target image repository.", - "type": "string", - "default": "quay.io/jetstack/trust-manager" + "type": "string" }, "helm-values.image.tag": { "description": "Override the image tag to deploy by setting this variable. If no value is set, the chart's appVersion is used.", "type": "string" }, "helm-values.imagePullSecrets": { - "description": "For Private docker registries, authentication is needed. Registry secrets are applied to the service account.", - "type": "array", "default": [], - "items": {} + "description": "For Private docker registries, authentication is needed. Registry secrets are applied to the service account.", + "items": {}, + "type": "array" }, "helm-values.nameOverride": { - "type": "string", - "default": "" + "default": "", + "type": "string" }, "helm-values.namespace": { + "default": "", "description": "The namespace to install trust-manager into.\nIf not set, the namespace of the release is used.\nThis is helpful when installing trust-manager as a chart dependency (sub chart).", - "type": "string", - "default": "" + "type": "string" }, "helm-values.nodeSelector": { - "description": "Configure the nodeSelector; defaults to any Linux node (trust-manager doesn't support Windows nodes)", - "type": "object", "default": { "kubernetes.io/os": "linux" - } + }, + "description": "Configure the nodeSelector; defaults to any Linux node (trust-manager doesn't support Windows nodes)", + "type": "object" }, "helm-values.podDisruptionBudget": { - "type": "object", + "additionalProperties": false, "properties": { "enabled": { "$ref": "#/$defs/helm-values.podDisruptionBudget.enabled" @@ -548,12 +546,12 @@ "$ref": "#/$defs/helm-values.podDisruptionBudget.minAvailable" } }, - "additionalProperties": false + "type": "object" }, "helm-values.podDisruptionBudget.enabled": { + "default": false, "description": "Enable or disable the PodDisruptionBudget resource.\n\nThis prevents downtime during voluntary disruptions such as during a Node upgrade. For example, the PodDisruptionBudget will block `kubectl drain` if it is used on the Node where the only remaining trust-manager\nPod is currently running.", - "type": "boolean", - "default": false + "type": "boolean" }, "helm-values.podDisruptionBudget.maxUnavailable": { "description": "This configures the maximum unavailable pods for disruptions. It can either be set to an integer (e.g. 1) or a percentage value (e.g. 25%). it cannot be used if `minAvailable` is set." @@ -562,21 +560,21 @@ "description": "This configures the minimum available pods for disruptions. It can either be set to an integer (e.g. 1) or a percentage value (e.g. 25%).\nIt cannot be used if `maxUnavailable` is set." }, "helm-values.priorityClassName": { + "default": "", "description": "Configure the priority class of the pod. For more information, see [PriorityClass](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#priorityclass).", - "type": "string", - "default": "" + "type": "string" }, "helm-values.replicaCount": { - "description": "The number of replicas of trust-manager to run.\n\nFor example:\n Use integer to set a fixed number of replicas\nreplicaCount: 2\nUse null, if you want to omit the replicas field and use the Kubernetes default value.\nreplicaCount: null\nUse a string if you want to insert a variable for post-processing of the rendered template.\nreplicaCount: ${REPLICAS_OVERRIDE:=3}", - "default": 1 + "default": 1, + "description": "The number of replicas of trust-manager to run.\n\nFor example:\n Use integer to set a fixed number of replicas\nreplicaCount: 2\nUse null, if you want to omit the replicas field and use the Kubernetes default value.\nreplicaCount: null\nUse a string if you want to insert a variable for post-processing of the rendered template.\nreplicaCount: ${REPLICAS_OVERRIDE:=3}" }, "helm-values.resources": { + "default": {}, "description": "Kubernetes pod resource limits for trust.\n\nFor example:\nresources:\n limits:\n cpu: 100m\n memory: 128Mi\n requests:\n cpu: 100m\n memory: 128Mi", - "type": "object", - "default": {} + "type": "object" }, "helm-values.secretTargets": { - "type": "object", + "additionalProperties": false, "properties": { "authorizedSecrets": { "$ref": "#/$defs/helm-values.secretTargets.authorizedSecrets" @@ -588,35 +586,37 @@ "$ref": "#/$defs/helm-values.secretTargets.enabled" } }, - "additionalProperties": false + "type": "object" }, "helm-values.secretTargets.authorizedSecrets": { - "description": "A list of secret names which trust-manager will be permitted to read and write across all namespaces. These are the only allowable Secrets that can be used as targets. If the list is empty (and authorizedSecretsAll is false), trust-manager can't write to secrets and can only read secrets in the trust namespace for use as sources.", - "type": "array", "default": [], - "items": {} + "description": "A list of secret names which trust-manager will be permitted to read and write across all namespaces. These are the only allowable Secrets that can be used as targets. If the list is empty (and authorizedSecretsAll is false), trust-manager can't write to secrets and can only read secrets in the trust namespace for use as sources.", + "items": {}, + "type": "array" }, "helm-values.secretTargets.authorizedSecretsAll": { + "default": false, "description": "If set to true, grant read/write permission to all secrets across the cluster. Use with caution!\nIf set, ignores the authorizedSecrets list.", - "type": "boolean", - "default": false + "type": "boolean" }, "helm-values.secretTargets.enabled": { + "default": false, "description": "If set to true, enable writing trust bundles to Kubernetes Secrets as a target. trust-manager can only write to secrets which are explicitly allowed via either authorizedSecrets or authorizedSecretsAll. Note that enabling secret targets will grant trust-manager read access to all secrets in the cluster.", - "type": "boolean", - "default": false + "type": "boolean" }, "helm-values.tolerations": { - "description": "List of Kubernetes Tolerations, if required. For more information, see [Toleration v1 core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#toleration-v1-core).\nFor example:\ntolerations:\n- key: foo.bar.com/role\n operator: Equal\n value: master\n effect: NoSchedule", - "type": "array", "default": [], - "items": {} + "description": "List of Kubernetes Tolerations, if required. For more information, see [Toleration v1 core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#toleration-v1-core).\nFor example:\ntolerations:\n- key: foo.bar.com/role\n operator: Equal\n value: master\n effect: NoSchedule", + "items": {}, + "type": "array" }, "helm-values.topologySpreadConstraints": { - "description": "List of Kubernetes TopologySpreadConstraints. For more information, see [TopologySpreadConstraint v1 core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#topologyspreadconstraint-v1-core).\nFor example:\ntopologySpreadConstraints:\n- maxSkew: 2\n topologyKey: topology.kubernetes.io/zone\n whenUnsatisfiable: ScheduleAnyway\n labelSelector:\n matchLabels:\n app.kubernetes.io/instance: cert-manager\n app.kubernetes.io/component: controller", - "type": "array", "default": [], - "items": {} + "description": "List of Kubernetes TopologySpreadConstraints. For more information, see [TopologySpreadConstraint v1 core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#topologyspreadconstraint-v1-core).\nFor example:\ntopologySpreadConstraints:\n- maxSkew: 2\n topologyKey: topology.kubernetes.io/zone\n whenUnsatisfiable: ScheduleAnyway\n labelSelector:\n matchLabels:\n app.kubernetes.io/instance: cert-manager\n app.kubernetes.io/component: controller", + "items": {}, + "type": "array" } - } + }, + "$ref": "#/$defs/helm-values", + "$schema": "http://json-schema.org/draft-07/schema#" } diff --git a/deploy/crds/trust.cert-manager.io_bundles.yaml b/deploy/crds/trust.cert-manager.io_bundles.yaml deleted file mode 100644 index 20d2f850..00000000 --- a/deploy/crds/trust.cert-manager.io_bundles.yaml +++ /dev/null @@ -1,368 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.14.0 - name: bundles.trust.cert-manager.io -spec: - group: trust.cert-manager.io - names: - kind: Bundle - listKind: BundleList - plural: bundles - singular: bundle - scope: Cluster - versions: - - additionalPrinterColumns: - - description: Bundle ConfigMap Target Key - jsonPath: .spec.target.configMap.key - name: ConfigMap Target - type: string - - description: Bundle Secret Target Key - jsonPath: .spec.target.secret.key - name: Secret Target - type: string - - description: Bundle has been synced - jsonPath: .status.conditions[?(@.type == "Synced")].status - name: Synced - type: string - - description: Reason Bundle has Synced status - jsonPath: .status.conditions[?(@.type == "Synced")].reason - name: Reason - type: string - - description: Timestamp Bundle was created - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - type: object - required: - - spec - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: Desired state of the Bundle resource. - type: object - required: - - sources - - target - properties: - sources: - description: Sources is a set of references to data whose data will sync to the target. - type: array - items: - description: |- - BundleSource is the set of sources whose data will be appended and synced to - the BundleTarget in all Namespaces. - type: object - properties: - configMap: - description: |- - ConfigMap is a reference (by name) to a ConfigMap's `data` key, or to a - list of ConfigMap's `data` key using label selector, in the trust Namespace. - type: object - required: - - key - properties: - key: - description: Key is the key of the entry in the object's `data` field to be used. - type: string - name: - description: |- - Name is the name of the source object in the trust Namespace. - This field must be left empty when `selector` is set - type: string - selector: - description: |- - Selector is the label selector to use to fetch a list of objects. Must not be set - when `Name` is set. - type: object - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - type: array - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - type: array - items: - type: string - x-kubernetes-list-type: atomic - x-kubernetes-list-type: atomic - matchLabels: - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - additionalProperties: - type: string - x-kubernetes-map-type: atomic - inLine: - description: InLine is a simple string to append as the source data. - type: string - secret: - description: |- - Secret is a reference (by name) to a Secret's `data` key, or to a - list of Secret's `data` key using label selector, in the trust Namespace. - type: object - required: - - key - properties: - key: - description: Key is the key of the entry in the object's `data` field to be used. - type: string - name: - description: |- - Name is the name of the source object in the trust Namespace. - This field must be left empty when `selector` is set - type: string - selector: - description: |- - Selector is the label selector to use to fetch a list of objects. Must not be set - when `Name` is set. - type: object - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - type: array - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - type: object - required: - - key - - operator - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - type: array - items: - type: string - x-kubernetes-list-type: atomic - x-kubernetes-list-type: atomic - matchLabels: - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - additionalProperties: - type: string - x-kubernetes-map-type: atomic - useDefaultCAs: - description: |- - UseDefaultCAs, when true, requests the default CA bundle to be used as a source. - Default CAs are available if trust-manager was installed via Helm - or was otherwise set up to include a package-injecting init container by using the - "--default-package-location" flag when starting the trust-manager controller. - If default CAs were not configured at start-up, any request to use the default - CAs will fail. - The version of the default CA package which is used for a Bundle is stored in the - defaultCAPackageVersion field of the Bundle's status field. - type: boolean - target: - description: Target is the target location in all namespaces to sync source data to. - type: object - properties: - additionalFormats: - description: AdditionalFormats specifies any additional formats to write to the target - type: object - properties: - jks: - description: |- - JKS requests a JKS-formatted binary trust bundle to be written to the target. - The bundle has "changeit" as the default password. - For more information refer to this link https://cert-manager.io/docs/faq/#keystore-passwords - type: object - required: - - key - properties: - key: - description: Key is the key of the entry in the object's `data` field to be used. - type: string - password: - description: Password for JKS trust store - type: string - default: changeit - maxLength: 128 - minLength: 1 - pkcs12: - description: |- - PKCS12 requests a PKCS12-formatted binary trust bundle to be written to the target. - The bundle is by default created without a password. - type: object - required: - - key - properties: - key: - description: Key is the key of the entry in the object's `data` field to be used. - type: string - password: - description: Password for PKCS12 trust store - type: string - default: "" - maxLength: 128 - configMap: - description: |- - ConfigMap is the target ConfigMap in Namespaces that all Bundle source - data will be synced to. - type: object - required: - - key - properties: - key: - description: Key is the key of the entry in the object's `data` field to be used. - type: string - namespaceSelector: - description: |- - NamespaceSelector will, if set, only sync the target resource in - Namespaces which match the selector. - type: object - properties: - matchLabels: - description: |- - MatchLabels matches on the set of labels that must be present on a - Namespace for the Bundle target to be synced there. - type: object - additionalProperties: - type: string - secret: - description: |- - Secret is the target Secret that all Bundle source data will be synced to. - Using Secrets as targets is only supported if enabled at trust-manager startup. - By default, trust-manager has no permissions for writing to secrets and can only read secrets in the trust namespace. - type: object - required: - - key - properties: - key: - description: Key is the key of the entry in the object's `data` field to be used. - type: string - status: - description: Status of the Bundle. This is set and managed automatically. - type: object - properties: - conditions: - description: |- - List of status conditions to indicate the status of the Bundle. - Known condition types are `Bundle`. - type: array - items: - description: BundleCondition contains condition information for a Bundle. - type: object - required: - - lastTransitionTime - - reason - - status - - type - properties: - lastTransitionTime: - description: |- - LastTransitionTime is the timestamp corresponding to the last status - change of this condition. - type: string - format: date-time - message: - description: |- - Message is a human-readable description of the details of the last - transition, complementing reason. - type: string - maxLength: 32768 - observedGeneration: - description: |- - If set, this represents the .metadata.generation that the condition was - set based upon. - For instance, if .metadata.generation is currently 12, but the - .status.condition[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the Bundle. - type: integer - format: int64 - minimum: 0 - reason: - description: |- - Reason is a brief machine-readable explanation for the condition's last - transition. - The value should be a CamelCase string. - This field may not be empty. - type: string - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - status: - description: Status of the condition, one of True, False, Unknown. - type: string - enum: - - "True" - - "False" - - Unknown - type: - description: Type of the condition, known values are (`Synced`). - type: string - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - defaultCAVersion: - description: |- - DefaultCAPackageVersion, if set and non-empty, indicates the version information - which was retrieved when the set of default CAs was requested in the bundle - source. This should only be set if useDefaultCAs was set to "true" on a source, - and will be the same for the same version of a bundle with identical certificates. - type: string - served: true - storage: true - subresources: - status: {} diff --git a/docs/api/api.md b/docs/api/api.md new file mode 100644 index 00000000..a3d999ed --- /dev/null +++ b/docs/api/api.md @@ -0,0 +1,650 @@ + + +# v1alpha1 + +```go +import "github.com/cert-manager/trust-manager/pkg/apis/trust/v1alpha1" +``` + +\+kubebuilder:object:generate=true \+groupName=trust.cert\-manager.io + +## Index + +- [Constants](<#constants>) +- [Variables](<#variables>) +- [func Resource\(resource string\) schema.GroupResource](<#Resource>) +- [type AdditionalFormats](<#AdditionalFormats>) + - [func \(in \*AdditionalFormats\) DeepCopy\(\) \*AdditionalFormats](<#AdditionalFormats.DeepCopy>) + - [func \(in \*AdditionalFormats\) DeepCopyInto\(out \*AdditionalFormats\)](<#AdditionalFormats.DeepCopyInto>) +- [type Bundle](<#Bundle>) + - [func \(in \*Bundle\) DeepCopy\(\) \*Bundle](<#Bundle.DeepCopy>) + - [func \(in \*Bundle\) DeepCopyInto\(out \*Bundle\)](<#Bundle.DeepCopyInto>) + - [func \(in \*Bundle\) DeepCopyObject\(\) runtime.Object](<#Bundle.DeepCopyObject>) +- [type BundleCondition](<#BundleCondition>) + - [func \(in \*BundleCondition\) DeepCopy\(\) \*BundleCondition](<#BundleCondition.DeepCopy>) + - [func \(in \*BundleCondition\) DeepCopyInto\(out \*BundleCondition\)](<#BundleCondition.DeepCopyInto>) +- [type BundleList](<#BundleList>) + - [func \(in \*BundleList\) DeepCopy\(\) \*BundleList](<#BundleList.DeepCopy>) + - [func \(in \*BundleList\) DeepCopyInto\(out \*BundleList\)](<#BundleList.DeepCopyInto>) + - [func \(in \*BundleList\) DeepCopyObject\(\) runtime.Object](<#BundleList.DeepCopyObject>) +- [type BundleSource](<#BundleSource>) + - [func \(in \*BundleSource\) DeepCopy\(\) \*BundleSource](<#BundleSource.DeepCopy>) + - [func \(in \*BundleSource\) DeepCopyInto\(out \*BundleSource\)](<#BundleSource.DeepCopyInto>) +- [type BundleSpec](<#BundleSpec>) + - [func \(in \*BundleSpec\) DeepCopy\(\) \*BundleSpec](<#BundleSpec.DeepCopy>) + - [func \(in \*BundleSpec\) DeepCopyInto\(out \*BundleSpec\)](<#BundleSpec.DeepCopyInto>) +- [type BundleStatus](<#BundleStatus>) + - [func \(in \*BundleStatus\) DeepCopy\(\) \*BundleStatus](<#BundleStatus.DeepCopy>) + - [func \(in \*BundleStatus\) DeepCopyInto\(out \*BundleStatus\)](<#BundleStatus.DeepCopyInto>) +- [type BundleTarget](<#BundleTarget>) + - [func \(in \*BundleTarget\) DeepCopy\(\) \*BundleTarget](<#BundleTarget.DeepCopy>) + - [func \(in \*BundleTarget\) DeepCopyInto\(out \*BundleTarget\)](<#BundleTarget.DeepCopyInto>) +- [type JKS](<#JKS>) + - [func \(in \*JKS\) DeepCopy\(\) \*JKS](<#JKS.DeepCopy>) + - [func \(in \*JKS\) DeepCopyInto\(out \*JKS\)](<#JKS.DeepCopyInto>) +- [type KeySelector](<#KeySelector>) + - [func \(in \*KeySelector\) DeepCopy\(\) \*KeySelector](<#KeySelector.DeepCopy>) + - [func \(in \*KeySelector\) DeepCopyInto\(out \*KeySelector\)](<#KeySelector.DeepCopyInto>) +- [type NamespaceSelector](<#NamespaceSelector>) + - [func \(in \*NamespaceSelector\) DeepCopy\(\) \*NamespaceSelector](<#NamespaceSelector.DeepCopy>) + - [func \(in \*NamespaceSelector\) DeepCopyInto\(out \*NamespaceSelector\)](<#NamespaceSelector.DeepCopyInto>) +- [type PKCS12](<#PKCS12>) + - [func \(in \*PKCS12\) DeepCopy\(\) \*PKCS12](<#PKCS12.DeepCopy>) + - [func \(in \*PKCS12\) DeepCopyInto\(out \*PKCS12\)](<#PKCS12.DeepCopyInto>) +- [type SourceObjectKeySelector](<#SourceObjectKeySelector>) + - [func \(in \*SourceObjectKeySelector\) DeepCopy\(\) \*SourceObjectKeySelector](<#SourceObjectKeySelector.DeepCopy>) + - [func \(in \*SourceObjectKeySelector\) DeepCopyInto\(out \*SourceObjectKeySelector\)](<#SourceObjectKeySelector.DeepCopyInto>) + + +## Constants + + + +```go +const ( + // BundleConditionSynced indicates that the Bundle has successfully synced + // all source bundle data to the Bundle target in all Namespaces. + BundleConditionSynced string = "Synced" +) +``` + +## Variables + + + +```go +var ( + SchemeBuilder runtime.SchemeBuilder + + AddToScheme = localSchemeBuilder.AddToScheme + + GlobalScheme *runtime.Scheme +) +``` + + + +```go +var BundleHashAnnotationKey = "trust.cert-manager.io/hash" +``` + + + +```go +var BundleKind = "Bundle" +``` + + + +```go +var BundleLabelKey = "trust.cert-manager.io/bundle" +``` + +SchemeGroupVersion is group version used to register these objects + +```go +var SchemeGroupVersion = schema.GroupVersion{Group: trust.GroupName, Version: "v1alpha1"} +``` + + +## func [Resource]() + +```go +func Resource(resource string) schema.GroupResource +``` + +Resource takes an unqualified resource and returns a Group qualified GroupResource + + +## type [AdditionalFormats]() + +AdditionalFormats specifies any additional formats to write to the target + +```go +type AdditionalFormats struct { + // JKS requests a JKS-formatted binary trust bundle to be written to the target. + // The bundle has "changeit" as the default password. + // For more information refer to this link https://cert-manager.io/docs/faq/#keystore-passwords + JKS *JKS `json:"jks,omitempty"` + // PKCS12 requests a PKCS12-formatted binary trust bundle to be written to the target. + // The bundle is by default created without a password. + PKCS12 *PKCS12 `json:"pkcs12,omitempty"` +} +``` + + +### func \(\*AdditionalFormats\) [DeepCopy]() + +```go +func (in *AdditionalFormats) DeepCopy() *AdditionalFormats +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdditionalFormats. + + +### func \(\*AdditionalFormats\) [DeepCopyInto]() + +```go +func (in *AdditionalFormats) DeepCopyInto(out *AdditionalFormats) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + + +## type [Bundle]() + + + +```go +type Bundle struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Desired state of the Bundle resource. + Spec BundleSpec `json:"spec"` + + // Status of the Bundle. This is set and managed automatically. + // +optional + Status BundleStatus `json:"status"` +} +``` + + +### func \(\*Bundle\) [DeepCopy]() + +```go +func (in *Bundle) DeepCopy() *Bundle +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Bundle. + + +### func \(\*Bundle\) [DeepCopyInto]() + +```go +func (in *Bundle) DeepCopyInto(out *Bundle) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + + +### func \(\*Bundle\) [DeepCopyObject]() + +```go +func (in *Bundle) DeepCopyObject() runtime.Object +``` + +DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. + + +## type [BundleCondition]() + +BundleCondition contains condition information for a Bundle. + +```go +type BundleCondition struct { + // Type of the condition, known values are (`Synced`). + // +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$` + // +kubebuilder:validation:MaxLength=316 + Type string `json:"type"` + + // Status of the condition, one of True, False, Unknown. + // +kubebuilder:validation:Enum=True;False;Unknown + Status metav1.ConditionStatus `json:"status"` + + // LastTransitionTime is the timestamp corresponding to the last status + // change of this condition. + // +kubebuilder:validation:Type=string + // +kubebuilder:validation:Format=date-time + LastTransitionTime metav1.Time `json:"lastTransitionTime"` + + // Reason is a brief machine-readable explanation for the condition's last + // transition. + // The value should be a CamelCase string. + // This field may not be empty. + // +kubebuilder:validation:MaxLength=1024 + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:Pattern=`^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$` + Reason string `json:"reason"` + + // Message is a human-readable description of the details of the last + // transition, complementing reason. + // +optional + // +kubebuilder:validation:MaxLength=32768 + Message string `json:"message,omitempty"` + + // If set, this represents the .metadata.generation that the condition was + // set based upon. + // For instance, if .metadata.generation is currently 12, but the + // .status.condition[x].observedGeneration is 9, the condition is out of date + // with respect to the current state of the Bundle. + // +optional + // +kubebuilder:validation:Minimum=0 + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} +``` + + +### func \(\*BundleCondition\) [DeepCopy]() + +```go +func (in *BundleCondition) DeepCopy() *BundleCondition +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleCondition. + + +### func \(\*BundleCondition\) [DeepCopyInto]() + +```go +func (in *BundleCondition) DeepCopyInto(out *BundleCondition) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + + +## type [BundleList]() + +\+kubebuilder:object:root=true + +```go +type BundleList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []Bundle `json:"items"` +} +``` + + +### func \(\*BundleList\) [DeepCopy]() + +```go +func (in *BundleList) DeepCopy() *BundleList +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleList. + + +### func \(\*BundleList\) [DeepCopyInto]() + +```go +func (in *BundleList) DeepCopyInto(out *BundleList) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + + +### func \(\*BundleList\) [DeepCopyObject]() + +```go +func (in *BundleList) DeepCopyObject() runtime.Object +``` + +DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. + + +## type [BundleSource]() + +BundleSource is the set of sources whose data will be appended and synced to the BundleTarget in all Namespaces. + +```go +type BundleSource struct { + // ConfigMap is a reference (by name) to a ConfigMap's `data` key, or to a + // list of ConfigMap's `data` key using label selector, in the trust Namespace. + // +optional + ConfigMap *SourceObjectKeySelector `json:"configMap,omitempty"` + + // Secret is a reference (by name) to a Secret's `data` key, or to a + // list of Secret's `data` key using label selector, in the trust Namespace. + // +optional + Secret *SourceObjectKeySelector `json:"secret,omitempty"` + + // InLine is a simple string to append as the source data. + // +optional + InLine *string `json:"inLine,omitempty"` + + // UseDefaultCAs, when true, requests the default CA bundle to be used as a source. + // Default CAs are available if trust-manager was installed via Helm + // or was otherwise set up to include a package-injecting init container by using the + // "--default-package-location" flag when starting the trust-manager controller. + // If default CAs were not configured at start-up, any request to use the default + // CAs will fail. + // The version of the default CA package which is used for a Bundle is stored in the + // defaultCAPackageVersion field of the Bundle's status field. + // +optional + UseDefaultCAs *bool `json:"useDefaultCAs,omitempty"` +} +``` + + +### func \(\*BundleSource\) [DeepCopy]() + +```go +func (in *BundleSource) DeepCopy() *BundleSource +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleSource. + + +### func \(\*BundleSource\) [DeepCopyInto]() + +```go +func (in *BundleSource) DeepCopyInto(out *BundleSource) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + + +## type [BundleSpec]() + +BundleSpec defines the desired state of a Bundle. + +```go +type BundleSpec struct { + // Sources is a set of references to data whose data will sync to the target. + Sources []BundleSource `json:"sources"` + + // Target is the target location in all namespaces to sync source data to. + Target BundleTarget `json:"target"` +} +``` + + +### func \(\*BundleSpec\) [DeepCopy]() + +```go +func (in *BundleSpec) DeepCopy() *BundleSpec +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleSpec. + + +### func \(\*BundleSpec\) [DeepCopyInto]() + +```go +func (in *BundleSpec) DeepCopyInto(out *BundleSpec) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + + +## type [BundleStatus]() + +BundleStatus defines the observed state of the Bundle. + +```go +type BundleStatus struct { + // List of status conditions to indicate the status of the Bundle. + // Known condition types are `Bundle`. + // +listType=map + // +listMapKey=type + // +optional + Conditions []BundleCondition `json:"conditions,omitempty"` + + // DefaultCAPackageVersion, if set and non-empty, indicates the version information + // which was retrieved when the set of default CAs was requested in the bundle + // source. This should only be set if useDefaultCAs was set to "true" on a source, + // and will be the same for the same version of a bundle with identical certificates. + // +optional + DefaultCAPackageVersion *string `json:"defaultCAVersion,omitempty"` +} +``` + + +### func \(\*BundleStatus\) [DeepCopy]() + +```go +func (in *BundleStatus) DeepCopy() *BundleStatus +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleStatus. + + +### func \(\*BundleStatus\) [DeepCopyInto]() + +```go +func (in *BundleStatus) DeepCopyInto(out *BundleStatus) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + + +## type [BundleTarget]() + +BundleTarget is the target resource that the Bundle will sync all source data to. + +```go +type BundleTarget struct { + // ConfigMap is the target ConfigMap in Namespaces that all Bundle source + // data will be synced to. + ConfigMap *KeySelector `json:"configMap,omitempty"` + + // Secret is the target Secret that all Bundle source data will be synced to. + // Using Secrets as targets is only supported if enabled at trust-manager startup. + // By default, trust-manager has no permissions for writing to secrets and can only read secrets in the trust namespace. + Secret *KeySelector `json:"secret,omitempty"` + + // AdditionalFormats specifies any additional formats to write to the target + // +optional + AdditionalFormats *AdditionalFormats `json:"additionalFormats,omitempty"` + + // NamespaceSelector will, if set, only sync the target resource in + // Namespaces which match the selector. + // +optional + NamespaceSelector *NamespaceSelector `json:"namespaceSelector,omitempty"` +} +``` + + +### func \(\*BundleTarget\) [DeepCopy]() + +```go +func (in *BundleTarget) DeepCopy() *BundleTarget +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BundleTarget. + + +### func \(\*BundleTarget\) [DeepCopyInto]() + +```go +func (in *BundleTarget) DeepCopyInto(out *BundleTarget) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + + +## type [JKS]() + + + +```go +type JKS struct { + KeySelector `json:",inline"` + + // Password for JKS trust store + //+optional + //+kubebuilder:validation:MinLength=1 + //+kubebuilder:validation:MaxLength=128 + //+kubebuilder:default=changeit + Password *string `json:"password"` +} +``` + + +### func \(\*JKS\) [DeepCopy]() + +```go +func (in *JKS) DeepCopy() *JKS +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JKS. + + +### func \(\*JKS\) [DeepCopyInto]() + +```go +func (in *JKS) DeepCopyInto(out *JKS) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + + +## type [KeySelector]() + +KeySelector is a reference to a key for some map data object. + +```go +type KeySelector struct { + // Key is the key of the entry in the object's `data` field to be used. + Key string `json:"key"` +} +``` + + +### func \(\*KeySelector\) [DeepCopy]() + +```go +func (in *KeySelector) DeepCopy() *KeySelector +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeySelector. + + +### func \(\*KeySelector\) [DeepCopyInto]() + +```go +func (in *KeySelector) DeepCopyInto(out *KeySelector) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + + +## type [NamespaceSelector]() + +NamespaceSelector defines selectors to match on Namespaces. + +```go +type NamespaceSelector struct { + // MatchLabels matches on the set of labels that must be present on a + // Namespace for the Bundle target to be synced there. + // +optional + MatchLabels map[string]string `json:"matchLabels,omitempty"` +} +``` + + +### func \(\*NamespaceSelector\) [DeepCopy]() + +```go +func (in *NamespaceSelector) DeepCopy() *NamespaceSelector +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceSelector. + + +### func \(\*NamespaceSelector\) [DeepCopyInto]() + +```go +func (in *NamespaceSelector) DeepCopyInto(out *NamespaceSelector) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + + +## type [PKCS12]() + + + +```go +type PKCS12 struct { + KeySelector `json:",inline"` + + // Password for PKCS12 trust store + //+optional + //+kubebuilder:validation:MaxLength=128 + //+kubebuilder:default="" + Password *string `json:"password,omitempty"` +} +``` + + +### func \(\*PKCS12\) [DeepCopy]() + +```go +func (in *PKCS12) DeepCopy() *PKCS12 +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PKCS12. + + +### func \(\*PKCS12\) [DeepCopyInto]() + +```go +func (in *PKCS12) DeepCopyInto(out *PKCS12) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + + +## type [SourceObjectKeySelector]() + +SourceObjectKeySelector is a reference to a source object and its \`data\` key in the trust Namespace. + +```go +type SourceObjectKeySelector struct { + // Name is the name of the source object in the trust Namespace. + // This field must be left empty when `selector` is set + //+optional + Name string `json:"name,omitempty"` + + // Selector is the label selector to use to fetch a list of objects. Must not be set + // when `Name` is set. + //+optional + Selector *metav1.LabelSelector `json:"selector,omitempty"` + + // KeySelector is the key of the entry in the objects' `data` field to be referenced. + KeySelector `json:",inline"` +} +``` + + +### func \(\*SourceObjectKeySelector\) [DeepCopy]() + +```go +func (in *SourceObjectKeySelector) DeepCopy() *SourceObjectKeySelector +``` + +DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SourceObjectKeySelector. + + +### func \(\*SourceObjectKeySelector\) [DeepCopyInto]() + +```go +func (in *SourceObjectKeySelector) DeepCopyInto(out *SourceObjectKeySelector) +``` + +DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non\-nil. + +Generated by [gomarkdoc]() diff --git a/gcb/ci-update-debian-trust-package.yaml b/gcb/ci-update-debian-trust-package.yaml deleted file mode 100644 index bae48de7..00000000 --- a/gcb/ci-update-debian-trust-package.yaml +++ /dev/null @@ -1,57 +0,0 @@ -# This job runs the ci-update-debian-trust-package target to keep the debian bundle up-to-date -# It's designed to be a cloudbuild trigger invoked on a regular schedule - -timeout: 14400s - -secrets: -- kmsKeyName: projects/cert-manager-release/locations/europe-west1/keyRings/cert-manager-release/cryptoKeys/cert-manager-release-secret-key - secretEnv: - # this key is generated using: - # gcloud kms encrypt \ - # --key projects/cert-manager-release/locations/europe-west1/keyRings/cert-manager-release/cryptoKeys/cert-manager-release-secret-key \ - # --plaintext-file=/tmp/credentials.json \ - # --ciphertext-file=- \ - # | base64 -w0 > encrypted_docker_config - # The config is using a "robot account" in the Jetstack quay.io organisation - DOCKER_CONFIG: CiQAPjqeE/lNpYDSJR7Z4Gm3i7c/LlYk4/6IFxYp+y2Vc4XWeh4S+QEAUOH2x97d4crKdEuCH+RvW0YbrcjiZHK+APSL5XO/QiKWhOWoaXzn6VrqLs/zuY8CVTvspiMbhHW+RRePF7Okgsm2lDF8CXAZ+mbRgrx5ftw+27OgGOHK3DgCEsZFTnP9NtP6vA8aTM7Ram9TijlkzTqESBlx3vO/QleeFG93N/nLzNCXUn+3FSW+1161GMl/7DEXuSPK/ye4XdXEAalnhIEkEbiuSf+stOzo3+9lTm+CI3jvyqsnyTaCCaEn+rROPEDXPgCpKCWq2n5qHTdTGkyh27EUPCmuLUCvoelSdhY6nevQWGBzrjH+121yz37HeCVVM3W0ZTw= - - -steps: -# NB: REF_NAME is auto-populated by cloud build based on the -# configured repo in the GCB trigger -- name: gcr.io/cloud-builders/git - dir: "trust-manager" - entrypoint: bash - args: - - -c - - | - set -e - git clone ${_REPO} . - git checkout ${REF_NAME} - -- name: 'eu.gcr.io/jetstack-build-infra-images/bazelbuild:${_BUILDER_IMAGE_TAG}' - entrypoint: bash - secretEnv: - - DOCKER_CONFIG - args: - - -c - - | - mkdir -p $$HOME/.docker - echo "$${DOCKER_CONFIG}" > $$HOME/.docker/config.json - -- name: 'eu.gcr.io/jetstack-build-infra-images/bazelbuild:${_BUILDER_IMAGE_TAG}' - dir: "trust-manager" - entrypoint: bash - args: - - -c - - | - set -eu -o pipefail - make provision-buildx - make ci-update-debian-trust-package - -tags: -- "trust-manager-cert-manager-package-debian" - -substitutions: - _REPO: "https://github.com/cert-manager/trust-manager" - _BUILDER_IMAGE_TAG: "20220629-ee75d11-4.2.1" diff --git a/hack/tools/go.mod b/hack/tools/go.mod deleted file mode 100644 index 92ad4182..00000000 --- a/hack/tools/go.mod +++ /dev/null @@ -1,70 +0,0 @@ -module github.com/cert-manager/tools/hack/tools - -go 1.21 - -require ( - github.com/cert-manager/boilersuite v0.1.0 - github.com/cert-manager/helm-tool v0.4.2 - k8s.io/code-generator v0.29.2 - sigs.k8s.io/controller-tools v0.14.0 - sigs.k8s.io/kind v0.22.0 -) - -require ( - github.com/BurntSushi/toml v1.0.0 // indirect - github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.2.0 // indirect - github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/alessio/shellescape v1.4.1 // indirect - github.com/evanphx/json-patch/v5 v5.6.0 // indirect - github.com/fatih/color v1.16.0 // indirect - github.com/go-logr/logr v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/gobuffalo/flect v1.0.2 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect - github.com/google/uuid v1.5.0 // indirect - github.com/huandu/xstrings v1.4.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml v1.9.4 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/shopspring/decimal v1.2.0 // indirect - github.com/spf13/cast v1.3.1 // indirect - github.com/spf13/cobra v1.8.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.16.1 // indirect - google.golang.org/protobuf v1.33.0 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.29.0 // indirect - k8s.io/apiextensions-apiserver v0.29.0 // indirect - k8s.io/apimachinery v0.29.0 // indirect - k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20240105020646-a37d4de58910 // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect -) diff --git a/hack/tools/go.sum b/hack/tools/go.sum deleted file mode 100644 index eab62f1a..00000000 --- a/hack/tools/go.sum +++ /dev/null @@ -1,258 +0,0 @@ -github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU= -github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= -github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= -github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= -github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= -github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= -github.com/cert-manager/boilersuite v0.1.0 h1:+1IQyi8kAI9yK2LdhwUmGWcH/ND6geu+cKyFccxGGQ4= -github.com/cert-manager/boilersuite v0.1.0/go.mod h1:1V/hWg8s4+tBfk24ZqM12l1w5PXAmSgZ574rVchEaIY= -github.com/cert-manager/helm-tool v0.4.2 h1:vht5NnR8M4Ck7k2one9EB8yhZDKJcDAqobOYMU3nQr0= -github.com/cert-manager/helm-tool v0.4.2/go.mod h1:y/MhtegWTi59aah/F6ex2E2QEq0pmHelMjQi3SGaVVU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= -github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= -github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 h1:SJ+NtwL6QaZ21U+IrK7d0gGgpjGGvd2kz+FzTHVzdqI= -github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2/go.mod h1:Tv1PlzqC9t8wNnpPdctvtSUOPUUg4SHeE6vR1Ir2hmg= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= -github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= -github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= -github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= -github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= -github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= -k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= -k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= -k8s.io/code-generator v0.29.2 h1:c9/iw2KnNpw2IRV+wwuG/Wns2TjPSgjWzbbjTevyiHI= -k8s.io/code-generator v0.29.2/go.mod h1:FwFi3C9jCrmbPjekhaCYcYG1n07CYiW1+PAPCockaos= -k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 h1:pWEwq4Asjm4vjW7vcsmijwBhOr1/shsbSYiWXmNGlks= -k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20240105020646-a37d4de58910 h1:1Rp/XEKP5uxPs6QrsngEHAxBjaAR78iJRiJq5Fi7LSU= -k8s.io/kube-openapi v0.0.0-20240105020646-a37d4de58910/go.mod h1:Pa1PvrP7ACSkuX6I7KYomY6cmMA0Tx86waBhDUgoKPw= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-tools v0.14.0 h1:rnNoCC5wSXlrNoBKKzL70LNJKIQKEzT6lloG6/LF73A= -sigs.k8s.io/controller-tools v0.14.0/go.mod h1:TV7uOtNNnnR72SpzhStvPkoS/U5ir0nMudrkrC4M9Sc= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kind v0.22.0 h1:z/+yr/azoOfzsfooqRsPw1wjJlqT/ukXP0ShkHwNlsI= -sigs.k8s.io/kind v0.22.0/go.mod h1:aBlbxg08cauDgZ612shr017/rZwqd7AS563FvpWKPVs= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh deleted file mode 100755 index d7b013d6..00000000 --- a/hack/update-codegen.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash - -# +skip_license_check - -# Copyright 2017 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. - -set -o errexit -set -o nounset -set -o pipefail - -if [[ -z "${1:-}" || -z "${2:-}" ]]; then - echo "usage: $0 " >&2 - exit 1 -fi - -CONTROLLER_GEN=$(realpath "$1") -YQ=$(realpath "$2") - -echo "Generating CRDs in ./deploy/crds" -$CONTROLLER_GEN crd schemapatch:manifests=./deploy/crds output:dir=./deploy/crds paths=./pkg/apis/... - -echo "Updating CRDs with helm templating, writing to ./deploy/charts/trust-manager/templates" -for i in $(ls ./deploy/crds); do - - crd_name=$($YQ eval '.metadata.name' "./deploy/crds/$i") - - cat << EOF > ./deploy/charts/trust-manager/templates/$i -{{- if .Values.crds.enabled }} -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: "$crd_name" - {{- if .Values.crds.keep }} - annotations: - helm.sh/resource-policy: keep - {{- end }} - labels: - {{- include "trust-manager.labels" . | nindent 4 }} -EOF - - $YQ -I2 '{"spec": .spec}' "./deploy/crds/$i" >> ./deploy/charts/trust-manager/templates/$i - - cat << EOF >> ./deploy/charts/trust-manager/templates/$i -{{- end }} -EOF -done diff --git a/hack/update-debian-trust-package.sh b/hack/update-debian-trust-package.sh deleted file mode 100755 index 29e377bc..00000000 --- a/hack/update-debian-trust-package.sh +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2022 The cert-manager 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. - -set -o errexit -set -o nounset -set -o pipefail - -# This script uses a container to install the latest ca-certificates package, and then -# checks to see if the installed version of that package matches the latest available -# debian trust package image in our container registry. - -# If we installed a newer version in the local container, we build a new image container -# and push it upstream - -CTR=${CTR:-docker} - -REPO=${1:-} -DEBIAN_TRUST_PACKAGE_SUFFIX=${2:-} -REGISTRY_API_URL=${3:-} - -DEBIAN_IMAGE=docker.io/library/debian:11-slim - -function print_usage() { - echo "usage: $0 " -} - -if ! command -v $CTR &>/dev/null; then - print_usage - echo "This script requires a docker CLI compatible runtime, either docker or podman" - echo "If CTR is not set, defaults to using docker" - echo "Couldn't find $CTR command; exiting" - exit 1 -fi - -if [[ -z $REPO ]]; then - print_usage - echo "Missing target-repo" - exit 1 -fi - -if [[ -z $DEBIAN_TRUST_PACKAGE_SUFFIX ]]; then - print_usage - echo "Missing version suffix" - exit 1 -fi - -function latest_ca_certificate_package_version() { - # Install the latest version of ca-certificates in a fresh container and print the - # installed version - - # There are several commands for querying remote repos (e.g. apt-cache madison) but - # it's not clear that these commands are guaranteed to return installable versions - # in order or in a parseable format - - # We specifically only want to query the latest version and without a guarantee on - # output ordering it's safest to install what apt thinks is the latest version and - # then see what we got. - - # NB: It's also very difficult to make 'apt-get' stay quiet when installing packages - # so we just let it be loud and then only take the last line of output - - $CTR run --rm $DEBIAN_IMAGE bash -c 'apt-get -yq update >/dev/null && DEBIAN_FRONTEND=noninteractive apt-get -qy -o=Dpkg::Use-Pty=0 install --no-install-recommends ca-certificates >/dev/null && dpkg-query --show --showformat="\${Version}" ca-certificates' | tail -1 -} - -echo "+++ fetching latest version of ca-certificates package" - -CA_CERTIFICATES_VERSION=$(latest_ca_certificate_package_version) - -# Rather than use CA_CERTIFICATES_VERSION directly as an image tag, suffix our own version number -# that we control. -# We can increment this if we need to build a second version of a given ca-certificates, -# say to add a new file or update the contents. - -IMAGE_TAG=$CA_CERTIFICATES_VERSION$DEBIAN_TRUST_PACKAGE_SUFFIX - -FULL_IMAGE=$REPO:$IMAGE_TAG - -# This ACCEPT_HEADER matches what `crane` sends, and causes the server to -# return a manifest we can parse as expected -ACCEPT_HEADER="Accept: application/vnd.docker.distribution.manifest.v1+json,application/vnd.docker.distribution.manifest.v1+prettyjws,application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.oci.image.index.v1+json" - -manifest=$(mktemp) - -trap 'rm -f -- "$manifest"' EXIT - -echo "+++ searching for $FULL_IMAGE in upstream registry" - -# Look for an image tagged with IMAGE_TAG; if this is successful, we're done. If we get a 404 we need to build + upload it. If we get any other error, we need to quit -STATUS_CODE=$(curl --silent --show-error --location --retry 5 --retry-connrefused --output $manifest --write-out "%{http_code}" --header "$ACCEPT_HEADER" $REGISTRY_API_URL/$IMAGE_TAG) - -if [[ $STATUS_CODE = "200" ]]; then - echo "upstream registry appears to contain $FULL_IMAGE, will check supported architectures" - - # NB: This ignores 32-bit ARM versions and other variables, but it works OK for now - EXPECTED_ARCHES="amd64 -arm -arm64 -ppc64le -s390x" - - GOT_ARCHES=$(jq '.manifests[].platform.architecture' -r <$manifest | sort) - - if [[ "$GOT_ARCHES" == "$EXPECTED_ARCHES" ]]; then - echo "upstream registry has all expected arches, exiting" - exit 0 - fi - - echo "+++ architectures didn't match" - echo -e "+++ wanted:\n$EXPECTED_ARCHES" - echo -e "+++ got:\n$GOT_ARCHES" - -elif [[ $STATUS_CODE != "404" ]]; then - echo "fatal: upstream registry returned an unexpected error response $STATUS_CODE, exiting" - exit 1 -fi - -echo "+++ latest image appears not to exist or to be missing archictures; building and pushing $FULL_IMAGE" - -make DEBIAN_TRUST_PACKAGE_VERSION=$CA_CERTIFICATES_VERSION DEBIAN_TRUST_PACKAGE_SUFFIX=$DEBIAN_TRUST_PACKAGE_SUFFIX trust-package-debian-push diff --git a/hack/wait-for-buildx.sh b/hack/wait-for-buildx.sh deleted file mode 100755 index db9b8385..00000000 --- a/hack/wait-for-buildx.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2022 The cert-manager 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. - -# File taken from a closed-source project originally written by SgtCoDFish -# Contributed to the trust-manager project under the above Apache license - -set -o errexit -set -o nounset -set -o pipefail - -# This script is required as "buildx rm" and "buildx create" can return successfully -# before they actually finish. We need to ensure that the builder is actually removed -# or created (as needed) before we proceed. - -BUILDX_BUILDER=${1:-} -MODE=${2:-} - -if [[ -z $BUILDX_BUILDER ]]; then - echo "usage: $0 " - echo "error: missing builder name. exiting" - exit 1 -fi - -if [[ $MODE != "exists" && $MODE != "gone" ]]; then - echo "usage: $0 " - echo "error: invalid mode, expected either 'exists' or 'gone'" - echo "'exists' means 'wait for the builder to exist'" - echo "'gone' means 'wait for the builder to not exist'" - exit 1 -fi - -RETRIES=5 - -if [[ $MODE = "exists" ]]; then - until docker buildx inspect --builder $1 >/dev/null 2>&1 || [ $RETRIES -eq 0 ]; do - echo "Waiting for buildx builder to exist, $((RETRIES--)) remaining attempts..." - sleep 1 - done -else - while docker buildx inspect --builder $1 >/dev/null 2>&1 || [ $RETRIES -eq 0 ]; do - echo "Waiting for buildx builder to not exist, $((RETRIES--)) remaining attempts..." - sleep 1 - done -fi diff --git a/klone.yaml b/klone.yaml new file mode 100644 index 00000000..08fe77e3 --- /dev/null +++ b/klone.yaml @@ -0,0 +1,79 @@ +# This klone.yaml file describes the Makefile modules and versions that are +# cloned into the "make/_shared" folder. These modules are dynamically imported +# by the root Makefile. The "make upgrade-klone" target can be used to pull +# the latest version from the upstream repositories (using the repo_ref value). +# +# More info can be found here: https://github.com/cert-manager/makefile-modules + +targets: + make/_shared: + - folder_name: api-docs + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/api-docs + - folder_name: boilerplate + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/boilerplate + - folder_name: cert-manager + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/cert-manager + - folder_name: controller-gen + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/controller-gen + - folder_name: generate-verify + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/generate-verify + - folder_name: go + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/go + - folder_name: helm + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/helm + - folder_name: help + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/help + - folder_name: kind + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/kind + - folder_name: klone + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/klone + - folder_name: oci-build + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/oci-build + - folder_name: oci-publish + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/oci-publish + - folder_name: repository-base + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/repository-base + - folder_name: tools + repo_url: https://github.com/cert-manager/makefile-modules.git + repo_ref: main + repo_hash: 35c5c672f9704edc555fcc9cd5c92b8fd8464cac + repo_path: modules/tools diff --git a/make/00_debian_version.mk b/make/00_debian_version.mk new file mode 100644 index 00000000..ff0b61ed --- /dev/null +++ b/make/00_debian_version.mk @@ -0,0 +1,20 @@ +# Copyright 2023 The cert-manager 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. + +# WARNING: Changing this file triggers a build and release of the debian trust package +# This file is used to store the latest version of the debian trust package and the DEBIAN_BUNDLE_VERSION +# variable is automatically updated by the `upgrade-debian-trust-package-version` target and cron GH action. + +DEBIAN_BUNDLE_VERSION := 20210119.0 +DEBIAN_BUNDLE_SOURCE_IMAGE=docker.io/library/debian:11-slim diff --git a/make/00_mod.mk b/make/00_mod.mk new file mode 100644 index 00000000..13b9bb35 --- /dev/null +++ b/make/00_mod.mk @@ -0,0 +1,64 @@ +# Copyright 2023 The cert-manager 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. + +include make/00_debian_version.mk + +repo_name := github.com/cert-manager/trust-manager + +kind_cluster_name := trust-manager +kind_cluster_config := $(bin_dir)/scratch/kind_cluster.yaml + +build_names := manager package_debian + +go_manager_main_dir := ./cmd/trust-manager +go_manager_mod_dir := . +go_manager_ldflags := -X $(repo_name)/internal/version.AppVersion=$(VERSION) -X $(repo_name)/internal/version.GitCommit=$(GITCOMMIT) +oci_manager_base_image_flavor := static +oci_manager_image_name := quay.io/jetstack/trust-manager +oci_manager_image_tag := $(VERSION) +oci_manager_image_name_development := cert-manager.local/trust-manager + +go_package_debian_main_dir := . +go_package_debian_mod_dir := ./trust-packages/debian +go_package_debian_ldflags := +oci_package_debian_base_image_flavor := static +oci_package_debian_image_name := quay.io/jetstack/cert-manager-package-debian +oci_package_debian_image_tag := $(DEBIAN_BUNDLE_VERSION) +oci_package_debian_image_name_development := cert-manager.local/cert-manager-package-debian + +deploy_name := trust-manager +deploy_namespace := cert-manager + +api_docs_outfile := docs/api/api.md +api_docs_package := $(repo_name)/pkg/apis/trust/v1alpha1 +api_docs_branch := main + +helm_chart_source_dir := deploy/charts/trust-manager +helm_chart_name := trust-manager +helm_chart_version := $(VERSION) +helm_labels_template_name := trust-manager.labels +helm_docs_use_helm_tool := 1 +helm_generate_schema := 1 +helm_verify_values := 1 + +golangci_lint_config := .golangci.yaml + +define helm_values_mutation_function +$(YQ) \ + '( .image.repository = "$(oci_manager_image_name)" ) | \ + ( .image.tag = "$(oci_manager_image_tag)" ) | \ + ( .defaultPackageImage.repository = "$(oci_package_debian_image_name)" ) | \ + ( .defaultPackageImage.tag = "$(oci_package_debian_image_tag)" )' \ + $1 --inplace +endef diff --git a/make/02_mod.mk b/make/02_mod.mk new file mode 100644 index 00000000..1427e4e4 --- /dev/null +++ b/make/02_mod.mk @@ -0,0 +1,61 @@ +# Copyright 2023 The cert-manager 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. + +$(kind_cluster_config): make/config/kind/cluster.yaml | $(bin_dir)/scratch + cat $< | \ + sed -e 's|{{KIND_IMAGES}}|$(CURDIR)/$(images_tar_dir)|g' \ + > $@ + +include make/test-smoke.mk +include make/test-integration.mk +include make/test-unit.mk + +# Deprecated ci-target for backwards compatibility +.PHONY: smoke-setup-trust-manager +provision-buildx: noop + +# Deprecated ci-target for backwards compatibility +.PHONY: smoke +smoke: + $(MAKE) test-unit + $(MAKE) test-integration + $(MAKE) test-smoke + +include make/debian-trust-package.mk + +.PHONY: release +## Publish all release artifacts (image + helm chart) +## @category [shared] Release +release: $(helm_chart_archive) | $(NEEDS_CRANE) + $(MAKE) oci-push-manager + $(MAKE) oci-maybe-push-package_debian + + @echo "RELEASE_OCI_MANAGER_IMAGE=$(oci_manager_image_name)" >> "$(GITHUB_OUTPUT)" + @echo "RELEASE_OCI_MANAGER_TAG=$(oci_manager_image_tag)" >> "$(GITHUB_OUTPUT)" + @echo "RELEASE_OCI_PACKAGE_DEBIAN_IMAGE=$(oci_package_debian_image_name)" >> "$(GITHUB_OUTPUT)" + @echo "RELEASE_OCI_PACKAGE_DEBIAN_TAG=$(oci_package_debian_image_tag)" >> "$(GITHUB_OUTPUT)" + @echo "RELEASE_HELM_CHART_NAME=$(helm_chart_name)" >> "$(GITHUB_OUTPUT)" + @echo "RELEASE_HELM_CHART_VERSION=$(helm_chart_version)" >> "$(GITHUB_OUTPUT)" + @echo "RELEASE_HELM_CHART_TAR=$(helm_chart_archive)" >> "$(GITHUB_OUTPUT)" + + @echo "Release complete!" + +.PHONY: release-debian-trust-package +release-debian-trust-package: | $(NEEDS_CRANE) + $(MAKE) oci-maybe-push-package_debian + + @echo "RELEASE_OCI_PACKAGE_DEBIAN_IMAGE=$(oci_package_debian_image_name)" >> "$(GITHUB_OUTPUT)" + @echo "RELEASE_OCI_PACKAGE_DEBIAN_TAG=$(oci_package_debian_image_tag)" >> "$(GITHUB_OUTPUT)" + + @echo "Release complete!" diff --git a/make/_shared/api-docs/01_mod.mk b/make/_shared/api-docs/01_mod.mk new file mode 100644 index 00000000..e395aad1 --- /dev/null +++ b/make/_shared/api-docs/01_mod.mk @@ -0,0 +1,55 @@ +# Copyright 2023 The cert-manager 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. + +ifndef repo_name +$(error repo_name is not set) +endif + +ifndef api_docs_outfile +$(error api_docs_outfile is not set) +endif + +ifndef api_docs_package +$(error api_docs_package is not set) +endif + +ifndef api_docs_branch +$(error api_docs_branch is not set) +endif + +########################################## + +GOMARKDOC_FLAGS=--format github --repository.url "https://$(repo_name)" --repository.default-branch $(api_docs_branch) --repository.path / + +.PHONY: generate-api-docs +## Generate API docs for the API types. +## @category [shared] Generate/ Verify +generate-api-docs: | $(NEEDS_GOMARKDOC) + $(GOMARKDOC) \ + $(GOMARKDOC_FLAGS) \ + --output $(api_docs_outfile) \ + $(api_docs_package) + +.PHONY: verify-generate-api-docs +## Verify that the API docs are up to date. +## @category [shared] Generate/ Verify +verify-generate-api-docs: | $(NEEDS_GOMARKDOC) + $(GOMARKDOC) \ + --check \ + $(GOMARKDOC_FLAGS) \ + --output $(api_docs_outfile) \ + $(api_docs_package) \ + || (echo "docs are not up to date; run 'make generate' and commit the result" && exit 1) + +shared_generate_targets += generate-api-docs diff --git a/make/color.mk b/make/_shared/boilerplate/00_mod.mk similarity index 75% rename from make/color.mk rename to make/_shared/boilerplate/00_mod.mk index f5897682..46f32fc5 100644 --- a/make/color.mk +++ b/make/_shared/boilerplate/00_mod.mk @@ -12,17 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -ifeq ($(strip $(CI)),) - _RED=\033[0;31m - _END=\033[0m -else - _RED= - _END= -endif +default_go_header_file := $(dir $(lastword $(MAKEFILE_LIST)))/template/boilerplate.go.txt -# Other colors: -# green="\033[0;32m" -# yel="\033[0;33m" -# cyan="\033[0;36m" -# bold="\033[0;37m" -# gray="\033[0;90m" +go_header_file ?= $(default_go_header_file) diff --git a/make/_shared/boilerplate/01_mod.mk b/make/_shared/boilerplate/01_mod.mk new file mode 100644 index 00000000..677fdff9 --- /dev/null +++ b/make/_shared/boilerplate/01_mod.mk @@ -0,0 +1,21 @@ +# Copyright 2023 The cert-manager 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. + +.PHONY: verify-boilerplate +## Verify that all files have the correct boilerplate. +## @category [shared] Generate/ Verify +verify-boilerplate: | $(NEEDS_BOILERSUITE) + $(BOILERSUITE) . + +shared_verify_targets += verify-boilerplate diff --git a/hack/boilerplate/boilerplate.go.txt b/make/_shared/boilerplate/template/boilerplate.go.txt similarity index 92% rename from hack/boilerplate/boilerplate.go.txt rename to make/_shared/boilerplate/template/boilerplate.go.txt index 1478e0b6..f0214588 100644 --- a/hack/boilerplate/boilerplate.go.txt +++ b/make/_shared/boilerplate/template/boilerplate.go.txt @@ -1,5 +1,5 @@ /* -Copyright 2023 The cert-manager Authors. +Copyright The cert-manager Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -12,5 +12,4 @@ 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. -*/ - +*/ \ No newline at end of file diff --git a/make/_shared/cert-manager/00_mod.mk b/make/_shared/cert-manager/00_mod.mk new file mode 100644 index 00000000..863508b4 --- /dev/null +++ b/make/_shared/cert-manager/00_mod.mk @@ -0,0 +1,28 @@ +# Copyright 2023 The cert-manager 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. + +images_amd64 ?= +images_arm64 ?= + +cert_manager_version := v1.14.5 + +images_amd64 += quay.io/jetstack/cert-manager-controller:$(cert_manager_version)@sha256:f37f460aaa7598ba251ff1cbe7438012fd56c4acc94be64245e8a836203c5542 +images_amd64 += quay.io/jetstack/cert-manager-cainjector:$(cert_manager_version)@sha256:6d9ebced61371cc903f7934690923034382456f3ce6e0fe2b692c40dbd67d523 +images_amd64 += quay.io/jetstack/cert-manager-webhook:$(cert_manager_version)@sha256:ac34b1905a2ff20789fde27115d3e1aa7b3d09f57efba4e91ae2ba1744de4ad2 +images_amd64 += quay.io/jetstack/cert-manager-startupapicheck:$(cert_manager_version)@sha256:5c74e4e37586dc5c35442515f43ecf222e961b65e954798428ac9239408bc0f3 + +images_arm64 += quay.io/jetstack/cert-manager-controller:$(cert_manager_version)@sha256:96668890d162a743407c0ef14d7769e970aa16655959b5f5cab0c595167148fa +images_arm64 += quay.io/jetstack/cert-manager-cainjector:$(cert_manager_version)@sha256:719aec5d99e86377829261451985592bc4129c5ca8dcb7f20b32170742f2b29b +images_arm64 += quay.io/jetstack/cert-manager-webhook:$(cert_manager_version)@sha256:874da5701a98e352fa28d88470671eb792a472737a3cf2b7ce9966817e962de8 +images_arm64 += quay.io/jetstack/cert-manager-startupapicheck:$(cert_manager_version)@sha256:35d35b325b980cc702324e52b443cc7eb1df7211ce4e8e91d96da4eff4b6c894 diff --git a/make/_shared/cert-manager/01_mod.mk b/make/_shared/cert-manager/01_mod.mk new file mode 100644 index 00000000..f1af5da0 --- /dev/null +++ b/make/_shared/cert-manager/01_mod.mk @@ -0,0 +1,17 @@ +# Copyright 2023 The cert-manager 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. + +cert_manager_crds := $(bin_dir)/scratch/cert-manager-$(cert_manager_version).yaml +$(cert_manager_crds): | $(bin_dir)/scratch + curl -sSLo $@ https://github.com/cert-manager/cert-manager/releases/download/$(cert_manager_version)/cert-manager.crds.yaml diff --git a/make/_shared/controller-gen/01_mod.mk b/make/_shared/controller-gen/01_mod.mk new file mode 100644 index 00000000..7dedf6b7 --- /dev/null +++ b/make/_shared/controller-gen/01_mod.mk @@ -0,0 +1,34 @@ +# Copyright 2023 The cert-manager 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. + +################ +# Check Inputs # +################ + +ifndef go_header_file +$(error go_header_file is not set) +endif + +################ +# Add targets # +################ + +.PHONY: generate-deepcopy +## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. +## @category [shared] Generate/ Verify +generate-deepcopy: | $(NEEDS_CONTROLLER-GEN) + $(eval directories := $(shell ls -d */ | grep -v '_bin' | grep -v 'make')) + $(CONTROLLER-GEN) object:headerFile=$(go_header_file) $(directories:%=paths=./%...) + +shared_generate_targets += generate-deepcopy diff --git a/make/_shared/generate-verify/00_mod.mk b/make/_shared/generate-verify/00_mod.mk new file mode 100644 index 00000000..43555138 --- /dev/null +++ b/make/_shared/generate-verify/00_mod.mk @@ -0,0 +1,18 @@ +# Copyright 2023 The cert-manager 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. + +shared_generate_targets ?= +shared_generate_targets_dirty ?= +shared_verify_targets ?= +shared_verify_targets_dirty ?= diff --git a/make/_shared/generate-verify/02_mod.mk b/make/_shared/generate-verify/02_mod.mk new file mode 100644 index 00000000..c1ed5e2b --- /dev/null +++ b/make/_shared/generate-verify/02_mod.mk @@ -0,0 +1,39 @@ +# Copyright 2023 The cert-manager 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. + +.PHONY: generate +## Generate all generate targets. +## @category [shared] Generate/ Verify +generate: $$(shared_generate_targets) + @echo "The following targets cannot be run simultaniously with each other or other generate scripts:" + $(foreach TARGET,$(shared_generate_targets_dirty), $(MAKE) $(TARGET)) + +verify_script := $(dir $(lastword $(MAKEFILE_LIST)))/util/verify.sh + +# Run the supplied make target argument in a temporary workspace and diff the results. +verify-%: FORCE + +$(verify_script) $(MAKE) $* + +verify_generated_targets = $(shared_generate_targets:%=verify-%) +verify_generated_targets_dirty = $(shared_generate_targets_dirty:%=verify-%) + +verify_targets = $(sort $(verify_generated_targets) $(shared_verify_targets)) +verify_targets_dirty = $(sort $(verify_generated_targets_dirty) $(shared_verify_targets_dirty)) + +.PHONY: verify +## Verify code and generate targets. +## @category [shared] Generate/ Verify +verify: $$(verify_targets) + @echo "The following targets create temporary files in the current directory, that is why they have to be run last:" + $(foreach TARGET,$(verify_targets_dirty), $(MAKE) $(TARGET)) diff --git a/hack/util/verify.sh b/make/_shared/generate-verify/util/verify.sh similarity index 89% rename from hack/util/verify.sh rename to make/_shared/generate-verify/util/verify.sh index 54e8df8a..4dbaefa2 100755 --- a/hack/util/verify.sh +++ b/make/_shared/generate-verify/util/verify.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright 2022 The cert-manager Authors. +# Copyright 2023 The cert-manager Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ set -o errexit set -o nounset set -o pipefail -projectdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )" +projectdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../../.." && pwd )" cd "${projectdir}" @@ -44,7 +44,7 @@ cleanup() { } trap "cleanup" EXIT SIGINT -cp -a "${projectdir}/." "${tmp}" +rsync -aEq "${projectdir}/." "${tmp}" --exclude "_bin/" pushd "${tmp}" >/dev/null "$@" @@ -53,8 +53,7 @@ popd >/dev/null if ! diff \ --exclude=".git" \ - --exclude="_artifacts" \ - --exclude="bin" \ + --exclude="_bin" \ --new-file --unified --show-c-function --recursive "${projectdir}" "${tmp}" then echo diff --git a/make/_shared/go/.golangci.override.yaml b/make/_shared/go/.golangci.override.yaml new file mode 100644 index 00000000..86c23375 --- /dev/null +++ b/make/_shared/go/.golangci.override.yaml @@ -0,0 +1,69 @@ +linters: + # Explicitly define all enabled linters + disable-all: true + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - contextcheck + - decorder + - dogsled + - dupword + - durationcheck + - errcheck + - errchkjson + - errname + - execinquery + - exhaustive + - exportloopref + - forbidigo + - gci + - ginkgolinter + - gocheckcompilerdirectives + - gochecksumtype + - gocritic + - gofmt + - goheader + - goprintffuncname + - gosec + - gosimple + - gosmopolitan + - govet + - grouper + - importas + - ineffassign + - interfacebloat + - loggercheck + - makezero + - mirror + - misspell + - musttag + - nakedret + - nilerr + - nilnil + - noctx + - nosprintfhostport + - predeclared + - promlinter + - protogetter + - reassign + - sloglint + - staticcheck + - tagalign + - tenv + - testableexamples + - typecheck + - unconvert + - unparam + - unused + - usestdlibvars + - wastedassign +linters-settings: + gci: + sections: + - standard # Standard section: captures all standard packages. + - default # Default section: contains all imports that could not be matched to another section type. + - prefix({{REPO-NAME}}) # Custom section: groups all imports with the specified Prefix. + - blank # Blank section: contains all blank imports. This section is not present unless explicitly enabled. + - dot # Dot section: contains all dot imports. This section is not present unless explicitly enabled. diff --git a/make/_shared/go/01_mod.mk b/make/_shared/go/01_mod.mk new file mode 100644 index 00000000..0e4d4185 --- /dev/null +++ b/make/_shared/go/01_mod.mk @@ -0,0 +1,110 @@ +# Copyright 2023 The cert-manager 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. + +ifndef bin_dir +$(error bin_dir is not set) +endif + +ifndef repo_name +$(error repo_name is not set) +endif + +go_base_dir := $(dir $(lastword $(MAKEFILE_LIST)))/base/ +golangci_lint_override := $(dir $(lastword $(MAKEFILE_LIST)))/.golangci.override.yaml + +.PHONY: generate-govulncheck +## Generate base files in the repository +## @category [shared] Generate/ Verify +generate-govulncheck: + cp -r $(go_base_dir)/. ./ + +shared_generate_targets += generate-govulncheck + +.PHONY: verify-govulncheck +## Verify all Go modules for vulnerabilities using govulncheck +## @category [shared] Generate/ Verify +# +# Runs `govulncheck` on all Go modules related to the project. +# Ignores Go modules among the temporary build artifacts in _bin, to avoid +# scanning the code of the vendored Go, after running make vendor-go. +# Ignores Go modules in make/_shared, because those will be checked in centrally +# in the makefile_modules repository. +# +# `verify-govulncheck` not added to the `shared_verify_targets` variable and is +# not run by `make verify`, because `make verify` is run for each PR, and we do +# not want new vulnerabilities in existing code to block the merging of PRs. +# Instead `make verify-govulnecheck` is intended to be run periodically by a CI job. +verify-govulncheck: | $(NEEDS_GOVULNCHECK) + @find . -name go.mod -not \( -path "./$(bin_dir)/*" -or -path "./make/_shared/*" \) \ + | while read d; do \ + target=$$(dirname $${d}); \ + echo "Running 'GOTOOLCHAIN=go$(VENDORED_GO_VERSION) $(bin_dir)/tools/govulncheck ./...' in directory '$${target}'"; \ + pushd "$${target}" >/dev/null; \ + GOTOOLCHAIN=go$(VENDORED_GO_VERSION) $(GOVULNCHECK) ./... || exit; \ + popd >/dev/null; \ + echo ""; \ + done + +ifdef golangci_lint_config + +.PHONY: generate-golangci-lint-config +## Generate a golangci-lint configuration file +## @category [shared] Generate/ Verify +generate-golangci-lint-config: | $(NEEDS_YQ) $(bin_dir)/scratch + cp $(golangci_lint_config) $(bin_dir)/scratch/golangci-lint.yaml.tmp + $(YQ) -i 'del(.linters.enable)' $(bin_dir)/scratch/golangci-lint.yaml.tmp + $(YQ) eval-all -i '. as $$item ireduce ({}; . * $$item)' $(bin_dir)/scratch/golangci-lint.yaml.tmp $(golangci_lint_override) + $(YQ) -i '(.. | select(tag == "!!str")) |= sub("{{REPO-NAME}}", "$(repo_name)")' $(bin_dir)/scratch/golangci-lint.yaml.tmp + mv $(bin_dir)/scratch/golangci-lint.yaml.tmp $(golangci_lint_config) + +shared_generate_targets += generate-golangci-lint-config + +.PHONY: verify-golangci-lint +## Verify all Go modules using golangci-lint +## @category [shared] Generate/ Verify +verify-golangci-lint: | $(NEEDS_GO) $(NEEDS_GOLANGCI-LINT) $(NEEDS_YQ) $(bin_dir)/scratch + @find . -name go.mod -not \( -path "./$(bin_dir)/*" -or -path "./make/_shared/*" \) \ + | while read d; do \ + target=$$(dirname $${d}); \ + echo "Running '$(bin_dir)/tools/golangci-lint run --go $(VENDORED_GO_VERSION) -c $(CURDIR)/$(golangci_lint_config)' in directory '$${target}'"; \ + pushd "$${target}" >/dev/null; \ + $(GOLANGCI-LINT) run --go $(VENDORED_GO_VERSION) -c $(CURDIR)/$(golangci_lint_config) --timeout 4m || exit; \ + popd >/dev/null; \ + echo ""; \ + done + +shared_verify_targets_dirty += verify-golangci-lint + +.PHONY: fix-golangci-lint +## Fix all Go modules using golangci-lint +## @category [shared] Generate/ Verify +fix-golangci-lint: | $(NEEDS_GOLANGCI-LINT) $(NEEDS_YQ) $(NEEDS_GCI) $(bin_dir)/scratch + $(GCI) write \ + -s "standard" \ + -s "default" \ + -s "prefix($(repo_name))" \ + -s "blank" \ + -s "dot" . + + @find . -name go.mod -not \( -path "./$(bin_dir)/*" -or -path "./make/_shared/*" \) \ + | while read d; do \ + target=$$(dirname $${d}); \ + echo "Running '$(bin_dir)/tools/golangci-lint run --go $(VENDORED_GO_VERSION) -c $(CURDIR)/$(golangci_lint_config) --fix' in directory '$${target}'"; \ + pushd "$${target}" >/dev/null; \ + $(GOLANGCI-LINT) run --go $(VENDORED_GO_VERSION) -c $(CURDIR)/$(golangci_lint_config) --fix || exit; \ + popd >/dev/null; \ + echo ""; \ + done + +endif diff --git a/make/_shared/go/README.md b/make/_shared/go/README.md new file mode 100644 index 00000000..ad1962ba --- /dev/null +++ b/make/_shared/go/README.md @@ -0,0 +1,3 @@ +# README + +A module for various Go static checks. diff --git a/make/_shared/go/base/.github/workflows/govulncheck.yaml b/make/_shared/go/base/.github/workflows/govulncheck.yaml new file mode 100644 index 00000000..405e8dec --- /dev/null +++ b/make/_shared/go/base/.github/workflows/govulncheck.yaml @@ -0,0 +1,28 @@ +# THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +# Edit https://github.com/cert-manager/makefile-modules/blob/main/modules/go/base/.github/workflows/govulncheck.yaml instead. + +# Run govulncheck at midnight every night on the main branch, +# to alert us to recent vulnerabilities which affect the Go code in this +# project. +name: govulncheck +on: + workflow_dispatch: {} + schedule: + - cron: '0 0 * * *' + +jobs: + govulncheck: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - id: go-version + run: | + make print-go-version >> "$GITHUB_OUTPUT" + + - uses: actions/setup-go@v5 + with: + go-version: ${{ steps.go-version.outputs.result }} + + - run: make verify-govulncheck diff --git a/make/_shared/helm/01_mod.mk b/make/_shared/helm/01_mod.mk new file mode 100644 index 00000000..8b365a0c --- /dev/null +++ b/make/_shared/helm/01_mod.mk @@ -0,0 +1,17 @@ +# Copyright 2023 The cert-manager 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. + +include $(dir $(lastword $(MAKEFILE_LIST)))/crds.mk +include $(dir $(lastword $(MAKEFILE_LIST)))/helm.mk +include $(dir $(lastword $(MAKEFILE_LIST)))/deploy.mk diff --git a/make/_shared/helm/crd.template.footer.yaml b/make/_shared/helm/crd.template.footer.yaml new file mode 100644 index 00000000..0a67617f --- /dev/null +++ b/make/_shared/helm/crd.template.footer.yaml @@ -0,0 +1 @@ +{{- end }} \ No newline at end of file diff --git a/make/_shared/helm/crd.template.header.yaml b/make/_shared/helm/crd.template.header.yaml new file mode 100644 index 00000000..663d7126 --- /dev/null +++ b/make/_shared/helm/crd.template.header.yaml @@ -0,0 +1,11 @@ +{{- if .Values.crds.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: "REPLACE_CRD_NAME" + {{- if .Values.crds.keep }} + annotations: + helm.sh/resource-policy: keep + {{- end }} + labels: + {{- include "REPLACE_LABELS_TEMPLATE" . | nindent 4 }} \ No newline at end of file diff --git a/make/_shared/helm/crds.mk b/make/_shared/helm/crds.mk new file mode 100644 index 00000000..3ddd6b53 --- /dev/null +++ b/make/_shared/helm/crds.mk @@ -0,0 +1,66 @@ +# Copyright 2023 The cert-manager 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. + +################ +# Check Inputs # +################ + +ifndef helm_chart_source_dir +$(error helm_chart_source_dir is not set) +endif + +ifndef helm_labels_template_name +$(error helm_labels_template_name is not set) +endif + +################ +# Add targets # +################ + +crd_template_header := $(dir $(lastword $(MAKEFILE_LIST)))/crd.template.header.yaml +crd_template_footer := $(dir $(lastword $(MAKEFILE_LIST)))/crd.template.footer.yaml + +# see https://stackoverflow.com/a/53408233 +sed_inplace := sed -i'' +ifeq ($(HOST_OS),darwin) + sed_inplace := sed -i '' +endif + +.PHONY: generate-crds +## Generate CRD manifests. +## @category [shared] Generate/ Verify +generate-crds: | $(NEEDS_CONTROLLER-GEN) $(NEEDS_YQ) + $(eval crds_gen_temp := $(bin_dir)/scratch/crds) + $(eval directories := $(shell ls -d */ | grep -v '_bin' | grep -v 'make')) + + rm -rf $(crds_gen_temp) + mkdir -p $(crds_gen_temp) + + $(CONTROLLER-GEN) crd \ + $(directories:%=paths=./%...) \ + output:crd:artifacts:config=$(crds_gen_temp) + + echo "Updating CRDs with helm templating, writing to $(helm_chart_source_dir)/templates" + + @for i in $$(ls $(crds_gen_temp)); do \ + crd_name=$$($(YQ) eval '.metadata.name' $(crds_gen_temp)/$$i); \ + cat $(crd_template_header) > $(helm_chart_source_dir)/templates/crd-$$i; \ + echo "" >> $(helm_chart_source_dir)/templates/crd-$$i; \ + $(sed_inplace) "s/REPLACE_CRD_NAME/$$crd_name/g" $(helm_chart_source_dir)/templates/crd-$$i; \ + $(sed_inplace) "s/REPLACE_LABELS_TEMPLATE/$(helm_labels_template_name)/g" $(helm_chart_source_dir)/templates/crd-$$i; \ + $(YQ) -I2 '{"spec": .spec}' $(crds_gen_temp)/$$i >> $(helm_chart_source_dir)/templates/crd-$$i; \ + cat $(crd_template_footer) >> $(helm_chart_source_dir)/templates/crd-$$i; \ + done + +shared_generate_targets += generate-crds diff --git a/make/_shared/helm/deploy.mk b/make/_shared/helm/deploy.mk new file mode 100644 index 00000000..8bc6ebb4 --- /dev/null +++ b/make/_shared/helm/deploy.mk @@ -0,0 +1,54 @@ +# Copyright 2023 The cert-manager 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. + +ifndef deploy_name +$(error deploy_name is not set) +endif + +ifndef deploy_namespace +$(error deploy_namespace is not set) +endif + +# Install options allows the user configuration of extra flags +INSTALL_OPTIONS ?= + +########################################## + +.PHONY: install +## Install controller helm chart on the current active K8S cluster. +## @category [shared] Deployment +install: $(helm_chart_archive) | $(NEEDS_HELM) + $(HELM) upgrade $(deploy_name) $(helm_chart_archive) \ + --wait \ + --install \ + --create-namespace \ + $(INSTALL_OPTIONS) \ + --namespace $(deploy_namespace) + +.PHONY: uninstall +## Uninstall controller helm chart from the current active K8S cluster. +## @category [shared] Deployment +uninstall: | $(NEEDS_HELM) + $(HELM) uninstall $(deploy_name) \ + --wait \ + --namespace $(deploy_namespace) + +.PHONY: template +## Template the helm chart. +## @category [shared] Deployment +template: $(helm_chart_archive) | $(NEEDS_HELM) + @$(HELM) template $(deploy_name) $(helm_chart_archive) \ + --create-namespace \ + $(INSTALL_OPTIONS) \ + --namespace $(deploy_namespace) diff --git a/make/_shared/helm/helm.mk b/make/_shared/helm/helm.mk new file mode 100644 index 00000000..7a0cc909 --- /dev/null +++ b/make/_shared/helm/helm.mk @@ -0,0 +1,126 @@ +# Copyright 2023 The cert-manager 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. + +ifndef bin_dir +$(error bin_dir is not set) +endif + +ifndef repo_name +$(error repo_name is not set) +endif + +ifndef helm_chart_source_dir +$(error helm_chart_source_dir is not set) +endif + +ifndef helm_chart_name +$(error helm_chart_name is not set) +endif + +ifndef helm_chart_version +$(error helm_chart_version is not set) +endif + +ifndef helm_values_mutation_function +$(error helm_values_mutation_function is not set) +endif + +########################################## + +helm_chart_sources := $(shell find $(helm_chart_source_dir) -maxdepth 1 -type f) $(shell find $(helm_chart_source_dir)/templates -type f) +helm_chart_archive := $(bin_dir)/scratch/image/$(helm_chart_name)-$(helm_chart_version).tgz + +$(helm_chart_archive): $(helm_chart_sources) | $(NEEDS_HELM) $(NEEDS_YQ) $(bin_dir)/scratch/image + $(eval helm_chart_source_dir_versioned := $@.tmp) + rm -rf $(helm_chart_source_dir_versioned) + mkdir -p $(dir $(helm_chart_source_dir_versioned)) + cp -a $(helm_chart_source_dir) $(helm_chart_source_dir_versioned) + + $(call helm_values_mutation_function,$(helm_chart_source_dir_versioned)/values.yaml) + + @if ! $(YQ) -oy '.name' $(helm_chart_source_dir_versioned)/Chart.yaml | grep -q '^$(helm_chart_name)$$'; then \ + echo "Chart name does not match the name in the helm_chart_name variable"; \ + exit 1; \ + fi + + $(YQ) '.annotations."artifacthub.io/prerelease" = "$(IS_PRERELEASE)"' \ + --inplace $(helm_chart_source_dir_versioned)/Chart.yaml + + mkdir -p $(dir $@) + $(HELM) package $(helm_chart_source_dir_versioned) \ + --app-version $(helm_chart_version) \ + --version $(helm_chart_version) \ + --destination $(dir $@) + +.PHONY: helm-chart +## Create a helm chart +## @category [shared] Helm Chart +helm-chart: $(helm_chart_archive) + +ifdef helm_docs_use_helm_tool + +helm_tool_header_search ?= ^ +helm_tool_footer_search ?= ^ + +.PHONY: generate-helm-docs +## Generate Helm chart documentation. +## @category [shared] Generate/ Verify +generate-helm-docs: | $(NEEDS_HELM-TOOL) + $(HELM-TOOL) inject -i $(helm_chart_source_dir)/values.yaml -o $(helm_chart_source_dir)/README.md --header-search "$(helm_tool_header_search)" --footer-search "$(helm_tool_footer_search)" +else +.PHONY: generate-helm-docs +## Generate Helm chart documentation. +## @category [shared] Generate/ Verify +generate-helm-docs: | $(NEEDS_HELM-DOCS) + $(HELM-DOCS) $(helm_chart_source_dir)/ +endif + +shared_generate_targets += generate-helm-docs + +ifdef helm_generate_schema +.PHONY: generate-helm-schema +## Generate Helm chart schema. +## @category [shared] Generate/ Verify +generate-helm-schema: | $(NEEDS_HELM-TOOL) $(NEEDS_GOJQ) + $(HELM-TOOL) schema -i $(helm_chart_source_dir)/values.yaml | $(GOJQ) > $(helm_chart_source_dir)/values.schema.json + +shared_generate_targets += generate-helm-schema +endif + +ifdef helm_verify_values +.PHONY: verify-helm-values +## Verify Helm chart values using helm-tool. +## @category [shared] Generate/ Verify +verify-helm-values: | $(NEEDS_HELM-TOOL) $(NEEDS_GOJQ) + $(HELM-TOOL) lint -i $(helm_chart_source_dir)/values.yaml -d $(helm_chart_source_dir)/templates -e $(helm_chart_source_dir)/values.linter.exceptions + +shared_verify_targets += verify-helm-values +endif + +.PHONY: verify-pod-security-standards +## Verify that the Helm chart complies with the pod security standards. +## @category [shared] Generate/ Verify +verify-pod-security-standards: $(helm_chart_archive) | $(NEEDS_KYVERNO) $(NEEDS_KUSTOMIZE) $(NEEDS_HELM) + $(KYVERNO) apply <($(KUSTOMIZE) build https://github.com/kyverno/policies/pod-security/enforce) \ + --resource <($(HELM) template $(helm_chart_archive)) 2>/dev/null + +shared_verify_targets_dirty += verify-pod-security-standards + +.PHONY: verify-helm-lint +## Verify that the Helm chart is linted. +## @category [shared] Generate/ Verify +verify-helm-lint: $(helm_chart_archive) | $(NEEDS_HELM) + $(HELM) lint $(helm_chart_archive) + +shared_verify_targets_dirty += verify-helm-lint diff --git a/make/_shared/help/01_mod.mk b/make/_shared/help/01_mod.mk new file mode 100644 index 00000000..1a6a3b48 --- /dev/null +++ b/make/_shared/help/01_mod.mk @@ -0,0 +1,22 @@ +# Copyright 2023 The cert-manager 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. + + +help_sh := $(dir $(lastword $(MAKEFILE_LIST)))/help.sh + +.PHONY: help +help: + @MAKEFILE_LIST="$(MAKEFILE_LIST)" \ + MAKE="$(MAKE)" \ + $(help_sh) diff --git a/make/_shared/help/help.sh b/make/_shared/help/help.sh new file mode 100755 index 00000000..d9c831ff --- /dev/null +++ b/make/_shared/help/help.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash + +# Copyright 2023 The cert-manager 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. + +set -o errexit +set -o nounset +set -o pipefail + +## 1. Build set of extracted line items + +EMPTYLINE_REGEX="^[[:space:]]*$" +DOCBLOCK_REGEX="^##[[:space:]]*(.*)$" +CATEGORY_REGEX="^##[[:space:]]*@category[[:space:]]*(.*)$" +TARGET_REGEX="^(([a-zA-Z0-9\_\/\%\$\(\)]|-)+):.*$" + +EMPTY_ITEM="" + +# shellcheck disable=SC2086 +raw_lines=$(cat ${MAKEFILE_LIST} | tr '\t' ' ' | grep -E "($TARGET_REGEX|$DOCBLOCK_REGEX|$EMPTYLINE_REGEX)") +extracted_lines="" +extracted_current="$EMPTY_ITEM" +max_target_length=0 + +## Extract all the commented targets from the Makefile +while read -r line; do + if [[ $line =~ $EMPTYLINE_REGEX ]]; then + # Reset current item. + extracted_current="$EMPTY_ITEM" + elif [[ $line =~ $CATEGORY_REGEX ]]; then + extracted_current=${extracted_current///${BASH_REMATCH[1]}} + elif [[ $line =~ $TARGET_REGEX ]]; then + # only keep the target if there is a comment + if [[ $extracted_current != *""* ]]; then + max_target_length=$(( ${#BASH_REMATCH[1]} > max_target_length ? ${#BASH_REMATCH[1]} : max_target_length )) + extracted_current=${extracted_current///${BASH_REMATCH[1]}} + extracted_lines="$extracted_lines\n$extracted_current" + fi + + extracted_current="$EMPTY_ITEM" + elif [[ $line =~ $DOCBLOCK_REGEX ]]; then + extracted_current=${extracted_current///${BASH_REMATCH[1]}} + fi +done <<< "$raw_lines" + +## 2. Build mapping for expanding targets + +ASSIGNMENT_REGEX="^(([a-zA-Z0-9\_\/\%\$\(\)]|-)+)[[:space:]]*:=[[:space:]]*(.*)$" + +raw_expansions=$(${MAKE} --dry-run --print-data-base noop | tr '\t' ' ' | grep -E "$ASSIGNMENT_REGEX") +extracted_expansions="" + +while read -r line; do + if [[ $line =~ $ASSIGNMENT_REGEX ]]; then + target=${BASH_REMATCH[1]} + expansion=${BASH_REMATCH[3]// /, } + extracted_expansions="$extracted_expansions\n$target$expansion" + fi +done <<< "$raw_expansions" + +## 3. Sort and print the extracted line items + +RULE_COLOR="$(tput setaf 6)" +CATEGORY_COLOR="$(tput setaf 3)" +CLEAR_STYLE="$(tput sgr0)" +PURPLE=$(tput setaf 125) + +extracted_lines=$(echo -e "$extracted_lines" | LC_ALL=C sort -r) +current_category="" + +## Print the help +echo "Usage: make [target1] [target2] ..." + +IFS=$'\n'; for line in $extracted_lines; do + category=$([[ $line =~ \(.*)\ ]] && echo "${BASH_REMATCH[1]}") + target=$([[ $line =~ \(.*)\ ]] && echo "${BASH_REMATCH[1]}") + comment=$([[ $line =~ \(.*)\ ]] && echo -e "${BASH_REMATCH[1]///\\n}") + + # Print the category header if it's changed + if [[ "$current_category" != "$category" ]]; then + current_category=$category + echo -e "\n${CATEGORY_COLOR}${current_category}${CLEAR_STYLE}" + fi + + # replace any $(...) with the actual value + if [[ $target =~ \$\((.*)\) ]]; then + new_target=$(echo -e "$extracted_expansions" | grep "${BASH_REMATCH[1]}" || true) + if [[ -n "$new_target" ]]; then + target=$([[ $new_target =~ \(.*)\ ]] && echo -e "${BASH_REMATCH[1]}") + fi + fi + + # Print the target and its multiline comment + is_first_line=true + while read -r comment_line; do + if [[ "$is_first_line" == true ]]; then + is_first_line=false + padding=$(( max_target_length - ${#target} )) + printf " %s%${padding}s ${PURPLE}>${CLEAR_STYLE} %s\n" "${RULE_COLOR}${target}${CLEAR_STYLE}" "" "${comment_line}" + else + printf " %${max_target_length}s %s\n" "" "${comment_line}" + fi + done <<< "$comment" +done diff --git a/make/_shared/kind/00_mod.mk b/make/_shared/kind/00_mod.mk new file mode 100644 index 00000000..0619ec58 --- /dev/null +++ b/make/_shared/kind/00_mod.mk @@ -0,0 +1,28 @@ +# Copyright 2023 The cert-manager 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. + +images_amd64 ?= +images_arm64 ?= + +kind_k8s_version := v1.29.2 + +# Goto https://github.com/kubernetes-sigs/kind/releases/tag/ and find the +# multi-arch digest for the image you want to use. Then use crane to get the platform +# specific digest. For example (digest is the multi-arch digest from the release page): +# digest="sha256:51a1434a5397193442f0be2a297b488b6c919ce8a3931be0ce822606ea5ca245" +# crane digest --platform=linux/amd64 docker.io/kindest/node@$digest +# crane digest --platform=linux/arm64 docker.io/kindest/node@$digest + +images_amd64 += docker.io/kindest/node:$(kind_k8s_version)@sha256:acc9e82a5a5bd3dfccfd03117e9ef5f96b46108b55cd647fb5e7d0d1a35c9c6f +images_arm64 += docker.io/kindest/node:$(kind_k8s_version)@sha256:068aaa834c09ab60d925a8569c6b5f5b9cf46eccf670499176f3267f2ac3189c diff --git a/make/_shared/kind/01_mod.mk b/make/_shared/kind/01_mod.mk new file mode 100644 index 00000000..a7eb1b2b --- /dev/null +++ b/make/_shared/kind/01_mod.mk @@ -0,0 +1,16 @@ +# Copyright 2023 The cert-manager 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. + +include $(dir $(lastword $(MAKEFILE_LIST)))/kind.mk +include $(dir $(lastword $(MAKEFILE_LIST)))/kind-image-preload.mk diff --git a/make/_shared/kind/kind-image-preload.mk b/make/_shared/kind/kind-image-preload.mk new file mode 100644 index 00000000..a157ad27 --- /dev/null +++ b/make/_shared/kind/kind-image-preload.mk @@ -0,0 +1,56 @@ +# Copyright 2023 The cert-manager 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. + +ifndef bin_dir +$(error bin_dir is not set) +endif + +ifndef images_amd64 +$(error images_amd64 is not set) +endif + +ifndef images_arm64 +$(error images_arm64 is not set) +endif + +########################################## + +images := $(images_$(HOST_ARCH)) +images_files := $(foreach image,$(images),$(subst :,+,$(image))) + +images_tar_dir := $(bin_dir)/downloaded/containers/$(HOST_ARCH) +images_tars := $(images_files:%=$(images_tar_dir)/%.tar) + +$(images_tars): $(images_tar_dir)/%.tar: | $(NEEDS_CRANE) + @$(eval image=$(subst +,:,$*)) + @$(eval image_without_digest=$(shell cut -d@ -f1 <<<"$(image)")) + @$(eval digest=$(subst $(image_without_digest)@,,$(image))) + @mkdir -p $(dir $@) + diff <(echo "$(digest) -" | cut -d: -f2) <($(CRANE) manifest --platform=linux/$(HOST_ARCH) $(image_without_digest) | sha256sum) + $(CRANE) pull $(image_without_digest) $@ --platform=linux/$(HOST_ARCH) + +images_tar_envs := $(images_files:%=env-%) + +.PHONY: $(images_tar_envs) +$(images_tar_envs): env-%: $(images_tar_dir)/%.tar | $(NEEDS_GOJQ) + @$(eval image_without_tag=$(shell cut -d+ -f1 <<<"$*")) + @$(eval $(image_without_tag).TAR="$(images_tar_dir)/$*.tar") + @$(eval $(image_without_tag).REPO=$(shell tar xfO "$(images_tar_dir)/$*.tar" manifest.json | $(GOJQ) '.[0].RepoTags[0]' -r | cut -d: -f1)) + @$(eval $(image_without_tag).TAG=$(shell tar xfO "$(images_tar_dir)/$*.tar" manifest.json | $(GOJQ) '.[0].RepoTags[0]' -r | cut -d: -f2)) + @$(eval $(image_without_tag).FULL=$($(image_without_tag).REPO):$($(image_without_tag).TAG)) + +.PHONY: images-preload +## Preload images. +## @category [shared] Kind cluster +images-preload: | $(images_tar_envs) diff --git a/make/_shared/kind/kind.mk b/make/_shared/kind/kind.mk new file mode 100644 index 00000000..c5734208 --- /dev/null +++ b/make/_shared/kind/kind.mk @@ -0,0 +1,79 @@ +# Copyright 2023 The cert-manager 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. + +ifndef bin_dir +$(error bin_dir is not set) +endif + +ifndef kind_cluster_name +$(error kind_cluster_name is not set) +endif + +ifndef kind_cluster_config +$(error kind_cluster_config is not set) +endif + +########################################## + +kind_kubeconfig := $(bin_dir)/scratch/kube.config +absolute_kubeconfig := $(CURDIR)/$(kind_kubeconfig) + +$(bin_dir)/scratch/cluster-check: FORCE | $(NEEDS_KIND) $(bin_dir)/scratch + @if ! $(KIND) get clusters -q | grep -q "^$(kind_cluster_name)\$$"; then \ + echo "❌ cluster $(kind_cluster_name) not found. Starting ..."; \ + echo "trigger" > $@; \ + else \ + echo "✅ existing cluster $(kind_cluster_name) found"; \ + fi + $(eval export KUBECONFIG=$(absolute_kubeconfig)) + +kind_post_create_hook ?= +$(kind_kubeconfig): $(kind_cluster_config) $(bin_dir)/scratch/cluster-check | images-preload $(bin_dir)/scratch $(NEEDS_KIND) $(NEEDS_KUBECTL) + @[ -f "$(bin_dir)/scratch/cluster-check" ] && ( \ + $(KIND) delete cluster --name $(kind_cluster_name); \ + $(CTR) load -i $(docker.io/kindest/node.TAR); \ + $(KIND) create cluster \ + --image $(docker.io/kindest/node.FULL) \ + --name $(kind_cluster_name) \ + --config "$<"; \ + $(CTR) exec $(kind_cluster_name)-control-plane find /mounted_images/ -name "*.tar" -exec echo {} \; -exec ctr --namespace=k8s.io images import --all-platforms --no-unpack --digests {} \; ; \ + $(MAKE) --no-print-directory noop $(kind_post_create_hook); \ + $(KUBECTL) config use-context kind-$(kind_cluster_name); \ + ) || true + + $(KIND) get kubeconfig --name $(kind_cluster_name) > $@ + +.PHONY: kind-cluster +## Create Kind cluster and wait for nodes to be ready +## @category [shared] Kind cluster +kind-cluster: $(kind_kubeconfig) | $(NEEDS_KUBECTL) + mkdir -p ~/.kube + KUBECONFIG=~/.kube/config:$(kind_kubeconfig) $(KUBECTL) config view --flatten > ~/.kube/config + $(KUBECTL) config use-context kind-$(kind_cluster_name) + +.PHONY: kind-cluster-clean +## Delete the Kind cluster +## @category [shared] Kind cluster +kind-cluster-clean: $(NEEDS_KIND) + $(KIND) delete cluster --name $(kind_cluster_name) + rm -rf $(kind_kubeconfig) + $(MAKE) --no-print-directory noop $(kind_post_create_hook) + +.PHONY: kind-logs +## Get the Kind cluster +## @category [shared] Kind cluster +kind-logs: | kind-cluster $(NEEDS_KIND) $(bin_dir)/artifacts + rm -rf $(bin_dir)/artifacts/e2e-logs + mkdir -p $(bin_dir)/artifacts/e2e-logs + $(KIND) export logs $(bin_dir)/artifacts/e2e-logs --name=$(kind_cluster_name) diff --git a/make/_shared/klone/01_mod.mk b/make/_shared/klone/01_mod.mk new file mode 100644 index 00000000..a3d07dd2 --- /dev/null +++ b/make/_shared/klone/01_mod.mk @@ -0,0 +1,27 @@ +# Copyright 2023 The cert-manager 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. + +.PHONY: generate-klone +## Generate klone shared Makefiles +## @category [shared] Generate/ Verify +generate-klone: | $(NEEDS_KLONE) + $(KLONE) sync + +shared_generate_targets += generate-klone + +.PHONY: upgrade-klone +## Upgrade klone Makefile modules to latest version +## @category [shared] Self-upgrade +upgrade-klone: | $(NEEDS_KLONE) + $(KLONE) upgrade diff --git a/make/_shared/oci-build/00_mod.mk b/make/_shared/oci-build/00_mod.mk new file mode 100644 index 00000000..2eb10e24 --- /dev/null +++ b/make/_shared/oci-build/00_mod.mk @@ -0,0 +1,125 @@ +# Copyright 2023 The cert-manager 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. + +oci_platforms ?= linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le + +# Use distroless as minimal base image to package the manager binary +# To get latest SHA run "crane digest quay.io/jetstack/base-static:latest" +base_image_static := quay.io/jetstack/base-static@sha256:ba3cff0a4cacc5ae564e04c1f645000e8c9234c0f4b09534be1dee7874a42141 + +# Use custom apko-built image as minimal base image to package the manager binary +# To get latest SHA run "crane digest quay.io/jetstack/base-static-csi:latest" +base_image_csi-static := quay.io/jetstack/base-static-csi@sha256:54bacd13cccc385ef66730dbc7eb13bdb6a9ff8853e7f551d025ccb0e8c6bf83 + +# Utility functions +fatal_if_undefined = $(if $(findstring undefined,$(origin $1)),$(error $1 is not set)) + +# Validate globals that are required +$(call fatal_if_undefined,bin_dir) +$(call fatal_if_undefined,build_names) + +# Set default config values +CGO_ENABLED ?= 0 +GOEXPERIMENT ?= # empty by default + +# Default variables per build_names entry +# +# $1 - build_name +define default_per_build_variables +cgo_enabled_$1 ?= $(CGO_ENABLED) +goexperiment_$1 ?= $(GOEXPERIMENT) +oci_additional_layers_$1 ?= +endef + +$(foreach build_name,$(build_names),$(eval $(call default_per_build_variables,$(build_name)))) + +# Validate variables per build_names entry +# +# $1 - build_name +define check_per_build_variables +# Validate required config exists +$(call fatal_if_undefined,go_$1_ldflags) +$(call fatal_if_undefined,go_$1_main_dir) +$(call fatal_if_undefined,go_$1_mod_dir) +$(call fatal_if_undefined,oci_$1_base_image_flavor) +$(call fatal_if_undefined,oci_$1_image_name_development) + +# Validate we have valid base image config +ifeq ($(oci_$1_base_image_flavor),static) + oci_$1_base_image := $(base_image_static) +else ifeq ($(oci_$1_base_image_flavor),csi-static) + oci_$1_base_image := $(base_image_csi-static) +else ifeq ($(oci_$1_base_image_flavor),custom) + $$(call fatal_if_undefined,oci_$1_base_image) +else + $$(error oci_$1_base_image_flavor has unknown value "$(oci_$1_base_image_flavor)") +endif + +# Validate the config required to build the golang based images +ifneq ($(go_$1_main_dir:.%=.),.) +$$(error go_$1_main_dir "$(go_$1_main_dir)" should be a directory path that DOES start with ".") +endif +ifeq ($(go_$1_main_dir:%/=/),/) +$$(error go_$1_main_dir "$(go_$1_main_dir)" should be a directory path that DOES NOT end with "/") +endif +ifeq ($(go_$1_main_dir:%.go=.go),.go) +$$(error go_$1_main_dir "$(go_$1_main_dir)" should be a directory path that DOES NOT end with ".go") +endif +ifneq ($(go_$1_mod_dir:.%=.),.) +$$(error go_$1_mod_dir "$(go_$1_mod_dir)" should be a directory path that DOES start with ".") +endif +ifeq ($(go_$1_mod_dir:%/=/),/) +$$(error go_$1_mod_dir "$(go_$1_mod_dir)" should be a directory path that DOES NOT end with "/") +endif +ifeq ($(go_$1_mod_dir:%.go=.go),.go) +$$(error go_$1_mod_dir "$(go_$1_mod_dir)" should be a directory path that DOES NOT end with ".go") +endif +ifeq ($(wildcard $(go_$1_mod_dir)/go.mod),) +$$(error go_$1_mod_dir "$(go_$1_mod_dir)" does not contain a go.mod file) +endif +ifeq ($(wildcard $(go_$1_mod_dir)/$(go_$1_main_dir)/main.go),) +$$(error go_$1_main_dir "$(go_$1_mod_dir)" does not contain a main.go file) +endif + +# Validate the config required to build OCI images +ifneq ($(words $(oci_$1_image_name_development)),1) +$$(error oci_$1_image_name_development "$(oci_$1_image_name_development)" should be a single image name) +endif + +endef + +$(foreach build_name,$(build_names),$(eval $(call check_per_build_variables,$(build_name)))) + +# Create variables holding targets +# +# We create the following targets for each $(build_names) +# - oci-build-$(build_name) = build the oci directory +# - oci-load-$(build_name) = load the image into docker using the oci_$(build_name)_image_name_development variable +# - docker-tarball-$(build_name) = build a "docker load" compatible tarball of the image +# - ko-config-$(build_name) = generate "ko" config for a given build +oci_build_targets := $(build_names:%=oci-build-%) +oci_load_targets := $(build_names:%=oci-load-%) +docker_tarball_targets := $(build_names:%=docker-tarball-%) +ko_config_targets := $(build_names:%=ko-config-%) + +# Derive config based on user config +# +# - oci_layout_path_$(build_name) = path that the OCI image will be saved in OCI layout directory format +# - oci_digest_path_$(build_name) = path to the file that will contain the digests +# - ko_config_path_$(build_name) = path to the ko config file +# - docker_tarball_path_$(build_name) = path that the docker tarball that the docker-tarball-$(build_name) will produce +$(foreach build_name,$(build_names),$(eval oci_layout_path_$(build_name) := $(bin_dir)/scratch/image/oci-layout-$(build_name).$(oci_$(build_name)_image_tag))) +$(foreach build_name,$(build_names),$(eval oci_digest_path_$(build_name) := $(CURDIR)/$(oci_layout_path_$(build_name)).digests)) +$(foreach build_name,$(build_names),$(eval ko_config_path_$(build_name) := $(CURDIR)/$(oci_layout_path_$(build_name)).ko_config.yaml)) +$(foreach build_name,$(build_names),$(eval docker_tarball_path_$(build_name) := $(CURDIR)/$(oci_layout_path_$(build_name)).docker.tar)) \ No newline at end of file diff --git a/make/_shared/oci-build/01_mod.mk b/make/_shared/oci-build/01_mod.mk new file mode 100644 index 00000000..ca6fc926 --- /dev/null +++ b/make/_shared/oci-build/01_mod.mk @@ -0,0 +1,90 @@ +# Copyright 2023 The cert-manager 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. + +# Utility variables +current_makefile = $(lastword $(MAKEFILE_LIST)) +current_makefile_directory = $(dir $(current_makefile)) + +# Build the image tool +image_tool_dir := $(current_makefile_directory:/=)/image_tool +IMAGE_TOOL := $(CURDIR)/$(bin_dir)/tools/image_tool +NEEDS_IMAGE_TOOL := $(bin_dir)/tools/image_tool +$(NEEDS_IMAGE_TOOL): $(wildcard $(image_tool_dir)/*.go) | $(NEEDS_GO) + cd $(image_tool_dir) && GOWORK=off GOBIN=$(CURDIR)/$(dir $@) $(GO) install . + +define ko_config_target +.PHONY: $(ko_config_path_$1:$(CURDIR)/%=%) +$(ko_config_path_$1:$(CURDIR)/%=%): | $(NEEDS_YQ) $(bin_dir)/scratch/image + echo '{}' | \ + $(YQ) '.defaultBaseImage = "$(oci_$1_base_image)"' | \ + $(YQ) '.builds[0].id = "$1"' | \ + $(YQ) '.builds[0].dir = "$(go_$1_mod_dir)"' | \ + $(YQ) '.builds[0].main = "$(go_$1_main_dir)"' | \ + $(YQ) '.builds[0].env[0] = "CGO_ENABLED=$(cgo_enabled_$1)"' | \ + $(YQ) '.builds[0].env[1] = "GOEXPERIMENT=$(goexperiment_$1)"' | \ + $(YQ) '.builds[0].ldflags[0] = "-s"' | \ + $(YQ) '.builds[0].ldflags[1] = "-w"' | \ + $(YQ) '.builds[0].ldflags[2] = "{{.Env.LDFLAGS}}"' \ + > $(CURDIR)/$(oci_layout_path_$1).ko_config.yaml + +ko-config-$1: $(ko_config_path_$1:$(CURDIR)/%=%) +endef + +.PHONY: $(ko_config_targets) +$(foreach build_name,$(build_names),$(eval $(call ko_config_target,$(build_name)))) + +.PHONY: $(oci_build_targets) +## Build the OCI image. +## @category [shared] Build +$(oci_build_targets): oci-build-%: ko-config-% | $(NEEDS_KO) $(NEEDS_GO) $(NEEDS_YQ) $(NEEDS_IMAGE_TOOL) $(bin_dir)/scratch/image + rm -rf $(CURDIR)/$(oci_layout_path_$*) + GOWORK=off \ + KO_DOCKER_REPO=$(oci_$*_image_name_development) \ + KOCACHE=$(CURDIR)/$(bin_dir)/scratch/image/ko_cache \ + KO_CONFIG_PATH=$(ko_config_path_$*) \ + SOURCE_DATE_EPOCH=$(GITEPOCH) \ + KO_GO_PATH=$(GO) \ + LDFLAGS="$(go_$*_ldflags)" \ + $(KO) build $(go_$*_mod_dir)/$(go_$*_main_dir) \ + --platform=$(oci_platforms) \ + --oci-layout-path=$(oci_layout_path_$*) \ + --sbom-dir=$(CURDIR)/$(oci_layout_path_$*).sbom \ + --sbom=spdx \ + --push=false \ + --bare + + $(IMAGE_TOOL) append-layers \ + $(CURDIR)/$(oci_layout_path_$*) \ + $(oci_additional_layers_$*) + + $(IMAGE_TOOL) list-digests \ + $(CURDIR)/$(oci_layout_path_$*) \ + > $(oci_digest_path_$*) + +# Only include the oci-load target if kind is provided by the kind makefile-module +ifdef kind_cluster_name +.PHONY: $(oci_load_targets) +## Build OCI image for the local architecture and load +## it into the $(kind_cluster_name) kind cluster. +## @category [shared] Build +$(oci_load_targets): oci-load-%: docker-tarball-% | kind-cluster $(NEEDS_KIND) + $(KIND) load image-archive --name $(kind_cluster_name) $(docker_tarball_path_$*) +endif + +## Build Docker tarball image for the local architecture +## @category [shared] Build +.PHONY: $(docker_tarball_targets) +$(docker_tarball_targets): oci_platforms := "linux/$(HOST_ARCH)" +$(docker_tarball_targets): docker-tarball-%: oci-build-% | $(NEEDS_GO) $(NEEDS_IMAGE_TOOL) + $(IMAGE_TOOL) convert-to-docker-tar $(CURDIR)/$(oci_layout_path_$*) $(docker_tarball_path_$*) $(oci_$*_image_name_development):$(oci_$*_image_tag) \ No newline at end of file diff --git a/make/_shared/oci-build/image_tool/append_layers.go b/make/_shared/oci-build/image_tool/append_layers.go new file mode 100644 index 00000000..3592c11c --- /dev/null +++ b/make/_shared/oci-build/image_tool/append_layers.go @@ -0,0 +1,199 @@ +/* +Copyright 2023 The cert-manager 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 main + +import ( + "archive/tar" + "bytes" + "io" + "io/fs" + "log/slog" + "os" + "path/filepath" + + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/layout" + "github.com/google/go-containerregistry/pkg/v1/match" + "github.com/google/go-containerregistry/pkg/v1/mutate" + "github.com/google/go-containerregistry/pkg/v1/tarball" + "github.com/google/go-containerregistry/pkg/v1/types" + "github.com/spf13/cobra" +) + +var CommandAppendLayers = cobra.Command{ + Use: "append-layers oci-path [path-to-tarball...]", + Short: "Appends a tarball or directory to every image in an OCI index.", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + oci := args[0] + extra := args[1:] + + if len(extra) == 0 { + return + } + + path, err := layout.FromPath(oci) + must("could not load oci directory", err) + + index, err := path.ImageIndex() + must("could not load oci image index", err) + + indexMediaType, err := index.MediaType() + must("could not get image index media type", err) + + layerType := types.DockerLayer + if indexMediaType == types.OCIImageIndex { + layerType = types.OCILayer + } + + layers := []v1.Layer{} + for _, path := range extra { + layers = append(layers, loadLayerFromDirOrTarball(path, layerType)) + } + + index = appendLayersToImageIndex(index, layers) + + _, err = layout.Write(oci, index) + must("could not write image", err) + }, +} + +func loadLayerFromDirOrTarball(path string, mediaType types.MediaType) v1.Layer { + stat, err := os.Stat(path) + must("could not open directory or tarball", err) + + var layer v1.Layer + if stat.IsDir() { + var buf bytes.Buffer + + tw := tar.NewWriter(&buf) + + filepath.Walk(path, func(target string, info fs.FileInfo, err error) error { + must("walk error", err) + + header, err := tar.FileInfoHeader(info, info.Name()) + must("could not create tar header", err) + + name, err := filepath.Rel(path, target) + must("could not build relative path", err) + + // Write simplified header, this removes all fields that would cause + // the build to be non-reproducible (like modtime for example) + err = tw.WriteHeader(&tar.Header{ + Typeflag: header.Typeflag, + Name: name, + Mode: header.Mode, + Linkname: header.Linkname, + Size: header.Size, + }) + + must("could not write tar header", err) + + if !info.IsDir() { + file, err := os.Open(target) + must("could not write tar contents", err) + + defer file.Close() + + _, err = io.Copy(tw, file) + must("could not write tar contents", err) + } + + return nil + }) + + tw.Close() + + byts := buf.Bytes() + + layer, err = tarball.LayerFromOpener( + func() (io.ReadCloser, error) { + return io.NopCloser(bytes.NewReader(byts)), nil + }, + tarball.WithMediaType(mediaType), + ) + + } else { + layer, err = tarball.LayerFromFile( + path, + tarball.WithMediaType(mediaType), + ) + } + + must("could not open directory or tarball", err) + return layer +} + +func appendLayersToImageIndex(index v1.ImageIndex, layers []v1.Layer) v1.ImageIndex { + manifest, err := index.IndexManifest() + must("could not load oci image manifest", err) + + for _, descriptor := range manifest.Manifests { + switch { + case descriptor.MediaType.IsImage(): + slog.Info("found image", "digest", descriptor.Digest, "platform", descriptor.Platform) + + img, err := index.Image(descriptor.Digest) + must("could not load oci image with digest", err) + + img, err = mutate.AppendLayers(img, layers...) + must("could not load append layer to image", err) + + digest, err := img.Digest() + must("could not get image digest", err) + + size, err := img.Size() + must("could not get image size", err) + + slog.Info("appended layers to image", "old_digest", descriptor.Digest, "digest", digest, "platform", descriptor.Platform) + + index = mutate.RemoveManifests(index, match.Digests(descriptor.Digest)) + + descriptor.Digest = digest + descriptor.Size = size + index = mutate.AppendManifests(index, mutate.IndexAddendum{ + Add: img, + Descriptor: descriptor, + }) + + case descriptor.MediaType.IsIndex(): + slog.Info("found image index", "digest", descriptor.Digest) + + child, err := index.ImageIndex(descriptor.Digest) + must("could not load oci index manifest", err) + + child = appendLayersToImageIndex(child, layers) + + digest, err := child.Digest() + must("could not get index digest", err) + + size, err := child.Size() + must("could not get index size", err) + + index = mutate.RemoveManifests(index, match.Digests(descriptor.Digest)) + + descriptor.Digest = digest + descriptor.Size = size + index = mutate.AppendManifests(index, mutate.IndexAddendum{ + Add: child, + Descriptor: descriptor, + }) + } + } + + return index +} diff --git a/make/_shared/oci-build/image_tool/convert_to_docker_tar.go b/make/_shared/oci-build/image_tool/convert_to_docker_tar.go new file mode 100644 index 00000000..c6e1e269 --- /dev/null +++ b/make/_shared/oci-build/image_tool/convert_to_docker_tar.go @@ -0,0 +1,97 @@ +/* +Copyright 2023 The cert-manager 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 main + +import ( + "runtime" + + "github.com/google/go-containerregistry/pkg/name" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/google/go-containerregistry/pkg/v1/layout" + "github.com/google/go-containerregistry/pkg/v1/match" + "github.com/google/go-containerregistry/pkg/v1/tarball" + "github.com/spf13/cobra" +) + +var CommandConvertToDockerTar = cobra.Command{ + Use: "convert-to-docker-tar oci-path output image-name", + Short: "Reads the OCI directory and outputs a tarball that is compatible with \"docker load\"", + Args: cobra.ExactArgs(3), + Run: func(cmd *cobra.Command, args []string) { + path := args[0] + output := args[1] + imageName := args[2] + + ociLayout, err := layout.FromPath(path) + must("could not load oci directory", err) + + index, err := ociLayout.ImageIndex() + must("could not load oci image index", err) + + images := getImagesFromIndex(index, func(desc v1.Descriptor) bool { + return desc.Platform != nil && desc.Platform.Architecture == runtime.GOARCH + }) + + switch { + case len(images) == 0: + fail("no matching images found") + case len(images) > 1: + fail("multiple matching images found") + } + + ref, err := name.ParseReference(imageName) + must("invalid image name", err) + + err = tarball.WriteToFile(output, ref, images[0]) + must("could not write tarball", err) + }, +} + +func getImagesFromIndex(index v1.ImageIndex, matcher match.Matcher) (images []v1.Image) { + manifest, err := index.IndexManifest() + must("could not load oci index manifest", err) + + for _, descriptor := range manifest.Manifests { + switch { + case descriptor.MediaType.IsImage(): + // If the platform is not part of the index manifest, attempt to + // load it from the image config + if descriptor.Platform == nil { + img, err := index.Image(descriptor.Digest) + must("could not load image", err) + + cfg, err := img.ConfigFile() + must("could not load image config", err) + + descriptor.Platform = cfg.Platform() + } + + if matcher(descriptor) { + img, err := index.Image(descriptor.Digest) + must("could not load image", err) + images = append(images, img) + } + + case descriptor.MediaType.IsIndex(): + idx, err := index.ImageIndex(descriptor.Digest) + must("could not load image index", err) + images = append(images, getImagesFromIndex(idx, matcher)...) + } + } + + return +} diff --git a/make/_shared/oci-build/image_tool/go.mod b/make/_shared/oci-build/image_tool/go.mod new file mode 100644 index 00000000..84c8b868 --- /dev/null +++ b/make/_shared/oci-build/image_tool/go.mod @@ -0,0 +1,19 @@ +module image_tool + +go 1.21 + +require ( + github.com/google/go-containerregistry v0.19.1 + github.com/spf13/cobra v1.8.0 +) + +require ( + github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/klauspost/compress v1.16.5 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc3 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/vbatts/tar-split v0.11.3 // indirect + golang.org/x/sync v0.2.0 // indirect +) diff --git a/make/_shared/oci-build/image_tool/go.sum b/make/_shared/oci-build/image_tool/go.sum new file mode 100644 index 00000000..a36acd3d --- /dev/null +++ b/make/_shared/oci-build/image_tool/go.sum @@ -0,0 +1,60 @@ +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= +github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docker/cli v24.0.0+incompatible h1:0+1VshNwBQzQAx9lOl+OYCTCEAD8fKs/qeXMx3O0wqM= +github.com/docker/cli v24.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v24.0.0+incompatible h1:z4bf8HvONXX9Tde5lGBMQ7yCJgNahmJumdrStZAbeY4= +github.com/docker/docker v24.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= +github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-containerregistry v0.19.1 h1:yMQ62Al6/V0Z7CqIrrS1iYoA5/oQCm88DeNujc7C1KY= +github.com/google/go-containerregistry v0.19.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8= +github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.1 h1:Ou41VVR3nMWWmTiEUnj0OlsgOSCUFgsPAOl6jRIcVtQ= +github.com/sirupsen/logrus v1.9.1/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= +github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= +github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/make/_shared/oci-build/image_tool/list_digests.go b/make/_shared/oci-build/image_tool/list_digests.go new file mode 100644 index 00000000..e08d9489 --- /dev/null +++ b/make/_shared/oci-build/image_tool/list_digests.go @@ -0,0 +1,46 @@ +/* +Copyright 2023 The cert-manager 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 main + +import ( + "fmt" + + "github.com/google/go-containerregistry/pkg/v1/layout" + "github.com/spf13/cobra" +) + +var CommandListDigests = cobra.Command{ + Use: "list-digests oci-path", + Short: "Outputs the digests for images found inside the tarball", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + path := args[0] + + ociLayout, err := layout.FromPath(path) + must("could not load oci directory", err) + + imageIndex, err := ociLayout.ImageIndex() + must("could not load oci image index", err) + + indexManifest, err := imageIndex.IndexManifest() + must("could not load oci index manifest", err) + + for _, man := range indexManifest.Manifests { + fmt.Println(man.Digest) + } + }, +} diff --git a/hack/tools/tools.go b/make/_shared/oci-build/image_tool/main.go similarity index 50% rename from hack/tools/tools.go rename to make/_shared/oci-build/image_tool/main.go index 03d42164..507281e7 100644 --- a/hack/tools/tools.go +++ b/make/_shared/oci-build/image_tool/main.go @@ -1,8 +1,5 @@ -//go:build tools -// +build tools - /* -Copyright 2021 The cert-manager Authors. +Copyright 2023 The cert-manager Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,15 +14,33 @@ See the License for the specific language governing permissions and limitations under the License. */ -// This file exists to force 'go mod' to fetch tool dependencies -// See: https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module - -package bin +package main import ( - _ "github.com/cert-manager/boilersuite" - _ "github.com/cert-manager/helm-tool" - _ "k8s.io/code-generator/cmd/applyconfiguration-gen" - _ "sigs.k8s.io/controller-tools/cmd/controller-gen" - _ "sigs.k8s.io/kind" + "fmt" + "os" + + "github.com/spf13/cobra" ) + +var CommandRoot = cobra.Command{ + Use: "image-tool", +} + +func main() { + CommandRoot.AddCommand(&CommandAppendLayers) + CommandRoot.AddCommand(&CommandConvertToDockerTar) + CommandRoot.AddCommand(&CommandListDigests) + must("error running command", CommandRoot.Execute()) +} + +func must(msg string, err error) { + if err != nil { + fail(msg+": %w", err) + } +} + +func fail(msg string, a ...any) { + fmt.Fprintf(os.Stderr, msg+"\n", a...) + os.Exit(1) +} diff --git a/make/_shared/oci-publish/00_mod.mk b/make/_shared/oci-publish/00_mod.mk new file mode 100644 index 00000000..f27062ad --- /dev/null +++ b/make/_shared/oci-publish/00_mod.mk @@ -0,0 +1,58 @@ +# Copyright 2023 The cert-manager 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. + +# Push names is equivilent to build_names, additional names can be added for +# pushing images that are not build with the oci-build module +push_names ?= +push_names += $(build_names) + +# Sometimes we need to push to one registry, but pull from another. This allows +# that. +# +# The lines should be in the format a=b +# +# The value on the left is the domain you include in your oci__image_name +# variable, the one on the right is the domain that is actually pushed to. +# +# For example, if we set up a vanity domain for the current quay: +# +# oci_controller_image_name = registry.cert-manager.io/cert-manager-controller` +# image_registry_rewrite += registry.cert-manager.io=quay.io/jetstack +# +# This would push to quay.io/jetstack/cert-manager-controller. +# +# The general idea is oci__image_name contains the final image name, after replication, after vanity domains etc. + +image_registry_rewrite ?= + +# Utilities for extracting the key and value from a foo=bar style line +kv_key = $(word 1,$(subst =, ,$1)) +kv_value = $(word 2,$(subst =, ,$1)) + +# Apply the image_registry_rewrite rules, if no rules match an image then the +# image name is not changed. Any rules that match will be applied. +# +# For example, if there was a rule vanity-domain.com=real-registry.com/foo +# then any references to vanity-domain.com/image would be rewritten to +# real-registry.com/foo/image +image_registry_rewrite_rules_for_image = $(strip $(sort $(foreach rule,$(image_registry_rewrite),$(if $(findstring $(call kv_key,$(rule)),$1),$(rule))))) +apply_image_registry_rewrite_rules_to_image = $(if $(call image_registry_rewrite_rules_for_image,$1),\ + $(foreach rule,$(call image_registry_rewrite_rules_for_image,$1),$(subst $(call kv_key,$(rule)),$(call kv_value,$(rule)),$1)),\ + $1) +apply_image_registry_rewrite_rules = $(foreach image_name,$1,$(call apply_image_registry_rewrite_rules_to_image,$(image_name))) + +# This is a helper function to return the image names for a given build_name. +# It will apply all rewrite rules to the image names +oci_image_names_for = $(call apply_image_registry_rewrite_rules,$(oci_$1_image_name)) +oci_image_tag_for = $(oci_$1_image_tag) \ No newline at end of file diff --git a/make/_shared/oci-publish/01_mod.mk b/make/_shared/oci-publish/01_mod.mk new file mode 100644 index 00000000..348490c9 --- /dev/null +++ b/make/_shared/oci-publish/01_mod.mk @@ -0,0 +1,127 @@ +# Copyright 2023 The cert-manager 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. + +# Utility functions +fatal_if_undefined = $(if $(findstring undefined,$(origin $1)),$(error $1 is not set)) +oci_digest = $(shell head -1 $(oci_digest_path_$1) 2> /dev/null) +sanitize_target = $(subst :,-,$1) +registry_for = $(firstword $(subst /, ,$1)) + +# Utility variables +current_makefile_directory := $(dir $(lastword $(MAKEFILE_LIST))) +image_exists_script := $(current_makefile_directory)/image-exists.sh + +# Validate globals that are required +$(call fatal_if_undefined,bin_dir) +$(call fatal_if_undefined,push_names) + +# Set default config values +RELEASE_DRYRUN ?= false +CRANE_FLAGS ?= # empty by default +COSIGN_FLAGS ?= # empty by default +OCI_SIGN_ON_PUSH ?= true + +# Default variables per push_names entry +# +# $1 - build_name +define default_per_build_variables +release_dryrun_$1 ?= $(RELEASE_DRYRUN) +crane_flags_$1 ?= $(CRANE_FLAGS) +cosign_flags_$1 ?= $(COSIGN_FLAGS) +oci_sign_on_push_$1 ?= $(OCI_SIGN_ON_PUSH) +endef + +$(foreach build_name,$(push_names),$(eval $(call default_per_build_variables,$(build_name)))) + +# Validate variables per push_names entry +# +# $1 - build_name +define check_per_build_variables +$(call fatal_if_undefined,oci_digest_path_$1) +$(call fatal_if_undefined,oci_layout_path_$1) +$(call fatal_if_undefined,oci_$1_image_name) +$(call fatal_if_undefined,oci_$1_image_tag) +endef + +$(foreach build_name,$(push_names),$(eval $(call check_per_build_variables,$(build_name)))) + +# Create variables holding targets +# +# We create the following targets for each $(push_names) +# - oci-build-$(build_name) = build the oci directory +# - oci-load-$(build_name) = load the image into docker using the oci_$(build_name)_image_name_development variable +# - docker-tarball-$(build_name) = build a "docker load" compatible tarball of the image +# - ko-config-$(build_name) = generate "ko" config for a given build +oci_push_targets := $(push_names:%=oci-push-%) +oci_sign_targets := $(push_names:%=oci-sign-%) +oci_maybe_push_targets := $(push_names:%=oci-maybe-push-%) + +# Define push target +# $1 - build_name +# $2 - image_name +define oci_push_target +.PHONY: $(call sanitize_target,oci-push-$2) +$(call sanitize_target,oci-push-$2): oci-build-$1 | $(NEEDS_CRANE) + $$(CRANE) $(crane_flags_$1) push "$(oci_layout_path_$1)" "$2:$(call oci_image_tag_for,$1)" + $(if $(filter true,$(oci_sign_on_push_$1)),$(MAKE) $(call sanitize_target,oci-sign-$2)) + +.PHONY: $(call sanitize_target,oci-maybe-push-$2) +$(call sanitize_target,oci-maybe-push-$2): oci-build-$1 | $(NEEDS_CRANE) + CRANE="$$(CRANE) $(crane_flags_$1)" \ + source $(image_exists_script) $2:$(call oci_image_tag_for,$1); \ + $$(CRANE) $(crane_flags_$1) push "$(oci_layout_path_$1)" "$2:$(call oci_image_tag_for,$1)"; \ + $(if $(filter true,$(oci_sign_on_push_$1)),$(MAKE) $(call sanitize_target,oci-sign-$2)) + +oci-push-$1: $(call sanitize_target,oci-push-$2) +oci-maybe-push-$1: $(call sanitize_target,oci-maybe-push-$2) +endef + +oci_push_target_per_image = $(foreach image_name,$2,$(eval $(call oci_push_target,$1,$(image_name)))) +$(foreach build_name,$(push_names),$(eval $(call oci_push_target_per_image,$(build_name),$(call oci_image_names_for,$(build_name))))) + +.PHONY: $(oci_push_targets) +## Build and push OCI image. +## If the tag already exists, this target will overwrite it. +## If an identical image was already built before, we will add a new tag to it, but we will not sign it again. +## Expected pushed images: +## - :v1.2.3, @sha256:0000001 +## - :v1.2.3.sig, :sha256-0000001.sig +## @category [shared] Publish +$(oci_push_targets): + +.PHONY: $(oci_maybe_push_targets) +## Push image if tag does not already exist in registry. +## @category [shared] Publish +$(oci_maybe_push_targets): + +# Define sign target +# $1 - build_name +# $2 - image_name +define oci_sign_target +.PHONY: $(call sanitize_target,oci-sign-$2) +$(call sanitize_target,oci-sign-$2): $(oci_digest_path_$1) | $(NEEDS_CRANE) $(NEEDS_COSIGN) + $$(CRANE) $(crane_flags_$1) manifest $2:$$(subst :,-,$$(call oci_digest,$1)).sig > /dev/null 2>&1 || \ + $$(COSIGN) sign --yes=true $(cosign_flags_$1) "$2@$$(call oci_digest,$1)" + +oci-sign-$1: $(call sanitize_target,oci-sign-$2) +endef + +oci_sign_target_per_image = $(foreach image_name,$2,$(eval $(call oci_sign_target,$1,$(image_name)))) +$(foreach build_name,$(push_names),$(eval $(call oci_sign_target_per_image,$(build_name),$(call oci_image_names_for,$(build_name))))) + +.PHONY: $(oci_sign_targets) +## Sign an OCI image. +## If a signature already exists, this will not overwrite it. +## @category [shared] Publish +$(oci_sign_targets): \ No newline at end of file diff --git a/make/_shared/oci-publish/image-exists.sh b/make/_shared/oci-publish/image-exists.sh new file mode 100755 index 00000000..9ecbb61a --- /dev/null +++ b/make/_shared/oci-publish/image-exists.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +# Copyright 2022 The cert-manager 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. + +set -o errexit +set -o nounset +set -o pipefail + +# This script checks if a given image exists in the upstream registry, and if it +# does, whether it contains all the expected architectures. + +crane=${CRANE:-} + +FULL_IMAGE=${1:-} + +function print_usage() { + echo "usage: $0 [commands...]" +} + +if [[ -z $FULL_IMAGE ]]; then + print_usage + echo "Missing full-image" + exit 1 +fi + +if [[ -z $crane ]]; then + echo "CRANE environment variable must be set to the path of the crane binary" + exit 1 +fi + +shift 1 + +manifest=$(mktemp) +trap 'rm -f "$manifest"' EXIT SIGINT + +manifest_error=$(mktemp) +trap 'rm -f "$manifest_error"' EXIT SIGINT + +echo "+++ searching for $FULL_IMAGE in upstream registry" + +set +o errexit +$crane manifest "$FULL_IMAGE" > "$manifest" 2> "$manifest_error" +exit_code=$? +set -o errexit + +manifest_error_data=$(cat "$manifest_error") +if [[ $exit_code -eq 0 ]]; then + echo "+++ upstream registry appears to contain $FULL_IMAGE, exiting" + exit 0 + +elif [[ "$manifest_error_data" == *"MANIFEST_UNKNOWN"* ]]; then + echo "+++ upstream registry does not contain $FULL_IMAGE, will build and push" + # fall through to run the commands passed to this script + +else + echo "FATAL: upstream registry returned an unexpected error: $manifest_error_data, exiting" + exit 1 +fi diff --git a/make/_shared/repository-base/01_mod.mk b/make/_shared/repository-base/01_mod.mk new file mode 100644 index 00000000..aa6b7ee2 --- /dev/null +++ b/make/_shared/repository-base/01_mod.mk @@ -0,0 +1,33 @@ +# Copyright 2023 The cert-manager 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. + +base_dir := $(dir $(lastword $(MAKEFILE_LIST)))/base/ +base_dependabot_dir := $(dir $(lastword $(MAKEFILE_LIST)))/base-dependabot/ + +ifdef repository_base_no_dependabot +.PHONY: generate-base +## Generate base files in the repository +## @category [shared] Generate/ Verify +generate-base: + cp -r $(base_dir)/. ./ +else +.PHONY: generate-base +## Generate base files in the repository +## @category [shared] Generate/ Verify +generate-base: + cp -r $(base_dir)/. ./ + cp -r $(base_dependabot_dir)/. ./ +endif + +shared_generate_targets += generate-base diff --git a/make/_shared/repository-base/base-dependabot/.github/dependabot.yaml b/make/_shared/repository-base/base-dependabot/.github/dependabot.yaml new file mode 100644 index 00000000..81b92973 --- /dev/null +++ b/make/_shared/repository-base/base-dependabot/.github/dependabot.yaml @@ -0,0 +1,20 @@ +# THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +# Edit https://github.com/cert-manager/makefile-modules/blob/main/modules/repository-base/base/.github/dependabot.yaml instead. + +# Update Go dependencies and GitHub Actions dependencies daily. +version: 2 +updates: +- package-ecosystem: gomod + directory: / + schedule: + interval: daily + groups: + all: + patterns: ["*"] +- package-ecosystem: github-actions + directory: / + schedule: + interval: daily + groups: + all: + patterns: ["*"] diff --git a/make/_shared/repository-base/base/.github/workflows/make-self-upgrade.yaml b/make/_shared/repository-base/base/.github/workflows/make-self-upgrade.yaml new file mode 100644 index 00000000..93beedff --- /dev/null +++ b/make/_shared/repository-base/base/.github/workflows/make-self-upgrade.yaml @@ -0,0 +1,90 @@ +# THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +# Edit https://github.com/cert-manager/makefile-modules/blob/main/modules/repository-base/base/.github/workflows/make-self-upgrade.yaml instead. + +name: make-self-upgrade +concurrency: make-self-upgrade +on: + workflow_dispatch: {} + schedule: + - cron: '0 0 * * *' + +jobs: + self_upgrade: + runs-on: ubuntu-latest + + permissions: + contents: write + pull-requests: write + + env: + SOURCE_BRANCH: "${{ github.ref_name }}" + SELF_UPGRADE_BRANCH: "self-upgrade-${{ github.ref_name }}" + + steps: + - name: Fail if branch is not head of branch. + if: ${{ !startsWith(github.ref, 'refs/heads/') && env.SOURCE_BRANCH != '' && env.SELF_UPGRADE_BRANCH != '' }} + run: | + echo "This workflow should not be run on a non-branch-head." + exit 1 + + - uses: actions/checkout@v4 + + - id: go-version + run: | + make print-go-version >> "$GITHUB_OUTPUT" + + - uses: actions/setup-go@v5 + with: + go-version: ${{ steps.go-version.outputs.result }} + + - run: | + git checkout -B "$SELF_UPGRADE_BRANCH" + + - run: | + make -j upgrade-klone + make -j generate + + - id: is-up-to-date + shell: bash + run: | + git_status=$(git status -s) + is_up_to_date="true" + if [ -n "$git_status" ]; then + is_up_to_date="false" + echo "The following changes will be committed:" + echo "$git_status" + fi + echo "result=$is_up_to_date" >> "$GITHUB_OUTPUT" + + - if: ${{ steps.is-up-to-date.outputs.result != 'true' }} + run: | + git config --global user.name "cert-manager-bot" + git config --global user.email "cert-manager-bot@users.noreply.github.com" + git add -A && git commit -m "BOT: run 'make upgrade-klone' and 'make generate'" --signoff + git push -f origin "$SELF_UPGRADE_BRANCH" + + - if: ${{ steps.is-up-to-date.outputs.result != 'true' }} + uses: actions/github-script@v7 + with: + script: | + const { repo, owner } = context.repo; + const pulls = await github.rest.pulls.list({ + owner: owner, + repo: repo, + head: owner + ':' + process.env.SELF_UPGRADE_BRANCH, + base: process.env.SOURCE_BRANCH, + state: 'open', + }); + + if (pulls.data.length < 1) { + await github.rest.pulls.create({ + title: '[CI] Merge ' + process.env.SELF_UPGRADE_BRANCH + ' into ' + process.env.SOURCE_BRANCH, + owner: owner, + repo: repo, + head: process.env.SELF_UPGRADE_BRANCH, + base: process.env.SOURCE_BRANCH, + body: [ + 'This PR is auto-generated to bump the Makefile modules.', + ].join('\n'), + }); + } diff --git a/make/_shared/repository-base/base/LICENSE b/make/_shared/repository-base/base/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/make/_shared/repository-base/base/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/make/_shared/repository-base/base/Makefile b/make/_shared/repository-base/base/Makefile new file mode 100644 index 00000000..6c5aa126 --- /dev/null +++ b/make/_shared/repository-base/base/Makefile @@ -0,0 +1,116 @@ +# Copyright 2023 The cert-manager 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. + +# THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +# Edit https://github.com/cert-manager/makefile-modules/blob/main/modules/repository-base/base/Makefile instead. + +# NOTE FOR DEVELOPERS: "How do the Makefiles work and how can I extend them?" +# +# Shared Makefile logic lives in the make/_shared/ directory. The source of truth for these files +# lies outside of this repository, eg. in the cert-manager/makefile-modules repository. +# +# Logic specific to this repository must be defined in the make/00_mod.mk and make/02_mod.mk files: +# - The make/00_mod.mk file is included first and contains variable definitions needed by +# the shared Makefile logic. +# - The make/02_mod.mk file is included later, it can make use of most of the shared targets +# defined in the make/_shared/ directory (all targets defined in 00_mod.mk and 01_mod.mk). +# This file should be used to define targets specific to this repository. + +################################## + +# Some modules build their dependencies from variables, we want these to be +# evalutated at the last possible moment. For this we use second expansion to +# re-evaluate the generate and verify targets a second time. +# +# See https://www.gnu.org/software/make/manual/html_node/Secondary-Expansion.html +.SECONDEXPANSION: + +# For details on some of these "prelude" settings, see: +# https://clarkgrubb.com/makefile-style-guide +MAKEFLAGS += --warn-undefined-variables --no-builtin-rules +SHELL := /usr/bin/env bash +.SHELLFLAGS := -uo pipefail -c +.DEFAULT_GOAL := help +.DELETE_ON_ERROR: +.SUFFIXES: +FORCE: + +noop: # do nothing + +# Set empty value for MAKECMDGOALS to prevent the "warning: undefined variable 'MAKECMDGOALS'" +# warning from happening when running make without arguments +MAKECMDGOALS ?= + +################################## +# Host OS and architecture setup # +################################## + +# The reason we don't use "go env GOOS" or "go env GOARCH" is that the "go" +# binary may not be available in the PATH yet when the Makefiles are +# evaluated. HOST_OS and HOST_ARCH only support Linux, *BSD and macOS (M1 +# and Intel). +host_os := $(shell uname -s | tr A-Z a-z) +host_arch := $(shell uname -m) +HOST_OS ?= $(host_os) +HOST_ARCH ?= $(host_arch) + +ifeq (x86_64, $(HOST_ARCH)) + HOST_ARCH = amd64 +else ifeq (aarch64, $(HOST_ARCH)) + # linux reports the arm64 arch as aarch64 + HOST_ARCH = arm64 +endif + +################################## +# Git and versioning information # +################################## + +git_version := $(shell git describe --tags --always --match='v*' --abbrev=14 --dirty) +VERSION ?= $(git_version) +IS_PRERELEASE := $(shell git describe --tags --always --match='v*' --abbrev=0 | grep -q '-' && echo true || echo false) +GITCOMMIT := $(shell git rev-parse HEAD) +GITEPOCH := $(shell git show -s --format=%ct HEAD) + +################################## +# Global variables and dirs # +################################## + +bin_dir := _bin + +# The ARTIFACTS environment variable is set by the CI system to a directory +# where artifacts should be placed. These artifacts are then uploaded to a +# storage bucket by the CI system (https://docs.prow.k8s.io/docs/components/pod-utilities/). +# An example of such an artifact is a jUnit XML file containing test results. +# If the ARTIFACTS environment variable is not set, we default to a local +# directory in the _bin directory. +ARTIFACTS ?= $(bin_dir)/artifacts + +$(bin_dir) $(ARTIFACTS) $(bin_dir)/scratch: + mkdir -p $@ + +.PHONY: clean +## Clean all temporary files +## @category [shared] Tools +clean: + rm -rf $(bin_dir) + +################################## +# Include all the Makefiles # +################################## + +-include make/00_mod.mk +-include make/_shared/*/00_mod.mk +-include make/_shared/*/01_mod.mk +-include make/02_mod.mk +-include make/_shared/*/02_mod.mk diff --git a/make/_shared/repository-base/base/OWNERS_ALIASES b/make/_shared/repository-base/base/OWNERS_ALIASES new file mode 100644 index 00000000..10d1279a --- /dev/null +++ b/make/_shared/repository-base/base/OWNERS_ALIASES @@ -0,0 +1,14 @@ +# THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +# Edit https://github.com/cert-manager/makefile-modules/blob/main/modules/repository-base/base/OWNERS_ALIASES instead. + +aliases: + cm-maintainers: + - munnerz + - joshvanl + - wallrj + - jakexks + - maelvls + - irbekrm + - sgtcodfish + - inteon + - thatsmrtalbot diff --git a/make/_shared/tools/00_mod.mk b/make/_shared/tools/00_mod.mk new file mode 100644 index 00000000..d162f22a --- /dev/null +++ b/make/_shared/tools/00_mod.mk @@ -0,0 +1,639 @@ +# Copyright 2023 The cert-manager 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. + +ifndef bin_dir +$(error bin_dir is not set) +endif + +########################################## + +export DOWNLOAD_DIR ?= $(CURDIR)/$(bin_dir)/downloaded +export GOVENDOR_DIR ?= $(CURDIR)/$(bin_dir)/go_vendor + +$(bin_dir)/scratch/image $(bin_dir)/tools $(DOWNLOAD_DIR)/tools: + @mkdir -p $@ + +checkhash_script := $(dir $(lastword $(MAKEFILE_LIST)))/util/checkhash.sh +lock_script := $(dir $(lastword $(MAKEFILE_LIST)))/util/lock.sh + +# $outfile is a variable in the lock script +outfile := $$outfile + +for_each_kv = $(foreach item,$2,$(eval $(call $1,$(word 1,$(subst =, ,$(item))),$(word 2,$(subst =, ,$(item)))))) + +# To make sure we use the right version of each tool, we put symlink in +# $(bin_dir)/tools, and the actual binaries are in $(bin_dir)/downloaded. When bumping +# the version of the tools, this symlink gets updated. + +# Let's have $(bin_dir)/tools in front of the PATH so that we don't inavertedly +# pick up the wrong binary somewhere. Watch out, $(shell echo $$PATH) will +# still print the original PATH, since GNU make does not honor exported +# variables: https://stackoverflow.com/questions/54726457 +export PATH := $(CURDIR)/$(bin_dir)/tools:$(PATH) + +CTR=docker + +tools := +# https://github.com/helm/helm/releases +tools += helm=v3.14.4 +# https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl +tools += kubectl=v1.30.0 +# https://github.com/kubernetes-sigs/kind/releases +tools += kind=v0.22.0 +# https://www.vaultproject.io/downloads +tools += vault=1.16.2 +# https://github.com/Azure/azure-workload-identity/releases +tools += azwi=v1.2.2 +# https://github.com/kyverno/kyverno/releases +tools += kyverno=v1.12.1 +# https://github.com/mikefarah/yq/releases +tools += yq=v4.43.1 +# https://github.com/ko-build/ko/releases +tools += ko=0.15.2 +# https://github.com/protocolbuffers/protobuf/releases +tools += protoc=26.1 +# https://github.com/aquasecurity/trivy/releases +tools += trivy=v0.50.4 +# https://github.com/vmware-tanzu/carvel-ytt/releases +tools += ytt=v0.49.0 +# https://github.com/rclone/rclone/releases +tools += rclone=v1.66.0 + +### go packages +# https://pkg.go.dev/sigs.k8s.io/controller-tools/cmd/controller-gen?tab=versions +tools += controller-gen=v0.14.0 +# https://pkg.go.dev/golang.org/x/tools/cmd/goimports?tab=versions +tools += goimports=v0.20.0 +# https://pkg.go.dev/github.com/google/go-licenses/licenses?tab=versions +tools += go-licenses=706b9c60edd424a8b6d253fe10dfb7b8e942d4a5 +# https://pkg.go.dev/gotest.tools/gotestsum?tab=versions +tools += gotestsum=v1.11.0 +# https://pkg.go.dev/sigs.k8s.io/kustomize/kustomize/v4?tab=versions +tools += kustomize=v4.5.7 +# https://pkg.go.dev/github.com/itchyny/gojq?tab=versions +tools += gojq=v0.12.15 +# https://pkg.go.dev/github.com/google/go-containerregistry/pkg/crane?tab=versions +tools += crane=v0.19.1 +# https://pkg.go.dev/google.golang.org/protobuf/cmd/protoc-gen-go?tab=versions +tools += protoc-gen-go=v1.34.0 +# https://pkg.go.dev/github.com/norwoodj/helm-docs/cmd/helm-docs?tab=versions +tools += helm-docs=v1.13.1 +# https://pkg.go.dev/github.com/sigstore/cosign/v2/cmd/cosign?tab=versions +tools += cosign=v2.2.4 +# https://pkg.go.dev/github.com/cert-manager/boilersuite?tab=versions +tools += boilersuite=v0.1.0 +# https://pkg.go.dev/github.com/princjef/gomarkdoc/cmd/gomarkdoc?tab=versions +tools += gomarkdoc=v1.1.0 +# https://pkg.go.dev/oras.land/oras/cmd/oras?tab=versions +tools += oras=v1.1.0 +# https://pkg.go.dev/github.com/onsi/ginkgo/v2/ginkgo?tab=versions +# The gingko version should be kept in sync with the version used in code. +# If there is no go.mod file (which is only the case for the makefile-modules +# repo), then we default to a version that we know exists. We have to do this +# because otherwise the awk failure renders the whole makefile unusable. +detected_ginkgo_version := $(shell [[ -f go.mod ]] && awk '/ginkgo\/v2/ {print $$2}' go.mod || echo "v2.13.2") +tools += ginkgo=$(detected_ginkgo_version) +# https://pkg.go.dev/github.com/cert-manager/klone?tab=versions +tools += klone=v0.0.5 +# https://pkg.go.dev/github.com/goreleaser/goreleaser?tab=versions +tools += goreleaser=v1.25.1 +# https://pkg.go.dev/github.com/anchore/syft/cmd/syft?tab=versions +tools += syft=v0.100.0 +# https://github.com/cert-manager/helm-tool +tools += helm-tool=v0.4.2 +# https://github.com/cert-manager/cmctl +tools += cmctl=v2.0.0 +# https://pkg.go.dev/github.com/cert-manager/release/cmd/cmrel?tab=versions +tools += cmrel=e4c3a4dc07df5c7c0379d334c5bb00e172462551 +# https://github.com/golangci/golangci-lint/releases +tools += golangci-lint=v1.57.2 +# https://pkg.go.dev/golang.org/x/vuln?tab=versions +tools += govulncheck=v1.1.0 +# https://pkg.go.dev/github.com/operator-framework/operator-sdk/cmd/operator-sdk?tab=versions +tools += operator-sdk=v1.34.1 +# https://pkg.go.dev/github.com/cli/cli/v2?tab=versions +tools += gh=v2.49.0 +# https:///github.com/redhat-openshift-ecosystem/openshift-preflight/releases +tools += preflight=1.9.2 +# https://github.com/daixiang0/gci/releases/ +tools += gci=v0.13.4 + +# https://pkg.go.dev/k8s.io/code-generator/cmd?tab=versions +K8S_CODEGEN_VERSION := v0.29.3 +tools += client-gen=$(K8S_CODEGEN_VERSION) +tools += deepcopy-gen=$(K8S_CODEGEN_VERSION) +tools += informer-gen=$(K8S_CODEGEN_VERSION) +tools += lister-gen=$(K8S_CODEGEN_VERSION) +tools += applyconfiguration-gen=$(K8S_CODEGEN_VERSION) +tools += openapi-gen=$(K8S_CODEGEN_VERSION) +tools += defaulter-gen=$(K8S_CODEGEN_VERSION) +tools += conversion-gen=$(K8S_CODEGEN_VERSION) + +# https://github.com/kubernetes-sigs/kubebuilder/blob/tools-releases/build/cloudbuild_tools.yaml +KUBEBUILDER_ASSETS_VERSION := 1.30.0 +tools += etcd=$(KUBEBUILDER_ASSETS_VERSION) +tools += kube-apiserver=$(KUBEBUILDER_ASSETS_VERSION) + +# Additional tools can be defined to reuse the tooling in this file +ADDITIONAL_TOOLS ?= +tools += $(ADDITIONAL_TOOLS) + +# https://go.dev/dl/ +VENDORED_GO_VERSION := 1.22.3 + +# Print the go version which can be used in GH actions +.PHONY: print-go-version +print-go-version: + @echo result=$(VENDORED_GO_VERSION) + +# When switching branches which use different versions of the tools, we +# need a way to re-trigger the symlinking from $(bin_dir)/downloaded to $(bin_dir)/tools. +$(bin_dir)/scratch/%_VERSION: FORCE | $(bin_dir)/scratch + @test "$($*_VERSION)" == "$(shell cat $@ 2>/dev/null)" || echo $($*_VERSION) > $@ + +# --silent = don't print output like progress meters +# --show-error = but do print errors when they happen +# --fail = exit with a nonzero error code without the response from the server when there's an HTTP error +# --location = follow redirects from the server +# --retry = the number of times to retry a failed attempt to connect +# --retry-connrefused = retry even if the initial connection was refused +CURL := curl --silent --show-error --fail --location --retry 10 --retry-connrefused + +# LN is expected to be an atomic action, meaning that two Make processes +# can run the "link $(DOWNLOAD_DIR)/tools/xxx@$(XXX_VERSION)_$(HOST_OS)_$(HOST_ARCH) +# to $(bin_dir)/tools/xxx" operation simulatiously without issues (both +# will perform the action and the second time the link will be overwritten). +LN := ln -fs + +upper_map := a:A b:B c:C d:D e:E f:F g:G h:H i:I j:J k:K l:L m:M n:N o:O p:P q:Q r:R s:S t:T u:U v:V w:W x:X y:Y z:Z +uc = $(strip \ + $(eval __upper := $1) \ + $(foreach p,$(upper_map), \ + $(eval __upper := $(subst $(word 1,$(subst :, ,$p)),$(word 2,$(subst :, ,$p)),$(__upper))) \ + ) \ + )$(__upper) + +tool_names := + +# for each item `xxx` in the tools variable: +# - a $(XXX_VERSION) variable is generated +# -> this variable contains the version of the tool +# - a $(NEEDS_XXX) variable is generated +# -> this variable contains the target name for the tool, +# which is the relative path of the binary, this target +# should be used when adding the tool as a dependency to +# your target, you can't use $(XXX) as a dependency because +# make does not support an absolute path as a dependency +# - a $(XXX) variable is generated +# -> this variable contains the absolute path of the binary, +# the absolute path should be used when executing the binary +# in targets or in scripts, because it is agnostic to the +# working directory +# - an unversioned target $(bin_dir)/tools/xxx is generated that +# creates a link to the corresponding versioned target: +# $(DOWNLOAD_DIR)/tools/xxx@$(XXX_VERSION)_$(HOST_OS)_$(HOST_ARCH) +define tool_defs +tool_names += $1 + +$(call uc,$1)_VERSION ?= $2 +NEEDS_$(call uc,$1) := $$(bin_dir)/tools/$1 +$(call uc,$1) := $$(CURDIR)/$$(bin_dir)/tools/$1 + +$$(bin_dir)/tools/$1: $$(bin_dir)/scratch/$(call uc,$1)_VERSION | $$(DOWNLOAD_DIR)/tools/$1@$$($(call uc,$1)_VERSION)_$$(HOST_OS)_$$(HOST_ARCH) $$(bin_dir)/tools + @cd $$(dir $$@) && $$(LN) $$(patsubst $$(bin_dir)/%,../%,$$(word 1,$$|)) $$(notdir $$@) + @touch $$@ # making sure the target of the symlink is newer than *_VERSION +endef + +$(foreach tool,$(tools),$(eval $(call tool_defs,$(word 1,$(subst =, ,$(tool))),$(word 2,$(subst =, ,$(tool)))))) + +tools_paths := $(tool_names:%=$(bin_dir)/tools/%) + +###### +# Go # +###### + +# $(NEEDS_GO) is a target that is set as an order-only prerequisite in +# any target that calls $(GO), e.g.: +# +# $(bin_dir)/tools/crane: $(NEEDS_GO) +# $(GO) build -o $(bin_dir)/tools/crane +# +# $(NEEDS_GO) is empty most of the time, except when running "make vendor-go" +# or when "make vendor-go" was previously run, in which case $(NEEDS_GO) is set +# to $(bin_dir)/tools/go, since $(bin_dir)/tools/go is a prerequisite of +# any target depending on Go when "make vendor-go" was run. + +detected_vendoring := $(findstring vendor-go,$(MAKECMDGOALS))$(shell [ -f $(bin_dir)/tools/go ] && echo yes) +export VENDOR_GO ?= $(detected_vendoring) + +ifeq ($(VENDOR_GO),) +GO := go +NEEDS_GO := # +else +export GOROOT := $(CURDIR)/$(bin_dir)/tools/goroot +export PATH := $(CURDIR)/$(bin_dir)/tools/goroot/bin:$(PATH) +GO := $(CURDIR)/$(bin_dir)/tools/go +NEEDS_GO := $(bin_dir)/tools/go +MAKE := $(MAKE) vendor-go +endif + +.PHONY: vendor-go +## By default, this Makefile uses the system's Go. You can use a "vendored" +## version of Go that will get downloaded by running this command once. To +## disable vendoring, run "make unvendor-go". When vendoring is enabled, +## you will want to set the following: +## +## export PATH="$PWD/$(bin_dir)/tools:$PATH" +## export GOROOT="$PWD/$(bin_dir)/tools/goroot" +## @category [shared] Tools +vendor-go: $(bin_dir)/tools/go + +.PHONY: unvendor-go +unvendor-go: $(bin_dir)/tools/go + rm -rf $(bin_dir)/tools/go $(bin_dir)/tools/goroot + +.PHONY: which-go +## Print the version and path of go which will be used for building and +## testing in Makefile commands. Vendored go will have a path in ./bin +## @category [shared] Tools +which-go: | $(NEEDS_GO) + @$(GO) version + @echo "go binary used for above version information: $(GO)" + +$(bin_dir)/tools/go: $(bin_dir)/scratch/VENDORED_GO_VERSION | $(bin_dir)/tools/goroot $(bin_dir)/tools + @cd $(dir $@) && $(LN) ./goroot/bin/go $(notdir $@) + @touch $@ # making sure the target of the symlink is newer than *_VERSION + +# The "_" in "_bin" prevents "go mod tidy" from trying to tidy the vendored goroot. +$(bin_dir)/tools/goroot: $(bin_dir)/scratch/VENDORED_GO_VERSION | $(GOVENDOR_DIR)/go@$(VENDORED_GO_VERSION)_$(HOST_OS)_$(HOST_ARCH)/goroot $(bin_dir)/tools + @cd $(dir $@) && $(LN) $(patsubst $(bin_dir)/%,../%,$(word 1,$|)) $(notdir $@) + @touch $@ # making sure the target of the symlink is newer than *_VERSION + +# Extract the tar to the $(GOVENDOR_DIR) directory, this directory is not cached across CI runs. +$(GOVENDOR_DIR)/go@$(VENDORED_GO_VERSION)_$(HOST_OS)_$(HOST_ARCH)/goroot: | $(DOWNLOAD_DIR)/tools/go@$(VENDORED_GO_VERSION)_$(HOST_OS)_$(HOST_ARCH).tar.gz + @source $(lock_script) $@; \ + mkdir -p $(outfile).dir; \ + tar xzf $| -C $(outfile).dir; \ + mv $(outfile).dir/go $(outfile); \ + rm -rf $(outfile).dir + +################### +# go dependencies # +################### + +go_dependencies := +go_dependencies += ginkgo=github.com/onsi/ginkgo/v2/ginkgo +go_dependencies += controller-gen=sigs.k8s.io/controller-tools/cmd/controller-gen +go_dependencies += goimports=golang.org/x/tools/cmd/goimports +go_dependencies += go-licenses=github.com/google/go-licenses +go_dependencies += gotestsum=gotest.tools/gotestsum +go_dependencies += kustomize=sigs.k8s.io/kustomize/kustomize/v4 +go_dependencies += gojq=github.com/itchyny/gojq/cmd/gojq +go_dependencies += crane=github.com/google/go-containerregistry/cmd/crane +go_dependencies += protoc-gen-go=google.golang.org/protobuf/cmd/protoc-gen-go +go_dependencies += helm-docs=github.com/norwoodj/helm-docs/cmd/helm-docs +go_dependencies += cosign=github.com/sigstore/cosign/v2/cmd/cosign +go_dependencies += boilersuite=github.com/cert-manager/boilersuite +go_dependencies += gomarkdoc=github.com/princjef/gomarkdoc/cmd/gomarkdoc +go_dependencies += oras=oras.land/oras/cmd/oras +go_dependencies += klone=github.com/cert-manager/klone +go_dependencies += goreleaser=github.com/goreleaser/goreleaser +go_dependencies += syft=github.com/anchore/syft/cmd/syft +go_dependencies += client-gen=k8s.io/code-generator/cmd/client-gen +go_dependencies += deepcopy-gen=k8s.io/code-generator/cmd/deepcopy-gen +go_dependencies += informer-gen=k8s.io/code-generator/cmd/informer-gen +go_dependencies += lister-gen=k8s.io/code-generator/cmd/lister-gen +go_dependencies += applyconfiguration-gen=k8s.io/code-generator/cmd/applyconfiguration-gen +go_dependencies += openapi-gen=k8s.io/code-generator/cmd/openapi-gen +go_dependencies += defaulter-gen=k8s.io/code-generator/cmd/defaulter-gen +go_dependencies += conversion-gen=k8s.io/code-generator/cmd/conversion-gen +go_dependencies += helm-tool=github.com/cert-manager/helm-tool +go_dependencies += cmctl=github.com/cert-manager/cmctl/v2 +go_dependencies += cmrel=github.com/cert-manager/release/cmd/cmrel +go_dependencies += golangci-lint=github.com/golangci/golangci-lint/cmd/golangci-lint +go_dependencies += govulncheck=golang.org/x/vuln/cmd/govulncheck +go_dependencies += operator-sdk=github.com/operator-framework/operator-sdk/cmd/operator-sdk +go_dependencies += gh=github.com/cli/cli/v2/cmd/gh +go_dependencies += gci=github.com/daixiang0/gci + +################# +# go build tags # +################# + +go_tags := + +# Additional Go dependencies can be defined to re-use the tooling in this file +ADDITIONAL_GO_DEPENDENCIES ?= +ADDITIONAL_GO_TAGS ?= +go_dependencies += $(ADDITIONAL_GO_DEPENDENCIES) +go_tags += $(ADDITIONAL_GO_TAGS) + +go_tags_init = go_tags_$1 := +$(call for_each_kv,go_tags_init,$(go_dependencies)) + +go_tags_defs = go_tags_$1 += $2 +$(call for_each_kv,go_tags_defs,$(go_tags)) + +define go_dependency +$$(DOWNLOAD_DIR)/tools/$1@$($(call uc,$1)_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $$(NEEDS_GO) $$(DOWNLOAD_DIR)/tools + @source $$(lock_script) $$@; \ + mkdir -p $$(outfile).dir; \ + GOWORK=off GOBIN=$$(outfile).dir $$(GO) install --tags "$(strip $(go_tags_$1))" $2@$($(call uc,$1)_VERSION); \ + mv $$(outfile).dir/$1 $$(outfile); \ + rm -rf $$(outfile).dir +endef +$(call for_each_kv,go_dependency,$(go_dependencies)) + +################## +# File downloads # +################## + +go_linux_amd64_SHA256SUM=5901c52b7a78002aeff14a21f93e0f064f74ce1360fce51c6ee68cd471216a17 +go_linux_arm64_SHA256SUM=36e720b2d564980c162a48c7e97da2e407dfcc4239e1e58d98082dfa2486a0c1 +go_darwin_amd64_SHA256SUM=33e7f63077b1c5bce4f1ecadd4d990cf229667c40bfb00686990c950911b7ab7 +go_darwin_arm64_SHA256SUM=660298be38648723e783ba0398e90431de1cb288c637880cdb124f39bd977f0d + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/go@$(VENDORED_GO_VERSION)_$(HOST_OS)_$(HOST_ARCH).tar.gz +$(DOWNLOAD_DIR)/tools/go@$(VENDORED_GO_VERSION)_$(HOST_OS)_$(HOST_ARCH).tar.gz: | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + $(CURL) https://go.dev/dl/go$(VENDORED_GO_VERSION).$(HOST_OS)-$(HOST_ARCH).tar.gz -o $(outfile); \ + $(checkhash_script) $(outfile) $(go_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM) + +helm_linux_amd64_SHA256SUM=a5844ef2c38ef6ddf3b5a8f7d91e7e0e8ebc39a38bb3fc8013d629c1ef29c259 +helm_linux_arm64_SHA256SUM=113ccc53b7c57c2aba0cd0aa560b5500841b18b5210d78641acfddc53dac8ab2 +helm_darwin_amd64_SHA256SUM=73434aeac36ad068ce2e5582b8851a286dc628eae16494a26e2ad0b24a7199f9 +helm_darwin_arm64_SHA256SUM=61e9c5455f06b2ad0a1280975bf65892e707adc19d766b0cf4e9006e3b7b4b6c + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/helm@$(HELM_VERSION)_$(HOST_OS)_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/helm@$(HELM_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + $(CURL) https://get.helm.sh/helm-$(HELM_VERSION)-$(HOST_OS)-$(HOST_ARCH).tar.gz -o $(outfile).tar.gz; \ + $(checkhash_script) $(outfile).tar.gz $(helm_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM); \ + tar xfO $(outfile).tar.gz $(HOST_OS)-$(HOST_ARCH)/helm > $(outfile); \ + chmod +x $(outfile); \ + rm -f $(outfile).tar.gz + +kubectl_linux_amd64_SHA256SUM=7c3807c0f5c1b30110a2ff1e55da1d112a6d0096201f1beb81b269f582b5d1c5 +kubectl_linux_arm64_SHA256SUM=669af0cf520757298ea60a8b6eb6b719ba443a9c7d35f36d3fb2fd7513e8c7d2 +kubectl_darwin_amd64_SHA256SUM=bcfa57d020b8d07d0ea77235ce8012c2c28fefdfd7cb9738f33674a7b16cef08 +kubectl_darwin_arm64_SHA256SUM=45cfa208151320153742062824398f22bb6bfb5a142bf6238476d55dacbd1bdd + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/kubectl@$(KUBECTL_VERSION)_$(HOST_OS)_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/kubectl@$(KUBECTL_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + $(CURL) https://dl.k8s.io/release/$(KUBECTL_VERSION)/bin/$(HOST_OS)/$(HOST_ARCH)/kubectl -o $(outfile); \ + $(checkhash_script) $(outfile) $(kubectl_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM); \ + chmod +x $(outfile) + +kind_linux_amd64_SHA256SUM=e4264d7ee07ca642fe52818d7c0ed188b193c214889dd055c929dbcb968d1f62 +kind_linux_arm64_SHA256SUM=4431805115da3b54290e3e976fe2db9a7e703f116177aace6735dfa1d8a4f3fe +kind_darwin_amd64_SHA256SUM=28a9f7ad7fd77922c639e21c034d0f989b33402693f4f842099cd9185b144d20 +kind_darwin_arm64_SHA256SUM=c8dd3b287965150ae4db668294edc48229116e95d94620c306d8fae932ee633f + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/kind@$(KIND_VERSION)_$(HOST_OS)_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/kind@$(KIND_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + $(CURL) https://github.com/kubernetes-sigs/kind/releases/download/$(KIND_VERSION)/kind-$(HOST_OS)-$(HOST_ARCH) -o $(outfile); \ + $(checkhash_script) $(outfile) $(kind_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM); \ + chmod +x $(outfile) + +vault_linux_amd64_SHA256SUM=688ce462b70cb674f84fddb731f75bb710db5ad9e4e5a17659e90e1283a8b4b7 +vault_linux_arm64_SHA256SUM=d5bd42227d295b1dcc4a5889c37e6a8ca945ece4795819718eaf54db87aa6d4f +vault_darwin_amd64_SHA256SUM=e4886d22273dedc579dc2382e114e7be29341049a48592f8f7be8a0020310731 +vault_darwin_arm64_SHA256SUM=ca59c85e7e3d67e25b6bfa505f7e7717b418452e8bfcd602a2a717bc06d5b1ee + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/vault@$(VAULT_VERSION)_$(HOST_OS)_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/vault@$(VAULT_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + $(CURL) https://releases.hashicorp.com/vault/$(VAULT_VERSION)/vault_$(VAULT_VERSION)_$(HOST_OS)_$(HOST_ARCH).zip -o $(outfile).zip; \ + $(checkhash_script) $(outfile).zip $(vault_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM); \ + unzip -qq -c $(outfile).zip > $(outfile); \ + chmod +x $(outfile); \ + rm -f $(outfile).zip + +azwi_linux_amd64_SHA256SUM=d33aaedbcbcc0ef61d845b3704ab336deaafc192c854e887896e163b99097871 +azwi_linux_arm64_SHA256SUM=7c4b55ef83e62f4b597885e66fbbdf0720cf0e2be3f1a16212f9b41d4b61b454 +azwi_darwin_amd64_SHA256SUM=47a9e99a7e02e531967d1c9a8abf12e73134f88ce3363007f411ba9b83497fd0 +azwi_darwin_arm64_SHA256SUM=19c5cf9fe4e1a7394bc01456d5e314fd898162d2d360c585fc72e46dae930659 + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/azwi@$(AZWI_VERSION)_$(HOST_OS)_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/azwi@$(AZWI_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + $(CURL) https://github.com/Azure/azure-workload-identity/releases/download/$(AZWI_VERSION)/azwi-$(AZWI_VERSION)-$(HOST_OS)-$(HOST_ARCH).tar.gz -o $(outfile).tar.gz; \ + $(checkhash_script) $(outfile).tar.gz $(azwi_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM); \ + tar xfO $(outfile).tar.gz azwi > $(outfile) && chmod 775 $(outfile); \ + rm -f $(outfile).tar.gz + +kubebuilder_tools_linux_amd64_SHA256SUM=d51dae845397b7548444157903f2d573493afb6f90ce9417c0f5c61d4b1f908d +kubebuilder_tools_linux_arm64_SHA256SUM=83123010f603390ee0f417ad1cf2a715f5bff335c5841dcd4221764e52732336 +kubebuilder_tools_darwin_amd64_SHA256SUM=46f5a680f28b6db9fdaaab4659dee68a1f2e04a0d9a39f9b0176562a9e95167b +kubebuilder_tools_darwin_arm64_SHA256SUM=ce37b6fcd7678d78a610da1ae5e8e68777025b2bf046558820f967fe7a8f0dfd + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/kubebuilder_tools_$(KUBEBUILDER_ASSETS_VERSION)_$(HOST_OS)_$(HOST_ARCH).tar.gz +$(DOWNLOAD_DIR)/tools/kubebuilder_tools_$(KUBEBUILDER_ASSETS_VERSION)_$(HOST_OS)_$(HOST_ARCH).tar.gz: | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + $(CURL) https://storage.googleapis.com/kubebuilder-tools/kubebuilder-tools-$(KUBEBUILDER_ASSETS_VERSION)-$(HOST_OS)-$(HOST_ARCH).tar.gz -o $(outfile); \ + $(checkhash_script) $(outfile) $(kubebuilder_tools_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM) + +$(DOWNLOAD_DIR)/tools/etcd@$(KUBEBUILDER_ASSETS_VERSION)_$(HOST_OS)_$(HOST_ARCH): $(DOWNLOAD_DIR)/tools/kubebuilder_tools_$(KUBEBUILDER_ASSETS_VERSION)_$(HOST_OS)_$(HOST_ARCH).tar.gz | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + tar xfO $< kubebuilder/bin/etcd > $(outfile) && chmod 775 $(outfile) + +$(DOWNLOAD_DIR)/tools/kube-apiserver@$(KUBEBUILDER_ASSETS_VERSION)_$(HOST_OS)_$(HOST_ARCH): $(DOWNLOAD_DIR)/tools/kubebuilder_tools_$(KUBEBUILDER_ASSETS_VERSION)_$(HOST_OS)_$(HOST_ARCH).tar.gz | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + tar xfO $< kubebuilder/bin/kube-apiserver > $(outfile) && chmod 775 $(outfile) + +kyverno_linux_amd64_SHA256SUM=a5f6e9070c17acc47168c8ce4db78e45258376551b8bf68ad2d5ed27454cf666 +kyverno_linux_arm64_SHA256SUM=007e828d622e73614365f5f7e8e107e36ae686e97e8982b1eeb53511fb2363c3 +kyverno_darwin_amd64_SHA256SUM=20786eebf45238e8b4a35f4146c3f8dfea35968cf8ef6ca6d6727559f5c0156e +kyverno_darwin_arm64_SHA256SUM=3a454fb0b2bfbca6225d46ff4cc0b702fd4a63e978718c50225472b9631a8015 + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/kyverno@$(KYVERNO_VERSION)_$(HOST_OS)_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/kyverno@$(KYVERNO_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + $(eval ARCH := $(subst amd64,x86_64,$(HOST_ARCH))) + + @source $(lock_script) $@; \ + $(CURL) https://github.com/kyverno/kyverno/releases/download/$(KYVERNO_VERSION)/kyverno-cli_$(KYVERNO_VERSION)_$(HOST_OS)_$(ARCH).tar.gz -o $(outfile).tar.gz; \ + $(checkhash_script) $(outfile).tar.gz $(kyverno_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM); \ + tar xfO $(outfile).tar.gz kyverno > $(outfile); \ + chmod +x $(outfile); \ + rm -f $(outfile).tar.gz + +yq_linux_amd64_SHA256SUM=cfbbb9ba72c9402ef4ab9d8f843439693dfb380927921740e51706d90869c7e1 +yq_linux_arm64_SHA256SUM=a8186efb079673293289f8c31ee252b0d533c7bb8b1ada6a778ddd5ec0f325b6 +yq_darwin_amd64_SHA256SUM=fdc42b132ac460037f4f0f48caea82138772c651d91cfbb735210075ddfdbaed +yq_darwin_arm64_SHA256SUM=9f1063d910698834cb9176593aa288471898031929138d226c2c2de9f262f8e5 + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/yq@$(YQ_VERSION)_$(HOST_OS)_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/yq@$(YQ_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + $(CURL) https://github.com/mikefarah/yq/releases/download/$(YQ_VERSION)/yq_$(HOST_OS)_$(HOST_ARCH) -o $(outfile); \ + $(checkhash_script) $(outfile) $(yq_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM); \ + chmod +x $(outfile) + +ko_linux_amd64_SHA256SUM=d11f03f23261d16f9e7802291e9d098e84f5daecc7931e8573bece9025b6a2c5 +ko_linux_arm64_SHA256SUM=8294849c0f12138006cd149dd02bb580c0eea41a6031473705cbf825e021a688 +ko_darwin_amd64_SHA256SUM=314c33154de941bfc4ede5e7283eb182028459bac36eb4223859e0b778254936 +ko_darwin_arm64_SHA256SUM=b6ecd62eb4f9238a0ed0512d7a34648b881aea0774c3830e3e5159370eb6834f + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/ko@$(KO_VERSION)_$(HOST_OS)_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/ko@$(KO_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + $(eval OS := $(subst linux,Linux,$(subst darwin,Darwin,$(HOST_OS)))) + $(eval ARCH := $(subst amd64,x86_64,$(HOST_ARCH))) + + @source $(lock_script) $@; \ + $(CURL) https://github.com/ko-build/ko/releases/download/v$(KO_VERSION)/ko_$(KO_VERSION)_$(OS)_$(ARCH).tar.gz -o $(outfile).tar.gz; \ + $(checkhash_script) $(outfile).tar.gz $(ko_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM); \ + tar xfO $(outfile).tar.gz ko > $(outfile); \ + chmod +x $(outfile); \ + rm -f $(outfile).tar.gz + +protoc_linux_amd64_SHA256SUM=a7be2928c0454f132c599e25b79b7ad1b57663f2337d7f7e468a1d59b98ec1b0 +protoc_linux_arm64_SHA256SUM=64a3b3b5f7dac0c8f9cf1cb85b2b1a237eb628644f6bcb0fb8f23db6e0d66181 +protoc_darwin_amd64_SHA256SUM=febd8821c3a2a23f72f4641471e0ab6486f4fb07b68111490a27a31681465b3c +protoc_darwin_arm64_SHA256SUM=26a29befa8891ecc48809958c909d284f2b9539a2eb47f22cadc631fe6abe8fd + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/protoc@$(PROTOC_VERSION)_$(HOST_OS)_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/protoc@$(PROTOC_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + $(eval OS := $(subst darwin,osx,$(HOST_OS))) + $(eval ARCH := $(subst arm64,aarch_64,$(subst amd64,x86_64,$(HOST_ARCH)))) + + @source $(lock_script) $@; \ + $(CURL) https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)-$(OS)-$(ARCH).zip -o $(outfile).zip; \ + $(checkhash_script) $(outfile).zip $(protoc_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM); \ + unzip -qq -c $(outfile).zip bin/protoc > $(outfile); \ + chmod +x $(outfile); \ + rm -f $(outfile).zip + +trivy_linux_amd64_SHA256SUM=b0d135815867246baba52f608f4af84beca90cfeb17a9ce407a21acca760ace1 +trivy_linux_arm64_SHA256SUM=1be1dee3a5e013528374f25391d6ba84e2a10fda59f4e98431e30d9c4975762b +trivy_darwin_amd64_SHA256SUM=744f5e8c5c09c1e5ec6ec6a0570f779d89964c0a91ab60b4e59b284cdd3e1576 +trivy_darwin_arm64_SHA256SUM=e78a0db86f6364e756d5e058316c7815a747fc7fd8e8e984e3baf5830166ec63 + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/trivy@$(TRIVY_VERSION)_$(HOST_OS)_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/trivy@$(TRIVY_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + $(eval OS := $(subst linux,Linux,$(subst darwin,macOS,$(HOST_OS)))) + $(eval ARCH := $(subst amd64,64bit,$(subst arm64,ARM64,$(HOST_ARCH)))) + + @source $(lock_script) $@; \ + $(CURL) https://github.com/aquasecurity/trivy/releases/download/$(TRIVY_VERSION)/trivy_$(patsubst v%,%,$(TRIVY_VERSION))_$(OS)-$(ARCH).tar.gz -o $(outfile).tar.gz; \ + $(checkhash_script) $(outfile).tar.gz $(trivy_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM); \ + tar xfO $(outfile).tar.gz trivy > $(outfile); \ + chmod +x $(outfile); \ + rm $(outfile).tar.gz + +ytt_linux_amd64_SHA256SUM=357ec754446b1eda29dd529e088f617e85809726c686598ab03cfc1c79f43b56 +ytt_linux_arm64_SHA256SUM=a2d195b058884c0e36a918936076965b8efb426f7e00f6b7d7b99b82737c7299 +ytt_darwin_amd64_SHA256SUM=71b5ea38bfc7a9748c35ce0735fd6f806dce46bd5c9039d527050c7682e62a70 +ytt_darwin_arm64_SHA256SUM=0658db4af8263ca091ca31e4b599cb40c324b75934660a4c0ed98ad9b701f7e9 + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/ytt@$(YTT_VERSION)_$(HOST_OS)_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/ytt@$(YTT_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + $(CURL) -sSfL https://github.com/vmware-tanzu/carvel-ytt/releases/download/$(YTT_VERSION)/ytt-$(HOST_OS)-$(HOST_ARCH) -o $(outfile); \ + $(checkhash_script) $(outfile) $(ytt_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM); \ + chmod +x $(outfile) + +rclone_linux_amd64_SHA256SUM=b4d304b1dc76001b1d3bb820ae8d1ae60a072afbd3296be904a3ee00b3d4fab9 +rclone_linux_arm64_SHA256SUM=c50a3ab93082f21788f9244393b19f2426edeeb896eec2e3e05ffb2e8727e075 +rclone_darwin_amd64_SHA256SUM=5adb4c5fe0675627461000a63156001301ec7cade966c55c8c4ebcfaeb62c5ae +rclone_darwin_arm64_SHA256SUM=b5f4c4d06ff3d426aee99870ad437276c9ddaad55442f2df6a58b918115fe4cf + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/rclone@$(RCLONE_VERSION)_$(HOST_OS)_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/rclone@$(RCLONE_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + $(eval OS := $(subst darwin,osx,$(HOST_OS))) + + @source $(lock_script) $@; \ + $(CURL) https://github.com/rclone/rclone/releases/download/$(RCLONE_VERSION)/rclone-$(RCLONE_VERSION)-$(OS)-$(HOST_ARCH).zip -o $(outfile).zip; \ + $(checkhash_script) $(outfile).zip $(rclone_$(HOST_OS)_$(HOST_ARCH)_SHA256SUM); \ + unzip -p $(outfile).zip rclone-$(RCLONE_VERSION)-$(OS)-$(HOST_ARCH)/rclone > $(outfile); \ + chmod +x $(outfile); \ + rm -f $(outfile).zip + +preflight_linux_amd64_SHA256SUM=20f31e4af2004e8e3407844afea4e973975069169d69794e0633f0cb91d45afd +preflight_linux_arm64_SHA256SUM=c42cf4132027d937da88da07760e8fd9b1a8836f9c7795a1b60513d99c6939fe + +# Currently there are no offical releases for darwin, you cannot submit results +# on non-official binaries, but we can still run tests. +# +# Once https://github.com/redhat-openshift-ecosystem/openshift-preflight/pull/942 is merged +# we can remove this darwin specific hack +.PRECIOUS: $(DOWNLOAD_DIR)/tools/preflight@$(PREFLIGHT_VERSION)_darwin_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/preflight@$(PREFLIGHT_VERSION)_darwin_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + mkdir -p $(outfile).dir; \ + GOWORK=off GOBIN=$(outfile).dir $(GO) install github.com/redhat-openshift-ecosystem/openshift-preflight/cmd/preflight@$(PREFLIGHT_VERSION); \ + mv $(outfile).dir/preflight $(outfile); \ + rm -rf $(outfile).dir + +.PRECIOUS: $(DOWNLOAD_DIR)/tools/preflight@$(PREFLIGHT_VERSION)_linux_$(HOST_ARCH) +$(DOWNLOAD_DIR)/tools/preflight@$(PREFLIGHT_VERSION)_linux_$(HOST_ARCH): | $(DOWNLOAD_DIR)/tools + @source $(lock_script) $@; \ + $(CURL) https://github.com/redhat-openshift-ecosystem/openshift-preflight/releases/download/$(PREFLIGHT_VERSION)/preflight-linux-$(HOST_ARCH) -o $(outfile); \ + $(checkhash_script) $(outfile) $(preflight_linux_$(HOST_ARCH)_SHA256SUM); \ + chmod +x $(outfile) + +################# +# Other Targets # +################# + +# Although we "vendor" most tools in $(bin_dir)/tools, we still require some binaries +# to be available on the system. The vendor-go MAKECMDGOALS trick prevents the +# check for the presence of Go when 'make vendor-go' is run. + +# Gotcha warning: MAKECMDGOALS only contains what the _top level_ make invocation used, and doesn't look at target dependencies +# i.e. if we have a target "abc: vendor-go test" and run "make abc", we'll get an error +# about go being missing even though abc itself depends on vendor-go! +# That means we need to pass vendor-go at the top level if go is not installed (i.e. "make vendor-go abc") + +missing=$(shell (command -v curl >/dev/null || echo curl) \ + && (command -v sha256sum >/dev/null || command -v shasum >/dev/null || echo sha256sum) \ + && (command -v git >/dev/null || echo git) \ + && (command -v rsync >/dev/null || echo rsync) \ + && ([ -n "$(findstring vendor-go,$(MAKECMDGOALS),)" ] \ + || command -v $(GO) >/dev/null || echo "$(GO) (or run 'make vendor-go')") \ + && (command -v $(CTR) >/dev/null || echo "$(CTR) (or set CTR to a docker-compatible tool)")) +ifneq ($(missing),) +$(error Missing required tools: $(missing)) +endif + +.PHONY: tools +## Download and setup all tools +## @category [shared] Tools +tools: $(tools_paths) + +self_file := $(dir $(lastword $(MAKEFILE_LIST)))/00_mod.mk + +# This target is used to learn the sha256sum of the tools. It is used only +# in the makefile-modules repo, and should not be used in any other repo. +.PHONY: tools-learn-sha +tools-learn-sha: | $(bin_dir) + rm -rf ./$(bin_dir)/ + mkdir -p ./$(bin_dir)/scratch/ + $(eval export LEARN_FILE=$(CURDIR)/$(bin_dir)/scratch/learn_tools_file) + echo -n "" > "$(LEARN_FILE)" + + HOST_OS=linux HOST_ARCH=amd64 $(MAKE) tools + HOST_OS=linux HOST_ARCH=arm64 $(MAKE) tools + HOST_OS=darwin HOST_ARCH=amd64 $(MAKE) tools + HOST_OS=darwin HOST_ARCH=arm64 $(MAKE) tools + + HOST_OS=linux HOST_ARCH=amd64 $(MAKE) vendor-go + HOST_OS=linux HOST_ARCH=arm64 $(MAKE) vendor-go + HOST_OS=darwin HOST_ARCH=amd64 $(MAKE) vendor-go + HOST_OS=darwin HOST_ARCH=arm64 $(MAKE) vendor-go + + while read p; do \ + sed -i "$$p" $(self_file); \ + done <"$(LEARN_FILE)" diff --git a/make/_shared/tools/util/checkhash.sh b/make/_shared/tools/util/checkhash.sh new file mode 100755 index 00000000..62e5489b --- /dev/null +++ b/make/_shared/tools/util/checkhash.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# Copyright 2023 The cert-manager 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. + +set -o errexit +set -o nounset +set -o pipefail + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +# This script takes the hash of its first argument and verifies it against the +# hex hash given in its second argument + +function usage_and_exit() { + echo "usage: $0 " + echo "or: LEARN_FILE= $0 " + exit 1 +} + +HASH_TARGET=${1:-} +EXPECTED_HASH=${2:-} + +if [[ -z $HASH_TARGET ]]; then + usage_and_exit +fi + +if [[ -z $EXPECTED_HASH ]]; then + usage_and_exit +fi + +SHASUM=$("${SCRIPT_DIR}/hash.sh" "$HASH_TARGET") + +if [[ "$SHASUM" == "$EXPECTED_HASH" ]]; then + exit 0 +fi + +# When running 'make learn-sha-tools', we don't want this script to fail. +# Instead we log what sha values are wrong, so the make.mk file can be updated. + +if [ "${LEARN_FILE:-}" != "" ]; then + echo "s/$EXPECTED_HASH/$SHASUM/g" >> "${LEARN_FILE:-}" + exit 0 +fi + +echo "invalid checksum for \"$HASH_TARGET\": wanted \"$EXPECTED_HASH\" but got \"$SHASUM\"" +exit 1 diff --git a/hack/update-helm-tool.sh b/make/_shared/tools/util/hash.sh similarity index 64% rename from hack/update-helm-tool.sh rename to make/_shared/tools/util/hash.sh index b08e5c95..21d006fc 100755 --- a/hack/update-helm-tool.sh +++ b/make/_shared/tools/util/hash.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright 2022 The cert-manager Authors. +# Copyright 2023 The cert-manager Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,11 +18,10 @@ set -o errexit set -o nounset set -o pipefail -HELM_TOOL_BIN=${1:-} +# This script is a wrapper for outputting purely the sha256 hash of the input file, +# ideally in a portable way. -if [[ -z $HELM_TOOL_BIN ]]; then - echo "usage: $0 " - exit 1 -fi - -$HELM_TOOL_BIN inject -i ./deploy/charts/trust-manager/values.yaml -o ./deploy/charts/trust-manager/README.md --header-search '^' --footer-search '^' +case "$(uname -s)" in + Darwin*) shasum -a 256 "$1";; + *) sha256sum "$1" +esac | cut -d" " -f1 \ No newline at end of file diff --git a/make/_shared/tools/util/lock.sh b/make/_shared/tools/util/lock.sh new file mode 100755 index 00000000..22564f7c --- /dev/null +++ b/make/_shared/tools/util/lock.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +# Copyright 2023 The cert-manager 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. + +set -o errexit +set -o nounset +set -o pipefail + +# This script is used to lock a file while it is being downloaded. It prevents +# multiple processes from downloading the same file at the same time or from reading +# a half-downloaded file. +# We need this solution because we have recursive $(MAKE) calls in our makefile +# which each will try to download a set of tools. To prevent them from all downloading +# the same files, we re-use the same downloads folder for all $(MAKE) invocations and +# use this script to deduplicate the download processes. + +finalfile="$1" +lockfile="$finalfile.lock" + +# On OSX, flock is not installed, we just skip locking in that case, +# this means that running verify in parallel without downloading all +# tools first will not work. +flock_installed=$(command -v flock >/dev/null && echo "yes" || echo "no") + +if [[ "$flock_installed" == "yes" ]]; then + mkdir -p "$(dirname "$lockfile")" + touch "$lockfile" + exec {FD}<>"$lockfile" + + # wait for the file to be unlocked + if ! flock -x $FD; then + echo "Failed to obtain a lock for $lockfile" + exit 1 + fi +fi + +# now that we have the lock, check if file is already there +if [[ -e "$finalfile" ]]; then + exit 0 +fi + +# use a temporary file to prevent Make from thinking the file is ready +# while in reality is is only a partial download +# shellcheck disable=SC2034 +outfile="$finalfile.tmp" + +finish() { + rv=$? + if [[ $rv -eq 0 ]]; then + mv "$outfile" "$finalfile" + echo "[info]: downloaded $finalfile" + else + rm -rf "$outfile" || true + rm -rf "$finalfile" || true + fi + rm -rf "$lockfile" || true +} +trap finish EXIT SIGINT diff --git a/make/config/kind/cluster.yaml b/make/config/kind/cluster.yaml new file mode 100644 index 00000000..507f1f9e --- /dev/null +++ b/make/config/kind/cluster.yaml @@ -0,0 +1,19 @@ +apiVersion: kind.x-k8s.io/v1alpha4 +kind: Cluster +kubeadmConfigPatches: + - | + kind: ClusterConfiguration + metadata: + name: config + etcd: + local: + extraArgs: + unsafe-no-fsync: "true" + networking: + serviceSubnet: 10.0.0.0/16 +nodes: +- role: control-plane + + extraMounts: + - hostPath: {{KIND_IMAGES}} + containerPath: /mounted_images diff --git a/make/debian-trust-package-fetch.sh b/make/debian-trust-package-fetch.sh new file mode 100755 index 00000000..05f55a29 --- /dev/null +++ b/make/debian-trust-package-fetch.sh @@ -0,0 +1,143 @@ +#!/usr/bin/env bash + +# Copyright 2022 The cert-manager 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. + +set -o errexit +set -o nounset +set -o pipefail + +# This script uses a container to install the latest ca-certificates package, and then +# checks to see if the installed version of that package matches the latest available +# debian trust package image in our container registry. + +# If we installed a newer version in the local container, we build a new image container +# and push it upstream + +CTR=${CTR:-docker} +BIN_VALIDATE_TRUST_PACKAGE=${BIN_VALIDATE_TRUST_PACKAGE:-} + +ACTION=${1:-} +DEBIAN_SOURCE_IMAGE=${2:-} +DESTINATION_FILE=${3:-} +TARGET_DEBIAN_BUNDLE_VERSION=${4:-} + +function print_usage() { + echo "usage: $0 " +} + +if ! command -v "$CTR" &>/dev/null; then + print_usage + echo "This script requires a docker CLI compatible runtime, either docker or podman" + echo "If CTR is not set, defaults to using docker" + echo "Couldn't find $CTR command; exiting" + exit 1 +fi + +if [[ -z $BIN_VALIDATE_TRUST_PACKAGE ]]; then + print_usage + echo "BIN_VALIDATE_TRUST_PACKAGE must be set to the path of the validate-trust-package binary" + exit 1 +fi + +if [[ -z $ACTION ]]; then + print_usage + echo "ACTION must be set to either 'latest' or 'exact'" + exit 1 +elif [[ $ACTION != "latest" && $ACTION != "exact" ]]; then + print_usage + echo "ACTION must be set to either 'latest' or 'exact'" + exit 1 +fi + +if [[ -z $DEBIAN_SOURCE_IMAGE ]]; then + print_usage + echo "debian source image must be specified" + exit 1 +fi + +if [[ -z $DESTINATION_FILE ]]; then + print_usage + echo "destination file must be specified" + exit 1 +fi + +if [[ -z $TARGET_DEBIAN_BUNDLE_VERSION ]]; then + print_usage + echo "target version must be specified" + exit 1 +fi +target_ca_certificates_version="${TARGET_DEBIAN_BUNDLE_VERSION%.*}" + +echo "+++ fetching latest version of ca-certificates package" + +TMP_DIR=$(mktemp -d) + +# register the cleanup function to be called on the EXIT signal +trap 'rm -rf -- "$TMP_DIR"' EXIT + +# Install the latest version of ca-certificates in a fresh container and print the +# installed version + +# There are several commands for querying remote repos (e.g. apt-cache madison) but +# it's not clear that these commands are guaranteed to return installable versions +# in order or in a parseable format + +# We specifically only want to query the latest version and without a guarantee on +# output ordering it's safest to install what apt thinks is the latest version and +# then see what we got. + +# NB: It's also very difficult to make 'apt-get' stay quiet when installing packages +# so we just let it be loud and then only take the last line of output + +install_target="ca-certificates" +if [[ "$ACTION" == "exact" ]]; then + install_target="${install_target}=${target_ca_certificates_version}" +fi + +cat << EOF > "$TMP_DIR/run.sh" +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +apt-get -y update + +DEBIAN_FRONTEND=noninteractive \ +apt-get install -y --no-install-recommends ${install_target} + +dpkg-query --show --showformat="\\\${Version}" ca-certificates | tail -n 1 > /workdir/version.txt + +cp /etc/ssl/certs/ca-certificates.crt /workdir/ca-certificates.crt +EOF + +$CTR run --rm --mount type=bind,source="$TMP_DIR",target=/workdir "$DEBIAN_SOURCE_IMAGE" /bin/bash /workdir/run.sh + +installed_version=$(cat "$TMP_DIR/version.txt") +version_suffix=".0" + +if [[ "$ACTION" == "latest" && "$installed_version" == "$target_ca_certificates_version" ]]; then + version_suffix=".${TARGET_DEBIAN_BUNDLE_VERSION##*.}" + echo "+++ installed version matches target version; reusing the current suffix '$version_suffix'" +fi + +echo "{}" | jq \ + --rawfile bundle /etc/ssl/certs/ca-certificates.crt \ + --arg name "cert-manager-debian" \ + --arg version "$installed_version$version_suffix" \ + '.name = $name | .bundle = $bundle | .version = $version' \ + > "$DESTINATION_FILE" + +${BIN_VALIDATE_TRUST_PACKAGE} < "$DESTINATION_FILE" diff --git a/make/debian-trust-package.mk b/make/debian-trust-package.mk new file mode 100644 index 00000000..520c6020 --- /dev/null +++ b/make/debian-trust-package.mk @@ -0,0 +1,46 @@ +# Copyright 2023 The cert-manager 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. + +debian_package_layer := $(bin_dir)/scratch/debian-trust-package +debian_package_json := $(debian_package_layer)/debian-package/cert-manager-package-debian.json + +$(debian_package_layer)/debian-package $(bin_dir)/bin: + mkdir -p $@ + +$(bin_dir)/bin/validate-trust-package: cmd/validate-trust-package/*.go pkg/fspkg/*.go | $(NEEDS_GO) $(bin_dir)/bin + $(GO) build -o $@ ./cmd/validate-trust-package + +$(debian_package_json): | $(bin_dir)/bin/validate-trust-package $(debian_package_layer)/debian-package + BIN_VALIDATE_TRUST_PACKAGE=$(bin_dir)/bin/validate-trust-package \ + ./make/debian-trust-package-fetch.sh exact $(DEBIAN_BUNDLE_SOURCE_IMAGE) $@ $(DEBIAN_BUNDLE_VERSION) + +oci-build-package_debian: $(debian_package_json) +oci_additional_layers_package_debian += $(debian_package_layer) + +# see https://stackoverflow.com/a/53408233 +sed_inplace := sed -i'' +ifeq ($(HOST_OS),darwin) + sed_inplace := sed -i '' +endif + +.PHONY: upgrade-debian-trust-package-version +upgrade-debian-trust-package-version: | $(bin_dir)/bin/validate-trust-package $(bin_dir)/scratch + $(eval temp_out := $(bin_dir)/scratch/debian-trust-package.temp.json) + rm -rf $(temp_out) + + BIN_VALIDATE_TRUST_PACKAGE=$(bin_dir)/bin/validate-trust-package \ + ./make/debian-trust-package-fetch.sh latest $(DEBIAN_BUNDLE_SOURCE_IMAGE) $(temp_out) $(DEBIAN_BUNDLE_VERSION) + + latest_version=$$(jq -r '.version' $(temp_out)); \ + $(sed_inplace) "s/DEBIAN_BUNDLE_VERSION := .*/DEBIAN_BUNDLE_VERSION := $$latest_version/" make/00_debian_version.mk diff --git a/make/test-integration.mk b/make/test-integration.mk new file mode 100644 index 00000000..75901d52 --- /dev/null +++ b/make/test-integration.mk @@ -0,0 +1,34 @@ +# Copyright 2023 The cert-manager 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. + +trust_manager_crds := $(bin_dir)/scratch/trust.cert-manager.io_bundles.yaml +$(trust_manager_crds): $(helm_chart_archive) | $(NEEDS_HELM) $(NEEDS_YQ) + $(HELM) template test "$(helm_chart_archive)" | \ + $(YQ) e '. | select(.kind == "CustomResourceDefinition")' \ + > $@ + +.PHONY: test-integration +## Integration tests +## @category Testing +test-integration: | $(trust_manager_crds) $(NEEDS_GOTESTSUM) $(NEEDS_ETCD) $(NEEDS_KUBE-APISERVER) $(NEEDS_KUBECTL) $(ARTIFACTS) + TRUST_MANAGER_CRDS=$(CURDIR)/$(trust_manager_crds) \ + KUBEBUILDER_ASSETS=$(CURDIR)/$(bin_dir)/tools \ + $(GOTESTSUM) \ + --junitfile=$(ARTIFACTS)/junit-go-e2e.xml \ + -- \ + -coverprofile=$(ARTIFACTS)/filtered.cov \ + ./test/integration/... \ + -- \ + -ldflags $(go_manager_ldflags) \ + -test.timeout 2m diff --git a/make/test-smoke.mk b/make/test-smoke.mk new file mode 100644 index 00000000..feb295af --- /dev/null +++ b/make/test-smoke.mk @@ -0,0 +1,64 @@ +# Copyright 2023 The cert-manager 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. + +.PHONY: smoke-setup-cert-manager +smoke-setup-cert-manager: | kind-cluster $(NEEDS_HELM) $(NEEDS_KUBECTL) + $(HELM) upgrade \ + --install \ + --create-namespace \ + --wait \ + --version $(quay.io/jetstack/cert-manager-controller.TAG) \ + --namespace cert-manager \ + --repo https://charts.jetstack.io \ + --set installCRDs=true \ + --set image.repository=$(quay.io/jetstack/cert-manager-controller.REPO) \ + --set image.tag=$(quay.io/jetstack/cert-manager-controller.TAG) \ + --set image.pullPolicy=Never \ + --set cainjector.image.repository=$(quay.io/jetstack/cert-manager-cainjector.REPO) \ + --set cainjector.image.tag=$(quay.io/jetstack/cert-manager-cainjector.TAG) \ + --set cainjector.image.pullPolicy=Never \ + --set webhook.image.repository=$(quay.io/jetstack/cert-manager-webhook.REPO) \ + --set webhook.image.tag=$(quay.io/jetstack/cert-manager-webhook.TAG) \ + --set webhook.image.pullPolicy=Never \ + --set startupapicheck.image.repository=$(quay.io/jetstack/cert-manager-startupapicheck.REPO) \ + --set startupapicheck.image.tag=$(quay.io/jetstack/cert-manager-startupapicheck.TAG) \ + --set startupapicheck.image.pullPolicy=Never \ + cert-manager cert-manager >/dev/null + +# The "install" target can be run on its own with any currently active cluster, +# we can't use any other cluster then a target containing "test-smoke" is run. +# When a "test-smoke" target is run, the currently active cluster must be the kind +# cluster created by the "kind-cluster" target. +ifeq ($(findstring test-smoke,$(MAKECMDGOALS)),test-smoke) +install: kind-cluster oci-load-manager oci-load-package_debian +endif + +test-smoke-deps: INSTALL_OPTIONS := +test-smoke-deps: INSTALL_OPTIONS += --set image.repository=$(oci_manager_image_name_development) +test-smoke-deps: INSTALL_OPTIONS += --set defaultPackageImage.repository=$(oci_package_debian_image_name_development) +test-smoke-deps: INSTALL_OPTIONS += --set secretTargets.enabled=true --set secretTargets.authorizedSecretsAll=true +test-smoke-deps: smoke-setup-cert-manager +test-smoke-deps: install + +.PHONY: test-smoke +## Smoke end-to-end tests +## @category Testing +test-smoke: test-smoke-deps | kind-cluster $(NEEDS_GINKGO) $(ARTIFACTS) + $(GINKGO) \ + --output-dir=$(ARTIFACTS) \ + --junit-report=junit-go-e2e.xml \ + ./test/smoke/ \ + -ldflags $(go_manager_ldflags) \ + -- \ + --kubeconfig-path $(CURDIR)/$(kind_kubeconfig) diff --git a/make/test-unit.mk b/make/test-unit.mk new file mode 100644 index 00000000..b17b346d --- /dev/null +++ b/make/test-unit.mk @@ -0,0 +1,26 @@ +# Copyright 2023 The cert-manager 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. + +.PHONY: test-unit +## Unit tests +## @category Testing +test-unit: | $(NEEDS_GOTESTSUM) $(ARTIFACTS) + $(GOTESTSUM) \ + --junitfile=$(ARTIFACTS)/junit-go-e2e.xml \ + -- \ + -coverprofile=$(ARTIFACTS)/filtered.cov \ + ./cmd/... ./pkg/... \ + -- \ + -ldflags $(go_manager_ldflags) \ + -test.timeout 2m diff --git a/make/trust-manager-build.mk b/make/trust-manager-build.mk deleted file mode 100644 index a3c245dc..00000000 --- a/make/trust-manager-build.mk +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2023 The cert-manager 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. - -define build_trust_manager - docker buildx build --builder $(BUILDX_BUILDER) \ - --platform=$(3) \ - -t $(CONTAINER_REGISTRY)/trust-manager:$(2) \ - --build-arg GOPROXY=$(GOPROXY) \ - --output $(1) \ - -f ./Dockerfile \ - . -endef - -.PHONY: trust-manager-save -trust-manager-save: - $(call build_trust_manager,type=local$(_COMMA)dest=$(BINDIR)/trust-manager,$(RELEASE_VERSION),$(IMAGE_PLATFORMS)) - -.PHONY: trust-manager-load -trust-manager-load: - $(call build_trust_manager,type=docker,latest,linux/$(ARCH)) - -.PHONY: trust-manager-push -trust-manager-push: - $(call build_trust_manager,type=registry,$(RELEASE_VERSION),$(IMAGE_PLATFORMS)) diff --git a/make/trust-package-debian.mk b/make/trust-package-debian.mk deleted file mode 100644 index 864d5ea5..00000000 --- a/make/trust-package-debian.mk +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright 2023 The cert-manager 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. - -DEBIAN_TRUST_PACKAGE_VERSION ?= -DEBIAN_TRUST_PACKAGE_SUFFIX ?= .0 - -define build_debian_trust_package - docker buildx build --builder $(BUILDX_BUILDER) \ - --platform=$(3) \ - -t $(CONTAINER_REGISTRY)/cert-manager-package-debian:$(2)$(DEBIAN_TRUST_PACKAGE_SUFFIX) \ - --build-arg GOPROXY=$(GOPROXY) \ - --build-arg EXPECTED_VERSION=$(2) \ - --build-arg VERSION_SUFFIX=$(DEBIAN_TRUST_PACKAGE_SUFFIX) \ - --output $(1) \ - -f ./trust-packages/debian/Containerfile \ - ./trust-packages/debian -endef - -.PHONY: trust-package-debian-save -trust-package-debian-save: -ifeq ($(strip $(DEBIAN_TRUST_PACKAGE_VERSION)),) - $(error DEBIAN_TRUST_PACKAGE_VERSION must be set for $@) -endif - - $(call build_debian_trust_package,type=local$(_COMMA)dest=$(BINDIR)/cert-manager-package-debian,$(DEBIAN_TRUST_PACKAGE_VERSION),$(IMAGE_PLATFORMS)) - -.PHONY: trust-package-debian-load -trust-package-debian-load: - $(call build_debian_trust_package,type=docker,latest,linux/$(ARCH)) - -.PHONY: trust-package-debian-push -trust-package-debian-push: -ifeq ($(strip $(DEBIAN_TRUST_PACKAGE_VERSION)),) - $(error DEBIAN_TRUST_PACKAGE_VERSION must be set for $@) -endif - - $(call build_debian_trust_package,type=registry,$(DEBIAN_TRUST_PACKAGE_VERSION),$(IMAGE_PLATFORMS)) - -.PHONY: ci-update-debian-trust-package -ci-update-debian-trust-package: - ./hack/update-debian-trust-package.sh "$(CONTAINER_REGISTRY)/cert-manager-package-debian" $(DEBIAN_TRUST_PACKAGE_SUFFIX) "$(CONTAINER_REGISTRY_API_URL)" diff --git a/pkg/apis/trust/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/trust/v1alpha1/zz_generated.deepcopy.go index ddf7af25..9537bdec 100644 --- a/pkg/apis/trust/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/trust/v1alpha1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ //go:build !ignore_autogenerated /* -Copyright 2023 The cert-manager Authors. +Copyright The cert-manager Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/test/integration/bundle/integration.go b/test/integration/bundle/integration.go index 50f85150..7a28751f 100644 --- a/test/integration/bundle/integration.go +++ b/test/integration/bundle/integration.go @@ -17,6 +17,8 @@ limitations under the License. package test import ( + "os" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "k8s.io/utils/ptr" @@ -34,10 +36,14 @@ var ( var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + crdsYamlFile := os.Getenv("TRUST_MANAGER_CRDS") + Expect(crdsYamlFile).NotTo(BeEmpty(), "TRUST_MANAGER_CRDS must be set to the path of the CRDs to install") + env = &envtest.Environment{ UseExistingCluster: ptr.To(false), CRDDirectoryPaths: []string{ - "../../../deploy/crds/trust.cert-manager.io_bundles.yaml", + crdsYamlFile, }, Scheme: trustapi.GlobalScheme, } diff --git a/trust-packages/debian/Containerfile b/trust-packages/debian/Containerfile deleted file mode 100644 index d6ff8670..00000000 --- a/trust-packages/debian/Containerfile +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2022 The cert-manager 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. - -FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.22 as gobuild - -ARG GOPROXY -ARG TARGETARCH - -WORKDIR /work - -COPY go.mod go.mod -COPY go.sum go.sum -COPY main.go main.go - -RUN GOPROXY=$GOPROXY CGO_ENABLED=0 GOARCH=$TARGETARCH go build -o copyandmaybepause main.go - -RUN GOPROXY=$GOPROXY go get github.com/cert-manager/trust-manager/cmd/validate-trust-package && GOPROXY=$GOPROXY CGO_ENABLED=0 GOARCH=$TARGETARCH go build -o /go/bin/validate-trust-package github.com/cert-manager/trust-manager/cmd/validate-trust-package - -FROM docker.io/library/debian:11-slim as debbase - -ARG EXPECTED_VERSION -ARG VERSION_SUFFIX - -WORKDIR /work - -COPY ./build.sh /work/build.sh -COPY --from=gobuild /go/bin/validate-trust-package /usr/bin/validate-trust-package - -RUN /work/build.sh $EXPECTED_VERSION $VERSION_SUFFIX /work/package.json - -FROM scratch - -ARG EXPECTED_VERSION -ARG VERSION_SUFFIX - -LABEL description="cert-manager trust package based on Debian" - -USER 1001 - -COPY --from=debbase /usr/bin/tini-static /tini -COPY --from=debbase /work/package.json /debian-package/cert-manager-package-debian.json -COPY --from=gobuild /work/copyandmaybepause /copyandmaybepause - -ENTRYPOINT ["/tini", "--"] - -CMD ["/copyandmaybepause", "/debian-package", "/packages"] diff --git a/trust-packages/debian/build.sh b/trust-packages/debian/build.sh deleted file mode 100755 index 8fbdc145..00000000 --- a/trust-packages/debian/build.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2022 The cert-manager 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. - -set -o errexit -set -o nounset -set -o pipefail - -# This script is designed to be run during a build of the debian bundle container -# As such, it's not designed to be portable and may only work in that situation - -EXPECTED_VERSION=${1:-} -VERSION_SUFFIX=${2:-} -DESTINATION_FILE=${3:-} - -if [[ -z $EXPECTED_VERSION || -z $VERSION_SUFFIX || -z $DESTINATION_FILE ]]; then - echo "usage: $0 " - exit 1 -fi - -apt-get -yq update -DEBIAN_FRONTEND=noninteractive apt-get -yq -o=Dpkg::Use-Pty=0 install --no-install-recommends ca-certificates jq tini - -INSTALLED_VERSION=$(dpkg-query --show --showformat="\${Version}" ca-certificates) - -if [[ "$EXPECTED_VERSION" != "latest" ]]; then - if [[ "$EXPECTED_VERSION" != "$INSTALLED_VERSION" ]]; then - echo "expected version $EXPECTED_VERSION but got $INSTALLED_VERSION" - echo "this might mean that debian released an update between querying for version $EXPECTED_VERSION and running this build script" - echo "exiting for safety" - exit 1 - fi -fi - -echo "{}" | jq \ - --rawfile bundle /etc/ssl/certs/ca-certificates.crt \ - --arg name "cert-manager-debian" \ - --arg version "$EXPECTED_VERSION$VERSION_SUFFIX" \ - '.name = $name | .bundle = $bundle | .version = $version' \ - > $DESTINATION_FILE - -validate-trust-package < $DESTINATION_FILE diff --git a/trust-packages/debian/main.go b/trust-packages/debian/main.go index 71a7a100..bb66ef38 100644 --- a/trust-packages/debian/main.go +++ b/trust-packages/debian/main.go @@ -59,14 +59,20 @@ func main() { flag.Parse() - if flag.NArg() != 2 { + var inputDir, destinationDir string + switch { + case flag.NArg() == 3 && flag.Arg(0) == "/copyandmaybepause": + stderrLogger.Printf("DEPRECATED: use the image's entrypoint instead of /copyandmaybepause") + inputDir = flag.Arg(1) + destinationDir = flag.Arg(2) + case flag.NArg() == 2: + inputDir = flag.Arg(0) + destinationDir = flag.Arg(1) + default: flag.Usage() os.Exit(1) } - inputDir := flag.Arg(0) - destinationDir := flag.Arg(1) - stderrLogger.Printf("reading from %s", inputDir) stderrLogger.Printf("writing to %s", destinationDir)