Repository: knative/pkg
Pull request #1728 (2020-09-21 22:38:05)

Remove apicoverage from pkg
and update the deps.

/assign mattmoor @chaodaiG 

knative-prow-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative/pkg/pull/1728#" title="Author self-approved">vagababov</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative%2Fpkg).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/knative/pkg/blob/master/OWNERS)~~ [vagababov]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
mattmoor: I want to rerun the downstream once the serving PR merges.
codecov[bot]: # [Codecov](https://codecov.io/gh/knative/pkg/pull/1728?src=pr&el=h1) Report
> Merging [#1728](https://codecov.io/gh/knative/pkg/pull/1728?src=pr&el=desc) into [master](https://codecov.io/gh/knative/pkg/commit/9128d4b9c1f2bfc33086e8c13f1c307d058c5687?el=desc) will **increase** coverage by `0.73%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/knative/pkg/pull/1728/graphs/tree.svg?width=650&height=150&src=pr&token=rlqpDnfxbO)](https://codecov.io/gh/knative/pkg/pull/1728?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1728      +/-   ##
==========================================
+ Coverage   67.62%   68.36%   +0.73%     
==========================================
  Files         226      215      -11     
  Lines        9547     9195     -352     
==========================================
- Hits         6456     6286     -170     
+ Misses       2719     2590     -129     
+ Partials      372      319      -53     
```


| [Impacted Files](https://codecov.io/gh/knative/pkg/pull/1728?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [network/transports.go](https://codecov.io/gh/knative/pkg/pull/1728/diff?src=pr&el=tree#diff-bmV0d29yay90cmFuc3BvcnRzLmdv) | `92.10% <0.00%> (-0.40%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/knative/pkg/pull/1728?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/knative/pkg/pull/1728?src=pr&el=footer). Last update [9128d4b...1579218](https://codecov.io/gh/knative/pkg/pull/1728?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

vagababov: > I want to rerun the downstream once the serving PR merges.

👍 

Patch:
diff --git a/.github/workflows/knative-go-build.yaml b/.github/workflows/knative-go-build.yaml
index 98c9e411a..609551157 100644
--- a/.github/workflows/knative-go-build.yaml
+++ b/.github/workflows/knative-go-build.yaml
@@ -27,7 +27,7 @@ jobs:
     name: Build
     strategy:
       matrix:
-        go-version: [1.14.x]
+        go-version: [1.15.x]
         platform: [ubuntu-latest]
 
     runs-on: ${{ matrix.platform }}
diff --git a/.github/workflows/knative-style.yaml b/.github/workflows/knative-style.yaml
index 49ef66bf1..31a0aeb2e 100644
--- a/.github/workflows/knative-style.yaml
+++ b/.github/workflows/knative-style.yaml
@@ -29,10 +29,10 @@ jobs:
 
     steps:
 
-      - name: Set up Go 1.14.x
+      - name: Set up Go 1.15.x
         uses: actions/setup-go@v2
         with:
-          go-version: 1.14.x
+          go-version: 1.15.x
         id: go
 
       - name: Check out code
@@ -83,11 +83,10 @@ jobs:
     runs-on: ubuntu-latest
 
     steps:
-
-      - name: Set up Go 1.14.x
+      - name: Set up Go 1.15.x
         uses: actions/setup-go@v2
         with:
-          go-version: 1.14.x
+          go-version: 1.15.x
         id: go
 
       - name: Check out code
diff --git a/.github/workflows/knative-verify.yaml b/.github/workflows/knative-verify.yaml
index c29a6a04d..57b541280 100644
--- a/.github/workflows/knative-verify.yaml
+++ b/.github/workflows/knative-verify.yaml
@@ -27,7 +27,7 @@ jobs:
     name: Verify Deps and Codegen
     strategy:
       matrix:
-        go-version: [1.14.x]
+        go-version: [1.15.x]
         platform: [ubuntu-latest]
 
     runs-on: ${{ matrix.platform }}
diff --git a/.golangci.yaml b/.golangci.yaml
index a33656679..9d60f5792 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -7,7 +7,16 @@ run:
 
 linters:
   enable:
-    - unconvert
+    - gosec
     - prealloc
+    - unconvert
+    - unparam
   disable:
     - errcheck
+
+issues:
+  exclude-rules:
+    - path: test # Excludes /test, *_test.go etc.
+      linters:
+        - gosec
+        - unparam
diff --git a/codegen/cmd/injection-gen/generators/packages.go b/codegen/cmd/injection-gen/generators/packages.go
index ab2ee1205..70e4eb7d1 100644
--- a/codegen/cmd/injection-gen/generators/packages.go
+++ b/codegen/cmd/injection-gen/generators/packages.go
@@ -572,7 +572,7 @@ func reconcilerPackages(basePackage string, groupPkgName string, gv clientgentyp
 	return vers
 }
 
-func versionDuckPackages(basePackage string, groupPkgName string, gv clientgentypes.GroupVersion, groupGoName string, boilerplate []byte, typesToGenerate []*types.Type, customArgs *informergenargs.CustomArgs) []generator.Package {
+func versionDuckPackages(basePackage string, groupPkgName string, gv clientgentypes.GroupVersion, groupGoName string, boilerplate []byte, typesToGenerate []*types.Type, _ *informergenargs.CustomArgs) []generator.Package {
 	packagePath := filepath.Join(basePackage, "ducks", groupPkgName, strings.ToLower(gv.Version.NonEmpty()))
 
 	vers := make([]generator.Package, 0, 2*len(typesToGenerate))
diff --git a/configmap/hash-gen/main.go b/configmap/hash-gen/main.go
index 8d9b7bfe0..bde4f7871 100644
--- a/configmap/hash-gen/main.go
+++ b/configmap/hash-gen/main.go
@@ -49,6 +49,7 @@ func processFile(fileName string) error {
 		return err
 	}
 
+	// nolint:gosec // This is not security critical so open permissions are fine.
 	if err := ioutil.WriteFile(fileName, out, 0644); err != nil {
 		return fmt.Errorf("failed to write file: %w", err)
 	}
diff --git a/kmeta/names.go b/kmeta/names.go
index c59090b52..43d12de80 100644
--- a/kmeta/names.go
+++ b/kmeta/names.go
@@ -17,7 +17,7 @@ limitations under the license.
 package kmeta
 
 import (
-	"crypto/md5"
+	"crypto/md5" // nolint:gosec // No strong cryptography needed.
 	"fmt"
 	"strings"
 )
@@ -42,6 +42,7 @@ func ChildName(parent, suffix string) string {
 		// If the suffix is longer than the longest allowed suffix, then
 		// we hash the whole combined string and use that as the suffix.
 		if head-len(suffix) <= 0 {
+			// nolint:gosec // No strong cryptography needed.
 			h := md5.Sum([]byte(parent + suffix))
 			// 1. trim parent, if needed
 			if head < len(parent) {
@@ -58,6 +59,7 @@ func ChildName(parent, suffix string) string {
 			// remove it.
 			return strings.TrimRight(ret, "-")
 		}
+		// nolint:gosec // No strong cryptography needed.
 		n = fmt.Sprintf("%s%x", parent[:head-len(suffix)], md5.Sum([]byte(parent)))
 	}
 	return n + suffix
diff --git a/metrics/config.go b/metrics/config.go
index e62250fb0..fdf3cb855 100644
--- a/metrics/config.go
+++ b/metrics/config.go
@@ -28,7 +28,6 @@ import (
 	"time"
 
 	"go.opencensus.io/stats"
-	"go.uber.org/zap"
 	corev1 "k8s.io/api/core/v1"
 	"knative.dev/pkg/metrics/metricskey"
 )
@@ -174,7 +173,7 @@ func (mc *metricsConfig) record(ctx context.Context, mss []stats.Measurement, ro
 	return mc.recorder(ctx, mss, ros...)
 }
 
-func createMetricsConfig(ctx context.Context, ops ExporterOptions, logger *zap.SugaredLogger) (*metricsConfig, error) {
+func createMetricsConfig(ctx context.Context, ops ExporterOptions) (*metricsConfig, error) {
 	var mc metricsConfig
 
 	if ops.Domain == "" {
diff --git a/metrics/exporter.go b/metrics/exporter.go
index da5c510c9..a606c8ad2 100644
--- a/metrics/exporter.go
+++ b/metrics/exporter.go
@@ -135,7 +135,7 @@ func UpdateExporterFromConfigMapWithOpts(ctx context.Context, opts ExporterOptio
 // and updating the current exporter.
 func UpdateExporter(ctx context.Context, ops ExporterOptions, logger *zap.SugaredLogger) error {
 	// TODO(https://github.com/knative/pkg/issues/1273): check if ops.secrets is `nil` after new metrics plan lands
-	newConfig, err := createMetricsConfig(ctx, ops, logger)
+	newConfig, err := createMetricsConfig(ctx, ops)
 	if err != nil {
 		if getCurMetricsConfig() == nil {
 			// Fail the process if there doesn't exist an exporter.
diff --git a/metrics/opencensus_exporter.go b/metrics/opencensus_exporter.go
index c0a475250..403449e23 100644
--- a/metrics/opencensus_exporter.go
+++ b/metrics/opencensus_exporter.go
@@ -99,6 +99,7 @@ func getCredentials(component string, secret *corev1.Secret, logger *zap.Sugared
 		return nil
 	}
 	return credentials.NewTLS(&tls.Config{
+		MinVersion: tls.VersionTLS12,
 		GetClientCertificate: func(*tls.CertificateRequestInfo) (*tls.Certificate, error) {
 			cert, err := tls.X509KeyPair(secret.Data["client-cert.pem"], secret.Data["client-key.pem"])
 			if err != nil {
diff --git a/vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp/gcp.go b/vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp/gcp.go
deleted file mode 100644
index e44c2adab..000000000
--- a/vendor/k8s.io/client-go/plugin/pkg/client/auth/gcp/gcp.go
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
-Copyright 2016 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.
-*/
-
-package gcp
-
-import (
-	"bytes"
-	"context"
-	"encoding/json"
-	"fmt"
-	"net/http"
-	"os/exec"
-	"strings"
-	"sync"
-	"time"
-
-	"golang.org/x/oauth2"
-	"golang.org/x/oauth2/google"
-	"k8s.io/apimachinery/pkg/util/net"
-	"k8s.io/apimachinery/pkg/util/yaml"
-	restclient "k8s.io/client-go/rest"
-	"k8s.io/client-go/util/jsonpath"
-	"k8s.io/klog"
-)
-
-func init() {
-	if err := restclient.RegisterAuthProviderPlugin("gcp", newGCPAuthProvider); err != nil {
-		klog.Fatalf("Failed to register gcp auth plugin: %v", err)
-	}
-}
-
-var (
-	// Stubbable for testing
-	execCommand = exec.Command
-
-	// defaultScopes:
-	// - cloud-platform is the base scope to authenticate to GCP.
-	// - userinfo.email is used to authenticate to GKE APIs with gserviceaccount
-	//   email instead of numeric uniqueID.
-	defaultScopes = []string{
-		"https://www.googleapis.com/auth/cloud-platform",
-		"https://www.googleapis.com/auth/userinfo.email"}
-)
-
-// gcpAuthProvider is an auth provider plugin that uses GCP credentials to provide
-// tokens for kubectl to authenticate itself to the apiserver. A sample json config
-// is provided below with all recognized options described.
-//
-// {
-//   'auth-provider': {
-//     # Required
-//     "name": "gcp",
-//
-//     'config': {
-//       # Authentication options
-//       # These options are used while getting a token.
-//
-//       # comma-separated list of GCP API scopes. default value of this field
-//       # is "https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email".
-// 		 # to override the API scopes, specify this field explicitly.
-//       "scopes": "https://www.googleapis.com/auth/cloud-platform"
-//
-//       # Caching options
-//
-//       # Raw string data representing cached access token.
-//       "access-token": "ya29.CjWdA4GiBPTt",
-//       # RFC3339Nano expiration timestamp for cached access token.
-//       "expiry": "2016-10-31 22:31:9.123",
-//
-//       # Command execution options
-//       # These options direct the plugin to execute a specified command and parse
-//       # token and expiry time from the output of the command.
-//
-//       # Command to execute for access token. Command output will be parsed as JSON.
-//       # If "cmd-args" is not present, this value will be split on whitespace, with
-//       # the first element interpreted as the command, remaining elements as args.
-//       "cmd-path": "/usr/bin/gcloud",
-//
-//       # Arguments to pass to command to execute for access token.
-//       "cmd-args": "config config-helper --output=json"
-//
-//       # JSONPath to the string field that represents the access token in
-//       # command output. If omitted, defaults to "{.access_token}".
-//       "token-key": "{.credential.access_token}",
-//
-//       # JSONPath to the string field that represents expiration timestamp
-//       # of the access token in the command output. If omitted, defaults to
-//       # "{.token_expiry}"
-//       "expiry-key": ""{.credential.token_expiry}",
-//
-//       # golang reference time in the format that the expiration timestamp uses.
-//       # If omitted, defaults to time.RFC3339Nano
-//       "time-fmt": "2006-01-02 15:04:05.999999999"
-//     }
-//   }
-// }
-//
-type gcpAuthProvider struct {
-	tokenSource oauth2.TokenSource
-	persister   restclient.AuthProviderConfigPersister
-}
-
-func newGCPAuthProvider(_ string, gcpConfig map[string]string, persister restclient.AuthProviderConfigPersister) (restclient.AuthProvider, error) {
-	ts, err := tokenSource(isCmdTokenSource(gcpConfig), gcpConfig)
-	if err != nil {
-		return nil, err
-	}
-	cts, err := newCachedTokenSource(gcpConfig["access-token"], gcpConfig["expiry"], persister, ts, gcpConfig)
-	if err != nil {
-		return nil, err
-	}
-	return &gcpAuthProvider{cts, persister}, nil
-}
-
-func isCmdTokenSource(gcpConfig map[string]string) bool {
-	_, ok := gcpConfig["cmd-path"]
-	return ok
-}
-
-func tokenSource(isCmd bool, gcpConfig map[string]string) (oauth2.TokenSource, error) {
-	// Command-based token source
-	if isCmd {
-		cmd := gcpConfig["cmd-path"]
-		if len(cmd) == 0 {
-			return nil, fmt.Errorf("missing access token cmd")
-		}
-		if gcpConfig["scopes"] != "" {
-			return nil, fmt.Errorf("scopes can only be used when kubectl is using a gcp service account key")
-		}
-		var args []string
-		if cmdArgs, ok := gcpConfig["cmd-args"]; ok {
-			args = strings.Fields(cmdArgs)
-		} else {
-			fields := strings.Fields(cmd)
-			cmd = fields[0]
-			args = fields[1:]
-		}
-		return newCmdTokenSource(cmd, args, gcpConfig["token-key"], gcpConfig["expiry-key"], gcpConfig["time-fmt"]), nil
-	}
-
-	// Google Application Credentials-based token source
-	scopes := parseScopes(gcpConfig)
-	ts, err := google.DefaultTokenSource(context.Background(), scopes...)
-	if err != nil {
-		return nil, fmt.Errorf("cannot construct google default token source: %v", err)
-	}
-	return ts, nil
-}
-
-// parseScopes constructs a list of scopes that should be included in token source
-// from the config map.
-func parseScopes(gcpConfig map[string]string) []string {
-	scopes, ok := gcpConfig["scopes"]
-	if !ok {
-		return defaultScopes
-	}
-	if scopes == "" {
-		return []string{}
-	}
-	return strings.Split(gcpConfig["scopes"], ",")
-}
-
-func (g *gcpAuthProvider) WrapTransport(rt http.RoundTripper) http.RoundTripper {
-	var resetCache map[string]string
-	if cts, ok := g.tokenSource.(*cachedTokenSource); ok {
-		resetCache = cts.baseCache()
-	} else {
-		resetCache = make(map[string]string)
-	}
-	return &conditionalTransport{&oauth2.Transport{Source: g.tokenSource, Base: rt}, g.persister, resetCache}
-}
-
-func (g *gcpAuthProvider) Login() error { return nil }
-
-type cachedTokenSource struct {
-	lk          sync.Mutex
-	source      oauth2.TokenSource
-	accessToken string
-	expiry      time.Time
-	persister   restclient.AuthProviderConfigPersister
-	cache       map[string]string
-}
-
-func newCachedTokenSource(accessToken, expiry string, persister restclient.AuthProviderConfigPersister, ts oauth2.TokenSource, cache map[string]string) (*cachedTokenSource, error) {
-	var expiryTime time.Time
-	if parsedTime, err := time.Parse(time.RFC3339Nano, expiry); err == nil {
-		expiryTime = parsedTime
-	}
-	if cache == nil {
-		cache = make(map[string]string)
-	}
-	return &cachedTokenSource{
-		source:      ts,
-		accessToken: accessToken,
-		expiry:      expiryTime,
-		persister:   persister,
-		cache:       cache,
-	}, nil
-}
-
-func (t *cachedTokenSource) Token() (*oauth2.Token, error) {
-	tok := t.cachedToken()
-	if tok.Valid() && !tok.Expiry.IsZero() {
-		return tok, nil
-	}
-	tok, err := t.source.Token()
-	if err != nil {
-		return nil, err
-	}
-	cache := t.update(tok)
-	if t.persister != nil {
-		if err := t.persister.Persist(cache); err != nil {
-			klog.V(4).Infof("Failed to persist token: %v", err)
-		}
-	}
-	return tok, nil
-}
-
-func (t *cachedTokenSource) cachedToken() *oauth2.Token {
-	t.lk.Lock()
-	defer t.lk.Unlock()
-	return &oauth2.Token{
-		AccessToken: t.accessToken,
-		TokenType:   "Bearer",
-		Expiry:      t.expiry,
-	}
-}
-
-func (t *cachedTokenSource) update(tok *oauth2.Token) map[string]string {
-	t.lk.Lock()
-	defer t.lk.Unlock()
-	t.accessToken = tok.AccessToken
-	t.expiry = tok.Expiry
-	ret := map[string]string{}
-	for k, v := range t.cache {
-		ret[k] = v
-	}
-	ret["access-token"] = t.accessToken
-	ret["expiry"] = t.expiry.Format(time.RFC3339Nano)
-	return ret
-}
-
-// baseCache is the base configuration value for this TokenSource, without any cached ephemeral tokens.
-func (t *cachedTokenSource) baseCache() map[string]string {
-	t.lk.Lock()
-	defer t.lk.Unlock()
-	ret := map[string]string{}
-	for k, v := range t.cache {
-		ret[k] = v
-	}
-	delete(ret, "access-token")
-	delete(ret, "expiry")
-	return ret
-}
-
-type commandTokenSource struct {
-	cmd       string
-	args      []string
-	tokenKey  string
-	expiryKey string
-	timeFmt   string
-}
-
-func newCmdTokenSource(cmd string, args []string, tokenKey, expiryKey, timeFmt string) *commandTokenSource {
-	if len(timeFmt) == 0 {
-		timeFmt = time.RFC3339Nano
-	}
-	if len(tokenKey) == 0 {
-		tokenKey = "{.access_token}"
-	}
-	if len(expiryKey) == 0 {
-		expiryKey = "{.token_expiry}"
-	}
-	return &commandTokenSource{
-		cmd:       cmd,
-		args:      args,
-		tokenKey:  tokenKey,
-		expiryKey: expiryKey,
-		timeFmt:   timeFmt,
-	}
-}
-
-func (c *commandTokenSource) Token() (*oauth2.Token, error) {
-	fullCmd := strings.Join(append([]string{c.cmd}, c.args...), " ")
-	cmd := execCommand(c.cmd, c.args...)
-	var stderr bytes.Buffer
-	cmd.Stderr = &stderr
-	output, err := cmd.Output()
-	if err != nil {
-		return nil, fmt.Errorf("error executing access token command %q: err=%v output=%s stderr=%s", fullCmd, err, output, string(stderr.Bytes()))
-	}
-	token, err := c.parseTokenCmdOutput(output)
-	if err != nil {
-		return nil, fmt.Errorf("error parsing output for access token command %q: %v", fullCmd, err)
-	}
-	return token, nil
-}
-
-func (c *commandTokenSource) parseTokenCmdOutput(output []byte) (*oauth2.Token, error) {
-	output, err := yaml.ToJSON(output)
-	if err != nil {
-		return nil, err
-	}
-	var data interface{}
-	if err := json.Unmarshal(output, &data); err != nil {
-		return nil, err
-	}
-
-	accessToken, err := parseJSONPath(data, "token-key", c.tokenKey)
-	if err != nil {
-		return nil, fmt.Errorf("error parsing token-key %q from %q: %v", c.tokenKey, string(output), err)
-	}
-	expiryStr, err := parseJSONPath(data, "expiry-key", c.expiryKey)
-	if err != nil {
-		return nil, fmt.Errorf("error parsing expiry-key %q from %q: %v", c.expiryKey, string(output), err)
-	}
-	var expiry time.Time
-	if t, err := time.Parse(c.timeFmt, expiryStr); err != nil {
-		klog.V(4).Infof("Failed to parse token expiry from %s (fmt=%s): %v", expiryStr, c.timeFmt, err)
-	} else {
-		expiry = t
-	}
-
-	return &oauth2.Token{
-		AccessToken: accessToken,
-		TokenType:   "Bearer",
-		Expiry:      expiry,
-	}, nil
-}
-
-func parseJSONPath(input interface{}, name, template string) (string, error) {
-	j := jsonpath.New(name)
-	buf := new(bytes.Buffer)
-	if err := j.Parse(template); err != nil {
-		return "", err
-	}
-	if err := j.Execute(buf, input); err != nil {
-		return "", err
-	}
-	return buf.String(), nil
-}
-
-type conditionalTransport struct {
-	oauthTransport *oauth2.Transport
-	persister      restclient.AuthProviderConfigPersister
-	resetCache     map[string]string
-}
-
-var _ net.RoundTripperWrapper = &conditionalTransport{}
-
-func (t *conditionalTransport) RoundTrip(req *http.Request) (*http.Response, error) {
-	if len(req.Header.Get("Authorization")) != 0 {
-		return t.oauthTransport.Base.RoundTrip(req)
-	}
-
-	res, err := t.oauthTransport.RoundTrip(req)
-
-	if err != nil {
-		return nil, err
-	}
-
-	if res.StatusCode == 401 {
-		klog.V(4).Infof("The credentials that were supplied are invalid for the target cluster")
-		t.persister.Persist(t.resetCache)
-	}
-
-	return res, nil
-}
-
-func (t *conditionalTransport) WrappedRoundTripper() http.RoundTripper { return t.oauthTransport.Base }
diff --git a/vendor/k8s.io/client-go/third_party/forked/golang/template/exec.go b/vendor/k8s.io/client-go/third_party/forked/golang/template/exec.go
deleted file mode 100644
index 739fd3509..000000000
--- a/vendor/k8s.io/client-go/third_party/forked/golang/template/exec.go
+++ /dev/null
@@ -1,94 +0,0 @@
-//This package is copied from Go library text/template.
-//The original private functions indirect and printableValue
-//are exported as public functions.
-package template
-
-import (
-	"fmt"
-	"reflect"
-)
-
-var Indirect = indirect
-var PrintableValue = printableValue
-
-var (
-	errorType       = reflect.TypeOf((*error)(nil)).Elem()
-	fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
-)
-
-// indirect returns the item at the end of indirection, and a bool to indicate if it's nil.
-// We indirect through pointers and empty interfaces (only) because
-// non-empty interfaces have methods we might need.
-func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
-	for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {
-		if v.IsNil() {
-			return v, true
-		}
-		if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
-			break
-		}
-	}
-	return v, false
-}
-
-// printableValue returns the, possibly indirected, interface value inside v that
-// is best for a call to formatted printer.
-func printableValue(v reflect.Value) (interface{}, bool) {
-	if v.Kind() == reflect.Ptr {
-		v, _ = indirect(v) // fmt.Fprint handles nil.
-	}
-	if !v.IsValid() {
-		return "<no value>", true
-	}
-
-	if !v.Type().Implements(errorType) && !v.Type().Implements(fmtStringerType) {
-		if v.CanAddr() && (reflect.PtrTo(v.Type()).Implements(errorType) || reflect.PtrTo(v.Type()).Implements(fmtStringerType)) {
-			v = v.Addr()
-		} else {
-			switch v.Kind() {
-			case reflect.Chan, reflect.Func:
-				return nil, false
-			}
-		}
-	}
-	return v.Interface(), true
-}
-
-// canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.
-func canBeNil(typ reflect.Type) bool {
-	switch typ.Kind() {
-	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
-		return true
-	}
-	return false
-}
-
-// isTrue reports whether the value is 'true', in the sense of not the zero of its type,
-// and whether the value has a meaningful truth value.
-func isTrue(val reflect.Value) (truth, ok bool) {
-	if !val.IsValid() {
-		// Something like var x interface{}, never set. It's a form of nil.
-		return false, true
-	}
-	switch val.Kind() {
-	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
-		truth = val.Len() > 0
-	case reflect.Bool:
-		truth = val.Bool()
-	case reflect.Complex64, reflect.Complex128:
-		truth = val.Complex() != 0
-	case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface:
-		truth = !val.IsNil()
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		truth = val.Int() != 0
-	case reflect.Float32, reflect.Float64:
-		truth = val.Float() != 0
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		truth = val.Uint() != 0
-	case reflect.Struct:
-		truth = true // Struct values are always true.
-	default:
-		return
-	}
-	return truth, true
-}
diff --git a/vendor/k8s.io/client-go/third_party/forked/golang/template/funcs.go b/vendor/k8s.io/client-go/third_party/forked/golang/template/funcs.go
deleted file mode 100644
index 27a008b0a..000000000
--- a/vendor/k8s.io/client-go/third_party/forked/golang/template/funcs.go
+++ /dev/null
@@ -1,599 +0,0 @@
-//This package is copied from Go library text/template.
-//The original private functions eq, ge, gt, le, lt, and ne
-//are exported as public functions.
-package template
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"net/url"
-	"reflect"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-)
-
-var Equal = eq
-var GreaterEqual = ge
-var Greater = gt
-var LessEqual = le
-var Less = lt
-var NotEqual = ne
-
-// FuncMap is the type of the map defining the mapping from names to functions.
-// Each function must have either a single return value, or two return values of
-// which the second has type error. In that case, if the second (error)
-// return value evaluates to non-nil during execution, execution terminates and
-// Execute returns that error.
-type FuncMap map[string]interface{}
-
-var builtins = FuncMap{
-	"and":      and,
-	"call":     call,
-	"html":     HTMLEscaper,
-	"index":    index,
-	"js":       JSEscaper,
-	"len":      length,
-	"not":      not,
-	"or":       or,
-	"print":    fmt.Sprint,
-	"printf":   fmt.Sprintf,
-	"println":  fmt.Sprintln,
-	"urlquery": URLQueryEscaper,
-
-	// Comparisons
-	"eq": eq, // ==
-	"ge": ge, // >=
-	"gt": gt, // >
-	"le": le, // <=
-	"lt": lt, // <
-	"ne": ne, // !=
-}
-
-var builtinFuncs = createValueFuncs(builtins)
-
-// createValueFuncs turns a FuncMap into a map[string]reflect.Value
-func createValueFuncs(funcMap FuncMap) map[string]reflect.Value {
-	m := make(map[string]reflect.Value)
-	addValueFuncs(m, funcMap)
-	return m
-}
-
-// addValueFuncs adds to values the functions in funcs, converting them to reflect.Values.
-func addValueFuncs(out map[string]reflect.Value, in FuncMap) {
-	for name, fn := range in {
-		v := reflect.ValueOf(fn)
-		if v.Kind() != reflect.Func {
-			panic("value for " + name + " not a function")
-		}
-		if !goodFunc(v.Type()) {
-			panic(fmt.Errorf("can't install method/function %q with %d results", name, v.Type().NumOut()))
-		}
-		out[name] = v
-	}
-}
-
-// AddFuncs adds to values the functions in funcs. It does no checking of the input -
-// call addValueFuncs first.
-func addFuncs(out, in FuncMap) {
-	for name, fn := range in {
-		out[name] = fn
-	}
-}
-
-// goodFunc checks that the function or method has the right result signature.
-func goodFunc(typ reflect.Type) bool {
-	// We allow functions with 1 result or 2 results where the second is an error.
-	switch {
-	case typ.NumOut() == 1:
-		return true
-	case typ.NumOut() == 2 && typ.Out(1) == errorType:
-		return true
-	}
-	return false
-}
-
-// findFunction looks for a function in the template, and global map.
-func findFunction(name string) (reflect.Value, bool) {
-	if fn := builtinFuncs[name]; fn.IsValid() {
-		return fn, true
-	}
-	return reflect.Value{}, false
-}
-
-// Indexing.
-
-// index returns the result of indexing its first argument by the following
-// arguments.  Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each
-// indexed item must be a map, slice, or array.
-func index(item interface{}, indices ...interface{}) (interface{}, error) {
-	v := reflect.ValueOf(item)
-	for _, i := range indices {
-		index := reflect.ValueOf(i)
-		var isNil bool
-		if v, isNil = indirect(v); isNil {
-			return nil, fmt.Errorf("index of nil pointer")
-		}
-		switch v.Kind() {
-		case reflect.Array, reflect.Slice, reflect.String:
-			var x int64
-			switch index.Kind() {
-			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-				x = index.Int()
-			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-				x = int64(index.Uint())
-			default:
-				return nil, fmt.Errorf("cannot index slice/array with type %s", index.Type())
-			}
-			if x < 0 || x >= int64(v.Len()) {
-				return nil, fmt.Errorf("index out of range: %d", x)
-			}
-			v = v.Index(int(x))
-		case reflect.Map:
-			if !index.IsValid() {
-				index = reflect.Zero(v.Type().Key())
-			}
-			if !index.Type().AssignableTo(v.Type().Key()) {
-				return nil, fmt.Errorf("%s is not index type for %s", index.Type(), v.Type())
-			}
-			if x := v.MapIndex(index); x.IsValid() {
-				v = x
-			} else {
-				v = reflect.Zero(v.Type().Elem())
-			}
-		default:
-			return nil, fmt.Errorf("can't index item of type %s", v.Type())
-		}
-	}
-	return v.Interface(), nil
-}
-
-// Length
-
-// length returns the length of the item, with an error if it has no defined length.
-func length(item interface{}) (int, error) {
-	v, isNil := indirect(reflect.ValueOf(item))
-	if isNil {
-		return 0, fmt.Errorf("len of nil pointer")
-	}
-	switch v.Kind() {
-	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
-		return v.Len(), nil
-	}
-	return 0, fmt.Errorf("len of type %s", v.Type())
-}
-
-// Function invocation
-
-// call returns the result of evaluating the first argument as a function.
-// The function must return 1 result, or 2 results, the second of which is an error.
-func call(fn interface{}, args ...interface{}) (interface{}, error) {
-	v := reflect.ValueOf(fn)
-	typ := v.Type()
-	if typ.Kind() != reflect.Func {
-		return nil, fmt.Errorf("non-function of type %s", typ)
-	}
-	if !goodFunc(typ) {
-		return nil, fmt.Errorf("function called with %d args; should be 1 or 2", typ.NumOut())
-	}
-	numIn := typ.NumIn()
-	var dddType reflect.Type
-	if typ.IsVariadic() {
-		if len(args) < numIn-1 {
-			return nil, fmt.Errorf("wrong number of args: got %d want at least %d", len(args), numIn-1)
-		}
-		dddType = typ.In(numIn - 1).Elem()
-	} else {
-		if len(args) != numIn {
-			return nil, fmt.Errorf("wrong number of args: got %d want %d", len(args), numIn)
-		}
-	}
-	argv := make([]reflect.Value, len(args))
-	for i, arg := range args {
-		value := reflect.ValueOf(arg)
-		// Compute the expected type. Clumsy because of variadics.
-		var argType reflect.Type
-		if !typ.IsVariadic() || i < numIn-1 {
-			argType = typ.In(i)
-		} else {
-			argType = dddType
-		}
-		if !value.IsValid() && canBeNil(argType) {
-			value = reflect.Zero(argType)
-		}
-		if !value.Type().AssignableTo(argType) {
-			return nil, fmt.Errorf("arg %d has type %s; should be %s", i, value.Type(), argType)
-		}
-		argv[i] = value
-	}
-	result := v.Call(argv)
-	if len(result) == 2 && !result[1].IsNil() {
-		return result[0].Interface(), result[1].Interface().(error)
-	}
-	return result[0].Interface(), nil
-}
-
-// Boolean logic.
-
-func truth(a interface{}) bool {
-	t, _ := isTrue(reflect.ValueOf(a))
-	return t
-}
-
-// and computes the Boolean AND of its arguments, returning
-// the first false argument it encounters, or the last argument.
-func and(arg0 interface{}, args ...interface{}) interface{} {
-	if !truth(arg0) {
-		return arg0
-	}
-	for i := range args {
-		arg0 = args[i]
-		if !truth(arg0) {
-			break
-		}
-	}
-	return arg0
-}
-
-// or computes the Boolean OR of its arguments, returning
-// the first true argument it encounters, or the last argument.
-func or(arg0 interface{}, args ...interface{}) interface{} {
-	if truth(arg0) {
-		return arg0
-	}
-	for i := range args {
-		arg0 = args[i]
-		if truth(arg0) {
-			break
-		}
-	}
-	return arg0
-}
-
-// not returns the Boolean negation of its argument.
-func not(arg interface{}) (truth bool) {
-	truth, _ = isTrue(reflect.ValueOf(arg))
-	return !truth
-}
-
-// Comparison.
-
-// TODO: Perhaps allow comparison between signed and unsigned integers.
-
-var (
-	errBadComparisonType = errors.New("invalid type for comparison")
-	errBadComparison     = errors.New("incompatible types for comparison")
-	errNoComparison      = errors.New("missing argument for comparison")
-)
-
-type kind int
-
-const (
-	invalidKind kind = iota
-	boolKind
-	complexKind
-	intKind
-	floatKind
-	integerKind
-	stringKind
-	uintKind
-)
-
-func basicKind(v reflect.Value) (kind, error) {
-	switch v.Kind() {
-	case reflect.Bool:
-		return boolKind, nil
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return intKind, nil
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return uintKind, nil
-	case reflect.Float32, reflect.Float64:
-		return floatKind, nil
-	case reflect.Complex64, reflect.Complex128:
-		return complexKind, nil
-	case reflect.String:
-		return stringKind, nil
-	}
-	return invalidKind, errBadComparisonType
-}
-
-// eq evaluates the comparison a == b || a == c || ...
-func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
-	v1 := reflect.ValueOf(arg1)
-	k1, err := basicKind(v1)
-	if err != nil {
-		return false, err
-	}
-	if len(arg2) == 0 {
-		return false, errNoComparison
-	}
-	for _, arg := range arg2 {
-		v2 := reflect.ValueOf(arg)
-		k2, err := basicKind(v2)
-		if err != nil {
-			return false, err
-		}
-		truth := false
-		if k1 != k2 {
-			// Special case: Can compare integer values regardless of type's sign.
-			switch {
-			case k1 == intKind && k2 == uintKind:
-				truth = v1.Int() >= 0 && uint64(v1.Int()) == v2.Uint()
-			case k1 == uintKind && k2 == intKind:
-				truth = v2.Int() >= 0 && v1.Uint() == uint64(v2.Int())
-			default:
-				return false, errBadComparison
-			}
-		} else {
-			switch k1 {
-			case boolKind:
-				truth = v1.Bool() == v2.Bool()
-			case complexKind:
-				truth = v1.Complex() == v2.Complex()
-			case floatKind:
-				truth = v1.Float() == v2.Float()
-			case intKind:
-				truth = v1.Int() == v2.Int()
-			case stringKind:
-				truth = v1.String() == v2.String()
-			case uintKind:
-				truth = v1.Uint() == v2.Uint()
-			default:
-				panic("invalid kind")
-			}
-		}
-		if truth {
-			return true, nil
-		}
-	}
-	return false, nil
-}
-
-// ne evaluates the comparison a != b.
-func ne(arg1, arg2 interface{}) (bool, error) {
-	// != is the inverse of ==.
-	equal, err := eq(arg1, arg2)
-	return !equal, err
-}
-
-// lt evaluates the comparison a < b.
-func lt(arg1, arg2 interface{}) (bool, error) {
-	v1 := reflect.ValueOf(arg1)
-	k1, err := basicKind(v1)
-	if err != nil {
-		return false, err
-	}
-	v2 := reflect.ValueOf(arg2)
-	k2, err := basicKind(v2)
-	if err != nil {
-		return false, err
-	}
-	truth := false
-	if k1 != k2 {
-		// Special case: Can compare integer values regardless of type's sign.
-		switch {
-		case k1 == intKind && k2 == uintKind:
-			truth = v1.Int() < 0 || uint64(v1.Int()) < v2.Uint()
-		case k1 == uintKind && k2 == intKind:
-			truth = v2.Int() >= 0 && v1.Uint() < uint64(v2.Int())
-		default:
-			return false, errBadComparison
-		}
-	} else {
-		switch k1 {
-		case boolKind, complexKind:
-			return false, errBadComparisonType
-		case floatKind:
-			truth = v1.Float() < v2.Float()
-		case intKind:
-			truth = v1.Int() < v2.Int()
-		case stringKind:
-			truth = v1.String() < v2.String()
-		case uintKind:
-			truth = v1.Uint() < v2.Uint()
-		default:
-			panic("invalid kind")
-		}
-	}
-	return truth, nil
-}
-
-// le evaluates the comparison <= b.
-func le(arg1, arg2 interface{}) (bool, error) {
-	// <= is < or ==.
-	lessThan, err := lt(arg1, arg2)
-	if lessThan || err != nil {
-		return lessThan, err
-	}
-	return eq(arg1, arg2)
-}
-
-// gt evaluates the comparison a > b.
-func gt(arg1, arg2 interface{}) (bool, error) {
-	// > is the inverse of <=.
-	lessOrEqual, err := le(arg1, arg2)
-	if err != nil {
-		return false, err
-	}
-	return !lessOrEqual, nil
-}
-
-// ge evaluates the comparison a >= b.
-func ge(arg1, arg2 interface{}) (bool, error) {
-	// >= is the inverse of <.
-	lessThan, err := lt(arg1, arg2)
-	if err != nil {
-		return false, err
-	}
-	return !lessThan, nil
-}
-
-// HTML escaping.
-
-var (
-	htmlQuot = []byte("&#34;") // shorter than "&quot;"
-	htmlApos = []byte("&#39;") // shorter than "&apos;" and apos was not in HTML until HTML5
-	htmlAmp  = []byte("&amp;")
-	htmlLt   = []byte("&lt;")
-	htmlGt   = []byte("&gt;")
-)
-
-// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
-func HTMLEscape(w io.Writer, b []byte) {
-	last := 0
-	for i, c := range b {
-		var html []byte
-		switch c {
-		case '"':
-			html = htmlQuot
-		case '\'':
-			html = htmlApos
-		case '&':
-			html = htmlAmp
-		case '<':
-			html = htmlLt
-		case '>':
-			html = htmlGt
-		default:
-			continue
-		}
-		w.Write(b[last:i])
-		w.Write(html)
-		last = i + 1
-	}
-	w.Write(b[last:])
-}
-
-// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
-func HTMLEscapeString(s string) string {
-	// Avoid allocation if we can.
-	if strings.IndexAny(s, `'"&<>`) < 0 {
-		return s
-	}
-	var b bytes.Buffer
-	HTMLEscape(&b, []byte(s))
-	return b.String()
-}
-
-// HTMLEscaper returns the escaped HTML equivalent of the textual
-// representation of its arguments.
-func HTMLEscaper(args ...interface{}) string {
-	return HTMLEscapeString(evalArgs(args))
-}
-
-// JavaScript escaping.
-
-var (
-	jsLowUni = []byte(`\u00`)
-	hex      = []byte("0123456789ABCDEF")
-
-	jsBackslash = []byte(`\\`)
-	jsApos      = []byte(`\'`)
-	jsQuot      = []byte(`\"`)
-	jsLt        = []byte(`\x3C`)
-	jsGt        = []byte(`\x3E`)
-)
-
-// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
-func JSEscape(w io.Writer, b []byte) {
-	last := 0
-	for i := 0; i < len(b); i++ {
-		c := b[i]
-
-		if !jsIsSpecial(rune(c)) {
-			// fast path: nothing to do
-			continue
-		}
-		w.Write(b[last:i])
-
-		if c < utf8.RuneSelf {
-			// Quotes, slashes and angle brackets get quoted.
-			// Control characters get written as \u00XX.
-			switch c {
-			case '\\':
-				w.Write(jsBackslash)
-			case '\'':
-				w.Write(jsApos)
-			case '"':
-				w.Write(jsQuot)
-			case '<':
-				w.Write(jsLt)
-			case '>':
-				w.Write(jsGt)
-			default:
-				w.Write(jsLowUni)
-				t, b := c>>4, c&0x0f
-				w.Write(hex[t : t+1])
-				w.Write(hex[b : b+1])
-			}
-		} else {
-			// Unicode rune.
-			r, size := utf8.DecodeRune(b[i:])
-			if unicode.IsPrint(r) {
-				w.Write(b[i : i+size])
-			} else {
-				fmt.Fprintf(w, "\\u%04X", r)
-			}
-			i += size - 1
-		}
-		last = i + 1
-	}
-	w.Write(b[last:])
-}
-
-// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
-func JSEscapeString(s string) string {
-	// Avoid allocation if we can.
-	if strings.IndexFunc(s, jsIsSpecial) < 0 {
-		return s
-	}
-	var b bytes.Buffer
-	JSEscape(&b, []byte(s))
-	return b.String()
-}
-
-func jsIsSpecial(r rune) bool {
-	switch r {
-	case '\\', '\'', '"', '<', '>':
-		return true
-	}
-	return r < ' ' || utf8.RuneSelf <= r
-}
-
-// JSEscaper returns the escaped JavaScript equivalent of the textual
-// representation of its arguments.
-func JSEscaper(args ...interface{}) string {
-	return JSEscapeString(evalArgs(args))
-}
-
-// URLQueryEscaper returns the escaped value of the textual representation of
-// its arguments in a form suitable for embedding in a URL query.
-func URLQueryEscaper(args ...interface{}) string {
-	return url.QueryEscape(evalArgs(args))
-}
-
-// evalArgs formats the list of arguments into a string. It is therefore equivalent to
-//	fmt.Sprint(args...)
-// except that each argument is indirected (if a pointer), as required,
-// using the same rules as the default string evaluation during template
-// execution.
-func evalArgs(args []interface{}) string {
-	ok := false
-	var s string
-	// Fast path for simple common case.
-	if len(args) == 1 {
-		s, ok = args[0].(string)
-	}
-	if !ok {
-		for i, arg := range args {
-			a, ok := printableValue(reflect.ValueOf(arg))
-			if ok {
-				args[i] = a
-			} // else left fmt do its thing
-		}
-		s = fmt.Sprint(args...)
-	}
-	return s
-}
diff --git a/vendor/k8s.io/client-go/util/jsonpath/doc.go b/vendor/k8s.io/client-go/util/jsonpath/doc.go
deleted file mode 100644
index 0effb15c4..000000000
--- a/vendor/k8s.io/client-go/util/jsonpath/doc.go
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-// package jsonpath is a template engine using jsonpath syntax,
-// which can be seen at http://goessner.net/articles/JsonPath/.
-// In addition, it has {range} {end} function to iterate list and slice.
-package jsonpath // import "k8s.io/client-go/util/jsonpath"
diff --git a/vendor/k8s.io/client-go/util/jsonpath/jsonpath.go b/vendor/k8s.io/client-go/util/jsonpath/jsonpath.go
deleted file mode 100644
index 78b6b678f..000000000
--- a/vendor/k8s.io/client-go/util/jsonpath/jsonpath.go
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-package jsonpath
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"reflect"
-	"strings"
-
-	"k8s.io/client-go/third_party/forked/golang/template"
-)
-
-type JSONPath struct {
-	name       string
-	parser     *Parser
-	stack      [][]reflect.Value // push and pop values in different scopes
-	cur        []reflect.Value   // current scope values
-	beginRange int
-	inRange    int
-	endRange   int
-
-	allowMissingKeys bool
-}
-
-// New creates a new JSONPath with the given name.
-func New(name string) *JSONPath {
-	return &JSONPath{
-		name:       name,
-		beginRange: 0,
-		inRange:    0,
-		endRange:   0,
-	}
-}
-
-// AllowMissingKeys allows a caller to specify whether they want an error if a field or map key
-// cannot be located, or simply an empty result. The receiver is returned for chaining.
-func (j *JSONPath) AllowMissingKeys(allow bool) *JSONPath {
-	j.allowMissingKeys = allow
-	return j
-}
-
-// Parse parses the given template and returns an error.
-func (j *JSONPath) Parse(text string) error {
-	var err error
-	j.parser, err = Parse(j.name, text)
-	return err
-}
-
-// Execute bounds data into template and writes the result.
-func (j *JSONPath) Execute(wr io.Writer, data interface{}) error {
-	fullResults, err := j.FindResults(data)
-	if err != nil {
-		return err
-	}
-	for ix := range fullResults {
-		if err := j.PrintResults(wr, fullResults[ix]); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (j *JSONPath) FindResults(data interface{}) ([][]reflect.Value, error) {
-	if j.parser == nil {
-		return nil, fmt.Errorf("%s is an incomplete jsonpath template", j.name)
-	}
-
-	j.cur = []reflect.Value{reflect.ValueOf(data)}
-	nodes := j.parser.Root.Nodes
-	fullResult := [][]reflect.Value{}
-	for i := 0; i < len(nodes); i++ {
-		node := nodes[i]
-		results, err := j.walk(j.cur, node)
-		if err != nil {
-			return nil, err
-		}
-
-		// encounter an end node, break the current block
-		if j.endRange > 0 && j.endRange <= j.inRange {
-			j.endRange--
-			break
-		}
-		// encounter a range node, start a range loop
-		if j.beginRange > 0 {
-			j.beginRange--
-			j.inRange++
-			for k, value := range results {
-				j.parser.Root.Nodes = nodes[i+1:]
-				if k == len(results)-1 {
-					j.inRange--
-				}
-				nextResults, err := j.FindResults(value.Interface())
-				if err != nil {
-					return nil, err
-				}
-				fullResult = append(fullResult, nextResults...)
-			}
-			break
-		}
-		fullResult = append(fullResult, results)
-	}
-	return fullResult, nil
-}
-
-// PrintResults writes the results into writer
-func (j *JSONPath) PrintResults(wr io.Writer, results []reflect.Value) error {
-	for i, r := range results {
-		text, err := j.evalToText(r)
-		if err != nil {
-			return err
-		}
-		if i != len(results)-1 {
-			text = append(text, ' ')
-		}
-		if _, err = wr.Write(text); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-// walk visits tree rooted at the given node in DFS order
-func (j *JSONPath) walk(value []reflect.Value, node Node) ([]reflect.Value, error) {
-	switch node := node.(type) {
-	case *ListNode:
-		return j.evalList(value, node)
-	case *TextNode:
-		return []reflect.Value{reflect.ValueOf(node.Text)}, nil
-	case *FieldNode:
-		return j.evalField(value, node)
-	case *ArrayNode:
-		return j.evalArray(value, node)
-	case *FilterNode:
-		return j.evalFilter(value, node)
-	case *IntNode:
-		return j.evalInt(value, node)
-	case *BoolNode:
-		return j.evalBool(value, node)
-	case *FloatNode:
-		return j.evalFloat(value, node)
-	case *WildcardNode:
-		return j.evalWildcard(value, node)
-	case *RecursiveNode:
-		return j.evalRecursive(value, node)
-	case *UnionNode:
-		return j.evalUnion(value, node)
-	case *IdentifierNode:
-		return j.evalIdentifier(value, node)
-	default:
-		return value, fmt.Errorf("unexpected Node %v", node)
-	}
-}
-
-// evalInt evaluates IntNode
-func (j *JSONPath) evalInt(input []reflect.Value, node *IntNode) ([]reflect.Value, error) {
-	result := make([]reflect.Value, len(input))
-	for i := range input {
-		result[i] = reflect.ValueOf(node.Value)
-	}
-	return result, nil
-}
-
-// evalFloat evaluates FloatNode
-func (j *JSONPath) evalFloat(input []reflect.Value, node *FloatNode) ([]reflect.Value, error) {
-	result := make([]reflect.Value, len(input))
-	for i := range input {
-		result[i] = reflect.ValueOf(node.Value)
-	}
-	return result, nil
-}
-
-// evalBool evaluates BoolNode
-func (j *JSONPath) evalBool(input []reflect.Value, node *BoolNode) ([]reflect.Value, error) {
-	result := make([]reflect.Value, len(input))
-	for i := range input {
-		result[i] = reflect.ValueOf(node.Value)
-	}
-	return result, nil
-}
-
-// evalList evaluates ListNode
-func (j *JSONPath) evalList(value []reflect.Value, node *ListNode) ([]reflect.Value, error) {
-	var err error
-	curValue := value
-	for _, node := range node.Nodes {
-		curValue, err = j.walk(curValue, node)
-		if err != nil {
-			return curValue, err
-		}
-	}
-	return curValue, nil
-}
-
-// evalIdentifier evaluates IdentifierNode
-func (j *JSONPath) evalIdentifier(input []reflect.Value, node *IdentifierNode) ([]reflect.Value, error) {
-	results := []reflect.Value{}
-	switch node.Name {
-	case "range":
-		j.stack = append(j.stack, j.cur)
-		j.beginRange++
-		results = input
-	case "end":
-		if j.endRange < j.inRange { // inside a loop, break the current block
-			j.endRange++
-			break
-		}
-		// the loop is about to end, pop value and continue the following execution
-		if len(j.stack) > 0 {
-			j.cur, j.stack = j.stack[len(j.stack)-1], j.stack[:len(j.stack)-1]
-		} else {
-			return results, fmt.Errorf("not in range, nothing to end")
-		}
-	default:
-		return input, fmt.Errorf("unrecognized identifier %v", node.Name)
-	}
-	return results, nil
-}
-
-// evalArray evaluates ArrayNode
-func (j *JSONPath) evalArray(input []reflect.Value, node *ArrayNode) ([]reflect.Value, error) {
-	result := []reflect.Value{}
-	for _, value := range input {
-
-		value, isNil := template.Indirect(value)
-		if isNil {
-			continue
-		}
-		if value.Kind() != reflect.Array && value.Kind() != reflect.Slice {
-			return input, fmt.Errorf("%v is not array or slice", value.Type())
-		}
-		params := node.Params
-		if !params[0].Known {
-			params[0].Value = 0
-		}
-		if params[0].Value < 0 {
-			params[0].Value += value.Len()
-		}
-		if !params[1].Known {
-			params[1].Value = value.Len()
-		}
-
-		if params[1].Value < 0 || (params[1].Value == 0 && params[1].Derived) {
-			params[1].Value += value.Len()
-		}
-		sliceLength := value.Len()
-		if params[1].Value != params[0].Value { // if you're requesting zero elements, allow it through.
-			if params[0].Value >= sliceLength || params[0].Value < 0 {
-				return input, fmt.Errorf("array index out of bounds: index %d, length %d", params[0].Value, sliceLength)
-			}
-			if params[1].Value > sliceLength || params[1].Value < 0 {
-				return input, fmt.Errorf("array index out of bounds: index %d, length %d", params[1].Value-1, sliceLength)
-			}
-			if params[0].Value > params[1].Value {
-				return input, fmt.Errorf("starting index %d is greater than ending index %d", params[0].Value, params[1].Value)
-			}
-		} else {
-			return result, nil
-		}
-
-		value = value.Slice(params[0].Value, params[1].Value)
-
-		step := 1
-		if params[2].Known {
-			if params[2].Value <= 0 {
-				return input, fmt.Errorf("step must be > 0")
-			}
-			step = params[2].Value
-		}
-		for i := 0; i < value.Len(); i += step {
-			result = append(result, value.Index(i))
-		}
-	}
-	return result, nil
-}
-
-// evalUnion evaluates UnionNode
-func (j *JSONPath) evalUnion(input []reflect.Value, node *UnionNode) ([]reflect.Value, error) {
-	result := []reflect.Value{}
-	for _, listNode := range node.Nodes {
-		temp, err := j.evalList(input, listNode)
-		if err != nil {
-			return input, err
-		}
-		result = append(result, temp...)
-	}
-	return result, nil
-}
-
-func (j *JSONPath) findFieldInValue(value *reflect.Value, node *FieldNode) (reflect.Value, error) {
-	t := value.Type()
-	var inlineValue *reflect.Value
-	for ix := 0; ix < t.NumField(); ix++ {
-		f := t.Field(ix)
-		jsonTag := f.Tag.Get("json")
-		parts := strings.Split(jsonTag, ",")
-		if len(parts) == 0 {
-			continue
-		}
-		if parts[0] == node.Value {
-			return value.Field(ix), nil
-		}
-		if len(parts[0]) == 0 {
-			val := value.Field(ix)
-			inlineValue = &val
-		}
-	}
-	if inlineValue != nil {
-		if inlineValue.Kind() == reflect.Struct {
-			// handle 'inline'
-			match, err := j.findFieldInValue(inlineValue, node)
-			if err != nil {
-				return reflect.Value{}, err
-			}
-			if match.IsValid() {
-				return match, nil
-			}
-		}
-	}
-	return value.FieldByName(node.Value), nil
-}
-
-// evalField evaluates field of struct or key of map.
-func (j *JSONPath) evalField(input []reflect.Value, node *FieldNode) ([]reflect.Value, error) {
-	results := []reflect.Value{}
-	// If there's no input, there's no output
-	if len(input) == 0 {
-		return results, nil
-	}
-	for _, value := range input {
-		var result reflect.Value
-		value, isNil := template.Indirect(value)
-		if isNil {
-			continue
-		}
-
-		if value.Kind() == reflect.Struct {
-			var err error
-			if result, err = j.findFieldInValue(&value, node); err != nil {
-				return nil, err
-			}
-		} else if value.Kind() == reflect.Map {
-			mapKeyType := value.Type().Key()
-			nodeValue := reflect.ValueOf(node.Value)
-			// node value type must be convertible to map key type
-			if !nodeValue.Type().ConvertibleTo(mapKeyType) {
-				return results, fmt.Errorf("%s is not convertible to %s", nodeValue, mapKeyType)
-			}
-			result = value.MapIndex(nodeValue.Convert(mapKeyType))
-		}
-		if result.IsValid() {
-			results = append(results, result)
-		}
-	}
-	if len(results) == 0 {
-		if j.allowMissingKeys {
-			return results, nil
-		}
-		return results, fmt.Errorf("%s is not found", node.Value)
-	}
-	return results, nil
-}
-
-// evalWildcard extracts all contents of the given value
-func (j *JSONPath) evalWildcard(input []reflect.Value, node *WildcardNode) ([]reflect.Value, error) {
-	results := []reflect.Value{}
-	for _, value := range input {
-		value, isNil := template.Indirect(value)
-		if isNil {
-			continue
-		}
-
-		kind := value.Kind()
-		if kind == reflect.Struct {
-			for i := 0; i < value.NumField(); i++ {
-				results = append(results, value.Field(i))
-			}
-		} else if kind == reflect.Map {
-			for _, key := range value.MapKeys() {
-				results = append(results, value.MapIndex(key))
-			}
-		} else if kind == reflect.Array || kind == reflect.Slice || kind == reflect.String {
-			for i := 0; i < value.Len(); i++ {
-				results = append(results, value.Index(i))
-			}
-		}
-	}
-	return results, nil
-}
-
-// evalRecursive visits the given value recursively and pushes all of them to result
-func (j *JSONPath) evalRecursive(input []reflect.Value, node *RecursiveNode) ([]reflect.Value, error) {
-	result := []reflect.Value{}
-	for _, value := range input {
-		results := []reflect.Value{}
-		value, isNil := template.Indirect(value)
-		if isNil {
-			continue
-		}
-
-		kind := value.Kind()
-		if kind == reflect.Struct {
-			for i := 0; i < value.NumField(); i++ {
-				results = append(results, value.Field(i))
-			}
-		} else if kind == reflect.Map {
-			for _, key := range value.MapKeys() {
-				results = append(results, value.MapIndex(key))
-			}
-		} else if kind == reflect.Array || kind == reflect.Slice || kind == reflect.String {
-			for i := 0; i < value.Len(); i++ {
-				results = append(results, value.Index(i))
-			}
-		}
-		if len(results) != 0 {
-			result = append(result, value)
-			output, err := j.evalRecursive(results, node)
-			if err != nil {
-				return result, err
-			}
-			result = append(result, output...)
-		}
-	}
-	return result, nil
-}
-
-// evalFilter filters array according to FilterNode
-func (j *JSONPath) evalFilter(input []reflect.Value, node *FilterNode) ([]reflect.Value, error) {
-	results := []reflect.Value{}
-	for _, value := range input {
-		value, _ = template.Indirect(value)
-
-		if value.Kind() != reflect.Array && value.Kind() != reflect.Slice {
-			return input, fmt.Errorf("%v is not array or slice and cannot be filtered", value)
-		}
-		for i := 0; i < value.Len(); i++ {
-			temp := []reflect.Value{value.Index(i)}
-			lefts, err := j.evalList(temp, node.Left)
-
-			//case exists
-			if node.Operator == "exists" {
-				if len(lefts) > 0 {
-					results = append(results, value.Index(i))
-				}
-				continue
-			}
-
-			if err != nil {
-				return input, err
-			}
-
-			var left, right interface{}
-			switch {
-			case len(lefts) == 0:
-				continue
-			case len(lefts) > 1:
-				return input, fmt.Errorf("can only compare one element at a time")
-			}
-			left = lefts[0].Interface()
-
-			rights, err := j.evalList(temp, node.Right)
-			if err != nil {
-				return input, err
-			}
-			switch {
-			case len(rights) == 0:
-				continue
-			case len(rights) > 1:
-				return input, fmt.Errorf("can only compare one element at a time")
-			}
-			right = rights[0].Interface()
-
-			pass := false
-			switch node.Operator {
-			case "<":
-				pass, err = template.Less(left, right)
-			case ">":
-				pass, err = template.Greater(left, right)
-			case "==":
-				pass, err = template.Equal(left, right)
-			case "!=":
-				pass, err = template.NotEqual(left, right)
-			case "<=":
-				pass, err = template.LessEqual(left, right)
-			case ">=":
-				pass, err = template.GreaterEqual(left, right)
-			default:
-				return results, fmt.Errorf("unrecognized filter operator %s", node.Operator)
-			}
-			if err != nil {
-				return results, err
-			}
-			if pass {
-				results = append(results, value.Index(i))
-			}
-		}
-	}
-	return results, nil
-}
-
-// evalToText translates reflect value to corresponding text
-func (j *JSONPath) evalToText(v reflect.Value) ([]byte, error) {
-	iface, ok := template.PrintableValue(v)
-	if !ok {
-		return nil, fmt.Errorf("can't print type %s", v.Type())
-	}
-	var buffer bytes.Buffer
-	fmt.Fprint(&buffer, iface)
-	return buffer.Bytes(), nil
-}
diff --git a/vendor/k8s.io/client-go/util/jsonpath/node.go b/vendor/k8s.io/client-go/util/jsonpath/node.go
deleted file mode 100644
index 83abe8b03..000000000
--- a/vendor/k8s.io/client-go/util/jsonpath/node.go
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-package jsonpath
-
-import "fmt"
-
-// NodeType identifies the type of a parse tree node.
-type NodeType int
-
-// Type returns itself and provides an easy default implementation
-func (t NodeType) Type() NodeType {
-	return t
-}
-
-func (t NodeType) String() string {
-	return NodeTypeName[t]
-}
-
-const (
-	NodeText NodeType = iota
-	NodeArray
-	NodeList
-	NodeField
-	NodeIdentifier
-	NodeFilter
-	NodeInt
-	NodeFloat
-	NodeWildcard
-	NodeRecursive
-	NodeUnion
-	NodeBool
-)
-
-var NodeTypeName = map[NodeType]string{
-	NodeText:       "NodeText",
-	NodeArray:      "NodeArray",
-	NodeList:       "NodeList",
-	NodeField:      "NodeField",
-	NodeIdentifier: "NodeIdentifier",
-	NodeFilter:     "NodeFilter",
-	NodeInt:        "NodeInt",
-	NodeFloat:      "NodeFloat",
-	NodeWildcard:   "NodeWildcard",
-	NodeRecursive:  "NodeRecursive",
-	NodeUnion:      "NodeUnion",
-	NodeBool:       "NodeBool",
-}
-
-type Node interface {
-	Type() NodeType
-	String() string
-}
-
-// ListNode holds a sequence of nodes.
-type ListNode struct {
-	NodeType
-	Nodes []Node // The element nodes in lexical order.
-}
-
-func newList() *ListNode {
-	return &ListNode{NodeType: NodeList}
-}
-
-func (l *ListNode) append(n Node) {
-	l.Nodes = append(l.Nodes, n)
-}
-
-func (l *ListNode) String() string {
-	return l.Type().String()
-}
-
-// TextNode holds plain text.
-type TextNode struct {
-	NodeType
-	Text string // The text; may span newlines.
-}
-
-func newText(text string) *TextNode {
-	return &TextNode{NodeType: NodeText, Text: text}
-}
-
-func (t *TextNode) String() string {
-	return fmt.Sprintf("%s: %s", t.Type(), t.Text)
-}
-
-// FieldNode holds field of struct
-type FieldNode struct {
-	NodeType
-	Value string
-}
-
-func newField(value string) *FieldNode {
-	return &FieldNode{NodeType: NodeField, Value: value}
-}
-
-func (f *FieldNode) String() string {
-	return fmt.Sprintf("%s: %s", f.Type(), f.Value)
-}
-
-// IdentifierNode holds an identifier
-type IdentifierNode struct {
-	NodeType
-	Name string
-}
-
-func newIdentifier(value string) *IdentifierNode {
-	return &IdentifierNode{
-		NodeType: NodeIdentifier,
-		Name:     value,
-	}
-}
-
-func (f *IdentifierNode) String() string {
-	return fmt.Sprintf("%s: %s", f.Type(), f.Name)
-}
-
-// ParamsEntry holds param information for ArrayNode
-type ParamsEntry struct {
-	Value   int
-	Known   bool // whether the value is known when parse it
-	Derived bool
-}
-
-// ArrayNode holds start, end, step information for array index selection
-type ArrayNode struct {
-	NodeType
-	Params [3]ParamsEntry // start, end, step
-}
-
-func newArray(params [3]ParamsEntry) *ArrayNode {
-	return &ArrayNode{
-		NodeType: NodeArray,
-		Params:   params,
-	}
-}
-
-func (a *ArrayNode) String() string {
-	return fmt.Sprintf("%s: %v", a.Type(), a.Params)
-}
-
-// FilterNode holds operand and operator information for filter
-type FilterNode struct {
-	NodeType
-	Left     *ListNode
-	Right    *ListNode
-	Operator string
-}
-
-func newFilter(left, right *ListNode, operator string) *FilterNode {
-	return &FilterNode{
-		NodeType: NodeFilter,
-		Left:     left,
-		Right:    right,
-		Operator: operator,
-	}
-}
-
-func (f *FilterNode) String() string {
-	return fmt.Sprintf("%s: %s %s %s", f.Type(), f.Left, f.Operator, f.Right)
-}
-
-// IntNode holds integer value
-type IntNode struct {
-	NodeType
-	Value int
-}
-
-func newInt(num int) *IntNode {
-	return &IntNode{NodeType: NodeInt, Value: num}
-}
-
-func (i *IntNode) String() string {
-	return fmt.Sprintf("%s: %d", i.Type(), i.Value)
-}
-
-// FloatNode holds float value
-type FloatNode struct {
-	NodeType
-	Value float64
-}
-
-func newFloat(num float64) *FloatNode {
-	return &FloatNode{NodeType: NodeFloat, Value: num}
-}
-
-func (i *FloatNode) String() string {
-	return fmt.Sprintf("%s: %f", i.Type(), i.Value)
-}
-
-// WildcardNode means a wildcard
-type WildcardNode struct {
-	NodeType
-}
-
-func newWildcard() *WildcardNode {
-	return &WildcardNode{NodeType: NodeWildcard}
-}
-
-func (i *WildcardNode) String() string {
-	return i.Type().String()
-}
-
-// RecursiveNode means a recursive descent operator
-type RecursiveNode struct {
-	NodeType
-}
-
-func newRecursive() *RecursiveNode {
-	return &RecursiveNode{NodeType: NodeRecursive}
-}
-
-func (r *RecursiveNode) String() string {
-	return r.Type().String()
-}
-
-// UnionNode is union of ListNode
-type UnionNode struct {
-	NodeType
-	Nodes []*ListNode
-}
-
-func newUnion(nodes []*ListNode) *UnionNode {
-	return &UnionNode{NodeType: NodeUnion, Nodes: nodes}
-}
-
-func (u *UnionNode) String() string {
-	return u.Type().String()
-}
-
-// BoolNode holds bool value
-type BoolNode struct {
-	NodeType
-	Value bool
-}
-
-func newBool(value bool) *BoolNode {
-	return &BoolNode{NodeType: NodeBool, Value: value}
-}
-
-func (b *BoolNode) String() string {
-	return fmt.Sprintf("%s: %t", b.Type(), b.Value)
-}
diff --git a/vendor/k8s.io/client-go/util/jsonpath/parser.go b/vendor/k8s.io/client-go/util/jsonpath/parser.go
deleted file mode 100644
index e1aab6804..000000000
--- a/vendor/k8s.io/client-go/util/jsonpath/parser.go
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-package jsonpath
-
-import (
-	"errors"
-	"fmt"
-	"regexp"
-	"strconv"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-)
-
-const eof = -1
-
-const (
-	leftDelim  = "{"
-	rightDelim = "}"
-)
-
-type Parser struct {
-	Name  string
-	Root  *ListNode
-	input string
-	pos   int
-	start int
-	width int
-}
-
-var (
-	ErrSyntax        = errors.New("invalid syntax")
-	dictKeyRex       = regexp.MustCompile(`^'([^']*)'$`)
-	sliceOperatorRex = regexp.MustCompile(`^(-?[\d]*)(:-?[\d]*)?(:-?[\d]*)?$`)
-)
-
-// Parse parsed the given text and return a node Parser.
-// If an error is encountered, parsing stops and an empty
-// Parser is returned with the error
-func Parse(name, text string) (*Parser, error) {
-	p := NewParser(name)
-	err := p.Parse(text)
-	if err != nil {
-		p = nil
-	}
-	return p, err
-}
-
-func NewParser(name string) *Parser {
-	return &Parser{
-		Name: name,
-	}
-}
-
-// parseAction parsed the expression inside delimiter
-func parseAction(name, text string) (*Parser, error) {
-	p, err := Parse(name, fmt.Sprintf("%s%s%s", leftDelim, text, rightDelim))
-	// when error happens, p will be nil, so we need to return here
-	if err != nil {
-		return p, err
-	}
-	p.Root = p.Root.Nodes[0].(*ListNode)
-	return p, nil
-}
-
-func (p *Parser) Parse(text string) error {
-	p.input = text
-	p.Root = newList()
-	p.pos = 0
-	return p.parseText(p.Root)
-}
-
-// consumeText return the parsed text since last cosumeText
-func (p *Parser) consumeText() string {
-	value := p.input[p.start:p.pos]
-	p.start = p.pos
-	return value
-}
-
-// next returns the next rune in the input.
-func (p *Parser) next() rune {
-	if p.pos >= len(p.input) {
-		p.width = 0
-		return eof
-	}
-	r, w := utf8.DecodeRuneInString(p.input[p.pos:])
-	p.width = w
-	p.pos += p.width
-	return r
-}
-
-// peek returns but does not consume the next rune in the input.
-func (p *Parser) peek() rune {
-	r := p.next()
-	p.backup()
-	return r
-}
-
-// backup steps back one rune. Can only be called once per call of next.
-func (p *Parser) backup() {
-	p.pos -= p.width
-}
-
-func (p *Parser) parseText(cur *ListNode) error {
-	for {
-		if strings.HasPrefix(p.input[p.pos:], leftDelim) {
-			if p.pos > p.start {
-				cur.append(newText(p.consumeText()))
-			}
-			return p.parseLeftDelim(cur)
-		}
-		if p.next() == eof {
-			break
-		}
-	}
-	// Correctly reached EOF.
-	if p.pos > p.start {
-		cur.append(newText(p.consumeText()))
-	}
-	return nil
-}
-
-// parseLeftDelim scans the left delimiter, which is known to be present.
-func (p *Parser) parseLeftDelim(cur *ListNode) error {
-	p.pos += len(leftDelim)
-	p.consumeText()
-	newNode := newList()
-	cur.append(newNode)
-	cur = newNode
-	return p.parseInsideAction(cur)
-}
-
-func (p *Parser) parseInsideAction(cur *ListNode) error {
-	prefixMap := map[string]func(*ListNode) error{
-		rightDelim: p.parseRightDelim,
-		"[?(":      p.parseFilter,
-		"..":       p.parseRecursive,
-	}
-	for prefix, parseFunc := range prefixMap {
-		if strings.HasPrefix(p.input[p.pos:], prefix) {
-			return parseFunc(cur)
-		}
-	}
-
-	switch r := p.next(); {
-	case r == eof || isEndOfLine(r):
-		return fmt.Errorf("unclosed action")
-	case r == ' ':
-		p.consumeText()
-	case r == '@' || r == '$': //the current object, just pass it
-		p.consumeText()
-	case r == '[':
-		return p.parseArray(cur)
-	case r == '"' || r == '\'':
-		return p.parseQuote(cur, r)
-	case r == '.':
-		return p.parseField(cur)
-	case r == '+' || r == '-' || unicode.IsDigit(r):
-		p.backup()
-		return p.parseNumber(cur)
-	case isAlphaNumeric(r):
-		p.backup()
-		return p.parseIdentifier(cur)
-	default:
-		return fmt.Errorf("unrecognized character in action: %#U", r)
-	}
-	return p.parseInsideAction(cur)
-}
-
-// parseRightDelim scans the right delimiter, which is known to be present.
-func (p *Parser) parseRightDelim(cur *ListNode) error {
-	p.pos += len(rightDelim)
-	p.consumeText()
-	return p.parseText(p.Root)
-}
-
-// parseIdentifier scans build-in keywords, like "range" "end"
-func (p *Parser) parseIdentifier(cur *ListNode) error {
-	var r rune
-	for {
-		r = p.next()
-		if isTerminator(r) {
-			p.backup()
-			break
-		}
-	}
-	value := p.consumeText()
-
-	if isBool(value) {
-		v, err := strconv.ParseBool(value)
-		if err != nil {
-			return fmt.Errorf("can not parse bool '%s': %s", value, err.Error())
-		}
-
-		cur.append(newBool(v))
-	} else {
-		cur.append(newIdentifier(value))
-	}
-
-	return p.parseInsideAction(cur)
-}
-
-// parseRecursive scans the recursive desent operator ..
-func (p *Parser) parseRecursive(cur *ListNode) error {
-	p.pos += len("..")
-	p.consumeText()
-	cur.append(newRecursive())
-	if r := p.peek(); isAlphaNumeric(r) {
-		return p.parseField(cur)
-	}
-	return p.parseInsideAction(cur)
-}
-
-// parseNumber scans number
-func (p *Parser) parseNumber(cur *ListNode) error {
-	r := p.peek()
-	if r == '+' || r == '-' {
-		p.next()
-	}
-	for {
-		r = p.next()
-		if r != '.' && !unicode.IsDigit(r) {
-			p.backup()
-			break
-		}
-	}
-	value := p.consumeText()
-	i, err := strconv.Atoi(value)
-	if err == nil {
-		cur.append(newInt(i))
-		return p.parseInsideAction(cur)
-	}
-	d, err := strconv.ParseFloat(value, 64)
-	if err == nil {
-		cur.append(newFloat(d))
-		return p.parseInsideAction(cur)
-	}
-	return fmt.Errorf("cannot parse number %s", value)
-}
-
-// parseArray scans array index selection
-func (p *Parser) parseArray(cur *ListNode) error {
-Loop:
-	for {
-		switch p.next() {
-		case eof, '\n':
-			return fmt.Errorf("unterminated array")
-		case ']':
-			break Loop
-		}
-	}
-	text := p.consumeText()
-	text = text[1 : len(text)-1]
-	if text == "*" {
-		text = ":"
-	}
-
-	//union operator
-	strs := strings.Split(text, ",")
-	if len(strs) > 1 {
-		union := []*ListNode{}
-		for _, str := range strs {
-			parser, err := parseAction("union", fmt.Sprintf("[%s]", strings.Trim(str, " ")))
-			if err != nil {
-				return err
-			}
-			union = append(union, parser.Root)
-		}
-		cur.append(newUnion(union))
-		return p.parseInsideAction(cur)
-	}
-
-	// dict key
-	value := dictKeyRex.FindStringSubmatch(text)
-	if value != nil {
-		parser, err := parseAction("arraydict", fmt.Sprintf(".%s", value[1]))
-		if err != nil {
-			return err
-		}
-		for _, node := range parser.Root.Nodes {
-			cur.append(node)
-		}
-		return p.parseInsideAction(cur)
-	}
-
-	//slice operator
-	value = sliceOperatorRex.FindStringSubmatch(text)
-	if value == nil {
-		return fmt.Errorf("invalid array index %s", text)
-	}
-	value = value[1:]
-	params := [3]ParamsEntry{}
-	for i := 0; i < 3; i++ {
-		if value[i] != "" {
-			if i > 0 {
-				value[i] = value[i][1:]
-			}
-			if i > 0 && value[i] == "" {
-				params[i].Known = false
-			} else {
-				var err error
-				params[i].Known = true
-				params[i].Value, err = strconv.Atoi(value[i])
-				if err != nil {
-					return fmt.Errorf("array index %s is not a number", value[i])
-				}
-			}
-		} else {
-			if i == 1 {
-				params[i].Known = true
-				params[i].Value = params[0].Value + 1
-				params[i].Derived = true
-			} else {
-				params[i].Known = false
-				params[i].Value = 0
-			}
-		}
-	}
-	cur.append(newArray(params))
-	return p.parseInsideAction(cur)
-}
-
-// parseFilter scans filter inside array selection
-func (p *Parser) parseFilter(cur *ListNode) error {
-	p.pos += len("[?(")
-	p.consumeText()
-	begin := false
-	end := false
-	var pair rune
-
-Loop:
-	for {
-		r := p.next()
-		switch r {
-		case eof, '\n':
-			return fmt.Errorf("unterminated filter")
-		case '"', '\'':
-			if begin == false {
-				//save the paired rune
-				begin = true
-				pair = r
-				continue
-			}
-			//only add when met paired rune
-			if p.input[p.pos-2] != '\\' && r == pair {
-				end = true
-			}
-		case ')':
-			//in rightParser below quotes only appear zero or once
-			//and must be paired at the beginning and end
-			if begin == end {
-				break Loop
-			}
-		}
-	}
-	if p.next() != ']' {
-		return fmt.Errorf("unclosed array expect ]")
-	}
-	reg := regexp.MustCompile(`^([^!<>=]+)([!<>=]+)(.+?)$`)
-	text := p.consumeText()
-	text = text[:len(text)-2]
-	value := reg.FindStringSubmatch(text)
-	if value == nil {
-		parser, err := parseAction("text", text)
-		if err != nil {
-			return err
-		}
-		cur.append(newFilter(parser.Root, newList(), "exists"))
-	} else {
-		leftParser, err := parseAction("left", value[1])
-		if err != nil {
-			return err
-		}
-		rightParser, err := parseAction("right", value[3])
-		if err != nil {
-			return err
-		}
-		cur.append(newFilter(leftParser.Root, rightParser.Root, value[2]))
-	}
-	return p.parseInsideAction(cur)
-}
-
-// parseQuote unquotes string inside double or single quote
-func (p *Parser) parseQuote(cur *ListNode, end rune) error {
-Loop:
-	for {
-		switch p.next() {
-		case eof, '\n':
-			return fmt.Errorf("unterminated quoted string")
-		case end:
-			//if it's not escape break the Loop
-			if p.input[p.pos-2] != '\\' {
-				break Loop
-			}
-		}
-	}
-	value := p.consumeText()
-	s, err := UnquoteExtend(value)
-	if err != nil {
-		return fmt.Errorf("unquote string %s error %v", value, err)
-	}
-	cur.append(newText(s))
-	return p.parseInsideAction(cur)
-}
-
-// parseField scans a field until a terminator
-func (p *Parser) parseField(cur *ListNode) error {
-	p.consumeText()
-	for p.advance() {
-	}
-	value := p.consumeText()
-	if value == "*" {
-		cur.append(newWildcard())
-	} else {
-		cur.append(newField(strings.Replace(value, "\\", "", -1)))
-	}
-	return p.parseInsideAction(cur)
-}
-
-// advance scans until next non-escaped terminator
-func (p *Parser) advance() bool {
-	r := p.next()
-	if r == '\\' {
-		p.next()
-	} else if isTerminator(r) {
-		p.backup()
-		return false
-	}
-	return true
-}
-
-// isTerminator reports whether the input is at valid termination character to appear after an identifier.
-func isTerminator(r rune) bool {
-	if isSpace(r) || isEndOfLine(r) {
-		return true
-	}
-	switch r {
-	case eof, '.', ',', '[', ']', '$', '@', '{', '}':
-		return true
-	}
-	return false
-}
-
-// isSpace reports whether r is a space character.
-func isSpace(r rune) bool {
-	return r == ' ' || r == '\t'
-}
-
-// isEndOfLine reports whether r is an end-of-line character.
-func isEndOfLine(r rune) bool {
-	return r == '\r' || r == '\n'
-}
-
-// isAlphaNumeric reports whether r is an alphabetic, digit, or underscore.
-func isAlphaNumeric(r rune) bool {
-	return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r)
-}
-
-// isBool reports whether s is a boolean value.
-func isBool(s string) bool {
-	return s == "true" || s == "false"
-}
-
-//UnquoteExtend is almost same as strconv.Unquote(), but it support parse single quotes as a string
-func UnquoteExtend(s string) (string, error) {
-	n := len(s)
-	if n < 2 {
-		return "", ErrSyntax
-	}
-	quote := s[0]
-	if quote != s[n-1] {
-		return "", ErrSyntax
-	}
-	s = s[1 : n-1]
-
-	if quote != '"' && quote != '\'' {
-		return "", ErrSyntax
-	}
-
-	// Is it trivial?  Avoid allocation.
-	if !contains(s, '\\') && !contains(s, quote) {
-		return s, nil
-	}
-
-	var runeTmp [utf8.UTFMax]byte
-	buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
-	for len(s) > 0 {
-		c, multibyte, ss, err := strconv.UnquoteChar(s, quote)
-		if err != nil {
-			return "", err
-		}
-		s = ss
-		if c < utf8.RuneSelf || !multibyte {
-			buf = append(buf, byte(c))
-		} else {
-			n := utf8.EncodeRune(runeTmp[:], c)
-			buf = append(buf, runeTmp[:n]...)
-		}
-	}
-	return string(buf), nil
-}
-
-func contains(s string, c byte) bool {
-	for i := 0; i < len(s); i++ {
-		if s[i] == c {
-			return true
-		}
-	}
-	return false
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 906ba91f1..1aec955e2 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -880,11 +880,9 @@ k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1
 k8s.io/client-go/pkg/apis/clientauthentication/v1beta1
 k8s.io/client-go/pkg/version
 k8s.io/client-go/plugin/pkg/client/auth/exec
-k8s.io/client-go/plugin/pkg/client/auth/gcp
 k8s.io/client-go/rest
 k8s.io/client-go/rest/watch
 k8s.io/client-go/testing
-k8s.io/client-go/third_party/forked/golang/template
 k8s.io/client-go/tools/auth
 k8s.io/client-go/tools/cache
 k8s.io/client-go/tools/clientcmd
@@ -903,7 +901,6 @@ k8s.io/client-go/util/cert
 k8s.io/client-go/util/connrotation
 k8s.io/client-go/util/flowcontrol
 k8s.io/client-go/util/homedir
-k8s.io/client-go/util/jsonpath
 k8s.io/client-go/util/keyutil
 k8s.io/client-go/util/retry
 k8s.io/client-go/util/workqueue
diff --git a/webhook/conversion.go b/webhook/conversion.go
index 73cddd7a4..a54a6cb8e 100644
--- a/webhook/conversion.go
+++ b/webhook/conversion.go
@@ -36,7 +36,7 @@ type ConversionController interface {
 	Convert(context.Context, *apixv1.ConversionRequest) *apixv1.ConversionResponse
 }
 
-func conversionHandler(rootLogger *zap.SugaredLogger, stats StatsReporter, c ConversionController) http.HandlerFunc {
+func conversionHandler(rootLogger *zap.SugaredLogger, _ StatsReporter, c ConversionController) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		logger := rootLogger
 		logger.Infof("Webhook ServeHTTP request=%#v", r)
diff --git a/webhook/webhook.go b/webhook/webhook.go
index 8d628c5e3..c65c9f3c3 100644
--- a/webhook/webhook.go
+++ b/webhook/webhook.go
@@ -183,6 +183,7 @@ func (wh *Webhook) Run(stop <-chan struct{}) error {
 		Handler: drainer,
 		Addr:    fmt.Sprintf(":%d", wh.Options.Port),
 		TLSConfig: &tls.Config{
+			MinVersion: tls.VersionTLS12,
 			GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
 				secret, err := wh.secretlister.Secrets(system.Namespace()).Get(wh.Options.SecretName)
 				if err != nil {
diff --git a/websocket/connection.go b/websocket/connection.go
index 360280227..00feceb50 100644
--- a/websocket/connection.go
+++ b/websocket/connection.go
@@ -64,6 +64,9 @@ type ManagedConnection struct {
 	closeChan chan struct{}
 	closeOnce sync.Once
 
+	establishChan chan struct{}
+	establishOnce sync.Once
+
 	// Used to capture asynchronous processes to be waited
 	// on when shutting the connection down.
 	processingWg sync.WaitGroup
@@ -92,6 +95,25 @@ func NewDurableSendingConnection(target string, logger *zap.SugaredLogger) *Mana
 	return NewDurableConnection(target, nil, logger)
 }
 
+// NewDurableSendingConnectionGuaranteed creates a new websocket connection
+// that can only send messages to the endpoint it connects to. It returns
+// the connection if the connection can be established within the given
+// `duration`. Otherwise it returns the ErrConnectionNotEstablished error.
+//
+// The connection will continuously be kept alive and reconnected
+// in case of a loss of connectivity.
+func NewDurableSendingConnectionGuaranteed(target string, duration time.Duration, logger *zap.SugaredLogger) (*ManagedConnection, error) {
+	c := NewDurableConnection(target, nil, logger)
+
+	select {
+	case <-c.establishChan:
+		return c, nil
+	case <-time.After(duration):
+		c.Shutdown()
+		return nil, ErrConnectionNotEstablished
+	}
+}
+
 // NewDurableConnection creates a new websocket connection, that
 // passes incoming messages to the given message channel. It can also
 // send messages to the endpoint it connects to.
@@ -175,6 +197,7 @@ func newConnection(connFactory func() (rawConnection, error), messageChan chan [
 	conn := &ManagedConnection{
 		connectionFactory: connFactory,
 		closeChan:         make(chan struct{}),
+		establishChan:     make(chan struct{}),
 		messageChan:       messageChan,
 		connectionBackoff: wait.Backoff{
 			Duration: 100 * time.Millisecond,
@@ -211,6 +234,9 @@ func (c *ManagedConnection) connect() error {
 			defer c.connectionLock.Unlock()
 
 			c.connection = conn
+			c.establishOnce.Do(func() {
+				close(c.establishChan)
+			})
 			return true, nil
 		case <-c.closeChan:
 			return false, errShuttingDown
@@ -327,11 +353,3 @@ func (c *ManagedConnection) Shutdown() error {
 	c.processingWg.Wait()
 	return err
 }
-
-// IsEstablished returns true the websocket connection has been established.
-func (c *ManagedConnection) IsEstablished() bool {
-	c.connectionLock.RLock()
-	defer c.connectionLock.RUnlock()
-
-	return c.connection != nil
-}


Test patch:
diff --git a/.github/workflows/knative-go-test.yaml b/.github/workflows/knative-go-test.yaml
index f8dcfd88d..bfe6c6ad2 100644
--- a/.github/workflows/knative-go-test.yaml
+++ b/.github/workflows/knative-go-test.yaml
@@ -31,7 +31,7 @@ jobs:
     name: Unit Tests
     strategy:
       matrix:
-        go-version: [1.14.x]
+        go-version: [1.15.x]
         platform: [ubuntu-latest]
 
     runs-on: ${{ matrix.platform }}
diff --git a/metrics/config_test.go b/metrics/config_test.go
index d6c1f5e05..f5683e065 100644
--- a/metrics/config_test.go
+++ b/metrics/config_test.go
@@ -536,7 +536,7 @@ func TestGetMetricsConfig(t *testing.T) {
 	ctx := context.Background()
 	for _, test := range errorTests {
 		t.Run(test.name, func(t *testing.T) {
-			_, err := createMetricsConfig(ctx, test.ops, TestLogger(t))
+			_, err := createMetricsConfig(ctx, test.ops)
 			if err == nil || err.Error() != test.expectedErr {
 				t.Errorf("Wanted err: %v, got: %v", test.expectedErr, err)
 			}
@@ -546,7 +546,7 @@ func TestGetMetricsConfig(t *testing.T) {
 	successTestsInit()
 	for _, test := range successTests {
 		t.Run(test.name, func(t *testing.T) {
-			mc, err := createMetricsConfig(ctx, test.ops, TestLogger(t))
+			mc, err := createMetricsConfig(ctx, test.ops)
 			if err != nil {
 				t.Errorf("Wanted valid config %v, got error %v", test.expectedConfig, err)
 			}
@@ -641,7 +641,7 @@ func TestGetMetricsConfig_fromEnv(t *testing.T) {
 			os.Setenv(test.varName, test.varValue)
 			defer os.Unsetenv(test.varName)
 
-			mc, err := createMetricsConfig(ctx, test.ops, TestLogger(t))
+			mc, err := createMetricsConfig(ctx, test.ops)
 			if err != nil {
 				t.Errorf("Wanted valid config %v, got error %v", test.expectedConfig, err)
 			}
@@ -656,7 +656,7 @@ func TestGetMetricsConfig_fromEnv(t *testing.T) {
 			os.Setenv(test.varName, test.varValue)
 			defer os.Unsetenv(test.varName)
 
-			mc, err := createMetricsConfig(ctx, test.ops, TestLogger(t))
+			mc, err := createMetricsConfig(ctx, test.ops)
 			if mc != nil {
 				t.Errorf("Wanted no config, got %v", mc)
 			}
@@ -674,7 +674,7 @@ func TestIsNewExporterRequiredFromNilConfig(t *testing.T) {
 
 	for _, test := range successTests {
 		t.Run(test.name, func(t *testing.T) {
-			mc, err := createMetricsConfig(ctx, test.ops, TestLogger(t))
+			mc, err := createMetricsConfig(ctx, test.ops)
 			if err != nil {
 				t.Errorf("Wanted valid config %v, got error %v", test.expectedConfig, err)
 			}
@@ -1052,7 +1052,7 @@ func TestStackdriverRecord(t *testing.T) {
 				Domain:    "knative.dev/internal/serving",
 				Component: "activator",
 			}
-			mc, err := createMetricsConfig(context.Background(), opts, TestLogger(t))
+			mc, err := createMetricsConfig(context.Background(), opts)
 			if err != nil {
 				t.Errorf("Expected valid config %+v, got error: %v\n", opts, err)
 			}
diff --git a/test/logstream/kubelogs.go b/test/logstream/kubelogs.go
index 592d3981d..ecd217329 100644
--- a/test/logstream/kubelogs.go
+++ b/test/logstream/kubelogs.go
@@ -110,7 +110,7 @@ func (k *kubelogs) watchPods(t test.TLegacy) {
 		t.Error("Logstream knative pod watch failed, logs might be missing", "error", err)
 		return
 	}
-	go func() error {
+	go func() {
 		watchedPods := sets.NewString()
 		for ev := range wi.ResultChan() {
 			p := ev.Object.(*corev1.Pod)
@@ -128,7 +128,6 @@ func (k *kubelogs) watchPods(t test.TLegacy) {
 				}
 			}
 		}
-		return nil
 	}()
 }
 
diff --git a/test/webhook-apicoverage/coveragecalculator/README.md b/test/webhook-apicoverage/coveragecalculator/README.md
deleted file mode 100644
index 39838d04e..000000000
--- a/test/webhook-apicoverage/coveragecalculator/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Coverage Calculator
-
-`coveragecalculator` package contains types and helper methods pertaining to
-coverage calculation.
-
-[TypeCoverage](coveragedata.go) is a type to represent coverage data for a
-particular API object type. This is the wire contract between the webhook server
-running inside the K8s cluster and any client using the API-Coverage tool. All
-API calls into the webhook-server would return response containing this object
-to represent coverage data.
-
-[IgnoredFields](ignorefields.go) type provides ability for individual repos to
-specify fields that they would like the API Coverage tool to ignore for coverage
-calculation. Individual repos are expected to provide a .yaml file providing
-fields that they would like to ignore and use helper method
-`ReadFromFile(filePath)` to read and intialize this type. `FieldIgnored()` can
-then be called by providing `packageName`, `typeName` and `FieldName` to check
-if the field needs to be ignored.
-
-[CalculateCoverage](calculator.go) method provides a capability to calculate
-coverage values. This method takes an array of [TypeCoverage](coveragedata.go)
-and iterates over them to aggreage coverage values. The aggregate result is
-encapsulated inside [CoverageValues](calculator.go) and returned.
diff --git a/test/webhook-apicoverage/coveragecalculator/calculator.go b/test/webhook-apicoverage/coveragecalculator/calculator.go
deleted file mode 100644
index 5c5262471..000000000
--- a/test/webhook-apicoverage/coveragecalculator/calculator.go
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-Copyright 2019 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 coveragecalculator
-
-import (
-	"math"
-)
-
-// CoverageValues encapsulates all the coverage related values.
-type CoverageValues struct {
-	TotalFields   int
-	CoveredFields int
-	IgnoredFields int
-
-	PercentCoverage float64
-}
-
-// CoveragePercentages encapsulate percentage coverage for resources.
-type CoveragePercentages struct {
-
-	// ResourceCoverages maps percentage coverage per resource.
-	ResourceCoverages map[string]float64
-}
-
-// CalculatePercentageValue calculates percentage value based on other fields.
-func (c *CoverageValues) CalculatePercentageValue() {
-	if c.TotalFields > 0 {
-		c.PercentCoverage = (float64(c.CoveredFields) / float64(c.TotalFields-c.IgnoredFields)) * 100
-	}
-}
-
-// GetAndRemoveResourceValue utility method to implement "get and delete"
-// semantics. This makes templating operations easy.
-func (c *CoveragePercentages) GetAndRemoveResourceValue(resource string) float64 {
-	if resourcePercentage, ok := c.ResourceCoverages[resource]; ok {
-		delete(c.ResourceCoverages, resource)
-		return resourcePercentage
-	}
-
-	return 0.0
-}
-
-// IsFailedBuild utility method to indicate if CoveragePercentages indicate
-// values of a failed build.
-func (c *CoveragePercentages) IsFailedBuild() bool {
-	return math.Abs(c.ResourceCoverages["Overall"]-0) == 0
-}
-
-// CalculateTypeCoverage calculates aggregate coverage values based on provided []TypeCoverage
-func CalculateTypeCoverage(typeCoverage []TypeCoverage) *CoverageValues {
-	cv := CoverageValues{}
-	for _, coverage := range typeCoverage {
-		for _, field := range coverage.Fields {
-			cv.TotalFields++
-			if field.Ignored {
-				cv.IgnoredFields++
-			} else if field.Coverage {
-				cv.CoveredFields++
-			}
-		}
-	}
-	return &cv
-}
diff --git a/test/webhook-apicoverage/coveragecalculator/coveragedata.go b/test/webhook-apicoverage/coveragecalculator/coveragedata.go
deleted file mode 100644
index 704812f6d..000000000
--- a/test/webhook-apicoverage/coveragecalculator/coveragedata.go
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-Copyright 2019 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 coveragecalculator
-
-import (
-	"strings"
-
-	"k8s.io/apimachinery/pkg/util/sets"
-)
-
-// FieldCoverage represents coverage data for a field.
-type FieldCoverage struct {
-	Field    string      `json:"Field"`
-	Values   sets.String `json:"Values"`
-	Coverage bool        `json:"Covered"`
-	Ignored  bool        `json:"Ignored"`
-}
-
-// Merge operation merges the field coverage data when multiple nodes represent the same type. (e.g. ConnectedNodes traversal)
-func (f *FieldCoverage) Merge(coverage bool, values sets.String) {
-	if coverage {
-		f.Coverage = coverage
-		f.Values = f.Values.Union(values)
-	}
-}
-
-// GetValues returns Values as slice
-func (f *FieldCoverage) GetValues() []string {
-	values := []string{}
-	for key := range f.Values {
-		values = append(values, key)
-	}
-	return values
-}
-
-// GetValuesForDisplay returns value strings as comma separated string.
-func (f *FieldCoverage) GetValuesForDisplay() string {
-	return strings.Join(f.GetValues(), ",")
-}
-
-// TypeCoverage encapsulates type information and field coverage.
-type TypeCoverage struct {
-	Package string                    `json:"Package"`
-	Type    string                    `json:"Type"`
-	Fields  map[string]*FieldCoverage `json:"Fields"`
-}
diff --git a/test/webhook-apicoverage/coveragecalculator/ignorefields.go b/test/webhook-apicoverage/coveragecalculator/ignorefields.go
deleted file mode 100644
index cf867012c..000000000
--- a/test/webhook-apicoverage/coveragecalculator/ignorefields.go
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-Copyright 2019 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 coveragecalculator
-
-import (
-	"fmt"
-	"io/ioutil"
-	"strings"
-
-	"k8s.io/apimachinery/pkg/util/sets"
-
-	yaml "gopkg.in/yaml.v2"
-)
-
-// IgnoredFields encapsulates fields to be ignored in a package for API coverage calculation.
-type IgnoredFields struct {
-	ignoredFields map[string]sets.String
-}
-
-// This type is used for deserialization from the input .yaml file
-type inputIgnoredFields struct {
-	Package string   `yaml:"package"`
-	Type    string   `yaml:"type"`
-	Fields  []string `yaml:"fields"`
-}
-
-// ReadFromFile is a utility method that can be used by repos to read .yaml input file into
-// IgnoredFields type.
-func (ig *IgnoredFields) ReadFromFile(filePath string) error {
-	data, err := ioutil.ReadFile(filePath)
-	if err != nil {
-		return fmt.Errorf("Error reading file: %s Error: %w", filePath, err)
-	}
-
-	var inputEntries []inputIgnoredFields
-	err = yaml.Unmarshal(data, &inputEntries)
-	if err != nil {
-		return fmt.Errorf("Error unmarshalling ignoredfields input yaml file: %s Content: %s Error: %w", filePath, string(data), err)
-	}
-
-	ig.ignoredFields = make(map[string]sets.String)
-
-	for _, entry := range inputEntries {
-		if _, ok := ig.ignoredFields[entry.Package]; !ok {
-			ig.ignoredFields[entry.Package] = sets.String{}
-		}
-
-		for _, field := range entry.Fields {
-			ig.ignoredFields[entry.Package].Insert(entry.Type + "." + field)
-		}
-	}
-	return nil
-}
-
-// FieldIgnored method given a package, type and field returns true if the field is marked ignored.
-func (ig *IgnoredFields) FieldIgnored(packageName, typeName, fieldName string) bool {
-	if ig.ignoredFields != nil {
-		for key, value := range ig.ignoredFields {
-			if strings.HasSuffix(packageName, key) {
-				if value.Has(typeName + "." + fieldName) {
-					return true
-				}
-			}
-		}
-	}
-	return false
-}
diff --git a/test/webhook-apicoverage/resourcetree/README.md b/test/webhook-apicoverage/resourcetree/README.md
deleted file mode 100644
index 660d57ffd..000000000
--- a/test/webhook-apicoverage/resourcetree/README.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Resource Tree
-
-resourcetree package contains types and interfaces that define a resource
-tree(n-ary tree based representation of an API resource). Each resource tree is
-composed of nodes which have data encapsulated inside [nodeData](node.go) and
-operations that can be performed on each node in the interface
-[NodeInterface](node.go). Type of a node is logically defined by reflect.Kind.
-Each node type is expected to satisfy the [NodeInterface](node.go) interface.
-
-## Resource Forest
-
-[ResourceForest](resourceforest.go) groups all resource trees that are part of
-an API version into a single construct and defines operations that span across
-them. As an example for Knative Serving, we will have individual resource trees
-for Configuration, Revision, Route and Service, and they are encapsulated inside
-a resource forest under version v1alpha1. Example of an operation that spans
-resource trees would be to get coverage details for outlined types connected
-using ConnectedNodes.
-
-ConnectedNodes represent connections between nodes that are of same
-type(reflect.Type) and belong to same package but span across different trees or
-branches of same tree. An example of ConnectedNodes would be
-v1alpha1.Route.Spec.Traffic and v1alpha1.Route.Status.Traffic, both these
-Traffic fields are of type v1alpha1.TrafficTarget, but are present in different
-paths inside the resource tree. ConnectedNodes connects these two nodes, and an
-outlining of this type would present the coverage across the two branches and
-gives a unified view of what fields are covered.
-
-## Type Analysis
-
-A Resource tree is built using reflect.Type Each node type is expected to
-implement NodeInterface method _buildChildNodes(t reflect.Type)_. Inside this
-method each node creates child nodes based on its type, for e.g. StructKindNode
-creates one child for each field defined in the struct. Type analysis are
-defined inside [typeanalyzer_tests](buildChildNodes_test.go)
-
-## Value Analysis
-
-A Resource tree is updated using reflect.Value Each node type is expected to
-implement NodeInterface method _updateCoverage(v reflect.Value)_. Inisde this
-method each node updates its nodeData.covered field based on whether the
-reflect.Value parameter being passed is set or not.
-
-## Rules
-
-To define traversal pattern on a [resourcetree](../resourcetree/resourcetree.go)
-`coveragecalculator` package supports defining rules that are applied during
-apicoverage walk-through. Currently the tool supports two types of Rule objects:
-
-1. `NodeRules`: Enforces node level semantics. e.g.: Avoid traversing any type
-   that belong to a particular package. To enforce this rule, the repo would
-   define an object that implements the [NodeRule](rule.go) interface's
-   `Apply(nodeInterface resourcetree.NodeInterface) bool` method and pass that
-   onto the `resourcetree` traversal routine.
-
-1. `FieldRules`: Enforces field level semantics. e.g. Avoid calculating coverage
-   for any field that starts with prefix `deprecated`. To enforce this rule, the
-   repo would define an object that implements [FieldRule](rule.go) interface's
-   `Apply(fieldName string) bool` method and pass that onto the `resourcetree`
-   traversal routine.
diff --git a/test/webhook-apicoverage/resourcetree/arraykindnode.go b/test/webhook-apicoverage/resourcetree/arraykindnode.go
deleted file mode 100644
index ac21fcd48..000000000
--- a/test/webhook-apicoverage/resourcetree/arraykindnode.go
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-Copyright 2019 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 resourcetree
-
-import (
-	"reflect"
-
-	"k8s.io/apimachinery/pkg/util/sets"
-)
-
-const (
-	arrayNodeNameSuffix = "-arr"
-)
-
-// ArrayKindNode represents resource tree node of types reflect.Kind.Array and reflect.Kind.Slice
-type ArrayKindNode struct {
-	NodeData
-	// Array type e.g. []int will store reflect.Kind.Int.
-	// This is required for type-expansion and value-evaluation decisions.
-	arrKind reflect.Kind
-}
-
-// GetData returns node data
-func (a *ArrayKindNode) GetData() NodeData {
-	return a.NodeData
-}
-
-func (a *ArrayKindNode) initialize(field string, parent NodeInterface, t reflect.Type, rt *ResourceTree) {
-	a.NodeData.initialize(field, parent, t, rt)
-	a.arrKind = t.Elem().Kind()
-}
-
-func (a *ArrayKindNode) buildChildNodes(t reflect.Type) {
-	childName := a.Field + arrayNodeNameSuffix
-	childNode := a.Tree.createNode(childName, a, t.Elem())
-	a.Children[childName] = childNode
-	childNode.buildChildNodes(t.Elem())
-}
-
-func (a *ArrayKindNode) updateCoverage(v reflect.Value) {
-	if !v.IsNil() {
-		a.Covered = true
-		for i := 0; i < v.Len(); i++ {
-			a.Children[a.Field+arrayNodeNameSuffix].updateCoverage(v.Index(i))
-		}
-	}
-}
-
-func (a *ArrayKindNode) buildCoverageData(coverageHelper coverageDataHelper) {
-	if a.arrKind == reflect.Struct {
-		a.Children[a.Field+arrayNodeNameSuffix].buildCoverageData(coverageHelper)
-	}
-}
-
-func (a *ArrayKindNode) getValues() sets.String {
-	return nil
-}
diff --git a/test/webhook-apicoverage/resourcetree/basictypekindnode.go b/test/webhook-apicoverage/resourcetree/basictypekindnode.go
deleted file mode 100644
index 7ebd1d72f..000000000
--- a/test/webhook-apicoverage/resourcetree/basictypekindnode.go
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-Copyright 2019 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 resourcetree
-
-import (
-	"fmt"
-	"reflect"
-	"strconv"
-
-	"k8s.io/apimachinery/pkg/util/sets"
-)
-
-// BasicTypeKindNode represents resource tree node of basic types like int, float, etc.
-type BasicTypeKindNode struct {
-	NodeData
-	values       sets.String // Values seen for this node. Useful for enum types.
-	possibleEnum bool        // Flag to indicate if this is a possible enum.
-}
-
-// GetData returns node data
-func (b *BasicTypeKindNode) GetData() NodeData {
-	return b.NodeData
-}
-
-func (b *BasicTypeKindNode) initialize(field string, parent NodeInterface, t reflect.Type, rt *ResourceTree) {
-	b.NodeData.initialize(field, parent, t, rt)
-	b.values = sets.String{}
-	b.NodeData.LeafNode = true
-}
-
-func (b *BasicTypeKindNode) buildChildNodes(t reflect.Type) {
-	// Treating bools as possible enums to support tighter coverage information.
-	if t.Name() != t.Kind().String() || b.FieldType.Kind() == reflect.Bool {
-		b.possibleEnum = true
-	}
-}
-
-func (b *BasicTypeKindNode) updateCoverage(v reflect.Value) {
-	if value := b.string(v); len(value) > 0 {
-		if b.possibleEnum || b.FieldType.Kind() == reflect.Bool {
-			b.values.Insert(value)
-		}
-		b.Covered = true
-	}
-}
-
-// no-op as the coverage is calculated as field coverage in parent node.
-func (b *BasicTypeKindNode) buildCoverageData(coverageHelper coverageDataHelper) {}
-
-func (b *BasicTypeKindNode) string(v reflect.Value) string {
-	switch v.Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		if v.Int() != 0 {
-			return strconv.Itoa(int(v.Int()))
-		}
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-		if v.Uint() != 0 {
-			return strconv.FormatUint(v.Uint(), 10)
-		}
-	case reflect.Float32, reflect.Float64:
-		if v.Float() != 0 {
-			return fmt.Sprint(v.Float())
-		}
-	case reflect.String:
-		if v.Len() != 0 {
-			return v.String()
-		}
-	case reflect.Bool:
-		return strconv.FormatBool(v.Bool())
-	}
-
-	return ""
-}
-
-func (b *BasicTypeKindNode) getValues() sets.String {
-	if b.possibleEnum {
-		return b.values
-	}
-
-	return nil
-}
diff --git a/test/webhook-apicoverage/resourcetree/buildChildNodes_test.go b/test/webhook-apicoverage/resourcetree/buildChildNodes_test.go
deleted file mode 100644
index dcf4b7aeb..000000000
--- a/test/webhook-apicoverage/resourcetree/buildChildNodes_test.go
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-Copyright 2018 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 resourcetree
-
-import (
-	"reflect"
-	"testing"
-)
-
-func TestSimpleStructType(t *testing.T) {
-	tree := getTestTree(basicTypeName, reflect.TypeOf(baseType{}))
-	if err := verifyBaseTypeNode("", tree.Root.GetData()); err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestPtrType(t *testing.T) {
-	tree := getTestTree(ptrTypeName, reflect.TypeOf(ptrType{}))
-	if err := verifyPtrNode(tree.Root.GetData()); err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestArrayType(t *testing.T) {
-	tree := getTestTree(arrayTypeName, reflect.TypeOf(arrayType{}))
-	if err := verifyArrayNode(tree.Root.GetData()); err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestOtherType(t *testing.T) {
-	tree := getTestTree(otherTypeName, reflect.TypeOf(otherType{}))
-	if err := verifyOtherTypeNode(tree.Root.GetData()); err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestCombinedType(t *testing.T) {
-	tree := getTestTree(combinedTypeName, reflect.TypeOf(combinedNodeType{}))
-	if err := verifyResourceForest(tree.Forest); err != nil {
-		t.Fatal(err)
-	}
-}
diff --git a/test/webhook-apicoverage/resourcetree/node.go b/test/webhook-apicoverage/resourcetree/node.go
deleted file mode 100644
index 935a9fe31..000000000
--- a/test/webhook-apicoverage/resourcetree/node.go
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-Copyright 2019 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.
-*/
-
-// node.go contains types and interfaces pertaining to nodes inside resource tree.
-
-package resourcetree
-
-import (
-	"reflect"
-
-	"k8s.io/apimachinery/pkg/util/sets"
-)
-
-// NodeInterface defines methods that can be performed on each node in the resource tree.
-type NodeInterface interface {
-	GetData() NodeData
-	initialize(field string, parent NodeInterface, t reflect.Type, rt *ResourceTree)
-	buildChildNodes(t reflect.Type)
-	updateCoverage(v reflect.Value)
-	buildCoverageData(coverageDataHelper coverageDataHelper)
-	getValues() sets.String
-}
-
-// NodeData is the data stored in each node of the resource tree.
-type NodeData struct {
-	// Represents the Name of the field e.g. field name inside the struct.
-	Field string
-	// Reference back to the resource tree. Required for cross-tree traversal(connected nodes traversal)
-	Tree *ResourceTree
-	// Required as type information is not available during tree traversal.
-	FieldType reflect.Type
-	// Path in the resource tree reaching this node.
-	NodePath string
-	// Link back to parent.
-	Parent NodeInterface
-	// Child nodes are keyed using field names(nodeData.field).
-	Children map[string]NodeInterface
-	// Storing this as an additional field because type-analysis determines the value,
-	// which gets used later in value-evaluation
-	LeafNode bool
-	Covered  bool
-}
-
-func (nd *NodeData) initialize(field string, parent NodeInterface, t reflect.Type, rt *ResourceTree) {
-	nd.Field = field
-	nd.Tree = rt
-	nd.Parent = parent
-	nd.FieldType = t
-	nd.Children = make(map[string]NodeInterface)
-
-	if parent != nil {
-		nd.NodePath = parent.GetData().NodePath + "." + field
-	} else {
-		nd.NodePath = field
-	}
-}
diff --git a/test/webhook-apicoverage/resourcetree/otherkindnode.go b/test/webhook-apicoverage/resourcetree/otherkindnode.go
deleted file mode 100644
index a44e5fd53..000000000
--- a/test/webhook-apicoverage/resourcetree/otherkindnode.go
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-Copyright 2019 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 resourcetree
-
-import (
-	"reflect"
-
-	"k8s.io/apimachinery/pkg/util/sets"
-)
-
-// OtherKindNode represents nodes in the resource tree of types like maps, interfaces, etc
-type OtherKindNode struct {
-	NodeData
-}
-
-// GetData returns node data
-func (o *OtherKindNode) GetData() NodeData {
-	return o.NodeData
-}
-
-func (o *OtherKindNode) initialize(field string, parent NodeInterface, t reflect.Type, rt *ResourceTree) {
-	o.NodeData.initialize(field, parent, t, rt)
-	o.NodeData.LeafNode = true
-}
-
-func (o *OtherKindNode) buildChildNodes(t reflect.Type) {}
-
-func (o *OtherKindNode) updateCoverage(v reflect.Value) {
-	if !v.IsNil() {
-		o.Covered = true
-	}
-}
-
-// no-op as the coverage is calculated as field coverage in parent node.
-func (o *OtherKindNode) buildCoverageData(coverageHelper coverageDataHelper) {}
-
-func (o *OtherKindNode) getValues() sets.String {
-	return nil
-}
diff --git a/test/webhook-apicoverage/resourcetree/ptrkindnode.go b/test/webhook-apicoverage/resourcetree/ptrkindnode.go
deleted file mode 100644
index 4689bf040..000000000
--- a/test/webhook-apicoverage/resourcetree/ptrkindnode.go
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-Copyright 2019 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 resourcetree
-
-import (
-	"reflect"
-
-	"k8s.io/apimachinery/pkg/util/sets"
-)
-
-const (
-	ptrNodeNameSuffix = "-ptr"
-)
-
-// PtrKindNode represents nodes in the resource tree of type reflect.Kind.Ptr, reflect.Kind.UnsafePointer, etc.
-type PtrKindNode struct {
-	NodeData
-	objKind reflect.Kind // Type of the object being pointed to. Eg: *int will store reflect.Kind.Int. This is required for type-expansion and value-evaluation decisions.
-}
-
-// GetData returns node data
-func (p *PtrKindNode) GetData() NodeData {
-	return p.NodeData
-}
-
-func (p *PtrKindNode) initialize(field string, parent NodeInterface, t reflect.Type, rt *ResourceTree) {
-	p.NodeData.initialize(field, parent, t, rt)
-	p.objKind = t.Elem().Kind()
-}
-
-func (p *PtrKindNode) buildChildNodes(t reflect.Type) {
-	childName := p.Field + ptrNodeNameSuffix
-	childNode := p.Tree.createNode(childName, p, t.Elem())
-	p.Children[childName] = childNode
-	childNode.buildChildNodes(t.Elem())
-}
-
-func (p *PtrKindNode) updateCoverage(v reflect.Value) {
-	if !v.IsNil() {
-		p.Covered = true
-		p.Children[p.Field+ptrNodeNameSuffix].updateCoverage(v.Elem())
-	}
-}
-
-func (p *PtrKindNode) buildCoverageData(coverageHelper coverageDataHelper) {
-	if p.objKind == reflect.Struct {
-		p.Children[p.Field+ptrNodeNameSuffix].buildCoverageData(coverageHelper)
-	}
-}
-
-func (p *PtrKindNode) getValues() sets.String {
-	return nil
-}
diff --git a/test/webhook-apicoverage/resourcetree/resourceforest.go b/test/webhook-apicoverage/resourcetree/resourceforest.go
deleted file mode 100644
index 9f0aba62b..000000000
--- a/test/webhook-apicoverage/resourcetree/resourceforest.go
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-Copyright 2019 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 resourcetree
-
-import (
-	"container/list"
-	"reflect"
-
-	"k8s.io/apimachinery/pkg/util/sets"
-	"knative.dev/pkg/test/webhook-apicoverage/coveragecalculator"
-)
-
-// ResourceForest represents the top-level forest that contains individual resource trees
-// for top-level resource types and all connected nodes across resource trees.
-type ResourceForest struct {
-	Version string
-	// Key is ResourceTree.ResourceName
-	TopLevelTrees map[string]ResourceTree
-	// Head of the linked list keyed by nodeData.fieldType.pkg + nodeData.fieldType.Name()
-	ConnectedNodes map[string]*list.List
-}
-
-// AddResourceTree adds a resource tree to the resource forest.
-func (r *ResourceForest) AddResourceTree(resourceName string, resourceType reflect.Type) {
-	tree := ResourceTree{
-		ResourceName: resourceName,
-		Forest:       r,
-	}
-	tree.BuildResourceTree(resourceType)
-	r.TopLevelTrees[resourceName] = tree
-}
-
-// getConnectedNodeCoverage calculates the outlined coverage for a Type using ConnectedNodes linkedlist.
-// We traverse through each element in the linkedlist and merge
-// coverage data into a single coveragecalculator.TypeCoverage object.
-func (r *ResourceForest) getConnectedNodeCoverage(
-	fieldType reflect.Type,
-	fieldRules FieldRules,
-	ignoredFields coveragecalculator.IgnoredFields) coveragecalculator.TypeCoverage {
-	packageName := fieldType.PkgPath()
-	coverage := coveragecalculator.TypeCoverage{
-		Type:    fieldType.Name(),
-		Package: packageName,
-		Fields:  make(map[string]*coveragecalculator.FieldCoverage),
-	}
-
-	if value, ok := r.ConnectedNodes[fieldType.PkgPath()+"."+fieldType.Name()]; ok {
-		for elem := value.Front(); elem != nil; elem = elem.Next() {
-			node := elem.Value.(NodeInterface)
-			for field, v := range node.GetData().Children {
-				if fieldRules.Apply(field) {
-					if _, ok := coverage.Fields[field]; !ok {
-						coverage.Fields[field] = &coveragecalculator.FieldCoverage{
-							Field:   field,
-							Ignored: ignoredFields.FieldIgnored(packageName, fieldType.Name(), field),
-							Values:  sets.String{},
-						}
-					}
-					// merge values across the list.
-					coverage.Fields[field].Merge(v.GetData().Covered, v.getValues())
-				}
-			}
-		}
-	}
-	return coverage
-}
diff --git a/test/webhook-apicoverage/resourcetree/resourcetree.go b/test/webhook-apicoverage/resourcetree/resourcetree.go
deleted file mode 100644
index b4c5c992c..000000000
--- a/test/webhook-apicoverage/resourcetree/resourcetree.go
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
-Copyright 2019 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 resourcetree
-
-import (
-	"container/list"
-	"reflect"
-
-	"k8s.io/apimachinery/pkg/util/sets"
-	"knative.dev/pkg/test/webhook-apicoverage/coveragecalculator"
-)
-
-// ResourceTree encapsulates a tree corresponding to a resource type.
-type ResourceTree struct {
-	ResourceName string
-	Root         NodeInterface
-	Forest       *ResourceForest
-}
-
-// coverageDataHelper is a encapsulator parameter type to the BuildCoverageData method
-// so as to avoid long parameter list.
-type coverageDataHelper struct {
-	typeCoverage  *[]coveragecalculator.TypeCoverage
-	nodeRules     NodeRules
-	fieldRules    FieldRules
-	ignoredFields coveragecalculator.IgnoredFields
-	coveredTypes  sets.String
-}
-
-func (r *ResourceTree) createNode(field string, parent NodeInterface, t reflect.Type) NodeInterface {
-	var n NodeInterface
-	switch t.Kind() {
-	case reflect.Struct:
-		n = new(StructKindNode)
-	case reflect.Array, reflect.Slice:
-		n = new(ArrayKindNode)
-	case reflect.Ptr, reflect.UnsafePointer, reflect.Uintptr:
-		n = new(PtrKindNode)
-	case reflect.Bool, reflect.String, reflect.Float32, reflect.Float64,
-		reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint,
-		reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-		n = new(BasicTypeKindNode)
-	default:
-		n = new(OtherKindNode) // Maps, interfaces, etc
-	}
-
-	n.initialize(field, parent, t, r)
-
-	if len(t.PkgPath()) != 0 {
-		typeName := t.PkgPath() + "." + t.Name()
-		if _, ok := r.Forest.ConnectedNodes[typeName]; !ok {
-			r.Forest.ConnectedNodes[typeName] = list.New()
-		}
-		r.Forest.ConnectedNodes[typeName].PushBack(n)
-	}
-
-	return n
-}
-
-// BuildResourceTree builds a resource tree by calling into analyzeType method starting from root.
-func (r *ResourceTree) BuildResourceTree(t reflect.Type) {
-	r.Root = r.createNode(r.ResourceName, nil, t)
-	r.Root.buildChildNodes(t)
-}
-
-// UpdateCoverage updates coverage data in the resource tree based on the provided reflect.Value
-func (r *ResourceTree) UpdateCoverage(v reflect.Value) {
-	r.Root.updateCoverage(v)
-}
-
-// BuildCoverageData calculates the coverage information for a resource tree by applying provided Node and Field rules.
-func (r *ResourceTree) BuildCoverageData(nodeRules NodeRules, fieldRules FieldRules,
-	ignoredFields coveragecalculator.IgnoredFields) []coveragecalculator.TypeCoverage {
-	coverageHelper := coverageDataHelper{
-		nodeRules:     nodeRules,
-		fieldRules:    fieldRules,
-		typeCoverage:  &[]coveragecalculator.TypeCoverage{},
-		ignoredFields: ignoredFields,
-		coveredTypes:  sets.String{},
-	}
-	r.Root.buildCoverageData(coverageHelper)
-	return *coverageHelper.typeCoverage
-}
diff --git a/test/webhook-apicoverage/resourcetree/rule.go b/test/webhook-apicoverage/resourcetree/rule.go
deleted file mode 100644
index f8d0c640a..000000000
--- a/test/webhook-apicoverage/resourcetree/rule.go
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-Copyright 2019 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 resourcetree
-
-// rule.go contains different rules that can be defined to control resource tree traversal.
-
-// NodeRules encapsulates all the node level rules defined by a repo.
-type NodeRules struct {
-	Rules []func(nodeInterface NodeInterface) bool
-}
-
-// Apply runs all the rules defined by a repo against a node.
-func (n *NodeRules) Apply(node NodeInterface) bool {
-	for _, rule := range n.Rules {
-		if !rule(node) {
-			return false
-		}
-	}
-	return true
-}
-
-// FieldRules encapsulates all the field level rules defined by a repo.
-type FieldRules struct {
-	Rules []func(fieldName string) bool
-}
-
-// Apply runs all the rules defined by a repo against a field.
-func (f *FieldRules) Apply(fieldName string) bool {
-	for _, rule := range f.Rules {
-		if !rule(fieldName) {
-			return false
-		}
-	}
-	return true
-}
diff --git a/test/webhook-apicoverage/resourcetree/structkindnode.go b/test/webhook-apicoverage/resourcetree/structkindnode.go
deleted file mode 100644
index 7eaa7e517..000000000
--- a/test/webhook-apicoverage/resourcetree/structkindnode.go
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
-Copyright 2018 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 resourcetree
-
-import (
-	"reflect"
-
-	"k8s.io/apimachinery/pkg/util/sets"
-)
-
-const (
-	v1TimeType       = "v1.Time"
-	volatileTimeType = "apis.VolatileTime"
-)
-
-// StructKindNode represents nodes in the resource tree of type reflect.Kind.Struct
-type StructKindNode struct {
-	NodeData
-}
-
-// GetData returns node data
-func (s *StructKindNode) GetData() NodeData {
-	return s.NodeData
-}
-
-func (s *StructKindNode) initialize(field string, parent NodeInterface, t reflect.Type, rt *ResourceTree) {
-	s.NodeData.initialize(field, parent, t, rt)
-}
-
-func (s *StructKindNode) buildChildNodes(t reflect.Type) {
-	// For types that are part of the standard package, we treat them as leaf nodes and don't expand further.
-	// https://golang.org/pkg/reflect/#StructField.
-	if s.FieldType.PkgPath() == "" {
-		s.LeafNode = true
-		return
-	}
-
-	for i := 0; i < t.NumField(); i++ {
-		var childNode NodeInterface
-		if s.isTimeNode(t.Field(i).Type) {
-			childNode = new(TimeTypeNode)
-			childNode.initialize(t.Field(i).Name, s, t.Field(i).Type, s.Tree)
-		} else {
-			childNode = s.Tree.createNode(t.Field(i).Name, s, t.Field(i).Type)
-		}
-		s.Children[t.Field(i).Name] = childNode
-		childNode.buildChildNodes(t.Field(i).Type)
-	}
-}
-
-func (s *StructKindNode) isTimeNode(t reflect.Type) bool {
-	if t.Kind() == reflect.Struct {
-		return t.String() == v1TimeType || t.String() == volatileTimeType
-	} else if t.Kind() == reflect.Ptr {
-		return t.Elem().String() == v1TimeType || t.String() == volatileTimeType
-	} else {
-		return false
-	}
-}
-
-func (s *StructKindNode) updateCoverage(v reflect.Value) {
-	if v.IsValid() {
-		s.Covered = true
-		if !s.LeafNode {
-			for i := 0; i < v.NumField(); i++ {
-				s.Children[v.Type().Field(i).Name].updateCoverage(v.Field(i))
-			}
-		}
-	}
-}
-
-func (s *StructKindNode) buildCoverageData(coverageHelper coverageDataHelper) {
-	if len(s.Children) == 0 {
-		return
-	}
-
-	coverage := s.Tree.Forest.getConnectedNodeCoverage(s.FieldType, coverageHelper.fieldRules, coverageHelper.ignoredFields)
-	*coverageHelper.typeCoverage = append(*coverageHelper.typeCoverage, coverage)
-	// Adding the type to covered fields so as to avoid revisiting the same node in other parts of the resource tree.
-	coverageHelper.coveredTypes.Insert(s.FieldType.PkgPath() + "." + s.FieldType.Name())
-
-	for field := range coverage.Fields {
-		node := s.Children[field]
-		if !coverage.Fields[field].Ignored && node.GetData().Covered && coverageHelper.nodeRules.Apply(node) {
-			// Check to see if the type has already been covered.
-			if !coverageHelper.coveredTypes.Has(node.GetData().FieldType.PkgPath() + "." + node.GetData().FieldType.Name()) {
-				node.buildCoverageData(coverageHelper)
-			}
-		}
-	}
-}
-
-func (s *StructKindNode) getValues() sets.String {
-	return nil
-}
diff --git a/test/webhook-apicoverage/resourcetree/test_util.go b/test/webhook-apicoverage/resourcetree/test_util.go
deleted file mode 100644
index a3752983e..000000000
--- a/test/webhook-apicoverage/resourcetree/test_util.go
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
-Copyright 2018 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 resourcetree
-
-//test_util contains types defined and used by types and their corresponding verification methods.
-//lint:file-ignore U1000 Ignore all unused code, it's needed
-
-import (
-	"container/list"
-	"errors"
-	"fmt"
-	"reflect"
-)
-
-const (
-	basicTypeName    = "BasicType"
-	ptrTypeName      = "PtrType"
-	arrayTypeName    = "ArrayType"
-	otherTypeName    = "OtherType"
-	combinedTypeName = "CombinedType"
-)
-
-type baseType struct {
-	field1 string
-	field2 int16
-}
-
-type ptrType struct {
-	structPtr *baseType
-	basePtr   *float32
-}
-
-type arrayType struct {
-	structArr []baseType
-	baseArr   []bool
-}
-
-//nolint:structcheck,unused // Disable warnings about unused fields.
-type otherType struct {
-	structMap map[string]baseType
-	baseMap   map[string]string
-}
-
-//nolint:structcheck,unused // Disable warnings about unused fields.
-type combinedNodeType struct {
-	b baseType
-	a arrayType
-	p ptrType
-}
-
-func getBaseTypeValue() baseType {
-	return baseType{
-		field1: "test",
-	}
-}
-
-func getPtrTypeValueAllCovered() ptrType {
-	f := new(float32)
-	*f = 3.142
-	b := getBaseTypeValue()
-	return ptrType{
-		basePtr:   f,
-		structPtr: &b,
-	}
-}
-
-func getPtrTypeValueSomeCovered() ptrType {
-	b := getBaseTypeValue()
-	return ptrType{
-		structPtr: &b,
-	}
-}
-
-func getArrValueAllCovered() arrayType {
-	b1 := getBaseTypeValue()
-	b2 := baseType{
-		field2: 32,
-	}
-
-	return arrayType{
-		structArr: []baseType{b1, b2},
-		baseArr:   []bool{true, false},
-	}
-}
-
-func getArrValueSomeCovered() arrayType {
-	return arrayType{
-		structArr: []baseType{getBaseTypeValue()},
-	}
-}
-
-func getOtherTypeValue() otherType {
-	m := make(map[string]baseType)
-	m["test"] = getBaseTypeValue()
-	return otherType{
-		structMap: m,
-	}
-}
-
-func getTestTree(treeName string, t reflect.Type) *ResourceTree {
-	forest := ResourceForest{
-		Version:        "TestVersion",
-		ConnectedNodes: make(map[string]*list.List),
-		TopLevelTrees:  make(map[string]ResourceTree),
-	}
-
-	tree := ResourceTree{
-		ResourceName: treeName,
-		Forest:       &forest,
-	}
-
-	tree.BuildResourceTree(t)
-	forest.TopLevelTrees[treeName] = tree
-	return &tree
-}
-
-func verifyBaseTypeNode(logPrefix string, data NodeData) error {
-	if len(data.Children) != 2 {
-		return fmt.Errorf("%s Expected 2 Children got only : %d", logPrefix, len(data.Children))
-	}
-
-	if value, ok := data.Children["field1"]; ok {
-		n := value.GetData()
-		if !n.LeafNode || n.FieldType.Kind() != reflect.String || n.FieldType.PkgPath() != "" || len(n.Children) != 0 {
-			return fmt.Errorf("%s Unexpected field: field1. Expected LeafNode:true, Kind: %s, pkgPath: '' Children: 0 Found LeafNode: %t Kind: %s pkgPath: %s Children:%d",
-				logPrefix, reflect.String, n.LeafNode, n.FieldType.Kind(), n.FieldType.PkgPath(), len(n.Children))
-		}
-	} else {
-		return fmt.Errorf("%s field1 child Not found", logPrefix)
-	}
-
-	return nil
-}
-
-func verifyPtrNode(data NodeData) error {
-	if len(data.Children) != 2 {
-		return fmt.Errorf("Expected 2 Children got: %d", len(data.Children))
-	}
-
-	child := data.Children["structPtr"]
-	if len(child.GetData().Children) != 1 {
-		return fmt.Errorf("Unexpected size for field:structPtr. Expected : 1, Found : %d", len(child.GetData().Children))
-	}
-
-	child = child.GetData().Children["structPtr-ptr"]
-	if err := verifyBaseTypeNode("child structPtr-ptr: ", child.GetData()); err != nil {
-		return err
-	}
-
-	child = data.Children["basePtr"]
-	if len(child.GetData().Children) != 1 {
-		return fmt.Errorf("Unexpected size for field:basePtr. Expected : 1 Found : %d", len(child.GetData().Children))
-	}
-
-	child = child.GetData().Children["basePtr-ptr"]
-	d := child.GetData()
-	if d.FieldType.Kind() != reflect.Float32 || !d.LeafNode || d.FieldType.PkgPath() != "" || len(d.Children) != 0 {
-		return fmt.Errorf("Unexpected field:basePtr-ptr: Expected: Kind: %s, LeafNode: true, pkgPath: '' Children: 0 Found Kind: %s, LeafNode: %t, pkgPath: %s Children:%d",
-			reflect.Float32, d.FieldType.Kind(), d.LeafNode, d.FieldType.PkgPath(), len(d.Children))
-	}
-
-	return nil
-}
-
-func verifyArrayNode(data NodeData) error {
-	if len(data.Children) != 2 {
-		return fmt.Errorf("Expected 2 Children got: %d", len(data.Children))
-	}
-
-	child := data.Children["structArr"]
-	d := child.GetData()
-	if d.FieldType.Kind() != reflect.Slice {
-		return fmt.Errorf("Unexpected kind for field:structArr: Expected : %s Found: %s", reflect.Slice, d.FieldType.Kind())
-	} else if len(d.Children) != 1 {
-		return fmt.Errorf("Unexpected number of Children for field:structArr: Expected : 1 Found : %d", len(d.Children))
-	}
-
-	child = child.GetData().Children["structArr-arr"]
-	if err := verifyBaseTypeNode("child structArr-arr:", child.GetData()); err != nil {
-		return err
-	}
-
-	child = data.Children["baseArr"]
-	d = child.GetData()
-	if d.FieldType.Kind() != reflect.Slice {
-		return fmt.Errorf("Unexpected kind for field:baseArr: Expected : %s Found : %s", reflect.Slice, d.FieldType.Kind())
-	} else if len(d.Children) != 1 {
-		return fmt.Errorf("Unexpected number of Children for field:baseArr: Expected : 1 Found : %d", len(d.Children))
-	}
-
-	child = child.GetData().Children["baseArr-arr"]
-	d = child.GetData()
-	if d.FieldType.Kind() != reflect.Bool || !d.LeafNode || d.FieldType.PkgPath() != "" || len(d.Children) != 0 {
-		return fmt.Errorf("Unexpected field:baseArr-arr Expected kind: %s, LeafNode: true, pkgPath: '', Children:0 Found: kind: %s, LeafNode: %t, pkgPath: %s, Children:%d",
-			reflect.Bool, d.FieldType.Kind(), d.LeafNode, d.FieldType.PkgPath(), len(d.Children))
-	}
-
-	return nil
-}
-
-func verifyOtherTypeNode(data NodeData) error {
-	if len(data.Children) != 2 {
-		return fmt.Errorf("OtherTypeVerification: Expected 2 Children got: %d", len(data.Children))
-	}
-
-	child := data.Children["structMap"]
-	d := child.GetData()
-	if d.FieldType.Kind() != reflect.Map || !d.LeafNode || len(d.Children) != 0 {
-		return fmt.Errorf("Unexpected field:structMap - Expected Kind: %s, LeafNode: true, Children:0 Found Kind: %s, LeafNode: %t, Children: %d",
-			reflect.Map, d.FieldType.Kind(), d.LeafNode, len(d.Children))
-	}
-
-	child = data.Children["baseMap"]
-	d = child.GetData()
-	if d.FieldType.Kind() != reflect.Map || !d.LeafNode || len(d.Children) != 0 {
-		return fmt.Errorf("Unexpected field:structMap - Expected Kind: %s, LeafNode: true, Children: 0 Found kind: %s, LeafNode: %t, Children: %d",
-			reflect.Map, d.FieldType.Kind(), d.LeafNode, len(d.Children))
-	}
-
-	return nil
-}
-
-func verifyResourceForest(forest *ResourceForest) error {
-	if len(forest.ConnectedNodes) != 4 {
-		return fmt.Errorf("Invalid number of connected nodes found. Expected : 4, Found : %d", len(forest.ConnectedNodes))
-	}
-
-	baseType := reflect.TypeOf(baseType{})
-	if value, found := forest.ConnectedNodes[baseType.PkgPath()+"."+baseType.Name()]; !found {
-		return errors.New("Cannot find baseType{} connectedNode")
-	} else if value.Len() != 3 {
-		return fmt.Errorf("Invalid length of baseType{} Node. Expected : 3 Found : %d", value.Len())
-	}
-
-	arrayType := reflect.TypeOf(arrayType{})
-	if value, found := forest.ConnectedNodes[arrayType.PkgPath()+"."+arrayType.Name()]; !found {
-		return errors.New("cannot find arrayType{} connectedNode")
-	} else if value.Len() != 1 {
-		return fmt.Errorf("invalid length of arrayType{} Node. Expected : 1 Found : %d", value.Len())
-	}
-
-	return nil
-}
-
-func verifyBaseTypeValue(logPrefix string, node NodeInterface) error {
-	if !node.GetData().Covered {
-		return errors.New(logPrefix + " Node marked as not-Covered. Expected to be Covered")
-	}
-
-	if !node.GetData().Children["field1"].GetData().Covered {
-		return errors.New(logPrefix + " field1 marked as not-Covered. Expected to be Covered")
-	}
-
-	if node.GetData().Children["field2"].GetData().Covered {
-		return errors.New(logPrefix + " field2 marked as Covered. Expected to be not-Covered")
-	}
-
-	return nil
-}
-
-func verifyPtrValueAllCovered(node NodeInterface) error {
-	if !node.GetData().Covered {
-		return errors.New("node marked as not-Covered. Expected to be Covered")
-	}
-
-	child := node.GetData().Children["basePtr"]
-	if !child.GetData().Covered {
-		return errors.New("field:base_ptr marked as not-Covered. Expected to be Covered")
-	}
-
-	if !child.GetData().Children["basePtr"+ptrNodeNameSuffix].GetData().Covered {
-		return errors.New("field:basePtr" + ptrNodeNameSuffix + "marked as not-Covered. Expected to be Covered")
-	}
-
-	child = node.GetData().Children["structPtr"]
-	if !child.GetData().Covered {
-		return errors.New("field:structPtr marked as not-Covered. Expected to be Covered")
-	}
-
-	if err := verifyBaseTypeValue("field:structPtr"+ptrNodeNameSuffix, child.GetData().Children["structPtr"+ptrNodeNameSuffix]); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func verifyPtrValueSomeCovered(node NodeInterface) error {
-	if !node.GetData().Covered {
-		return errors.New("node marked as not-Covered. Expected to be Covered")
-	}
-
-	child := node.GetData().Children["basePtr"]
-	if child.GetData().Covered {
-		return errors.New("field:basePtr marked as Covered. Expected to be not-Covered")
-	}
-
-	if child.GetData().Children["basePtr"+ptrNodeNameSuffix].GetData().Covered {
-		return errors.New("field:basePtr" + ptrNodeNameSuffix + "marked as Covered. Expected to be not-Covered")
-	}
-
-	child = node.GetData().Children["structPtr"]
-	if !child.GetData().Covered {
-		return errors.New("field:structPtr marked as not-Covered. Expected to be Covered")
-	}
-
-	if err := verifyBaseTypeValue("field:structPtr"+ptrNodeNameSuffix, child.GetData().Children["structPtr"+ptrNodeNameSuffix]); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func verifyArryValueAllCovered(node NodeInterface) error {
-	if !node.GetData().Covered {
-		return errors.New("node marked as not-Covered. Expected to be Covered")
-	}
-
-	child := node.GetData().Children["baseArr"]
-	if !child.GetData().Covered {
-		return errors.New("field:baseArr marked as not-Covered. Expected to be Covered")
-	}
-
-	if !child.GetData().Children["baseArr"+arrayNodeNameSuffix].GetData().Covered {
-		return errors.New("field:baseArr" + arrayNodeNameSuffix + " marked as not-Covered. Expected to be Covered")
-	}
-
-	child = node.GetData().Children["structArr"]
-	if !child.GetData().Covered {
-		return errors.New("field:structArr marked as not-Covered. Expected to be Covered")
-	}
-
-	child = child.GetData().Children["structArr"+arrayNodeNameSuffix]
-	if !child.GetData().Covered {
-		return errors.New("structArr" + arrayNodeNameSuffix + " marked as not-Covered. Expected to be Covered")
-	}
-
-	if !child.GetData().Children["field1"].GetData().Covered {
-		return errors.New("structArr" + arrayNodeNameSuffix + ".field1 marked as not-Covered. Expected to be Covered")
-	}
-
-	if !child.GetData().Children["field2"].GetData().Covered {
-		return errors.New("structArr" + arrayNodeNameSuffix + ".field1 marked as not-Covered. Expected to be Covered")
-	}
-
-	return nil
-}
-
-func verifyArrValueSomeCovered(node NodeInterface) error {
-	if !node.GetData().Covered {
-		return errors.New("node marked as not-Covered. Expected to be Covered")
-	}
-
-	child := node.GetData().Children["baseArr"]
-	if child.GetData().Covered {
-		return errors.New("field:baseArr marked as Covered. Expected to be not-Covered")
-	}
-
-	if child.GetData().Children["baseArr"+arrayNodeNameSuffix].GetData().Covered {
-		return errors.New("field:baseArr" + arrayNodeNameSuffix + " marked as Covered. Expected to be not-Covered")
-	}
-
-	child = node.GetData().Children["structArr"]
-	if !child.GetData().Covered {
-		return errors.New("field:structArr marked as not-Covered. Expected to be Covered")
-	}
-
-	if err := verifyBaseTypeValue("field:structArr"+arrayNodeNameSuffix, child.GetData().Children["structArr"+arrayNodeNameSuffix]); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func verifyOtherTypeValue(node NodeInterface) error {
-	if !node.GetData().Covered {
-		return errors.New("node marked as not-Covered. Expected to be Covered")
-	}
-
-	if !node.GetData().Children["structMap"].GetData().Covered {
-		return errors.New("field:structMap marked as not-Covered. Expected to be Covered")
-	}
-
-	if node.GetData().Children["baseMap"].GetData().Covered {
-		return errors.New("field:baseMap marked as Covered. Expected to be not-Covered")
-	}
-
-	return nil
-}
diff --git a/test/webhook-apicoverage/resourcetree/timetypenode.go b/test/webhook-apicoverage/resourcetree/timetypenode.go
deleted file mode 100644
index 237d12d33..000000000
--- a/test/webhook-apicoverage/resourcetree/timetypenode.go
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-Copyright 2018 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 resourcetree
-
-import (
-	"reflect"
-
-	"k8s.io/apimachinery/pkg/util/sets"
-)
-
-// TimeTypeNode is a node type that encapsulates fields that are internally time based. E.g metav1.ObjectMeta.CreationTimestamp or metav1.ObjectMeta.DeletionTimestamp.
-// These are internally of type metav1.Time which use standard time type, but their values are specified as timestamp strings with parsing logic to create time objects. For
-// use-case we only care if the value is set, so we create TimeTypeNodes and mark them as leafnodes.
-type TimeTypeNode struct {
-	NodeData
-}
-
-// GetData returns node data
-func (ti *TimeTypeNode) GetData() NodeData {
-	return ti.NodeData
-}
-
-func (ti *TimeTypeNode) initialize(field string, parent NodeInterface, t reflect.Type, rt *ResourceTree) {
-	ti.NodeData.initialize(field, parent, t, rt)
-	ti.LeafNode = true
-}
-
-func (ti *TimeTypeNode) buildChildNodes(t reflect.Type) {}
-
-func (ti *TimeTypeNode) updateCoverage(v reflect.Value) {
-	if v.Type().Kind() == reflect.Struct && v.IsValid() {
-		ti.Covered = true
-	} else if v.Type().Kind() == reflect.Ptr && !v.IsNil() {
-		ti.Covered = true
-	}
-}
-
-// no-op as the coverage is calculated as field coverage in parent node.
-func (ti *TimeTypeNode) buildCoverageData(coverageHelper coverageDataHelper) {}
-
-func (ti *TimeTypeNode) getValues() sets.String {
-	return nil
-}
diff --git a/test/webhook-apicoverage/resourcetree/updateCoverage_test.go b/test/webhook-apicoverage/resourcetree/updateCoverage_test.go
deleted file mode 100644
index f107db9bf..000000000
--- a/test/webhook-apicoverage/resourcetree/updateCoverage_test.go
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-Copyright 2018 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 resourcetree
-
-import (
-	"reflect"
-	"testing"
-)
-
-func TestSimpleStructValue(t *testing.T) {
-	tree := getTestTree(basicTypeName, reflect.TypeOf(baseType{}))
-	tree.UpdateCoverage(reflect.ValueOf(getBaseTypeValue()))
-	if err := verifyBaseTypeValue("", tree.Root); err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestUpdateCoverage(t *testing.T) {
-	datas := []struct {
-		TestName string
-		name     string
-		typeI    interface{}
-		value    interface{}
-		f        func(NodeInterface) error
-	}{{
-		"TestPtrValueAllCovered", ptrTypeName, ptrType{}, getPtrTypeValueAllCovered(), verifyPtrValueAllCovered,
-	}, {
-		"TestPtrValueSomeCovered", ptrTypeName, ptrType{}, getPtrTypeValueSomeCovered(), verifyPtrValueSomeCovered,
-	}, {
-		"TestArrValueAllCovered", arrayTypeName, arrayType{}, getArrValueAllCovered(), verifyArryValueAllCovered,
-	}, {
-		"TestArrValueSomeCovered", arrayTypeName, arrayType{}, getArrValueSomeCovered(), verifyArrValueSomeCovered,
-	}, {
-		"TestOtherValue", otherTypeName, otherType{}, getOtherTypeValue(), verifyOtherTypeValue,
-	}}
-
-	for _, data := range datas {
-		t.Run(data.TestName, func(t *testing.T) {
-			tree := getTestTree(data.name, reflect.TypeOf(data.typeI))
-			tree.UpdateCoverage(reflect.ValueOf(data.value))
-			if err := data.f(tree.Root); err != nil {
-				t.Fatal(err)
-			}
-		})
-
-	}
-}
diff --git a/test/webhook-apicoverage/tools/README.md b/test/webhook-apicoverage/tools/README.md
deleted file mode 100644
index 3588e0585..000000000
--- a/test/webhook-apicoverage/tools/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Tools
-
-Tools package is intended to contain types and public helper methods that
-provide utilities to solves common requirements across repos. It currently
-contains following helper methods:
-
-1. `GetDefaultKubePath`: Helper method to retrieve the path for Kubeconfig
-   inside users home directory.
-1. `GetWebhookServiceIP`: Helper method to retrieve the public IP address for
-   the webhook service. The service is setup as part of the apicoverage-webhook
-   setup.
-1. `GetResourceCoverage`: Helper method to retrieve Coverage data for a resource
-   passed as parameter. The coverage data is retrieved from the API that is
-   exposed by the HTTP server in [Webhook Setup](../webhook/webhook.go)
-1. `GetAndWriteResourceCoverage`: Helper method that uses `GetResourceCoverage`
-   to retrieve resource coverage and writes output to a file.
-1. `GetTotalCoverage`: Helper method to retrieve total coverage data for a repo.
-   The coverage data is retrieved from the API that is exposed by the HTTP
-   server in [Webhook Setup](../webhook/webhook.go)
-1. `GetAndWriteTotalCoverage`: Helper method that uses `GetTotalCoverage` to
-   retrieve total coverage and writes output to a file.
diff --git a/test/webhook-apicoverage/tools/tools.go b/test/webhook-apicoverage/tools/tools.go
deleted file mode 100644
index aa813d761..000000000
--- a/test/webhook-apicoverage/tools/tools.go
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
-Copyright 2019 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 tools
-
-import (
-	"context"
-	"crypto/tls"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"os"
-	"os/user"
-	"path"
-	"path/filepath"
-	"regexp"
-
-	"knative.dev/pkg/test/webhook-apicoverage/coveragecalculator"
-	"knative.dev/pkg/test/webhook-apicoverage/view"
-	"knative.dev/pkg/test/webhook-apicoverage/webhook"
-
-	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/client-go/kubernetes"
-
-	// Mysteriously required to support GCP auth (required by k8s libs).
-	// Apparently just importing it is enough. @_@ side effects @_@.
-	// https://github.com/kubernetes/client-go/issues/242
-	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
-	"k8s.io/client-go/tools/clientcmd"
-)
-
-// tools.go contains utility methods to help repos use the webhook-apicoverage tool.
-
-const (
-	// WebhookResourceCoverageEndPoint constant for resource coverage API endpoint.
-	WebhookResourceCoverageEndPoint = "https://%s:443" + webhook.ResourceCoverageEndPoint + "?resource=%s"
-
-	// WebhookTotalCoverageEndPoint constant for total coverage API endpoint.
-	WebhookTotalCoverageEndPoint = "https://%s:443" + webhook.TotalCoverageEndPoint
-
-	// WebhookResourcePercentageCoverageEndPoint constant for
-	// ResourcePercentageCoverage API endpoint.
-	WebhookResourcePercentageCoverageEndPoint = "https://%s:443" + webhook.ResourcePercentageCoverageEndPoint
-)
-
-var (
-	jUnitFileRegexExpr = regexp.MustCompile(`junit_.*\.xml`)
-)
-
-// GetDefaultKubePath helper method to fetch kubeconfig path.
-func GetDefaultKubePath() (string, error) {
-	var (
-		usr *user.User
-		err error
-	)
-	if usr, err = user.Current(); err != nil {
-		return "", fmt.Errorf("error retrieving current user: %w", err)
-	}
-
-	return path.Join(usr.HomeDir, ".kube/config"), nil
-}
-
-func getKubeClient(kubeConfigPath string, clusterName string) (*kubernetes.Clientset, error) {
-	overrides := clientcmd.ConfigOverrides{}
-	overrides.Context.Cluster = clusterName
-	clientCfg, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
-		&clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeConfigPath},
-		&overrides).ClientConfig()
-	if err != nil {
-		return nil, fmt.Errorf("error building kube client config: %w", err)
-	}
-
-	var kubeClient *kubernetes.Clientset
-	if kubeClient, err = kubernetes.NewForConfig(clientCfg); err != nil {
-		return nil, fmt.Errorf("error building KubeClient from config: %w", err)
-	}
-
-	return kubeClient, nil
-}
-
-// GetWebhookServiceIP is a helper method to fetch IP Address of the LoadBalancer webhook service.
-func GetWebhookServiceIP(kubeConfigPath string, clusterName string, namespace string, serviceName string) (string, error) {
-	kubeClient, err := getKubeClient(kubeConfigPath, clusterName)
-	if err != nil {
-		return "", err
-	}
-
-	svc, err := kubeClient.CoreV1().Services(namespace).Get(context.Background(), serviceName, v1.GetOptions{})
-	if err != nil {
-		return "", fmt.Errorf("error encountered while retrieving service: %s Error: %w", serviceName, err)
-	}
-
-	if len(svc.Status.LoadBalancer.Ingress) == 0 {
-		return "", errors.New("found zero Ingress instances for service: " + serviceName)
-	}
-
-	return svc.Status.LoadBalancer.Ingress[0].IP, nil
-}
-
-// GetResourceCoverage is a helper method to get Coverage data for a resource from the service webhook.
-func GetResourceCoverage(webhookIP string, resourceName string) (string, error) {
-	client := &http.Client{Transport: &http.Transport{
-		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
-	},
-	}
-	resp, err := client.Get(fmt.Sprintf(WebhookResourceCoverageEndPoint, webhookIP, resourceName))
-	if err != nil {
-		return "", fmt.Errorf("encountered error making resource coverage request: %w", err)
-	}
-	if resp.StatusCode != http.StatusOK {
-		return "", fmt.Errorf("invalid HTTP Status received for resource coverage request. Status: %d", resp.StatusCode)
-	}
-
-	var body []byte
-	if body, err = ioutil.ReadAll(resp.Body); err != nil {
-		return "", fmt.Errorf("failed reading resource coverage response: %w", err)
-	}
-
-	return string(body), nil
-}
-
-// GetAndWriteResourceCoverage is a helper method that uses GetResourceCoverage to get coverage and write it to a file.
-func GetAndWriteResourceCoverage(webhookIP string, resourceName string, outputFile string, displayRules view.DisplayRules) error {
-	var (
-		err              error
-		resourceCoverage string
-	)
-
-	if resourceCoverage, err = GetResourceCoverage(webhookIP, resourceName); err != nil {
-		return err
-	}
-
-	return ioutil.WriteFile(outputFile, []byte(resourceCoverage), 0400)
-}
-
-// GetTotalCoverage calls the total coverage API to retrieve total coverage values.
-func GetTotalCoverage(webhookIP string) (*coveragecalculator.CoverageValues, error) {
-	client := &http.Client{Transport: &http.Transport{
-		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
-	},
-	}
-
-	resp, err := client.Get(fmt.Sprintf(WebhookTotalCoverageEndPoint, webhookIP))
-	if err != nil {
-		return nil, fmt.Errorf("encountered error making total coverage request: %w", err)
-	}
-	if resp.StatusCode != http.StatusOK {
-		return nil, fmt.Errorf("invalid HTTP Status received for total coverage request. Status: %d", resp.StatusCode)
-	}
-
-	var body []byte
-	if body, err = ioutil.ReadAll(resp.Body); err != nil {
-		return nil, fmt.Errorf("error reading total coverage response: %w", err)
-	}
-
-	var coverage coveragecalculator.CoverageValues
-	if err = json.Unmarshal(body, &coverage); err != nil {
-		return nil, fmt.Errorf("failed unmarshalling response to CoverageValues instance: %w", err)
-	}
-
-	return &coverage, nil
-}
-
-// GetAndWriteTotalCoverage uses the GetTotalCoverage method to get total coverage and write it to a output file.
-func GetAndWriteTotalCoverage(webhookIP string, outputFile string) error {
-	var (
-		totalCoverage *coveragecalculator.CoverageValues
-		err           error
-	)
-
-	if totalCoverage, err = GetTotalCoverage(webhookIP); err != nil {
-		return err
-	}
-
-	htmlData, err := view.GetHTMLCoverageValuesDisplay(totalCoverage)
-	if err != nil {
-		return fmt.Errorf("failed building html file from total coverage: %w", err)
-	}
-
-	return ioutil.WriteFile(outputFile, []byte(htmlData), 0400)
-}
-
-// GetResourcePercentages calls resource percentage coverage API to retrieve
-// percentage values.
-func GetResourcePercentages(webhookIP string) (
-	*coveragecalculator.CoveragePercentages, error) {
-	client := &http.Client{Transport: &http.Transport{
-		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
-	},
-	}
-
-	resp, err := client.Get(fmt.Sprintf(WebhookResourcePercentageCoverageEndPoint,
-		webhookIP))
-	if err != nil {
-		return nil, fmt.Errorf("encountered error making resource percentage coverage request: %w", err)
-	}
-	if resp.StatusCode != http.StatusOK {
-		return nil, fmt.Errorf("invalid HTTP Status received for resource"+
-			" percentage coverage request. Status: %d", resp.StatusCode)
-	}
-
-	var body []byte
-	if body, err = ioutil.ReadAll(resp.Body); err != nil {
-		return nil, fmt.Errorf("failed reading resource percentage coverage response: %w", err)
-	}
-
-	coveragePercentages := &coveragecalculator.CoveragePercentages{}
-	if err = json.Unmarshal(body, coveragePercentages); err != nil {
-		return nil, fmt.Errorf("failed unmarshalling response to CoveragePercentages instance: %w", err)
-	}
-
-	return coveragePercentages, nil
-}
-
-// WriteResourcePercentages writes CoveragePercentages to junit_xml output file.
-func WriteResourcePercentages(outputFile string,
-	coveragePercentages *coveragecalculator.CoveragePercentages) error {
-	htmlData, err := view.GetCoveragePercentageXMLDisplay(coveragePercentages)
-	if err != nil {
-		return fmt.Errorf("failed building coverage percentage xml file: %w", err)
-	}
-
-	return ioutil.WriteFile(outputFile, []byte(htmlData), 0400)
-}
-
-// Helper function to cleanup any existing Junit XML files.
-// This is done to ensure that we only have one Junit XML file providing the
-// API Coverage summary.
-func CleanupJunitFiles(artifactsDir string) {
-	filepath.Walk(artifactsDir, func(path string, info os.FileInfo, err error) error {
-		if !info.IsDir() && jUnitFileRegexExpr.MatchString(info.Name()) {
-			return os.Remove(path)
-		}
-		return nil
-	})
-}
diff --git a/test/webhook-apicoverage/view/README.md b/test/webhook-apicoverage/view/README.md
deleted file mode 100644
index 46d369496..000000000
--- a/test/webhook-apicoverage/view/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# View
-
-This package contains types and helper methods that repos can use to display API
-Coverage results.
-
-[DisplayRules](rule.go) provides a mechanism for repos to define their own
-display rules. DisplayHelper methods can use these rules to define how to
-display results.
-
-`GetHTMLDisplay()` is a utility method that can be used by repos to get a
-HTML(JSON) like textual display of API Coverage. This method takes an array of
-[TypeCoverage](../coveragecalculator/coveragedata.go) and
-[DisplayRules](rule.go) object and returns a string representing its coverage in
-the color coded format inside a HTML page:
-
-```
-Package: <PackageName>
-Type: <TypeName>
-{
-    <FieldName> <Ignored>/<Coverage:TrueorFalse> [Values]
-    ....
-    ....
-    ....
-}
-```
-
-`GetHTMLCoverageValuesDisplay()` is a utility method that can be used by repos
-to produce coverage values display. The method takes as input
-[CoverageValue](../coveragecalculator/calculator.go) and produces a display in
-the format inside a HTML page:
-
-```
-CoverageValues:
-
-Total Fields:  <Number of total fields>
-Covered Fields: <Number of fields covered>
-Ignored Fields: <Number of fields ignored>
-Coverage Percentage: <Percentage value of coverage>
-```
-
-`GetCoveragePercentageXMLDisplay()` is a utility method that can be used by
-repos to produce coverage percentage for each resource in a Junit XML results
-file. The method takes
-[CoveragePercentages](../coveragecalculator/calculator.go) as input and produces
-a Junit result file format.
diff --git a/test/webhook-apicoverage/view/html_display.go b/test/webhook-apicoverage/view/html_display.go
deleted file mode 100644
index 1c93c9bd0..000000000
--- a/test/webhook-apicoverage/view/html_display.go
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
-Copyright 2019 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 view
-
-import (
-	"html/template"
-	"strings"
-
-	"knative.dev/pkg/test/webhook-apicoverage/coveragecalculator"
-)
-
-type HtmlDisplayData struct {
-	TypeCoverages   []coveragecalculator.TypeCoverage
-	CoverageNumbers *coveragecalculator.CoverageValues
-}
-
-// GetHTMLDisplay is a helper method to display API Coverage details in
-// json-like format inside a HTML page.
-func GetHTMLDisplay(coverageData []coveragecalculator.TypeCoverage,
-	coverageValues *coveragecalculator.CoverageValues) (string, error) {
-	htmlData := HtmlDisplayData{
-		TypeCoverages:   coverageData,
-		CoverageNumbers: coverageValues,
-	}
-
-	tmpl, err := template.New("TypeCoverage").Parse(TypeCoverageTempl)
-	if err != nil {
-		return "", err
-	}
-
-	var buffer strings.Builder
-	err = tmpl.Execute(&buffer, htmlData)
-	if err != nil {
-		return "", err
-	}
-
-	return buffer.String(), nil
-}
-
-// GetHTMLCoverageValuesDisplay is a helper method to display coverage values inside a HTML table.
-func GetHTMLCoverageValuesDisplay(coverageValues *coveragecalculator.CoverageValues) (string, error) {
-	tmpl, err := template.New("AggregateCoverage").Parse(AggregateCoverageTmpl)
-	if err != nil {
-		return "", err
-	}
-
-	var buffer strings.Builder
-	err = tmpl.Execute(&buffer, coverageValues)
-	if err != nil {
-		return "", err
-	}
-
-	return buffer.String(), nil
-}
diff --git a/test/webhook-apicoverage/view/html_template.go b/test/webhook-apicoverage/view/html_template.go
deleted file mode 100644
index 15539598d..000000000
--- a/test/webhook-apicoverage/view/html_template.go
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-Copyright 2019 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 view
-
-var TypeCoverageTempl = `<!DOCTYPE html>
-<html>
-<style type="text/css">
-  <!--
-
-  .tab { margin-left: 50px; }
-
-  .styleheader {color: white; size: A4}
-
-  .covered {color: green; size: A3}
-
-  .notcovered {color: red; size: A3}
-
-  .ignored {color: white; size: A4}
-
-  .values {color: yellow; size: A3}
-
-  table, th, td { border: 1px solid white; text-align: center}
-
-  .braces {color: white; size: A3}
-  -->
-</style>
-<body style="background-color:rgb(0,0,0); font-family: Arial">
-{{ range $coverageType := .TypeCoverages }}
-  <div class="styleheader">
-    <br>Package: {{ $coverageType.Package }}
-    <br>Type: {{ $coverageType.Type }}
-    <br>
-    <div class="braces">
-      <br>{
-    </div>
-    {{ range $key, $value := $coverageType.Fields }}
-      {{if $value.Ignored }}
-        <div class="ignored tab">{{ $value.Field }}</div>
-      {{else if $value.Coverage}}
-        <div class="covered tab">{{ $value.Field }}
-          {{ $valueLen := len $value.Values }}
-          {{if gt $valueLen 0 }}
-            &emsp; &emsp; <span class="values">Values: [{{$value.GetValuesForDisplay}}]</span>
-          {{end}}
-        </div>
-      {{else}}
-        <div class="notcovered tab">{{ $value.Field }}</div>
-      {{end}}
-    {{end}}
-    <div class="braces">}</div>
-  </div>
-{{end}}
-
-<br>
-<br>
-<div class="styleheader">Coverage Values</div>
-<br>
-<table style="width: 30%">
-  <tr class="styleheader"><td>Total Fields</td><td>{{ .CoverageNumbers.TotalFields }}</td></tr>
-  <tr class="styleheader"><td>Covered Fields</td><td>{{ .CoverageNumbers.CoveredFields }}</td></tr>
-  <tr class="styleheader"><td>Ignored Fields</td><td>{{ .CoverageNumbers.IgnoredFields }}</td></tr>
-  <tr class="styleheader"><td>Coverage Percentage</td><td>{{ .CoverageNumbers.PercentCoverage }}</td></tr>
-</table>
-</body>
-</html>
-`
-
-var AggregateCoverageTmpl = `<!DOCTYPE html>
-<html>
-<style type="text/css">
-  <!--
-
-  .tab { margin-left: 50px; }
-
-  .styleheader {color: white; size: A4}
-
-  .values {color: yellow; size: A3}
-
-  table, th, td { border: 1px solid white; text-align: center}
-
-  .braces {color: white; size: A3}
-  -->
-</style>
-<body style="background-color:rgb(0,0,0); font-family: Arial">
-<table style="width: 30%">
-  <tr class="styleheader"><td>Total Fields</td><td>{{ .TotalFields }}</td></tr>
-  <tr class="styleheader"><td>Covered Fields</td><td>{{ .CoveredFields }}</td></tr>
-  <tr class="styleheader"><td>Ignored Fields</td><td>{{ .IgnoredFields }}</td></tr>
-  <tr class="styleheader"><td>Coverage Percentage</td><td>{{ .PercentCoverage }}</td></tr>
-</table>
-</body>
-</html>
-`
diff --git a/test/webhook-apicoverage/view/rule.go b/test/webhook-apicoverage/view/rule.go
deleted file mode 100644
index defa98055..000000000
--- a/test/webhook-apicoverage/view/rule.go
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-Copyright 2019 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 view
-
-import "knative.dev/pkg/test/webhook-apicoverage/coveragecalculator"
-
-// DisplayRules provides a mechanism for repos to define their own display rules.
-// DisplayHelper methods can use these rules to define how to display results.
-type DisplayRules struct {
-	PackageNameRule func(packageName string) string
-	TypeNameRule    func(typeName string) string
-	FieldRule       func(coverage *coveragecalculator.FieldCoverage) string
-}
diff --git a/test/webhook-apicoverage/view/xml_display.go b/test/webhook-apicoverage/view/xml_display.go
deleted file mode 100644
index 159c6528e..000000000
--- a/test/webhook-apicoverage/view/xml_display.go
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-Copyright 2019 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 view
-
-import (
-	"strings"
-	"text/template"
-
-	"knative.dev/pkg/test/webhook-apicoverage/coveragecalculator"
-)
-
-// GetCoveragePercentageXMLDisplay is a helper method to write resource coverage
-// percentage values to junit xml file format.
-func GetCoveragePercentageXMLDisplay(
-	percentageCoverages *coveragecalculator.CoveragePercentages) (string, error) {
-	tmpl, err := template.New("JunitResult").Parse(junitResultTmpl)
-	if err != nil {
-		return "", err
-	}
-
-	var buffer strings.Builder
-	err = tmpl.Execute(&buffer, percentageCoverages)
-	if err != nil {
-		return "", err
-	}
-
-	return buffer.String(), nil
-}
diff --git a/test/webhook-apicoverage/view/xml_template.go b/test/webhook-apicoverage/view/xml_template.go
deleted file mode 100644
index 36c97ad28..000000000
--- a/test/webhook-apicoverage/view/xml_template.go
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-Copyright 2019 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 view
-
-var junitResultTmpl = `<testsuites>
-  <testsuite name="" time="0" {{ if .IsFailedBuild }} failures="1" {{ else }} failures = "0" {{ end }} tests="0">
-      <testcase name="Overall" time="0" classname="go_coverage">
-				{{ if .IsFailedBuild }}
-					<failure>true</failure>
-        {{ end }}
-				<properties>
-          <property name="coverage" value="{{ .GetAndRemoveResourceValue "Overall" }}"/>
-        </properties>
-      </testcase>
-    {{ range $key, $value := .ResourceCoverages }}
-      <testcase name="{{ $key }}" time="0" classname="go_coverage">
-        <properties>
-          <property name="coverage" value="{{ $value }}"/>
-        </properties>
-      </testcase>
-    {{end}}
-  </testsuite>
-</testsuites>`
diff --git a/test/webhook-apicoverage/webhook/README.md b/test/webhook-apicoverage/webhook/README.md
deleted file mode 100644
index 5888dbd50..000000000
--- a/test/webhook-apicoverage/webhook/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# Webhook
-
-Webhook based API-Coverage tool uses
-[ValidatingAdmissionWebhook](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook)
-which is a web-server that the K8 API-Server calls into for every API-Object
-update to verify if the object is valid before storing it into its datastore.
-Each validation request has the json representation of the object being
-created/modified, that the tool uses to capture coverage data. `webhook` package
-inside this folder provides a mechanism for individual repos to setup
-ValidatingAdmissionWebhook.
-
-[APICoverageWebhook](webhook.go) type inside the package encapsulates necessary
-configuration details and helper methods required to setup the webhook. Each
-repo is expected to call into `SetupWebhook()` providing following three
-parameters:
-
-1. `http.Handler`: This is the http handler (that implements
-   `ServeHTTP( w http.ResponseWriter, r *http.Request)`) that the web server
-   created by APICoverageWebhook uses.
-1. `rules`: This is an array of `RuleWithOperations` objects from the
-   `k8s.io/api/admissionregistration/v1beta1` package that the webhook uses for
-   validation on each API Object update. e.g: knative-serving while calling this
-   method would provide rules that will handle API Objects like `Service`,
-   `Configuration`, `Route` and `Revision`.
-1. `namespace`: Namespace name where the webhook would be installed.
-1. `stop` channel: Channel to terminate webhook's web server.
-
-`SetupWebhook()` method in its implementation creates a TLS based web server and
-registers the webhook by creating a ValidatingWebhookConfiguration object inside
-the K8 cluster.
-
-[APICoverageRecorder](apicoverage_recorder.go) type inside the package
-encapsulates the apicoverage recording capabilities. Repo using this type is
-expected to set:
-
-1. `ResourceForest`: Specifying the version and initializing the
-   [ResourceTrees](../resourcetree/resourcetree.go)
-1. `ResourceMap`: Identifying the resources whose APICoverage needs to be
-   calculated.
-1. `NodeRules`: [NodeRules](../resourcetree/rule.go) that are applicable for the
-   repo.
-1. `FieldRules`: [FieldRules](../resourcetree/rule.go) that are applicable for
-   the repo.
-1. `DisplayRules`: [DisplayRules](../view/rule.go) to be used by
-   `GetResourceCoverage` method.
diff --git a/test/webhook-apicoverage/webhook/apicoverage_recorder.go b/test/webhook-apicoverage/webhook/apicoverage_recorder.go
deleted file mode 100644
index d78f54194..000000000
--- a/test/webhook-apicoverage/webhook/apicoverage_recorder.go
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
-Copyright 2018 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 webhook
-
-import (
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"os"
-	"reflect"
-
-	"go.uber.org/zap"
-	v1 "k8s.io/api/admission/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/runtime/schema"
-	"k8s.io/apimachinery/pkg/runtime/serializer"
-	"knative.dev/pkg/test/webhook-apicoverage/coveragecalculator"
-	"knative.dev/pkg/test/webhook-apicoverage/resourcetree"
-	"knative.dev/pkg/test/webhook-apicoverage/view"
-	"knative.dev/pkg/webhook/resourcesemantics"
-)
-
-var (
-	decoder = serializer.NewCodecFactory(runtime.NewScheme()).UniversalDeserializer()
-)
-
-const (
-	// ResourceQueryParam query param name to provide the resource.
-	ResourceQueryParam = "resource"
-
-	// ResourceCoverageEndPoint is the endpoint for Resource Coverage API
-	ResourceCoverageEndPoint = "/resourcecoverage"
-
-	// TotalCoverageEndPoint is the endpoint for Total Coverage API
-	TotalCoverageEndPoint = "/totalcoverage"
-
-	// ResourcePercentageCoverageEndPoint is the end point for Resource Percentage
-	// coverages API
-	ResourcePercentageCoverageEndPoint = "/resourcepercentagecoverage"
-
-	// resourceChannelQueueSize size of the queue maintained for resource channel.
-	resourceChannelQueueSize = 10
-)
-
-type resourceChannelMsg struct {
-	resourceType     schema.GroupVersionKind
-	rawResourceValue []byte
-}
-
-// APICoverageRecorder type contains resource tree to record API coverage for resources.
-type APICoverageRecorder struct {
-	Logger          *zap.SugaredLogger
-	ResourceForest  resourcetree.ResourceForest
-	ResourceMap     map[schema.GroupVersionKind]resourcesemantics.GenericCRD
-	NodeRules       resourcetree.NodeRules
-	FieldRules      resourcetree.FieldRules
-	DisplayRules    view.DisplayRules
-	resourceChannel chan resourceChannelMsg
-}
-
-// Init initializes the resources trees for set resources.
-func (a *APICoverageRecorder) Init() {
-	for resourceKind, resourceObj := range a.ResourceMap {
-		a.ResourceForest.AddResourceTree(resourceKind.Kind, reflect.ValueOf(resourceObj).Elem().Type())
-	}
-	a.resourceChannel = make(chan resourceChannelMsg, resourceChannelQueueSize)
-	go a.updateResourceCoverageTree()
-}
-
-// updateResourceCoverageTree updates the resource coverage tree.
-func (a *APICoverageRecorder) updateResourceCoverageTree() {
-	for {
-		channelMsg := <-a.resourceChannel
-		if err := json.Unmarshal(channelMsg.rawResourceValue, a.ResourceMap[channelMsg.resourceType]); err != nil {
-			a.Logger.Errorf("Failed unmarshalling review.Request.Object.Raw for type: %s Error: %v", channelMsg.resourceType.Kind, err)
-			continue
-		}
-		resourceTree := a.ResourceForest.TopLevelTrees[channelMsg.resourceType.Kind]
-		resourceTree.UpdateCoverage(reflect.ValueOf(a.ResourceMap[channelMsg.resourceType]).Elem())
-		a.Logger.Info("Successfully recorded coverage for resource ", channelMsg.resourceType.Kind)
-	}
-}
-
-// RecordResourceCoverage updates the resource tree with the request.
-func (a *APICoverageRecorder) RecordResourceCoverage(w http.ResponseWriter, r *http.Request) {
-	var (
-		body []byte
-		err  error
-	)
-
-	review := &v1.AdmissionReview{}
-	if body, err = ioutil.ReadAll(r.Body); err != nil {
-		a.Logger.Errorf("Failed reading request body: %v", err)
-		a.appendAndWriteAdmissionResponse(review, false, "Admission Denied", w)
-		return
-	}
-
-	if _, _, err := decoder.Decode(body, nil, review); err != nil {
-		a.Logger.Errorf("Unable to decode request: %v", err)
-		a.appendAndWriteAdmissionResponse(review, false, "Admission Denied", w)
-		return
-	}
-
-	gvk := schema.GroupVersionKind{
-		Group:   review.Request.Kind.Group,
-		Version: review.Request.Kind.Version,
-		Kind:    review.Request.Kind.Kind,
-	}
-	// We only care about resources the repo has setup.
-	if _, ok := a.ResourceMap[gvk]; !ok {
-		a.Logger.Info("By-passing resource coverage update for resource : %s", gvk.Kind)
-		a.appendAndWriteAdmissionResponse(review, true, "Welcome Aboard", w)
-		return
-	}
-
-	a.resourceChannel <- resourceChannelMsg{
-		resourceType:     gvk,
-		rawResourceValue: review.Request.Object.Raw,
-	}
-	a.appendAndWriteAdmissionResponse(review, true, "Welcome Aboard", w)
-}
-
-func (a *APICoverageRecorder) appendAndWriteAdmissionResponse(review *v1.AdmissionReview, allowed bool, message string, w http.ResponseWriter) {
-	review.Response = &v1.AdmissionResponse{
-		Allowed: allowed,
-		Result: &metav1.Status{
-			Message: message,
-		},
-	}
-
-	responseInBytes, err := json.Marshal(review)
-	if err != nil {
-		a.Logger.Errorf("Failing mashalling review response: %v", err)
-	}
-
-	if _, err := w.Write(responseInBytes); err != nil {
-		a.Logger.Errorf("%v", err)
-	}
-}
-
-// GetResourceCoverage retrieves resource coverage data for the passed in resource via query param.
-func (a *APICoverageRecorder) GetResourceCoverage(w http.ResponseWriter, r *http.Request) {
-	resource := r.URL.Query().Get(ResourceQueryParam)
-	if _, ok := a.ResourceForest.TopLevelTrees[resource]; !ok {
-		fmt.Fprintf(w, "Resource information not found for resource: %s", resource)
-		return
-	}
-
-	var ignoredFields coveragecalculator.IgnoredFields
-	ignoredFieldsFilePath := os.Getenv("KO_DATA_PATH") + "/ignoredfields.yaml"
-	if err := ignoredFields.ReadFromFile(ignoredFieldsFilePath); err != nil {
-		a.Logger.Errorf("Error reading file %s: %v", ignoredFieldsFilePath, err)
-	}
-
-	tree := a.ResourceForest.TopLevelTrees[resource]
-	typeCoverage := tree.BuildCoverageData(a.NodeRules, a.FieldRules, ignoredFields)
-	coverageValues := coveragecalculator.CalculateTypeCoverage(typeCoverage)
-	coverageValues.CalculatePercentageValue()
-
-	if htmlData, err := view.GetHTMLDisplay(typeCoverage, coverageValues); err != nil {
-		fmt.Fprintf(w, "Error generating html file %v", err)
-	} else {
-		fmt.Fprint(w, htmlData)
-	}
-}
-
-// GetTotalCoverage goes over all the resources setup for the apicoverage tool and returns total coverage values.
-func (a *APICoverageRecorder) GetTotalCoverage(w http.ResponseWriter, r *http.Request) {
-	var (
-		ignoredFields coveragecalculator.IgnoredFields
-		err           error
-	)
-
-	ignoredFieldsFilePath := os.Getenv("KO_DATA_PATH") + "/ignoredfields.yaml"
-	if err = ignoredFields.ReadFromFile(ignoredFieldsFilePath); err != nil {
-		a.Logger.Errorf("Error reading file %s: %v", ignoredFieldsFilePath, err)
-	}
-
-	totalCoverage := coveragecalculator.CoverageValues{}
-	for resource := range a.ResourceMap {
-		tree := a.ResourceForest.TopLevelTrees[resource.Kind]
-		typeCoverage := tree.BuildCoverageData(a.NodeRules, a.FieldRules, ignoredFields)
-		coverageValues := coveragecalculator.CalculateTypeCoverage(typeCoverage)
-		totalCoverage.TotalFields += coverageValues.TotalFields
-		totalCoverage.CoveredFields += coverageValues.CoveredFields
-		totalCoverage.IgnoredFields += coverageValues.IgnoredFields
-	}
-
-	totalCoverage.CalculatePercentageValue()
-	var body []byte
-	if body, err = json.Marshal(totalCoverage); err != nil {
-		fmt.Fprintf(w, "error marshalling total coverage response: %v", err)
-		return
-	}
-
-	if _, err = w.Write(body); err != nil {
-		fmt.Fprintf(w, "error writing total coverage response: %v", err)
-	}
-}
-
-// GetResourceCoveragePercentags goes over all the resources setup for the
-// apicoverage tool and returns percentage coverage for each resource.
-func (a *APICoverageRecorder) GetResourceCoveragePercentages(
-	w http.ResponseWriter, r *http.Request) {
-	var (
-		ignoredFields coveragecalculator.IgnoredFields
-		err           error
-	)
-
-	ignoredFieldsFilePath :=
-		os.Getenv("KO_DATA_PATH") + "/ignoredfields.yaml"
-	if err = ignoredFields.ReadFromFile(ignoredFieldsFilePath); err != nil {
-		a.Logger.Errorf("Error reading file %s: %v",
-			ignoredFieldsFilePath, err)
-	}
-
-	totalCoverage := coveragecalculator.CoverageValues{}
-	percentCoverages := make(map[string]float64)
-	for resource := range a.ResourceMap {
-		tree := a.ResourceForest.TopLevelTrees[resource.Kind]
-		typeCoverage := tree.BuildCoverageData(a.NodeRules, a.FieldRules,
-			ignoredFields)
-		coverageValues := coveragecalculator.CalculateTypeCoverage(typeCoverage)
-		coverageValues.CalculatePercentageValue()
-		percentCoverages[resource.Kind] = coverageValues.PercentCoverage
-		totalCoverage.TotalFields += coverageValues.TotalFields
-		totalCoverage.CoveredFields += coverageValues.CoveredFields
-		totalCoverage.IgnoredFields += coverageValues.IgnoredFields
-	}
-	totalCoverage.CalculatePercentageValue()
-	percentCoverages["Overall"] = totalCoverage.PercentCoverage
-
-	var body []byte
-	if body, err = json.Marshal(
-		coveragecalculator.CoveragePercentages{
-			ResourceCoverages: percentCoverages,
-		}); err != nil {
-		fmt.Fprintf(w, "error marshalling percentage coverage response: %v",
-			err)
-		return
-	}
-
-	if _, err = w.Write(body); err != nil {
-		fmt.Fprintf(w, "error writing percentage coverage response: %v",
-			err)
-	}
-}
diff --git a/test/webhook-apicoverage/webhook/webhook.go b/test/webhook-apicoverage/webhook/webhook.go
deleted file mode 100644
index e8f01856c..000000000
--- a/test/webhook-apicoverage/webhook/webhook.go
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
-Copyright 2018 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 webhook
-
-import (
-	"context"
-	"crypto/tls"
-	"errors"
-	"fmt"
-	"log"
-	"net/http"
-	"strings"
-	"time"
-
-	"github.com/markbates/inflect"
-	"go.uber.org/zap"
-	admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
-	extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime/schema"
-	"k8s.io/client-go/kubernetes"
-	"k8s.io/client-go/rest"
-	"knative.dev/pkg/configmap"
-	"knative.dev/pkg/logging"
-	certresources "knative.dev/pkg/webhook/certificates/resources"
-	"knative.dev/pkg/webhook/resourcesemantics"
-)
-
-var (
-	// GroupVersionKind for deployment to be used to set the webhook's owner reference.
-	deploymentKind = extensionsv1beta1.SchemeGroupVersion.WithKind("Deployment")
-)
-
-// APICoverageWebhook encapsulates necessary configuration details for the api-coverage webhook.
-type APICoverageWebhook struct {
-	// WebhookName is the name of the validation webhook we create to intercept API calls.
-	WebhookName string
-
-	// ServiceName is the name of K8 service under which the webhook runs.
-	ServiceName string
-
-	// DeploymentName is the deployment name for the webhook.
-	DeploymentName string
-
-	// Namespace is the namespace in which everything above lives.
-	Namespace string
-
-	// Port where the webhook is served.
-	Port int
-
-	// RegistrationDelay controls how long validation requests
-	// occurs after the webhook is started. This is used to avoid
-	// potential races where registration completes and k8s apiserver
-	// invokes the webhook before the HTTP server is started.
-	RegistrationDelay time.Duration
-
-	// ClientAuthType declares the policy the webhook server will follow for TLS Client Authentication.
-	ClientAuth tls.ClientAuthType
-
-	// CaCert is the CA Cert for the webhook server.
-	CaCert []byte
-
-	// FailurePolicy policy governs the webhook validation decisions.
-	FailurePolicy admissionregistrationv1beta1.FailurePolicyType
-
-	// Logger is the configured logger for the webhook.
-	Logger *zap.SugaredLogger
-
-	// KubeClient is the K8 client to the target cluster.
-	KubeClient kubernetes.Interface
-}
-
-func (acw *APICoverageWebhook) generateServerConfig() (*tls.Config, error) {
-	serverKey, serverCert, caCert, err := certresources.CreateCerts(context.Background(), acw.ServiceName, acw.Namespace, time.Now().AddDate(1, 0, 0))
-	if err != nil {
-		return nil, fmt.Errorf("error creating webhook certificates: %w", err)
-	}
-
-	cert, err := tls.X509KeyPair(serverCert, serverKey)
-	if err != nil {
-		return nil, fmt.Errorf("error creating X509 Key pair for webhook server: %w", err)
-	}
-
-	acw.CaCert = caCert
-	return &tls.Config{
-		Certificates: []tls.Certificate{cert},
-		ClientAuth:   acw.ClientAuth,
-	}, nil
-}
-
-func (acw *APICoverageWebhook) getWebhookServer(handler http.Handler) (*http.Server, error) {
-	tlsConfig, err := acw.generateServerConfig()
-	if err != nil {
-		// generateServerConfig() is expected to provided explanatory error message.
-		return nil, err
-	}
-
-	return &http.Server{
-		Handler:   handler,
-		Addr:      fmt.Sprintf(":%d", acw.Port),
-		TLSConfig: tlsConfig,
-	}, nil
-}
-
-func (acw *APICoverageWebhook) registerWebhook(rules []admissionregistrationv1beta1.RuleWithOperations, namespace string) error {
-	webhook := &admissionregistrationv1beta1.ValidatingWebhookConfiguration{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      acw.WebhookName,
-			Namespace: namespace,
-		},
-		Webhooks: []admissionregistrationv1beta1.ValidatingWebhook{{
-			Name:  acw.WebhookName,
-			Rules: rules,
-			ClientConfig: admissionregistrationv1beta1.WebhookClientConfig{
-				Service: &admissionregistrationv1beta1.ServiceReference{
-					Namespace: namespace,
-					Name:      acw.ServiceName,
-				},
-				CABundle: acw.CaCert,
-			},
-			FailurePolicy: &acw.FailurePolicy,
-		},
-		},
-	}
-
-	deployment, err := acw.KubeClient.ExtensionsV1beta1().Deployments(namespace).Get(context.Background(), acw.DeploymentName, metav1.GetOptions{})
-	if err != nil {
-		return fmt.Errorf("error retrieving Deployment Extension object: %w", err)
-	}
-	deploymentRef := metav1.NewControllerRef(deployment, deploymentKind)
-	webhook.OwnerReferences = append(webhook.OwnerReferences, *deploymentRef)
-
-	_, err = acw.KubeClient.AdmissionregistrationV1beta1().ValidatingWebhookConfigurations().Create(context.Background(), webhook, metav1.CreateOptions{})
-	if err != nil {
-		return fmt.Errorf("error creating ValidatingWebhookConfigurations object: %w", err)
-	}
-
-	return nil
-}
-
-func (acw *APICoverageWebhook) getValidationRules(resources map[schema.GroupVersionKind]resourcesemantics.GenericCRD) []admissionregistrationv1beta1.RuleWithOperations {
-	rules := make([]admissionregistrationv1beta1.RuleWithOperations, 0, len(resources))
-	for gvk := range resources {
-		plural := strings.ToLower(inflect.Pluralize(gvk.Kind))
-
-		rules = append(rules, admissionregistrationv1beta1.RuleWithOperations{
-			Operations: []admissionregistrationv1beta1.OperationType{
-				admissionregistrationv1beta1.Create,
-				admissionregistrationv1beta1.Update,
-			},
-			Rule: admissionregistrationv1beta1.Rule{
-				APIGroups:   []string{gvk.Group},
-				APIVersions: []string{gvk.Version},
-				Resources:   []string{plural},
-			},
-		})
-	}
-	return rules
-}
-
-// SetupWebhook sets up the webhook with the provided http.handler, resourcegroup Map, namespace and stop channel.
-func (acw *APICoverageWebhook) SetupWebhook(handler http.Handler, resources map[schema.GroupVersionKind]resourcesemantics.GenericCRD, namespace string, stop <-chan struct{}) error {
-	server, err := acw.getWebhookServer(handler)
-	rules := acw.getValidationRules(resources)
-	if err != nil {
-		return fmt.Errorf("Webhook server object creation failed: %w", err)
-	}
-
-	select {
-	case <-time.After(acw.RegistrationDelay):
-		err = acw.registerWebhook(rules, namespace)
-		if err != nil {
-			return fmt.Errorf("Webhook registration failed: %w", err)
-		}
-		acw.Logger.Info("Successfully registered webhook")
-	case <-stop:
-		return nil
-	}
-
-	serverBootstrapErrCh := make(chan struct{})
-	go func() {
-		if err := server.ListenAndServeTLS("", ""); err != nil {
-			acw.Logger.Error("ListenAndServeTLS for admission webhook returned error", zap.Error(err))
-			close(serverBootstrapErrCh)
-			return
-		}
-		acw.Logger.Info("Successfully started webhook server")
-	}()
-
-	select {
-	case <-stop:
-		return server.Close()
-	case <-serverBootstrapErrCh:
-		return errors.New("webhook server bootstrap failed")
-	}
-}
-
-// BuildWebhookConfiguration builds the APICoverageWebhook object using the provided names.
-func BuildWebhookConfiguration(componentCommonName string, webhookName string, namespace string) *APICoverageWebhook {
-	cm, err := configmap.Load("/etc/config-logging")
-	if err != nil {
-		log.Fatalf("Error loading logging configuration: %v", err)
-	}
-
-	config, err := logging.NewConfigFromMap(cm)
-	if err != nil {
-		log.Fatalf("Error parsing logging configuration: %v", err)
-	}
-	logger, _ := logging.NewLoggerFromConfig(config, "webhook")
-
-	clusterConfig, err := rest.InClusterConfig()
-	if err != nil {
-		log.Fatalf("Failed to get in cluster config: %v", err)
-	}
-
-	kubeClient, err := kubernetes.NewForConfig(clusterConfig)
-	if err != nil {
-		log.Fatalf("Failed to get client set: %v", err)
-	}
-
-	return &APICoverageWebhook{
-		Logger:            logger,
-		KubeClient:        kubeClient,
-		FailurePolicy:     admissionregistrationv1beta1.Fail,
-		ClientAuth:        tls.NoClientCert,
-		RegistrationDelay: time.Second * 2,
-		Port:              8443, // Using port greater than 1024 as webhook runs as non-root user.
-		Namespace:         namespace,
-		DeploymentName:    componentCommonName,
-		ServiceName:       componentCommonName,
-		WebhookName:       webhookName,
-	}
-}
diff --git a/websocket/connection_test.go b/websocket/connection_test.go
index 69a674fe6..b98510187 100644
--- a/websocket/connection_test.go
+++ b/websocket/connection_test.go
@@ -419,16 +419,43 @@ func TestDurableConnectionSendsPingsRegularly(t *testing.T) {
 	}
 }
 
-func TestIsEstablished(t *testing.T) {
-	c := &ManagedConnection{}
-	if got, want := c.IsEstablished(), false; got != want {
-		t.Errorf("IsEstablished() = %v, want = %v", got, want)
+func TestNewDurableSendingConnectionGuaranteed(t *testing.T) {
+	// Unhappy case.
+	logger := ktesting.TestLogger(t)
+	_, err := NewDurableSendingConnectionGuaranteed("ws://somewhere.not.exist", time.Second, logger)
+	if got, want := err.Error(), ErrConnectionNotEstablished.Error(); got != want {
+		t.Errorf("Got error: %v, want error: %v", got, want)
 	}
 
-	c.connection = &inspectableConnection{
-		writeMessageCalls: make(chan struct{}, 1),
+	// Happy case.
+	const testPayload = "test"
+	reconnectChan := make(chan struct{})
+	upgrader := websocket.Upgrader{}
+	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		c, err := upgrader.Upgrade(w, r, nil)
+		if err != nil {
+			return
+		}
+
+		// Waits for a message to be sent before dropping the connection.
+		<-reconnectChan
+		c.Close()
+	}))
+	defer s.Close()
+
+	target := "ws" + strings.TrimPrefix(s.URL, "http")
+	conn, err := NewDurableSendingConnectionGuaranteed(target, time.Second, logger)
+	if err != nil {
+		t.Errorf("Got error from NewDurableSendingConnectionGuaranteed: %v", err)
 	}
-	if got, want := c.IsEstablished(), true; got != want {
-		t.Errorf("IsEstablished() = %v, want = %v", got, want)
+	defer conn.Shutdown()
+
+	// Sending the message immediately should be fine as the connection has been established.
+	if err := conn.Send(testPayload); err != nil {
+		t.Errorf("Failed to send a message: %v", err)
 	}
+
+	// Message successfully sent, instruct the server to drop the connection.
+	reconnectChan <- struct{}{}
+
 }