Repository: tetratelabs/getenvoy
Pull request #174 (2021-04-12 07:12:33)

Updates to Envoy 1.15 and Istio 1.7
This migrates to floor versions implied in Istio 1.7

See #169


codefromthecrypt: inlined the api from getenvoy-package per https://github.com/tetratelabs/getenvoy-package/pull/103

this allowed us to use latest protobuf libs
codefromthecrypt: cmd test is wrestling about space-after in json encoding.. locally even with the exact same golang version, make test is fine..
mathetake: Thanks for all the work here! 🚀 

Patch:
diff --git a/.bingo/Variables.mk b/.bingo/Variables.mk
index 2c2b121..66b9f12 100644
--- a/.bingo/Variables.mk
+++ b/.bingo/Variables.mk
@@ -13,10 +13,16 @@ GO     ?= $(shell which go)
 #
 #include .bingo/Variables.mk # Assuming -dir was set to .bingo .
 #
-#command: $(GOIMPORTS)
-#	@echo "Running goimports"
-#	@$(GOIMPORTS) <flags/args..>
+#command: $(BUF)
+#	@echo "Running buf"
+#	@$(BUF) <flags/args..>
 #
+BUF := $(GOBIN)/buf-v0.41.0
+$(BUF): $(BINGO_DIR)/buf.mod
+	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
+	@echo "(re)installing $(GOBIN)/buf-v0.41.0"
+	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=buf.mod -o=$(GOBIN)/buf-v0.41.0 "github.com/bufbuild/buf/cmd/buf"
+
 GOIMPORTS := $(GOBIN)/goimports-v0.1.0
 $(GOIMPORTS): $(BINGO_DIR)/goimports.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@@ -35,6 +41,12 @@ $(LICENSER): $(BINGO_DIR)/licenser.mod
 	@echo "(re)installing $(GOBIN)/licenser-v0.6.0"
 	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=licenser.mod -o=$(GOBIN)/licenser-v0.6.0 "github.com/liamawhite/licenser"
 
+PROTOC_GEN_GO := $(GOBIN)/protoc-gen-go-v1.26.0
+$(PROTOC_GEN_GO): $(BINGO_DIR)/protoc-gen-go.mod
+	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
+	@echo "(re)installing $(GOBIN)/protoc-gen-go-v1.26.0"
+	@cd $(BINGO_DIR) && $(GO) build -mod=mod -modfile=protoc-gen-go.mod -o=$(GOBIN)/protoc-gen-go-v1.26.0 "google.golang.org/protobuf/cmd/protoc-gen-go"
+
 SHFMT := $(GOBIN)/shfmt-v3.2.4
 $(SHFMT): $(BINGO_DIR)/shfmt.mod
 	@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
diff --git a/.bingo/buf.mod b/.bingo/buf.mod
new file mode 100644
index 0000000..546ed93
--- /dev/null
+++ b/.bingo/buf.mod
@@ -0,0 +1,5 @@
+module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT
+
+go 1.16
+
+require github.com/bufbuild/buf v0.41.0 // cmd/buf
diff --git a/.bingo/protoc-gen-go.mod b/.bingo/protoc-gen-go.mod
new file mode 100644
index 0000000..657bc8d
--- /dev/null
+++ b/.bingo/protoc-gen-go.mod
@@ -0,0 +1,5 @@
+module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT
+
+go 1.16
+
+require google.golang.org/protobuf v1.26.0 // cmd/protoc-gen-go
diff --git a/.bingo/variables.env b/.bingo/variables.env
index 6d0c436..a2c0320 100644
--- a/.bingo/variables.env
+++ b/.bingo/variables.env
@@ -7,6 +7,7 @@ if [ -z "$GOBIN" ]; then
 	GOBIN="$(go env GOPATH)/bin"
 fi
 
+BUF="${GOBIN}/buf-v0.41.0"
 
 GOIMPORTS="${GOBIN}/goimports-v0.1.0"
 
@@ -14,5 +15,7 @@ GOLANGCI_LINT="${GOBIN}/golangci-lint-v1.39.0"
 
 LICENSER="${GOBIN}/licenser-v0.6.0"
 
+PROTOC_GEN_GO="${GOBIN}/protoc-gen-go-v1.26.0"
+
 SHFMT="${GOBIN}/shfmt-v3.2.4"
 
diff --git a/.github/workflows/commit.yaml b/.github/workflows/commit.yaml
index 09758b7..9aaf0bd 100644
--- a/.github/workflows/commit.yaml
+++ b/.github/workflows/commit.yaml
@@ -43,7 +43,7 @@ jobs:
         # Prefetch envoy to avoid latency during "go test" which contributes to timeouts.
         # This version must align with pkg/binary/envoytest/util.go
         run: |
-          go run cmd/getenvoy/main.go fetch standard:1.12.7
+          go run cmd/getenvoy/main.go fetch standard:1.15.3
           make test
 
       - name: "Generate test coverage report"
diff --git a/.golangci.yml b/.golangci.yml
index 3d28f29..d38a133 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -47,7 +47,7 @@ linters:
   disable:
     - "gochecknoinits"
     - "gochecknoglobals"
-    - "gomoddirectives"  # Istio 1.6 dependency conflicts prevent enabling this
+    - "gomoddirectives"  # Istio 1.7 dependency conflicts prevent enabling this
 
 # all available settings of specific linters
 linters-settings:
diff --git a/.licenserignore b/.licenserignore
index 0677762..3c023c5 100644
--- a/.licenserignore
+++ b/.licenserignore
@@ -10,3 +10,6 @@ go.sum
 .bingo
 .dockerignore
 .idea
+
+# imported file from istio
+envoy_bootstrap.json
diff --git a/Makefile b/Makefile
index da781fe..4b12313 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@
 # bingo manages go binaries needed for building the project
 include .bingo/Variables.mk
 
-ENVOY = standard:1.11.1
+ENVOY = standard:1.15.3
 HUB ?= docker.io/getenvoy
 GETENVOY_TAG ?= dev
 BUILDERS_LANGS := rust tinygo
