Repository: Azure/aad-pod-identity
Pull request #597 (2020-05-02 23:44:03)

Code clean up
Fix typos
Fix swallowed errors
Report Metrics reporter errors
Remove unused/dead code
Properly goimports/gofmt files
Rename stats.StatsType to stats.Type

Issue: #571

elsesiy: @aramase @chewong As per our conversation, I fixed the linting errors. Please have a look and let me know if you want me to undo some of the fixes, thanks!
elsesiy: @aramase @chewong Updated the PR with the review comments, please let me know if it's good to go now
chewong: /azp run
azure-pipelines[bot]: <samp>
Azure Pipelines successfully started running 1 pipeline(s).<br>

</samp>
chewong: /azp run
azure-pipelines[bot]: <samp>
Azure Pipelines successfully started running 1 pipeline(s).<br>

</samp>
chewong: /azp run


azure-pipelines[bot]: <samp>
Azure Pipelines successfully started running 1 pipeline(s).<br>

</samp>
elsesiy: > Hmm golangci-lint v1.24.0 hangs in Azure DevOps pipeline. What do you think of upgrading it to v1.27.0? I opened a test PR #616 and it looks like it works with v1.27.0.

I was skeptical already with the long build time so that might explain it, I'll update it.
aramase: /azp run
azure-pipelines[bot]: <samp>
Azure Pipelines successfully started running 1 pipeline(s).<br>

</samp>
elsesiy: @chewong I fixed the last two files 👍 
chewong: /azp run
azure-pipelines[bot]: <samp>
Azure Pipelines successfully started running 1 pipeline(s).<br>

</samp>

Patch:
diff --git a/CHANGELOG-1.5.md b/CHANGELOG-1.5.md
index 688c660e..16a66cd4 100644
--- a/CHANGELOG-1.5.md
+++ b/CHANGELOG-1.5.md
@@ -77,7 +77,7 @@
 
 ### Bug Fixes
 
