compose/ecs/pkg/docker/contextStore.go
Nicolas De Loof 4700fed836
Unwrapp API errors to get user-friendly error message
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-08-17 21:26:22 +02:00

101 lines
2.6 KiB
Go

package docker
import (
"fmt"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/docker/cli/cli/command"
cliconfig "github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/context/store"
amazon "github.com/docker/ecs-plugin/pkg/amazon/backend"
"github.com/mitchellh/mapstructure"
"github.com/spf13/cobra"
)
const contextType = "aws"
type TypeContext struct {
Type string
}
func getter() interface{} {
return &TypeContext{}
}
type AwsContext struct {
Profile string
Cluster string
Region string
}
func NewContext(name string, awsContext *AwsContext) error {
_, err := NewContextWithStore(name, awsContext, cliconfig.ContextStoreDir())
return err
}
func NewContextWithStore(name string, awsContext *AwsContext, contextDirectory string) (store.Store, error) {
contextStore := initContextStore(contextDirectory)
endpoints := map[string]interface{}{
"aws": awsContext,
"docker": awsContext,
}
metadata := store.Metadata{
Name: name,
Endpoints: endpoints,
Metadata: TypeContext{Type: contextType},
}
return contextStore, contextStore.CreateOrUpdate(metadata)
}
func initContextStore(contextDir string) store.Store {
config := store.NewConfig(getter)
return store.New(contextDir, config)
}
func checkAwsContextExists(contextName string) (*AwsContext, error) {
if contextName == command.DefaultContextName {
return nil, fmt.Errorf("can't use \"%s\" with ECS command because it is not an AWS context", contextName)
}
contextStore := initContextStore(cliconfig.ContextStoreDir())
metadata, err := contextStore.GetMetadata(contextName)
if err != nil {
return nil, err
}
endpoint := metadata.Endpoints["aws"]
awsContext := AwsContext{}
err = mapstructure.Decode(endpoint, &awsContext)
if err != nil {
return nil, err
}
if awsContext == (AwsContext{}) {
return nil, fmt.Errorf("can't use \"%s\" with ECS command because it is not an AWS context", contextName)
}
return &awsContext, nil
}
type ContextFunc func(ctx AwsContext, backend *amazon.Backend, args []string) error
func WithAwsContext(dockerCli command.Cli, f ContextFunc) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
ctx, err := GetAwsContext(dockerCli)
if err != nil {
return err
}
backend, err := amazon.NewBackend(ctx.Profile, ctx.Cluster, ctx.Region)
if err != nil {
return err
}
err = f(*ctx, backend, args)
if e, ok := err.(awserr.Error); ok {
return fmt.Errorf(e.Message())
}
return err
}
}
func GetAwsContext(dockerCli command.Cli) (*AwsContext, error) {
contextName := dockerCli.CurrentContext()
return checkAwsContextExists(contextName)
}