From f4bde8cb89e18c3b6b3384e5b6e5da50e1c935c6 Mon Sep 17 00:00:00 2001 From: Djordje Lukic Date: Wed, 29 Apr 2020 19:57:53 +0200 Subject: [PATCH] Multiple backend for the cli * implement a little azure backend * implement an example backend * use the right backend from the context --- Makefile | 10 +--- azure/backend.go | 81 ++++++++++++++++++++++++++++ backend/backend.go | 54 +++++++++++++++++++ cli/cmd/context.go | 3 +- cli/cmd/ps.go | 41 +++++++++++++++ cli/main.go | 5 ++ client/client.go | 22 +++++--- containers/api.go | 22 ++++++++ context/store/store.go | 7 +-- example/backend.go | 33 ++++++++++++ example/backend/main.go | 114 ---------------------------------------- go.mod | 8 ++- go.sum | 44 +++++++++++++++- 13 files changed, 305 insertions(+), 139 deletions(-) create mode 100644 azure/backend.go create mode 100644 backend/backend.go create mode 100644 cli/cmd/ps.go create mode 100644 containers/api.go create mode 100644 example/backend.go delete mode 100644 example/backend/main.go diff --git a/Makefile b/Makefile index 87186234e..969ad76b3 100644 --- a/Makefile +++ b/Makefile @@ -42,19 +42,11 @@ protos: cli: protos GOOS=${GOOS} GOARCH=${GOARCH} go build -v -o bin/docker ./cli -example: protos - cd example/backend && go build -v -o ../../bin/backend-example - xcli: cli GOOS=linux GOARCH=amd64 go build -v -o bin/docker-linux-amd64 ./cli GOOS=darwin GOARCH=amd64 go build -v -o bin/docker-darwin-amd64 ./cli GOOS=windows GOARCH=amd64 go build -v -o bin/docker-windows-amd64.exe ./cli -xexample: example - GOOS=linux GOARCH=amd64 go build -v -o bin/backend-example-linux-amd64 ./example/backend - GOOS=darwin GOARCH=amd64 go build -v -o bin/backend-example-darwin-amd64 ./example/backend - GOOS=windows GOARCH=amd64 go build -v -o bin/backend-example-windows-amd64.exe ./example/backend - dprotos: docker build . \ --output type=local,dest=./backend/v1 \ @@ -81,4 +73,4 @@ test: FORCE: -.PHONY: all xall protos example xexample xcli cli bins dbins dxbins dprotos +.PHONY: all xall protos xcli cli bins dbins dxbins dprotos diff --git a/azure/backend.go b/azure/backend.go new file mode 100644 index 000000000..884a9dc4a --- /dev/null +++ b/azure/backend.go @@ -0,0 +1,81 @@ +package azure + +import ( + "context" + + "github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance" + "github.com/Azure/go-autorest/autorest/azure/auth" + "github.com/pkg/errors" + + "github.com/docker/api/backend" + "github.com/docker/api/containers" + apicontext "github.com/docker/api/context" + "github.com/docker/api/context/store" +) + +type containerService struct { + cgc containerinstance.ContainerGroupsClient + ctx store.AciContext +} + +func init() { + backend.Register("aci", "aci", func(ctx context.Context) (interface{}, error) { + return New(ctx) + }) +} + +func getter() interface{} { + return &store.AciContext{} +} + +func New(ctx context.Context) (containers.ContainerService, error) { + cc := apicontext.CurrentContext(ctx) + s, err := store.New() + if err != nil { + return nil, err + } + m, err := s.Get(cc, getter) + if err != nil { + return nil, errors.Wrap(err, "wrong context type") + } + tc, _ := m.Metadata.Data.(store.AciContext) + + auth, _ := auth.NewAuthorizerFromCLI() + containerGroupsClient := containerinstance.NewContainerGroupsClient(tc.SubscriptionID) + containerGroupsClient.Authorizer = auth + + return &containerService{ + cgc: containerGroupsClient, + ctx: tc, + }, nil +} + +func (cs *containerService) List(ctx context.Context) ([]containers.Container, error) { + var cg []containerinstance.ContainerGroup + result, err := cs.cgc.ListByResourceGroup(ctx, cs.ctx.ResourceGroup) + + if err != nil { + return []containers.Container{}, err + } + + for result.NotDone() { + cg = append(cg, result.Values()...) + if err := result.NextWithContext(ctx); err != nil { + return []containers.Container{}, err + } + } + + res := []containers.Container{} + for _, c := range cg { + cc := *c.Containers + for _, d := range cc { + res = append(res, containers.Container{ + ID: *c.Name, + Image: *d.Image, + // Command: strings.Join(*d.ContainerProperties.Command, " "), // TODO command can be null + }) + } + } + + return res, nil +} diff --git a/backend/backend.go b/backend/backend.go new file mode 100644 index 000000000..fec32c865 --- /dev/null +++ b/backend/backend.go @@ -0,0 +1,54 @@ +package backend + +import ( + "context" + "errors" +) + +var ( + ErrNoType = errors.New("backend: no type") + ErrNoName = errors.New("backend: no name") + ErrTypeRegistered = errors.New("backend: already registered") +) + +type InitFunc func(context.Context) (interface{}, error) + +type Backend struct { + name string + backendType string + init InitFunc +} + +var backends = struct { + r []*Backend +}{} + +func Register(name string, backendType string, init InitFunc) { + if name == "" { + panic(ErrNoName) + } + if backendType == "" { + panic(ErrNoType) + } + for _, b := range backends.r { + if b.backendType == backendType { + panic(ErrTypeRegistered) + } + } + + backends.r = append(backends.r, &Backend{ + name, + backendType, + init, + }) +} + +func Get(ctx context.Context, backendType string) (interface{}, error) { + for _, b := range backends.r { + if b.backendType == backendType { + return b.init(ctx) + } + } + + return nil, errors.New("not found") +} diff --git a/cli/cmd/context.go b/cli/cmd/context.go index 428ecea62..d6af64573 100644 --- a/cli/cmd/context.go +++ b/cli/cmd/context.go @@ -99,6 +99,7 @@ func runCreate(ctx context.Context, opts createOpts, name string, contextType st default: s := store.ContextStore(ctx) return s.Create(name, store.TypedContext{ + Type: contextType, Description: opts.description, }) } @@ -129,7 +130,7 @@ func runList(ctx context.Context) error { format := "%s\t%s\t%s\n" for _, c := range contexts { - fmt.Fprintf(w, format, c.Name, c.Metadata.Description) + fmt.Fprintf(w, format, c.Name, c.Metadata.Description, c.Metadata.Type) } return w.Flush() diff --git a/cli/cmd/ps.go b/cli/cmd/ps.go new file mode 100644 index 000000000..2f980a12d --- /dev/null +++ b/cli/cmd/ps.go @@ -0,0 +1,41 @@ +package cmd + +import ( + "fmt" + "os" + "text/tabwriter" + + client2 "github.com/docker/api/client" + "github.com/pkg/errors" + "github.com/spf13/cobra" +) + +var PsCommand = cobra.Command{ + Use: "ps", + Short: "List containers", + RunE: func(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + + // get our current context + ctx = current(ctx) + + client, err := client2.New(ctx) + if err != nil { + return errors.Wrap(err, "cannot connect to backend") + } + defer client.Close() + + containers, err := client.ContainerService(ctx).List(ctx) + if err != nil { + return errors.Wrap(err, "fetch containers") + } + + w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) + fmt.Fprintf(w, "NAME\tIMAGE\tCOMMAND\n") + format := "%s\t%s\t%s\n" + for _, c := range containers { + fmt.Fprintf(w, format, c.ID, c.Image, c.Command) + } + return w.Flush() + }, +} diff --git a/cli/main.go b/cli/main.go index 9f37379f4..a1cda0d3f 100644 --- a/cli/main.go +++ b/cli/main.go @@ -36,6 +36,10 @@ import ( "path/filepath" "strings" + // Backend registrations + _ "github.com/docker/api/azure" + _ "github.com/docker/api/example" + "github.com/docker/api/cli/cmd" apicontext "github.com/docker/api/context" "github.com/docker/api/context/store" @@ -107,6 +111,7 @@ func main() { root.AddCommand( cmd.ContextCommand(), + &cmd.PsCommand, &cmd.ExampleCommand, ) diff --git a/client/client.go b/client/client.go index 604a6ae5a..145cd78dd 100644 --- a/client/client.go +++ b/client/client.go @@ -29,14 +29,15 @@ package client import ( "context" + "errors" "google.golang.org/grpc" + "github.com/docker/api/backend" v1 "github.com/docker/api/backend/v1" "github.com/docker/api/containers" apicontext "github.com/docker/api/context" "github.com/docker/api/context/store" - "github.com/docker/api/example" ) // New returns a GRPC client @@ -50,20 +51,29 @@ func New(ctx context.Context) (*Client, error) { } contextType := s.GetType(cc) - return &Client{ - backendType: contextType, - }, nil + b, err := backend.Get(ctx, contextType) + if err != nil { + return nil, err + } + + if ba, ok := b.(containers.ContainerService); ok { + return &Client{ + backendType: contextType, + cc: ba, + }, nil + } + return nil, errors.New("backend not found") } type Client struct { conn *grpc.ClientConn v1.BackendClient backendType string + cc containers.ContainerService } func (c *Client) ContainerService(ctx context.Context) containers.ContainerService { - return example.New() - + return c.cc } func (c *Client) Close() error { diff --git a/containers/api.go b/containers/api.go new file mode 100644 index 000000000..dc1ae5420 --- /dev/null +++ b/containers/api.go @@ -0,0 +1,22 @@ +package containers + +import ( + "context" +) + +type Container struct { + ID string + Status string + Image string + Command string + CpuTime uint64 + MemoryUsage uint64 + MemoryLimit uint64 + PidsCurrent uint64 + PidsLimit uint64 + Labels []string +} + +type ContainerService interface { + List(context.Context) ([]Container, error) +} diff --git a/context/store/store.go b/context/store/store.go index d1118fc0a..a9e46588e 100644 --- a/context/store/store.go +++ b/context/store/store.go @@ -111,10 +111,6 @@ func New(opts ...StoreOpt) (Store, error) { // Get returns the context with the given name func (s *store) Get(name string, getter func() interface{}) (*Metadata, error) { - if name == "default" { - return &Metadata{}, nil - } - meta := filepath.Join(s.root, contextsDir, metadataDir, contextdirOf(name), metaFile) return read(meta, getter) } @@ -195,7 +191,8 @@ func (s *store) Create(name string, data TypedContext) error { Name: name, Metadata: data, Endpoints: map[string]interface{}{ - "docker": DummyContext{}, + "docker": DummyContext{}, + (data.Type): DummyContext{}, }, } diff --git a/example/backend.go b/example/backend.go new file mode 100644 index 000000000..805b4e4a5 --- /dev/null +++ b/example/backend.go @@ -0,0 +1,33 @@ +package example + +import ( + "context" + + "github.com/docker/api/backend" + "github.com/docker/api/containers" +) + +type containerService struct{} + +func init() { + backend.Register("example", "example", func(ctx context.Context) (interface{}, error) { + return New(), nil + }) +} + +func New() containers.ContainerService { + return &containerService{} +} + +func (cs *containerService) List(ctx context.Context) ([]containers.Container, error) { + return []containers.Container{ + { + ID: "id", + Image: "nginx", + }, + { + ID: "1234", + Image: "alpine", + }, + }, nil +} diff --git a/example/backend/main.go b/example/backend/main.go deleted file mode 100644 index a7d18f442..000000000 --- a/example/backend/main.go +++ /dev/null @@ -1,114 +0,0 @@ -/* - Copyright (c) 2020 Docker Inc. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, - DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH - THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -package main - -import ( - "context" - "fmt" - "net" - "os" - - "github.com/golang/protobuf/ptypes/empty" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" - - v1 "github.com/docker/api/backend/v1" - "github.com/docker/api/server" - apiUtil "github.com/docker/api/util" -) - -func main() { - app := cli.NewApp() - app.Name = "example" - app.Usage = "example backend" - app.Description = "" - app.UseShortOptionHandling = true - app.EnableBashCompletion = true - app.Flags = []cli.Flag{ - &cli.BoolFlag{ - Name: "debug", - Usage: "enable debug output in the logs", - }, - &cli.StringFlag{ - Name: "address,a", - Usage: "address of the server", - }, - } - app.Before = func(clix *cli.Context) error { - if clix.Bool("debug") { - logrus.SetLevel(logrus.DebugLevel) - } - return nil - } - app.Action = func(clix *cli.Context) error { - ctx, cancel := apiUtil.NewSigContext() - defer cancel() - - // create a new GRPC server with the provided server package - s := server.New() - - // listen on a socket to accept connects - l, err := net.Listen("unix", clix.String("address")) - if err != nil { - return errors.Wrap(err, "listen unix socket") - } - defer l.Close() - - // create our instance of the backend server implementation - backend := &backend{} - - // register our instance with the GRPC server - v1.RegisterBackendServer(s, backend) - - // handle context being closed or canceled - go func() { - <-ctx.Done() - logrus.Info("backend signaled to stop") - - s.Stop() - }() - - logrus.WithField("address", clix.String("address")).Info("serving daemon API") - // start the GRPC server to serve on the listener - return s.Serve(l) - } - if err := app.Run(os.Args); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} - -type backend struct { -} - -func (b *backend) BackendInformation(ctx context.Context, _ *empty.Empty) (*v1.BackendInformationResponse, error) { - return &v1.BackendInformationResponse{ - Id: "com.docker.api.backend.example.v1", - }, nil -} diff --git a/go.mod b/go.mod index dc204573c..e47c5f406 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,11 @@ module github.com/docker/api go 1.13 require ( - github.com/coreos/etcd v3.3.10+incompatible + github.com/Azure/azure-sdk-for-go v42.0.0+incompatible + github.com/Azure/go-autorest/autorest v0.10.0 // indirect + github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 + github.com/Azure/go-autorest/autorest/to v0.3.0 // indirect + github.com/Azure/go-autorest/autorest/validation v0.2.0 // indirect github.com/golang/protobuf v1.4.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/mitchellh/go-homedir v1.1.0 @@ -15,7 +19,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.5.1 github.com/urfave/cli/v2 v2.2.0 - golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect + golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 golang.org/x/text v0.3.2 // indirect google.golang.org/grpc v1.29.1 google.golang.org/protobuf v1.21.0 diff --git a/go.sum b/go.sum index c9c3e8ee3..eccc33cfa 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,39 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/Azure/azure-sdk-for-go v41.3.0+incompatible h1:W5px0x53aa47nmIAuF1XWR1ZzFuUnkJBGUuzHnNp+Nk= +github.com/Azure/azure-sdk-for-go v41.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v42.0.0+incompatible h1:yz6sFf5bHZ+gEOQVuK5JhPqTTAmv+OvSLSaqgzqaCwY= +github.com/Azure/azure-sdk-for-go v42.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-autorest v14.0.1+incompatible h1:YhojO9jolWIvvTW7ORhz2ZSNF6Q1TbLqUunKd3jrtyw= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.9.3 h1:OZEIaBbMdUE/Js+BQKlpO81XlISgipr6yDJ+PSwsgi4= +github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= +github.com/Azure/go-autorest/autorest v0.10.0 h1:mvdtztBqcL8se7MdrUweNieTNi4kfNG6GOJuurQJpuY= +github.com/Azure/go-autorest/autorest v0.10.0/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= +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 h1:pZdL8o72rK+avFWl+p9nE8RWi1JInZrWJYlnpfXJwHk= +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 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0= +github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= +github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 h1:iM6UAvjR97ZIeR93qTcwpKNMpV+/FTWjwEbuPD495Tk= +github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= +github.com/Azure/go-autorest/autorest/azure/cli v0.3.1 h1:LXl088ZQlP0SBppGFsRZonW6hSvwgL5gRByMbvUbx8U= +github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= +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 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8= +github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= +github.com/Azure/go-autorest/autorest/validation v0.2.0 h1:15vMO4y76dehZSq7pAaOLQxC6dZYsSrj2GQpflyM/L4= +github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= +github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -30,8 +65,11 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr 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/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 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= @@ -183,6 +221,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -194,11 +234,10 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI= -golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U= golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -213,6 +252,7 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h 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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU=