mirror of https://github.com/docker/compose.git
Add setup command to define a docker context for ecs-plugin
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com> Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
09871400ef
commit
aa8587095f
|
@ -6,16 +6,11 @@ import (
|
||||||
|
|
||||||
"github.com/docker/ecs-plugin/pkg/amazon"
|
"github.com/docker/ecs-plugin/pkg/amazon"
|
||||||
"github.com/docker/ecs-plugin/pkg/compose"
|
"github.com/docker/ecs-plugin/pkg/compose"
|
||||||
|
"github.com/docker/ecs-plugin/pkg/docker"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ClusterOptions struct {
|
func ComposeCommand(clusteropts *docker.AwsContext) *cobra.Command {
|
||||||
Profile string
|
|
||||||
Region string
|
|
||||||
Cluster string
|
|
||||||
}
|
|
||||||
|
|
||||||
func ComposeCommand(clusteropts *ClusterOptions) *cobra.Command {
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "compose",
|
Use: "compose",
|
||||||
}
|
}
|
||||||
|
@ -41,7 +36,7 @@ func (o upOptions) LoadBalancerArn() *string {
|
||||||
return &o.loadBalancerArn
|
return &o.loadBalancerArn
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertCommand(clusteropts *ClusterOptions, projectOpts *compose.ProjectOptions) *cobra.Command {
|
func ConvertCommand(clusteropts *docker.AwsContext, projectOpts *compose.ProjectOptions) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "convert",
|
Use: "convert",
|
||||||
RunE: compose.WithProject(projectOpts, func(project *compose.Project, args []string) error {
|
RunE: compose.WithProject(projectOpts, func(project *compose.Project, args []string) error {
|
||||||
|
@ -66,7 +61,7 @@ func ConvertCommand(clusteropts *ClusterOptions, projectOpts *compose.ProjectOpt
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpCommand(clusteropts *ClusterOptions, projectOpts *compose.ProjectOptions) *cobra.Command {
|
func UpCommand(clusteropts *docker.AwsContext, projectOpts *compose.ProjectOptions) *cobra.Command {
|
||||||
opts := upOptions{}
|
opts := upOptions{}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "up",
|
Use: "up",
|
||||||
|
@ -86,7 +81,7 @@ type downOptions struct {
|
||||||
DeleteCluster bool
|
DeleteCluster bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func DownCommand(clusteropts *ClusterOptions, projectOpts *compose.ProjectOptions) *cobra.Command {
|
func DownCommand(clusteropts *docker.AwsContext, projectOpts *compose.ProjectOptions) *cobra.Command {
|
||||||
opts := downOptions{}
|
opts := downOptions{}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "down",
|
Use: "down",
|
||||||
|
|
|
@ -22,7 +22,7 @@ type deleteSecretOptions struct {
|
||||||
recover bool
|
recover bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func SecretCommand(clusteropts *ClusterOptions) *cobra.Command {
|
func SecretCommand(clusteropts *docker.AwsContext) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "secret",
|
Use: "secret",
|
||||||
Short: "Manages secrets",
|
Short: "Manages secrets",
|
||||||
|
@ -37,7 +37,7 @@ func SecretCommand(clusteropts *ClusterOptions) *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateSecret(clusteropts *ClusterOptions) *cobra.Command {
|
func CreateSecret(clusteropts *docker.AwsContext) *cobra.Command {
|
||||||
//opts := createSecretOptions{}
|
//opts := createSecretOptions{}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "create NAME SECRET",
|
Use: "create NAME SECRET",
|
||||||
|
@ -60,7 +60,7 @@ func CreateSecret(clusteropts *ClusterOptions) *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func InspectSecret(clusteropts *ClusterOptions) *cobra.Command {
|
func InspectSecret(clusteropts *docker.AwsContext) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "inspect ID",
|
Use: "inspect ID",
|
||||||
Short: "Displays secret details",
|
Short: "Displays secret details",
|
||||||
|
@ -88,7 +88,7 @@ func InspectSecret(clusteropts *ClusterOptions) *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListSecrets(clusteropts *ClusterOptions) *cobra.Command {
|
func ListSecrets(clusteropts *docker.AwsContext) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
|
@ -110,7 +110,7 @@ func ListSecrets(clusteropts *ClusterOptions) *cobra.Command {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteSecret(clusteropts *ClusterOptions) *cobra.Command {
|
func DeleteSecret(clusteropts *docker.AwsContext) *cobra.Command {
|
||||||
opts := deleteSecretOptions{}
|
opts := deleteSecretOptions{}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "delete NAME",
|
Use: "delete NAME",
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/docker/cli/cli-plugins/plugin"
|
||||||
|
contextStore "github.com/docker/ecs-plugin/pkg/docker"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetupCommand() *cobra.Command {
|
||||||
|
var opts contextStore.AwsContext
|
||||||
|
var name string
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "setup",
|
||||||
|
Short: "",
|
||||||
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
//Override the root command PersistentPreRun
|
||||||
|
//We just need to initialize the top parent command
|
||||||
|
return plugin.PersistentPreRunE(cmd, args)
|
||||||
|
},
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return contextStore.NewContext(name, &opts)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd.Flags().StringVarP(&name, "name", "n", "aws", "Context Name")
|
||||||
|
cmd.Flags().StringVarP(&opts.Profile, "profile", "p", "", "AWS Profile")
|
||||||
|
cmd.Flags().StringVarP(&opts.Cluster, "cluster", "c", "", "ECS cluster")
|
||||||
|
cmd.Flags().StringVarP(&opts.Region, "region", "r", "", "AWS region")
|
||||||
|
|
||||||
|
cmd.MarkFlagRequired("profile")
|
||||||
|
cmd.MarkFlagRequired("cluster")
|
||||||
|
cmd.MarkFlagRequired("region")
|
||||||
|
return cmd
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/docker/cli/cli-plugins/plugin"
|
"github.com/docker/cli/cli-plugins/plugin"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
commands "github.com/docker/ecs-plugin/cmd/commands"
|
commands "github.com/docker/ecs-plugin/cmd/commands"
|
||||||
|
"github.com/docker/ecs-plugin/pkg/docker"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,23 +27,29 @@ func main() {
|
||||||
|
|
||||||
// NewRootCmd returns the base root command.
|
// NewRootCmd returns the base root command.
|
||||||
func NewRootCmd(name string, dockerCli command.Cli) *cobra.Command {
|
func NewRootCmd(name string, dockerCli command.Cli) *cobra.Command {
|
||||||
var opts commands.ClusterOptions
|
var opts *docker.AwsContext
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Short: "Docker ECS",
|
Short: "Docker ECS",
|
||||||
Long: `run multi-container applications on Amazon ECS.`,
|
Long: `run multi-container applications on Amazon ECS.`,
|
||||||
Use: name,
|
Use: name,
|
||||||
Annotations: map[string]string{"experimentalCLI": "true"},
|
Annotations: map[string]string{"experimentalCLI": "true"},
|
||||||
|
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
err := plugin.PersistentPreRunE(cmd, args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
contextName := dockerCli.CurrentContext()
|
||||||
|
opts, err = docker.CheckAwsContextExists(contextName)
|
||||||
|
return err
|
||||||
|
},
|
||||||
}
|
}
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
VersionCommand(),
|
VersionCommand(),
|
||||||
commands.ComposeCommand(&opts),
|
commands.ComposeCommand(opts),
|
||||||
commands.SecretCommand(&opts),
|
commands.SecretCommand(opts),
|
||||||
|
commands.SetupCommand(),
|
||||||
)
|
)
|
||||||
cmd.Flags().StringVarP(&opts.Profile, "profile", "p", "default", "AWS Profile")
|
|
||||||
cmd.Flags().StringVarP(&opts.Cluster, "cluster", "c", "default", "ECS cluster")
|
|
||||||
cmd.Flags().StringVarP(&opts.Region, "region", "r", "", "AWS region")
|
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ require (
|
||||||
github.com/lib/pq v1.3.0 // indirect
|
github.com/lib/pq v1.3.0 // indirect
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
||||||
github.com/miekg/pkcs11 v1.0.3 // indirect
|
github.com/miekg/pkcs11 v1.0.3 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.2.2
|
||||||
github.com/morikuni/aec v1.0.0 // indirect
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
github.com/onsi/ginkgo v1.11.0 // indirect
|
github.com/onsi/ginkgo v1.11.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
package docker
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
cliconfig "github.com/docker/cli/cli/config"
|
||||||
|
"github.com/docker/cli/cli/context/store"
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
|
)
|
||||||
|
|
||||||
|
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 {
|
||||||
|
contextStore := initContextStore()
|
||||||
|
endpoints := map[string]interface{}{
|
||||||
|
"aws": awsContext,
|
||||||
|
"docker": awsContext,
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata := store.Metadata{
|
||||||
|
Name: name,
|
||||||
|
Endpoints: endpoints,
|
||||||
|
Metadata: TypeContext{Type: contextType},
|
||||||
|
}
|
||||||
|
return contextStore.CreateOrUpdate(metadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initContextStore() store.Store {
|
||||||
|
config := store.NewConfig(getter)
|
||||||
|
return store.New(cliconfig.ContextStoreDir(), config)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckAwsContextExists(contextName string) (*AwsContext, error) {
|
||||||
|
contextStore := initContextStore()
|
||||||
|
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
|
||||||
|
}
|
Loading…
Reference in New Issue