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 2020/11/04 09:28:49 UTC

[trafficserver-ingress-controller] branch master updated: Updates on 2020/11 (#48)

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 4b3dac1  Updates on 2020/11 (#48)
4b3dac1 is described below

commit 4b3dac11dc241e81b1da9a2d6ec7bb6efca9029b
Author: Kit Chan <ki...@apache.org>
AuthorDate: Wed Nov 4 01:26:02 2020 -0800

    Updates on 2020/11 (#48)
    
    Reorganize directory structure
    Reorganize document structure
    Upgrade to go1.15.3
---
 .github/workflows/build.yml                        |  10 +-
 .gitignore                                         |   2 +-
 .gitmodules                                        |   4 +-
 .vscode/extensions.json                            |   3 +-
 Dockerfile                                         |  21 +-
 README.md                                          | 194 +---------
 entry.sh => bin/entry.sh                           |   0
 tls-config.sh => bin/tls-config.sh                 |   0
 tls-reload.sh => bin/tls-reload.sh                 |   0
 logging.yaml => config/logging.yaml                |   0
 logrotate.ingress => config/logrotate.ingress      |   0
 plugin.config => config/plugin.config              |   0
 records.config => config/records.config            |   0
 redis.conf => config/redis.conf                    |   0
 docs/ARCHITECTURE.md                               |  28 ++
 docs/DEVELOPMENT.md                                |  57 +++
 README.md => docs/TUTORIAL.md                      | 148 +++----
 endpoint/endpoint.go                               |  12 -
 go.mod                                             |  20 +-
 go.sum                                             | 225 +++++++++++
 .../node-app-2 => images/node-app-1}/.dockerignore |   0
 .../node-app-2 => images/node-app-1}/Dockerfile    |   0
 .../node-app-1/hello-updated.html                  |   0
 k8s/{backend => images}/node-app-1/hello.html      |   0
 .../node-app-1}/package-lock.json                  |   0
 .../node-app-2 => images/node-app-1}/package.json  |   0
 k8s/{backend => images}/node-app-1/server.js       |   0
 .../node-app-1 => images/node-app-2}/.dockerignore |   0
 .../node-app-1 => images/node-app-2}/Dockerfile    |   0
 k8s/{backend => images}/node-app-2/hello.html      |   0
 .../node-app-2}/package-lock.json                  |   0
 .../node-app-1 => images/node-app-2}/package.json  |   0
 k8s/{backend => images}/node-app-2/server.js       |   0
 k8s/{backend => images}/trafficserver_exporter     |   0
 k8s/traffic-server/ats-deployment.yaml             |   6 +-
 namespace/namespace.go                             |   2 -
 redis/redis.go                                     |   2 -
 .../data/setup/traffic-server/ats-deployment.yaml  |   6 +-
 types/metadataManagers.go                          | 292 --------------
 types/types.go                                     | 424 ---------------------
 util/util.go                                       |   2 -
 watcher/handlerConfigmap.go                        |   1 -
 watcher/handlerEndpoint.go                         |   3 -
 watcher/handlerIngress.go                          |   2 -
 watcher/watcher_test.go                            |  37 +-
 45 files changed, 410 insertions(+), 1091 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 92881b2..55881c8 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -28,16 +28,16 @@ jobs:
           python-version: '3.7' 
       
       - name: Build ATS Alpine
-        run: docker build -t ats_alpine .
+        run: docker build -t ats-ingress .
       
       - name: Build Exporter
-        run: docker build -t tsexporter k8s/backend/trafficserver_exporter/
+        run: docker build -t ats-ingress-exporter k8s/images/trafficserver_exporter/
       
       - name: Build App 1
-        run: docker build -t node-app-1 k8s/backend/node-app-1/
+        run: docker build -t node-app-1 k8s/images/node-app-1/
       
       - name: Build App 2
-        run: docker build -t node-app-2 k8s/backend/node-app-2/
+        run: docker build -t node-app-2 k8s/images/node-app-2/
       
       - name: Install dependencies
         run: |
@@ -48,4 +48,4 @@ jobs:
       - name: Test 
         run: |
           cd tests
-          pytest -q --minikubeip="$(minikube ip)" suite/test_ingress.py
\ No newline at end of file
+          pytest -q --minikubeip="$(minikube ip)" suite/test_ingress.py
diff --git a/.gitignore b/.gitignore
index 26f910c..447b340 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,7 @@
 vendor/
 
 # go mod
-go.sum
+!go.sum
 !go.mod
 
 # builds
diff --git a/.gitmodules b/.gitmodules
index 5a61bfb..9b0ea0a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
-[submodule "k8s/backend/trafficserver_exporter"]
-	path = k8s/backend/trafficserver_exporter
+[submodule "k8s/images/trafficserver_exporter"]
+	path = k8s/images/trafficserver_exporter
 	url = https://github.com/gdvalle/trafficserver_exporter.git
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 22a7434..6bb4d20 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -4,7 +4,6 @@
 
 	// List of extensions which should be recommended for users of this workspace.
 	"recommendations": [
-		"ms-vscode.go", // Go-lang language support
 		"redhat.vscode-yaml", // docker + k8s code hints and code snippets
 		"keyring.lua", // lua language support
 		"ms-kubernetes-tools.vscode-kubernetes-tools", // managing k8s
@@ -15,4 +14,4 @@
 	"unwantedRecommendations": [
 		
 	]
-}
\ No newline at end of file
+}
diff --git a/Dockerfile b/Dockerfile
index b1d895e..9050e73 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -33,9 +33,9 @@ RUN curl -L https://www-us.apache.org/dist/trafficserver/trafficserver-8.1.0.tar
   && make \
   && make install
 
-COPY ["./plugin.config", "/usr/local/etc/trafficserver/plugin.config"]
-COPY ["./records.config", "/usr/local/etc/trafficserver/records.config"]
-COPY ["./logging.yaml", "/usr/local/etc/trafficserver/logging.yaml"]
+COPY ["./config/plugin.config", "/usr/local/etc/trafficserver/plugin.config"]
+COPY ["./config/records.config", "/usr/local/etc/trafficserver/records.config"]
+COPY ["./config/logging.yaml", "/usr/local/etc/trafficserver/logging.yaml"]
 
 # enable traffic.out for alpine/gentoo
 RUN sed -i "s/TM_DAEMON_ARGS=\"\"/TM_DAEMON_ARGS=\" --bind_stdout \/usr\/local\/var\/log\/trafficserver\/traffic.out --bind_stderr \/usr\/local\/var\/log\/trafficserver\/traffic.out \"/" /usr/local/bin/trafficserver
@@ -67,8 +67,8 @@ RUN apk add --no-cache --virtual .ingress-build-deps \
   bash gcc musl-dev openssl go
 
 # Installing Golang https://github.com/CentOS/CentOS-Dockerfiles/blob/master/golang/centos7/Dockerfile
-RUN wget https://dl.google.com/go/go1.12.8.src.tar.gz \
-    && tar -C /usr/local -xzf go1.12.8.src.tar.gz && cd /usr/local/go/src/ && ./make.bash
+RUN wget https://dl.google.com/go/go1.15.3.src.tar.gz \
+    && tar -C /usr/local -xzf go1.15.3.src.tar.gz && cd /usr/local/go/src/ && ./make.bash
 ENV PATH=${PATH}:/usr/local/go/bin
 ENV GOPATH="/usr/local/go/bin"
 
@@ -79,7 +79,6 @@ COPY ["./main/", "$GOPATH/src/ingress-ats/main"]
 COPY ["./proxy/", "$GOPATH/src/ingress-ats/proxy"]
 COPY ["./namespace/", "$GOPATH/src/ingress-ats/namespace"]
 COPY ["./endpoint/", "$GOPATH/src/ingress-ats/endpoint"]
-COPY ["./types/", "$GOPATH/src/ingress-ats/types"]
 COPY ["./util/", "$GOPATH/src/ingress-ats/util"]
 COPY ["./watcher/", "$GOPATH/src/ingress-ats/watcher"]
 COPY ["./pluginats/", "$GOPATH/src/ingress-ats/pluginats"]
@@ -92,12 +91,12 @@ ENV GO111MODULE=on
 RUN go build -o ingress_ats main/main.go 
 
 # redis conf 
-COPY ["./redis.conf", "/usr/local/etc/redis.conf"]
+COPY ["./config/redis.conf", "/usr/local/etc/redis.conf"]
 
 # entry.sh + other scripts
-COPY ["./tls-config.sh", "/usr/local/bin/tls-config.sh"]
-COPY ["./tls-reload.sh", "/usr/local/bin/tls-reload.sh"]
-COPY ["./entry.sh", "/usr/local/bin/entry.sh"]
+COPY ["./bin/tls-config.sh", "/usr/local/bin/tls-config.sh"]
+COPY ["./bin/tls-reload.sh", "/usr/local/bin/tls-reload.sh"]
+COPY ["./bin/entry.sh", "/usr/local/bin/entry.sh"]
 WORKDIR /usr/local/bin/
 RUN chmod 755 tls-config.sh
 RUN chmod 755 tls-reload.sh
@@ -139,6 +138,6 @@ RUN ln -sf /usr/lib/libluajit-5.1.so.2.1.0 /usr/lib/libluajit-5.1.so
 
 # set up ingress log location
 RUN mkdir -p /usr/local/var/log/ingress/
-COPY ["./logrotate.ingress", "/etc/logrotate.d/ingress"]
+COPY ["./config/logrotate.ingress", "/etc/logrotate.d/ingress"]
 
 ENTRYPOINT ["/usr/local/bin/entry.sh"]
