You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ki...@apache.org on 2022/03/01 00:58:31 UTC

[trafficserver-ingress-controller] branch master updated: Project update for k8s 1.22 (#106)

This is an automated email from the ASF dual-hosted git repository.

kichan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver-ingress-controller.git


The following commit(s) were added to refs/heads/master by this push:
     new b3f8bb3  Project update for k8s 1.22 (#106)
b3f8bb3 is described below

commit b3f8bb35a580c5eeb99d5ca1999986c8fcff91dd
Author: Kit Chan <ki...@apache.org>
AuthorDate: Mon Feb 28 16:58:23 2022 -0800

    Project update for k8s 1.22 (#106)
    
    * remove use of beta API
    
    * Update tests for removing use of beta API
    
    * Use v1.18+ ingress class name and fix compile warning
    
    * Update controller for k8s upgrade
    
    * update lua script for exact path type match
    
    * Improve logging
    
    * update lua script
    
    * Update documents
---
 docs/TUTORIAL.md                                   |  25 +-
 go.mod                                             |   8 +-
 go.sum                                             | 289 +++++++++++++++++++++
 k8s/configmaps/fluentd-configmap.yaml              |   7 +-
 k8s/ingresses/ats-ingress-2.yaml                   |   9 +-
 k8s/ingresses/ats-ingress-2s.yaml                  |   9 +-
 k8s/ingresses/ats-ingress.yaml                     |  25 +-
 k8s/prometheus/ats-stats.yaml                      |   2 +-
 k8s/traffic-server/ats-deployment.yaml             |   2 +-
 k8s/traffic-server/ats-rbac.yaml                   |   4 +-
 main/main.go                                       |   6 +-
 pluginats/connect_redis.lua                        | 147 ++++++++---
 pluginats/connect_redis_test.lua                   |   6 +-
 tests/data/ats-ingress-add.yaml                    |  23 +-
 tests/data/ats-ingress-delete.yaml                 |  16 +-
 tests/data/ats-ingress-snippet.yaml                |   9 +-
 tests/data/ats-ingress-update.yaml                 |  23 +-
 tests/data/setup/configmaps/fluentd-configmap.yaml |   5 +-
 tests/data/setup/ingresses/ats-ingress-2.yaml      |   9 +-
 tests/data/setup/ingresses/ats-ingress-2s.yaml     |   9 +-
 tests/data/setup/ingresses/ats-ingress.yaml        |  23 +-
 .../data/setup/traffic-server/ats-deployment.yaml  |   2 +-
 tests/data/setup/traffic-server/ats-rbac.yaml      |   4 +-
 util/util.go                                       |  26 +-
 watcher/handlerConfigmap.go                        |   1 -
 watcher/handlerEndpoint.go                         |  12 +-
 watcher/handlerIngress.go                          | 243 +++++++++++++----
 watcher/handlerIngress_test.go                     | 116 +++++----
 watcher/watcher.go                                 |  20 +-
 watcher/watcher_test.go                            |   6 +-
 30 files changed, 848 insertions(+), 238 deletions(-)

diff --git a/docs/TUTORIAL.md b/docs/TUTORIAL.md
index d70bf4d..9ac77d3 100644
--- a/docs/TUTORIAL.md
+++ b/docs/TUTORIAL.md
@@ -37,7 +37,7 @@
 
 ### Requirements
 - Docker 
-- (Tested on) Kubernetes 1.21.4 (through Minikube 1.23.0)
+- (Tested on) Kubernetes 1.22.* (through Minikube 1.23.0)
 
 To install Docker, visit its [official page](https://docs.docker.com/) and install the correct version for your system.
 
@@ -58,7 +58,7 @@ Once you have cloned the project repo and started Docker and Minikube, in the te
 5. `$ docker build -t ats-ingress-exporter k8s/images/trafficserver_exporter/` 
 6. `$ docker build -t node-app-1 k8s/images/node-app-1/`    
 7. `$ docker build -t node-app-2 k8s/images/node-app-2/`
-8. `$ docker pull fluent/fluentd:v1.6-debian-1`
+8. `$ docker pull fluent/fluentd:v1.14-debian-1`
 
 - At this point, we have created necessary images for our example:
   - Step 4 builds an image to create a Docker container that will contain the Apache Traffic Server (ATS) itself, the kubernetes ingress controller, along with other software required for the controller to do its job.
@@ -66,7 +66,7 @@ Once you have cloned the project repo and started Docker and Minikube, in the te
   - Steps 6 and 7 build 2 images that will serve as backends to [kubernetes services](https://kubernetes.io/docs/concepts/services-networking/service/) which we will shortly create
   - Step 8 builds an image for fluentd. This is for log collection.
 
-9. `$ kubectl create namespace trafficserver-test`
+9. `$ kubectl apply -f k8s/traffic-server/ats-ns.yaml`
 10. `$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=atssvc/O=atssvc"`
 11. `$ kubectl create secret tls tls-secret --key tls.key --cert tls.crt -n trafficserver-test --dry-run=client -o yaml | kubectl apply -f -`
 12. `$ kubectl apply -f k8s/configmaps/fluentd-configmap.yaml`
@@ -107,11 +107,6 @@ ATS proxying should have started to work. To see proxy in action, we can use [cu
 
 You may have problem with minikube using docker driver as localhost (i.e. 127.0.0.1) will be used as the cluster ip. So you will need to forward the traffic designated for the port to the ports of the ATS pods inside the cluster before the above curl commands will work. Each command below needs to be run in separate terminal. 
 
-- `$ kubectl port-forward <pod name> 30443:8443 -n trafficserver-test`
-- `$ kubectl port-forward <pod name> 30080:8080 -n trafficserver-test`
-
-You may also use the following to fetch the Pod name automatically.
-
 - `$ kubectl port-forward $(kubectl -n trafficserver-test get pods -l=app="trafficserver-test" -o name) 30443:8443 -n trafficserver-test`
 - `$ kubectl port-forward $(kubectl -n trafficserver-test get pods -l=app="trafficserver-test" -o name) 30080:8080 -n trafficserver-test`
 
@@ -128,7 +123,7 @@ Below is an example of configuring Apache Traffic Server [_reloadable_ configura
 
 #### Namespaces for Ingresses
 
-You can specifiy the list of namespaces to look for ingress object by providing `INGRESS_NS`. The default is `all`, which tells the controller to look for ingress objects in all namespaces. Alternatively you can provide a comma-separated list of namespaces for the controller to look for ingresses. Similarly you can specifiy a comma-separated list of namespaces to ignore while the controller is looking for ingresses by providing `INGRESS_IGNORE_NS`. 
+You can specifiy the list of namespaces to look for ingress object by providing an environment variable called `INGRESS_NS`. The default is `all`, which tells the controller to look for ingress objects in all namespaces. Alternatively you can provide a comma-separated list of namespaces for the controller to look for ingresses. Similarly you can specifiy a comma-separated list of namespaces to ignore while the controller is looking for ingresses by providing `INGRESS_IGNORE_NS`.
 
 #### Snippet
 
@@ -136,11 +131,12 @@ You can attach [ATS lua script](https://docs.trafficserver.apache.org/en/8.0.x/a
 
 #### Ingress Class
 
-You can provide an environment variable called `INGRESS_CLASS` in the deployment to specify the ingress class. See an example commented out [here](../k8s/trafficserver/ats-deployment.yaml). Only ingress object with annotation `kubernetes.io/ingress.class` with value equal to the environment variable value will be used by ATS for routing
+You can provide an environment variable called `INGRESS_CLASS` in the deployment to specify the ingress class. See an example commented out [here](../k8s/traffic-server/ats-deployment.yaml). Only ingress object with parameter `ingressClassName` in `spec` section with value equal to the environment variable value will be used by ATS for routing
 
 #### Customizing Logging and TLS
 
-You can specify a different [logging.yaml](https://docs.trafficserver.apache.org/en/8.1.x/admin-guide/files/logging.yaml.en.html) and [ssl_server_name.yaml](https://docs.trafficserver.apache.org/en/8.1.x/admin-guide/files/ssl_server_name.yaml.en.html) by providing environment variable `LOG_CONFIG_FNAME` and `SSL_SERVER_FNAME` respsectively. See an example commented out [here](../k8s/traffici-server/ats-deployment.yaml). The new contents of them can be provided through a ConfigMap and loa [...]
+You can specify a different
+[logging.yaml](https://docs.trafficserver.apache.org/en/8.1.x/admin-guide/files/logging.yaml.en.html) and [ssl_server_name.yaml](https://docs.trafficserver.apache.org/en/8.1.x/admin-guide/files/ssl_server_name.yaml.en.html) by providing environment variable `LOG_CONFIG_FNAME` and `SSL_SERVER_FNAME` respsectively. See an example commented out [here](../k8s/traffic-server/ats-deployment.yaml). The new contents of them can be provided through a ConfigMap and loaded to a volume mounted for t [...]
 
 #### Customizing Plugins
 
@@ -152,7 +148,12 @@ You can specify extra plugins for [plugin.config](https://docs.trafficserver.apa
 
 The above tutorial is already integrated with [Fluentd](https://docs.fluentd.org/). The configuration file used for the same can be found [here](../k8s/configmaps/fluentd-configmap.yaml)
 
-As can be seen from the default configuration file, Fluentd reads the Apache Traffic Server access logs located at `/opt/ats/var/log/trafficserver/squid.log` and outputs them to `stdout`. The ouput plugin for Fluentd can be changed to send the logs to any desired location supported by Fluentd including Elasticsearch, Kafka, MongoDB etc. You can read more about output plugins [here](https://docs.fluentd.org/output). 
+As can be seen from the default configuration file, Fluentd reads the Apache Traffic Server access logs located at
+`/opt/ats/var/log/trafficserver/squid.log` and outputs them to `stdout`. Use `kubectl logs` to check the logs
+
+- `kubectl logs $(kubectl -n trafficserver-test get pods -l=app="trafficserver-test" -o name) -n trafficserver-test -c log-collector`
+
+The ouput plugin for Fluentd can be changed to send the logs to any desired location supported by Fluentd including Elasticsearch, Kafka, MongoDB etc. You can read more about output plugins [here](https://docs.fluentd.org/output).
 
 #### Prometheus and Grafana
 
diff --git a/go.mod b/go.mod
index 1ee648c..119df47 100644
--- a/go.mod
+++ b/go.mod
@@ -4,8 +4,10 @@ go 1.15
 
 require (
 	github.com/alicebob/miniredis/v2 v2.13.0
+	github.com/evanphx/json-patch v4.9.0+incompatible // indirect
 	github.com/go-redis/redis v6.15.2+incompatible
-	k8s.io/api v0.18.10
-	k8s.io/apimachinery v0.18.10
-	k8s.io/client-go v0.18.10
+	k8s.io/api v0.21.9
+	k8s.io/apimachinery v0.21.9
+	k8s.io/client-go v0.21.9
+	sigs.k8s.io/yaml v1.2.0 // indirect
 )
diff --git a/go.sum b/go.sum
index 269f011..0a63064 100644
--- a/go.sum
+++ b/go.sum
@@ -1,25 +1,58 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
+cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
+cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
+cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
+cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
+cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
+cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
+cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
+cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
+cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
+cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
+cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
+cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
+cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
 github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
+github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
 github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
+github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
 github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
+github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
 github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
 github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
 github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
+github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
 github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
+github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
 github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
 github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
 github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
 github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
 github.com/alicebob/miniredis/v2 v2.13.0 h1:QPosMaxm+r6Qs+YcCtL2Z2a2RSdC9VfXJLpd80l8ICU=
 github.com/alicebob/miniredis/v2 v2.13.0/go.mod h1:0UIBNuf97uxrWhdVBpJvPtafKyGpL2NS2pYe0tYM97k=
+github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -27,31 +60,60 @@ github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9r
 github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
+github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
 github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
 github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
 github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
+github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
+github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
 github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
+github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
+github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
 github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
+github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
+github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
 github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
+github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
 github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
+github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
 github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
 github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
 github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
 github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8=
 github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
+github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
 github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/gomodule/redigo v1.8.1 h1:Abmo0bI7Xf0IhdIPc7HZQzZcShdnmxeoVuDDtIQp8N8=
 github.com/gomodule/redigo v1.8.1/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -59,19 +121,33 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
 github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
 github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI=
 github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
+github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I=
+github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
 github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
 github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -79,21 +155,33 @@ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
 github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
 github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -102,6 +190,7 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
@@ -112,28 +201,72 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb h1:ZkM6LRnq40pR1Ox0hTHlnpkcOTuFIDQpZ1IN8rKKhX0=
 github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
+go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
 golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
+golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
+golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -142,52 +275,181 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
 golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY=
+golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
+golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU=
 golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs=
+golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
+golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
+golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
+google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
+google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
@@ -199,26 +461,53 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 k8s.io/api v0.18.10 h1:M0/vqfuBAIIS7jsOOcosT0niiotZGqw6/zHTFpyi8iQ=
 k8s.io/api v0.18.10/go.mod h1:xWtwPX1v47j5RTncmlMFGCx8b0avh+nP8OgZZ9hjo3M=
+k8s.io/api v0.21.9 h1:dgxM5d8/kLw0mz7JmyixJk3I84JT2B52Yz8p0lTMFes=
+k8s.io/api v0.21.9/go.mod h1:jyTBdRcQnzZodHyJdeDEqVcxkaqJAgjrRx30EysE1Ik=
 k8s.io/apimachinery v0.18.10 h1:Zupk3lPrUfhCF9puTpA8EvEfPsrhNZtrpOqdp66mKVs=
 k8s.io/apimachinery v0.18.10/go.mod h1:PF5taHbXgTEJLU+xMypMmYTXTWPJ5LaW8bfsisxnEXk=
+k8s.io/apimachinery v0.21.9 h1:8WffZaaNB2ft5wOiFPktkZRZQxMoTxwVrITC73SJ1V8=
+k8s.io/apimachinery v0.21.9/go.mod h1:USs+ifLG6ZUgHGA/9lGxjdHzCB3hUO3fG1VBOwi0IHo=
 k8s.io/client-go v0.18.10 h1:fETWvjTtnE3/s+h0SYr2wvlKWFDF+NrhwAL/ddqVa2Q=
 k8s.io/client-go v0.18.10/go.mod h1:XBkFAqPrzqfwmGkV5ac+mlgBpWcz5TkhLw2808q8C3c=
+k8s.io/client-go v0.21.9 h1:GexEazmr/ulHLNBKDE/pc2WTbZ0JLUJLv05Va9kE/B0=
+k8s.io/client-go v0.21.9/go.mod h1:uMq9B14yobLb20bDZ1xVrXUpPbDCeWEjJfGeTt2n0/Q=
 k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
+k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
 k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
 k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
 k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
 k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
+k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
+k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
+k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
 k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY=
 k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
+k8s.io/kube-openapi v0.0.0-20211110012726-3cc51fd1e909 h1:s77MRc/+/eQjsF89MB12JssAlsoi9mnNoaacRqibeAU=
+k8s.io/kube-openapi v0.0.0-20211110012726-3cc51fd1e909/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
 k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU=
 k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
+k8s.io/utils v0.0.0-20210521133846-da695404a2bc h1:dx6VGe+PnOW/kD/2UV4aUSsRfJGd7+lcqgJ6Xg0HwUs=
+k8s.io/utils v0.0.0-20210521133846-da695404a2bc/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
+rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
 sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
 sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E=
 sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
+sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
+sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
+sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
 sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
 sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
 sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
diff --git a/k8s/configmaps/fluentd-configmap.yaml b/k8s/configmaps/fluentd-configmap.yaml
index 35d9202..e83b100 100644
--- a/k8s/configmaps/fluentd-configmap.yaml
+++ b/k8s/configmaps/fluentd-configmap.yaml
@@ -22,7 +22,7 @@ metadata:
 data:
   fluent.conf: |
     <source>
-      type tail
+      @type tail
       path /var/log/trafficserver/squid.log
       pos_file /var/log/trafficserver/squid.log.pos
       <parse>
@@ -33,7 +33,7 @@ data:
     </source>
 
     <source>
-      type tail
+      @type tail
       path /var/log/ingress/ingress_ats.err
       pos_file /var/log/ingress/ingress_ats.err.pos
       <parse>
@@ -47,6 +47,3 @@ data:
       @type stdout
     </match>
 
-    <match fluent.**>
-      @type null
-    </match>
\ No newline at end of file
diff --git a/k8s/ingresses/ats-ingress-2.yaml b/k8s/ingresses/ats-ingress-2.yaml
index e9abdfc..43fbdde 100644
--- a/k8s/ingresses/ats-ingress-2.yaml
+++ b/k8s/ingresses/ats-ingress-2.yaml
@@ -21,7 +21,7 @@ metadata:
 
 ---
 
-apiVersion: extensions/v1beta1
+apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: app-ingress
@@ -42,6 +42,9 @@ spec:
     http:
       paths:
       - path: /app2
+        pathType: Exact
         backend:
-          serviceName: appsvc2
-          servicePort: 8080
+          service:
+            name: appsvc2
+            port:
+              number: 8080
diff --git a/k8s/ingresses/ats-ingress-2s.yaml b/k8s/ingresses/ats-ingress-2s.yaml
index 8396ea9..108ddf1 100644
--- a/k8s/ingresses/ats-ingress-2s.yaml
+++ b/k8s/ingresses/ats-ingress-2s.yaml
@@ -21,7 +21,7 @@ metadata:
 
 ---
 
-apiVersion: extensions/v1beta1
+apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: app-ingress-https
@@ -35,6 +35,9 @@ spec:
     http:
       paths:
       - path: /app2
+        pathType: Exact
         backend:
-          serviceName: appsvc2
-          servicePort: 8080
+          service:
+            name: appsvc2
+            port:
+              number: 8080
diff --git a/k8s/ingresses/ats-ingress.yaml b/k8s/ingresses/ats-ingress.yaml
index bddf63b..d91c4dc 100644
--- a/k8s/ingresses/ats-ingress.yaml
+++ b/k8s/ingresses/ats-ingress.yaml
@@ -21,7 +21,7 @@ metadata:
 
 ---
 
-apiVersion: extensions/v1beta1
+apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: app-ingress
@@ -32,19 +32,28 @@ spec:
     http:
       paths:
       - path: /app1
+        pathType: Exact
         backend:
-          serviceName: appsvc1
-          servicePort: 8080
+          service:
+            name: appsvc1
+            port:
+              number: 8080
       - path: /app2
+        pathType: Exact
         backend:
-          serviceName: appsvc2
-          servicePort: 8080
+          service:
+            name: appsvc2
+            port:
+              number: 8080
 
   - host: test.edge.com
     http:
       paths:
       - path: /app1
+        pathType: Exact
         backend:
-          serviceName: appsvc1
-          servicePort: 8080
-          
+          service:
+            name: appsvc1
+            port:
+              number: 8080
+ 
diff --git a/k8s/prometheus/ats-stats.yaml b/k8s/prometheus/ats-stats.yaml
index 751e2a6..41869cd 100644
--- a/k8s/prometheus/ats-stats.yaml
+++ b/k8s/prometheus/ats-stats.yaml
@@ -25,4 +25,4 @@ spec:
   - port: 80
     targetPort: 9122
   selector:
-    app: trafficserver-test
\ No newline at end of file
+    app: trafficserver-test
diff --git a/k8s/traffic-server/ats-deployment.yaml b/k8s/traffic-server/ats-deployment.yaml
index 9f12438..7749f4f 100644
--- a/k8s/traffic-server/ats-deployment.yaml
+++ b/k8s/traffic-server/ats-deployment.yaml
@@ -83,7 +83,7 @@ spec:
             name: https
             protocol: TCP
         - name: log-collector
-          image: fluent/fluentd:v1.6-debian-1
+          image: fluent/fluentd:v1.14-debian-1
           volumeMounts:
           - name: log-trafficserver
             mountPath: "/var/log/trafficserver"
diff --git a/k8s/traffic-server/ats-rbac.yaml b/k8s/traffic-server/ats-rbac.yaml
index bb04ba2..f2c222e 100644
--- a/k8s/traffic-server/ats-rbac.yaml
+++ b/k8s/traffic-server/ats-rbac.yaml
@@ -22,7 +22,7 @@ metadata:
 
 ---
 
-apiVersion: rbac.authorization.k8s.io/v1beta1
+apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRole
 metadata:
   name: trafficserver-test
@@ -45,7 +45,7 @@ rules:
 
 ---
 
-apiVersion: rbac.authorization.k8s.io/v1beta1
+apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
   name: trafficserver-test
diff --git a/main/main.go b/main/main.go
index 4d5fdb7..614449c 100644
--- a/main/main.go
+++ b/main/main.go
@@ -30,7 +30,7 @@ import (
 
 	_ "k8s.io/client-go/util/workqueue"
 
-	_ "k8s.io/api/extensions/v1beta1"
+	_ "k8s.io/api/networking/v1"
 
 	ep "ingress-ats/endpoint"
 	"ingress-ats/namespace"
@@ -120,7 +120,7 @@ func main() {
 	/* creates the clientset */
 	clientset, err := kubernetes.NewForConfig(config)
 	if err != nil {
-		log.Panic(err.Error())
+		log.Panicln(err.Error())
 	}
 
 	stopChan := make(chan struct{})
@@ -139,8 +139,6 @@ func main() {
 		log.Panicln("Redis Error: ", err)
 	}
 
-	// IMPORTANT:
-	// We're assuming ingress must be using EXTENSIONS V1BETA1 API
 	// ALL services must be using CORE V1 API
 	endpoint := ep.Endpoint{
 		RedisClient: rClient,
diff --git a/pluginats/connect_redis.lua b/pluginats/connect_redis.lua
index da90994..0888bc3 100644
--- a/pluginats/connect_redis.lua
+++ b/pluginats/connect_redis.lua
@@ -33,6 +33,68 @@ function ipport_split(s, delimiter)
   return result
 end
 
+function check_path_exact_match(req_scheme, req_host, req_path)
+  local host_path = "E+"..req_scheme .. "://" .. req_host .. req_path
+  ts.debug('checking host_path: '..host_path)
+  client:select(1) -- go with hostpath table first
+  return client:smembers(host_path) -- redis blocking call
+end
+
+function check_path_prefix_match(req_scheme, req_host, req_path)
+  local host_path = "P+"..req_scheme .. "://" .. req_host .. req_path
+  ts.debug('checking host_path: '..host_path)
+  client:select(1)
+  local svcs = client:smembers(host_path) -- redis blocking call
+
+  if (svcs ~= nil and #svcs > 0) then
+    return svcs
+  end
+
+  -- finding location of / in request path
+  local t = {}                   -- table to store the indices
+  local i = 0
+  while true do
+    i = string.find(req_path, "%/", i+1)    -- find 'next' dir
+    if i == nil then break end
+    table.insert(t, i)
+  end
+
+  for index = #t, 1, -1 do
+    local pathindex = t[index]
+    local subpath = string.sub (req_path, 1, pathindex)
+
+    host_path = "P+"..req_scheme .. "://" .. req_host .. subpath
+    ts.debug('checking host_path: '..host_path)
+    client:select(1)
+    svcs =client:smembers(host_path) -- redis blocking call
+    if (svcs ~= nil and #svcs > 0) then
+      return svcs
+    end
+
+    if pathindex > 1 then
+      subpath = string.sub (req_path, 1, pathindex - 1)
+
+      host_path = "P+"..req_scheme .. "://" .. req_host .. subpath
+      ts.debug('checking host_path: '..host_path)
+      client:select(1)
+      svcs = client:smembers(host_path) -- redis blocking call
+      if (svcs ~= nil and #svcs > 0) then
+        return svcs
+      end
+    end
+  end
+
+  return nil
+end
+
+function get_wildcard_domain(req_host)
+  local pos = string.find( req_host, '%.' )
+  if pos == nil then
+    return nil
+  end
+  return "*" .. string.sub (req_host, pos)
+end
+
 ---------------------------------------------
 ----------------- DO_REMAP ------------------
 ---------------------------------------------
@@ -41,7 +103,7 @@ function do_global_read_request()
   local response = client:ping()
 
   -- if cannot connect to redis client, terminate early
-  if not response then 
+  if not response then
     ts.debug("In 'not response: '", response)
     return 0
   end
@@ -51,28 +113,54 @@ function do_global_read_request()
   local req_host = ts.client_request.get_url_host() or ''
   local req_path = ts.client_request.get_uri() or ''
   local req_port = ts.client_request.get_url_port() or ''
+
+  local wildcard_req_host = get_wildcard_domain(req_host)
   ts.debug("-----Request-----")
   ts.debug("req_scheme: "..req_scheme)
   ts.debug("req_host: " .. req_host)
   ts.debug("req_port: " .. req_port)
   ts.debug("req_path: " .. req_path)
+  ts.debug("wildcard_req_host: " .. (wildcard_req_host or 'invalid domain name'))
   ts.debug("-----------------")
 
-  local host_path = req_scheme .. "://" .. req_host .. req_path
-  
-  client:select(1) -- go with hostpath table first
-  local svcs = client:smembers(host_path) -- redis blocking call
-  -- host/path not in redis DB
-  if svcs == nil then
+  -- check for path exact match
+  local svcs = check_path_exact_match(req_scheme, req_host, req_path)
+
+  if (svcs == nil or #svcs == 0) then
+    -- check for path prefix match
+    svcs = check_path_prefix_match(req_scheme, req_host, req_path)
+  end
+
+  if (svcs == nil or #svcs == 0) and wildcard_req_host ~= nil then
+    -- check for path exact match with wildcard domain name in prefix
+    svcs = check_path_exact_match(req_scheme, wildcard_req_host, req_path)
+  end
+
+  if (svcs == nil or #svcs == 0) and wildcard_req_host ~= nil then
+    -- check for path prefix match with wildcard domain name in prefix
+    svcs = check_path_prefix_match(req_scheme, wildcard_req_host, req_path)
+  end
+
+  if (svcs == nil or #svcs == 0) then
+    -- check for path exact match with wildcard domain name
+    svcs = check_path_exact_match(req_scheme, '*', req_path)
+  end
+
+  if (svcs == nil or #svcs == 0) then
+    -- check for path prefix match with wildcard domain name
+    svcs = check_path_prefix_match(req_scheme, '*', req_path)
+  end
+
+  if (svcs == nil or #svcs == 0) then
     ts.error("Redis Lookup Failure: svcs == nil for hostpath")
-    return 0 
+    return 0
   end
 
   for _, svc in ipairs(svcs) do
     if svc == nil then
       ts.error("Redis Lookup Failure: svc == nil for hostpath")
       return 0
-    end 
+    end
     if string.sub(svc, 1, 1) ~= "$" then
       ts.debug("routing")
       client:select(0) -- go with svc table second
@@ -95,33 +183,34 @@ function do_global_read_request()
       ts.client_request.set_uri(req_path)
       ts.client_request.set_url_host(values[1])
       ts.client_request.set_url_port(values[2])
-    end 
+    end
   end
 
-  for _, svc in ipairs(svcs) do               
+  for _, svc in ipairs(svcs) do
     if svc == nil then
-      ts.error("Redis Lookup Failure: svc == nil for hostpath")        
-      return 0                                                       
-    end                                                                     
-    if string.sub(svc, 1, 1) == "$" then                               
-      ts.debug("snippet")                    
-      client:select(1)           
-      local snippets = client:smembers(svc)        
-                                
+      ts.error("Redis Lookup Failure: svc == nil for hostpath")
+      return 0
+    end
+    if string.sub(svc, 1, 1) == "$" then
+      ts.debug("snippet")
+      client:select(1)
+      local snippets = client:smembers(svc)
+
       if snippets == nil then
         ts.error("Redis Lookup Failure: snippets == nil for hostpath")
-        return 0      
-      end                                    
-            
+        return 0
+      end
+
       local snippet = snippets[1]
       if snippet == nil then
         ts.error("Redis Lookup Failure: snippet == nil for hostpath")
-        return 0                                                 
-      end                                                
-                                                    
-      local f = loadstring(snippet)                      
-      f()                      
-    end                               
-  end                               
+        return 0
+      end
+
+      local f = loadstring(snippet)
+      f()
+    end
+  end
 
 end
+
diff --git a/pluginats/connect_redis_test.lua b/pluginats/connect_redis_test.lua
index 008479f..d142beb 100644
--- a/pluginats/connect_redis_test.lua
+++ b/pluginats/connect_redis_test.lua
@@ -108,7 +108,7 @@ describe("Unit tests - Lua", function()
       client = redis.connect()
 
       client:select(1)
-      client:sadd("http://test.edge.com/app1","trafficserver-test-2:appsvc1:8080")
+      client:sadd("E+http://test.edge.com/app1","trafficserver-test-2:appsvc1:8080")
       client:select(0)
       client:sadd("trafficserver-test-2:appsvc1:8080","172.17.0.3#8080#http","172.17.0.5#8080#http")
       --require 'pl.pretty'.dump(client)
@@ -136,7 +136,7 @@ describe("Unit tests - Lua", function()
 
     it("Test - Snippet", function()
       client:select(1)
-      client:sadd("http://test.edge.com/app1","$trafficserver-test-3/app-ingress/411990")
+      client:sadd("E+http://test.edge.com/app1","$trafficserver-test-3/app-ingress/411990")
       snippet = "ts.debug('Debug msg example')\nts.error('Error msg example')\n-- ts.hook(TS_LUA_HOOK_SEND_RESPONSE_HDR, function()\n--   ts.client_response.header['Location'] = 'https://test.edge.com/app2'\n-- end)\nts.http.skip_remapping_set(0)\nts.http.set_resp(301, 'Redirect')\nts.debug('Uncomment the above lines to redirect http request to https')\nts.debug('Modification for testing')\n"
       client:sadd("$trafficserver-test-3/app-ingress/411990",snippet) 
 
@@ -150,4 +150,4 @@ describe("Unit tests - Lua", function()
     end)
 
   end)
-end)
\ No newline at end of file
+end)
diff --git a/tests/data/ats-ingress-add.yaml b/tests/data/ats-ingress-add.yaml
index 56bf49d..4474e51 100644
--- a/tests/data/ats-ingress-add.yaml
+++ b/tests/data/ats-ingress-add.yaml
@@ -13,7 +13,7 @@
 #  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.
-apiVersion: extensions/v1beta1
+apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: app-ingress
@@ -24,19 +24,28 @@ spec:
     http:
       paths:
       - path: /app1
+        pathType: Exact
         backend:
-          serviceName: appsvc1
-          servicePort: 8080
+          service:
+            name: appsvc1
+            port:
+              number: 8080
       - path: /test
+        pathType: Exact
         backend:
-          serviceName: appsvc1
-          servicePort: 8080
+          service:
+            name: appsvc1
+            port:
+              number: 8080
                     
   - host: test.edge.com
     http:
       paths:
       - path: /app1
+        pathType: Exact
         backend:
-          serviceName: appsvc1
-          servicePort: 8080
+          service:
+            name: appsvc1
+            port:
+              number: 8080
           
diff --git a/tests/data/ats-ingress-delete.yaml b/tests/data/ats-ingress-delete.yaml
index 9bc9546..7570f38 100644
--- a/tests/data/ats-ingress-delete.yaml
+++ b/tests/data/ats-ingress-delete.yaml
@@ -13,7 +13,7 @@
 #  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.
-apiVersion: extensions/v1beta1
+apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: app-ingress
@@ -24,15 +24,21 @@ spec:
     http:
       paths:
       - path: /app1
+        pathType: Exact
         backend:
-          serviceName: appsvc1
-          servicePort: 8080
+          service:
+            name: appsvc1
+            port:
+              number: 8080
                     
   - host: test.edge.com
     http:
       paths:
       - path: /app1
+        pathType: Exact
         backend:
-          serviceName: appsvc1
-          servicePort: 8080
+          service:
+            name: appsvc1
+            port:
+              number: 8080
           
diff --git a/tests/data/ats-ingress-snippet.yaml b/tests/data/ats-ingress-snippet.yaml
index fd348c5..5695c2c 100644
--- a/tests/data/ats-ingress-snippet.yaml
+++ b/tests/data/ats-ingress-snippet.yaml
@@ -13,7 +13,7 @@
 #  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.
-apiVersion: extensions/v1beta1
+apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: app-ingress
@@ -31,6 +31,9 @@ spec:
     http:
       paths:
       - path: /app2
+        pathType: Exact
         backend:
-          serviceName: appsvc2
-          servicePort: 8080
\ No newline at end of file
+          service:
+            name: appsvc2
+            port:
+              number: 8080
diff --git a/tests/data/ats-ingress-update.yaml b/tests/data/ats-ingress-update.yaml
index 3737c4b..205fed4 100644
--- a/tests/data/ats-ingress-update.yaml
+++ b/tests/data/ats-ingress-update.yaml
@@ -13,7 +13,7 @@
 #  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.
-apiVersion: extensions/v1beta1
+apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: app-ingress
@@ -24,19 +24,28 @@ spec:
     http:
       paths:
       - path: /app1
+        pathType: Exact
         backend:
-          serviceName: appsvc1
-          servicePort: 8080
+          service:
+            name: appsvc1
+            port:
+              number: 8080
       - path: /app2
+        pathType: Exact
         backend:
-          serviceName: appsvc1
-          servicePort: 8080
+          service:
+            name: appsvc1
+            port:
+              number: 8080
           
   - host: test.edge.com
     http:
       paths:
       - path: /app1
+        pathType: Exact
         backend:
-          serviceName: appsvc1
-          servicePort: 8080
+          service:
+            name: appsvc1
+            port:
+              number: 8080
           
diff --git a/tests/data/setup/configmaps/fluentd-configmap.yaml b/tests/data/setup/configmaps/fluentd-configmap.yaml
index f42bbb7..0d26e14 100644
--- a/tests/data/setup/configmaps/fluentd-configmap.yaml
+++ b/tests/data/setup/configmaps/fluentd-configmap.yaml
@@ -22,7 +22,7 @@ metadata:
 data:
   fluent.conf: |
     <source>
-      type tail
+      @type tail
       path /var/log/squid.log
       pos_file /var/log/squid.log.pos
       <parse>
@@ -36,6 +36,3 @@ data:
       @type stdout
     </match>
 
-    <match fluent.**>
-      @type null
-    </match>
\ No newline at end of file
diff --git a/tests/data/setup/ingresses/ats-ingress-2.yaml b/tests/data/setup/ingresses/ats-ingress-2.yaml
index e9abdfc..43fbdde 100644
--- a/tests/data/setup/ingresses/ats-ingress-2.yaml
+++ b/tests/data/setup/ingresses/ats-ingress-2.yaml
@@ -21,7 +21,7 @@ metadata:
 
 ---
 
-apiVersion: extensions/v1beta1
+apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: app-ingress
@@ -42,6 +42,9 @@ spec:
     http:
       paths:
       - path: /app2
+        pathType: Exact
         backend:
-          serviceName: appsvc2
-          servicePort: 8080
+          service:
+            name: appsvc2
+            port:
+              number: 8080
diff --git a/tests/data/setup/ingresses/ats-ingress-2s.yaml b/tests/data/setup/ingresses/ats-ingress-2s.yaml
index 8396ea9..108ddf1 100644
--- a/tests/data/setup/ingresses/ats-ingress-2s.yaml
+++ b/tests/data/setup/ingresses/ats-ingress-2s.yaml
@@ -21,7 +21,7 @@ metadata:
 
 ---
 
-apiVersion: extensions/v1beta1
+apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: app-ingress-https
@@ -35,6 +35,9 @@ spec:
     http:
       paths:
       - path: /app2
+        pathType: Exact
         backend:
-          serviceName: appsvc2
-          servicePort: 8080
+          service:
+            name: appsvc2
+            port:
+              number: 8080
diff --git a/tests/data/setup/ingresses/ats-ingress.yaml b/tests/data/setup/ingresses/ats-ingress.yaml
index bddf63b..49ec984 100644
--- a/tests/data/setup/ingresses/ats-ingress.yaml
+++ b/tests/data/setup/ingresses/ats-ingress.yaml
@@ -21,7 +21,7 @@ metadata:
 
 ---
 
-apiVersion: extensions/v1beta1
+apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: app-ingress
@@ -32,19 +32,28 @@ spec:
     http:
       paths:
       - path: /app1
+        pathType: Exact
         backend:
-          serviceName: appsvc1
-          servicePort: 8080
+          service:
+            name: appsvc1
+            port:
+              number: 8080
       - path: /app2
+        pathType: Exact
         backend:
-          serviceName: appsvc2
-          servicePort: 8080
+          service:
+            name: appsvc2
+            port:
+              number: 8080
 
   - host: test.edge.com
     http:
       paths:
       - path: /app1
+        pathType: Exact
         backend:
-          serviceName: appsvc1
-          servicePort: 8080
+          service:
+            name: appsvc1
+            port:
+              number: 8080
           
diff --git a/tests/data/setup/traffic-server/ats-deployment.yaml b/tests/data/setup/traffic-server/ats-deployment.yaml
index 79dd276..e9824ab 100644
--- a/tests/data/setup/traffic-server/ats-deployment.yaml
+++ b/tests/data/setup/traffic-server/ats-deployment.yaml
@@ -75,7 +75,7 @@ spec:
             name: https
             protocol: TCP
         - name: log-collector
-          image: fluent/fluentd:v1.6-debian-1
+          image: fluent/fluentd:v1.14-debian-1
           volumeMounts:
           - name: varlog
             mountPath: "/var/log"
diff --git a/tests/data/setup/traffic-server/ats-rbac.yaml b/tests/data/setup/traffic-server/ats-rbac.yaml
index bb04ba2..f2c222e 100644
--- a/tests/data/setup/traffic-server/ats-rbac.yaml
+++ b/tests/data/setup/traffic-server/ats-rbac.yaml
@@ -22,7 +22,7 @@ metadata:
 
 ---
 
-apiVersion: rbac.authorization.k8s.io/v1beta1
+apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRole
 metadata:
   name: trafficserver-test
@@ -45,7 +45,7 @@ rules:
 
 ---
 
-apiVersion: rbac.authorization.k8s.io/v1beta1
+apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
   name: trafficserver-test
diff --git a/util/util.go b/util/util.go
index 96051aa..d0f6bad 100644
--- a/util/util.go
+++ b/util/util.go
@@ -18,8 +18,11 @@ package util
 import (
 	"encoding/json"
 	"fmt"
+	"log"
 	"os"
 	"sync"
+
+	nv1 "k8s.io/api/networking/v1"
 )
 
 // Writer writes the JSON file synchronously
@@ -95,11 +98,16 @@ func (w *Writer) CreateFileIfNotExist() (file *os.File, err error) {
 }
 
 // ConstructHostPathString constructs the string representation of Host + Path
-func ConstructHostPathString(scheme, host, path string) string {
+func ConstructHostPathString(scheme, host, path string, pathType nv1.PathType) string {
 	if path == "" {
 		path = "/"
 	}
-	return scheme + "://" + host + path
+	// default pathType is "Exact"
+	if pathType == nv1.PathTypePrefix {
+		return "P+" + scheme + "://" + host + path
+	} else {
+		return "E+" + scheme + "://" + host + path
+	}
 	//return p.Clean(fmt.Sprintf("%s/%s", host, path))
 }
 
@@ -145,6 +153,20 @@ func ExtractIngressClass(ann map[string]string) (class string, err error) {
 	return ingress_class, nil
 }
 
+func ExtractIngressClassName(obj interface{}) (class string, err error) {
+	ingressObj, ok := obj.(*nv1.Ingress)
+	if !ok {
+		log.Println("Extracting ingress class name; cannot cast to *nv1.Ingress")
+		return "", fmt.Errorf("Extracting ingress class name; cannot cast to *nv1.Ingress")
+	}
+
+	if ingressObj.Spec.IngressClassName == nil {
+		return "", fmt.Errorf("Extracting ingress class name; missing the field")
+	}
+
+	return *ingressObj.Spec.IngressClassName, nil
+}
+
 // FmtMarshalled converts json marshalled bytes to string
 func FmtMarshalled(marshalled []byte) string {
 	return fmt.Sprintf("%q", marshalled)
diff --git a/watcher/handlerConfigmap.go b/watcher/handlerConfigmap.go
index 0e49cb7..b65bfa3 100644
--- a/watcher/handlerConfigmap.go
+++ b/watcher/handlerConfigmap.go
@@ -68,7 +68,6 @@ func (c *CMHandler) Update(obj, newObj interface{}) {
 // Delete for EventHandler
 func (c *CMHandler) Delete(obj interface{}) {
 	// do not handle delete events for now
-	return
 }
 
 // GetResourceName returns the resource name
diff --git a/watcher/handlerEndpoint.go b/watcher/handlerEndpoint.go
index ed14d69..ead9c8a 100644
--- a/watcher/handlerEndpoint.go
+++ b/watcher/handlerEndpoint.go
@@ -32,7 +32,7 @@ type EpHandler struct {
 }
 
 func (e *EpHandler) Add(obj interface{}) {
-	log.Printf("\n\nIn EndpointHandler ADD %#v \n\n", obj)
+	log.Printf("Endpoint ADD %#v \n", obj)
 	e.add(obj)
 	e.Ep.RedisClient.PrintAllKeys()
 }
@@ -40,7 +40,7 @@ func (e *EpHandler) Add(obj interface{}) {
 func (e *EpHandler) add(obj interface{}) {
 	eps, ok := obj.(*v1.Endpoints)
 	if !ok {
-		log.Println("In EndpointHandler Add; cannot cast to *v1.Endpoints.")
+		log.Println("In Endpoint Add; cannot cast to *v1.Endpoints.")
 		return
 	}
 	podSvcName := eps.GetObjectMeta().GetName()
@@ -67,7 +67,7 @@ func (e *EpHandler) add(obj interface{}) {
 
 // Update for EventHandler
 func (e *EpHandler) Update(obj, newObj interface{}) {
-	log.Printf("\n\nEndpoint Update\n Obj: %#v \n newObj: %#v", obj, newObj)
+	log.Printf("Endpoint Update Obj: %#v , newObj: %#v \n", obj, newObj)
 	e.update(newObj)
 	e.Ep.RedisClient.PrintAllKeys()
 }
@@ -75,7 +75,7 @@ func (e *EpHandler) Update(obj, newObj interface{}) {
 func (e *EpHandler) update(obj interface{}) {
 	eps, ok := obj.(*v1.Endpoints)
 	if !ok {
-		log.Println("In EndpointHandler Add; cannot cast to *v1.Endpoints.")
+		log.Println("In Endpoint Update; cannot cast to *v1.Endpoints.")
 		return
 	}
 	podSvcName := eps.GetObjectMeta().GetName()
@@ -105,7 +105,7 @@ func (e *EpHandler) update(obj interface{}) {
 
 // Delete for EventHandler
 func (e *EpHandler) Delete(obj interface{}) {
-	log.Printf("\n\nEndpoint Delete: %#v \n\n", obj)
+	log.Printf("Endpoint Delete: %#v \n", obj)
 	e.delete(obj)
 	e.Ep.RedisClient.PrintAllKeys()
 }
@@ -113,7 +113,7 @@ func (e *EpHandler) Delete(obj interface{}) {
 func (e *EpHandler) delete(obj interface{}) {
 	eps, ok := obj.(*v1.Endpoints)
 	if !ok {
-		log.Println("In EndpointHandler DELETE; cannot cast to *v1.Endpoints.")
+		log.Println("In Endpoint DELETE; cannot cast to *v1.Endpoints.")
 		return
 	}
 	podSvcName := eps.GetObjectMeta().GetName()
diff --git a/watcher/handlerIngress.go b/watcher/handlerIngress.go
index ca76e54..a437a23 100644
--- a/watcher/handlerIngress.go
+++ b/watcher/handlerIngress.go
@@ -17,11 +17,12 @@ package watcher
 
 import (
 	"log"
+	"strconv"
 
 	"ingress-ats/endpoint"
 	"ingress-ats/util"
 
-	v1beta1 "k8s.io/api/extensions/v1beta1"
+	nv1 "k8s.io/api/networking/v1"
 )
 
 // IgHandler implements EventHandler
@@ -31,34 +32,65 @@ type IgHandler struct {
 }
 
 func (g *IgHandler) Add(obj interface{}) {
-	log.Printf("\n\nIn INGRESS_HANDLER ADD %#v \n\n", obj)
+	log.Printf("In INGRESS_HANDLER ADD %#v \n", obj)
 	g.add(obj)
 	g.Ep.RedisClient.PrintAllKeys()
 }
 
 func (g *IgHandler) add(obj interface{}) {
-	ingressObj, ok := obj.(*v1beta1.Ingress)
+	ingressObj, ok := obj.(*nv1.Ingress)
 	if !ok {
-		log.Println("In HandlerIngress Add; cannot cast to *v1beta1.Ingress")
+		log.Println("In HandlerIngress Add; cannot cast to *nv1.Ingress")
 		return
 	}
 
 	namespace := ingressObj.GetNamespace()
-	ingressClass, _ := util.ExtractIngressClass(ingressObj.GetAnnotations())
+	// v1.18 ingress class name field in ingress object
+	//ingressClass, _ := util.ExtractIngressClass(ingressObj.GetAnnotations())
+	ingressClass, _ := util.ExtractIngressClassName(obj)
 	if !g.Ep.NsManager.IncludeNamespace(namespace) || !g.Ep.ATSManager.IncludeIngressClass(ingressClass) {
 		log.Println("Namespace not included or Ingress Class not matched")
 		return
 	}
 
+	name := ingressObj.GetName()
+	version := ingressObj.GetResourceVersion()
+	nameversion := util.ConstructNameVersionString(namespace, name, version)
+
 	// add the script before adding route
 	snippet, snippetErr := util.ExtractServerSnippet(ingressObj.GetAnnotations())
 	if snippetErr == nil {
-		name := ingressObj.GetName()
-		version := ingressObj.GetResourceVersion()
-		nameversion := util.ConstructNameVersionString(namespace, name, version)
 		g.Ep.RedisClient.DBOneSAdd(nameversion, snippet)
 	}
 
+	// add default backend rules
+	if ingressObj.Spec.DefaultBackend != nil {
+		host := "*"
+		scheme := "http"
+		path := "/"
+		pathType := nv1.PathTypePrefix
+		hostPath := util.ConstructHostPathString(scheme, host, path, pathType)
+		service := ingressObj.Spec.DefaultBackend.Service.Name
+		port := strconv.Itoa(int(ingressObj.Spec.DefaultBackend.Service.Port.Number))
+		svcport := util.ConstructSvcPortString(namespace, service, port)
+
+		g.Ep.RedisClient.DBOneSAdd(hostPath, svcport)
+
+		if snippetErr == nil {
+			g.Ep.RedisClient.DBOneSAdd(hostPath, nameversion)
+		}
+
+		// add default backend rule for https as well
+		scheme = "https"
+		hostPath = util.ConstructHostPathString(scheme, host, path, pathType)
+
+		g.Ep.RedisClient.DBOneSAdd(hostPath, svcport)
+
+		if snippetErr == nil {
+			g.Ep.RedisClient.DBOneSAdd(hostPath, nameversion)
+		}
+	}
+
 	tlsHosts := make(map[string]string)
 
 	for _, ingressTLS := range ingressObj.Spec.TLS {
@@ -69,6 +101,9 @@ func (g *IgHandler) add(obj interface{}) {
 
 	for _, ingressRule := range ingressObj.Spec.Rules {
 		host := ingressRule.Host
+		if host == "" {
+			host = "*"
+		}
 		scheme := "http"
 		if _, ok := tlsHosts[host]; ok {
 			scheme = "https"
@@ -77,17 +112,15 @@ func (g *IgHandler) add(obj interface{}) {
 		for _, httpPath := range ingressRule.HTTP.Paths {
 
 			path := httpPath.Path
-			hostPath := util.ConstructHostPathString(scheme, host, path)
-			service := httpPath.Backend.ServiceName
-			port := httpPath.Backend.ServicePort.String()
+			pathType := *httpPath.PathType
+			hostPath := util.ConstructHostPathString(scheme, host, path, pathType)
+			service := httpPath.Backend.Service.Name
+			port := strconv.Itoa(int(httpPath.Backend.Service.Port.Number))
 			svcport := util.ConstructSvcPortString(namespace, service, port)
 
 			g.Ep.RedisClient.DBOneSAdd(hostPath, svcport)
 
 			if snippetErr == nil {
-				name := ingressObj.GetName()
-				version := ingressObj.GetResourceVersion()
-				nameversion := util.ConstructNameVersionString(namespace, name, version)
 				g.Ep.RedisClient.DBOneSAdd(hostPath, nameversion)
 			}
 		}
@@ -97,33 +130,74 @@ func (g *IgHandler) add(obj interface{}) {
 
 // Update for EventHandler
 func (g *IgHandler) Update(obj, newObj interface{}) {
-	log.Printf("\n\nIn INGRESS_HANDLER UPDATE %#v \n\n", newObj)
+	log.Printf("In INGRESS_HANDLER UPDATE %#v \n", newObj)
 	g.update(obj, newObj)
 	g.Ep.RedisClient.PrintAllKeys()
 }
 
 func (g *IgHandler) update(obj, newObj interface{}) {
-	ingressObj, ok := obj.(*v1beta1.Ingress)
+	ingressObj, ok := obj.(*nv1.Ingress)
 	if !ok {
-		log.Println("In HandlerIngress Update; cannot cast to *v1beta1.Ingress")
+		log.Println("In HandlerIngress Update; cannot cast to *nv1.Ingress")
 		return
 	}
 
-	newIngressObj, ok := newObj.(*v1beta1.Ingress)
+	newIngressObj, ok := newObj.(*nv1.Ingress)
 	if !ok {
-		log.Println("In HandlerIngress Update; cannot cast to *v1beta1.Ingress")
+		log.Println("In HandlerIngress Update; cannot cast to *nv1.Ingress")
 		return
 	}
 
 	m := make(map[string]string)
 
 	namespace := ingressObj.GetNamespace()
-	ingressClass, _ := util.ExtractIngressClass(ingressObj.GetAnnotations())
+	// v1.18 ingress class name field in ingress object
+	//ingressClass, _ := util.ExtractIngressClass(ingressObj.GetAnnotations())
+	ingressClass, _ := util.ExtractIngressClassName(obj)
 	if g.Ep.NsManager.IncludeNamespace(namespace) && g.Ep.ATSManager.IncludeIngressClass(ingressClass) {
 		log.Println("Old Namespace included")
 
+		name := ingressObj.GetName()
+		version := ingressObj.GetResourceVersion()
+		nameversion := util.ConstructNameVersionString(namespace, name, version)
+
 		_, snippetErr := util.ExtractServerSnippet(ingressObj.GetAnnotations())
 
+		// handle default backend rules
+		if ingressObj.Spec.DefaultBackend != nil {
+			host := "*"
+			scheme := "http"
+			path := "/"
+			pathType := nv1.PathTypePrefix
+			hostPath := util.ConstructHostPathString(scheme, host, path, pathType)
+
+			g.Ep.RedisClient.DBOneSUnionStore("temp_"+hostPath, hostPath)
+			m["temp_"+hostPath] = hostPath
+
+			service := ingressObj.Spec.DefaultBackend.Service.Name
+			port := strconv.Itoa(int(ingressObj.Spec.DefaultBackend.Service.Port.Number))
+			svcport := util.ConstructSvcPortString(namespace, service, port)
+
+			g.Ep.RedisClient.DBOneSRem("temp_"+hostPath, svcport)
+
+			if snippetErr == nil {
+				g.Ep.RedisClient.DBOneSRem("temp_"+hostPath, nameversion)
+			}
+
+			// handle default backend https rule
+			scheme = "https"
+			hostPath = util.ConstructHostPathString(scheme, host, path, pathType)
+
+			g.Ep.RedisClient.DBOneSUnionStore("temp_"+hostPath, hostPath)
+			m["temp_"+hostPath] = hostPath
+
+			g.Ep.RedisClient.DBOneSRem("temp_"+hostPath, svcport)
+
+			if snippetErr == nil {
+				g.Ep.RedisClient.DBOneSRem("temp_"+hostPath, nameversion)
+			}
+		}
+
 		tlsHosts := make(map[string]string)
 
 		for _, ingressTLS := range ingressObj.Spec.TLS {
@@ -134,6 +208,9 @@ func (g *IgHandler) update(obj, newObj interface{}) {
 
 		for _, ingressRule := range ingressObj.Spec.Rules {
 			host := ingressRule.Host
+			if host == "" {
+				host = "*"
+			}
 			scheme := "http"
 			if _, ok := tlsHosts[host]; ok {
 				scheme = "https"
@@ -142,21 +219,19 @@ func (g *IgHandler) update(obj, newObj interface{}) {
 			for _, httpPath := range ingressRule.HTTP.Paths {
 
 				path := httpPath.Path
-				hostPath := util.ConstructHostPathString(scheme, host, path)
+				pathType := *httpPath.PathType
+				hostPath := util.ConstructHostPathString(scheme, host, path, pathType)
 
 				g.Ep.RedisClient.DBOneSUnionStore("temp_"+hostPath, hostPath)
 				m["temp_"+hostPath] = hostPath
 
-				service := httpPath.Backend.ServiceName
-				port := httpPath.Backend.ServicePort.String()
+				service := httpPath.Backend.Service.Name
+				port := strconv.Itoa(int(httpPath.Backend.Service.Port.Number))
 				svcport := util.ConstructSvcPortString(namespace, service, port)
 
 				g.Ep.RedisClient.DBOneSRem("temp_"+hostPath, svcport)
 
 				if snippetErr == nil {
-					name := ingressObj.GetName()
-					version := ingressObj.GetResourceVersion()
-					nameversion := util.ConstructNameVersionString(namespace, name, version)
 					g.Ep.RedisClient.DBOneSRem("temp_"+hostPath, nameversion)
 				}
 			}
@@ -164,17 +239,51 @@ func (g *IgHandler) update(obj, newObj interface{}) {
 		}
 	}
 
-	newNamespace := ingressObj.GetNamespace()
-	newIngressClass, _ := util.ExtractIngressClass(ingressObj.GetAnnotations())
+	newNamespace := newIngressObj.GetNamespace()
+	// v1.18 ingress class name field in ingress object
+	//newIngressClass, _ := util.ExtractIngressClass(newIngressObj.GetAnnotations())
+	newIngressClass, _ := util.ExtractIngressClassName(newObj)
 	if g.Ep.NsManager.IncludeNamespace(newNamespace) && g.Ep.ATSManager.IncludeIngressClass(newIngressClass) {
 		log.Println("New Namespace included")
 
+		name := newIngressObj.GetName()
+		version := newIngressObj.GetResourceVersion()
+		nameversion := util.ConstructNameVersionString(newNamespace, name, version)
+
 		newSnippet, newSnippetErr := util.ExtractServerSnippet(newIngressObj.GetAnnotations())
 		if newSnippetErr == nil {
-			newName := newIngressObj.GetName()
-			newVersion := newIngressObj.GetResourceVersion()
-			newNameversion := util.ConstructNameVersionString(newNamespace, newName, newVersion)
-			g.Ep.RedisClient.DBOneSAdd(newNameversion, newSnippet)
+			g.Ep.RedisClient.DBOneSAdd(nameversion, newSnippet)
+		}
+
+		// handle default backend rule
+		if newIngressObj.Spec.DefaultBackend != nil {
+			host := "*"
+			scheme := "http"
+			path := "/"
+			pathType := nv1.PathTypePrefix
+			hostPath := util.ConstructHostPathString(scheme, host, path, pathType)
+
+			service := newIngressObj.Spec.DefaultBackend.Service.Name
+			port := strconv.Itoa(int(newIngressObj.Spec.DefaultBackend.Service.Port.Number))
+			svcport := util.ConstructSvcPortString(newNamespace, service, port)
+
+			g.Ep.RedisClient.DBOneSAdd("temp_"+hostPath, svcport)
+			m["temp_"+hostPath] = hostPath
+
+			if newSnippetErr == nil {
+				g.Ep.RedisClient.DBOneSAdd("temp_"+hostPath, nameversion)
+			}
+
+			// handle default backend rule for https as well
+			scheme = "https"
+			hostPath = util.ConstructHostPathString(scheme, host, path, pathType)
+
+			g.Ep.RedisClient.DBOneSAdd("temp_"+hostPath, svcport)
+			m["temp_"+hostPath] = hostPath
+
+			if newSnippetErr == nil {
+				g.Ep.RedisClient.DBOneSAdd("temp_"+hostPath, nameversion)
+			}
 		}
 
 		newTlsHosts := make(map[string]string)
@@ -187,6 +296,9 @@ func (g *IgHandler) update(obj, newObj interface{}) {
 
 		for _, ingressRule := range newIngressObj.Spec.Rules {
 			host := ingressRule.Host
+			if host == "" {
+				host = "*"
+			}
 			scheme := "http"
 			if _, ok := newTlsHosts[host]; ok {
 				scheme = "https"
@@ -195,20 +307,18 @@ func (g *IgHandler) update(obj, newObj interface{}) {
 			for _, httpPath := range ingressRule.HTTP.Paths {
 
 				path := httpPath.Path
-				hostPath := util.ConstructHostPathString(scheme, host, path)
+				pathType := *httpPath.PathType
+				hostPath := util.ConstructHostPathString(scheme, host, path, pathType)
 
-				service := httpPath.Backend.ServiceName
-				port := httpPath.Backend.ServicePort.String()
-				svcport := util.ConstructSvcPortString(namespace, service, port)
+				service := httpPath.Backend.Service.Name
+				port := strconv.Itoa(int(httpPath.Backend.Service.Port.Number))
+				svcport := util.ConstructSvcPortString(newNamespace, service, port)
 
 				g.Ep.RedisClient.DBOneSAdd("temp_"+hostPath, svcport)
 				m["temp_"+hostPath] = hostPath
 
 				if newSnippetErr == nil {
-					newName := newIngressObj.GetName()
-					newVersion := newIngressObj.GetResourceVersion()
-					newNameversion := util.ConstructNameVersionString(newNamespace, newName, newVersion)
-					g.Ep.RedisClient.DBOneSAdd("temp_"+hostPath, newNameversion)
+					g.Ep.RedisClient.DBOneSAdd("temp_"+hostPath, nameversion)
 				}
 			}
 
@@ -223,28 +333,60 @@ func (g *IgHandler) update(obj, newObj interface{}) {
 
 // Delete for EventHandler
 func (g *IgHandler) Delete(obj interface{}) {
-	log.Printf("\n\nIn INGRESS_HANDLER DELETE %#v \n\n", obj)
+	log.Printf("In INGRESS_HANDLER DELETE %#v \n", obj)
 	g.delete(obj)
 	g.Ep.RedisClient.PrintAllKeys()
 }
 
 // Helper for Deletes
 func (g *IgHandler) delete(obj interface{}) {
-	ingressObj, ok := obj.(*v1beta1.Ingress)
+	ingressObj, ok := obj.(*nv1.Ingress)
 	if !ok {
-		log.Println("In HandlerIngress Delete; cannot cast to *v1beta1.Ingress")
+		log.Println("In HandlerIngress Delete; cannot cast to *nv1.Ingress")
 		return
 	}
 
 	namespace := ingressObj.GetNamespace()
-	ingressClass, _ := util.ExtractIngressClass(ingressObj.GetAnnotations())
+	// v1.18 ingress class name field in ingress object
+	//ingressClass, _ := util.ExtractIngressClass(ingressObj.GetAnnotations())
+	ingressClass, _ := util.ExtractIngressClassName(obj)
 	if !g.Ep.NsManager.IncludeNamespace(namespace) || !g.Ep.ATSManager.IncludeIngressClass(ingressClass) {
 		log.Println("Namespace not included or Ingress Class not matched")
 		return
 	}
 
+	name := ingressObj.GetName()
+	version := ingressObj.GetResourceVersion()
+	nameversion := util.ConstructNameVersionString(namespace, name, version)
+
 	_, snippetErr := util.ExtractServerSnippet(ingressObj.GetAnnotations())
 
+	if ingressObj.Spec.DefaultBackend != nil {
+		host := "*"
+		scheme := "http"
+		path := "/"
+		pathType := nv1.PathTypePrefix
+		hostPath := util.ConstructHostPathString(scheme, host, path, pathType)
+		service := ingressObj.Spec.DefaultBackend.Service.Name
+		port := strconv.Itoa(int(ingressObj.Spec.DefaultBackend.Service.Port.Number))
+		svcport := util.ConstructSvcPortString(namespace, service, port)
+
+		g.Ep.RedisClient.DBOneSRem(hostPath, svcport)
+
+		if snippetErr == nil {
+			g.Ep.RedisClient.DBOneSRem(hostPath, nameversion)
+		}
+
+		scheme = "https"
+		hostPath = util.ConstructHostPathString(scheme, host, path, pathType)
+
+		g.Ep.RedisClient.DBOneSRem(hostPath, svcport)
+
+		if snippetErr == nil {
+			g.Ep.RedisClient.DBOneSRem(hostPath, nameversion)
+		}
+	}
+
 	tlsHosts := make(map[string]string)
 
 	for _, ingressTLS := range ingressObj.Spec.TLS {
@@ -255,6 +397,9 @@ func (g *IgHandler) delete(obj interface{}) {
 
 	for _, ingressRule := range ingressObj.Spec.Rules {
 		host := ingressRule.Host
+		if host == "" {
+			host = "*"
+		}
 		scheme := "http"
 		if _, ok := tlsHosts[host]; ok {
 			scheme = "https"
@@ -263,17 +408,15 @@ func (g *IgHandler) delete(obj interface{}) {
 		for _, httpPath := range ingressRule.HTTP.Paths {
 
 			path := httpPath.Path
-			hostPath := util.ConstructHostPathString(scheme, host, path)
-			service := httpPath.Backend.ServiceName
-			port := httpPath.Backend.ServicePort.String()
+			pathType := *httpPath.PathType
+			hostPath := util.ConstructHostPathString(scheme, host, path, pathType)
+			service := httpPath.Backend.Service.Name
+			port := strconv.Itoa(int(httpPath.Backend.Service.Port.Number))
 			svcport := util.ConstructSvcPortString(namespace, service, port)
 
 			g.Ep.RedisClient.DBOneSRem(hostPath, svcport)
 
 			if snippetErr == nil {
-				name := ingressObj.GetName()
-				version := ingressObj.GetResourceVersion()
-				nameversion := util.ConstructNameVersionString(namespace, name, version)
 				g.Ep.RedisClient.DBOneSRem(hostPath, nameversion)
 			}
 		}
diff --git a/watcher/handlerIngress_test.go b/watcher/handlerIngress_test.go
index 96c7315..57cb2cf 100644
--- a/watcher/handlerIngress_test.go
+++ b/watcher/handlerIngress_test.go
@@ -24,11 +24,12 @@ import (
 	"ingress-ats/redis"
 	"ingress-ats/util"
 
-	v1beta1 "k8s.io/api/extensions/v1beta1"
+	nv1 "k8s.io/api/networking/v1"
 	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/util/intstr"
 )
 
+var pathExact nv1.PathType = nv1.PathTypeExact
+
 func TestAdd_ExampleIngress(t *testing.T) {
 	igHandler := createExampleIgHandler()
 	exampleIngress := createExampleIngress()
@@ -68,8 +69,8 @@ func TestAdd_ExampleIngressWithTLS(t *testing.T) {
 	returnedKeys := igHandler.Ep.RedisClient.GetDBOneKeyValues()
 
 	expectedKeys := getExpectedKeysForAdd()
-	expectedKeys["https://test.edge.com/app1"] = expectedKeys["http://test.edge.com/app1"]
-	delete(expectedKeys, "http://test.edge.com/app1")
+	expectedKeys["E+https://test.edge.com/app1"] = expectedKeys["E+http://test.edge.com/app1"]
+	delete(expectedKeys, "E+http://test.edge.com/app1")
 
 	if !util.IsSameMap(returnedKeys, expectedKeys) {
 		t.Errorf("returned \n%v,  but expected \n%v", returnedKeys, expectedKeys)
@@ -120,8 +121,8 @@ func TestUpdate_ModifyIngress(t *testing.T) {
 	updatedExampleIngress := createExampleIngress()
 
 	updatedExampleIngress.Spec.Rules[0].IngressRuleValue.HTTP.Paths[1].Path = "/app2-modified"
-	updatedExampleIngress.Spec.Rules[1].IngressRuleValue.HTTP.Paths[0].Backend.ServiceName = "appsvc1-modified"
-	updatedExampleIngress.Spec.Rules[1].IngressRuleValue.HTTP.Paths[0].Backend.ServicePort = intstr.FromString("9090")
+	updatedExampleIngress.Spec.Rules[1].IngressRuleValue.HTTP.Paths[0].Backend.Service.Name = "appsvc1-modified"
+	updatedExampleIngress.Spec.Rules[1].IngressRuleValue.HTTP.Paths[0].Backend.Service.Port.Number = 9090
 
 	igHandler.add(&exampleIngress)
 	igHandler.update(&exampleIngress, &updatedExampleIngress)
@@ -186,8 +187,8 @@ func TestUpdate_ModifyTLS(t *testing.T) {
 
 	returnedKeys := igHandler.Ep.RedisClient.GetDBOneKeyValues()
 	expectedKeys := getExpectedKeysForAdd()
-	expectedKeys["https://test.edge.com/app1"] = expectedKeys["http://test.edge.com/app1"]
-	expectedKeys["http://test.edge.com/app1"] = []string{}
+	expectedKeys["E+https://test.edge.com/app1"] = expectedKeys["E+http://test.edge.com/app1"]
+	expectedKeys["E+http://test.edge.com/app1"] = []string{}
 
 	if !util.IsSameMap(returnedKeys, expectedKeys) {
 		t.Errorf("returned \n%v,  but expected \n%v", returnedKeys, expectedKeys)
@@ -210,10 +211,10 @@ func TestDelete(t *testing.T) {
 
 }
 
-func createExampleIngressWithTLS() v1beta1.Ingress {
+func createExampleIngressWithTLS() nv1.Ingress {
 	exampleIngress := createExampleIngress()
 
-	exampleIngress.Spec.TLS = []v1beta1.IngressTLS{
+	exampleIngress.Spec.TLS = []nv1.IngressTLS{
 		{
 			Hosts: []string{"test.edge.com"},
 		},
@@ -222,7 +223,7 @@ func createExampleIngressWithTLS() v1beta1.Ingress {
 	return exampleIngress
 }
 
-func createExampleIngressWithAnnotation() v1beta1.Ingress {
+func createExampleIngressWithAnnotation() nv1.Ingress {
 	exampleIngress := createExampleIngress()
 
 	exampleIngress.ObjectMeta.Annotations = make(map[string]string)
@@ -232,31 +233,41 @@ func createExampleIngressWithAnnotation() v1beta1.Ingress {
 	return exampleIngress
 }
 
-func createExampleIngress() v1beta1.Ingress {
-	exampleIngress := v1beta1.Ingress{
+func createExampleIngress() nv1.Ingress {
+	exampleIngress := nv1.Ingress{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:      "example-ingress",
 			Namespace: "trafficserver-test",
 		},
-		Spec: v1beta1.IngressSpec{
-			Rules: []v1beta1.IngressRule{
+		Spec: nv1.IngressSpec{
+			Rules: []nv1.IngressRule{
 				{
 					Host: "test.media.com",
-					IngressRuleValue: v1beta1.IngressRuleValue{
-						HTTP: &v1beta1.HTTPIngressRuleValue{
-							Paths: []v1beta1.HTTPIngressPath{
+					IngressRuleValue: nv1.IngressRuleValue{
+						HTTP: &nv1.HTTPIngressRuleValue{
+							Paths: []nv1.HTTPIngressPath{
 								{
-									Path: "/app1",
-									Backend: v1beta1.IngressBackend{
-										ServiceName: "appsvc1",
-										ServicePort: intstr.FromString("8080"),
+									Path:     "/app1",
+									PathType: &pathExact,
+									Backend: nv1.IngressBackend{
+										Service: &nv1.IngressServiceBackend{
+											Name: "appsvc1",
+											Port: nv1.ServiceBackendPort{
+												Number: 8080,
+											},
+										},
 									},
 								},
 								{
-									Path: "/app2",
-									Backend: v1beta1.IngressBackend{
-										ServiceName: "appsvc2",
-										ServicePort: intstr.FromString("8080"),
+									Path:     "/app2",
+									PathType: &pathExact,
+									Backend: nv1.IngressBackend{
+										Service: &nv1.IngressServiceBackend{
+											Name: "appsvc2",
+											Port: nv1.ServiceBackendPort{
+												Number: 8080,
+											},
+										},
 									},
 								},
 							},
@@ -265,14 +276,19 @@ func createExampleIngress() v1beta1.Ingress {
 				},
 				{
 					Host: "test.edge.com",
-					IngressRuleValue: v1beta1.IngressRuleValue{
-						HTTP: &v1beta1.HTTPIngressRuleValue{
-							Paths: []v1beta1.HTTPIngressPath{
+					IngressRuleValue: nv1.IngressRuleValue{
+						HTTP: &nv1.HTTPIngressRuleValue{
+							Paths: []nv1.HTTPIngressPath{
 								{
-									Path: "/app1",
-									Backend: v1beta1.IngressBackend{
-										ServiceName: "appsvc1",
-										ServicePort: intstr.FromString("8080"),
+									Path:     "/app1",
+									PathType: &pathExact,
+									Backend: nv1.IngressBackend{
+										Service: &nv1.IngressServiceBackend{
+											Name: "appsvc1",
+											Port: nv1.ServiceBackendPort{
+												Number: 8080,
+											},
+										},
 									},
 								},
 							},
@@ -331,8 +347,8 @@ func getExpectedKeysForUpdate_ModifySnippet() map[string][]string {
 	expectedKeys["$trafficserver-test/example-ingress/10"] = []string{}
 	expectedKeys["$trafficserver-test/example-ingress/10"] = append(expectedKeys["$trafficserver-test/example-ingress/10"], updatedSnippet)
 
-	expectedKeys["http://test.edge.com/app1"] = expectedKeys["http://test.edge.com/app1"][:1]
-	expectedKeys["http://test.edge.com/app1"] = append(expectedKeys["http://test.edge.com/app1"], "$trafficserver-test/example-ingress/10")
+	expectedKeys["E+http://test.edge.com/app1"] = expectedKeys["E+http://test.edge.com/app1"][:1]
+	expectedKeys["E+http://test.edge.com/app1"] = append(expectedKeys["E+http://test.edge.com/app1"], "$trafficserver-test/example-ingress/10")
 
 	return expectedKeys
 }
@@ -340,13 +356,13 @@ func getExpectedKeysForUpdate_ModifySnippet() map[string][]string {
 func getExpectedKeysForUpdate_ModifyIngress() map[string][]string {
 	expectedKeys := getExpectedKeysForAdd()
 
-	expectedKeys["http://test.media.com/app2"] = []string{}
+	expectedKeys["E+http://test.media.com/app2"] = []string{}
 
-	expectedKeys["http://test.media.com/app2-modified"] = []string{}
-	expectedKeys["http://test.media.com/app2-modified"] = append(expectedKeys["http://test.media.com/app2"], "trafficserver-test:appsvc2:8080")
+	expectedKeys["E+http://test.media.com/app2-modified"] = []string{}
+	expectedKeys["E+http://test.media.com/app2-modified"] = append(expectedKeys["E+http://test.media.com/app2"], "trafficserver-test:appsvc2:8080")
 
-	expectedKeys["http://test.edge.com/app1"] = []string{}
-	expectedKeys["http://test.edge.com/app1"] = append(expectedKeys["http://test.edge.com/app1"], "trafficserver-test:appsvc1-modified:9090")
+	expectedKeys["E+http://test.edge.com/app1"] = []string{}
+	expectedKeys["E+http://test.edge.com/app1"] = append(expectedKeys["E+http://test.edge.com/app1"], "trafficserver-test:appsvc1-modified:9090")
 
 	return expectedKeys
 }
@@ -354,20 +370,20 @@ func getExpectedKeysForUpdate_ModifyIngress() map[string][]string {
 func getExpectedKeysForUpdate_DeleteService() map[string][]string {
 	expectedKeys := getExpectedKeysForAdd()
 
-	expectedKeys["http://test.media.com/app2"] = []string{}
+	expectedKeys["E+http://test.media.com/app2"] = []string{}
 
 	return expectedKeys
 }
 
 func getExpectedKeysForAdd() map[string][]string {
 	expectedKeys := make(map[string][]string)
-	expectedKeys["http://test.edge.com/app1"] = []string{}
-	expectedKeys["http://test.media.com/app1"] = []string{}
-	expectedKeys["http://test.media.com/app2"] = []string{}
+	expectedKeys["E+http://test.edge.com/app1"] = []string{}
+	expectedKeys["E+http://test.media.com/app1"] = []string{}
+	expectedKeys["E+http://test.media.com/app2"] = []string{}
 
-	expectedKeys["http://test.edge.com/app1"] = append(expectedKeys["http://test.edge.com/app1"], "trafficserver-test:appsvc1:8080")
-	expectedKeys["http://test.media.com/app2"] = append(expectedKeys["http://test.media.com/app2"], "trafficserver-test:appsvc2:8080")
-	expectedKeys["http://test.media.com/app1"] = append(expectedKeys["http://test.media.com/app1"], "trafficserver-test:appsvc1:8080")
+	expectedKeys["E+http://test.edge.com/app1"] = append(expectedKeys["E+http://test.edge.com/app1"], "trafficserver-test:appsvc1:8080")
+	expectedKeys["E+http://test.media.com/app2"] = append(expectedKeys["E+http://test.media.com/app2"], "trafficserver-test:appsvc2:8080")
+	expectedKeys["E+http://test.media.com/app1"] = append(expectedKeys["E+http://test.media.com/app1"], "trafficserver-test:appsvc1:8080")
 
 	return expectedKeys
 }
@@ -375,10 +391,10 @@ func getExpectedKeysForAdd() map[string][]string {
 func getExpectedKeysForAddWithAnnotation() map[string][]string {
 	expectedKeys := getExpectedKeysForAdd()
 
-	delete(expectedKeys, "http://test.media.com/app1")
-	delete(expectedKeys, "http://test.media.com/app2")
+	delete(expectedKeys, "E+http://test.media.com/app1")
+	delete(expectedKeys, "E+http://test.media.com/app2")
 
-	expectedKeys["http://test.edge.com/app1"] = append(expectedKeys["http://test.edge.com/app1"], "$trafficserver-test/example-ingress/")
+	expectedKeys["E+http://test.edge.com/app1"] = append(expectedKeys["E+http://test.edge.com/app1"], "$trafficserver-test/example-ingress/")
 
 	exampleSnippet := getExampleSnippet()
 
diff --git a/watcher/watcher.go b/watcher/watcher.go
index f0c451f..8c97317 100644
--- a/watcher/watcher.go
+++ b/watcher/watcher.go
@@ -27,7 +27,7 @@ import (
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/tools/cache"
 
-	v1beta1 "k8s.io/api/extensions/v1beta1"
+	nv1 "k8s.io/api/networking/v1"
 
 	"k8s.io/apimachinery/pkg/fields"
 	pkgruntime "k8s.io/apimachinery/pkg/runtime"
@@ -59,9 +59,9 @@ type EventHandler interface {
 func (w *Watcher) Watch() error {
 	//================= Watch for Ingress ==================
 	igHandler := IgHandler{"ingresses", w.Ep}
-	igListWatch := cache.NewListWatchFromClient(w.Cs.ExtensionsV1beta1().RESTClient(), igHandler.GetResourceName(), v1.NamespaceAll, fields.Everything())
-	err := w.allNamespacesWatchFor(&igHandler, w.Cs.ExtensionsV1beta1().RESTClient(),
-		fields.Everything(), &v1beta1.Ingress{}, 0, igListWatch)
+	igListWatch := cache.NewListWatchFromClient(w.Cs.NetworkingV1().RESTClient(), igHandler.GetResourceName(), v1.NamespaceAll, fields.Everything())
+	err := w.allNamespacesWatchFor(&igHandler, w.Cs.NetworkingV1().RESTClient(),
+		fields.Everything(), &nv1.Ingress{}, 0, igListWatch)
 	if err != nil {
 		return err
 	}
@@ -75,7 +75,7 @@ func (w *Watcher) Watch() error {
 	}
 	//================= Watch for ConfigMaps =================
 	cmHandler := CMHandler{"configmaps", w.Ep}
-	targetNs := make([]string, 1, 1)
+	targetNs := make([]string, 1)
 	targetNs[0] = w.Ep.ATSManager.(*proxy.ATSManager).Namespace
 	err = w.inNamespacesWatchFor(&cmHandler, w.Cs.CoreV1().RESTClient(),
 		targetNs, fields.Everything(), &v1.ConfigMap{}, 0)
@@ -94,8 +94,8 @@ func (w *Watcher) allNamespacesWatchFor(h EventHandler, c cache.Getter,
 	switch objType.(type) {
 	case *v1.Endpoints:
 		sharedInformer = factory.Core().V1().Endpoints().Informer()
-	case *v1beta1.Ingress:
-		sharedInformer = factory.Extensions().V1beta1().Ingresses().Informer()
+	case *nv1.Ingress:
+		sharedInformer = factory.Networking().V1().Ingresses().Informer()
 	}
 
 	sharedInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
@@ -120,7 +120,7 @@ func (w *Watcher) inNamespacesWatchFor(h EventHandler, c cache.Getter,
 	namespaces []string, fieldSelector fields.Selector, objType pkgruntime.Object,
 	resyncPeriod time.Duration) error {
 	if len(namespaces) == 0 {
-		log.Panic("inNamespacesWatchFor must have at least 1 namespace")
+		log.Panicln("inNamespacesWatchFor must have at least 1 namespace")
 	}
 	syncFuncs := make([]cache.InformerSynced, len(namespaces))
 	for i, ns := range namespaces {
@@ -130,8 +130,8 @@ func (w *Watcher) inNamespacesWatchFor(h EventHandler, c cache.Getter,
 		switch objType.(type) {
 		case *v1.Endpoints:
 			sharedInformer = factory.Core().V1().Endpoints().Informer()
-		case *v1beta1.Ingress:
-			sharedInformer = factory.Extensions().V1beta1().Ingresses().Informer()
+		case *nv1.Ingress:
+			sharedInformer = factory.Networking().V1().Ingresses().Informer()
 		case *v1.ConfigMap:
 			sharedInformer = factory.Core().V1().ConfigMaps().Informer()
 		}
diff --git a/watcher/watcher_test.go b/watcher/watcher_test.go
index 6d8b5e6..34bcbb8 100644
--- a/watcher/watcher_test.go
+++ b/watcher/watcher_test.go
@@ -227,7 +227,7 @@ func TestInNamespacesWatchFor_Add(t *testing.T) {
 	w, _ := getTestWatcher()
 
 	cmHandler := CMHandler{"configmaps", w.Ep}
-	targetNs := make([]string, 1, 1)
+	targetNs := make([]string, 1)
 	targetNs[0] = "trafficserver"
 
 	err := w.inNamespacesWatchFor(&cmHandler, w.Cs.CoreV1().RESTClient(),
@@ -282,7 +282,7 @@ func TestInNamespacesWatchFor_Update(t *testing.T) {
 	w, _ := getTestWatcher()
 
 	cmHandler := CMHandler{"configmaps", w.Ep}
-	targetNs := make([]string, 1, 1)
+	targetNs := make([]string, 1)
 	targetNs[0] = "trafficserver"
 
 	err := w.inNamespacesWatchFor(&cmHandler, w.Cs.CoreV1().RESTClient(),
@@ -353,7 +353,7 @@ func TestInNamespacesWatchFor_ShouldNotAdd(t *testing.T) {
 	w, _ := getTestWatcher()
 
 	cmHandler := CMHandler{"configmaps", w.Ep}
-	targetNs := make([]string, 1, 1)
+	targetNs := make([]string, 1)
 	targetNs[0] = "trafficserver"
 
 	err := w.inNamespacesWatchFor(&cmHandler, w.Cs.CoreV1().RESTClient(),