-- Fix AzureIdentity with sevice principal ([#197](https://github.com/Azure/aad-pod-identity/pull/197))
+- Fix AzureIdentity with service principal ([#197](https://github.com/Azure/aad-pod-identity/pull/197))
 - Determine resource manager endpoint based on cloud name ([#226](https://github.com/Azure/aad-pod-identity/pull/226))
 - Fix incorrect resource endpoint with sp ([#251](https://github.com/Azure/aad-pod-identity/pull/251))
 - Fix vmss identity deletion for ID in use ([#203](https://github.com/Azure/aad-pod-identity/pull/203))
diff --git a/CHANGELOG-1.6.md b/CHANGELOG-1.6.md
index bbb386ec..9984bf3d 100644
--- a/CHANGELOG-1.6.md
+++ b/CHANGELOG-1.6.md
@@ -7,7 +7,7 @@
 - Deny requests without metadata header to avoid SSRF ([#500](https://github.com/Azure/aad-pod-identity/pull/500))
 
 ### Bug Fixes
-- Fix issue that casued failures with long pod name > 63 chars ([#545](https://github.com/Azure/aad-pod-identity/pull/545))
+- Fix issue that caused failures with long pod name > 63 chars ([#545](https://github.com/Azure/aad-pod-identity/pull/545))
 - Fix updating assigned identity when azure identity updated ([#559](https://github.com/Azure/aad-pod-identity/pull/559))
 
 ### Other Improvements
diff --git a/Dockerfile b/Dockerfile
index f67757a1..f297643c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.14.1 AS build
+FROM golang:1.14 AS build
 WORKDIR /go/src/github.com/Azure/aad-pod-identity
 COPY go.mod go.sum ./
 RUN go mod download
@@ -9,7 +9,7 @@ ARG DEMO_VERSION=0.0.0-dev
 ARG IDENTITY_VALIDATOR_VERSION=0.0.0-dev
 RUN make build
 
-FROM alpine:3.11.5 AS base
+FROM alpine:3.11 AS base
 RUN apk add --no-cache \
     ca-certificates \
     iptables \
diff --git a/README.md b/README.md
index 21c1b127..e5934271 100644
--- a/README.md
+++ b/README.md
@@ -235,10 +235,10 @@ kubectl logs demo
 If successful, the log output would be similar to the following output:
 ```
 ...
-succesfully doARMOperations vm count 1
-succesfully acquired a token using the MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token)
-succesfully acquired a token, userAssignedID MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token) clientID(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
-succesfully made GET on instance metadata
+successfully doARMOperations vm count 1
+successfully acquired a token using the MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token)
+successfully acquired a token, userAssignedID MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token) clientID(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
+successfully made GET on instance metadata
 ...
 ```
 
diff --git a/charts/aad-pod-identity/README.md b/charts/aad-pod-identity/README.md
index 83c32f6e..d10c5b3e 100644
--- a/charts/aad-pod-identity/README.md
+++ b/charts/aad-pod-identity/README.md
@@ -93,7 +93,7 @@ az identity create -g <resource-group> -n <id-name>
 #### Installing charts
 
 * If you need the `AzureIdentity` and `AzureIdentityBinding` resources to be created as part of the chart installation, update the values.yml to enable the azureIdentity and replace the resourceID, clientID using the values for the user identity.
-* If you need the aad-pod-identity deployment to use it's own service principal credentials instead of the cluster service prinicipal '/etc/kubernetes/azure.json`, then uncomment this section and add the appropriate values for each required field.
+* If you need the aad-pod-identity deployment to use it's own service principal credentials instead of the cluster service principal '/etc/kubernetes/azure.json`, then uncomment this section and add the appropriate values for each required field.
 
 ```
 adminsecret:
diff --git a/cmd/demo/main.go b/cmd/demo/main.go
index 2b43af1b..1025d475 100644
--- a/cmd/demo/main.go
+++ b/cmd/demo/main.go
@@ -9,12 +9,10 @@ import (
 	"time"
 
 	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
-
-	"k8s.io/klog"
-
 	"github.com/Azure/go-autorest/autorest/adal"
 	"github.com/Azure/go-autorest/autorest/azure/auth"
 	"github.com/spf13/pflag"
+	"k8s.io/klog"
 )
 
 var (
diff --git a/cmd/mic/main.go b/cmd/mic/main.go
index 44e47805..54bfbb46 100644
--- a/cmd/mic/main.go
+++ b/cmd/mic/main.go
@@ -12,6 +12,7 @@ import (
 	"github.com/Azure/aad-pod-identity/pkg/mic"
 	"github.com/Azure/aad-pod-identity/pkg/probes"
 	"github.com/Azure/aad-pod-identity/version"
+
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/clientcmd"
 	"k8s.io/klog"
diff --git a/cmd/nmi/main.go b/cmd/nmi/main.go
index 4b9c2eb7..cbf563fa 100644
--- a/cmd/nmi/main.go
+++ b/cmd/nmi/main.go
@@ -2,17 +2,17 @@ package main
 
 import (
 	goflag "flag"
-	"os"
-	"strings"
-
 	"net/http"
 	_ "net/http/pprof"
+	"os"
+	"strings"
 
 	"github.com/Azure/aad-pod-identity/pkg/metrics"
 	"github.com/Azure/aad-pod-identity/pkg/nmi"
 	server "github.com/Azure/aad-pod-identity/pkg/nmi/server"
 	"github.com/Azure/aad-pod-identity/pkg/probes"
 	"github.com/Azure/aad-pod-identity/version"
+
 	"github.com/spf13/pflag"
 	"k8s.io/klog"
 )
@@ -28,7 +28,6 @@ const (
 )
 
 var (
-	debug                              = pflag.Bool("debug", false, "sets log to debug level")
 	versionInfo                        = pflag.Bool("version", false, "prints the version information")
 	nmiPort                            = pflag.String("nmi-port", defaultNmiPort, "NMI application port")
 	metadataIP                         = pflag.String("metadata-ip", defaultMetadataIP, "instance metadata host ip")
diff --git a/cmd/simple/main.go b/cmd/simple/main.go
index 5d686418..b8c35c95 100644
--- a/cmd/simple/main.go
+++ b/cmd/simple/main.go
@@ -1,15 +1,14 @@
 package main
 
 import (
-	"flag"
-
-	"github.com/Azure/aad-pod-identity/version"
-
 	"encoding/json"
+	"flag"
 	"os"
 
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity"
 	"github.com/Azure/aad-pod-identity/pkg/crd"
+	"github.com/Azure/aad-pod-identity/version"
+
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/clientcmd"
 	"k8s.io/klog"
@@ -23,8 +22,8 @@ func main() {
 	defer klog.Flush()
 	flag.StringVar(&kubeconfig, "kubeconfig", "", "Path to the kube config")
 
-	flag.Set("logtostderr", "true")
-	flag.Set("v", "10")
+	_ = flag.Set("logtostderr", "true")
+	_ = flag.Set("v", "10")
 
 	flag.Parse()
 
@@ -58,7 +57,7 @@ func main() {
 	for _, v := range *ids {
 		buf, err := json.MarshalIndent(v, "", "    ")
 		if err != nil {
-			klog.Errorf("Error in marshalling: %+v", err)
+			klog.Errorf("Error in marshaling: %+v", err)
 			os.Exit(1)
 		}
 		klog.Infof("\n%s", string(buf))
@@ -72,7 +71,7 @@ func main() {
 	for _, v := range *bindings {
 		buf, err := json.MarshalIndent(v, "", "    ")
 		if err != nil {
-			klog.Errorf("Error in marshalling: %+v", err)
+			klog.Errorf("Error in marshaling: %+v", err)
 			os.Exit(1)
 		}
 		klog.Infof("\n%s", string(buf))
@@ -86,7 +85,7 @@ func main() {
 	for _, a := range *assignedIDs {
 		buf, err := json.MarshalIndent(a, "", "    ")
 		if err != nil {
-			klog.Errorf("Error in marshalling: %+v", err)
+			klog.Errorf("Error in marshaling: %+v", err)
 			os.Exit(1)
 		}
 		klog.Infof("\n%s", string(buf))
diff --git a/docs/readmes/README.troubleshooting.md b/docs/readmes/README.troubleshooting.md
index 74b02da8..ee7dbfcd 100644
--- a/docs/readmes/README.troubleshooting.md
+++ b/docs/readmes/README.troubleshooting.md
@@ -38,4 +38,4 @@ Common issues or questions that users have run into when using pod identity are
 
 ### Ignoring azure identity \<podns\>/\<podname\>, error: Invalid resource id: "", must match /subscriptions/\<subid\>/resourcegroups/\<resourcegroup\>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/\<name\>
 
-If you are using MIC v1.6.0+, you will need to ensure the correct captialization of `AzureIdentity` and `AzureIdentityBinding` fields. For more information, please refer to [this section](../../README.md#v160-breaking-change).
+If you are using MIC v1.6.0+, you will need to ensure the correct capitalization of `AzureIdentity` and `AzureIdentityBinding` fields. For more information, please refer to [this section](../../README.md#v160-breaking-change).
diff --git a/docs/tutorial/README.md b/docs/tutorial/README.md
index c7ee73ed..39a608d5 100644
--- a/docs/tutorial/README.md
+++ b/docs/tutorial/README.md
@@ -81,7 +81,7 @@ aks-nodepool1-15831963-0   Ready     agent     01h       v1.9.6
 Pod Identity requires two components:
 
  1. Managed Identity Controller (MIC). A pod that binds Azure Ids to other pods - creates azureAssignedIdentity CRD. 
- 2. Node Managed Identity (NMI). Identifies the pod based on the remote address of the incoming request, and then queries the k8s (through MIC) for a matching Azure Id. It then make a adal request to get the token for the client id and returns as a reponse to the request. Implemented as a [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/).
+ 2. Node Managed Identity (NMI). Identifies the pod based on the remote address of the incoming request, and then queries the k8s (through MIC) for a matching Azure Id. It then make a adal request to get the token for the client id and returns as a response to the request. Implemented as a [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/).
 
 Deploy the infrastructure with the following command to deploy MIC, NMI, and MIC CRDs.
 
@@ -198,9 +198,9 @@ The demo pod should be reporting on the virtual machines in the resource group.
 $ kubectl logs demo-757967c54-64pzr
 ...
 time="2018-06-07T01:32:30Z" level=error msg="failed list all vm compute.VirtualMachinesClient#List: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code=\"AuthorizationFailed\" Message=\"The client '48affddb-9972-4b7e-a82b-c5d32d2a3dd5' with object id '48affddb-9972-4b7e-a82b-c5d32d2a3dd5' does not have authorization to perform action 'Microsoft.Compute/virtualMachines/read' over scope '/subscriptions/c5760548-23c2-4223-b41e-5d68a8320a0c/resourceGroups/MC_k8s-test_clusterFrank_eastus/providers/Microsoft.Compute'.\"" podip=10.244.0.25 podname=demo-757967c54-64pzr podnamespace=demo-757967c54-64pzr
-time="2018-06-07T01:32:30Z" level=info msg="succesfully acquired a token using the MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token)" podip=10.244.0.25 podname=demo-757967c54-64pzr podnamespace=demo-757967c54-64pzr
-time="2018-06-07T01:32:30Z" level=info msg="succesfully acquired a token, userAssignedID MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token) clientID(a40e83f9-6198-4633-afae-d860eb5b7f7c)" podip=10.244.0.25 podname=demo-757967c54-64pzr podnamespace=demo-757967c54-64pzr
-time="2018-06-07T01:32:30Z" level=info msg="succesfully made GET on instance metadata, {\"compute\":{\"location\":\"eastus\",\"name\":\"aks-nodepool1-15831963-0\",\"offer\":\"UbuntuServer\",\"osType\":\"Linux\",\"placementGroupId\":\"\",\"platformFaultDomain\":\"0\",\"platformUpdateDomain\":\"0\",\"publisher\":\"Canonical\",\"resourceGroupName\":\"MC_k8s-test_clusterFrank_eastus\",\"sku\":\"16.04-LTS\",\"subscriptionId\":\"c5760548-23c2-4223-b41e-5d68a8320a0c\",\"tags\":\"acsengineVersion:v0.17.0-aks;creationSource:aks-aks-nodepool1-15831963-0;orchestrator:Kubernetes:1.9.6;poolName:nodepool1;resourceNameSuffix:15831963\",\"version\":\"16.04.201805090\",\"vmId\":\"3fea4c7e-4aaf-400f-a588-2a851f6fd0cf\",\"vmSize\":\"Standard_DS1_v2\"},\"network\":{\"interface\":[{\"ipv4\":{\"ipAddress\":[{\"privateIpAddress\":\"10.240.0.4\",\"publicIpAddress\":\"\"}],\"subnet\":[{\"address\":\"10.240.0.0\",\"prefix\":\"16\"}]},\"ipv6\":{\"ipAddress\":[]},\"macAddress\":\"000D3A13DEE3\"}]}}" podip=10.244.0.25 podname=demo-757967c54-64pzr podnamespace=demo-757967c54-64pzr
+time="2018-06-07T01:32:30Z" level=info msg="successfully acquired a token using the MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token)" podip=10.244.0.25 podname=demo-757967c54-64pzr podnamespace=demo-757967c54-64pzr
+time="2018-06-07T01:32:30Z" level=info msg="successfully acquired a token, userAssignedID MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token) clientID(a40e83f9-6198-4633-afae-d860eb5b7f7c)" podip=10.244.0.25 podname=demo-757967c54-64pzr podnamespace=demo-757967c54-64pzr
+time="2018-06-07T01:32:30Z" level=info msg="successfully made GET on instance metadata, {\"compute\":{\"location\":\"eastus\",\"name\":\"aks-nodepool1-15831963-0\",\"offer\":\"UbuntuServer\",\"osType\":\"Linux\",\"placementGroupId\":\"\",\"platformFaultDomain\":\"0\",\"platformUpdateDomain\":\"0\",\"publisher\":\"Canonical\",\"resourceGroupName\":\"MC_k8s-test_clusterFrank_eastus\",\"sku\":\"16.04-LTS\",\"subscriptionId\":\"c5760548-23c2-4223-b41e-5d68a8320a0c\",\"tags\":\"acsengineVersion:v0.17.0-aks;creationSource:aks-aks-nodepool1-15831963-0;orchestrator:Kubernetes:1.9.6;poolName:nodepool1;resourceNameSuffix:15831963\",\"version\":\"16.04.201805090\",\"vmId\":\"3fea4c7e-4aaf-400f-a588-2a851f6fd0cf\",\"vmSize\":\"Standard_DS1_v2\"},\"network\":{\"interface\":[{\"ipv4\":{\"ipAddress\":[{\"privateIpAddress\":\"10.240.0.4\",\"publicIpAddress\":\"\"}],\"subnet\":[{\"address\":\"10.240.0.0\",\"prefix\":\"16\"}]},\"ipv6\":{\"ipAddress\":[]},\"macAddress\":\"000D3A13DEE3\"}]}}" podip=10.244.0.25 podname=demo-757967c54-64pzr podnamespace=demo-757967c54-64pzr
 
 ```
 
diff --git a/pkg/apis/aadpodidentity/types.go b/pkg/apis/aadpodidentity/types.go
index 5be08a8e..e3ebf881 100644
--- a/pkg/apis/aadpodidentity/types.go
+++ b/pkg/apis/aadpodidentity/types.go
@@ -206,7 +206,7 @@ type AzureAssignedIdentitySpec struct {
 	Replicas *int32 `json:"replicas"`
 }
 
-// AzureAssignedIdentityStatus has the replica status of the resouce.
+// AzureAssignedIdentityStatus has the replica status of the resource.
 type AzureAssignedIdentityStatus struct {
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 	Status            string `json:"status"`
diff --git a/pkg/apis/aadpodidentity/v1/conversion.go b/pkg/apis/aadpodidentity/v1/conversion.go
index e253db61..721e117d 100644
--- a/pkg/apis/aadpodidentity/v1/conversion.go
+++ b/pkg/apis/aadpodidentity/v1/conversion.go
@@ -4,6 +4,7 @@ import (
 	"reflect"
 
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity"
+
 	"k8s.io/apimachinery/pkg/runtime/schema"
 )
 
diff --git a/pkg/apis/aadpodidentity/v1/types.go b/pkg/apis/aadpodidentity/v1/types.go
index 8b586164..22cdb2bf 100644
--- a/pkg/apis/aadpodidentity/v1/types.go
+++ b/pkg/apis/aadpodidentity/v1/types.go
@@ -191,7 +191,7 @@ type AzureAssignedIdentitySpec struct {
 	Replicas *int32 `json:"replicas"`
 }
 
-// AzureAssignedIdentityStatus has the replica status of the resouce.
+// AzureAssignedIdentityStatus has the replica status of the resource.
 type AzureAssignedIdentityStatus struct {
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 	Status            string `json:"status"`
diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go
index e42ff905..e372e9b5 100644
--- a/pkg/auth/auth.go
+++ b/pkg/auth/auth.go
@@ -6,7 +6,9 @@ import (
 
 	"github.com/Azure/aad-pod-identity/pkg/metrics"
 	"github.com/Azure/aad-pod-identity/version"
-	adal "github.com/Azure/go-autorest/autorest/adal"
+
+	"github.com/Azure/go-autorest/autorest/adal"
+	"k8s.io/klog"
 )
 
 const (
@@ -22,10 +24,16 @@ func GetServicePrincipalTokenFromMSI(resource string) (*adal.Token, error) {
 
 	defer func() {
 		if err != nil {
-			reporter.ReportIMDSOperationError(metrics.AdalTokenFromMSIOperationName)
+			err = reporter.ReportIMDSOperationError(metrics.AdalTokenFromMSIOperationName)
+			if err != nil {
+				klog.Warningf("Metrics reporter error: %+v", err)
+			}
 			return
 		}
-		reporter.ReportIMDSOperationDuration(metrics.AdalTokenFromMSIOperationName, time.Since(begin))
+		err = reporter.ReportIMDSOperationDuration(metrics.AdalTokenFromMSIOperationName, time.Since(begin))
+		if err != nil {
+			klog.Warningf("Metrics reporter error: %+v", err)
+		}
 	}()
 
 	// Get the MSI endpoint accoriding with the OS (Linux/Windows)
@@ -54,10 +62,16 @@ func GetServicePrincipalTokenFromMSIWithUserAssignedID(clientID, resource string
 
 	defer func() {
 		if err != nil {
-			reporter.ReportIMDSOperationError(metrics.AdalTokenFromMSIWithUserAssignedIDOperationName)
+			err = reporter.ReportIMDSOperationError(metrics.AdalTokenFromMSIWithUserAssignedIDOperationName)
+			if err != nil {
+				klog.Warningf("Metrics reporter error: %+v", err)
+			}
 			return
 		}
-		reporter.ReportIMDSOperationDuration(metrics.AdalTokenFromMSIWithUserAssignedIDOperationName, time.Since(begin))
+		err = reporter.ReportIMDSOperationDuration(metrics.AdalTokenFromMSIWithUserAssignedIDOperationName, time.Since(begin))
+		if err != nil {
+			klog.Warningf("Metrics reporter error: %+v", err)
+		}
 	}()
 
 	// Get the MSI endpoint accoriding with the OS (Linux/Windows)
@@ -89,10 +103,16 @@ func GetServicePrincipalToken(tenantID, clientID, secret, resource string) (*ada
 
 	defer func() {
 		if err != nil {
-			reporter.ReportIMDSOperationError(metrics.AdalTokenOperationName)
+			err = reporter.ReportIMDSOperationError(metrics.AdalTokenOperationName)
+			if err != nil {
+				klog.Warningf("Metrics reporter error: %+v", err)
+			}
 			return
 		}
-		reporter.ReportIMDSOperationDuration(metrics.AdalTokenOperationName, time.Since(begin))
+		err = reporter.ReportIMDSOperationDuration(metrics.AdalTokenOperationName, time.Since(begin))
+		if err != nil {
+			klog.Warningf("Metrics reporter error: %+v", err)
+		}
 	}()
 
 	oauthConfig, err := adal.NewOAuthConfig(activeDirectoryEndpoint, tenantID)
diff --git a/pkg/cloudprovider/cloudprovider.go b/pkg/cloudprovider/cloudprovider.go
index 7f9a4e5c..bdbb1522 100644
--- a/pkg/cloudprovider/cloudprovider.go
+++ b/pkg/cloudprovider/cloudprovider.go
@@ -3,16 +3,16 @@ package cloudprovider
 import (
 	"fmt"
 	"io/ioutil"
-	"net/http"
 	"os"
 	"path"
 	"regexp"
 	"strings"
 	"time"
 
-	config "github.com/Azure/aad-pod-identity/pkg/config"
+	"github.com/Azure/aad-pod-identity/pkg/config"
 	"github.com/Azure/aad-pod-identity/pkg/utils"
 	"github.com/Azure/aad-pod-identity/version"
+
 	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
 	"github.com/Azure/go-autorest/autorest"
 	"github.com/Azure/go-autorest/autorest/adal"
@@ -48,16 +48,6 @@ func NewCloudProvider(configFile string) (c *Client, e error) {
 	return client, nil
 }
 
-func withInspection() autorest.PrepareDecorator {
-	return func(p autorest.Preparer) autorest.Preparer {
-		return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) {
-			klog.Infof("Inspecting Request: Method: %s \n URL: %s, URI: %s\n", r.Method, r.URL, r.RequestURI)
-
-			return p.Prepare(r)
-		})
-	}
-}
-
 // Init initializes the cloud provider client based
 // on a config path or environment variables
 func (c *Client) Init() error {
@@ -253,16 +243,6 @@ const (
 	VMSSResourceType = "virtualMachineScaleSets"
 )
 
-func vmTypeOrDefault(r *azure.Resource, val string) string {
-	switch r.ResourceType {
-	case VMResourceType:
-		return "vm"
-	case VMSSResourceType:
-		return "vmss"
-	}
-	return val
-}
-
 // ParseResourceID is a slightly modified version of https://github.com/Azure/go-autorest/blob/528b76fd0ebec0682f3e3da7c808cd472b999615/autorest/azure/azure.go#L175
 // The modification here is to support a nested resource such as is the case for a node resource in a vmss.
 func ParseResourceID(resourceID string) (azure.Resource, error) {
diff --git a/pkg/cloudprovider/identity.go b/pkg/cloudprovider/identity.go
index 0b7c66ee..a8f36ca4 100644
--- a/pkg/cloudprovider/identity.go
+++ b/pkg/cloudprovider/identity.go
@@ -1,8 +1,6 @@
 package cloudprovider
 
 import (
-	"strings"
-
 	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
 )
 
@@ -23,15 +21,6 @@ type IdentityInfo interface {
 	SetUserIdentities(map[string]bool) bool
 }
 
-func checkIfIDInList(idList []string, desiredID string) bool {
-	for _, id := range idList {
-		if strings.EqualFold(id, desiredID) {
-			return true
-		}
-	}
-	return false
-}
-
 // getUpdatedResourceIdentityType returns the new resource identity type
 // to be set on the VM/VMSS based on current type
 func getUpdatedResourceIdentityType(identityType compute.ResourceIdentityType) compute.ResourceIdentityType {
diff --git a/pkg/cloudprovider/vm.go b/pkg/cloudprovider/vm.go
index bc6b761b..09e487c0 100644
--- a/pkg/cloudprovider/vm.go
+++ b/pkg/cloudprovider/vm.go
@@ -8,6 +8,7 @@ import (
 	"github.com/Azure/aad-pod-identity/pkg/metrics"
 	"github.com/Azure/aad-pod-identity/pkg/stats"
 	"github.com/Azure/aad-pod-identity/version"
+
 	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
 	"github.com/Azure/go-autorest/autorest"
 	"github.com/Azure/go-autorest/autorest/adal"
@@ -39,7 +40,11 @@ func NewVirtualMachinesClient(config config.AzureConfig, spt *adal.ServicePrinci
 	client.BaseURI = azureEnv.ResourceManagerEndpoint
 	client.Authorizer = autorest.NewBearerAuthorizer(spt)
 	client.PollingDelay = 5 * time.Second
-	client.AddToUserAgent(version.GetUserAgent("MIC", version.MICVersion))
+	err = client.AddToUserAgent(version.GetUserAgent("MIC", version.MICVersion))
+	if err != nil {
+		klog.Errorf("Error updating user agent: %+v", err)
+		return nil, err
+	}
 
 	reporter, err := metrics.NewReporter()
 	if err != nil {
@@ -61,10 +66,16 @@ func (c *VMClient) Get(rgName string, nodeName string) (compute.VirtualMachine,
 
 	defer func() {
 		if err != nil {
-			c.reporter.ReportCloudProviderOperationError(metrics.GetVMOperationName)
+			err = c.reporter.ReportCloudProviderOperationError(metrics.GetVMOperationName)
+			if err != nil {
+				klog.Warningf("Metrics reporter error: %+v", err)
+			}
 			return
 		}
-		c.reporter.ReportCloudProviderOperationDuration(metrics.GetVMOperationName, time.Since(begin))
+		err = c.reporter.ReportCloudProviderOperationDuration(metrics.GetVMOperationName, time.Since(begin))
+		if err != nil {
+			klog.Warningf("Metrics reporter error: %+v", err)
+		}
 	}()
 
 	vm, err := c.client.Get(ctx, rgName, nodeName, "")
@@ -86,10 +97,16 @@ func (c *VMClient) UpdateIdentities(rg, nodeName string, vm compute.VirtualMachi
 
 	defer func() {
 		if err != nil {
-			c.reporter.ReportCloudProviderOperationError(metrics.PutVMOperationName)
+			err = c.reporter.ReportCloudProviderOperationError(metrics.PutVMOperationName)
+			if err != nil {
+				klog.Warningf("Metrics reporter error: %+v", err)
+			}
 			return
 		}
-		c.reporter.ReportCloudProviderOperationDuration(metrics.PutVMOperationName, time.Since(begin))
+		err = c.reporter.ReportCloudProviderOperationDuration(metrics.PutVMOperationName, time.Since(begin))
+		if err != nil {
+			klog.Warningf("Metrics reporter error: %+v", err)
+		}
 	}()
 
 	if future, err = c.client.Update(ctx, rg, nodeName, compute.VirtualMachineUpdate{
diff --git a/pkg/cloudprovider/vmss.go b/pkg/cloudprovider/vmss.go
index 973e0cba..753bd2b0 100644
--- a/pkg/cloudprovider/vmss.go
+++ b/pkg/cloudprovider/vmss.go
@@ -8,6 +8,7 @@ import (
 	"github.com/Azure/aad-pod-identity/pkg/metrics"
 	"github.com/Azure/aad-pod-identity/pkg/stats"
 	"github.com/Azure/aad-pod-identity/version"
+
 	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
 	"github.com/Azure/go-autorest/autorest"
 	"github.com/Azure/go-autorest/autorest/adal"
@@ -39,7 +40,11 @@ func NewVMSSClient(config config.AzureConfig, spt *adal.ServicePrincipalToken) (
 	client.BaseURI = azureEnv.ResourceManagerEndpoint
 	client.Authorizer = autorest.NewBearerAuthorizer(spt)
 	client.PollingDelay = 5 * time.Second
-	client.AddToUserAgent(version.GetUserAgent("MIC", version.MICVersion))
+	err = client.AddToUserAgent(version.GetUserAgent("MIC", version.MICVersion))
+	if err != nil {
+		klog.Errorf("Error updating user agent: %+v", err)
+		return nil, err
+	}
 
 	reporter, err := metrics.NewReporter()
 	if err != nil {
@@ -62,10 +67,16 @@ func (c *VMSSClient) UpdateIdentities(rg, vmssName string, vmssIdentities comput
 
 	defer func() {
 		if err != nil {
-			c.reporter.ReportCloudProviderOperationError(metrics.PutVmssOperationName)
+			err = c.reporter.ReportCloudProviderOperationError(metrics.PutVmssOperationName)
+			if err != nil {
+				klog.Warningf("Metrics reporter error: %+v", err)
+			}
 			return
 		}
-		c.reporter.ReportCloudProviderOperationDuration(metrics.PutVmssOperationName, time.Since(begin))
+		err = c.reporter.ReportCloudProviderOperationDuration(metrics.PutVmssOperationName, time.Since(begin))
+		if err != nil {
+			klog.Warningf("Metrics reporter error: %+v", err)
+		}
 	}()
 
 	if future, err = c.client.Update(ctx, rg, vmssName, compute.VirtualMachineScaleSetUpdate{
@@ -89,10 +100,16 @@ func (c *VMSSClient) Get(rgName string, vmssName string) (ret compute.VirtualMac
 
 	defer func() {
 		if err != nil {
-			c.reporter.ReportCloudProviderOperationError(metrics.GetVmssOperationName)
+			err = c.reporter.ReportCloudProviderOperationError(metrics.GetVmssOperationName)
+			if err != nil {
+				klog.Warningf("Metrics reporter error: %+v", err)
+			}
 			return
 		}
-		c.reporter.ReportCloudProviderOperationDuration(metrics.GetVmssOperationName, time.Since(begin))
+		err = c.reporter.ReportCloudProviderOperationDuration(metrics.GetVmssOperationName, time.Since(begin))
+		if err != nil {
+			klog.Warningf("Metrics reporter error: %+v", err)
+		}
 	}()
 	vm, err := c.client.Get(ctx, rgName, vmssName)
 	if err != nil {
diff --git a/pkg/crd/crd.go b/pkg/crd/crd.go
index 08243da7..358842c8 100644
--- a/pkg/crd/crd.go
+++ b/pkg/crd/crd.go
@@ -11,6 +11,7 @@ import (
 	aadpodv1 "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity/v1"
 	"github.com/Azure/aad-pod-identity/pkg/metrics"
 	"github.com/Azure/aad-pod-identity/pkg/stats"
+
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/api/meta"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -255,7 +256,6 @@ func NodeNameFilter(nodeName string) internalinterfaces.TweakListOptionsFunc {
 			l = &v1.ListOptions{}
 		}
 		l.LabelSelector = l.LabelSelector + "nodename=" + nodeName
-		return
 	}
 }
 
@@ -479,7 +479,10 @@ func (c *Client) RemoveAssignedIdentity(assignedIdentity *aadpodid.AzureAssigned
 
 	defer func() {
 		if err != nil {
-			c.reporter.ReportKubernetesAPIOperationError(metrics.AssignedIdentityDeletionOperationName)
+			err = c.reporter.ReportKubernetesAPIOperationError(metrics.AssignedIdentityDeletionOperationName)
+			if err != nil {
+				klog.Warningf("Metrics reporter error: %+v", err)
+			}
 			return
 		}
 		c.reporter.Report(
@@ -514,7 +517,10 @@ func (c *Client) CreateAssignedIdentity(assignedIdentity *aadpodid.AzureAssigned
 
 	defer func() {
 		if err != nil {
-			c.reporter.ReportKubernetesAPIOperationError(metrics.AssignedIdentityAdditionOperationName)
+			err = c.reporter.ReportKubernetesAPIOperationError(metrics.AssignedIdentityAdditionOperationName)
+			if err != nil {
+				klog.Warningf("Metrics reporter error: %+v", err)
+			}
 			return
 		}
 		c.reporter.Report(
@@ -539,13 +545,15 @@ func (c *Client) CreateAssignedIdentity(assignedIdentity *aadpodid.AzureAssigned
 	return nil
 }
 
+// UpdateAssignedIdentity updates an existing assigned identity
 func (c *Client) UpdateAssignedIdentity(assignedIdentity *aadpodid.AzureAssignedIdentity) (err error) {
 	klog.Infof("Got assigned id %s/%s to update", assignedIdentity.Namespace, assignedIdentity.Name)
 	begin := time.Now()
 
 	defer func() {
 		if err != nil {
-			c.reporter.ReportKubernetesAPIOperationError(metrics.AssignedIdentityUpdateOperationName)
+			err = c.reporter.ReportKubernetesAPIOperationError(metrics.AssignedIdentityUpdateOperationName)
+			klog.Warningf("Metrics reporter error: %+v", err)
 			return
 		}
 		c.reporter.Report(
@@ -786,7 +794,10 @@ func (c *Client) UpdateAzureAssignedIdentityStatus(assignedIdentity *aadpodid.Az
 
 	defer func() {
 		if err != nil {
-			c.reporter.ReportKubernetesAPIOperationError(metrics.UpdateAzureAssignedIdentityStatusOperationName)
+			err = c.reporter.ReportKubernetesAPIOperationError(metrics.UpdateAzureAssignedIdentityStatusOperationName)
+			if err != nil {
+				klog.Warningf("Metrics reporter error: %+v", err)
+			}
 		}
 	}()
 
diff --git a/pkg/k8s/client.go b/pkg/k8s/client.go
index a5196bca..1ad4837e 100644
--- a/pkg/k8s/client.go
+++ b/pkg/k8s/client.go
@@ -7,20 +7,20 @@ import (
 	"strings"
 	"time"
 
-	v1 "k8s.io/api/core/v1"
-	"k8s.io/client-go/kubernetes"
-	"k8s.io/client-go/rest"
-	"k8s.io/client-go/tools/cache"
-	"k8s.io/client-go/tools/clientcmd"
-	"k8s.io/klog"
-
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity"
 	crd "github.com/Azure/aad-pod-identity/pkg/crd"
 	"github.com/Azure/aad-pod-identity/pkg/metrics"
 	"github.com/Azure/aad-pod-identity/version"
+
+	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	informersv1 "k8s.io/client-go/informers/core/v1"
 	"k8s.io/client-go/informers/internalinterfaces"
+	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/rest"
+	"k8s.io/client-go/tools/cache"
+	"k8s.io/client-go/tools/clientcmd"
+	"k8s.io/klog"
 )
 
 const (
@@ -121,7 +121,6 @@ func NodeNameFilter(nodeName string) internalinterfaces.TweakListOptionsFunc {
 			l = &metav1.ListOptions{}
 		}
 		l.FieldSelector = l.FieldSelector + "spec.nodeName=" + nodeName
-		return
 	}
 }
 
@@ -199,7 +198,10 @@ func (c *KubeClient) getPodListRetry(podip string, retries int, sleeptime time.D
 		if err == nil {
 			return podList, nil
 		}
-		c.reporter.ReportKubernetesAPIOperationError(metrics.GetPodListOperationName)
+		err = c.reporter.ReportKubernetesAPIOperationError(metrics.GetPodListOperationName)
+		if err != nil {
+			klog.Warningf("Metrics reporter error: %+v", err)
+		}
 
 		if i >= retries {
 			break
@@ -249,7 +251,10 @@ func (c *KubeClient) ListPodIdentityExceptions(ns string) (*[]aadpodid.AzurePodI
 func (c *KubeClient) GetSecret(secretRef *v1.SecretReference) (*v1.Secret, error) {
 	secret, err := c.ClientSet.CoreV1().Secrets(secretRef.Namespace).Get(secretRef.Name, metav1.GetOptions{})
 	if err != nil {
-		c.reporter.ReportKubernetesAPIOperationError(metrics.GetSecretOperationName)
+		merr := c.reporter.ReportKubernetesAPIOperationError(metrics.GetSecretOperationName)
+		if merr != nil {
+			klog.Warningf("Metrics reporter error: %+v", err)
+		}
 		return nil, err
 	}
 	return secret, nil
@@ -274,12 +279,3 @@ func buildConfig() (*rest.Config, error) {
 
 	return rest.InClusterConfig()
 }
-
-// recordError records the error in appropriate metric
-func recordError(reporter *metrics.Reporter, operation string) {
-	if reporter != nil {
-		reporter.ReportOperation(
-			operation,
-			metrics.KubernetesAPIOperationsErrorsCountM.M(1))
-	}
-}
diff --git a/pkg/k8s/fake.go b/pkg/k8s/fake.go
index bb9f6e58..da0f270f 100644
--- a/pkg/k8s/fake.go
+++ b/pkg/k8s/fake.go
@@ -2,6 +2,7 @@ package k8s
 
 import (
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity"
+
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go
index a5aad09c..77eee7c2 100644
--- a/pkg/metrics/metrics.go
+++ b/pkg/metrics/metrics.go
@@ -8,7 +8,6 @@ import (
 	"go.opencensus.io/stats"
 	"go.opencensus.io/stats/view"
 	"go.opencensus.io/tag"
-
 	"k8s.io/klog"
 )
 
@@ -167,83 +166,83 @@ func SinceInSeconds(start time.Time) float64 {
 // registerViews register views to be collected by exporter
 func registerViews() error {
 	views := []*view.View{
-		&view.View{
+		{
 			Description: AssignedIdentityAdditionDurationM.Description(),
 			Measure:     AssignedIdentityAdditionDurationM,
 			Aggregation: view.Distribution(0.01, 0.02, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 2, 3, 4, 5, 10),
 		},
-		&view.View{
+		{
 			Description: AssignedIdentityAdditionCountM.Description(),
 			Measure:     AssignedIdentityAdditionCountM,
 			Aggregation: view.Count(),
 		},
-		&view.View{
+		{
 			Description: AssignedIdentityDeletionDurationM.Description(),
 			Measure:     AssignedIdentityDeletionDurationM,
 			Aggregation: view.Distribution(0.01, 0.02, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 2, 3, 4, 5, 10),
 		},
-		&view.View{
+		{
 			Description: AssignedIdentityDeletionCountM.Description(),
 			Measure:     AssignedIdentityDeletionCountM,
 			Aggregation: view.Count(),
 		},
-		&view.View{
+		{
 			Description: NMIOperationsDurationM.Description(),
 			Measure:     NMIOperationsDurationM,
 			Aggregation: view.Distribution(0.5, 1, 2, 3, 4, 5, 10, 15, 20, 25, 30, 40, 50, 60, 70, 80, 90, 100),
 			TagKeys:     []tag.Key{operationTypeKey, statusCodeKey, namespaceKey, resourceKey},
 		},
-		&view.View{
+		{
 			Description: MICCycleDurationM.Description(),
 			Measure:     MICCycleDurationM,
 			Aggregation: view.Distribution(0.5, 1, 5, 10, 30, 60, 120, 300, 600, 900, 1200),
 		},
-		&view.View{
+		{
 			Description: MICCycleCountM.Description(),
 			Measure:     MICCycleCountM,
 			Aggregation: view.Count(),
 		},
-		&view.View{
+		{
 			Description: MICNewLeaderElectionCountM.Description(),
 			Measure:     MICNewLeaderElectionCountM,
 			Aggregation: view.Count(),
 		},
-		&view.View{
+		{
 			Description: CloudProviderOperationsErrorsCountM.Description(),
 			Measure:     CloudProviderOperationsErrorsCountM,
 			Aggregation: view.Count(),
 			TagKeys:     []tag.Key{operationTypeKey},
 		},
-		&view.View{
+		{
 			Description: CloudProviderOperationsDurationM.Description(),
 			Measure:     CloudProviderOperationsDurationM,
 			Aggregation: view.Distribution(0.5, 1, 5, 10, 30, 60, 120, 300, 600, 900, 1200),
 			TagKeys:     []tag.Key{operationTypeKey},
 		},
-		&view.View{
+		{
 			Description: KubernetesAPIOperationsErrorsCountM.Description(),
 			Measure:     KubernetesAPIOperationsErrorsCountM,
 			Aggregation: view.Count(),
 			TagKeys:     []tag.Key{operationTypeKey},
 		},
-		&view.View{
+		{
 			Description: ImdsOperationsErrorsCountM.Description(),
 			Measure:     ImdsOperationsErrorsCountM,
 			Aggregation: view.Count(),
 			TagKeys:     []tag.Key{operationTypeKey},
 		},
-		&view.View{
+		{
 			Description: ImdsOperationsDurationM.Description(),
 			Measure:     ImdsOperationsDurationM,
 			Aggregation: view.Distribution(0.01, 0.02, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 2, 3, 4, 5, 10),
 			TagKeys:     []tag.Key{operationTypeKey},
 		},
-		&view.View{
+		{
 			Description: AssignedIdentityUpdateDurationM.Description(),
 			Measure:     AssignedIdentityUpdateDurationM,
 			Aggregation: view.Distribution(0.01, 0.02, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 2, 3, 4, 5, 10),
 		},
-		&view.View{
+		{
 			Description: AssignedIdentityUpdateCountM.Description(),
 			Measure:     AssignedIdentityUpdateCountM,
 			Aggregation: view.Count(),
diff --git a/pkg/metrics/prometheus_exporter.go b/pkg/metrics/prometheus_exporter.go
index f758f3fc..e376ec6e 100644
--- a/pkg/metrics/prometheus_exporter.go
+++ b/pkg/metrics/prometheus_exporter.go
@@ -5,7 +5,6 @@ import (
 	"net/http"
 
 	"contrib.go.opencensus.io/exporter/prometheus"
-
 	"k8s.io/klog"
 )
 
diff --git a/pkg/mic/mic.go b/pkg/mic/mic.go
index b10f04ae..bc04a3e5 100644
--- a/pkg/mic/mic.go
+++ b/pkg/mic/mic.go
@@ -405,8 +405,8 @@ func (c *Client) Sync(exit <-chan struct{}) {
 
 		cacheTime := time.Now()
 
-		// There is a delay in data propogation to cache. It's possible that the creates performed in the previous sync cycle
-		// are not propogated before this sync cycle began. In order to avoid redoing the cycle, we sync cache again.
+		// There is a delay in data propagation to cache. It's possible that the creates performed in the previous sync cycle
+		// are not propagated before this sync cycle began. In order to avoid redoing the cycle, we sync cache again.
 		c.CRDClient.SyncCacheAll(exit, false)
 		stats.Put(stats.CacheSync, time.Since(cacheTime))
 
@@ -524,37 +524,31 @@ func (c *Client) Sync(exit <-chan struct{}) {
 }
 
 func (c *Client) convertAssignedIDListToMap(addList, deleteList, updateList map[string]aadpodid.AzureAssignedIdentity, nodeMap map[string]trackUserAssignedMSIIds) {
-	if addList != nil {
-		for _, createID := range addList {
-			if trackList, ok := nodeMap[createID.Spec.NodeName]; ok {
-				trackList.assignedIDsToCreate = append(trackList.assignedIDsToCreate, createID)
-				nodeMap[createID.Spec.NodeName] = trackList
-				continue
-			}
-			nodeMap[createID.Spec.NodeName] = trackUserAssignedMSIIds{assignedIDsToCreate: []aadpodid.AzureAssignedIdentity{createID}}
+	for _, createID := range addList {
+		if trackList, ok := nodeMap[createID.Spec.NodeName]; ok {
+			trackList.assignedIDsToCreate = append(trackList.assignedIDsToCreate, createID)
+			nodeMap[createID.Spec.NodeName] = trackList
+			continue
 		}
+		nodeMap[createID.Spec.NodeName] = trackUserAssignedMSIIds{assignedIDsToCreate: []aadpodid.AzureAssignedIdentity{createID}}
 	}
 
-	if deleteList != nil {
-		for _, delID := range deleteList {
-			if trackList, ok := nodeMap[delID.Spec.NodeName]; ok {
-				trackList.assignedIDsToDelete = append(trackList.assignedIDsToDelete, delID)
-				nodeMap[delID.Spec.NodeName] = trackList
-				continue
-			}
-			nodeMap[delID.Spec.NodeName] = trackUserAssignedMSIIds{assignedIDsToDelete: []aadpodid.AzureAssignedIdentity{delID}}
+	for _, delID := range deleteList {
+		if trackList, ok := nodeMap[delID.Spec.NodeName]; ok {
+			trackList.assignedIDsToDelete = append(trackList.assignedIDsToDelete, delID)
+			nodeMap[delID.Spec.NodeName] = trackList
+			continue
 		}
+		nodeMap[delID.Spec.NodeName] = trackUserAssignedMSIIds{assignedIDsToDelete: []aadpodid.AzureAssignedIdentity{delID}}
 	}
 
-	if updateList != nil {
-		for _, updateID := range updateList {
-			if trackList, ok := nodeMap[updateID.Spec.NodeName]; ok {
-				trackList.assignedIDsToUpdate = append(trackList.assignedIDsToUpdate, updateID)
-				nodeMap[updateID.Spec.NodeName] = trackList
-				continue
-			}
-			nodeMap[updateID.Spec.NodeName] = trackUserAssignedMSIIds{assignedIDsToUpdate: []aadpodid.AzureAssignedIdentity{updateID}}
+	for _, updateID := range updateList {
+		if trackList, ok := nodeMap[updateID.Spec.NodeName]; ok {
+			trackList.assignedIDsToUpdate = append(trackList.assignedIDsToUpdate, updateID)
+			nodeMap[updateID.Spec.NodeName] = trackList
+			continue
 		}
+		nodeMap[updateID.Spec.NodeName] = trackUserAssignedMSIIds{assignedIDsToUpdate: []aadpodid.AzureAssignedIdentity{updateID}}
 	}
 }
 
@@ -692,7 +686,7 @@ func (c *Client) shouldRemoveID(assignedID aadpodid.AzureAssignedIdentity,
 	id := assignedID.Spec.AzureIdentityRef
 	isUserAssignedMSI := c.checkIfUserAssignedMSI(*id)
 	isImmutableIdentity := c.checkIfIdentityImmutable(id.Spec.ClientID)
-	// this case includes Assigned state and empty state to ensure backward compatability
+	// this case includes Assigned state and empty state to ensure backward compatibility
 	if assignedID.Status.Status == aadpodid.AssignedIDAssigned || assignedID.Status.Status == "" {
 		// only user assigned identities that are not in use and are not defined as
 		// immutable will be removed from underlying node/vmss
diff --git a/pkg/mic/vmss.go b/pkg/mic/vmss.go
index 320fc367..757c622f 100644
--- a/pkg/mic/vmss.go
+++ b/pkg/mic/vmss.go
@@ -4,6 +4,7 @@ import (
 	"path"
 
 	"github.com/Azure/aad-pod-identity/pkg/cloudprovider"
+
 	"github.com/Azure/go-autorest/autorest/azure"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
diff --git a/pkg/nmi/iptables/iptables.go b/pkg/nmi/iptables/iptables.go
index d776651e..d36ff51d 100644
--- a/pkg/nmi/iptables/iptables.go
+++ b/pkg/nmi/iptables/iptables.go
@@ -4,9 +4,8 @@ import (
 	"errors"
 	"strings"
 
-	"k8s.io/klog"
-
 	"github.com/coreos/go-iptables/iptables"
+	"k8s.io/klog"
 )
 
 var (
diff --git a/pkg/nmi/managed.go b/pkg/nmi/managed.go
index a0783d27..8030e33d 100644
--- a/pkg/nmi/managed.go
+++ b/pkg/nmi/managed.go
@@ -9,6 +9,7 @@ import (
 	auth "github.com/Azure/aad-pod-identity/pkg/auth"
 	k8s "github.com/Azure/aad-pod-identity/pkg/k8s"
 	utils "github.com/Azure/aad-pod-identity/pkg/utils"
+
 	"github.com/Azure/go-autorest/autorest/adal"
 	"k8s.io/klog"
 )
@@ -41,6 +42,10 @@ func (mc *ManagedClient) GetIdentities(ctx context.Context, podns, podname, clie
 	}
 	// get all the azure identities based on azure identity bindings
 	azureIdentities, err := mc.KubeClient.ListPodIdsWithBinding(podns, pod.Labels)
+	if err != nil {
+		return nil, fmt.Errorf("failed to get azure identities %s/%s, err: %+v", podns, podname, err)
+	}
+
 	for _, id := range azureIdentities {
 		// if client id exists in the request, then send the first identity that matched the client id
 		if len(clientID) != 0 && id.Spec.ClientID == clientID {
diff --git a/pkg/nmi/nmi.go b/pkg/nmi/nmi.go
index 13692a72..b38e2820 100644
--- a/pkg/nmi/nmi.go
+++ b/pkg/nmi/nmi.go
@@ -6,6 +6,7 @@ import (
 
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity"
 	"github.com/Azure/aad-pod-identity/pkg/k8s"
+
 	"github.com/Azure/go-autorest/autorest/adal"
 	"k8s.io/klog"
 )
diff --git a/pkg/nmi/server/server.go b/pkg/nmi/server/server.go
index 024ccc84..f9988a66 100644
--- a/pkg/nmi/server/server.go
+++ b/pkg/nmi/server/server.go
@@ -23,6 +23,7 @@ import (
 	"github.com/Azure/aad-pod-identity/pkg/nmi"
 	"github.com/Azure/aad-pod-identity/pkg/nmi/iptables"
 	"github.com/Azure/aad-pod-identity/pkg/pod"
+
 	"github.com/Azure/go-autorest/autorest/adal"
 	"k8s.io/klog"
 )
@@ -192,12 +193,15 @@ func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	_, resource := parseRequestClientIDAndResource(r)
 
 	if appHandlerReporter != nil {
-		appHandlerReporter.ReportOperationAndStatus(
+		err := appHandlerReporter.ReportOperationAndStatus(
 			r.URL.Path,
 			strconv.Itoa(rw.statusCode),
 			ns,
 			resource,
 			metrics.NMIOperationsDurationM.M(metrics.SinceInSeconds(start)))
+		if err != nil {
+			klog.Warningf("Metrics reporter error: %+v", err)
+		}
 	}
 }
 
@@ -245,7 +249,7 @@ func (s *Server) hostHandler(w http.ResponseWriter, r *http.Request) (ns string)
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	w.Write(response)
+	_, _ = w.Write(response)
 	return
 }
 
@@ -357,7 +361,7 @@ func (s *Server) msiHandler(w http.ResponseWriter, r *http.Request) (ns string)
 			http.Error(w, err.Error(), errorCode)
 			return
 		}
-		w.Write(response)
+		_, _ = w.Write(response)
 		return
 	}
 
@@ -380,7 +384,7 @@ func (s *Server) msiHandler(w http.ResponseWriter, r *http.Request) (ns string)
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	w.Write(response)
+	_, _ = w.Write(response)
 	return
 }
 
@@ -402,7 +406,6 @@ func metadataNotSpecifiedError(w http.ResponseWriter) {
 	w.Header().Set("Content-Type", "application/json; charset=utf-8")
 	w.WriteHeader(http.StatusBadRequest)
 	fmt.Fprintln(w, string(response))
-	return
 }
 
 func parseMetadata(r *http.Request) (metadata string) {
@@ -475,7 +478,7 @@ func (s *Server) defaultPathHandler(w http.ResponseWriter, r *http.Request) (ns
 		klog.Errorf("failed io operation of reading response body for %s, %+v", req.URL.String(), err)
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 	}
-	w.Write(body)
+	_, _ = w.Write(body)
 	return
 }
 
@@ -528,8 +531,5 @@ func validateResourceParamExists(resource string) bool {
 	// if resource doesn't exist in the request, then adal libraries will return the same error
 	// IMDS also returns an error with 400 response code if resource parameter is empty
 	// this is done to emulate same behavior observed while requesting token from IMDS
-	if len(resource) == 0 {
-		return false
-	}
-	return true
+	return len(resource) != 0
 }
diff --git a/pkg/nmi/standard.go b/pkg/nmi/standard.go
index 9dd1e372..e2eb6585 100644
--- a/pkg/nmi/standard.go
+++ b/pkg/nmi/standard.go
@@ -10,8 +10,8 @@ import (
 	auth "github.com/Azure/aad-pod-identity/pkg/auth"
 	k8s "github.com/Azure/aad-pod-identity/pkg/k8s"
 	utils "github.com/Azure/aad-pod-identity/pkg/utils"
-	"github.com/Azure/go-autorest/autorest/adal"
 
+	"github.com/Azure/go-autorest/autorest/adal"
 	"k8s.io/klog"
 )
 
@@ -95,7 +95,7 @@ func (sc *StandardClient) listPodIDsWithRetry(ctx context.Context, podns, podnam
 		idStateMap, err = sc.KubeClient.ListPodIds(podns, podname)
 		if err == nil {
 			if len(rqClientID) == 0 {
-				// check to ensure backward compatability with assignedIDs that have no state
+				// check to ensure backward compatibility with assignedIDs that have no state
 				// assigned identites created with old version of mic will not contain a state. So first we check to see if an assigned identity with
 				// no state exists that matches req client id.
 				if len(idStateMap[""]) != 0 {
@@ -112,7 +112,7 @@ func (sc *StandardClient) listPodIDsWithRetry(ctx context.Context, podns, podnam
 			} else {
 				// if client id exists in request, we need to ensure the identity with this client
 				// exists and is in Assigned state
-				// check to ensure backward compatability with assignedIDs that have no state
+				// check to ensure backward compatibility with assignedIDs that have no state
 				for _, podID := range idStateMap[""] {
 					if strings.EqualFold(rqClientID, podID.Spec.ClientID) {
 						klog.Warningf("found assignedIDs with no state for pod:%s/%s. AssignedIDs created with old version of mic.", podns, podname)
diff --git a/pkg/pod/pod.go b/pkg/pod/pod.go
index 9a3ee3ad..b9a7f169 100644
--- a/pkg/pod/pod.go
+++ b/pkg/pod/pod.go
@@ -4,6 +4,7 @@ import (
 	"strings"
 	"time"
 
+	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity"
 	"github.com/Azure/aad-pod-identity/pkg/stats"
 
 	v1 "k8s.io/api/core/v1"
@@ -13,8 +14,6 @@ import (
 	informersv1 "k8s.io/client-go/informers/core/v1"
 	"k8s.io/client-go/tools/cache"
 	"k8s.io/klog"
-
-	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity"
 )
 
 // Client represents new pod client
diff --git a/pkg/probes/probes.go b/pkg/probes/probes.go
index 6c2b333c..719184d3 100644
--- a/pkg/probes/probes.go
+++ b/pkg/probes/probes.go
@@ -14,9 +14,9 @@ func InitHealthProbe(condition *bool) {
 	http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(200)
 		if *condition {
-			w.Write([]byte("Active"))
+			_, _ = w.Write([]byte("Active"))
 		} else {
-			w.Write([]byte("Not Active"))
+			_, _ = w.Write([]byte("Not Active"))
 		}
 	})
 }
diff --git a/pkg/stats/stats.go b/pkg/stats/stats.go
index 19989831..514a4497 100644
--- a/pkg/stats/stats.go
+++ b/pkg/stats/stats.go
@@ -7,50 +7,50 @@ import (
 	"k8s.io/klog"
 )
 
-var GlobalStats map[StatsType]time.Duration
-var CountStats map[StatsType]int
+var GlobalStats map[Type]time.Duration
+var CountStats map[Type]int
 
 var Mutex *sync.RWMutex
 
-type StatsType string
+type Type string
 
 const (
-	Total                   StatsType = "Total"
-	System                  StatsType = "System"
-	CacheSync               StatsType = "CacheSync"
-	CurrentState            StatsType = "Gather current state"
-	PodList                 StatsType = "Pod listing"
-	BindingList             StatsType = "Binding listing"
-	IDList                  StatsType = "ID listing"
-	ExceptionList           StatsType = "Pod Identity Exception listing"
-	AssignedIDList          StatsType = "Assigned ID listing"
-	CloudGet                StatsType = "Cloud provider get"
-	CloudPut                StatsType = "Cloud provider put"
-	TotalPutCalls           StatsType = "Number of cloud provider PUT"
-	TotalGetCalls           StatsType = "Number of cloud provider GET"
-	TotalAssignedIDsCreated StatsType = "Number of assigned ids created in this sync cycle"
-	TotalAssignedIDsUpdated StatsType = "Number of assigned ids updated in this sync cycle"
-	TotalAssignedIDsDeleted StatsType = "Number of assigned ids deleted in this sync cycle"
-	K8sGet                  StatsType = "K8s get"
-	K8sPut                  StatsType = "K8s put"
-	FindAssignedIDDel       StatsType = "Find assigned ids to delete"
-	FindAssignedIDCreate    StatsType = "Find assigned ids to create"
-	AssignedIDDel           StatsType = "Assigned ID deletion"
-	AssignedIDAdd           StatsType = "Assigned ID addition"
-	TotalIDDel              StatsType = "Total time to delete assigned IDs"
-	TotalIDAdd              StatsType = "Total time to add assigned IDs"
-	TotalCreateOrUpdate     StatsType = "Total time to assign or remove IDs"
-
-	EventRecord StatsType = "Event recording"
+	Total                   Type = "Total"
+	System                  Type = "System"
+	CacheSync               Type = "CacheSync"
+	CurrentState            Type = "Gather current state"
+	PodList                 Type = "Pod listing"
+	BindingList             Type = "Binding listing"
+	IDList                  Type = "ID listing"
+	ExceptionList           Type = "Pod Identity Exception listing"
+	AssignedIDList          Type = "Assigned ID listing"
+	CloudGet                Type = "Cloud provider get"
+	CloudPut                Type = "Cloud provider put"
+	TotalPutCalls           Type = "Number of cloud provider PUT"
+	TotalGetCalls           Type = "Number of cloud provider GET"
+	TotalAssignedIDsCreated Type = "Number of assigned ids created in this sync cycle"
+	TotalAssignedIDsUpdated Type = "Number of assigned ids updated in this sync cycle"
+	TotalAssignedIDsDeleted Type = "Number of assigned ids deleted in this sync cycle"
+	K8sGet                  Type = "K8s get"
+	K8sPut                  Type = "K8s put"
+	FindAssignedIDDel       Type = "Find assigned ids to delete"
+	FindAssignedIDCreate    Type = "Find assigned ids to create"
+	AssignedIDDel           Type = "Assigned ID deletion"
+	AssignedIDAdd           Type = "Assigned ID addition"
+	TotalIDDel              Type = "Total time to delete assigned IDs"
+	TotalIDAdd              Type = "Total time to add assigned IDs"
+	TotalCreateOrUpdate     Type = "Total time to assign or remove IDs"
+
+	EventRecord Type = "Event recording"
 )
 
 func Init() {
-	GlobalStats = make(map[StatsType]time.Duration)
-	CountStats = make(map[StatsType]int)
+	GlobalStats = make(map[Type]time.Duration)
+	CountStats = make(map[Type]int)
 	Mutex = &sync.RWMutex{}
 }
 
-func Put(key StatsType, val time.Duration) {
+func Put(key Type, val time.Duration) {
 	if GlobalStats != nil {
 		Mutex.Lock()
 		defer Mutex.Unlock()
@@ -58,7 +58,7 @@ func Put(key StatsType, val time.Duration) {
 	}
 }
 
-func Get(key StatsType) time.Duration {
+func Get(key Type) time.Duration {
 	if GlobalStats != nil {
 		Mutex.RLock()
 		defer Mutex.RUnlock()
@@ -67,7 +67,7 @@ func Get(key StatsType) time.Duration {
 	return 0
 }
 
-func Update(key StatsType, val time.Duration) {
+func Update(key Type, val time.Duration) {
 	if GlobalStats != nil {
 		Mutex.Lock()
 		defer Mutex.Unlock()
@@ -75,21 +75,21 @@ func Update(key StatsType, val time.Duration) {
 	}
 }
 
-func Print(key StatsType) {
+func Print(key Type) {
 	Mutex.RLock()
 	defer Mutex.RUnlock()
 
 	klog.Infof("%s: %s", key, GlobalStats[key])
 }
 
-func PrintCount(key StatsType) {
+func PrintCount(key Type) {
 	Mutex.RLock()
 	defer Mutex.RUnlock()
 
 	klog.Infof("%s: %d", key, CountStats[key])
 }
 
-func UpdateCount(key StatsType, val int) {
+func UpdateCount(key Type, val int) {
 	Mutex.Lock()
 	defer Mutex.Unlock()
 	CountStats[key] = CountStats[key] + val
@@ -129,7 +129,7 @@ func PrintSync() {
 	klog.Infof("*********************")
 }
 
-func GetAll() map[StatsType]time.Duration {
+func GetAll() map[Type]time.Duration {
 	Mutex.RLock()
 	defer Mutex.RUnlock()
 	return GlobalStats
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go
index 7b82debc..0015f342 100644
--- a/pkg/utils/utils.go
+++ b/pkg/utils/utils.go
@@ -11,7 +11,7 @@ func RedactClientID(clientID string) string {
 }
 
 func redact(src, repl string) string {
-	r, _ := regexp.Compile("^(\\S{4})(\\S|\\s)*(\\S{4})$")
+	r, _ := regexp.Compile(`^(\S{4})(\S|\s)*(\S{4})$`)
 	return r.ReplaceAllString(src, repl)
 }
 
diff --git a/tools/go.mod b/tools/go.mod
index c58519e0..5514b738 100644
--- a/tools/go.mod
+++ b/tools/go.mod
@@ -4,5 +4,5 @@ go 1.14
 
 require (
 	github.com/client9/misspell v0.3.4
-	github.com/golangci/golangci-lint v1.24.0
+	github.com/golangci/golangci-lint v1.27.0
 )
diff --git a/tools/go.sum b/tools/go.sum
index a796ee22..79fb7f20 100644
--- a/tools/go.sum
+++ b/tools/go.sum
@@ -1,6 +1,8 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157 h1:hY39LwQHh+1kaovmIjOrlqnXNX6tygSRfLkkK33IkZU=
+github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us=
 github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
@@ -10,8 +12,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
 github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
-github.com/bombsimon/wsl/v2 v2.0.0 h1:+Vjcn+/T5lSrO8Bjzhk4v14Un/2UyCA1E3V5j9nwTkQ=
-github.com/bombsimon/wsl/v2 v2.0.0/go.mod h1:mf25kr/SqFEPhhcxW1+7pxzGlW+hIl/hYTKY95VwV8U=
+github.com/bombsimon/wsl/v3 v3.0.0 h1:w9f49xQatuaeTJFaNP4SpiWSR5vfT6IstPtM62JjcqA=
+github.com/bombsimon/wsl/v3 v3.0.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@@ -22,7 +24,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
-github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -64,6 +66,7 @@ github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUD
 github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
 github.com/go-toolsmith/typep v1.0.0 h1:zKymWyA1TRYvqYrYDrfEMZULyrhcnGY3x7LDKU2XQaA=
 github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
+github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
 github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
 github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
 github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b h1:ekuhfTjngPhisSjOJ0QWKpPQE8/rbknHaes6WVJj5Hw=
@@ -92,8 +95,8 @@ github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee h1:J2XAy40+7yz70u
 github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU=
 github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks=
 github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU=
-github.com/golangci/golangci-lint v1.24.0 h1:OcmSTTMPqI/VT4GvN1fKuE9NX15dDXIwolO0l08334U=
-github.com/golangci/golangci-lint v1.24.0/go.mod h1:yIqiAZ2SSQqg+1JeFlAdvEWjGVz4uu5jr4lrciqA1gE=
+github.com/golangci/golangci-lint v1.27.0 h1:VYLx63qb+XJsHdZ27PMS2w5JZacN0XG8ffUwe7yQomo=
+github.com/golangci/golangci-lint v1.27.0/go.mod h1:+eZALfxIuthdrHPtfM7w/R3POJLjHDfJJw8XZl9xOng=
 github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI=
 github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU=
 github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA=
@@ -113,6 +116,7 @@ github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
@@ -149,15 +153,17 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
 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/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
 github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ=
+github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU=
 github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb h1:RHba4YImhrUVQDHUCe2BNSOz4tVy2yGyXhvYDvxGgeE=
 github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
 github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@@ -172,19 +178,25 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
 github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
+github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw=
+github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c=
 github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E=
 github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
 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 v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
-github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
+github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
+github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
+github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
 github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
 github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -203,8 +215,10 @@ github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
-github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83 h1:AtnWoOvTioyDXFvu96MWEeE8qj4COSQnJogzLy/u41A=
-github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83/go.mod h1:vvbZ2Ae7AzSq3/kywjUDxSNq2SJ27RxCz2un0H3ePqE=
+github.com/ryancurrah/gomodguard v1.0.4 h1:oCreMAt9GuFXDe9jW4HBpc3GjdX3R/sUEcLAGh1zPx8=
+github.com/ryancurrah/gomodguard v1.0.4/go.mod h1:9T/Cfuxs5StfsocWr4WzDL36HqnX0fVb9d5fSEaLhoE=
+github.com/securego/gosec/v2 v2.3.0 h1:y/9mCF2WPDbSDpL3QDWZD3HHGrSYw0QSHnCqTfs4JPE=
+github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME=
 github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
 github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
 github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e h1:MZM7FHLqUHYI0Y/mQAt3d2aYa0SiNms/hFqC9qJYolM=
@@ -237,15 +251,20 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
 github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk=
 github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
-github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 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/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
+github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2 h1:Xr9gkxfOP0KQWXKNqmwe8vEeSUiUj4Rlee9CMVX2ZUQ=
+github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM=
+github.com/tetafro/godot v0.3.7 h1:+mecr7RKrUKB5UQ1gwqEMn13sDKTyDR8KNIquB9mm+8=
+github.com/tetafro/godot v0.3.7/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0=
 github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e h1:RumXZ56IrCj4CL+g1b9OL/oH0QnsF976bC8xQFYUD5Q=
 github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -265,6 +284,8 @@ github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOV
 github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
@@ -277,8 +298,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 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=
@@ -290,13 +311,14 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
-golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/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/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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -307,8 +329,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM=
-golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/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=
@@ -328,14 +350,19 @@ golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBn
 golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
 golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191113232020-e2727e816f5a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20200102140908-9497f49d5709/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200204192400-7124308813f3 h1:Ms82wn6YK4ZycO6Bxyh0kxX3gFFVGo79CCuc52xgcys=
-golang.org/x/tools v0.0.0-20200204192400-7124308813f3/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200331202046-9d5940d49312/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770 h1:M9Fif0OxNji8w+HvmhVQ8KJtiZOsjU9RgslJGhn95XE=
+golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 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/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@@ -346,6 +373,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
@@ -358,9 +387,8 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
-gopkg.in/yaml.v2 v2.2.7/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.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
 honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=


Test patch:
diff --git a/.pipelines/unit-tests-template.yml b/.pipelines/unit-tests-template.yml
index 71a92eae..c4d77e0a 100644
--- a/.pipelines/unit-tests-template.yml
+++ b/.pipelines/unit-tests-template.yml
@@ -1,16 +1,18 @@
 jobs:
   - job: unit_tests
-    timeoutInMinutes: 10
+    timeoutInMinutes: 20
     cancelTimeoutInMinutes: 5
     workspace:
       clean: all
     steps:
       - task: GoTool@0
         inputs:
-          version: 1.14.1
+          version: 1.14.2
       - script: make build
         displayName: Build
       - script: make unit-test
         displayName: Run unit tests
+      - script: make lint
+        displayName: Run lint
       - script: make helm-lint
         displayName: Run helm lint
diff --git a/pkg/apis/aadpodidentity/v1/conversion_test.go b/pkg/apis/aadpodidentity/v1/conversion_test.go
index e72e9f84..b6f9cd4e 100644
--- a/pkg/apis/aadpodidentity/v1/conversion_test.go
+++ b/pkg/apis/aadpodidentity/v1/conversion_test.go
@@ -4,6 +4,7 @@ import (
 	"testing"
 
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity"
+
 	"github.com/google/go-cmp/cmp"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
diff --git a/pkg/cloudprovider/cloudprovider_test.go b/pkg/cloudprovider/cloudprovider_test.go
index a30bbe5c..966f24cf 100644
--- a/pkg/cloudprovider/cloudprovider_test.go
+++ b/pkg/cloudprovider/cloudprovider_test.go
@@ -6,11 +6,11 @@ import (
 	"testing"
 
 	"github.com/Azure/aad-pod-identity/pkg/config"
+
+	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
 	"github.com/Azure/go-autorest/autorest/azure"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
-	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
 )
 
 func TestParseResourceID(t *testing.T) {
@@ -76,11 +76,26 @@ func TestSimple(t *testing.T) {
 			node3 := &corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: "node3-0"}, Spec: corev1.NodeSpec{ProviderID: vmProvider}}
 			node4 := &corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: "node4-vmss0000000"}, Spec: corev1.NodeSpec{ProviderID: vmssProvider}}
 
-			cloudClient.UpdateUserMSI([]string{"ID0", "ID0again"}, []string{}, node0.Name, false)
-			cloudClient.UpdateUserMSI([]string{"ID1"}, []string{}, node1.Name, false)
-			cloudClient.UpdateUserMSI([]string{"ID2"}, []string{}, node2.Name, false)
-			cloudClient.UpdateUserMSI([]string{"ID3"}, []string{}, node3.Name, false)
-			cloudClient.UpdateUserMSI([]string{"ID4"}, []string{}, node4.Name, true)
+			err := cloudClient.UpdateUserMSI([]string{"ID0", "ID0again"}, []string{}, node0.Name, false)
+			if err != nil {
+				t.Errorf("Couldn't update MSI: %v", err)
+			}
+			err = cloudClient.UpdateUserMSI([]string{"ID1"}, []string{}, node1.Name, false)
+			if err != nil {
+				t.Errorf("Couldn't update MSI: %v", err)
+			}
+			err = cloudClient.UpdateUserMSI([]string{"ID2"}, []string{}, node2.Name, false)
+			if err != nil {
+				t.Errorf("Couldn't update MSI: %v", err)
+			}
+			err = cloudClient.UpdateUserMSI([]string{"ID3"}, []string{}, node3.Name, false)
+			if err != nil {
+				t.Errorf("Couldn't update MSI: %v", err)
+			}
+			err = cloudClient.UpdateUserMSI([]string{"ID4"}, []string{}, node4.Name, true)
+			if err != nil {
+				t.Errorf("Couldn't update MSI: %v", err)
+			}
 
 			testMSI := []string{"ID0", "ID0again"}
 			if !cloudClient.CompareMSI(node0.Name, false, testMSI) {
@@ -88,8 +103,14 @@ func TestSimple(t *testing.T) {
 				t.Error("MSI mismatch")
 			}
 
-			cloudClient.UpdateUserMSI([]string{}, []string{"ID0"}, node0.Name, false)
-			cloudClient.UpdateUserMSI([]string{}, []string{"ID2"}, node2.Name, false)
+			err = cloudClient.UpdateUserMSI([]string{}, []string{"ID0"}, node0.Name, false)
+			if err != nil {
+				t.Errorf("Couldn't update MSI: %v", err)
+			}
+			err = cloudClient.UpdateUserMSI([]string{}, []string{"ID2"}, node2.Name, false)
+			if err != nil {
+				t.Errorf("Couldn't update MSI: %v", err)
+			}
 
 			testMSI = []string{"ID0again"}
 			if !cloudClient.CompareMSI(node0.Name, false, testMSI) {
@@ -115,28 +136,44 @@ func TestSimple(t *testing.T) {
 			}
 
 			// test the UpdateUserMSI interface
-			cloudClient.UpdateUserMSI([]string{"ID1", "ID2", "ID3"}, []string{"ID0again"}, node0.Name, false)
+			err = cloudClient.UpdateUserMSI([]string{"ID1", "ID2", "ID3"}, []string{"ID0again"}, node0.Name, false)
+			if err != nil {
+				t.Errorf("Couldn't update MSI: %v", err)
+			}
+
 			testMSI = []string{"ID1", "ID2", "ID3"}
 			if !cloudClient.CompareMSI(node0.Name, false, testMSI) {
 				cloudClient.PrintMSI(t)
 				t.Error("MSI mismatch")
 			}
 
-			cloudClient.UpdateUserMSI(nil, []string{"ID3"}, node3.Name, false)
+			err = cloudClient.UpdateUserMSI(nil, []string{"ID3"}, node3.Name, false)
+			if err != nil {
+				t.Errorf("Couldn't update MSI: %v", err)
+			}
+
 			testMSI = []string{}
 			if !cloudClient.CompareMSI(node3.Name, false, testMSI) {
 				cloudClient.PrintMSI(t)
 				t.Error("MSI mismatch")
 			}
 
-			cloudClient.UpdateUserMSI([]string{"ID3"}, nil, node4.Name, true)
+			err = cloudClient.UpdateUserMSI([]string{"ID3"}, nil, node4.Name, true)
+			if err != nil {
+				t.Error("Couldn't update MSI")
+			}
+
 			testMSI = []string{"ID4", "ID3"}
 			if !cloudClient.CompareMSI(node4.Name, true, testMSI) {
 				cloudClient.PrintMSI(t)
 				t.Error("MSI mismatch")
 			}
 
-			cloudClient.UpdateUserMSI([]string{"ID3"}, []string{"ID3"}, node4.Name, true)
+			err = cloudClient.UpdateUserMSI([]string{"ID3"}, []string{"ID3"}, node4.Name, true)
+			if err != nil {
+				t.Errorf("Couldn't update MSI: %v", err)
+			}
+
 			testMSI = []string{"ID4", "ID3"}
 			if !cloudClient.CompareMSI(node4.Name, true, testMSI) {
 				cloudClient.PrintMSI(t)
diff --git a/pkg/cloudprovider/identity_test.go b/pkg/cloudprovider/identity_test.go
index 53a845c4..d1babbe8 100644
--- a/pkg/cloudprovider/identity_test.go
+++ b/pkg/cloudprovider/identity_test.go
@@ -6,18 +6,6 @@ import (
 	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
 )
 
-func checkIDList(t *testing.T, expect, actual []string) {
-	t.Helper()
-	if len(actual) != len(expect) {
-		t.Fatalf("expected %v, got: %v", expect, actual)
-	}
-	for i, v := range expect {
-		if actual[i] != v {
-			t.Fatalf("expected entry %d to be %q, got: %s", i, v, actual[i])
-		}
-	}
-}
-
 func TestGetUpdatedResourceIdentityType(t *testing.T) {
 	cases := []struct {
 		current  compute.ResourceIdentityType
diff --git a/pkg/crd/crd_test.go b/pkg/crd/crd_test.go
index ad86503a..53354812 100644
--- a/pkg/crd/crd_test.go
+++ b/pkg/crd/crd_test.go
@@ -3,12 +3,11 @@ package crd
 import (
 	"testing"
 
-	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/client-go/rest"
-
 	internalaadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity"
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity/v1"
+
 	api "k8s.io/api/core/v1"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
 type TestCrdClient struct {
@@ -18,19 +17,10 @@ type TestCrdClient struct {
 	idMap         map[string]*aadpodid.AzureIdentity
 }
 
-func NewTestCrdClient(config *rest.Config) *TestCrdClient {
-	return &TestCrdClient{
-		assignedIDMap: make(map[string]*aadpodid.AzureAssignedIdentity),
-		bindingMap:    make(map[string]*aadpodid.AzureIdentityBinding),
-		idMap:         make(map[string]*aadpodid.AzureIdentity),
-	}
-}
-
 func (c *TestCrdClient) Start(exit <-chan struct{}) {
 }
 
 func (c *TestCrdClient) SyncCache(exit <-chan struct{}) {
-
 }
 
 func (c *TestCrdClient) CreateCrdWatchers(eventCh chan internalaadpodid.EventType) (err error) {
diff --git a/pkg/k8s/client_test.go b/pkg/k8s/client_test.go
index b0f9bfd8..75e3732e 100644
--- a/pkg/k8s/client_test.go
+++ b/pkg/k8s/client_test.go
@@ -27,7 +27,10 @@ func TestGetSecret(t *testing.T) {
 	fakeClient := fake.NewSimpleClientset()
 
 	secret := &v1.Secret{ObjectMeta: metav1.ObjectMeta{Name: secretName}}
-	fakeClient.CoreV1().Secrets("default").Create(secret)
+	_, err := fakeClient.CoreV1().Secrets("default").Create(secret)
+	if err != nil {
+		t.Fatalf("Error creating secret: %v", err)
+	}
 
 	kubeClient := &KubeClient{ClientSet: fakeClient}
 
@@ -114,10 +117,7 @@ func (t *TestClientSet) GetPodList() io.ReadCloser {
 	defer t.mu.Unlock()
 
 	podList := &v1.PodList{}
-	for _, p := range t.podList {
-		podList.Items = append(podList.Items, p)
-	}
-
+	podList.Items = append(podList.Items, t.podList...)
 	podList.TypeMeta = metav1.TypeMeta{
 		Kind:       "PodList",
 		APIVersion: "v1",
diff --git a/pkg/metrics/metrics_test.go b/pkg/metrics/metrics_test.go
index 2bd1590d..23df82dc 100644
--- a/pkg/metrics/metrics_test.go
+++ b/pkg/metrics/metrics_test.go
@@ -30,8 +30,14 @@ func testOperationDurationMetric(t *testing.T, reporter *Reporter, m *stats.Floa
 	minimumDuration := float64(2)
 	maximumDuration := float64(4)
 	testOperationKey := "test"
-	reporter.ReportOperation(testOperationKey, m.M(minimumDuration))
-	reporter.ReportOperation(testOperationKey, m.M(maximumDuration))
+	err := reporter.ReportOperation(testOperationKey, m.M(minimumDuration))
+	if err != nil {
+		t.Errorf("Error when reporting metrics: %v from %v", err, m.Name())
+	}
+	err = reporter.ReportOperation(testOperationKey, m.M(maximumDuration))
+	if err != nil {
+		t.Errorf("Error when reporting metrics: %v from %v", err, m.Name())
+	}
 
 	row, err := view.RetrieveData(m.Name())
 	if err != nil {
diff --git a/pkg/mic/mic_test.go b/pkg/mic/mic_test.go
index 328ae0df..881bf228 100644
--- a/pkg/mic/mic_test.go
+++ b/pkg/mic/mic_test.go
@@ -11,13 +11,12 @@ import (
 
 	internalaadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity"
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity/v1"
+	cp "github.com/Azure/aad-pod-identity/pkg/cloudprovider"
 	"github.com/Azure/aad-pod-identity/pkg/config"
 	"github.com/Azure/aad-pod-identity/pkg/crd"
 	"github.com/Azure/aad-pod-identity/pkg/metrics"
 
 	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute"
-
-	cp "github.com/Azure/aad-pod-identity/pkg/cloudprovider"
 	api "k8s.io/api/core/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -572,9 +571,7 @@ func (c *TestCrdClient) UnSetError() {
 func (c *TestCrdClient) waitForAssignedIDs(count int) bool {
 	i := 0
 	for i < 10 {
-		select {
-		case <-time.After(1 * time.Second):
-		}
+		time.Sleep(1 * time.Second)
 
 		assignedIDs, err := c.ListAssignedIDs()
 		if err != nil {
@@ -1091,12 +1088,10 @@ func TestAddDelMICClient(t *testing.T) {
 
 	nodeClient.AddNode("test-node2")
 	podClient.AddPod("test-pod2", "default", "test-node2", "test-select2")
-	podClient.GetPods()
 
 	crdClient.CreateID("test-id4", "default", aadpodid.UserAssignedMSI, testResourceID, "test-user-msi-clientid", nil, "", "", "", "")
 	crdClient.CreateBinding("testbinding4", "default", "test-id4", "test-select4", "")
 	podClient.AddPod("test-pod4", "default", "test-node2", "test-select4")
-	podClient.GetPods()
 
 	eventCh <- internalaadpodid.PodCreated
 	eventCh <- internalaadpodid.PodCreated
@@ -1119,7 +1114,6 @@ func TestAddDelMICClient(t *testing.T) {
 	crdClient.CreateID("test-id3", "default", aadpodid.UserAssignedMSI, testResourceID, "test-user-msi-clientid", nil, "", "", "", "")
 	crdClient.CreateBinding("testbinding3", "default", "test-id3", "test-select3", "")
 	podClient.AddPod("test-pod3", "default", "test-node2", "test-select3")
-	podClient.GetPods()
 
 	eventCh <- internalaadpodid.PodCreated
 	eventCh <- internalaadpodid.PodDeleted
diff --git a/pkg/nmi/managed_test.go b/pkg/nmi/managed_test.go
index d3cf121a..a72dbfba 100644
--- a/pkg/nmi/managed_test.go
+++ b/pkg/nmi/managed_test.go
@@ -6,6 +6,7 @@ import (
 	"testing"
 
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity"
+
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
diff --git a/pkg/nmi/standard_test.go b/pkg/nmi/standard_test.go
index 3d427949..11497405 100644
--- a/pkg/nmi/standard_test.go
+++ b/pkg/nmi/standard_test.go
@@ -28,10 +28,6 @@ func NewTestKubeClient(azids interface{}) *TestKubeClient {
 	}
 }
 
-func (c *TestKubeClient) setError(err error) {
-	c.err = err
-}
-
 func (c *TestKubeClient) ListPodIds(podns, podname string) (map[string][]aadpodid.AzureIdentity, error) {
 	identities, _ := c.azureIdentities.(map[string][]aadpodid.AzureIdentity)
 	return identities, c.err
@@ -48,7 +44,10 @@ func TestGetTokenForMatchingIDBySP(t *testing.T) {
 	secret := &v1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "clientSecret"}, Data: make(map[string][]byte)}
 	val, _ := base64.StdEncoding.DecodeString("YWJjZA==")
 	secret.Data["key1"] = val
-	fakeClient.CoreV1().Secrets("default").Create(secret)
+	_, err = fakeClient.CoreV1().Secrets("default").Create(secret)
+	if err != nil {
+		t.Fatalf("Error creating secret: %v", err)
+	}
 
 	kubeClient := &k8s.KubeClient{ClientSet: fakeClient}
 	tokenClient, err := NewStandardTokenClient(kubeClient, Config{})
@@ -64,12 +63,12 @@ func TestGetTokenForMatchingIDBySP(t *testing.T) {
 	podID := aadpodid.AzureIdentity{
 		Spec: aadpodid.AzureIdentitySpec{
 			Type:           aadpodid.ServicePrincipal,
-			TenantID:       "tid",
+			TenantID:       "11111111-1111-1111-1111-111111111111",
 			ClientID:       "aabc0000-a83v-9h4m-000j-2c0a66b0c1f9",
 			ClientPassword: secretRef,
 		},
 	}
-	tokenClient.GetToken(context.Background(), podID.Spec.ClientID, "https://management.azure.com/", podID)
+	_, _ = tokenClient.GetToken(context.Background(), podID.Spec.ClientID, "https://management.azure.com/", podID)
 }
 
 func TestGetIdentitiesStandardClient(t *testing.T) {
@@ -94,7 +93,7 @@ func TestGetIdentitiesStandardClient(t *testing.T) {
 		{
 			name: "azure identities with old 1.3/1.4, no request client id",
 			azureIdentities: map[string][]aadpodid.AzureIdentity{
-				"": []aadpodid.AzureIdentity{
+				"": {
 					{
 						ObjectMeta: metav1.ObjectMeta{
 							Name:      "azid1",
@@ -131,7 +130,7 @@ func TestGetIdentitiesStandardClient(t *testing.T) {
 		{
 			name: "no request client id, found in created state only",
 			azureIdentities: map[string][]aadpodid.AzureIdentity{
-				aadpodid.AssignedIDCreated: []aadpodid.AzureIdentity{
+				aadpodid.AssignedIDCreated: {
 					{
 						ObjectMeta: metav1.ObjectMeta{
 							Name:      "azid3",
@@ -160,7 +159,7 @@ func TestGetIdentitiesStandardClient(t *testing.T) {
 		{
 			name: "no request client id, found in assigned state",
 			azureIdentities: map[string][]aadpodid.AzureIdentity{
-				aadpodid.AssignedIDAssigned: []aadpodid.AzureIdentity{
+				aadpodid.AssignedIDAssigned: {
 					{
 						ObjectMeta: metav1.ObjectMeta{
 							Name:      "azid5",
@@ -197,7 +196,7 @@ func TestGetIdentitiesStandardClient(t *testing.T) {
 		{
 			name: "client id in request, no identity with same client id in assigned state",
 			azureIdentities: map[string][]aadpodid.AzureIdentity{
-				aadpodid.AssignedIDCreated: []aadpodid.AzureIdentity{
+				aadpodid.AssignedIDCreated: {
 					{
 						ObjectMeta: metav1.ObjectMeta{
 							Name:      "azid1",
@@ -208,7 +207,7 @@ func TestGetIdentitiesStandardClient(t *testing.T) {
 						},
 					},
 				},
-				aadpodid.AssignedIDAssigned: []aadpodid.AzureIdentity{
+				aadpodid.AssignedIDAssigned: {
 					{
 						ObjectMeta: metav1.ObjectMeta{
 							Name:      "azid2",
@@ -229,7 +228,7 @@ func TestGetIdentitiesStandardClient(t *testing.T) {
 		{
 			name: "client id in request, identity in same namespace returned with force namespace mode",
 			azureIdentities: map[string][]aadpodid.AzureIdentity{
-				aadpodid.AssignedIDAssigned: []aadpodid.AzureIdentity{
+				aadpodid.AssignedIDAssigned: {
 					{
 						ObjectMeta: metav1.ObjectMeta{
 							Name:      "azid2",
@@ -277,7 +276,7 @@ func TestGetIdentitiesStandardClient(t *testing.T) {
 		{
 			name: "no client id in request, identity in same namespace returned with force namespace mode",
 			azureIdentities: map[string][]aadpodid.AzureIdentity{
-				aadpodid.AssignedIDAssigned: []aadpodid.AzureIdentity{
+				aadpodid.AssignedIDAssigned: {
 					{
 						ObjectMeta: metav1.ObjectMeta{
 							Name:      "azid2",
diff --git a/pkg/pod/pod_test.go b/pkg/pod/pod_test.go
index d5af21b7..c0b08ba7 100644
--- a/pkg/pod/pod_test.go
+++ b/pkg/pod/pod_test.go
@@ -14,13 +14,6 @@ type TestPodClient struct {
 	pods []*corev1.Pod
 }
 
-func NewTestPodClient() *TestPodClient {
-	var pods []*corev1.Pod
-	return &TestPodClient{
-		pods: pods,
-	}
-}
-
 func (c TestPodClient) Start(exit <-chan struct{}) {
 	klog.Info("Start called from the test interface")
 }
diff --git a/pkg/stats/stats_test.go b/pkg/stats/stats_test.go
index 1545244c..f9f8586d 100644
--- a/pkg/stats/stats_test.go
+++ b/pkg/stats/stats_test.go
@@ -10,7 +10,7 @@ import (
 )
 
 func TestBasics(t *testing.T) {
-	validateMap := make(map[stats.StatsType]time.Duration)
+	validateMap := make(map[stats.Type]time.Duration)
 	stats.Init()
 	stats.Put(stats.Total, time.Second*20)
 	validateMap[stats.Total] = time.Second * 20
diff --git a/test/common/k8s/azureassignedidentity/azureassignedidentity.go b/test/common/k8s/azureassignedidentity/azureassignedidentity.go
index 204bf21e..586529f3 100644
--- a/test/common/k8s/azureassignedidentity/azureassignedidentity.go
+++ b/test/common/k8s/azureassignedidentity/azureassignedidentity.go
@@ -10,6 +10,7 @@ import (
 
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity/v1"
 	"github.com/Azure/aad-pod-identity/test/common/util"
+
 	"github.com/pkg/errors"
 )
 
diff --git a/test/common/k8s/azureidentity/azureidentity.go b/test/common/k8s/azureidentity/azureidentity.go
index 0de7c360..cf44a239 100644
--- a/test/common/k8s/azureidentity/azureidentity.go
+++ b/test/common/k8s/azureidentity/azureidentity.go
@@ -13,6 +13,7 @@ import (
 
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity/v1"
 	"github.com/Azure/aad-pod-identity/test/common/util"
+
 	"github.com/pkg/errors"
 )
 
diff --git a/test/common/k8s/azureidentitybinding/azureidentitybinding.go b/test/common/k8s/azureidentitybinding/azureidentitybinding.go
index 7d08f4ae..a37cb657 100644
--- a/test/common/k8s/azureidentitybinding/azureidentitybinding.go
+++ b/test/common/k8s/azureidentitybinding/azureidentitybinding.go
@@ -9,6 +9,7 @@ import (
 
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity/v1"
 	"github.com/Azure/aad-pod-identity/test/common/util"
+
 	"github.com/pkg/errors"
 )
 
diff --git a/test/common/k8s/azurepodidentityexception/azurepodidentityexception.go b/test/common/k8s/azurepodidentityexception/azurepodidentityexception.go
index 2d514c7e..2d7f107d 100644
--- a/test/common/k8s/azurepodidentityexception/azurepodidentityexception.go
+++ b/test/common/k8s/azurepodidentityexception/azurepodidentityexception.go
@@ -9,6 +9,7 @@ import (
 
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity/v1"
 	"github.com/Azure/aad-pod-identity/test/common/util"
+
 	"github.com/pkg/errors"
 )
 
diff --git a/test/common/k8s/daemonset/daemonset.go b/test/common/k8s/daemonset/daemonset.go
index 4ec3eb60..5e3e3130 100644
--- a/test/common/k8s/daemonset/daemonset.go
+++ b/test/common/k8s/daemonset/daemonset.go
@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/Azure/aad-pod-identity/test/common/util"
+
 	"github.com/pkg/errors"
 )
 
diff --git a/test/common/k8s/deploy/deploy.go b/test/common/k8s/deploy/deploy.go
index 97466bbf..005e8702 100644
--- a/test/common/k8s/deploy/deploy.go
+++ b/test/common/k8s/deploy/deploy.go
@@ -9,6 +9,7 @@ import (
 	"time"
 
 	"github.com/Azure/aad-pod-identity/test/common/util"
+
 	"github.com/pkg/errors"
 )
 
diff --git a/test/common/k8s/infra/infra.go b/test/common/k8s/infra/infra.go
index 47ab9bfb..d679c0db 100644
--- a/test/common/k8s/infra/infra.go
+++ b/test/common/k8s/infra/infra.go
@@ -7,6 +7,7 @@ import (
 	"text/template"
 
 	"github.com/Azure/aad-pod-identity/test/common/util"
+
 	"github.com/pkg/errors"
 )
 
diff --git a/test/common/k8s/node/node.go b/test/common/k8s/node/node.go
index 3d5ab4c6..b375296f 100644
--- a/test/common/k8s/node/node.go
+++ b/test/common/k8s/node/node.go
@@ -5,6 +5,7 @@ import (
 	"os/exec"
 
 	"github.com/Azure/aad-pod-identity/test/common/util"
+
 	"github.com/pkg/errors"
 )
 
diff --git a/test/common/k8s/pod/pod.go b/test/common/k8s/pod/pod.go
index c7421069..b760d74c 100644
--- a/test/common/k8s/pod/pod.go
+++ b/test/common/k8s/pod/pod.go
@@ -9,6 +9,7 @@ import (
 	"time"
 
 	"github.com/Azure/aad-pod-identity/test/common/util"
+
 	"github.com/pkg/errors"
 )
 
@@ -95,7 +96,7 @@ func RunCommandInPod(execCmd ...string) (string, error) {
 	util.PrintCommand(cmd)
 	out, err := cmd.CombinedOutput()
 	if err != nil {
-		return string(out), errors.Wrap(err, fmt.Sprintf("Failed to execute command in pod"))
+		return string(out), errors.Wrap(err, "Failed to execute command in pod")
 	}
 	return string(out), err
 }
@@ -172,7 +173,9 @@ func DeletePod(podName string) error {
 	_, err := cmd.CombinedOutput()
 
 	if err != nil {
-		errors.Wrap(err, "Pod delete command failed with error")
+		err = errors.Wrap(err, "Pod delete command failed with error")
+		return err
 	}
+
 	return nil
 }
diff --git a/test/e2e/aadpodidentity_test.go b/test/e2e/aadpodidentity_test.go
index 8820186d..6dac315e 100644
--- a/test/e2e/aadpodidentity_test.go
+++ b/test/e2e/aadpodidentity_test.go
@@ -12,6 +12,10 @@ import (
 	"sync"
 	"time"
 
+	"github.com/pkg/errors"
+	corev1 "k8s.io/api/core/v1"
+	rl "k8s.io/client-go/tools/leaderelection/resourcelock"
+
 	aadpodid "github.com/Azure/aad-pod-identity/pkg/apis/aadpodidentity/v1"
 	"github.com/Azure/aad-pod-identity/pkg/cloudprovider"
 	"github.com/Azure/aad-pod-identity/test/common/azure"
@@ -26,9 +30,6 @@ import (
 	"github.com/Azure/aad-pod-identity/test/common/k8s/pod"
 	"github.com/Azure/aad-pod-identity/test/common/util"
 	"github.com/Azure/aad-pod-identity/test/e2e/config"
-	"github.com/pkg/errors"
-	corev1 "k8s.io/api/core/v1"
-	rl "k8s.io/client-go/tools/leaderelection/resourcelock"
 
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
@@ -216,7 +217,8 @@ var _ = Describe("Kubernetes cluster using aad-pod-identity", func() {
 		Expect(nodeName).NotTo(Equal(""))
 
 		// Drain the node that contains identity validator
-		node.Drain(nodeName)
+		err = node.Drain(nodeName)
+		Expect(err).NotTo(HaveOccurred())
 
 		ok, err := azureassignedidentity.WaitOnLengthMatched(1, true)
 		Expect(ok).To(Equal(true))
@@ -228,7 +230,8 @@ var _ = Describe("Kubernetes cluster using aad-pod-identity", func() {
 		// Make sure the AzureAssignedIdentity is updated along with the new pod
 		validateAzureAssignedIdentity(azureAssignedIdentity, keyvaultIdentity, keyvaultIdentity)
 
-		node.Uncordon(nodeName)
+		err = node.Uncordon(nodeName)
+		Expect(err).NotTo(HaveOccurred())
 	})
 
 	It("should remove the correct identities when adding AzureIdentity and AzureIdentityBinding in order and removing them in random order", func() {
@@ -1053,10 +1056,17 @@ func collectDebuggingInfo() {
 	fd, err := os.Create(infoFile)
 	Expect(err).NotTo(HaveOccurred())
 
-	fd.WriteString("Test name: " + CurrentGinkgoTestDescription().TestText + "\n")
-	fd.WriteString("Collecting diagnostics at: " + tNow.Format(time.UnixDate))
-	fd.Sync()
-	fd.Close()
+	_, err = fd.WriteString("Test name: " + CurrentGinkgoTestDescription().TestText + "\n")
+	Expect(err).NotTo(HaveOccurred())
+
+	_, err = fd.WriteString("Collecting diagnostics at: " + tNow.Format(time.UnixDate))
+	Expect(err).NotTo(HaveOccurred())
+
+	err = fd.Sync()
+	Expect(err).NotTo(HaveOccurred())
+
+	err = fd.Close()
+	Expect(err).NotTo(HaveOccurred())
 
 	collectPods(logDirName)
 	collectEvents(logDirName)
@@ -1305,6 +1315,8 @@ func enableUserAssignedIdentityOnCluster(nodeList *node.List, identityName strin
 		Expect(err).NotTo(HaveOccurred())
 
 		resourceID, err := azure.GetIdentityResourceID(cfg.IdentityResourceGroup, identityName)
+		Expect(err).NotTo(HaveOccurred())
+
 		err = m.EnableUserAssignedIdentity(resourceID)
 		Expect(err).NotTo(HaveOccurred())
 	}