diff --git a/README.md b/README.md
index 9d21cc3..86e91e5 100644
--- a/README.md
+++ b/README.md
@@ -22,201 +22,19 @@ ATS Kubernetes Ingress Controller
 ![Test](https://github.com/apache/trafficserver-ingress-controller/workflows/Test/badge.svg)
 ![Build and Integrate](https://github.com/apache/trafficserver-ingress-controller/workflows/Build%20and%20Integrate/badge.svg)
 
-## Contents
-- [Introduction](#Introduction)
-- [Versions of Software Used](#versions-of-software-used)
-- [How to use](#how-to-use)
-  - [Requirements](#requirements)
-  - [Download project](#download-project)
-  - [Example Walkthrough](#example-walkthrough)
-    - [Proxy](#proxy)
-    - [ConfigMap](#configmap)
-    - [Snippet](#snippet)
-    - [Ingress Class](#ingressclass)
-  - [Logging and Monitoring](#logging-and-monitoring)
-    - [Fluentd](#fluend)
-    - [Prometheus and Grafana](#prometheus-and-grafana)
-- [Development](#development)
-  - [Develop with Go-Lang in Linux](#develop-with-go-lang-in-linux)
-  - [Compilation](#compilation)
-  - [Unit Tests](#unit-tests)
-  - [Text-Editor](#text-editor)
-- [Documentation](#documentation)
-
-## Introduction 
+## Introduction
 [Apache Traffic Server (ATS)](https://trafficserver.apache.org/) is a high performance, open-source, caching proxy server that is scalable and configurable. This project uses ATS as a [Kubernetes(K8s)](https://kubernetes.io/) [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)
 
-![Abstract](docs/images/abstract.png)
-
-From high-level, the ingress controller talks to K8s' API and sets up `watchers` on specific resources that are interesting to ATS. Then, the controller _controls_ ATS by either(1) relay the information from K8s API to ATS, or (2) configure ATS directly.
-
-![How](docs/images/how-it-works.png)
+- [Architecture](https://github.com/apache/trafficserver-ingress-controller/blob/master/docs/ARCHITECTURE.md)
+- [Tutorial](https://github.com/apache/trafficserver-ingress-controller/blob/master/docs/TUTORIAL.md)
+- [Development](https://github.com/apache/trafficserver-ingress-controller/blob/master/docs/DEVELOPMENT.md)
 
 ## Versions of Software Used
 - Alpine 3.12.1
 - Apache Traffic Server 8.1.0
-- LuaJIT 2.0.4
-- Lua 5.1.4
-- Go 1.12.8
+- LuaJIT 2.0.4 / Lua 5.1.4
+- Go 1.15.3
 - Other Packages
   - luasocket 3.0rc1
   - redis-lua 2.0.4
 
-## How to use
-
-### Requirements
-- Docker
-- Kubernetes 1.18 (Minikube 1.11)
-
-To install Docker, visit its [official page](https://docs.docker.com/) and install the correct version for your system.
-
-The walkthrough uses Minikube to guide you through the setup process. Visit the [official Minikube page](https://kubernetes.io/docs/tasks/tools/install-minikube/) to install Minikube. 
-
-### Download project 
-If you are cloning this project for development, visit [Setting up Go-Lang](#setting-up-go-lang) for detailed guide on how to develop projects in Go. 
-
-For other purposes, you can use `git clone` or directly download repository to your computer.
-
-### Example Walkthrough
-Once you have cloned the project repo and started Docker and Minikube, in the terminal:
-1. `$ eval $(minikube docker-env)`
-      - To understand why we do this, please read [Use local images by re-using the docker daemon](https://kubernetes.io/docs/setup/learning-environment/minikube/#use-local-images-by-re-using-the-docker-daemon)
-2. `$ cd trafficserver-ingress-controller`
-3. `$ git submodule update --init`
-4. `$ docker build -t ats_alpine .` 
-5. `$ docker build -t tsexporter k8s/backend/trafficserver_exporter/` 
-6. `$ docker build -t node-app-1 k8s/backend/node-app-1/`    
-7. `$ docker build -t node-app-2 k8s/backend/node-app-2/`
-8. `$ docker pull fluent/fluentd:v1.6-debian-1`
-
-- At this point, we have created necessary images for our example. Let's talk about what each step does:
-  - 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.
-  - Step 5 builds an image for the trafficserver exporter. This exports the ATS statistics over HTTP for Prometheus to read. 
-  - 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
-
-9. `$ kubectl create namespace trafficserver-test`
-    - Create a namespace for ATS pod
-10. `$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=atssvc/O=atssvc"`
-    - Create a self-signed certificate
-11. `$ kubectl create secret tls tls-secret --key tls.key --cert tls.crt -n trafficserver-test --dry-run=client -o yaml | kubectl apply -f -`
-    - Create a secret in the namespace just created
-12. `$ kubectl apply -f k8s/configmaps/fluentd-configmap.yaml`
-    - Create config map for fluentd
-13. `$ kubectl apply -f k8s/traffic-server/`
-    -  will define a new [kubernetes namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) named `trafficserver-test` and deploy a single ATS pod to said namespace. The ATS pod is also where the ingress controller lives. 
-
-#### Proxy
-
-The following steps can be executed in any order, thus list numbers are not used.
-
-- `$ kubectl apply -f k8s/apps/`
-  - creates namespaces `trafficserver-test-2` and `trafficserver-test-3` if not already exist
-  - creates kubernetes services and [deployments](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) for `appsvc1` and `appsvc2`
-  - deploy 2 of each `appsvc1`, and `appsvc2` pods in `trafficserver-test-2`, totally 4 pods in said namespace.
-  - similarly, deploy 2 of each `appsvc1`, and `appsvc2` pods in `trafficserver-test-3`, totally 4 pods in this namespace. We now have 8 pods in total for the 2 services we have created and deployed in the 2 namespaces.
-
-- `$ kubectl apply -f k8s/ingresses/`
-  - creates namespaces `trafficserver-test-2` and `trafficserver-test-3` if not already exist
-  - defines an ingress resource in both `trafficserver-test-2` and `trafficserver-test-3`
-  - the ingress resource in `trafficserver-test-2` defines domain name `test.media.com` with `/app1` and `/app2` as its paths
-  - both ingress resources define domain name `test.edge.com`; however, `test.edge.com/app1` is only defined in `trafficserver-test-2` and `test.edge.com/app2` is only defined in `trafficserver-test-3`
-  - Addtionally, an ingress resources defines HTTPS access for `test.edge.com/app2` in namespace `trafficserver-test-3`
-
-When both steps _above_ have executed at least once, ATS proxying will have started to work. To see proxy in action, we can use [curl](https://linux.die.net/man/1/curl):
-
-1. `$ curl -vH "HOST:test.media.com" "$(minikube ip):30000/app1"`
-2. `$ curl -vH "HOST:test.media.com" "$(minikube ip):30000/app2"`
-3. `$ curl -vH "HOST:test.edge.com" "$(minikube ip):30000/app1"`
-4. `$ curl -vH "HOST:test.edge.com" "$(minikube ip):30000/app2"`
-5. `$ curl -vH "HOST:test.edge.com" -k "https://$(minikube ip):30043/app2"`
-
-#### ConfigMap
-
-Below is an example of configuring Apache Traffic Server [_reloadable_ configurations](https://docs.trafficserver.apache.org/en/8.0.x/admin-guide/files/records.config.en.html#reloadable) using [kubernetes configmap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) resource:
-
-- `$ kubectl apply -f k8s/configmaps/ats-configmap.yaml`
-  - create a ConfigMap resource in `trafficserver-test` with the annotation `"ats-configmap":"true"` if not already exist
-  - configure 3 _reloadable_ ATS configurations:
-    1. `proxy.config.output.logfile.rolling_enabled: "1"`
-    2. `proxy.config.output.logfile.rolling_interval_sec: "3000"`
-    3. `proxy.config.restart.active_client_threshold: "0"`
-
-#### Snippet
-
-You can attach [ATS lua script](https://docs.trafficserver.apache.org/en/8.0.x/admin-guide/plugins/lua.en.html) to an ingress object and ATS will execute it for requests matching the routing rules defined in the ingress object. See an example in annotation section of yaml file [here](k8s/ingresses/ats-ingress-2.yaml) 
-
-#### Ingress Class
-
-You can provide an environment variable called `INGRESS_CLASS` in the deployment to specify the ingress class. Only ingress object with annotation `kubernetes.io/ingress.class` with value equal to the environment variable value will be used by ATS for routing
-
-### Logging and Monitoring
-
-#### Fluentd
-
-This project ships with [Fluentd](https://docs.fluentd.org/) already integrated with the Apache Traffic Server. 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 `/usr/local/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). 
-
-#### Prometheus and Grafana
-
-Use the following steps to install [Prometheus](https://prometheus.io/docs/prometheus/latest/getting_started/) and [Grafana](https://grafana.com/docs/grafana/latest/) and use them to monitor the Apache Traffic Server statistics.
-
-1. `$ kubectl apply -f k8s/prometheus/ats-stats.yaml`
-  - Creates a new service which connects to the ATS pod on port 9122. This service will be used by Prometheus to read the Apache Traffic Server stats.  
-2. `$ kubectl apply -f k8s/configmaps/prometheus-configmap.yaml`
-  - Creates a new configmap which holds the configuration file for Prometheus. You can modify this configuration file to suit your needs. More about that can be read [here](https://prometheus.io/docs/prometheus/latest/configuration/configuration/)
-3. `$ kubectl apply -f k8s/prometheus/prometheus-deployment.yaml`
-  - Creates a new deployment consisting of Prometheus and Grafana. Also creates two new services to access prometheus and grafana. 
-4. Open `x.x.x.x:30090` in your web browser to access Prometheus where `x.x.x.x` is the IP returned by the command: `$ minikube ip` 
-5. Open `x.x.x.x:30030` in your web browser to access the Grafana dashboard where `x.x.x.x` is the IP returned by the command: `$ minikube ip`.
-6. The default credentials for logging into Grafana are `admin:admin`
-7. Click on `Add your first data source' and select Prometheus under the 'Time series databases category'
-8. Set an appropriate name for the data source and enter `localhost:9090` as the URL
-  ![New Datasource](docs/images/new-datasource.png)
-9. Click on 'Save & Test'. If everything has been installed correctly you should get a notification saying 'Data source is working'
-  ![Datasource add success](docs/images/datasource-success.png) 
-10. Click on the '+' icon in the left handside column and select 'Dashboard'
-11. Click on '+ Add new panel'
-12. Enter a PromQL query. For example if you want to add a graph showing the total number of responses over time enter `trafficserver_responses_total` and press Shift + Enter.
-  ![New Graph](docs/images/new-graph.png)
-13. Click on Apply to add the graph to your dashboard. You can similarly make add more graphs to your dashboard to suit your needs. To learn more about Grafana click [here](https://grafana.com/docs/grafana/latest/)
-
-## Development
-
-### Develop with Go-Lang in Linux
-1. Get Go-lang 1.12 from [official site](https://golang.org/dl/)
-2. Add `go` command to your PATH: `export PATH=$PATH:/usr/local/go/bin`
-3. Define GOPATH: `export GOPATH=$(go env GOPATH)`
-4. Add Go workspace to your PATH: `export PATH=$PATH:$(go env GOPATH)/bin`
-5. Define Go import Paths
-   - Go's import path is different from other languages in that all import paths are _absolute paths_. Due to this reason, it is important to set up your project paths correctly
-   - define the base path: `mkdir -p $GOPATH/src/github.com/`
-6. Clone the project:
-   - `cd $GOPATH/src/github.com/`
-   - `git clone <project>`
-7. As of Go 1.12 in order to have `go.mod` within Go paths, you must export: `export GO111MODULE=on` to be able to compile locally. 
-
-### Compilation
-To compile, type: `go build -o ingress_ats main/main.go`
-
-### Unit Tests
-The project includes unit tests for the controller written in Golang and the plugin written in Lua.
-
-To run the Golang unit tests: `go test ./watcher/ && go test ./redis/`
-
-The Lua unit tests use `busted` for testing. `busted` can be installed using `luarocks`:`luarocks install busted`. More information on how to install busted is available [here](https://olivinelabs.com/busted/). 
-> :warning: **Note that the project uses Lua 5.1 version**
-
-To run the Lua unit tests: 
-- `cd pluginats`
-- `busted connect_redis_test.lua` 
-
-### Text-Editor
-The repository comes with basic support for both [vscode](https://code.visualstudio.com/) and `vim`. 
-
-If you're using `vscode`:
-- `.vscode/settings.json` contains some basic settings for whitespaces and tabs
-- `.vscode/extensions.json` contains a few recommended extensions for this project. It is highly recommended to install the [Go extension](https://github.com/Microsoft/vscode-go) since it contains the code lint this project used during development.
-
-If you're using `vim`, a `vimrc` file with basic whitespace and tab configurations is also provided
-
diff --git a/entry.sh b/bin/entry.sh
similarity index 100%
rename from entry.sh
rename to bin/entry.sh
diff --git a/tls-config.sh b/bin/tls-config.sh
similarity index 100%
rename from tls-config.sh
rename to bin/tls-config.sh
diff --git a/tls-reload.sh b/bin/tls-reload.sh
similarity index 100%
rename from tls-reload.sh
rename to bin/tls-reload.sh
diff --git a/logging.yaml b/config/logging.yaml
similarity index 100%
rename from logging.yaml
rename to config/logging.yaml
diff --git a/logrotate.ingress b/config/logrotate.ingress
similarity index 100%
rename from logrotate.ingress
rename to config/logrotate.ingress
diff --git a/plugin.config b/config/plugin.config
similarity index 100%
rename from plugin.config
rename to config/plugin.config
diff --git a/records.config b/config/records.config
similarity index 100%
rename from records.config
rename to config/records.config
diff --git a/redis.conf b/config/redis.conf
similarity index 100%
rename from redis.conf
rename to config/redis.conf
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
new file mode 100644
index 0000000..8627808
--- /dev/null
+++ b/docs/ARCHITECTURE.md
@@ -0,0 +1,28 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+## Architecture
+[Apache Traffic Server (ATS)](https://trafficserver.apache.org/) is a high performance, open-source, caching proxy server that is scalable and configurable. This project uses ATS as a [Kubernetes(K8s)](https://kubernetes.io/) [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)
+
+![Abstract](images/abstract.png)
+
+From high-level, the ingress controller talks to K8s' API and sets up `watchers` on specific resources that are interesting to ATS. Then, the controller _controls_ ATS by either(1) relay the information from K8s API to ATS, or (2) configure ATS directly.
+
+![How](images/how-it-works.png)
+
diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md
new file mode 100644
index 0000000..e55211e
--- /dev/null
+++ b/docs/DEVELOPMENT.md
@@ -0,0 +1,57 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+## Development
+
+### Develop with Go-Lang in Linux
+1. Get Go-lang 1.15.3 from [official site](https://golang.org/dl/)
+2. Add `go` command to your PATH: `export PATH=$PATH:/usr/local/go/bin`
+3. Define GOPATH: `export GOPATH=$(go env GOPATH)`
+4. Add Go workspace to your PATH: `export PATH=$PATH:$(go env GOPATH)/bin`
+5. Define the base path: `mkdir -p $GOPATH/src/github.com/`
+6. Clone the project:
+   - `cd $GOPATH/src/github.com/`
+   - `git clone <project>`
+   - `cd <project>`
+7. Define GO111MODULE: `export GO111MODULE=on` to be able to compile locally. 
+
+### Compilation
+To compile, type: `go build -o ingress-ats main/main.go`
+
+### Unit Tests
+The project includes unit tests for the controller written in Golang and the ATS plugin written in Lua.
+
+To run the Golang unit tests: `go test ./watcher/ && go test ./redis/`
+
+The Lua unit tests use `busted` for testing. `busted` can be installed using `luarocks`:`luarocks install busted`. More information on how to install busted is available [here](https://olivinelabs.com/busted/). 
+> :warning: **Note that the project uses Lua 5.1 version**
+
+To run the Lua unit tests: 
+- `cd pluginats`
+- `busted connect_redis_test.lua` 
+
+### Text-Editor
+The repository comes with basic support for both [vscode](https://code.visualstudio.com/) and `vim`. 
+
+If you're using `vscode`:
+- `.vscode/settings.json` contains some basic settings for whitespaces and tabs
+- `.vscode/extensions.json` contains a few recommended extensions for this project.
+- It is highly recommended to install the Go extension since it contains the code lint this project used during development.
+
+If you're using `vim`, a `vimrc` file with basic whitespace and tab configurations is also provided
diff --git a/README.md b/docs/TUTORIAL.md
similarity index 62%
copy from README.md
copy to docs/TUTORIAL.md
index 9d21cc3..5aeb710 100644
--- a/README.md
+++ b/docs/TUTORIAL.md
@@ -17,82 +17,51 @@
     under the License.
 -->
 
-ATS Kubernetes Ingress Controller
-=================================
-![Test](https://github.com/apache/trafficserver-ingress-controller/workflows/Test/badge.svg)
-![Build and Integrate](https://github.com/apache/trafficserver-ingress-controller/workflows/Build%20and%20Integrate/badge.svg)
-
-## Contents
-- [Introduction](#Introduction)
-- [Versions of Software Used](#versions-of-software-used)
-- [How to use](#how-to-use)
-  - [Requirements](#requirements)
-  - [Download project](#download-project)
-  - [Example Walkthrough](#example-walkthrough)
-    - [Proxy](#proxy)
-    - [ConfigMap](#configmap)
-    - [Snippet](#snippet)
-    - [Ingress Class](#ingressclass)
-  - [Logging and Monitoring](#logging-and-monitoring)
-    - [Fluentd](#fluend)
-    - [Prometheus and Grafana](#prometheus-and-grafana)
-- [Development](#development)
-  - [Develop with Go-Lang in Linux](#develop-with-go-lang-in-linux)
-  - [Compilation](#compilation)
-  - [Unit Tests](#unit-tests)
-  - [Text-Editor](#text-editor)
-- [Documentation](#documentation)
-
-## Introduction 
-[Apache Traffic Server (ATS)](https://trafficserver.apache.org/) is a high performance, open-source, caching proxy server that is scalable and configurable. This project uses ATS as a [Kubernetes(K8s)](https://kubernetes.io/) [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)
-
-![Abstract](docs/images/abstract.png)
-
-From high-level, the ingress controller talks to K8s' API and sets up `watchers` on specific resources that are interesting to ATS. Then, the controller _controls_ ATS by either(1) relay the information from K8s API to ATS, or (2) configure ATS directly.
-
-![How](docs/images/how-it-works.png)
-
-## Versions of Software Used
-- Alpine 3.12.1
-- Apache Traffic Server 8.1.0
-- LuaJIT 2.0.4
-- Lua 5.1.4
-- Go 1.12.8
-- Other Packages
-  - luasocket 3.0rc1
-  - redis-lua 2.0.4
-
-## How to use
+## Tutorial
+- [Requirements](#requirements)
+- [Download project](#download-project)
+- [Example Walkthrough](#example-walkthrough)
+  - [Setting Up Proxy](#setting-up-proxy)
+  - [Setting Up Backend Applications](#setting-up-backend-applications)
+  - [Checking Results](#checking-results)
+  - [ConfigMap](#configmap)
+  - [Snippet](#snippet)
+  - [Ingress Class](#ingressclass)
+- [Logging and Monitoring](#logging-and-monitoring)
+  - [Fluentd](#fluend)
+  - [Prometheus and Grafana](#prometheus-and-grafana)
 
 ### Requirements
-- Docker
-- Kubernetes 1.18 (Minikube 1.11)
+- Docker 
+- Kubernetes 1.18.10 (through Minikube 1.14.2)
 
 To install Docker, visit its [official page](https://docs.docker.com/) and install the correct version for your system.
 
 The walkthrough uses Minikube to guide you through the setup process. Visit the [official Minikube page](https://kubernetes.io/docs/tasks/tools/install-minikube/) to install Minikube. 
 
 ### Download project 
-If you are cloning this project for development, visit [Setting up Go-Lang](#setting-up-go-lang) for detailed guide on how to develop projects in Go. 
-
-For other purposes, you can use `git clone` or directly download repository to your computer.
+You can use `git clone` to download repository to your computer.
 
 ### Example Walkthrough
+
+#### Setting Up Proxy
+
 Once you have cloned the project repo and started Docker and Minikube, in the terminal:
 1. `$ eval $(minikube docker-env)`
       - To understand why we do this, please read [Use local images by re-using the docker daemon](https://kubernetes.io/docs/setup/learning-environment/minikube/#use-local-images-by-re-using-the-docker-daemon)
 2. `$ cd trafficserver-ingress-controller`
 3. `$ git submodule update --init`
-4. `$ docker build -t ats_alpine .` 
-5. `$ docker build -t tsexporter k8s/backend/trafficserver_exporter/` 
-6. `$ docker build -t node-app-1 k8s/backend/node-app-1/`    
-7. `$ docker build -t node-app-2 k8s/backend/node-app-2/`
+4. `$ docker build -t ats-ingress .` 
+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`
 
-- At this point, we have created necessary images for our example. Let's talk about what each step does:
+- 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.
   - Step 5 builds an image for the trafficserver exporter. This exports the ATS statistics over HTTP for Prometheus to read. 
   - 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`
     - Create a namespace for ATS pod
@@ -103,9 +72,14 @@ Once you have cloned the project repo and started Docker and Minikube, in the te
 12. `$ kubectl apply -f k8s/configmaps/fluentd-configmap.yaml`
     - Create config map for fluentd
 13. `$ kubectl apply -f k8s/traffic-server/`
-    -  will define a new [kubernetes namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) named `trafficserver-test` and deploy a single ATS pod to said namespace. The ATS pod is also where the ingress controller lives. 
 
-#### Proxy
+- Now we have an ATS running inside the cluster. 
+  - Step 9 creates a namespace for ATS pod.
+  - Steps 10 and 11 create a self-signed SSL certificate and keep it in a secret inside the namespace above.
+  - Step 12 provides the ConfigMap for configuration options for fluentd
+  - Step 13 deploys a single ATS pod to said namespace. The ATS pod is also where the ingress controller lives. 
+
+#### Setting Up Backend Applications
 
 The following steps can be executed in any order, thus list numbers are not used.
 
@@ -122,7 +96,9 @@ The following steps can be executed in any order, thus list numbers are not used
   - both ingress resources define domain name `test.edge.com`; however, `test.edge.com/app1` is only defined in `trafficserver-test-2` and `test.edge.com/app2` is only defined in `trafficserver-test-3`
   - Addtionally, an ingress resources defines HTTPS access for `test.edge.com/app2` in namespace `trafficserver-test-3`
 
-When both steps _above_ have executed at least once, ATS proxying will have started to work. To see proxy in action, we can use [curl](https://linux.die.net/man/1/curl):
+#### Checking Results
+
+ATS proxying should have started to work. To see proxy in action, we can use [curl](https://linux.die.net/man/1/curl):
 
 1. `$ curl -vH "HOST:test.media.com" "$(minikube ip):30000/app1"`
 2. `$ curl -vH "HOST:test.media.com" "$(minikube ip):30000/app2"`
@@ -130,6 +106,11 @@ When both steps _above_ have executed at least once, ATS proxying will have star
 4. `$ curl -vH "HOST:test.edge.com" "$(minikube ip):30000/app2"`
 5. `$ curl -vH "HOST:test.edge.com" -k "https://$(minikube ip):30043/app2"`
 
+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> 30043:443 -n trafficserver-test`
+- `$ kubectl port-forward <pod name> 30000:80 -n trafficserver-test`
+
 #### ConfigMap
 
 Below is an example of configuring Apache Traffic Server [_reloadable_ configurations](https://docs.trafficserver.apache.org/en/8.0.x/admin-guide/files/records.config.en.html#reloadable) using [kubernetes configmap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) resource:
@@ -143,7 +124,7 @@ Below is an example of configuring Apache Traffic Server [_reloadable_ configura
 
 #### Snippet
 
-You can attach [ATS lua script](https://docs.trafficserver.apache.org/en/8.0.x/admin-guide/plugins/lua.en.html) to an ingress object and ATS will execute it for requests matching the routing rules defined in the ingress object. See an example in annotation section of yaml file [here](k8s/ingresses/ats-ingress-2.yaml) 
+You can attach [ATS lua script](https://docs.trafficserver.apache.org/en/8.0.x/admin-guide/plugins/lua.en.html) to an ingress object and ATS will execute it for requests matching the routing rules defined in the ingress object. See an example in annotation section of yaml file [here](../k8s/ingresses/ats-ingress-2.yaml) 
 
 #### Ingress Class
 
@@ -153,7 +134,7 @@ You can provide an environment variable called `INGRESS_CLASS` in the deployment
 
 #### Fluentd
 
-This project ships with [Fluentd](https://docs.fluentd.org/) already integrated with the Apache Traffic Server. The configuration file used for the same can be found [here](k8s/configmaps/fluentd-configmap.yaml)
+This project ships with [Fluentd](https://docs.fluentd.org/) already integrated with the Apache Traffic Server. 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 `/usr/local/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). 
 
@@ -172,51 +153,12 @@ Use the following steps to install [Prometheus](https://prometheus.io/docs/prome
 6. The default credentials for logging into Grafana are `admin:admin`
 7. Click on `Add your first data source' and select Prometheus under the 'Time series databases category'
 8. Set an appropriate name for the data source and enter `localhost:9090` as the URL
-  ![New Datasource](docs/images/new-datasource.png)
+  ![New Datasource](images/new-datasource.png)
 9. Click on 'Save & Test'. If everything has been installed correctly you should get a notification saying 'Data source is working'
-  ![Datasource add success](docs/images/datasource-success.png) 
+  ![Datasource add success](images/datasource-success.png) 
 10. Click on the '+' icon in the left handside column and select 'Dashboard'
 11. Click on '+ Add new panel'
 12. Enter a PromQL query. For example if you want to add a graph showing the total number of responses over time enter `trafficserver_responses_total` and press Shift + Enter.
-  ![New Graph](docs/images/new-graph.png)
+  ![New Graph](images/new-graph.png)
 13. Click on Apply to add the graph to your dashboard. You can similarly make add more graphs to your dashboard to suit your needs. To learn more about Grafana click [here](https://grafana.com/docs/grafana/latest/)
 
-## Development
-
-### Develop with Go-Lang in Linux
-1. Get Go-lang 1.12 from [official site](https://golang.org/dl/)
-2. Add `go` command to your PATH: `export PATH=$PATH:/usr/local/go/bin`
-3. Define GOPATH: `export GOPATH=$(go env GOPATH)`
-4. Add Go workspace to your PATH: `export PATH=$PATH:$(go env GOPATH)/bin`
-5. Define Go import Paths
-   - Go's import path is different from other languages in that all import paths are _absolute paths_. Due to this reason, it is important to set up your project paths correctly
-   - define the base path: `mkdir -p $GOPATH/src/github.com/`
-6. Clone the project:
-   - `cd $GOPATH/src/github.com/`
-   - `git clone <project>`
-7. As of Go 1.12 in order to have `go.mod` within Go paths, you must export: `export GO111MODULE=on` to be able to compile locally. 
-
-### Compilation
-To compile, type: `go build -o ingress_ats main/main.go`
-
-### Unit Tests
-The project includes unit tests for the controller written in Golang and the plugin written in Lua.
-
-To run the Golang unit tests: `go test ./watcher/ && go test ./redis/`
-
-The Lua unit tests use `busted` for testing. `busted` can be installed using `luarocks`:`luarocks install busted`. More information on how to install busted is available [here](https://olivinelabs.com/busted/). 
-> :warning: **Note that the project uses Lua 5.1 version**
-
-To run the Lua unit tests: 
-- `cd pluginats`
-- `busted connect_redis_test.lua` 
-
-### Text-Editor
-The repository comes with basic support for both [vscode](https://code.visualstudio.com/) and `vim`. 
-
-If you're using `vscode`:
-- `.vscode/settings.json` contains some basic settings for whitespaces and tabs
-- `.vscode/extensions.json` contains a few recommended extensions for this project. It is highly recommended to install the [Go extension](https://github.com/Microsoft/vscode-go) since it contains the code lint this project used during development.
-
-If you're using `vim`, a `vimrc` file with basic whitespace and tab configurations is also provided
-
diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go
index 73fc74d..b84bb3b 100644
--- a/endpoint/endpoint.go
+++ b/endpoint/endpoint.go
@@ -16,21 +16,9 @@
 package endpoint
 
 import (
-	//	"fmt"
-	//	"log"
-
-	//	corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
-
-	//	v1beta1 "k8s.io/api/extensions/v1beta1"
-	//	extensionsV1beta1 "k8s.io/client-go/kubernetes/typed/extensions/v1beta1"
-
-	//	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
 	"ingress-ats/namespace"
 	"ingress-ats/proxy"
 	"ingress-ats/redis"
-	//	t "ingress-ats/types"
-	//	"ingress-ats/util"
 )
 
 const (
diff --git a/go.mod b/go.mod
index b04380f..1ee648c 100644
--- a/go.mod
+++ b/go.mod
@@ -1,21 +1,11 @@
 module ingress-ats
 
-go 1.12
+go 1.15
 
 require (
-	github.com/deckarep/golang-set v1.7.1
-	github.com/go-redis/redis v6.15.2+incompatible
-	github.com/golang/protobuf v1.3.1 // indirect
-	github.com/googleapis/gnostic v0.3.0 // indirect
-	github.com/imdario/mergo v0.3.7 // indirect
-	golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 // indirect
-	golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect
-	golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect
-	golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
-	k8s.io/api v0.0.0-20190626000116-b178a738ed00
-	k8s.io/apimachinery v0.0.0-20190624085041-961b39a1baa0
-	k8s.io/client-go v0.0.0-20190626045420-1ec4b74c7bda
-	k8s.io/klog v0.3.3 // indirect
-	k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a // indirect
 	github.com/alicebob/miniredis/v2 v2.13.0
+	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
 )
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..269f011
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,225 @@
+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=
+github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
+github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
+github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
+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/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
+github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+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/urlesc v0.0.0-20160726150825-5bd2802263f2/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/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/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=
+github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
+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/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/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/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-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
+github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
+github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
+github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
+github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
+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/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/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/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.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+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=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+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/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/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
+github.com/google/uuid v1.1.1/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/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/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
+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=
+github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
+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/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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
+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/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+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/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+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=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
+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/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=
+github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
+github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
+github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+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/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/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=
+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-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
+golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+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/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=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+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-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/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/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/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-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-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU=
+golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/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/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/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-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+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/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/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+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/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=
+gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+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=
+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=
+k8s.io/api v0.18.10 h1:M0/vqfuBAIIS7jsOOcosT0niiotZGqw6/zHTFpyi8iQ=
+k8s.io/api v0.18.10/go.mod h1:xWtwPX1v47j5RTncmlMFGCx8b0avh+nP8OgZZ9hjo3M=
+k8s.io/apimachinery v0.18.10 h1:Zupk3lPrUfhCF9puTpA8EvEfPsrhNZtrpOqdp66mKVs=
+k8s.io/apimachinery v0.18.10/go.mod h1:PF5taHbXgTEJLU+xMypMmYTXTWPJ5LaW8bfsisxnEXk=
+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/gengo v0.0.0-20190128074634-0689ccc1d7d6/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/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/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU=
+k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
+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/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=
+sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
diff --git a/k8s/backend/node-app-2/.dockerignore b/k8s/images/node-app-1/.dockerignore
similarity index 100%
rename from k8s/backend/node-app-2/.dockerignore
rename to k8s/images/node-app-1/.dockerignore
diff --git a/k8s/backend/node-app-2/Dockerfile b/k8s/images/node-app-1/Dockerfile
similarity index 100%
rename from k8s/backend/node-app-2/Dockerfile
rename to k8s/images/node-app-1/Dockerfile
diff --git a/k8s/backend/node-app-1/hello-updated.html b/k8s/images/node-app-1/hello-updated.html
similarity index 100%
rename from k8s/backend/node-app-1/hello-updated.html
rename to k8s/images/node-app-1/hello-updated.html
diff --git a/k8s/backend/node-app-1/hello.html b/k8s/images/node-app-1/hello.html
similarity index 100%
rename from k8s/backend/node-app-1/hello.html
rename to k8s/images/node-app-1/hello.html
diff --git a/k8s/backend/node-app-2/package-lock.json b/k8s/images/node-app-1/package-lock.json
similarity index 100%
rename from k8s/backend/node-app-2/package-lock.json
rename to k8s/images/node-app-1/package-lock.json
diff --git a/k8s/backend/node-app-2/package.json b/k8s/images/node-app-1/package.json
similarity index 100%
rename from k8s/backend/node-app-2/package.json
rename to k8s/images/node-app-1/package.json
diff --git a/k8s/backend/node-app-1/server.js b/k8s/images/node-app-1/server.js
similarity index 100%
rename from k8s/backend/node-app-1/server.js
rename to k8s/images/node-app-1/server.js
diff --git a/k8s/backend/node-app-1/.dockerignore b/k8s/images/node-app-2/.dockerignore
similarity index 100%
rename from k8s/backend/node-app-1/.dockerignore
rename to k8s/images/node-app-2/.dockerignore
diff --git a/k8s/backend/node-app-1/Dockerfile b/k8s/images/node-app-2/Dockerfile
similarity index 100%
rename from k8s/backend/node-app-1/Dockerfile
rename to k8s/images/node-app-2/Dockerfile
diff --git a/k8s/backend/node-app-2/hello.html b/k8s/images/node-app-2/hello.html
similarity index 100%
rename from k8s/backend/node-app-2/hello.html
rename to k8s/images/node-app-2/hello.html
diff --git a/k8s/backend/node-app-1/package-lock.json b/k8s/images/node-app-2/package-lock.json
similarity index 100%
rename from k8s/backend/node-app-1/package-lock.json
rename to k8s/images/node-app-2/package-lock.json
diff --git a/k8s/backend/node-app-1/package.json b/k8s/images/node-app-2/package.json
similarity index 100%
rename from k8s/backend/node-app-1/package.json
rename to k8s/images/node-app-2/package.json
diff --git a/k8s/backend/node-app-2/server.js b/k8s/images/node-app-2/server.js
similarity index 100%
rename from k8s/backend/node-app-2/server.js
rename to k8s/images/node-app-2/server.js
diff --git a/k8s/backend/trafficserver_exporter b/k8s/images/trafficserver_exporter
similarity index 100%
rename from k8s/backend/trafficserver_exporter
rename to k8s/images/trafficserver_exporter
diff --git a/k8s/traffic-server/ats-deployment.yaml b/k8s/traffic-server/ats-deployment.yaml
index 35434c3..82b0697 100644
--- a/k8s/traffic-server/ats-deployment.yaml
+++ b/k8s/traffic-server/ats-deployment.yaml
@@ -45,7 +45,7 @@ spec:
     spec:
       containers:
         - name: trafficserver-test
-          image: ats_alpine:latest # Needs to be updated
+          image: ats-ingress:latest # Needs to be updated
           volumeMounts:
             - mountPath: "/etc/ats/ssl"
               name: ats-ssl
@@ -87,7 +87,7 @@ spec:
           - name: config-volume
             mountPath: "/fluentd/etc"
         - name: trafficserver-exporter
-          image: tsexporter:latest
+          image: ats-ingress-exporter:latest
           imagePullPolicy: IfNotPresent
           ports:
           - containerPort: 9122
@@ -124,4 +124,4 @@ spec:
     targetPort: 443
     nodePort: 30043
   selector:
-    app: trafficserver-test
\ No newline at end of file
+    app: trafficserver-test
diff --git a/namespace/namespace.go b/namespace/namespace.go
index 7b09ac0..521d138 100644
--- a/namespace/namespace.go
+++ b/namespace/namespace.go
@@ -15,8 +15,6 @@
 
 package namespace
 
-// import v1 "k8s.io/api/core/v1"
-
 // ALL Namespaces constant for unified text
 const ALL string = "all"
 
diff --git a/redis/redis.go b/redis/redis.go
index 1661137..be37067 100644
--- a/redis/redis.go
+++ b/redis/redis.go
@@ -19,8 +19,6 @@ import (
 	"fmt"
 	"log"
 
-	//	"sync"
-
 	"github.com/alicebob/miniredis/v2"
 	"github.com/go-redis/redis"
 )
diff --git a/tests/data/setup/traffic-server/ats-deployment.yaml b/tests/data/setup/traffic-server/ats-deployment.yaml
index 15fc4d1..f4b29fb 100644
--- a/tests/data/setup/traffic-server/ats-deployment.yaml
+++ b/tests/data/setup/traffic-server/ats-deployment.yaml
@@ -46,7 +46,7 @@ spec:
 
       containers:
         - name: trafficserver-test
-          image: ats_alpine:latest # Needs to be updated
+          image: ats-ingress:latest # Needs to be updated
           volumeMounts:
             - mountPath: "/etc/ats/ssl"
               name: ats-ssl
@@ -84,7 +84,7 @@ spec:
           - name: config-volume
             mountPath: "/fluentd/etc"
         - name: trafficserver-exporter
-          image: tsexporter:latest
+          image: ats-ingress-exporter:latest
           imagePullPolicy: IfNotPresent
           ports:
           - containerPort: 9122
@@ -119,4 +119,4 @@ spec:
     targetPort: 443
     nodePort: 30043
   selector:
-    app: trafficserver-test
\ No newline at end of file
+    app: trafficserver-test
diff --git a/types/metadataManagers.go b/types/metadataManagers.go
deleted file mode 100644
index 0a6e401..0000000
--- a/types/metadataManagers.go
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-*/
-
-package types
-
-import (
-	"encoding/json"
-	"sync"
-
-	"ingress-ats/util"
-
-	set "github.com/deckarep/golang-set"
-)
-
-//----------------- nsSvc ---------------------------------
-
-// map[namespace]map[svc][]PathPtr
-type nsSvc struct {
-	// ns -> []svc -> []*path
-	NsToSvc map[string]*svcPaths
-	mux     sync.RWMutex
-}
-
-// newNsSvc creates a new empty nsSvc
-func newNsSvc() *nsSvc {
-	return &nsSvc{
-		NsToSvc: make(map[string]*svcPaths),
-	}
-}
-
-// SetNamespaceSvcPaths adds or sets a path/svc within namespace
-func (n *nsSvc) SetNamespaceSvcPaths(namespace string, pathPtr *Path) {
-	n.mux.Lock()
-	if svcPathsPtr, found := n.NsToSvc[namespace]; found {
-		svcPathsPtr.AddSvcPath(pathPtr)
-	} else {
-		newSvcPaths := newSvcPaths()
-		newSvcPaths.AddSvcPath(pathPtr)
-		n.NsToSvc[namespace] = newSvcPaths
-	}
-	n.mux.Unlock()
-}
-
-// DelNamespaceSvcPath deletes a Path ptr from namespace
-func (n *nsSvc) DelNamespaceSvcPath(pathPtr *Path) {
-	n.mux.Lock()
-	defer n.mux.Unlock()
-	namespace := pathPtr.GetNamespace()
-	if svcPathsPtr, found := n.NsToSvc[namespace]; found {
-		deletedSvc := svcPathsPtr.DelSvcPath(pathPtr)
-		if deletedSvc && svcPathsPtr.NumSvc() == 0 {
-			// when ns has no ingress defined deployed service
-			delete(n.NsToSvc, namespace)
-		}
-	}
-}
-
-// NumNamespace returns the number of namespaces being managed
-func (n *nsSvc) NumNamespace() int {
-	n.mux.RLock()
-	defer n.mux.RUnlock()
-	return len(n.NsToSvc)
-}
-
-// HasSvc returns true if namespace exists, and svc exists in
-// same namespace
-func (n *nsSvc) HasSvc(namespace, svcName string) bool {
-	n.mux.RLock()
-	defer n.mux.RUnlock()
-	if svcPaths, found := n.NsToSvc[namespace]; found {
-		return svcPaths.Has(svcName)
-	}
-	return false
-}
-
-// NumHostPathInNamespace returns number of paths of hostName are in namespace
-// TODO: can add more metadata in the future to make this faster
-func (n *nsSvc) NoHostPathInNamespace(hostName, pathName, namespace string) bool {
-	res := 0
-	n.mux.RLock()
-	svcPathsPtr := n.NsToSvc[namespace]
-	n.mux.RUnlock()
-	svcPathsPtr.rLock()
-	for _, pathSet := range svcPathsPtr.StoPs {
-		for path := range pathSet.Iter() {
-			pathPtr := path.(*Path)
-			if pathPtr.GetHostName() == hostName &&
-				pathPtr.GetPathName() == pathName {
-				res++
-			}
-		}
-	}
-	svcPathsPtr.rUnlock()
-	return res == 0
-}
-
-// Iter returns a rangable channel of all Paths using svc, within namespace
-func (n *nsSvc) Iter(namespace, svc string) <-chan interface{} {
-	n.mux.RLock()
-	defer n.mux.RUnlock()
-	return n.NsToSvc[namespace].Iter(svc)
-}
-
-func (n *nsSvc) String() string {
-	n.mux.RLock()
-	defer n.mux.RUnlock()
-	marshalled, _ := json.Marshal(n)
-	return util.FmtMarshalled(marshalled)
-}
-
-//----------------- svcPaths ------------------------------
-
-// serviceName -> []PathPtr
-type svcPaths struct {
-	StoPs map[string]set.Set `json:"StoPs"` // svcName -> []Pathptr
-	mux   sync.RWMutex
-}
-
-// newSvcPaths returns a new empty SvcPaths struct ptr
-func newSvcPaths() *svcPaths {
-	return &svcPaths{StoPs: make(map[string]set.Set)}
-}
-
-func (s *svcPaths) rLock() {
-	s.mux.RLock()
-}
-
-func (s *svcPaths) rUnlock() {
-	s.mux.RUnlock()
-}
-
-// checkAddSvc adds/initialize svc if not stored
-func (s *svcPaths) checkAddSvc(svc string) {
-	s.mux.Lock()
-	if _, found := s.StoPs[svc]; !found {
-		s.StoPs[svc] = set.NewSet()
-	}
-	s.mux.Unlock()
-}
-
-// AddSvcPath adds a Mapping svc --> PathPtr safely
-func (s *svcPaths) AddSvcPath(pathPtr *Path) {
-	// path cannot be updated during this operation
-	pathPtr.RLock()
-	s.checkAddSvc(pathPtr.ServiceName)
-	// v ^ order here cannot switch!
-	s.mux.RLock()
-	s.StoPs[pathPtr.ServiceName].Add(pathPtr)
-	s.mux.RUnlock()
-	pathPtr.RUnlock()
-}
-
-// DelSvcPath deletes a path ptr associated with svc
-// returns true if svc no longer referenced by any path/backend and is deleted
-func (s *svcPaths) DelSvcPath(pathPtr *Path) (deletedSvc bool) {
-	s.mux.Lock()
-	pathPtr.RLock() // path cannot be updated during this operation
-	defer pathPtr.RUnlock()
-	defer s.mux.Unlock()
-	svc := pathPtr.ServiceName
-	if _, found := s.StoPs[svc]; found {
-		s.StoPs[svc].Remove(pathPtr)
-		// if svc no longer needed by any backend
-		if s.StoPs[svc].Cardinality() == 0 {
-			delete(s.StoPs, svc)
-			return true
-		}
-	}
-	return false
-
-}
-
-// Iter returns a channel of path ptrs associated with svc
-// this is meant to be used with "range"
-func (s *svcPaths) Iter(svc string) <-chan interface{} {
-	s.mux.RLock()
-	defer s.mux.RUnlock()
-	return s.StoPs[svc].Iter() // this itself is threadsafe
-}
-
-// Has returns whether the svc is stored
-func (s *svcPaths) Has(svc string) bool {
-	s.mux.RLock()
-	defer s.mux.RUnlock()
-	_, found := s.StoPs[svc]
-	return found
-}
-
-// NumSvc returns number of svcs stored
-func (s *svcPaths) NumSvc() int {
-	s.mux.RLock()
-	defer s.mux.RUnlock()
-	return len(s.StoPs)
-}
-
-func (s *svcPaths) String() string {
-	s.mux.RLock()
-	defer s.mux.RUnlock()
-	marshalled, _ := json.Marshal(s)
-	return util.FmtMarshalled(marshalled)
-}
-
-//----------------- hostNamespaces ------------------------
-
-// hostName -> []namespace
-type hostNamespaces struct {
-	HtoN map[string]set.Set
-	mux  sync.RWMutex
-}
-
-// newHostNamespaces returns a new empty hostNamespaces struct
-func newHostNamespaces() *hostNamespaces {
-	return &hostNamespaces{
-		HtoN: make(map[string]set.Set),
-	}
-}
-
-// checkInit checks of hostName is initialized in map
-func (h *hostNamespaces) checkInit(hostName string) {
-	h.mux.Lock()
-	if _, found := h.HtoN[hostName]; !found {
-		h.HtoN[hostName] = set.NewSet()
-	}
-	h.mux.Unlock()
-}
-
-// AddNamespace adds namespace to hostname's set of namespaces
-// that it belongs to
-func (h *hostNamespaces) AddNamespace(hostName, namespace string) {
-	h.checkInit(hostName)
-	h.mux.RLock()
-	h.HtoN[hostName].Add(namespace)
-	h.mux.RUnlock()
-}
-
-// DelNamespace deletes namespace from hostname's set of namespaces
-// if host no longer belongs in any namespace, function will clear hostname
-// from its map and return true.
-func (h *hostNamespaces) DelNamespace(hostName, namespace string) (deletedHost bool) {
-	h.mux.Lock()
-	defer h.mux.Unlock()
-	_, found := h.HtoN[hostName]
-	if found {
-		h.HtoN[hostName].Remove(namespace)
-		if h.HtoN[hostName].Cardinality() == 0 {
-			delete(h.HtoN, hostName)
-			return true
-		}
-	}
-	return false
-}
-
-// hostPathInNamespace returns true if host has a path in namespace
-func (h *hostNamespaces) hostPathInNamespace(hostName, namespace string) bool {
-	h.mux.RLock()
-	defer h.mux.RUnlock()
-	_, found := h.HtoN[hostName]
-	if found {
-		return h.HtoN[hostName].Contains(namespace)
-	}
-	return false
-}
-
-// hostOnlyInNamespace returns true if host only has path(s) in namespace
-// and nowhere else
-func (h *hostNamespaces) hostOnlyInNamespace(hostName, namespace string) bool {
-	h.mux.RLock()
-	defer h.mux.RUnlock()
-	_, found := h.HtoN[hostName]
-	if !found {
-		// returning false here because host might
-		// very well be deleted by another thread before this function
-		// got ran; in which case, return false so caller don't do
-		// anything that might be dangerous
-		return false
-	}
-	return h.HtoN[hostName].Cardinality() == 1 &&
-		h.HtoN[hostName].Contains(namespace)
-
-}
diff --git a/types/types.go b/types/types.go
deleted file mode 100644
index b7cf504..0000000
--- a/types/types.go
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-*/
-
-package types
-
-import (
-	"encoding/json"
-	"log"
-	"sync"
-
-	"ingress-ats/util"
-	// set.NewSet() is threadsafe from this package
-	set "github.com/deckarep/golang-set"
-)
-
-// ControllerConfig is the outmost struct storing everything
-// as part of the outputs
-type ControllerConfig struct {
-	// Annotations []SSPair     `json:"annotations"`
-	ConfigGroup *ConfigGroup `json:"configgroup"`
-	HostGroup   *HostGroup   `json:"hostgroup"`
-}
-
-//---------------------------------------------------------
-//----------------- ConfigGroup ---------------------------
-//---------------------------------------------------------
-
-// ConfigGroup stores all ConfigMap settings for ATS
-type ConfigGroup struct {
-	ConfigMap *configMap `json:"configmaps"`
-}
-
-// NewConfigGroup returns an empty new ConfigGroup struct
-func NewConfigGroup() *ConfigGroup {
-	return &ConfigGroup{
-		ConfigMap: newConfigMap(),
-	}
-}
-
-//----------------- ConfigMap -----------------------------
-
-// ConfigMap stores one Configmap
-type configMap struct {
-	Annotations map[string]string `json:"annotations"`
-	Data        map[string]string `json:"data"`
-	mux         sync.RWMutex
-}
-
-type filter func(string) bool
-
-// this is possible because map in Go are references
-func (c *configMap) load(dest, src map[string]string, fn filter) {
-	c.mux.Lock()
-	for k, v := range src {
-		if fn(k) {
-			dest[k] = v
-		}
-	}
-	c.mux.Unlock()
-}
-
-// LoadAnnotations loads everything in input map safely
-func (c *configMap) LoadAnnotations(input map[string]string, fn filter) {
-	c.load(c.Annotations, input, fn)
-}
-
-// LoadData loads everything in input map safely
-func (c *configMap) LoadData(input map[string]string, fn filter) {
-	c.load(c.Data, input, fn)
-}
-
-// DelFromData deletes a key from Data
-func (c *configMap) DelFromData(key string) {
-	c.mux.Lock()
-	delete(c.Data, key)
-	c.mux.Unlock()
-}
-
-// HasKeyVal returns whether this ConfigMap contains a key mapped to val
-func (c *configMap) HasKeyVal(key, val string) bool {
-	c.mux.RLock()
-	defer c.mux.RUnlock()
-	if v, found := c.Data[key]; found {
-		return v == val
-	}
-	return false
-}
-
-// SetData does add and update
-func (c *configMap) SetData(k, v string) {
-	c.mux.Lock()
-	c.Data[k] = v
-	c.mux.Unlock()
-}
-
-// String is toString
-func (c *configMap) String() string {
-	c.mux.RLock()
-	defer c.mux.RUnlock()
-	marshalled, _ := json.Marshal(c)
-	return util.FmtMarshalled(marshalled)
-}
-
-// NewConfigMap creates a new empty ConfigMap struct
-func newConfigMap() *configMap {
-	return &configMap{
-		Annotations: make(map[string]string),
-		Data:        make(map[string]string)}
-}
-
-//---------------------------------------------------------
-//----------------- HostGroup -----------------------------
-//---------------------------------------------------------
-
-// TODO: HostGroup methods should orchestrate everything
-// under it, as well as updating both Hosts, and ServiceMgr
-
-// HostGroup is a collection of Hosts
-type HostGroup struct {
-	Hosts      map[string]*Host `json:"hosts"` // different Hosts e.g. test.akomljen.com
-	ServiceMgr *nsSvc           `json:"-"`
-	HostNsMgr  *hostNamespaces  `json:"-"`
-	mux        sync.RWMutex
-}
-
-// NewHostGroup returns an empty HostGroup struct
-func NewHostGroup() *HostGroup {
-	return &HostGroup{
-		Hosts:      make(map[string]*Host),
-		ServiceMgr: newNsSvc(),
-		HostNsMgr:  newHostNamespaces(),
-	}
-}
-
-// hasHost returns true if hostName is already stored in HostGroup
-func (h *HostGroup) hasHost(hostName string) bool {
-	h.mux.RLock()
-	defer h.mux.RUnlock()
-	_, found := h.Hosts[hostName]
-	return found
-}
-
-// AddHost adds a new Host -> HostPtr to HostGroup
-func (h *HostGroup) AddHost(hostName string, hostPtr *Host) {
-	if h.hasHost(hostName) {
-		log.Panicf("HostGroup::AddHost(%s) existing host", hostName)
-	}
-	h.mux.Lock()
-	h.Hosts[hostName] = hostPtr
-	h.mux.Unlock()
-}
-
-// DelHost safely deletes a hostName
-func (h *HostGroup) DelHost(hostName string) {
-	h.mux.RLock()
-	targetHost := h.Hosts[hostName]
-	h.mux.RUnlock()
-	targetHost.lock()
-	for _, pathPtr := range targetHost.Paths {
-		h.ServiceMgr.DelNamespaceSvcPath(pathPtr)
-	}
-	targetHost.unlock()
-	h.mux.Lock()
-	delete(h.Hosts, hostName)
-	h.mux.Unlock()
-}
-
-// GetHost returns Host of hostName
-func (h *HostGroup) GetHost(hostName string) *Host {
-	h.mux.RLock()
-	defer h.mux.RUnlock()
-	return h.Hosts[hostName]
-}
-
-// HostPathInNamespace returns true if host belongs in namespace
-func (h *HostGroup) HostPathInNamespace(hostName, namespace string) bool {
-	return h.HostNsMgr.hostPathInNamespace(hostName, namespace)
-}
-
-// HostOnlyInNamespace returns true if host only has path(s) in namespace
-// and nowhere else
-func (h *HostGroup) HostOnlyInNamespace(hostName, namespace string) bool {
-	return h.HostNsMgr.hostOnlyInNamespace(hostName, namespace)
-}
-
-//----------------- Host ----------------------------------
-
-// Host stores a host name to ALL of its paths
-// From Ingress Resource
-// NOTE: if too many paths exist e.g. x/  x/y  x/y/z etc. maybe implement trees
-type Host struct { // a single Host
-	HostName string           `json:"hostname"` // host name
-	Paths    map[string]*Path `json:"paths"`    // a list of paths
-	mux      sync.RWMutex
-}
-
-// NewHost returns a new empty Host struct
-func NewHost(hostName string) *Host {
-	return &Host{
-		HostName: hostName,
-		Paths:    make(map[string]*Path),
-	}
-}
-
-// lock locks up Host
-func (h *Host) lock() {
-	h.mux.Lock()
-}
-
-// unlock once done
-func (h *Host) unlock() {
-	h.mux.Unlock()
-}
-
-// hasPath return true if path exists under Host
-func (h *Host) hasPath(pathName string) bool {
-	h.mux.RLock()
-	defer h.mux.RUnlock()
-	_, found := h.Paths[pathName]
-	return found
-}
-
-// GetPath safely returns the Path ptr under pathName
-func (h *Host) GetPath(pathName string) *Path {
-	h.mux.RLock()
-	defer h.mux.RUnlock()
-	return h.Paths[pathName]
-}
-
-// AddPath adds a new pathName -> pathPtr
-func (h *Host) AddPath(pathName string, pathPtr *Path) {
-	if h.hasPath(pathName) {
-		log.Panicf("Host::AddPath(%s, pathPtr) already exists", pathName)
-	}
-	h.mux.Lock()
-	h.Paths[pathName] = pathPtr
-	h.mux.Unlock()
-}
-
-// DelPath safely deletes a pathName
-func (h *Host) DelPath(pathName string) {
-	h.mux.Lock()
-	delete(h.Paths, pathName)
-	h.mux.Unlock()
-}
-
-// HasDuplicatePath returns true if pathName is defined in a namespace that is
-// *different* from newNamespace
-func (h *Host) HasDuplicatePath(pathName, newNamespace string) bool {
-	h.mux.RLock()
-	defer h.mux.RUnlock()
-	if pathPtr, found := h.Paths[pathName]; found {
-		return pathPtr.GetNamespace() != newNamespace
-	}
-	return false
-}
-
-//----------------- Path ----------------------------------
-
-// Path is a specific path e.g. /api that stores some request data
-// as well as services associated with the path.
-// From Ingress Resource
-type Path struct { // A single Path
-	HostName    string  `json:"hostname"`    // host name of this path
-	PathName    string  `json:"pathname"`    // path name
-	Namespace   string  `json:"namespace"`   // namespace this path is in
-	ServiceName string  `json:"servicename"` // service name associated with path name
-	ServicePort string  `json:"serviceport"` // port of referenced service
-	Server      *Server `json:"server"`      // A list of services
-	mux         sync.RWMutex
-}
-
-// NewPath constructs and returns a ptr to a new path struct
-func NewPath(hostName, pathName, namespace, serviceName, servicePort string,
-	server *Server) *Path {
-	return &Path{
-		HostName:    hostName,
-		PathName:    pathName,
-		Namespace:   namespace,
-		ServiceName: serviceName,
-		ServicePort: servicePort,
-		Server:      server,
-	}
-}
-
-func (p *Path) String() string {
-	p.mux.RLock()
-	defer p.mux.RUnlock()
-	marshalled, _ := json.Marshal(p)
-	return util.FmtMarshalled(marshalled)
-}
-
-// RLock used by other struct
-func (p *Path) RLock() {
-	p.mux.RLock()
-}
-
-// RUnlock when done
-func (p *Path) RUnlock() {
-	p.mux.RUnlock()
-}
-
-// GetHostName returns HostName of this Path
-// this never changes, no locking
-func (p *Path) GetHostName() string {
-	return p.HostName
-}
-
-// GetPathName returns Path Name of this Path
-// this never changes, no locking
-func (p *Path) GetPathName() string {
-	return p.PathName
-}
-
-// GetNamespace returns the namespace this Path belongs to
-// this never changes, no locking
-func (p *Path) GetNamespace() string {
-	return p.Namespace
-}
-
-// GetServiceName returns serviceName of this Path
-func (p *Path) GetServiceName() string {
-	p.mux.RLock()
-	defer p.mux.RUnlock()
-	return p.ServiceName
-}
-
-// SetService safely sets the serviceName of this Path
-// this also includes updating the server!
-func (p *Path) SetService(serviceName string, server *Server) {
-	p.mux.Lock()
-	p.ServiceName = serviceName
-	p.Server = server
-	p.mux.Unlock()
-}
-
-// GetServicePort returns servicePort of this Path
-func (p *Path) GetServicePort() string {
-	p.mux.RLock()
-	defer p.mux.RUnlock()
-	return p.ServicePort
-}
-
-// SetServicePort safely sets the servicePort this Path
-func (p *Path) SetServicePort(servicePort string) {
-	p.mux.Lock()
-	p.ServicePort = servicePort
-	p.mux.Unlock()
-}
-
-// InNamespace returns true if Path belongs in namespace
-// this never changes, no locking
-func (p *Path) InNamespace(namespace string) bool {
-	return p.Namespace == namespace
-}
-
-//----------------- Server --------------------------------
-
-// Server stores essential info of each service and how to reach it.
-// From Endpoint Resource
-type Server struct {
-	IPAddresses set.Set `json:"ipaddresses"` // []string IP address IPV4 or IPV6
-	Ports       set.Set `json:"ports"`       // []Ports port number of the pod
-}
-
-// NewServer returns a new emtpy server struct
-func NewServer() *Server {
-	return &Server{
-		IPAddresses: set.NewSet(),
-		Ports:       set.NewSet(),
-	}
-}
-
-// Port stores job of each port number
-// From Endpoint Resource
-type Port struct {
-	Name     string `json:"name"`
-	Port     string `json:"port"`
-	Protocol string `json:"protocol"` // TCP, UDP, HTTP etc
-}
-
-//---------------------------------------------------------
-//-------------- Helper [unused] --------------------------
-//---------------------------------------------------------
-
-// SSPair stores key val String pairs of one annotation
-// Annotations is an unstructured key value map stored with a resource that may be
-// set by external tools to store and retrieve arbitrary metadata. They are not
-// queryable and should be preserved when modifying objects.
-// More info: http://kubernetes.io/docs/user-guide/annotations
-type SSPair struct {
-	Key string `json:"key"`
-	Val string `json:"val"`
-}
-
-// CreateSSPairs constructs an array of SSPair using a string string map and
-// a filter function
-func CreateSSPairs(m map[string]string, filter func(string) bool) []SSPair {
-	if m != nil && len(m) > 0 {
-		var res []SSPair
-		for k, v := range m {
-			if filter(k) {
-				res = append(res, SSPair{
-					Key: k,
-					Val: v,
-				})
-			}
-		}
-		return res
-	}
-	return nil
-}
diff --git a/util/util.go b/util/util.go
index ae2afb7..96051aa 100644
--- a/util/util.go
+++ b/util/util.go
@@ -19,8 +19,6 @@ import (
 	"encoding/json"
 	"fmt"
 	"os"
-
-	//	p "path"
 	"sync"
 )
 
diff --git a/watcher/handlerConfigmap.go b/watcher/handlerConfigmap.go
index 0283c0d..0e49cb7 100644
--- a/watcher/handlerConfigmap.go
+++ b/watcher/handlerConfigmap.go
@@ -19,7 +19,6 @@ import (
 	"log"
 
 	"ingress-ats/endpoint"
-	//	t "ingress-ats/types"
 
 	v1 "k8s.io/api/core/v1"
 )
diff --git a/watcher/handlerEndpoint.go b/watcher/handlerEndpoint.go
index d364c35..ed14d69 100644
--- a/watcher/handlerEndpoint.go
+++ b/watcher/handlerEndpoint.go
@@ -16,16 +16,13 @@
 package watcher
 
 import (
-	//"encoding/json"
 	"fmt"
 	"log"
 
 	"ingress-ats/endpoint"
-	//	t "ingress-ats/types"
 	"ingress-ats/util"
 
 	v1 "k8s.io/api/core/v1"
-	//	set "github.com/deckarep/golang-set"
 )
 
 // EpHandler implements EventHandler
diff --git a/watcher/handlerIngress.go b/watcher/handlerIngress.go
index 40963ef..ca76e54 100644
--- a/watcher/handlerIngress.go
+++ b/watcher/handlerIngress.go
@@ -16,11 +16,9 @@
 package watcher
 
 import (
-	//	"encoding/json"
 	"log"
 
 	"ingress-ats/endpoint"
-	//	t "ingress-ats/types"
 	"ingress-ats/util"
 
 	v1beta1 "k8s.io/api/extensions/v1beta1"
diff --git a/watcher/watcher_test.go b/watcher/watcher_test.go
index 9bd8dfc..6d8b5e6 100644
--- a/watcher/watcher_test.go
+++ b/watcher/watcher_test.go
@@ -15,6 +15,7 @@
 package watcher
 
 import (
+	"context"
 	"reflect"
 	"testing"
 	"time"
@@ -37,7 +38,7 @@ func TestAllNamespacesWatchFor_Add(t *testing.T) {
 		t.Error(err)
 	}
 
-	w.Cs.CoreV1().Endpoints("trafficserver-test-2").Create(&v1.Endpoints{
+	w.Cs.CoreV1().Endpoints("trafficserver-test-2").Create(context.TODO(), &v1.Endpoints{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:      "testsvc",
 			Namespace: "trafficserver-test-2",
@@ -61,7 +62,7 @@ func TestAllNamespacesWatchFor_Add(t *testing.T) {
 				},
 			},
 		},
-	})
+	}, meta_v1.CreateOptions{})
 
 	time.Sleep(100 * time.Millisecond)
 
@@ -84,7 +85,7 @@ func TestAllNamespacesWatchFor_Update(t *testing.T) {
 		t.Error(err)
 	}
 
-	w.Cs.CoreV1().Endpoints("trafficserver-test-2").Create(&v1.Endpoints{
+	w.Cs.CoreV1().Endpoints("trafficserver-test-2").Create(context.TODO(), &v1.Endpoints{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:      "testsvc",
 			Namespace: "trafficserver-test-2",
@@ -108,11 +109,11 @@ func TestAllNamespacesWatchFor_Update(t *testing.T) {
 				},
 			},
 		},
-	})
+	}, meta_v1.CreateOptions{})
 
 	time.Sleep(100 * time.Millisecond)
 
-	w.Cs.CoreV1().Endpoints("trafficserver-test-2").Update(&v1.Endpoints{
+	w.Cs.CoreV1().Endpoints("trafficserver-test-2").Update(context.TODO(), &v1.Endpoints{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:      "testsvc",
 			Namespace: "trafficserver-test-2",
@@ -136,7 +137,7 @@ func TestAllNamespacesWatchFor_Update(t *testing.T) {
 				},
 			},
 		},
-	})
+	}, meta_v1.UpdateOptions{})
 
 	time.Sleep(100 * time.Millisecond)
 
@@ -236,7 +237,7 @@ func TestInNamespacesWatchFor_Add(t *testing.T) {
 		t.Error(err)
 	}
 
-	w.Cs.CoreV1().ConfigMaps("trafficserver").Create(&v1.ConfigMap{
+	w.Cs.CoreV1().ConfigMaps("trafficserver").Create(context.TODO(), &v1.ConfigMap{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:      "testsvc",
 			Namespace: "trafficserver",
@@ -249,7 +250,7 @@ func TestInNamespacesWatchFor_Add(t *testing.T) {
 			"proxy.config.output.logfile.rolling_interval_sec": "4000",
 			"proxy.config.restart.active_client_threshold":     "2",
 		},
-	})
+	}, meta_v1.CreateOptions{})
 	time.Sleep(100 * time.Millisecond)
 
 	rEnabled, err := cmHandler.Ep.ATSManager.ConfigGet("proxy.config.output.logfile.rolling_enabled")
@@ -291,7 +292,7 @@ func TestInNamespacesWatchFor_Update(t *testing.T) {
 		t.Error(err)
 	}
 
-	w.Cs.CoreV1().ConfigMaps("trafficserver").Create(&v1.ConfigMap{
+	w.Cs.CoreV1().ConfigMaps("trafficserver").Create(context.TODO(), &v1.ConfigMap{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:      "testsvc",
 			Namespace: "trafficserver",
@@ -304,10 +305,10 @@ func TestInNamespacesWatchFor_Update(t *testing.T) {
 			"proxy.config.output.logfile.rolling_interval_sec": "4000",
 			"proxy.config.restart.active_client_threshold":     "2",
 		},
-	})
+	}, meta_v1.CreateOptions{})
 	time.Sleep(100 * time.Millisecond)
 
-	w.Cs.CoreV1().ConfigMaps("trafficserver").Update(&v1.ConfigMap{
+	w.Cs.CoreV1().ConfigMaps("trafficserver").Update(context.TODO(), &v1.ConfigMap{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:      "testsvc",
 			Namespace: "trafficserver",
@@ -320,7 +321,7 @@ func TestInNamespacesWatchFor_Update(t *testing.T) {
 			"proxy.config.output.logfile.rolling_interval_sec": "3000",
 			"proxy.config.restart.active_client_threshold":     "0",
 		},
-	})
+	}, meta_v1.UpdateOptions{})
 	time.Sleep(100 * time.Millisecond)
 
 	rEnabled, err := cmHandler.Ep.ATSManager.ConfigGet("proxy.config.output.logfile.rolling_enabled")
@@ -362,7 +363,7 @@ func TestInNamespacesWatchFor_ShouldNotAdd(t *testing.T) {
 		t.Error(err)
 	}
 
-	w.Cs.CoreV1().ConfigMaps("trafficserver").Create(&v1.ConfigMap{
+	w.Cs.CoreV1().ConfigMaps("trafficserver").Create(context.TODO(), &v1.ConfigMap{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:      "testsvc",
 			Namespace: "trafficserver",
@@ -375,10 +376,10 @@ func TestInNamespacesWatchFor_ShouldNotAdd(t *testing.T) {
 			"proxy.config.output.logfile.rolling_interval_sec": "4000",
 			"proxy.config.restart.active_client_threshold":     "2",
 		},
-	})
+	}, meta_v1.CreateOptions{})
 	time.Sleep(100 * time.Millisecond)
 
-	w.Cs.CoreV1().ConfigMaps("trafficserver-2").Create(&v1.ConfigMap{
+	w.Cs.CoreV1().ConfigMaps("trafficserver-2").Create(context.TODO(), &v1.ConfigMap{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:      "testsvc-2",
 			Namespace: "trafficserver-2",
@@ -388,7 +389,7 @@ func TestInNamespacesWatchFor_ShouldNotAdd(t *testing.T) {
 			"proxy.config.output.logfile.rolling_interval_sec": "3000",
 			"proxy.config.restart.active_client_threshold":     "4",
 		},
-	})
+	}, meta_v1.CreateOptions{})
 	time.Sleep(100 * time.Millisecond)
 
 	rEnabled, err := cmHandler.Ep.ATSManager.ConfigGet("proxy.config.output.logfile.rolling_enabled")
@@ -415,7 +416,7 @@ func TestInNamespacesWatchFor_ShouldNotAdd(t *testing.T) {
 		t.Errorf("returned \n%s,  but expected \n%s", threshold, "2")
 	}
 
-	w.Cs.CoreV1().ConfigMaps("trafficserver-2").Create(&v1.ConfigMap{
+	w.Cs.CoreV1().ConfigMaps("trafficserver-2").Create(context.TODO(), &v1.ConfigMap{
 		ObjectMeta: meta_v1.ObjectMeta{
 			Name:      "testsvc",
 			Namespace: "trafficserver",
@@ -425,7 +426,7 @@ func TestInNamespacesWatchFor_ShouldNotAdd(t *testing.T) {
 			"proxy.config.output.logfile.rolling_interval_sec": "3000",
 			"proxy.config.restart.active_client_threshold":     "4",
 		},
-	})
+	}, meta_v1.CreateOptions{})
 	time.Sleep(100 * time.Millisecond)
 
 	rEnabled, err = cmHandler.Ep.ATSManager.ConfigGet("proxy.config.output.logfile.rolling_enabled")