From 348aa440dbbe77078e3ef198fb532c0f5a1dc75a Mon Sep 17 00:00:00 2001 From: Zhongcheng Lao Date: Tue, 12 Sep 2023 23:19:47 +0800 Subject: [PATCH] Add verify-import-restrictions to enforce import restrictions --- Makefile | 17 +++++++- api/.import-restrictions | 5 +++ api/v1alpha4/groupversion_info.go | 18 +++++++-- api/v1beta1/.import-restrictions | 5 +++ api/v1beta1/index/.import-restrictions | 5 +++ hack/verify-import-restrictions.sh | 55 ++++++++++++++++++++++++++ 6 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 api/.import-restrictions create mode 100644 api/v1beta1/.import-restrictions create mode 100644 api/v1beta1/index/.import-restrictions create mode 100755 hack/verify-import-restrictions.sh diff --git a/Makefile b/Makefile index 2bd6cefb9b55..554819e6d9fb 100644 --- a/Makefile +++ b/Makefile @@ -175,6 +175,11 @@ GOVULNCHECK_VER := v1.0.0 GOVULNCHECK := $(abspath $(TOOLS_BIN_DIR)/$(GOVULNCHECK_BIN)-$(GOVULNCHECK_VER)) GOVULNCHECK_PKG := golang.org/x/vuln/cmd/govulncheck +IMPORT_BOSS_BIN := import-boss +IMPORT_BOSS_VER := v0.28.1 +IMPORT_BOSS := $(abspath $(TOOLS_BIN_DIR)/$(IMPORT_BOSS_BIN)) +IMPORT_BOSS_PKG := k8s.io/code-generator/cmd/import-boss + CONVERSION_VERIFIER_BIN := conversion-verifier CONVERSION_VERIFIER := $(abspath $(TOOLS_BIN_DIR)/$(CONVERSION_VERIFIER_BIN)) @@ -607,7 +612,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 = licenses boilerplate shellcheck tiltfile modules gen conversions doctoc capi-book-summary diagrams +ALL_VERIFY_CHECKS = licenses boilerplate shellcheck tiltfile modules gen conversions doctoc capi-book-summary diagrams import-restrictions .PHONY: verify verify: $(addprefix verify-,$(ALL_VERIFY_CHECKS)) lint-dockerfiles ## Run all verify-* targets @@ -690,6 +695,10 @@ verify-security: ## Verify code and images for vulnerabilities exit 1; \ fi +.PHONY: verify-import-restrictions +verify-import-restrictions: $(IMPORT_BOSS) ## Verify import restrictions with import-boss + ./hack/verify-import-restrictions.sh + ## -------------------------------------- ## Binaries ## -------------------------------------- @@ -1305,6 +1314,9 @@ $(GOLANGCI_LINT_BIN): $(GOLANGCI_LINT) ## Build a local copy of golangci-lint. .PHONY: $(GOVULNCHECK_BIN) $(GOVULNCHECK_BIN): $(GOVULNCHECK) ## Build a local copy of govulncheck. +.PHONY: $(IMPORT_BOSS_BIN) +$(IMPORT_BOSS_BIN): $(IMPORT_BOSS) + $(CONTROLLER_GEN): # Build controller-gen from tools folder. GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(CONTROLLER_GEN_PKG) $(CONTROLLER_GEN_BIN) $(CONTROLLER_GEN_VER) @@ -1359,6 +1371,9 @@ $(GOLANGCI_LINT): # Build golangci-lint from tools folder. $(GOVULNCHECK): # Build govulncheck. GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(GOVULNCHECK_PKG) $(GOVULNCHECK_BIN) $(GOVULNCHECK_VER) +$(IMPORT_BOSS): # Build import-boss + GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) $(IMPORT_BOSS_PKG) $(IMPORT_BOSS_BIN) $(IMPORT_BOSS_VER) + ## -------------------------------------- ## Helpers ## -------------------------------------- diff --git a/api/.import-restrictions b/api/.import-restrictions new file mode 100644 index 000000000000..f6f10b3ff544 --- /dev/null +++ b/api/.import-restrictions @@ -0,0 +1,5 @@ +rules: + - selectorRegexp: sigs[.]k8s[.]io/controller-runtime + allowedPrefixes: + - "sigs.k8s.io/controller-runtime/pkg/conversion" + forbiddenPrefixes: [] diff --git a/api/v1alpha4/groupversion_info.go b/api/v1alpha4/groupversion_info.go index 382657c78967..cd8adb96d73e 100644 --- a/api/v1alpha4/groupversion_info.go +++ b/api/v1alpha4/groupversion_info.go @@ -20,8 +20,9 @@ limitations under the License. package v1alpha4 import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" ) var ( @@ -29,10 +30,19 @@ var ( GroupVersion = schema.GroupVersion{Group: "cluster.x-k8s.io", Version: "v1alpha4"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme. - SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) // AddToScheme adds the types in this group-version to the given scheme. - AddToScheme = SchemeBuilder.AddToScheme + AddToScheme = schemeBuilder.AddToScheme - localSchemeBuilder = SchemeBuilder.SchemeBuilder + objectTypes = []runtime.Object{} + + // localSchemeBuilder is used for type conversions. + localSchemeBuilder = schemeBuilder ) + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(GroupVersion, objectTypes...) + metav1.AddToGroupVersion(scheme, GroupVersion) + return nil +} diff --git a/api/v1beta1/.import-restrictions b/api/v1beta1/.import-restrictions new file mode 100644 index 000000000000..a2e1dfd08133 --- /dev/null +++ b/api/v1beta1/.import-restrictions @@ -0,0 +1,5 @@ +rules: + - selectorRegexp: sigs[.]k8s[.]io/controller-runtime + allowedPrefixes: [] + forbiddenPrefixes: + - "sigs.k8s.io/controller-runtime" diff --git a/api/v1beta1/index/.import-restrictions b/api/v1beta1/index/.import-restrictions new file mode 100644 index 000000000000..b3ee9a15dbda --- /dev/null +++ b/api/v1beta1/index/.import-restrictions @@ -0,0 +1,5 @@ +rules: + - selectorRegexp: sigs[.]k8s[.]io/controller-runtime + allowedPrefixes: + - "sigs.k8s.io/controller-runtime" + forbiddenPrefixes: [] diff --git a/hack/verify-import-restrictions.sh b/hack/verify-import-restrictions.sh new file mode 100755 index 000000000000..818503a72f06 --- /dev/null +++ b/hack/verify-import-restrictions.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env 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. + +# This script checks import restrictions. The script looks for a file called +# `.import-restrictions` in each directory, then all imports of the package are +# checked against each "rule" in the file. +# Usage: `hack/verify-import-restrictions.sh`. + +set -o errexit +set -o nounset +set -o pipefail + +sub_packages=( + "api" +) + +packages=() +visit() { + local count=0 + for file in "$1"/* ; do + if [ -d "$file" ]; then + visit "$file" + elif [ -f "$file" ]; then + ((count += 1)) + fi + done + if [ "$count" -gt 0 ]; then + # import-boss may not accept directories without any sources + packages+=("./$1") + fi +} +for d in "${sub_packages[@]}"; do + visit "$d" +done + +INPUT_DIRS="$(IFS=, ; echo "${packages[*]}")" +echo "Enforcing imports in source codes under the following directories: ${INPUT_DIRS}" + +# Make sure GOPATH is unset to avoid behavior inconsistency +# as import-boss will go through the sources +unset GOPATH +import-boss --include-test-files=true --verify-only --input-dirs "${INPUT_DIRS}"