Repository: kumahq/kuma
Pull request #1487 (2021-01-28 11:02:22)

docs(kuma-cp) timeouts proposal
### Summary

Proposal for the new Timeout policy


Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 3c044bd7c..02a80d1fa 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -105,7 +105,7 @@ jobs:
     environment:
       GO_VERSION: *go_version
       GO111MODULE: "on"
-      CLANG_FORMAT_PATH: clang-format-12
+      CLANG_FORMAT_PATH: clang-format-13
       # if GOPATH is not set, `golang-ci` fails with an obscure message
       # "ERRO Running error: context loading failed: failed to load program with go/packages: could not determine GOARCH and Go compiler"
       GOPATH: /root/.go-kuma-go
@@ -215,7 +215,7 @@ jobs:
     # we need a large resource class to satisfy the needs of golangci-lint run under `make check`
     resource_class: large
     environment:
-      CLANG_FORMAT_PATH: clang-format-12
+      CLANG_FORMAT_PATH: clang-format-13
     steps:
     - checkout
     - restore_cache:
@@ -243,7 +243,7 @@ jobs:
 
          wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|apt-key add -
 
-         apt update && apt install -y clang-format-12
+         apt update && apt install -y clang-format-13
     - run:
         name: "Run code generators (go generate, protoc, ...) and code checks (go fmt, go vet, ...)"
         command: make check
diff --git a/api/mesh/v1alpha1/dataplane_helpers.go b/api/mesh/v1alpha1/dataplane_helpers.go
index 40e74ef10..d03a8db90 100644
--- a/api/mesh/v1alpha1/dataplane_helpers.go
+++ b/api/mesh/v1alpha1/dataplane_helpers.go
@@ -31,6 +31,9 @@ const (
 	RegularDpType DpType = "regular"
 	IngressDpType DpType = "ingress"
 	GatewayDpType DpType = "gateway"
+
+	// Used for Service-less dataplanes
+	TCPPortReserved = 49151 // IANA Reserved
 )
 
 type DpType string
@@ -56,6 +59,10 @@ func (i InboundInterface) String() string {
 	return fmt.Sprintf("%s:%d:%d", i.DataplaneIP, i.DataplanePort, i.WorkloadPort)
 }
 
+func (i *InboundInterface) IsServiceLess() bool {
+	return i.DataplanePort == TCPPortReserved
+}
+
 type OutboundInterface struct {
 	DataplaneIP   string
 	DataplanePort uint32
diff --git a/app/kuma-dp/cmd/context.go b/app/kuma-dp/cmd/context.go
new file mode 100644
index 000000000..4d62f575a
--- /dev/null
+++ b/app/kuma-dp/cmd/context.go
@@ -0,0 +1,27 @@
+package cmd
+
+import (
+	"crypto/tls"
+	"net/http"
+	"time"
+
+	"github.com/kumahq/kuma/app/kuma-dp/pkg/dataplane/envoy"
+	"github.com/kumahq/kuma/pkg/core/runtime/component"
+	leader_memory "github.com/kumahq/kuma/pkg/plugins/leader/memory"
+)
+
+// RootContext contains variables, functions and components that can be overridden when extending kuma-dp or running the test.
+type RootContext struct {
+	ComponentManager   component.Manager
+	BootstrapGenerator envoy.BootstrapConfigFactoryFunc
+}
+
+func DefaultRootContext() *RootContext {
+	return &RootContext{
+		ComponentManager: component.NewManager(leader_memory.NewNeverLeaderElector()),
+		BootstrapGenerator: envoy.NewRemoteBootstrapGenerator(&http.Client{
+			Timeout:   10 * time.Second,
+			Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}},
+		}),
+	}
+}
diff --git a/app/kuma-dp/cmd/root.go b/app/kuma-dp/cmd/root.go
index e622aa8dc..7447640f7 100644
--- a/app/kuma-dp/cmd/root.go
+++ b/app/kuma-dp/cmd/root.go
@@ -15,8 +15,8 @@ var (
 	dataplaneLog = core.Log.WithName("kuma-dp")
 )
 
