Repository: traPtitech/NeoShowcase
Pull request #178 (2021-05-05 09:42:10)

Clean


Patch:
diff --git a/.golangci.yml b/.golangci.yml
index 8688e531..385da805 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -2,4 +2,4 @@ run:
   skip-files:
     - ".*\\.pb\\.go$"
   skip-dirs:
-    - pkg/models
+    - pkg/infrastructure/admindb/models
diff --git a/Dockerfile b/Dockerfile
index dc30fc41..8d3f029a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
 # build stage
-FROM golang:1.16.0-alpine AS builder
+FROM golang:1.16-alpine AS builder
 RUN apk add --update --no-cache git
 WORKDIR /go/src/github.com/traPtitech/NeoShowcase
 COPY ./go.* ./
@@ -25,19 +25,8 @@ RUN go build -o /app/ns-migrate -ldflags "-s -w -X main.version=$APP_VERSION -X
 FROM builder as builder-ns-ssgen
 RUN go build -o /app/ns-ssgen -ldflags "-s -w -X main.version=$APP_VERSION -X main.revision=$APP_REVISION" ./cmd/ns-ssgen
 
-# artifact base image
-FROM alpine:3.13.2 as dockerize
-ENV DOCKERIZE_VERSION v0.6.1
-RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
-    && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
-    && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz
-
-FROM alpine:3.13.2 as base
+FROM alpine:3 as base
 WORKDIR /app
