mirror of https://github.com/docker/compose.git
Multiple backend for the cli
* implement a little azure backend * implement an example backend * use the right backend from the context
This commit is contained in:
parent
f5bf355d1f
commit
f4bde8cb89
10
Makefile
10
Makefile
|
@ -42,19 +42,11 @@ protos:
|
||||||
cli: protos
|
cli: protos
|
||||||
GOOS=${GOOS} GOARCH=${GOARCH} go build -v -o bin/docker ./cli
|
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
|
xcli: cli
|
||||||
GOOS=linux GOARCH=amd64 go build -v -o bin/docker-linux-amd64 ./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=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
|
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:
|
dprotos:
|
||||||
docker build . \
|
docker build . \
|
||||||
--output type=local,dest=./backend/v1 \
|
--output type=local,dest=./backend/v1 \
|
||||||
|
@ -81,4 +73,4 @@ test:
|
||||||
|
|
||||||
FORCE:
|
FORCE:
|
||||||
|
|
||||||
.PHONY: all xall protos example xexample xcli cli bins dbins dxbins dprotos
|
.PHONY: all xall protos xcli cli bins dbins dxbins dprotos
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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")
|
||||||
|
}
|
|
@ -99,6 +99,7 @@ func runCreate(ctx context.Context, opts createOpts, name string, contextType st
|
||||||
default:
|
default:
|
||||||
s := store.ContextStore(ctx)
|
s := store.ContextStore(ctx)
|
||||||
return s.Create(name, store.TypedContext{
|
return s.Create(name, store.TypedContext{
|
||||||
|
Type: contextType,
|
||||||
Description: opts.description,
|
Description: opts.description,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -129,7 +130,7 @@ func runList(ctx context.Context) error {
|
||||||
format := "%s\t%s\t%s\n"
|
format := "%s\t%s\t%s\n"
|
||||||
|
|
||||||
for _, c := range contexts {
|
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()
|
return w.Flush()
|
||||||
|
|
|
@ -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()
|
||||||
|
},
|
||||||
|
}
|
|
@ -36,6 +36,10 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
// Backend registrations
|
||||||
|
_ "github.com/docker/api/azure"
|
||||||
|
_ "github.com/docker/api/example"
|
||||||
|
|
||||||
"github.com/docker/api/cli/cmd"
|
"github.com/docker/api/cli/cmd"
|
||||||
apicontext "github.com/docker/api/context"
|
apicontext "github.com/docker/api/context"
|
||||||
"github.com/docker/api/context/store"
|
"github.com/docker/api/context/store"
|
||||||
|
@ -107,6 +111,7 @@ func main() {
|
||||||
|
|
||||||
root.AddCommand(
|
root.AddCommand(
|
||||||
cmd.ContextCommand(),
|
cmd.ContextCommand(),
|
||||||
|
&cmd.PsCommand,
|
||||||
&cmd.ExampleCommand,
|
&cmd.ExampleCommand,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -29,14 +29,15 @@ package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
|
"github.com/docker/api/backend"
|
||||||
v1 "github.com/docker/api/backend/v1"
|
v1 "github.com/docker/api/backend/v1"
|
||||||
"github.com/docker/api/containers"
|
"github.com/docker/api/containers"
|
||||||
apicontext "github.com/docker/api/context"
|
apicontext "github.com/docker/api/context"
|
||||||
"github.com/docker/api/context/store"
|
"github.com/docker/api/context/store"
|
||||||
"github.com/docker/api/example"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// New returns a GRPC client
|
// New returns a GRPC client
|
||||||
|
@ -50,20 +51,29 @@ func New(ctx context.Context) (*Client, error) {
|
||||||
}
|
}
|
||||||
contextType := s.GetType(cc)
|
contextType := s.GetType(cc)
|
||||||
|
|
||||||
|
b, err := backend.Get(ctx, contextType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if ba, ok := b.(containers.ContainerService); ok {
|
||||||
return &Client{
|
return &Client{
|
||||||
backendType: contextType,
|
backendType: contextType,
|
||||||
|
cc: ba,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
return nil, errors.New("backend not found")
|
||||||
|
}
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
conn *grpc.ClientConn
|
conn *grpc.ClientConn
|
||||||
v1.BackendClient
|
v1.BackendClient
|
||||||
backendType string
|
backendType string
|
||||||
|
cc containers.ContainerService
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) ContainerService(ctx context.Context) containers.ContainerService {
|
func (c *Client) ContainerService(ctx context.Context) containers.ContainerService {
|
||||||
return example.New()
|
return c.cc
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Close() error {
|
func (c *Client) Close() error {
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -111,10 +111,6 @@ func New(opts ...StoreOpt) (Store, error) {
|
||||||
|
|
||||||
// Get returns the context with the given name
|
// Get returns the context with the given name
|
||||||
func (s *store) Get(name string, getter func() interface{}) (*Metadata, error) {
|
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)
|
meta := filepath.Join(s.root, contextsDir, metadataDir, contextdirOf(name), metaFile)
|
||||||
return read(meta, getter)
|
return read(meta, getter)
|
||||||
}
|
}
|
||||||
|
@ -196,6 +192,7 @@ func (s *store) Create(name string, data TypedContext) error {
|
||||||
Metadata: data,
|
Metadata: data,
|
||||||
Endpoints: map[string]interface{}{
|
Endpoints: map[string]interface{}{
|
||||||
"docker": DummyContext{},
|
"docker": DummyContext{},
|
||||||
|
(data.Type): DummyContext{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
|
||||||
}
|
|
8
go.mod
8
go.mod
|
@ -3,7 +3,11 @@ module github.com/docker/api
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
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/golang/protobuf v1.4.0
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
|
@ -15,7 +19,7 @@ require (
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/stretchr/testify v1.5.1
|
github.com/stretchr/testify v1.5.1
|
||||||
github.com/urfave/cli/v2 v2.2.0
|
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
|
golang.org/x/text v0.3.2 // indirect
|
||||||
google.golang.org/grpc v1.29.1
|
google.golang.org/grpc v1.29.1
|
||||||
google.golang.org/protobuf v1.21.0
|
google.golang.org/protobuf v1.21.0
|
||||||
|
|
44
go.sum
44
go.sum
|
@ -1,4 +1,39 @@
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
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=
|
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.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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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/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/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.0/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.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
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-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 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
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/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-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
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-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 h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
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-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 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-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 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U=
|
||||||
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
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=
|
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-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-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-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 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
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=
|
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU=
|
||||||
|
|
Loading…
Reference in New Issue