...
1#!/usr/bin/env bash
2
3# Copyright 2021 The Kubernetes Authors.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17# This script validates that only a restricted set of packages are importing
18# github.com/prometheus/*
19
20# NOTE: this is not the same as verify-imports which can only verify
21# that within a particular package the imports made are allowed.
22#
23# This is also not the same thing as verify-import-boss, which is pretty
24# powerful for specifying restricted imports but does not scale to checking
25# the entire source tree well and is only enabled for specific packages.
26#
27# See: https://github.com/kubernetes/kubernetes/issues/99876
28
29set -o errexit
30set -o nounset
31set -o pipefail
32
33KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
34source "${KUBE_ROOT}/hack/lib/init.sh"
35source "${KUBE_ROOT}/hack/lib/util.sh"
36
37# See: https://github.com/kubernetes/kubernetes/issues/89267
38allowed_prometheus_importers=(
39 ./cluster/images/etcd-version-monitor/etcd-version-monitor.go
40 ./staging/src/k8s.io/component-base/metrics/prometheusextension/timing_histogram.go
41 ./staging/src/k8s.io/component-base/metrics/prometheusextension/timing_histogram_test.go
42 ./staging/src/k8s.io/component-base/metrics/prometheusextension/timing_histogram_vec.go
43 ./staging/src/k8s.io/component-base/metrics/prometheusextension/weighted_histogram.go
44 ./staging/src/k8s.io/component-base/metrics/prometheusextension/weighted_histogram_test.go
45 ./staging/src/k8s.io/component-base/metrics/prometheusextension/weighted_histogram_vec.go
46 ./staging/src/k8s.io/component-base/metrics/buckets.go
47 ./staging/src/k8s.io/component-base/metrics/collector.go
48 ./staging/src/k8s.io/component-base/metrics/collector_test.go
49 ./staging/src/k8s.io/component-base/metrics/counter.go
50 ./staging/src/k8s.io/component-base/metrics/counter_test.go
51 ./staging/src/k8s.io/component-base/metrics/desc.go
52 ./staging/src/k8s.io/component-base/metrics/gauge.go
53 ./staging/src/k8s.io/component-base/metrics/gauge_test.go
54 ./staging/src/k8s.io/component-base/metrics/histogram.go
55 ./staging/src/k8s.io/component-base/metrics/histogram_test.go
56 ./staging/src/k8s.io/component-base/metrics/http.go
57 ./staging/src/k8s.io/component-base/metrics/labels.go
58 ./staging/src/k8s.io/component-base/metrics/legacyregistry/registry.go
59 ./staging/src/k8s.io/component-base/metrics/metric.go
60 ./staging/src/k8s.io/component-base/metrics/opts.go
61 ./staging/src/k8s.io/component-base/metrics/processstarttime_others.go
62 ./staging/src/k8s.io/component-base/metrics/registry.go
63 ./staging/src/k8s.io/component-base/metrics/registry_test.go
64 ./staging/src/k8s.io/component-base/metrics/summary.go
65 ./staging/src/k8s.io/component-base/metrics/testutil/metrics.go
66 ./staging/src/k8s.io/component-base/metrics/testutil/metrics_test.go
67 ./staging/src/k8s.io/component-base/metrics/testutil/promlint.go
68 ./staging/src/k8s.io/component-base/metrics/testutil/testutil.go
69 ./staging/src/k8s.io/component-base/metrics/timing_histogram_test.go
70 ./staging/src/k8s.io/component-base/metrics/value.go
71 ./staging/src/k8s.io/component-base/metrics/wrappers.go
72 ./test/e2e/apimachinery/flowcontrol.go
73 ./test/e2e_node/mirror_pod_grace_period_test.go
74 ./test/e2e/node/pods.go
75 ./test/e2e_node/resource_metrics_test.go
76 ./test/instrumentation/main_test.go
77 ./test/integration/apiserver/flowcontrol/concurrency_test.go
78 ./test/integration/apiserver/flowcontrol/concurrency_util_test.go
79 ./test/integration/metrics/metrics_test.go
80)
81
82# Go imports always involve a double quoted string of the package path
83# https://golang.org/ref/spec#Import_declarations
84#
85# If you *really* need a string literal that looks like "github.com/prometheus/.*"
86# somewhere else that actually isn't an import, you can use backticks / a raw
87# string literal instead (which cannot be used in imports, only double quotes).
88#
89# NOTE: we previously had an implementation that checked for an actual import
90# as a post-processing step on the matching files, which is cheap enough and
91# accurate, except that it's difficult to guarantee we check for all supported
92# GOOS, GOARCH, and other build tags, and we want to prevent all imports.
93# So we dropped this, in favor of only the grep call.
94# See: https://github.com/kubernetes/kubernetes/pull/100552
95really_failing_files=()
96all_failing_files=()
97while IFS='' read -r filepath; do
98 # convert from file to package, and only insert unique results
99 # we want to minimize the amount of `go list` calls we need to make
100 if ! kube::util::array_contains "$filepath" "${allowed_prometheus_importers[@]}"; then
101 # record a failure if not
102 really_failing_files+=("$filepath")
103 fi
104 all_failing_files+=("$filepath")
105done < <(cd "${KUBE_ROOT}" && grep \
106 --exclude-dir={_output,vendor} \
107 --include='*.go' \
108 -R . \
109 -l \
110 -Ee '"github.com/prometheus/.*"' \
111| LC_ALL=C sort -u)
112
113# check for any files we're allowing to fail that are no longer failing, so we
114# can enforce that the list shrinks
115allowed_but_not_failing=()
116for allowed_file in "${allowed_prometheus_importers[@]}"; do
117 if ! kube::util::array_contains "$allowed_file" "${all_failing_files[@]}"; then
118 allowed_but_not_failing+=("$allowed_file")
119 fi
120done
121
122# we will exit with this at the end of the script depending on the checks below
123exit_code=0
124
125# check for files we've allow-listed that no longer need to be
126if [ -n "${allowed_but_not_failing[*]}" ]; then
127 {
128 echo "ERROR: Some files allow-listed to import prometheus are no longer failing and should be removed."
129 echo "Please remove these files from allowed_prometheus_importers in hack/verify-prometheus-imports.sh"
130 echo ""
131 echo "Non-failing but allow-listed files:"
132 for non_failing_file in "${allowed_but_not_failing[@]}"; do
133 echo " ${non_failing_file}"
134 done
135 } >&2
136 exit_code=1
137fi
138# check for files that fail but are not allow-listed
139if [ -n "${really_failing_files[*]}" ]; then
140 {
141 echo "ERROR: Some files are importing packages under github.com/prometheus/* but are not allow-listed to do so."
142 echo ""
143 echo "See: https://github.com/kubernetes/kubernetes/issues/89267"
144 echo ""
145 echo "Failing files:"
146 for failing_file in "${really_failing_files[@]}"; do
147 echo " ${failing_file}"
148 done
149 } >&2
150 exit_code=2
151fi
152
153exit "$exit_code"
View as plain text