Repository: linkerd/linkerd2
Pull request #6125 (2021-05-14 15:14:19)

Remove `--addon-overwrite` flag in `linkerd upgrade`
No longer used, left-over from the previously discarded add-ons approach.


Patch:
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 000000000..1691af43a
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,39 @@
+# See https://github.com/github/codeql-action/tree/v1 for more information.
+
+name: CodeQL
+
+on:
+  push:
+    branches: [ main, stable-* ]
+  pull_request:
+    # The branches below must be a subset of the branches above
+    branches: [ main, stable-* ]
+  schedule:
+    - cron: '40 5 * * 3'
+
+jobs:
+  analyze:
+    name: Analyze
+    runs-on: ubuntu-latest
+    permissions:
+      actions: read
+      contents: read
+      security-events: write
+
+    strategy:
+      fail-fast: false
+      matrix:
+        language: [ 'go', 'javascript' ]
+
+    steps:
+    - name: Checkout
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
+
+    - name: Initialize
+      # Unpinned action version so that we automatically get analyzer updates.
+      uses: github/codeql-action/init@v1
+      with:
+        languages: ${{ matrix.language }}
+
+    - name: Analyze
+      uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 951116263..33ed139d0 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -16,8 +16,7 @@ jobs:
     timeout-minutes: 30
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Set environment variables from scripts
       run: |
         . bin/_tag.sh
@@ -77,8 +76,7 @@ jobs:
     needs: [docker_build]
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Try to load cached Go modules
       # actions/cache@v1.1.2
       uses: actions/cache@70655ec8323daeeaa7ef06d7c56e1b9191396cbe
@@ -110,12 +108,11 @@ jobs:
         - cni-calico-deep
     needs: [docker_build]
     name: Integration tests (${{ matrix.integration_test }})
-    timeout-minutes: 30
+    timeout-minutes: 60
     runs-on: ubuntu-20.04
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Try to load cached Go modules
       # actions/cache@v1.1.2
       uses: actions/cache@70655ec8323daeeaa7ef06d7c56e1b9191396cbe
@@ -144,8 +141,7 @@ jobs:
     steps:
     - name: Checkout code
       #if: startsWith(github.ref, 'refs/tags/stable')
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Try to load cached Go modules
       #if: startsWith(github.ref, 'refs/tags/stable')
       # actions/cache@v1.1.2
@@ -197,8 +193,7 @@ jobs:
     steps:
     - name: Checkout code
       if: startsWith(github.ref, 'refs/tags/stable')
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Chocolatey - update nuspec
       if: startsWith(github.ref, 'refs/tags/stable')
       run: |
@@ -225,8 +220,7 @@ jobs:
     needs: [choco_pack]
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Set environment variables from scripts
       run: |
         . bin/_tag.sh
@@ -286,8 +280,7 @@ jobs:
     needs: [website_publish]
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Set environment variables from scripts
       run: |
         . bin/_tag.sh
@@ -316,8 +309,7 @@ jobs:
     needs: [gh_release]
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Configure gsutils
       # linkerd/linkerd2-action-gcloud@v1.0.1
       uses: linkerd/linkerd2-action-gcloud@308c4df7314264c90d240e77e27d0d875d3c8ec1
diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml
index f84593bbf..4ed43e34a 100644
--- a/.github/workflows/static_checks.yml
+++ b/.github/workflows/static_checks.yml
@@ -16,8 +16,7 @@ jobs:
       image: golang:1.16.2
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Go lint
       run: bin/lint --verbose
   go_format:
@@ -28,8 +27,7 @@ jobs:
       image: golang:1.16.2
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Format
       run: bin/fmt
   proto_diff:
@@ -42,8 +40,7 @@ jobs:
       - name: Prerequisites
         run: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y --no-install-recommends install unzip
       - name: Checkout code
-        # actions/checkout@v2
-        uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+        uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
       - name: Diff proto files
         run: bin/protoc-diff
   shellcheck:
@@ -52,8 +49,7 @@ jobs:
     runs-on: ubuntu-20.04
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: shellcheck
       # For more information on shellcheck failures:
       # https://github.com/koalaman/shellcheck/wiki/Checks
@@ -65,8 +61,7 @@ jobs:
     runs-on: ubuntu-20.04
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Chocolatey - lint
       # devblackops/github-action-psscriptanalyzer@v2.3.0
       uses: devblackops/github-action-psscriptanalyzer@819c15c7d02dec0611fe3ded6f8e259b0b925754
@@ -82,8 +77,7 @@ jobs:
     runs-on: ubuntu-20.04
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Markdown lint
       run: bin/markdownlint-all
   chart_docs_diff:
@@ -91,7 +85,6 @@ jobs:
     runs-on: ubuntu-20.04
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Check docs for diff
       run: bin/helm-docs-diff
diff --git a/.proxy-version b/.proxy-version
index e2d4912bb..fb741f89d 100644
--- a/.proxy-version
+++ b/.proxy-version
@@ -1,1 +1,1 @@
-v2.141.1
+v2.144.0
\ No newline at end of file
diff --git a/BUILD.md b/BUILD.md
index 56a7f716c..0259d872f 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -422,6 +422,27 @@ proxy binary:
 bin/docker-build-proxy
 ```
 
+#### Locally built proxy
+
+If you want to deploy a locally built proxy, you can build it in the
+[`linkerd2-proxy`](https://github.com/linkerd/linkerd2-proxy) repo by running:
+
+```bash
+DOCKER_TAG=cr.l5d.io/linkerd/proxy:dev make docker
+```
+
+Then, in this repo, run:
+
+```bash
+./bin/k3d image import cr.l5d.io/linkerd/proxy:dev
+```
+
+Now, to make a pod use your image, add the following annotations to it:
+
+```yaml
+config.linkerd.io/proxy-version: dev
+```
+
 ### Multi-architecture builds
 
 Besides the default Linux/amd64 architecture, you can build controller images
diff --git a/CHANGES.md b/CHANGES.md
index 3a1e53f34..d5ea14f6e 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,58 @@
 # Changes
 
+## edge-21.5.2
+
+This edge release updates the proxy-init container to check whether the iptables
+rules have already been added, which prevents errors if the proxy-init container
+is restarted. Also, the `viz stat` command now has tab completion for Kubernetes
+resources, saving you precious keystrokes! Finally, the proxy has been updated
+with several fixes and improvements.
+
+* Added instructions to `build.md` for using a locally built proxy
+  (thanks @jroper!)
+* Added support for Kubernetes resource aware tab completion to the `viz stat`
+  command
+* Updated `proxy-init` to skip configuring firewall if rules exists
+* Fixed `viz uninstall` to delete all RBAC objects (thanks @aryan9600!)
+* Improved diagnostics for rejected profile discovery
+* Added the `l5d-client-id` header on mutually-authenticated inbound requests so
+  that applications can discover the client's identity.
+* Reduced proxy resource usage when there are no profiles
+* Changed the admin server to assume all meshed connections are HTTP/2 and fail
+  connections when that is not the case
+* Updated the proxy to require the `l5d-dst-override` header on outbound
+  requests when the proxy is in ingress-mode
+* Removed support for TCP-forwarding in ingress-mode
+
+## edge-21.5.1
+
+This edge release adds support for versioned hint URLs in `linkerd check` and
+support for traffic splitting through ServiceProfiles, among other fixes and
+improvements. Additionally, more options have been added to the
+linkerd-multicluster and linkerd-jaeger helm charts.
+
+* Added support for traffic splitting through a ServiceProfile's `dstOverrides`
+  field.
+* Added `nodePorts` option to the multicluster helm chart (thanks @psmit!).
+* Added `nodeSelector` and toleration options to the linkerd-jaeger helm chart
+  (thanks @aatarasoff!).
+* Added versioned hint URLs to the CLI `check` command when encountering an
+  error; each major CLI version will now point to that version's relevant
+  section in the Linkerd troubleshooting page.
+* Fixed an issue in the CLI `check` command where error messages for
+  healthchecks that were being retried would be outputted repeatedly instead of
+  just once.
+* Fixed an issue in the proxy injector where a namespace annotated with opaque
+  ports would overwrite all service annotations.
+* Fixed a regression in the proxy that caused all logs to be output with ANSI
+  control characters, by default logs are output in plaintext now.
+* Simplified proxy internals in order to distinguish endpoint-forwarding logic
+  from the handling of load balanced services.
+* Simplified the ingress-mode outbound proxy by requiring the
+  `l5d-dst-override` header and by failing non-HTTP communication. Proxies
+  running in ingress-mode will not unexpectedly revert to insecure
+  communication as a result.
+
 ## edge-21.4.5
 
 This edge release adds a new output format `short` for `linkerd check` to show a
diff --git a/charts/linkerd2/README.md b/charts/linkerd2/README.md
index 412c3048c..b799c893e 100644
--- a/charts/linkerd2/README.md
+++ b/charts/linkerd2/README.md
@@ -192,7 +192,7 @@ Kubernetes: `>=1.16.0-0`
 | proxyInit.ignoreOutboundPorts | string | `""` | Default set of outbound ports to skip via itpables |
 | proxyInit.image.name | string | `"cr.l5d.io/linkerd/proxy-init"` | Docker image for the proxy-init container |
 | proxyInit.image.pullPolicy | string | imagePullPolicy | Pull policy for the proxy-init container Docker image |
-| proxyInit.image.version | string | `"v1.3.11"` | Tag for the proxy-init container Docker image |
+| proxyInit.image.version | string | `"v1.3.12"` | Tag for the proxy-init container Docker image |
 | proxyInit.resources.cpu.limit | string | `"100m"` | Maximum amount of CPU units that the proxy-init container can use |
 | proxyInit.resources.cpu.request | string | `"10m"` | Amount of CPU units that the proxy-init container requests |
 | proxyInit.resources.memory.limit | string | `"50Mi"` | Maximum amount of memory that the proxy-init container can use |
diff --git a/charts/linkerd2/values.yaml b/charts/linkerd2/values.yaml
index bbb60d928..08ba652be 100644
--- a/charts/linkerd2/values.yaml
+++ b/charts/linkerd2/values.yaml
@@ -122,7 +122,7 @@ proxyInit:
     # @default -- imagePullPolicy
     pullPolicy: ""
     # -- Tag for the proxy-init container Docker image
-    version: v1.3.11
+    version: v1.3.12
   resources:
     cpu:
       # -- Maximum amount of CPU units that the proxy-init container can use
diff --git a/cli/cmd/completion.go b/cli/cmd/completion.go
index 28fb3f9ca..58d6511a5 100644
--- a/cli/cmd/completion.go
+++ b/cli/cmd/completion.go
@@ -12,11 +12,13 @@ import (
 // enabling linkerd auto completion
 func newCmdCompletion() *cobra.Command {
 	example := `  # bash <= 3.2:
+  # To load shell completion into your current shell session
   source /dev/stdin <<< "$(linkerd completion bash)"
 
   # bash >= 4.0:
   source <(linkerd completion bash)
 
+  # To load shell completion for every shell session
   # bash <= 3.2 on osx:
   brew install bash-completion # ensure you have bash-completion 1.3+
   linkerd completion bash > $(brew --prefix)/etc/bash_completion.d/linkerd
@@ -25,14 +27,22 @@ func newCmdCompletion() *cobra.Command {
   brew install bash-completion@2
   linkerd completion bash > $(brew --prefix)/etc/bash_completion.d/linkerd
 
+  # bash >= 4.0 on linux:
+  linkerd completion bash > /etc/bash_completion.d/linkerd
+
+  # You will need to start a new shell for this setup to take effect.
+
   # zsh:
   # If shell completion is not already enabled in your environment you will need
   # to enable it.  You can execute the following once:
 
-  echo "autoload -U compinit; compinit" >> ~/.zshrc
+  echo "autoload -U compinit && compinit" >> ~/.zshrc
+
+  # create a linkerd 'plugins' folder and add it to your $fpath
+  mkdir $ZSH/plugins/linkerd && echo "fpath=($ZSH/plugins/linkerd $fpath)" >> ~/.zshrc
 
   # To load completions for each session, execute once:
-  linkerd completion zsh > "${fpath[1]}/_linkerd"
+  linkerd completion zsh > "${fpath[1]}/_linkerd" && exec $SHELL
 
   # You will need to start a new shell for this setup to take effect.
 
diff --git a/cli/cmd/upgrade.go b/cli/cmd/upgrade.go
index 4d6287bb3..79cf64f99 100644
--- a/cli/cmd/upgrade.go
+++ b/cli/cmd/upgrade.go
@@ -33,9 +33,8 @@ const (
 )
 
 var (
-	addOnOverwrite bool
-	manifests      string
-	force          bool
+	manifests string
+	force     bool
 )
 
 /* The upgrade commands all follow the same flow:
@@ -231,10 +230,6 @@ func makeUpgradeFlags() *pflag.FlagSet {
 		&force, "force", false,
 		"Force upgrade operation even when issuer certificate does not work with the trust anchors of all proxies",
 	)
-	upgradeFlags.BoolVar(
-		&addOnOverwrite, "addon-overwrite", false,
-		"Overwrite add-on configuration instead of loading the existing config (or reset to defaults if no new config is specified)",
-	)
 	return upgradeFlags
 }
 
diff --git a/controller/proxy-injector/fake/data/pod-with-debug.patch.json b/controller/proxy-injector/fake/data/pod-with-debug.patch.json
index 384b9b782..95dd0ed35 100644
--- a/controller/proxy-injector/fake/data/pod-with-debug.patch.json
+++ b/controller/proxy-injector/fake/data/pod-with-debug.patch.json
@@ -56,7 +56,7 @@
         "--inbound-ports-to-ignore",
         "4190,4191"
       ],
-      "image": "cr.l5d.io/linkerd/proxy-init:v1.3.11",
+      "image": "cr.l5d.io/linkerd/proxy-init:v1.3.12",
       "imagePullPolicy": "IfNotPresent",
       "name": "linkerd-init",
       "resources": {
diff --git a/controller/proxy-injector/fake/data/pod-with-ns-annotations.patch.json b/controller/proxy-injector/fake/data/pod-with-ns-annotations.patch.json
index 197ddc9a2..540d3e585 100644
--- a/controller/proxy-injector/fake/data/pod-with-ns-annotations.patch.json
+++ b/controller/proxy-injector/fake/data/pod-with-ns-annotations.patch.json
@@ -68,7 +68,7 @@
         "--outbound-ports-to-ignore",
         "34567"
       ],
-      "image": "cr.l5d.io/linkerd/proxy-init:v1.3.11",
+      "image": "cr.l5d.io/linkerd/proxy-init:v1.3.12",
       "imagePullPolicy": "IfNotPresent",
       "name": "linkerd-init",
       "resources": {
diff --git a/controller/proxy-injector/fake/data/pod.patch.json b/controller/proxy-injector/fake/data/pod.patch.json
index d48c17f4c..7fb38c840 100644
--- a/controller/proxy-injector/fake/data/pod.patch.json
+++ b/controller/proxy-injector/fake/data/pod.patch.json
@@ -56,7 +56,7 @@
         "--inbound-ports-to-ignore",
         "4190,4191"
       ],
-      "image": "cr.l5d.io/linkerd/proxy-init:v1.3.11",
+      "image": "cr.l5d.io/linkerd/proxy-init:v1.3.12",
       "imagePullPolicy": "IfNotPresent",
       "name": "linkerd-init",
       "resources": {
diff --git a/go.mod b/go.mod
index 310a63b1c..be8e0b82a 100644
--- a/go.mod
+++ b/go.mod
@@ -16,13 +16,13 @@ require (
 	github.com/ghodss/yaml v1.0.0
 	github.com/go-openapi/spec v0.19.3
 	github.com/golang/protobuf v1.4.3
-	github.com/gorilla/websocket v1.4.0
+	github.com/gorilla/websocket v1.4.2
 	github.com/grantae/certinfo v0.0.0-20170412194111-59d56a35515b
 	github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
 	github.com/imdario/mergo v0.3.8
 	github.com/julienschmidt/httprouter v1.2.0
 	github.com/linkerd/linkerd2-proxy-api v0.1.16
-	github.com/linkerd/linkerd2-proxy-init v1.3.11
+	github.com/linkerd/linkerd2-proxy-init v1.3.12
 	github.com/mattn/go-isatty v0.0.12
 	github.com/mattn/go-runewidth v0.0.4
 	github.com/nsf/termbox-go v0.0.0-20180613055208-5c94acc5e6eb
@@ -36,7 +36,7 @@ require (
 	github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
 	github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
 	github.com/sirupsen/logrus v1.7.0
-	github.com/spf13/cobra v1.0.0
+	github.com/spf13/cobra v1.1.3
 	github.com/spf13/pflag v1.0.5
 	go.opencensus.io v0.22.2
 	golang.org/x/net v0.0.0-20200707034311-ab3426394381
diff --git a/go.sum b/go.sum
index eef3ec7d9..98a1e014d 100644
--- a/go.sum
+++ b/go.sum
@@ -10,6 +10,7 @@ cloud.google.com/go v0.51.0 h1:PvKAVQWCtlGUSlZkGW3QLelKaWq7KYv/MW1EboG8bfM=
 cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
 cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
 contrib.go.opencensus.io/exporter/ocagent v0.6.0 h1:Z1n6UAyr0QwM284yUuh5Zd8JlvxUGAhFZcgMJkMPrGM=
@@ -103,6 +104,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
+github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
 github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
@@ -146,6 +148,7 @@ github.com/containernetworking/cni v0.6.1-0.20180218032124-142cde0c766c h1:X6Gxg
 github.com/containernetworking/cni v0.6.1-0.20180218032124-142cde0c766c/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
 github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
 github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
 github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
@@ -228,6 +231,7 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
 github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@@ -367,8 +371,9 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
 github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
 github.com/grantae/certinfo v0.0.0-20170412194111-59d56a35515b h1:NGgE5ELokSf2tZ/bydyDUKrvd/jP8lrAoPNeBuMOTOk=
 github.com/grantae/certinfo v0.0.0-20170412194111-59d56a35515b/go.mod h1:zT/uzhdQGTqlwTq7Lpbj3JoJQWfPfIJ1tE0OidAmih8=
@@ -380,7 +385,9 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy
 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
 github.com/grpc-ecosystem/grpc-gateway v1.14.8 h1:hXClj+iFpmLM8i3lkO6i4Psli4P2qObQuQReiII26U8=
 github.com/grpc-ecosystem/grpc-gateway v1.14.8/go.mod h1:NZE8t6vs6TnwLL/ITkaK8W3ecMLGAbh2jXTclvpiwYo=
+github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
 github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
+github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
 github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
 github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -458,11 +465,12 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b
 github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
 github.com/linkerd/linkerd2-proxy-api v0.1.16 h1:Qjqbw5Bw3QYUJpUSpYHr4nkJqBRnTlsFUwncCtCdOEs=
 github.com/linkerd/linkerd2-proxy-api v0.1.16/go.mod h1:yFz+DCCEomC3vpsChFzfCuOuSJtzx7jMNNHBIlbFil0=
-github.com/linkerd/linkerd2-proxy-init v1.3.11 h1:RVwHgkOVVVQWoZqiFURsXZFjXvtOG8/+v9kqb+XEmoE=
-github.com/linkerd/linkerd2-proxy-init v1.3.11/go.mod h1:iYv3JOgCBpOr6T5qjfE1IeO9/33oaq349kOFMNyvoeM=
+github.com/linkerd/linkerd2-proxy-init v1.3.12 h1:/8fuDFLaa+dq1hZYuL06Fo6kHuq2T+VC10m3goVf3t0=
+github.com/linkerd/linkerd2-proxy-init v1.3.12/go.mod h1:iYv3JOgCBpOr6T5qjfE1IeO9/33oaq349kOFMNyvoeM=
 github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
 github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
@@ -667,8 +675,9 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
 github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
-github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
 github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
+github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
+github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
@@ -678,6 +687,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
 github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
+github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
 github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
 github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
@@ -690,6 +700,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -762,6 +773,7 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
 golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
 golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
@@ -907,6 +919,7 @@ golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
@@ -923,6 +936,7 @@ google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEt
 google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
 google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
 google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
 google.golang.org/api v0.15.0 h1:yzlyyDW/J0w8yNFJIhiAJy4kq74S+1DOLdawELNxFMA=
 google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
@@ -943,6 +957,7 @@ google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98
 google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
 google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
 google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
@@ -991,6 +1006,7 @@ gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKW
 gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
 gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
@@ -1001,8 +1017,9 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.3/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.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
diff --git a/pkg/k8s/completion.go b/pkg/k8s/completion.go
new file mode 100644
index 000000000..35ff5e4e3
--- /dev/null
+++ b/pkg/k8s/completion.go
@@ -0,0 +1,180 @@
+package k8s
+
+import (
+	"context"
+	"fmt"
+	"strings"
+	"time"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+// CommandCompletion generates CLI suggestions from resources in a given cluster
+// It uses a list of arguments and a substring from the CLI to filter suggestions.
+type CommandCompletion struct {
+	k8sAPI    *KubernetesAPI
+	namespace string
+}
+
+// NewCommandCompletion creates a command completion module
+func NewCommandCompletion(
+	k8sAPI *KubernetesAPI,
+	namespace string,
+) *CommandCompletion {
+	return &CommandCompletion{
+		k8sAPI:    k8sAPI,
+		namespace: namespace,
+	}
+}
+
+// Complete accepts a list of arguments and a substring to generate CLI suggestions.
+// `args` represent a list of arguments a user has already enterd in the CLI. These
+// arguments are used for determining what resource type we'd like to receive
+// suggestions for as well as a list of resources names that have already provided.
+// `toComplete` represents the string prefix of a resource name that we'd like to
+// use to search for suggestions
+//
+// If `args` is empty, send back a list of all resource types support by the CLI.
+// If `args` has at least one or more items, assume that the first item in `args`
+// is the resource type we are trying to get suggestions for e.g. Deployment, StatefulSets.
+//
+// Complete is generic enough so that it can find suggestions for any type of resource
+// in a Kubernetes cluster. It does this by first querying what GroupVersion a resource
+// belongs to and then does a dynamic `List` query to get resources under that GroupVersion
+func (c *CommandCompletion) Complete(args []string, toComplete string) ([]string, error) {
+	ctx, cancelFn := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancelFn()
+
+	suggestions := []string{}
+	if len(args) == 0 && toComplete == "" {
+		return StatAllResourceTypes, nil
+	}
+
+	if len(args) == 0 && toComplete != "" {
+		for _, t := range StatAllResourceTypes {
+			if strings.HasPrefix(t, toComplete) {
+				suggestions = append(suggestions, t)
+			}
+		}
+		return suggestions, nil
+	}
+
+	resType, err := CanonicalResourceNameFromFriendlyName(args[0])
+	if err != nil {
+		return nil, fmt.Errorf("%s is not a valid resource name", args)
+	}
+
+	// if we are looking for namespace suggestions clear namespace selector
+	if resType == "namespace" {
+		c.namespace = ""
+	}
+
+	// Similar to kubectl's completion for bash and zsh only, we don't provide
+	// resource completion when the resource provided is in format
+	// <kind>/<resourceName>.
+	if strings.Contains(args[0], "/") {
+		return []string{}, nil
+	}
+
+	gvr, err := c.getGroupVersionKindForResource(resType)
+	if err != nil {
+		return nil, err
+	}
+
+	uList, err := c.k8sAPI.DynamicClient.
+		Resource(*gvr).
+		Namespace(c.namespace).
+		List(ctx, metav1.ListOptions{})
+	if err != nil {
+		return nil, err
+	}
+
+	otherResources := args[1:]
+	for _, u := range uList.Items {
+		name := u.GetName()
+
+		// Filter out the list of resource items returned from k8s API to
+		// only include items that have the prefix `toComplete` and items
+		// that aren't in the list of resources already provided in the
+		// list of arguments.
+		//
+		// This is useful so that we avoid duplicate suggestions if they
+		// are already in the list of args
+		if strings.HasPrefix(name, toComplete) &&
+			!containsResource(name, otherResources) {
+			suggestions = append(suggestions, name)
+		}
+	}
+
+	return suggestions, nil
+}
+
+func (c *CommandCompletion) getGroupVersionKindForResource(resourceName string) (*schema.GroupVersionResource, error) {
+	_, apiResourceList, err := c.k8sAPI.Discovery().ServerGroupsAndResources()
+	if err != nil {
+		return nil, err
+	}
+
+	// find the plural name to ensure the resource we are searching for is not a subresource
+	// i.e. deployment/scale
+	pluralResourceName, err := PluralResourceNameFromFriendlyName(resourceName)
+	if err != nil {
+		return nil, fmt.Errorf("%s not a valid resource name", resourceName)
+	}
+
+	gvr, err := findGroupVersionResource(resourceName, pluralResourceName, apiResourceList)
+	if err != nil {
+		return nil, fmt.Errorf("could not find GroupVersionResource for %s", resourceName)
+	}
+
+	return gvr, nil
+}
+
+func findGroupVersionResource(singularName string, pluralName string, apiResourceList []*metav1.APIResourceList) (*schema.GroupVersionResource, error) {
+	err := fmt.Errorf("could not find the requested resource")
+	for _, res := range apiResourceList {
+		for _, r := range res.APIResources {
+
+			// Make sure we get a resource type where its Kind matches the
+			// singularName passed into this function and its Name (which is always
+			// the pluralName of an api resource) matches the pluralName passed
+			// into this function. Skip further processing of this APIResource
+			// if this is not the case.
+			if strings.ToLower(r.Kind) != singularName || r.Name != pluralName {
+				continue
+			}
+
+			gv := strings.Split(res.GroupVersion, "/")
+
+			if len(gv) == 1 && gv[0] == "v1" {
+				return &schema.GroupVersionResource{
+					Version:  gv[0],
+					Resource: r.Name,
+				}, nil
+			}
+
+			if len(gv) != 2 {
+				return nil, err
+			}
+
+			return &schema.GroupVersionResource{
+				Group:    gv[0],
+				Version:  gv[1],
+				Resource: r.Name,
+			}, nil
+		}
+	}
+
+	return nil, err
+}
+
+func containsResource(resource string, otherResources []string) bool {
+	for _, r := range otherResources {
+		if r == resource {
+			return true
+		}
+	}
+
+	return false
+}
diff --git a/pkg/k8s/k8s.go b/pkg/k8s/k8s.go
index e480d3375..aa989b3c5 100644
--- a/pkg/k8s/k8s.go
+++ b/pkg/k8s/k8s.go
@@ -62,7 +62,7 @@ var AllResources = []string{
 
 // StatAllResourceTypes represents the resources to query in StatSummary when Resource.Type is "all"
 var StatAllResourceTypes = []string{
-	// TODO: add Namespace here to decrease queries from the web process
+	Namespace,
 	DaemonSet,
 	StatefulSet,
 	Job,
diff --git a/pkg/k8s/resource/resource.go b/pkg/k8s/resource/resource.go
index f03cf503a..798c66511 100644
--- a/pkg/k8s/resource/resource.go
+++ b/pkg/k8s/resource/resource.go
@@ -89,9 +89,15 @@ func FetchKubernetesResources(ctx context.Context, k *k8s.KubernetesAPI, options
 	}
 	resources = append(resources, clusterRoleBindings...)
 
-	roleBindings, err := fetchKubeSystemRoleBindings(ctx, k, options)
+	roles, err := fetchRoles(ctx, k, options)
 	if err != nil {
-		return nil, fmt.Errorf("could not fetch RoleBindings from kube-system namespace:%v", err)
+		return nil, fmt.Errorf("could not fetch Roles:%v", err)
+	}
+	resources = append(resources, roles...)
+
+	roleBindings, err := fetchRoleBindings(ctx, k, options)
+	if err != nil {
+		return nil, fmt.Errorf("could not fetch RoleBindings:%v", err)
 	}
 	resources = append(resources, roleBindings...)
 
@@ -162,11 +168,23 @@ func fetchClusterRoleBindings(ctx context.Context, k *k8s.KubernetesAPI, options
 	return resources, nil
 }
 
-// Although role bindings are namespaced resources in nature
-// some admin role bindings are created and persisted in the kube-system namespace and will not be deleted
-// when the namespace is deleted
-func fetchKubeSystemRoleBindings(ctx context.Context, k *k8s.KubernetesAPI, options metav1.ListOptions) ([]Kubernetes, error) {
-	list, err := k.RbacV1().RoleBindings("kube-system").List(ctx, options)
+func fetchRoles(ctx context.Context, k *k8s.KubernetesAPI, options metav1.ListOptions) ([]Kubernetes, error) {
+	list, err := k.RbacV1().Roles("").List(ctx, options)
+	if err != nil {
+		return nil, err
+	}
+
+	resources := make([]Kubernetes, len(list.Items))
+	for i, item := range list.Items {
+		r := New(rbac.SchemeGroupVersion.String(), "Role", item.Name)
+		r.Namespace = item.Namespace
+		resources[i] = r
+	}
+	return resources, nil
+}
+
+func fetchRoleBindings(ctx context.Context, k *k8s.KubernetesAPI, options metav1.ListOptions) ([]Kubernetes, error) {
+	list, err := k.RbacV1().RoleBindings("").List(ctx, options)
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/version/version.go b/pkg/version/version.go
index 66a4492ca..1db8c21ef 100644
--- a/pkg/version/version.go
+++ b/pkg/version/version.go
@@ -16,7 +16,7 @@ var Version = undefinedVersion
 // https://github.com/linkerd/linkerd2-proxy-init
 // This has to be kept in sync with the constraint version for
 // github.com/linkerd/linkerd2-proxy-init in /go.mod
-var ProxyInitVersion = "v1.3.11"
+var ProxyInitVersion = "v1.3.12"
 
 const (
 	// undefinedVersion should take the form `channel-version` to conform to
diff --git a/viz/cmd/stat.go b/viz/cmd/stat.go
index 05039a661..9c80a59a1 100644
--- a/viz/cmd/stat.go
+++ b/viz/cmd/stat.go
@@ -18,10 +18,10 @@ import (
 	"github.com/linkerd/linkerd2/pkg/k8s"
 	pb "github.com/linkerd/linkerd2/viz/metrics-api/gen/viz"
 	"github.com/linkerd/linkerd2/viz/metrics-api/util"
-	"github.com/linkerd/linkerd2/viz/pkg"
 	"github.com/linkerd/linkerd2/viz/pkg/api"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
+	v1 "k8s.io/api/core/v1"
 )
 
 type statOptions struct {
@@ -167,8 +167,31 @@ If no resource name is specified, displays stats about all resources of the spec
 
   # Get all inbound stats to the test namespace.
   linkerd viz stat ns/test`,
-		Args:      cobra.MinimumNArgs(1),
-		ValidArgs: pkg.ValidTargets,
+		Args: cobra.MinimumNArgs(1),
+		ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+
+			k8sAPI, err := k8s.NewAPI(kubeconfigPath, kubeContext, impersonate, impersonateGroup, 0)
+			if err != nil {
+				return nil, cobra.ShellCompDirectiveError
+			}
+
+			if options.namespace == "" {
+				options.namespace = pkgcmd.GetDefaultNamespace(kubeconfigPath, kubeContext)
+			}
+
+			if options.allNamespaces {
+				options.namespace = v1.NamespaceAll
+			}
+
+			cc := k8s.NewCommandCompletion(k8sAPI, options.namespace)
+
+			results, err := cc.Complete(args, toComplete)
+			if err != nil {
+				return nil, cobra.ShellCompDirectiveError
+			}
+
+			return results, cobra.ShellCompDirectiveDefault
+		},
 		RunE: func(cmd *cobra.Command, args []string) error {
 			if options.namespace == "" {
 				options.namespace = pkgcmd.GetDefaultNamespace(kubeconfigPath, kubeContext)
@@ -229,9 +252,33 @@ If no resource name is specified, displays stats about all resources of the spec
 	cmd.PersistentFlags().StringVarP(&options.outputFormat, "output", "o", options.outputFormat, "Output format; one of: \"table\" or \"json\" or \"wide\"")
 	cmd.PersistentFlags().StringVarP(&options.labelSelector, "selector", "l", options.labelSelector, "Selector (label query) to filter on, supports '=', '==', and '!='")
 	cmd.PersistentFlags().BoolVar(&options.unmeshed, "unmeshed", options.unmeshed, "If present, include unmeshed resources in the output")
+
+	configureFlagCompletions(cmd)
 	return cmd
 }
 
+func configureFlagCompletions(cmd *cobra.Command) {
+	flagNames := []string{"namespace", "to-namespace", "from-namespace"}
+	for _, flagName := range flagNames {
+		cmd.RegisterFlagCompletionFunc(flagName,
+			func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+				k8sAPI, err := k8s.NewAPI(kubeconfigPath, kubeContext, impersonate, impersonateGroup, 0)
+				if err != nil {
+					return nil, cobra.ShellCompDirectiveError
+				}
+
+				cc := k8s.NewCommandCompletion(k8sAPI, "")
+				results, err := cc.Complete([]string{"namespaces"}, toComplete)
+				if err != nil {
+					cobra.CompErrorln(err.Error())
+					return nil, cobra.ShellCompDirectiveError
+				}
+
+				return results, cobra.ShellCompDirectiveDefault
+			})
+	}
+}
+
 func respToRows(resp *pb.StatSummaryResponse) []*pb.StatTable_PodGroup_Row {
 	rows := make([]*pb.StatTable_PodGroup_Row, 0)
 	if resp != nil {


Test patch:
diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml
index 2096eb970..154155876 100644
--- a/.github/workflows/integration_tests.yml
+++ b/.github/workflows/integration_tests.yml
@@ -20,8 +20,7 @@ jobs:
     timeout-minutes: 30
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Set environment variables from scripts
       run: |
         . bin/_tag.sh
@@ -75,8 +74,7 @@ jobs:
     timeout-minutes: 30
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Try to load cached Go modules
       # actions/cache@v1.1.2
       uses: actions/cache@70655ec8323daeeaa7ef06d7c56e1b9191396cbe
@@ -112,11 +110,10 @@ jobs:
     needs: [docker_build]
     name: Integration tests (${{ matrix.integration_test }})
     runs-on: ubuntu-20.04
-    timeout-minutes: 30
+    timeout-minutes: 60
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Try to load cached Go modules
       # actions/cache@v1.1.2
       uses: actions/cache@70655ec8323daeeaa7ef06d7c56e1b9191396cbe
diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml
index 094e3d9d7..3c797664e 100644
--- a/.github/workflows/unit_tests.yml
+++ b/.github/workflows/unit_tests.yml
@@ -16,8 +16,7 @@ jobs:
       image: golang:1.16.2
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Go unit tests
       run: |
         go get gotest.tools/gotestsum@v0.4.2
@@ -31,8 +30,7 @@ jobs:
       image: node:14-stretch
     steps:
     - name: Checkout code
-      # actions/checkout@v2
-      uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598
+      uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
     - name: Yarn setup
       run: curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.21.1 --network-concurrency 1
     - name: JS unit tests
diff --git a/bin/_test-helpers.sh b/bin/_test-helpers.sh
index 0d7d84fa4..d9c0828b9 100644
--- a/bin/_test-helpers.sh
+++ b/bin/_test-helpers.sh
@@ -348,7 +348,7 @@ run_test(){
 
   printf 'Test script: [%s] Params: [%s]\n' "${filename##*/}" "$*"
   # Exit on failure here