@@ -164,6 +164,15 @@ $(foreach lang,$(BUILDERS_LANGS),$(eval $(call GEN_PULL_EXTENSION_BUILDER_IMAGE_
 .PHONY: builders.pull
 builders.pull: $(foreach lang,$(BUILDERS_LANGS), pull/builder/$(lang))
 
+.PHONY: api
+api: api/manifest.proto $(BUF) $(PROTOC_GEN_GO)
+	@echo "--- api ---"
+	@rm api/*.go
+	@$(BUF) protoc \
+		--plugin=protoc-gen-go=$(PROTOC_GEN_GO) \
+		--go_out=paths=source_relative:. \
+		api/manifest.proto
+
 ##@ Code quality and integrity
 
 LINT_OPTS ?= --timeout 5m
@@ -190,7 +199,6 @@ format: $(GOIMPORTS) $(SHFMT) ## Format all Go code
 	    $(GOIMPORTS) -w -local github.com/tetratelabs/getenvoy $$f; \
 	done
 
-
 # Enforce go version matches what's in go.mod when running `make check` assuming the following:
 # * 'go version' returns output like "go version go1.16 darwin/amd64"
 # * go.mod contains a line like "go 1.16"
@@ -204,6 +212,7 @@ check:  ## CI blocks merge until this passes. If this fails, run "make check" lo
 		echo "Expected 'go version' to start with $(EXPECTED_GO_VERSION_PREFIX), but it didn't: $(GO_VERSION)"; \
 		exit 1; \
 	esac
+	@$(MAKE) api
 	@$(MAKE) lint
 	@$(MAKE) format
 	@go mod tidy
diff --git a/README.md b/README.md
index b3a13c9..adfc8b1 100644
--- a/README.md
+++ b/README.md
@@ -5,4 +5,4 @@
 
 **GetEnvoy is spread across multiple repos. For more details head over to [GetEnvoy.io](https://getenvoy.io/github).**
 
-The GetEnvoy project is a collection of tooling focused on building, distributing, deploying and maintaining a fleet of Envoys.
+The GetEnvoy project focuses on building, distributing, deploying and maintaining a fleet of Envoys.
diff --git a/api/manifest.pb.go b/api/manifest.pb.go
new file mode 100644
index 0000000..1fc43d0
--- /dev/null
+++ b/api/manifest.pb.go
@@ -0,0 +1,567 @@
+// Copyright 2021 Tetrate
+//
+// 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.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.26.0
+// 	protoc        v3.15.2
+// source: api/manifest.proto
+
+package api
+
+import (
+	reflect "reflect"
+	sync "sync"
+
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// Compliances should be single word, no underscores
+type Compliance int32
+
+const (
+	Compliance_FIPS1402 Compliance = 0
+)
+
+// Enum value maps for Compliance.
+var (
+	Compliance_name = map[int32]string{
+		0: "FIPS1402",
+	}
+	Compliance_value = map[string]int32{
+		"FIPS1402": 0,
+	}
+)
+
+func (x Compliance) Enum() *Compliance {
+	p := new(Compliance)
+	*p = x
+	return p
+}
+
+func (x Compliance) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Compliance) Descriptor() protoreflect.EnumDescriptor {
+	return file_api_manifest_proto_enumTypes[0].Descriptor()
+}
+
+func (Compliance) Type() protoreflect.EnumType {
+	return &file_api_manifest_proto_enumTypes[0]
+}
+
+func (x Compliance) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Compliance.Descriptor instead.
+func (Compliance) EnumDescriptor() ([]byte, []int) {
+	return file_api_manifest_proto_rawDescGZIP(), []int{0}
+}
+
+// Default must be unknown in order to sort correctly
+type Build_Platform int32
+
+const (
+	Build_UNKNOWN     Build_Platform = 0
+	Build_DARWIN      Build_Platform = 1
+	Build_WINDOWS     Build_Platform = 2
+	Build_LINUX_GLIBC Build_Platform = 3
+)
+
+// Enum value maps for Build_Platform.
+var (
+	Build_Platform_name = map[int32]string{
+		0: "UNKNOWN",
+		1: "DARWIN",
+		2: "WINDOWS",
+		3: "LINUX_GLIBC",
+	}
+	Build_Platform_value = map[string]int32{
+		"UNKNOWN":     0,
+		"DARWIN":      1,
+		"WINDOWS":     2,
+		"LINUX_GLIBC": 3,
+	}
+)
+
+func (x Build_Platform) Enum() *Build_Platform {
+	p := new(Build_Platform)
+	*p = x
+	return p
+}
+
+func (x Build_Platform) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Build_Platform) Descriptor() protoreflect.EnumDescriptor {
+	return file_api_manifest_proto_enumTypes[1].Descriptor()
+}
+
+func (Build_Platform) Type() protoreflect.EnumType {
+	return &file_api_manifest_proto_enumTypes[1]
+}
+
+func (x Build_Platform) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Build_Platform.Descriptor instead.
+func (Build_Platform) EnumDescriptor() ([]byte, []int) {
+	return file_api_manifest_proto_rawDescGZIP(), []int{3, 0}
+}
+
+type Manifest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ManifestVersion string `protobuf:"bytes,1,opt,name=manifest_version,json=manifestVersion,proto3" json:"manifest_version,omitempty"`
+	// Key is the flavor name
+	Flavors map[string]*Flavor `protobuf:"bytes,2,rep,name=flavors,proto3" json:"flavors,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *Manifest) Reset() {
+	*x = Manifest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_manifest_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Manifest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Manifest) ProtoMessage() {}
+
+func (x *Manifest) ProtoReflect() protoreflect.Message {
+	mi := &file_api_manifest_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Manifest.ProtoReflect.Descriptor instead.
+func (*Manifest) Descriptor() ([]byte, []int) {
+	return file_api_manifest_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Manifest) GetManifestVersion() string {
+	if x != nil {
+		return x.ManifestVersion
+	}
+	return ""
+}
+
+func (x *Manifest) GetFlavors() map[string]*Flavor {
+	if x != nil {
+		return x.Flavors
+	}
+	return nil
+}
+
+type Flavor struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Name is the composite key of the value's filter_profile and compliance
+	// Format: filter_profile or filter_profile-compliance1-compliance2
+	// Examples: standard, istio-fips1402
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	// Filter profile is the name of the collection of filters
+	// Examples: standard, istio, minimal
+	FilterProfile string `protobuf:"bytes,2,opt,name=filter_profile,json=filterProfile,proto3" json:"filter_profile,omitempty"`
+	// All filters available in this flavor
+	Filters []string `protobuf:"bytes,3,rep,name=filters,proto3" json:"filters,omitempty"`
+	// Compliance requirements met by this flavor
+	Compliances []Compliance `protobuf:"varint,4,rep,packed,name=compliances,proto3,enum=api.Compliance" json:"compliances,omitempty"`
+	// Key is the version's name
+	Versions map[string]*Version `protobuf:"bytes,5,rep,name=versions,proto3" json:"versions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *Flavor) Reset() {
+	*x = Flavor{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_manifest_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Flavor) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Flavor) ProtoMessage() {}
+
+func (x *Flavor) ProtoReflect() protoreflect.Message {
+	mi := &file_api_manifest_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Flavor.ProtoReflect.Descriptor instead.
+func (*Flavor) Descriptor() ([]byte, []int) {
+	return file_api_manifest_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *Flavor) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *Flavor) GetFilterProfile() string {
+	if x != nil {
+		return x.FilterProfile
+	}
+	return ""
+}
+
+func (x *Flavor) GetFilters() []string {
+	if x != nil {
+		return x.Filters
+	}
+	return nil
+}
+
+func (x *Flavor) GetCompliances() []Compliance {
+	if x != nil {
+		return x.Compliances
+	}
+	return nil
+}
+
+func (x *Flavor) GetVersions() map[string]*Version {
+	if x != nil {
+		return x.Versions
+	}
+	return nil
+}
+
+type Version struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Name is the Envoy version
+	// Examples: 1.10.0, 1.11.0, nightly
+	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+	// Key is the build's platform
+	Builds map[string]*Build `protobuf:"bytes,5,rep,name=builds,proto3" json:"builds,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *Version) Reset() {
+	*x = Version{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_manifest_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Version) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Version) ProtoMessage() {}
+
+func (x *Version) ProtoReflect() protoreflect.Message {
+	mi := &file_api_manifest_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Version.ProtoReflect.Descriptor instead.
+func (*Version) Descriptor() ([]byte, []int) {
+	return file_api_manifest_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *Version) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *Version) GetBuilds() map[string]*Build {
+	if x != nil {
+		return x.Builds
+	}
+	return nil
+}
+
+type Build struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Platform            Build_Platform `protobuf:"varint,1,opt,name=platform,proto3,enum=api.Build_Platform" json:"platform,omitempty"`
+	DownloadLocationUrl string         `protobuf:"bytes,2,opt,name=download_location_url,json=downloadLocationUrl,proto3" json:"download_location_url,omitempty"`
+}
+
+func (x *Build) Reset() {
+	*x = Build{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_api_manifest_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Build) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Build) ProtoMessage() {}
+
+func (x *Build) ProtoReflect() protoreflect.Message {
+	mi := &file_api_manifest_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Build.ProtoReflect.Descriptor instead.
+func (*Build) Descriptor() ([]byte, []int) {
+	return file_api_manifest_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *Build) GetPlatform() Build_Platform {
+	if x != nil {
+		return x.Platform
+	}
+	return Build_UNKNOWN
+}
+
+func (x *Build) GetDownloadLocationUrl() string {
+	if x != nil {
+		return x.DownloadLocationUrl
+	}
+	return ""
+}
+
+var File_api_manifest_proto protoreflect.FileDescriptor
+
+var file_api_manifest_proto_rawDesc = []byte{
+	0x0a, 0x12, 0x61, 0x70, 0x69, 0x2f, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x61, 0x70, 0x69, 0x22, 0xb4, 0x01, 0x0a, 0x08, 0x4d, 0x61,
+	0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65,
+	0x73, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0f, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+	0x6e, 0x12, 0x34, 0x0a, 0x07, 0x66, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73,
+	0x74, 0x2e, 0x46, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07,
+	0x66, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x73, 0x1a, 0x47, 0x0a, 0x0c, 0x46, 0x6c, 0x61, 0x76, 0x6f,
+	0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x05, 0x76, 0x61, 0x6c,
+	0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x46,
+	0x6c, 0x61, 0x76, 0x6f, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
+	0x22, 0x92, 0x02, 0x0a, 0x06, 0x46, 0x6c, 0x61, 0x76, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+	0x25, 0x0a, 0x0e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x50,
+	0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72,
+	0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73,
+	0x12, 0x31, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18,
+	0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x70,
+	0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e,
+	0x63, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18,
+	0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x46, 0x6c, 0x61, 0x76,
+	0x6f, 0x72, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
+	0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x49, 0x0a, 0x0d, 0x56, 0x65,
+	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
+	0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x22, 0x0a,
+	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61,
+	0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
+	0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x96, 0x01, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+	0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x06, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x18,
+	0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x72, 0x73,
+	0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
+	0x06, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x1a, 0x45, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64,
+	0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x75,
+	0x69, 0x6c, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xaf,
+	0x01, 0x0a, 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x2f, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74,
+	0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x61, 0x70, 0x69,
+	0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52,
+	0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x6f, 0x77,
+	0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75,
+	0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f,
+	0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x72, 0x6c, 0x22, 0x41, 0x0a,
+	0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b,
+	0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x41, 0x52, 0x57, 0x49, 0x4e,
+	0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x10, 0x02, 0x12,
+	0x0f, 0x0a, 0x0b, 0x4c, 0x49, 0x4e, 0x55, 0x58, 0x5f, 0x47, 0x4c, 0x49, 0x42, 0x43, 0x10, 0x03,
+	0x2a, 0x1a, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x0c,
+	0x0a, 0x08, 0x46, 0x49, 0x50, 0x53, 0x31, 0x34, 0x30, 0x32, 0x10, 0x00, 0x42, 0x29, 0x5a, 0x27,
+	0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x65, 0x74, 0x72, 0x61,
+	0x74, 0x65, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x67, 0x65, 0x74, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x2f,
+	0x61, 0x70, 0x69, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_api_manifest_proto_rawDescOnce sync.Once
+	file_api_manifest_proto_rawDescData = file_api_manifest_proto_rawDesc
+)
+
+func file_api_manifest_proto_rawDescGZIP() []byte {
+	file_api_manifest_proto_rawDescOnce.Do(func() {
+		file_api_manifest_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_manifest_proto_rawDescData)
+	})
+	return file_api_manifest_proto_rawDescData
+}
+
+var file_api_manifest_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_api_manifest_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
+var file_api_manifest_proto_goTypes = []interface{}{
+	(Compliance)(0),     // 0: api.Compliance
+	(Build_Platform)(0), // 1: api.Build.Platform
+	(*Manifest)(nil),    // 2: api.Manifest
+	(*Flavor)(nil),      // 3: api.Flavor
+	(*Version)(nil),     // 4: api.Version
+	(*Build)(nil),       // 5: api.Build
+	nil,                 // 6: api.Manifest.FlavorsEntry
+	nil,                 // 7: api.Flavor.VersionsEntry
+	nil,                 // 8: api.Version.BuildsEntry
+}
+var file_api_manifest_proto_depIdxs = []int32{
+	6, // 0: api.Manifest.flavors:type_name -> api.Manifest.FlavorsEntry
+	0, // 1: api.Flavor.compliances:type_name -> api.Compliance
+	7, // 2: api.Flavor.versions:type_name -> api.Flavor.VersionsEntry
+	8, // 3: api.Version.builds:type_name -> api.Version.BuildsEntry
+	1, // 4: api.Build.platform:type_name -> api.Build.Platform
+	3, // 5: api.Manifest.FlavorsEntry.value:type_name -> api.Flavor
+	4, // 6: api.Flavor.VersionsEntry.value:type_name -> api.Version
+	5, // 7: api.Version.BuildsEntry.value:type_name -> api.Build
+	8, // [8:8] is the sub-list for method output_type
+	8, // [8:8] is the sub-list for method input_type
+	8, // [8:8] is the sub-list for extension type_name
+	8, // [8:8] is the sub-list for extension extendee
+	0, // [0:8] is the sub-list for field type_name
+}
+
+func init() { file_api_manifest_proto_init() }
+func file_api_manifest_proto_init() {
+	if File_api_manifest_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_api_manifest_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Manifest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_manifest_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Flavor); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_manifest_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Version); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_api_manifest_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Build); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_api_manifest_proto_rawDesc,
+			NumEnums:      2,
+			NumMessages:   7,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_api_manifest_proto_goTypes,
+		DependencyIndexes: file_api_manifest_proto_depIdxs,
+		EnumInfos:         file_api_manifest_proto_enumTypes,
+		MessageInfos:      file_api_manifest_proto_msgTypes,
+	}.Build()
+	File_api_manifest_proto = out.File
+	file_api_manifest_proto_rawDesc = nil
+	file_api_manifest_proto_goTypes = nil
+	file_api_manifest_proto_depIdxs = nil
+}
diff --git a/api/manifest.proto b/api/manifest.proto
new file mode 100644
index 0000000..cd53ee3
--- /dev/null
+++ b/api/manifest.proto
@@ -0,0 +1,72 @@
+// Copyright 2021 Tetrate
+//
+// 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.
+
+syntax = "proto3";
+package api;
+
+option go_package = "github.com/tetratelabs/getenvoy/api;api";
+
+message Manifest {
+   string manifest_version = 1;
+
+   // Key is the flavor name
+   map<string, Flavor> flavors = 2;
+}
+
+message Flavor {
+   // Name is the composite key of the value's filter_profile and compliance
+   // Format: filter_profile or filter_profile-compliance1-compliance2
+   // Examples: standard, istio-fips1402
+   string name = 1;
+   
+   // Filter profile is the name of the collection of filters
+   // Examples: standard, istio, minimal
+   string filter_profile = 2;
+
+   // All filters available in this flavor
+   repeated string filters = 3;
+
+   // Compliance requirements met by this flavor
+   repeated Compliance compliances = 4;
+  
+   // Key is the version's name 
+   map <string, Version> versions = 5;
+}
+
+// Compliances should be single word, no underscores
+enum Compliance {
+   FIPS1402 = 0;
+}
+
+message Version {
+   // Name is the Envoy version
+   // Examples: 1.10.0, 1.11.0, nightly
+   string name = 1;
+
+   // Key is the build's platform 
+   map <string, Build> builds = 5;
+}
+
+message Build {
+   // Default must be unknown in order to sort correctly
+   enum Platform {
+      UNKNOWN = 0;
+      DARWIN = 1;
+      WINDOWS = 2;
+      LINUX_GLIBC = 3;
+   }
+
+   Platform platform = 1;
+   string download_location_url = 2;
+}
diff --git a/go.mod b/go.mod
index 88199d5..181a63e 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.16
 
 require (
 	bitbucket.org/creachadair/shell v0.0.6
-	github.com/Masterminds/semver v1.5.0
+	github.com/Masterminds/semver/v3 v3.1.1
 	github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3 // indirect
 	github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect
 	github.com/andybalholm/brotli v1.0.1 // indirect
@@ -19,15 +19,11 @@ require (
 	github.com/docker/go-metrics v0.0.1 // indirect
 	github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad
 	github.com/envoyproxy/protoc-gen-validate v0.5.1 // indirect
-	github.com/fsnotify/fsnotify v1.4.9 // indirect
-	github.com/ghodss/yaml v1.0.0
 	github.com/go-ole/go-ole v1.2.5 // indirect
-	github.com/gogo/protobuf v1.3.2
+	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
-	github.com/golang/protobuf v1.5.2
 	github.com/golang/snappy v0.0.3 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
-	github.com/googleapis/gnostic v0.4.0 // indirect
 	github.com/gorilla/mux v1.8.0 // indirect
 	github.com/hashicorp/errwrap v1.1.0 // indirect
 	github.com/imdario/mergo v0.3.11 // indirect
@@ -47,6 +43,7 @@ require (
 	github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
 	github.com/onsi/gomega v1.10.2 // indirect
 	github.com/opencontainers/image-spec v1.0.1
+	github.com/openshift/api v3.9.1-0.20191008181517-e4fd21196097+incompatible // indirect
 	github.com/otiai10/copy v1.5.1
 	github.com/pierrec/lz4/v4 v4.1.4 // indirect
 	github.com/pkg/errors v0.9.1
@@ -55,10 +52,8 @@ require (
 	github.com/russross/blackfriday/v2 v2.1.0 // indirect
 	github.com/schollz/progressbar/v3 v3.7.6
 	github.com/shirou/gopsutil/v3 v3.21.3
-	github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
 	github.com/spf13/cobra v1.1.3
 	github.com/stretchr/testify v1.7.0
-	github.com/tetratelabs/getenvoy-package v0.4.0
 	github.com/tetratelabs/log v0.0.0-20210323000454-90a3a3e141b5
 	github.com/tetratelabs/multierror v1.1.0
 	// Match data/extension/init/templates/tinygo/*/default/go.mod_ See RATIONALE.md for why
@@ -72,54 +67,41 @@ require (
 	golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
 	golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 // indirect
 	google.golang.org/genproto v0.0.0-20210406143921-e86de6bf7a46 // indirect
+	google.golang.org/protobuf v1.26.0
 	gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
 	gopkg.in/square/go-jose.v2 v2.5.1 // indirect
-	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
+	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
 	honnef.co/go/tools v0.0.1-2020.1.5 // indirect
-	istio.io/api v0.0.0-20201113182140-d4b7e3fc2b44
-	istio.io/istio v0.0.0-20201120194348-3ddc57b6d1e1
-	k8s.io/api v0.20.1 // indirect
-	k8s.io/apiextensions-apiserver v0.19.3 // indirect
-	k8s.io/apimachinery v0.20.1 // indirect
-	k8s.io/client-go v0.20.1 // indirect
+	istio.io/api v0.0.0-20210128181506-0c4b8e54850f
+	istio.io/istio v1.7.8
+	k8s.io/apiextensions-apiserver v0.18.17 // indirect
 	k8s.io/klog/v2 v2.4.0 // indirect
 	k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect
 	rsc.io/letsencrypt v0.0.3 // indirect
 	sigs.k8s.io/service-apis v0.1.0-rc2.0.20201112213625-c0375b7fa81f // indirect
+	sigs.k8s.io/yaml v1.2.0
 )
 
-// Resolve import problems caused by using istio, currently istio/istio@1.6.14
-// See See https://github.com/istio/istio/blob/1.6.14/go.mod and go.sum
+// Resolve import problems caused by using istio, currently istio/istio@1.7.8
+// See https://github.com/istio/istio/blob/1.7.8/go.mod and go.sum
 replace (
-	// Needed for import github.com/envoyproxy/go-control-plane/envoy/config/wasm/v2alpha
-	github.com/envoyproxy/go-control-plane => github.com/envoyproxy/go-control-plane v0.9.5
+	// istio 1.7.8 deps
+	github.com/envoyproxy/go-control-plane => github.com/envoyproxy/go-control-plane v0.9.7-0.20200730005029-803dd64f0468
 
-	// Istio 1.6 used gogo, which conflicted with a lot of other libraries
-	github.com/golang/protobuf => github.com/golang/protobuf v1.3.5
-	github.com/googleapis/gnostic => github.com/googleapis/gnostic v0.4.0
-	google.golang.org/genproto => google.golang.org/genproto v0.0.0-20191223191004-3caeed10a8bf
-	google.golang.org/grpc => google.golang.org/grpc v1.28.1
+	google.golang.org/grpc => google.golang.org/grpc v1.29.1
+	istio.io/api => istio.io/api v0.0.0-20210128181506-0c4b8e54850f
+	istio.io/istio => istio.io/istio v0.0.0-20210223230603-30e54dcb8a1c
 
-	// istio/istio@1.6.14
-	istio.io/istio => istio.io/istio v0.0.0-20201120194348-3ddc57b6d1e1
-
-	// Latests patch of k8s version included in istio 1.6
+	// Latest patch of k8s version included in istio 1.7.8
 	k8s.io/api => k8s.io/api v0.18.17
 	k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.18.17
 	k8s.io/apimachinery => k8s.io/apimachinery v0.18.17
 	k8s.io/client-go => k8s.io/client-go v0.18.17
-
-	// Set to the last commit before kube-openapi switched imports from gnostic/OpenAPIv2 -> openapi
-	// See https://github.com/kubernetes/kube-openapi/issues/209
-	k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20200204173128-addea2498afe
-
-	// Needed for import sigs.k8s.io/service-apis/api/v1alpha1
-	sigs.k8s.io/service-apis => sigs.k8s.io/service-apis v0.0.0-20200227172328-b9010cfacdbe
+	sigs.k8s.io/service-apis => sigs.k8s.io/service-apis v0.0.0-20200708220836-10c7cb28ed93
 )
 
 // Handle ambiguous import due istio imports
 exclude (
 	github.com/Azure/go-autorest v10.8.1+incompatible
-	github.com/census-instrumentation/opencensus-proto v0.3.0
 	github.com/hashicorp/consul v1.3.1
 )
diff --git a/go.sum b/go.sum
index b83996f..5048713 100644
--- a/go.sum
+++ b/go.sum
@@ -16,13 +16,13 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl
 cloud.google.com/go/logging v1.0.0/go.mod h1:V1cc3ogwobYzQq5f2R7DS/GvRIrI4FKj01Gs5glwAls=
 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
-contrib.go.opencensus.io/exporter/prometheus v0.1.0 h1:SByaIoWwNgMdPSgl5sMqM2KDE5H/ukPWBRo314xiDvg=
-contrib.go.opencensus.io/exporter/prometheus v0.1.0/go.mod h1:cGFniUXGZlKRjzOyuZJ6mgB+PgBcCIa79kEKR8YCW+A=
+contrib.go.opencensus.io/exporter/prometheus v0.2.0 h1:9PUk0/8V0LGoPqVCrf8fQZJkFGBxudu8jOjQSMwoD6w=
+contrib.go.opencensus.io/exporter/prometheus v0.2.0/go.mod h1:TYmVAyE8Tn1lyPcltF5IYYfWp2KHu7lQGIZnj8iZMys=
 contrib.go.opencensus.io/exporter/stackdriver v0.12.9/go.mod h1:XyyafDnFOsqoxHJgTFycKZMrRUrPThLh2iYTJF6uoO0=
 contrib.go.opencensus.io/exporter/zipkin v0.1.1/go.mod h1:GMvdSl3eJ2gapOaLKzTKE3qDgUkJ86k9k3yY2eqwkzc=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
-fortio.org/fortio v1.3.1 h1:XScQoLYEdMmlmPyueDwEZxrMOaoX9V9juSIkxkZf5zM=
-fortio.org/fortio v1.3.1/go.mod h1:Go0fRqoPJ1xy5JOWcS23jyF58byVZxFyEePYsGmCR0k=
+fortio.org/fortio v1.4.1 h1:afOESSYecZ5eMBIYdNDJ8Yx5+a7Sg0aVVNvDa1Z4laU=
+fortio.org/fortio v1.4.1/go.mod h1:a5CRkkB3+UTJsVV+T5N9WqV3xXMFDyW4TfJWMSFL+J8=
 github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
 github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
 github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
@@ -38,6 +38,7 @@ github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSW
 github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
 github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
 github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
 github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
 github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
 github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
@@ -49,14 +50,15 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
 github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
 github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
 github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU=
 github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
 github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
 github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
+github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=
 github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
-github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
-github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
-github.com/Masterminds/semver/v3 v3.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvoqmMUQk=
 github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
+github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
+github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
 github.com/Masterminds/sprig v2.20.0+incompatible h1:dJTKKuUkYW3RMFdQFXPU/s6hg10RgctmTjRcbZ98Ap8=
 github.com/Masterminds/sprig v2.20.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
 github.com/Masterminds/sprig/v3 v3.1.0 h1:j7GpgZ7PdFqNsmncycTHsLmVPf5/3wJtlgW9TNDYD9Y=
@@ -75,8 +77,10 @@ github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb0
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
 github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
 github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
 github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
 github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
 github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
 github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
@@ -85,15 +89,17 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx
 github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
 github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 h1:5sXbqlSomvdjlRbWyNqkPsJ3Fg+tQZCbgeX1VGljbQY=
 github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
-github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
 github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
 github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
 github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
 github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
+github.com/ahmetb/gen-crd-api-reference-docs v0.2.0/go.mod h1:P/XzJ+c2+khJKNKABcm2biRwk2QAuwbLf8DlXuaL7WM=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
 github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
 github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
 github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
@@ -150,10 +156,11 @@ github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM=
 github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8=
 github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
-github.com/cheggaaa/pb/v3 v3.0.4 h1:QZEPYOj2ix6d5oEg63fbHmpolrnNiwjUsk+h74Yt4bM=
 github.com/cheggaaa/pb/v3 v3.0.4/go.mod h1:7rgWxLrAUcFMkvJuv09+DYi7mMUYi8nO9iOWcvGJPfw=
 github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
@@ -166,8 +173,9 @@ github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX
 github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
 github.com/circonus-labs/circonusllhist v0.1.4/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
 github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
-github.com/cncf/udpa/go v0.0.0-20200313221541-5f7e5dd04533 h1:8wZizuKuZVu5COB7EsBYxBQz8nRcXXn5d4Gt91eJLvU=
-github.com/cncf/udpa/go v0.0.0-20200313221541-5f7e5dd04533/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354 h1:9kRtNpqLHbZVO/NNxhHp2ymxFxsHOe3x2efJGn//Tas=
+github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
 github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
 github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
@@ -188,6 +196,8 @@ github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv
 github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
 github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
 github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
+github.com/containernetworking/cni v0.7.0-alpha1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
+github.com/containernetworking/plugins v0.7.3/go.mod h1:dagHaAhNjXjT9QYOklkKJDGaQPTg4pf//FrUcJeb7FU=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
 github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@@ -257,6 +267,7 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
 github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4=
 github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
 github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
+github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c h1:ZfSZ3P3BedhKGUhzj7BQlPSU4OvT6tfOKe3DVHzOA7s=
 github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
 github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
 github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
@@ -269,13 +280,15 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1
 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
 github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
 github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
+github.com/elazarl/goproxy v0.0.0-20190630181448-f1e96bc0f4c5 h1:Zp2QJezMfAbYc5fLiDUZ8x3vNroDxnufFCOIJjgL5tY=
 github.com/elazarl/goproxy v0.0.0-20190630181448-f1e96bc0f4c5/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
 github.com/elazarl/goproxy/ext v0.0.0-20190630181448-f1e96bc0f4c5/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
 github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/emicklei/go-restful v2.9.6+incompatible h1:tfrHha8zJ01ywiOEC1miGY8st1/igzWB8OmvPgoYX7w=
 github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/envoyproxy/go-control-plane v0.9.5 h1:lRJIqDD8yjV1YyPRqecMdytjDLs2fTXq363aCib5xPU=
-github.com/envoyproxy/go-control-plane v0.9.5/go.mod h1:OXl5to++W0ctG+EHWTFUjiypVxC/Y4VLc/KFU+al13s=
+github.com/envoyproxy/go-control-plane v0.9.7-0.20200730005029-803dd64f0468 h1:d6NP0AddmfOtmgiEBSyNU7Q8FfCXUjISIyXWU76oaAc=
+github.com/envoyproxy/go-control-plane v0.9.7-0.20200730005029-803dd64f0468/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/envoyproxy/protoc-gen-validate v0.5.1 h1:MkpAQXrYF26uVnlFruA05G0xmM5rfE0OZDZPGY/UABU=
 github.com/envoyproxy/protoc-gen-validate v0.5.1/go.mod h1:xL5IroIBOR+aTp0IZk48epGwBV3+LcuaosPL0pr0hE0=
@@ -283,9 +296,9 @@ github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
 github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
 github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
 github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
 github.com/fluent/fluent-logger-golang v1.3.0/go.mod h1:2/HCT/jTy78yGyeNGQLGQsjF3zzzAuy6Xlk6FCMV5eU=
@@ -332,11 +345,13 @@ github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+
 github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
 github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
 github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
+github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
 github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
 github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
 github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
 github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
 github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
+github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
 github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
 github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
 github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
@@ -351,6 +366,7 @@ github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsd
 github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
 github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
 github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
+github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw=
 github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
 github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
 github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
@@ -361,6 +377,7 @@ github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/
 github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
 github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.6 h1:JSUbVWlaTLMhXeOMyArSUNCdroxZu2j1TcrsOV8Mj7Q=
 github.com/go-openapi/swag v0.19.6/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
 github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
 github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
@@ -372,7 +389,7 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me
 github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
 github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
 github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w=
-github.com/gobuffalo/flect v0.1.5/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80=
+github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80=
 github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs=
 github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q=
 github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc=
@@ -384,7 +401,6 @@ github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
-github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
 github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
 github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
 github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
@@ -394,7 +410,6 @@ github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2V
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -404,8 +419,23 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4er
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
-github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
+github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
 github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
@@ -429,8 +459,9 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
@@ -445,8 +476,10 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
 github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
-github.com/googleapis/gnostic v0.4.0 h1:BXDUo8p/DaxC+4FJY/SSx3gvnx9C1VdHNgaUkiEL5mk=
-github.com/googleapis/gnostic v0.4.0/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
+github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
+github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
+github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
+github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
 github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o=
 github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -464,6 +497,7 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
 github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
+github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
 github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
 github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
 github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg=
@@ -494,8 +528,9 @@ github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP
 github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI=
 github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
 github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
-github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
 github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
+github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
 github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
 github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
 github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
@@ -549,6 +584,7 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5i
 github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
 github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
 github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
+github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
 github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@@ -596,6 +632,7 @@ github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/Y
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
 github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
 github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
 github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
@@ -611,6 +648,7 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN
 github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
 github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
 github.com/manifoldco/promptui v0.8.0 h1:R95mMF+McvXZQ7j1g8ucVZE1gLP3Sv6j9vlF9kyRqQo=
 github.com/manifoldco/promptui v0.8.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ=
@@ -656,6 +694,7 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
 github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
 github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
 github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
 github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
 github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
@@ -705,22 +744,20 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v
 github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
 github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=
 github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.4.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ=
 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.13.0 h1:M76yO2HkZASFjXL0HSoZJ1AYEmQxNJmY41Jx1zNUq1Y=
+github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
 github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
-github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
-github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
+github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
 github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
@@ -738,8 +775,10 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P
 github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
 github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
 github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
+github.com/openshift/api v0.0.0-20200713203337-b2494ecb17dd/go.mod h1:vWmWTm4y7XR3wkLR+bDDjRbvkBfx2yP7yve6kfb7+Ts=
 github.com/openshift/api v3.9.1-0.20191008181517-e4fd21196097+incompatible h1:CIa+Zv6vIPhJl5OHmKxVpnekHC54YYe49L9GLr7IxGI=
 github.com/openshift/api v3.9.1-0.20191008181517-e4fd21196097+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY=
+github.com/openshift/build-machinery-go v0.0.0-20200713135615-1f43d26dccc7/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
 github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
 github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
 github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
@@ -764,6 +803,7 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pelletier/go-toml v1.3.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
 github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
+github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
@@ -790,12 +830,12 @@ github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d h1:7gXyC293Ls
 github.com/pquerna/cachecontrol v0.0.0-20180306154005-525d0eb5f91d/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
 github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
 github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
 github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
 github.com/prometheus/client_golang v0.9.4/go.mod h1:oCXIBxdI62A4cR6aTRJCgetEjecSIYzOEaeAn4iYEpM=
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
 github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
+github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U=
 github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
 github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
 github.com/prometheus/client_golang v1.10.0 h1:/o0BDeWzLWXNZ+4q5gXltUvaMpJqckTa+jTNoB+z4cg=
@@ -822,12 +862,12 @@ github.com/prometheus/common v0.20.0 h1:pfeDeUdQcIxOMutNjCejsEFp7qeP+/iltHSSmLpE
 github.com/prometheus/common v0.20.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
 github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
 github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
+github.com/prometheus/procfs v0.0.6/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
 github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
 github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
 github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
@@ -835,9 +875,10 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
 github.com/prometheus/prom2json v1.1.0/go.mod h1:v7OY1795b9fEUZgq4UU2+15YjRv0LfpxKejIQCy3L7o=
 github.com/prometheus/prom2json v1.2.2 h1:6Byhwq8biAw6H7IXky/XEtys7Uthw0NekOfKDTO8mFI=
 github.com/prometheus/prom2json v1.2.2/go.mod h1:yIcXOj/TLPdtZ12qRyhswPnu+02sfDoqatDjj0WGSvo=
+github.com/prometheus/statsd_exporter v0.15.0 h1:UiwC1L5HkxEPeapXdm2Ye0u1vUJfTj7uwT5yydYpa1E=
+github.com/prometheus/statsd_exporter v0.15.0/go.mod h1:Dv8HnkoLQkeEjkIE4/2ndAA7WL1zHKK7WMqFQqu72rw=
 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
 github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
@@ -861,13 +902,12 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0
 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
 github.com/schollz/progressbar/v3 v3.7.6 h1:akAvVpTy2IAcePWYndctoBaY9bLE3z4LE1Hn91BJ9g4=
 github.com/schollz/progressbar/v3 v3.7.6/go.mod h1:Y9mmL2knZj3LUaBDyBEzFdPrymIr08hnlFMZmfxwbx4=
+github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 github.com/shirou/gopsutil/v3 v3.21.3 h1:wgcdAHZS2H6qy4JFewVTtqfiYxFzCeEJod/mLztdPG8=
 github.com/shirou/gopsutil/v3 v3.21.3/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
-github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
-github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@@ -923,8 +963,6 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/tetratelabs/getenvoy-package v0.4.0 h1:MgIFtGj6SnLA405x+5i/FmWv3/E20lT5wKLkwtnt/U0=
-github.com/tetratelabs/getenvoy-package v0.4.0/go.mod h1:IrGJ2YZz3+qia1dEU9GFg3QieuMUUwiJf5tjG8uhogg=
 github.com/tetratelabs/log v0.0.0-20210323000454-90a3a3e141b5 h1:0EB6NF2qf74IIEc5P7KfOXUBZ0F8jMTb4+Z5e09z1G0=
 github.com/tetratelabs/log v0.0.0-20210323000454-90a3a3e141b5/go.mod h1:f/tP3FhNTKy6gn0QjYCXViykWjTHceFedy5O4xklKCE=
 github.com/tetratelabs/multierror v1.1.0 h1:cKmV/Pbf42K5wp8glxa2YIausbxIraPN8fzru9Pn1Cg=
@@ -1007,7 +1045,6 @@ go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKY
 go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
 go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
 go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
-go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
 go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
@@ -1038,9 +1075,7 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP
 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
 golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
@@ -1049,12 +1084,14 @@ golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMx
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
-golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
@@ -1064,7 +1101,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1092,13 +1128,15 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -1116,7 +1154,6 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180117170059-2c42eef0765b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1153,9 +1190,10 @@ golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1165,17 +1203,21 @@ golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
 golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1186,12 +1228,12 @@ golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 h1:VqE9gduFZ4dbR7XoL77lHFp0
 golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1203,7 +1245,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
 golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190213192042-740235f6c0d8/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -1211,6 +1253,7 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
@@ -1230,20 +1273,19 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200115044656-831fdb1e1868/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
-gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
-gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
-gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
 google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
 google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
@@ -1262,12 +1304,41 @@ google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww
 google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
 google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
-google.golang.org/genproto v0.0.0-20191223191004-3caeed10a8bf h1:1x8rC5/IgdLMPbPTvlQTN28+rcy8XL9Q19UWUMDyqYs=
-google.golang.org/genproto v0.0.0-20191223191004-3caeed10a8bf/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/grpc v1.28.1 h1:C1QC6KzgSiLyBabDi87BbjaGreoRgGUF5nOyvfrAZ1k=
-google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
+google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
+google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/genproto v0.0.0-20200619004808-3e7fca5c55db/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
+google.golang.org/genproto v0.0.0-20210406143921-e86de6bf7a46 h1:f4STrQZf8jaowsiUitigvrqMCCM4QJH1A2JCSI7U1ow=
+google.golang.org/genproto v0.0.0-20210406143921-e86de6bf7a46/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
+google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
+google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -1298,7 +1369,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
 gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
-gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -1317,8 +1387,8 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81
 gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
 gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
 gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
-helm.sh/helm/v3 v3.2.0 h1:V12EGAmr2DJ/fWrPo2fPdXWSIXvlXm51vGkQIXMeymE=
-helm.sh/helm/v3 v3.2.0/go.mod h1:ZaXz/vzktgwjyGGFbUWtIQkscfE7WYoRGP2szqAFHR0=
+helm.sh/helm/v3 v3.2.4 h1:lz/0ZRkSgyIF+pCo6pjFzap1udCARB1IN6CRfqkpcOg=
+helm.sh/helm/v3 v3.2.4/go.mod h1:ZaXz/vzktgwjyGGFbUWtIQkscfE7WYoRGP2szqAFHR0=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -1326,16 +1396,17 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
 honnef.co/go/tools v0.0.1-2020.1.5 h1:nI5egYTGJakVyOryqLs1cQO5dO0ksin5XXs2pspk75k=
 honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-istio.io/api v0.0.0-20190515205759-982e5c3888c6/go.mod h1:hhLFQmpHia8zgaM37vb2ml9iS5NfNfqZGRt1pS9aVEo=
-istio.io/api v0.0.0-20201113182140-d4b7e3fc2b44 h1:mfs4UJtpH8ElVEohFZw39qDGv9gg7TOkYVTwJZGQ5Yc=
-istio.io/api v0.0.0-20201113182140-d4b7e3fc2b44/go.mod h1:kyq3g5w42zl/AKlbzDGppYpGMQYMYMyZKeq0/eexML8=
+istio.io/api v0.0.0-20210128181506-0c4b8e54850f h1:zUFsawgPj5oI9p5cf91YCExRlxLIVsEkIunN9ODUSJs=
+istio.io/api v0.0.0-20210128181506-0c4b8e54850f/go.mod h1:88HN3o1fSD1jo+Z1WTLlJfMm9biopur6Ct9BFKjiB64=
+istio.io/client-go v0.0.0-20200626204548-8f69a2d0fe26 h1:XLTmjndquXukwZVU9G6c3d/2ew43te4SuMap8UTP1R4=
+istio.io/client-go v0.0.0-20200626204548-8f69a2d0fe26/go.mod h1:OQTGBgFbgNzUMafgS5LExTTMQAA+JeC6d0m1Tphi2dk=
 istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a/go.mod h1:OzpAts7jljZceG4Vqi5/zXy/pOg1b209T3jb7Nv5wIs=
-istio.io/gogo-genproto v0.0.0-20201113182723-5b8563d8a012 h1:rCPnRe6A2LvpvP1/fy1ZzPFBUaWmBUHxFEw4Onphd7c=
-istio.io/gogo-genproto v0.0.0-20201113182723-5b8563d8a012/go.mod h1:OzpAts7jljZceG4Vqi5/zXy/pOg1b209T3jb7Nv5wIs=
-istio.io/istio v0.0.0-20201120194348-3ddc57b6d1e1 h1:lIk7XC+bSjXbrh+PRTQcLnXgfLdyfO+sUJY7XJ75imk=
-istio.io/istio v0.0.0-20201120194348-3ddc57b6d1e1/go.mod h1:5hRpO7SVsWHPNlWbRQdGPquaVBmP/tBZ5dWJaE1uu+s=
-istio.io/pkg v0.0.0-20201113182530-a5cdf6e8c3cd h1:7C+MPiK9MJoGtzrXC0Jlq4r9e084LipK9FePdkCHNUM=
-istio.io/pkg v0.0.0-20201113182530-a5cdf6e8c3cd/go.mod h1:pwGaxLUDLobzL/WvWV94z72LvBbB1dr2UUUyPuasfIU=
+istio.io/gogo-genproto v0.0.0-20201202160550-002d724ddaf1 h1:W26FOSrTCACYL44NLI80b0TzEidJJIArZKM5SyMpQXc=
+istio.io/gogo-genproto v0.0.0-20201202160550-002d724ddaf1/go.mod h1:OzpAts7jljZceG4Vqi5/zXy/pOg1b209T3jb7Nv5wIs=
+istio.io/istio v0.0.0-20210223230603-30e54dcb8a1c h1:J0Mo4V7SZixhsm5WOaLvi6HaNkhWaxa4ldabiAyfePA=
+istio.io/istio v0.0.0-20210223230603-30e54dcb8a1c/go.mod h1:HOQAPYUj6hCen/Hpe/yxqYb+PrdI+XOvcutoytMKvsI=
+istio.io/pkg v0.0.0-20201202160453-b7f8c8c88ca3 h1:WwzSeggtAh8VN0MOrHSXNIS7qfRoK9jOooMUlM3hHhk=
+istio.io/pkg v0.0.0-20201202160453-b7f8c8c88ca3/go.mod h1:EwvmercDF5DLCg5qUQlkM40xHwCxGoY1H/2LhI1p2YU=
 k8s.io/api v0.18.17 h1:agJCdV5RfRhMwq4cMOHg0OmgBHtJy6sPhHwplYlSxUA=
 k8s.io/api v0.18.17/go.mod h1:V+urZjc5sy5ASshZ2x3BwXpWq8odNu3oHCkFNBkWP4A=
 k8s.io/apiextensions-apiserver v0.18.17 h1:vsibwtMQsjPFoNQzW89WoNSNqueIKhzb+vHAQCNIW8g=
@@ -1344,53 +1415,53 @@ k8s.io/apimachinery v0.18.17 h1:iCWRsVV6/e1hKjlQmUYB59TJ0rDAuZAH8BAB1/J4z24=
 k8s.io/apimachinery v0.18.17/go.mod h1:PF5taHbXgTEJLU+xMypMmYTXTWPJ5LaW8bfsisxnEXk=
 k8s.io/apiserver v0.18.17/go.mod h1:N/k1smGLNF7pSB8uJo7++x4euJDXrQYxkvKe/jvP54g=
 k8s.io/cli-runtime v0.18.0/go.mod h1:1eXfmBsIJosjn9LjEBUd2WVPoPAY9XGTqTFcPMIBsUQ=
+k8s.io/cli-runtime v0.18.3 h1:8IBtaTYmXiXipKdx2FAKotvnQMjcF0kSLvX4szY340c=
+k8s.io/cli-runtime v0.18.3/go.mod h1:pqbbi4nqRIQhUWAVzen8uE8DD/zcZLwf+8sQYO4lwLk=
 k8s.io/client-go v0.18.17 h1:swxjxi4kjd6qEGLJx52kDzydRXmp8suBKTzuj6Nt5Ts=
 k8s.io/client-go v0.18.17/go.mod h1:GQAMNBybHOUvL/Hq1JRl8HnUgI1ZO0lpAjIp32rX1qs=
-k8s.io/code-generator v0.17.0/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s=
 k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
+k8s.io/code-generator v0.18.3/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
 k8s.io/code-generator v0.18.17/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
 k8s.io/component-base v0.18.0/go.mod h1:u3BCg0z1uskkzrnAKFzulmYaEpZF7XC9Pf/uFyb1v2c=
+k8s.io/component-base v0.18.3/go.mod h1:bp5GzGR0aGkYEfTj+eTY0AN/vXTgkJdQXjNTTVUaa3k=
+k8s.io/component-base v0.18.17 h1:dRelNl8+ATDH7cdVuNW1/9OUYsI26pGxZ8NUqx3K6zs=
 k8s.io/component-base v0.18.17/go.mod h1:0KWlkryUhBq2TrS1F/HovpyLn2tCY1VsapktQqQEgmM=
 k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
 k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
 k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
+k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
 k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
 k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
 k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
 k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
 k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ=
 k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
-k8s.io/kube-openapi v0.0.0-20200204173128-addea2498afe h1:GOfbcWvX5wW2vcfNch83xYp9SDZjRgAJk+t373yaHKk=
-k8s.io/kube-openapi v0.0.0-20200204173128-addea2498afe/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
-k8s.io/kubectl v0.18.0 h1:hu52Ndq/d099YW+3sS3VARxFz61Wheiq8K9S7oa82Dk=
+k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
+k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY=
+k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
 k8s.io/kubectl v0.18.0/go.mod h1:LOkWx9Z5DXMEg5KtOjHhRiC1fqJPLyCr3KtQgEolCkU=
+k8s.io/kubectl v0.18.3 h1:WvlO1MQvteqrpoX1SgYf5TZ+ofTGvdkhoNELzc2EBkQ=
+k8s.io/kubectl v0.18.3/go.mod h1:k/EpvXBDgEsHBzWr0A44l9+ArvYi3txBBnzXBjQasUQ=
 k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
 k8s.io/metrics v0.18.0/go.mod h1:8aYTW18koXqjLVKL7Ds05RPMX9ipJZI3mywYvBOxXd4=
-k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
+k8s.io/metrics v0.18.3/go.mod h1:TkuJE3ezDZ1ym8pYkZoEzJB7HDiFE7qxl+EmExEBoPA=
 k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
 k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw=
 k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
-modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
-modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
-modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
-modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
 rsc.io/letsencrypt v0.0.3 h1:H7xDfhkaFFSYEJlKeq38RwX2jYcnTeHuDQyT+mMNMwM=
 rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
-sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
-sigs.k8s.io/controller-runtime v0.5.1-0.20200327213554-2d4c4877f906 h1:GmjdjkxJjSpke49jWgDxBsd9uuHFdxEkBntoImFd2D8=
-sigs.k8s.io/controller-runtime v0.5.1-0.20200327213554-2d4c4877f906/go.mod h1:j4echH3Y/UPHRpXS65rxGXujda8iWOheMQvDh1uNgaY=
-sigs.k8s.io/controller-tools v0.2.4/go.mod h1:m/ztfQNocGYBgTTCmFdnK94uVvgxeZeE3LtJvd/jIzA=
+sigs.k8s.io/controller-runtime v0.6.0 h1:Fzna3DY7c4BIP6KwfSlrfnj20DJ+SeMBK8HSFvOk9NM=
+sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo=
+sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI=
+sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
 sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
-sigs.k8s.io/service-apis v0.0.0-20200227172328-b9010cfacdbe h1:Tn0sYnXtLIOKiThxkyCXloG7t8B6WMF5vfbJeY58Jno=
-sigs.k8s.io/service-apis v0.0.0-20200227172328-b9010cfacdbe/go.mod h1:fkpFab5voExC6b20STN308OokChxH4wQl95RLbo8WOA=
+sigs.k8s.io/service-apis v0.0.0-20200708220836-10c7cb28ed93 h1:nDMWlSSF9VMlyUnDqHSjqHIBemtt7cS3QM2NDVIhsy0=
+sigs.k8s.io/service-apis v0.0.0-20200708220836-10c7cb28ed93/go.mod h1:s/e4e7RMwEcieVQ33+YMaKbSeaQyatebjinhC/kIJ3U=
 sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
 sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E=
 sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
-sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
 sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
 sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
 sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
diff --git a/pkg/binary/envoy/adminport.go b/pkg/binary/envoy/adminport.go
index f8e55ee..1bc5990 100644
--- a/pkg/binary/envoy/adminport.go
+++ b/pkg/binary/envoy/adminport.go
@@ -16,8 +16,8 @@ package envoy
 
 import (
 	"fmt"
-	"io/ioutil"
 	"net"
+	"os"
 	"path/filepath"
 
 	"github.com/tetratelabs/log"
@@ -46,7 +46,7 @@ func appendArg(r binary.Runner) error {
 
 func readAdminAddressFile(r *Runtime) string {
 	adminAddressFile := filepath.Join(r.DebugStore(), "admin-address.txt")
-	adminAddress, err := ioutil.ReadFile(adminAddressFile) //nolint:gosec
+	adminAddress, err := os.ReadFile(adminAddressFile) //nolint:gosec
 	if err != nil {
 		log.Debugf("unable to read %s: %v", adminAddressFile, err)
 		return ""
diff --git a/pkg/binary/envoy/config.go b/pkg/binary/envoy/config.go
index 55222ef..36d8ba6 100644
--- a/pkg/binary/envoy/config.go
+++ b/pkg/binary/envoy/config.go
@@ -16,13 +16,10 @@ package envoy
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
 	"path/filepath"
-	"time"
 
-	"github.com/golang/protobuf/ptypes"
-	durationpb "github.com/golang/protobuf/ptypes/duration"
+	durationpb "google.golang.org/protobuf/types/known/durationpb"
 )
 
 // Mode is the mode Envoy should run in
@@ -54,9 +51,8 @@ func ParseMode(s string) Mode {
 func NewConfig(options ...func(*Config)) *Config {
 	cfg := &Config{
 		AdminPort:      15000,
-		StatNameLength: 189,
-		DrainDuration:  ptypes.DurationProto(30 * time.Second),
-		ConnectTimeout: ptypes.DurationProto(5 * time.Second),
+		DrainDuration:  &durationpb.Duration{Seconds: 30},
+		ConnectTimeout: &durationpb.Duration{Seconds: 5},
 	}
 	for _, o := range options {
 		o(cfg)
@@ -74,7 +70,6 @@ type Config struct {
 	ConnectTimeout *durationpb.Duration
 	AdminAddress   string
 	AdminPort      int32
-	StatNameLength int32
 }
 
 // GetAdminAddress returns a host:port formatted address of the Envoy admin listener.
@@ -97,7 +92,7 @@ func (r *Runtime) SaveConfig(name, config string) (string, error) {
 		return "", fmt.Errorf("Unable to create directory %q: %v", configDir, err)
 	}
 	filename := name + ".yaml"
-	err := ioutil.WriteFile(filepath.Join(configDir, filename), []byte(config), 0600)
+	err := os.WriteFile(filepath.Join(configDir, filename), []byte(config), 0600)
 	if err != nil {
 		return "", fmt.Errorf("Cannot save config file %s: %s", filepath.Join(configDir, filename), err)
 	}
diff --git a/pkg/binary/envoy/controlplane/istio-1.6.14/tools/packaging/common/envoy_bootstrap_v2.json b/pkg/binary/envoy/controlplane/istio-1.7.8/tools/packaging/common/envoy_bootstrap.json
similarity index 87%
rename from pkg/binary/envoy/controlplane/istio-1.6.14/tools/packaging/common/envoy_bootstrap_v2.json
rename to pkg/binary/envoy/controlplane/istio-1.7.8/tools/packaging/common/envoy_bootstrap.json
index cc519d3..fafda2f 100644
--- a/pkg/binary/envoy/controlplane/istio-1.6.14/tools/packaging/common/envoy_bootstrap_v2.json
+++ b/pkg/binary/envoy/controlplane/istio-1.7.8/tools/packaging/common/envoy_bootstrap.json
@@ -21,6 +21,21 @@
     },
     "metadata": {{ .meta_json_str }}
   },
+  "layered_runtime": {
+      "layers": [
+          {
+              "name": "deprecation",
+              "static_layer": {
+                  "envoy.deprecated_features:envoy.config.listener.v3.Listener.hidden_envoy_deprecated_use_original_dst": true,
+                  "envoy.reloadable_features.strict_1xx_and_204_response_headers": false
+              }
+          },
+          {
+              "name": "admin",
+              "admin_layer": {}
+          }
+      ]
+  },
   "stats_config": {
     "use_all_default_tags": false,
     "stats_tags": [
@@ -119,13 +134,16 @@
   },
   "dynamic_resources": {
     "lds_config": {
-      "ads": {}
+      "ads": {},
+      "resource_api_version": "V3"
     },
     "cds_config": {
-      "ads": {}
+      "ads": {},
+      "resource_api_version": "V3"
     },
     "ads_config": {
       "api_type": "GRPC",
+      "transport_api_version": "V3",
       "grpc_services": [
         {
           "envoy_grpc": {
@@ -213,7 +231,8 @@
         "transport_socket": {
           "name": "envoy.transport_sockets.tls",
           "typed_config": {
-            "@type": "type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext",
+            "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
+            "sni": "{{ .discovery_host }}",
             "common_tls_context": {
               "alpn_protocols": [
                 "h2"
@@ -222,8 +241,11 @@
                 {
                   "name": "default",
                   "sds_config": {
+                    "resource_api_version": "V3",
+                    "initial_fetch_timeout": "0s",
                     "api_config_source": {
                       "api_type": "GRPC",
+                      "transport_api_version": "V3",
                       "grpc_services": [
                         {
                           "envoy_grpc": { "cluster_name": "sds-grpc" }
@@ -289,9 +311,9 @@
       ,
       {
         "name": "zipkin",
-        {{ if .tracing_tls }}
+        {{- if .tracing_tls }}
         "transport_socket": {{ .tracing_tls }},
-        {{ end }}
+        {{- end }}
         "type": "STRICT_DNS",
         "respect_dns_ttl": true,
         "dns_lookup_family": "{{ .dns_lookup_family }}",
@@ -314,9 +336,9 @@
       ,
       {
         "name": "lightstep",
-        {{ if .tracing_tls }}
+        {{- if .tracing_tls }}
         "transport_socket": {{ .tracing_tls }},
-        {{ end }}
+        {{- end }}
         "http2_protocol_options": {},
         "type": "STRICT_DNS",
         "respect_dns_ttl": true,
@@ -340,9 +362,9 @@
       ,
       {
         "name": "datadog_agent",
-        {{ if .tracing_tls }}
+        {{- if .tracing_tls }}
         "transport_socket": {{ .tracing_tls }},
-        {{ end }}
+        {{- end }}
         "connect_timeout": "1s",
         "type": "STRICT_DNS",
         "respect_dns_ttl": true,
@@ -362,17 +384,17 @@
         }
       }
       {{ end }}
-      {{ if .envoy_metrics_service_address }}
+      {{- if .envoy_metrics_service_address }}
       ,
       {
         "name": "envoy_metrics_service",
         "type": "STRICT_DNS",
-      {{ if .envoy_metrics_service_tls }}
-        "tls_context": {{ .envoy_metrics_service_tls }},
-      {{ end }}
-      {{ if .envoy_metrics_service_tcp_keepalive }}
+      {{- if .envoy_metrics_service_tls }}
+        "transport_socket": {{ .envoy_metrics_service_tls }},
+      {{- end }}
+      {{- if .envoy_metrics_service_tcp_keepalive }}
         "upstream_connection_options": {{ .envoy_metrics_service_tcp_keepalive }},
-      {{ end }}
+      {{- end }}
         "respect_dns_ttl": true,
         "dns_lookup_family": "{{ .dns_lookup_family }}",
         "connect_timeout": "1s",
@@ -397,10 +419,10 @@
       {
         "name": "envoy_accesslog_service",
         "type": "STRICT_DNS",
-      {{ if .envoy_accesslog_service_tls }}
-        "tls_context": {{ .envoy_accesslog_service_tls }},
-      {{ end }}
-      {{ if .envoy_accesslog_service_tcp_keepalive }}
+      {{- if .envoy_accesslog_service_tls }}
+        "transport_socket": {{ .envoy_accesslog_service_tls }},
+      {{- end }}
+      {{- if .envoy_accesslog_service_tcp_keepalive }}
         "upstream_connection_options": {{ .envoy_accesslog_service_tcp_keepalive }},
       {{ end }}
         "respect_dns_ttl": true,
@@ -438,7 +460,7 @@
               {
                 "name": "envoy.http_connection_manager",
                 "typed_config": {
-                  "@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager",
+                  "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
                   "codec_type": "AUTO",
                   "stat_prefix": "stats",
                   "route_config": {
@@ -464,7 +486,7 @@
                   "http_filters": [{
                     "name": "envoy.router",
                     "typed_config": {
-                      "@type": "type.googleapis.com/envoy.config.filter.http.router.v2.Router"
+                      "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
                     }
                   }]
                 }
@@ -487,7 +509,7 @@
               {
                 "name": "envoy.http_connection_manager",
                 "typed_config": {
-                  "@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager",
+                  "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
                   "codec_type": "AUTO",
                   "stat_prefix": "agent",
                   "route_config": {
@@ -513,7 +535,7 @@
                   "http_filters": [{
                     "name": "envoy.router",
                     "typed_config": {
-                      "@type": "type.googleapis.com/envoy.config.filter.http.router.v2.Router"
+                      "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
                     }
                   }]
                 }
@@ -524,13 +546,13 @@
       }
     ]
   }
-  {{ if .zipkin }}
+  {{- if .zipkin }}
   ,
   "tracing": {
     "http": {
       "name": "envoy.zipkin",
       "typed_config": {
-        "@type": "type.googleapis.com/envoy.config.trace.v2.ZipkinConfig",
+        "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
         "collector_cluster": "zipkin",
         "collector_endpoint": "/api/v2/spans",
         "collector_endpoint_version": "HTTP_JSON",
@@ -539,37 +561,37 @@
       }
     }
   }
-  {{ else if .lightstep }}
+  {{- else if .lightstep }}
   ,
   "tracing": {
     "http": {
       "name": "envoy.lightstep",
       "typed_config": {
-        "@type": "type.googleapis.com/envoy.config.trace.v2.LightstepConfig",
+        "@type": "type.googleapis.com/envoy.config.trace.v3.LightstepConfig",
         "collector_cluster": "lightstep",
         "access_token_file": "{{ .lightstepToken}}"
       }
     }
   }
-  {{ else if .datadog }}
+  {{- else if .datadog }}
   ,
   "tracing": {
     "http": {
       "name": "envoy.tracers.datadog",
       "typed_config": {
-        "@type": "type.googleapis.com/envoy.config.trace.v2.DatadogConfig",
+        "@type": "type.googleapis.com/envoy.config.trace.v3.DatadogConfig",
         "collector_cluster": "datadog_agent",
         "service_name": "{{ .cluster }}"
       }
     }
   }
-  {{ else if .stackdriver }}
+  {{- else if .stackdriver }}
   ,
   "tracing": {
     "http": {
       "name": "envoy.tracers.opencensus",
       "typed_config": {
-      "@type": "type.googleapis.com/envoy.config.trace.v2.OpenCensusConfig",
+      "@type": "type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig",
       "stackdriver_exporter_enabled": true,
       "stackdriver_project_id": "{{ .stackdriverProjectID }}",
       {{ if .sts_port }}
@@ -584,14 +606,14 @@
               }
             }
           },
-          "call_credentials": {
+          "call_credentials": [{
             "sts_service": {
               "token_exchange_service_uri": "http://localhost:{{ .sts_port }}/token",
               "subject_token_path": "/var/run/secrets/tokens/istio-token",
               "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
-              "scope": "https://www.googleapis.com/auth/cloud-platform",
+              "scope": "https://www.googleapis.com/auth/cloud-platform"
             }
-          }
+          }]
         },
         "initial_metadata": [
         {{ if .gcp_project_id }}
@@ -613,7 +635,7 @@
         "max_number_of_annotations": {{ .stackdriverMaxAnnotations }},
         "max_number_of_attributes": {{ .stackdriverMaxAttributes }},
         "max_number_of_message_events": {{ .stackdriverMaxEvents }},
-        "max_number_of_links": 200,
+        "max_number_of_links": 200
        }
      }
   }}
@@ -649,7 +671,7 @@
   ,
   "cluster_manager": {
     "outlier_detection": {
-      "event_log_path": {{ .outlier_log_path }}
+      "event_log_path": "{{ .outlier_log_path }}"
     }
   }
   {{ end }}
diff --git a/pkg/binary/envoy/controlplane/istio.go b/pkg/binary/envoy/controlplane/istio.go
index 69b6e6b..b03109a 100644
--- a/pkg/binary/envoy/controlplane/istio.go
+++ b/pkg/binary/envoy/controlplane/istio.go
@@ -18,15 +18,10 @@ import (
 	_ "embed" //nolint
 	"errors"
 	"fmt"
-	"io/ioutil"
 	"net"
 	"os"
 	"path/filepath"
-	"time"
 
-	"github.com/golang/protobuf/ptypes"
-	durationpb "github.com/golang/protobuf/ptypes/duration"
-	"github.com/tetratelabs/log"
 	meshconfig "istio.io/api/mesh/v1alpha1"
 	"istio.io/istio/pilot/pkg/model"
 	"istio.io/istio/pkg/bootstrap"
@@ -41,11 +36,11 @@ const (
 	initialEpochBootstrap = "envoy-rev1.json"
 )
 
-// envoyBootstrapTemplate is the "envoy_bootstrap_v2.json" from the Istio release tag or distribution
-//go:embed istio-1.6.14/tools/packaging/common/envoy_bootstrap_v2.json
+// envoyBootstrapTemplate is the "envoy_bootstrap.json" from the Istio release tag or distribution
+//go:embed istio-1.7.8/tools/packaging/common/envoy_bootstrap.json
 var envoyBootstrapTemplate []byte
 
-//  ^^ ex source: https://raw.githubusercontent.com/istio/istio/1.6.14/tools/packaging/common/envoy_bootstrap_v2.json
+//  ^^ ex source: https://raw.githubusercontent.com/istio/istio/1.7.8/tools/packaging/common/envoy_bootstrap.json
 
 // Istio tells GetEnvoy that it's using Istio for xDS and should bootstrap accordingly
 func Istio(r *envoy.Runtime) {
@@ -71,24 +66,12 @@ func appendArgs(r binary.Runner) error {
 	}
 	args := []string{
 		"--config-path", filepath.Join(e.DebugStore(), initialEpochBootstrap),
-		"--drain-time-s", fmt.Sprint(int(convertDuration(e.Config.DrainDuration) / time.Second)),
-		"--max-obj-name-len", fmt.Sprint(e.Config.StatNameLength),
+		"--drain-time-s", fmt.Sprint(e.Config.DrainDuration.Seconds),
 	}
 	r.AppendArgs(args)
 	return nil
 }
 
-func convertDuration(d *durationpb.Duration) time.Duration {
-	if d == nil {
-		return 0
-	}
-	dur, err := ptypes.Duration(d)
-	if err != nil {
-		log.Warnf("unable to convert proto duration %v to time.Duration", d)
-	}
-	return dur
-}
-
 func writeBootstrap(r binary.Runner) error {
 	// Type assert as we're using Envoy specific config
 	e, ok := r.(*envoy.Runtime)
@@ -117,7 +100,8 @@ func generateIstioConfig(e *envoy.Runtime) meshconfig.ProxyConfig {
 	cfg.ProxyAdminPort = e.Config.AdminPort
 	cfg.ProxyBootstrapTemplatePath = filepath.Join(e.TmplDir, "istio_bootstrap_tmpl.json")
 	cfg.EnvoyAccessLogService = &meshconfig.RemoteService{Address: e.Config.ALSAddresss}
-	// cfg.ControlPlaneAuthPolicy = v1alpha1.AuthenticationPolicy_MUTUAL_TLS // TODO: turn on!
+	// Required: Defaults to MUTUAL_TLS, but we don't configure auth, yet, so it has to be set to NONE
+	cfg.ControlPlaneAuthPolicy = meshconfig.AuthenticationPolicy_NONE
 	return cfg
 }
 
@@ -156,7 +140,7 @@ func writeProxyBootstrapTemplate(proxyBootstrapTemplatePath string) error {
 	if err := os.MkdirAll(filepath.Dir(proxyBootstrapTemplatePath), os.ModePerm); err != nil {
 		return err
 	}
-	if err := ioutil.WriteFile(proxyBootstrapTemplatePath, envoyBootstrapTemplate, 0600); err != nil {
+	if err := os.WriteFile(proxyBootstrapTemplatePath, envoyBootstrapTemplate, 0600); err != nil {
 		return err
 	}
 	return nil
diff --git a/pkg/cmd/extension/run/cmd.go b/pkg/cmd/extension/run/cmd.go
index 6d6da71..e8f561a 100644
--- a/pkg/cmd/extension/run/cmd.go
+++ b/pkg/cmd/extension/run/cmd.go
@@ -15,9 +15,10 @@
 package run
 
 import (
-	"io/ioutil"
+	"errors"
+	"fmt"
+	"os"
 
-	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
 
 	"github.com/tetratelabs/getenvoy/pkg/cmd/extension/build"
@@ -66,14 +67,14 @@ func (opts *runOpts) validateExtension() error {
 	// pre-built *.wasm file
 	if opts.Extension.WasmFile != "" {
 		if err := osutil.IsRegularFile(opts.Extension.WasmFile); err != nil {
-			return errors.Wrapf(err, "unable to find a pre-built *.wasm file at %q", opts.Extension.WasmFile)
+			return fmt.Errorf("unable to find a pre-built *.wasm file at %q: %w", opts.Extension.WasmFile, err)
 		}
 	}
 	// custom extension config
 	if opts.Extension.Config.Source != "" {
-		data, err := ioutil.ReadFile(opts.Extension.Config.Source)
+		data, err := os.ReadFile(opts.Extension.Config.Source)
 		if err != nil {
-			return errors.Wrapf(err, "failed to read custom extension config from file %q", opts.Extension.Config.Source)
+			return fmt.Errorf("failed to read custom extension config from file %q: %w", opts.Extension.Config.Source, err)
 		}
 		opts.Extension.Config.Content = data
 	}
@@ -88,13 +89,13 @@ func (opts *runOpts) validateEnvoy() error {
 	// Envoy version
 	if opts.Envoy.Version != "" {
 		if _, err := commontypes.ParseReference(opts.Envoy.Version); err != nil {
-			return errors.Wrap(err, "Envoy version is not valid")
+			return fmt.Errorf("envoy version is not valid: %w", err)
 		}
 	}
 	// Envoy path
 	if opts.Envoy.Path != "" {
 		if err := osutil.IsExecutable(opts.Envoy.Path); err != nil {
-			return errors.Wrapf(err, "unable to find custom Envoy binary at %q", opts.Envoy.Path)
+			return fmt.Errorf("unable to find custom Envoy binary at %q: %w", opts.Envoy.Path, err)
 		}
 	}
 	// Envoy args
@@ -212,7 +213,7 @@ Run Envoy extension in the example setup.`,
 				IO:   cmdutil.StreamsOf(cmd),
 			})
 			if err != nil {
-				return errors.Wrapf(err, "failed to run %q example", opts.Run.Example.Name)
+				return fmt.Errorf("failed to run %q example: %w", opts.Run.Example.Name, err)
 			}
 			return nil
 		},
diff --git a/pkg/extension/example/init/registry/default.go b/pkg/extension/example/init/registry/default.go
index c61a364..9d4fa97 100644
--- a/pkg/extension/example/init/registry/default.go
+++ b/pkg/extension/example/init/registry/default.go
@@ -15,7 +15,6 @@
 package registry
 
 import (
-	"net/http"
 	"path"
 
 	exampleTemplates "github.com/tetratelabs/getenvoy/data/example/init"
@@ -26,9 +25,9 @@ var templatesFs = exampleTemplates.GetTemplates()
 
 func newDefaultRegistry() registry {
 	return &fsRegistry{
-		fs: http.FS(templatesFs),
+		fs: templatesFs,
 		namingScheme: func(category extension.Category, example string) string {
-			return "/" + path.Join(category.String(), example)
+			return path.Join(category.String(), example)
 		},
 	}
 }
diff --git a/pkg/extension/example/init/registry/types.go b/pkg/extension/example/init/registry/types.go
index 45ba188..a2bcdda 100644
--- a/pkg/extension/example/init/registry/types.go
+++ b/pkg/extension/example/init/registry/types.go
@@ -15,16 +15,13 @@
 package registry
 
 import (
-	"io/ioutil"
-	"net/http"
-	"os"
+	"fmt"
+	"io"
+	"io/fs"
 	"path"
 	"path/filepath"
 	"strings"
 
-	"github.com/pkg/errors"
-	"github.com/shurcooL/httpfs/vfsutil"
-
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config/extension"
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/model"
 )
@@ -38,7 +35,7 @@ type registry interface {
 // fsRegistry represents a registry of example templates backed by
 // an in-memory file system.
 type fsRegistry struct {
-	fs           http.FileSystem
+	fs           fs.FS
 	namingScheme func(category extension.Category, example string) string
 }
 
@@ -46,15 +43,15 @@ func (r *fsRegistry) Get(descriptor *extension.Descriptor, example string) (*Ent
 	dirName := r.namingScheme(descriptor.Category, example)
 	dir, err := r.fs.Open(dirName)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to open: %s", dirName)
+		return nil, fmt.Errorf(`failed to open %q: %w`, dirName, err)
 	}
 	defer dir.Close() //nolint:errcheck
 	info, err := dir.Stat()
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to stat: %s", dirName)
+		return nil, fmt.Errorf(`failed to stat %q: %w`, dirName, err)
 	}
 	if !info.IsDir() {
-		return nil, errors.Errorf("%q is not a directory", dirName)
+		return nil, fmt.Errorf(`%q is not a directory: %w`, dirName, err)
 	}
 
 	return &Entry{
@@ -66,7 +63,7 @@ func (r *fsRegistry) Get(descriptor *extension.Descriptor, example string) (*Ent
 			// Add language independent files
 			fileNames, err := listFiles(r.fs, dirName)
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to list files in a directory: %s", dirName)
+				return nil, fmt.Errorf(`failed to list files in a directory %q: %w`, dirName, err)
 			}
 			for _, fileName := range fileNames {
 				err = r.addFile(fileSet, dirName, fileName, descriptor.Language)
@@ -76,10 +73,10 @@ func (r *fsRegistry) Get(descriptor *extension.Descriptor, example string) (*Ent
 			}
 
 			// Add language specific files
-			languageDir := path.Join("/language-specific", descriptor.Language.String())
+			languageDir := path.Join("language-specific", descriptor.Language.String())
 			fileNames, err = listFiles(r.fs, languageDir)
 			if err != nil {
-				return nil, errors.Wrapf(err, "failed to list files in a directory: %s", dirName)
+				return nil, fmt.Errorf(`failed to list files in a directory %q: %w`, dirName, err)
 			}
 			for _, fileName := range fileNames {
 				err = r.addFile(fileSet, languageDir, fileName, descriptor.Language)
@@ -95,12 +92,12 @@ func (r *fsRegistry) Get(descriptor *extension.Descriptor, example string) (*Ent
 func (r *fsRegistry) addFile(fileSet model.FileSet, dirName, fileName string, language extension.Language) error {
 	file, err := r.fs.Open(fileName)
 	if err != nil {
-		return errors.Wrapf(err, "failed to open: %s", fileName)
+		return fmt.Errorf(`failed to open %q: %w`, dirName, err)
 	}
 	defer file.Close() //nolint:errcheck
-	data, err := ioutil.ReadAll(file)
+	data, err := io.ReadAll(file)
 	if err != nil {
-		return errors.Wrapf(err, "failed to read: %s", fileName)
+		return fmt.Errorf(`failed to read %q: %w`, fileName, err)
 	}
 	relPath, err := filepath.Rel(dirName, fileName)
 	if err != nil {
@@ -125,13 +122,13 @@ func (r *fsRegistry) addFile(fileSet model.FileSet, dirName, fileName string, la
 	return nil
 }
 
-func listFiles(fs http.FileSystem, root string) ([]string, error) {
+func listFiles(f fs.FS, root string) ([]string, error) {
 	fileNames := make([]string, 0)
-	err := vfsutil.Walk(fs, root, func(path string, info os.FileInfo, err error) error {
+	err := fs.WalkDir(f, root, func(path string, d fs.DirEntry, err error) error {
 		if err != nil {
 			return err
 		}
-		if info.IsDir() {
+		if d.IsDir() {
 			return nil
 		}
 		fileNames = append(fileNames, path)
diff --git a/pkg/extension/init/init.go b/pkg/extension/init/init.go
index 882e504..5b14edb 100644
--- a/pkg/extension/init/init.go
+++ b/pkg/extension/init/init.go
@@ -18,14 +18,12 @@ import (
 	"bytes"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"os"
 	"path"
 	"path/filepath"
 	"text/template"
 
-	"github.com/pkg/errors"
 	"github.com/tetratelabs/multierror"
 
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config/extension"
@@ -124,7 +122,7 @@ func (s *scaffolder) visit(sourceDirName, destinationDirName string, sourceFileI
 			errs = multierror.Append(errs, e)
 		}
 	}()
-	content, err := ioutil.ReadAll(sourceFile)
+	content, err := io.ReadAll(sourceFile)
 	if err != nil {
 		return err
 	}
@@ -135,7 +133,7 @@ func (s *scaffolder) visit(sourceDirName, destinationDirName string, sourceFileI
 		}
 		content = data
 	}
-	if err := ioutil.WriteFile(outputFileName, content, sourceFileInfo.Mode()); err != nil {
+	if err := os.WriteFile(outputFileName, content, sourceFileInfo.Mode()); err != nil {
 		return err
 	}
 	s.opts.ProgressSink.OnFile(relOutputFileName)
@@ -159,7 +157,7 @@ func interpolate(descriptor *extension.Descriptor) func(string, []byte) ([]byte,
 		var out bytes.Buffer
 		err = tmpl.Execute(&out, data)
 		if err != nil {
-			return nil, errors.Wrapf(err, "failed to render %q", file)
+			return nil, fmt.Errorf("failed to render %q: %w", file, err)
 		}
 		return out.Bytes(), nil
 	}
diff --git a/pkg/extension/wasmimage/puller.go b/pkg/extension/wasmimage/puller.go
index c3aa11f..0b2e2e1 100644
--- a/pkg/extension/wasmimage/puller.go
+++ b/pkg/extension/wasmimage/puller.go
@@ -18,8 +18,8 @@ import (
 	"context"
 	"crypto/tls"
 	"fmt"
-	"io/ioutil"
 	"net/http"
+	"os"
 
 	"github.com/containerd/containerd/remotes"
 	"github.com/deislabs/oras/pkg/auth/docker"
@@ -77,7 +77,7 @@ func (p *Puller) Pull(imageRef, imagePath string) (ocispec.Descriptor, error) {
 	}
 	manifest, image, _ := store.Get(layers[0])
 
-	if err := ioutil.WriteFile(imagePath, image, 0600); err != nil {
+	if err := os.WriteFile(imagePath, image, 0600); err != nil {
 		return manifest, fmt.Errorf("failed to write image: %w", err)
 	}
 
diff --git a/pkg/extension/wasmimage/wasmimage.go b/pkg/extension/wasmimage/wasmimage.go
index 5bcf1de..89b8217 100644
--- a/pkg/extension/wasmimage/wasmimage.go
+++ b/pkg/extension/wasmimage/wasmimage.go
@@ -17,7 +17,6 @@ package wasmimage
 import (
 	"bytes"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 
@@ -51,7 +50,7 @@ func newWasmImage(ref, path string) (*wasmImage, error) {
 
 	name := filepath.Base(path)
 
-	contents, err := ioutil.ReadFile(filepath.Clean(path))
+	contents, err := os.ReadFile(filepath.Clean(path))
 	if err != nil {
 		return nil, fmt.Errorf("failed to read %#v: %w", path, err)
 	}
diff --git a/pkg/extension/workspace/config/extension/helpers.go b/pkg/extension/workspace/config/extension/helpers.go
index 64b75a0..a76d828 100644
--- a/pkg/extension/workspace/config/extension/helpers.go
+++ b/pkg/extension/workspace/config/extension/helpers.go
@@ -16,10 +16,11 @@ package extension
 
 import (
 	"encoding/json"
+	"errors"
+	"fmt"
 	"regexp"
 	"strings"
 
-	"github.com/pkg/errors"
 	"github.com/tetratelabs/multierror"
 
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config"
@@ -56,7 +57,7 @@ var (
 func ParseCategory(text string) (Category, error) {
 	category, valid := categoryIndex[text]
 	if !valid {
-		return "", errors.Errorf("%q is not a valid extension category", text)
+		return "", fmt.Errorf("%q is not a valid extension category", text)
 	}
 	return category, nil
 }
@@ -96,7 +97,7 @@ var (
 func ParseLanguage(text string) (Language, error) {
 	language, valid := languageIndex[text]
 	if !valid {
-		return "", errors.Errorf("%q is not a valid programming language", text)
+		return "", fmt.Errorf("%q is not a valid programming language", text)
 	}
 	return language, nil
 }
@@ -124,7 +125,7 @@ var (
 // extension name.
 func ValidateExtensionName(text string) error {
 	if !referenceNameFormat.MatchString(text) {
-		return errors.Errorf("%q is not a valid extension name. Extension name must match the format %q."+
+		return fmt.Errorf("%q is not a valid extension name. Extension name must match the format %q."+
 			" E.g., 'mycompany.filters.http.custom_metrics'", text, referenceNameFormat)
 	}
 	return nil
@@ -170,7 +171,7 @@ func (d *Descriptor) Validate() (errs error) {
 		errs = multierror.Append(errs, errors.New("programming language cannot be empty"))
 	}
 	if err := d.Runtime.Validate(); err != nil {
-		errs = multierror.Append(errs, errors.Wrap(err, "runtime description is not valid"))
+		errs = multierror.Append(errs, fmt.Errorf("runtime description is not valid: %w", err))
 	}
 	return
 }
@@ -178,11 +179,11 @@ func (d *Descriptor) Validate() (errs error) {
 // Validate returns an error if Runtime is not valid.
 func (r *Runtime) Validate() (errs error) {
 	if r.Envoy.Version == "" {
-		errs = multierror.Append(errs, errors.New("Envoy version cannot be empty"))
+		errs = multierror.Append(errs, errors.New("envoy version cannot be empty"))
 	}
 	if r.Envoy.Version != "" {
 		if _, err := types.ParseReference(r.Envoy.Version); err != nil {
-			errs = multierror.Append(errs, errors.Wrap(err, "Envoy version is not valid"))
+			errs = multierror.Append(errs, fmt.Errorf("envoy version is not valid: %w", err))
 		}
 	}
 	return
diff --git a/pkg/extension/workspace/config/helpers.go b/pkg/extension/workspace/config/helpers.go
deleted file mode 100644
index fd0d889..0000000
--- a/pkg/extension/workspace/config/helpers.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2020 Tetrate
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package config
-
-import (
-	"github.com/ghodss/yaml"
-)
-
-var (
-	// Marshal converts an object into its YAML representation.
-	Marshal func(interface{}) ([]byte, error) = yaml.Marshal
-	// Unmarshal converts YAML into an object.
-	Unmarshal func([]byte, interface{}) error = yaml.Unmarshal
-)
diff --git a/pkg/extension/workspace/config/toolchain/builtin/types.go b/pkg/extension/workspace/config/toolchain/builtin/types.go
index 6eca0dd..de164ae 100644
--- a/pkg/extension/workspace/config/toolchain/builtin/types.go
+++ b/pkg/extension/workspace/config/toolchain/builtin/types.go
@@ -25,47 +25,47 @@ const (
 
 // ToolchainConfig represents configuration of the built-in toolchain.
 type ToolchainConfig struct {
-	config.Meta `json:",inline"`
+	config.Meta `yaml:",inline"`
 	// Configuration of the default Docker build container.
-	Container *ContainerConfig `json:"container,omitempty"`
+	Container *ContainerConfig `yaml:"container,omitempty"`
 	// Configuration of `build` tool.
-	Build *BuildConfig `json:"build,omitempty"`
+	Build *BuildConfig `yaml:"build,omitempty"`
 	// Configuration of `test` tool.
-	Test *TestConfig `json:"test,omitempty"`
+	Test *TestConfig `yaml:"test,omitempty"`
 	// Configuration of `clean` tool.
-	Clean *CleanConfig `json:"clean,omitempty"`
+	Clean *CleanConfig `yaml:"clean,omitempty"`
 }
 
 // BuildConfig represents configuration of `build` tool.
 type BuildConfig struct {
 	// Configuration of a Docker build container.
-	Container *ContainerConfig `json:"container,omitempty"`
+	Container *ContainerConfig `yaml:"container,omitempty"`
 	// Build artifacts.
-	Output *BuildOutput `json:"output,omitempty"`
+	Output *BuildOutput `yaml:"output,omitempty"`
 }
 
 // BuildOutput represents configuration of build artifacts.
 type BuildOutput struct {
 	// Path to the *.wasm file (relative to the workspace root).
-	WasmFile string `json:"wasmFile,omitempty"`
+	WasmFile string `yaml:"wasmFile,omitempty"`
 }
 
 // TestConfig represents configuration of `test` tool.
 type TestConfig struct {
 	// Configuration of a Docker build container.
-	Container *ContainerConfig `json:"container,omitempty"`
+	Container *ContainerConfig `yaml:"container,omitempty"`
 }
 
 // CleanConfig represents configuration of `clean` tool.
 type CleanConfig struct {
 	// Configuration of a Docker build container.
-	Container *ContainerConfig `json:"container,omitempty"`
+	Container *ContainerConfig `yaml:"container,omitempty"`
 }
 
 // ContainerConfig represents configuration of a Docker build container.
 type ContainerConfig struct {
 	// Builder image.
-	Image string `json:"image,omitempty"`
+	Image string `yaml:"image,omitempty"`
 	// Docker cli options.
-	Options []string `json:"options,omitempty"`
+	Options []string `yaml:"options,omitempty"`
 }
diff --git a/pkg/extension/workspace/example/envoy/template/data.go b/pkg/extension/workspace/example/envoy/template/data.go
index 5176456..8cbc57b 100644
--- a/pkg/extension/workspace/example/envoy/template/data.go
+++ b/pkg/extension/workspace/example/envoy/template/data.go
@@ -15,12 +15,13 @@
 package template
 
 import (
+	"fmt"
+
 	envoycore "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
-	"github.com/golang/protobuf/jsonpb"
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/ptypes"
-	"github.com/golang/protobuf/ptypes/wrappers"
-	"github.com/pkg/errors"
+	"google.golang.org/protobuf/encoding/protojson"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/types/known/anypb"
+	"google.golang.org/protobuf/types/known/wrapperspb"
 )
 
 // newExpandData creates a template data object for the Expand operation.
@@ -61,12 +62,12 @@ func (e *getEnvoy) Extension() *getEnvoyExtension {
 	return &e.getEnvoyExtension
 }
 
-// Code handles {{ .GetEnvoy.Extension.Name }} pipeline.
+// Name handles {{ .GetEnvoy.Extension.Name }} pipeline.
 func (e *getEnvoyExtension) Name(modules ...string) (getEnvoyValue, error) {
 	if len(modules) > 0 {
-		return nil, errors.Errorf("unable to resolve Wasm module %v: not supported yet", modules)
+		return nil, fmt.Errorf("unable to resolve Wasm module %s: not supported yet", modules)
 	}
-	return wrap(&wrappers.StringValue{
+	return wrap(&wrapperspb.StringValue{
 		Value: e.ctx.DefaultExtension.GetDescriptor().Name,
 	})
 }
@@ -74,7 +75,7 @@ func (e *getEnvoyExtension) Name(modules ...string) (getEnvoyValue, error) {
 // Code handles {{ .GetEnvoy.Extension.Code }} pipeline.
 func (e *getEnvoyExtension) Code(modules ...string) (getEnvoyValue, error) {
 	if len(modules) > 0 {
-		return nil, errors.Errorf("unable to resolve Wasm module %v: not supported yet", modules)
+		return nil, fmt.Errorf("unable to resolve Wasm module %s: not supported yet", modules)
 	}
 	return wrap(&envoycore.AsyncDataSource{
 		Specifier: &envoycore.AsyncDataSource_Local{
@@ -90,9 +91,9 @@ func (e *getEnvoyExtension) Code(modules ...string) (getEnvoyValue, error) {
 // Config handles {{ .GetEnvoy.Extension.Config }} pipeline.
 func (e *getEnvoyExtension) Config(names ...string) (getEnvoyValue, error) {
 	if len(names) > 0 {
-		return nil, errors.Errorf("unable to resolve a named config %v: not supported yet", names)
+		return nil, fmt.Errorf("unable to resolve a named config %s: not supported yet", names)
 	}
-	any, err := ptypes.MarshalAny(&wrappers.StringValue{
+	any, err := anypb.New(&wrapperspb.StringValue{
 		Value: e.ctx.DefaultExtensionConfig,
 	})
 	if err != nil {
@@ -111,11 +112,11 @@ type getEnvoyValue interface {
 }
 
 func wrap(message proto.Message) (getEnvoyValue, error) {
-	json, err := new(jsonpb.Marshaler).MarshalToString(message)
+	json, err := protojson.Marshal(message)
 	if err != nil {
 		return nil, err
 	}
-	return &wrapper{message: message, json: json}, nil
+	return &wrapper{message: message, json: string(json)}, nil
 }
 
 // wrapper implements getEnvoyValue abstraction.
diff --git a/pkg/extension/workspace/example/envoy/template/defaults.go b/pkg/extension/workspace/example/envoy/template/defaults.go
index 89e563e..a626776 100644
--- a/pkg/extension/workspace/example/envoy/template/defaults.go
+++ b/pkg/extension/workspace/example/envoy/template/defaults.go
@@ -15,11 +15,12 @@
 package template
 
 import (
+	"fmt"
+
 	envoybootstrap "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3"
 	envoycore "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/ptypes/wrappers"
-	"github.com/pkg/errors"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/types/known/wrapperspb"
 )
 
 // List of properties supported by the {{ .GetEnvoy.DefaultValue "<property>" }} placeholder.
@@ -56,21 +57,21 @@ func (e *getEnvoy) DefaultValue(property string) (getEnvoyValue, error) {
 		case propAdmin:
 			return defaultAdmin(), nil
 		case propAdminAccessLogPath:
-			return &wrappers.StringValue{
+			return &wrapperspb.StringValue{
 				Value: defaultAdmin().GetAccessLogPath(),
 			}, nil
 		case propAdminAddress:
 			return defaultAdmin().GetAddress(), nil
 		case propAdminAddressSocketAddress:
-			return &wrappers.StringValue{
+			return &wrapperspb.StringValue{
 				Value: defaultAdmin().GetAddress().GetSocketAddress().GetAddress(),
 			}, nil
 		case propAdminAddressSocketPort:
-			return &wrappers.UInt32Value{
+			return &wrapperspb.UInt32Value{
 				Value: defaultAdmin().GetAddress().GetSocketAddress().GetPortValue(),
 			}, nil
 		default:
-			return nil, errors.Errorf("unknown property %q", property)
+			return nil, fmt.Errorf("unknown property %q", property)
 		}
 	}
 	value, err := eval(property)
diff --git a/pkg/extension/workspace/example/envoy/util/load.go b/pkg/extension/workspace/example/envoy/util/load.go
index 8ab1edf..100d905 100644
--- a/pkg/extension/workspace/example/envoy/util/load.go
+++ b/pkg/extension/workspace/example/envoy/util/load.go
@@ -15,13 +15,15 @@
 package util
 
 import (
-	"bytes"
+	"fmt"
 
 	envoymatcher "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
-	"github.com/ghodss/yaml"
-	"github.com/golang/protobuf/jsonpb"
-	"github.com/golang/protobuf/proto"
-	"github.com/pkg/errors"
+	"google.golang.org/protobuf/encoding/protojson"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+	"google.golang.org/protobuf/runtime/protoimpl"
+	"sigs.k8s.io/yaml"
 
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/model"
 )
@@ -30,32 +32,41 @@ import (
 func Load(config *model.File, message proto.Message) error {
 	json, err := yaml.YAMLToJSON(config.Content)
 	if err != nil {
-		return errors.Wrapf(err, "failed to convert into JSON Envoy config coming from %q", config.Source)
+		return fmt.Errorf("failed to convert into JSON Envoy config coming from %q: %w", config.Source, err)
 	}
 
-	unmarshaller := jsonpb.Unmarshaler{
-		AllowUnknownFields: true,
+	unmarshaller := protojson.UnmarshalOptions{
+		DiscardUnknown: true,
 		// ignore unknown extension types that might appear in a user-defined Envoy config
-		AnyResolver: newFakeAnyResolver(),
+		Resolver: fakeAnyResolver{},
 	}
-	return unmarshaller.Unmarshal(bytes.NewReader(json), message)
-}
-
-func newFakeAnyResolver() jsonpb.AnyResolver {
-	return fakeAnyResolver{}
+	return unmarshaller.Unmarshal(json, message)
 }
 
 // fakeAnyResolver resolves any type URL into a wrong but known message type.
 //
-// When using fakeAnyResolver, the actual payload of a google.protobug.Any field
+// When using fakeAnyResolver, the actual payload of a google.protobuf.Any field
 // will be lost during unmarshalling.
 // On the bright side, unmarshalling will never fail due to use of unknown types.
 type fakeAnyResolver struct{}
 
-func (r fakeAnyResolver) Resolve(typeURL string) (proto.Message, error) {
+func (r fakeAnyResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) {
+	return r.FindMessageByURL(string(message))
+}
+
+func (r fakeAnyResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) {
 	// NOTE: as of github.com/golang/protobuf/jsonpb@v1.3.x, the only way to achieve
 	// desired behavior is to return a Protobuf message that has no fields.
 	// As an extra constraint, it cannot be a well-known type, such as google.protobuf.Empty.
 	// That is why we are reusing an empty message type that already exists in Envoy API.
-	return new(envoymatcher.ValueMatcher_NullMatch), nil
+	m := new(envoymatcher.ValueMatcher_NullMatch)
+	return protoimpl.X.MessageTypeOf(m), nil
+}
+
+func (r fakeAnyResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
+	return protoregistry.GlobalTypes.FindExtensionByName(field)
+}
+
+func (r fakeAnyResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
+	return protoregistry.GlobalTypes.FindExtensionByNumber(message, field)
 }
diff --git a/pkg/extension/workspace/example/runtime/configdir/configdir.go b/pkg/extension/workspace/example/runtime/configdir/configdir.go
index 53cf2cd..4ab3251 100644
--- a/pkg/extension/workspace/example/runtime/configdir/configdir.go
+++ b/pkg/extension/workspace/example/runtime/configdir/configdir.go
@@ -15,13 +15,13 @@
 package configdir
 
 import (
+	"fmt"
 	"io"
 	"io/ioutil"
 	"os"
 	"path/filepath"
 
 	envoybootstrap "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3"
-	"github.com/pkg/errors"
 	"github.com/tetratelabs/multierror"
 
 	"github.com/tetratelabs/getenvoy/pkg/extension/manager"
@@ -155,7 +155,7 @@ func (d *configDir) process() error {
 func (d *configDir) newExpandContext() (*template.ExpandContext, error) {
 	wasmFile, err := filepath.Abs(d.ctx.Opts.Extension.WasmFile)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to resolve absolute path of a *.wasm file %q", d.ctx.Opts.Extension.WasmFile)
+		return nil, fmt.Errorf("failed to resolve absolute path of a *.wasm file %q: %w", d.ctx.Opts.Extension.WasmFile, err)
 	}
 	configuration := string(d.ctx.Opts.GetExtensionConfig().Content)
 
@@ -180,11 +180,11 @@ func (d *configDir) processEnvoyXdsFile(fileName string, expandContext *template
 	return d.writeFile(fileName, content)
 }
 
-// processEnvoyTemplate resolves placehoders in an Envoy config file.
+// processEnvoyTemplate resolves placeholders in an Envoy config file.
 func (d *configDir) processEnvoyTemplate(configFile *model.File, expandContext *template.ExpandContext) ([]byte, error) {
 	config, err := template.Expand(configFile.Content, expandContext)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to process Envoy config template coming from %q", configFile.Source)
+		return nil, fmt.Errorf("failed to process Envoy config template coming from %q: %w", configFile.Source, err)
 	}
 	return config, nil
 }
@@ -194,8 +194,8 @@ func (d *configDir) writeFile(fileName string, data []byte) error {
 	if err := osutil.EnsureDirExists(filepath.Dir(outputFile)); err != nil {
 		return err
 	}
-	if err := ioutil.WriteFile(outputFile, data, 0600); err != nil {
-		return errors.Wrapf(err, "failed to write config file to %q", outputFile)
+	if err := os.WriteFile(outputFile, data, 0600); err != nil {
+		return fmt.Errorf("failed to write config file to %q: %w", outputFile, err)
 	}
 	return nil
 }
diff --git a/pkg/extension/workspace/fs/types.go b/pkg/extension/workspace/fs/types.go
index 91c0bec..853e67e 100644
--- a/pkg/extension/workspace/fs/types.go
+++ b/pkg/extension/workspace/fs/types.go
@@ -15,12 +15,10 @@
 package fs
 
 import (
-	"io/ioutil"
+	"fmt"
 	"os"
 	"path/filepath"
 
-	"github.com/pkg/errors"
-
 	osutil "github.com/tetratelabs/getenvoy/pkg/util/os"
 )
 
@@ -49,7 +47,7 @@ func (d workspaceDir) HasFile(path string) (bool, error) {
 
 func (d workspaceDir) ReadFile(path string) ([]byte, error) {
 	path = d.Abs(path)
-	return ioutil.ReadFile(filepath.Clean(path))
+	return os.ReadFile(filepath.Clean(path))
 }
 
 func (d workspaceDir) WriteFile(path string, data []byte) error {
@@ -57,7 +55,7 @@ func (d workspaceDir) WriteFile(path string, data []byte) error {
 	if err := osutil.EnsureDirExists(filepath.Dir(path)); err != nil {
 		return err
 	}
-	return ioutil.WriteFile(path, data, 0600)
+	return os.WriteFile(path, data, 0600)
 }
 
 func (d workspaceDir) HasDir(path string) (bool, error) {
@@ -66,7 +64,7 @@ func (d workspaceDir) HasDir(path string) (bool, error) {
 
 func (d workspaceDir) ListDirs(path string) ([]string, error) {
 	path = d.Abs(path)
-	infos, err := ioutil.ReadDir(path)
+	infos, err := os.ReadDir(path)
 	if err != nil {
 		if os.IsNotExist(err) {
 			return nil, nil
@@ -127,14 +125,14 @@ func (d workspaceDir) hasFile(path string, test func(string, os.FileInfo) error)
 
 func isRegularFile(path string, info os.FileInfo) error {
 	if !info.Mode().IsRegular() {
-		return errors.Errorf("unexpected file type: expected a regular file at a given path: %s", path)
+		return fmt.Errorf("unexpected file type: expected a regular file at a given path: %s", path)
 	}
 	return nil
 }
 
 func isDir(path string, info os.FileInfo) error {
 	if !info.Mode().IsDir() {
-		return errors.Errorf("unexpected file type: expected a directory at a given path: %s", path)
+		return fmt.Errorf("unexpected file type: expected a directory at a given path: %s", path)
 	}
 	return nil
 }
diff --git a/pkg/extension/workspace/model/example.go b/pkg/extension/workspace/model/example.go
index 4769826..1227527 100644
--- a/pkg/extension/workspace/model/example.go
+++ b/pkg/extension/workspace/model/example.go
@@ -15,9 +15,10 @@
 package model
 
 import (
-	"github.com/pkg/errors"
+	"fmt"
+
+	"gopkg.in/yaml.v3"
 
-	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config"
 	exampleconfig "github.com/tetratelabs/getenvoy/pkg/extension/workspace/config/example"
 )
 
@@ -31,7 +32,7 @@ var (
 // NewExample returns a new Example that consists of a given set of files.
 func NewExample(files ImmutableFileSet) (Example, error) {
 	if !files.Has(exampleDescriptorFile) {
-		return nil, errors.Errorf("extension descriptor file %q is missing", exampleDescriptorFile)
+		return nil, fmt.Errorf("extension descriptor file %q is missing", exampleDescriptorFile)
 	}
 	descriptor, err := parseExampleDescriptor(files.Get(exampleDescriptorFile))
 	if err != nil {
@@ -42,24 +43,24 @@ func NewExample(files ImmutableFileSet) (Example, error) {
 		descriptor: descriptor,
 	}
 	if _, file := exampl.GetEnvoyConfig(); file == nil {
-		return nil, errors.Errorf("Envoy bootstrap config file is missing: every example must include one of %v", exampleEnvoyBootstrapFileAltNames)
+		return nil, fmt.Errorf("Envoy bootstrap config file is missing: every example must include one of %v", exampleEnvoyBootstrapFileAltNames)
 	}
 	if _, file := exampl.GetExtensionConfig(); file == nil {
-		return nil, errors.Errorf("extension config file is missing: every example must include one of %v", exampleExtensionConfigFileAltNames)
+		return nil, fmt.Errorf("extension config file is missing: every example must include one of %v", exampleExtensionConfigFileAltNames)
 	}
 	return exampl, nil
 }
 
 func parseExampleDescriptor(file *File) (*exampleconfig.Descriptor, error) {
 	descriptor := exampleconfig.NewExampleDescriptor()
-	err := config.Unmarshal(file.Content, descriptor)
+	err := yaml.Unmarshal(file.Content, descriptor)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to unmarshal example descriptor: %s", file.Source)
+		return nil, fmt.Errorf("failed to unmarshal example descriptor %s: %w", file.Source, err)
 	}
 	descriptor.Default()
 	err = descriptor.Validate()
 	if err != nil {
-		return nil, errors.Wrapf(err, "example descriptor is not valid: %s", file.Source)
+		return nil, fmt.Errorf("example descriptor is not valid %s: %w", file.Source, err)
 	}
 	return descriptor, nil
 }
diff --git a/pkg/extension/workspace/model/workspace.go b/pkg/extension/workspace/model/workspace.go
index 7886a12..ac96453 100644
--- a/pkg/extension/workspace/model/workspace.go
+++ b/pkg/extension/workspace/model/workspace.go
@@ -15,11 +15,11 @@
 package model
 
 import (
+	"fmt"
 	"path/filepath"
 
-	"github.com/pkg/errors"
+	"gopkg.in/yaml.v3"
 
-	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config"
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config/extension"
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/fs"
 )
@@ -50,17 +50,17 @@ func getExtensionDescriptor(dir fs.WorkspaceDir) (*extension.Descriptor, error)
 	path := DescriptorFile
 	data, err := dir.ReadFile(path)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to read extension descriptor: %s", dir.Abs(path))
+		return nil, fmt.Errorf("failed to read extension descriptor %s: %w", dir.Abs(path), err)
 	}
 	descriptor := extension.NewExtensionDescriptor()
-	err = config.Unmarshal(data, descriptor)
+	err = yaml.Unmarshal(data, descriptor)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to unmarshal extension descriptor: %s", dir.Abs(path))
+		return nil, fmt.Errorf("failed to unmarshal extension descriptor %s: %w", dir.Abs(path), err)
 	}
 	descriptor.Default()
 	err = descriptor.Validate()
 	if err != nil {
-		return nil, errors.Wrapf(err, "extension descriptor is not valid: %s", dir.Abs(path))
+		return nil, fmt.Errorf("extension descriptor is not valid %s: %w", dir.Abs(path), err)
 	}
 	return descriptor, nil
 }
@@ -160,7 +160,7 @@ func (w workspace) RemoveExample(exampleName string, opts ...RemoveOption) error
 func (w workspace) readFile(path string) (*File, error) {
 	data, err := w.dir.ReadFile(path)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to read: %s", w.dir.Abs(path))
+		return nil, fmt.Errorf("failed to read %s: %w", w.dir.Abs(path), err)
 	}
 	return &File{Source: w.dir.Abs(path), Content: data}, nil
 }
@@ -168,7 +168,7 @@ func (w workspace) readFile(path string) (*File, error) {
 func (w workspace) writeFile(path string, data []byte) error {
 	err := w.dir.WriteFile(path, data)
 	if err != nil {
-		return errors.Wrapf(err, "failed to write: %s", w.dir.Abs(path))
+		return fmt.Errorf("failed to write %s: %w", w.dir.Abs(path), err)
 	}
 	return nil
 }
@@ -176,7 +176,7 @@ func (w workspace) writeFile(path string, data []byte) error {
 func (w workspace) removeAll(path string) error {
 	err := w.dir.RemoveAll(path)
 	if err != nil {
-		return errors.Wrapf(err, "failed to remove: %s", w.dir.Abs(path))
+		return fmt.Errorf("failed to remove %s: %w", w.dir.Abs(path), err)
 	}
 	return nil
 }
diff --git a/pkg/extension/workspace/toolchain/builtin/factory.go b/pkg/extension/workspace/toolchain/builtin/factory.go
index c4180b0..3dd7dea 100644
--- a/pkg/extension/workspace/toolchain/builtin/factory.go
+++ b/pkg/extension/workspace/toolchain/builtin/factory.go
@@ -15,7 +15,8 @@
 package builtin
 
 import (
-	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config"
+	"gopkg.in/yaml.v3"
+
 	builtinconfig "github.com/tetratelabs/getenvoy/pkg/extension/workspace/config/toolchain/builtin"
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/model"
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/toolchain/registry"
@@ -27,7 +28,7 @@ func init() {
 		Kind: builtinconfig.Kind,
 		LoadConfig: func(args registry.LoadConfigArgs) (types.ToolchainBuilder, error) {
 			cfg := builtinconfig.NewToolchainConfig()
-			if err := config.Unmarshal(args.Toolchain.Config.Content, cfg); err != nil {
+			if err := yaml.Unmarshal(args.Toolchain.Config.Content, cfg); err != nil {
 				return nil, err
 			}
 			extension := args.Workspace.GetExtensionDescriptor()
diff --git a/pkg/extension/workspace/toolchain/lookup.go b/pkg/extension/workspace/toolchain/lookup.go
index f040d42..1db76ef 100644
--- a/pkg/extension/workspace/toolchain/lookup.go
+++ b/pkg/extension/workspace/toolchain/lookup.go
@@ -15,7 +15,9 @@
 package toolchain
 
 import (
-	"github.com/pkg/errors"
+	"fmt"
+
+	"gopkg.in/yaml.v3"
 
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config"
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/model"
@@ -34,10 +36,10 @@ func LoadToolchain(name string, workspace model.Workspace) (types.ToolchainBuild
 	switch name {
 	case Default:
 		if err := ensureDefaultToolchainExists(workspace); err != nil {
-			return nil, errors.Wrap(err, "failed to ensure the default toolchain exists")
+			return nil, fmt.Errorf("failed to ensure the default toolchain exists: %w", err)
 		}
 	default:
-		return nil, errors.Errorf("unknown toolchain %q. At the moment, only %q toolchain is supported", name, Default)
+		return nil, fmt.Errorf("unknown toolchain %q. At the moment, only %q toolchain is supported", name, Default)
 	}
 	return loadToolchain(name, workspace)
 }
@@ -45,7 +47,7 @@ func LoadToolchain(name string, workspace model.Workspace) (types.ToolchainBuild
 func ensureDefaultToolchainExists(workspace model.Workspace) error {
 	exists, err := workspace.HasToolchain(Default)
 	if err != nil {
-		return errors.Wrapf(err, "failed to determine whether toolchain %q already exists", Default)
+		return fmt.Errorf("failed to determine whether toolchain %q already exists: %w", Default, err)
 	}
 	if exists {
 		return nil
@@ -58,26 +60,26 @@ func ensureDefaultToolchainExists(workspace model.Workspace) error {
 func loadToolchain(name string, workspace model.Workspace) (types.ToolchainBuilder, error) {
 	exists, err := workspace.HasToolchain(name)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to determine whether toolchain %q exists", name)
+		return nil, fmt.Errorf("failed to determine whether toolchain %q exists: %w", name, err)
 	}
 	if !exists {
-		return nil, errors.Errorf("unknown toolchain %q", name)
+		return nil, fmt.Errorf("unknown toolchain %q", name)
 	}
 	file, err := workspace.GetToolchainConfig(name)
 	if err != nil {
-		return nil, errors.Wrapf(err, "failed to load configuration for toolchain %q", name)
+		return nil, fmt.Errorf("failed to load configuration for toolchain %q: %w", name, err)
 	}
 	configErr := func(err error) error {
-		return errors.Wrapf(err, "toolchain %q has invalid configuration coming from %q", name, file.Source)
+		return fmt.Errorf("toolchain %q has invalid configuration coming from %q: %w", name, file.Source, err)
 	}
 	meta := new(config.Meta)
-	err = config.Unmarshal(file.Content, meta)
+	err = yaml.Unmarshal(file.Content, meta)
 	if err != nil {
 		return nil, configErr(err)
 	}
 	factory, exists := registry.Get(meta.Kind)
 	if !exists {
-		return nil, configErr(errors.Errorf("unknown toolchain kind %q", meta.Kind))
+		return nil, configErr(fmt.Errorf("unknown toolchain kind %q", meta.Kind))
 	}
 	builder, err := factory.LoadConfig(registry.LoadConfigArgs{
 		Workspace: workspace,
@@ -102,7 +104,7 @@ type validatingBuilder struct {
 
 func (b *validatingBuilder) Build() (types.Toolchain, error) {
 	if err := b.GetConfig().Validate(); err != nil {
-		return nil, errors.Wrapf(err, "toolchain %q has invalid configuration", b.name)
+		return nil, fmt.Errorf("toolchain %q has invalid configuration: %w", b.name, err)
 	}
 	return b.ToolchainBuilder.Build()
 }
diff --git a/pkg/manifest/locate.go b/pkg/manifest/locate.go
index b957365..f8c76ab 100644
--- a/pkg/manifest/locate.go
+++ b/pkg/manifest/locate.go
@@ -15,14 +15,14 @@
 package manifest
 
 import (
+	"errors"
 	"fmt"
 	"net/url"
 	"os"
 
-	"github.com/pkg/errors"
 	"github.com/tetratelabs/log"
 
-	"github.com/tetratelabs/getenvoy-package/api"
+	"github.com/tetratelabs/getenvoy/api"
 	"github.com/tetratelabs/getenvoy/pkg/types"
 )
 
@@ -48,7 +48,7 @@ func GetURL() string {
 func SetURL(rawurl string) error {
 	otherURL, err := url.Parse(rawurl)
 	if err != nil || otherURL.Host == "" || otherURL.Scheme == "" {
-		return errors.Errorf("%q is not a valid manifest URL", rawurl)
+		return fmt.Errorf("%q is not a valid manifest URL", rawurl)
 	}
 	manifestURL = otherURL
 	return nil
diff --git a/pkg/manifest/print.go b/pkg/manifest/print.go
index 2d8b48c..e1b875c 100644
--- a/pkg/manifest/print.go
+++ b/pkg/manifest/print.go
@@ -21,9 +21,9 @@ import (
 	"sort"
 	"text/tabwriter"
 
-	"github.com/golang/protobuf/jsonpb"
+	"google.golang.org/protobuf/encoding/protojson"
 
-	"github.com/tetratelabs/getenvoy-package/api"
+	"github.com/tetratelabs/getenvoy/api"
 	"github.com/tetratelabs/getenvoy/pkg/transport"
 	"github.com/tetratelabs/getenvoy/pkg/types"
 )
@@ -54,19 +54,25 @@ func fetch(url string) (*api.Manifest, error) {
 	if err != nil {
 		return nil, err
 	}
+	defer resp.Body.Close() //nolint
+
 	if resp.StatusCode != http.StatusOK {
 		return nil, fmt.Errorf("received %v response code from %v", resp.StatusCode, url)
 	}
-	defer resp.Body.Close() //nolint
+	body, err := io.ReadAll(resp.Body) // fully read the response
+	if err != nil {
+		return nil, fmt.Errorf("error reading %s: %w", url, err)
+	}
+
 	result := api.Manifest{}
-	if err := jsonpb.Unmarshal(resp.Body, &result); err != nil {
-		return nil, fmt.Errorf("error unmarshalling manifest: %v", err)
+	if err := protojson.Unmarshal(body, &result); err != nil {
+		return nil, fmt.Errorf("error unmarshalling manifest: %w", err)
 	}
 	return &result, nil
 }
 
 func deterministicFlavors(flavors map[string]*api.Flavor) []*api.Flavor {
-	flavorList := []*api.Flavor{}
+	flavorList := make([]*api.Flavor, 0, len(flavors))
 	for _, flavor := range flavors {
 		flavorList = append(flavorList, flavor)
 	}
@@ -77,11 +83,10 @@ func deterministicFlavors(flavors map[string]*api.Flavor) []*api.Flavor {
 }
 
 func deterministicVersions(versions map[string]*api.Version) []*api.Version {
-	versionList := []*api.Version{}
+	versionList := make([]*api.Version, 0, len(versions))
 	for _, version := range versions {
 		versionList = append(versionList, version)
 	}
-
 	sort.Slice(versionList, func(i, j int) bool {
 		// Note: version is reverse alphabetical so that newer versions are first
 		return versionList[i].Name > versionList[j].Name
@@ -90,9 +95,9 @@ func deterministicVersions(versions map[string]*api.Version) []*api.Version {
 }
 
 func deterministicBuilds(builds map[string]*api.Build) []*api.Build {
-	buildList := []*api.Build{}
-	for _, flavor := range builds {
-		buildList = append(buildList, flavor)
+	buildList := make([]*api.Build, 0, len(builds))
+	for _, build := range builds {
+		buildList = append(buildList, build)
 	}
 	sort.Slice(buildList, func(i, j int) bool {
 		// Note: build is reverse alphabetical so that Linux versions are before Darwin


Test patch:
diff --git a/pkg/binary/envoy/controlplane/istio_test.go b/pkg/binary/envoy/controlplane/istio_test.go
index acbee23..392df9e 100644
--- a/pkg/binary/envoy/controlplane/istio_test.go
+++ b/pkg/binary/envoy/controlplane/istio_test.go
@@ -16,18 +16,15 @@ package controlplane
 
 import (
 	"fmt"
-	"io/ioutil"
 	"net/http"
 	"os"
 	"path/filepath"
 	"testing"
 	"time"
 
-	"github.com/gogo/protobuf/types"
 	"github.com/stretchr/testify/require"
 	"istio.io/istio/pilot/pkg/bootstrap"
 	"istio.io/istio/pilot/pkg/networking/plugin"
-	"istio.io/istio/pkg/config/mesh"
 	"istio.io/istio/pkg/keepalive"
 
 	"github.com/tetratelabs/getenvoy/pkg/binary"
@@ -57,17 +54,17 @@ func TestConnectsToMockPilotAsAGateway(t *testing.T) {
 	require.NoError(t, err, "error creating envoy runtime")
 	defer os.RemoveAll(runtime.DebugStore())
 
-	envoytest.RequireRunKill(t, runtime, envoytest.RunKillOptions{
+	envoytest.RequireRunTerminate(t, runtime, envoytest.RunKillOptions{
 		// Envoy won't achieve ready status because endpoints in testdata/configs.yaml are unreachable
 		ExpectedStatus: binary.StatusInitializing,
 		// We sleep to allow the configuration to populate, so that we can read it back.
-		SleepBeforeKill: 5 * time.Second,
+		SleepBeforeTerminate: 5 * time.Second,
 		// Assertions below inspect files in the debug store
 		RetainDebugStore: true,
 	})
 
 	// Verify configuration from istio testdata/configs.yaml ended up in envoy
-	gotClusters, err := ioutil.ReadFile(filepath.Join(runtime.DebugStore(), "clusters.txt"))
+	gotClusters, err := os.ReadFile(filepath.Join(runtime.DebugStore(), "clusters.txt"))
 	require.NoError(t, err, "error getting envoy clusters")
 	require.Contains(t, string(gotClusters), "istio-ingressgateway.istio-system.svc.cluster.local::1.1.1.1:8443")
 }
@@ -98,26 +95,18 @@ func requireMockPilot(t *testing.T, configFileDir string) (string, func()) {
 	_, revertChDir := morerequire.RequireChDir(t, workDir)
 	cleanups = append(cleanups, revertChDir)
 
-	meshConfig := mesh.DefaultMeshConfig()
-	meshConfig.EnableTracing = false
 	// TODO: figure out how to set telemetry enabled = false as this reduces the amount of listeners
-	meshConfig.EnablePrometheusMerge = &types.BoolValue{Value: false}
-	meshConfig.DnsRefreshRate = types.DurationProto(time.Minute)
-	meshConfig.DisableMixerHttpReports = true
-	// Create a test pilot discovery service configured to watch the tempDir.
 	args := bootstrap.PilotArgs{
 		Namespace: "testing",
-		Config:    bootstrap.ConfigArgs{FileDir: configFileDir},
-		DiscoveryOptions: bootstrap.DiscoveryServiceOptions{
+		ServerOptions: bootstrap.DiscoveryServerOptions{
 			HTTPAddr: "127.0.0.1:", // instead of listening on all addresses
-			GrpcAddr: "127.0.0.1:",
+			GRPCAddr: "127.0.0.1:",
 		},
-		MeshConfig:       &meshConfig,
 		MCPOptions:       bootstrap.MCPOptions{MaxMessageSize: 1024 * 1024 * 4},
 		KeepaliveOptions: keepalive.DefaultOption(),
-		ForceStop:        true,
-		Plugins:          []string{plugin.Health}, // only health, no mixer or authorization
-		Service:          bootstrap.ServiceArgs{}, // no service registries
+		ShutdownDuration: 1 * time.Second,
+		Plugins:          []string{plugin.Health},                           // only health, no mixer or authorization
+		RegistryOptions:  bootstrap.RegistryOptions{FileDir: configFileDir}, // no service registries
 	}
 
 	s, err := bootstrap.NewServer(&args)
diff --git a/pkg/binary/envoy/debug/admin_test.go b/pkg/binary/envoy/debug/admin_test.go
index 6706f5b..d88d0dd 100644
--- a/pkg/binary/envoy/debug/admin_test.go
+++ b/pkg/binary/envoy/debug/admin_test.go
@@ -34,7 +34,7 @@ func TestEnableEnvoyAdminDataCollection(t *testing.T) {
 	require.NoError(t, err, "error getting envoy runtime")
 	defer os.RemoveAll(r.DebugStore())
 
-	envoytest.RequireRunKill(t, r, envoytest.RunKillOptions{
+	envoytest.RequireRunTerminate(t, r, envoytest.RunKillOptions{
 		Bootstrap:        "testdata/admin.yaml", // we need services defined in order to check adminAPIPaths
 		RetainDebugStore: true,                  // Assertions below inspect files in the debug store
 	})
diff --git a/pkg/binary/envoy/debug/log_test.go b/pkg/binary/envoy/debug/log_test.go
index bd17f47..a5bd071 100644
--- a/pkg/binary/envoy/debug/log_test.go
+++ b/pkg/binary/envoy/debug/log_test.go
@@ -30,7 +30,7 @@ func TestEnableEnvoyLogCollection(t *testing.T) {
 	require.NoError(t, err, "error getting envoy runtime")
 	defer os.RemoveAll(r.DebugStore())
 
-	envoytest.RequireRunKill(t, r, envoytest.RunKillOptions{
+	envoytest.RequireRunTerminate(t, r, envoytest.RunKillOptions{
 		RetainDebugStore: false, // We don't need to unarchive the tar.gz because access logs hold the DebugStore open.
 	})
 
diff --git a/pkg/binary/envoy/debug/lsof_test.go b/pkg/binary/envoy/debug/lsof_test.go
index 728bc25..fb02a10 100644
--- a/pkg/binary/envoy/debug/lsof_test.go
+++ b/pkg/binary/envoy/debug/lsof_test.go
@@ -16,7 +16,6 @@ package debug
 
 import (
 	"encoding/json"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"runtime"
@@ -33,7 +32,7 @@ func TestEnableOpenFilesDataCollection(t *testing.T) {
 	require.NoError(t, err, "error getting envoy runtime")
 	defer os.RemoveAll(r.DebugStore())
 
-	envoytest.RequireRunKill(t, r, envoytest.RunKillOptions{
+	envoytest.RequireRunTerminate(t, r, envoytest.RunKillOptions{
 		RetainDebugStore: true, // Assertions below inspect files in the debug store
 	})
 
@@ -46,7 +45,7 @@ func TestEnableOpenFilesDataCollection(t *testing.T) {
 		require.Empty(t, f.Size(), "file %v was not empty", path)
 	} else {
 		require.NotEmpty(t, f.Size(), "file %v was empty", path)
-		raw, err := ioutil.ReadFile(path)
+		raw, err := os.ReadFile(path)
 		require.NoError(t, err, "error reading file %v", path)
 
 		var is []interface{}
diff --git a/pkg/binary/envoy/debug/node_test.go b/pkg/binary/envoy/debug/node_test.go
index cb9afe2..3b83912 100644
--- a/pkg/binary/envoy/debug/node_test.go
+++ b/pkg/binary/envoy/debug/node_test.go
@@ -16,7 +16,6 @@ package debug
 
 import (
 	"encoding/json"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strings"
@@ -33,7 +32,7 @@ func TestEnableNodeCollection(t *testing.T) {
 	require.NoError(t, err, "error creating envoy runtime")
 	defer os.RemoveAll(r.DebugStore())
 
-	envoytest.RequireRunKill(t, r, envoytest.RunKillOptions{
+	envoytest.RequireRunTerminate(t, r, envoytest.RunKillOptions{
 		RetainDebugStore: true, // Assertions below inspect files in the debug store
 	})
 
@@ -45,7 +44,7 @@ func TestEnableNodeCollection(t *testing.T) {
 		require.NotEmpty(t, f.Size(), "file %v was empty", path)
 
 		if strings.HasSuffix(file, ".json") {
-			raw, err := ioutil.ReadFile(path)
+			raw, err := os.ReadFile(path)
 			require.NoError(t, err, "error to read the file %v", path)
 			var is []interface{}
 
diff --git a/pkg/binary/envoy/debug/testdata/admin.yaml b/pkg/binary/envoy/debug/testdata/admin.yaml
index 57ec269..f4c6d9d 100644
--- a/pkg/binary/envoy/debug/testdata/admin.yaml
+++ b/pkg/binary/envoy/debug/testdata/admin.yaml
@@ -22,7 +22,7 @@ static_resources:
         - filters:
             - name: envoy.http_connection_manager
               typed_config:
-                "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
+                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                 codec_type: auto
                 stat_prefix: ingress_http
                 route_config:
diff --git a/pkg/binary/envoy/fetch_test.go b/pkg/binary/envoy/fetch_test.go
index 244822a..b912d3e 100644
--- a/pkg/binary/envoy/fetch_test.go
+++ b/pkg/binary/envoy/fetch_test.go
@@ -15,6 +15,7 @@
 package envoy
 
 import (
+	"io"
 	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
@@ -23,13 +24,13 @@ import (
 	"testing"
 
 	"github.com/mholt/archiver/v3"
-	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 
 	"github.com/tetratelabs/getenvoy/pkg/manifest"
 )
 
 func TestRuntime_Fetch(t *testing.T) {
-	defaultDarwinKey := &manifest.Key{Flavor: "standard", Version: "1.12.7", Platform: "darwin"}
+	defaultDarwinKey := &manifest.Key{Flavor: "standard", Version: "1.15.3", Platform: "darwin"}
 	tests := []struct {
 		name             string
 		key              *manifest.Key
@@ -48,8 +49,8 @@ func TestRuntime_Fetch(t *testing.T) {
 			tarballStructure: "envoy",
 			tarExtension:     ".tar.gz",
 			responseStatus:   http.StatusOK,
-			envoyLocation:    "builds/standard/1.12.7/darwin/bin/envoy",
-			libLocation:      "builds/standard/1.12.7/darwin/lib/somelib",
+			envoyLocation:    "builds/standard/1.15.3/darwin/bin/envoy",
+			libLocation:      "builds/standard/1.15.3/darwin/lib/somelib",
 			wantServerCalled: true,
 		},
 		{
@@ -58,15 +59,15 @@ func TestRuntime_Fetch(t *testing.T) {
 			tarballStructure: "envoy",
 			tarExtension:     ".tar.xz",
 			responseStatus:   http.StatusOK,
-			envoyLocation:    "builds/standard/1.12.7/darwin/bin/envoy",
-			libLocation:      "builds/standard/1.12.7/darwin/lib/somelib",
+			envoyLocation:    "builds/standard/1.15.3/darwin/bin/envoy",
+			libLocation:      "builds/standard/1.15.3/darwin/lib/somelib",
 			wantServerCalled: true,
 		},
 		{
 			name:             "Does nothing if it already has a local copy",
 			key:              defaultDarwinKey,
-			envoyLocation:    "builds/standard/1.12.7/darwin/bin/envoy",
-			libLocation:      "builds/standard/1.12.7/darwin/lib/somelib",
+			envoyLocation:    "builds/standard/1.15.3/darwin/bin/envoy",
+			libLocation:      "builds/standard/1.15.3/darwin/lib/somelib",
 			alreadyLocal:     true,
 			wantServerCalled: false,
 		},
@@ -105,16 +106,16 @@ func TestRuntime_Fetch(t *testing.T) {
 			r := &Runtime{fetcher: fetcher{tmpDir}}
 			err := r.Fetch(tc.key, mock.URL+"/"+tc.tarballStructure+tc.tarExtension)
 			if tc.wantErr {
-				assert.Error(t, err)
+				require.Error(t, err)
 			} else {
-				assert.Nil(t, err)
+				require.Nil(t, err)
 				for _, location := range []string{libLocation, envoyLocation} {
 					f, _ := os.Open(location)
-					bytes, _ := ioutil.ReadAll(f)
-					assert.Contains(t, string(bytes), "some c++")
+					bytes, _ := io.ReadAll(f)
+					require.Contains(t, string(bytes), "some c++")
 				}
 			}
-			assert.Equal(t, tc.wantServerCalled, *gotCalled, "mismatch of expectations for calling of remote server")
+			require.Equal(t, tc.wantServerCalled, *gotCalled, "mismatch of expectations for calling of remote server")
 		})
 	}
 }
@@ -135,7 +136,7 @@ func mockServer(responseStatusCode int, tarballStructure, tarExtension, tmpDir s
 		if responseStatusCode == http.StatusOK {
 			tarball := filepath.Join(tmpDir, tarballStructure+tarExtension)
 			archiver.Archive([]string{filepath.Join("testdata", tarballStructure)}, tarball)
-			bytes, _ := ioutil.ReadFile(tarball)
+			bytes, _ := os.ReadFile(tarball)
 			w.Write(bytes)
 		}
 	})), &called
diff --git a/pkg/binary/envoytest/util.go b/pkg/binary/envoytest/util.go
index 661ae3b..2f42590 100644
--- a/pkg/binary/envoytest/util.go
+++ b/pkg/binary/envoytest/util.go
@@ -16,7 +16,6 @@ package envoytest
 
 import (
 	"fmt"
-	"math/rand"
 	"os"
 	"path/filepath"
 	"sync"
@@ -33,15 +32,19 @@ import (
 	"github.com/tetratelabs/getenvoy/pkg/manifest"
 )
 
-// Reference indicates the default Envoy version to be used for testing.
-// 1.12.7 is the last version to match the Istio version we are using (see go.mod)
-var Reference = "standard:1.12.7"
+// reference indicates the default Envoy version to be used for testing.
+// 1.15.3 is the last version to match the Istio version we are using in go.mod:
+//   https://github.com/istio/istio/blob/1.7.8/istio.deps ->
+//   https://github.com/istio/proxy/blob/d68172a37cb87c52d683a906bd2fba90060f8d82/WORKSPACE ->
+//   https://github.com/istio/envoy/commit/4abbbc0394b247d4ea37fd8f9137732c3d0a2b91 ->
+//   https://github.com/istio/envoy/pull/290 -> ~ 1.15
+var reference = "standard:1.15.3"
 
 var once sync.Once
 var errorFetchingEnvoy error
 
-// FetchEnvoyAndRun retrieves the Envoy indicated by Reference only once. This is intended to be used with TestMain.
-// In CI, you can execute this to obviate latency during test runs: "go run cmd/getenvoy/main.go fetch standard:1.12.7"
+// FetchEnvoyAndRun retrieves the Envoy indicated by reference only once. This is intended to be used with TestMain.
+// In CI, you can execute this to obviate latency during test runs: "go run cmd/getenvoy/main.go fetch standard:1.15.3"
 func FetchEnvoyAndRun(m *testing.M) {
 	once.Do(func() {
 		errorFetchingEnvoy = fetchEnvoy()
@@ -56,9 +59,9 @@ func FetchEnvoyAndRun(m *testing.M) {
 }
 
 func fetchEnvoy() error {
-	key, err := manifest.NewKey(Reference)
+	key, err := manifest.NewKey(reference)
 	if err != nil {
-		return fmt.Errorf("unable to make manifest key %v: %w", Reference, err)
+		return fmt.Errorf("unable to make manifest key %v: %w", reference, err)
 	}
 
 	r, err := envoy.NewRuntime()
@@ -82,16 +85,16 @@ func fetchEnvoy() error {
 
 // RunKillOptions allows customization of Envoy lifecycle.
 type RunKillOptions struct {
-	Bootstrap        string
-	ExpectedStatus   int
-	RetainDebugStore bool
-	SleepBeforeKill  time.Duration
+	Bootstrap            string
+	ExpectedStatus       int
+	RetainDebugStore     bool
+	SleepBeforeTerminate time.Duration
 }
 
-// RequireRunKill executes envoy, waits for ready, sends sigint, waits for termination, then unarchives the debug directory.
+// RequireRunTerminate executes envoy, waits for ready, sends sigint, waits for termination, then unarchives the debug directory.
 // It should be used when you just want to cycle through an Envoy lifecycle.
-func RequireRunKill(t *testing.T, r binary.Runner, options RunKillOptions) {
-	key, err := manifest.NewKey(Reference)
+func RequireRunTerminate(t *testing.T, r binary.Runner, options RunKillOptions) {
+	key, err := manifest.NewKey(reference)
 	require.NoError(t, err)
 	var args []string
 	if options.Bootstrap != "" {
@@ -99,11 +102,11 @@ func RequireRunKill(t *testing.T, r binary.Runner, options RunKillOptions) {
 	}
 
 	args = append(args,
-		// Use ephemeral admin port to avoid test conflicts. Enable admin access logging to help debug test failures.
+		// Use ephemeral admin port to avoid test conflicts.
+		// Enable admin access logging to help debug test failures. (minimum Envoy 1.12 for macOS support)
 		"--config-yaml", "admin: {access_log_path: '/dev/stdout', address: {socket_address: {address: '127.0.0.1', port_value: 0}}}",
-		// Generate base id to allow concurrent envoys in tests. When envoy is v1.15+, switch to --use-dynamic-base-id
-		// This prevents "unable to bind domain socket with id=0" on Linux hosts.
-		"--base-id", fmt.Sprintf("%d", rand.Int31()), // nolint it isn't important to use a secure random here
+		// Generate base id to allow concurrent envoys in tests. (minimum Envoy 1.15)
+		"--use-dynamic-base-id",
 	)
 	// Allows us the status checker to read the resolved admin port after envoy starts
 	envoy.EnableAdminAddressDetection(r.(*envoy.Runtime))
@@ -139,11 +142,11 @@ func RequireRunKill(t *testing.T, r binary.Runner, options RunKillOptions) {
 	}, 30*time.Second, 100*time.Millisecond, "never achieved status(%d) or StatusTerminated", expectedStatus)
 	require.Equal(t, expectedStatus, r.Status(), "never achieved status(%d)", expectedStatus)
 
-	time.Sleep(options.SleepBeforeKill)
+	time.Sleep(options.SleepBeforeTerminate)
 
 	require.NotEqual(t, binary.StatusTerminated, r.Status(), "already StatusTerminated")
 
-	r.SendSignal(syscall.SIGINT)
+	r.SendSignal(syscall.SIGTERM)
 	require.Eventually(t, func() bool {
 		return r.Status() == binary.StatusTerminated
 	}, 10*time.Second, 50*time.Millisecond, "never achieved StatusTerminated")
diff --git a/pkg/cmd/extension/example/cmd_add_test.go b/pkg/cmd/extension/example/cmd_add_test.go
index ec9da6c..f059ef6 100644
--- a/pkg/cmd/extension/example/cmd_add_test.go
+++ b/pkg/cmd/extension/example/cmd_add_test.go
@@ -16,7 +16,7 @@ package example_test
 
 import (
 	"fmt"
-	"io/ioutil"
+	"os"
 	"path/filepath"
 	"testing"
 
@@ -170,7 +170,7 @@ Done!
 
 			// Check README substitution: ${EXTENSION_CONFIG_FILE_NAME} must be replaced with "extension.json".
 			readmePath := filepath.Join(exampleDir, `README.md`)
-			data, err := ioutil.ReadFile(readmePath)
+			data, err := os.ReadFile(readmePath)
 			require.NoError(t, err, `expected no error reading README.md file: %s`, readmePath)
 
 			// Check one variable, noting that EXTENSION_CONFIG_FILE_NAME is language specific.
diff --git a/pkg/cmd/extension/example/testdata/workspaceTinyGoNoExample/.getenvoy/extension/extension.yaml b/pkg/cmd/extension/example/testdata/workspaceTinyGoNoExample/.getenvoy/extension/extension.yaml
index 839b9ae..cc05c4a 100644
--- a/pkg/cmd/extension/example/testdata/workspaceTinyGoNoExample/.getenvoy/extension/extension.yaml
+++ b/pkg/cmd/extension/example/testdata/workspaceTinyGoNoExample/.getenvoy/extension/extension.yaml
@@ -3,7 +3,7 @@
 #
 kind: Extension
 
-name: me.filters.http.my_http_filter
+name: mycompany.filters.http.custom_metrics
 
 category: envoy.filters.http
 language: tinygo
diff --git a/pkg/cmd/extension/push/cmd_test.go b/pkg/cmd/extension/push/cmd_test.go
index 31173ec..09ef996 100644
--- a/pkg/cmd/extension/push/cmd_test.go
+++ b/pkg/cmd/extension/push/cmd_test.go
@@ -18,7 +18,7 @@ import (
 	"crypto/sha256"
 	"encoding/hex"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"net/http/httptest"
 	"path/filepath"
@@ -122,7 +122,7 @@ func mockRegistryServer(t *testing.T) *httptest.Server {
 	return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		statusCode := 500
 
-		body, err := ioutil.ReadAll(r.Body) // fully read the request
+		body, err := io.ReadAll(r.Body) // fully read the request
 		require.NoError(t, err, "Error reading body of %s %s", r.Method, r.URL.Path)
 
 		switch r.Method {
diff --git a/pkg/cmd/extension/run/cmd_test.go b/pkg/cmd/extension/run/cmd_test.go
index 6dbafe3..c6bfe19 100644
--- a/pkg/cmd/extension/run/cmd_test.go
+++ b/pkg/cmd/extension/run/cmd_test.go
@@ -16,16 +16,14 @@ package run_test
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
 	"os/user"
 	"path/filepath"
 	"runtime"
 	"testing"
 
-	"github.com/Masterminds/semver"
+	"github.com/Masterminds/semver/v3"
 	"github.com/otiai10/copy"
-	"github.com/pkg/errors"
 	"github.com/stretchr/testify/require"
 
 	"github.com/tetratelabs/getenvoy/pkg/manifest"
@@ -51,7 +49,7 @@ func TestGetEnvoyExtensionRunValidateFlag(t *testing.T) {
 
 	// Create a fake envoy script so that we can verify execute bit is required.
 	notExecutable := filepath.Join(tempDir, "envoy")
-	err := ioutil.WriteFile(notExecutable, []byte(`#!/bin/sh`), 0600)
+	err := os.WriteFile(notExecutable, []byte(`#!/bin/sh`), 0600)
 	require.NoError(t, err, `couldn't create fake envoy script'`)
 
 	tests := []testCase{
@@ -78,7 +76,7 @@ func TestGetEnvoyExtensionRunValidateFlag(t *testing.T) {
 		{
 			name:        "--envoy-version with invalid value",
 			args:        []string{"--envoy-version", "???"},
-			expectedErr: `Envoy version is not valid: "???" is not a valid GetEnvoy reference. Expected format: <flavor>:<version>[/<platform>]`,
+			expectedErr: `envoy version is not valid: "???" is not a valid GetEnvoy reference. Expected format: <flavor>:<version>[/<platform>]`,
 		},
 		{
 			name:        "--envoy-version and --envoy-path flags at the same time",
@@ -178,13 +176,13 @@ envoy args: -c %s/envoy.tmpl.yaml`,
 	require.Equal(t, expectedStdout+"\n", stdout.String(), `expected stdout running [%v]`, c)
 	require.Equal(t, "docker stderr\nenvoy stderr\n", stderr.String(), `expected stderr running [%v]`, c)
 
-	// Verify the placeholders envoy would have ran substituted, notably including the generated extension.wasm
-	expectedYaml := fmt.Sprintf(`'extension.name': "mycompany.filters.http.custom_metrics"
-'extension.code': {"local":{"filename":"%s/target/getenvoy/extension.wasm"}}
-'extension.config': {"@type":"type.googleapis.com/google.protobuf.StringValue","value":"{\"key\":\"value\"}"}
-`, config.workspaceDir)
+	// Verify the placeholders envoy would have ran substituted, including generated extension.wasm and escaped config.
+	withoutSpace := expectedYAML(config.workspaceDir, false, `{"key":"value"}`)
+	withSpace := expectedYAML(config.workspaceDir, true, `{"key":"value"}`)
 	yaml := requirePlaceholdersYaml(t, config.envoyHome)
-	require.Equal(t, expectedYaml, yaml, `unexpected placeholders yaml after running [%v]`, c)
+	if withoutSpace != yaml {
+		require.Equal(t, yaml, withSpace, `unexpected placeholders yaml after running [%v]`, c)
+	}
 }
 
 // TestGetEnvoyExtensionRunDockerFail ensures docker failures show useful information in stderr
@@ -295,7 +293,7 @@ func TestGetEnvoyExtensionRunWithWasm(t *testing.T) {
 
 	// As all scripts invoked are fakes, we only need to touch a file as it isn't read
 	wasmFile := filepath.Join(config.tempDir, "extension.wasm")
-	err := ioutil.WriteFile(wasmFile, []byte{}, 0600)
+	err := os.WriteFile(wasmFile, []byte{}, 0600)
 	require.NoError(t, err, `expected no error creating extension.wasm: %s`, wasmFile)
 
 	// Run "getenvoy extension run --extension-file /path/to/extension.wasm"
@@ -332,7 +330,7 @@ func TestGetEnvoyExtensionRunWithConfig(t *testing.T) {
 
 	// As all scripts invoked are fakes, we only need to touch a file as it isn't read
 	configFile := filepath.Join(config.tempDir, "config.json")
-	err := ioutil.WriteFile(configFile, []byte(`{"key2":"value2"}`), 0600)
+	err := os.WriteFile(configFile, []byte(`{"key2":"value2"}`), 0600)
 	require.NoError(t, err, `expected no error creating extension.wasm: %s`, configFile)
 
 	// Run "getenvoy extension run --extension-config-file /path/to/config.json"
@@ -343,10 +341,29 @@ func TestGetEnvoyExtensionRunWithConfig(t *testing.T) {
 	// Verify the command invoked, passing the correct default commandline
 	require.NoError(t, err, `expected no error running [%v]`, c)
 
-	// Verify the placeholders envoy would have ran substituted, notably including the escaped config
-	yamlExtensionConfig := `'extension.config': {"@type":"type.googleapis.com/google.protobuf.StringValue","value":"{\"key2\":\"value2\"}"}`
+	// Verify the placeholders envoy would have ran substituted, including generated extension.wasm and escaped config.
+	withoutSpace := expectedYAML(config.workspaceDir, false, `{"key2":"value2"}`)
+	withSpace := expectedYAML(config.workspaceDir, true, `{"key2":"value2"}`)
 	yaml := requirePlaceholdersYaml(t, config.envoyHome)
-	require.Contains(t, yaml, yamlExtensionConfig, `unexpected placeholders yaml after running [%v]`, c)
+	if withoutSpace != yaml {
+		require.Equal(t, yaml, withSpace, `unexpected placeholders yaml after running [%v]`, c)
+	}
+}
+
+// Google made json formatting (json.prepareNext) intentionally unstable, technically by adding a space randomly.
+// https://github.com/golang/protobuf/issues/920 requested an option for stability, but it was closed and locked.
+// https://github.com/golang/protobuf/issues/1121 remains open, but unlikely to change.
+// Hence, we have to check two possible formats via the shouldSpace parameter.
+func expectedYAML(workspaceDir string, shouldSpace bool, extensionConfigValue string) string {
+	space := ""
+	if shouldSpace {
+		space = " "
+	}
+	// Verify the placeholders envoy would have ran substituted, notably including the generated extension.wasm
+	return fmt.Sprintf(`'extension.name': "mycompany.filters.http.custom_metrics"
+'extension.code': {"local":{"filename":"%s/target/getenvoy/extension.wasm"}}
+'extension.config': {"@type":"type.googleapis.com/google.protobuf.StringValue",%s"value":%q}
+`, workspaceDir, space, extensionConfigValue)
 }
 
 func TestGetEnvoyExtensionRunCreatesExampleWhenMissing(t *testing.T) {
@@ -460,7 +477,7 @@ func setupTest(t *testing.T, relativeWorkspaceTemplate string) (*testEnvoyExtens
 
 func requirePlaceholdersYaml(t *testing.T, envoyHome string) string {
 	placeholders := filepath.Join(envoyHome, "capture", "placeholders.tmpl.yaml")
-	b, err := ioutil.ReadFile(placeholders)
+	b, err := os.ReadFile(placeholders)
 	require.NoError(t, err, `expected no error reading placeholders: %s`, placeholders)
 	return string(b)
 }
@@ -495,7 +512,7 @@ func requireManifestTestServer(t *testing.T, envoySubstituteArchiveDir string) f
 					return envoySubstituteArchiveDir, nil
 				}
 			}
-			return "", errors.Errorf("unexpected version of Envoy %q", uri)
+			return "", fmt.Errorf("unexpected version of Envoy %q", uri)
 		},
 		OnError: func(err error) {
 			require.NoError(t, err, `unexpected error from test manifest server`)
diff --git a/pkg/extension/init/init_test.go b/pkg/extension/init/init_test.go
index 71a48fd..a175233 100644
--- a/pkg/extension/init/init_test.go
+++ b/pkg/extension/init/init_test.go
@@ -16,7 +16,7 @@ package init
 
 import (
 	"fmt"
-	"io/ioutil"
+	"os"
 	"path/filepath"
 	"testing"
 
@@ -111,7 +111,7 @@ func TestScaffold(t *testing.T) {
 			err := Scaffold(opts)
 			require.NoError(t, err)
 
-			actual, err := ioutil.ReadFile(filepath.Join(outputDir, test.file))
+			actual, err := os.ReadFile(filepath.Join(outputDir, test.file))
 			require.NoError(t, err)
 			require.Contains(t, string(actual), test.expected)
 		})
diff --git a/pkg/extension/workspace/config/extension/extension_test.go b/pkg/extension/workspace/config/extension/extension_test.go
index 1b654eb..1adb595 100644
--- a/pkg/extension/workspace/config/extension/extension_test.go
+++ b/pkg/extension/workspace/config/extension/extension_test.go
@@ -19,8 +19,8 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	"gopkg.in/yaml.v3"
 
-	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config"
 	. "github.com/tetratelabs/getenvoy/pkg/extension/workspace/config/extension"
 )
 
@@ -41,7 +41,7 @@ runtime:
     version: standard:1.17.0
 `
 	var descriptor Descriptor
-	err := config.Unmarshal([]byte(input), &descriptor)
+	err := yaml.Unmarshal([]byte(input), &descriptor)
 	require.NoError(t, err)
 
 	err = descriptor.Validate()
@@ -57,10 +57,10 @@ func TestDescriptorValidateError(t *testing.T) {
 		{
 			name:        "empty",
 			input:       ``,
-			expectedErr: `4 errors occurred: extension name cannot be empty; extension category cannot be empty; programming language cannot be empty; runtime description is not valid: Envoy version cannot be empty`,
+			expectedErr: `4 errors occurred: extension name cannot be empty; extension category cannot be empty; programming language cannot be empty; runtime description is not valid: envoy version cannot be empty`,
 		},
 		{
-			name: "invalid Envoy version",
+			name: "invalid envoy version",
 			input: `#
 # Envoy Wasm extension created with getenvoy toolkit.
 #
@@ -76,7 +76,7 @@ runtime:
   envoy:
     version: invalid value
 `,
-			expectedErr: `runtime description is not valid: Envoy version is not valid: "invalid value" is not a valid GetEnvoy reference. Expected format: <flavor>:<version>[/<platform>]`,
+			expectedErr: `runtime description is not valid: envoy version is not valid: "invalid value" is not a valid GetEnvoy reference. Expected format: <flavor>:<version>[/<platform>]`,
 		},
 		{
 			name: "missing extension name",
@@ -120,7 +120,7 @@ runtime:
 
 		t.Run(test.name, func(t *testing.T) {
 			var descriptor Descriptor
-			err := config.Unmarshal([]byte(test.input), &descriptor)
+			err := yaml.Unmarshal([]byte(test.input), &descriptor)
 			require.NoError(t, err)
 
 			err = descriptor.Validate()
diff --git a/pkg/extension/workspace/config/toolchain/builtin/helpers_test.go b/pkg/extension/workspace/config/toolchain/builtin/helpers_test.go
index 9d340a0..866881c 100644
--- a/pkg/extension/workspace/config/toolchain/builtin/helpers_test.go
+++ b/pkg/extension/workspace/config/toolchain/builtin/helpers_test.go
@@ -18,8 +18,8 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	"gopkg.in/yaml.v3"
 
-	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config"
 	. "github.com/tetratelabs/getenvoy/pkg/extension/workspace/config/toolchain/builtin"
 )
 
@@ -98,7 +98,7 @@ func TestToolchainConfigValidate(t *testing.T) {
 
 		t.Run(test.name, func(t *testing.T) {
 			var toolchainConfig ToolchainConfig
-			err := config.Unmarshal([]byte(test.input), &toolchainConfig)
+			err := yaml.Unmarshal([]byte(test.input), &toolchainConfig)
 			require.NoError(t, err)
 
 			err = toolchainConfig.Validate()
@@ -245,7 +245,7 @@ func TestToolchainConfigValidateError(t *testing.T) {
 
 		t.Run(test.name, func(t *testing.T) {
 			var toolchainConfig ToolchainConfig
-			err := config.Unmarshal([]byte(test.input), &toolchainConfig)
+			err := yaml.Unmarshal([]byte(test.input), &toolchainConfig)
 			require.NoError(t, err)
 
 			err = toolchainConfig.Validate()
@@ -321,7 +321,7 @@ func TestToolchainConfigGetBuildOutputWasmFile(t *testing.T) {
 
 		t.Run(test.name, func(t *testing.T) {
 			var toolchainConfig ToolchainConfig
-			err := config.Unmarshal([]byte(test.input), &toolchainConfig)
+			err := yaml.Unmarshal([]byte(test.input), &toolchainConfig)
 			require.NoError(t, err)
 
 			actual := toolchainConfig.GetBuildOutputWasmFile()
diff --git a/pkg/extension/workspace/example/envoy/template/data_test.go b/pkg/extension/workspace/example/envoy/template/data_test.go
new file mode 100644
index 0000000..041dfed
--- /dev/null
+++ b/pkg/extension/workspace/example/envoy/template/data_test.go
@@ -0,0 +1,45 @@
+// Copyright 2021 Tetrate
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package template
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func defaultExtensionConfigJSON(t *testing.T, defaultExtensionConfig string) string {
+	e := getEnvoyExtension{ctx: &ExpandContext{DefaultExtensionConfig: defaultExtensionConfig}}
+
+	getEnvoyValue, err := e.Config()
+	require.NoError(t, err)
+	require.NotNil(t, getEnvoyValue)
+
+	return getEnvoyValue.String()
+}
+
+func TestConfigMarshalsDefaultExtensionConfig(t *testing.T) {
+	json := defaultExtensionConfigJSON(t, `{"key":"value"}`)
+
+	// Google made json formatting (json.prepareNext) intentionally unstable, technically by adding a space randomly.
+	// https://github.com/golang/protobuf/issues/920 requested an option for stability, but it was closed and locked.
+	// https://github.com/golang/protobuf/issues/1121 remains open, but unlikely to change.
+	// Hence, we have to check two possible formats.
+	withoutSpace := `{"@type":"type.googleapis.com/google.protobuf.StringValue","value":"{\"key\":\"value\"}"}`
+	withSpace := `{"@type":"type.googleapis.com/google.protobuf.StringValue", "value":"{\"key\":\"value\"}"}`
+	if withoutSpace != json {
+		require.Equal(t, withSpace, json)
+	}
+}
diff --git a/pkg/extension/workspace/example/envoy/template/expand_test.go b/pkg/extension/workspace/example/envoy/template/expand_test.go
index 9b97988..07f1574 100644
--- a/pkg/extension/workspace/example/envoy/template/expand_test.go
+++ b/pkg/extension/workspace/example/envoy/template/expand_test.go
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package template_test
+package template
 
 import (
 	"testing"
@@ -21,7 +21,6 @@ import (
 
 	"github.com/tetratelabs/getenvoy/pkg/extension/manager"
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config/extension"
-	. "github.com/tetratelabs/getenvoy/pkg/extension/workspace/example/envoy/template"
 )
 
 func TestExpand(t *testing.T) {
@@ -68,12 +67,12 @@ func TestExpand(t *testing.T) {
 		{
 			name:     "extension: config",
 			input:    `{{ .GetEnvoy.Extension.Config }}`,
-			expected: `{"@type":"type.googleapis.com/google.protobuf.StringValue","value":"{\"key\":\"value\"}"}`,
+			expected: defaultExtensionConfigJSON(t, `{"key":"value"}`),
 		},
 		{
 			name:     "access to proto message",
-			input:    `{{ (.GetEnvoy.Extension.Code).Message.GetLocal.GetFilename }}`,
-			expected: `/path/to/extension.wasm`,
+			input:    `"{{ (.GetEnvoy.Extension.Code).Message.GetLocal.GetFilename }}"`,
+			expected: `"/path/to/extension.wasm"`,
 		},
 	}
 
@@ -95,7 +94,7 @@ func TestExpand(t *testing.T) {
 
 			actual, err := Expand([]byte(test.input), ctx)
 			require.NoError(t, err)
-			require.Equal(t, test.expected, string(actual))
+			require.JSONEq(t, test.expected, string(actual))
 		})
 	}
 }
diff --git a/pkg/extension/workspace/example/envoy/util/load_test.go b/pkg/extension/workspace/example/envoy/util/load_test.go
index 190ce6e..d94bf1b 100644
--- a/pkg/extension/workspace/example/envoy/util/load_test.go
+++ b/pkg/extension/workspace/example/envoy/util/load_test.go
@@ -15,12 +15,9 @@
 package util
 
 import (
-	"reflect"
-	"strings"
 	"testing"
 
 	envoylistener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
-	"github.com/golang/protobuf/proto"
 	"github.com/stretchr/testify/require"
 
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/model"
@@ -55,7 +52,7 @@ func TestLoadValidatesYAML(t *testing.T) {
 	require.EqualError(t, err, expectedErr)
 }
 
-func TestNewFakeAnyResolver(t *testing.T) {
+func TestFakeAnyResolver(t *testing.T) {
 	tests := []struct {
 		name    string
 		typeURL string
@@ -68,28 +65,11 @@ func TestNewFakeAnyResolver(t *testing.T) {
 		test := test // pin! see https://github.com/kyoh86/scopelint for why
 
 		t.Run(test.name, func(t *testing.T) {
-			resolver := newFakeAnyResolver()
+			resolver := fakeAnyResolver{}
 
-			actual, err := resolver.Resolve(test.typeURL)
+			actual, err := resolver.FindMessageByURL(test.typeURL)
 			require.NoError(t, err)
-
-			props := proto.GetProperties(reflect.ValueOf(actual).Elem().Type())
-			fields := MessageFields(props.Prop).Filter(func(field *proto.Properties) bool {
-				return !strings.HasPrefix(field.Name, "XXX_")
-			})
-			require.Empty(t, fields)
+			require.NotNil(t, actual)
 		})
 	}
 }
-
-type MessageFields []*proto.Properties
-
-func (fields MessageFields) Filter(test func(*proto.Properties) bool) MessageFields {
-	result := make(MessageFields, 0)
-	for _, field := range fields {
-		if test(field) {
-			result = append(result, field)
-		}
-	}
-	return result
-}
diff --git a/pkg/extension/workspace/example/runtime/configdir/configdir_test.go b/pkg/extension/workspace/example/runtime/configdir/configdir_test.go
index 57a4f80..74218fc 100644
--- a/pkg/extension/workspace/example/runtime/configdir/configdir_test.go
+++ b/pkg/extension/workspace/example/runtime/configdir/configdir_test.go
@@ -16,12 +16,11 @@ package configdir_test
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
 	"path/filepath"
+	"strings"
 	"testing"
 
-	envoybootstrap "github.com/envoyproxy/go-control-plane/envoy/config/bootstrap/v3"
 	"github.com/stretchr/testify/require"
 
 	workspaces "github.com/tetratelabs/getenvoy/pkg/extension/workspace"
@@ -32,50 +31,34 @@ import (
 
 func TestNewConfigDir(t *testing.T) {
 	tests := []struct {
-		name             string
-		workspaceDir     string
-		isEnvoyTemplate  func(string) bool
-		requireBootstrap func(t *testing.T, bootstrap *envoybootstrap.Bootstrap)
+		name                 string
+		workspaceDir         string
+		expectValidBootstrap bool
 	}{
 		{
-			name:         "envoy.tmpl.yaml",
-			workspaceDir: "testdata/workspace1",
-			isEnvoyTemplate: func(name string) bool {
-				return name == "envoy.tmpl.yaml" //nolint:goconst
-			},
-			requireBootstrap: expectValidBootstrap,
+			name:                 "envoy.tmpl.yaml",
+			workspaceDir:         "testdata/workspace1",
+			expectValidBootstrap: true,
 		},
 		{
-			name:         "envoy.tmpl.yaml + lds.tmpl.yaml + cds.yaml",
-			workspaceDir: "testdata/workspace2",
-			isEnvoyTemplate: func(name string) bool {
-				return name == "envoy.tmpl.yaml" || name == "lds.tmpl.yaml" || name == "cds.yaml"
-			},
-			requireBootstrap: expectValidBootstrap,
+			name:                 "envoy.tmpl.yaml + lds.tmpl.yaml + cds.yaml",
+			workspaceDir:         "testdata/workspace2",
+			expectValidBootstrap: true,
 		},
 		{
-			name:         "envoy.tmpl.yaml: not a valid YAML",
-			workspaceDir: "testdata/workspace3",
-			isEnvoyTemplate: func(name string) bool {
-				return false
-			},
-			requireBootstrap: expectInvalidBootstrap,
+			name:                 "envoy.tmpl.yaml: not a valid YAML",
+			workspaceDir:         "testdata/workspace3",
+			expectValidBootstrap: false,
 		},
 		{
-			name:         "envoy.tmpl.yaml: invalid paths to `lds` and `cds` files",
-			workspaceDir: "testdata/workspace4",
-			isEnvoyTemplate: func(name string) bool {
-				return name == "envoy.tmpl.yaml"
-			},
-			requireBootstrap: expectValidBootstrap,
+			name:                 "envoy.tmpl.yaml: invalid paths to `lds` and `cds` files",
+			workspaceDir:         "testdata/workspace4",
+			expectValidBootstrap: true,
 		},
 		{
-			name:         "envoy.tmpl.yaml: .txt configuration",
-			workspaceDir: "testdata/workspace8",
-			isEnvoyTemplate: func(name string) bool {
-				return name == "envoy.tmpl.yaml"
-			},
-			requireBootstrap: expectValidBootstrap,
+			name:                 "envoy.tmpl.yaml: .txt configuration",
+			workspaceDir:         "testdata/workspace8",
+			expectValidBootstrap: true,
 		},
 	}
 
@@ -104,19 +87,33 @@ func TestNewConfigDir(t *testing.T) {
 				require.True(t, os.IsNotExist(err))
 			}()
 
-			// verify the config dir
+			// verify the bootstrap file
 			require.FileExists(t, configDir.GetBootstrapFile())
-			test.requireBootstrap(t, configDir.GetBootstrap())
+			bootstrap := configDir.GetBootstrap()
+
+			if !test.expectValidBootstrap {
+				require.Nil(t, bootstrap)
+				return // don't check for evaluation of template inputs when the bootstrap was invalid
+			}
+
+			require.NotNil(t, bootstrap)
+			require.Equal(t, "/dev/null", bootstrap.GetAdmin().GetAccessLogPath())
+			require.Equal(t, "127.0.0.1", bootstrap.GetAdmin().GetAddress().GetSocketAddress().GetAddress())
+			require.Equal(t, uint32(9901), bootstrap.GetAdmin().GetAddress().GetSocketAddress().GetPortValue())
 
 			// verify contents of the config dir
 			for _, fileName := range ctx.Opts.Example.GetFiles().GetNames() {
-				expected, err := ioutil.ReadFile(filepath.Join(test.workspaceDir, "expected/getenvoy_extension_run", fileName))
+				expected, err := os.ReadFile(filepath.Join(test.workspaceDir, "expected/getenvoy_extension_run", fileName))
 				require.NoError(t, err)
-				actual, err := ioutil.ReadFile(filepath.Join(configDir.GetDir(), fileName))
+				actual, err := os.ReadFile(filepath.Join(configDir.GetDir(), fileName))
 				require.NoError(t, err)
-				if test.isEnvoyTemplate(fileName) {
-					require.YAMLEq(t, string(expected), string(actual))
-				} else {
+
+				switch {
+				case strings.HasSuffix(fileName, ".yaml") && fileName != "envoy.tmpl.yaml":
+					require.YAMLEq(t, string(expected), string(actual), `%s is not valid yaml`, fileName)
+				case strings.HasSuffix(fileName, ".json"):
+					require.JSONEq(t, string(expected), string(actual), `%s is not valid json`, fileName)
+				case fileName != "envoy.tmpl.yaml": // we don't need to check our input template
 					require.Equal(t, string(expected), string(actual))
 				}
 			}
@@ -141,17 +138,6 @@ func runContext(workspace model.Workspace, example model.Example) *runtime.RunCo
 	}
 }
 
-func expectValidBootstrap(t *testing.T, bootstrap *envoybootstrap.Bootstrap) {
-	require.NotNil(t, bootstrap)
-	require.Equal(t, "/dev/null", bootstrap.GetAdmin().GetAccessLogPath())
-	require.Equal(t, "127.0.0.1", bootstrap.GetAdmin().GetAddress().GetSocketAddress().GetAddress())
-	require.Equal(t, uint32(9901), bootstrap.GetAdmin().GetAddress().GetSocketAddress().GetPortValue())
-}
-
-func expectInvalidBootstrap(t *testing.T, bootstrap *envoybootstrap.Bootstrap) {
-	require.Nil(t, bootstrap)
-}
-
 func TestNewConfigDirValidates(t *testing.T) {
 	abs := func(path string) string {
 		path, err := filepath.Abs(path)
diff --git a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace3/expected/getenvoy_extension_run/envoy.tmpl.yaml b/pkg/extension/workspace/example/runtime/configdir/testdata/workspace3/expected/getenvoy_extension_run/envoy.tmpl.yaml
deleted file mode 100644
index 634a0fb..0000000
--- a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace3/expected/getenvoy_extension_run/envoy.tmpl.yaml
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# Example Envoy configuration.
-#
-invalid yaml
-
-admin: {"accessLogPath":"/dev/null","address":{"socketAddress":{"address":"127.0.0.1","portValue":9901}}}
-
-static_resources:
-  listeners:
-    - name: ingress
-      address:
-        socket_address:
-          address: 0.0.0.0
-          port_value: 10000
-      filter_chains:
-        - filters:
-            - name: envoy.filters.network.wasm
-              typed_config:
-                "@type": type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm
-                config:
-                  configuration: {"@type":"type.googleapis.com/google.protobuf.StringValue","value":"{\"key\":\"value\"}\n"}
-                  name: "mycompany.filters.http.custom_metrics"
-                  root_id: "mycompany.filters.http.custom_metrics"
-                  vm_config:
-                    vm_id: "mycompany.filters.http.custom_metrics"
-                    runtime: envoy.wasm.runtime.v8
-                    code: {"local":{"filename":"/path/to/extension.wasm"}}
-            - name: envoy.filters.network.tcp_proxy
-              typed_config:
-                "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-                stat_prefix: ingress
-                cluster: mock_service
-
-    - name: mock
-      address:
-        socket_address:
-          address: 127.0.0.1
-          port_value: 10001
-      filter_chains:
-        - filters:
-            - name: envoy.filters.network.http_connection_manager
-              typed_config:
-                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
-                stat_prefix: mock
-                route_config:
-                  name: local_route
-                  virtual_hosts:
-                    - name: mock
-                      domains:
-                        - "*"
-                      routes:
-                        - match:
-                            prefix: "/"
-                          direct_response:
-                            status: 200
-                            body:
-                              inline_string: "Hi from mock service!\n"
-                http_filters:
-                  - name: envoy.filters.http.router
-
-  clusters:
-    - name: mock_service
-      connect_timeout: 0.25s
-      type: STATIC
-      lb_policy: ROUND_ROBIN
-      load_assignment:
-        cluster_name: mock_service
-        endpoints:
-        - lb_endpoints:
-          - endpoint:
-              address:
-                socket_address:
-                  address: 127.0.0.1
-                  port_value: 10001
diff --git a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace3/expected/getenvoy_extension_run/example.yaml b/pkg/extension/workspace/example/runtime/configdir/testdata/workspace3/expected/getenvoy_extension_run/example.yaml
deleted file mode 100644
index c45b126..0000000
--- a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace3/expected/getenvoy_extension_run/example.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# Example of a Wasm Http Filter.
-#
-kind: Example
diff --git a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace3/expected/getenvoy_extension_run/extension.json b/pkg/extension/workspace/example/runtime/configdir/testdata/workspace3/expected/getenvoy_extension_run/extension.json
deleted file mode 100644
index 29f05f6..0000000
--- a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace3/expected/getenvoy_extension_run/extension.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"key":"value"}
diff --git a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace4/.getenvoy/extension/examples/default/cds.yaml b/pkg/extension/workspace/example/runtime/configdir/testdata/workspace4/.getenvoy/extension/examples/default/cds.yaml
deleted file mode 100644
index 10cbcf7..0000000
--- a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace4/.getenvoy/extension/examples/default/cds.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-version_info: v0
-type_url: type.googleapis.com/envoy.config.cluster.v3.Cluster
-resources:
-- "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster
-  name: xds_mock_service
-  connect_timeout: 0.25s
-  type: STATIC
-  lb_policy: ROUND_ROBIN
-  load_assignment:
-    cluster_name: xds_mock_service
-    endpoints:
-    - lb_endpoints:
-      - endpoint:
-          address:
-            socket_address:
-              address: 127.0.0.1
-              port_value: 20001
diff --git a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace4/.getenvoy/extension/examples/default/lds.tmpl.yaml b/pkg/extension/workspace/example/runtime/configdir/testdata/workspace4/.getenvoy/extension/examples/default/lds.tmpl.yaml
deleted file mode 100644
index 50cbde0..0000000
--- a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace4/.getenvoy/extension/examples/default/lds.tmpl.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-version_info: v0
-type_url: type.googleapis.com/envoy.config.listener.v3.Listener
-resources:
-- "@type": type.googleapis.com/envoy.config.listener.v3.Listener
-  name: xds_ingress
-  address:
-    socket_address:
-      address: 0.0.0.0
-      port_value: 20000
-  filter_chains:
-    - filters:
-        - name: envoy.filters.network.wasm
-          typed_config:
-            "@type": type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm
-            config:
-              configuration: {{ .GetEnvoy.Extension.Config }}
-              name: {{ .GetEnvoy.Extension.Name }}
-              root_id: {{ .GetEnvoy.Extension.Name }}
-              vm_config:
-                vm_id: {{ .GetEnvoy.Extension.Name }}
-                runtime: envoy.wasm.runtime.v8
-                code: {{ .GetEnvoy.Extension.Code }}
-        - name: envoy.filters.network.tcp_proxy
-          typed_config:
-            "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-            stat_prefix: ingress
-            cluster: xds_mock_service
diff --git a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace4/expected/getenvoy_extension_run/cds.yaml b/pkg/extension/workspace/example/runtime/configdir/testdata/workspace4/expected/getenvoy_extension_run/cds.yaml
deleted file mode 100644
index 10cbcf7..0000000
--- a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace4/expected/getenvoy_extension_run/cds.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-version_info: v0
-type_url: type.googleapis.com/envoy.config.cluster.v3.Cluster
-resources:
-- "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster
-  name: xds_mock_service
-  connect_timeout: 0.25s
-  type: STATIC
-  lb_policy: ROUND_ROBIN
-  load_assignment:
-    cluster_name: xds_mock_service
-    endpoints:
-    - lb_endpoints:
-      - endpoint:
-          address:
-            socket_address:
-              address: 127.0.0.1
-              port_value: 20001
diff --git a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace4/expected/getenvoy_extension_run/lds.tmpl.yaml b/pkg/extension/workspace/example/runtime/configdir/testdata/workspace4/expected/getenvoy_extension_run/lds.tmpl.yaml
deleted file mode 100644
index 50cbde0..0000000
--- a/pkg/extension/workspace/example/runtime/configdir/testdata/workspace4/expected/getenvoy_extension_run/lds.tmpl.yaml
+++ /dev/null
@@ -1,27 +0,0 @@
-version_info: v0
-type_url: type.googleapis.com/envoy.config.listener.v3.Listener
-resources:
-- "@type": type.googleapis.com/envoy.config.listener.v3.Listener
-  name: xds_ingress
-  address:
-    socket_address:
-      address: 0.0.0.0
-      port_value: 20000
-  filter_chains:
-    - filters:
-        - name: envoy.filters.network.wasm
-          typed_config:
-            "@type": type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm
-            config:
-              configuration: {{ .GetEnvoy.Extension.Config }}
-              name: {{ .GetEnvoy.Extension.Name }}
-              root_id: {{ .GetEnvoy.Extension.Name }}
-              vm_config:
-                vm_id: {{ .GetEnvoy.Extension.Name }}
-                runtime: envoy.wasm.runtime.v8
-                code: {{ .GetEnvoy.Extension.Code }}
-        - name: envoy.filters.network.tcp_proxy
-          typed_config:
-            "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
-            stat_prefix: ingress
-            cluster: xds_mock_service
diff --git a/pkg/extension/workspace/toolchain/builtin/default_config_test.go b/pkg/extension/workspace/toolchain/builtin/default_config_test.go
index a3bce6b..66b48da 100644
--- a/pkg/extension/workspace/toolchain/builtin/default_config_test.go
+++ b/pkg/extension/workspace/toolchain/builtin/default_config_test.go
@@ -16,12 +16,12 @@ package builtin
 
 import (
 	"fmt"
-	"io/ioutil"
+	"os"
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	"gopkg.in/yaml.v3"
 
-	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config"
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config/extension"
 )
 
@@ -34,7 +34,7 @@ func TestDefaultConfigForValidate(t *testing.T) {
 
 	tests := make([]testCase, len(extension.Languages))
 	for i, lang := range extension.Languages {
-		expected, err := ioutil.ReadFile(fmt.Sprintf("testdata/default_config/%s.toolchain.yaml", lang))
+		expected, err := os.ReadFile(fmt.Sprintf("testdata/default_config/%s.toolchain.yaml", lang))
 		if err != nil {
 			panic(fmt.Errorf("missing default config for language %s: %w", lang, err))
 		}
@@ -50,7 +50,7 @@ func TestDefaultConfigForValidate(t *testing.T) {
 			err := cfg.Validate()
 			require.NoError(t, err)
 
-			actual, err := config.Marshal(cfg)
+			actual, err := yaml.Marshal(cfg)
 			require.NoError(t, err)
 			require.YAMLEq(t, test.expected, string(actual))
 		})
diff --git a/pkg/extension/workspace/toolchain/builtin/example_config_test.go b/pkg/extension/workspace/toolchain/builtin/example_config_test.go
index 34c9a2d..74af63f 100644
--- a/pkg/extension/workspace/toolchain/builtin/example_config_test.go
+++ b/pkg/extension/workspace/toolchain/builtin/example_config_test.go
@@ -16,7 +16,7 @@ package builtin
 
 import (
 	"fmt"
-	"io/ioutil"
+	"os"
 	"testing"
 
 	"github.com/stretchr/testify/require"
@@ -33,7 +33,7 @@ func TestExampleConfigValidate(t *testing.T) {
 
 	tests := make([]testCase, len(extension.Languages))
 	for i, lang := range extension.Languages {
-		expected, err := ioutil.ReadFile(fmt.Sprintf("testdata/example_config/%s.toolchain.yaml", lang))
+		expected, err := os.ReadFile(fmt.Sprintf("testdata/example_config/%s.toolchain.yaml", lang))
 		if err != nil {
 			panic(fmt.Errorf("missing example config for language %s: %w", lang, err))
 		}
diff --git a/pkg/extension/workspace/toolchain/builtin/factory_test.go b/pkg/extension/workspace/toolchain/builtin/factory_test.go
index d890cd3..62168b2 100644
--- a/pkg/extension/workspace/toolchain/builtin/factory_test.go
+++ b/pkg/extension/workspace/toolchain/builtin/factory_test.go
@@ -17,9 +17,9 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	"gopkg.in/yaml.v3"
 
 	workspaces "github.com/tetratelabs/getenvoy/pkg/extension/workspace"
-	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config"
 	extensionconfig "github.com/tetratelabs/getenvoy/pkg/extension/workspace/config/extension"
 	builtinconfig "github.com/tetratelabs/getenvoy/pkg/extension/workspace/config/toolchain/builtin"
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/model"
@@ -125,7 +125,7 @@ func TestBuiltinToolchainLoadConfig(t *testing.T) {
 			require.NoError(t, err)
 
 			// verify defaults get applied to the toolchain config
-			actual, err := config.Marshal(builder.GetConfig())
+			actual, err := yaml.Marshal(builder.GetConfig())
 			require.NoError(t, err)
 			require.YAMLEq(t, test.expected, string(actual))
 
diff --git a/pkg/extension/workspace/toolchain/builtin/toolchain_test.go b/pkg/extension/workspace/toolchain/builtin/toolchain_test.go
index d84b967..661289c 100644
--- a/pkg/extension/workspace/toolchain/builtin/toolchain_test.go
+++ b/pkg/extension/workspace/toolchain/builtin/toolchain_test.go
@@ -24,9 +24,9 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	"gopkg.in/yaml.v3"
 
 	workspaces "github.com/tetratelabs/getenvoy/pkg/extension/workspace"
-	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/config"
 	builtinconfig "github.com/tetratelabs/getenvoy/pkg/extension/workspace/config/toolchain/builtin"
 	. "github.com/tetratelabs/getenvoy/pkg/extension/workspace/toolchain/builtin"
 	"github.com/tetratelabs/getenvoy/pkg/extension/workspace/toolchain/types"
@@ -277,7 +277,7 @@ func TestBuiltinToolchain(t *testing.T) {
 
 		t.Run(test.name, func(t *testing.T) {
 			var cfg builtinconfig.ToolchainConfig
-			err = config.Unmarshal([]byte(test.config), &cfg)
+			err = yaml.Unmarshal([]byte(test.config), &cfg)
 			require.NoError(t, err)
 
 			err = cfg.Validate()
diff --git a/pkg/manifest/locate_test.go b/pkg/manifest/locate_test.go
index 49bb3f3..7b20806 100644
--- a/pkg/manifest/locate_test.go
+++ b/pkg/manifest/locate_test.go
@@ -20,7 +20,7 @@ import (
 	"os"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestLocate(t *testing.T) {
@@ -34,22 +34,22 @@ func TestLocate(t *testing.T) {
 		wantErr            bool
 	}{
 		{
-			name:               "standard 1.12.7 linux-glibc matches",
-			reference:          "standard:1.12.7/linux-glibc",
-			want:               "standard:1.12.7/linux-glibc",
+			name:               "standard 1.15.3 linux-glibc matches",
+			reference:          "standard:1.15.3/linux-glibc",
+			want:               "standard:1.15.3/linux-glibc",
 			responseStatusCode: http.StatusOK,
 		},
 		{
 			name:               "@ uses env var",
 			reference:          "@",
-			envVar:             "standard:1.12.7/linux-glibc",
-			want:               "standard:1.12.7/linux-glibc",
+			envVar:             "standard:1.15.3/linux-glibc",
+			want:               "standard:1.15.3/linux-glibc",
 			responseStatusCode: http.StatusOK,
 		},
 		{
-			name:               "standard 1.12.7 matches",
-			reference:          "standard:1.12.7",
-			want:               fmt.Sprintf("standard:1.12.7/%v", platform()),
+			name:               "standard 1.15.3 matches",
+			reference:          "standard:1.15.3",
+			want:               fmt.Sprintf("standard:1.15.3/%v", platform()),
 			responseStatusCode: http.StatusOK,
 		},
 		{
@@ -66,7 +66,7 @@ func TestLocate(t *testing.T) {
 		},
 		{
 			name:               "Error if not found",
-			reference:          "notaFlavor:1.12.7/notaPlatform",
+			reference:          "notaFlavor:1.15.3/notaPlatform",
 			responseStatusCode: http.StatusOK,
 			wantErr:            true,
 		},
@@ -77,7 +77,7 @@ func TestLocate(t *testing.T) {
 		},
 		{
 			name:               "Error on failed fetch",
-			reference:          "standard:1.12.7",
+			reference:          "standard:1.15.3",
 			responseStatusCode: http.StatusTeapot,
 			wantErr:            true,
 		},
@@ -93,21 +93,21 @@ func TestLocate(t *testing.T) {
 			}
 			defer func(originalURL string) {
 				err := SetURL(originalURL)
-				assert.NoError(t, err)
+				require.NoError(t, err)
 			}(GetURL())
 			err := SetURL(location)
-			assert.NoError(t, err)
+			require.NoError(t, err)
 			if len(tc.envVar) > 0 {
 				os.Setenv(referenceEnv, tc.envVar)
 				defer os.Unsetenv(referenceEnv)
 			}
 			key, _ := NewKey(tc.reference)
 			if got, err := Locate(key); tc.wantErr {
-				assert.Error(t, err)
-				assert.Equal(t, "", got)
+				require.Error(t, err)
+				require.Equal(t, "", got)
 			} else {
-				assert.NoError(t, err)
-				assert.Equal(t, tc.want, got)
+				require.NoError(t, err)
+				require.Equal(t, tc.want, got)
 			}
 		})
 	}
@@ -134,11 +134,11 @@ func TestNewKey(t *testing.T) {
 		t.Run(tc.reference, func(t *testing.T) {
 			got, err := NewKey(tc.reference)
 			if tc.wantErr {
-				assert.Error(t, err)
-				assert.Nil(t, got)
+				require.Error(t, err)
+				require.Nil(t, got)
 			} else {
-				assert.Nil(t, err)
-				assert.Equal(t, tc.want, got)
+				require.Nil(t, err)
+				require.Equal(t, tc.want, got)
 			}
 		})
 	}
diff --git a/pkg/manifest/print_test.go b/pkg/manifest/print_test.go
index cc142f2..89c5d79 100644
--- a/pkg/manifest/print_test.go
+++ b/pkg/manifest/print_test.go
@@ -16,15 +16,15 @@ package manifest
 
 import (
 	"bytes"
-	"io/ioutil"
 	"net/http"
 	"net/http/httptest"
+	"os"
 	"path/filepath"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 
-	"github.com/tetratelabs/getenvoy-package/api"
+	"github.com/tetratelabs/getenvoy/api"
 )
 
 func TestPrint(t *testing.T) {
@@ -51,17 +51,17 @@ func TestPrint(t *testing.T) {
 			}
 			defer func(originalURL string) {
 				err := SetURL(originalURL)
-				assert.NoError(t, err)
+				require.NoError(t, err)
 			}(GetURL())
 			err := SetURL(location)
-			assert.NoError(t, err)
+			require.NoError(t, err)
 			if err := Print(got); tc.wantErr {
-				assert.Error(t, err)
+				require.Error(t, err)
 			} else {
-				assert.NoError(t, err)
+				require.NoError(t, err)
 			}
-			want, _ := ioutil.ReadFile(filepath.Join("testdata", tc.wantOutputFile))
-			assert.Equal(t, string(want), got.String())
+			want, _ := os.ReadFile(filepath.Join("testdata", tc.wantOutputFile))
+			require.Equal(t, string(want), got.String())
 		})
 	}
 }
@@ -99,11 +99,12 @@ func TestFetch(t *testing.T) {
 			mock := mockServer(tc.responseStatusCode, tc.responseManifestFile)
 			defer mock.Close()
 			got, err := fetch(mock.URL)
-			assert.Equal(t, tc.want, got)
+			// Use prototext comparison to avoid comparing internal state
+			require.Equal(t, tc.want.String(), got.String())
 			if tc.wantErr {
-				assert.Error(t, err)
+				require.Error(t, err)
 			} else {
-				assert.NoError(t, err)
+				require.NoError(t, err)
 			}
 		})
 	}
@@ -113,7 +114,7 @@ func mockServer(responseStatusCode int, responseManifestFile string) *httptest.S
 	return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(responseStatusCode)
 		if responseStatusCode == http.StatusOK {
-			b, _ := ioutil.ReadFile(filepath.Join("testdata", responseManifestFile))
+			b, _ := os.ReadFile(filepath.Join("testdata", responseManifestFile))
 			w.Write(b)
 		}
 	}))
@@ -127,16 +128,16 @@ func goodManifest() *api.Manifest {
 				Name:          "standard",
 				FilterProfile: "standard",
 				Versions: map[string]*api.Version{
-					"1.12.7": {
-						Name: "1.12.7",
+					"1.15.3": {
+						Name: "1.15.3",
 						Builds: map[string]*api.Build{
 							api.Build_LINUX_GLIBC.String(): {
 								Platform:            api.Build_LINUX_GLIBC,
-								DownloadLocationUrl: "standard:1.12.7/linux-glibc",
+								DownloadLocationUrl: "standard:1.15.3/linux-glibc",
 							},
 							api.Build_DARWIN.String(): {
 								Platform:            api.Build_DARWIN,
-								DownloadLocationUrl: "standard:1.12.7/darwin",
+								DownloadLocationUrl: "standard:1.15.3/darwin",
 							},
 						},
 					},
diff --git a/pkg/manifest/testdata/list.golden b/pkg/manifest/testdata/list.golden
index 22927fc..eeb9412 100644
--- a/pkg/manifest/testdata/list.golden
+++ b/pkg/manifest/testdata/list.golden
@@ -1,5 +1,5 @@
 REFERENCE                                FLAVOR                VERSION
 standard:nightly/linux-glibc             standard              nightly
-standard:1.12.7/linux-glibc              standard              1.12.7
-standard:1.12.7/darwin                   standard              1.12.7
+standard:1.15.3/linux-glibc              standard              1.15.3
+standard:1.15.3/darwin                   standard              1.15.3
 standard-fips1402:1.10.0/linux-glibc     standard-fips1402     1.10.0
diff --git a/pkg/manifest/testdata/manifest.golden b/pkg/manifest/testdata/manifest.golden
index afad4cc..3005ce7 100644
--- a/pkg/manifest/testdata/manifest.golden
+++ b/pkg/manifest/testdata/manifest.golden
@@ -14,15 +14,15 @@
             }
           }
         },
-        "1.12.7": {
-          "name": "1.12.7",
+        "1.15.3": {
+          "name": "1.15.3",
           "builds": {
             "LINUX_GLIBC": {
-              "downloadLocationUrl": "standard:1.12.7/linux-glibc",
+              "downloadLocationUrl": "standard:1.15.3/linux-glibc",
               "platform": "LINUX_GLIBC"
             },
             "DARWIN": {
-              "downloadLocationUrl": "standard:1.12.7/darwin",
+              "downloadLocationUrl": "standard:1.15.3/darwin",
               "platform": "DARWIN"
             }
           }
diff --git a/pkg/test/cmd/command.go b/pkg/test/cmd/command.go
index d462ebf..b6a890c 100644
--- a/pkg/test/cmd/command.go
+++ b/pkg/test/cmd/command.go
@@ -18,7 +18,6 @@ import (
 	"bytes"
 	"fmt"
 	"io/fs"
-	"io/ioutil"
 	"os"
 	"os/user"
 	"path/filepath"
@@ -104,7 +103,7 @@ echo >&2 envoy stderr
 
 	// Write $envoyHome/bin/envoy and ensure it is executable
 	fakeEnvoyPath := filepath.Join(envoyBin, "envoy")
-	err := ioutil.WriteFile(fakeEnvoyPath, []byte(fakeEnvoyScript), 0700) // nolint:gosec
+	err := os.WriteFile(fakeEnvoyPath, []byte(fakeEnvoyScript), 0700) // nolint:gosec
 	require.NoError(t, err, `couldn't create fake envoy script: %s`, fakeEnvoyPath)
 	return fakeEnvoyPath
 }
diff --git a/pkg/test/manifest/manifest.go b/pkg/test/manifest/manifest.go
index a346339..a5126f5 100644
--- a/pkg/test/manifest/manifest.go
+++ b/pkg/test/manifest/manifest.go
@@ -15,7 +15,7 @@
 package manifest
 
 import (
-	"github.com/tetratelabs/getenvoy-package/api"
+	"github.com/tetratelabs/getenvoy/api"
 	"github.com/tetratelabs/getenvoy/pkg/types"
 )
 
diff --git a/pkg/test/manifest/platform.go b/pkg/test/manifest/platform.go
index 769f4ef..0c70e74 100644
--- a/pkg/test/manifest/platform.go
+++ b/pkg/test/manifest/platform.go
@@ -15,11 +15,10 @@
 package manifest
 
 import (
+	"fmt"
 	"strings"
 
-	"github.com/pkg/errors"
-
-	"github.com/tetratelabs/getenvoy-package/api"
+	"github.com/tetratelabs/getenvoy/api"
 )
 
 // Platform represents a platform.
@@ -44,7 +43,7 @@ func (p Platform) BuildPlatform() api.Build_Platform {
 	case PlatformDarwin:
 		return api.Build_DARWIN
 	default:
-		panic(errors.Errorf("unknown platform %q", p))
+		panic(fmt.Errorf("unknown platform %q", p))
 	}
 }
 
@@ -80,7 +79,7 @@ var (
 func ParsePlatform(text string) (Platform, error) {
 	p, ok := supportedPlatformsIndex[text]
 	if !ok {
-		return "", errors.Errorf("unknown platform %q", text)
+		return "", fmt.Errorf("unknown platform %q", text)
 	}
 	return p, nil
 }
diff --git a/pkg/test/manifest/server.go b/pkg/test/manifest/server.go
index c49efee..c6fd19d 100644
--- a/pkg/test/manifest/server.go
+++ b/pkg/test/manifest/server.go
@@ -23,12 +23,11 @@ import (
 	"path/filepath"
 	"strings"
 
-	"github.com/golang/protobuf/jsonpb"
-	"github.com/golang/protobuf/proto"
 	"github.com/mholt/archiver/v3"
-	"github.com/pkg/errors"
+	"google.golang.org/protobuf/encoding/protojson"
+	"google.golang.org/protobuf/proto"
 
-	"github.com/tetratelabs/getenvoy-package/api"
+	"github.com/tetratelabs/getenvoy/api"
 )
 
 const (
@@ -108,16 +107,16 @@ func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 }
 
 func (s *server) GetManifest() ([]byte, error) {
-	data, err := new(jsonpb.Marshaler).MarshalToString(s.manifest)
+	data, err := protojson.Marshal(s.manifest)
 	if err != nil {
 		return nil, err
 	}
-	return []byte(data), nil
+	return data, nil
 }
 
 func (s *server) GetArtifact(uri string) ([]byte, error) {
 	if !strings.HasSuffix(uri, archiveFormat) {
-		return nil, errors.Errorf("unexpected uri %q: expected archive suffix %q", uri, archiveFormat)
+		return nil, fmt.Errorf("unexpected uri %q: expected archive suffix %q", uri, archiveFormat)
 	}
 	uri = uri[:len(uri)-len(archiveFormat)]
 	dir, err := s.opts.GetArtifactDir(uri)
@@ -134,7 +133,7 @@ func (s *server) GetArtifact(uri string) ([]byte, error) {
 	if err != nil {
 		return nil, err
 	}
-	return ioutil.ReadFile(filepath.Clean(tarFile))
+	return os.ReadFile(filepath.Clean(tarFile))
 }
 
 func (s *server) rewriteManifestURLs(manifest *api.Manifest) {
diff --git a/pkg/types/types_test.go b/pkg/types/types_test.go
index 79f8c23..da452d9 100644
--- a/pkg/types/types_test.go
+++ b/pkg/types/types_test.go
@@ -29,19 +29,19 @@ func TestParseReference(t *testing.T) {
 		expected Reference
 	}{
 		{
-			name:     "standard:1.12.7",
-			input:    `standard:1.12.7`,
-			expected: Reference{Flavor: "standard", Version: "1.12.7", Platform: ""},
+			name:     "standard:1.15.3",
+			input:    `standard:1.15.3`,
+			expected: Reference{Flavor: "standard", Version: "1.15.3", Platform: ""},
 		},
 		{
-			name:     "standard:1.12.7/darwin",
-			input:    `standard:1.12.7/darwin`,
-			expected: Reference{Flavor: "standard", Version: "1.12.7", Platform: "darwin"},
+			name:     "standard:1.15.3/darwin",
+			input:    `standard:1.15.3/darwin`,
+			expected: Reference{Flavor: "standard", Version: "1.15.3", Platform: "darwin"},
 		},
 		{
-			name:     "standard:1.12.7/linux-glibc",
-			input:    `standard:1.12.7/linux-glibc`,
-			expected: Reference{Flavor: "standard", Version: "1.12.7", Platform: "linux-glibc"},
+			name:     "standard:1.15.3/linux-glibc",
+			input:    `standard:1.15.3/linux-glibc`,
+			expected: Reference{Flavor: "standard", Version: "1.15.3", Platform: "linux-glibc"},
 		},
 		{
 			name:     "wasm:1.15",
@@ -65,8 +65,8 @@ func TestParseReference(t *testing.T) {
 		},
 		{
 			name:     "trailing slash",
-			input:    `standard:1.12.7/`,
-			expected: Reference{Flavor: "standard", Version: "1.12.7", Platform: ""},
+			input:    `standard:1.15.3/`,
+			expected: Reference{Flavor: "standard", Version: "1.15.3", Platform: ""},
 		},
 		{
 			name:     "special characters",
@@ -104,8 +104,8 @@ func TestParseReferenceValidatesInput(t *testing.T) {
 		},
 		{
 			name:        "no flavor",
-			input:       `:1.12.7/darwin`,
-			expectedErr: `":1.12.7/darwin" is not a valid GetEnvoy reference. Expected format: <flavor>:<version>[/<platform>]`,
+			input:       `:1.15.3/darwin`,
+			expectedErr: `":1.15.3/darwin" is not a valid GetEnvoy reference. Expected format: <flavor>:<version>[/<platform>]`,
 		},
 		{
 			name:        "no version",
@@ -114,8 +114,8 @@ func TestParseReferenceValidatesInput(t *testing.T) {
 		},
 		{
 			name:        "invalid character in flavor",
-			input:       `stan dard:1.12.7/darwin`,
-			expectedErr: `"stan dard:1.12.7/darwin" is not a valid GetEnvoy reference. Expected format: <flavor>:<version>[/<platform>]`,
+			input:       `stan dard:1.15.3/darwin`,
+			expectedErr: `"stan dard:1.15.3/darwin" is not a valid GetEnvoy reference. Expected format: <flavor>:<version>[/<platform>]`,
 		},
 	}
 
@@ -136,16 +136,16 @@ func TestParseReferenceNormalizesStringForm(t *testing.T) {
 		expected string
 	}{
 		{
-			input:    `standard:1.12.7`,
-			expected: `standard:1.12.7`,
+			input:    `standard:1.15.3`,
+			expected: `standard:1.15.3`,
 		},
 		{
-			input:    `standard:1.12.7/darwin`,
-			expected: `standard:1.12.7/darwin`,
+			input:    `standard:1.15.3/darwin`,
+			expected: `standard:1.15.3/darwin`,
 		},
 		{
-			input:    `standard:1.12.7/`,
-			expected: `standard:1.12.7`,
+			input:    `standard:1.15.3/`,
+			expected: `standard:1.15.3`,
 		},
 	}
 
diff --git a/test/e2e/getenvoy_extension_push_test.go b/test/e2e/getenvoy_extension_push_test.go
index 52919fb..f70328c 100644
--- a/test/e2e/getenvoy_extension_push_test.go
+++ b/test/e2e/getenvoy_extension_push_test.go
@@ -16,7 +16,7 @@ package e2e_test
 
 import (
 	"fmt"
-	"io/ioutil"
+	"os"
 	"path/filepath"
 	"testing"
 
@@ -97,7 +97,7 @@ digest: sha256`, defaultTag, imageRef), `unexpected stderr after running [%v]`,
 			require.FileExists(t, dstPath, `image not written after running [%v]`, c)
 
 			// Verify the bytes pulled are exactly the same as what we pushed.
-			pulledBytes, err := ioutil.ReadFile(dstPath)
+			pulledBytes, err := os.ReadFile(dstPath)
 			require.NoError(t, err, `error reading file wasm %s after running [%v]`, dstPath, c)
 			require.NotEmpty(t, wasmBytes, `%s empty after running [%v]`, dstPath, c)
 			require.Equal(t, wasmBytes, pulledBytes, `pulled bytes don't match source after running [%v]`, c)
diff --git a/test/e2e/getenvoy_extension_run_test.go b/test/e2e/getenvoy_extension_run_test.go
index 14b9820..c89dde0 100644
--- a/test/e2e/getenvoy_extension_run_test.go
+++ b/test/e2e/getenvoy_extension_run_test.go
@@ -15,7 +15,6 @@
 package e2e_test
 
 import (
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"regexp"
@@ -106,7 +105,7 @@ func TestGetEnvoyExtensionRun(t *testing.T) {
 			}
 
 			// verify the debug dump of Envoy state has been taken
-			files, err := ioutil.ReadDir(debugDir)
+			files, err := os.ReadDir(debugDir)
 			require.NoError(t, err, `error reading %s after stopping [%v]`, debugDir, c)
 			require.Equal(t, 1, len(files), `expected 1 file in %s after stopping [%v]`, debugDir, c)
 			defer func() {
diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go
index 53e5fdf..1c6c98c 100644
--- a/test/e2e/main_test.go
+++ b/test/e2e/main_test.go
@@ -16,7 +16,6 @@ package e2e_test
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"regexp"
@@ -198,7 +197,7 @@ func requireExtensionBuild(t *testing.T, language extension.Language, workDir st
 	extensionWasmFile := filepath.Join(workDir, extensionWasmPath(language))
 	require.FileExists(t, extensionWasmFile, `extension wasm file %s missing after running [%v]`, extensionWasmFile, c)
 
-	wasmBytes, err := ioutil.ReadFile(extensionWasmFile)
+	wasmBytes, err := os.ReadFile(extensionWasmFile)
 	require.NoError(t, err, `error reading %s after running [%v]: %s`, extensionWasmFile, c)
 	require.NotEmpty(t, wasmBytes, `%s empty after running [%v]`, extensionWasmFile, c)
 	return wasmBytes
diff --git a/test/e2e/util/envoy/admin.go b/test/e2e/util/envoy/admin.go
index ac7795d..bcb2f84 100644
--- a/test/e2e/util/envoy/admin.go
+++ b/test/e2e/util/envoy/admin.go
@@ -17,11 +17,9 @@ package envoy
 import (
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net"
 	"net/http"
-
-	"github.com/pkg/errors"
 )
 
 // AdminAPI represents Envoy Admin API.
@@ -80,9 +78,9 @@ func (c *client) GetStats() (*Stats, error) {
 	}
 	defer resp.Body.Close() //nolint:errcheck
 	if resp.StatusCode != http.StatusOK {
-		return nil, errors.Errorf("unexpected status code: %d", resp.StatusCode)
+		return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
 	}
-	body, err := ioutil.ReadAll(resp.Body)
+	body, err := io.ReadAll(resp.Body)
 	if err != nil {
 		return nil, err
 	}