From fc68b01c350c66716bba8563ad6f51ab9001a8de Mon Sep 17 00:00:00 2001 From: killianmuldoon Date: Mon, 14 Aug 2023 15:19:42 +0100 Subject: [PATCH] Add licence-scan for pull requests Signed-off-by: killianmuldoon --- CONTRIBUTING.md | 5 ++ Makefile | 10 ++- hack/ensure-trivy.sh | 57 +++++++++++++ hack/verify-container-images.sh | 45 +++------- hack/verify-licenses.sh | 36 ++++++++ trivy.yaml | 142 ++++++++++++++++++++++++++++++++ 6 files changed, 259 insertions(+), 36 deletions(-) create mode 100644 hack/ensure-trivy.sh create mode 100755 hack/verify-licenses.sh create mode 100644 trivy.yaml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3a542eb0c373..b1673d3c5332 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,6 +23,7 @@ - [Features and bugs](#features-and-bugs) - [Experiments](#experiments) - [Breaking Changes](#breaking-changes) +- [Dependency Licence Management](#dependency-licence-management) - [API conventions](#api-conventions) - [Optional vs. Required](#optional-vs-required) - [Example](#example) @@ -415,6 +416,10 @@ There may, at times, need to be exceptions where breaking changes are allowed in discretion of the project's maintainers, and must be carefully considered before merging. An example of an allowed breaking change might be a fix for a behavioral bug that was released in an initial minor version (such as `v0.3.0`). +## Dependency Licence Management + +Cluster API follows the [license policy of the CNCF](https://github.com/cncf/foundation/blob/main/allowed-third-party-license-policy.md). This sets limits on which +licenses dependencies and other artifacts use. For go dependencies only dependencies listed in the `go.mod` are considered dependencies. This is in line with [how dependencies are reviewed in Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/vendor.md#reviewing-and-approving-dependency-changes). ## API conventions diff --git a/Makefile b/Makefile index dc3164877a47..fe5e55e4bacd 100644 --- a/Makefile +++ b/Makefile @@ -144,6 +144,8 @@ HADOLINT_FAILURE_THRESHOLD = warning SHELLCHECK_VER := v0.9.0 +TRIVY_VER := 0.44.1 + KPROMO_VER := v4.0.4 KPROMO_BIN := kpromo KPROMO := $(abspath $(TOOLS_BIN_DIR)/$(KPROMO_BIN)-$(KPROMO_VER)) @@ -605,7 +607,7 @@ APIDIFF_OLD_COMMIT ?= $(shell git rev-parse origin/main) apidiff: $(GO_APIDIFF) ## Check for API differences $(GO_APIDIFF) $(APIDIFF_OLD_COMMIT) --print-compatible -ALL_VERIFY_CHECKS = boilerplate shellcheck tiltfile modules gen conversions doctoc capi-book-summary +ALL_VERIFY_CHECKS = licenses boilerplate shellcheck tiltfile modules gen conversions doctoc capi-book-summary .PHONY: verify verify: $(addprefix verify-,$(ALL_VERIFY_CHECKS)) lint-dockerfiles ## Run all verify-* targets @@ -657,7 +659,11 @@ verify-tiltfile: ## Verify Tiltfile format .PHONY: verify-container-images verify-container-images: ## Verify container images - TRACE=$(TRACE) ./hack/verify-container-images.sh + TRACE=$(TRACE) ./hack/verify-container-images.sh $(TRIVY_VER) + +.PHONY: verify-licenses +verify-licenses: ## Verify licenses + TRACE=$(TRACE) ./hack/verify-licenses.sh $(TRIVY_VER) .PHONY: verify-govulncheck verify-govulncheck: $(GOVULNCHECK) ## Verify code for vulnerabilities diff --git a/hack/ensure-trivy.sh b/hack/ensure-trivy.sh new file mode 100644 index 000000000000..9ae64fc3b538 --- /dev/null +++ b/hack/ensure-trivy.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# Copyright 2023 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 [[ "${TRACE-0}" == "1" ]]; then + set -o xtrace +fi + +VERSION=${1} + +GO_OS="$(go env GOOS)" +if [[ "${GO_OS}" == "linux" ]]; then + TRIVY_OS="Linux" +elif [[ "${GO_OS}" == "darwin"* ]]; then + TRIVY_OS="macOS" +fi + +GO_ARCH="$(go env GOARCH)" +if [[ "${GO_ARCH}" == "amd" ]]; then + TRIVY_ARCH="32bit" +elif [[ "${GO_ARCH}" == "amd64"* ]]; then + TRIVY_ARCH="64bit" +elif [[ "${GO_ARCH}" == "arm" ]]; then + TRIVY_ARCH="ARM" +elif [[ "${GO_ARCH}" == "arm64" ]]; then + TRIVY_ARCH="ARM64" +fi + +TOOL_BIN=hack/tools/bin +mkdir -p ${TOOL_BIN} + +TRIVY="${TOOL_BIN}/trivy/${VERSION}/trivy" + +# Downloads trivy scanner +if [ ! -f "$TRIVY" ]; then + curl -L -o ${TOOL_BIN}/trivy.tar.gz "https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_${TRIVY_OS}-${TRIVY_ARCH}.tar.gz" + mkdir -p "$(dirname "$0")/tools/bin/trivy/${VERSION}" + tar -xf "${TOOL_BIN}/trivy.tar.gz" -C "${TOOL_BIN}/trivy/${VERSION}" trivy + chmod +x "${TOOL_BIN}/trivy/${VERSION}/trivy" + rm "${TOOL_BIN}/trivy.tar.gz" +fi diff --git a/hack/verify-container-images.sh b/hack/verify-container-images.sh index 496e03faaeeb..cf9e5aa39dfa 100755 --- a/hack/verify-container-images.sh +++ b/hack/verify-container-images.sh @@ -22,48 +22,25 @@ if [[ "${TRACE-0}" == "1" ]]; then set -o xtrace fi -TRIVY_VERSION=0.34.0 +VERSION=${1} -GO_OS="$(go env GOOS)" -if [[ "${GO_OS}" == "linux" ]]; then - TRIVY_OS="Linux" -elif [[ "${GO_OS}" == "darwin"* ]]; then - TRIVY_OS="macOS" -fi - -GO_ARCH="$(go env GOARCH)" -if [[ "${GO_ARCH}" == "amd" ]]; then - TRIVY_ARCH="32bit" -elif [[ "${GO_ARCH}" == "amd64"* ]]; then - TRIVY_ARCH="64bit" -elif [[ "${GO_ARCH}" == "arm" ]]; then - TRIVY_ARCH="ARM" -elif [[ "${GO_ARCH}" == "arm64" ]]; then - TRIVY_ARCH="ARM64" -fi - -TOOL_BIN=hack/tools/bin -mkdir -p ${TOOL_BIN} - -# Downloads trivy scanner -curl -L -o ${TOOL_BIN}/trivy.tar.gz "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_${TRIVY_OS}-${TRIVY_ARCH}.tar.gz" +REPO_ROOT=$(git rev-parse --show-toplevel) +source "${REPO_ROOT}/hack/ensure-trivy.sh" -tar -xf "${TOOL_BIN}/trivy.tar.gz" -C "${TOOL_BIN}" trivy -chmod +x ${TOOL_BIN}/trivy -rm ${TOOL_BIN}/trivy.tar.gz +TRIVY="${REPO_ROOT}/hack/tools/bin/trivy/${VERSION}/trivy" # Builds all the container images to be scanned and cleans up changes to ./*manager_image_patch.yaml ./*manager_pull_policy.yaml. make REGISTRY=gcr.io/k8s-staging-cluster-api PULL_POLICY=IfNotPresent TAG=dev docker-build make clean-release-git # Scan the images -${TOOL_BIN}/trivy image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/clusterctl-"${GO_ARCH}":dev && R1=$? || R1=$? -${TOOL_BIN}/trivy image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/test-extension-"${GO_ARCH}":dev && R2=$? || R2=$? -${TOOL_BIN}/trivy image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/kubeadm-control-plane-controller-"${GO_ARCH}":dev && R3=$? || R3=$? -${TOOL_BIN}/trivy image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/kubeadm-bootstrap-controller-"${GO_ARCH}":dev && R4=$? || R4=$? -${TOOL_BIN}/trivy image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/cluster-api-controller-"${GO_ARCH}":dev && R5=$? || R5=$? -${TOOL_BIN}/trivy image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/capd-manager-"${GO_ARCH}":dev && R6=$? || R6=$? -${TOOL_BIN}/trivy image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/capim-manager-"${GO_ARCH}":dev && R6=$? || R6=$? +"${TRIVY}" image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/clusterctl-"${GO_ARCH}":dev && R1=$? || R1=$? +"${TRIVY}" image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/test-extension-"${GO_ARCH}":dev && R2=$? || R2=$? +"${TRIVY}" image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/kubeadm-control-plane-controller-"${GO_ARCH}":dev && R3=$? || R3=$? +"${TRIVY}" image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/kubeadm-bootstrap-controller-"${GO_ARCH}":dev && R4=$? || R4=$? +"${TRIVY}" image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/cluster-api-controller-"${GO_ARCH}":dev && R5=$? || R5=$? +"${TRIVY}" image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/capd-manager-"${GO_ARCH}":dev && R6=$? || R6=$? +"${TRIVY}" image -q --exit-code 1 --ignore-unfixed --severity MEDIUM,HIGH,CRITICAL gcr.io/k8s-staging-cluster-api/capim-manager-"${GO_ARCH}":dev && R6=$? || R6=$? echo "" BRed='\033[1;31m' diff --git a/hack/verify-licenses.sh b/hack/verify-licenses.sh new file mode 100755 index 000000000000..f1ba0af47b06 --- /dev/null +++ b/hack/verify-licenses.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Copyright 2023 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 [[ "${TRACE-0}" == "1" ]]; then + set -o xtrace +fi + +VERSION=${1} + +REPO_ROOT=$(git rev-parse --show-toplevel) +source "${REPO_ROOT}/hack/ensure-trivy.sh" + +TRIVY="${REPO_ROOT}/hack/tools/bin/trivy/${VERSION}/trivy" +$TRIVY filesystem . --license-full --config "${REPO_ROOT}/trivy.yaml" --scanners license --severity UNKNOWN,MEDIUM,HIGH,CRITICAL -f json | \ +# Specifically ignore 'github.com/hashicorp/hcl'. This is a known indirect dependency that we should remove where possible. +jq '.Results[] | select( .Licenses[]?.PkgName != "github.com/hashicorp/hcl") | if . == {} then . else error(.) end' + + + diff --git a/trivy.yaml b/trivy.yaml new file mode 100644 index 000000000000..1068882dfdfa --- /dev/null +++ b/trivy.yaml @@ -0,0 +1,142 @@ +license: + confidencelevel: "0.9" + full: "true" + # This is the list of licenses explicitly allowed by the CNCF. + # See: https://github.com/cncf/foundation/blob/main/allowed-third-party-license-policy.md + unencumbered: + - Apache-2.0 + - BSD-2-Clause + - SD-2-Clause-FreeBSD + - BSD-3-Clause + - MIT + - ISC + - Python-2.0 + - PostgreSQL + - X11 + - Zlib + # OFL-1.1 is a font license. We need to understand the current status of this license in the CNCF. + - OFL-1.1 + forbidden: + - AFL-1.1 + - AFL-1.2 + - AFL-2.0 + - AFL-2.1 + - AFL-3.0 + - AGPL-1.0 + - AGPL-3.0 + - APSL-1.0 + - APSL-1.1 + - APSL-1.2 + - APSL-2.0 + - Apache-1.0 + - Apache-1.1 + - Artistic-1.0 + - Artistic-1.0-Perl + - Artistic-1.0-cl8 + - Artistic-2.0 + - BCL + - BSD-2-Clause-NetBSD + - BSD-3-Clause-Attribution + - BSD-3-Clause-Clear + - BSD-3-Clause-LBNL + - BSD-4-Clause + - BSD-4-Clause-UC + - BSD-Protection + - BSL-1.0 + - CC-BY-1.0 + - CC-BY-2.0 + - CC-BY-2.5 + - CC-BY-3.0 + - CC-BY-4.0 + - CC-BY-NC-1.0 + - CC-BY-NC-2.0 + - CC-BY-NC-2.5 + - CC-BY-NC-3.0 + - CC-BY-NC-4.0 + - CC-BY-NC-ND-1.0 + - CC-BY-NC-ND-2.0 + - CC-BY-NC-ND-2.5 + - CC-BY-NC-ND-3.0 + - CC-BY-NC-ND-4.0 + - CC-BY-NC-SA-1.0 + - CC-BY-NC-SA-2.0 + - CC-BY-NC-SA-2.5 + - CC-BY-NC-SA-3.0 + - CC-BY-NC-SA-4.0 + - CC-BY-ND-1.0 + - CC-BY-ND-2.0 + - CC-BY-ND-2.5 + - CC-BY-ND-3.0 + - CC-BY-ND-4.0 + - CC-BY-SA-1.0 + - CC-BY-SA-2.0 + - CC-BY-SA-2.5 + - CC-BY-SA-3.0 + - CC-BY-SA-4.0 + - CDDL-1.0 + - CDDL-1.1 + - CPL-1.0 + - Commons-Clause + - EPL-1.0 + - EPL-2.0 + - FTL + - Facebook-2-Clause + - Facebook-3-Clause + - Facebook-Examples + - FreeImage + - GPL-1.0 + - GPL-2.0 + - GPL-2.0-with-GCC-exception + - GPL-2.0-with-autoconf-exception + - GPL-2.0-with-bison-exception + - GPL-2.0-with-classpath-exception + - GPL-2.0-with-font-exception + - GPL-3.0 + - GPL-3.0-with-GCC-exception + - GPL-3.0-with-autoconf-exception + - IPL-1.0 + - ImageMagick + - LGPL-2.0 + - LGPL-2.1 + - LGPL-3.0 + - LPL-1.0 + - LPL-1.02 + - Libpng + - Lil-1.0 + - Linux-OpenIB + - MPL-1.0 + - MPL-1.1 + - MPL-2.0 + - MS-PL + - NCSA + - NPL-1.0 + - NPL-1.1 + - OSL-1.0 + - OSL-1.1 + - OSL-2.0 + - OSL-2.1 + - OSL-3.0 + - OpenSSL + - PHP-3.0 + - PHP-3.01 + - PIL + - QPL-1.0 + - Ruby + - SGI-B-1.0 + - SGI-B-1.1 + - SGI-B-2.0 + - Sleepycat + - UPL-1.0 + - Unicode-DFS-2015 + - Unicode-DFS-2016 + - Unicode-TOU + - W3C + - W3C-19980720 + - W3C-20150513 + - WTFPL + - Xnet + - ZPL-1.1 + - ZPL-2.0 + - ZPL-2.1 + - Zend-2.0 + - zlib-acknowledgement \ No newline at end of file