-  GO111MODULE=on go test --failfast --mod=readonly "$filename" --linkerd="$linkerd_path" --helm-path="$helm_path" --k8s-context="$context" --integration-tests "$@" || exit 1
+  GO111MODULE=on go test -test.timeout=60m --failfast --mod=readonly "$filename" --linkerd="$linkerd_path" --helm-path="$helm_path" --k8s-context="$context" --integration-tests "$@" || exit 1
 }
 
 # Returns the latest version for the release channel
@@ -386,7 +386,7 @@ install_version() {
 
     (
         set -x
-        "$linkerd_path" check 2>&1
+        "$linkerd_path" check --wait 60m 2>&1
     )
     exit_on_err 'install_version() - linkerd check failed'
 
diff --git a/cli/cmd/testdata/inject-filepath/expected/injected_nginx.yaml b/cli/cmd/testdata/inject-filepath/expected/injected_nginx.yaml
index 2e709be36..38c19c8b0 100644
--- a/cli/cmd/testdata/inject-filepath/expected/injected_nginx.yaml
+++ b/cli/cmd/testdata/inject-filepath/expected/injected_nginx.yaml
@@ -139,7 +139,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject-filepath/expected/injected_nginx_redis.yaml b/cli/cmd/testdata/inject-filepath/expected/injected_nginx_redis.yaml
index c925700e4..8763eade2 100644
--- a/cli/cmd/testdata/inject-filepath/expected/injected_nginx_redis.yaml
+++ b/cli/cmd/testdata/inject-filepath/expected/injected_nginx_redis.yaml
@@ -139,7 +139,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -311,7 +311,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject-filepath/expected/injected_redis.yaml b/cli/cmd/testdata/inject-filepath/expected/injected_redis.yaml
index b8a344b42..796079179 100644
--- a/cli/cmd/testdata/inject-filepath/expected/injected_redis.yaml
+++ b/cli/cmd/testdata/inject-filepath/expected/injected_redis.yaml
@@ -139,7 +139,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_contour.golden.yml b/cli/cmd/testdata/inject_contour.golden.yml
index a6a13e8b5..158590e7a 100644
--- a/cli/cmd/testdata/inject_contour.golden.yml
+++ b/cli/cmd/testdata/inject_contour.golden.yml
@@ -179,7 +179,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_already_injected.golden.yml b/cli/cmd/testdata/inject_emojivoto_already_injected.golden.yml
index 617ce627f..605e18abb 100644
--- a/cli/cmd/testdata/inject_emojivoto_already_injected.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_already_injected.golden.yml
@@ -150,7 +150,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -333,7 +333,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -516,7 +516,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -699,7 +699,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_deployment.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment.golden.yml
index e4e50c1ec..6a899c192 100644
--- a/cli/cmd/testdata/inject_emojivoto_deployment.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_deployment.golden.yml
@@ -150,7 +150,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_capabilities.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_capabilities.golden.yml
index fdc6de618..6bc19e083 100644
--- a/cli/cmd/testdata/inject_emojivoto_deployment_capabilities.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_deployment_capabilities.golden.yml
@@ -163,7 +163,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_config_overrides.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_config_overrides.golden.yml
index 3cf3dc9b8..70d5f3cde 100644
--- a/cli/cmd/testdata/inject_emojivoto_deployment_config_overrides.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_deployment_config_overrides.golden.yml
@@ -169,7 +169,7 @@ spec:
         - 4190,9998,7777,8888
         - --outbound-ports-to-ignore
         - "9999"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_controller_name.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_controller_name.golden.yml
index aa2005756..c9bc00546 100644
--- a/cli/cmd/testdata/inject_emojivoto_deployment_controller_name.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_deployment_controller_name.golden.yml
@@ -150,7 +150,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -333,7 +333,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_debug.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_debug.golden.yml
index 2c514f94d..5fa4e4240 100644
--- a/cli/cmd/testdata/inject_emojivoto_deployment_debug.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_deployment_debug.golden.yml
@@ -155,7 +155,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_empty_resources.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_empty_resources.golden.yml
index 088d2b3bc..bb04a634e 100644
--- a/cli/cmd/testdata/inject_emojivoto_deployment_empty_resources.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_deployment_empty_resources.golden.yml
@@ -150,7 +150,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_hostNetwork_false.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_hostNetwork_false.golden.yml
index f0f25c0c0..3dadd6556 100644
--- a/cli/cmd/testdata/inject_emojivoto_deployment_hostNetwork_false.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_deployment_hostNetwork_false.golden.yml
@@ -151,7 +151,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_opaque_ports.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_opaque_ports.golden.yml
index 6344bda01..4872de2d6 100644
--- a/cli/cmd/testdata/inject_emojivoto_deployment_opaque_ports.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_deployment_opaque_ports.golden.yml
@@ -151,7 +151,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_overridden.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_overridden.golden.yml
index 1e4ef9a03..f8f2f4baa 100644
--- a/cli/cmd/testdata/inject_emojivoto_deployment_overridden.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_deployment_overridden.golden.yml
@@ -151,7 +151,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,1234
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_proxyignores.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_proxyignores.golden.yml
index 145e908ab..c8b0dc10c 100644
--- a/cli/cmd/testdata/inject_emojivoto_deployment_proxyignores.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_deployment_proxyignores.golden.yml
@@ -154,7 +154,7 @@ spec:
         - 4190,4191,22,8100-8102
         - --outbound-ports-to-ignore
         - "5432"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_deployment_udp.golden.yml b/cli/cmd/testdata/inject_emojivoto_deployment_udp.golden.yml
index 597ca579d..bbce1860b 100644
--- a/cli/cmd/testdata/inject_emojivoto_deployment_udp.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_deployment_udp.golden.yml
@@ -152,7 +152,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_list.golden.yml b/cli/cmd/testdata/inject_emojivoto_list.golden.yml
index ae4c33b6a..ca9a3da14 100644
--- a/cli/cmd/testdata/inject_emojivoto_list.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_list.golden.yml
@@ -152,7 +152,7 @@ items:
           - "2102"
           - --inbound-ports-to-ignore
           - 4190,4191
-          image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+          image: cr.l5d.io/linkerd/proxy-init:v1.3.12
           imagePullPolicy: IfNotPresent
           name: linkerd-init
           resources:
@@ -329,7 +329,7 @@ items:
           - "2102"
           - --inbound-ports-to-ignore
           - 4190,4191
-          image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+          image: cr.l5d.io/linkerd/proxy-init:v1.3.12
           imagePullPolicy: IfNotPresent
           name: linkerd-init
           resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_list_empty_resources.golden.yml b/cli/cmd/testdata/inject_emojivoto_list_empty_resources.golden.yml
index c35595ebe..6c1749c74 100644
--- a/cli/cmd/testdata/inject_emojivoto_list_empty_resources.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_list_empty_resources.golden.yml
@@ -152,7 +152,7 @@ items:
           - "2102"
           - --inbound-ports-to-ignore
           - 4190,4191
-          image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+          image: cr.l5d.io/linkerd/proxy-init:v1.3.12
           imagePullPolicy: IfNotPresent
           name: linkerd-init
           resources:
@@ -329,7 +329,7 @@ items:
           - "2102"
           - --inbound-ports-to-ignore
           - 4190,4191
-          image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+          image: cr.l5d.io/linkerd/proxy-init:v1.3.12
           imagePullPolicy: IfNotPresent
           name: linkerd-init
           resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_pod.golden.yml b/cli/cmd/testdata/inject_emojivoto_pod.golden.yml
index 187967b71..5dcc85b14 100644
--- a/cli/cmd/testdata/inject_emojivoto_pod.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_pod.golden.yml
@@ -135,7 +135,7 @@ spec:
     - "2102"
     - --inbound-ports-to-ignore
     - 4190,4191
-    image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+    image: cr.l5d.io/linkerd/proxy-init:v1.3.12
     imagePullPolicy: IfNotPresent
     name: linkerd-init
     resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_pod_ingress.golden.yml b/cli/cmd/testdata/inject_emojivoto_pod_ingress.golden.yml
index 06eb16526..f26116773 100644
--- a/cli/cmd/testdata/inject_emojivoto_pod_ingress.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_pod_ingress.golden.yml
@@ -138,7 +138,7 @@ spec:
     - "2102"
     - --inbound-ports-to-ignore
     - 4190,4191
-    image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+    image: cr.l5d.io/linkerd/proxy-init:v1.3.12
     imagePullPolicy: IfNotPresent
     name: linkerd-init
     resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_pod_proxyignores.golden.yml b/cli/cmd/testdata/inject_emojivoto_pod_proxyignores.golden.yml
index be6548f32..dcf16e224 100644
--- a/cli/cmd/testdata/inject_emojivoto_pod_proxyignores.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_pod_proxyignores.golden.yml
@@ -139,7 +139,7 @@ spec:
     - 4190,4191,22,8100-8102
     - --outbound-ports-to-ignore
     - "5432"
-    image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+    image: cr.l5d.io/linkerd/proxy-init:v1.3.12
     imagePullPolicy: IfNotPresent
     name: linkerd-init
     resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_pod_with_requests.golden.yml b/cli/cmd/testdata/inject_emojivoto_pod_with_requests.golden.yml
index aa15f284b..9898af462 100644
--- a/cli/cmd/testdata/inject_emojivoto_pod_with_requests.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_pod_with_requests.golden.yml
@@ -146,7 +146,7 @@ spec:
     - "2102"
     - --inbound-ports-to-ignore
     - 4190,4191
-    image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+    image: cr.l5d.io/linkerd/proxy-init:v1.3.12
     imagePullPolicy: IfNotPresent
     name: linkerd-init
     resources:
diff --git a/cli/cmd/testdata/inject_emojivoto_statefulset.golden.yml b/cli/cmd/testdata/inject_emojivoto_statefulset.golden.yml
index 4a924586c..0e21e694c 100644
--- a/cli/cmd/testdata/inject_emojivoto_statefulset.golden.yml
+++ b/cli/cmd/testdata/inject_emojivoto_statefulset.golden.yml
@@ -151,7 +151,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_gettest_deployment.good.golden.yml b/cli/cmd/testdata/inject_gettest_deployment.good.golden.yml
index 822e1d756..747d76d1a 100644
--- a/cli/cmd/testdata/inject_gettest_deployment.good.golden.yml
+++ b/cli/cmd/testdata/inject_gettest_deployment.good.golden.yml
@@ -152,7 +152,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -337,7 +337,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_tap_deployment.input.yml b/cli/cmd/testdata/inject_tap_deployment.input.yml
index 1ad577b54..ffb29bd86 100644
--- a/cli/cmd/testdata/inject_tap_deployment.input.yml
+++ b/cli/cmd/testdata/inject_tap_deployment.input.yml
@@ -203,7 +203,7 @@ spec:
         - 4190,4191
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/inject_tap_deployment_debug.golden.yml b/cli/cmd/testdata/inject_tap_deployment_debug.golden.yml
index 9ade0aef2..bf00d19bb 100644
--- a/cli/cmd/testdata/inject_tap_deployment_debug.golden.yml
+++ b/cli/cmd/testdata/inject_tap_deployment_debug.golden.yml
@@ -204,7 +204,7 @@ spec:
         - "2102"
         - --inbound-ports-to-ignore
         - 4190,4191
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/install_controlplane_tracing_output.golden b/cli/cmd/testdata/install_controlplane_tracing_output.golden
index 35a15dbef..d94b78bed 100644
--- a/cli/cmd/testdata/install_controlplane_tracing_output.golden
+++ b/cli/cmd/testdata/install_controlplane_tracing_output.golden
@@ -917,7 +917,7 @@ data:
       image:
         name: cr.l5d.io/linkerd/proxy-init
         pullPolicy: ""
-        version: v1.3.11
+        version: v1.3.12
       resources:
         cpu:
           limit: 100m
@@ -1188,7 +1188,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1496,7 +1496,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1766,7 +1766,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/install_custom_domain.golden b/cli/cmd/testdata/install_custom_domain.golden
index 7238a1930..d8b00964c 100644
--- a/cli/cmd/testdata/install_custom_domain.golden
+++ b/cli/cmd/testdata/install_custom_domain.golden
@@ -917,7 +917,7 @@ data:
       image:
         name: cr.l5d.io/linkerd/proxy-init
         pullPolicy: ""
-        version: v1.3.11
+        version: v1.3.12
       resources:
         cpu:
           limit: 100m
@@ -1187,7 +1187,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1494,7 +1494,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1764,7 +1764,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/install_custom_registry.golden b/cli/cmd/testdata/install_custom_registry.golden
index 261927267..140e98f9b 100644
--- a/cli/cmd/testdata/install_custom_registry.golden
+++ b/cli/cmd/testdata/install_custom_registry.golden
@@ -917,7 +917,7 @@ data:
       image:
         name: my.custom.registry/linkerd-io/proxy-init
         pullPolicy: ""
-        version: v1.3.11
+        version: v1.3.12
       resources:
         cpu:
           limit: 100m
@@ -1187,7 +1187,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: my.custom.registry/linkerd-io/proxy-init:v1.3.11
+        image: my.custom.registry/linkerd-io/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1494,7 +1494,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: my.custom.registry/linkerd-io/proxy-init:v1.3.11
+        image: my.custom.registry/linkerd-io/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1764,7 +1764,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: my.custom.registry/linkerd-io/proxy-init:v1.3.11
+        image: my.custom.registry/linkerd-io/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/install_default.golden b/cli/cmd/testdata/install_default.golden
index 114965312..337a8657d 100644
--- a/cli/cmd/testdata/install_default.golden
+++ b/cli/cmd/testdata/install_default.golden
@@ -917,7 +917,7 @@ data:
       image:
         name: cr.l5d.io/linkerd/proxy-init
         pullPolicy: ""
-        version: v1.3.11
+        version: v1.3.12
       resources:
         cpu:
           limit: 100m
@@ -1187,7 +1187,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1494,7 +1494,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1764,7 +1764,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/install_default_override_dst_get_nets.golden b/cli/cmd/testdata/install_default_override_dst_get_nets.golden
index 11d923efa..3ddf83b43 100644
--- a/cli/cmd/testdata/install_default_override_dst_get_nets.golden
+++ b/cli/cmd/testdata/install_default_override_dst_get_nets.golden
@@ -917,7 +917,7 @@ data:
       image:
         name: cr.l5d.io/linkerd/proxy-init
         pullPolicy: ""
-        version: v1.3.11
+        version: v1.3.12
       resources:
         cpu:
           limit: 100m
@@ -1187,7 +1187,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1494,7 +1494,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1764,7 +1764,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/install_ha_output.golden b/cli/cmd/testdata/install_ha_output.golden
index ddcf7f364..629d46b34 100644
--- a/cli/cmd/testdata/install_ha_output.golden
+++ b/cli/cmd/testdata/install_ha_output.golden
@@ -935,7 +935,7 @@ data:
       image:
         name: cr.l5d.io/linkerd/proxy-init
         pullPolicy: ""
-        version: v1.3.11
+        version: v1.3.12
       resources:
         cpu:
           limit: 100m
@@ -1261,7 +1261,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1618,7 +1618,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1928,7 +1928,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/install_ha_with_overrides_output.golden b/cli/cmd/testdata/install_ha_with_overrides_output.golden
index 2cdc83002..fcd4d70d7 100644
--- a/cli/cmd/testdata/install_ha_with_overrides_output.golden
+++ b/cli/cmd/testdata/install_ha_with_overrides_output.golden
@@ -935,7 +935,7 @@ data:
       image:
         name: cr.l5d.io/linkerd/proxy-init
         pullPolicy: ""
-        version: v1.3.11
+        version: v1.3.12
       resources:
         cpu:
           limit: 100m
@@ -1261,7 +1261,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1618,7 +1618,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1928,7 +1928,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/install_heartbeat_disabled_output.golden b/cli/cmd/testdata/install_heartbeat_disabled_output.golden
index 0a5b50069..6fa255e47 100644
--- a/cli/cmd/testdata/install_heartbeat_disabled_output.golden
+++ b/cli/cmd/testdata/install_heartbeat_disabled_output.golden
@@ -845,7 +845,7 @@ data:
       image:
         name: cr.l5d.io/linkerd/proxy-init
         pullPolicy: ""
-        version: v1.3.11
+        version: v1.3.12
       resources:
         cpu:
           limit: 100m
@@ -1115,7 +1115,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1422,7 +1422,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1643,7 +1643,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/install_no_init_container.golden b/cli/cmd/testdata/install_no_init_container.golden
index 8d1dbd75f..cf6fe27b6 100644
--- a/cli/cmd/testdata/install_no_init_container.golden
+++ b/cli/cmd/testdata/install_no_init_container.golden
@@ -914,7 +914,7 @@ data:
       image:
         name: cr.l5d.io/linkerd/proxy-init
         pullPolicy: ""
-        version: v1.3.11
+        version: v1.3.12
       resources:
         cpu:
           limit: 100m
diff --git a/cli/cmd/testdata/install_proxy_ignores.golden b/cli/cmd/testdata/install_proxy_ignores.golden
index 9436150e5..5026b92c9 100644
--- a/cli/cmd/testdata/install_proxy_ignores.golden
+++ b/cli/cmd/testdata/install_proxy_ignores.golden
@@ -917,7 +917,7 @@ data:
       image:
         name: cr.l5d.io/linkerd/proxy-init
         pullPolicy: ""
-        version: v1.3.11
+        version: v1.3.12
       resources:
         cpu:
           limit: 100m
@@ -1187,7 +1187,7 @@ spec:
         - "4190,4191,22,8100-8102"
         - --outbound-ports-to-ignore
         - "5432,443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1494,7 +1494,7 @@ spec:
         - "4190,4191,22,8100-8102"
         - --outbound-ports-to-ignore
         - "5432,443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1764,7 +1764,7 @@ spec:
         - "4190,4191,22,8100-8102"
         - --outbound-ports-to-ignore
         - "5432,443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/cli/cmd/testdata/install_values_file.golden b/cli/cmd/testdata/install_values_file.golden
index c48d1979a..a9c17916d 100644
--- a/cli/cmd/testdata/install_values_file.golden
+++ b/cli/cmd/testdata/install_values_file.golden
@@ -903,7 +903,7 @@ data:
       image:
         name: cr.l5d.io/linkerd/proxy-init
         pullPolicy: ""
-        version: v1.3.11
+        version: v1.3.12
       resources:
         cpu:
           limit: 100m
@@ -1173,7 +1173,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1480,7 +1480,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
@@ -1750,7 +1750,7 @@ spec:
         - "4190,4191"
         - --outbound-ports-to-ignore
         - "443"
-        image: cr.l5d.io/linkerd/proxy-init:v1.3.11
+        image: cr.l5d.io/linkerd/proxy-init:v1.3.12
         imagePullPolicy: IfNotPresent
         name: linkerd-init
         resources:
diff --git a/pkg/healthcheck/healthcheck_test.go b/pkg/healthcheck/healthcheck_test.go
index 587be2435..49173eaaf 100644
--- a/pkg/healthcheck/healthcheck_test.go
+++ b/pkg/healthcheck/healthcheck_test.go
@@ -2055,7 +2055,7 @@ data:
   global: |
     {"linkerdNamespace":"linkerd","cniEnabled":false,"version":"install-control-plane-version","identityContext":{"trustDomain":"cluster.local","trustAnchorsPem":"fake-trust-anchors-pem","issuanceLifetime":"86400s","clockSkewAllowance":"20s"}}
   proxy: |
-    {"proxyImage":{"imageName":"cr.l5d.io/linkerd/proxy","pullPolicy":"IfNotPresent"},"proxyInitImage":{"imageName":"cr.l5d.io/linkerd/proxy-init","pullPolicy":"IfNotPresent"},"controlPort":{"port":4190},"ignoreInboundPorts":[],"ignoreOutboundPorts":[],"inboundPort":{"port":4143},"adminPort":{"port":4191},"outboundPort":{"port":4140},"resource":{"requestCpu":"","requestMemory":"","limitCpu":"","limitMemory":""},"proxyUid":"2102","logLevel":{"level":"warn,linkerd=info"},"disableExternalProfiles":true,"proxyVersion":"install-proxy-version","proxy_init_image_version":"v1.3.11","debugImage":{"imageName":"cr.l5d.io/linkerd/debug","pullPolicy":"IfNotPresent"},"debugImageVersion":"install-debug-version"}
+    {"proxyImage":{"imageName":"cr.l5d.io/linkerd/proxy","pullPolicy":"IfNotPresent"},"proxyInitImage":{"imageName":"cr.l5d.io/linkerd/proxy-init","pullPolicy":"IfNotPresent"},"controlPort":{"port":4190},"ignoreInboundPorts":[],"ignoreOutboundPorts":[],"inboundPort":{"port":4143},"adminPort":{"port":4191},"outboundPort":{"port":4140},"resource":{"requestCpu":"","requestMemory":"","limitCpu":"","limitMemory":""},"proxyUid":"2102","logLevel":{"level":"warn,linkerd=info"},"disableExternalProfiles":true,"proxyVersion":"install-proxy-version","proxy_init_image_version":"v1.3.12","debugImage":{"imageName":"cr.l5d.io/linkerd/debug","pullPolicy":"IfNotPresent"},"debugImageVersion":"install-debug-version"}
   install: |
     {"cliVersion":"dev-undefined","flags":[]}`,
 			},
@@ -2101,7 +2101,7 @@ data:
 					},
 					DisableExternalProfiles: true,
 					ProxyVersion:            "install-proxy-version",
-					ProxyInitImageVersion:   "v1.3.11",
+					ProxyInitImageVersion:   "v1.3.12",
 					DebugImage: &configPb.Image{
 						ImageName:  "cr.l5d.io/linkerd/debug",
 						PullPolicy: "IfNotPresent",
@@ -2193,7 +2193,7 @@ data:
   global: |
     {"linkerdNamespace":"linkerd","cniEnabled":false,"version":"install-control-plane-version","identityContext":{"trustDomain":"cluster.local","trustAnchorsPem":"fake-trust-anchors-pem","issuanceLifetime":"86400s","clockSkewAllowance":"20s"}}
   proxy: |
-    {"proxyImage":{"imageName":"cr.l5d.io/linkerd/proxy","pullPolicy":"IfNotPresent"},"proxyInitImage":{"imageName":"cr.l5d.io/linkerd/proxy-init","pullPolicy":"IfNotPresent"},"controlPort":{"port":4190},"ignoreInboundPorts":[],"ignoreOutboundPorts":[],"inboundPort":{"port":4143},"adminPort":{"port":4191},"outboundPort":{"port":4140},"resource":{"requestCpu":"","requestMemory":"","limitCpu":"","limitMemory":""},"proxyUid":"2102","logLevel":{"level":"warn,linkerd=info"},"disableExternalProfiles":true,"proxyVersion":"install-proxy-version","proxy_init_image_version":"v1.3.11","debugImage":{"imageName":"cr.l5d.io/linkerd/debug","pullPolicy":"IfNotPresent"},"debugImageVersion":"install-debug-version"}
+    {"proxyImage":{"imageName":"cr.l5d.io/linkerd/proxy","pullPolicy":"IfNotPresent"},"proxyInitImage":{"imageName":"cr.l5d.io/linkerd/proxy-init","pullPolicy":"IfNotPresent"},"controlPort":{"port":4190},"ignoreInboundPorts":[],"ignoreOutboundPorts":[],"inboundPort":{"port":4143},"adminPort":{"port":4191},"outboundPort":{"port":4140},"resource":{"requestCpu":"","requestMemory":"","limitCpu":"","limitMemory":""},"proxyUid":"2102","logLevel":{"level":"warn,linkerd=info"},"disableExternalProfiles":true,"proxyVersion":"install-proxy-version","proxy_init_image_version":"v1.3.12","debugImage":{"imageName":"cr.l5d.io/linkerd/debug","pullPolicy":"IfNotPresent"},"debugImageVersion":"install-debug-version"}
   install: |
     {"cliVersion":"dev-undefined","flags":[]}
   values: |
@@ -2355,7 +2355,7 @@ data:
   global: |
     {"linkerdNamespace":"linkerd","cniEnabled":false,"version":"install-control-plane-version","identityContext":{"trustDomain":"cluster.local","trustAnchorsPem":"fake-trust-anchors-pem","issuanceLifetime":"86400s","clockSkewAllowance":"20s"}}
   proxy: |
-    {"proxyImage":{"imageName":"cr.l5d.io/linkerd/proxy","pullPolicy":"IfNotPresent"},"proxyInitImage":{"imageName":"cr.l5d.io/linkerd/proxy-init","pullPolicy":"IfNotPresent"},"controlPort":{"port":4190},"ignoreInboundPorts":[],"ignoreOutboundPorts":[],"inboundPort":{"port":4143},"adminPort":{"port":4191},"outboundPort":{"port":4140},"resource":{"requestCpu":"","requestMemory":"","limitCpu":"","limitMemory":""},"proxyUid":"2102","logLevel":{"level":"warn,linkerd=info"},"disableExternalProfiles":true,"proxyVersion":"install-proxy-version","proxy_init_image_version":"v1.3.11","debugImage":{"imageName":"cr.l5d.io/linkerd/debug","pullPolicy":"IfNotPresent"},"debugImageVersion":"install-debug-version"}
+    {"proxyImage":{"imageName":"cr.l5d.io/linkerd/proxy","pullPolicy":"IfNotPresent"},"proxyInitImage":{"imageName":"cr.l5d.io/linkerd/proxy-init","pullPolicy":"IfNotPresent"},"controlPort":{"port":4190},"ignoreInboundPorts":[],"ignoreOutboundPorts":[],"inboundPort":{"port":4143},"adminPort":{"port":4191},"outboundPort":{"port":4140},"resource":{"requestCpu":"","requestMemory":"","limitCpu":"","limitMemory":""},"proxyUid":"2102","logLevel":{"level":"warn,linkerd=info"},"disableExternalProfiles":true,"proxyVersion":"install-proxy-version","proxy_init_image_version":"v1.3.12","debugImage":{"imageName":"cr.l5d.io/linkerd/debug","pullPolicy":"IfNotPresent"},"debugImageVersion":"install-debug-version"}
   install: |
     {"cliVersion":"dev-undefined","flags":[]}
   values: |
diff --git a/test/integration/install_test.go b/test/integration/install_test.go
index 29904f84d..717044810 100644
--- a/test/integration/install_test.go
+++ b/test/integration/install_test.go
@@ -234,7 +234,7 @@ func TestInstallCNIPlugin(t *testing.T) {
 	// perform a linkerd check with --linkerd-cni-enabled
 	timeout := time.Minute
 	err = TestHelper.RetryFor(timeout, func() error {
-		out, err = TestHelper.LinkerdRun("check", "--pre", "--linkerd-cni-enabled", "--wait=0")
+		out, err = TestHelper.LinkerdRun("check", "--pre", "--linkerd-cni-enabled", "--wait=60m")
 		if err != nil {
 			return err
 		}
@@ -861,7 +861,7 @@ func testCheckCommand(t *testing.T, stage, expectedVersion, namespace, cliVersio
 	var golden string
 	proxyStage := "proxy"
 	if stage == proxyStage {
-		cmd = []string{"check", "--proxy", "--expected-version", expectedVersion, "--namespace", namespace, "--wait=0"}
+		cmd = []string{"check", "--proxy", "--expected-version", expectedVersion, "--namespace", namespace, "--wait=60m"}
 		// if TestHelper.GetMulticlusterHelmReleaseName() != "" || TestHelper.Multicluster() {
 		// golden = "check.multicluster.proxy.golden"
 		// } else if TestHelper.CNI() {
@@ -871,10 +871,10 @@ func testCheckCommand(t *testing.T, stage, expectedVersion, namespace, cliVersio
 			golden = "check.proxy.golden"
 		}
 	} else if stage == "config" {
-		cmd = []string{"check", "config", "--expected-version", expectedVersion, "--wait=0"}
+		cmd = []string{"check", "config", "--expected-version", expectedVersion, "--wait=60m"}
 		golden = "check.config.golden"
 	} else {
-		cmd = []string{"check", "--expected-version", expectedVersion, "--wait=0"}
+		cmd = []string{"check", "--expected-version", expectedVersion, "--wait=60m"}
 		// if TestHelper.GetMulticlusterHelmReleaseName() != "" || TestHelper.Multicluster() {
 		// golden = "check.multicluster.golden"
 		// } else if TestHelper.CNI() {
@@ -970,7 +970,7 @@ func TestCheckPostInstall(t *testing.T) {
 }
 
 func TestCheckViz(t *testing.T) {
-	cmd := []string{"viz", "check", "--wait=0"}
+	cmd := []string{"viz", "check", "--wait=60m"}
 	golden := "check.viz.golden"
 	if TestHelper.ExternalPrometheus() {
 		golden = "check.viz.external-prometheus.golden"
@@ -1213,7 +1213,7 @@ func TestRestarts(t *testing.T) {
 
 func TestCheckMulticluster(t *testing.T) {
 	if TestHelper.GetMulticlusterHelmReleaseName() != "" || TestHelper.Multicluster() {
-		cmd := []string{"multicluster", "check", "--wait=0"}
+		cmd := []string{"multicluster", "check", "--wait=60m"}
 		golden := "check.multicluster.golden"
 		timeout := time.Minute
 		err := TestHelper.RetryFor(timeout, func() error {
diff --git a/test/integration/uninstall/uninstall_test.go b/test/integration/uninstall/uninstall_test.go
index f90f1fead..02489945d 100644
--- a/test/integration/uninstall/uninstall_test.go
+++ b/test/integration/uninstall/uninstall_test.go
@@ -42,7 +42,7 @@ func TestInstall(t *testing.T) {
 	var (
 		vizCmd  = []string{"viz", "install"}
 		vizArgs = []string{
-			"--set", fmt.Sprintf("namespace=%s", TestHelper.GetVizNamespace())}
+			"--set", fmt.Sprintf("namespace=%s", TestHelper.GetVizNamespace()), "--wait", "60m"}
 	)
 
 	// Install Linkerd Viz Extension
diff --git a/testutil/kubernetes_helper.go b/testutil/kubernetes_helper.go
index 81fe57aa2..8953c7b04 100644
--- a/testutil/kubernetes_helper.go
+++ b/testutil/kubernetes_helper.go
@@ -182,7 +182,7 @@ func (h *KubernetesHelper) GetResources(ctx context.Context, containerName, depl
 func (h *KubernetesHelper) CheckPods(ctx context.Context, namespace string, deploymentName string, replicas int) error {
 	var checkedPods []corev1.Pod
 
-	err := h.retryFor(6*time.Minute, func() error {
+	err := h.retryFor(60*time.Minute, func() error {
 		checkedPods = []corev1.Pod{}
 		pods, err := h.GetPodsForDeployment(ctx, namespace, deploymentName)
 		if err != nil {
@@ -325,7 +325,7 @@ func (h *KubernetesHelper) URLFor(ctx context.Context, namespace, deployName str
 func (h *KubernetesHelper) WaitRollout(t *testing.T) {
 	for deploy, deploySpec := range LinkerdDeployReplicasEdge {
 		if deploySpec.Namespace == "linkerd" {
-			o, err := h.Kubectl("", "--namespace=linkerd", "rollout", "status", "--timeout=120s", "deploy/"+deploy)
+			o, err := h.Kubectl("", "--namespace=linkerd", "rollout", "status", "--timeout=60m", "deploy/"+deploy)
 			if err != nil {
 				AnnotatedFatalf(t,
 					fmt.Sprintf("failed to wait rollout of deploy/%s", deploy),
diff --git a/testutil/test_helper.go b/testutil/test_helper.go
index 7b690d853..899be08cb 100644
--- a/testutil/test_helper.go
+++ b/testutil/test_helper.go
@@ -477,6 +477,8 @@ func (h *TestHelper) HelmUpgrade(chart string, arg ...string) (string, string, e
 		h.helm.releaseName,
 		"--kube-context", h.k8sContext,
 		"--set", "namespace=" + h.namespace,
+		"--timeout", "60m",
+		"--wait",
 		chart,
 	}, arg...)
 	return combinedOutput("", h.helm.path, withParams...)
@@ -490,6 +492,8 @@ func (h *TestHelper) HelmInstall(chart string, arg ...string) (string, string, e
 		chart,
 		"--kube-context", h.k8sContext,
 		"--set", "namespace=" + h.namespace,
+		"--timeout", "60m",
+		"--wait",
 	}, arg...)
 	return combinedOutput("", h.helm.path, withParams...)
 }
diff --git a/viz/metrics-api/stat_summary_test.go b/viz/metrics-api/stat_summary_test.go
index 755e04a79..e3a4ee59a 100644
--- a/viz/metrics-api/stat_summary_test.go
+++ b/viz/metrics-api/stat_summary_test.go
@@ -1316,6 +1316,13 @@ status:
 										},
 									},
 								},
+								{
+									Table: &pb.StatTable_PodGroup_{
+										PodGroup: &pb.StatTable_PodGroup{
+											Rows: []*pb.StatTable_PodGroup_Row{},
+										},
+									},
+								},
 								{
 									Table: &pb.StatTable_PodGroup_{
 										PodGroup: &pb.StatTable_PodGroup{