mirror of https://github.com/knative/client.git
upgrade to latest dependencies (#1120)
Signed-off-by: Knative Automation <automation@knative.team>
This commit is contained in:
parent
dca9561993
commit
10128901aa
10
go.mod
10
go.mod
|
|
@ -22,11 +22,11 @@ require (
|
|||
k8s.io/cli-runtime v0.18.8
|
||||
k8s.io/client-go v11.0.1-0.20190805182717-6502b5e7b1b5+incompatible
|
||||
k8s.io/code-generator v0.18.8
|
||||
knative.dev/eventing v0.19.0
|
||||
knative.dev/hack v0.0.0-20201103151104-3d5abc3a0075
|
||||
knative.dev/networking v0.0.0-20201103163404-b9f80f4537af
|
||||
knative.dev/pkg v0.0.0-20201103163404-5514ab0c1fdf
|
||||
knative.dev/serving v0.19.0
|
||||
knative.dev/eventing v0.19.1-0.20201117061051-47ee6e3586ca
|
||||
knative.dev/hack v0.0.0-20201112185459-01a34c573bd8
|
||||
knative.dev/networking v0.0.0-20201117131851-29d71950ee3d
|
||||
knative.dev/pkg v0.0.0-20201117020252-ab1a398f669c
|
||||
knative.dev/serving v0.19.1-0.20201117120351-3e2a380308b2
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
)
|
||||
|
||||
|
|
|
|||
30
go.sum
30
go.sum
|
|
@ -202,7 +202,6 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
|
|||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
|
|
@ -1182,11 +1181,9 @@ honnef.co/go/tools v0.0.1-2020.1.5 h1:nI5egYTGJakVyOryqLs1cQO5dO0ksin5XXs2pspk75
|
|||
honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.18.8 h1:aIKUzJPb96f3fKec2lxtY7acZC9gQNDLVhfSGpxBAC4=
|
||||
k8s.io/api v0.18.8/go.mod h1:d/CXqwWv+Z2XEG1LgceeDmHQwpUJhROPx16SlxJgERY=
|
||||
k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio=
|
||||
k8s.io/apiextensions-apiserver v0.18.8/go.mod h1:7f4ySEkkvifIr4+BRrRWriKKIJjPyg9mb/p63dJKnlM=
|
||||
k8s.io/apimachinery v0.18.8 h1:jimPrycCqgx2QPearX3to1JePz7wSbVLq+7PdBTTwQ0=
|
||||
k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig=
|
||||
k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8=
|
||||
k8s.io/apiserver v0.18.8/go.mod h1:12u5FuGql8Cc497ORNj79rhPdiXQC4bf53X/skR/1YM=
|
||||
k8s.io/cli-runtime v0.18.8 h1:ycmbN3hs7CfkJIYxJAOB10iW7BVPmXGXkfEyiV9NJ+k=
|
||||
k8s.io/cli-runtime v0.18.8/go.mod h1:7EzWiDbS9PFd0hamHHVoCY4GrokSTPSL32MA4rzIu0M=
|
||||
|
|
@ -1195,7 +1192,6 @@ k8s.io/client-go v0.18.8/go.mod h1:HqFqMllQ5NnQJNwjro9k5zMyfhZlOwpuTLVrxjkYSxU=
|
|||
k8s.io/cloud-provider v0.18.8/go.mod h1:cn9AlzMPVIXA4HHLVbgGUigaQlZyHSZ7WAwDEFNrQSs=
|
||||
k8s.io/code-generator v0.18.8 h1:lgO1P1wjikEtzNvj7ia+x1VC4svJ28a/r0wnOLhhOTU=
|
||||
k8s.io/code-generator v0.18.8/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
|
||||
k8s.io/component-base v0.18.4/go.mod h1:7jr/Ef5PGmKwQhyAz/pjByxJbC58mhKAhiaDu0vXfPk=
|
||||
k8s.io/component-base v0.18.8/go.mod h1:00frPRDas29rx58pPCxNkhUfPbwajlyyvu8ruNgSErU=
|
||||
k8s.io/csi-translation-lib v0.18.8/go.mod h1:6cA6Btlzxy9s3QrS4BCZzQqclIWnTLr6Jx3H2ctAzY4=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
|
|
@ -1215,20 +1211,22 @@ k8s.io/legacy-cloud-providers v0.18.8/go.mod h1:tgp4xYf6lvjrWnjQwTOPvWQE9IVqSBGP
|
|||
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20200603063816-c1c6865ac451 h1:v8ud2Up6QK1lNOKFgiIVrZdMg7MpmSnvtrOieolJKoE=
|
||||
k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
knative.dev/caching v0.0.0-20201104174804-1a305923cfbe/go.mod h1:twy5Yz5LtFbmihtbBG0CcgwJzV5d8RUBoGkZFs7uRQs=
|
||||
knative.dev/eventing v0.19.0 h1:9TdB1E4mwGYnuAJxSbNoljVsZRM+HUKEgsWiBXUIZEc=
|
||||
knative.dev/eventing v0.19.0/go.mod h1:jwhDgDvoscWE4jWF8cXh7yHfxJcK0mTawVKVfrSjnvg=
|
||||
knative.dev/hack v0.0.0-20201102193445-9349aeeb6701 h1:at6mUfi8gHWlBRd/qNM66JvUQ4C964cOpsy9hzac+7c=
|
||||
knative.dev/hack v0.0.0-20201102193445-9349aeeb6701/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||
knative.dev/caching v0.0.0-20201113182901-ee88f744543c/go.mod h1:gGr7clElRu3BOrGHex96ZjEPIM7+5dDd5XHeIRle4vE=
|
||||
knative.dev/eventing v0.19.1-0.20201117061051-47ee6e3586ca h1:WFTkuMRlPvcLaNBdbM5y5xOxVDzzETOhBEBkznVPV5I=
|
||||
knative.dev/eventing v0.19.1-0.20201117061051-47ee6e3586ca/go.mod h1:I5ysDZ5GyEut5p+jVHfuBKk33agLfqKJaF4kQpwvS2M=
|
||||
knative.dev/hack v0.0.0-20201103151104-3d5abc3a0075 h1:YAgWplKIy4O5e3F5vUUECmXAAyZ0M5ymo6fCt1jeZhs=
|
||||
knative.dev/hack v0.0.0-20201103151104-3d5abc3a0075/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||
knative.dev/networking v0.0.0-20201103163404-b9f80f4537af h1:xPS3bRfp30XHb69B0F9Pgv4Nc2eTfJHWR0TzVRHf1hU=
|
||||
knative.dev/networking v0.0.0-20201103163404-b9f80f4537af/go.mod h1:0OaR4FLbs3Xn6UjeX1zYql9RWO8sLTO/ZMJS4jDbfFE=
|
||||
knative.dev/pkg v0.0.0-20201103150904-7f1970af5b6f/go.mod h1:2hMxAUviPH2nl3BuODx5L6shYCdzA+7SPzQpdkcg9wc=
|
||||
knative.dev/pkg v0.0.0-20201103163404-5514ab0c1fdf h1:QwULgRwcv6R3Ya1GZlf/E1atcaGUNw4DKjxSQUfcR6U=
|
||||
knative.dev/pkg v0.0.0-20201103163404-5514ab0c1fdf/go.mod h1:cuKOgUvJvnWHIps/apCXX8wZuMlT0dyMZLqRQfsENbQ=
|
||||
knative.dev/serving v0.19.0 h1:aXJs15J7FKocVFxB+PTS2Yned2+8fvrgxMQH2sV/DWM=
|
||||
knative.dev/serving v0.19.0/go.mod h1:G5FVEbwcHKLvf8XTr6XEVqLd3tn31JX8vGFEI8kdYlk=
|
||||
knative.dev/hack v0.0.0-20201112185459-01a34c573bd8 h1:RNbZsAjhswBPtl4C5C5gEFX5/GfWIOZQxfYD9DhkHdY=
|
||||
knative.dev/hack v0.0.0-20201112185459-01a34c573bd8/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
|
||||
knative.dev/networking v0.0.0-20201116165202-57530ee4cbfc/go.mod h1:DCZ5pdCpaPkgvwSvgFzDXSDjZ2dByl+tMIHlXV4wvws=
|
||||
knative.dev/networking v0.0.0-20201117131851-29d71950ee3d h1:MLhF77IJoVjMKTK6cNht+X4G9L1r5dJHGfLv5w07K94=
|
||||
knative.dev/networking v0.0.0-20201117131851-29d71950ee3d/go.mod h1:/+3beeK3eK+igEo/0GHtqGlUXJDhSScMI4/pnHojIUc=
|
||||
knative.dev/pkg v0.0.0-20201112201059-93fedf141385/go.mod h1:5vNHKNtZtzlNeNrcDoUtZIn+dma/8DjmpjfdHiwoQyM=
|
||||
knative.dev/pkg v0.0.0-20201116214403-188df22c59ac/go.mod h1:4kXxEyYWdNk3pUR6/cx/ToMKG/dAJvEpDYUfV5RYHeU=
|
||||
knative.dev/pkg v0.0.0-20201117020252-ab1a398f669c h1:dMBwabvusJrldjzIj4lces/96SnVgFXV7Kpv9z9fiCI=
|
||||
knative.dev/pkg v0.0.0-20201117020252-ab1a398f669c/go.mod h1:4kXxEyYWdNk3pUR6/cx/ToMKG/dAJvEpDYUfV5RYHeU=
|
||||
knative.dev/serving v0.19.1-0.20201117120351-3e2a380308b2 h1:D3+uDOvUfrAvlVGqqzN+nlpWub22xX/9QkbhpKTRZ9A=
|
||||
knative.dev/serving v0.19.1-0.20201117120351-3e2a380308b2/go.mod h1:/Y2mRdW1VwRW0K3yqLGKZbakSK+4ihWHbs08NAO9ppE=
|
||||
pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
|
|
|
|||
|
|
@ -124,8 +124,7 @@ func (sb *SinkBinding) Do(ctx context.Context, ps *duckv1.WithPod) {
|
|||
spec.InitContainers[i].Env = append(spec.InitContainers[i].Env, corev1.EnvVar{
|
||||
Name: "K_SINK",
|
||||
Value: uri.String(),
|
||||
})
|
||||
spec.InitContainers[i].Env = append(spec.InitContainers[i].Env, corev1.EnvVar{
|
||||
}, corev1.EnvVar{
|
||||
Name: "K_CE_OVERRIDES",
|
||||
Value: ceOverrides,
|
||||
})
|
||||
|
|
@ -134,8 +133,7 @@ func (sb *SinkBinding) Do(ctx context.Context, ps *duckv1.WithPod) {
|
|||
spec.Containers[i].Env = append(spec.Containers[i].Env, corev1.EnvVar{
|
||||
Name: "K_SINK",
|
||||
Value: uri.String(),
|
||||
})
|
||||
spec.Containers[i].Env = append(spec.Containers[i].Env, corev1.EnvVar{
|
||||
}, corev1.EnvVar{
|
||||
Name: "K_CE_OVERRIDES",
|
||||
Value: ceOverrides,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ benchmarking jobs for each repo. To use it:
|
|||
- `SERVICE_ACCOUNT_NAME`: Service account name for controlling GKE clusters
|
||||
and interacting with [Mako](https://github.com/google/mako) server. It MUST
|
||||
have `Kubernetes Engine Admin` and `Storage Admin` role, and be
|
||||
[whitelisted](https://github.com/google/mako/blob/master/docs/ACCESS.md) by
|
||||
[allowed](https://github.com/google/mako/blob/master/docs/ACCESS.md) by
|
||||
Mako admin. Defaults to `mako-job`.
|
||||
|
||||
1. [optional] Customize root path of the benchmarks. This root folder should
|
||||
|
|
|
|||
|
|
@ -353,13 +353,10 @@ function report_go_test() {
|
|||
report="$(mktemp)"
|
||||
local xml
|
||||
xml="$(mktemp_with_extension "${ARTIFACTS}"/junit_XXXXXXXX xml)"
|
||||
local json
|
||||
json="$(mktemp_with_extension "${ARTIFACTS}"/json_XXXXXXXX json)"
|
||||
echo "Running go test with args: ${go_test_args[*]}"
|
||||
# TODO(chizhg): change to `--format testname`?
|
||||
capture_output "${report}" gotestsum --format "${GO_TEST_VERBOSITY:-standard-verbose}" \
|
||||
--junitfile "${xml}" --junitfile-testsuite-name relative --junitfile-testcase-classname relative \
|
||||
--jsonfile "${json}" \
|
||||
-- "${go_test_args[@]}"
|
||||
local failed=$?
|
||||
echo "Finished run, return code is ${failed}"
|
||||
|
|
@ -517,7 +514,7 @@ function go_update_deps() {
|
|||
echo "=== Update Deps for Golang"
|
||||
|
||||
local UPGRADE=0
|
||||
local VERSION="master"
|
||||
local VERSION="v9000.1" # release v9000 is so far in the future, it will always pick the default branch.
|
||||
local DOMAIN="knative.dev"
|
||||
while [[ $# -ne 0 ]]; do
|
||||
parameter=$1
|
||||
|
|
|
|||
|
|
@ -65,7 +65,10 @@ func NewLogger(configJSON string, levelOverride string, opts ...zap.Option) (*za
|
|||
if err2 != nil {
|
||||
panic(err2)
|
||||
}
|
||||
return enrichLoggerWithCommitID(logger.Named(fallbackLoggerName)), loggingCfg.Level
|
||||
|
||||
slogger := enrichLoggerWithCommitID(logger.Named(fallbackLoggerName))
|
||||
slogger.Warnw("Failed to parse logging config - using default zap production config", zap.Error(err))
|
||||
return slogger, loggingCfg.Level
|
||||
}
|
||||
|
||||
func enrichLoggerWithCommitID(logger *zap.Logger) *zap.SugaredLogger {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,9 @@ const (
|
|||
defaultPrometheusPort = 9090
|
||||
maxPrometheusPort = 65535
|
||||
minPrometheusPort = 1024
|
||||
defaultPrometheusHost = "0.0.0.0"
|
||||
prometheusPortEnvName = "METRICS_PROMETHEUS_PORT"
|
||||
prometheusHostEnvName = "METRICS_PROMETHEUS_HOST"
|
||||
)
|
||||
|
||||
// Metrics backend "enum".
|
||||
|
|
@ -105,6 +107,10 @@ type metricsConfig struct {
|
|||
// format. It defaults to 9090.
|
||||
prometheusPort int
|
||||
|
||||
// prometheusHost is the host where the metrics are exposed in Prometheus
|
||||
// format. It defaults to "0.0.0.0"
|
||||
prometheusHost string
|
||||
|
||||
// ---- Stackdriver specific below ----
|
||||
// True if backendDestination equals to "stackdriver". Store this in a variable
|
||||
// to reduce string comparison operations.
|
||||
|
|
@ -240,6 +246,7 @@ func createMetricsConfig(ctx context.Context, ops ExporterOptions) (*metricsConf
|
|||
}
|
||||
|
||||
mc.prometheusPort = pp
|
||||
mc.prometheusHost = prometheusHost()
|
||||
case stackdriver:
|
||||
// If stackdriverClientConfig is not provided for stackdriver backend destination, OpenCensus will try to
|
||||
// use the application default credentials. If that is not available, Opencensus would fail to create the
|
||||
|
|
@ -341,6 +348,17 @@ func prometheusPort() (int, error) {
|
|||
return int(pp), nil
|
||||
}
|
||||
|
||||
// prometheusHost returns the host configured via the environment
|
||||
// for the Prometheus metrics exporter if it's set, a default value otherwise.
|
||||
// No validation is done here.
|
||||
func prometheusHost() string {
|
||||
phStr := os.Getenv(prometheusHostEnvName)
|
||||
if phStr == "" {
|
||||
return defaultPrometheusHost
|
||||
}
|
||||
return phStr
|
||||
}
|
||||
|
||||
// JSONToOptions converts a json string to ExporterOptions.
|
||||
func JSONToOptions(jsonOpts string) (*ExporterOptions, error) {
|
||||
var opts ExporterOptions
|
||||
|
|
|
|||
|
|
@ -66,10 +66,15 @@ type ExporterOptions struct {
|
|||
|
||||
// PrometheusPort is the port to expose metrics if metrics backend is Prometheus.
|
||||
// It should be between maxPrometheusPort and maxPrometheusPort. 0 value means
|
||||
// using the default 9090 value. If is ignored if metrics backend is not
|
||||
// using the default 9090 value. It is ignored if metrics backend is not
|
||||
// Prometheus.
|
||||
PrometheusPort int
|
||||
|
||||
// PrometheusHost is the host to expose metrics on if metrics backend is Prometheus.
|
||||
// The default value is "0.0.0.0". It is ignored if metrics backend is not
|
||||
// Prometheus.
|
||||
PrometheusHost string
|
||||
|
||||
// ConfigMap is the data from config map config-observability. Must be present.
|
||||
// See https://github.com/knative/serving/blob/master/config/config-observability.yaml
|
||||
// for details.
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ limitations under the License.
|
|||
package metrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
prom "contrib.go.opencensus.io/exporter/prometheus"
|
||||
|
|
@ -41,6 +41,7 @@ func (emptyPromExporter) ExportView(viewData *view.Data) {
|
|||
// a signal to enrich the internal Meters with Resource information.
|
||||
}
|
||||
|
||||
//nolint: unparam // False positive of flagging the second result of this function unused.
|
||||
func newPrometheusExporter(config *metricsConfig, logger *zap.SugaredLogger) (view.Exporter, ResourceExporterFactory, error) {
|
||||
e, err := prom.NewExporter(prom.Options{Namespace: config.component})
|
||||
if err != nil {
|
||||
|
|
@ -50,7 +51,7 @@ func newPrometheusExporter(config *metricsConfig, logger *zap.SugaredLogger) (vi
|
|||
logger.Infof("Created Opencensus Prometheus exporter with config: %v. Start the server for Prometheus exporter.", config)
|
||||
// Start the server for Prometheus scraping
|
||||
go func() {
|
||||
srv := startNewPromSrv(e, config.prometheusPort)
|
||||
srv := startNewPromSrv(e, config.prometheusHost, config.prometheusPort)
|
||||
srv.ListenAndServe()
|
||||
}()
|
||||
return e,
|
||||
|
|
@ -73,7 +74,7 @@ func resetCurPromSrv() {
|
|||
}
|
||||
}
|
||||
|
||||
func startNewPromSrv(e *prom.Exporter, port int) *http.Server {
|
||||
func startNewPromSrv(e *prom.Exporter, host string, port int) *http.Server {
|
||||
sm := http.NewServeMux()
|
||||
sm.Handle("/metrics", e)
|
||||
curPromSrvMux.Lock()
|
||||
|
|
@ -82,7 +83,7 @@ func startNewPromSrv(e *prom.Exporter, port int) *http.Server {
|
|||
curPromSrv.Close()
|
||||
}
|
||||
curPromSrv = &http.Server{
|
||||
Addr: fmt.Sprint(":", port),
|
||||
Addr: host + ":" + strconv.Itoa(port),
|
||||
Handler: sm,
|
||||
}
|
||||
return curPromSrv
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -54,6 +55,16 @@ const (
|
|||
// included in request metrics.
|
||||
ProbeHeaderName = "K-Network-Probe"
|
||||
|
||||
// ProbeHeaderValue is the value of a header that can be added to
|
||||
// requests to probe the knative networking layer. Requests
|
||||
// with `K-Network-Probe` this value will not be passed to the user
|
||||
// container or included in request metrics.
|
||||
ProbeHeaderValue = "probe"
|
||||
|
||||
// HashHeaderName is the name of an internal header that Ingress controller
|
||||
// uses to find out which version of the networking config is deployed.
|
||||
HashHeaderName = "K-Network-Hash"
|
||||
|
||||
// Since K8s 1.8, prober requests have
|
||||
// User-Agent = "kube-probe/{major-version}.{minor-version}".
|
||||
KubeProbeUAPrefix = "kube-probe/"
|
||||
|
|
@ -68,3 +79,19 @@ func IsKubeletProbe(r *http.Request) bool {
|
|||
return strings.HasPrefix(r.Header.Get("User-Agent"), KubeProbeUAPrefix) ||
|
||||
r.Header.Get(KubeletProbeHeaderName) != ""
|
||||
}
|
||||
|
||||
// IsKProbe returns true if the request is a knatvie probe.
|
||||
func IsKProbe(r *http.Request) bool {
|
||||
return r.Header.Get(ProbeHeaderName) == ProbeHeaderValue
|
||||
}
|
||||
|
||||
// ServeKProbe serve KProbe requests.
|
||||
func ServeKProbe(w http.ResponseWriter, r *http.Request) {
|
||||
hh := r.Header.Get(HashHeaderName)
|
||||
if hh == "" {
|
||||
http.Error(w, fmt.Sprintf("a probe request must contain a non-empty %q header", HashHeaderName), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
w.Header().Set(HashHeaderName, hh)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
memory_encoder.go coverage-excluded=true
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
Copyright 2020 The Knative 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 logging assists setting up test logging and using leveled logging in tests.
|
||||
|
||||
The TLogger is designed to assist the test writer in creating more useful tests and
|
||||
collecting log data in multiple streams, optimizing for human readability in one and
|
||||
machine readability in another. It's designed to mimic the testing.T object rather closely and
|
||||
use Zap logging semantics, both things already in use in Knative, to minimize the time developers
|
||||
need to spend learning the tool.
|
||||
|
||||
Inspired by and uses go-logr.
|
||||
|
||||
Advantages
|
||||
|
||||
The TLogger enhances test design through subtle nudges and affordances:
|
||||
|
||||
* It encourages only logging with .V(), giving the writer a nudge to think about how important it is,
|
||||
but without requiring them to fit it in a narrowly-defined category.
|
||||
|
||||
* Reduces boilerplate of carrying around context for errors in several different variables,
|
||||
using .WithValues(), which results in more consistent and reusable code across the tests.
|
||||
|
||||
Porting
|
||||
|
||||
To port code from using testing.T to logging.TLogger, the interfaces knative.dev/pkg/test.T and
|
||||
knative.dev/pkg/test.TLegacy have been created. All library functions should be refactored to use
|
||||
one interface and all .Log() calls rewritten to use structured format, which works with testing and
|
||||
TLogger. If a library function needs test functions not available even in test.TLegacy,
|
||||
it's probably badly written.
|
||||
|
||||
Then any test can be incrementally rewritten to use TLogger, as it coexists with testing.T without issue.
|
||||
|
||||
*/
|
||||
package logging
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
Copyright 2020 The Knative 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 logging
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
// StructuredError is an error which can hold arbitrary key-value arguments.
|
||||
//
|
||||
// TODO(coryrc): The Structured Error is experimental and likely to be removed, but is currently in use in a refactored test.
|
||||
type StructuredError interface {
|
||||
error
|
||||
GetValues() []interface{}
|
||||
WithValues(...interface{}) StructuredError
|
||||
DisableValuePrinting()
|
||||
EnableValuePrinting()
|
||||
}
|
||||
|
||||
type structuredError struct {
|
||||
msg string
|
||||
keysAndValues []interface{}
|
||||
print bool
|
||||
}
|
||||
|
||||
func keysAndValuesToSpewedMap(args ...interface{}) map[string]string {
|
||||
m := make(map[string]string, len(args)/2)
|
||||
for i := 0; i < len(args); i += 2 {
|
||||
key, val := args[i], args[i+1]
|
||||
if keyStr, ok := key.(string); ok {
|
||||
m[keyStr] = spew.Sdump(val)
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// Error implements `error` interface
|
||||
func (e structuredError) Error() string {
|
||||
// TODO(coryrc): accept zap.Field entries?
|
||||
if e.print {
|
||||
// %v for fmt.Sprintf does print keys sorted
|
||||
return fmt.Sprintf("Error: %s\nContext:\n%v", e.msg, keysAndValuesToSpewedMap(e.keysAndValues...))
|
||||
}
|
||||
return e.msg
|
||||
}
|
||||
|
||||
// GetValues gives you the structured key values in a plist
|
||||
func (e structuredError) GetValues() []interface{} {
|
||||
return e.keysAndValues
|
||||
}
|
||||
|
||||
// DisableValuePrinting disables printing out the keys and values from the Error() method
|
||||
func (e *structuredError) DisableValuePrinting() {
|
||||
e.print = false
|
||||
}
|
||||
|
||||
// EnableValuePrinting enables printing out the keys and values from the Error() method
|
||||
func (e *structuredError) EnableValuePrinting() {
|
||||
e.print = true
|
||||
}
|
||||
|
||||
// Create a StructuredError. Gives a little better logging when given to a TLogger.
|
||||
// This may prove to not be useful if users use the logger's WithValues() better.
|
||||
func Error(msg string, keysAndValues ...interface{}) error {
|
||||
return &structuredError{msg, keysAndValues, true}
|
||||
}
|
||||
|
||||
// WithValues operates just like TLogger's WithValues but stores them in the error object.
|
||||
func (e *structuredError) WithValues(keysAndValues ...interface{}) StructuredError {
|
||||
newKAV := make([]interface{}, 0, len(keysAndValues)+len(e.keysAndValues))
|
||||
newKAV = append(newKAV, e.keysAndValues...)
|
||||
newKAV = append(newKAV, keysAndValues...)
|
||||
return &structuredError{e.msg, newKAV, e.print}
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
// Copyright 2020 The Knative Authors
|
||||
// Copyright (c) 2017 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
// Copying testingWriter from zaptest and allowing it to be disabled
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// testingWriter is a WriteSyncer that writes to the given testing.TB.
|
||||
type testingWriter struct {
|
||||
t *testing.T
|
||||
|
||||
// If true, the test will be marked as failed if this testingWriter is
|
||||
// ever used.
|
||||
markFailed bool
|
||||
}
|
||||
|
||||
func newTestingWriter(t *testing.T) testingWriter {
|
||||
return testingWriter{t: t}
|
||||
}
|
||||
|
||||
// WithMarkFailed returns a copy of this testingWriter with markFailed set to
|
||||
// the provided value.
|
||||
func (w testingWriter) WithMarkFailed(v bool) testingWriter {
|
||||
w.markFailed = v
|
||||
return w
|
||||
}
|
||||
|
||||
func (w testingWriter) Write(p []byte) (n int, err error) {
|
||||
if w.t == nil {
|
||||
return 0, errors.New("Write to buffer after test function completed")
|
||||
}
|
||||
n = len(p)
|
||||
|
||||
// Strip trailing newline because t.Log always adds one.
|
||||
p = bytes.TrimRight(p, "\n")
|
||||
|
||||
// Note: t.Log is safe for concurrent use.
|
||||
w.t.Logf("%s", p)
|
||||
if w.markFailed {
|
||||
w.t.Fail()
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (w testingWriter) Sync() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *testingWriter) Disable() {
|
||||
w.t = nil
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
// Copyright 2020 The Knative Authors
|
||||
// Copyright (c) 2016 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// sliceArrayEncoder is an ArrayEncoder backed by a simple []interface{}. Like
|
||||
// the MapObjectEncoder, it's not designed for production use.
|
||||
type sliceArrayEncoder struct {
|
||||
elems []interface{}
|
||||
}
|
||||
|
||||
func (s *sliceArrayEncoder) AppendArray(v zapcore.ArrayMarshaler) error {
|
||||
enc := &sliceArrayEncoder{}
|
||||
err := v.MarshalLogArray(enc)
|
||||
s.elems = append(s.elems, enc.elems)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *sliceArrayEncoder) AppendObject(v zapcore.ObjectMarshaler) error {
|
||||
m := zapcore.NewMapObjectEncoder()
|
||||
err := v.MarshalLogObject(m)
|
||||
s.elems = append(s.elems, m.Fields)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *sliceArrayEncoder) AppendReflected(v interface{}) error {
|
||||
s.elems = append(s.elems, v)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *sliceArrayEncoder) AppendBool(v bool) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendByteString(v []byte) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendComplex128(v complex128) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendComplex64(v complex64) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendDuration(v time.Duration) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendFloat64(v float64) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendFloat32(v float32) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendInt(v int) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendInt64(v int64) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendInt32(v int32) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendInt16(v int16) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendInt8(v int8) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendString(v string) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendTime(v time.Time) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendUint(v uint) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendUint64(v uint64) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendUint32(v uint32) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendUint16(v uint16) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendUint8(v uint8) { s.elems = append(s.elems, v) }
|
||||
func (s *sliceArrayEncoder) AppendUintptr(v uintptr) { s.elems = append(s.elems, v) }
|
||||
|
|
@ -1,196 +0,0 @@
|
|||
// Copyright 2020 The Knative Authors
|
||||
// Copyright (c) 2016 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/buffer"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
var (
|
||||
_pool = buffer.NewPool()
|
||||
_sliceEncoderPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &sliceArrayEncoder{elems: make([]interface{}, 0, 2)}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
zap.RegisterEncoder("spew", func(encoderConfig zapcore.EncoderConfig) (zapcore.Encoder, error) {
|
||||
return NewSpewEncoder(encoderConfig), nil
|
||||
})
|
||||
}
|
||||
|
||||
// NewSpewEncoder encodes logs using the spew library.
|
||||
//
|
||||
// The JSON encoder (also used by the console encoder) included in Zap can only print objects that
|
||||
// can be serialized to JSON and doesn't print them in the most readable way. This spew encoder is
|
||||
// designed to make human-readable log only and get the most information to the user on any data type.
|
||||
//
|
||||
// Code is mostly from console_encoder.go in zapcore.
|
||||
func NewSpewEncoder(cfg zapcore.EncoderConfig) *SpewEncoder {
|
||||
enc := SpewEncoder{}
|
||||
enc.MapObjectEncoder = zapcore.NewMapObjectEncoder()
|
||||
enc.EncoderConfig = &cfg
|
||||
return &enc
|
||||
}
|
||||
|
||||
// SpewEncoder implements zapcore.Encoder interface
|
||||
type SpewEncoder struct {
|
||||
*zapcore.MapObjectEncoder
|
||||
*zapcore.EncoderConfig
|
||||
}
|
||||
|
||||
// Implements zapcore.Encoder interface
|
||||
func (enc *SpewEncoder) Clone() zapcore.Encoder {
|
||||
n := NewSpewEncoder(*(enc.EncoderConfig))
|
||||
for k, v := range enc.Fields {
|
||||
n.Fields[k] = v
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func getSliceEncoder() *sliceArrayEncoder {
|
||||
return _sliceEncoderPool.Get().(*sliceArrayEncoder)
|
||||
}
|
||||
|
||||
func putSliceEncoder(e *sliceArrayEncoder) {
|
||||
e.elems = e.elems[:0]
|
||||
_sliceEncoderPool.Put(e)
|
||||
}
|
||||
|
||||
// Implements zapcore.Encoder interface.
|
||||
func (enc *SpewEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
|
||||
line := _pool.Get()
|
||||
|
||||
// Could probably rewrite this portion and remove the copied
|
||||
// memory_encoder.go from this folder
|
||||
arr := getSliceEncoder()
|
||||
defer putSliceEncoder(arr)
|
||||
|
||||
if enc.TimeKey != "" && enc.EncodeTime != nil {
|
||||
enc.EncodeTime(ent.Time, arr)
|
||||
}
|
||||
if enc.LevelKey != "" && enc.EncodeLevel != nil {
|
||||
enc.EncodeLevel(ent.Level, arr)
|
||||
}
|
||||
|
||||
if ent.LoggerName != "" && enc.NameKey != "" {
|
||||
nameEncoder := enc.EncodeName
|
||||
|
||||
if nameEncoder == nil {
|
||||
// Fall back to FullNameEncoder for backward compatibility.
|
||||
nameEncoder = zapcore.FullNameEncoder
|
||||
}
|
||||
|
||||
nameEncoder(ent.LoggerName, arr)
|
||||
}
|
||||
if ent.Caller.Defined && enc.CallerKey != "" && enc.EncodeCaller != nil {
|
||||
enc.EncodeCaller(ent.Caller, arr)
|
||||
}
|
||||
for i := range arr.elems {
|
||||
if i > 0 {
|
||||
line.AppendByte('\t')
|
||||
}
|
||||
fmt.Fprint(line, arr.elems[i])
|
||||
}
|
||||
|
||||
// Add the message itself.
|
||||
if enc.MessageKey != "" {
|
||||
enc.addTabIfNecessary(line)
|
||||
line.AppendString(ent.Message)
|
||||
}
|
||||
|
||||
// Add any structured context.
|
||||
enc.writeContext(line, fields)
|
||||
|
||||
// If there's no stacktrace key, honor that; this allows users to force
|
||||
// single-line output.
|
||||
if ent.Stack != "" && enc.StacktraceKey != "" {
|
||||
line.AppendByte('\n')
|
||||
line.AppendString(ent.Stack)
|
||||
}
|
||||
|
||||
if enc.LineEnding != "" {
|
||||
line.AppendString(enc.LineEnding)
|
||||
} else {
|
||||
line.AppendString(zapcore.DefaultLineEnding)
|
||||
}
|
||||
return line, nil
|
||||
}
|
||||
|
||||
func (enc *SpewEncoder) writeContext(line *buffer.Buffer, extra []zapcore.Field) {
|
||||
if len(extra) == 0 && len(enc.Fields) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// This could probably be more efficient, but .AddTo() is convenient
|
||||
|
||||
context := zapcore.NewMapObjectEncoder()
|
||||
for k, v := range enc.Fields {
|
||||
context.Fields[k] = v
|
||||
}
|
||||
for i := range extra {
|
||||
extra[i].AddTo(context)
|
||||
}
|
||||
|
||||
enc.addTabIfNecessary(line)
|
||||
line.AppendString("\nContext:\n")
|
||||
keys := make([]string, 0, len(context.Fields))
|
||||
for k := range context.Fields {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
line.AppendString(k)
|
||||
line.AppendString(": ")
|
||||
line.AppendString(stringify(context.Fields[k]))
|
||||
line.TrimNewline()
|
||||
line.AppendString("\n")
|
||||
}
|
||||
}
|
||||
|
||||
func stringify(a interface{}) string {
|
||||
s, ok := a.(string)
|
||||
if !ok {
|
||||
s = strings.TrimSuffix(spewConfig.Sdump(a), "\n")
|
||||
}
|
||||
ret := strings.ReplaceAll(s, "\n", "\n ")
|
||||
hasNewlines := s != ret
|
||||
if hasNewlines {
|
||||
return "\n " + ret
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (enc *SpewEncoder) addTabIfNecessary(line *buffer.Buffer) {
|
||||
if line.Len() > 0 {
|
||||
line.AppendByte('\t')
|
||||
}
|
||||
}
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
// Copyright 2020 Knative Authors
|
||||
// Copyright (c) 2016 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
"go.uber.org/multierr"
|
||||
)
|
||||
|
||||
const (
|
||||
_oddNumberErrMsg = "Ignored key without a value."
|
||||
_nonStringKeyErrMsg = "Ignored key-value pairs with non-string keys."
|
||||
)
|
||||
|
||||
var spewConfig *spew.ConfigState
|
||||
|
||||
func init() {
|
||||
spewConfig = spew.NewDefaultConfig()
|
||||
spewConfig.DisableCapacities = true
|
||||
spewConfig.SortKeys = true
|
||||
spewConfig.SpewKeys = true
|
||||
spewConfig.ContinueOnMethod = true
|
||||
}
|
||||
|
||||
func (o *TLogger) handleFields(args []interface{}) []zap.Field {
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
s := o.l.Sugar()
|
||||
|
||||
// Allocate enough space for the worst case; if users pass only structured
|
||||
// fields, we shouldn't penalize them with extra allocations.
|
||||
fields := make([]zap.Field, 0, len(args))
|
||||
var invalid invalidPairs
|
||||
|
||||
for i := 0; i < len(args); {
|
||||
// This is a strongly-typed field. Consume it and move on.
|
||||
if f, ok := args[i].(zap.Field); ok {
|
||||
fields = append(fields, f)
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
||||
// Make sure this element isn't a dangling key.
|
||||
if i == len(args)-1 {
|
||||
s.DPanic(_oddNumberErrMsg, zap.Any("ignored", args[i]))
|
||||
break
|
||||
}
|
||||
|
||||
// Consume this value and the next, treating them as a key-value pair. If the
|
||||
// key isn't a string, add this pair to the slice of invalid pairs.
|
||||
key, val := args[i], args[i+1]
|
||||
if keyStr, ok := key.(string); !ok {
|
||||
// Subsequent errors are likely, so allocate once up front.
|
||||
if cap(invalid) == 0 {
|
||||
invalid = make(invalidPairs, 0, len(args)/2)
|
||||
}
|
||||
invalid = append(invalid, invalidPair{i, key, val})
|
||||
} else {
|
||||
fields = append(fields, zap.Any(keyStr, val))
|
||||
}
|
||||
i += 2
|
||||
}
|
||||
|
||||
// If we encountered any invalid key-value pairs, log an error.
|
||||
if len(invalid) > 0 {
|
||||
s.DPanic(_nonStringKeyErrMsg, zap.Array("invalid", invalid), zap.String("all_input", spew.Sprintf("%#+v", args)))
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
type invalidPair struct {
|
||||
position int
|
||||
key, value interface{}
|
||||
}
|
||||
|
||||
func (p invalidPair) MarshalLogObject(enc zapcore.ObjectEncoder) error {
|
||||
enc.AddInt64("position", int64(p.position))
|
||||
zap.Any("key", p.key).AddTo(enc)
|
||||
zap.Any("value", p.value).AddTo(enc)
|
||||
return nil
|
||||
}
|
||||
|
||||
type invalidPairs []invalidPair
|
||||
|
||||
func (ps invalidPairs) MarshalLogArray(enc zapcore.ArrayEncoder) error {
|
||||
var err error
|
||||
for i := range ps {
|
||||
err = multierr.Append(err, enc.AppendObject(ps[i]))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
@ -1,372 +0,0 @@
|
|||
/*
|
||||
Copyright 2020 The Knative 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 logging
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// TLogger is TLogger
|
||||
type TLogger struct {
|
||||
l *zap.Logger
|
||||
level int
|
||||
t *testing.T
|
||||
errs map[string][]interface{} // For Collect()
|
||||
dontFail bool
|
||||
}
|
||||
|
||||
// V() returns an InfoLogger from go-logr.
|
||||
//
|
||||
// This should be the main way your tests log.
|
||||
// Most frequent usage is used directly:
|
||||
// t.V(2).Info("Something at regular level")
|
||||
// But if something computationally difficult is to be done, can do:
|
||||
// if l := t.V(8); l.Enabled() {
|
||||
// x := somethingExpensive()
|
||||
// l.Info("logging it", "expensiveThing", x)
|
||||
// }
|
||||
//
|
||||
// Elsewhere in this documentation refers to a hypothetical .V(errorLevel) to simplify explanations.
|
||||
// The V() function cannot write to the error level; the Error, ErrorIfErr, Fatal, and
|
||||
// FatalIfErr methods are the only way to write to the error level.
|
||||
func (o *TLogger) V(level int) logr.InfoLogger {
|
||||
// Consider adding || (level <= logrZapDebugLevel && o.l.Core().Enabled(zapLevelFromLogrLevel(level)))
|
||||
// Reason to add it is even if you ask for verbosity=1, in case of error you'll get up to verbosity=3 in the debug output
|
||||
// but since zapTest uses Debug, you always get V(<=3) even when verbosity < 3
|
||||
// Probable solution is to write to t.Log at Info level?
|
||||
if level <= o.level {
|
||||
return &infoLogger{
|
||||
logrLevel: o.level,
|
||||
t: o,
|
||||
}
|
||||
}
|
||||
return disabledInfoLogger
|
||||
}
|
||||
|
||||
// WithValues() acts like Zap's With() method.
|
||||
// Consistent with logr.Logger.WithValues()
|
||||
// Whenever anything is logged with the returned TLogger,
|
||||
// it will act as if these keys and values were passed into every logging call.
|
||||
func (o *TLogger) WithValues(keysAndValues ...interface{}) *TLogger {
|
||||
return o.cloneWithNewLogger(o.l.With(o.handleFields(keysAndValues)...))
|
||||
}
|
||||
|
||||
// WithName() acts like Zap's Named() method.
|
||||
// Consistent with logr.Logger.WithName()
|
||||
// Appends the name onto the current logger
|
||||
func (o *TLogger) WithName(name string) *TLogger {
|
||||
return o.cloneWithNewLogger(o.l.Named(name))
|
||||
}
|
||||
|
||||
// Custom additions:
|
||||
|
||||
// ErrorIfErr fails the current test if the err != nil.
|
||||
// Remaining arguments function as if passed to .V(errorLevel).Info() (were that a thing)
|
||||
// Same signature as logr.Logger.Error() method, but as this is a test, it functions slightly differently.
|
||||
func (o *TLogger) ErrorIfErr(err error, msg string, keysAndValues ...interface{}) {
|
||||
if err != nil {
|
||||
o.error(err, msg, keysAndValues)
|
||||
o.fail()
|
||||
}
|
||||
}
|
||||
|
||||
// FatalIfErr is just like ErrorIfErr() but test execution stops immediately
|
||||
func (o *TLogger) FatalIfErr(err error, msg string, keysAndValues ...interface{}) {
|
||||
if err != nil {
|
||||
o.error(err, msg, keysAndValues)
|
||||
o.failNow()
|
||||
}
|
||||
}
|
||||
|
||||
// Error is essentially a .V(errorLevel).Info() followed by failing the test.
|
||||
// Intended usage is Error(msg string, key-value alternating arguments)
|
||||
// Same effect as testing.T.Error
|
||||
// Generic definition for compatibility with test.T interface
|
||||
// Implements test.T
|
||||
func (o *TLogger) Error(stringThenKeysAndValues ...interface{}) {
|
||||
// Using o.error to have consistent call depth for Error, FatalIfErr, Info, etc
|
||||
o.error(o.errorWithRuntimeCheck(stringThenKeysAndValues...))
|
||||
o.fail()
|
||||
}
|
||||
|
||||
// Fatal is essentially a .V(errorLevel).Info() followed by failing and immediately stopping the test.
|
||||
// Intended usage is Fatal(msg string, key-value alternating arguments)
|
||||
// Same effect as testing.T.Fatal
|
||||
// Generic definition for compatibility with test.TLegacy interface
|
||||
// Implements test.TLegacy
|
||||
func (o *TLogger) Fatal(stringThenKeysAndValues ...interface{}) {
|
||||
o.error(o.errorWithRuntimeCheck(stringThenKeysAndValues...))
|
||||
o.failNow()
|
||||
}
|
||||
|
||||
func (o *TLogger) fail() {
|
||||
if o.t != nil && !o.dontFail {
|
||||
o.t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func (o *TLogger) failNow() {
|
||||
if o.t != nil && !o.dontFail {
|
||||
o.t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func validateKeysAndValues(keysAndValues ...interface{}) bool {
|
||||
length := len(keysAndValues)
|
||||
for i := 0; i < length; {
|
||||
_, isField := keysAndValues[i].(zapcore.Field)
|
||||
_, isString := keysAndValues[i].(string)
|
||||
if isField {
|
||||
i++
|
||||
} else if isString {
|
||||
if i == length-1 {
|
||||
return false
|
||||
}
|
||||
i += 2
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (o *TLogger) interfacesToFields(things ...interface{}) []interface{} {
|
||||
o.V(5).Info("DEPRECATED Error/Fatal usage", zap.Stack("callstack"))
|
||||
fields := make([]interface{}, 2*len(things))
|
||||
for i, d := range things {
|
||||
fields[i*2] = fmt.Sprintf("arg %d", i)
|
||||
fields[i*2+1] = d
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
func (o *TLogger) errorWithRuntimeCheck(stringThenKeysAndValues ...interface{}) (error, string, []interface{}) { //nolint // Returning the error first is okay and expected here.
|
||||
if len(stringThenKeysAndValues) == 0 {
|
||||
return nil, "", nil
|
||||
}
|
||||
s, isString := stringThenKeysAndValues[0].(string)
|
||||
if isString {
|
||||
// Desired case (hopefully)
|
||||
remainder := stringThenKeysAndValues[1:]
|
||||
if !validateKeysAndValues(remainder...) {
|
||||
remainder = o.interfacesToFields(remainder...)
|
||||
}
|
||||
return nil, s, remainder
|
||||
}
|
||||
e, isError := stringThenKeysAndValues[0].(error)
|
||||
if isError && len(stringThenKeysAndValues) == 1 {
|
||||
return e, "", nil
|
||||
}
|
||||
return nil, "unstructured error", o.interfacesToFields(stringThenKeysAndValues...)
|
||||
}
|
||||
|
||||
// Cleanup registers a cleanup callback.
|
||||
func (o *TLogger) Cleanup(c func()) {
|
||||
o.t.Cleanup(c)
|
||||
}
|
||||
|
||||
// Run a subtest. Just like testing.T.Run but creates a TLogger.
|
||||
func (o *TLogger) Run(name string, f func(t *TLogger)) {
|
||||
tfunc := func(ts *testing.T) {
|
||||
tl, cancel := newTLogger(ts, o.level, o.dontFail)
|
||||
defer cancel()
|
||||
f(tl)
|
||||
}
|
||||
o.t.Run(name, tfunc)
|
||||
}
|
||||
|
||||
// Name is just like testing.T.Name()
|
||||
// Implements test.T
|
||||
func (o *TLogger) Name() string {
|
||||
return o.t.Name()
|
||||
}
|
||||
|
||||
// Helper cannot work as an indirect call, so just do nothing :(
|
||||
// Implements test.T
|
||||
func (o *TLogger) Helper() {
|
||||
}
|
||||
|
||||
// SkipNow immediately stops test execution
|
||||
// Implements test.T
|
||||
func (o *TLogger) SkipNow() {
|
||||
o.t.SkipNow()
|
||||
}
|
||||
|
||||
// Log is deprecated: only existing for test.T compatibility
|
||||
// Please use leveled logging via .V().Info()
|
||||
// Will panic if given data incompatible with Info() function
|
||||
// Implements test.T
|
||||
func (o *TLogger) Log(args ...interface{}) {
|
||||
// This is complicated to ensure exactly 2 levels of indirection
|
||||
i := o.V(2)
|
||||
iL, ok := i.(*infoLogger)
|
||||
if ok {
|
||||
iL.indirectWrite(args[0].(string), args[1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
// Parallel allows tests or subtests to run in parallel
|
||||
// Just calls the testing.T.Parallel() under the hood
|
||||
func (o *TLogger) Parallel() {
|
||||
o.t.Parallel()
|
||||
}
|
||||
|
||||
// Logf is deprecated: only existing for test.TLegacy compatibility
|
||||
// Please use leveled logging via .V().Info()
|
||||
// Implements test.TLegacy
|
||||
func (o *TLogger) Logf(fmtS string, args ...interface{}) {
|
||||
// This is complicated to ensure exactly 2 levels of indirection
|
||||
iL, ok := o.V(2).(*infoLogger)
|
||||
if ok {
|
||||
iL.indirectWrite(fmt.Sprintf(fmtS, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (o *TLogger) error(err error, msg string, keysAndValues []interface{}) {
|
||||
var newKAV []interface{}
|
||||
var serr StructuredError
|
||||
if errors.As(err, &serr) {
|
||||
serr.DisableValuePrinting()
|
||||
defer serr.EnableValuePrinting()
|
||||
newLen := len(keysAndValues) + len(serr.GetValues())
|
||||
newKAV = make([]interface{}, 0, newLen+2)
|
||||
newKAV = append(newKAV, keysAndValues...)
|
||||
newKAV = append(newKAV, serr.GetValues()...)
|
||||
}
|
||||
if err != nil {
|
||||
if msg == "" { // This is used if just the error is given to .Error() or .Fatal()
|
||||
msg = err.Error()
|
||||
} else {
|
||||
if newKAV == nil {
|
||||
newKAV = make([]interface{}, 0, len(keysAndValues)+1)
|
||||
newKAV = append(newKAV, keysAndValues...)
|
||||
}
|
||||
newKAV = append(newKAV, zap.Error(err))
|
||||
}
|
||||
}
|
||||
if newKAV != nil {
|
||||
keysAndValues = newKAV
|
||||
}
|
||||
if checkedEntry := o.l.Check(zap.ErrorLevel, msg); checkedEntry != nil {
|
||||
checkedEntry.Write(o.handleFields(keysAndValues)...)
|
||||
}
|
||||
}
|
||||
|
||||
// Creation and Teardown
|
||||
|
||||
// Create a TLogger object using the global Zap logger and the current testing.T
|
||||
// `defer` a call to second return value immediately after.
|
||||
func NewTLogger(t *testing.T) (*TLogger, func()) {
|
||||
return newTLogger(t, verbosity, false)
|
||||
}
|
||||
|
||||
func newTLogger(t *testing.T, verbosity int, dontFail bool) (*TLogger, func()) {
|
||||
testOptions := []zap.Option{
|
||||
zap.AddCaller(),
|
||||
zap.AddCallerSkip(2),
|
||||
zap.Development(),
|
||||
}
|
||||
writer := newTestingWriter(t)
|
||||
// Based off zap.NewDevelopmentEncoderConfig()
|
||||
cfg := zapcore.EncoderConfig{
|
||||
// Wanted keys can be anything except the empty string.
|
||||
TimeKey: "",
|
||||
LevelKey: "",
|
||||
NameKey: "",
|
||||
CallerKey: "C",
|
||||
MessageKey: "M",
|
||||
StacktraceKey: "S",
|
||||
LineEnding: zapcore.DefaultLineEnding,
|
||||
EncodeLevel: zapcore.CapitalLevelEncoder,
|
||||
EncodeTime: zapcore.ISO8601TimeEncoder,
|
||||
EncodeDuration: zapcore.StringDurationEncoder,
|
||||
EncodeCaller: zapcore.ShortCallerEncoder,
|
||||
}
|
||||
core := zapcore.NewCore(
|
||||
NewSpewEncoder(cfg),
|
||||
writer,
|
||||
zapcore.DebugLevel,
|
||||
)
|
||||
if zapCore != nil {
|
||||
core = zapcore.NewTee(
|
||||
zapCore,
|
||||
core,
|
||||
// TODO(coryrc): Open new file (maybe creating JUnit!?) with test output?
|
||||
)
|
||||
}
|
||||
log := zap.New(core, testOptions...).Named(t.Name())
|
||||
tlogger := TLogger{
|
||||
l: log,
|
||||
level: verbosity,
|
||||
t: t,
|
||||
errs: make(map[string][]interface{}),
|
||||
dontFail: dontFail,
|
||||
}
|
||||
return &tlogger, func() {
|
||||
tlogger.handleCollectedErrors()
|
||||
// Sometimes goroutines exist after a test and they cause panics if they attempt to call t.Log().
|
||||
// Prevent this panic by disabling writes to the testing.T (we'll still get them everywhere else).
|
||||
writer.Disable()
|
||||
}
|
||||
}
|
||||
|
||||
func (o *TLogger) cloneWithNewLogger(l *zap.Logger) *TLogger {
|
||||
t := TLogger{
|
||||
l: l,
|
||||
level: o.level,
|
||||
t: o.t,
|
||||
errs: o.errs,
|
||||
dontFail: o.dontFail,
|
||||
}
|
||||
return &t
|
||||
}
|
||||
|
||||
// Collect allows you to commingle multiple validations during one test execution.
|
||||
// Under the hood, it creates a sub-test during cleanup and iterates through the collected values, printing them.
|
||||
// If any are errors, it fails the subtest.
|
||||
// Currently experimental and likely to be removed
|
||||
func (o *TLogger) Collect(key string, value interface{}) {
|
||||
list, hasKey := o.errs[key]
|
||||
if hasKey {
|
||||
list = append(list, value)
|
||||
} else {
|
||||
list = make([]interface{}, 1)
|
||||
list[0] = value
|
||||
}
|
||||
o.errs[key] = list
|
||||
}
|
||||
|
||||
func (o *TLogger) handleCollectedErrors() {
|
||||
for name, list := range o.errs {
|
||||
o.Run(name, func(t *TLogger) {
|
||||
for _, item := range list {
|
||||
_, isError := item.(error)
|
||||
if isError {
|
||||
t.Error(item)
|
||||
} else {
|
||||
t.V(3).Info(spewConfig.Sprint(item))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
// Copyright 2020 Knative Authors
|
||||
// Copyright 2018 Solly Ross
|
||||
//
|
||||
// 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.
|
||||
|
||||
// The useful parts of this file have been preserved
|
||||
// from their origin at https://github.com/go-logr/zapr/tree/8f2487342d52a33a1793e50e3ca04bc1767aa65c
|
||||
|
||||
package logging
|
||||
|
||||
// noopInfoLogger is a logr.InfoLogger that's always disabled, and does nothing.
|
||||
type noopInfoLogger struct{}
|
||||
|
||||
func (l *noopInfoLogger) Enabled() bool { return false }
|
||||
func (l *noopInfoLogger) Info(_ string, _ ...interface{}) {}
|
||||
|
||||
var disabledInfoLogger = &noopInfoLogger{}
|
||||
|
||||
// infoLogger is a logr.InfoLogger that uses Zap to log at a particular
|
||||
// level.
|
||||
type infoLogger struct {
|
||||
logrLevel int
|
||||
t *TLogger
|
||||
}
|
||||
|
||||
func (i *infoLogger) Enabled() bool { return true }
|
||||
func (i *infoLogger) Info(msg string, keysAndVals ...interface{}) {
|
||||
i.indirectWrite(msg, keysAndVals...)
|
||||
}
|
||||
|
||||
// This function just exists to have consistent 2-level call depth for Zap proxying
|
||||
func (i *infoLogger) indirectWrite(msg string, keysAndVals ...interface{}) {
|
||||
lvl := zapLevelFromLogrLevel(i.logrLevel)
|
||||
if checkedEntry := i.t.l.Check(lvl, msg); checkedEntry != nil {
|
||||
checkedEntry.Write(i.t.handleFields(keysAndVals)...)
|
||||
}
|
||||
}
|
||||
|
|
@ -216,9 +216,18 @@ func isExpired(expiry time.Time) bool {
|
|||
|
||||
// OnChanged implements Interface.
|
||||
func (i *impl) OnChanged(obj interface{}) {
|
||||
observers := i.GetObservers(obj)
|
||||
|
||||
for _, observer := range observers {
|
||||
i.cb(observer)
|
||||
}
|
||||
}
|
||||
|
||||
// GetObservers implements Interface.
|
||||
func (i *impl) GetObservers(obj interface{}) []types.NamespacedName {
|
||||
item, err := kmeta.DeletionHandlingAccessor(obj)
|
||||
if err != nil {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
or := kmeta.ObjectReference(item)
|
||||
|
|
@ -229,14 +238,9 @@ func (i *impl) OnChanged(obj interface{}) {
|
|||
Name: or.Name,
|
||||
}
|
||||
|
||||
i.m.Lock()
|
||||
// Call the callbacks without the lock held.
|
||||
var keys []types.NamespacedName
|
||||
defer func(cb func(types.NamespacedName)) {
|
||||
for _, key := range keys {
|
||||
cb(key)
|
||||
}
|
||||
}(i.cb) // read i.cb with the lock held
|
||||
|
||||
i.m.Lock()
|
||||
defer i.m.Unlock()
|
||||
|
||||
// Handle exact matches.
|
||||
|
|
@ -274,6 +278,8 @@ func (i *impl) OnChanged(obj interface{}) {
|
|||
delete(i.exact, ref)
|
||||
}
|
||||
}
|
||||
|
||||
return keys
|
||||
}
|
||||
|
||||
// OnChanged implements Interface.
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
|
||||
"knative.dev/pkg/apis"
|
||||
|
|
@ -71,6 +72,10 @@ type Interface interface {
|
|||
// so that we are notified for appropriate object changes.
|
||||
OnChanged(obj interface{})
|
||||
|
||||
// GetObservers returns the names of all observers for the given
|
||||
// object.
|
||||
GetObservers(obj interface{}) []types.NamespacedName
|
||||
|
||||
// OnDeletedObserver is a callback to register with the InformerFactory
|
||||
// so that we are notified for deletions of a watching parent to
|
||||
// remove the respective tracking.
|
||||
|
|
|
|||
|
|
@ -823,7 +823,7 @@ k8s.io/kube-openapi/pkg/util/sets
|
|||
k8s.io/utils/buffer
|
||||
k8s.io/utils/integer
|
||||
k8s.io/utils/trace
|
||||
# knative.dev/eventing v0.19.0
|
||||
# knative.dev/eventing v0.19.1-0.20201117061051-47ee6e3586ca
|
||||
## explicit
|
||||
knative.dev/eventing/pkg/apis/config
|
||||
knative.dev/eventing/pkg/apis/configs
|
||||
|
|
@ -852,15 +852,15 @@ knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1/fake
|
|||
knative.dev/eventing/pkg/client/clientset/versioned/typed/messaging/v1beta1
|
||||
knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha2
|
||||
knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha2/fake
|
||||
# knative.dev/hack v0.0.0-20201103151104-3d5abc3a0075
|
||||
# knative.dev/hack v0.0.0-20201112185459-01a34c573bd8
|
||||
## explicit
|
||||
knative.dev/hack
|
||||
# knative.dev/networking v0.0.0-20201103163404-b9f80f4537af
|
||||
# knative.dev/networking v0.0.0-20201117131851-29d71950ee3d
|
||||
## explicit
|
||||
knative.dev/networking/pkg
|
||||
knative.dev/networking/pkg/apis/networking
|
||||
knative.dev/networking/pkg/apis/networking/v1alpha1
|
||||
# knative.dev/pkg v0.0.0-20201103163404-5514ab0c1fdf
|
||||
# knative.dev/pkg v0.0.0-20201117020252-ab1a398f669c
|
||||
## explicit
|
||||
knative.dev/pkg/apis
|
||||
knative.dev/pkg/apis/duck
|
||||
|
|
@ -900,7 +900,7 @@ knative.dev/pkg/tracing/config
|
|||
knative.dev/pkg/tracing/propagation
|
||||
knative.dev/pkg/tracing/propagation/tracecontextb3
|
||||
knative.dev/pkg/tracker
|
||||
# knative.dev/serving v0.19.0
|
||||
# knative.dev/serving v0.19.1-0.20201117120351-3e2a380308b2
|
||||
## explicit
|
||||
knative.dev/serving/pkg/apis/autoscaling
|
||||
knative.dev/serving/pkg/apis/autoscaling/v1alpha1
|
||||
|
|
|
|||
Loading…
Reference in New Issue