-// newRootCmd represents the base command when called without any subcommands.
-func newRootCmd() *cobra.Command {
+// NewRootCmd represents the base command when called without any subcommands.
+func NewRootCmd(rootCtx *RootContext) *cobra.Command {
 	args := struct {
 		logLevel string
 	}{}
@@ -41,13 +41,13 @@ func newRootCmd() *cobra.Command {
 	// root flags
 	cmd.PersistentFlags().StringVar(&args.logLevel, "log-level", kuma_log.InfoLevel.String(), kuma_cmd.UsageOptions("log level", kuma_log.OffLevel, kuma_log.InfoLevel, kuma_log.DebugLevel))
 	// sub-commands
-	cmd.AddCommand(newRunCmd())
+	cmd.AddCommand(newRunCmd(rootCtx))
 	cmd.AddCommand(version.NewVersionCmd())
 	return cmd
 }
 
 func DefaultRootCmd() *cobra.Command {
-	return newRootCmd()
+	return NewRootCmd(DefaultRootContext())
 }
 
 // Execute adds all child commands to the root command and sets flags appropriately.
diff --git a/app/kuma-dp/cmd/run.go b/app/kuma-dp/cmd/run.go
index fb679b96b..0b26780ac 100644
--- a/app/kuma-dp/cmd/run.go
+++ b/app/kuma-dp/cmd/run.go
@@ -1,12 +1,9 @@
 package cmd
 
 import (
-	"crypto/tls"
 	"io/ioutil"
-	"net/http"
 	"os"
 	"path/filepath"
-	"time"
 
 	kumadp_config "github.com/kumahq/kuma/app/kuma-dp/pkg/config"
 
@@ -19,23 +16,13 @@ import (
 	kuma_dp "github.com/kumahq/kuma/pkg/config/app/kuma-dp"
 	config_types "github.com/kumahq/kuma/pkg/config/types"
 	"github.com/kumahq/kuma/pkg/core"
-	"github.com/kumahq/kuma/pkg/core/runtime/component"
-	leader_memory "github.com/kumahq/kuma/pkg/plugins/leader/memory"
 	util_net "github.com/kumahq/kuma/pkg/util/net"
 	kuma_version "github.com/kumahq/kuma/pkg/version"
 )
 
-var (
-	runLog = dataplaneLog.WithName("run")
-	// overridable by tests
-	bootstrapGenerator = envoy.NewRemoteBootstrapGenerator(&http.Client{
-		Timeout:   10 * time.Second,
-		Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}},
-	},
-	)
-)
+var runLog = dataplaneLog.WithName("run")
 
-func newRunCmd() *cobra.Command {
+func newRunCmd(rootCtx *RootContext) *cobra.Command {
 	cfg := kuma_dp.DefaultConfig()
 	cmd := &cobra.Command{
 		Use:   "run",
@@ -116,7 +103,7 @@ func newRunCmd() *cobra.Command {
 
 			dataplane, err := envoy.New(envoy.Opts{
 				Config:    cfg,
-				Generator: bootstrapGenerator,
+				Generator: rootCtx.BootstrapGenerator,
 				Dataplane: dp,
 				Stdout:    cmd.OutOrStdout(),
 				Stderr:    cmd.OutOrStderr(),
@@ -127,13 +114,12 @@ func newRunCmd() *cobra.Command {
 			}
 			server := accesslogs.NewAccessLogServer(cfg.Dataplane)
 
-			componentMgr := component.NewManager(leader_memory.NewNeverLeaderElector())
-			if err := componentMgr.Add(server, dataplane); err != nil {
+			if err := rootCtx.ComponentManager.Add(server, dataplane); err != nil {
 				return err
 			}
 
 			runLog.Info("starting Kuma DP", "version", kuma_version.Build.Version)
-			if err := componentMgr.Start(shouldQuit); err != nil {
+			if err := rootCtx.ComponentManager.Start(shouldQuit); err != nil {
 				runLog.Error(err, "error while running Kuma DP")
 				return err
 			}
diff --git a/app/kumactl/cmd/install/render_helm_files.go b/app/kumactl/cmd/install/render_helm_files.go
index e33e6157c..7d2a5ab0f 100644
--- a/app/kumactl/cmd/install/render_helm_files.go
+++ b/app/kumactl/cmd/install/render_helm_files.go
@@ -85,26 +85,15 @@ func loadCharts(templates []data.File) (*chart.Chart, error) {
 		})
 	}
 
-	loadedChart, err := loader.LoadFiles(files)
-	if err != nil {
-		return nil, err
-	}
-
-	// Filter out the pre- templates
-	loadedTemplates := loadedChart.Templates
-	loadedChart.Templates = []*chart.File{}
-
-	for _, t := range loadedTemplates {
-		if !strings.HasPrefix(t.Name, "templates/pre-") &&
-			!strings.HasPrefix(t.Name, "templates/post-") {
-			loadedChart.Templates = append(loadedChart.Templates, &chart.File{
-				Name: t.Name,
-				Data: t.Data,
-			})
+	var fileteredFiles []*loader.BufferedFile
+	for _, f := range files {
+		if strings.Contains(f.Name, "templates/pre-") || strings.Contains(f.Name, "templates/post-") {
+			continue
 		}
+		fileteredFiles = append(fileteredFiles, f)
 	}
 
-	return loadedChart, nil
+	return loader.LoadFiles(fileteredFiles)
 }
 
 func generateOverrideValues(args interface{}, helmValuesPrefix string) map[string]interface{} {
diff --git a/app/kumactl/pkg/install/k8s/control-plane/helmtemplates_vfsdata.go b/app/kumactl/pkg/install/k8s/control-plane/helmtemplates_vfsdata.go
index 3f6fea22b..a81327cda 100644
--- a/app/kumactl/pkg/install/k8s/control-plane/helmtemplates_vfsdata.go
+++ b/app/kumactl/pkg/install/k8s/control-plane/helmtemplates_vfsdata.go
@@ -37,14 +37,14 @@ var HelmTemplates = func() http.FileSystem {
 		},
 		"/Chart.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "Chart.yaml",
-			modTime:          time.Date(2021, 1, 26, 12, 1, 33, 745000000, time.UTC),
+			modTime:          time.Date(2021, 1, 27, 13, 48, 38, 738000000, time.UTC),
 			uncompressedSize: 458,
 
 			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\x5c\x90\x41\x4f\xc3\x30\x0c\x85\xef\xf9\x15\xfe\x03\x4b\x07\x42\x20\xf5\x34\xc4\x05\x89\x0b\x27\xee\x5e\x6a\x1a\xd3\x24\xce\x92\xb4\x55\xf7\xeb\x51\xba\x15\x55\x9c\x2c\xbd\xa7\xef\xd9\xcf\x18\xf9\x8b\x52\x66\x09\x2d\x4c\x8f\x2a\xa0\xa7\x16\x86\xd1\xa3\xea\x28\x9b\xc4\xb1\xac\xd6\x2b\xbc\x93\xf3\x60\x2c\xa6\x02\xdf\x92\xa0\x58\x82\x8f\xd1\x23\xbc\x49\x28\x49\x1c\x7c\x3a\x0c\xa4\xca\x12\xa9\x05\x8c\xd1\xb1\xc1\x8a\xaa\x69\x4b\x3f\xea\x27\xfd\xa2\x30\xc6\xbf\x7d\x0f\xfa\xa8\x9f\x95\x95\xba\xd2\x96\x12\x73\xdb\x34\x3d\x17\x3b\x9e\xb5\x11\xdf\xd4\x2b\xec\x65\x1d\xca\x23\x87\x82\x1c\x28\xe5\x56\x01\x1c\xe0\x76\x28\x8e\xb9\x70\x30\xa4\x00\x00\xc8\x23\xbb\x4d\xd3\x06\x67\x47\xcb\xa9\xaf\x62\x8d\xdb\x51\x3f\x38\x8c\xe7\x6e\xc9\xd7\x81\x69\x66\x73\xdd\xd3\xab\xa7\x77\xe6\x69\x90\xd0\xdb\xcb\xbf\x88\xc0\x66\x10\x87\x34\xed\xd9\xc0\x55\x5b\xf4\x6d\xd2\xb4\x47\xd9\xd4\xc6\x5b\xcb\xda\x49\xb3\x34\xec\xb1\xa7\xdc\x9c\x13\x86\x6e\x15\x0f\x4e\x7a\x39\x04\x9a\x75\x9e\x7a\x35\xd0\x32\x4b\xea\xee\x95\x33\xa5\x89\x0d\x81\xa7\x6c\x57\xc1\xdc\x5f\x1f\xd7\xd7\xff\x06\x00\x00\xff\xff\x7f\xd8\x20\xfe\xca\x01\x00\x00"),
 		},
 		"/README.md": &vfsgen۰CompressedFileInfo{
 			name:             "README.md",
-			modTime:          time.Date(2021, 1, 26, 12, 1, 33, 775000000, time.UTC),
+			modTime:          time.Date(2021, 1, 27, 13, 51, 10, 322000000, time.UTC),
 			uncompressedSize: 8865,
 
 			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\xb4\x5a\x5b\x73\xdb\xb6\xb3\x7f\xe7\xa7\xd8\xca\x0f\xb9\x8c\x44\x39\xf9\xb7\x39\x19\xcd\xb9\x8c\x6b\xb7\x27\x9e\xa4\xa9\x26\x76\x7a\x1e\x5c\x4f\x08\x01\x2b\x0a\x11\x08\x30\x00\x28\x47\x8d\xf2\xdd\xcf\x2c\x40\x52\xa4\x24\x5f\xf2\x6f\xda\x87\x86\x22\x17\xbf\x5d\x2c\xf6\x8a\xf5\xd5\x0f\x57\xd7\x57\xcb\xaa\x60\x23\x65\x72\x73\x5d\x3f\x57\x56\x5d\x27\xc9\x09\xbc\x42\x55\x00\x5f\x30\xeb\x61\x6e\x2c\xf8\x05\xc2\xeb\xaa\x60\x70\x6a\xb4\xb7\x46\xc1\x54\x31\x8d\x49\xf2\xc3\xd5\xe5\xba\xc4\x09\xb0\xb2\x54\x92\x33\x2f\x8d\xbe\x7e\xbc\xf0\xbe\x74\x93\xf1\x58\x16\x79\xea\x16\x12\x95\x70\xa9\x34\xe3\x19\x13\x39\x8e\x89\x7e\xd4\x21\x1f\x49\x3d\x37\xb6\x08\xcf\x4c\xfd\x8f\xf3\x6b\x85\xff\x35\x57\xcc\x8f\xdc\xa7\x8a\x59\x7c\x02\x3f\x5c\xfd\x81\xd6\x49\xa3\x27\x70\x9c\xfe\x98\xfe\xc7\x3d\x0c\x6a\xe2\x51\xa0\x7d\x08\xfa\x49\x59\xb6\x0c\x9e\xa5\xc7\xe9\x8b\x7b\x18\x6c\xe9\x47\x81\xfc\x5e\x1e\x49\xf2\xf4\xe9\x2b\x53\x60\xc9\x72\x9c\x3c\x7d\x0a\xff\xd9\xc0\xe7\xd2\x2f\xaa\x59\xca\x4d\x31\x26\xe5\x2f\x3e\x85\x7f\xfe\x3b\x49\x8e\x8e\xe0\x0f\xa6\x2a\x74\x49\xb2\x81\xd7\xb8\x86\x0d\x90\xde\x60\x03\x67\x38\x67\x95\xf2\xe1\xc9\x71\x2b\x4b\xe2\x0a\x9b\x64\x33\xa2\xff\xe2\xff\x9b\x7f\x7a\x4f\xe1\x57\xb2\x81\x5c\x99\x19\x53\xa9\x2c\x58\x8e\xa9\xc5\x5c\x3a\x6f\x09\xdf\x79\x2b\x75\x0e\x1b\xc8\x06\x4b\xa3\xf3\x91\x30\x7c\x89\x76\x14\x8c\x22\x3e\xa7\x33\xa9\xbd\x65\xeb\x54\x9a\x41\xd6\x11\xa5\x05\x21\x43\x61\x4a\x45\x43\x39\x27\x06\x0e\xf6\x58\x7a\x96\xf7\xb8\x69\xa9\x08\xec\x72\x81\x20\x6a\x40\x22\xe9\x61\x85\x95\x6e\x08\x37\x0b\xc9\x17\x20\xbd\x43\x35\x6f\xa8\x1d\x78\x03\xe9\x29\x59\x6a\xba\x3d\x99\xc0\xb7\x64\x9e\x2f\x2e\xd6\xce\x63\xf1\x96\x15\xe8\x4a\xc6\x49\x85\x33\x63\x14\x71\xf6\xb6\x42\x62\xfd\x7f\x0b\xf4\x0b\xb4\x60\x2c\x68\xe3\x09\x2e\x2c\x0c\x36\xef\x99\xcd\xd1\x83\x6e\x97\xdf\x48\x1f\xbf\xb8\x80\x0b\x8a\xcd\x50\x05\x6e\x3c\x7a\x46\x70\x8c\x54\x99\xfc\x0d\xae\xe8\x4b\x57\xb1\x64\x28\x41\x75\xd1\x95\xa6\xa0\x4c\x0e\x8a\xe8\x26\x60\x34\x82\x99\x83\x99\xcf\x87\x44\x36\x14\x38\xab\xf2\x7d\xe0\xc2\x08\xec\x83\x3a\xcf\xb4\x60\xca\x68\xec\x41\x13\xa1\x6b\x61\xb7\x44\x43\x8b\x85\xf1\x38\x8c\x87\xb2\xcf\xe0\x2f\x5a\x71\xe0\x80\x1a\x5c\xfa\x3e\x04\x39\x07\x5b\x69\x4d\x24\x45\xa5\xbc\x8c\xab\x76\xb1\x96\xc2\xfd\x6f\x60\x73\x22\x84\x45\xe7\xfa\x82\x07\x71\x7f\xd7\x6a\x0d\x95\x43\x01\x52\x43\x16\x65\xcb\x20\xee\x72\x17\xce\x62\x88\x1a\x04\x23\x35\xb9\x40\xf6\x8c\x20\xde\x56\xc5\x8c\x8e\x6f\x0e\x2d\x81\x99\x77\x22\xd6\x34\x85\xf3\x5c\x1b\x8b\x02\x6e\x16\xa8\x81\x55\xde\x38\xce\x14\xc9\x21\x1d\xa0\x66\x33\x85\x62\x9f\x5d\x87\x2e\x6d\x89\x5a\xeb\x99\x33\xe5\x7a\xe6\xe3\x4d\x0d\x05\xaf\x8c\x25\x85\x78\xa6\x60\x6a\x04\x9c\x6c\x71\x1a\x13\xb6\xf8\xa9\x92\x16\x5d\x90\xf2\xea\x37\xf4\x56\x72\x07\x17\x68\x57\x68\xb7\xd1\xa7\x17\x1e\x66\x68\x35\x7a\x74\x23\x27\x73\x37\x2e\xe2\x92\x91\x0b\x4b\x9e\x90\xf2\x08\x8a\xab\xca\x79\xb4\x77\xef\xa5\x90\xfa\xdd\x9e\x26\x9f\x37\x4e\x58\x48\x2d\x8b\xaa\xa0\xa3\x2e\x8d\x08\xde\xc5\x94\x32\x37\xf7\x60\xb2\xcf\xfb\x98\x3f\xb5\x98\xec\x73\x17\x8f\x16\x21\x3d\xdc\x09\x19\x5d\xef\x74\xfa\xfe\xbd\x97\x4a\xfe\x15\xc2\xeb\x14\x2d\x47\xed\x59\x8e\x5b\x2e\x2f\x8f\x89\xcd\xaf\xc6\x36\xbb\x27\xad\x32\x0f\xc2\xe8\x47\x1e\x5c\x55\x96\xc6\xfa\xee\xa1\x8f\x57\xcf\x67\xe8\xd9\xb0\xff\xee\x19\xd9\x42\x30\xc4\xbb\x37\x5a\x9f\xd5\x06\x94\x74\x81\xff\xd5\x97\x81\x45\x67\x2a\xcb\x71\x30\xf9\x32\xa0\x50\x31\x98\x0c\x78\x59\x0d\x86\x83\xb8\x07\x7a\xcd\x56\x68\x59\x8e\x9d\xbd\x0c\x26\x2f\x8f\x87\x03\xbf\x2e\x89\xbc\xfb\xfe\xeb\xd7\xf6\xf5\xbb\x06\xf8\xeb\xf5\x6d\x9b\xbc\x73\x87\x95\x43\x68\x25\xde\xdd\x96\x36\x02\x2f\x50\x21\xf7\xc6\xc2\x06\xcc\xec\x23\xf2\xb0\xa3\x2f\x83\xad\xb9\x51\xda\x63\x96\x2f\x06\x93\x01\x2b\xc4\x8b\x1f\x07\xc3\x9d\x8f\xc6\x0d\x26\x03\x25\x75\xf5\x79\xf0\x35\x78\x23\xb9\xae\x6b\x60\x6f\xaf\x1d\xa2\x35\xec\x09\x25\xf5\xc7\xb0\xf2\x57\x26\x55\x65\x71\x6a\x94\xe4\x3b\xe9\x29\x3a\x73\x88\x1e\x35\x15\x94\x91\xac\x76\xfb\xa2\xf2\xcc\x13\xf5\x0d\xce\x16\xc6\x2c\x41\x16\xa5\xc2\x02\xb5\x47\x01\xb3\xf5\x56\xa0\xf3\x9a\x19\x70\x53\x94\x46\x23\x19\xd4\xae\x40\xe4\x61\x92\x63\x4a\xe7\x7a\x28\x2e\xfe\x5e\xc6\xbc\xaf\xd6\x60\x56\x68\xad\x14\xd8\x0f\x3f\xbd\x4d\x5f\x44\xb4\x47\x0e\x22\xde\x6d\xdc\x7c\xcc\xf6\x9d\x5d\x9f\xc6\x73\x3f\x9f\x86\x8d\xd7\x38\x10\xe8\x6e\x67\x77\x2b\x3e\xd3\xda\xf8\x60\x6e\xae\x7f\xf4\xe1\x0c\x4f\x84\x90\x71\x57\xd0\x25\xa4\xcc\x58\x79\x30\xfa\xc1\xec\x62\x92\x79\x17\xa2\xfa\xc5\x5a\xf3\x46\xec\xbe\xb5\x75\x78\x0c\x26\x5f\xbe\x0e\x07\x64\xcf\x83\xc9\x4f\x2f\x5e\xfe\xd4\x7a\xc2\x1b\xc3\xc4\xcf\x4c\x31\xcd\xd1\x46\x43\x7b\xff\xee\x0d\xed\x3c\x26\x98\x36\x3d\x3d\x54\x84\x03\x1a\xee\xb1\xb8\x4d\xc9\x91\xdd\x28\xe2\x81\x5b\x6b\xfe\x70\x96\xdf\x41\xe9\xf5\x6e\x6b\xf6\x04\xde\x4a\xf9\x60\x31\x42\xb4\xd8\x06\xe9\x17\x2f\x43\x9c\x9e\xd2\x5b\xa3\xeb\x04\x75\x07\x1f\x4a\x99\x9f\x4b\x73\x30\x52\x36\x35\x59\xea\x96\xb2\xfc\x0d\xdd\xe2\xd4\x22\x8b\x15\xea\xed\x89\x73\x5b\x77\xd1\x2a\xe0\x61\x89\xce\xc3\x7e\x9b\x92\x90\xb0\x0e\x15\x04\x31\x3c\xba\x87\x3a\x26\x41\x36\x8b\xc0\x95\x78\xe0\xf0\xbc\x72\x69\x8e\x1a\x2d\x53\xa9\x43\x6e\xd1\xbf\xdd\xf5\xfc\x41\x6d\x1d\xf4\x31\x86\x61\x42\x60\x92\x4e\x4b\xb9\x94\x5b\x3f\x84\x25\xae\xe9\x01\x98\x16\xc0\x59\x78\xa4\x58\x58\x5a\xe3\x91\x87\xed\xc5\xca\x56\x8f\x9a\x9c\xcd\x4d\x51\x54\xba\xee\x8a\xee\x96\x8b\xb3\x9f\x2b\x2d\xd4\x21\xa9\x7e\x66\x0e\x5f\xfc\x08\xa8\xb9\x11\x28\xe0\xf4\x04\x38\x5a\x2f\xe7\x84\x8b\xf0\x38\x54\xae\xb4\x1f\xe6\xa8\x66\xb8\x67\xe7\x47\x51\xf2\x27\x87\xa5\x61\xa5\x8c\x15\xcb\xf7\xd0\xd3\x21\xe5\x9c\x4c\xcf\xc9\x22\x5f\x5d\x5e\x4e\x2f\xee\x13\x81\x2b\x89\xda\x9f\xa2\xf5\xee\xe2\x9b\xa5\x09\xa9\xdc\xcc\x21\x2d\xb1\xe8\xea\xab\x4e\xb2\x9c\x69\x60\x9c\x53\x01\xcb\x44\x21\x35\xa0\x16\xa5\x91\xda\x87\x42\xf3\x81\xa2\xb6\xb5\xf0\x3f\xa6\x33\x6e\x8d\x73\xf0\x0d\xe6\xb4\x14\x2e\x3a\xf8\x69\x50\xde\xbf\x21\x52\x6d\xd9\x31\x66\xdc\xb0\xba\x80\x22\x4f\x96\xb9\x86\xd7\x67\x17\x4d\x20\x89\x75\x6a\x0a\xef\xe9\x3b\xc9\x7d\x3a\x85\x15\xda\xa8\xe7\x83\x02\xc6\x6e\xb1\xac\x94\x3a\x58\x03\xcc\xdf\x1a\x3f\xb5\xe8\x50\xfb\x5e\xdb\x13\xda\xce\x69\x67\xd5\x61\x5c\x8b\xa5\x71\xd2\x9b\xbd\xd6\x97\xda\x5d\x5e\xf6\x20\xc3\x0a\xe8\xae\xd8\xcf\xaa\xa4\x9b\xb6\x28\x34\x73\xf8\x02\xbf\xe8\xd5\xa4\x46\x1e\xd6\xca\xdb\xfe\x7e\x8d\xeb\xe6\x07\x7c\xed\xc4\xac\x8b\x1a\x88\x8a\x6e\x21\xc8\x49\x51\xaf\xa4\x35\x9a\x8a\x17\x58\x31\x2b\xa9\xc1\x08\x9d\x30\x5a\x84\xec\x17\xbd\xca\x28\x20\x93\x5b\x87\x82\xa2\xce\x52\xa8\x57\x2d\xf5\x10\xb2\x08\x7b\x90\x32\x7e\x1a\x86\x38\x95\xbd\xc6\x75\x4b\xb4\xc4\x75\x9f\x06\x56\x4c\x55\xa1\x6c\xa7\xaa\x72\x4f\x07\xa8\x57\x7f\x30\x7b\x4f\x62\x3b\xb8\x9b\x68\x53\x37\x52\x29\x98\x21\x94\xcc\xd5\x36\x14\x1a\x9a\xba\xbe\x28\x0f\xd7\x17\x75\x81\xe7\xd2\x15\x53\x52\x30\x6f\x6c\xca\x5a\x6e\xef\x2a\x85\x87\x5a\xce\x8e\x3c\x36\x90\x90\xb6\xcb\x92\xf2\x84\x8e\x87\xde\xa2\x35\x15\x64\x30\xdc\x79\xa5\x62\x03\x39\xab\xa4\x12\xc1\xe3\x2a\xe7\x4d\xd1\x56\x9f\x1a\xbc\x29\x9b\x90\x90\xde\x21\xad\xb9\xd1\x68\xdf\xe1\x1c\x2d\x6a\xaa\x0b\xbe\x83\xc8\x01\x12\x6c\x83\xf9\xf7\x05\xd7\xf2\xae\xa6\xf7\x5c\x3b\xdf\x5e\xcf\x84\x3b\x91\xd3\xb7\xe7\x20\xb5\xf3\xc8\x04\x21\x95\xd6\x7c\x5e\x83\xd4\xb2\x8d\x16\x4d\x5b\xaa\x65\xca\x17\xf4\xfb\x4e\xe0\x08\x07\x0d\xe5\xf6\x42\x40\xcb\x54\xa3\x3f\x93\xb6\xaf\xa6\x31\x7a\x3e\xe6\x5a\x8e\x8b\x4a\xf9\xca\x8d\x35\xfa\x54\xd4\x81\xcb\x07\x53\x6a\x04\x24\x74\x21\x6d\x28\xfc\xd7\x2d\xe6\x4c\xea\x7d\xcc\x15\xb3\x63\x25\x67\x01\x77\x26\xf5\x1e\xdc\x4c\xea\x03\x50\xdc\xe8\xf9\x7e\x10\x8d\x91\xa5\xfe\xbc\x87\x44\x2f\x65\x5e\xd9\x18\x0c\xb7\xbd\x81\x96\xf7\x5d\x25\xd1\xea\x87\x5d\x23\x91\xe6\xfe\xb9\x96\xef\x62\xb7\xe5\x23\xc1\xb6\x3d\x9e\x96\x77\x5e\x39\xd6\x37\x8c\x72\xbb\xa7\x26\xea\x36\xd4\x3b\x20\x87\xc3\xb7\x32\xb3\xa5\x59\x49\xb5\x66\xe3\xfa\xa8\x49\xe5\x7b\x98\xfd\x48\xde\xa2\xee\x5e\x4d\x0e\x8e\xd3\xe3\xf4\xf9\xce\xea\x40\x94\x6c\x40\x30\xcf\x1e\x9c\x51\x44\xcc\x28\x97\x4d\xdb\x74\x76\x4b\x56\xd9\x05\xfd\xb6\xf4\x77\x76\x38\xfd\x75\x40\xb5\xf4\xe7\xf7\x4b\x4b\x64\xfb\xf2\x92\x2b\x1f\x14\x5a\xea\xdc\xa2\x73\x77\x86\x8b\x39\x78\x5b\xe1\x10\xa4\x07\x81\xa5\x32\x6b\x07\xe7\x71\x59\xb0\x97\xfb\x4a\x97\x86\x45\x11\xda\x80\x9e\xe1\xc4\x06\x21\x88\x1b\x9a\x04\x6f\xea\x72\xe4\x8c\x79\x16\xd3\x46\xc3\x69\x86\xca\xe8\xdc\x35\x37\x4f\x0d\xa8\xb0\x4c\xea\x4b\xb9\xeb\xb0\xff\x3a\x76\x51\x09\xf4\x85\x84\x8c\xb0\x46\x89\x90\xe5\xa9\x50\x8e\x49\xcb\xf9\x3a\x75\x31\xee\xe5\x2a\x94\xd6\x01\x32\x00\x75\xf8\x7c\xf3\xf5\x65\x23\x77\x17\xc4\xfd\xbd\xf6\xf5\x2e\xc8\xef\xd0\x9e\x36\xf0\xae\xd3\x93\xee\xb2\xe9\xb7\x9f\xcf\x8e\x8f\x8f\x9f\xed\xf7\x9f\x0d\x50\xaf\xd9\x4c\x8e\x8e\xe0\x34\x66\xae\xe6\x62\x0c\xce\x70\x4e\x96\x49\xb2\x24\xc9\x49\x93\x91\x4e\xdf\x9d\x39\x60\x16\x41\x19\x46\x6d\xd0\x4a\xb2\x78\xd5\x9a\x71\x2b\x5c\x76\xfd\x98\xfe\x79\xb2\x8d\xdd\x69\xb8\x5a\x2b\x8c\xa5\x8e\xd3\x33\xa9\xc2\x7d\x74\x3b\xd5\x21\xb9\x22\xa4\x16\x61\x32\x36\x4c\x4a\x85\xcc\x61\x4c\xb8\xa4\x84\x2b\x82\x0f\x43\x33\x61\x78\x45\x05\x4e\x1c\x86\x5d\x2d\x50\x15\x23\x6e\xc5\x75\x1a\xe4\x3f\x43\x85\x54\xad\x27\xc9\x89\x83\x92\xd9\x50\x2d\x5e\xd1\xc2\x47\xd4\x87\x14\xb2\x56\xec\x76\xe1\xa8\xfb\x76\x18\xe5\x08\x76\x47\x4d\xf3\x8c\x04\x56\xe8\x9b\xbb\x6d\x92\x22\x23\x27\xce\xea\xe1\x9d\x74\x2d\x01\xd3\x22\x29\x2a\xd7\x5b\x54\x30\x5d\x51\x8b\x9c\x52\x37\xae\x21\x68\xae\xbb\xe6\x75\x1b\xf8\xeb\x57\x2e\x4c\x65\xb6\x8d\x77\xb0\x2b\xe6\x61\x29\x75\xa8\x57\x6f\x50\xa9\x21\x38\xaa\xde\xa4\x03\xb7\x30\x95\x12\x09\x31\xa4\xc4\xc4\x99\xa5\x62\x44\xad\xd3\x24\xb9\x34\x20\x6a\xaa\x50\x3f\x64\x94\x63\xb8\x57\x19\x29\xfb\xa9\x96\x9f\xa9\xe6\xf3\x74\x04\x6e\x08\xb6\xd2\x93\x24\xc9\xb2\xcc\x2d\x50\xa9\xa4\x26\x85\x1c\x3d\xd0\x49\xc2\x06\x72\x8b\x25\xd0\xc6\x53\x69\x60\x03\xde\xc2\xc8\xc1\x00\x06\xb0\x01\x5e\x79\x18\x89\xf0\x63\x34\x7f\x06\x1b\xf8\xcc\x6c\xee\xa0\x01\x89\xfb\x22\x9c\x24\x39\x02\xf2\x73\x12\xe7\xe3\xa7\x7d\x2e\x23\x03\x1f\x5d\xb8\xcb\xf8\xf8\x09\x1e\xa5\xd2\x63\xe1\xae\xae\xd3\x02\x3d\xa3\x18\xdb\x5e\x11\x86\x4c\xf8\x38\xdd\x78\x74\xfe\xf1\x20\x7d\x4a\x62\xfd\xf9\x27\x25\xb7\x27\x4f\x1e\xdd\xc5\x3f\xcb\xb2\x60\x24\x9d\x89\x41\x92\x9c\x6b\x2a\xa6\x44\xc5\xc9\x02\x42\x04\x95\xd4\x87\xae\xa4\x0b\xc3\x86\xed\xd8\xa1\x7f\x17\xd7\x9d\x72\x50\xf4\x7a\x25\xf3\x05\x9c\xac\x98\x54\x6c\x26\x95\xf4\xeb\xb4\xcb\x86\x6a\xfa\x50\xf7\x27\xd9\x76\x7a\x31\x35\xa2\x21\x41\x9b\x6d\x2f\x4e\xea\xee\xc4\xa2\xa8\xb4\x60\x9a\xaf\x83\x5f\xd4\xb7\xfa\x94\xf9\xeb\xab\xfe\x19\x23\xbf\x25\xdf\x99\xbe\x87\x6a\x7b\xc3\xbd\x3b\x05\x49\x82\x6b\x2e\x5f\x3a\xe8\x8f\x35\xae\xaf\x48\x47\xa3\x9d\x97\xc4\x7e\x86\xed\xf8\xc9\xf4\x26\x1f\x8d\x93\xad\x50\x99\x92\xbc\x30\x49\x28\x89\x05\x5f\x88\x11\xa1\x9e\x35\x79\xb4\xf1\x6e\x48\xea\xe8\x30\x74\x14\x75\xcd\x90\x0d\x09\xd2\xe2\x9c\xe2\x01\x81\xcf\x8d\x52\xe6\x86\xb8\xc5\xea\x3b\x96\xde\xc1\xe1\x44\x64\x45\xdf\x34\xde\x10\x23\x0f\x73\x64\xbe\xb2\xe8\x26\x09\x3c\x0d\xcd\x52\x56\xb0\x25\x42\xbc\x5b\xf1\x38\xae\xd9\x35\x25\xca\x78\xf9\xd2\x8d\xeb\x46\x61\x14\x32\x56\x16\x5a\xe8\xb5\xe6\xd0\x46\x95\x30\xe0\x8c\x5d\xda\xae\xb4\xe0\xb1\x20\x5f\x41\x47\xfc\xc8\x3d\xdb\x17\xd1\x37\x9d\xa7\xb5\xd1\xcb\x4a\x8b\xa3\x2c\xe2\x94\xc6\x79\x7a\xb6\x08\xa6\x90\xbe\x8d\x21\xa5\x35\x1c\x9d\x0b\xe3\xb1\x03\xca\x21\x0d\x1f\x35\x75\x3a\x11\xf5\xc7\x57\xc1\xd8\xfa\x06\x3c\xef\x1e\x16\x05\x8a\x21\xb9\x99\xa1\x70\xd3\xa4\xfc\x20\x1c\x03\x27\x0b\xa9\x98\x55\x6b\x72\xa2\xf9\xc8\xc9\x9c\x8a\x7f\x8e\xd6\x0f\xe3\xcd\x7e\xcd\x2a\x9a\x02\x34\xd1\xac\xa9\x9e\x63\xdf\x18\xc6\x55\x89\xd4\x0e\x79\x65\x31\xf8\x99\x42\x0f\x97\x6f\x2e\xd2\x7a\x1a\xb5\xa4\x32\xce\x2d\x21\x23\x61\xc6\xb1\x20\xd9\x19\xa9\x65\xcd\x7e\x5d\x8c\x51\x61\x24\x4c\x99\xa4\x9e\x2f\xd7\xf9\xb4\xbe\xd7\x48\x92\xed\x5f\x4f\x4c\xa0\x99\xdf\xd5\xe1\x68\x9c\x74\xfe\xcc\xa2\xff\x75\x54\x56\x33\x25\xf9\x88\x7a\x5e\xef\x52\xf7\xaf\x94\x15\xec\x2f\xa3\xd9\x8d\x6b\xff\x2a\x20\xac\x1b\xad\x9e\xa7\xa5\xce\x93\x6d\x3a\xd9\x02\xd1\xab\xd4\x2d\xc6\xc2\x70\x37\x0e\x96\xfe\x61\x86\xce\x7f\x28\x2d\x15\x24\x1c\xdd\x38\xb6\x7b\x1f\x1a\x07\xfe\x20\xb6\x49\x73\x9c\x1c\x4e\x34\xb7\xc0\x7b\x53\xca\x86\x8b\x1b\x1f\x75\x56\x8c\x8c\x26\x10\x97\x1c\x74\xda\x2d\xdc\x83\x87\x9a\xc9\xff\x07\x00\x00\xff\xff\x72\xe8\x78\x23\xa1\x22\x00\x00"),
@@ -192,10 +192,10 @@ var HelmTemplates = func() http.FileSystem {
 		},
 		"/templates/_helpers.tpl": &vfsgen۰CompressedFileInfo{
 			name:             "_helpers.tpl",
-			modTime:          time.Date(2021, 1, 22, 14, 32, 7, 748000000, time.UTC),
-			uncompressedSize: 5570,
+			modTime:          time.Date(2021, 1, 28, 16, 7, 7, 527000000, time.UTC),
+			uncompressedSize: 5686,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\xb4\x58\xdf\x6f\xab\x38\x16\x7e\xcf\x5f\x61\xa1\x7b\xa5\x76\xf6\x42\x1e\x66\x76\x1f\x22\x8d\x46\xdc\xc4\x73\xcb\x36\x21\x11\xd0\xae\xba\x2f\xc8\x81\x93\xd4\x2a\x18\x6a\x9b\xec\x64\xdb\xfe\xef\x2b\xdb\x90\x00\x49\xda\xa4\xda\xfb\xe6\xe2\xe3\xef\x7c\xe7\xd7\x67\xa7\x2f\x2f\xc3\x5f\xd0\x86\xe6\x23\x24\x40\xa2\x15\xcd\x40\x6e\x4b\xf8\x3d\xaf\x84\x24\xc9\x23\x8c\xd0\x2f\xc3\xb7\xb7\x81\xb2\x1a\xe0\xbf\x4a\xc2\x52\x24\x1f\x01\x31\x92\x03\x2a\x56\x7a\x9d\x3c\x12\x2e\x9d\x41\x6d\x67\xa3\x14\x56\x94\x01\xb2\x9e\xaa\x9c\x38\xca\xd0\x42\xf6\x7e\x8b\x54\x99\x44\xce\x58\x9f\xf1\x15\x8a\x73\x4f\xb2\x0a\x84\xb6\x9c\x6f\x80\x73\x9a\x02\x7a\x45\x92\x57\x2c\x41\xff\xf8\x55\x2f\x69\x1e\x56\xab\x15\xfd\x0b\x59\xb6\x85\x6a\x2c\x60\xa9\x5a\x1a\x6a\x63\x0e\x44\x02\x22\x3b\x0f\xab\x2a\xcb\xb6\xe8\xb9\x22\x19\x5d\x51\x48\x11\x29\x4b\x4d\xda\x19\xfc\x0b\x0c\xb6\xb6\x97\xca\x83\x0a\x40\xa0\x25\x24\xa4\x12\x80\x44\x91\x03\xba\xad\x96\xc0\x19\x48\x10\x26\xd4\x15\x85\x2c\x15\x88\x70\x40\x19\xcd\xa9\x84\x14\xc9\x02\xc9\x47\x2a\xd0\xd5\x72\xab\xd3\x30\xf1\x43\x65\x4b\xd9\x1a\x89\x12\x92\x6b\x67\xe0\xad\x10\x87\x0c\x88\xa8\xf3\x95\x14\x4c\x12\xca\x84\xc9\x98\xf9\x46\x25\xfa\x0f\xcd\x32\xb4\x04\x54\x09\xc5\x53\x20\xa2\xc9\xd7\x6c\x8f\x67\x55\x19\x74\x33\x4b\x57\xbb\x44\x36\x9b\xbb\x64\xd6\x26\x27\xf7\xcf\x49\x76\x26\x76\x38\x5f\x34\xf1\xd1\xef\xe7\x57\x73\xcf\x71\x97\x02\x03\xe2\x04\x26\x3f\xe6\x6c\xc3\xb3\xf3\xf1\x42\x72\x25\xa7\x4c\xae\x90\xf5\x55\xd8\x5f\x85\xd5\xc3\x32\x4e\xcf\xef\xad\xe3\xcb\x4e\xc7\xb5\x4a\xa9\x66\x63\x03\x5c\xd0\x82\xa9\x32\xea\x72\xd6\xbd\x61\xac\x32\xb2\x84\xec\x54\x49\xb5\xc9\xbe\x9e\xfd\x38\xda\x29\x36\xeb\xfb\xda\xd5\x2b\xe2\x50\x66\x24\x01\x64\xfd\xcd\x42\x56\x6c\x5d\x36\x3c\x7d\x1a\x05\x93\xbc\xc8\x16\x19\x61\xe0\x08\xe0\x1b\x9a\x80\xdf\xe9\xb4\x2f\x75\xd9\xc3\x4d\xe2\xd7\x8d\xd0\x22\x5b\x9f\xb7\x4b\x05\x60\xa1\x2b\xca\x92\xac\x4a\xbb\x6a\xe0\x5c\xd7\x60\xad\x83\x16\xba\x6a\xda\xa9\xef\xa0\x69\xa9\x63\xd4\x34\xe2\xf5\x65\x51\xad\xb3\x62\x49\xb2\x00\xf2\x42\x42\xb8\x65\xc9\x67\xc2\x34\x18\x36\xd7\x20\xb6\xd8\xb2\xe4\x27\xc6\xda\x27\x1c\x5e\x14\x3b\x65\x6b\x0e\x42\x7c\x26\xca\xfa\xe8\xff\x37\xb4\x1e\x9f\x53\x51\xa8\x11\x2b\xf2\xbc\x60\x66\x6c\xc4\x89\xb1\x31\x9b\x26\xa0\x47\xc8\x72\x47\x3c\x0e\xf5\x28\x8d\xd0\xcb\x0b\xea\xd2\xae\x47\xcc\x31\xce\x7a\x9b\x02\x32\x48\x64\xc1\xa7\x35\xa0\xd3\x52\xad\x7a\xe2\xdc\xb2\x6c\x86\xee\xed\x6d\x40\xca\xd2\x79\xda\x5d\x13\x0e\x2d\x86\xf5\xf0\x6b\xcf\x87\x47\x5e\xd1\x73\x55\x48\xe8\x45\x7a\x88\x92\x13\x46\xd6\x90\xda\xcb\xad\x01\x6a\x14\xac\xae\xfa\xd1\x4c\x85\x35\xf9\xf7\x73\xd5\x0f\xd1\x3e\xea\x5f\xd5\xe3\x48\xf2\xea\x9a\x1f\xe7\x4c\x99\x90\x84\x25\xd0\x65\xdc\x16\xf5\x6e\x61\x7d\xef\x7d\xa6\x09\xa3\x3d\x92\xef\x32\xb2\x13\x46\x0f\x2b\x9a\xf5\x2b\x79\xc0\x41\x9c\x95\xb6\x84\xd1\xf0\x78\xe6\x3e\x41\xea\x64\x9b\x75\xc8\x95\x84\x93\x5c\x8c\xd0\x0b\xa2\x39\x59\xab\xb4\x22\x0e\x6b\x2a\x24\xdf\xfe\xf1\x4d\xe9\x7d\x21\xa8\x2c\xf8\xf6\x1b\x92\x64\xfd\x07\x7a\xfb\x86\x78\x51\xc8\x11\xfa\x82\xde\x06\x1c\x64\xc5\x99\x18\xa1\x55\xc1\x73\x22\xd5\x53\x45\x83\x20\x21\x39\x65\xeb\x53\x2f\x0a\x6d\xec\x29\xc3\x96\x3a\xd0\x7c\xad\x24\xc1\x31\x00\xcd\x57\xe5\x4b\x7f\xd6\x8b\xdd\xd7\x9a\xa0\xda\xb9\x52\x27\x9d\xdd\x97\xd7\xdd\x53\x41\x9f\x6d\x94\xc0\xe8\x9a\x01\xdf\x19\x5f\xef\xbd\xab\x38\xdb\x68\x4d\xd4\xfa\xca\x7b\xae\x28\x87\x14\x59\xb3\x4a\x48\xfd\xe0\xa2\xab\x6d\x1d\xe8\xde\xd2\xba\x3e\x50\xba\x88\xac\x0d\xe6\x49\x26\x92\xac\x0f\x18\xf7\xa7\xb9\x85\x2b\x1b\x40\x45\xb2\x77\x76\xef\xf3\xfa\xc8\xcd\x3e\xfc\x2a\x46\x4a\x32\xf7\xa9\x33\x21\x6b\x48\xbb\xd5\x17\xf6\x51\x61\xaf\xc1\x31\xdb\x98\x8a\x01\xdb\x8c\x06\x36\x32\xf3\x7b\x7b\x37\x73\x63\xec\xdf\x7b\xc1\xdc\x9f\x61\x3f\x1a\x20\xb4\x51\xb1\x8e\xd4\xe1\x66\x74\xad\xae\x79\x18\xcd\x03\x1c\x47\x0f\x0b\x7c\xbe\xf5\xed\xdd\x77\x1c\xf8\x38\xc2\x61\x1c\x3e\x84\x11\x9e\xc5\xbe\x3b\xc3\xe1\xc2\x1d\xb7\x40\xfa\xa2\x20\x4a\xf5\x5c\x69\x09\x62\x07\xf8\x07\xf6\x71\xe0\x4e\xe3\x68\x1a\xc6\x63\x1c\x44\xf1\x9f\xde\xb4\x05\x36\xdc\x10\x3e\xe4\x15\x1b\x0a\x48\x38\x48\x31\x34\xb7\x5c\x31\x94\x99\xb0\x13\xe0\x52\x2d\x9c\x84\xcb\xd3\xa8\xb7\xf8\xe1\x53\xa0\x4f\xb0\x6d\xae\x04\x78\x3e\x7e\x57\xe7\x85\x1a\x75\xf3\x2e\xb0\x0e\x42\x9b\xdd\x4d\x23\xef\xdf\x73\x1f\xc7\x01\x9e\xcd\x23\x1c\xff\x98\xce\xbf\xbb\xd3\xd8\x9d\x4c\x02\x1c\x86\xdd\x8c\x1d\x83\x7f\x4a\xc5\x0f\xdd\xab\x6e\x9a\xaa\x5b\xb4\xa7\x1e\x1d\x67\x93\x45\x1c\xe2\xe0\x1e\x07\xf1\xcd\x24\x8c\xb1\xef\x7e\x9f\xe2\x49\xab\xb2\x2b\x92\x09\xe8\x15\xd5\x5d\x78\xcd\xa1\x00\xbb\x93\x78\xee\x4f\x1f\x5a\x47\x24\xaf\xfa\x27\x82\x3b\x3f\xf2\x66\x9d\x46\x70\x27\x33\x2f\x0c\xbd\xb9\xdf\x40\x2d\xe6\x41\xbb\x01\xff\xfe\xdb\x6f\xbf\x7e\x02\x45\xf7\xc2\xc4\x0b\x2e\xa8\xda\x87\x4e\x3c\xff\x9f\x78\x1c\xcd\x83\x78\xec\x7b\x87\x29\x6a\x57\x81\x51\x07\x18\x59\x66\x90\x9e\x6c\xdc\xf7\xf0\x43\x6f\x82\xc7\x6e\x10\x8f\xe7\x7e\xe4\x7a\x3e\x0e\x62\x6f\xe6\xfe\xe8\xce\x48\xf7\xa6\xe8\x28\xf2\x55\x4a\x13\x89\x2c\x6a\xfe\x6a\x48\xa5\x44\x12\xd3\x17\x46\xf8\x2c\xa5\x55\x16\xfa\x72\x7d\x92\xe2\x8e\x8f\xe7\x7b\xd1\x4f\x23\xc3\xa8\x31\x3d\x83\xd0\xbb\x35\x71\x3f\x37\xff\x09\x39\x1c\xff\x09\xfe\xd3\xbd\x9b\x46\x61\x1c\xde\x7a\x8b\x78\x86\xc3\x9b\x78\x1c\x60\x37\xf2\xe6\xfe\xc7\x53\x57\x2b\xad\x70\xc4\x13\x2d\x67\x20\x1e\xf5\x8f\xbf\xde\xa3\xae\x3b\xe8\xf3\x09\xfe\x18\x57\x8b\x45\xef\x5d\xd8\xfa\x21\xdf\xb1\xfd\x6f\xc1\xe0\x63\x3d\x51\xeb\x8f\xfd\x6a\xac\xe3\xef\xd1\xf7\x28\x28\x09\x24\x25\x55\x0f\x51\xe0\x8e\x49\x7f\xf3\xc6\x3b\xa5\x22\x37\x51\xb4\x08\x2f\x96\x72\x52\x52\x5b\x68\x37\xf6\xfb\xaa\x7e\xd4\xd3\x05\xf2\x7e\xca\x51\xa3\xf4\x17\x67\x25\xc9\x28\x30\x39\x06\x2e\x45\x78\x56\x82\xdc\xbb\xe8\x26\x1e\x4f\x3d\xec\x47\x3a\x45\xe1\x99\x12\xd7\x62\x6e\x7c\x6a\xf2\x62\x78\x09\xed\xdd\x6d\xf2\x71\x49\xf7\x9d\x56\x5f\x59\xb7\x93\xcb\xcb\xfa\x94\x8a\xf3\xca\x7a\xd2\xdb\x05\xa5\x3d\xe5\xec\xc2\xd2\x3e\xa5\xc2\xfc\xf2\x1e\xeb\x2c\x9f\x97\xa3\x7a\x1a\x15\xeb\x60\x3e\x8f\x94\x92\x5d\xc0\xba\xae\x67\x5f\xcf\x4e\xfc\x37\x6a\xf0\xbf\x00\x00\x00\xff\xff\xb8\x26\xfd\x69\xc2\x15\x00\x00"),
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\xb4\x58\x5d\x6f\xa3\x38\x14\x7d\xcf\xaf\xb0\x50\x47\x6a\x67\x07\xf2\x30\xb3\xfb\x10\x69\x34\x62\x12\x4f\xcb\x36\x81\x08\x68\x57\xdd\x17\xe4\x80\x93\x5a\x05\x43\x6d\x93\x9d\x6c\xdb\xff\xbe\xb2\x0d\x09\x90\xd0\x26\xd5\xce\x9b\x8b\xaf\xcf\x3d\xf7\xeb\xd8\xcd\xd3\xd3\xf0\x23\x58\x93\x6c\x04\x38\x16\x60\x49\x52\x2c\x36\x05\xfe\x9a\x95\x5c\xa0\xf8\x1e\x8f\xc0\xc7\xe1\xcb\xcb\x40\x5a\x0d\xe0\xcf\x02\xd1\x04\x88\x7b\x0c\x28\xca\x30\xc8\x97\x6a\x1d\xdf\x23\x26\xac\x41\x65\x67\x82\x04\x2f\x09\xc5\xc0\x78\x28\x33\x64\x49\x43\x03\x98\xbb\x2d\x54\xa6\x02\x58\x63\x75\xc6\x95\x28\xd6\x2d\x4a\x4b\xcc\x95\xa5\xb7\xc6\x8c\x91\x04\x83\x67\x20\x58\x49\x63\xf0\xc7\x67\xb5\x24\x59\x50\x2e\x97\xe4\x27\x30\x4c\x03\x54\x58\x98\x26\x72\xa9\xa9\x8d\x19\x46\x02\x03\xb4\xf5\xb0\x2c\xd3\x74\x03\x1e\x4b\x94\x92\x25\xc1\x09\x40\x45\xa1\x48\x5b\x83\xbf\xb0\xc6\x56\xf6\x42\x7a\x90\x01\x70\xb0\xc0\x31\x2a\x39\x06\x3c\xcf\x30\xb8\x2e\x17\x98\x51\x2c\x30\xd7\xa1\x2e\x09\x4e\x13\x0e\x10\xc3\x20\x25\x19\x11\x38\x01\x22\x07\xe2\x9e\x70\x70\xbe\xd8\xa8\x34\x4c\xdc\x40\xda\x12\xba\x02\xbc\xc0\xf1\x85\x35\x70\x96\x80\xe1\x14\x23\x5e\xe5\x2b\xce\xa9\x40\x84\x72\x9d\x31\xfd\x8d\x08\xf0\x0f\x49\x53\xb0\xc0\xa0\xe4\x92\x27\x07\x48\x91\xaf\xd8\x1e\xce\xaa\x34\x68\x67\x96\x2c\xb7\x89\xac\x37\xb7\xc9\xac\x4c\x7a\xf7\x8f\x49\x76\xca\xb7\x38\x67\x8a\xf8\xe8\xeb\xf1\xd5\xdc\x71\xdc\xa6\x40\x83\x58\xbe\xce\x8f\x3e\x5b\xf3\x6c\x7d\x3c\x91\x5c\xc1\x08\x15\x4b\x60\x7c\xe0\xe6\x07\x6e\x74\xb0\xb4\xd3\xe3\x7b\xeb\xf0\xb2\xd5\x71\x8d\x52\xca\xd9\x58\x63\xc6\x49\x4e\x65\x19\x55\x39\xab\xde\xd0\x56\x29\x5a\xe0\xb4\xaf\xa4\xca\x64\x57\xcf\x6e\x1c\xcd\x14\xeb\xf5\x6d\xe5\xea\x19\x30\x5c\xa4\x28\xc6\xc0\xf8\xcd\x00\x46\x64\x9c\x36\x3c\x5d\x1a\x39\x15\x2c\x4f\xe7\x29\xa2\xd8\xe2\x98\xad\x49\x8c\xdd\x56\xa7\x9d\x55\x65\x0f\xd6\xb1\x5b\x35\x42\x83\x6c\x75\xde\x2c\x24\x80\x01\xce\x09\x8d\xd3\x32\x69\xab\x81\x75\x51\x81\x35\x0e\x1a\xe0\xbc\x6e\xa7\xae\x83\xba\xa5\x0e\x51\x53\x88\x17\xa7\x45\xb5\x4a\xf3\x05\x4a\x7d\x9c\xe5\x02\x07\x1b\x1a\xbf\x27\x4c\x8d\x61\x32\x05\x62\xf2\x0d\x8d\x7f\x61\xac\x5d\xc2\xc1\x49\xb1\x13\xba\x62\x98\xf3\xf7\x44\x59\x1d\xfd\x7f\x43\xeb\xf0\xe9\x8b\x42\x8e\x58\x9e\x65\x39\xd5\x63\xc3\x7b\xc6\x46\x6f\xea\x80\xee\x71\x9a\x59\xfc\x7e\xa8\x46\x69\x04\x9e\x9e\x40\x9b\x76\x35\x62\x96\x76\xd6\xd9\xe4\x38\xc5\xb1\xc8\xd9\xb4\x02\xb4\x1a\xaa\x55\x4d\x9c\x5d\x14\xf5\xd0\xbd\xbc\x0c\x50\x51\x58\x0f\xdb\x6b\xc2\x22\xf9\xb0\x1a\x7e\xe5\x79\xff\xc8\x33\x78\x2c\x73\x81\x3b\x91\xee\xa3\x64\x88\xa2\x15\x4e\xcc\xc5\x46\x03\xd5\x0a\x56\x55\xfd\x60\xa6\x82\x8a\xfc\xeb\xb9\xea\x86\x68\x1e\xf4\x2f\xeb\x71\x20\x79\x55\xcd\x0f\x73\x26\x94\x0b\x44\x63\xdc\x66\xdc\x14\xf5\x76\x61\x5d\xe7\x75\xa6\x31\x25\x1d\x92\xaf\x32\x32\x63\x4a\xf6\x2b\x9a\x76\x2b\xb9\xc7\x81\x1f\x95\xb6\x98\x92\xe0\x70\xe6\xde\x41\xaa\xb7\xcd\x5a\xe4\x0a\xc4\x50\xc6\x47\xe0\x09\x90\x0c\xad\x64\x5a\x01\xc3\x2b\xc2\x05\xdb\x7c\xfb\x24\xf5\x3e\xe7\x44\xe4\x6c\xf3\x09\x08\xb4\xfa\x06\x5e\x3e\x01\x96\xe7\x62\x04\xce\xc0\xcb\x80\x61\x51\x32\xca\x47\x60\x99\xb3\x0c\x09\xf9\x54\x51\x20\x80\x0b\x46\xe8\xaa\xef\x45\xa1\x8c\x1d\x69\xd8\x50\x07\x92\xad\xa4\x24\x58\x1a\xa0\xfe\x2a\x7d\xa9\xcf\x6a\xb1\xfd\x5a\x11\x94\x3b\xe7\xf2\xa4\xb5\xfd\xf2\xbc\x7d\x2a\xa8\xb3\xb5\x12\x68\x5d\xd3\xe0\x5b\xe3\x8b\x9d\x77\x19\x67\x13\xad\x8e\x5a\x5d\x79\x8f\x25\x61\x38\x01\xc6\xac\xe4\x42\x3d\xb8\xc8\x72\x53\x05\xba\xb3\x34\x2e\xf6\x94\x2e\x44\x2b\x8d\xd9\xcb\x44\xa0\xd5\x1e\xe3\xee\x34\x37\x70\x45\x0d\x28\x49\x76\xce\xee\x7c\x5e\x1c\xb8\xd9\x87\x1f\xf8\x48\x4a\xe6\x2e\x75\x3a\x64\x05\x69\x36\xfa\xc2\x3c\x28\xec\x15\x38\xa4\x6b\x5d\x31\x4c\xd7\xa3\x81\x09\xf4\xfc\x5e\xdf\xcc\xec\x08\xba\xb7\x8e\xef\xb9\x33\xe8\x86\x03\x00\xd6\x32\xd6\x91\x3c\x5c\x8f\xae\xd1\x36\x0f\x42\xcf\x87\x51\x78\x37\x87\xc7\x5b\x5f\xdf\x7c\x87\xbe\x0b\x43\x18\x44\xc1\x5d\x10\xc2\x59\xe4\xda\x33\x18\xcc\xed\x71\x03\xa4\x2b\x0a\xbc\x90\xcf\x95\x86\x20\xb6\x80\xfd\x1b\x37\x74\x66\x2d\xe8\xb1\xe7\x86\xbe\x37\x8d\xe6\x53\xdb\x85\x51\x00\xfd\x5b\x67\x0c\x95\xa7\x96\x93\x8e\xdc\xf7\x3e\x65\xac\x3d\x9f\x97\xd0\x85\xbe\x3d\x8d\xc2\x69\x10\x8d\xa1\x1f\x46\x3f\x9c\x69\x03\x7b\xb8\x46\x6c\xc8\x4a\x3a\xe4\x38\x66\x58\xf0\xa1\xbe\x59\xf3\xa1\x48\xb9\x19\x63\x26\xe4\xc2\x8a\x99\xe8\x47\xbd\x86\x77\xef\x02\x7d\xc0\x9b\xfa\x1a\xc2\x8f\x87\xdf\x07\x59\x2e\x63\xd6\x6f\x11\x63\x2f\xb4\xd9\xcd\x34\x74\xfe\xf6\x5c\x18\xf9\x70\xe6\x85\x30\xba\x9c\x7a\xdf\xed\x69\x64\x4f\x26\x3e\x0c\x82\x76\x95\x0e\xc1\x3f\x24\xfc\x52\xcd\x87\x9d\x24\xf2\xe6\xee\x28\x56\xcb\xd9\x64\xae\xaa\x03\xfd\xe8\x6a\x12\x44\xd0\xb5\xbf\x4f\xe1\xa4\xd1\x4d\x4b\x94\x72\xdc\x69\x24\x7b\xee\xd4\x87\x7c\x68\x4f\x22\xcf\x9d\xde\x35\x8e\x08\x56\x76\x4f\x1c\xe8\x10\x7b\x32\x73\x82\xc0\xf1\xdc\x1a\x6a\xee\xf9\xcd\xa6\xff\xfd\xcb\x97\xcf\xef\x40\x51\xbd\x30\x71\xfc\x13\xaa\xf6\xa6\x13\xc7\xfd\x13\x8e\x43\xcf\x8f\xc6\xae\xb3\x9f\xa2\x66\x15\x28\xb1\x30\x45\x8b\x14\x27\xa7\x0c\xcb\x16\x3f\x70\x26\x70\x6c\xfb\x6a\x7a\x6c\xc7\x85\x7e\xe4\xcc\xec\xcb\xd7\x46\xa6\x75\x0b\x9c\x27\x24\x16\xc0\x20\xfa\xaf\x9a\x54\x82\x04\xd2\x7d\xa1\xc5\xd6\x90\xfa\x68\x80\xb3\x8b\x5e\x8a\x5b\x3e\x8e\xeb\x84\xbf\x8c\x0c\x25\xda\xf4\x08\x42\xaf\xd6\xc4\x7e\xdf\xfc\xc7\x68\x7f\xfc\x27\xf0\x87\x7d\x33\x0d\x83\x28\xb8\x76\xe6\xd1\x0c\x06\x57\xd1\xd8\x87\x76\xe8\x78\xee\xdb\x53\x57\xa9\x3b\xb7\xf8\x03\x29\x66\x98\xdf\xab\x7f\x38\x3b\x0f\xc9\xf6\xa0\x7b\x13\xf8\x36\xae\x12\x8b\xce\x5b\xb4\xf1\xe3\x41\xcb\xf6\xdf\x9c\xe2\xb7\xf5\x44\xae\xdf\xf6\xab\xb0\x0e\xbf\x81\x5f\xa3\x20\x25\x10\x15\x44\x3e\x7e\x31\xb3\x74\xfa\xeb\x77\x65\x9f\x8a\x5c\x85\xe1\x3c\x38\x59\xca\x51\x41\x4c\xae\xdc\x98\xaf\xab\xfa\x41\x4f\x27\xc8\x7b\x9f\xa3\x5a\xe9\x4f\xce\x4a\x9c\x12\x4c\xc5\x18\x33\xc1\x83\xa3\x12\x64\xdf\x84\x57\xd1\x78\xea\x40\x37\x54\x29\x0a\x8e\x94\xb8\x06\x73\xed\x53\x91\xe7\xc3\x53\x68\x6f\x6f\x93\xb7\x4b\xba\xeb\xb4\xea\xca\xba\x9e\x9c\x5e\xd6\x87\x84\x1f\x57\xd6\x5e\x6f\x27\x94\xb6\xcf\xd9\x89\xa5\x7d\x48\xb8\xfe\x6f\x7f\xac\xb2\x7c\x5c\x8e\xaa\x69\x94\xac\x7d\xcf\x0b\xa5\x92\x9d\xc0\xba\xaa\x67\x57\xcf\x7a\x7e\x01\x1b\xfc\x17\x00\x00\xff\xff\x36\xe4\x5f\xf6\x36\x16\x00\x00"),
 		},
 		"/templates/cni-configmap.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "cni-configmap.yaml",
@@ -206,10 +206,10 @@ var HelmTemplates = func() http.FileSystem {
 		},
 		"/templates/cni-daemonset.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "cni-daemonset.yaml",
-			modTime:          time.Date(2020, 12, 23, 14, 58, 20, 392000000, time.UTC),
-			uncompressedSize: 2978,
+			modTime:          time.Date(2021, 1, 28, 16, 7, 7, 528000000, time.UTC),
+			uncompressedSize: 3001,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\x94\x56\x5d\x6f\xdb\xb8\x12\x7d\xf7\xaf\x18\xa8\x05\xda\x02\xb1\x8c\x5e\xdc\x16\x17\xba\x4f\xd9\x24\xed\x1a\x6d\xdc\x20\x1f\x5d\x2c\x16\x8b\x60\x4c\x8e\x2d\xc2\x14\x47\x4b\x8e\x9c\x7a\xd3\xfc\xf7\x05\xf5\x65\x29\x75\xbb\xa9\x1e\x82\x88\x9c\x39\x3c\x9a\x73\x66\xe8\xfb\xfb\x29\x98\x15\xa4\x9f\xd1\x56\x14\x52\xe5\x4c\x4a\x0e\x97\x96\x34\x3c\x3c\x4c\x36\xc6\xe9\x0c\x4e\x91\x0a\x76\x57\x24\x13\x2c\xcd\x67\xf2\xc1\xb0\xcb\x00\xcb\x32\xcc\xb6\xaf\x27\x05\x09\x6a\x14\xcc\x26\x00\x0e\x0b\xca\xe0\xfe\x1e\x8c\x53\xb6\xd2\x04\xc9\xa6\x2a\x30\x8d\xcb\x09\xa4\xf0\xf0\x30\x55\xce\x4c\x1d\x6b\x6a\x83\x43\x89\x8a\x32\xd8\x54\x4b\x9a\x86\x5d\x10\x2a\x26\x00\x16\x97\x64\x43\xc4\xab\xd9\x8d\xa0\x94\x33\x1f\xeb\xed\x88\xf7\x15\x9c\x71\x9a\x9c\xc0\x7f\x23\xdb\x50\x92\x8a\x59\x81\x2c\x29\x61\x1f\xff\x07\x28\x50\x54\xfe\xf1\xc7\x90\x57\x6d\xc6\x21\xe8\xb7\x11\x1a\xa0\x2a\x35\x0a\x5d\x89\x47\xa1\xf5\xae\x81\x96\x5d\x49\x19\x5c\xb2\xb5\xc6\xad\x6f\xea\x80\x7a\xdd\x0f\x57\x9a\xd0\xc8\xe3\xcb\x8d\xc3\x2d\x1a\x1b\xcb\x9b\xc1\xeb\x09\x80\x50\x51\xda\x3e\x66\x58\xc9\xf8\xec\xeb\x10\x9f\x9f\x26\xfe\xbf\x86\x78\x7c\xd0\x39\x16\x14\xc3\xae\x87\x03\x78\x06\xd7\xb9\x09\x47\x80\x96\xdd\x1a\xee\x8c\xe4\x20\x39\xc1\x89\x37\x62\x14\xda\x63\xad\xd9\x85\x4f\xce\xee\x40\xd8\x92\xaf\xd3\x61\x49\x96\xef\x8e\x06\x18\x05\xfa\x4d\xa8\x13\x4b\xd6\x80\x01\x10\x54\x8b\x00\xa8\xf5\x94\xdd\x11\x90\x0b\x95\x37\x6e\x0d\x46\x60\x4d\x12\x06\xe9\xa5\x37\xec\x8d\xec\x20\xa8\x9c\x74\x15\xcb\x06\xe8\x34\x48\x8e\x02\x46\x02\x78\x0a\x5c\x79\x45\x01\xd0\x53\x7c\x23\xbf\x25\x3d\x40\x30\xab\x08\x4b\x5b\xf2\x35\x36\xd0\xd6\x28\x21\x9d\xf6\x21\x2d\x32\xf9\x14\x6d\x99\x63\x1a\xcd\xe6\x1d\x09\x85\xd4\xf0\xac\x23\x3b\x2d\x59\x67\xf0\xe2\x45\x9f\xa6\x72\x52\x9b\x50\x15\x33\xc5\x6e\x65\xd6\x23\x5b\xbf\x2c\xbd\x71\x02\xcf\xd3\xeb\x56\xc0\xf4\x17\x0c\x74\x81\x92\x43\x32\x8b\x16\x6f\x72\x0a\x2c\xd3\x1d\x16\x36\x79\x55\x0b\x13\x72\xfc\xcf\x9b\xb7\xa1\x2a\x3a\x61\x3a\xc3\x76\xf2\xd6\x1a\x0c\x5b\x31\x76\x4a\x27\xf1\x5e\xcd\xe1\xea\x3e\x1d\x84\x7f\xc7\xc2\x7e\xcf\x02\x11\x9f\x9c\xde\x2f\xe4\x1c\x64\x41\x72\xc7\x7e\x93\x81\xf8\x8a\xda\xf5\xbd\xd8\x23\xaf\x9c\xe3\x86\x20\x54\x9e\x20\x7a\xaf\xef\xe3\xa6\xe6\x5d\x89\x35\xb0\x03\xb4\xb6\xa6\x18\xf6\x12\x4c\x81\x56\x2b\x52\x92\xc1\x82\xaf\xda\xd8\x7e\x13\x80\xcb\x78\x22\xfb\x0c\xce\xbe\x98\x30\xf2\xc7\x39\xfa\xcd\x0f\xdd\x05\x2b\xf6\xd1\x16\xbd\x7d\x86\xa7\x6e\x68\x97\x1d\x30\xf4\x53\x8e\x1e\x52\x3e\xfb\x42\xaa\x92\x27\x30\xee\xdc\x7c\x62\x31\x84\x45\x3d\x0c\x9b\xa9\x36\x55\xb6\x0a\x42\x7e\xda\xb1\x6f\x13\xa2\x9b\x8d\xa2\x63\xa5\xb8\x72\xd2\x64\x74\xf5\x9d\xf4\x35\x30\xce\x14\xe6\x6f\x02\xcd\x77\x4e\x4c\x41\xa0\x9b\x76\xc2\x6e\xd2\x40\x55\xae\x3d\x6a\x02\xf6\xa0\xc9\x52\x54\xef\xff\x20\x64\x2d\x7c\xe8\xdd\x0e\xc2\xa0\x19\x10\x92\x15\x7b\x45\x3d\x7c\x97\x90\x64\x90\x8b\x94\x21\x9b\xcd\xc6\x2d\xa2\x59\x85\xd8\x05\x8a\x4a\x09\xb3\x68\x18\xcb\xa8\xc3\xac\xe4\xe6\xcf\xec\x99\x90\x2f\x8c\xab\x4d\x33\xe5\x55\x6c\xa5\x5e\xfc\xc1\xd6\x7b\x8f\x8a\x2e\xc8\x1b\xd6\x57\xa4\xd8\xe9\x90\xc1\x9b\x36\x4c\xb1\x13\x34\x8e\xfc\xc0\x74\xd3\xf6\x3e\x31\x2e\x08\x5a\x3b\xa8\x49\x7c\x4c\x81\xeb\x43\x97\xcd\x8a\x7d\x81\x32\x8f\xbb\x09\xbc\xd4\x46\x09\x24\xa6\x79\x1b\xb6\x56\xbd\x04\x89\x67\x96\x04\x9e\xbf\x82\xaf\xf0\x57\xc5\x42\xfb\xfe\xe8\xcf\xb8\xa8\xac\xbd\x60\x6b\xd4\x2e\x83\x63\x7b\x87\xbb\x30\x88\x50\x5c\x14\x18\x2f\xc9\x3f\x92\xd9\x80\x67\x1a\xf2\xe4\xcf\x41\x18\xb9\x6d\x36\x78\x8d\x65\x8f\x62\x03\xaf\x9a\x99\xbb\x98\x43\x33\x32\x60\x65\x2c\x45\xa5\x94\xa7\x38\x57\x46\x49\x5d\x41\x4e\x16\xf3\xdb\x93\x4f\x8b\x77\xb7\x8b\xe3\xf3\xb3\x51\x04\xc0\x36\x7e\x62\x06\xc9\xfd\xfd\xe8\x73\x23\x7a\x7d\xe2\xc3\x43\xf2\x88\xc8\x75\x4b\xc0\x35\xc3\xa0\x23\x22\xdc\x15\x3e\x36\x35\xa1\xca\xeb\xae\xfe\x3e\xa3\xc5\xd9\xf5\x6f\x9f\x2e\x3f\xd4\xcc\xe6\xef\x0f\xd1\x7a\xe7\xb9\xc8\x1e\x6d\x40\x7b\xde\x39\x96\x1f\x68\x77\x49\xab\x6f\x03\x9e\xfa\xbb\xa2\x01\x3a\x90\x5e\x8f\x01\xe5\xcc\x6d\xfb\x89\xb7\x07\x22\x1f\x7d\xc9\xed\xe9\xfc\xf2\x69\x95\x75\x24\xa7\xc6\x1f\xa8\xeb\x7c\x55\x8f\xd5\x23\xd0\x54\x5a\xde\xb5\xd3\x2b\x8f\x2e\xd7\x75\xc1\x4b\x5b\xad\x8d\x3b\x02\x96\x9c\xfc\x9d\x09\x34\x8a\x0c\x82\x4e\xc7\xbb\xb9\x56\xe7\x30\xd7\x5f\x8f\xe7\x8b\xb3\xd3\xdb\xc8\xf9\xe2\xe3\xcd\xfb\xf9\xe2\x89\x66\x68\x49\x8c\x39\x6f\xd9\x56\x05\x9d\xc7\x41\x14\xb2\x47\xe7\x15\x71\x35\xde\x6f\x19\xcc\xe2\xc5\x31\xe3\x52\xe2\x45\x37\x5b\x1a\x37\x39\xa4\x55\xd4\x63\x69\xdc\x54\x1b\xff\x6f\x50\x24\xaa\x86\x72\x24\xa9\xfe\x2e\x98\x23\x19\x80\x35\x5c\x47\x17\xd4\x4d\x20\x3d\x34\xed\xc9\x62\x9e\x7e\x33\x4a\x0e\xd3\x8a\x34\x6a\x46\xa3\xd3\xcb\x9a\xe3\xa3\xd2\x2d\x8d\x6b\xd4\x3e\x08\x3d\x26\xf9\x93\xd0\xbd\x91\x26\xa3\xdb\xfa\x9f\x00\x00\x00\xff\xff\xb9\xf0\xa1\xb9\xa2\x0b\x00\x00"),
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\x94\x56\x5d\x6f\xdb\xb8\x12\x7d\xf7\xaf\x18\xa8\x05\xda\x02\xb1\x8c\x5e\xdc\x16\x17\xba\x4f\xd9\x24\xed\x1a\x6d\xdc\x20\x1f\x5d\x2c\x16\x8b\x60\x4c\x8e\x2d\xc2\x14\x47\x4b\x8e\x9c\x7a\xd3\xfc\xf7\x05\xf5\x65\x29\x75\xbb\xa9\x1e\x82\x88\x9c\x39\x3c\x3a\x73\x66\xe8\xfb\xfb\x29\x98\x15\xa4\x9f\xd1\x56\x14\x52\xe5\x4c\x4a\x0e\x97\x96\x34\x3c\x3c\x4c\x36\xc6\xe9\x0c\x4e\x91\x0a\x76\x57\x24\x13\x2c\xcd\x67\xf2\xc1\xb0\xcb\x00\xcb\x32\xcc\xb6\xaf\x27\x05\x09\x6a\x14\xcc\x26\x00\x0e\x0b\xca\xe0\xfe\x1e\x8c\x53\xb6\xd2\x04\xc9\xa6\x2a\x30\x8d\xcb\x09\xa4\xf0\xf0\x30\x55\xce\x4c\x1d\x6b\x6a\x83\x43\x89\x8a\x32\xd8\x54\x4b\x9a\x86\x5d\x10\x2a\x26\x00\x16\x97\x64\x43\xc4\xab\xd9\x8d\xa0\x94\x33\x1f\xeb\xed\x88\xf7\x15\x9c\x71\x9a\x9c\xc0\x7f\x23\xdb\x50\x92\x8a\x59\x81\x2c\x29\x61\x1f\xff\x07\x28\x50\x54\xfe\xf1\xc7\x90\x57\x6d\xc6\x21\xe8\xb7\x11\x1a\xa0\x2a\x35\x0a\x5d\x89\x47\xa1\xf5\xae\x81\x96\x5d\x49\x19\x5c\xb2\xb5\xc6\xad\x6f\xea\x80\x7a\xdd\x0f\x57\x9a\xd0\xc8\xe3\xcb\x8d\xc3\x2d\x1a\x1b\xe5\xcd\xe0\xf5\x04\x40\xa8\x28\x6d\x1f\x33\x54\x32\x3e\x7b\x1d\xe2\xf3\xd3\xc4\xff\xd7\x10\x8f\x0f\x3a\xc7\x82\x62\xd8\xf5\x70\x00\xcf\xe0\x3a\x37\xe1\x08\xd0\xb2\x5b\xc3\x9d\x91\x1c\x24\x27\x38\xf1\x46\x8c\x42\x7b\xac\x35\xbb\xf0\xc9\xd9\x1d\x08\x5b\xf2\x75\x3a\x2c\xc9\xf2\xdd\xd1\x00\xa3\x40\xbf\x09\x75\x62\xc9\x1a\x30\x00\x82\x6a\x11\x00\xb5\x9e\xb2\x3b\x02\x72\xa1\xf2\xc6\xad\xc1\x08\xac\x49\xc2\x20\xbd\xf4\x86\xbd\x91\x1d\x04\x95\x93\xae\xa2\x6c\x80\x4e\x83\xe4\x28\x60\x24\x80\xa7\xc0\x95\x57\x14\x00\x3d\xc5\x37\xf2\x5b\xd2\x03\x04\xb3\x8a\xb0\xb4\x25\x5f\x63\x03\x6d\x8d\x12\xd2\x69\x1f\xd2\x22\x93\x4f\xd1\x96\x39\xa6\xd1\x6c\xde\x91\x50\x48\x0d\xcf\x3a\xb2\xd3\x92\x75\x06\x2f\x5e\xf4\x69\x2a\x27\xb5\x09\x55\x31\x53\xec\x56\x66\x3d\xb2\xf5\xcb\xd2\x1b\x27\xf0\x3c\xbd\x6e\x0b\x98\xfe\x82\x81\x2e\x50\x72\x48\x66\xd1\xe2\x4d\x4e\x81\x65\xba\xc3\xc2\x26\xaf\xea\xc2\x84\x1c\xff\xf3\xe6\x6d\xa8\x8a\xae\x30\x9d\x61\xbb\xf2\xd6\x35\x18\xb6\x62\xec\x94\xae\xc4\xfb\x6a\x0e\x57\xf7\xe9\x20\xfc\x3b\x16\xf6\x7b\x16\x88\xf8\xe4\xf4\x7e\x21\xe7\x20\x0b\x92\x3b\xf6\x9b\x0c\xc4\x57\xd4\xae\xef\x8b\x3d\xf2\xca\x39\x6e\x08\x42\xe5\x09\xa2\xf7\xfa\x3e\x6e\x34\xef\x24\xd6\xc0\x0e\xd0\xda\x9a\x62\xd8\x97\x60\x0a\xb4\x5a\x91\x92\x0c\x16\x7c\xd5\xc6\xf6\x9b\x00\x5c\xc6\x13\xd9\x67\x70\xf6\xc5\x84\x91\x3f\xce\xd1\x6f\x7e\xe8\x2e\x58\xb1\x8f\xb6\xe8\xed\x33\x3c\x75\x43\xbb\xec\x80\xa1\x9f\x72\xf4\x90\xf2\xd9\x17\x52\x95\x3c\x81\x71\xe7\xe6\x13\x8b\x21\x2c\xea\x61\xd8\x4c\xb5\xa9\xb2\x55\x10\xf2\xd3\x8e\x7d\x9b\x10\xdd\x6c\x14\x1d\x2b\xc5\x95\x93\xc5\x53\xc6\xe7\xa4\x97\xc6\x38\x53\x98\xbf\x09\x34\xdf\x39\x31\x05\x81\x6e\xba\x0c\xbb\x01\x04\x55\xb9\xf6\xa8\x09\xd8\x83\x26\x4b\xb1\xa8\xff\x07\x21\x6b\xe1\x43\xdf\x04\x20\x0c\x9a\x01\x21\x59\xb1\x57\xd4\xc3\x77\x09\x49\x06\xb9\x48\x19\xb2\xd9\x6c\xdc\x39\x9a\x55\x88\xcd\xa1\xa8\x94\x30\x8b\x3e\xb2\x8c\x3a\xcc\x4a\x6e\xfe\xcc\x9e\x09\xf9\xc2\xb8\xda\x4b\x53\x5e\xc5\x0e\xeb\x3d\x31\xd8\x7a\xef\x51\xd1\x05\x79\xc3\xfa\x8a\x14\x3b\x1d\x32\x78\xd3\x86\x29\x76\x82\xc6\x91\x1f\x78\x71\xda\x5e\x33\xc6\x05\x41\x6b\x07\x9a\xc4\xc7\x14\xb8\x3e\x24\xe2\x8a\x7d\x81\x32\x8f\xbb\x09\xbc\xd4\x46\x09\x24\xa6\x79\x1b\x76\x5c\xbd\x04\x89\x67\x96\x04\x9e\xbf\x82\xaf\xf0\x57\xc5\x42\xfb\xb6\xe9\xcf\xb8\xa8\xac\xbd\x60\x6b\xd4\x2e\x83\x63\x7b\x87\xbb\x30\x88\x50\x5c\x14\x18\xef\xce\x3f\x92\xd9\x80\x67\x1a\xf2\xe4\xcf\x41\x18\xb9\x6d\x36\x78\x8d\xb2\x47\x0f\x00\xaf\x9a\x51\xbc\x98\x43\x33\x49\x60\x65\x2c\xc5\x4a\x29\x4f\x71\xdc\x8c\x92\x3a\x41\x4e\x16\xf3\xdb\x93\x4f\x8b\x77\xb7\x8b\xe3\xf3\xb3\x51\x04\xc0\x36\x7e\x62\x06\xc9\xfd\xfd\xe8\x73\x23\x7a\x7d\xe2\xc3\x43\xf2\x88\xc8\x75\x4b\xc0\x35\x33\xa2\x23\x22\xdc\x09\x1f\x7b\x9d\x50\xe5\x75\xb3\x7f\x9f\xd1\xe2\xec\xfa\xb7\x4f\x97\x1f\x6a\x66\xf3\xf7\x87\x68\xbd\xf3\x5c\x64\x8f\x36\xa0\x3d\xef\x1c\xcb\x0f\xb4\xbb\xa4\xd5\xb7\x01\x4f\xfd\xb9\xd1\x00\x1d\x48\xaf\xa7\x83\x72\xe6\xb6\xfd\xc4\xdb\x03\x91\x8f\xbe\xe4\xf6\x74\x7e\xf9\x34\x65\x1d\xc9\xa9\xf1\x07\x74\x9d\xaf\xea\x69\x7b\x04\x9a\x4a\xcb\xbb\x76\xa8\xe5\xd1\xe5\xba\x16\xbc\xb4\xd5\xda\xb8\x23\x60\xc9\xc9\xdf\x99\x40\xa3\xc8\x20\xe8\x74\xbc\xb2\xeb\xea\x1c\xe6\xfa\xeb\xf1\x7c\x71\x76\x7a\x1b\x39\x5f\x7c\xbc\x79\x3f\x5f\x3c\xd1\x0c\x2d\x89\x31\xe7\x2d\xdb\xaa\xa0\xf3\x38\x9f\x42\xf6\xe8\xbc\x22\xae\xc6\x6b\x2f\x83\x59\xbc\x4f\x66\x5c\x4a\xbc\xff\x66\x4b\xe3\x26\x87\x6a\x15\xeb\xb1\x34\x6e\xaa\x8d\xff\x37\x28\x12\x55\x43\x39\x92\x54\x7f\x17\xcc\x91\x0c\xc0\x1a\xae\xa3\x7b\xeb\x26\x90\x1e\x9a\xf6\x64\x31\x4f\xbf\x19\x25\x87\x69\x45\x1a\x35\xa3\xd1\xe9\x65\xcd\xf1\x91\x74\x4b\xe3\x9a\x6a\x1f\x84\x1e\x93\xfc\x49\xe8\xde\x48\x93\xd1\x25\xfe\x4f\x00\x00\x00\xff\xff\x50\x80\x02\xaf\xb9\x0b\x00\x00"),
 		},
 		"/templates/cni-rbac.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "cni-rbac.yaml",
@@ -262,7 +262,7 @@ var HelmTemplates = func() http.FileSystem {
 		},
 		"/templates/cp-webhooks-and-secrets.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "cp-webhooks-and-secrets.yaml",
-			modTime:          time.Date(2021, 1, 22, 14, 32, 11, 152000000, time.UTC),
+			modTime:          time.Date(2021, 1, 27, 13, 9, 49, 688000000, time.UTC),
 			uncompressedSize: 6045,
 
 			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\xe4\x58\x5b\x6f\xdb\xb8\x12\x7e\xd7\xaf\x18\x08\x2d\xd0\x16\x10\x15\x27\x71\x90\x23\x20\x0f\x3d\x6d\xda\x73\x70\xd2\xa2\x68\x73\xda\x67\x8a\x1a\x49\x5c\x53\xa4\x96\xa4\xec\x7a\xd3\xfc\xf7\x05\xa9\x8b\x25\xdb\xb9\x6c\x5b\x6c\xb3\xad\xdf\x3c\x57\xce\x37\xdf\x0c\x09\x5d\x5d\x45\xf0\x88\xd1\x7f\x37\x32\x13\x08\xc9\x19\x90\x8f\x54\x34\x68\x08\x53\xd2\x6a\x25\xde\x09\x2a\x91\x58\x61\x48\x81\x12\x35\x15\x64\x30\xbe\xbe\x0e\xae\xae\xe2\x67\xc1\x6b\xaf\xb0\x08\x0c\xb5\xe5\x39\x67\xd4\xa2\x09\x0c\x62\x02\xa5\xb5\xb5\x49\xe2\xb8\xa2\xc6\xa2\xae\xb8\xcc\x0c\x29\xb8\x2d\x9b\x94\x70\x15\x9b\x5a\xf3\x22\x66\x7a\x5d\x5b\x45\x4a\x5b\x89\x2d\x27\xcc\x78\x53\x11\xa6\xaa\x58\x36\x4b\x15\x15\x5a\x35\x75\x64\x91\x95\x71\xa5\x96\x18\xad\x55\xa3\x23\x97\xd3\x44\x56\x45\x25\x8a\x2a\x3a\xce\xe7\xf9\xc9\xec\xe8\xe8\x94\x32\x3a\x0d\xd6\x65\xf5\xc1\xd0\xae\x94\x5e\x18\xd4\x4b\xce\xb0\x42\x53\xee\x13\xa5\x42\xa5\xf1\xe9\xc1\x31\xcd\xe6\x07\x87\x27\x69\x3a\xcf\xd2\xec\xf0\x74\xce\x0e\x0f\x0f\xf2\xd9\xfc\xe8\x5f\xf3\x1c\x0f\xe7\x78\x7c\x92\xcf\x31\x4b\xe3\x0c\x6b\xa1\xd6\x15\x4a\x6b\x62\x77\x92\x58\x9a\x2a\x66\x25\xd5\xd6\xc4\x34\xab\xb8\x31\x5c\xc9\x68\x85\x69\xa9\xd4\x22\xb6\x58\xd5\xc2\xa1\xb4\xab\x8b\x0c\x32\x8d\x96\xd8\x5a\x04\xc1\x27\x04\x25\xc5\x1a\x68\x63\x55\x31\x46\xd9\x00\xcf\xa1\x31\xa8\x21\xe3\x19\x48\x65\x81\x95\xca\x20\xd8\x12\xb9\x06\xb5\x92\xd0\x85\xb9\x23\x84\x2d\xdb\x3f\xc0\x8d\x8f\xb2\x46\x0b\xbd\x55\x46\xe0\xb2\xe4\x06\x56\x74\x0d\x2b\x84\x05\x62\xed\xed\xdb\xc8\x06\x52\xb4\x2b\x44\x09\xff\x39\xbf\x78\x03\x4d\x5d\x68\x9a\xa1\x21\xc1\xb3\xf8\xfa\x3a\x08\x1c\xad\x78\x0e\xf8\xfb\xdd\x7c\x6a\xe3\xbd\xa5\x15\x42\x18\x42\xe4\x59\xe5\x38\xe9\x8e\x95\x9c\x39\x59\x2f\x5a\xe0\x7a\x4b\x32\xf2\x4d\xce\xa0\xd6\x5c\x5a\x78\xc2\x25\x13\x4d\x86\x10\x2e\x9a\x8a\x12\x49\x2b\x0c\x81\x3c\x85\x30\xb2\xc2\x78\xbe\x78\xff\x71\x00\xe7\xfc\x44\x28\xb5\x68\x6a\x08\x97\xb3\x10\xc2\x0f\x5e\x1e\x02\x79\x8f\x02\xa9\x41\xe2\x72\x98\x9a\x32\x1c\x27\x7d\x3a\x1c\x97\xe7\x43\x2c\x27\x02\xd8\xd4\x70\x06\x5c\x66\xf8\xb9\xd7\x93\x8c\x5a\x0a\xa1\x43\x80\xb9\xa3\x8c\xcc\x5d\x7d\x37\x5b\x2f\x70\x3d\xb1\x1e\xe6\x70\xbf\x0b\xa3\x9b\xf8\xce\x1e\x85\xc1\x89\xbb\xaa\x2a\x25\x7b\xe8\xb6\x40\x9b\x34\xab\x9b\x8a\xb7\x3d\x90\xa3\x20\x54\x78\x1c\x8c\x0b\x21\xb8\xb1\xf0\xc4\xf7\x20\x87\xf0\xb1\x21\x8f\x4d\x38\x49\xb3\x8b\xe5\xd3\x2d\x7b\x62\x96\xec\x6e\x9f\x2d\x80\x2f\x2f\x2f\x5c\xfa\xa3\x93\xf9\xc1\x14\x1e\x27\x2d\x50\xbe\x78\xde\x16\x15\x31\x1a\x6e\x3c\x9c\x65\x6f\xea\x8c\x3a\xb6\x15\x28\x3f\xf0\x42\x62\xe6\x05\xe3\x93\x48\x2e\x46\xf5\x0e\x71\x5c\x9e\xdd\x8e\xf7\x21\x89\x0f\xf3\x05\xd2\x93\x63\x94\x6c\xb7\xd7\x83\xdd\xff\x70\xbd\x6b\x36\xe9\xf1\x23\x46\xb7\xa2\xf5\x8d\x95\x99\xf7\x88\xa2\x28\xa0\x35\xff\x88\xda\xed\x93\x04\x96\xb3\x60\xc1\x65\x96\x40\xcb\xe5\xc0\xae\x6b\x4c\x60\xd1\xa4\xa8\x25\x5a\x34\x6e\x03\x5b\x61\x82\x0a\x2d\x75\x94\x49\x02\x00\x37\x2c\x89\xcf\x3c\x9a\x2c\x7f\x1a\xd9\xe3\xef\xd5\x7b\xc6\xc2\x5b\x09\x9a\xa2\x30\x49\x57\xe4\x94\x53\xad\x2e\x04\x02\x5f\x40\x3a\xc6\x4a\x0b\xc7\xce\xad\x4f\xde\x8d\x44\x9b\xdf\x03\xe9\x63\x76\xdc\x6f\xc5\x0e\x36\x2f\x6d\xe9\x9d\x4c\x51\x1a\x21\xb2\x07\x90\x61\xd7\x6a\x2c\xb8\xb1\x9a\x5a\xae\x24\x59\x9c\x7a\x24\x96\xb3\x14\x2d\xed\x21\x7b\xd3\x58\x6a\xb9\x2c\x3e\xb5\x4b\xf9\x85\x92\x39\x2f\x9a\xd6\x63\x3f\x60\x7b\x97\x0e\x5c\x5f\x47\x9b\x0d\x5f\x75\x41\x87\x55\xcf\x26\x61\xbf\x06\xe3\xfb\x42\xdc\x65\xf4\x5e\x51\x77\x68\x77\xcb\x91\x0c\x73\xda\x08\x8b\x9a\xf8\x11\x19\x0e\xeb\xff\x12\xae\x02\x00\x80\x9c\x72\xd1\x68\x7c\xa7\x04\x67\xeb\x04\x5e\x51\x2e\xbc\x9c\x09\x8e\xd2\xb6\xe0\x24\x5e\xe2\xfa\xd2\xf6\x62\xb7\x33\xad\xbe\x5b\x26\xbd\xf9\x7d\x8b\xde\xd8\xee\x41\xfb\x96\x6d\x35\xf6\xae\xa9\x2d\x13\x88\xbb\x92\x23\x5f\x30\x57\xd1\x72\x46\x45\x5d\xd2\x59\xe4\x00\xf1\xc6\xba\x11\x68\xfa\x13\x46\x40\x6b\xfe\xda\x3d\x3d\xcc\xe6\xd0\x4e\x3c\x46\xc8\xfd\x36\x54\xdb\x32\xec\x13\x0c\x42\x55\x63\xdb\xf3\x2d\xc3\x17\xef\xcf\x9f\x5f\x9e\x4f\x44\xff\x7f\xf7\x72\x2c\xd2\x68\x54\xa3\x19\x6e\x39\xba\x93\xa3\xf1\x22\xc3\x33\x3c\xcf\x73\x64\xd6\x24\xf0\x56\x49\x1c\x75\x5c\xad\x24\xea\x48\x63\x8e\x1a\x25\xc3\x5f\xa7\xe5\x5b\x85\xef\xb4\xfe\x21\x75\xfd\x86\x16\x33\xae\x59\xc3\x6d\xaa\x91\x2e\x50\x9b\x89\x0e\x3f\x5b\xd4\x92\x8a\x0e\x87\xa9\xd2\x93\x9d\xcb\xdf\x90\xf9\xdc\x13\x5d\x89\x54\xd8\x92\x95\xc8\x16\x53\x85\x46\xab\xf9\x56\xa0\x5a\xab\xcf\xeb\xe1\xe5\x3a\x51\x59\x4d\xf3\x9c\x33\xa1\x8a\xbd\xf2\xda\x3d\xfd\x3d\xc7\xf6\xaa\xb5\x6a\x6e\x08\x68\x35\xed\xcb\x71\x44\xd9\xf7\x92\xec\x37\x1b\x59\x52\xc1\x33\x6a\x95\x26\x34\xcb\xb8\xab\x95\x8a\xf7\xae\xa5\xa3\x5d\x78\xd2\x73\xe3\xb6\x29\x69\xc9\xe1\x01\x53\xfa\xb6\xa1\xb8\xe9\x48\xbd\xef\xab\xb1\x79\x9f\xf9\x9f\x39\x40\x6d\x49\x91\x83\x8d\x51\xfd\x17\xc6\x25\x0c\xef\x33\x29\xdf\x69\x46\x6a\x95\xdd\xb4\x04\xbf\xe1\x2d\xf0\xb1\x25\xd6\xf7\x79\x0d\x2c\x87\x60\x0f\xe4\x15\xb0\x19\x9b\x5f\xe6\x36\xe8\x4a\x7e\xd8\xd7\xc0\x9e\xcb\xdf\x89\x5e\x9e\x5f\x9c\x7f\xdb\x65\xe1\xb8\x5a\x3b\xa0\x7e\xc4\x1d\x32\x7a\xa8\x3c\x8c\x6b\xa5\xd7\xfc\xa1\xe4\xdf\x7e\xd1\x74\x50\x93\xaf\x19\xc1\xff\x16\x52\x69\xfc\x19\x86\x70\x39\x8b\x3a\xe3\x1f\x7e\xad\xdc\xff\xc1\x3d\x99\x92\xdb\x7b\xec\x3f\xc9\xdc\xab\xc5\x43\x0f\x3e\xa0\xf0\x0f\x88\x3e\x67\x45\x2d\x2b\x2f\x86\x85\xdf\xfe\x3a\xcf\xd8\xac\x8d\xc5\x2a\x1a\x35\x30\xb4\xba\xc1\xf0\x27\x60\xcd\x9d\xb4\xf1\xdf\x35\x1e\x20\x6b\xee\xbf\xa9\xbb\x8f\xa9\x37\xf0\xe8\xcf\x00\x00\x00\xff\xff\xab\x32\x4a\x63\x9d\x17\x00\x00"),
@@ -304,7 +304,7 @@ var HelmTemplates = func() http.FileSystem {
 		},
 		"/values.yaml": &vfsgen۰CompressedFileInfo{
 			name:             "values.yaml",
-			modTime:          time.Date(2021, 1, 22, 14, 35, 54, 856000000, time.UTC),
+			modTime:          time.Date(2021, 1, 27, 13, 9, 49, 692000000, time.UTC),
 			uncompressedSize: 5534,
 
 			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x02\xff\xb4\x58\x5f\x93\xdb\x36\x0e\x7f\xd7\xa7\xc0\xb8\x0f\x4d\x66\xd6\xf6\x26\xd7\x64\x3a\x7a\xba\xcd\x6e\x7b\xf5\xe4\x4f\x3d\xeb\x4d\xef\xe1\xe6\x66\x96\x22\x61\x99\x67\x0a\xd4\x91\x94\x37\x6e\xa7\xdf\xfd\x06\x24\x25\xcb\x8e\xb3\x49\x6e\xd2\x37\x89\x02\x7e\x00\x49\xe0\x07\x40\xb5\xb1\x95\x30\x65\x01\xa0\x1b\x51\x23\x3f\x00\x7c\x07\xd3\x29\xdc\xe0\x5a\x74\x26\x80\xc3\x5a\xfb\xe0\xf6\xb0\xb6\x0e\x84\x31\xf0\xba\x6b\x04\x2c\x58\xda\x47\xe9\x5e\xa0\x84\xc9\xd6\x52\x3d\x55\x56\x6e\xd1\x4d\xb7\x5d\x23\xf2\xf3\xac\xd2\x14\x9c\xd8\xcf\xb4\x9d\x1c\x0c\xdc\x6d\x10\x54\x36\x12\x44\x7d\x8c\x1f\xbd\xf1\x17\xf0\xb0\xd1\x72\x03\x3a\x78\x34\xeb\x5e\xda\x43\xb0\x30\xbb\xde\x08\x17\x66\x57\x6d\xfb\x1b\x3a\xaf\x2d\x45\xe0\x20\xea\xb2\x28\x22\xfc\x3f\x37\x18\x36\xe8\xc0\x3a\x20\x1b\x58\xa5\x15\x41\x6e\x20\x6c\x10\x82\x70\x35\x06\x20\xd1\xa0\x6f\x85\x44\x78\xd0\x21\x7d\xf1\x7b\x1f\xb0\x01\x23\x2a\x34\x45\x54\x58\xc5\x95\x77\xbd\x68\x09\xc1\x75\x58\x14\xd2\x52\x70\xd6\x2c\x8d\xa0\x78\x6a\xd1\x66\x74\xfd\x7a\x09\xc6\xd6\x60\x70\x87\xa6\x04\x4b\x08\x76\x0d\x76\xbd\xbe\xd0\xb4\xb6\x17\x0a\xab\xae\x2e\x80\x45\xde\x24\x89\x09\xaf\x4f\x8a\x53\x8c\xc6\x2a\xf4\x83\xbe\x0f\x82\x94\x30\x96\xf0\xc2\x61\x63\x03\x5e\xa4\x9b\x2b\x20\x0a\x96\x30\x39\x48\x1c\xb0\x9e\xf8\xe0\x34\xd5\x4f\x07\xd0\xdf\x19\x00\xf4\x1a\x5c\x47\xa4\xa9\x86\xa6\x33\x41\xf3\x6a\x01\xf1\x63\x39\xe8\xfe\x4a\x66\x0f\x9d\x47\x05\x9a\xe0\x3e\x19\xbd\x8f\xc6\x0a\x80\xad\xf2\xff\x88\xf6\xaf\x94\x72\xe8\x7d\x09\x93\x83\xd5\x77\x5d\x53\xf1\xc1\xaf\xc1\x61\x6b\xb4\x14\x9e\x9f\xf9\x74\xb3\x1b\x33\x58\xd4\x64\x1d\x2a\x78\xd8\x20\x81\xe8\x82\xf5\x52\x18\xf6\x47\x7b\x40\x12\x95\x41\x55\xc0\xa0\x5e\xc2\xb3\x04\xfe\x8b\x75\xec\x6c\x10\x06\x96\x56\xc1\xd5\x48\x51\x5a\x5a\xeb\xba\x73\x22\xa4\x58\x18\x81\x8e\x82\xba\x0f\x8a\x60\xb3\x99\x47\x20\xfb\xe0\x73\xf8\xdf\x4e\x3b\xf4\x71\x07\xff\x7a\x8b\xc1\x69\xe9\x61\x85\x6e\x87\xee\xdf\x4f\x36\x21\xb4\xbe\x9c\xcf\x6b\x1d\x36\x5d\x35\x93\xb6\x99\x6f\xbb\x0a\x1d\x61\x40\x3f\xf5\xba\xf6\xf3\x26\xa9\x4c\x7d\x54\x79\xca\xe7\xc9\x50\xd2\x74\x3e\xa0\x8b\xce\xe5\x3d\x97\xb0\x16\xc6\x63\x71\x9c\x24\x8d\x26\xdd\x74\x0d\xdf\x5f\x6b\x55\x8c\x7e\x61\x8c\x7d\x88\x52\x8d\xa6\xdb\xe1\x98\x9e\x9f\x28\x8a\x0f\x63\x25\xde\x17\x42\xb0\x49\x4f\x7c\x38\xe8\xbd\x18\x59\xfc\xd9\xba\xde\x35\xde\xb2\x08\xa0\x2c\x7d\x1f\xc0\x77\x6d\x6b\x5d\x18\x1f\xec\x7c\xf7\xbc\xc2\x20\x2e\x8e\xd7\x9e\xf1\x25\x72\xe0\xe4\x8c\xe4\x54\xbb\x5e\xbe\x7f\x1f\xb4\xd1\xbf\xc7\xeb\x59\xa2\x93\x48\x81\xf9\x06\x7e\xbc\x7c\xdc\xf4\xa3\x76\x3b\x8f\x90\x4f\x37\x6d\x2a\x3d\xa7\x0b\x07\x98\x42\xd8\xb7\x58\xc2\x2d\x7a\xdb\x39\x89\x79\x99\x03\x2b\x2d\x94\xc3\x0a\x44\x32\x28\x41\xb6\xdd\x68\x2d\x39\x3f\x96\x82\x0c\x39\xda\xcd\xd1\x57\xb1\x43\x27\x6a\x1c\x7d\x8e\x5b\x1c\x52\xc3\x2a\x04\x8f\x06\x65\xb0\x2e\x32\xde\x21\x2d\x12\xa1\x40\x64\x94\x78\x67\x05\x00\x59\x85\xab\x2c\x9e\xdc\x38\x04\xd7\x4c\xdb\xb9\xf5\x25\x18\x4d\xdd\x87\x33\xdf\x84\x93\x9b\x12\x44\xa3\x5e\xfe\x30\xd8\xff\x59\x68\xd3\x39\x86\x37\x5a\xee\xfb\xb4\x6c\xba\x20\x02\x27\xd1\x03\x56\x1b\x6b\xb7\xa0\x9b\xd6\x60\x83\x14\x50\x41\xb5\x3f\xf8\xb8\xa0\xff\x24\xcf\xa5\x6d\x5a\x4b\x48\x81\x0b\x47\x5e\xcc\xd8\xcb\x08\x5d\xe6\x14\x67\xcb\x1c\xf7\x5a\x8e\x6b\xcb\xc0\x4b\xbf\xb6\x7c\x44\xc2\x98\x3d\xd8\x1d\x3a\xa7\x15\x1e\x73\xc5\xd1\xa1\xac\x12\xd0\xf7\x3e\x5e\x56\x31\xdc\xda\x28\x7a\xb3\x48\xbc\xa5\x4f\x23\x15\x87\x8b\xbc\x4e\xf1\xb6\x58\x8e\x40\xae\x94\xd2\xc9\x2f\x10\x44\x36\xc4\x7b\x8c\x29\xd4\x76\x01\x2c\x3d\x86\x3a\x52\x28\xe1\x8f\x3f\x87\x93\x7f\x7f\xfb\x86\xfd\x49\xac\xd9\x13\x61\x01\x90\x68\xfc\x36\xd2\xeb\x6a\x4f\x72\xf5\xd1\x61\x9d\xdb\x52\x82\x99\x26\x35\xf0\x7b\x92\xa3\x2d\xbd\xb1\x42\xbd\x12\x46\x90\xcc\xec\xf2\xe5\x9b\xca\xee\x65\x5c\xf6\xa7\x37\x7f\x76\x73\x03\xf8\x92\x33\xd4\x52\x66\xcc\x4f\xa3\x44\x7e\xff\xd0\xda\x9e\x1d\x38\xb3\x4b\x78\xf1\xf2\xc7\xc8\x40\x7d\x7d\x3f\x43\xd8\x87\x2a\xee\xb7\xba\x05\xe9\x30\x45\x6c\x18\x35\x11\x6f\xd1\x6f\xa2\x26\x8b\xf0\xcb\x75\x94\xe2\x14\x1c\x68\x35\x95\xb6\x33\x51\xc7\x40\x3d\x2d\x80\x6f\x51\x46\xe1\xbf\xf7\xd8\xd3\xe9\x91\x84\x87\x07\x6d\x0c\x54\x08\x72\x63\x3d\x12\x54\x82\x2b\x65\x3e\xc5\x5c\x24\x07\xe1\xd4\x1f\xc4\x42\x82\x3e\xf4\xaf\xc0\x64\x53\xc2\xb3\xcb\xcb\xa6\x5f\x68\xb0\xb1\xdc\x48\x3d\x7f\xf1\xf2\xad\x4e\xee\xde\xbd\x59\x45\x9e\xd8\x09\xa7\x6d\xe7\x21\x15\x11\xe6\x86\x60\xf2\x41\xd5\x48\xe8\x52\x13\x37\x0a\x1a\xe9\x30\x24\x12\xe5\x56\x45\x68\xbe\x6b\xe3\x67\xd2\x85\x0b\xd8\xe2\x9e\x1f\x40\x90\x02\x29\xe2\x23\xdb\x68\x9d\x0d\x28\xe3\xb9\xa6\x26\x8c\xa6\x99\x8e\x39\xe1\x9b\x8e\xb4\x1c\x33\x9e\x8f\x36\xde\x45\xde\x9c\x4c\xc6\xd6\x5f\x09\x8f\x2f\x7f\x00\x24\x69\x15\x2a\xb8\xbe\x02\x89\x2e\xe8\x35\xeb\x23\x3c\x89\x8d\x96\x68\x10\x84\xe7\x62\x38\x6e\xa5\x66\xec\x63\xde\xd0\x2c\x19\xf8\x2e\x79\xf8\x34\x1b\x90\xe2\x55\x47\xca\x1c\x6c\x8a\x56\xa7\x62\xfc\x7f\x1c\xc0\xb9\x5d\x5f\x2d\x17\x7c\x91\xbf\xdc\xdd\x2d\x57\x9f\xdd\xe9\x59\x33\x46\xfb\xc0\x99\x3a\x6b\xb1\x19\xef\x3c\x17\x35\x29\x08\x84\x94\xe8\x3d\x08\xd5\x68\x02\x24\xd5\x5a\x4d\x21\xf6\x49\x9f\xf2\x41\x1a\x8d\x14\xae\xd1\x05\xbf\xfa\xd8\x9d\xa1\x21\xfb\x56\x47\x21\x9d\xf5\x1e\xbe\xf2\xfa\xb7\xca\xa7\xa4\xbf\x8e\xce\x7e\xde\x8b\x1c\x7c\x89\x36\x1e\x44\xea\x1b\x62\x96\xeb\x9a\xe0\xf5\xcd\xaa\xe7\x92\x14\xf6\x33\x78\xcf\xdf\xd9\xd5\xeb\x25\xec\xd0\xa5\x83\xfd\xa4\x4f\x67\xc6\x9a\xbe\x13\x8e\x03\xcc\xb2\x33\x26\xd5\xab\xc4\x46\xc3\x6b\x09\x8b\xf5\x3b\x1b\x96\x0e\x7d\x2a\x72\x27\xda\x11\x95\xfb\x53\xeb\x75\xb0\x6e\x9f\x07\xa1\xfe\x95\x47\x21\x1e\x7f\x64\x3b\xea\xc5\xfb\xa8\xf8\x03\x7e\xa2\x5d\x09\xa9\x04\x5e\xe4\x73\x39\xbc\xbf\xc6\x7d\xff\x02\x7f\x3e\xcd\x9f\x53\xd3\xa7\x14\x67\x0c\xd2\x4e\x3b\x4b\x5c\x9e\x23\x2b\x70\xe7\xe8\x2f\xa2\x99\x87\x0d\x3a\x84\xfb\x9f\x68\x77\xcf\x4c\xcb\x79\xc6\x05\xb2\xaf\x1a\x48\xbb\x41\x23\x29\xdc\x27\xf8\xb3\xd2\xe9\x53\x92\x63\xa2\xb8\x7f\x8d\xfb\x41\x70\x8b\xfb\x63\x39\xd8\x09\xd3\x71\x77\xc9\x57\x58\xf4\x37\xe1\x0f\xf3\xc4\xa8\xfe\x9c\xdd\x41\x8a\x8c\x9e\x56\x5b\xe1\x73\x24\xc4\x56\x39\x97\xd9\x36\x97\x59\xa4\xdd\x6f\xc2\x0d\x05\x36\xb7\x2d\x99\x0e\x77\xc2\x68\x25\x86\x86\xe9\x63\xf3\xae\x8b\xe6\x2c\x88\xb6\xe5\x12\x40\xe9\x5a\x07\xbd\x1e\x2f\x46\xdb\xba\x33\x69\x4a\xa9\x3a\x6d\x54\xcc\x8c\xce\x07\xdb\x0c\x2d\x14\x41\xb0\x6d\x9f\xb8\xb3\x6c\x52\x0c\xd6\x6e\xd9\xd8\x90\x20\xf6\x81\xd0\xdd\xe2\x1a\x1d\xd2\xa1\xfd\xfc\x42\x07\xa3\x32\xb8\x5e\xfb\x2f\x72\xb3\x90\xa4\x87\x81\x76\x41\x3e\x0c\x33\x79\x1c\x92\xaf\xdf\x2d\x40\x93\x0f\x28\x14\xa3\xb5\xce\x7e\xd8\x83\x26\x3d\x24\x75\xec\x39\x4e\xe6\x99\x13\xb4\x84\x01\x72\xc3\xe2\xaa\x2f\x97\xf9\xf5\x44\x67\x15\x39\x03\x07\xbb\xac\xaf\xb4\x8b\x1d\x27\xa7\x1d\x61\xb8\xd1\xae\x84\x39\x06\x39\x97\xa4\xe7\x3c\xd1\x76\x7e\x4e\x18\x66\xea\x1c\x48\xa5\xe9\x08\xa0\xd2\x94\x00\x76\xc2\xcd\x8d\xae\x22\x48\xa5\xe9\x9c\xee\xd1\x90\xd9\x37\xa1\xbc\x98\x18\x27\xe5\x3c\xe9\x19\x2f\xf5\xfa\xac\xf7\x55\xff\x03\x78\xf9\x68\x5e\x58\x9d\xce\x0b\x0c\xf9\xed\x07\x84\x53\xa6\x8c\x27\x9e\x79\x2e\xfd\xe1\x39\xfd\xdd\x93\xff\xee\x1c\xfd\xd5\x19\x6b\x7d\x9a\x1d\x8d\xad\xb6\x76\xa7\xcd\x5e\xcc\xf3\xa5\xf2\xb9\x9d\x85\x09\xa2\x1e\x7e\xed\xc0\xe4\x72\x76\x39\x7b\x3e\x29\x0a\x25\x82\x18\xfe\xbd\x9c\x7a\x7e\xd7\xb7\xe7\x37\x5f\xcc\xd4\xaa\x9d\x9c\xb0\xfc\xcd\x57\xd6\x88\x38\x09\xe9\xb0\x78\xcc\x17\x4e\x93\x2f\x74\x88\x65\x27\x45\xa1\xa9\x8e\xff\x57\x86\x14\x5a\xc7\xff\x4f\x17\xa0\x03\x28\x6c\x8d\xdd\x7b\x58\x24\x99\x18\x1e\x8f\x97\xed\xf3\x69\xc9\xad\x32\xb3\x4d\xaa\xc2\x37\x22\x88\xc8\xb3\x03\x6e\x85\xc6\x52\xed\xd3\x9f\x83\x06\xfd\xa6\xec\x5b\xee\x1e\xe1\x4e\x37\x18\xcd\x27\x08\x6b\x54\xec\x81\xb8\x8d\x4b\x8c\xee\x43\xe6\x75\x21\x83\xde\xc5\xc6\x4f\x39\xa1\x49\x13\x5f\x6e\x7c\x64\x8c\x12\xfe\x76\xe9\x3f\xff\x1b\x29\x3b\x76\xf2\x87\xe8\xdc\xa0\x79\x6e\x76\x3a\x68\x7f\x83\x81\xa9\x3f\x23\xff\xf5\x53\x52\xaf\x7a\x76\x24\x7a\x76\x79\x79\xf9\xac\xf8\x5f\x00\x00\x00\xff\xff\x49\xe3\x57\x8c\x9e\x15\x00\x00"),
diff --git a/deployments/charts/kuma/templates/_helpers.tpl b/deployments/charts/kuma/templates/_helpers.tpl
index 4bd5c32a2..d5d82ab9d 100644
--- a/deployments/charts/kuma/templates/_helpers.tpl
+++ b/deployments/charts/kuma/templates/_helpers.tpl
@@ -104,6 +104,8 @@ env:
   value: "kubernetes"
 - name: KUMA_STORE_KUBERNETES_SYSTEM_NAMESPACE
   value: {{ .Release.Namespace | quote }}
+- name: KUMA_RUNTIME_KUBERNETES_CONTROL_PLANE_SERVICE_NAME
+  value: {{ include "kuma.controlPlane.serviceName" . }}
 - name: KUMA_GENERAL_TLS_CERT_FILE
   value: /var/run/secrets/kuma.io/tls-cert/tls.crt
 - name: KUMA_GENERAL_TLS_KEY_FILE
diff --git a/deployments/charts/kuma/templates/cni-daemonset.yaml b/deployments/charts/kuma/templates/cni-daemonset.yaml
index b0b0d0610..e589c8567 100644
--- a/deployments/charts/kuma/templates/cni-daemonset.yaml
+++ b/deployments/charts/kuma/templates/cni-daemonset.yaml
@@ -41,7 +41,7 @@ spec:
         - effect: NoExecute
           operator: Exists
       priorityClassName: system-cluster-critical
-      serviceAccountName: kuma-cni
+      serviceAccountName: {{ include "kuma.name" . }}-cni
       # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force
       # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods.
       terminationGracePeriodSeconds: 5
diff --git a/dev/examples/k8s/example-app/example-app.yaml b/dev/examples/k8s/example-app/example-app.yaml
index a0a3ce48f..4640d8b7b 100644
--- a/dev/examples/k8s/example-app/example-app.yaml
+++ b/dev/examples/k8s/example-app/example-app.yaml
@@ -2,20 +2,20 @@
 apiVersion: v1
 kind: Service
 metadata:
-  name: example-app
+  name: example-server
 spec:
   ports:
   - port: 80
     name: http
   selector:
-    app: example-app
+    app: example-server
 ---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
-  name: example-app
+  name: example-server
   labels:
-    app: example-app
+    app: example-server
 spec:
   strategy:
     rollingUpdate:
@@ -23,11 +23,11 @@ spec:
       maxUnavailable: 0
   selector:
     matchLabels:
-      app: example-app
+      app: example-server
   template:
     metadata:
       labels:
-        app: example-app
+        app: example-server
     spec:
       containers:
       - name: nginx
@@ -39,3 +39,32 @@ spec:
           requests:
             cpu: 10m
             memory: 32Mi
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: example-client
+  labels:
+    app: example-client
+spec:
+  strategy:
+    rollingUpdate:
+      maxSurge: 1
+      maxUnavailable: 0
+  selector:
+    matchLabels:
+      app: example-client
+  template:
+    metadata:
+      labels:
+        app: example-client
+    spec:
+      containers:
+        - name: alpine
+          image: "alpine:latest"
+          imagePullPolicy: IfNotPresent
+          command: ["sh", "-c", "tail -f /dev/null"]
+          resources:
+            requests:
+              cpu: 10m
+              memory: 32Mi
diff --git a/docs/proposals/timeouts.md b/docs/proposals/timeouts.md
new file mode 100644
index 000000000..8e09e67c7
--- /dev/null
+++ b/docs/proposals/timeouts.md
@@ -0,0 +1,256 @@
+# Timeout policy
+
+## Context
+
+Envoy allows users to configure plenty of different timeouts. All of them are applied to the different parts of configuration, all of them protects different stages of Connect / Request / Response process. There are the most important timeouts that Envoy allows to configure:
+
+* [1] [connect_timeout](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#envoy-v3-api-field-config-cluster-v3-cluster-connect-timeout) - specifies the amount of time Envoy will wait for an upstream TCP connection to be established.
+  
+  Place: cluster
+  
+  Required: true
+  
+  Default: no
+  
+  Protocol: TCP
+
+
+* [2] [idle_timeout](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto#envoy-v3-api-field-extensions-filters-network-tcp-proxy-v3-tcpproxy-idle-timeout) - is defined as the period in which there are no bytes sent or received on either the upstream or downstream connection.
+  
+  Place: TCPProxy
+  
+  Required: false (0 value for disabling)
+  
+  Default: 1h
+  
+  Protocol: TCP
+
+
+* [3] [idle_timeout](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-idle-timeout) - the idle timeout is the time at which a downstream or upstream connection will be terminated if there are no active streams.
+  
+  Place: HttpConnectionManager, Cluster
+  
+  Required: false
+  
+  Default: 1h
+  
+  Protocol: HTTP
+
+
+* [4] [request_timeout](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-request-timeout) - the amount of time that Envoy will wait for the entire request to be received. The timer is activated when the request is initiated, and is disarmed when the last byte of the request is sent upstream (i.e. all decoding filters have processed the request), OR when the response is initiated. If not specified or set to 0, this timeout is disabled. This timeout is not compatible with streaming requests.
+  
+  Place: HttpConnectionManager
+  
+  Required: false (0 value for disabling)
+  
+  Default: not specified
+  
+  Protocol: HTTP
+
+
+* [5] [max_stream_duration](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-max-stream-duration) - Total duration to keep alive an HTTP request/response stream. If the time limit is reached the stream will be reset independent of any other timeouts.
+  
+  Place: HttpConnectionManager, Cluster
+  
+  Required: false
+  
+  Default: not specified
+  
+  Protocol: HTTP
+
+
+* [6] [stream_idle_timeout](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-stream-idle-timeout) - when an initiated request is being sent too slowly in a way that even the headers are not delivered at required intervals, Envoy will respond with a 408 error code.
+  
+  Place: HttpConnectionManager
+  
+  Required: false (0 value for disabling)
+  
+  Default: 5 min
+  
+  Protocol: HTTP
+
+
+* [7] [timeout](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-timeout) - this spans between the point at which the entire downstream request (i.e. end-of-stream) has been processed and when the upstream response has been completely processed.
+  
+  Place: Route
+  
+  Required: false (0 value for disabling)
+  
+  Default: 15s
+  
+  Protocol: HTTP
+
+
+* [8] [idle_timeout](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-idle-timeout) - the way to override [stream_idle_timeout](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-stream-idle-timeout)  [6]
+  
+  Place: Route
+  
+  Required:  false (0 value for disabling)
+  
+  Default: not specified
+  
+  Protocol: HTTP
+
+
+* [9] [per_try_timeout](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-retrypolicy-per-try-timeout) - can be configured when using retries so that individual tries using a shorter timeout than the overall request timeout described above. This timeout only applies before any part of the response is sent to the downstream, which normally happens after the upstream has sent response headers. This timeout can be used with streaming endpoints to retry if the upstream fails to begin a response within the timeout.
+  
+  Place: Route
+  
+  Required: false
+  
+  Default: not specified
+  
+  Protocol: HTTP
+
+
+* [10] [max_stream_duration](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-msg-config-route-v3-routeaction-maxstreamduration) - the way to override [max_stream_duration](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/core/v3/protocol.proto#envoy-v3-api-field-config-core-v3-httpprotocoloptions-max-stream-duration)  [5]
+  
+  Place: Route
+  
+  Required:  false (0 value for disabling)
+  
+  Default: not specified
+  
+  Protocol: HTTP
+
+
+* [11] [request_headers_timeout](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-field-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-request-headers-timeout) - The amount of time that Envoy will wait for the request headers to be received. The timer is activated when the first byte of the headers is received, and is disarmed when the last byte of the headers has been received.
+  
+  Place: HttpConnectionManager
+  
+  Required: false (0 value for disabling)
+  
+  Default: not specified
+  
+  Protocol: HTTP
+
+
+* [12] [transport_socket_connect_timeout](https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener_components.proto#envoy-v3-api-field-config-listener-v3-filterchain-transport-socket-connect-timeout) - If present and nonzero, the amount of time to allow incoming connections to complete any transport socket negotiations. If this expires before the transport reports connection establishment, the connection is summarily closed.
+  
+  Place: FilterChain
+  
+  Required: false
+  
+  Default: not specified
+
+  Protocol: TCP
+
+
+## Use cases
+
+1. **As a**  service owner
+   
+   **I want to** propagate default recommended timeouts for applications which consumes my service
+   
+   **so that** they know approximately how much time it will take to request my service
+
+
+2. **As a** service owner
+   
+   **I want to** set service side timeouts
+   
+   **so that**  I can protect my service from abusive application which is trying to consume it
+
+
+3. **As a** service consumer
+   
+   **I want to** set different timeouts for different outbounds of my application
+   
+   **so that** I can granularly make decisions regarding the time to wait for specific service
+
+
+4. **As a** service consumer
+   
+   **I want to** be able to overrider existing default recommended timeouts for the service that I consume
+   
+   **so that** I can control outgoing timeouts myself
+
+
+## Proposed solution
+
+In order to satisfy all the use cases we can introduce 2 new policies: `Timeout` and `InboundTimeout`.
+
+### Timeout
+
+Service A -> SRC Envoy -> -> -> DST Envoy -> Service B
+
+Timeout policy is a connection policy so it will be applied to the pair of service (A and B in the example). 
+The idea of the policy is to instruct Service A how to request Service B. Example:
+
+```yaml
+type: Timeout
+mesh: default
+name: default-timeouts-srv-B
+sources:
+- match:
+    kuma.io/service: '*'
+destinations:
+- match:
+    kuma.io/service: 'srv-B'
+conf:
+  # connectTimeout defines time to establish connection, 'connect_timeout' on Cluster [1]
+  connectTimeout: 10s 
+  tcp:
+    # 'idle_timeout' on TCPProxy [2]
+    idleTimeout: 1h
+  http:
+    # 'timeout' on Route [7]
+    requestTimeout: 5s
+    # 'idle_timeout' on Cluster [3]
+    idleTimeout: 1h 
+  grpc:
+    # 'stream_idle_timeout' on HttpConnectionManager [6]
+    streamIdleTimeout: 5m
+    # 'max_stream_duration' on Cluster [5]
+    maxStreamDuration: 30m
+``` 
+
+As an owner of Service B you have some SLA regarding the upper boundaries of the request/response time, so you can apply
+this `default-timeouts-srv-B` and every service which is trying to consume Service B will have those timeouts by default.
+
+At the same time if you are an owner of Service A you can override this policy for your service and put different timeout 
+values. From the Service B perspective `default-timeouts-srv-B` policy has an advisory nature, every service can override it,
+`Timeout` policy is not purposed to protect Service B. In order to protect Service B from abusive clients with long
+requests it’s better to use `InboundTimeouts`.
+
+### InboundTimeout
+
+Unlike the `Timeout` this policy is matched for the Dataplane rather than pair of services (applied only to the Dataplanes of the Service B). `InboundTimeout` has the same configuration, but values are mapped to the different Envoy timeouts:
+
+```yaml
+type: InboundTimeout
+mesh: default
+name: timeouts-srv-B
+selectors:
+  - match:
+      kuma.io/service: srv-B
+conf:
+  connectTimeout: 10s # 'transport_socket_connect_timeout' on FilterChain [12]
+  tcp:
+    # 'idle_timeout' on TCPProxy [2]
+    idleTimeout: 1h
+  http:
+    # 'request_timeout' on HttpConnectionManager [4]
+    requestTimeout: 10s
+    # 'request_headers_timeout' on HttpConnectionManager [11]
+    requestHeadersTimeout: 5s
+    # 'idle_timeout' on HttpConnectionManager [3]
+    idleTimeout: 1h
+  grpc:
+    # 'stream_idle_timeout' on HttpConnectionManager [6]
+    streamIdleTimeout: 5s
+    # 'max_stream_duration' on HttpConnectionManager [5]
+    maxStreamDuration: 30m
+``` 
+
+This policy aims to protect your service from the long living requests, if the service is not designed to support them.
+
+### Uncovered timeouts
+
+There are 3 uncovered timeouts - [8], [9], [10].
+
+[8] and [10] allows to override existing timeouts on per-route basis, probably it makes sense to implement them in L7 
+TrafficRoutes.
+
+[9] - probably makes sense to implement in the scope of Retry policy. 
+
diff --git a/go.sum b/go.sum
index 15430137e..c7f0e4389 100644
--- a/go.sum
+++ b/go.sum
@@ -1603,7 +1603,6 @@ google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
 google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
 google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
-google.golang.org/grpc v1.34.0 h1:raiipEjMOIC/TO2AvyTxP25XFdLxNIBwzDh3FM3XztI=
 google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
 google.golang.org/grpc v1.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8=
 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
diff --git a/pkg/config/app/kuma-cp/kuma-cp.defaults.yaml b/pkg/config/app/kuma-cp/kuma-cp.defaults.yaml
index aa7b54333..605e04ca5 100644
--- a/pkg/config/app/kuma-cp/kuma-cp.defaults.yaml
+++ b/pkg/config/app/kuma-cp/kuma-cp.defaults.yaml
@@ -149,6 +149,8 @@ apiServer:
 runtime:
   # Kubernetes-specific configuration
   kubernetes:
+    # Service name of the Kuma Control Plane. It is used to point Kuma DP to proper URL.
+    controlPlaneServiceName: kuma-control-plane
     # Admission WebHook Server configuration
     admissionServer:
       # Address the Admission WebHook Server should be listening on
diff --git a/pkg/config/plugins/runtime/k8s/config.go b/pkg/config/plugins/runtime/k8s/config.go
index 345d60a18..694262450 100644
--- a/pkg/config/plugins/runtime/k8s/config.go
+++ b/pkg/config/plugins/runtime/k8s/config.go
@@ -15,6 +15,7 @@ func DefaultKubernetesRuntimeConfig() *KubernetesRuntimeConfig {
 		AdmissionServer: AdmissionServerConfig{
 			Port: 5443,
 		},
+		ControlPlaneServiceName: "kuma-control-plane",
 		Injector: Injector{
 			CNIEnabled:           false,
 			VirtualProbesEnabled: true,
@@ -81,6 +82,8 @@ type KubernetesRuntimeConfig struct {
 	// marshaled objects will be stored in the cache. If equal to 0s then
 	// cache is turned off
 	MarshalingCacheExpirationTime time.Duration `yaml:"marshalingCacheExpirationTime" envconfig:"kuma_runtime_kubernetes_marshaling_cache_expiration_time"`
+	// ControlPlaneServiceName defines service name of the Kuma control plane. It is used to point Kuma DP to proper URL.
+	ControlPlaneServiceName string `yaml:"controlPlaneServiceName,omitempty" envconfig:"kuma_runtime_kubernetes_control_plane_service_name"`
 }
 
 // Configuration of the Admission WebHook Server implemented by the Control Plane.
diff --git a/pkg/core/bootstrap/bootstrap.go b/pkg/core/bootstrap/bootstrap.go
index 9b8f2dc0d..4a920e23d 100644
--- a/pkg/core/bootstrap/bootstrap.go
+++ b/pkg/core/bootstrap/bootstrap.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/kumahq/kuma/pkg/api-server/customization"
 	"github.com/kumahq/kuma/pkg/core/managers/apis/zone"
+	xds_hooks "github.com/kumahq/kuma/pkg/xds/hooks"
 
 	"github.com/pkg/errors"
 
@@ -90,6 +91,7 @@ func buildRuntime(cfg kuma_cp.Config, closeCh <-chan struct{}) (core_runtime.Run
 
 	builder.WithLookupIP(lookup.CachedLookupIP(net.LookupIP, cfg.General.DNSCacheTTL))
 	builder.WithAPIManager(customization.NewAPIList())
+	builder.WithXDSHooks(&xds_hooks.Hooks{})
 
 	if err := initializeAfterBootstrap(cfg, builder); err != nil {
 		return nil, err
diff --git a/pkg/core/policy/dataplane_matcher.go b/pkg/core/policy/dataplane_matcher.go
index c04ede3c4..60a79e086 100644
--- a/pkg/core/policy/dataplane_matcher.go
+++ b/pkg/core/policy/dataplane_matcher.go
@@ -49,6 +49,56 @@ func SelectDataplanePolicy(dataplane *mesh.DataplaneResource, policies []Datapla
 	return bestPolicy
 }
 
+// SelectInboundDataplanePolicies given a Dataplane definition and a list of DataplanePolicy returns the "best matching" DataplanePolicy for each inbound separately.
+// A DataplanePolicy for an inbound is considered a match if the inbound matches all the tags listed in selector of the DataplanePolicy.
+// Every matching DataplanePolicy gets a rank (score) defined as a maximum number of tags in a matching selector.
+// DataplanePolicy with an empty list of selectors is considered a match with a rank (score) of 0.
+// DataplanePolicy with an empty selector (one that has no tags) is considered a match with a rank (score) of 0.
+// In case if there are multiple DataplanePolicies with the same rank (score), the policy created last is chosen.
+func SelectInboundDataplanePolicies(dataplane *mesh.DataplaneResource, policies []DataplanePolicy) InboundDataplanePolicyMap {
+	sort.Stable(DataplanePolicyByName(policies)) // sort to avoid flakiness
+
+	match := InboundDataplanePolicyMap{}
+
+	for _, inbound := range dataplane.Spec.Networking.GetInbound() {
+		var bestPolicy DataplanePolicy
+		var bestRank mesh_proto.TagSelectorRank
+		sameRankCreatedLater := func(policy DataplanePolicy, rank mesh_proto.TagSelectorRank) bool {
+			return rank.CompareTo(bestRank) == 0 && policy.GetMeta().GetCreationTime().After(bestPolicy.GetMeta().GetCreationTime())
+		}
+		for _, policy := range policies {
+			if 0 == len(policy.Selectors()) { // match everything
+				if bestPolicy == nil || sameRankCreatedLater(policy, mesh_proto.TagSelectorRank{}) {
+					bestPolicy = policy
+				}
+				continue
+			}
+			for _, selector := range policy.Selectors() {
+				if 0 == len(selector.Match) { // match everything
+					if bestPolicy == nil || sameRankCreatedLater(policy, mesh_proto.TagSelectorRank{}) {
+						bestPolicy = policy
+					}
+					continue
+				}
+				tagSelector := mesh_proto.TagSelector(selector.Match)
+				if inbound.MatchTags(tagSelector) {
+					rank := tagSelector.Rank()
+					if rank.CompareTo(bestRank) > 0 || sameRankCreatedLater(policy, rank) {
+						bestRank = rank
+						bestPolicy = policy
+					}
+				}
+			}
+		}
+		if bestPolicy != nil {
+			iface := dataplane.Spec.GetNetworking().ToInboundInterface(inbound)
+			match[iface] = bestPolicy
+		}
+	}
+
+	return match
+}
+
 type DataplanePolicyByName []DataplanePolicy
 
 func (a DataplanePolicyByName) Len() int      { return len(a) }
diff --git a/pkg/core/policy/types.go b/pkg/core/policy/types.go
index 5d227ecca..0146d295e 100644
--- a/pkg/core/policy/types.go
+++ b/pkg/core/policy/types.go
@@ -23,3 +23,5 @@ type DataplanePolicy interface {
 	core_model.Resource
 	Selectors() []*mesh_proto.Selector
 }
+
+type InboundDataplanePolicyMap map[mesh_proto.InboundInterface]DataplanePolicy
diff --git a/pkg/core/runtime/builder.go b/pkg/core/runtime/builder.go
index bf1de0d22..848ed55f2 100644
--- a/pkg/core/runtime/builder.go
+++ b/pkg/core/runtime/builder.go
@@ -6,6 +6,7 @@ import (
 	"os"
 
 	api_server "github.com/kumahq/kuma/pkg/api-server/customization"
+	xds_hooks "github.com/kumahq/kuma/pkg/xds/hooks"
 
 	"github.com/pkg/errors"
 
@@ -42,6 +43,7 @@ type BuilderContext interface {
 	Metrics() metrics.Metrics
 	EventReaderFactory() events.ListenerFactory
 	APIManager() api_server.APIManager
+	XDSHooks() *xds_hooks.Hooks
 }
 
 var _ BuilderContext = &Builder{}
@@ -65,6 +67,7 @@ type Builder struct {
 	metrics  metrics.Metrics
 	erf      events.ListenerFactory
 	apim     api_server.APIManager
+	xdsh     *xds_hooks.Hooks
 	closeCh  <-chan struct{}
 	*runtimeInfo
 }
@@ -176,6 +179,11 @@ func (b *Builder) WithAPIManager(apim api_server.APIManager) *Builder {
 	return b
 }
 
+func (b *Builder) WithXDSHooks(xdsh *xds_hooks.Hooks) *Builder {
+	b.xdsh = xdsh
+	return b
+}
+
 func (b *Builder) Build() (Runtime, error) {
 	if b.cm == nil {
 		return nil, errors.Errorf("ComponentManager has not been configured")
@@ -213,6 +221,9 @@ func (b *Builder) Build() (Runtime, error) {
 	if b.apim == nil {
 		return nil, errors.Errorf("APIManager has not been configured")
 	}
+	if b.xdsh == nil {
+		return nil, errors.Errorf("XDSHooks has not been configured")
+	}
 	return &runtime{
 		RuntimeInfo: b.runtimeInfo,
 		RuntimeContext: &runtimeContext{
@@ -231,6 +242,7 @@ func (b *Builder) Build() (Runtime, error) {
 			metrics:  b.metrics,
 			erf:      b.erf,
 			apim:     b.apim,
+			xdsh:     b.xdsh,
 		},
 		Manager: b.cm,
 	}, nil
@@ -284,10 +296,12 @@ func (b *Builder) Metrics() metrics.Metrics {
 func (b *Builder) EventReaderFactory() events.ListenerFactory {
 	return b.erf
 }
-
 func (b *Builder) APIManager() api_server.APIManager {
 	return b.apim
 }
+func (b *Builder) XDSHooks() *xds_hooks.Hooks {
+	return b.xdsh
+}
 func (b *Builder) CloseCh() <-chan struct{} {
 	return b.closeCh
 }
diff --git a/pkg/core/runtime/runtime.go b/pkg/core/runtime/runtime.go
index 1a1557132..7a88b4170 100644
--- a/pkg/core/runtime/runtime.go
+++ b/pkg/core/runtime/runtime.go
@@ -5,6 +5,7 @@ import (
 	"sync"
 
 	api_server "github.com/kumahq/kuma/pkg/api-server/customization"
+	xds_hooks "github.com/kumahq/kuma/pkg/xds/hooks"
 
 	"github.com/kumahq/kuma/pkg/core/datasource"
 	"github.com/kumahq/kuma/pkg/dns/resolver"
@@ -54,6 +55,7 @@ type RuntimeContext interface {
 	Metrics() metrics.Metrics
 	EventReaderFactory() events.ListenerFactory
 	APIInstaller() api_server.APIInstaller
+	XDSHooks() *xds_hooks.Hooks
 }
 
 var _ Runtime = &runtime{}
@@ -108,6 +110,7 @@ type runtimeContext struct {
 	metrics  metrics.Metrics
 	erf      events.ListenerFactory
 	apim     api_server.APIInstaller
+	xdsh     *xds_hooks.Hooks
 }
 
 func (rc *runtimeContext) Metrics() metrics.Metrics {
@@ -169,6 +172,11 @@ func (rc *runtimeContext) LeaderInfo() component.LeaderInfo {
 func (rc *runtimeContext) LookupIP() lookup.LookupIPFunc {
 	return rc.lif
 }
+
 func (rc *runtimeContext) APIInstaller() api_server.APIInstaller {
 	return rc.apim
 }
+
+func (rc *runtimeContext) XDSHooks() *xds_hooks.Hooks {
+	return rc.xdsh
+}
diff --git a/pkg/dns/outbound.go b/pkg/dns/outbound.go
index e244e5f33..1da742288 100644
--- a/pkg/dns/outbound.go
+++ b/pkg/dns/outbound.go
@@ -3,6 +3,8 @@ package dns
 import (
 	"sort"
 
+	"github.com/kumahq/kuma/pkg/core/resources/model"
+
 	"github.com/pkg/errors"
 
 	"github.com/kumahq/kuma/pkg/dns/vips"
@@ -14,7 +16,7 @@ import (
 const VIPListenPort = uint32(80)
 
 func VIPOutbounds(
-	name string,
+	resourceKey model.ResourceKey,
 	dataplanes []*core_mesh.DataplaneResource,
 	vips vips.List,
 	externalServices []*core_mesh.ExternalServiceResource,
@@ -22,18 +24,21 @@ func VIPOutbounds(
 	serviceVIPMap := map[string]string{}
 	services := []string{}
 	for _, dataplane := range dataplanes {
-		if dataplane.Meta.GetName() == name {
+		if resourceKey == model.MetaToResourceKey(dataplane.Meta) {
 			continue
 		}
 
 		if dataplane.Spec.IsIngress() {
 			for _, service := range dataplane.Spec.Networking.Ingress.AvailableServices {
-				inService := service.Tags[mesh_proto.ServiceTag]
-				if _, found := serviceVIPMap[inService]; !found {
-					vip, err := ForwardLookup(vips, inService)
-					if err == nil {
-						serviceVIPMap[inService] = vip
-						services = append(services, inService)
+				if service.Mesh == resourceKey.Mesh {
+					// Only add outbounds for services in the same mesh
+					inService := service.Tags[mesh_proto.ServiceTag]
+					if _, found := serviceVIPMap[inService]; !found {
+						vip, err := ForwardLookup(vips, inService)
+						if err == nil {
+							serviceVIPMap[inService] = vip
+							services = append(services, inService)
+						}
 					}
 				}
 			}
diff --git a/pkg/plugins/runtime/k8s/controllers/inbound_converter.go b/pkg/plugins/runtime/k8s/controllers/inbound_converter.go
index f75159af0..5851ebef0 100644
--- a/pkg/plugins/runtime/k8s/controllers/inbound_converter.go
+++ b/pkg/plugins/runtime/k8s/controllers/inbound_converter.go
@@ -2,6 +2,7 @@ package controllers
 
 import (
 	"fmt"
+	"strings"
 
 	"github.com/pkg/errors"
 	kube_core "k8s.io/api/core/v1"
@@ -11,67 +12,116 @@ import (
 	util_k8s "github.com/kumahq/kuma/pkg/plugins/runtime/k8s/util"
 )
 
-func InboundInterfacesFor(zone string, pod *kube_core.Pod, services []*kube_core.Service) ([]*mesh_proto.Dataplane_Networking_Inbound, error) {
-	var ifaces []*mesh_proto.Dataplane_Networking_Inbound
-	for _, svc := range services {
-		for _, svcPort := range svc.Spec.Ports {
-			if svcPort.Protocol != "" && svcPort.Protocol != kube_core.ProtocolTCP {
-				// ignore non-TCP ports
-				continue
-			}
-			containerPort, container, err := util_k8s.FindPort(pod, &svcPort)
-			if err != nil {
-				converterLog.Error(err, "failed to find a container port in a given Pod that would match a given Service port", "namespace", pod.Namespace, "podName", pod.Name, "serviceName", svc.Name, "servicePortName", svcPort.Name)
-				// ignore those cases where a Pod doesn't have all the ports a Service has
-				continue
+func inboundForService(zone string, pod *kube_core.Pod, service *kube_core.Service) (ifaces []*mesh_proto.Dataplane_Networking_Inbound) {
+	for _, svcPort := range service.Spec.Ports {
+		if svcPort.Protocol != "" && svcPort.Protocol != kube_core.ProtocolTCP {
+			// ignore non-TCP ports
+			continue
+		}
+		containerPort, container, err := util_k8s.FindPort(pod, &svcPort)
+		if err != nil {
+			converterLog.Error(err, "failed to find a container port in a given Pod that would match a given Service port", "namespace", pod.Namespace, "podName", pod.Name, "serviceName", service.Name, "servicePortName", svcPort.Name)
+			// ignore those cases where a Pod doesn't have all the ports a Service has
+			continue
+		}
+
+		tags := InboundTagsForService(zone, pod, service, &svcPort)
+		var health *mesh_proto.Dataplane_Networking_Inbound_Health
+
+		// if container is not equal nil then port is explicitly defined as containerPort so we're able
+		// to figure out which container implements which service. Since we know container we can check its status
+		// and map it to the Dataplane health
+		if container != nil {
+			if cs := util_k8s.FindContainerStatus(pod, container.Name); cs != nil {
+				health = &mesh_proto.Dataplane_Networking_Inbound_Health{
+					Ready: cs.Ready,
+				}
 			}
+		}
 
-			tags := InboundTagsFor(zone, pod, svc, &svcPort)
-			var health *mesh_proto.Dataplane_Networking_Inbound_Health
-
-			// if container is not equal nil then port is explicitly defined as containerPort so we're able
-			// to figure out which container implements which service. Since we know container we can check its status
-			// and map it to the Dataplane health
-			if container != nil {
-				if cs := util_k8s.FindContainerStatus(pod, container.Name); cs != nil {
-					health = &mesh_proto.Dataplane_Networking_Inbound_Health{
-						Ready: cs.Ready,
-					}
+		// also we're checking whether kuma-sidecar container is ready
+		if cs := util_k8s.FindContainerStatus(pod, util_k8s.KumaSidecarContainerName); cs != nil {
+			if health != nil {
+				health.Ready = health.Ready && cs.Ready
+			} else {
+				health = &mesh_proto.Dataplane_Networking_Inbound_Health{
+					Ready: cs.Ready,
 				}
 			}
+		}
 
-			// also we're checking whether kuma-sidecar container is ready
-			if cs := util_k8s.FindContainerStatus(pod, util_k8s.KumaSidecarContainerName); cs != nil {
-				if health != nil {
-					health.Ready = health.Ready && cs.Ready
-				} else {
-					health = &mesh_proto.Dataplane_Networking_Inbound_Health{
-						Ready: cs.Ready,
-					}
+		ifaces = append(ifaces, &mesh_proto.Dataplane_Networking_Inbound{
+			Port:   uint32(containerPort),
+			Tags:   tags,
+			Health: health,
+		})
+	}
+
+	return
+}
+
+func inboundForServiceless(zone string, pod *kube_core.Pod) (ifaces []*mesh_proto.Dataplane_Networking_Inbound) {
+	// The Pod does not have any services associated with it, just get the data from the Pod itself
+
+	// We still need that extra listener with a service because it is required in many places of the code (e.g. mTLS)
+	// TCPPortReserved, is a special port that will never be allocated from the TCP/IP stack. We use it as special
+	// designator that this is actually a service-less inbound.
+
+	// NOTE: It is cleaner to implement an equivalent of Gateway which is inbound-less dataplane. However such approch
+	// will create lots of code changes to account for this other type of dataplne (we already have GW and Ingress),
+	// including GUI and CLI changes
+
+	tags := InboundTagsForPod(zone, pod)
+	var health *mesh_proto.Dataplane_Networking_Inbound_Health
+
+	for _, container := range pod.Spec.Containers {
+		if container.Name != util_k8s.KumaSidecarContainerName {
+			if cs := util_k8s.FindContainerStatus(pod, container.Name); cs != nil {
+				health = &mesh_proto.Dataplane_Networking_Inbound_Health{
+					Ready: cs.Ready,
 				}
 			}
+		}
+	}
 
-			ifaces = append(ifaces, &mesh_proto.Dataplane_Networking_Inbound{
-				Port:   uint32(containerPort),
-				Tags:   tags,
-				Health: health,
-			})
+	// also we're checking whether kuma-sidecar container is ready
+	if cs := util_k8s.FindContainerStatus(pod, util_k8s.KumaSidecarContainerName); cs != nil {
+		if health != nil {
+			health.Ready = health.Ready && cs.Ready
+		} else {
+			health = &mesh_proto.Dataplane_Networking_Inbound_Health{
+				Ready: cs.Ready,
+			}
 		}
 	}
+
+	ifaces = append(ifaces, &mesh_proto.Dataplane_Networking_Inbound{
+		Port:   mesh_proto.TCPPortReserved,
+		Tags:   tags,
+		Health: health,
+	})
+
+	return
+}
+
+func InboundInterfacesFor(zone string, pod *kube_core.Pod, services []*kube_core.Service) ([]*mesh_proto.Dataplane_Networking_Inbound, error) {
+	ifaces := []*mesh_proto.Dataplane_Networking_Inbound{}
+	for _, svc := range services {
+		svcIfaces := inboundForService(zone, pod, svc)
+		ifaces = append(ifaces, svcIfaces...)
+	}
+
 	if len(ifaces) == 0 {
-		// Notice that here we return an error immediately
-		// instead of leaving Dataplane validation up to a ValidatingAdmissionWebHook.
-		// We do it this way in order to provide the most descriptive error message.
-		cause := "However, there are no Services that select this Pod."
 		if len(services) > 0 {
-			cause = "However, this Pod doesn't have any container ports that would satisfy matching Service(s)."
+			return nil, errors.Errorf("A service that selects pod %s was found, but it doesn't match any container ports.", pod.GetName())
 		}
-		return nil, errors.Errorf("Kuma requires every Pod in a Mesh to be a part of at least one Service. %s", cause)
+
+		ifaces = append(ifaces, inboundForServiceless(zone, pod)...)
 	}
 	return ifaces, nil
 }
 
-func InboundTagsFor(zone string, pod *kube_core.Pod, svc *kube_core.Service, svcPort *kube_core.ServicePort) map[string]string {
+func InboundTagsForService(zone string, pod *kube_core.Pod, svc *kube_core.Service, svcPort *kube_core.ServicePort) map[string]string {
 	tags := util_k8s.CopyStringMap(pod.Labels)
 	for key, value := range tags {
 		if value == "" {
@@ -110,3 +160,33 @@ func ProtocolTagFor(svc *kube_core.Service, svcPort *kube_core.ServicePort) stri
 	// to a user that at least `<port>.service.kuma.io/protocol` has an effect
 	return protocolValue
 }
+
+func InboundTagsForPod(zone string, pod *kube_core.Pod) map[string]string {
+	tags := util_k8s.CopyStringMap(pod.Labels)
+	for key, value := range tags {
+		if value == "" {
+			delete(tags, key)
+		}
+	}
+	if tags == nil {
+		tags = make(map[string]string)
+	}
+	tags[mesh_proto.ServiceTag] = fmt.Sprintf("%s_%s_svc", nameFromPod(pod), pod.Namespace)
+	if zone != "" {
+		tags[mesh_proto.ZoneTag] = zone
+	}
+	tags[mesh_proto.ProtocolTag] = mesh_core.ProtocolTCP
+	tags[mesh_proto.InstanceTag] = pod.Name
+
+	return tags
+}
+
+func nameFromPod(pod *kube_core.Pod) string {
+	// the name is in format <name>-<replica set id>-<pod id>
+	split := strings.Split(pod.Name, "-")
+	if len(split) > 2 {
+		split = split[:len(split)-2]
+	}
+
+	return strings.Join(split, "-")
+}
diff --git a/pkg/plugins/runtime/k8s/controllers/outbound_converter.go b/pkg/plugins/runtime/k8s/controllers/outbound_converter.go
index ac6f70d25..8dd069d73 100644
--- a/pkg/plugins/runtime/k8s/controllers/outbound_converter.go
+++ b/pkg/plugins/runtime/k8s/controllers/outbound_converter.go
@@ -5,6 +5,8 @@ import (
 	"strconv"
 	"strings"
 
+	"github.com/kumahq/kuma/pkg/core/resources/model"
+
 	core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
 	"github.com/kumahq/kuma/pkg/dns"
 	"github.com/kumahq/kuma/pkg/dns/vips"
@@ -50,6 +52,12 @@ func (p *PodConverter) OutboundInterfacesFor(
 			converterLog.Error(err, "could not get K8S Service for service tag")
 			continue // one invalid Dataplane definition should not break the entire mesh
 		}
+
+		// Do not generate outbounds for service-less
+		if isServiceLess(port) {
+			continue
+		}
+
 		if isHeadlessService(service) {
 			// Generate outbound listeners for every endpoint of services.
 			for _, endpoint := range endpoints[serviceTag] {
@@ -77,7 +85,11 @@ func (p *PodConverter) OutboundInterfacesFor(
 		}
 	}
 
-	outbounds = append(outbounds, dns.VIPOutbounds(pod.Name, dataplanes, vips, externalServicesRes)...)
+	resourceKey := model.ResourceKey{
+		Mesh: MeshFor(pod),
+		Name: pod.Name,
+	}
+	outbounds = append(outbounds, dns.VIPOutbounds(resourceKey, dataplanes, vips, externalServicesRes)...)
 	return outbounds, nil
 }
 
@@ -85,10 +97,17 @@ func isHeadlessService(svc *kube_core.Service) bool {
 	return svc.Spec.ClusterIP == "None"
 }
 
+func isServiceLess(port uint32) bool {
+	return port == mesh_proto.TCPPortReserved
+}
+
 func (p *PodConverter) k8sService(serviceTag string) (*kube_core.Service, uint32, error) {
-	name, ns, port, err := ParseService(serviceTag)
+	name, ns, port, err := parseService(serviceTag)
 	if err != nil {
-		return nil, 0, errors.Errorf("failed to parse `service` host %q as FQDN", serviceTag)
+		return nil, 0, errors.Wrapf(err, "failed to parse `service` host %q as FQDN", serviceTag)
+	}
+	if isServiceLess(port) {
+		return nil, port, nil
 	}
 
 	svc := &kube_core.Service{}
@@ -99,17 +118,24 @@ func (p *PodConverter) k8sService(serviceTag string) (*kube_core.Service, uint32
 	return svc, port, nil
 }
 
-func ParseService(host string) (name string, namespace string, port uint32, err error) {
+func parseService(host string) (name string, namespace string, port uint32, err error) {
 	// split host into <name>_<namespace>_svc_<port>
 	segments := strings.Split(host, "_")
-	if len(segments) != 4 {
+	switch len(segments) {
+	case 4:
+		p, err := strconv.Atoi(segments[3])
+		if err != nil {
+			return "", "", 0, err
+		}
+		port = uint32(p)
+	case 3:
+		// service less service names have no port, so we just put the reserved
+		// one here to note that this service is actually
+		port = mesh_proto.TCPPortReserved
+	default:
 		return "", "", 0, errors.Errorf("service tag in unexpected format")
 	}
-	p, err := strconv.Atoi(segments[3])
-	if err != nil {
-		return "", "", 0, err
-	}
-	port = uint32(p)
+
 	name, namespace = segments[0], segments[1]
 	return
 }
diff --git a/pkg/plugins/runtime/k8s/plugin.go b/pkg/plugins/runtime/k8s/plugin.go
index 4b8a608c0..f7b802601 100644
--- a/pkg/plugins/runtime/k8s/plugin.go
+++ b/pkg/plugins/runtime/k8s/plugin.go
@@ -248,7 +248,7 @@ func addValidators(mgr kube_ctrl.Manager, rt core_runtime.Runtime, converter k8s
 
 func addMutators(mgr kube_ctrl.Manager, rt core_runtime.Runtime, converter k8s_common.Converter) error {
 	if rt.Config().Mode != config_core.Global {
-		address := fmt.Sprintf("https://kuma-control-plane.%s:%d", rt.Config().Store.Kubernetes.SystemNamespace, rt.Config().DpServer.Port)
+		address := fmt.Sprintf("https://%s.%s:%d", rt.Config().Runtime.Kubernetes.ControlPlaneServiceName, rt.Config().Store.Kubernetes.SystemNamespace, rt.Config().DpServer.Port)
 		kumaInjector, err := injector.New(
 			rt.Config().Runtime.Kubernetes.Injector,
 			address,
diff --git a/pkg/plugins/runtime/universal/outbound/outbound.go b/pkg/plugins/runtime/universal/outbound/outbound.go
index 76f137641..94fe5e3aa 100644
--- a/pkg/plugins/runtime/universal/outbound/outbound.go
+++ b/pkg/plugins/runtime/universal/outbound/outbound.go
@@ -4,6 +4,8 @@ import (
 	"context"
 	"time"
 
+	"github.com/kumahq/kuma/pkg/core/resources/model"
+
 	"github.com/kumahq/kuma/pkg/core"
 	"github.com/kumahq/kuma/pkg/dns/resolver"
 
@@ -59,6 +61,18 @@ func (v *VIPOutboundsReconciler) Start(stop <-chan struct{}) error {
 }
 
 func (v *VIPOutboundsReconciler) UpdateVIPOutbounds(ctx context.Context) error {
+	// First get all ingresses
+	var ingresses []*mesh.DataplaneResource
+	dpList := &mesh.DataplaneResourceList{}
+	if err := v.rorm.List(ctx, dpList); err != nil {
+		return err
+	}
+	for _, dp := range dpList.Items {
+		if dp.Spec.IsIngress() {
+			ingresses = append(ingresses, dp)
+		}
+	}
+	// Then add outbounds to each Dataplane
 	meshes := &mesh.MeshResourceList{}
 	if err := v.rorm.List(ctx, meshes); err != nil {
 		return err
@@ -73,11 +87,16 @@ func (v *VIPOutboundsReconciler) UpdateVIPOutbounds(ctx context.Context) error {
 			return err
 		}
 		dpsUpdated := 0
+
+		allDps := make([]*mesh.DataplaneResource, len(ingresses)+len(dpList.Items))
+		copy(allDps[:len(ingresses)], ingresses)
+		copy(allDps[len(ingresses):], dpList.Items)
+
 		for _, dp := range dpList.Items {
 			if dp.Spec.Networking.GetTransparentProxying() == nil {
 				continue
 			}
-			newOutbounds := dns.VIPOutbounds(dp.Meta.GetName(), dpList.Items, v.resolver.GetVIPs(), externalServices.Items)
+			newOutbounds := dns.VIPOutbounds(model.MetaToResourceKey(dp.Meta), allDps, v.resolver.GetVIPs(), externalServices.Items)
 
 			if outboundsEqual(newOutbounds, dp.Spec.Networking.Outbound) {
 				continue
diff --git a/pkg/xds/generator/inbound_proxy_generator.go b/pkg/xds/generator/inbound_proxy_generator.go
index 173a81bae..cd27d1355 100644
--- a/pkg/xds/generator/inbound_proxy_generator.go
+++ b/pkg/xds/generator/inbound_proxy_generator.go
@@ -27,6 +27,11 @@ func (g InboundProxyGenerator) Generate(ctx xds_context.Context, proxy *model.Pr
 	}
 	resources := model.NewResourceSet()
 	for i, endpoint := range endpoints {
+		// we do not create inbounds for serviceless
+		if endpoint.IsServiceLess() {
+			continue
+		}
+
 		iface := proxy.Dataplane.Spec.Networking.Inbound[i]
 		protocol := mesh_core.ParseProtocol(iface.GetProtocol())
 
diff --git a/pkg/xds/hooks/hooks.go b/pkg/xds/hooks/hooks.go
new file mode 100644
index 000000000..1f2377a27
--- /dev/null
+++ b/pkg/xds/hooks/hooks.go
@@ -0,0 +1,13 @@
+package hooks
+
+type Hooks struct {
+	resourceSetHooks []ResourceSetHook
+}
+
+func (h *Hooks) AddResourceSetHook(hook ResourceSetHook) {
+	h.resourceSetHooks = append(h.resourceSetHooks, hook)
+}
+
+func (h *Hooks) ResourceSetHooks() []ResourceSetHook {
+	return h.resourceSetHooks
+}
diff --git a/pkg/xds/hooks/resource_set.go b/pkg/xds/hooks/resource_set.go
new file mode 100644
index 000000000..d611959ad
--- /dev/null
+++ b/pkg/xds/hooks/resource_set.go
@@ -0,0 +1,14 @@
+package hooks
+
+import (
+	core_xds "github.com/kumahq/kuma/pkg/core/xds"
+	xds_context "github.com/kumahq/kuma/pkg/xds/context"
+)
+
+// ResourceSetHook is a way to modify XDS resources generated by Kuma
+// Since resourceSet is an argument, you can add new, remove or modify the existing resources
+// To support V2 and V3, search the resource set for typeUrls for proper version
+// If you want to for example modify only inbound listeners, search for the resource origin of OriginInbound
+type ResourceSetHook interface {
+	Modify(resourceSet *core_xds.ResourceSet, ctx xds_context.Context, proxy *core_xds.Proxy) error
+}
diff --git a/pkg/xds/server/components.go b/pkg/xds/server/components.go
index 200367f62..7e47476ab 100644
--- a/pkg/xds/server/components.go
+++ b/pkg/xds/server/components.go
@@ -20,12 +20,13 @@ import (
 )
 
 var (
-	meshResources = meshResourceTypes(map[core_model.ResourceType]bool{
+	// HashMeshExcludedResources defines Mesh-scoped resources that are not used in XDS therefore when counting hash mesh we can skip them
+	HashMeshExcludedResources = map[core_model.ResourceType]bool{
 		core_mesh.DataplaneInsightType:  true,
 		core_mesh.DataplaneOverviewType: true,
 		core_mesh.ServiceInsightType:    true,
 		core_system.ConfigType:          true,
-	})
+	}
 )
 
 func meshResourceTypes(exclude map[core_model.ResourceType]bool) []core_model.ResourceType {
@@ -53,7 +54,7 @@ func RegisterXDS(rt core_runtime.Runtime, server *grpc.Server) error {
 	if err != nil {
 		return err
 	}
-	meshSnapshotCache, err := mesh.NewCache(rt.ReadOnlyResourceManager(), rt.Config().Store.Cache.ExpirationTime, meshResources, rt.LookupIP(), rt.Metrics())
+	meshSnapshotCache, err := mesh.NewCache(rt.ReadOnlyResourceManager(), rt.Config().Store.Cache.ExpirationTime, meshResourceTypes(HashMeshExcludedResources), rt.LookupIP(), rt.Metrics())
 	if err != nil {
 		return err
 	}
diff --git a/pkg/xds/server/v2/components.go b/pkg/xds/server/v2/components.go
index b9c75326c..b66345042 100644
--- a/pkg/xds/server/v2/components.go
+++ b/pkg/xds/server/v2/components.go
@@ -73,6 +73,7 @@ func RegisterXDS(
 func DefaultReconciler(rt core_runtime.Runtime, xdsContext v2.XdsContext) xds_sync.SnapshotReconciler {
 	return &reconciler{
 		&templateSnapshotGenerator{
+			ResourceSetHooks: rt.XDSHooks().ResourceSetHooks(),
 			ProxyTemplateResolver: &xds_template.SimpleProxyTemplateResolver{
 				ReadOnlyResourceManager: rt.ReadOnlyResourceManager(),
 				DefaultProxyTemplate:    xds_template.DefaultProxyTemplate,
@@ -85,6 +86,7 @@ func DefaultReconciler(rt core_runtime.Runtime, xdsContext v2.XdsContext) xds_sy
 func DefaultIngressReconciler(rt core_runtime.Runtime, xdsContext v2.XdsContext) xds_sync.SnapshotReconciler {
 	return &reconciler{
 		generator: &templateSnapshotGenerator{
+			ResourceSetHooks: rt.XDSHooks().ResourceSetHooks(),
 			ProxyTemplateResolver: &xds_template.StaticProxyTemplateResolver{
 				Template: xds_template.IngressProxyTemplate,
 			},
diff --git a/pkg/xds/server/v2/reconcile.go b/pkg/xds/server/v2/reconcile.go
index 829155195..fe495dd58 100644
--- a/pkg/xds/server/v2/reconcile.go
+++ b/pkg/xds/server/v2/reconcile.go
@@ -2,11 +2,13 @@ package v2
 
 import (
 	"github.com/golang/protobuf/proto"
+	"github.com/pkg/errors"
 
 	"github.com/kumahq/kuma/pkg/core"
 	model "github.com/kumahq/kuma/pkg/core/xds"
 	xds_context "github.com/kumahq/kuma/pkg/xds/context"
 	"github.com/kumahq/kuma/pkg/xds/generator"
+	xds_hooks "github.com/kumahq/kuma/pkg/xds/hooks"
 	xds_sync "github.com/kumahq/kuma/pkg/xds/sync"
 	xds_template "github.com/kumahq/kuma/pkg/xds/template"
 
@@ -93,6 +95,7 @@ type snapshotGenerator interface {
 
 type templateSnapshotGenerator struct {
 	ProxyTemplateResolver xds_template.ProxyTemplateResolver
+	ResourceSetHooks      []xds_hooks.ResourceSetHook
 }
 
 func (s *templateSnapshotGenerator) GenerateSnapshot(ctx xds_context.Context, proxy *model.Proxy) (envoy_cache.Snapshot, error) {
@@ -105,6 +108,11 @@ func (s *templateSnapshotGenerator) GenerateSnapshot(ctx xds_context.Context, pr
 		reconcileLog.Error(err, "failed to generate a snapshot", "proxy", proxy, "template", template)
 		return envoy_cache.Snapshot{}, err
 	}
+	for _, hook := range s.ResourceSetHooks {
+		if err := hook.Modify(rs, ctx, proxy); err != nil {
+			return envoy_cache.Snapshot{}, errors.Wrapf(err, "could not apply hook %T", hook)
+		}
+	}
 
 	version := "" // empty value is a sign to other components to generate the version automatically
 	out := envoy_cache.Snapshot{
diff --git a/pkg/xds/server/v3/components.go b/pkg/xds/server/v3/components.go
index 857f3d9f6..46e5e4df9 100644
--- a/pkg/xds/server/v3/components.go
+++ b/pkg/xds/server/v3/components.go
@@ -73,6 +73,7 @@ func RegisterXDS(
 func DefaultReconciler(rt core_runtime.Runtime, xdsContext v3.XdsContext) xds_sync.SnapshotReconciler {
 	return &reconciler{
 		&templateSnapshotGenerator{
+			ResourceSetHooks: rt.XDSHooks().ResourceSetHooks(),
 			ProxyTemplateResolver: &xds_template.SimpleProxyTemplateResolver{
 				ReadOnlyResourceManager: rt.ReadOnlyResourceManager(),
 				DefaultProxyTemplate:    xds_template.DefaultProxyTemplate,
@@ -85,6 +86,7 @@ func DefaultReconciler(rt core_runtime.Runtime, xdsContext v3.XdsContext) xds_sy
 func DefaultIngressReconciler(rt core_runtime.Runtime, xdsContext v3.XdsContext) xds_sync.SnapshotReconciler {
 	return &reconciler{
 		generator: &templateSnapshotGenerator{
+			ResourceSetHooks: rt.XDSHooks().ResourceSetHooks(),
 			ProxyTemplateResolver: &xds_template.StaticProxyTemplateResolver{
 				Template: xds_template.IngressProxyTemplate,
 			},
diff --git a/pkg/xds/server/v3/reconcile.go b/pkg/xds/server/v3/reconcile.go
index 47cb5c33b..5c7ad7254 100644
--- a/pkg/xds/server/v3/reconcile.go
+++ b/pkg/xds/server/v3/reconcile.go
@@ -2,11 +2,13 @@ package v3
 
 import (
 	"github.com/golang/protobuf/proto"
+	"github.com/pkg/errors"
 
 	"github.com/kumahq/kuma/pkg/core"
 	model "github.com/kumahq/kuma/pkg/core/xds"
 	xds_context "github.com/kumahq/kuma/pkg/xds/context"
 	"github.com/kumahq/kuma/pkg/xds/generator"
+	xds_hooks "github.com/kumahq/kuma/pkg/xds/hooks"
 	xds_sync "github.com/kumahq/kuma/pkg/xds/sync"
 	xds_template "github.com/kumahq/kuma/pkg/xds/template"
 
@@ -93,6 +95,7 @@ type snapshotGenerator interface {
 
 type templateSnapshotGenerator struct {
 	ProxyTemplateResolver xds_template.ProxyTemplateResolver
+	ResourceSetHooks      []xds_hooks.ResourceSetHook
 }
 
 func (s *templateSnapshotGenerator) GenerateSnapshot(ctx xds_context.Context, proxy *model.Proxy) (envoy_cache.Snapshot, error) {
@@ -105,6 +108,11 @@ func (s *templateSnapshotGenerator) GenerateSnapshot(ctx xds_context.Context, pr
 		reconcileLog.Error(err, "failed to generate a snapshot", "proxy", proxy, "template", template)
 		return envoy_cache.Snapshot{}, err
 	}
+	for _, hook := range s.ResourceSetHooks {
+		if err := hook.Modify(rs, ctx, proxy); err != nil {
+			return envoy_cache.Snapshot{}, errors.Wrapf(err, "could not apply hook %T", hook)
+		}
+	}
 
 	version := "" // empty value is a sign to other components to generate the version automatically
 	out := envoy_cache.Snapshot{


Test patch:
diff --git a/app/kuma-dp/cmd/root_test.go b/app/kuma-dp/cmd/root_test.go
index 2e9839fb4..6de0e9bf1 100644
--- a/app/kuma-dp/cmd/root_test.go
+++ b/app/kuma-dp/cmd/root_test.go
@@ -8,7 +8,7 @@ import (
 var _ = Describe("root", func() {
 	It("should be possible to run `kuma-dp` without a sub-command", func() {
 		// given
-		cmd := newRootCmd()
+		cmd := NewRootCmd(DefaultRootContext())
 		cmd.SetArgs([]string{})
 		// when
 		err := cmd.Execute()
diff --git a/app/kuma-dp/cmd/run_test.go b/app/kuma-dp/cmd/run_test.go
index c5dcbd687..90afe22f2 100644
--- a/app/kuma-dp/cmd/run_test.go
+++ b/app/kuma-dp/cmd/run_test.go
@@ -29,20 +29,12 @@ import (
 var _ = Describe("run", func() {
 
 	var backupSetupSignalHandler func() <-chan struct{}
-	var backupBootstrapGenerator envoy.BootstrapConfigFactoryFunc
 
 	BeforeEach(func() {
 		backupSetupSignalHandler = core.SetupSignalHandler
-		backupBootstrapGenerator = bootstrapGenerator
-		bootstrapGenerator = func(_ string, cfg kumadp.Config, _ *rest.Resource, _ types.BootstrapVersion, version envoy.EnvoyVersion) ([]byte, types.BootstrapVersion, error) {
-			respBytes, err := ioutil.ReadFile(filepath.Join("testdata", "bootstrap-config.golden.yaml"))
-			Expect(err).ToNot(HaveOccurred())
-			return respBytes, "", nil
-		}
 	})
 	AfterEach(func() {
 		core.SetupSignalHandler = backupSetupSignalHandler
-		bootstrapGenerator = backupBootstrapGenerator
 	})
 
 	var stopCh chan struct{}
@@ -113,7 +105,13 @@ var _ = Describe("run", func() {
 			}
 
 			// given
-			cmd := newRootCmd()
+			rootCtx := DefaultRootContext()
+			rootCtx.BootstrapGenerator = func(_ string, cfg kumadp.Config, _ *rest.Resource, _ types.BootstrapVersion, version envoy.EnvoyVersion) ([]byte, types.BootstrapVersion, error) {
+				respBytes, err := ioutil.ReadFile(filepath.Join("testdata", "bootstrap-config.golden.yaml"))
+				Expect(err).ToNot(HaveOccurred())
+				return respBytes, "", nil
+			}
+			cmd := NewRootCmd(rootCtx)
 			cmd.SetArgs(append([]string{"run"}, given.args...))
 			cmd.SetOut(&bytes.Buffer{})
 			cmd.SetErr(&bytes.Buffer{})
@@ -305,7 +303,7 @@ var _ = Describe("run", func() {
 		defer l.Close()
 
 		// given
-		cmd := newRootCmd()
+		cmd := NewRootCmd(DefaultRootContext())
 		cmd.SetArgs([]string{
 			"run",
 			"--cp-address", "http://localhost:1234",
diff --git a/app/kumactl/cmd/completion/completion_test.go b/app/kumactl/cmd/completion/completion_test.go
index 8d8fe3186..76f22b056 100644
--- a/app/kumactl/cmd/completion/completion_test.go
+++ b/app/kumactl/cmd/completion/completion_test.go
@@ -2,7 +2,6 @@ package completion_test
 
 import (
 	"bytes"
-	"io/ioutil"
 	"path/filepath"
 
 	. "github.com/onsi/ginkgo"
@@ -10,7 +9,7 @@ import (
 	. "github.com/onsi/gomega"
 
 	"github.com/kumahq/kuma/app/kumactl/cmd"
-	"github.com/kumahq/kuma/pkg/test/golden"
+	. "github.com/kumahq/kuma/pkg/test/matchers"
 )
 
 var _ = Describe("kumactl completion", func() {
@@ -43,17 +42,9 @@ var _ = Describe("kumactl completion", func() {
 			Expect(err).ToNot(HaveOccurred())
 			Expect(stderr.Bytes()).To(BeNil())
 
-			// and output matches golden files
+			// and
 			actual := stdout.Bytes()
-			goldenFilePath := filepath.Join("testdata", given.goldenFile)
-			if golden.UpdateGoldenFiles() {
-				err := ioutil.WriteFile(goldenFilePath, actual, 0664)
-				Expect(err).ToNot(HaveOccurred())
-			}
-			expected, err := ioutil.ReadFile(goldenFilePath)
-			Expect(err).ToNot(HaveOccurred())
-			Expect(len(actual)).To(Equal(len(expected)), golden.RerunMsg)
-			Expect(string(actual)).To(Equal(string(expected)))
+			Expect(actual).To(MatchGoldenEqual(filepath.Join("testdata", given.goldenFile)))
 		},
 		Entry("should generate bash completion code", testCase{
 			extraArgs: []string{
diff --git a/app/kumactl/cmd/install/install_control_plane_test.go b/app/kumactl/cmd/install/install_control_plane_test.go
index 8cbe78f68..b6fbca15d 100644
--- a/app/kumactl/cmd/install/install_control_plane_test.go
+++ b/app/kumactl/cmd/install/install_control_plane_test.go
@@ -2,18 +2,14 @@ package install_test
 
 import (
 	"bytes"
-	"io/ioutil"
 	"path/filepath"
 
-	"github.com/kumahq/kuma/app/kumactl/cmd"
-	kumactl_cmd "github.com/kumahq/kuma/app/kumactl/pkg/cmd"
-	"github.com/kumahq/kuma/app/kumactl/pkg/install/data"
-	"github.com/kumahq/kuma/pkg/test/golden"
-
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/ginkgo/extensions/table"
 	. "github.com/onsi/gomega"
 
+	"github.com/kumahq/kuma/app/kumactl/cmd"
+	kumactl_cmd "github.com/kumahq/kuma/app/kumactl/pkg/cmd"
 	"github.com/kumahq/kuma/pkg/tls"
 	kuma_version "github.com/kumahq/kuma/pkg/version"
 )
@@ -79,21 +75,7 @@ var _ = Describe("kumactl install control-plane", func() {
 
 			// and output matches golden files
 			actual := stdout.Bytes()
-			actualManifests := data.SplitYAML(data.File{Data: actual})
-
-			goldenFilePath := filepath.Join("testdata", given.goldenFile)
-			if golden.UpdateGoldenFiles() {
-				err := ioutil.WriteFile(goldenFilePath, actual, 0664)
-				Expect(err).ToNot(HaveOccurred())
-			}
-			expected, err := ioutil.ReadFile(goldenFilePath)
-			Expect(err).ToNot(HaveOccurred())
-			expectedManifests := data.SplitYAML(data.File{Data: expected})
-
-			Expect(len(actualManifests)).To(Equal(len(expectedManifests)), golden.RerunMsg)
-			for i := range expectedManifests {
-				Expect(actualManifests[i]).To(MatchYAML(expectedManifests[i]), golden.RerunMsg)
-			}
+			ExpectMatchesGoldenFiles(actual, filepath.Join("testdata", given.goldenFile))
 		},
 		Entry("should generate Kubernetes resources with default settings", testCase{
 			extraArgs: []string{
diff --git a/app/kumactl/cmd/install/install_helpers_test.go b/app/kumactl/cmd/install/install_helpers_test.go
new file mode 100644
index 000000000..ab4d7afb1
--- /dev/null
+++ b/app/kumactl/cmd/install/install_helpers_test.go
@@ -0,0 +1,27 @@
+package install_test
+
+import (
+	"io/ioutil"
+
+	"github.com/kumahq/kuma/app/kumactl/pkg/install/data"
+	"github.com/kumahq/kuma/pkg/test/golden"
+
+	. "github.com/onsi/gomega"
+)
+
+func ExpectMatchesGoldenFiles(actual []byte, goldenFilePath string) {
+	actualManifests := data.SplitYAML(data.File{Data: actual})
+
+	if golden.UpdateGoldenFiles() {
+		err := ioutil.WriteFile(goldenFilePath, actual, 0664)
+		Expect(err).ToNot(HaveOccurred())
+	}
+	expected, err := ioutil.ReadFile(goldenFilePath)
+	Expect(err).ToNot(HaveOccurred())
+	expectedManifests := data.SplitYAML(data.File{Data: expected})
+
+	Expect(len(actualManifests)).To(Equal(len(expectedManifests)), golden.RerunMsg)
+	for i := range expectedManifests {
+		Expect(actualManifests[i]).To(MatchYAML(expectedManifests[i]), golden.RerunMsg)
+	}
+}
diff --git a/app/kumactl/cmd/install/install_logging_test.go b/app/kumactl/cmd/install/install_logging_test.go
index dc4e7b2a8..2159a6ce3 100644
--- a/app/kumactl/cmd/install/install_logging_test.go
+++ b/app/kumactl/cmd/install/install_logging_test.go
@@ -2,7 +2,6 @@ package install_test
 
 import (
 	"bytes"
-	"io/ioutil"
 	"path/filepath"
 
 	kuma_version "github.com/kumahq/kuma/pkg/version"
@@ -12,7 +11,6 @@ import (
 	. "github.com/onsi/gomega"
 
 	"github.com/kumahq/kuma/app/kumactl/cmd"
-	"github.com/kumahq/kuma/app/kumactl/pkg/install/data"
 )
 
 var _ = Describe("kumactl install logging", func() {
@@ -49,31 +47,14 @@ var _ = Describe("kumactl install logging", func() {
 
 			// when
 			err := rootCmd.Execute()
-			// then
-			Expect(err).ToNot(HaveOccurred())
-			// and
-			Expect(stderr.Bytes()).To(BeNil())
 
-			// when
-			expected, err := ioutil.ReadFile(filepath.Join("testdata", given.goldenFile))
 			// then
 			Expect(err).ToNot(HaveOccurred())
-			// and
-			expectedManifests := data.SplitYAML(data.File{Data: expected})
+			Expect(stderr.Bytes()).To(BeNil())
 
-			// when
+			// and output matches golden files
 			actual := stdout.Bytes()
-			// then
-			Expect(actual).To(MatchYAML(expected))
-			// and
-			actualManifests := data.SplitYAML(data.File{Data: actual})
-
-			// and
-			Expect(len(actualManifests)).To(Equal(len(expectedManifests)))
-			// and
-			for i := range expectedManifests {
-				Expect(actualManifests[i]).To(MatchYAML(expectedManifests[i]))
-			}
+			ExpectMatchesGoldenFiles(actual, filepath.Join("testdata", given.goldenFile))
 		},
 		Entry("should generate Kubernetes resources with default settings", testCase{
 			extraArgs:  nil,
diff --git a/app/kumactl/cmd/install/install_metrics_test.go b/app/kumactl/cmd/install/install_metrics_test.go
index a4b628068..9dc52d251 100644
--- a/app/kumactl/cmd/install/install_metrics_test.go
+++ b/app/kumactl/cmd/install/install_metrics_test.go
@@ -2,7 +2,6 @@ package install_test
 
 import (
 	"bytes"
-	"io/ioutil"
 	"path/filepath"
 
 	. "github.com/onsi/ginkgo"
@@ -11,7 +10,6 @@ import (
 
 	"github.com/kumahq/kuma/app/kumactl/cmd"
 	"github.com/kumahq/kuma/app/kumactl/cmd/install"
-	"github.com/kumahq/kuma/app/kumactl/pkg/install/data"
 	kuma_version "github.com/kumahq/kuma/pkg/version"
 )
 
@@ -50,31 +48,14 @@ var _ = Describe("kumactl install metrics", func() {
 
 			// when
 			err := rootCmd.Execute()
-			// then
-			Expect(err).ToNot(HaveOccurred())
-			// and
-			Expect(stderr.Bytes()).To(BeNil())
 
-			// when
-			expected, err := ioutil.ReadFile(filepath.Join("testdata", given.goldenFile))
 			// then
 			Expect(err).ToNot(HaveOccurred())
-			// and
-			expectedManifests := data.SplitYAML(data.File{Data: expected})
+			Expect(stderr.Bytes()).To(BeNil())
 
-			// when
+			// and output matches golden files
 			actual := stdout.Bytes()
-			// then
-			Expect(actual).To(MatchYAML(expected))
-			// and
-			actualManifests := data.SplitYAML(data.File{Data: actual})
-
-			// and
-			Expect(len(actualManifests)).To(Equal(len(expectedManifests)))
-			// and
-			for i := range expectedManifests {
-				Expect(actualManifests[i]).To(MatchYAML(expectedManifests[i]))
-			}
+			ExpectMatchesGoldenFiles(actual, filepath.Join("testdata", given.goldenFile))
 		},
 		Entry("should generate Kubernetes resources with default settings", testCase{
 			extraArgs:  nil,
diff --git a/app/kumactl/cmd/install/install_tracing_test.go b/app/kumactl/cmd/install/install_tracing_test.go
index fe64ffc98..cdf5304d0 100644
--- a/app/kumactl/cmd/install/install_tracing_test.go
+++ b/app/kumactl/cmd/install/install_tracing_test.go
@@ -2,7 +2,6 @@ package install_test
 
 import (
 	"bytes"
-	"io/ioutil"
 	"path/filepath"
 
 	. "github.com/onsi/ginkgo"
@@ -10,7 +9,6 @@ import (
 	. "github.com/onsi/gomega"
 
 	"github.com/kumahq/kuma/app/kumactl/cmd"
-	"github.com/kumahq/kuma/app/kumactl/pkg/install/data"
 )
 
 var _ = Describe("kumactl install tracing", func() {
@@ -38,31 +36,14 @@ var _ = Describe("kumactl install tracing", func() {
 
 			// when
 			err := rootCmd.Execute()
-			// then
-			Expect(err).ToNot(HaveOccurred())
-			// and
-			Expect(stderr.Bytes()).To(BeNil())
 
-			// when
-			expected, err := ioutil.ReadFile(filepath.Join("testdata", given.goldenFile))
 			// then
 			Expect(err).ToNot(HaveOccurred())
-			// and
-			expectedManifests := data.SplitYAML(data.File{Data: expected})
+			Expect(stderr.Bytes()).To(BeNil())
 
-			// when
+			// and output matches golden files
 			actual := stdout.Bytes()
-			// then
-			Expect(actual).To(MatchYAML(expected))
-			// and
-			actualManifests := data.SplitYAML(data.File{Data: actual})
-
-			// and
-			Expect(len(actualManifests)).To(Equal(len(expectedManifests)))
-			// and
-			for i := range expectedManifests {
-				Expect(actualManifests[i]).To(MatchYAML(expectedManifests[i]))
-			}
+			ExpectMatchesGoldenFiles(actual, filepath.Join("testdata", given.goldenFile))
 		},
 		Entry("should generate Kubernetes resources with default settings", testCase{
 			extraArgs:  nil,
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.cni-enabled.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.cni-enabled.golden.yaml
index d7579a3be..885c7de47 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.cni-enabled.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.cni-enabled.golden.yaml
@@ -7145,6 +7145,8 @@ spec:
               value: "/var/run/secrets/kuma.io/tls-cert"
             - name: KUMA_RUNTIME_KUBERNETES_ADMISSION_SERVER_PORT
               value: "5443"
+            - name: KUMA_RUNTIME_KUBERNETES_CONTROL_PLANE_SERVICE_NAME
+              value: "kuma-control-plane"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CA_CERT_FILE
               value: "/var/run/secrets/kuma.io/tls-cert/ca.crt"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CNI_ENABLED
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml
index 11e38d3f3..29d7ea0aa 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml
@@ -6978,6 +6978,8 @@ spec:
               value: "/var/run/secrets/kuma.io/tls-cert"
             - name: KUMA_RUNTIME_KUBERNETES_ADMISSION_SERVER_PORT
               value: "5443"
+            - name: KUMA_RUNTIME_KUBERNETES_CONTROL_PLANE_SERVICE_NAME
+              value: "kuma-control-plane"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CA_CERT_FILE
               value: "/var/run/secrets/kuma.io/tls-cert/ca.crt"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CNI_ENABLED
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.global.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.global.golden.yaml
index 2f4644849..1853334c1 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.global.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.global.golden.yaml
@@ -6987,6 +6987,8 @@ spec:
               value: "/var/run/secrets/kuma.io/tls-cert"
             - name: KUMA_RUNTIME_KUBERNETES_ADMISSION_SERVER_PORT
               value: "5443"
+            - name: KUMA_RUNTIME_KUBERNETES_CONTROL_PLANE_SERVICE_NAME
+              value: "kuma-control-plane"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CA_CERT_FILE
               value: "/var/run/secrets/kuma.io/tls-cert/ca.crt"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CNI_ENABLED
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.override-env-vars.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.override-env-vars.golden.yaml
index 9098629ad..5eef30d43 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.override-env-vars.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.override-env-vars.golden.yaml
@@ -6978,6 +6978,8 @@ spec:
               value: "/var/run/secrets/kuma.io/tls-cert"
             - name: KUMA_RUNTIME_KUBERNETES_ADMISSION_SERVER_PORT
               value: "5443"
+            - name: KUMA_RUNTIME_KUBERNETES_CONTROL_PLANE_SERVICE_NAME
+              value: "kuma-control-plane"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CA_CERT_FILE
               value: "/var/run/secrets/kuma.io/tls-cert/ca.crt"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CNI_ENABLED
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.overrides.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.overrides.golden.yaml
index 45241996a..98c5b022c 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.overrides.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.overrides.golden.yaml
@@ -6998,6 +6998,8 @@ spec:
               value: "/var/run/secrets/kuma.io/tls-cert"
             - name: KUMA_RUNTIME_KUBERNETES_ADMISSION_SERVER_PORT
               value: "5443"
+            - name: KUMA_RUNTIME_KUBERNETES_CONTROL_PLANE_SERVICE_NAME
+              value: "kuma-ctrl-plane"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CA_CERT_FILE
               value: "/var/run/secrets/kuma.io/tls-cert/ca.crt"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CNI_ENABLED
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.remote.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.remote.golden.yaml
index 1af332819..06c4fe116 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.remote.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.remote.golden.yaml
@@ -6986,6 +6986,8 @@ spec:
               value: "/var/run/secrets/kuma.io/tls-cert"
             - name: KUMA_RUNTIME_KUBERNETES_ADMISSION_SERVER_PORT
               value: "5443"
+            - name: KUMA_RUNTIME_KUBERNETES_CONTROL_PLANE_SERVICE_NAME
+              value: "kuma-control-plane"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CA_CERT_FILE
               value: "/var/run/secrets/kuma.io/tls-cert/ca.crt"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CNI_ENABLED
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.with-ingress.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.with-ingress.golden.yaml
index 6bb235e28..5f879cc73 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.with-ingress.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.with-ingress.golden.yaml
@@ -7007,6 +7007,8 @@ spec:
               value: "/var/run/secrets/kuma.io/tls-cert"
             - name: KUMA_RUNTIME_KUBERNETES_ADMISSION_SERVER_PORT
               value: "5443"
+            - name: KUMA_RUNTIME_KUBERNETES_CONTROL_PLANE_SERVICE_NAME
+              value: "kuma-control-plane"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CA_CERT_FILE
               value: "/var/run/secrets/kuma.io/tls-cert/ca.crt"
             - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CNI_ENABLED
diff --git a/app/kumactl/cmd/install/testdata/install-logging.defaults.golden.yaml b/app/kumactl/cmd/install/testdata/install-logging.defaults.golden.yaml
index dc5c9fdb0..1b16eae79 100644
--- a/app/kumactl/cmd/install/testdata/install-logging.defaults.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-logging.defaults.golden.yaml
@@ -687,4 +687,4 @@ spec:
           secret:
             secretName: loki
         - name: storage
-          emptyDir: {}
+          emptyDir: {}
\ No newline at end of file
diff --git a/app/kumactl/cmd/install/testdata/install-logging.overrides.golden.yaml b/app/kumactl/cmd/install/testdata/install-logging.overrides.golden.yaml
index bb168a7df..cbd1c1195 100644
--- a/app/kumactl/cmd/install/testdata/install-logging.overrides.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-logging.overrides.golden.yaml
@@ -687,4 +687,4 @@ spec:
           secret:
             secretName: loki
         - name: storage
-          emptyDir: {}
+          emptyDir: {}
\ No newline at end of file
diff --git a/app/kumactl/cmd/install/testdata/install-metrics.defaults.golden.yaml b/app/kumactl/cmd/install/testdata/install-metrics.defaults.golden.yaml
index fc468fafa..074056655 100644
--- a/app/kumactl/cmd/install/testdata/install-metrics.defaults.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-metrics.defaults.golden.yaml
@@ -2515,7 +2515,7 @@ data:
       "version": 1,
       "description": "Statistics of a single Dataplane in Kuma Service Mesh"
     }
-
+    
   kuma-mesh.json: |
     {
       "__inputs": [
@@ -3265,7 +3265,7 @@ data:
       "version": 1,
       "description": "Statistics of the single Mesh in Kuma Service Mesh"
     }
-
+    
   kuma-service-to-service.json: |
     {
       "__inputs": [
@@ -9548,4 +9548,4 @@ spec:
           persistentVolumeClaim:
             claimName: prometheus-server
         - name: kuma-prometheus-sd-volume
-          emptyDir: {}
+          emptyDir: {}
\ No newline at end of file
diff --git a/app/kumactl/cmd/install/testdata/install-metrics.no-grafana.golden.yaml b/app/kumactl/cmd/install/testdata/install-metrics.no-grafana.golden.yaml
index c8563668b..312995013 100644
--- a/app/kumactl/cmd/install/testdata/install-metrics.no-grafana.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-metrics.no-grafana.golden.yaml
@@ -999,4 +999,4 @@ spec:
             name: prometheus-alertmanager
         - name: storage-volume
           persistentVolumeClaim:
-            claimName: prometheus-alertmanager
+            claimName: prometheus-alertmanager
\ No newline at end of file
diff --git a/app/kumactl/cmd/install/testdata/install-metrics.no-prometheus.golden.yaml b/app/kumactl/cmd/install/testdata/install-metrics.no-prometheus.golden.yaml
index cfde28e10..64862c52f 100644
--- a/app/kumactl/cmd/install/testdata/install-metrics.no-prometheus.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-metrics.no-prometheus.golden.yaml
@@ -2451,7 +2451,7 @@ data:
       "version": 1,
       "description": "Statistics of a single Dataplane in Kuma Service Mesh"
     }
-
+    
   kuma-mesh.json: |
     {
       "__inputs": [
@@ -3201,7 +3201,7 @@ data:
       "version": 1,
       "description": "Statistics of the single Mesh in Kuma Service Mesh"
     }
-
+    
   kuma-service-to-service.json: |
     {
       "__inputs": [
@@ -8555,4 +8555,4 @@ spec:
           configMap:
             name: provisioning-dashboards
         - name: storage
-          emptyDir: {}
+          emptyDir: {}
\ No newline at end of file
diff --git a/app/kumactl/cmd/install/testdata/install-metrics.overrides.golden.yaml b/app/kumactl/cmd/install/testdata/install-metrics.overrides.golden.yaml
index 247fbe5c8..5585f5b71 100644
--- a/app/kumactl/cmd/install/testdata/install-metrics.overrides.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-metrics.overrides.golden.yaml
@@ -2515,7 +2515,7 @@ data:
       "version": 1,
       "description": "Statistics of a single Dataplane in Kuma Service Mesh"
     }
-
+    
   kuma-mesh.json: |
     {
       "__inputs": [
@@ -3265,7 +3265,7 @@ data:
       "version": 1,
       "description": "Statistics of the single Mesh in Kuma Service Mesh"
     }
-
+    
   kuma-service-to-service.json: |
     {
       "__inputs": [
@@ -9548,4 +9548,4 @@ spec:
           persistentVolumeClaim:
             claimName: prometheus-server
         - name: kuma-prometheus-sd-volume
-          emptyDir: {}
+          emptyDir: {}
\ No newline at end of file
diff --git a/app/kumactl/cmd/install/testdata/install-tracing.defaults.golden.yaml b/app/kumactl/cmd/install/testdata/install-tracing.defaults.golden.yaml
index 77f802533..8f81a5734 100644
--- a/app/kumactl/cmd/install/testdata/install-tracing.defaults.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-tracing.defaults.golden.yaml
@@ -5,6 +5,22 @@ kind: Namespace
 metadata:
   name: kuma-tracing
 ---
+# Based on https://github.com/jaegertracing/jaeger-kubernetes/blob/master/all-in-one/jaeger-all-in-one-template.yml
+
+#
+# Copyright 2017-2019 The Jaeger Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+# in compliance with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License
+# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+# or implied. See the License for the specific language governing permissions and limitations under
+# the License.
+#
+
 apiVersion: v1
 kind: List
 items:
@@ -18,10 +34,10 @@ items:
         app.kubernetes.io/name: jaeger
         app.kubernetes.io/component: all-in-one
     spec:
+      replicas: 1
       selector:
         matchLabels:
           app: jaeger
-      replicas: 1
       strategy:
         type: Recreate
       template:
@@ -165,4 +181,4 @@ items:
       clusterIP: None
       selector:
         app.kubernetes.io/name: jaeger
-        app.kubernetes.io/component: all-in-one
+        app.kubernetes.io/component: all-in-one
\ No newline at end of file
diff --git a/app/kumactl/cmd/install/testdata/install-tracing.overrides.golden.yaml b/app/kumactl/cmd/install/testdata/install-tracing.overrides.golden.yaml
index 747c9fd71..92e54dbf3 100644
--- a/app/kumactl/cmd/install/testdata/install-tracing.overrides.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-tracing.overrides.golden.yaml
@@ -5,6 +5,22 @@ kind: Namespace
 metadata:
   name: kuma
 ---
+# Based on https://github.com/jaegertracing/jaeger-kubernetes/blob/master/all-in-one/jaeger-all-in-one-template.yml
+
+#
+# Copyright 2017-2019 The Jaeger Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+# in compliance with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License
+# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+# or implied. See the License for the specific language governing permissions and limitations under
+# the License.
+#
+
 apiVersion: v1
 kind: List
 items:
@@ -18,10 +34,10 @@ items:
         app.kubernetes.io/name: jaeger
         app.kubernetes.io/component: all-in-one
     spec:
+      replicas: 1
       selector:
         matchLabels:
           app: jaeger
-      replicas: 1
       strategy:
         type: Recreate
       template:
@@ -165,4 +181,4 @@ items:
       clusterIP: None
       selector:
         app.kubernetes.io/name: jaeger
-        app.kubernetes.io/component: all-in-one
+        app.kubernetes.io/component: all-in-one
\ No newline at end of file
diff --git a/mk/e2e.new.mk b/mk/e2e.new.mk
index 0e57a8631..791589c8c 100644
--- a/mk/e2e.new.mk
+++ b/mk/e2e.new.mk
@@ -41,11 +41,12 @@ test/e2e/kind/start: $(K8SCLUSTERS_START_TARGETS)
 test/e2e/kind/stop: $(K8SCLUSTERS_STOP_TARGETS)
 
 .PHONY: test/e2e/test
+test/e2e/test: PKG_LIST=./test/e2e/...
 test/e2e/test:
 	K8SCLUSTERS="$(K8SCLUSTERS)" \
 	KUMACTLBIN=${BUILD_ARTIFACTS_DIR}/kumactl/kumactl \
 	API_VERSION="$(API_VERSION)" \
-		$(GO_TEST) -v -timeout=45m ./test/e2e/...
+		$(GO_TEST) -v -timeout=45m $(PKG_LIST)
 
 # test/e2e/debug is used for quicker feedback of E2E tests (ex. debugging flaky tests)
 # It runs tests with fail fast which means you don't have to wait for all tests to get information that something failed
@@ -53,12 +54,13 @@ test/e2e/test:
 # GINKGO_EDITOR_INTEGRATION is required to work with focused test. Normally they exit with non 0 code which prevents clusters to be cleaned up.
 # We run ginkgo instead of "go test" to fail fast (builtin "go test" fail fast does not seem to work with individual ginkgo tests)
 .PHONY: test/e2e/debug
+test/e2e/debug: PKG_LIST=./test/e2e/...
 test/e2e/debug: build/kumactl images docker/build/universal test/e2e/kind/start
 	K8SCLUSTERS="$(K8SCLUSTERS)" \
 	KUMACTLBIN=${BUILD_ARTIFACTS_DIR}/kumactl/kumactl \
 	API_VERSION="$(API_VERSION)" \
 	GINKGO_EDITOR_INTEGRATION=true \
-		ginkgo --failFast $(GOFLAGS) $(LD_FLAGS) ./test/e2e/...
+		ginkgo --failFast $(GOFLAGS) $(LD_FLAGS) $(PKG_LIST)
 	$(MAKE) test/e2e/kind/stop
 
 .PHONY: test/e2e
diff --git a/pkg/api-server/config_ws_test.go b/pkg/api-server/config_ws_test.go
index 00461af94..0919ae7f8 100644
--- a/pkg/api-server/config_ws_test.go
+++ b/pkg/api-server/config_ws_test.go
@@ -147,6 +147,7 @@ var _ = Describe("Config WS", func() {
           },
           "runtime": {
             "kubernetes": {
+              "controlPlaneServiceName": "kuma-control-plane",
               "admissionServer": {
                 "address": "",
                 "certDir": "",
diff --git a/pkg/config/loader_test.go b/pkg/config/loader_test.go
index 5f2497f51..5c89a2f49 100644
--- a/pkg/config/loader_test.go
+++ b/pkg/config/loader_test.go
@@ -134,6 +134,8 @@ var _ = Describe("Config loader", func() {
 			Expect(cfg.MonitoringAssignmentServer.GrpcPort).To(Equal(uint32(3333)))
 			Expect(cfg.MonitoringAssignmentServer.AssignmentRefreshInterval).To(Equal(12 * time.Second))
 
+			Expect(cfg.Runtime.Kubernetes.ControlPlaneServiceName).To(Equal("custom-control-plane"))
+
 			Expect(cfg.Runtime.Kubernetes.AdmissionServer.Address).To(Equal("127.0.0.2"))
 			Expect(cfg.Runtime.Kubernetes.AdmissionServer.Port).To(Equal(uint32(9443)))
 			Expect(cfg.Runtime.Kubernetes.AdmissionServer.CertDir).To(Equal("/var/run/secrets/kuma.io/kuma-admission-server/tls-cert"))
@@ -291,6 +293,7 @@ runtime:
   universal:
     dataplaneCleanupAge: 1h
   kubernetes:
+    controlPlaneServiceName: custom-control-plane
     admissionServer:
       address: 127.0.0.2
       port: 9443
@@ -450,6 +453,7 @@ sdsServer:
 				"KUMA_MONITORING_ASSIGNMENT_SERVER_GRPC_PORT":                                              "3333",
 				"KUMA_MONITORING_ASSIGNMENT_SERVER_ASSIGNMENT_REFRESH_INTERVAL":                            "12s",
 				"KUMA_REPORTS_ENABLED":                                                                     "false",
+				"KUMA_RUNTIME_KUBERNETES_CONTROL_PLANE_SERVICE_NAME":                                       "custom-control-plane",
 				"KUMA_RUNTIME_KUBERNETES_ADMISSION_SERVER_ADDRESS":                                         "127.0.0.2",
 				"KUMA_RUNTIME_KUBERNETES_ADMISSION_SERVER_PORT":                                            "9443",
 				"KUMA_RUNTIME_KUBERNETES_ADMISSION_SERVER_CERT_DIR":                                        "/var/run/secrets/kuma.io/kuma-admission-server/tls-cert",
diff --git a/pkg/config/plugins/runtime/k8s/config_test.go b/pkg/config/plugins/runtime/k8s/config_test.go
index 0742379e6..65252e6ef 100644
--- a/pkg/config/plugins/runtime/k8s/config_test.go
+++ b/pkg/config/plugins/runtime/k8s/config_test.go
@@ -1,11 +1,11 @@
 package k8s_test
 
 import (
-	"io/ioutil"
 	"path/filepath"
 	"time"
 
 	runtime_k8s "github.com/kumahq/kuma/pkg/config/plugins/runtime/k8s"
+	. "github.com/kumahq/kuma/pkg/test/matchers"
 
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
@@ -25,6 +25,8 @@ var _ = Describe("Config", func() {
 		Expect(err).ToNot(HaveOccurred())
 
 		// and
+		Expect(cfg.ControlPlaneServiceName).To(Equal("custom-control-plane"))
+
 		Expect(cfg.AdmissionServer.Address).To(Equal("127.0.0.2"))
 		Expect(cfg.AdmissionServer.Port).To(Equal(uint32(8442)))
 		Expect(cfg.AdmissionServer.CertDir).To(Equal("/var/secret/kuma-cp"))
@@ -65,15 +67,10 @@ var _ = Describe("Config", func() {
 
 		// when
 		actual, err := config.ToYAML(cfg)
-		// then
-		Expect(err).ToNot(HaveOccurred())
 
-		// when
-		expected, err := ioutil.ReadFile(filepath.Join("testdata", "default-config.golden.yaml"))
 		// then
 		Expect(err).ToNot(HaveOccurred())
-		// and
-		Expect(actual).To(MatchYAML(expected))
+		Expect(actual).To(MatchGoldenYAML(filepath.Join("testdata", "default-config.golden.yaml")))
 	})
 
 	It("should have validators", func() {
diff --git a/pkg/config/plugins/runtime/k8s/testdata/default-config.golden.yaml b/pkg/config/plugins/runtime/k8s/testdata/default-config.golden.yaml
index b4fa91b04..5da272684 100644
--- a/pkg/config/plugins/runtime/k8s/testdata/default-config.golden.yaml
+++ b/pkg/config/plugins/runtime/k8s/testdata/default-config.golden.yaml
@@ -1,31 +1,27 @@
 admissionServer:
   address: ""
-  certDir: ""
   port: 5443
+  certDir: ""
 injector:
-  cniEnabled: false
-  virtualProbesEnabled: true
-  virtualProbesPort: 9000
   sidecarContainer:
     image: kuma/kuma-dp:latest
-    redirectPortOutbound: 15001
     redirectPortInbound: 15006
+    redirectPortOutbound: 15001
     uid: 5678
     gid: 5678
     adminPort: 9901
     drainTime: 30s
-
     readinessProbe:
       initialDelaySeconds: 1
-      timeoutSeconds:      3
-      periodSeconds:       5
-      successThreshold:    1
-      failureThreshold:    12
+      timeoutSeconds: 3
+      periodSeconds: 5
+      successThreshold: 1
+      failureThreshold: 12
     livenessProbe:
       initialDelaySeconds: 60
-      timeoutSeconds:      3
-      periodSeconds:       5
-      failureThreshold:    12
+      timeoutSeconds: 3
+      periodSeconds: 5
+      failureThreshold: 12
     resources:
       requests:
         cpu: 50m
@@ -35,12 +31,16 @@ injector:
         memory: 512Mi
   initContainer:
     image: kuma/kuma-init:latest
+  cniEnabled: false
+  virtualProbesEnabled: true
+  virtualProbesPort: 9000
   sidecarTraffic:
     excludeInboundPorts: []
     excludeOutboundPorts: []
-  caCertFile: ""
   exceptions:
     labels:
-      openshift.io/build.name: "*"
-      openshift.io/deployer-pod-for.name: "*"
+      openshift.io/build.name: '*'
+      openshift.io/deployer-pod-for.name: '*'
+  caCertFile: ""
 marshalingCacheExpirationTime: 5m0s
+controlPlaneServiceName: kuma-control-plane
diff --git a/pkg/config/plugins/runtime/k8s/testdata/valid-config.input.yaml b/pkg/config/plugins/runtime/k8s/testdata/valid-config.input.yaml
index 959af226c..a64b3a0f1 100644
--- a/pkg/config/plugins/runtime/k8s/testdata/valid-config.input.yaml
+++ b/pkg/config/plugins/runtime/k8s/testdata/valid-config.input.yaml
@@ -33,4 +33,5 @@ injector:
         memory: 1512Mi
   initContainer:
     image: kuma-init:latest
-marshalingCacheExpirationTime: 1s
\ No newline at end of file
+marshalingCacheExpirationTime: 1s
+controlPlaneServiceName: custom-control-plane
diff --git a/pkg/dns/outbound_test.go b/pkg/dns/outbound_test.go
index d1b9c9875..8e1766a5a 100644
--- a/pkg/dns/outbound_test.go
+++ b/pkg/dns/outbound_test.go
@@ -4,6 +4,8 @@ import (
 	"fmt"
 	"strconv"
 
+	"github.com/kumahq/kuma/pkg/core/resources/model"
+
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
 
@@ -69,7 +71,7 @@ var _ = Describe("VIPOutbounds", func() {
 		}
 
 		// when
-		outbounds := dns.VIPOutbounds(dataplane.Meta.GetName(), dataplanes.Items, vipList, externalServices.Items)
+		outbounds := dns.VIPOutbounds(model.MetaToResourceKey(dataplane.Meta), dataplanes.Items, vipList, externalServices.Items)
 		// and
 		Expect(outbounds).To(HaveLen(4))
 		// and
@@ -77,4 +79,73 @@ var _ = Describe("VIPOutbounds", func() {
 		// and
 		Expect(outbounds[3].Port).To(Equal(dns.VIPListenPort))
 	})
+
+	It("shouldn't add outbounds from other meshes", func() {
+		dataplane := &core_mesh.DataplaneResource{
+			Meta: &test_model.ResourceMeta{
+				Name: "dp1",
+				Mesh: "default",
+			},
+			Spec: &mesh_proto.Dataplane{
+				Networking: &mesh_proto.Dataplane_Networking{
+					Address: "192.168.0.1",
+					Inbound: []*mesh_proto.Dataplane_Networking_Inbound{
+						{
+							Port: 8080,
+							Tags: map[string]string{
+								"kuma.io/service": "backend",
+							},
+						},
+					},
+				},
+			},
+		}
+
+		// given
+		vipList := vips.List{
+			"service-a": "240.0.0.1",
+			"service-b": "240.0.0.2",
+		}
+		services := []*mesh_proto.Dataplane_Networking_Ingress_AvailableService{
+			{
+				Mesh: "default",
+				Tags: map[string]string{
+					"kuma.io/service": "service-a",
+				},
+			},
+			{
+				Mesh: "other",
+				Tags: map[string]string{
+					"kuma.io/service": "service-b",
+				},
+			},
+		}
+		externalServices := &core_mesh.ExternalServiceResourceList{}
+		dataplanes := core_mesh.DataplaneResourceList{
+			Items: []*core_mesh.DataplaneResource{
+				{
+					Meta: &test_model.ResourceMeta{
+						Name: "dp-ingress",
+						Mesh: "default",
+					},
+					Spec: &mesh_proto.Dataplane{
+						Networking: &mesh_proto.Dataplane_Networking{
+							Ingress: &mesh_proto.Dataplane_Networking_Ingress{
+								AvailableServices: services,
+							},
+						},
+					},
+				},
+			},
+		}
+
+		// when
+		outbounds := dns.VIPOutbounds(model.MetaToResourceKey(dataplane.Meta), dataplanes.Items, vipList, externalServices.Items)
+		// and
+		Expect(outbounds).To(HaveLen(1))
+		// and
+		Expect(outbounds[0].GetTags()[mesh_proto.ServiceTag]).To(Equal("service-a"))
+		// and
+		Expect(outbounds[0].Port).To(Equal(dns.VIPListenPort))
+	})
 })
diff --git a/pkg/plugins/runtime/k8s/controllers/pod_converter_test.go b/pkg/plugins/runtime/k8s/controllers/pod_converter_test.go
index 138808eac..5fe1f41b9 100644
--- a/pkg/plugins/runtime/k8s/controllers/pod_converter_test.go
+++ b/pkg/plugins/runtime/k8s/controllers/pod_converter_test.go
@@ -55,25 +55,6 @@ var _ = Describe("PodToDataplane(..)", func() {
       podIP: 192.168.0.1
 `
 
-	gatewayPod := `
-    metadata:
-      namespace: demo
-      name: example
-      labels:
-        app: example
-        version: "0.1"
-      annotations:
-        kuma.io/gateway: enabled
-    spec:
-      containers:
-      - ports:
-        - containerPort: 7070
-        - containerPort: 6060
-          name: metrics
-    status:
-      podIP: 192.168.0.1
-`
-
 	ParseServices := func(values []string) ([]*kube_core.Service, error) {
 		services := make([]*kube_core.Service, len(values))
 		for i, value := range values {
@@ -117,11 +98,14 @@ var _ = Describe("PodToDataplane(..)", func() {
 			Expect(err).ToNot(HaveOccurred())
 
 			// services for pod
-			bytes, err = ioutil.ReadFile(filepath.Join("testdata", given.servicesForPod))
-			Expect(err).ToNot(HaveOccurred())
-			YAMLs := util_yaml.SplitYAML(string(bytes))
-			services, err := ParseServices(YAMLs)
-			Expect(err).ToNot(HaveOccurred())
+			services := []*kube_core.Service{}
+			if given.servicesForPod != "" {
+				bytes, err = ioutil.ReadFile(filepath.Join("testdata", given.servicesForPod))
+				Expect(err).ToNot(HaveOccurred())
+				YAMLs := util_yaml.SplitYAML(string(bytes))
+				services, err = ParseServices(YAMLs)
+				Expect(err).ToNot(HaveOccurred())
+			}
 
 			// other services
 			var serviceGetter kube_client.Reader
@@ -238,6 +222,14 @@ var _ = Describe("PodToDataplane(..)", func() {
 			servicesForPod: "12.services-for-pod.yaml",
 			dataplane:      "12.dataplane.yaml",
 		}),
+		Entry("13. Pod without a service", testCase{
+			pod:       "13.pod.yaml",
+			dataplane: "13.dataplane.yaml",
+		}),
+		Entry("14. Gateway pod without a service", testCase{
+			pod:       "14.pod.yaml",
+			dataplane: "14.dataplane.yaml",
+		}),
 	)
 
 	DescribeTable("should convert Pod into a Dataplane YAML version",
@@ -346,16 +338,6 @@ var _ = Describe("PodToDataplane(..)", func() {
 				Expect(err).To(HaveOccurred())
 				Expect(err.Error()).To(Equal(given.expectedErr))
 			},
-			Entry("regular Pod without Services", testCase{
-				pod:         pod,
-				services:    nil,
-				expectedErr: `Kuma requires every Pod in a Mesh to be a part of at least one Service. However, there are no Services that select this Pod.`,
-			}),
-			Entry("gateway Pod without Services", testCase{
-				pod:         gatewayPod,
-				services:    nil,
-				expectedErr: `Kuma requires every Pod in a Mesh to be a part of at least one Service. However, there are no Services that select this Pod.`,
-			}),
 			Entry("Pod with a Service but mismatching ports", testCase{
 				pod: pod,
 				services: []string{`
@@ -375,7 +357,7 @@ var _ = Describe("PodToDataplane(..)", func() {
                     port: 6060
                     targetPort: diagnostics
 `},
-				expectedErr: `Kuma requires every Pod in a Mesh to be a part of at least one Service. However, this Pod doesn't have any container ports that would satisfy matching Service(s).`,
+				expectedErr: `A service that selects pod example was found, but it doesn't match any container ports.`,
 			}),
 		)
 	})
@@ -419,7 +401,7 @@ var _ = Describe("MeshFor(..)", func() {
 	)
 })
 
-var _ = Describe("InboundTagsFor(..)", func() {
+var _ = Describe("InboundTagsForService(..)", func() {
 
 	type testCase struct {
 		isGateway      bool
@@ -462,7 +444,7 @@ var _ = Describe("InboundTagsFor(..)", func() {
 			}
 
 			// expect
-			Expect(InboundTagsFor(given.zone, pod, svc, &svc.Spec.Ports[0])).To(Equal(given.expected))
+			Expect(InboundTagsForService(given.zone, pod, svc, &svc.Spec.Ports[0])).To(Equal(given.expected))
 		},
 		Entry("Pod without labels", testCase{
 			isGateway: false,
diff --git a/pkg/plugins/runtime/k8s/controllers/testdata/13.dataplane.yaml b/pkg/plugins/runtime/k8s/controllers/testdata/13.dataplane.yaml
new file mode 100644
index 000000000..8776943a3
--- /dev/null
+++ b/pkg/plugins/runtime/k8s/controllers/testdata/13.dataplane.yaml
@@ -0,0 +1,17 @@
+mesh: default
+metadata:
+  creationTimestamp: null
+spec:
+  networking:
+    address: 192.168.0.1
+    inbound:
+      - health:
+          ready: true
+        port: 49151
+        tags:
+          app: example
+          kuma.io/instance: example
+          kuma.io/protocol: tcp
+          kuma.io/service: example_demo_svc
+          kuma.io/zone: zone-1
+          version: "0.1"
diff --git a/pkg/plugins/runtime/k8s/controllers/testdata/13.pod.yaml b/pkg/plugins/runtime/k8s/controllers/testdata/13.pod.yaml
new file mode 100644
index 000000000..eecce6e2e
--- /dev/null
+++ b/pkg/plugins/runtime/k8s/controllers/testdata/13.pod.yaml
@@ -0,0 +1,16 @@
+metadata:
+  namespace: demo
+  name: example
+  labels:
+    app: example
+    version: "0.1"
+spec:
+  containers:
+    - ports: []
+    - ports:
+        - containerPort: 7070
+status:
+  podIP: 192.168.0.1
+  containerStatuses:
+    - ready: true
+      started: true
diff --git a/pkg/plugins/runtime/k8s/controllers/testdata/14.dataplane.yaml b/pkg/plugins/runtime/k8s/controllers/testdata/14.dataplane.yaml
new file mode 100644
index 000000000..460d463c4
--- /dev/null
+++ b/pkg/plugins/runtime/k8s/controllers/testdata/14.dataplane.yaml
@@ -0,0 +1,14 @@
+mesh: default
+metadata:
+  creationTimestamp: null
+spec:
+  networking:
+    address: 192.168.0.1
+    gateway:
+      tags:
+        app: example
+        kuma.io/instance: example
+        kuma.io/protocol: tcp
+        kuma.io/service: example_demo_svc
+        kuma.io/zone: zone-1
+        version: "0.1"
diff --git a/pkg/plugins/runtime/k8s/controllers/testdata/14.pod.yaml b/pkg/plugins/runtime/k8s/controllers/testdata/14.pod.yaml
new file mode 100644
index 000000000..8a69a9de5
--- /dev/null
+++ b/pkg/plugins/runtime/k8s/controllers/testdata/14.pod.yaml
@@ -0,0 +1,16 @@
+metadata:
+  namespace: demo
+  name: example
+  labels:
+    app: example
+    version: "0.1"
+  annotations:
+    kuma.io/gateway: enabled
+spec:
+  containers:
+    - ports:
+        - containerPort: 7070
+        - containerPort: 6060
+          name: metrics
+status:
+  podIP: 192.168.0.1
diff --git a/pkg/plugins/runtime/universal/outbound/outbound_suite_test.go b/pkg/plugins/runtime/universal/outbound/outbound_suite_test.go
new file mode 100644
index 000000000..6fc91e01d
--- /dev/null
+++ b/pkg/plugins/runtime/universal/outbound/outbound_suite_test.go
@@ -0,0 +1,13 @@
+package outbound_test
+
+import (
+	"testing"
+
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+)
+
+func TestOutbound(t *testing.T) {
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "Universal outbound test")
+}
diff --git a/pkg/plugins/runtime/universal/outbound/outbound_test.go b/pkg/plugins/runtime/universal/outbound/outbound_test.go
index d9d1378c7..a8500daaf 100644
--- a/pkg/plugins/runtime/universal/outbound/outbound_test.go
+++ b/pkg/plugins/runtime/universal/outbound/outbound_test.go
@@ -134,6 +134,124 @@ var _ = Describe("UpdateOutbound", func() {
 			Expect(dp1.Spec.Networking.Outbound).To(HaveLen(0))
 		})
 
+		It("should update dataplane outbounds when new service in the same mesh is added to an ingress", func() {
+			// when
+			err := rm.Create(context.Background(), &mesh.DataplaneResource{
+				Spec: &mesh_proto.Dataplane{
+					Networking: &mesh_proto.Dataplane_Networking{
+						Address: "127.0.0.1",
+						Ingress: &mesh_proto.Dataplane_Networking_Ingress{
+							AvailableServices: []*mesh_proto.Dataplane_Networking_Ingress_AvailableService{
+								{
+									Mesh: "default",
+									Tags: map[string]string{
+										mesh_proto.ServiceTag: "service-2",
+									},
+								},
+							},
+						},
+						Inbound: []*mesh_proto.Dataplane_Networking_Inbound{
+							{
+								Port: 8081,
+								Tags: map[string]string{
+									"kuma.io/service": "ingress",
+								},
+							},
+						},
+					},
+				},
+			}, store.CreateByKey("dp-2", "default"))
+			Expect(err).ToNot(HaveOccurred())
+			err = vipOutboundsReconciler.UpdateVIPOutbounds(context.Background())
+			Expect(err).ToNot(HaveOccurred())
+			// then
+			dp1 := mesh.NewDataplaneResource()
+			err = rm.Get(context.Background(), dp1, store.GetByKey("dp-1", "default"))
+			Expect(err).ToNot(HaveOccurred())
+			Expect(dp1.Spec.Networking.Outbound).To(HaveLen(1))
+			Expect(dp1.Spec.Networking.Outbound[0].Tags["kuma.io/service"]).To(Equal("service-2"))
+			Expect(dp1.Spec.Networking.Outbound[0].Address).To(Equal("240.0.0.2"))
+		})
+
+		It("shouldn't update dataplane outbounds when new service in a different mesh is added to an ingress", func() {
+			// when
+			err := rm.Create(context.Background(), &mesh.DataplaneResource{
+				Spec: &mesh_proto.Dataplane{
+					Networking: &mesh_proto.Dataplane_Networking{
+						Address: "127.0.0.1",
+						Ingress: &mesh_proto.Dataplane_Networking_Ingress{
+							AvailableServices: []*mesh_proto.Dataplane_Networking_Ingress_AvailableService{
+								{
+									Mesh: "other-mesh",
+									Tags: map[string]string{
+										mesh_proto.ServiceTag: "service-2",
+									},
+								},
+							},
+						},
+						Inbound: []*mesh_proto.Dataplane_Networking_Inbound{
+							{
+								Port: 8081,
+								Tags: map[string]string{
+									"kuma.io/service": "ingress",
+								},
+							},
+						},
+					},
+				},
+			}, store.CreateByKey("dp-2", "default"))
+			Expect(err).ToNot(HaveOccurred())
+			err = vipOutboundsReconciler.UpdateVIPOutbounds(context.Background())
+			Expect(err).ToNot(HaveOccurred())
+			// then
+			dp1 := mesh.NewDataplaneResource()
+			err = rm.Get(context.Background(), dp1, store.GetByKey("dp-1", "default"))
+			Expect(err).ToNot(HaveOccurred())
+			Expect(dp1.Spec.Networking.Outbound).To(HaveLen(0))
+		})
+
+		It("should update dataplane outbounds when new service is added to an ingress in a different mesh", func() {
+			// when
+			err := rm.Create(context.Background(), mesh.NewMeshResource(), store.CreateByKey("another-mesh", model.NoMesh))
+			Expect(err).ToNot(HaveOccurred())
+			// and
+			err = rm.Create(context.Background(), &mesh.DataplaneResource{
+				Spec: &mesh_proto.Dataplane{
+					Networking: &mesh_proto.Dataplane_Networking{
+						Address: "127.0.0.1",
+						Ingress: &mesh_proto.Dataplane_Networking_Ingress{
+							AvailableServices: []*mesh_proto.Dataplane_Networking_Ingress_AvailableService{
+								{
+									Mesh: "default",
+									Tags: map[string]string{
+										mesh_proto.ServiceTag: "service-2",
+									},
+								},
+							},
+						},
+						Inbound: []*mesh_proto.Dataplane_Networking_Inbound{
+							{
+								Port: 8081,
+								Tags: map[string]string{
+									"kuma.io/service": "ingress",
+								},
+							},
+						},
+					},
+				},
+			}, store.CreateByKey("dp-2", "another-mesh"))
+			Expect(err).ToNot(HaveOccurred())
+			err = vipOutboundsReconciler.UpdateVIPOutbounds(context.Background())
+			Expect(err).ToNot(HaveOccurred())
+			// then
+			dp1 := mesh.NewDataplaneResource()
+			err = rm.Get(context.Background(), dp1, store.GetByKey("dp-1", "default"))
+			Expect(err).ToNot(HaveOccurred())
+			Expect(dp1.Spec.Networking.Outbound).To(HaveLen(1))
+			Expect(dp1.Spec.Networking.Outbound[0].Tags["kuma.io/service"]).To(Equal("service-2"))
+			Expect(dp1.Spec.Networking.Outbound[0].Address).To(Equal("240.0.0.2"))
+		})
+
 		Context("outbounds already updated", func() {
 			BeforeEach(func() {
 				err := rm.Create(context.Background(), &mesh.DataplaneResource{
diff --git a/pkg/test/golden/update_files.go b/pkg/test/golden/update_files.go
index 20eee3946..6329fb6e5 100644
--- a/pkg/test/golden/update_files.go
+++ b/pkg/test/golden/update_files.go
@@ -1,10 +1,12 @@
 package golden
 
-import "os"
+import (
+	"os"
+)
 
 func UpdateGoldenFiles() bool {
 	value, found := os.LookupEnv("UPDATE_GOLDEN_FILES")
 	return found && value == "true"
 }
 
-const RerunMsg = "rerun the test with UPDATE_GOLDEN_FILES=true flag. Example: make test UPDATE_GOLDEN_FILES=true"
+const RerunMsg = "Rerun the test with UPDATE_GOLDEN_FILES=true flag. Example: make test UPDATE_GOLDEN_FILES=true"
diff --git a/pkg/test/matchers/golden.go b/pkg/test/matchers/golden.go
new file mode 100644
index 000000000..6a5897fb5
--- /dev/null
+++ b/pkg/test/matchers/golden.go
@@ -0,0 +1,98 @@
+package matchers
+
+import (
+	"io/ioutil"
+
+	"github.com/onsi/gomega"
+	"github.com/onsi/gomega/types"
+	"github.com/pkg/errors"
+
+	"github.com/kumahq/kuma/pkg/test/golden"
+)
+
+func MatchGoldenYAML(goldenFilePath string) types.GomegaMatcher {
+	return MatchGolden(gomega.MatchYAML, goldenFilePath)
+}
+
+func MatchGoldenJSON(goldenFilePath string) types.GomegaMatcher {
+	return MatchGolden(gomega.MatchJSON, goldenFilePath)
+}
+
+func MatchGoldenEqual(goldenFilePath string) types.GomegaMatcher {
+	return MatchGolden(func(expected interface{}) types.GomegaMatcher {
+		if expectedBytes, ok := expected.([]byte); ok {
+			expected = string(expectedBytes)
+		}
+		return gomega.Equal(expected)
+	}, goldenFilePath)
+}
+
+type MatcherFn = func(expected interface{}) types.GomegaMatcher
+
+// MatchGolden matches Golden file overriding it with actual content if UPDATE_GOLDEN_FILES is set to true
+func MatchGolden(matcherFn MatcherFn, goldenFilePath string) types.GomegaMatcher {
+	return &GoldenYAMLMatcher{
+		MatcherFn:      matcherFn,
+		GoldenFilePath: goldenFilePath,
+	}
+}
+
+type GoldenYAMLMatcher struct {
+	MatcherFn      MatcherFn
+	GoldenFilePath string
+}
+
+var _ types.GomegaMatcher = &GoldenYAMLMatcher{}
+
+func (g *GoldenYAMLMatcher) Match(actual interface{}) (success bool, err error) {
+	actualContent, err := g.actualBytes(actual)
+	if err != nil {
+		return false, err
+	}
+	if golden.UpdateGoldenFiles() {
+		err := ioutil.WriteFile(g.GoldenFilePath, []byte(actualContent), 0644)
+		if err != nil {
+			return false, errors.Wrap(err, "could not update golden file")
+		}
+	}
+	expected, err := ioutil.ReadFile(g.GoldenFilePath)
+	if err != nil {
+		return false, errors.Wrap(err, "could not read golden file")
+	}
+	return g.MatcherFn(expected).Match(actualContent)
+}
+
+func (g *GoldenYAMLMatcher) FailureMessage(actual interface{}) (message string) {
+	actualContent, err := g.actualBytes(actual)
+	if err != nil {
+		return err.Error()
+	}
+	expected, err := ioutil.ReadFile(g.GoldenFilePath)
+	if err != nil {
+		return errors.Wrap(err, "could not read golden file").Error()
+	}
+	return golden.RerunMsg + "\n\n" + g.MatcherFn(expected).FailureMessage(actualContent)
+}
+
+func (g *GoldenYAMLMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	actualContent, err := g.actualBytes(actual)
+	if err != nil {
+		return err.Error()
+	}
+	expected, err := ioutil.ReadFile(g.GoldenFilePath)
+	if err != nil {
+		return errors.Wrap(err, "could not read golden file").Error()
+	}
+	return g.MatcherFn(expected).NegatedFailureMessage(actualContent)
+}
+
+func (g *GoldenYAMLMatcher) actualBytes(actual interface{}) (string, error) {
+	switch actual := actual.(type) {
+	case []byte:
+		return string(actual), nil
+	case string:
+		return actual, nil
+	default:
+		return "", errors.Errorf("not supported type %T for MatchGolden", actual)
+	}
+}
diff --git a/pkg/test/runtime/runtime.go b/pkg/test/runtime/runtime.go
index bd9ec05b8..3e7973396 100644
--- a/pkg/test/runtime/runtime.go
+++ b/pkg/test/runtime/runtime.go
@@ -4,6 +4,7 @@ import (
 	"net"
 
 	"github.com/kumahq/kuma/pkg/api-server/customization"
+	xds_hooks "github.com/kumahq/kuma/pkg/xds/hooks"
 
 	kuma_cp "github.com/kumahq/kuma/pkg/config/app/kuma-cp"
 	config_manager "github.com/kumahq/kuma/pkg/core/config/manager"
@@ -71,6 +72,7 @@ func BuilderFor(cfg kuma_cp.Config) (*core_runtime.Builder, error) {
 	builder.WithLookupIP(net.LookupIP)
 	builder.WithEventReaderFactory(events.NewEventBus())
 	builder.WithAPIManager(customization.NewAPIList())
+	builder.WithXDSHooks(&xds_hooks.Hooks{})
 
 	_ = initializeConfigManager(cfg, builder)
 	_ = initializeDNSResolver(cfg, builder)
diff --git a/test/e2e/tracing_kubernetes_test.go b/test/e2e/tracing_kubernetes_test.go
index ce7c0b561..b1742144a 100644
--- a/test/e2e/tracing_kubernetes_test.go
+++ b/test/e2e/tracing_kubernetes_test.go
@@ -123,7 +123,7 @@ spec:
 					return "", err
 				}
 
-				expectedServices := []string{"demo-client_kuma-test_svc_3000", "echo-server_kuma-test_svc_80", "jaeger-query"}
+				expectedServices := []string{"demo-client_kuma-test_svc", "echo-server_kuma-test_svc_80", "jaeger-query"}
 				if !reflect.DeepEqual(services, expectedServices) {
 					return "", errors.Errorf("services not traced. Expected %q, got %q", expectedServices, services)
 				}
diff --git a/test/framework/constants.go b/test/framework/constants.go
index 1cdf35c73..95c25f9ad 100644
--- a/test/framework/constants.go
+++ b/test/framework/constants.go
@@ -37,9 +37,6 @@ const (
 	kumaCPAPIPort        = 5681
 	kumaCPAPIPortFwdBase = 32000 + kumaCPAPIPort
 
-	cniApp       = "kuma-cni"
-	cniNamespace = "kube-system"
-
 	redirectPortInbound  = "15006"
 	redirectPortOutbound = "15001"
 )
@@ -50,6 +47,9 @@ var HelmSubChartPrefix = ""
 var KumaNamespace = "kuma-system"
 var KumaServiceName = "kuma-control-plane"
 
+var CNIApp = "kuma-cni"
+var CNINamespace = "kube-system"
+
 var KumaImageRegistry = "kuma"
 var KumaCPImageRepo = "kuma-cp"
 var KumaDPImageRepo = "kuma-dp"
diff --git a/test/framework/k8s_cluster.go b/test/framework/k8s_cluster.go
index 3a267da0d..9de85ede8 100644
--- a/test/framework/k8s_cluster.go
+++ b/test/framework/k8s_cluster.go
@@ -396,7 +396,7 @@ func (c *K8sCluster) DeployKuma(mode string, fs ...DeployOptionsFunc) error {
 	}
 
 	if opts.cni {
-		err = c.WaitApp(cniApp, cniNamespace, 1)
+		err = c.WaitApp(CNIApp, CNINamespace, 1)
 		if err != nil {
 			return err
 		}
diff --git a/test/framework/setup.go b/test/framework/setup.go
index faa0b0e23..e16163e0f 100644
--- a/test/framework/setup.go
+++ b/test/framework/setup.go
@@ -228,19 +228,6 @@ func IngressUniversal(mesh, token string) InstallFunc {
 
 func DemoClientK8s(mesh string) InstallFunc {
 	const name = "demo-client"
-	service := `
-apiVersion: v1
-kind: Service
-metadata:
-  name: demo-client
-  namespace: kuma-test
-spec:
-  ports:
-    - port: 3000
-      name: http
-  selector:
-    app: demo-client
-`
 	deployment := `
 apiVersion: apps/v1
 kind: Deployment
@@ -281,9 +268,7 @@ spec:
               memory: 128Mi
 `
 	return Combine(
-		YamlK8s(service),
 		YamlK8s(fmt.Sprintf(deployment, mesh)),
-		WaitService(TestNamespace, name),
 		WaitNumPods(1, name),
 		WaitPodsAvailable(TestNamespace, name),
 	)