-RUN apk add --update ca-certificates && \
-    update-ca-certificates && \
-    rm -rf /var/cache/apk/*
-COPY --from=dockerize /usr/local/bin/dockerize /usr/local/bin/dockerize
 
 # artifact images
 FROM base as ns
diff --git a/Makefile b/Makefile
index a4fc7507..01af6691 100644
--- a/Makefile
+++ b/Makefile
@@ -6,12 +6,13 @@ PROTOC_OPTS := -I ./api/proto --go_out=. --go_opt=module=$(GO_REPO_ROOT_PACKAGE)
 PROTOC_SOURCES ?= $(shell find ./api/proto/neoshowcase -type f -name "*.proto" -print)
 
 SQL_MIGRATE_CMD := go run github.com/rubenv/sql-migrate/sql-migrate
+EVANS_CMD := go run github.com/ktr0731/evans
 
 .PHONY: init
 init:
 	go mod download
 	go install google.golang.org/protobuf/cmd/protoc-gen-go
-	go get google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.0
+	go install google.golang.org/grpc/cmd/protoc-gen-go-grpc
 	go install github.com/volatiletech/sqlboiler/v4
 	go install github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-mysql
 
@@ -56,23 +57,23 @@ migrate-down:
 
 .PHONY: ns-builder-evans
 ns-builder-evans:
-	@evans --host localhost -p 5006 -r repl
+	@$(EVANS_CMD) --host localhost -p 5006 -r repl
 
 .PHONY: ns-builder-rebuild
 ns-builder-rebuild:
-	@docker-compose up -d --build ns-builder
+	@docker compose up -d --build ns-builder
 
 .PHONY: ns-ssgen-evans
 ns-ssgen-evans:
-	@evans --host localhost -p 5007 -r repl
+	@$(EVANS_CMD) --host localhost -p 5007 -r repl
 
 .PHONY: ns-ssgen-rebuild
 ns-ssgen-rebuild:
-	@docker-compose up -d --build ns-ssgen
+	@docker compose up -d --build ns-ssgen
 
 .PHONY: ns-rebuild
 ns-rebuild:
-	@docker-compose up -d --build ns
+	@docker compose up -d --build ns
 
 .PHONY: db-update
 db-update: migrate-up gogen db-gen-docs
@@ -88,7 +89,7 @@ dind-down:
 .PHONY: docker-test
 docker-test:
 	@docker container inspect ns-test-dind > /dev/null || make dind-up
-	ENABLE_DOCKER_TESTS=true DOCKER_HOST=tcp://localhost:5555 DOCKER_CERT_PATH=$$PWD/local-dev/dind/client DOCKER_TLS_VERIFY=true go test -v ./pkg/container/dockerimpl
+	ENABLE_DOCKER_TESTS=true DOCKER_HOST=tcp://localhost:5555 DOCKER_CERT_PATH=$$PWD/local-dev/dind/client DOCKER_TLS_VERIFY=true go test -v ./pkg/infrastructure/backend/dockerimpl
 
 .PHONY: k3d-up
 k3d-up:
@@ -100,4 +101,4 @@ k3d-down:
 
 .PHONY: k8s-test
 k8s-test:
-	ENABLE_K8S_TESTS=true K8S_TESTS_CLUSTER_CONTEXT=k3d-ns-test go test -v ./pkg/container/k8simpl
+	ENABLE_K8S_TESTS=true K8S_TESTS_CLUSTER_CONTEXT=k3d-ns-test go test -v ./pkg/infrastructure/backend/k8simpl
diff --git a/cmd/ns-builder/main.go b/cmd/ns-builder/main.go
index 5e85ee67..d5315298 100644
--- a/cmd/ns-builder/main.go
+++ b/cmd/ns-builder/main.go
@@ -12,11 +12,11 @@ import (
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
-	"github.com/traPtitech/neoshowcase/pkg/cliutil"
 	"github.com/traPtitech/neoshowcase/pkg/domain/builder"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/storage"
 	"github.com/traPtitech/neoshowcase/pkg/interface/grpc"
+	"github.com/traPtitech/neoshowcase/pkg/util/cli"
 )
 
 var (
@@ -33,7 +33,7 @@ var rootCommand = &cobra.Command{
 	Use:              "ns-builder",
 	Short:            "NeoShowcase BuilderService",
 	Version:          fmt.Sprintf("%s (%s)", version, revision),
-	PersistentPreRun: cliutil.PrintVersion,
+	PersistentPreRun: cli.PrintVersion,
 }
 
 func runCommand() *cobra.Command {
@@ -53,7 +53,7 @@ func runCommand() *cobra.Command {
 			}()
 
 			log.Info("NeoShowcase BuilderService started")
-			cliutil.WaitSIGINT()
+			cli.WaitSIGINT()
 			ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 			defer cancel()
 			return service.Shutdown(ctx)
@@ -64,17 +64,17 @@ func runCommand() *cobra.Command {
 
 func main() {
 	rand.Seed(time.Now().UnixNano())
-	cobra.OnInitialize(cliutil.CobraOnInitializeFunc(&configFilePath, "NS_BUILDER", &c))
+	cobra.OnInitialize(cli.CobraOnInitializeFunc(&configFilePath, "NS_BUILDER", &c))
 
 	rootCommand.AddCommand(
 		runCommand(),
-		cliutil.PrintConfCommand(&c),
+		cli.PrintConfCommand(&c),
 	)
 
 	flags := rootCommand.PersistentFlags()
 	flags.StringVarP(&configFilePath, "config", "c", "", "config file path")
-	cliutil.SetupDebugFlag(flags)
-	cliutil.SetupLogLevelFlag(flags)
+	cli.SetupDebugFlag(flags)
+	cli.SetupLogLevelFlag(flags)
 
 	viper.SetDefault("buildkit.address", appdefaults.Address)
 	viper.SetDefault("buildkit.registry", "localhost:5000")
@@ -143,4 +143,4 @@ func initBuildkitClient(c Config) (*buildkit.Client, error) {
 		return nil, fmt.Errorf("failed to initialize Buildkit Client: %w", err)
 	}
 	return client, nil
-}
\ No newline at end of file
+}
diff --git a/cmd/ns-mc/main.go b/cmd/ns-mc/main.go
index 1ed3f8bc..7ee4ed42 100644
--- a/cmd/ns-mc/main.go
+++ b/cmd/ns-mc/main.go
@@ -12,10 +12,10 @@ import (
 	"github.com/labstack/echo/v4"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
-	"github.com/traPtitech/neoshowcase/pkg/cliutil"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/web"
 	"github.com/traPtitech/neoshowcase/pkg/interface/handler"
 	"github.com/traPtitech/neoshowcase/pkg/usecase"
+	"github.com/traPtitech/neoshowcase/pkg/util/cli"
 )
 
 var (
@@ -32,7 +32,7 @@ var rootCommand = &cobra.Command{
 	Use:              "ns-mc",
 	Short:            "NeoShowcase MemberCheckerServer",
 	Version:          fmt.Sprintf("%s (%s)", version, revision),
-	PersistentPreRun: cliutil.PrintVersion,
+	PersistentPreRun: cli.PrintVersion,
 }
 
 func serveCommand() *cobra.Command {
@@ -51,7 +51,7 @@ func serveCommand() *cobra.Command {
 				}
 			}()
 
-			cliutil.WaitSIGINT()
+			cli.WaitSIGINT()
 			ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 			defer cancel()
 			return server.Shutdown(ctx)
@@ -66,17 +66,18 @@ func main() {
 		serveCommand(),
 	)
 	flags := rootCommand.PersistentFlags()
-	cliutil.SetupDebugFlag(flags)
-	cliutil.SetupLogLevelFlag(flags)
+	cli.SetupDebugFlag(flags)
+	cli.SetupLogLevelFlag(flags)
 
-	flags.IntVarP(&port, "port", "p", cliutil.GetIntEnvOrDefault("NS_MC_PORT", 8081), "port num")
-	flags.StringVarP(&pubkeyFilePath, "pubkey-file", "k", cliutil.GetEnvOrDefault("NS_MC_PUBKEY_FILE", ""), "public key PEM file path")
+	flags.IntVarP(&port, "port", "p", cli.GetIntEnvOrDefault("NS_MC_PORT", 8081), "port num")
+	flags.StringVarP(&pubkeyFilePath, "pubkey-file", "k", cli.GetEnvOrDefault("NS_MC_PUBKEY_FILE", ""), "public key PEM file path")
 
 	if err := rootCommand.Execute(); err != nil {
 		log.Fatal(err)
 	}
 }
 
+//nolint
 var handlerSet = wire.NewSet(
 	handler.NewMemberCheckHandler,
 )
diff --git a/cmd/ns-migrate/main.go b/cmd/ns-migrate/main.go
index 53659e31..a041e97a 100644
--- a/cmd/ns-migrate/main.go
+++ b/cmd/ns-migrate/main.go
@@ -12,7 +12,7 @@ import (
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 	"github.com/traPtitech/neoshowcase/migrations"
-	"github.com/traPtitech/neoshowcase/pkg/cliutil"
+	"github.com/traPtitech/neoshowcase/pkg/util/cli"
 )
 
 var (
@@ -34,7 +34,7 @@ var rootCommand = &cobra.Command{
 	Use:              "ns-migrate",
 	Short:            "NeoShowcase DB Migration Tool",
 	Version:          fmt.Sprintf("%s (%s)", version, revision),
-	PersistentPreRun: cliutil.PrintVersion,
+	PersistentPreRun: cli.PrintVersion,
 }
 
 func upCommand() *cobra.Command {
@@ -144,14 +144,14 @@ func init() {
 		listMigrationsCommand(),
 	)
 	flags := rootCommand.PersistentFlags()
-	cliutil.SetupDebugFlag(flags)
-	cliutil.SetupLogLevelFlag(flags)
+	cli.SetupDebugFlag(flags)
+	cli.SetupLogLevelFlag(flags)
 
-	flags.StringVarP(&dbHost, "dbhost", "H", cliutil.GetEnvOrDefault("DB_HOST", "localhost"), "database host name")
-	flags.IntVarP(&dbPort, "dbport", "P", cliutil.GetIntEnvOrDefault("DB_PORT", 3306), "database port number")
-	flags.StringVarP(&dbName, "dbname", "n", cliutil.GetEnvOrDefault("DB_NAME", "neoshowcase"), "database name")
-	flags.StringVarP(&dbUser, "dbuser", "u", cliutil.GetEnvOrDefault("DB_USER", "root"), "database user name")
-	flags.StringVarP(&dbPassword, "dbpassword", "p", cliutil.GetEnvOrDefault("DB_PASS", "password"), "database user password")
+	flags.StringVarP(&dbHost, "dbhost", "H", cli.GetEnvOrDefault("DB_HOST", "localhost"), "database host name")
+	flags.IntVarP(&dbPort, "dbport", "P", cli.GetIntEnvOrDefault("DB_PORT", 3306), "database port number")
+	flags.StringVarP(&dbName, "dbname", "n", cli.GetEnvOrDefault("DB_NAME", "neoshowcase"), "database name")
+	flags.StringVarP(&dbUser, "dbuser", "u", cli.GetEnvOrDefault("DB_USER", "root"), "database user name")
+	flags.StringVarP(&dbPassword, "dbpassword", "p", cli.GetEnvOrDefault("DB_PASS", "password"), "database user password")
 	flags.BoolVarP(&dryrun, "dryrun", "d", false, "dry run")
 	migrate.SetTable("migrations")
 }
diff --git a/cmd/ns-ssgen/main.go b/cmd/ns-ssgen/main.go
index cf195e9a..5c84df29 100644
--- a/cmd/ns-ssgen/main.go
+++ b/cmd/ns-ssgen/main.go
@@ -10,11 +10,11 @@ import (
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
-	"github.com/traPtitech/neoshowcase/pkg/cliutil"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/staticserver"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/storage"
 	"github.com/traPtitech/neoshowcase/pkg/interface/grpc"
+	"github.com/traPtitech/neoshowcase/pkg/util/cli"
 )
 
 var (
@@ -31,7 +31,7 @@ var rootCommand = &cobra.Command{
 	Use:              "ns-ssgen",
 	Short:            "NeoShowcase StaticSiteGenerator",
 	Version:          fmt.Sprintf("%s (%s)", version, revision),
-	PersistentPreRun: cliutil.PrintVersion,
+	PersistentPreRun: cli.PrintVersion,
 }
 
 func runCommand() *cobra.Command {
@@ -51,7 +51,7 @@ func runCommand() *cobra.Command {
 			}()
 
 			log.Info("NeoShowcase StaticSiteGenerator started")
-			cliutil.WaitSIGINT()
+			cli.WaitSIGINT()
 			ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 			defer cancel()
 			return server.Shutdown(ctx)
@@ -62,17 +62,17 @@ func runCommand() *cobra.Command {
 
 func main() {
 	rand.Seed(time.Now().UnixNano())
-	cobra.OnInitialize(cliutil.CobraOnInitializeFunc(&configFilePath, "NS_SSGEN", &c))
+	cobra.OnInitialize(cli.CobraOnInitializeFunc(&configFilePath, "NS_SSGEN", &c))
 
 	rootCommand.AddCommand(
 		runCommand(),
-		cliutil.PrintConfCommand(&c),
+		cli.PrintConfCommand(&c),
 	)
 
 	flags := rootCommand.PersistentFlags()
 	flags.StringVarP(&configFilePath, "config", "c", "", "config file path")
-	cliutil.SetupDebugFlag(flags)
-	cliutil.SetupLogLevelFlag(flags)
+	cli.SetupDebugFlag(flags)
+	cli.SetupLogLevelFlag(flags)
 
 	viper.SetDefault("artifactsRoot", "/srv/artifacts")
 	viper.SetDefault("builtin.port", 80)
diff --git a/cmd/ns-ssgen/wire.go b/cmd/ns-ssgen/wire.go
index 390c506d..aa191337 100644
--- a/cmd/ns-ssgen/wire.go
+++ b/cmd/ns-ssgen/wire.go
@@ -14,7 +14,7 @@ func New(c Config) (*Server, error) {
 	wire.Build(
 		grpc.NewServer,
 		grpc.NewStaticSiteServiceServer,
-		usecase.NewStaticSiteService,
+		usecase.NewStaticSiteServerService,
 		admindb.New,
 		staticserver.NewBuiltIn,
 		provideGRPCPort,
diff --git a/cmd/ns-ssgen/wire_gen.go b/cmd/ns-ssgen/wire_gen.go
index 1611fef2..9a50e9d6 100644
--- a/cmd/ns-ssgen/wire_gen.go
+++ b/cmd/ns-ssgen/wire_gen.go
@@ -29,14 +29,14 @@ func New(c2 Config) (*Server, error) {
 	webServerDocumentRootPath := provideWebServerDocumentRootPath(c2)
 	webServerPort := provideWebServerPort(c2)
 	engine := staticserver.NewBuiltIn(storage, webServerDocumentRootPath, webServerPort)
-	staticSiteService := usecase.NewStaticSiteService(engine, db)
-	grpcStaticSiteService := grpc.NewStaticSiteServiceServer(staticSiteService)
+	staticSiteServerService := usecase.NewStaticSiteServerService(engine, db)
+	staticSiteService := grpc.NewStaticSiteServiceServer(staticSiteServerService)
 	tcpListenPort := provideGRPCPort(c2)
 	mainServer := &Server{
 		db:         db,
 		grpcServer: server,
 		engine:     engine,
-		sss:        grpcStaticSiteService,
+		sss:        staticSiteService,
 		port:       tcpListenPort,
 	}
 	return mainServer, nil
diff --git a/cmd/ns/config.go b/cmd/ns/config.go
index c6722b41..45765b17 100644
--- a/cmd/ns/config.go
+++ b/cmd/ns/config.go
@@ -1,10 +1,11 @@
 package main
 
 import (
-	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb"
-	"google.golang.org/grpc"
-
 	"strings"
+
+	"github.com/traPtitech/neoshowcase/pkg/domain/builder"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb"
+	"github.com/traPtitech/neoshowcase/pkg/interface/grpc"
 )
 
 const (
@@ -13,17 +14,17 @@ const (
 )
 
 type Config struct {
-	Mode    string           `mapstructure:"mode" yaml:"mode"`
-	Builder GRPCClientConfig `mapstructure:"builder" yaml:"builder"`
-	SSGen   GRPCClientConfig `mapstructure:"ssgen" yaml:"ssgen"`
-	DB      admindb.Config   `mapstructure:"db" yaml:"db"`
+	Mode    string                             `mapstructure:"mode" yaml:"mode"`
+	Builder grpc.BuilderServiceClientConfig    `mapstructure:"builder" yaml:"builder"`
+	SSGen   grpc.StaticSiteServiceClientConfig `mapstructure:"ssgen" yaml:"ssgen"`
+	DB      admindb.Config                     `mapstructure:"db" yaml:"db"`
 	HTTP    struct {
 		Debug bool `mapstructure:"debug" yaml:"debug"`
 		Port  int  `mapstructure:"port" yaml:"port"`
 	} `mapstructure:"http" yaml:"http"`
 	Image struct {
-		Registry   string `mapstructure:"registry" yaml:"registry"`
-		NamePrefix string `mapstructure:"namePrefix" yaml:"namePrefix"`
+		Registry   builder.DockerImageRegistryString   `mapstructure:"registry" yaml:"registry"`
+		NamePrefix builder.DockerImageNamePrefixString `mapstructure:"namePrefix" yaml:"namePrefix"`
 	} `mapstructure:"image" yaml:"image"`
 }
 
@@ -38,16 +39,10 @@ func (c *Config) GetMode() int {
 	}
 }
 
-type GRPCClientConfig struct {
-	Insecure bool   `mapstructure:"insecure" yaml:"insecure"`
-	Addr     string `mapstructure:"addr" yaml:"addr"`
+func provideImageRegistry(c Config) builder.DockerImageRegistryString {
+	return c.Image.Registry
 }
 
-func (c *GRPCClientConfig) Connect() (*grpc.ClientConn, error) {
-	var opts []grpc.DialOption
-	if c.Insecure {
-		opts = append(opts, grpc.WithInsecure())
-	}
-
-	return grpc.Dial(c.Addr, opts...)
+func provideImagePrefix(c Config) builder.DockerImageNamePrefixString {
+	return c.Image.NamePrefix
 }
diff --git a/cmd/ns/main.go b/cmd/ns/main.go
index 48fd6dfa..7dadd9a6 100644
--- a/cmd/ns/main.go
+++ b/cmd/ns/main.go
@@ -12,10 +12,9 @@ import (
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
-	"github.com/traPtitech/neoshowcase/pkg/cliutil"
-	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/web"
 	"github.com/traPtitech/neoshowcase/pkg/interface/handler"
+	"github.com/traPtitech/neoshowcase/pkg/util/cli"
 )
 
 var (
@@ -32,7 +31,7 @@ var rootCommand = &cobra.Command{
 	Use:              "ns",
 	Short:            "NeoShowcase Core API Server",
 	Version:          fmt.Sprintf("%s (%s)", version, revision),
-	PersistentPreRun: cliutil.PrintVersion,
+	PersistentPreRun: cli.PrintVersion,
 }
 
 func runCommand() *cobra.Command {
@@ -52,7 +51,7 @@ func runCommand() *cobra.Command {
 			}()
 
 			log.Info("NeoShowcase ApiServer started")
-			cliutil.WaitSIGINT()
+			cli.WaitSIGINT()
 			ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 			defer cancel()
 			return service.Shutdown(ctx)
@@ -63,17 +62,17 @@ func runCommand() *cobra.Command {
 
 func main() {
 	rand.Seed(time.Now().UnixNano())
-	cobra.OnInitialize(cliutil.CobraOnInitializeFunc(&configFilePath, "NS_APISERVER", &c))
+	cobra.OnInitialize(cli.CobraOnInitializeFunc(&configFilePath, "NS_APISERVER", &c))
 
 	rootCommand.AddCommand(
 		runCommand(),
-		cliutil.PrintConfCommand(&c),
+		cli.PrintConfCommand(&c),
 	)
 
 	flags := rootCommand.PersistentFlags()
 	flags.StringVarP(&configFilePath, "config", "c", "", "config file path")
-	cliutil.SetupDebugFlag(flags)
-	cliutil.SetupLogLevelFlag(flags)
+	cli.SetupDebugFlag(flags)
+	cli.SetupLogLevelFlag(flags)
 
 	viper.SetDefault("mode", "docker")
 	viper.SetDefault("image.registry", "")
@@ -117,7 +116,3 @@ func provideWebServerConfig(router web.Router) web.Config {
 		Router: router,
 	}
 }
-
-func provideAdminDBConfig() admindb.Config {
-	return c.DB
-}
\ No newline at end of file
diff --git a/cmd/ns/server.go b/cmd/ns/server.go
index a1c1137c..2420a25e 100644
--- a/cmd/ns/server.go
+++ b/cmd/ns/server.go
@@ -3,143 +3,30 @@ package main
 import (
 	"context"
 	"database/sql"
-	"fmt"
 
-	docker "github.com/fsouza/go-dockerclient"
-	log "github.com/sirupsen/logrus"
-	"github.com/traPtitech/neoshowcase/pkg/appmanager"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/backend"
-	"github.com/traPtitech/neoshowcase/pkg/infrastructure/backend/dockerimpl"
-	"github.com/traPtitech/neoshowcase/pkg/infrastructure/backend/k8simpl"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/eventbus"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/web"
-	"github.com/traPtitech/neoshowcase/pkg/interface/grpc/pb"
+	"github.com/traPtitech/neoshowcase/pkg/interface/broker"
+	"github.com/traPtitech/neoshowcase/pkg/interface/grpc"
+	"github.com/traPtitech/neoshowcase/pkg/usecase"
 	"golang.org/x/sync/errgroup"
-	"google.golang.org/grpc"
-	"k8s.io/client-go/kubernetes"
-	"k8s.io/client-go/rest"
 )
 
 type Server struct {
-	webserver  *web.Server
-	db         *sql.DB
-	bus        eventbus.Bus
-	appmanager appmanager.Manager
-
-	builderConn *grpc.ClientConn
-	ssgenConn   *grpc.ClientConn
-	backend     backend.Backend
-
-	k8sCSet *kubernetes.Clientset
-}
-
-func NewServer(c Config, webserver *web.Server, db *sql.DB, bus eventbus.Bus) (*Server, error) {
-	s := &Server{
-		webserver: webserver,
-		db:        db,
-		bus:       bus,
-	}
-
-	switch c.GetMode() {
-	case ModeDocker:
-		// Builderに接続
-		builderConn, err := c.Builder.Connect()
-		if err != nil {
-			return nil, fmt.Errorf("failed to connect builder service: %w", err)
-		}
-		s.builderConn = builderConn
-
-		// SSGenに接続
-		ssgenConn, err := c.SSGen.Connect()
-		if err != nil {
-			return nil, fmt.Errorf("failed to connect ssgen service: %w", err)
-		}
-		s.ssgenConn = ssgenConn
-
-		// Dockerデーモンに接続 (DooD)
-		dc, err := docker.NewClientFromEnv()
-		if err != nil {
-			return nil, fmt.Errorf("failed to create docker client: %w", err)
-		}
-
-		// コンテナマネージャー生成
-		connM, err := dockerimpl.NewDockerBackend(dc, s.bus)
-		if err != nil {
-			return nil, fmt.Errorf("failed to init container manager: %w", err)
-		}
-		s.backend = connM
-
-		// appmanger生成
-		am, err := appmanager.NewManager(appmanager.Config{
-			DB:              db,
-			Hub:             s.bus,
-			Builder:         pb.NewBuilderServiceClient(builderConn),
-			SS:              pb.NewStaticSiteServiceClient(ssgenConn),
-			Backend:         connM,
-			ImageRegistry:   c.Image.Registry,
-			ImageNamePrefix: c.Image.NamePrefix,
-		})
-		if err != nil {
-			return nil, fmt.Errorf("failed to init app manager: %w", err)
-		}
-		s.appmanager = am
-
-	case ModeK8s:
-		// Builderに接続
-		builderConn, err := c.Builder.Connect()
-		if err != nil {
-			return nil, fmt.Errorf("failed to connect builder service: %w", err)
-		}
-		s.builderConn = builderConn
-
-		// SSGenに接続
-		ssgenConn, err := c.SSGen.Connect()
-		if err != nil {
-			return nil, fmt.Errorf("failed to connect ssgen service: %w", err)
-		}
-		s.ssgenConn = ssgenConn
-
-		// k8s接続
-		kubeconf, err := rest.InClusterConfig()
-		if err != nil {
-			return nil, fmt.Errorf("failed to load kubeconfig: %w", err)
-		}
-		clientset, err := kubernetes.NewForConfig(kubeconf)
-		if err != nil {
-			return nil, fmt.Errorf("failed to create clientset: %w", err)
-		}
-		s.k8sCSet = clientset
-
-		// コンテナマネージャー生成
-		connM, err := k8simpl.NewK8SBackend(s.bus, clientset)
-		if err != nil {
-			return nil, fmt.Errorf("failed to init container manager: %w", err)
-		}
-		s.backend = connM
-
-		// appmanger生成
-		am, err := appmanager.NewManager(appmanager.Config{
-			DB:              db,
-			Hub:             s.bus,
-			Builder:         pb.NewBuilderServiceClient(builderConn),
-			SS:              pb.NewStaticSiteServiceClient(ssgenConn),
-			Backend:         connM,
-			ImageRegistry:   c.Image.Registry,
-			ImageNamePrefix: c.Image.NamePrefix,
-		})
-		if err != nil {
-			return nil, fmt.Errorf("failed to init app manager: %w", err)
-		}
-		s.appmanager = am
-
-	default:
-		log.Fatalf("unknown mode: %s", c.Mode)
-	}
-
-	return s, nil
+	webserver           *web.Server
+	db                  *sql.DB
+	builderConn         *grpc.BuilderServiceClientConn
+	ssgenConn           *grpc.StaticSiteServiceClientConn
+	backend             backend.Backend
+	bus                 eventbus.Bus
+	builderEventsBroker broker.BuilderEventsBroker
+	cdService           usecase.ContinuousDeploymentService
 }
 
 func (s *Server) Start(ctx context.Context) error {
+	go s.builderEventsBroker.Run()
+	go s.cdService.Run()
 	return s.webserver.Start(ctx)
 }
 
@@ -162,10 +49,10 @@ func (s *Server) Shutdown(ctx context.Context) error {
 		return s.backend.Dispose(ctx)
 	})
 	eg.Go(func() error {
-		return s.appmanager.Shutdown(ctx)
+		return s.bus.Close(ctx)
 	})
 	eg.Go(func() error {
-		return s.bus.Close(ctx)
+		return s.cdService.Stop(ctx)
 	})
 
 	return eg.Wait()
diff --git a/cmd/ns/wire.go b/cmd/ns/wire.go
index a88241b2..b55cffc3 100644
--- a/cmd/ns/wire.go
+++ b/cmd/ns/wire.go
@@ -3,29 +3,77 @@
 package main
 
 import (
+	"fmt"
+
+	docker "github.com/fsouza/go-dockerclient"
 	"github.com/google/wire"
 	"github.com/leandro-lugaresi/hub"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/backend/dockerimpl"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/backend/k8simpl"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/eventbus"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/web"
+	"github.com/traPtitech/neoshowcase/pkg/interface/broker"
+	"github.com/traPtitech/neoshowcase/pkg/interface/grpc"
 	"github.com/traPtitech/neoshowcase/pkg/interface/repository"
 	"github.com/traPtitech/neoshowcase/pkg/usecase"
+	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/rest"
+)
+
+var commonSet = wire.NewSet(
+	web.NewServer,
+	usecase.NewGitPushWebhookService,
+	usecase.NewAppBuildService,
+	usecase.NewAppDeployService,
+	usecase.NewContinuousDeploymentService,
+	repository.NewWebhookSecretRepository,
+	repository.NewApplicationRepository,
+	broker.NewBuilderEventsBroker,
+	eventbus.NewLocal,
+	admindb.New,
+	handlerSet,
+	provideWebServerConfig,
+	provideImagePrefix,
+	provideImageRegistry,
+	hub.New,
+	grpc.NewBuilderServiceClientConn,
+	grpc.NewStaticSiteServiceClientConn,
+	grpc.NewBuilderServiceClient,
+	grpc.NewStaticSiteServiceClient,
+	wire.FieldsOf(new(Config), "Builder", "SSGen", "DB"),
+	wire.Struct(new(Router), "*"),
+	wire.Bind(new(web.Router), new(*Router)),
+	wire.Struct(new(Server), "*"),
 )
 
 func New(c Config) (*Server, error) {
+	switch c.GetMode() {
+	case ModeDocker:
+		return NewWithDocker(c)
+	case ModeK8s:
+		return NewWithK8S(c)
+	default:
+		return nil, fmt.Errorf("unknown mode: %s", c.Mode)
+	}
+}
+
+func NewWithDocker(c Config) (*Server, error) {
+	wire.Build(
+		commonSet,
+		docker.NewClientFromEnv,
+		dockerimpl.NewDockerBackend,
+		wire.Value(dockerimpl.IngressConfDirPath("/opt/traefik/conf")),
+	)
+	return nil, nil
+}
+
+func NewWithK8S(c Config) (*Server, error) {
 	wire.Build(
-		NewServer,
-		web.NewServer,
-		usecase.NewGitPushWebhookService,
-		repository.NewWebhookSecretRepository,
-		eventbus.NewLocal,
-		admindb.New,
-		handlerSet,
-		provideAdminDBConfig,
-		provideWebServerConfig,
-		hub.New,
-		wire.Struct(new(Router), "*"),
-		wire.Bind(new(web.Router), new(*Router)),
+		commonSet,
+		rest.InClusterConfig,
+		kubernetes.NewForConfig,
+		k8simpl.NewK8SBackend,
 	)
 	return nil, nil
 }
diff --git a/cmd/ns/wire_gen.go b/cmd/ns/wire_gen.go
index 1050b111..51866e45 100644
--- a/cmd/ns/wire_gen.go
+++ b/cmd/ns/wire_gen.go
@@ -6,13 +6,22 @@
 package main
 
 import (
+	"fmt"
+	"github.com/fsouza/go-dockerclient"
+	"github.com/google/wire"
 	"github.com/leandro-lugaresi/hub"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/backend/dockerimpl"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/backend/k8simpl"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/eventbus"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/web"
+	"github.com/traPtitech/neoshowcase/pkg/interface/broker"
+	"github.com/traPtitech/neoshowcase/pkg/interface/grpc"
 	"github.com/traPtitech/neoshowcase/pkg/interface/handler"
 	"github.com/traPtitech/neoshowcase/pkg/interface/repository"
 	"github.com/traPtitech/neoshowcase/pkg/usecase"
+	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/rest"
 )
 
 import (
@@ -21,10 +30,10 @@ import (
 
 // Injectors from wire.go:
 
-func New(c2 Config) (*Server, error) {
+func NewWithDocker(c2 Config) (*Server, error) {
 	hubHub := hub.New()
 	bus := eventbus.NewLocal(hubHub)
-	config := provideAdminDBConfig()
+	config := c2.DB
 	db, err := admindb.New(config)
 	if err != nil {
 		return nil, err
@@ -37,9 +46,132 @@ func New(c2 Config) (*Server, error) {
 	}
 	webConfig := provideWebServerConfig(router)
 	server := web.NewServer(webConfig)
-	mainServer, err := NewServer(c2, server, db, bus)
+	builderServiceClientConfig := c2.Builder
+	builderServiceClientConn, err := grpc.NewBuilderServiceClientConn(builderServiceClientConfig)
+	if err != nil {
+		return nil, err
+	}
+	staticSiteServiceClientConfig := c2.SSGen
+	staticSiteServiceClientConn, err := grpc.NewStaticSiteServiceClientConn(staticSiteServiceClientConfig)
 	if err != nil {
 		return nil, err
 	}
+	client, err := docker.NewClientFromEnv()
+	if err != nil {
+		return nil, err
+	}
+	ingressConfDirPath := _wireIngressConfDirPathValue
+	backend, err := dockerimpl.NewDockerBackend(client, bus, ingressConfDirPath)
+	if err != nil {
+		return nil, err
+	}
+	builderServiceClient := grpc.NewBuilderServiceClient(builderServiceClientConn)
+	builderEventsBroker, err := broker.NewBuilderEventsBroker(builderServiceClient, bus)
+	if err != nil {
+		return nil, err
+	}
+	applicationRepository := repository.NewApplicationRepository(db)
+	staticSiteServiceClient := grpc.NewStaticSiteServiceClient(staticSiteServiceClientConn)
+	dockerImageRegistryString := provideImageRegistry(c2)
+	dockerImageNamePrefixString := provideImagePrefix(c2)
+	appDeployService := usecase.NewAppDeployService(backend, staticSiteServiceClient, dockerImageRegistryString, dockerImageNamePrefixString, db)
+	appBuildService := usecase.NewAppBuildService(applicationRepository, builderServiceClient, dockerImageRegistryString, dockerImageNamePrefixString)
+	continuousDeploymentService := usecase.NewContinuousDeploymentService(bus, applicationRepository, appDeployService, appBuildService)
+	mainServer := &Server{
+		webserver:           server,
+		db:                  db,
+		builderConn:         builderServiceClientConn,
+		ssgenConn:           staticSiteServiceClientConn,
+		backend:             backend,
+		bus:                 bus,
+		builderEventsBroker: builderEventsBroker,
+		cdService:           continuousDeploymentService,
+	}
 	return mainServer, nil
 }
+
+var (
+	_wireIngressConfDirPathValue = dockerimpl.IngressConfDirPath("/opt/traefik/conf")
+)
+
+func NewWithK8S(c2 Config) (*Server, error) {
+	hubHub := hub.New()
+	bus := eventbus.NewLocal(hubHub)
+	config := c2.DB
+	db, err := admindb.New(config)
+	if err != nil {
+		return nil, err
+	}
+	webhookSecretRepository := repository.NewWebhookSecretRepository(db)
+	gitPushWebhookService := usecase.NewGitPushWebhookService(webhookSecretRepository)
+	webhookReceiverHandler := handler.NewWebhookReceiverHandler(bus, gitPushWebhookService)
+	router := &Router{
+		wr: webhookReceiverHandler,
+	}
+	webConfig := provideWebServerConfig(router)
+	server := web.NewServer(webConfig)
+	builderServiceClientConfig := c2.Builder
+	builderServiceClientConn, err := grpc.NewBuilderServiceClientConn(builderServiceClientConfig)
+	if err != nil {
+		return nil, err
+	}
+	staticSiteServiceClientConfig := c2.SSGen
+	staticSiteServiceClientConn, err := grpc.NewStaticSiteServiceClientConn(staticSiteServiceClientConfig)
+	if err != nil {
+		return nil, err
+	}
+	restConfig, err := rest.InClusterConfig()
+	if err != nil {
+		return nil, err
+	}
+	clientset, err := kubernetes.NewForConfig(restConfig)
+	if err != nil {
+		return nil, err
+	}
+	backend, err := k8simpl.NewK8SBackend(bus, clientset)
+	if err != nil {
+		return nil, err
+	}
+	builderServiceClient := grpc.NewBuilderServiceClient(builderServiceClientConn)
+	builderEventsBroker, err := broker.NewBuilderEventsBroker(builderServiceClient, bus)
+	if err != nil {
+		return nil, err
+	}
+	applicationRepository := repository.NewApplicationRepository(db)
+	staticSiteServiceClient := grpc.NewStaticSiteServiceClient(staticSiteServiceClientConn)
+	dockerImageRegistryString := provideImageRegistry(c2)
+	dockerImageNamePrefixString := provideImagePrefix(c2)
+	appDeployService := usecase.NewAppDeployService(backend, staticSiteServiceClient, dockerImageRegistryString, dockerImageNamePrefixString, db)
+	appBuildService := usecase.NewAppBuildService(applicationRepository, builderServiceClient, dockerImageRegistryString, dockerImageNamePrefixString)
+	continuousDeploymentService := usecase.NewContinuousDeploymentService(bus, applicationRepository, appDeployService, appBuildService)
+	mainServer := &Server{
+		webserver:           server,
+		db:                  db,
+		builderConn:         builderServiceClientConn,
+		ssgenConn:           staticSiteServiceClientConn,
+		backend:             backend,
+		bus:                 bus,
+		builderEventsBroker: builderEventsBroker,
+		cdService:           continuousDeploymentService,
+	}
+	return mainServer, nil
+}
+
+// wire.go:
+
+var commonSet = wire.NewSet(web.NewServer, usecase.NewGitPushWebhookService, usecase.NewAppBuildService, usecase.NewAppDeployService, usecase.NewContinuousDeploymentService, repository.NewWebhookSecretRepository, repository.NewApplicationRepository, broker.NewBuilderEventsBroker, eventbus.NewLocal, admindb.New, handlerSet,
+	provideWebServerConfig,
+	provideImagePrefix,
+	provideImageRegistry, hub.New, grpc.NewBuilderServiceClientConn, grpc.NewStaticSiteServiceClientConn, grpc.NewBuilderServiceClient, grpc.NewStaticSiteServiceClient, wire.FieldsOf(new(Config), "Builder", "SSGen", "DB"), wire.Struct(new(Router), "*"), wire.Bind(new(web.Router), new(*Router)), wire.Struct(new(Server), "*"),
+)
+
+func New(c2 Config) (*Server, error) {
+	switch c2.GetMode() {
+	case ModeDocker:
+		return NewWithDocker(c2)
+	case ModeK8s:
+		return NewWithK8S(c2)
+	default:
+		return nil, fmt.Errorf("unknown mode: %s", c2.Mode)
+	}
+}
diff --git a/docker-compose.yaml b/docker-compose.yaml
index b3a5808d..89e68fa5 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -5,8 +5,7 @@ services:
     build:
       context: .
       target: ns
-    entrypoint: dockerize -timeout 60s -wait tcp://mysql:3306 -wait tcp://ns-builder:10000 -wait tcp://ns-ssgen:10000
-    command: /app/ns run --debug --loglevel=trace
+    command: run --debug --loglevel=trace
     restart: always
     environment:
       NS_APISERVER_DB_HOST: "mysql"
@@ -20,6 +19,7 @@ services:
     volumes:
       - /var/run/docker.sock:/var/run/docker.sock
       - ./local-dev/neoshowcase:/data
+      - ./local-dev/traefik:/opt/traefik/conf
     labels:
       - "traefik.enable=true"
       - "traefik.http.routers.ns_admin.rule=Host(`local.wtks.work`)"
@@ -43,8 +43,7 @@ services:
     build:
       context: .
       target: ns-builder
-    entrypoint: dockerize -timeout 60s -wait tcp://mysql:3306 -wait tcp://buildkitd:1234
-    command: /app/ns-builder run --debug --loglevel=trace
+    command: run --debug --loglevel=trace
     restart: always
     environment:
       NS_BUILDER_BUILDKIT_ADDRESS: "tcp://buildkitd:1234"
@@ -65,8 +64,7 @@ services:
     build:
       context: .
       target: ns-ssgen
-    entrypoint: dockerize -timeout 60s -wait tcp://mysql:3306
-    command: /app/ns-ssgen run --debug --loglevel=trace
+    command: run --debug --loglevel=trace
     restart: always
     environment:
       NS_SSGEN_DB_HOST: "mysql"
@@ -79,10 +77,6 @@ services:
       - "5008:80"
     depends_on:
       - mysql
-    labels:
-      - "traefik.enable=true"
-      - "traefik.http.routers.ss.rule=PathPrefix(`/`)"
-      - "traefik.http.services.ss.loadbalancer.server.port=80"
     networks:
       - default
 
@@ -171,31 +165,22 @@ services:
   traefik:
     image: traefik:v2.3
     restart: always
-    command: --api.insecure=true --providers.docker --providers.docker.exposedByDefault=false
+    command:
+      - --api.insecure=true
+      - --providers.docker
+      - --providers.docker.exposedByDefault=false
+      - --providers.file
+      - --providers.file.directory=/opt/neoshowcase/conf
     ports:
       - "8888:80"
       - "8080:8080"
     volumes:
       - /var/run/docker.sock:/var/run/docker.sock
+      - ./local-dev/traefik:/opt/neoshowcase/conf
     networks:
       - default
       - apps
 
-  swagger-ui:
-    image: swaggerapi/swagger-ui
-    volumes:
-      - ./api/http/swagger.yaml:/swagger.yaml
-    environment:
-      SWAGGER_JSON: /swagger.yaml
-    labels:
-      - "traefik.enable=true"
-      - "traefik.http.routers.ns_swagger.rule=Host(`swagger.local.wtks.work`)"
-      - "traefik.http.services.ns_swagger.loadbalancer.server.port=8080"
-    depends_on:
-      - mysql
-    networks:
-      - default
-
 networks:
   default: { }
   apps: { }
diff --git a/go.mod b/go.mod
index 7f87449a..1af7b0bc 100644
--- a/go.mod
+++ b/go.mod
@@ -11,20 +11,17 @@ require (
 	github.com/gavv/httpexpect/v2 v2.2.0
 	github.com/go-git/go-git/v5 v5.3.0
 	github.com/go-sql-driver/mysql v1.5.0
-	github.com/golang/mock v1.5.0 // indirect
-	github.com/golang/protobuf v1.5.2
+	github.com/golang/mock v1.5.0
+	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/google/wire v0.5.0
 	github.com/kat-co/vala v0.0.0-20170210184112-42e1d8b61f12
+	github.com/ktr0731/evans v0.9.3
 	github.com/labstack/echo/v4 v4.2.2
 	github.com/leandro-lugaresi/hub v1.1.1
-	github.com/magiconair/properties v1.8.4 // indirect
-	github.com/mitchellh/mapstructure v1.3.3 // indirect
 	github.com/moby/buildkit v0.8.3
 	github.com/ncw/swift v1.0.53
-	github.com/pelletier/go-toml v1.8.1 // indirect
 	github.com/rubenv/sql-migrate v0.0.0-20210408115534-a32ed26c37ea
 	github.com/sirupsen/logrus v1.8.1
-	github.com/spf13/afero v1.4.0 // indirect
 	github.com/spf13/cobra v1.1.3
 	github.com/spf13/pflag v1.0.5
 	github.com/spf13/viper v1.7.1
@@ -36,10 +33,9 @@ require (
 	github.com/ziutek/mymysql v1.5.4 // indirect
 	go.mongodb.org/mongo-driver v1.5.1
 	golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
-	google.golang.org/genproto v0.0.0-20201008135153-289734e2e40c // indirect
 	google.golang.org/grpc v1.35.0
+	google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0
 	google.golang.org/protobuf v1.26.0
-	gopkg.in/ini.v1 v1.61.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0
 	k8s.io/api v0.20.4
 	k8s.io/apimachinery v0.20.4
diff --git a/go.sum b/go.sum
index 51f2027c..42d55592 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,4 @@
+4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo=
 bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
 bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
 cloud.google.com/go v0.25.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
@@ -19,44 +20,66 @@ cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6
 cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
 cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
 cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
+cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
+cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
+cloud.google.com/go v0.66.0/go.mod h1:dgqGAjKCDxyhGTtC9dAREQGUJpkceNm1yt590Qno0Ko=
+cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
 cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
 cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
 cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
 cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
 cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
+cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
 cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
+cloud.google.com/go/firestore v1.4.0/go.mod h1:NjjGEnxCS3CAKYp+vmALu20QzcqasGodQp48WxJGAYc=
 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
 cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
 cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
 cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
+cloud.google.com/go/pubsub v1.9.0/go.mod h1:G3o6/kJvEMIEAN5urdkaP4be49WQsjNiykBIto9LFtY=
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
 cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
 cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
 cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
+cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
+cloud.google.com/go/storage v1.12.0/go.mod h1:fFLk2dp2oAhDz8QFKwqrjdJvxSp/W2g7nillojlL5Ho=
 code.gitea.io/sdk/gitea v0.12.0/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY=
+code.gitea.io/sdk/gitea v0.13.2/go.mod h1:lee2y8LeV3kQb2iK+hHlMqoadL4bp27QOkOV/hawLKg=
 contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=
+contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=
 contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0=
 contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw=
+contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
 contrib.go.opencensus.io/integrations/ocsql v0.1.4/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE=
+contrib.go.opencensus.io/integrations/ocsql v0.1.7/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE=
 contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
 git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
 github.com/AkihiroSuda/containerd-fuse-overlayfs v1.0.0/go.mod h1:0mMDvQFeLbbn1Wy8P2j3hwFhqBq+FKn8OZPno8WLmp8=
 github.com/Azure/azure-amqp-common-go/v2 v2.1.0/go.mod h1:R8rea+gJRuJR6QxTir/XuEd+YuKoUiazDC/N96FiDEU=
+github.com/Azure/azure-amqp-common-go/v3 v3.0.1/go.mod h1:PBIGdzcO1teYoufTKMcGibdKaYZv4avS+O6LNIp8bq0=
+github.com/Azure/azure-amqp-common-go/v3 v3.1.0/go.mod h1:PBIGdzcO1teYoufTKMcGibdKaYZv4avS+O6LNIp8bq0=
 github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
 github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
+github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k=
 github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
 github.com/Azure/azure-sdk-for-go v19.1.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
 github.com/Azure/azure-sdk-for-go v29.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
 github.com/Azure/azure-sdk-for-go v30.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
 github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
+github.com/Azure/azure-sdk-for-go v37.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
 github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
 github.com/Azure/azure-sdk-for-go v42.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
+github.com/Azure/azure-sdk-for-go v49.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
 github.com/Azure/azure-service-bus-go v0.9.1/go.mod h1:yzBx6/BUGfjfeqbRZny9AQIbIe3AcV9WZbAdpkoXOa0=
+github.com/Azure/azure-service-bus-go v0.10.7/go.mod h1:o5z/3lDG1iT/T/G7vgIwIqVDTx9Qa2wndf5OdzSzpF8=
 github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0=
+github.com/Azure/azure-storage-blob-go v0.11.0/go.mod h1:A0u4VjtpgZJ7Y7um/+ix2DHBuEKFC6sEIlj0xc13a4Q=
+github.com/Azure/go-amqp v0.13.0/go.mod h1:qj+o8xPCz9tMSbQ83Vp8boHahuRDl5mkNHyt1xlxUTs=
+github.com/Azure/go-amqp v0.13.1/go.mod h1:qj+o8xPCz9tMSbQ83Vp8boHahuRDl5mkNHyt1xlxUTs=
 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=
 github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
@@ -69,15 +92,24 @@ github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8
 github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
 github.com/Azure/go-autorest/autorest v0.10.2/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
 github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
+github.com/Azure/go-autorest/autorest v0.11.3/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
+github.com/Azure/go-autorest/autorest v0.11.7/go.mod h1:V6p3pKZx1KKkJubbxnDWrzNhEIfOy/pTGasLqzHIPHs=
+github.com/Azure/go-autorest/autorest v0.11.9/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
+github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
 github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
 github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
 github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
 github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
 github.com/Azure/go-autorest/autorest/adal v0.8.3/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
 github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
+github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE=
+github.com/Azure/go-autorest/autorest/adal v0.9.4/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE=
 github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
+github.com/Azure/go-autorest/autorest/adal v0.9.6/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
 github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM=
+github.com/Azure/go-autorest/autorest/azure/auth v0.5.3/go.mod h1:4bJZhUhcq8LB20TruwHbAQsmUs2Xh+QR7utuJpLXX3A=
 github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw=
+github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM=
 github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
 github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
 github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
@@ -88,8 +120,10 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935
 github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
 github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc=
 github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
+github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
 github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
 github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI=
+github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E=
 github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
 github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
 github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
@@ -99,13 +133,16 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
 github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1MRDJM=
 github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
 github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
+github.com/Djarvur/go-err113 v0.0.0-20200511133814-5174e21577d5/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
 github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
 github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20191009163259-e802c2cb94ae/go.mod h1:mjwGPas4yKduTyubHvD1Atl9r1rUq8DfVy+gkVvZ+oo=
+github.com/GoogleCloudPlatform/cloudsql-proxy v1.19.1/go.mod h1:+yYmuKqcBVkgRePGpUhTA9OEg0XsnFE96eZ6nJ2yCQM=
 github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190822182118-27a4ced34534/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14=
 github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
 github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
 github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
 github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
+github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
 github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
 github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
 github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
@@ -140,12 +177,16 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
 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-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
+github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
+github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
 github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
 github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
 github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 github.com/apex/log v1.1.4/go.mod h1:AlpoD9aScyQfJDVHmLMEcx4oU6LqzkWp4Mg9GdAcEvQ=
 github.com/apex/log v1.3.0/go.mod h1:jd8Vpsr46WAe3EZSQ/IUMs2qQD/GOycT5rPWCO1yGcs=
+github.com/apex/log v1.9.0/go.mod h1:m82fZlWIuiWzWP04XCTXmnX0xRkYYbCdYn8jbJeLBEA=
 github.com/apex/logs v0.0.4/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo=
+github.com/apex/logs v1.0.0/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo=
 github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE=
 github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys=
 github.com/apmckinlay/gsuneido v0.0.0-20180907175622-1f10244968e3/go.mod h1:hJnaqxrCRgMCTWtpNz9XUFkBCREiQdlcyK6YNmOfroM=
@@ -156,6 +197,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/ashanbrown/forbidigo v1.0.0/go.mod h1:PH+zMRWE15yW69fYfe7Kn8nYR6yYyafc3ntEGh2BBAg=
+github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU=
 github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
 github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
 github.com/aws/aws-sdk-go v1.15.90/go.mod h1:es1KtYUFs7le0xQ3rOihkuoVD90z7D0fR2Qm4S00/gU=
@@ -163,10 +206,12 @@ github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpi
 github.com/aws/aws-sdk-go v1.19.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
 github.com/aws/aws-sdk-go v1.19.45/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
 github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
 github.com/aws/aws-sdk-go v1.25.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
 github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
 github.com/aws/aws-sdk-go v1.31.6/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
 github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
+github.com/aws/aws-sdk-go v1.36.1/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
 github.com/aws/aws-sdk-go v1.38.30 h1:X+JDSwkpSQfoLqH4fBLmS0rou8W/cdCCCD5lntTk9Vs=
 github.com/aws/aws-sdk-go v1.38.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
 github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
@@ -194,15 +239,20 @@ github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMS
 github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A=
 github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
+github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
 github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 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/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
 github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
@@ -260,19 +310,24 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
 github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
 github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
+github.com/daixiang0/gci v0.2.7/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc=
+github.com/daixiang0/gci v0.2.8/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc=
 github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA=
 github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
 github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
 github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
+github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
 github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY=
 github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
 github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
+github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
 github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
 github.com/docker/cli v0.0.0-20190925022749-754388324470/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
@@ -321,15 +376,19 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
 github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/ericlagergren/decimal v0.0.0-20181231230500-73749d4874d5/go.mod h1:1yj25TwtUlJ+pfOu9apAVaM1RWfZGg+aFpd4hPQZekQ=
+github.com/esimonov/ifshort v1.0.0/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE=
 github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/fasthttp/websocket v1.4.2 h1:AU/zSiIIAuJjBMf5o+vO0syGOnEfvZRu40xIhW/3RuM=
 github.com/fasthttp/websocket v1.4.2/go.mod h1:smsv/h4PBEBaU0XDTY5UwJTpZv69fQ0FfcLJr21mA6Y=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
+github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
+github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
 github.com/fatih/structs v1.0.0 h1:BrX964Rv5uQ3wwS+KRUAJCBBw5PQmgJfJ6v4yly5QwU=
 github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -348,11 +407,15 @@ github.com/gavv/httpexpect/v2 v2.2.0 h1:0VwaEBmQaNFHX9x591A8Up+8shCwdF/nF0qlRd/n
 github.com/gavv/httpexpect/v2 v2.2.0/go.mod h1:lnd0TqJLrP+wkJk3SFwtrpSlOAZQ7HaaIFuOYbgqgUM=
 github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
 github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
 github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
 github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
 github.com/go-critic/go-critic v0.4.1/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g=
 github.com/go-critic/go-critic v0.4.3/go.mod h1:j4O3D4RoIwRqlZw5jJpx0BNfXWWbpcJoKu5cYSe4YmQ=
+github.com/go-critic/go-critic v0.5.2/go.mod h1:cc0+HvdE3lFpqLecgqMaJcvWWH77sLdBp+wLGPM1Yyo=
+github.com/go-critic/go-critic v0.5.3/go.mod h1:2Lrs1m4jtOnnG/EdezbSpAoL0F2pRW+9HWJUZ+QaktY=
 github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
 github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
 github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
@@ -360,6 +423,7 @@ github.com/go-git/go-billy/v5 v5.1.0 h1:4pl5BV4o7ZG/lterP4S6WzJ6xr49Ba5ET9ygheTY
 github.com/go-git/go-billy/v5 v5.1.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
 github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M=
 github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
+github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs=
 github.com/go-git/go-git/v5 v5.3.0 h1:8WKMtJR2j8RntEXR/uvTKagfEt4GYlwQ7mntE4+0GWc=
 github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@@ -387,6 +451,10 @@ github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8
 github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
 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-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
+github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
 github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
@@ -439,12 +507,16 @@ github.com/gobuffalo/packr/v2 v2.8.1 h1:tkQpju6i3EtMXJ9uoF5GT6kB+LMTimDWD8Xvbz6z
 github.com/gobuffalo/packr/v2 v2.8.1/go.mod h1:c/PLlOuTU+p3SybaJATW3H6lX/iK7xEz5OeMf+NnJpg=
 github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
 github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
+github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
+github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
+github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
 github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
 github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE=
 github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
-github.com/gofrs/flock v0.7.3 h1:I0EKY9l8HZCXTMYC4F80vwT6KNypV9uYKP3Alm/hjmQ=
 github.com/gofrs/flock v0.7.3/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
+github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY=
+github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
 github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
 github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
@@ -472,6 +544,7 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU
 github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
 github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
 github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
 github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
 github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
 github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -505,6 +578,9 @@ github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d/go.mod h1:ozx7R9S
 github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU=
 github.com/golangci/golangci-lint v1.23.7/go.mod h1:g/38bxfhp4rI7zeWSxcdIeHTQGS58TCak8FYcyCmavQ=
 github.com/golangci/golangci-lint v1.27.0/go.mod h1:+eZALfxIuthdrHPtfM7w/R3POJLjHDfJJw8XZl9xOng=
+github.com/golangci/golangci-lint v1.34.1/go.mod h1:6Bnn7T0JYin7uukitgL6f9E9auQatlT0RMNOKG9lSHU=
+github.com/golangci/golangci-lint v1.35.2/go.mod h1:Sg5fFp5oLLI1B8gXfUVUSePju8XF0uWefMkuZuGIHUo=
+github.com/golangci/golangci-lint v1.36.0/go.mod h1:SZhIZhUXXT/OcDb9rymj0J21mOVikjj51zunqnXM34Y=
 github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU=
 github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=
 github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=
@@ -524,17 +600,23 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.1/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/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/go-containerregistry v0.0.0-20191010200024-a3d713f9b7f8/go.mod h1:KyKXa9ciM8+lgMXwOVsXi7UxGrsf9mM61Mzs+xKUrKE=
 github.com/google/go-containerregistry v0.1.2/go.mod h1:GPivBPgdAyd2SU+vf6EpsgOtWDuPqjW0hJZt4rNdTZ4=
+github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
 github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
 github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
 github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
 github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
 github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE=
+github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE=
 github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no=
+github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no=
 github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
 github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -542,14 +624,20 @@ github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
 github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
 github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
 github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
 github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
 github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg=
+github.com/google/rpmpack v0.0.0-20201225075926-0a97c2c4b688/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk=
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
 github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k=
@@ -571,12 +659,18 @@ github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTV
 github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I=
 github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
 github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg=
+github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ=
+github.com/gookit/color v1.3.6/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ=
 github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/goreleaser/chglog v0.1.2/go.mod h1:tTZsFuSZK4epDXfjMkxzcGbrIOXprf0JFp47BjIr3B8=
+github.com/goreleaser/fileglob v0.3.1/go.mod h1:kNcPrPzjCp+Ox3jmXLU5QEsjhqrtLBm6OnXAif8KRl8=
 github.com/goreleaser/goreleaser v0.136.0/go.mod h1:wiKrPUeSNh6Wu8nUHxZydSOVQ/OZvOaO7DTtFqie904=
+github.com/goreleaser/goreleaser v0.155.0/go.mod h1:2zpmKlkp5Qd0U/7mqKrqbW4fg5ylKUBqNKKskUDJ8+w=
 github.com/goreleaser/nfpm v1.2.1/go.mod h1:TtWrABZozuLOttX2uDlYyECfQX7x5XYkVxhjYcR6G9w=
 github.com/goreleaser/nfpm v1.3.0/go.mod h1:w0p7Kc9TAUgWMyrub63ex3M2Mgw88M4GZXoTq5UCb40=
+github.com/goreleaser/nfpm/v2 v2.2.2/go.mod h1:WtPzYQh+Ls57prS9RzXegrGejqILUS1aZibXHTTJ8eI=
 github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
 github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
 github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
@@ -586,10 +680,16 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7
 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
 github.com/gorilla/websocket v1.0.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
 github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
+github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw=
+github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0=
+github.com/gostaticanalysis/analysisutil v0.6.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0=
+github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI=
+github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=
 github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
 github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
 github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
@@ -610,6 +710,7 @@ github.com/hanwen/go-fuse/v2 v2.0.3/go.mod h1:0EQM6aH2ctVpvZ6a+onrQ/vaykxh2GH7hy
 github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
 github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
 github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
 github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
@@ -617,6 +718,8 @@ github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh
 github.com/hashicorp/go-msgpack v0.5.3/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/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-retryablehttp v0.6.4/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
 github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
 github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
@@ -624,7 +727,11 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX
 github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
 github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
 github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
+github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -636,10 +743,10 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m
 github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
 github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
 github.com/hashicorp/uuid v0.0.0-20160311170451-ebb0a03e909c/go.mod h1:fHzc09UnyJyqyW+bFuq864eh+wC7dj65aXmXLRe5to0=
-github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
 github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
 github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
@@ -648,14 +755,22 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
 github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
 github.com/imkira/go-interpol v1.0.0 h1:HrmLyvOLJyjR0YofMw8QGdCIuYOs4TJUBDNU5sJC09E=
 github.com/imkira/go-interpol v1.0.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
+github.com/improbable-eng/grpc-web v0.12.0/go.mod h1:6hRR09jOEG81ADP5wCQju1z71g6OL4eEvELdran/3cs=
+github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8=
+github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
 github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
 github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
+github.com/jarcoal/httpmock v1.0.7/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
 github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
+github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
 github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
+github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
+github.com/jhump/protoreflect v1.5.1-0.20191024213132-10815c273d3f h1:/3LGRkPUNMBo1CxyZ9+AkXGXvPagj2QS/owPN0VlagA=
+github.com/jhump/protoreflect v1.5.1-0.20191024213132-10815c273d3f/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
 github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s=
 github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
 github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
@@ -667,6 +782,7 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
 github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
+github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
 github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
 github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
 github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
@@ -684,25 +800,36 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
+github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM=
 github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
+github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40=
+github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
 github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
 github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
 github.com/karrick/godirwalk v1.15.8 h1:7+rWAZPn9zuRxaIqqT8Ohs2Q2Ac0msBqwRdxNCr2VVs=
 github.com/karrick/godirwalk v1.15.8/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
 github.com/kat-co/vala v0.0.0-20170210184112-42e1d8b61f12 h1:DQVOxR9qdYEybJUr/c7ku34r3PfajaMYXZwgDM7KuSk=
 github.com/kat-co/vala v0.0.0-20170210184112-42e1d8b61f12/go.mod h1:u9MdXq/QageOOSGp7qG4XAQsYUMP+V5zEel/Vrl6OOc=
+github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
 github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
 github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/godepgraph v0.0.0-20190626013829-57a7e4a651a9/go.mod h1:Gb5YEgxqiSSVrXKWQxDcKoCM94NO5QAwOwTaVmIUAMI=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
-github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M=
 github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.3 h1:dB4Bn0tN3wdCzQxnS8r06kV74qN/TAfaIS0bVE8h3jc=
+github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
@@ -723,20 +850,49 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/ktr0731/bump v0.1.0/go.mod h1:RaAnwhvNY1dzTpF3ptJA7Z9EBW8OuVYOGXBcr7iRcgg=
+github.com/ktr0731/dept v0.1.1/go.mod h1:RTx3aP/gE0/MNhYgOcxETTNBudO24Nbis4y4KImynVA=
+github.com/ktr0731/dept v0.1.3/go.mod h1:b1EtCEjbjGShAfhZue+BrFKTG7sQmK7aSD7Q6VcGvO0=
+github.com/ktr0731/evans v0.9.3 h1:xO43QTSF/Jr3VpHC3lHGYsp1jvl3plAFx4RsZ9hILV8=
+github.com/ktr0731/evans v0.9.3/go.mod h1:lSIYB4f8STMtLa/x5q+qOrCG5mO+0kTZC0sB1UZHDZY=
+github.com/ktr0731/go-multierror v0.0.0-20171204182908-b7773ae21874 h1:eVBpZQfZSR9LO3CGKsUToWuGFw55oFISeI7wFNBS1xU=
+github.com/ktr0731/go-multierror v0.0.0-20171204182908-b7773ae21874/go.mod h1:ZWayuE/hCzOD96CJizvcYnqrbmTC7RAG332yNtlKj6w=
+github.com/ktr0731/go-prompt v0.2.2-0.20190609072126-7894cc3f2925 h1:nV9LIfb0tEvCAFjH8knSY5+1/OB7Vtxz0+VAR2BWcno=
+github.com/ktr0731/go-prompt v0.2.2-0.20190609072126-7894cc3f2925/go.mod h1:wmOS5scuWlKkbJFD0l2d/Uc6M8h01Zw4y1lPpzYerhc=
+github.com/ktr0731/go-semver v0.1.1/go.mod h1:gE6cyNMdgKcUY/d9tdlZDqiLYPixpJcZh3addTcQSp4=
+github.com/ktr0731/go-shellstring v0.1.3 h1:PH3Y2SHbdBF5G9+XrRlT3Dpgl/2CzQHIqFOOBz6Nco8=
+github.com/ktr0731/go-shellstring v0.1.3/go.mod h1:f0/XX0hsm6A02Es/UDQ9MGd3VqpCHrCw5pMjE2y6qTU=
+github.com/ktr0731/go-updater v0.1.5 h1:AiaQxJoI0OTGqvsJYdIITCOaEzQQOqU2MHKUwttVShY=
+github.com/ktr0731/go-updater v0.1.5/go.mod h1:dsdOg7a9sj6ttcOU5ZxPCtKdm9WeB1hwcX/7oKgz9/0=
+github.com/ktr0731/grpc-test v0.1.4/go.mod h1:v47616grayBYXQveGWxO3OwjLB3nEEnHsZuMTc73FM0=
+github.com/ktr0731/grpc-test v0.1.7 h1:QwjxlKMHb1FzQMoXjjK1F2HDdIf5f72WXWZs4He8nNI=
+github.com/ktr0731/grpc-test v0.1.7/go.mod h1:vjMPOfGerucM+ysAKiynHDS6IUSErB6O9gBOHWyUs5s=
+github.com/ktr0731/grpc-web-go-client v0.2.7 h1:Op1U1XC29kb7S8XptqYd742JwcG7oR5Q7QoYPZMN2T4=
+github.com/ktr0731/grpc-web-go-client v0.2.7/go.mod h1:1Iac8gFJvC/DRfZoGnFZsfEbEq/wQFK+2Ve1o3pHkCQ=
+github.com/ktr0731/modfile v1.11.2/go.mod h1:LzNwnHJWHbuDh3BO17lIqzqDldXqGu1HCydWH3SinE0=
+github.com/kulti/thelper v0.1.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U=
+github.com/kulti/thelper v0.2.1/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U=
+github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30=
 github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
+github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg=
 github.com/labstack/echo/v4 v4.2.2 h1:bq2fdZCionY1jck8rzUpQEu2YSmI8QbX6LHrCa60IVs=
 github.com/labstack/echo/v4 v4.2.2/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
 github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=
 github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
 github.com/leandro-lugaresi/hub v1.1.1 h1:zqp0HzFvj4HtqjMBXM2QF17o6PNmR8MJOChgeKl/aw8=
 github.com/leandro-lugaresi/hub v1.1.1/go.mod h1:XEFWanhHv6Rt3XlteHMxuNDYi8dJcpJjodpqkU+BtIo=
+github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.2.1-0.20191011153232-f91d3411e481/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E=
 github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
+github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
+github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8=
+github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY=
@@ -745,6 +901,8 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN
 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/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=
 github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU=
 github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
 github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
@@ -755,13 +913,16 @@ github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=
 github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
 github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
 github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
+github.com/matoous/godox v0.0.0-20200801072554-4fb83dc2941e/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
+github.com/matryer/moq v0.1.6/go.mod h1:9RtPYjTnH1bSBIkpvtHkFN7nbWAnO7oRpdJkEIn6UtE=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
 github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
-github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
 github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
+github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
 github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
 github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E=
@@ -774,16 +935,27 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA
 github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
 github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI=
+github.com/mattn/go-pipeline v0.0.0-20170920030317-cfb87a531e2b/go.mod h1:THCMZVX5asLpinN+6hFlR1xKFcFsaDpAtUltGqZauBM=
+github.com/mattn/go-pipeline v0.0.0-20190323144519-32d779b32768 h1:uZ41sUUU0/vDwBwMVz7O1jtcSyLFn/AeUdMr9MKcDsc=
+github.com/mattn/go-pipeline v0.0.0-20190323144519-32d779b32768/go.mod h1:THCMZVX5asLpinN+6hFlR1xKFcFsaDpAtUltGqZauBM=
 github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
 github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
 github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
 github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
+github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
+github.com/mattn/go-tty v0.0.0-20190424173100-523744f04859 h1:smQbSzmT3EHl4EUwtFwFGmGIpiYgIiiPeVv1uguIQEE=
+github.com/mattn/go-tty v0.0.0-20190424173100-523744f04859/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
 github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
 github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
+github.com/mbilski/exhaustivestruct v1.1.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc=
 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@@ -793,6 +965,7 @@ github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
 github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
+github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
 github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
 github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
 github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
@@ -800,10 +973,12 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
 github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
 github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.4.0 h1:7ks8ZkOP5/ujthUsT07rNv+nkLXCQWKNHuwzOAesEks=
+github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
 github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
 github.com/moby/buildkit v0.8.3 h1:vFlwUQ6BZE1loZ8zoZH3fYgmA1djFCS3DrOhCVU6ZZE=
 github.com/moby/buildkit v0.8.3/go.mod h1:jUezwyOvKdkbcvR66WuKzPYQUO3sQ8i/eChLZ7kEmg8=
 github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
@@ -827,10 +1002,12 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
 github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
+github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k=
 github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
 github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
 github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
 github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
+github.com/mozilla/tls-observatory v0.0.0-20201209171846-0547674fceff/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
 github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
 github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
@@ -838,12 +1015,19 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW
 github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
 github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c=
 github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
+github.com/nbutton23/zxcvbn-go v0.0.0-20201221231540-e56b841a3c88/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
 github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
 github.com/ncw/swift v1.0.53 h1:luHjjTNtekIEvHg5KdAFIBaH7bWfNkefwFnpDffSIks=
 github.com/ncw/swift v1.0.53/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ=
+github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE=
+github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
 github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
 github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
+github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
 github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -852,16 +1036,22 @@ github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
 github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.10.3/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.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
 github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
+github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
+github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
 github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/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 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
 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/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U=
+github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ=
 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
 github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
 github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
@@ -901,6 +1091,7 @@ github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNC
 github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
+github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -909,9 +1100,13 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
 github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
+github.com/pkg/term v0.0.0-20180423043932-cda20d4ac917/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
+github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 h1:A7GG7zcGjl3jqAqGPmcNjd/D9hzL95SuoOQAaFNdLU0=
+github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
 github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw=
 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
 github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -938,11 +1133,17 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R
 github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
 github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
 github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
 github.com/quasilyte/go-ruleguard v0.1.2-0.20200318202121-b00d7a75d3d8/go.mod h1:CGFX09Ci3pq9QZdj86B+VGIdNj4VyCo2iPOGS9esB/k=
+github.com/quasilyte/go-ruleguard v0.2.0/go.mod h1:2RT/tf0Ce0UDj5y243iWKosQogJd8+1G3Rs2fxmlYnw=
+github.com/quasilyte/go-ruleguard v0.2.1-0.20201030093329-408e96760278/go.mod h1:2RT/tf0Ce0UDj5y243iWKosQogJd8+1G3Rs2fxmlYnw=
+github.com/quasilyte/go-ruleguard v0.2.1/go.mod h1:hN2rVc/uS4bQhQKTio2XaSJSafJwqBUWWwtssT3cQmc=
+github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
+github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
+github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs=
+github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc=
 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/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
@@ -951,6 +1152,8 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
 github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
 github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
 github.com/rubenv/sql-migrate v0.0.0-20210408115534-a32ed26c37ea h1:Yiqmu2rZoPdjxW2fWX5gAMpKfi9tYF5ak+lcGwZA4Qg=
 github.com/rubenv/sql-migrate v0.0.0-20210408115534-a32ed26c37ea/go.mod h1:HFLT6i9iR4QBOF5rdCyjddC9t59ArqWJV2xx+jwcCMo=
@@ -959,6 +1162,8 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/ryancurrah/gomodguard v1.0.4/go.mod h1:9T/Cfuxs5StfsocWr4WzDL36HqnX0fVb9d5fSEaLhoE=
 github.com/ryancurrah/gomodguard v1.1.0/go.mod h1:4O8tr7hBODaGE6VIhfJDHcwzh5GUccKSJBU0UMXJFVM=
+github.com/ryancurrah/gomodguard v1.2.0/go.mod h1:rNqbC4TOIdUDcVMSIpNNAzTbzXAZa6W5lnUepvuMMgQ=
+github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA=
 github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
 github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I=
 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
@@ -970,10 +1175,13 @@ github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvW
 github.com/securego/gosec v0.0.0-20200103095621-79fbf3af8d83/go.mod h1:vvbZ2Ae7AzSq3/kywjUDxSNq2SJ27RxCz2un0H3ePqE=
 github.com/securego/gosec v0.0.0-20200401082031-e946c8c39989/go.mod h1:i9l/TNj+yDFh9SZXUTvspXTjbFXgZGP/UvhU1S65A4A=
 github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME=
+github.com/securego/gosec/v2 v2.5.0/go.mod h1:L/CDXVntIff5ypVHIkqPXbtRpJiNCh6c6Amn68jXDjo=
+github.com/securego/gosec/v2 v2.6.1/go.mod h1:I76p3NTHBXsGhybUW+cEQ692q2Vp+A0Z6ZLzDIZy+Ao=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
 github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
 github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc=
+github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
 github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
 github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
 github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
@@ -998,13 +1206,16 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK
 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs=
 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI=
 github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE=
 github.com/sourcegraph/go-diff v0.5.3/go.mod h1:v9JDtjCE4HHHCZGId75rg8gkKKa98RVjBcBGsVmMmak=
+github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
-github.com/spf13/afero v1.4.0 h1:jsLTaI1zwYO3vjrzHalkVcIHXTNmdQFepW4OI8H3+x8=
-github.com/spf13/afero v1.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
+github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
+github.com/spf13/afero v1.5.1 h1:VHu76Lk0LSP1x254maIu2bplkWpfBWI+B+6fdoZprcg=
+github.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
 github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
@@ -1013,6 +1224,7 @@ github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3
 github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
 github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
+github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
 github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
 github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
@@ -1031,12 +1243,15 @@ github.com/spf13/viper v1.6.3/go.mod h1:jUMtyi0/lB5yZH/FjyGAoH7IMNrIhlBf6pXZmbMD
 github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
 github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
 github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
 github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -1054,18 +1269,27 @@ github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0
 github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM=
 github.com/tetafro/godot v0.3.7/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0=
 github.com/tetafro/godot v0.4.2/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0=
+github.com/tetafro/godot v1.3.2/go.mod h1:ah7jjYmOMnIjS9ku2krapvGQrFNtTLo9Z/qB3dGU1eU=
+github.com/tetafro/godot v1.4.3/go.mod h1:ah7jjYmOMnIjS9ku2krapvGQrFNtTLo9Z/qB3dGU1eU=
 github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
 github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
 github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=
+github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk=
+github.com/tj/go-buffer v1.1.0/go.mod h1:iyiJpfFcR2B9sXu7KvjbT9fpM4mOelRSDTbntVj52Uc=
 github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
 github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao=
+github.com/tj/go-spin v1.1.0 h1:lhdWZsvImxvZ3q1C5OIB7d72DuOwP4O2NdBg9PyzNds=
 github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/tomarrell/wrapcheck v0.0.0-20200807122107-df9e8bcb914d/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0=
+github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0=
 github.com/tommy-muehle/go-mnd v1.1.1/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig=
 github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig=
+github.com/tommy-muehle/go-mnd v1.3.1-0.20201008215730-16041ac3fe65/go.mod h1:T22e7iRN4LsFPZGyRLRXeF+DWVXFuV9thsyO7NjbbTI=
+github.com/tommy-muehle/go-mnd/v2 v2.3.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
 github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85 h1:014iQD8i8EabPWK2XgUuOTxg5s2nhfDmq6GupskfUO8=
 github.com/tonistiigi/fsutil v0.0.0-20201103201449-0834f99b7b85/go.mod h1:a7cilN64dG941IOXfhJhlH0qB92hxJ9A1ewrdUmJ6xo=
 github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0=
@@ -1075,10 +1299,14 @@ github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305/go.mod h1:gXOLibK
 github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
 github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
 github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
 github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
 github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
+github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
 github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
+github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
 github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
 github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
@@ -1088,12 +1316,14 @@ github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
-github.com/valyala/fasthttp v1.9.0 h1:hNpmUdy/+ZXYpGy0OBfm7K0UQTzb73W0T0U4iJIVrMw=
 github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
+github.com/valyala/fasthttp v1.16.0 h1:9zAqOYLl8Tuy3E5R6ckzGDJ1g8+pw15oQp2iL9Jl6gQ=
+github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA=
 github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
 github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
 github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
 github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
+github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY=
 github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
 github.com/vdemeester/k8s-pkg-credentialprovider v1.17.4/go.mod h1:inCTmtUdr5KJbreVojo06krnTgaeAz/Z7lynpPk/Q2c=
 github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
@@ -1114,6 +1344,8 @@ github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE=
 github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
 github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
 github.com/xanzy/go-gitlab v0.32.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
+github.com/xanzy/go-gitlab v0.42.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
+github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
 github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
 github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
 github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
@@ -1149,6 +1381,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
 github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
 github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
 github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
+github.com/zchee/go-xdgbasedir v1.0.3 h1:loLl3qosOHcMSCtV9ciISdjEQuXcj56BYccRNBvQKDY=
+github.com/zchee/go-xdgbasedir v1.0.3/go.mod h1:Ta5nXXeucstQZw/DpFneOcG3OF8i3pxPTqda2w+nyc8=
 github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
 github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
 go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
@@ -1164,14 +1398,21 @@ go.opencensus.io v0.19.2/go.mod h1:NO/8qkisMZLZ1FCsKNqtJPwc8/TaclWyY0B6wcYNg9M=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
 go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0=
+go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/goleak v0.10.0 h1:G3eWbSNIskeRqtsN/1uI5B+eP73y3JUuBsv9AZjehb4=
+go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
 gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI=
+gocloud.dev v0.21.0/go.mod h1:rELLUUon1rJUS/cLC3gLgwUtWlU1yaCgf4alO8HHpYo=
 golang.org/x/build v0.0.0-20190314133821-5284462c4bec/go.mod h1:atTaCNAy0f16Ah5aV1gMSwgiKVHwu/JncqDpuRr7lS4=
 golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -1195,9 +1436,13 @@ golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 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=
@@ -1225,6 +1470,7 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
 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-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+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/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=
@@ -1233,9 +1479,11 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 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/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
+golang.org/x/mod v0.4.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-20180530234432-1e491301e022/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=
@@ -1275,11 +1523,19 @@ golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/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-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200904194848-62affa334b73/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-20201031054903-ff519b6c9102/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-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs=
 golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
@@ -1292,8 +1548,11 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr
 golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201203001011-0b49973bad19 h1:ZD+2Sd/BnevwJp8PSli8WgGAGzb9IZtxBsv1iZMYeEA=
+golang.org/x/oauth2 v0.0.0-20201203001011-0b49973bad19/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1307,6 +1566,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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-20180620133508-ad87a3a340fa/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-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1315,11 +1575,13 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116161606-93218def8b18/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181218192612-074acd46bca6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1340,6 +1602,7 @@ golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1365,20 +1628,30 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201013081832-0aaa2718063a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201109165425-215b40eba54c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/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-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210216224549-f992740a1bac/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg=
@@ -1417,6 +1690,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
 golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -1442,8 +1716,12 @@ golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDq
 golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -1456,6 +1734,7 @@ golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapK
 golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200102140908-9497f49d5709/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/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-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
@@ -1468,16 +1747,52 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs
 golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
 golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
 golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
 golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
 golang.org/x/tools v0.0.0-20200331202046-9d5940d49312/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/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-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
 golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200815165600-90abf76919f3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200828161849-5deb26317202/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20200915173823-2db8f0ff891c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201007032633-0806396f153e/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201030010431-2feb2bb1ff51/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201121010211-780cb80bd7fb/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201202200335-bef1c476418a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201203202102-a1a1cbeaa516/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210102185154-773b96fafca2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210105210202-9ed45478a130/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 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/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1501,6 +1816,7 @@ google.golang.org/api v0.6.1-0.20190607001116-5213b8090861/go.mod h1:btoxGiFvQNV
 google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
 google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
 google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
 google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
 google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
 google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
@@ -1511,16 +1827,26 @@ google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
 google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
 google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
 google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
+google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
+google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo=
+google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
+google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
+google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
 google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
 google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
+google.golang.org/appengine v1.6.7/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-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@@ -1543,6 +1869,7 @@ google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvx
 google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
 google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
 google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
+google.golang.org/genproto v0.0.0-20200204235621-fb4a7afc5178/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
 google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
@@ -1551,11 +1878,23 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG
 google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
 google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
-google.golang.org/genproto v0.0.0-20201008135153-289734e2e40c h1:dvSnJCVti7yKNAZrunMpEE4QLfy5b/UdEKt+UH39BW4=
-google.golang.org/genproto v0.0.0-20201008135153-289734e2e40c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
+google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201203001206-6486ece9c497 h1:jDYzwXmX9tLnuG4sL85HPmE1ruErXOopALp2i/0AHnI=
+google.golang.org/genproto v0.0.0-20201203001206-6486ece9c497/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
 google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
@@ -1571,8 +1910,16 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
 google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
+google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
 google.golang.org/grpc v1.35.0 h1:TwIQcH3es+MojMVojxxfQ3l3OF2KzlRxML2xZq0kRo8=
 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE=
+google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 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=
@@ -1597,7 +1944,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
 gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
@@ -1607,8 +1953,8 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.61.0 h1:LBCdW4FmFYL4s/vDZD1RQYX7oAR6IjujCYgMdbHBR10=
-gopkg.in/ini.v1 v1.61.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
+gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
@@ -1627,8 +1973,10 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
 gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
 gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
@@ -1643,7 +1991,9 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
 honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY=
 k8s.io/api v0.0.0-20180904230853-4e7be11eab3f/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
 k8s.io/api v0.17.4/go.mod h1:5qxx6vjmwUVG2nHQTKGlLts8Tbok8PzHl4vHtVFuZCA=
 k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw=
@@ -1694,10 +2044,13 @@ modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs
 modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
 moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e h1:C7q+e9M5nggAvWfVg9Nl66kebKeuJlP3FD58V4RR5wo=
 moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e/go.mod h1:nejbQVfXh96n9dSF6cH3Jsk/QI1Z2oEL7sSI2ifXFNA=
+mvdan.cc/gofumpt v0.0.0-20201129102820-5c11c50e9475/go.mod h1:E4LOcu9JQEtnYXtB1Y51drqh2Qr2Ngk9J3YrRCwcbd0=
+mvdan.cc/gofumpt v0.1.0/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
 mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
 mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
 mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
 mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vCGb9oLhHoScFwkHDJm/05RdSTc=
+nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
 pack.ag/amqp v0.11.2/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
diff --git a/local-dev/.gitignore b/local-dev/.gitignore
index 4222113d..a04a8f3f 100644
--- a/local-dev/.gitignore
+++ b/local-dev/.gitignore
@@ -1,3 +1,4 @@
 neoshowcase/**
 staticsite/**
 dind/**
+traefik/**
diff --git a/local-dev/Caddyfile b/local-dev/Caddyfile
deleted file mode 100644
index 21cce157..00000000
--- a/local-dev/Caddyfile
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  auto_https off
-  admin 0.0.0.0:2019
-}
diff --git a/pkg/appmanager/app.go b/pkg/appmanager/app.go
deleted file mode 100644
index 187b2d92..00000000
--- a/pkg/appmanager/app.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package appmanager
-
-import "context"
-
-// App アプリモデル
-type App interface {
-	// GetID アプリIDを返します
-	GetID() string
-	// GetName アプリ名を返します
-	GetName() string
-	// GetEnvs アプリの全ての環境の配列を返します
-	GetEnvs() []Env
-	// GetEnvByBranchName 指定したブランチ名の環境を返します
-	GetEnvByBranchName(branch string) (Env, error)
-	// CreateEnv アプリに新しく環境を作成します
-	CreateEnv(branchName string, buildType BuildType) (Env, error)
-
-	// Start アプリを起動します
-	Start(args AppStartArgs) error
-	// RequestBuild builderにappのビルドをリクエストする
-	RequestBuild(ctx context.Context, envID string) error
-}
-
-type AppStartArgs struct {
-	// 操作したい環境ID
-	EnvironmentID string
-	// 起動したいビルドID
-	BuildID string
-}
diff --git a/pkg/appmanager/app_impl.go b/pkg/appmanager/app_impl.go
deleted file mode 100644
index 03e779e6..00000000
--- a/pkg/appmanager/app_impl.go
+++ /dev/null
@@ -1,322 +0,0 @@
-package appmanager
-
-import (
-	"context"
-	"database/sql"
-	"fmt"
-
-	log "github.com/sirupsen/logrus"
-	"github.com/traPtitech/neoshowcase/pkg/domain"
-	"github.com/traPtitech/neoshowcase/pkg/interface/grpc/pb"
-	"github.com/traPtitech/neoshowcase/pkg/models"
-	"github.com/volatiletech/null/v8"
-	"github.com/volatiletech/sqlboiler/v4/boil"
-	"github.com/volatiletech/sqlboiler/v4/queries/qm"
-)
-
-func (m *managerImpl) GetApp(appID string) (App, error) {
-	app, err := models.Applications(
-		qm.Load(models.ApplicationRels.Repository),
-		qm.Load(qm.Rels(models.ApplicationRels.Environments, models.EnvironmentRels.Website)),
-		models.ApplicationWhere.DeletedAt.IsNull(),
-		models.ApplicationWhere.ID.EQ(appID),
-	).One(context.Background(), m.db)
-	if err != nil {
-		if err == sql.ErrNoRows {
-			return nil, ErrNotFound
-		}
-		return nil, fmt.Errorf("failed to GetApp: %w", err)
-	}
-
-	return &appImpl{
-		m:       m,
-		dbmodel: app,
-	}, nil
-}
-
-func (m *managerImpl) GetAppByRepository(repo string) (App, error) {
-	repoModel, err := models.Repositories(models.RepositoryWhere.Remote.EQ(repo)).One(context.Background(), m.db)
-	if err != nil {
-		if err == sql.ErrNoRows {
-			return nil, ErrNotFound
-		}
-		return nil, fmt.Errorf("failed to GetAppByRepository: %w", err)
-	}
-
-	app, err := models.Applications(
-		qm.Load(models.ApplicationRels.Repository),
-		qm.Load(qm.Rels(models.ApplicationRels.Environments, models.EnvironmentRels.Website)),
-		models.ApplicationWhere.DeletedAt.IsNull(),
-		models.ApplicationWhere.RepositoryID.EQ(repoModel.ID),
-	).One(context.Background(), m.db)
-	if err != nil {
-		if err == sql.ErrNoRows {
-			return nil, ErrNotFound
-		}
-		return nil, fmt.Errorf("failed to GetApp: %w", err)
-	}
-
-	return &appImpl{
-		m:       m,
-		dbmodel: app,
-	}, nil
-}
-
-func (m *managerImpl) GetAppByEnvironment(envID string) (App, error) {
-	env, err := models.FindEnvironment(context.Background(), m.db, envID)
-	if err != nil {
-		if err == sql.ErrNoRows {
-			return nil, ErrNotFound
-		}
-		return nil, fmt.Errorf("failed to GetAppByEnvironment: %w", err)
-	}
-
-	app, err := models.Applications(
-		qm.Load(models.ApplicationRels.Repository),
-		qm.Load(qm.Rels(models.ApplicationRels.Environments, models.EnvironmentRels.Website)),
-		models.ApplicationWhere.DeletedAt.IsNull(),
-		models.ApplicationWhere.ID.EQ(env.ApplicationID),
-	).One(context.Background(), m.db)
-	if err != nil {
-		if err == sql.ErrNoRows {
-			return nil, ErrNotFound
-		}
-		return nil, fmt.Errorf("failed to GetApp: %w", err)
-	}
-
-	return &appImpl{
-		m:       m,
-		dbmodel: app,
-	}, nil
-}
-
-func (m *managerImpl) CreateApp(args CreateAppArgs) (App, error) {
-	// リポジトリ情報を設定
-	repo, err := models.Repositories(models.RepositoryWhere.Remote.EQ(args.RepositoryURL)).One(context.Background(), m.db)
-	if err != nil && err != sql.ErrNoRows {
-		return nil, fmt.Errorf("failed to get repository: %w", err)
-	} else if repo == nil {
-		repo = &models.Repository{
-			ID:     domain.NewID(),
-			Remote: args.RepositoryURL,
-		}
-		if err := repo.Insert(context.Background(), m.db, boil.Infer()); err != nil {
-			return nil, fmt.Errorf("failed to insert repository: %w", err)
-		}
-	}
-
-	// アプリケーション作成
-	app := &models.Application{
-		ID:           domain.NewID(),
-		Owner:        args.Owner,
-		Name:         args.Name,
-		RepositoryID: repo.ID,
-	}
-	if err := app.Insert(context.Background(), m.db, boil.Infer()); err != nil {
-		return nil, fmt.Errorf("failed to insert application: %w", err)
-	}
-	if err := app.SetRepository(context.Background(), m.db, false, repo); err != nil {
-		return nil, fmt.Errorf("failed to associate repository: %w", err)
-	}
-
-	log.WithField("appID", app.ID).Info("app created")
-	appI := &appImpl{
-		m:       m,
-		dbmodel: app,
-	}
-
-	// 初期Env作成
-	if _, err := appI.CreateEnv(args.BranchName, args.BuildType); err != nil {
-		return nil, err
-	}
-	return appI, nil
-}
-
-type appImpl struct {
-	m *managerImpl
-	// dbmodelはEnvironments.WebsiteとRepositoryがプレロードされてる事
-	dbmodel *models.Application
-}
-
-func (app *appImpl) GetID() string {
-	return app.dbmodel.ID
-}
-
-func (app *appImpl) GetName() string {
-	return app.dbmodel.Name
-}
-
-func (app *appImpl) GetEnvs() []Env {
-	result := make([]Env, 0)
-	for _, env := range app.dbmodel.R.Environments {
-		result = append(result, &envImpl{
-			m:       app.m,
-			dbmodel: env,
-		})
-	}
-	return result
-}
-
-func (app *appImpl) GetEnvByBranchName(branch string) (Env, error) {
-	for _, env := range app.dbmodel.R.Environments {
-		if env.BranchName == branch {
-			return &envImpl{
-				m:       app.m,
-				dbmodel: env,
-			}, nil
-		}
-	}
-	return nil, ErrNotFound
-}
-
-func (app *appImpl) CreateEnv(branchName string, buildType BuildType) (Env, error) {
-	// 指定したブランチの環境が存在しないことを確認
-	for _, env := range app.dbmodel.R.Environments {
-		if env.BranchName == branchName {
-			return nil, fmt.Errorf("the environment for branch `%s` has already existed", branchName)
-		}
-	}
-
-	env := &models.Environment{
-		ID:         domain.NewID(),
-		BranchName: branchName,
-		BuildType:  buildType.String(),
-	}
-	if err := app.dbmodel.AddEnvironments(context.Background(), app.m.db, true, env); err != nil {
-		return nil, fmt.Errorf("failed to create environment: %w", err)
-	}
-	log.WithField("appID", env.ApplicationID).
-		WithField("envID", env.ID).
-		Info("env created")
-	return &envImpl{m: app.m, dbmodel: env}, nil
-}
-
-func (app *appImpl) Start(args AppStartArgs) error {
-	var env *models.Environment
-	for _, _env := range app.dbmodel.R.Environments {
-		if _env.ID == args.EnvironmentID {
-			env = _env
-			break
-		}
-	}
-	if env == nil {
-		return fmt.Errorf("environtment not found: %s", args.EnvironmentID)
-	}
-
-	if args.BuildID == "" {
-		// buildIDの指定がない場合は最新のビルドを使用
-		build, err := env.BuildLogs(
-			qm.OrderBy(fmt.Sprintf("%s DESC", models.BuildLogColumns.StartedAt)),
-			models.BuildLogWhere.Result.EQ(models.BuildLogsResultSUCCEEDED),
-		).One(context.Background(), app.m.db)
-		if err != nil {
-			if err == sql.ErrNoRows {
-				return fmt.Errorf("no successful build exists")
-			}
-			return fmt.Errorf("failed to get BuildLogs: %w", err)
-		}
-		args.BuildID = build.ID
-	} else {
-		// buildIDのビルドが存在するかどうか確認
-		ok, err := models.BuildLogExists(context.Background(), app.m.db, args.BuildID)
-		if err != nil {
-			return fmt.Errorf("failed to BuildLogExists: %w", err)
-		}
-		if !ok {
-			return fmt.Errorf("build (%s) was not found", args.BuildID)
-		}
-	}
-
-	switch env.BuildType {
-	case models.EnvironmentsBuildTypeImage:
-		// HTTP公開設定があれば取得
-		var httpProxy *domain.ContainerHTTPProxy
-		website, err := env.Website().One(context.Background(), app.m.db)
-		if err == nil {
-			httpProxy = &domain.ContainerHTTPProxy{
-				Domain: website.FQDN,
-				Port:   website.HTTPPort,
-			}
-		} else if err != sql.ErrNoRows {
-			return fmt.Errorf("failed to query website: %w", err)
-		}
-
-		err = app.m.backend.CreateContainer(context.Background(), domain.ContainerCreateArgs{
-			ApplicationID: app.GetID(),
-			EnvironmentID: env.ID,
-			ImageName:     app.m.getFullImageName(app),
-			ImageTag:      args.BuildID,
-			HTTPProxy:     httpProxy,
-			Recreate:      true,
-		})
-		if err != nil {
-			return fmt.Errorf("failed to Create container: %w", err)
-		}
-
-		env.BuildID = null.StringFrom(args.BuildID)
-		if _, err := env.Update(context.Background(), app.m.db, boil.Infer()); err != nil {
-			return fmt.Errorf("failed to Update website: %w", err)
-		}
-
-	case models.EnvironmentsBuildTypeStatic:
-		env.BuildID = null.StringFrom(args.BuildID)
-		if _, err := env.Update(context.Background(), app.m.db, boil.Infer()); err != nil {
-			return fmt.Errorf("failed to Update website: %w", err)
-		}
-
-		if _, err := app.m.ss.Reload(context.Background(), &pb.ReloadRequest{}); err != nil {
-			return fmt.Errorf("failed to Reload ss: %w", err)
-		}
-	default:
-		return fmt.Errorf("unknown build type: %s", env.BuildType)
-	}
-	return nil
-}
-
-func (app *appImpl) RequestBuild(ctx context.Context, envID string) error {
-	var env *models.Environment
-	for _, _env := range app.dbmodel.R.Environments {
-		if _env.ID == envID {
-			env = _env
-			break
-		}
-	}
-	if env == nil {
-		return fmt.Errorf("environtment not found: %s", envID)
-	}
-
-	switch env.BuildType {
-	case models.EnvironmentsBuildTypeImage:
-		_, err := app.m.builder.StartBuildImage(ctx, &pb.StartBuildImageRequest{
-			ImageName: app.m.getImageName(app),
-			Source: &pb.BuildSource{
-				RepositoryUrl: app.dbmodel.R.Repository.Remote, // TODO ブランチ・タグ指定に対応
-			},
-			Options:       &pb.BuildOptions{}, // TODO 汎用ベースイメージビルドに対応させる
-			EnvironmentId: env.ID,
-		})
-		if err != nil {
-			return fmt.Errorf("builder failed to start build image: %w", err)
-		}
-
-	case models.EnvironmentsBuildTypeStatic:
-		_, err := app.m.builder.StartBuildStatic(ctx, &pb.StartBuildStaticRequest{
-			Source: &pb.BuildSource{
-				RepositoryUrl: app.dbmodel.R.Repository.Remote, // TODO ブランチ・タグ指定に対応
-			},
-			Options:       &pb.BuildOptions{}, // TODO 汎用ベースイメージビルドに対応させる
-			EnvironmentId: env.ID,
-		})
-		if err != nil {
-			return fmt.Errorf("builder failed to start build static: %w", err)
-		}
-
-	default:
-		return fmt.Errorf("unknown build type: %s", env.BuildType)
-	}
-
-	log.WithField("envID", envID).
-		Info("build requested")
-
-	return nil
-}
diff --git a/pkg/appmanager/env.go b/pkg/appmanager/env.go
deleted file mode 100644
index ebbe57a3..00000000
--- a/pkg/appmanager/env.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package appmanager
-
-// Env アプリ環境モデル
-type Env interface {
-	// GetID 環境IDを返します
-	GetID() string
-	// GetBranchName 環境に対応するブランチ名を返します
-	GetBranchName() string
-	// GetBuildType 環境のビルドタイプを返します
-	GetBuildType() BuildType
-	// SetupWebsite 環境にHTTPウェブサイトを設定します
-	SetupWebsite(fqdn string, httpPort int) error
-}
diff --git a/pkg/appmanager/env_impl.go b/pkg/appmanager/env_impl.go
deleted file mode 100644
index eda701fd..00000000
--- a/pkg/appmanager/env_impl.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package appmanager
-
-import (
-	"context"
-	"fmt"
-
-	"github.com/traPtitech/neoshowcase/pkg/domain"
-	"github.com/traPtitech/neoshowcase/pkg/models"
-	"github.com/volatiletech/sqlboiler/v4/boil"
-)
-
-type envImpl struct {
-	m       *managerImpl
-	dbmodel *models.Environment
-}
-
-func (env *envImpl) GetID() string {
-	return env.dbmodel.ID
-}
-
-func (env *envImpl) GetBranchName() string {
-	return env.dbmodel.BranchName
-}
-
-func (env *envImpl) GetBuildType() BuildType {
-	return BuildTypeFromString(env.dbmodel.BuildType)
-}
-
-func (env *envImpl) SetupWebsite(fqdn string, httpPort int) error {
-	if httpPort <= 0 || httpPort > 65535 {
-		httpPort = 80
-	}
-	if fqdn == "" {
-		// ドメインを自動的に生成
-		d, err := env.m.generateRandomDomain()
-		if err != nil {
-			return fmt.Errorf("failed to generateRandomDomain: %w", err)
-		}
-		fqdn = d
-	}
-
-	ws := env.dbmodel.R.Website
-	if ws != nil {
-		// テーブルの情報を更新
-		ws.FQDN = fqdn
-		ws.HTTPPort = httpPort
-		if _, err := ws.Update(context.Background(), env.m.db, boil.Infer()); err != nil {
-			return fmt.Errorf("failed to update website: %w", err)
-		}
-		return nil
-	}
-
-	// Websiteをテーブルに挿入
-	ws = &models.Website{
-		ID:       domain.NewID(),
-		FQDN:     fqdn,
-		HTTPPort: httpPort,
-	}
-	if err := env.dbmodel.SetWebsite(context.Background(), env.m.db, true, ws); err != nil {
-		return fmt.Errorf("failed to SetWebsite: %w", err)
-	}
-	return nil
-}
diff --git a/pkg/appmanager/manager.go b/pkg/appmanager/manager.go
deleted file mode 100644
index 104e8972..00000000
--- a/pkg/appmanager/manager.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package appmanager
-
-import (
-	"context"
-	"errors"
-)
-
-// ErrNotFound 汎用エラー 見つかりません
-var ErrNotFound = errors.New("not found")
-
-// Manager アプリマネージャー
-type Manager interface {
-	// GetRepo 指定したリポジトリURLのRepoを取得します
-	GetRepoByURL(url string) (Repo, error)
-	// GetApp 指定したIDのアプリを取得します
-	GetApp(appID string) (App, error)
-	// GetAppByRepository 指定したリポジトリURLのアプリを取得します
-	GetAppByRepository(repo string) (App, error)
-	// GetAppByEnvironment 指定した環境IDのアプリを取得します
-	GetAppByEnvironment(envID string) (App, error)
-	CreateApp(args CreateAppArgs) (App, error)
-	Shutdown(ctx context.Context) error
-}
-
-type CreateAppArgs struct {
-	Owner         string
-	Name          string
-	RepositoryURL string
-	BranchName    string
-	BuildType     BuildType
-}
diff --git a/pkg/appmanager/manager_impl.go b/pkg/appmanager/manager_impl.go
deleted file mode 100644
index 29f594f5..00000000
--- a/pkg/appmanager/manager_impl.go
+++ /dev/null
@@ -1,176 +0,0 @@
-package appmanager
-
-import (
-	"context"
-	"database/sql"
-	"io"
-
-	log "github.com/sirupsen/logrus"
-	"github.com/traPtitech/neoshowcase/pkg/domain/event"
-	"github.com/traPtitech/neoshowcase/pkg/infrastructure/backend"
-	"github.com/traPtitech/neoshowcase/pkg/infrastructure/eventbus"
-	"github.com/traPtitech/neoshowcase/pkg/interface/grpc/pb"
-	"github.com/traPtitech/neoshowcase/pkg/util"
-	"google.golang.org/protobuf/types/known/emptypb"
-)
-
-type managerImpl struct {
-	db      *sql.DB
-	bus     eventbus.Bus
-	builder pb.BuilderServiceClient
-	ss      pb.StaticSiteServiceClient
-	backend backend.Backend
-
-	config Config
-
-	stream pb.BuilderService_ConnectEventStreamClient
-}
-
-type Config struct {
-	DB              *sql.DB
-	Hub             eventbus.Bus
-	Builder         pb.BuilderServiceClient
-	SS              pb.StaticSiteServiceClient
-	Backend         backend.Backend
-	ImageRegistry   string
-	ImageNamePrefix string
-}
-
-func NewManager(config Config) (Manager, error) {
-	stream, err := config.Builder.ConnectEventStream(context.Background(), &emptypb.Empty{})
-	if err != nil {
-		return nil, err
-	}
-
-	m := &managerImpl{
-		db:      config.DB,
-		bus:     config.Hub,
-		builder: config.Builder,
-		ss:      config.SS,
-		backend: config.Backend,
-		config:  config,
-		stream:  stream,
-	}
-	go m.appDeployLoop()
-	go m.receiveBuilderEvents()
-	return m, nil
-}
-
-// receiveBuilderEvents　builderから届くイベントを内部イベントに変換してpublish
-func (m *managerImpl) receiveBuilderEvents() error {
-	for {
-		ev, err := m.stream.Recv()
-		if err == io.EOF {
-			log.Debug("builder event stream was closed: EOF")
-			break
-		}
-		if err != nil {
-			log.WithError(err).
-				Debug("builder event stream was disconnected with error")
-			return err
-		}
-
-		payload := util.FromJSON(ev.Body)
-
-		log.WithField("type", ev.Type).
-			WithField("payload", payload).
-			Info("builder event received")
-
-		switch ev.Type {
-		case pb.Event_BUILD_STARTED:
-			m.bus.Publish(event.BuilderBuildStarted, payload)
-		case pb.Event_BUILD_SUCCEEDED:
-			m.bus.Publish(event.BuilderBuildSucceeded, payload)
-		case pb.Event_BUILD_FAILED:
-			m.bus.Publish(event.BuilderBuildFailed, payload)
-		case pb.Event_BUILD_CANCELED:
-			m.bus.Publish(event.BuilderBuildCanceled, payload)
-		}
-	}
-	return nil
-}
-
-func (m *managerImpl) appDeployLoop() {
-	sub := m.bus.Subscribe(event.BuilderBuildSucceeded, event.WebhookRepositoryPush)
-	defer sub.Unsubscribe()
-	for ev := range sub.Chan() {
-		switch ev.Type {
-		case event.WebhookRepositoryPush:
-			repoURL := ev.Body["repository_url"].(string)
-			branch := ev.Body["branch"].(string)
-
-			log.WithField("repo", repoURL).
-				WithField("refs", branch).
-				Info("repository push event received")
-
-			app, err := m.GetAppByRepository(repoURL)
-			if err != nil {
-				if err != ErrNotFound {
-					log.WithError(err).WithField("repoURL", repoURL).Error("failed to GetAppByRepository")
-				}
-				continue
-			}
-
-			env, err := app.GetEnvByBranchName(branch)
-			if err != nil {
-				if err != ErrNotFound {
-					log.WithError(err).WithField("repoURL", repoURL).Error("failed to GetAppByRepository")
-				}
-				continue
-			}
-
-			if err := app.RequestBuild(context.Background(), env.GetID()); err != nil {
-				log.WithError(err).
-					WithField("appID", app.GetID()).
-					WithField("envID", env.GetID()).
-					Error("failed to RequestBuild")
-			}
-
-		case event.BuilderBuildSucceeded:
-			envID := ev.Body["environment_id"].(string)
-			buildID := ev.Body["build_id"].(string)
-			if len(envID) == 0 {
-				// envIDが無い場合はテストビルド
-				continue
-			}
-
-			app, err := m.GetAppByEnvironment(envID)
-			if err != nil {
-				log.WithError(err).WithField("envID", envID).Error("failed to GetAppByEnvironment")
-				continue
-			}
-
-			// 自動デプロイ
-			log.WithField("envID", envID).
-				WithField("buildID", buildID).
-				Error("starting application")
-			err = app.Start(AppStartArgs{
-				EnvironmentID: envID,
-				BuildID:       buildID,
-			})
-			if err != nil {
-				log.WithError(err).
-					WithField("envID", envID).
-					WithField("buildID", buildID).
-					Error("failed to Start Application")
-			}
-		}
-	}
-}
-
-// getFullImageName registryのhost付きのイメージ名を返す
-func (m *managerImpl) getFullImageName(app App) string {
-	if m.config.ImageRegistry == "" {
-		return m.getImageName(app)
-	}
-	return m.config.ImageRegistry + "/" + m.getImageName(app)
-}
-
-// getImageName イメージ名を返す
-func (m *managerImpl) getImageName(app App) string {
-	return m.config.ImageNamePrefix + app.GetID()
-}
-
-func (m *managerImpl) Shutdown(ctx context.Context) error {
-	return nil
-}
diff --git a/pkg/appmanager/repo.go b/pkg/appmanager/repo.go
deleted file mode 100644
index 479525f4..00000000
--- a/pkg/appmanager/repo.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package appmanager
-
-// Repo リポジトリモデル
-type Repo interface {
-	// GetID リポジトリIDを返します
-	GetID() string
-	// GetGitURL リポジトリのGitURLを返します
-	GetGitURL() string
-	// GetWebhookSecret リポジトリのWebhookSecret文字列を返します
-	GetWebhookSecret() string
-	// SetWebhookSecret リポジトリのWebhookSecret文字列を変更します
-	SetWebhookSecret(secret string) error
-}
diff --git a/pkg/appmanager/repo_impl.go b/pkg/appmanager/repo_impl.go
deleted file mode 100644
index 88a989c0..00000000
--- a/pkg/appmanager/repo_impl.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package appmanager
-
-import (
-	"context"
-	"database/sql"
-	"fmt"
-	"github.com/traPtitech/neoshowcase/pkg/models"
-)
-
-func (m *managerImpl) GetRepoByURL(url string) (Repo, error) {
-	repoModel, err := models.Repositories(models.RepositoryWhere.Remote.EQ(url)).One(context.Background(), m.db)
-	if err != nil {
-		if err == sql.ErrNoRows {
-			return nil, ErrNotFound
-		}
-		return nil, fmt.Errorf("failed to GetRepoByURL: %w", err)
-	}
-	return &repoImpl{
-		m:       m,
-		dbModel: repoModel,
-	}, nil
-}
-
-type repoImpl struct {
-	m       *managerImpl
-	dbModel *models.Repository
-}
-
-func (r *repoImpl) GetID() string {
-	return r.dbModel.ID
-}
-
-func (r *repoImpl) GetGitURL() string {
-	return r.dbModel.Remote
-}
-
-func (r *repoImpl) GetWebhookSecret() string {
-	panic("implement me") // TODO
-}
-
-func (r *repoImpl) SetWebhookSecret(secret string) error {
-	panic("implement me") // TODO
-}
diff --git a/pkg/domain/app.go b/pkg/domain/app.go
new file mode 100644
index 00000000..c0f03de3
--- /dev/null
+++ b/pkg/domain/app.go
@@ -0,0 +1,20 @@
+package domain
+
+import "github.com/traPtitech/neoshowcase/pkg/domain/builder"
+
+type Application struct {
+	ID         string
+	Repository Repository
+}
+
+type Environment struct {
+	ID            string
+	ApplicationID string
+	BranchName    string
+	BuildType     builder.BuildType
+}
+
+type Repository struct {
+	ID        string
+	RemoteURL string
+}
diff --git a/pkg/appmanager/models.go b/pkg/domain/builder/build_type.go
similarity index 86%
rename from pkg/appmanager/models.go
rename to pkg/domain/builder/build_type.go
index c8bb9f39..36327e78 100644
--- a/pkg/appmanager/models.go
+++ b/pkg/domain/builder/build_type.go
@@ -1,8 +1,9 @@
-package appmanager
+package builder
 
 import (
 	"fmt"
-	"github.com/traPtitech/neoshowcase/pkg/models"
+
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb/models"
 )
 
 type BuildType int
diff --git a/pkg/domain/builder/registry.go b/pkg/domain/builder/registry.go
index 4ef465b9..9c194d12 100644
--- a/pkg/domain/builder/registry.go
+++ b/pkg/domain/builder/registry.go
@@ -1,3 +1,8 @@
 package builder
 
 type DockerImageRegistryString string
+type DockerImageNamePrefixString string
+
+func GetImageName(registry string, prefix string, appID string) string {
+	return registry + "/" + prefix + appID
+}
diff --git a/pkg/models/boil_queries.go b/pkg/infrastructure/admindb/models/boil_queries.go
similarity index 100%
rename from pkg/models/boil_queries.go
rename to pkg/infrastructure/admindb/models/boil_queries.go
diff --git a/pkg/models/boil_queries_test.go b/pkg/infrastructure/admindb/models/boil_queries_test.go
similarity index 100%
rename from pkg/models/boil_queries_test.go
rename to pkg/infrastructure/admindb/models/boil_queries_test.go
diff --git a/pkg/models/boil_suites_test.go b/pkg/infrastructure/admindb/models/boil_suites_test.go
similarity index 100%
rename from pkg/models/boil_suites_test.go
rename to pkg/infrastructure/admindb/models/boil_suites_test.go
diff --git a/pkg/models/boil_table_names.go b/pkg/infrastructure/admindb/models/boil_table_names.go
similarity index 100%
rename from pkg/models/boil_table_names.go
rename to pkg/infrastructure/admindb/models/boil_table_names.go
diff --git a/pkg/models/boil_types.go b/pkg/infrastructure/admindb/models/boil_types.go
similarity index 100%
rename from pkg/models/boil_types.go
rename to pkg/infrastructure/admindb/models/boil_types.go
diff --git a/pkg/models/build_logs.go b/pkg/infrastructure/admindb/models/build_logs.go
similarity index 100%
rename from pkg/models/build_logs.go
rename to pkg/infrastructure/admindb/models/build_logs.go
diff --git a/pkg/models/build_logs_test.go b/pkg/infrastructure/admindb/models/build_logs_test.go
similarity index 100%
rename from pkg/models/build_logs_test.go
rename to pkg/infrastructure/admindb/models/build_logs_test.go
diff --git a/pkg/models/environments.go b/pkg/infrastructure/admindb/models/environments.go
similarity index 100%
rename from pkg/models/environments.go
rename to pkg/infrastructure/admindb/models/environments.go
diff --git a/pkg/models/environments_test.go b/pkg/infrastructure/admindb/models/environments_test.go
similarity index 100%
rename from pkg/models/environments_test.go
rename to pkg/infrastructure/admindb/models/environments_test.go
diff --git a/pkg/models/mysql_main_test.go b/pkg/infrastructure/admindb/models/mysql_main_test.go
similarity index 100%
rename from pkg/models/mysql_main_test.go
rename to pkg/infrastructure/admindb/models/mysql_main_test.go
diff --git a/pkg/models/mysql_suites_test.go b/pkg/infrastructure/admindb/models/mysql_suites_test.go
similarity index 100%
rename from pkg/models/mysql_suites_test.go
rename to pkg/infrastructure/admindb/models/mysql_suites_test.go
diff --git a/pkg/models/mysql_upsert.go b/pkg/infrastructure/admindb/models/mysql_upsert.go
similarity index 100%
rename from pkg/models/mysql_upsert.go
rename to pkg/infrastructure/admindb/models/mysql_upsert.go
diff --git a/pkg/models/repositories.go b/pkg/infrastructure/admindb/models/repositories.go
similarity index 100%
rename from pkg/models/repositories.go
rename to pkg/infrastructure/admindb/models/repositories.go
diff --git a/pkg/models/repositories_test.go b/pkg/infrastructure/admindb/models/repositories_test.go
similarity index 100%
rename from pkg/models/repositories_test.go
rename to pkg/infrastructure/admindb/models/repositories_test.go
diff --git a/pkg/models/websites.go b/pkg/infrastructure/admindb/models/websites.go
similarity index 100%
rename from pkg/models/websites.go
rename to pkg/infrastructure/admindb/models/websites.go
diff --git a/pkg/models/websites_test.go b/pkg/infrastructure/admindb/models/websites_test.go
similarity index 100%
rename from pkg/models/websites_test.go
rename to pkg/infrastructure/admindb/models/websites_test.go
diff --git a/pkg/infrastructure/backend/backend.go b/pkg/infrastructure/backend/backend.go
index eb67937e..795c60b2 100644
--- a/pkg/infrastructure/backend/backend.go
+++ b/pkg/infrastructure/backend/backend.go
@@ -4,6 +4,7 @@ import (
 	"context"
 
 	"github.com/traPtitech/neoshowcase/pkg/domain"
+	"github.com/volatiletech/null/v8"
 )
 
 type Backend interface {
@@ -11,5 +12,7 @@ type Backend interface {
 	RestartContainer(ctx context.Context, appID string, envID string) error
 	DestroyContainer(ctx context.Context, appID string, envID string) error
 	ListContainers(ctx context.Context) ([]domain.Container, error)
+	RegisterIngress(ctx context.Context, appID string, envID string, host string, destination null.String, port null.Int) error
+	UnregisterIngress(ctx context.Context, appID string, envID string) error
 	Dispose(ctx context.Context) error
 }
diff --git a/pkg/infrastructure/backend/dockerimpl/backend.go b/pkg/infrastructure/backend/dockerimpl/backend.go
index 04c2e2dc..ce59ced3 100644
--- a/pkg/infrastructure/backend/dockerimpl/backend.go
+++ b/pkg/infrastructure/backend/dockerimpl/backend.go
@@ -11,6 +11,8 @@ import (
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/eventbus"
 )
 
+type IngressConfDirPath string
+
 const (
 	appNetwork                     = "neoshowcase_apps"
 	appContainerLabel              = "neoshowcase.trap.jp/app"
@@ -20,21 +22,23 @@ const (
 )
 
 type dockerBackend struct {
-	c           *docker.Client
-	bus         eventbus.Bus
-	dockerEvent chan *docker.APIEvents
+	c              *docker.Client
+	bus            eventbus.Bus
+	dockerEvent    chan *docker.APIEvents
+	ingressConfDir string
 }
 
-func NewDockerBackend(c *docker.Client, bus eventbus.Bus) (backend.Backend, error) {
+func NewDockerBackend(c *docker.Client, bus eventbus.Bus, path IngressConfDirPath) (backend.Backend, error) {
 	// showcase用のネットワークを用意
 	if err := initNetworks(c); err != nil {
 		return nil, fmt.Errorf("failed to init networks: %w", err)
 	}
 
 	b := &dockerBackend{
-		c:           c,
-		bus:         bus,
-		dockerEvent: make(chan *docker.APIEvents, 10),
+		c:              c,
+		bus:            bus,
+		dockerEvent:    make(chan *docker.APIEvents, 10),
+		ingressConfDir: string(path),
 	}
 
 	if err := c.AddEventListener(b.dockerEvent); err != nil {
diff --git a/pkg/infrastructure/backend/dockerimpl/create_container.go b/pkg/infrastructure/backend/dockerimpl/create_container.go
index 3a251667..d7bf9add 100644
--- a/pkg/infrastructure/backend/dockerimpl/create_container.go
+++ b/pkg/infrastructure/backend/dockerimpl/create_container.go
@@ -29,14 +29,6 @@ func (b *dockerBackend) CreateContainer(ctx context.Context, args domain.Contain
 		appContainerEnvironmentIDLabel: args.EnvironmentID,
 	})
 
-	if args.HTTPProxy != nil {
-		labels = util.MergeLabels(labels, map[string]string{
-			"traefik.enable": "true",
-			fmt.Sprintf("traefik.http.routers.nsapp-%s-%s.rule", args.ApplicationID, args.EnvironmentID):                      fmt.Sprintf("Host(`%s`)", args.HTTPProxy.Domain),
-			fmt.Sprintf("traefik.http.services.nsapp-%s-%s.loadbalancer.server.port", args.ApplicationID, args.EnvironmentID): fmt.Sprintf("%d", args.HTTPProxy.Port),
-		})
-	}
-
 	var envs []string
 
 	for name, value := range args.Envs {
diff --git a/pkg/infrastructure/backend/dockerimpl/register_ingress.go b/pkg/infrastructure/backend/dockerimpl/register_ingress.go
new file mode 100644
index 00000000..23e80642
--- /dev/null
+++ b/pkg/infrastructure/backend/dockerimpl/register_ingress.go
@@ -0,0 +1,52 @@
+package dockerimpl
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"path/filepath"
+	"text/template"
+
+	"github.com/volatiletech/null/v8"
+)
+
+var ingressTmpl = template.Must(template.New("ingress").Parse(ingressTmplString))
+
+const ingressTmplString = `
+http:
+  routers:
+    nsapp-{{.AppID}}-{{.EnvID}}:
+      service: "nsapp-{{.AppID}}-{{.EnvID}}"
+      rule: "Host('{{.Host}}')"
+  services:
+    nsapp-{{.AppID}}-{{.EnvID}}:
+      loadBalancer:
+        servers:
+        - url: http://{{.Destination}}:{{.Port}}
+`
+
+func (b *dockerBackend) RegisterIngress(ctx context.Context, appID string, envID string, host string, destination null.String, port null.Int) error {
+	conf := filepath.Join(b.ingressConfDir, containerName(appID, envID)+".yaml")
+
+	data := map[string]interface{}{
+		"AppID":       appID,
+		"EnvID":       envID,
+		"Host":        host,
+		"Destination": containerName(appID, envID),
+		"Port":        80,
+	}
+	if destination.Valid {
+		data["Destination"] = destination.String
+	}
+	if port.Valid {
+		data["Port"] = port.Int
+	}
+
+	f, err := os.OpenFile(conf, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.ModePerm)
+	if err != nil {
+		return fmt.Errorf("failed to open file: %w", err)
+	}
+	defer f.Close()
+
+	return ingressTmpl.Execute(f, data)
+}
diff --git a/pkg/infrastructure/backend/dockerimpl/unregister_ingress.go b/pkg/infrastructure/backend/dockerimpl/unregister_ingress.go
new file mode 100644
index 00000000..d48a4784
--- /dev/null
+++ b/pkg/infrastructure/backend/dockerimpl/unregister_ingress.go
@@ -0,0 +1,17 @@
+package dockerimpl
+
+import (
+	"context"
+	"os"
+	"path/filepath"
+
+	"github.com/traPtitech/neoshowcase/pkg/util"
+)
+
+func (b *dockerBackend) UnregisterIngress(ctx context.Context, appID string, envID string) error {
+	conf := filepath.Join(b.ingressConfDir, containerName(appID, envID)+".yaml")
+	if util.FileExists(conf) {
+		return os.Remove(conf)
+	}
+	return nil
+}
diff --git a/pkg/infrastructure/backend/k8simpl/create_container.go b/pkg/infrastructure/backend/k8simpl/create_container.go
index 9baa888d..cb37680e 100644
--- a/pkg/infrastructure/backend/k8simpl/create_container.go
+++ b/pkg/infrastructure/backend/k8simpl/create_container.go
@@ -8,7 +8,6 @@ import (
 	"github.com/traPtitech/neoshowcase/pkg/domain"
 	"github.com/traPtitech/neoshowcase/pkg/util"
 	apiv1 "k8s.io/api/core/v1"
-	networkingv1 "k8s.io/api/networking/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/intstr"
@@ -66,41 +65,6 @@ func (b *k8sBackend) CreateContainer(ctx context.Context, args domain.ContainerC
 				},
 			},
 		}
-		ingress := &networkingv1.Ingress{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:      deploymentName(args.ApplicationID, args.EnvironmentID),
-				Namespace: appNamespace,
-				Labels:    labels,
-				Annotations: map[string]string{
-					"traefik.ingress.kubernetes.io/router.entrypoints": "web, websecure", // TODO HTTPS可能かどうかを判断
-				},
-			},
-			Spec: networkingv1.IngressSpec{
-				Rules: []networkingv1.IngressRule{
-					{
-						Host: args.HTTPProxy.Domain,
-						IngressRuleValue: networkingv1.IngressRuleValue{
-							HTTP: &networkingv1.HTTPIngressRuleValue{
-								Paths: []networkingv1.HTTPIngressPath{
-									{
-										Path:     "/",
-										PathType: pathTypePtr(networkingv1.PathTypePrefix),
-										Backend: networkingv1.IngressBackend{
-											Service: &networkingv1.IngressServiceBackend{
-												Name: deploymentName(args.ApplicationID, args.EnvironmentID),
-												Port: networkingv1.ServiceBackendPort{
-													Number: 80,
-												},
-											},
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		}
 
 		if _, err := b.clientset.CoreV1().Services(appNamespace).Create(ctx, svc, metav1.CreateOptions{}); err != nil {
 			if args.Recreate && errors.IsAlreadyExists(err) {
@@ -114,15 +78,6 @@ func (b *k8sBackend) CreateContainer(ctx context.Context, args domain.ContainerC
 				return fmt.Errorf("failed to create service: %w", err)
 			}
 		}
-		if _, err := b.clientset.NetworkingV1().Ingresses(appNamespace).Create(ctx, ingress, metav1.CreateOptions{}); err != nil {
-			if args.Recreate && errors.IsAlreadyExists(err) {
-				if _, err = b.clientset.NetworkingV1().Ingresses(appNamespace).Update(ctx, ingress, metav1.UpdateOptions{}); err != nil {
-					return fmt.Errorf("failed to update ingress: %w", err)
-				}
-			} else {
-				return fmt.Errorf("failed to create ingress: %w", err)
-			}
-		}
 	}
 
 	pod := &apiv1.Pod{
diff --git a/pkg/infrastructure/backend/k8simpl/destroy_container.go b/pkg/infrastructure/backend/k8simpl/destroy_container.go
index 4eb3b441..8b936dc1 100644
--- a/pkg/infrastructure/backend/k8simpl/destroy_container.go
+++ b/pkg/infrastructure/backend/k8simpl/destroy_container.go
@@ -20,10 +20,5 @@ func (b *k8sBackend) DestroyContainer(ctx context.Context, appID string, envID s
 		return fmt.Errorf("failed to delete service: %w", err)
 	}
 
-	err = b.clientset.NetworkingV1().Ingresses(appNamespace).Delete(ctx, name, metav1.DeleteOptions{})
-	if err != nil && !errors.IsNotFound(err) {
-		return fmt.Errorf("failed to delete ingress: %w", err)
-	}
-
 	return nil
 }
diff --git a/pkg/infrastructure/backend/k8simpl/register_ingress.go b/pkg/infrastructure/backend/k8simpl/register_ingress.go
new file mode 100644
index 00000000..bf2e1d59
--- /dev/null
+++ b/pkg/infrastructure/backend/k8simpl/register_ingress.go
@@ -0,0 +1,71 @@
+package k8simpl
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/volatiletech/null/v8"
+	networkingv1 "k8s.io/api/networking/v1"
+	"k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func (b *k8sBackend) RegisterIngress(ctx context.Context, appID string, envID string, host string, destination null.String, port null.Int) error {
+	labels := map[string]string{
+		appContainerLabel:              "true",
+		appContainerApplicationIDLabel: appID,
+		appContainerEnvironmentIDLabel: envID,
+	}
+
+	svc := &networkingv1.IngressServiceBackend{
+		Name: deploymentName(appID, envID),
+		Port: networkingv1.ServiceBackendPort{
+			Number: 80,
+		},
+	}
+	if destination.Valid {
+		svc.Name = destination.String
+	}
+	if port.Valid {
+		svc.Port.Number = int32(port.Int)
+	}
+
+	ingress := &networkingv1.Ingress{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      deploymentName(appID, envID),
+			Namespace: appNamespace,
+			Labels:    labels,
+		},
+		Spec: networkingv1.IngressSpec{
+			Rules: []networkingv1.IngressRule{
+				{
+					Host: host,
+					IngressRuleValue: networkingv1.IngressRuleValue{
+						HTTP: &networkingv1.HTTPIngressRuleValue{
+							Paths: []networkingv1.HTTPIngressPath{
+								{
+									Path:     "/",
+									PathType: pathTypePtr(networkingv1.PathTypePrefix),
+									Backend: networkingv1.IngressBackend{
+										Service: svc,
+									},
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+	}
+
+	if _, err := b.clientset.NetworkingV1().Ingresses(appNamespace).Create(ctx, ingress, metav1.CreateOptions{}); err != nil {
+		if errors.IsAlreadyExists(err) {
+			if _, err = b.clientset.NetworkingV1().Ingresses(appNamespace).Update(ctx, ingress, metav1.UpdateOptions{}); err != nil {
+				return fmt.Errorf("failed to update ingress: %w", err)
+			}
+		} else {
+			return fmt.Errorf("failed to create ingress: %w", err)
+		}
+	}
+	return nil
+}
diff --git a/pkg/infrastructure/backend/k8simpl/unregister_ingress.go b/pkg/infrastructure/backend/k8simpl/unregister_ingress.go
new file mode 100644
index 00000000..cf99f996
--- /dev/null
+++ b/pkg/infrastructure/backend/k8simpl/unregister_ingress.go
@@ -0,0 +1,18 @@
+package k8simpl
+
+import (
+	"context"
+	"fmt"
+
+	"k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func (b *k8sBackend) UnregisterIngress(ctx context.Context, appID string, envID string) error {
+	name := deploymentName(appID, envID)
+	err := b.clientset.NetworkingV1().Ingresses(appNamespace).Delete(ctx, name, metav1.DeleteOptions{})
+	if err != nil && !errors.IsNotFound(err) {
+		return fmt.Errorf("failed to delete ingress: %w", err)
+	}
+	return nil
+}
diff --git a/pkg/infrastructure/storage/storage.go b/pkg/infrastructure/storage/storage.go
index 7d03f268..b776b6c3 100644
--- a/pkg/infrastructure/storage/storage.go
+++ b/pkg/infrastructure/storage/storage.go
@@ -12,7 +12,7 @@ import (
 	"time"
 
 	log "github.com/sirupsen/logrus"
-	"github.com/traPtitech/neoshowcase/pkg/models"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb/models"
 	"github.com/volatiletech/sqlboiler/v4/boil"
 )
 
diff --git a/pkg/interface/broker/builder_events.go b/pkg/interface/broker/builder_events.go
new file mode 100644
index 00000000..77b279a3
--- /dev/null
+++ b/pkg/interface/broker/builder_events.go
@@ -0,0 +1,68 @@
+package broker
+
+import (
+	"context"
+	"fmt"
+	"io"
+
+	log "github.com/sirupsen/logrus"
+	"github.com/traPtitech/neoshowcase/pkg/domain/event"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/eventbus"
+	"github.com/traPtitech/neoshowcase/pkg/interface/grpc/pb"
+	"github.com/traPtitech/neoshowcase/pkg/util"
+	"google.golang.org/protobuf/types/known/emptypb"
+)
+
+type BuilderEventsBroker interface {
+	Run() error
+}
+
+type builderEventsBroker struct {
+	bus    eventbus.Bus
+	client pb.BuilderServiceClient
+}
+
+func NewBuilderEventsBroker(client pb.BuilderServiceClient, bus eventbus.Bus) (BuilderEventsBroker, error) {
+	return &builderEventsBroker{
+		bus:    bus,
+		client: client,
+	}, nil
+}
+
+func (b *builderEventsBroker) Run() error {
+	stream, err := b.client.ConnectEventStream(context.Background(), &emptypb.Empty{})
+	if err != nil {
+		return fmt.Errorf("failed to connect events tream: %w", err)
+	}
+
+	for {
+		ev, err := stream.Recv()
+		if err == io.EOF {
+			log.Debug("builder event stream was closed: EOF")
+			break
+		}
+		if err != nil {
+			log.WithError(err).
+				Debug("builder event stream was disconnected with error")
+			return err
+		}
+
+		payload := util.FromJSON(ev.Body)
+
+		log.WithField("type", ev.Type).
+			WithField("payload", payload).
+			Info("builder event received")
+
+		switch ev.Type {
+		case pb.Event_BUILD_STARTED:
+			b.bus.Publish(event.BuilderBuildStarted, payload)
+		case pb.Event_BUILD_SUCCEEDED:
+			b.bus.Publish(event.BuilderBuildSucceeded, payload)
+		case pb.Event_BUILD_FAILED:
+			b.bus.Publish(event.BuilderBuildFailed, payload)
+		case pb.Event_BUILD_CANCELED:
+			b.bus.Publish(event.BuilderBuildCanceled, payload)
+		}
+	}
+	return nil
+}
diff --git a/pkg/interface/grpc/builder_service_client.go b/pkg/interface/grpc/builder_service_client.go
new file mode 100644
index 00000000..afb27e1d
--- /dev/null
+++ b/pkg/interface/grpc/builder_service_client.go
@@ -0,0 +1,34 @@
+package grpc
+
+import (
+	"github.com/traPtitech/neoshowcase/pkg/interface/grpc/pb"
+	"google.golang.org/grpc"
+)
+
+type BuilderServiceClientConn struct {
+	*grpc.ClientConn
+}
+
+type BuilderServiceClientConfig struct {
+	Insecure bool   `mapstructure:"insecure" yaml:"insecure"`
+	Addr     string `mapstructure:"addr" yaml:"addr"`
+}
+
+func (c *BuilderServiceClientConfig) provideClientConfig() ClientConfig {
+	return ClientConfig{
+		Insecure: c.Insecure,
+		Addr:     c.Addr,
+	}
+}
+
+func NewBuilderServiceClientConn(c BuilderServiceClientConfig) (*BuilderServiceClientConn, error) {
+	conn, err := NewClient(c.provideClientConfig())
+	if err != nil {
+		return nil, err
+	}
+	return &BuilderServiceClientConn{ClientConn: conn}, nil
+}
+
+func NewBuilderServiceClient(cc *BuilderServiceClientConn) pb.BuilderServiceClient {
+	return pb.NewBuilderServiceClient(cc.ClientConn)
+}
diff --git a/pkg/interface/grpc/grpc.go b/pkg/interface/grpc/grpc.go
index 5fd6ab98..2dcf1fc8 100644
--- a/pkg/interface/grpc/grpc.go
+++ b/pkg/interface/grpc/grpc.go
@@ -12,3 +12,16 @@ func NewServer() *grpc.Server {
 	reflection.Register(s)
 	return s
 }
+
+type ClientConfig struct {
+	Insecure bool   `mapstructure:"insecure" yaml:"insecure"`
+	Addr     string `mapstructure:"addr" yaml:"addr"`
+}
+
+func NewClient(c ClientConfig) (*grpc.ClientConn, error) {
+	var opts []grpc.DialOption
+	if c.Insecure {
+		opts = append(opts, grpc.WithInsecure())
+	}
+	return grpc.Dial(c.Addr, opts...)
+}
diff --git a/pkg/interface/grpc/static_site_service.go b/pkg/interface/grpc/static_site_service.go
index 0faee669..36a553bc 100644
--- a/pkg/interface/grpc/static_site_service.go
+++ b/pkg/interface/grpc/static_site_service.go
@@ -10,12 +10,12 @@ import (
 )
 
 type StaticSiteService struct {
-	svc usecase.StaticSiteService
+	svc usecase.StaticSiteServerService
 
 	pb.UnimplementedStaticSiteServiceServer
 }
 
-func NewStaticSiteServiceServer(svc usecase.StaticSiteService) *StaticSiteService {
+func NewStaticSiteServiceServer(svc usecase.StaticSiteServerService) *StaticSiteService {
 	return &StaticSiteService{svc: svc}
 }
 
diff --git a/pkg/interface/grpc/static_site_service_client.go b/pkg/interface/grpc/static_site_service_client.go
new file mode 100644
index 00000000..3ff44899
--- /dev/null
+++ b/pkg/interface/grpc/static_site_service_client.go
@@ -0,0 +1,34 @@
+package grpc
+
+import (
+	"github.com/traPtitech/neoshowcase/pkg/interface/grpc/pb"
+	"google.golang.org/grpc"
+)
+
+type StaticSiteServiceClientConn struct {
+	*grpc.ClientConn
+}
+
+type StaticSiteServiceClientConfig struct {
+	Insecure bool   `mapstructure:"insecure" yaml:"insecure"`
+	Addr     string `mapstructure:"addr" yaml:"addr"`
+}
+
+func (c *StaticSiteServiceClientConfig) provideClientConfig() ClientConfig {
+	return ClientConfig{
+		Insecure: c.Insecure,
+		Addr:     c.Addr,
+	}
+}
+
+func NewStaticSiteServiceClientConn(c StaticSiteServiceClientConfig) (*StaticSiteServiceClientConn, error) {
+	conn, err := NewClient(c.provideClientConfig())
+	if err != nil {
+		return nil, err
+	}
+	return &StaticSiteServiceClientConn{ClientConn: conn}, nil
+}
+
+func NewStaticSiteServiceClient(cc *StaticSiteServiceClientConn) pb.StaticSiteServiceClient {
+	return pb.NewStaticSiteServiceClient(cc.ClientConn)
+}
diff --git a/pkg/interface/repository/application.go b/pkg/interface/repository/application.go
new file mode 100644
index 00000000..bbc65c77
--- /dev/null
+++ b/pkg/interface/repository/application.go
@@ -0,0 +1,252 @@
+package repository
+
+import (
+	"context"
+	"database/sql"
+	"fmt"
+
+	log "github.com/sirupsen/logrus"
+	"github.com/traPtitech/neoshowcase/pkg/domain"
+	"github.com/traPtitech/neoshowcase/pkg/domain/builder"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb/models"
+	"github.com/volatiletech/sqlboiler/v4/boil"
+	"github.com/volatiletech/sqlboiler/v4/queries/qm"
+)
+
+type ApplicationRepository interface {
+	CreateApplication(ctx context.Context, args CreateApplicationArgs) (*domain.Application, error)
+	GetApplicationByID(ctx context.Context, id string) (*domain.Application, error)
+	CreateEnvironment(ctx context.Context, appID string, branchName string, buildType builder.BuildType) (*domain.Environment, error)
+	GetEnvironmentByID(ctx context.Context, id string) (*domain.Environment, error)
+	GetEnvironmentByRepoAndBranch(ctx context.Context, repoURL string, branch string) (*domain.Environment, error)
+	SetWebsite(ctx context.Context, envID string, fqdn string, httpPort int) error
+}
+
+type applicationRepository struct {
+	db *sql.DB
+}
+
+func NewApplicationRepository(db *sql.DB) ApplicationRepository {
+	return &applicationRepository{
+		db: db,
+	}
+}
+
+type CreateApplicationArgs struct {
+	Owner         string
+	Name          string
+	RepositoryURL string
+	BranchName    string
+	BuildType     builder.BuildType
+}
+
+func (r *applicationRepository) CreateApplication(ctx context.Context, args CreateApplicationArgs) (*domain.Application, error) {
+	const errMsg = "failed to CreateApplication: %w"
+
+	// リポジトリ情報を設定
+	repo, err := models.Repositories(models.RepositoryWhere.Remote.EQ(args.RepositoryURL)).One(ctx, r.db)
+	if err != nil && err != sql.ErrNoRows {
+		return nil, fmt.Errorf(errMsg, err)
+	} else if repo == nil {
+		repo = &models.Repository{
+			ID:     domain.NewID(),
+			Remote: args.RepositoryURL,
+		}
+		if err := repo.Insert(ctx, r.db, boil.Infer()); err != nil {
+			return nil, fmt.Errorf(errMsg, err)
+		}
+	}
+
+	// アプリケーション作成
+	app := &models.Application{
+		ID:           domain.NewID(),
+		Owner:        args.Owner,
+		Name:         args.Name,
+		RepositoryID: repo.ID,
+	}
+	if err := app.Insert(ctx, r.db, boil.Infer()); err != nil {
+		return nil, fmt.Errorf(errMsg, err)
+	}
+
+	log.WithField("appID", app.ID).
+		Info("app created")
+
+	// 初期Env作成
+	env := &models.Environment{
+		ID:         domain.NewID(),
+		BranchName: args.BranchName,
+		BuildType:  args.BuildType.String(),
+	}
+	if err := app.AddEnvironments(ctx, r.db, true, env); err != nil {
+		return nil, fmt.Errorf(errMsg, err)
+	}
+
+	log.WithField("appID", app.ID).
+		WithField("envID", env.ID).
+		Info("env created")
+
+	return &domain.Application{
+		ID: app.ID,
+		Repository: domain.Repository{
+			ID:        repo.ID,
+			RemoteURL: repo.Remote,
+		},
+	}, nil
+}
+
+func (r *applicationRepository) GetApplicationByID(ctx context.Context, id string) (*domain.Application, error) {
+	const errMsg = "failed to GetApplicationByID: %w"
+
+	app, err := models.Applications(
+		qm.Load(models.ApplicationRels.Repository),
+		models.ApplicationWhere.ID.EQ(id),
+		models.ApplicationWhere.DeletedAt.IsNull(),
+	).One(ctx, r.db)
+	if err != nil {
+		if err == sql.ErrNoRows {
+			return nil, ErrNotFound
+		}
+		return nil, fmt.Errorf(errMsg, err)
+	}
+
+	return &domain.Application{
+		ID: app.ID,
+		Repository: domain.Repository{
+			ID:        app.R.Repository.ID,
+			RemoteURL: app.R.Repository.Remote,
+		},
+	}, nil
+}
+
+func (r *applicationRepository) CreateEnvironment(ctx context.Context, appID string, branchName string, buildType builder.BuildType) (*domain.Environment, error) {
+	const errMsg = "failed to CreateEnvironment: %w"
+
+	app, err := models.Applications(
+		qm.Load(models.ApplicationRels.Environments, models.EnvironmentWhere.BranchName.EQ(branchName)),
+		models.ApplicationWhere.ID.EQ(appID),
+		models.ApplicationWhere.DeletedAt.IsNull(),
+	).One(ctx, r.db)
+	if err != nil {
+		if err == sql.ErrNoRows {
+			return nil, ErrNotFound
+		}
+		return nil, fmt.Errorf(errMsg, err)
+	}
+
+	// 指定したブランチのEnvironmentが存在しないことを確認
+	if len(app.R.Environments) > 0 {
+		return nil, fmt.Errorf("the environment for branch `%s` has already existed", branchName)
+	}
+
+	env := &models.Environment{
+		ID:         domain.NewID(),
+		BranchName: branchName,
+		BuildType:  buildType.String(),
+	}
+	if err := app.AddEnvironments(ctx, r.db, true, env); err != nil {
+		return nil, fmt.Errorf(errMsg, err)
+	}
+
+	log.WithField("appID", env.ApplicationID).
+		WithField("envID", env.ID).
+		Info("env created")
+
+	return &domain.Environment{
+		ID:            env.ID,
+		ApplicationID: env.ApplicationID,
+		BranchName:    env.BranchName,
+		BuildType:     builder.BuildTypeFromString(env.BuildType),
+	}, nil
+}
+
+func (r *applicationRepository) GetEnvironmentByID(ctx context.Context, id string) (*domain.Environment, error) {
+	const errMsg = "failed to GetEnvironmentByID: %w"
+
+	env, err := models.FindEnvironment(ctx, r.db, id)
+	if err != nil {
+		if err == sql.ErrNoRows {
+			return nil, ErrNotFound
+		}
+		return nil, fmt.Errorf(errMsg, err)
+	}
+
+	return &domain.Environment{
+		ID:            env.ID,
+		ApplicationID: env.ApplicationID,
+		BranchName:    env.BranchName,
+		BuildType:     builder.BuildTypeFromString(env.BuildType),
+	}, nil
+}
+
+func (r *applicationRepository) GetEnvironmentByRepoAndBranch(ctx context.Context, repoURL string, branch string) (*domain.Environment, error) {
+	const errMsg = "failed to GetEnvironmentByRepoAndBranch: %w"
+
+	repo, err := models.Repositories(
+		models.RepositoryWhere.Remote.EQ(repoURL),
+	).One(ctx, r.db)
+	if err != nil {
+		if err == sql.ErrNoRows {
+			return nil, ErrNotFound
+		}
+		return nil, fmt.Errorf(errMsg, err)
+	}
+
+	app, err := repo.Applications(
+		qm.Load(models.ApplicationRels.Environments, models.EnvironmentWhere.BranchName.EQ(branch)),
+		models.ApplicationWhere.DeletedAt.IsNull(),
+	).One(ctx, r.db)
+	if err != nil {
+		if err == sql.ErrNoRows {
+			return nil, ErrNotFound
+		}
+		return nil, fmt.Errorf(errMsg, err)
+	}
+
+	if len(app.R.Environments) > 0 {
+		env := app.R.Environments[0]
+		return &domain.Environment{
+			ID:            env.ID,
+			ApplicationID: env.ApplicationID,
+			BranchName:    env.BranchName,
+			BuildType:     builder.BuildTypeFromString(env.BuildType),
+		}, nil
+	}
+	return nil, ErrNotFound
+}
+
+func (r *applicationRepository) SetWebsite(ctx context.Context, envID string, fqdn string, httpPort int) error {
+	const errMsg = "failed to SetWebsite: %w"
+
+	env, err := models.Environments(
+		qm.Load(models.EnvironmentRels.Website),
+		models.EnvironmentWhere.ID.EQ(envID),
+	).One(ctx, r.db)
+	if err != nil {
+		if err == sql.ErrNoRows {
+			return ErrNotFound
+		}
+		return fmt.Errorf(errMsg, err)
+	}
+
+	ws := env.R.Website
+	if ws != nil {
+		// テーブルの情報を更新
+		ws.FQDN = fqdn
+		ws.HTTPPort = httpPort
+		if _, err := ws.Update(ctx, r.db, boil.Infer()); err != nil {
+			return fmt.Errorf(errMsg, err)
+		}
+		return nil
+	}
+
+	// Websiteをテーブルに挿入
+	ws = &models.Website{
+		ID:       domain.NewID(),
+		FQDN:     fqdn,
+		HTTPPort: httpPort,
+	}
+	if err := env.SetWebsite(ctx, r.db, true, ws); err != nil {
+		return fmt.Errorf(errMsg, err)
+	}
+	return nil
+}
diff --git a/pkg/interface/repository/webhook_secret.go b/pkg/interface/repository/webhook_secret.go
index d5154ff9..92496092 100644
--- a/pkg/interface/repository/webhook_secret.go
+++ b/pkg/interface/repository/webhook_secret.go
@@ -5,7 +5,7 @@ import (
 	"database/sql"
 	"fmt"
 
-	"github.com/traPtitech/neoshowcase/pkg/models"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb/models"
 )
 
 //go:generate go run github.com/golang/mock/mockgen -source=$GOFILE -package=mock_$GOPACKAGE -destination=./mock/$GOFILE
@@ -24,8 +24,7 @@ func NewWebhookSecretRepository(db *sql.DB) WebhookSecretRepository {
 }
 
 func (r *webhookSecretRepository) GetWebhookSecretKeys(ctx context.Context, repositoryUrl string) ([]string, error) {
-	_, err := models.
-		Repositories(models.RepositoryWhere.Remote.EQ(repositoryUrl)).
+	_, err := models.Repositories(models.RepositoryWhere.Remote.EQ(repositoryUrl)).
 		One(ctx, r.db)
 	if err != nil {
 		if err == sql.ErrNoRows {
diff --git a/pkg/usecase/app_build_service.go b/pkg/usecase/app_build_service.go
new file mode 100644
index 00000000..cee4f38c
--- /dev/null
+++ b/pkg/usecase/app_build_service.go
@@ -0,0 +1,79 @@
+package usecase
+
+import (
+	"context"
+	"fmt"
+
+	log "github.com/sirupsen/logrus"
+	"github.com/traPtitech/neoshowcase/pkg/domain"
+	"github.com/traPtitech/neoshowcase/pkg/domain/builder"
+	"github.com/traPtitech/neoshowcase/pkg/interface/grpc/pb"
+	"github.com/traPtitech/neoshowcase/pkg/interface/repository"
+)
+
+type AppBuildService interface {
+	QueueBuild(ctx context.Context, env *domain.Environment) error
+}
+
+type appBuildService struct {
+	repo    repository.ApplicationRepository
+	builder pb.BuilderServiceClient
+
+	imageRegistry   string
+	imageNamePrefix string
+}
+
+func NewAppBuildService(repo repository.ApplicationRepository, builder pb.BuilderServiceClient, registry builder.DockerImageRegistryString, prefix builder.DockerImageNamePrefixString) AppBuildService {
+	return &appBuildService{
+		repo:            repo,
+		builder:         builder,
+		imageRegistry:   string(registry),
+		imageNamePrefix: string(prefix),
+	}
+}
+
+func (s *appBuildService) QueueBuild(ctx context.Context, env *domain.Environment) error {
+	app, err := s.repo.GetApplicationByID(ctx, env.ApplicationID)
+	if err != nil {
+		return fmt.Errorf("failed to QueueBuild: %w", err)
+	}
+
+	// TODO キューに入れて、非同期で処理する
+	return s.requestBuild(ctx, app, env)
+}
+
+func (s *appBuildService) requestBuild(ctx context.Context, app *domain.Application, env *domain.Environment) error {
+	switch env.BuildType {
+	case builder.BuildTypeImage:
+		_, err := s.builder.StartBuildImage(ctx, &pb.StartBuildImageRequest{
+			ImageName: builder.GetImageName(s.imageNamePrefix, s.imageNamePrefix, env.ApplicationID),
+			Source: &pb.BuildSource{
+				RepositoryUrl: app.Repository.RemoteURL, // TODO ブランチ・タグ指定に対応
+			},
+			Options:       &pb.BuildOptions{}, // TODO 汎用ベースイメージビルドに対応させる
+			EnvironmentId: env.ID,
+		})
+		if err != nil {
+			return fmt.Errorf("builder failed to start build image: %w", err)
+		}
+
+	case builder.BuildTypeStatic:
+		_, err := s.builder.StartBuildStatic(ctx, &pb.StartBuildStaticRequest{
+			Source: &pb.BuildSource{
+				RepositoryUrl: app.Repository.RemoteURL, // TODO ブランチ・タグ指定に対応
+			},
+			Options:       &pb.BuildOptions{}, // TODO 汎用ベースイメージビルドに対応させる
+			EnvironmentId: env.ID,
+		})
+		if err != nil {
+			return fmt.Errorf("builder failed to start build static: %w", err)
+		}
+
+	default:
+		return fmt.Errorf("unknown build type: %s", env.BuildType)
+	}
+
+	log.WithField("envID", env.ID).
+		Info("build requested")
+	return nil
+}
diff --git a/pkg/usecase/app_deploy_service.go b/pkg/usecase/app_deploy_service.go
new file mode 100644
index 00000000..e107ee4e
--- /dev/null
+++ b/pkg/usecase/app_deploy_service.go
@@ -0,0 +1,148 @@
+package usecase
+
+import (
+	"context"
+	"database/sql"
+	"fmt"
+	"time"
+
+	log "github.com/sirupsen/logrus"
+	"github.com/traPtitech/neoshowcase/pkg/domain"
+	"github.com/traPtitech/neoshowcase/pkg/domain/builder"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb/models"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/backend"
+	"github.com/traPtitech/neoshowcase/pkg/interface/grpc/pb"
+	"github.com/volatiletech/null/v8"
+	"github.com/volatiletech/sqlboiler/v4/boil"
+	"github.com/volatiletech/sqlboiler/v4/queries/qm"
+)
+
+type AppDeployService interface {
+	QueueDeployment(ctx context.Context, envID string, buildID string) error
+}
+
+type appDeployService struct {
+	backend backend.Backend
+	ss      pb.StaticSiteServiceClient
+
+	imageRegistry   string
+	imageNamePrefix string
+
+	// TODO 後で消す
+	db *sql.DB
+}
+
+func NewAppDeployService(backend backend.Backend, ss pb.StaticSiteServiceClient, registry builder.DockerImageRegistryString, prefix builder.DockerImageNamePrefixString, db *sql.DB) AppDeployService {
+	return &appDeployService{
+		backend:         backend,
+		ss:              ss,
+		imageRegistry:   string(registry),
+		imageNamePrefix: string(prefix),
+		db:              db,
+	}
+}
+
+func (s *appDeployService) QueueDeployment(ctx context.Context, envID string, buildID string) error {
+	env, err := models.Environments(
+		qm.Load(models.EnvironmentRels.Website),
+		models.EnvironmentWhere.ID.EQ(envID),
+	).One(ctx, s.db)
+	if err != nil {
+		if err == sql.ErrNoRows {
+			return fmt.Errorf("environment (%s) was not found", envID)
+		}
+		return fmt.Errorf("failed to get Environment: %w", err)
+	}
+
+	ok, err := env.BuildLogs(
+		models.BuildLogWhere.ID.EQ(buildID),
+		models.BuildLogWhere.Result.EQ(models.BuildLogsResultSUCCEEDED),
+	).Exists(ctx, s.db)
+	if err != nil {
+		return fmt.Errorf("failed to BuildLogExists: %w", err)
+	}
+	if !ok {
+		return fmt.Errorf("build (%s) was not found", buildID)
+	}
+
+	entry := &appDeployment{
+		EnvID:    envID,
+		BuildID:  buildID,
+		QueuedAt: time.Now(),
+		env:      env,
+	}
+	// TODO ちゃんとキューに入れて非同期処理する
+	go s.deploy(entry)
+	return nil
+}
+
+type appDeployment struct {
+	EnvID    string
+	BuildID  string
+	QueuedAt time.Time
+	env      *models.Environment
+}
+
+func (s *appDeployService) deploy(entry *appDeployment) {
+	env := entry.env
+	website := env.R.Website
+
+	// TODO Ingressの設定がここでする必要があるかどうか確認する
+	switch builder.BuildTypeFromString(env.BuildType) {
+	case builder.BuildTypeImage:
+		var httpProxy *domain.ContainerHTTPProxy
+		if website != nil {
+			httpProxy = &domain.ContainerHTTPProxy{
+				Domain: website.FQDN,
+				Port:   website.HTTPPort,
+			}
+		}
+
+		err := s.backend.CreateContainer(context.Background(), domain.ContainerCreateArgs{
+			ApplicationID: env.ApplicationID,
+			EnvironmentID: env.ID,
+			ImageName:     builder.GetImageName(s.imageRegistry, s.imageNamePrefix, env.ApplicationID),
+			ImageTag:      entry.BuildID,
+			HTTPProxy:     httpProxy,
+			Recreate:      true,
+		})
+		if err != nil {
+			log.WithField("envID", entry.EnvID).
+				WithField("buildID", entry.BuildID).
+				WithField("queuedAt", entry.QueuedAt).
+				WithError(err).
+				Errorf("failed to create container")
+			return
+		}
+
+		env.BuildID = null.StringFrom(entry.BuildID)
+		if _, err := env.Update(context.Background(), s.db, boil.Infer()); err != nil {
+			log.WithField("envID", entry.EnvID).
+				WithField("buildID", entry.BuildID).
+				WithField("queuedAt", entry.QueuedAt).
+				WithError(err).
+				Errorf("failed to update env")
+			return
+		}
+
+	case builder.BuildTypeStatic:
+		env.BuildID = null.StringFrom(entry.BuildID)
+		if _, err := env.Update(context.Background(), s.db, boil.Infer()); err != nil {
+			log.WithField("envID", entry.EnvID).
+				WithField("buildID", entry.BuildID).
+				WithField("queuedAt", entry.QueuedAt).
+				WithError(err).
+				Errorf("failed to update env")
+			return
+		}
+
+		if _, err := s.ss.Reload(context.Background(), &pb.ReloadRequest{}); err != nil {
+			log.WithField("envID", entry.EnvID).
+				WithField("buildID", entry.BuildID).
+				WithField("queuedAt", entry.QueuedAt).
+				WithError(err).
+				Errorf("failed to reload StaticSiteServer")
+			return
+		}
+	}
+}
diff --git a/pkg/usecase/builder_service.go b/pkg/usecase/builder_service.go
index a59f7a45..0650f487 100644
--- a/pkg/usecase/builder_service.go
+++ b/pkg/usecase/builder_service.go
@@ -23,9 +23,9 @@ import (
 	"github.com/traPtitech/neoshowcase/pkg/domain"
 	"github.com/traPtitech/neoshowcase/pkg/domain/builder"
 	"github.com/traPtitech/neoshowcase/pkg/domain/event"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb/models"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/eventbus"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/storage"
-	"github.com/traPtitech/neoshowcase/pkg/models"
 	"github.com/volatiletech/null/v8"
 	"github.com/volatiletech/sqlboiler/v4/boil"
 	"golang.org/x/sync/errgroup"
diff --git a/pkg/usecase/continuous_deployment_service.go b/pkg/usecase/continuous_deployment_service.go
new file mode 100644
index 00000000..3963a4b2
--- /dev/null
+++ b/pkg/usecase/continuous_deployment_service.go
@@ -0,0 +1,103 @@
+package usecase
+
+import (
+	"context"
+
+	log "github.com/sirupsen/logrus"
+	"github.com/traPtitech/neoshowcase/pkg/domain/event"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/eventbus"
+	"github.com/traPtitech/neoshowcase/pkg/interface/repository"
+)
+
+type ContinuousDeploymentService interface {
+	Run()
+	Stop(ctx context.Context) error
+}
+
+type continuousDeploymentService struct {
+	bus      eventbus.Bus
+	repo     repository.ApplicationRepository
+	deployer AppDeployService
+	builder  AppBuildService
+}
+
+func NewContinuousDeploymentService(bus eventbus.Bus, repo repository.ApplicationRepository, deployer AppDeployService, builder AppBuildService) ContinuousDeploymentService {
+	return &continuousDeploymentService{
+		bus:      bus,
+		repo:     repo,
+		deployer: deployer,
+		builder:  builder,
+	}
+}
+
+func (cd *continuousDeploymentService) Run() {
+	cd.loop()
+}
+
+func (cd *continuousDeploymentService) Stop(ctx context.Context) error {
+	return nil
+}
+
+func (cd *continuousDeploymentService) loop() {
+	sub := cd.bus.Subscribe(event.BuilderBuildSucceeded, event.WebhookRepositoryPush)
+	defer sub.Unsubscribe()
+	for ev := range sub.Chan() {
+		switch ev.Type {
+		case event.WebhookRepositoryPush:
+			repoURL := ev.Body["repository_url"].(string)
+			branch := ev.Body["branch"].(string)
+			cd.handleWebhookRepositoryPush(repoURL, branch)
+		case event.BuilderBuildSucceeded:
+			envID := ev.Body["environment_id"].(string)
+			buildID := ev.Body["build_id"].(string)
+			cd.handleBuilderBuildSucceeded(envID, buildID)
+		}
+	}
+}
+
+func (cd *continuousDeploymentService) handleWebhookRepositoryPush(repoURL string, branch string) {
+	log.WithField("repo", repoURL).
+		WithField("refs", branch).
+		Info("repository push event received")
+
+	env, err := cd.repo.GetEnvironmentByRepoAndBranch(context.Background(), repoURL, branch)
+	if err != nil {
+		if err == repository.ErrNotFound {
+			return
+		}
+		log.WithError(err).
+			WithField("repo", repoURL).
+			WithField("refs", branch).
+			Error("failed to GetEnvironmentByRepoAndBranch")
+		return
+	}
+
+	err = cd.builder.QueueBuild(context.Background(), env)
+	if err != nil {
+		log.WithError(err).
+			WithField("appID", env.ApplicationID).
+			WithField("envID", env.ID).
+			Error("failed to RequestBuild")
+		return
+	}
+}
+
+func (cd *continuousDeploymentService) handleBuilderBuildSucceeded(envID string, buildID string) {
+	if envID == "" {
+		// envIDが無い場合はテストビルド
+		return
+	}
+
+	// 自動デプロイ
+	log.WithField("envID", envID).
+		WithField("buildID", buildID).
+		Error("starting application")
+	err := cd.deployer.QueueDeployment(context.Background(), envID, buildID)
+	if err != nil {
+		// TODO エラー処理
+		log.WithError(err).
+			WithField("envID", envID).
+			WithField("buildID", buildID).
+			Error("failed to Start Application")
+	}
+}
diff --git a/pkg/usecase/static_site_service.go b/pkg/usecase/static_site_server_service.go
similarity index 76%
rename from pkg/usecase/static_site_service.go
rename to pkg/usecase/static_site_server_service.go
index ed0cb6b0..8f87d9f2 100644
--- a/pkg/usecase/static_site_service.go
+++ b/pkg/usecase/static_site_server_service.go
@@ -5,30 +5,30 @@ import (
 	"database/sql"
 
 	"github.com/traPtitech/neoshowcase/pkg/domain"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb/models"
 	"github.com/traPtitech/neoshowcase/pkg/infrastructure/staticserver"
-	"github.com/traPtitech/neoshowcase/pkg/models"
 	"github.com/volatiletech/sqlboiler/v4/queries/qm"
 )
 
-type StaticSiteService interface {
+type StaticSiteServerService interface {
 	Reload(ctx context.Context) error
 }
 
-type staticSiteService struct {
+type staticSiteServerService struct {
 	engine staticserver.Engine
 
 	// TODO 後で消す
 	db *sql.DB
 }
 
-func NewStaticSiteService(engine staticserver.Engine, db *sql.DB) StaticSiteService {
-	return &staticSiteService{
+func NewStaticSiteServerService(engine staticserver.Engine, db *sql.DB) StaticSiteServerService {
+	return &staticSiteServerService{
 		engine: engine,
 		db:     db,
 	}
 }
 
-func (s *staticSiteService) Reload(ctx context.Context) error {
+func (s *staticSiteServerService) Reload(ctx context.Context) error {
 	envs, err := models.Environments(
 		models.EnvironmentWhere.BuildType.EQ(models.EnvironmentsBuildTypeStatic),
 		qm.Load(models.EnvironmentRels.Website),
diff --git a/pkg/appmanager/domains_impl.go b/pkg/usecase/virtual_host_service.go
similarity index 58%
rename from pkg/appmanager/domains_impl.go
rename to pkg/usecase/virtual_host_service.go
index ebbdae55..5fa1cc3b 100644
--- a/pkg/appmanager/domains_impl.go
+++ b/pkg/usecase/virtual_host_service.go
@@ -1,4 +1,4 @@
-package appmanager
+package usecase
 
 import (
 	"context"
@@ -6,14 +6,25 @@ import (
 	"fmt"
 
 	petname "github.com/dustinkirkland/golang-petname"
-	"github.com/traPtitech/neoshowcase/pkg/models"
+	"github.com/traPtitech/neoshowcase/pkg/infrastructure/admindb/models"
 )
 
-// generateRandomDomain ランダムなドメインを生成する
-func (m *managerImpl) generateRandomDomain() (string, error) {
+type VirtualHostService interface {
+	GenerateRandomDomain(ctx context.Context) (string, error)
+}
+
+type virtualHostService struct {
+	db *sql.DB
+}
+
+func NewVirtualHostService(db *sql.DB) VirtualHostService {
+	return &virtualHostService{db: db}
+}
+
+func (s *virtualHostService) GenerateRandomDomain(ctx context.Context) (string, error) {
 	d, err := models.AvailableDomains(
 		models.AvailableDomainWhere.Subdomain.EQ(true),
-	).One(context.Background(), m.db)
+	).One(context.Background(), s.db)
 	if err != nil {
 		if err == sql.ErrNoRows {
 			// DBに親ドメインが登録されてないと生成できない
@@ -26,7 +37,7 @@ func (m *managerImpl) generateRandomDomain() (string, error) {
 	var candidate string
 	for {
 		candidate = petname.Generate(3, "-") + "." + d.Domain
-		ng, err := models.Websites(models.WebsiteWhere.FQDN.EQ(candidate)).Exists(context.Background(), m.db)
+		ng, err := models.Websites(models.WebsiteWhere.FQDN.EQ(candidate)).Exists(context.Background(), s.db)
 		if err != nil {
 			return "", fmt.Errorf("db error: %w", err)
 		}
diff --git a/pkg/cliutil/config.go b/pkg/util/cli/config.go
similarity index 98%
rename from pkg/cliutil/config.go
rename to pkg/util/cli/config.go
index a432412c..bbd6ee07 100644
--- a/pkg/cliutil/config.go
+++ b/pkg/util/cli/config.go
@@ -1,10 +1,11 @@
-package cliutil
+package cli
 
 import (
+	"strings"
+
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/pflag"
 	"github.com/spf13/viper"
-	"strings"
 )
 
 func BindPFlag(flags *pflag.FlagSet, key string, flag ...string) {
diff --git a/pkg/cliutil/env.go b/pkg/util/cli/env.go
similarity index 95%
rename from pkg/cliutil/env.go
rename to pkg/util/cli/env.go
index 8f74b7ae..e83445cf 100644
--- a/pkg/cliutil/env.go
+++ b/pkg/util/cli/env.go
@@ -1,4 +1,4 @@
-package cliutil
+package cli
 
 import (
 	"os"
diff --git a/pkg/cliutil/flag.go b/pkg/util/cli/flag.go
similarity index 98%
rename from pkg/cliutil/flag.go
rename to pkg/util/cli/flag.go
index 9e60d559..ba80e37b 100644
--- a/pkg/cliutil/flag.go
+++ b/pkg/util/cli/flag.go
@@ -1,4 +1,4 @@
-package cliutil
+package cli
 
 import (
 	log "github.com/sirupsen/logrus"
diff --git a/pkg/cliutil/print_conf.go b/pkg/util/cli/print_conf.go
similarity index 96%
rename from pkg/cliutil/print_conf.go
rename to pkg/util/cli/print_conf.go
index d28a9ba0..41e48a55 100644
--- a/pkg/cliutil/print_conf.go
+++ b/pkg/util/cli/print_conf.go
@@ -1,4 +1,4 @@
-package cliutil
+package cli
 
 import (
 	log "github.com/sirupsen/logrus"
diff --git a/pkg/cliutil/signal.go b/pkg/util/cli/signal.go
similarity index 93%
rename from pkg/cliutil/signal.go
rename to pkg/util/cli/signal.go
index d36235f9..2d954039 100644
--- a/pkg/cliutil/signal.go
+++ b/pkg/util/cli/signal.go
@@ -1,4 +1,4 @@
-package cliutil
+package cli
 
 import (
 	"os"
diff --git a/pkg/cliutil/version.go b/pkg/util/cli/version.go
similarity index 93%
rename from pkg/cliutil/version.go
rename to pkg/util/cli/version.go
index ebb76357..7208e06f 100644
--- a/pkg/cliutil/version.go
+++ b/pkg/util/cli/version.go
@@ -1,4 +1,4 @@
-package cliutil
+package cli
 
 import (
 	log "github.com/sirupsen/logrus"
diff --git a/sqlboiler.toml b/sqlboiler.toml
index f46e2f96..2b74ddda 100644
--- a/sqlboiler.toml
+++ b/sqlboiler.toml
@@ -1,4 +1,4 @@
-output = "pkg/models"
+output = "pkg/infrastructure/admindb/models"
 wipe = true
 
 [mysql]
diff --git a/tools.go b/tools.go
index 3198d7e7..6ce72683 100644
--- a/tools.go
+++ b/tools.go
@@ -5,6 +5,8 @@ package main
 import (
 	_ "github.com/golang/mock/mockgen"
 	_ "github.com/google/wire/cmd/wire"
+	_ "github.com/ktr0731/evans"
 	_ "github.com/rubenv/sql-migrate"
 	_ "github.com/volatiletech/sqlboiler/v4"
+	_ "google.golang.org/grpc/cmd/protoc-gen-go-grpc"
 )


Test patch:
diff --git a/pkg/models/applications.go b/pkg/infrastructure/admindb/models/applications.go
similarity index 100%
rename from pkg/models/applications.go
rename to pkg/infrastructure/admindb/models/applications.go
diff --git a/pkg/models/applications_test.go b/pkg/infrastructure/admindb/models/applications_test.go
similarity index 100%
rename from pkg/models/applications_test.go
rename to pkg/infrastructure/admindb/models/applications_test.go
diff --git a/pkg/models/artifacts.go b/pkg/infrastructure/admindb/models/artifacts.go
similarity index 100%
rename from pkg/models/artifacts.go
rename to pkg/infrastructure/admindb/models/artifacts.go
diff --git a/pkg/models/artifacts_test.go b/pkg/infrastructure/admindb/models/artifacts_test.go
similarity index 100%
rename from pkg/models/artifacts_test.go
rename to pkg/infrastructure/admindb/models/artifacts_test.go
diff --git a/pkg/models/available_domains.go b/pkg/infrastructure/admindb/models/available_domains.go
similarity index 100%
rename from pkg/models/available_domains.go
rename to pkg/infrastructure/admindb/models/available_domains.go
diff --git a/pkg/models/available_domains_test.go b/pkg/infrastructure/admindb/models/available_domains_test.go
similarity index 100%
rename from pkg/models/available_domains_test.go
rename to pkg/infrastructure/admindb/models/available_domains_test.go
diff --git a/pkg/models/boil_main_test.go b/pkg/infrastructure/admindb/models/boil_main_test.go
similarity index 98%
rename from pkg/models/boil_main_test.go
rename to pkg/infrastructure/admindb/models/boil_main_test.go
index 9bbc840c..924496fe 100644
--- a/pkg/models/boil_main_test.go
+++ b/pkg/infrastructure/admindb/models/boil_main_test.go
@@ -21,7 +21,7 @@ import (
 var flagDebugMode = flag.Bool("test.sqldebug", false, "Turns on debug mode for SQL statements")
 var flagConfigFile = flag.String("test.config", "", "Overrides the default config")
 
-const outputDirDepth = 2
+const outputDirDepth = 4
 
 var (
 	dbMain tester
diff --git a/pkg/infrastructure/backend/dockerimpl/backend_test.go b/pkg/infrastructure/backend/dockerimpl/backend_test.go
index a9e56c78..f7983550 100644
--- a/pkg/infrastructure/backend/dockerimpl/backend_test.go
+++ b/pkg/infrastructure/backend/dockerimpl/backend_test.go
@@ -22,7 +22,7 @@ func prepareManager(t *testing.T, bus eventbus.Bus) (*dockerBackend, *docker.Cli
 		t.Fatal(err)
 	}
 
-	m, err := NewDockerBackend(c, bus)
+	m, err := NewDockerBackend(c, bus, "./local-dev/traefik")
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/pkg/infrastructure/backend/k8simpl/create_container_test.go b/pkg/infrastructure/backend/k8simpl/create_container_test.go
index 93ff4aa5..931ebd58 100644
--- a/pkg/infrastructure/backend/k8simpl/create_container_test.go
+++ b/pkg/infrastructure/backend/k8simpl/create_container_test.go
@@ -51,7 +51,6 @@ func TestK8sBackend_CreateContainer(t *testing.T) {
 			waitPodRunning(t, c, deploymentName(appID, envID))
 			require.NoError(t, c.CoreV1().Pods(appNamespace).Delete(context.Background(), deploymentName(appID, envID), metav1.DeleteOptions{}))
 			require.NoError(t, c.CoreV1().Services(appNamespace).Delete(context.Background(), deploymentName(appID, envID), metav1.DeleteOptions{}))
-			require.NoError(t, c.NetworkingV1().Ingresses(appNamespace).Delete(context.Background(), deploymentName(appID, envID), metav1.DeleteOptions{}))
 		}
 	})
 
@@ -89,7 +88,6 @@ func TestK8sBackend_CreateContainer(t *testing.T) {
 			waitPodRunning(t, c, deploymentName(appID, envID))
 			require.NoError(t, c.CoreV1().Pods(appNamespace).Delete(context.Background(), deploymentName(appID, envID), metav1.DeleteOptions{}))
 			require.NoError(t, c.CoreV1().Services(appNamespace).Delete(context.Background(), deploymentName(appID, envID), metav1.DeleteOptions{}))
-			require.NoError(t, c.NetworkingV1().Ingresses(appNamespace).Delete(context.Background(), deploymentName(appID, envID), metav1.DeleteOptions{}))
 		}
 	})
 }
diff --git a/pkg/infrastructure/userdb/mariadb_impl_test.go b/pkg/infrastructure/userdb/mariadb_impl_test.go
index d31fd643..815abab9 100644
--- a/pkg/infrastructure/userdb/mariadb_impl_test.go
+++ b/pkg/infrastructure/userdb/mariadb_impl_test.go
@@ -6,7 +6,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
-	"github.com/traPtitech/neoshowcase/pkg/cliutil"
+	"github.com/traPtitech/neoshowcase/pkg/util/cli"
 )
 
 func TestNewMariaDBManager(t *testing.T) {
@@ -14,10 +14,10 @@ func TestNewMariaDBManager(t *testing.T) {
 	t.Parallel()
 
 	c := MariaDBConfig{
-		Host:          cliutil.GetEnvOrDefault("TEST_APP_MARIADB_HOST", "localhost"),
-		Port:          cliutil.GetIntEnvOrDefault("TEST_APP_MARIADB_PORT", 5004),
-		AdminUser:     cliutil.GetEnvOrDefault("TEST_APP_MARIADB_USER", "root"),
-		AdminPassword: cliutil.GetEnvOrDefault("TEST_APP_MARIADB_PASSWORD", "password"),
+		Host:          cli.GetEnvOrDefault("TEST_APP_MARIADB_HOST", "localhost"),
+		Port:          cli.GetIntEnvOrDefault("TEST_APP_MARIADB_PORT", 5004),
+		AdminUser:     cli.GetEnvOrDefault("TEST_APP_MARIADB_USER", "root"),
+		AdminPassword: cli.GetEnvOrDefault("TEST_APP_MARIADB_PASSWORD", "password"),
 	}
 
 	_, err := NewMariaDBManager(c)
@@ -61,10 +61,10 @@ func initMariaDBManager(t *testing.T) (*mariaDBManagerImpl, *sql.DB) {
 	t.Helper()
 
 	c := MariaDBConfig{
-		Host:          cliutil.GetEnvOrDefault("TEST_APP_MARIADB_HOST", "localhost"),
-		Port:          cliutil.GetIntEnvOrDefault("TEST_APP_MARIADB_PORT", 5004),
-		AdminUser:     cliutil.GetEnvOrDefault("TEST_APP_MARIADB_USER", "root"),
-		AdminPassword: cliutil.GetEnvOrDefault("TEST_APP_MARIADB_PASSWORD", "password"),
+		Host:          cli.GetEnvOrDefault("TEST_APP_MARIADB_HOST", "localhost"),
+		Port:          cli.GetIntEnvOrDefault("TEST_APP_MARIADB_PORT", 5004),
+		AdminUser:     cli.GetEnvOrDefault("TEST_APP_MARIADB_USER", "root"),
+		AdminPassword: cli.GetEnvOrDefault("TEST_APP_MARIADB_PASSWORD", "password"),
 	}
 
 	m, err := NewMariaDBManager(c)
diff --git a/pkg/infrastructure/userdb/mongo_impl_test.go b/pkg/infrastructure/userdb/mongo_impl_test.go
index f424ceda..8daffe8b 100644
--- a/pkg/infrastructure/userdb/mongo_impl_test.go
+++ b/pkg/infrastructure/userdb/mongo_impl_test.go
@@ -5,7 +5,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
-	"github.com/traPtitech/neoshowcase/pkg/cliutil"
+	"github.com/traPtitech/neoshowcase/pkg/util/cli"
 	"go.mongodb.org/mongo-driver/mongo"
 )
 
@@ -14,10 +14,10 @@ func TestNewMongoManager(t *testing.T) {
 	t.Parallel()
 
 	c := MongoConfig{
-		Host:          cliutil.GetEnvOrDefault("TEST_APP_MONGO_HOST", "localhost"),
-		Port:          cliutil.GetIntEnvOrDefault("TEST_APP_MONGO_PORT", 5010),
-		AdminUser:     cliutil.GetEnvOrDefault("TEST_APP_MONGO_USER", "root"),
-		AdminPassword: cliutil.GetEnvOrDefault("TEST_APP_MONGO_PASSWORD", "password"),
+		Host:          cli.GetEnvOrDefault("TEST_APP_MONGO_HOST", "localhost"),
+		Port:          cli.GetIntEnvOrDefault("TEST_APP_MONGO_PORT", 5010),
+		AdminUser:     cli.GetEnvOrDefault("TEST_APP_MONGO_USER", "root"),
+		AdminPassword: cli.GetEnvOrDefault("TEST_APP_MONGO_PASSWORD", "password"),
 	}
 
 	_, err := NewMongoManager(c)
@@ -61,10 +61,10 @@ func initMongoManager(t *testing.T) (*mongoManagerImpl, *mongo.Client) {
 	t.Helper()
 
 	c := MongoConfig{
-		Host:          cliutil.GetEnvOrDefault("TEST_APP_MONGO_HOST", "localhost"),
-		Port:          cliutil.GetIntEnvOrDefault("TEST_APP_MONGO_PORT", 5010),
-		AdminUser:     cliutil.GetEnvOrDefault("TEST_APP_MONGO_USER", "root"),
-		AdminPassword: cliutil.GetEnvOrDefault("TEST_APP_MONGO_PASSWORD", "password"),
+		Host:          cli.GetEnvOrDefault("TEST_APP_MONGO_HOST", "localhost"),
+		Port:          cli.GetIntEnvOrDefault("TEST_APP_MONGO_PORT", 5010),
+		AdminUser:     cli.GetEnvOrDefault("TEST_APP_MONGO_USER", "root"),
+		AdminPassword: cli.GetEnvOrDefault("TEST_APP_MONGO_PASSWORD", "password"),
 	}
 
 	m, err := NewMongoManager(c)