mirror of
https://github.com/docker/compose.git
synced 2025-07-23 21:54:40 +02:00
Use Project
from compose-go
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
dcf84f2499
commit
c5895fe09a
@ -7,9 +7,10 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/compose-spec/compose-go/cli"
|
||||||
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
amazon "github.com/docker/ecs-plugin/pkg/amazon/backend"
|
amazon "github.com/docker/ecs-plugin/pkg/amazon/backend"
|
||||||
"github.com/docker/ecs-plugin/pkg/compose"
|
|
||||||
"github.com/docker/ecs-plugin/pkg/docker"
|
"github.com/docker/ecs-plugin/pkg/docker"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -18,8 +19,8 @@ func ComposeCommand(dockerCli command.Cli) *cobra.Command {
|
|||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "compose",
|
Use: "compose",
|
||||||
}
|
}
|
||||||
opts := &compose.ProjectOptions{}
|
opts := &cli.ProjectOptions{}
|
||||||
opts.AddFlags(cmd.Flags())
|
AddFlags(opts, cmd.Flags())
|
||||||
|
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
ConvertCommand(dockerCli, opts),
|
ConvertCommand(dockerCli, opts),
|
||||||
@ -42,10 +43,10 @@ func (o upOptions) LoadBalancerArn() *string {
|
|||||||
return &o.loadBalancerArn
|
return &o.loadBalancerArn
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command {
|
func ConvertCommand(dockerCli command.Cli, projectOpts *cli.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: WithProject(projectOpts, func(project *types.Project, args []string) error {
|
||||||
clusteropts, err := docker.GetAwsContext(dockerCli)
|
clusteropts, err := docker.GetAwsContext(dockerCli)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -71,7 +72,7 @@ func ConvertCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions)
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command {
|
func UpCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
|
||||||
opts := upOptions{}
|
opts := upOptions{}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "up",
|
Use: "up",
|
||||||
@ -87,11 +88,11 @@ func UpCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobr
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func PsCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command {
|
func PsCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
|
||||||
opts := upOptions{}
|
opts := upOptions{}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "ps",
|
Use: "ps",
|
||||||
RunE: compose.WithProject(projectOpts, func(project *compose.Project, args []string) error {
|
RunE: WithProject(projectOpts, func(project *types.Project, args []string) error {
|
||||||
clusteropts, err := docker.GetAwsContext(dockerCli)
|
clusteropts, err := docker.GetAwsContext(dockerCli)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -120,7 +121,7 @@ type downOptions struct {
|
|||||||
DeleteCluster bool
|
DeleteCluster bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func DownCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command {
|
func DownCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
|
||||||
opts := downOptions{}
|
opts := downOptions{}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "down",
|
Use: "down",
|
||||||
@ -136,7 +137,7 @@ func DownCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *co
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func LogsCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command {
|
func LogsCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "logs [PROJECT NAME]",
|
Use: "logs [PROJECT NAME]",
|
||||||
RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error {
|
RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error {
|
||||||
@ -147,7 +148,7 @@ func LogsCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *co
|
|||||||
var name string
|
var name string
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
project, err := compose.ProjectFromOptions(projectOpts)
|
project, err := cli.ProjectFromOptions(projectOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,23 @@
|
|||||||
package compose
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/compose-spec/compose-go/cli"
|
||||||
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProjectOptions struct {
|
func AddFlags(o *cli.ProjectOptions, flags *pflag.FlagSet) {
|
||||||
ConfigPaths []string
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *ProjectOptions) AddFlags(flags *pflag.FlagSet) {
|
|
||||||
flags.StringArrayVarP(&o.ConfigPaths, "file", "f", nil, "Specify an alternate compose file")
|
flags.StringArrayVarP(&o.ConfigPaths, "file", "f", nil, "Specify an alternate compose file")
|
||||||
flags.StringVarP(&o.Name, "project-name", "n", "", "Specify an alternate project name (default: directory name)")
|
flags.StringVarP(&o.Name, "project-name", "n", "", "Specify an alternate project name (default: directory name)")
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProjectFunc func(project *Project, args []string) error
|
type ProjectFunc func(project *types.Project, args []string) error
|
||||||
|
|
||||||
// WithProject wrap a ProjectFunc into a cobra command
|
// WithProject wrap a ProjectFunc into a cobra command
|
||||||
func WithProject(options *ProjectOptions, f ProjectFunc) func(cmd *cobra.Command, args []string) error {
|
func WithProject(options *cli.ProjectOptions, f ProjectFunc) func(cmd *cobra.Command, args []string) error {
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *cobra.Command, args []string) error {
|
||||||
project, err := ProjectFromOptions(options)
|
project, err := cli.ProjectFromOptions(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
amazon "github.com/docker/ecs-plugin/pkg/amazon/backend"
|
amazon "github.com/docker/ecs-plugin/pkg/amazon/backend"
|
||||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
"github.com/docker/ecs-plugin/pkg/compose"
|
||||||
"github.com/docker/ecs-plugin/pkg/docker"
|
"github.com/docker/ecs-plugin/pkg/docker"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -57,7 +57,7 @@ func CreateSecret(dockerCli command.Cli) *cobra.Command {
|
|||||||
}
|
}
|
||||||
name := args[0]
|
name := args[0]
|
||||||
|
|
||||||
secret := types.NewSecret(name, opts.Username, opts.Password, opts.Description)
|
secret := compose.NewSecret(name, opts.Username, opts.Password, opts.Description)
|
||||||
id, err := backend.CreateSecret(context.Background(), secret)
|
id, err := backend.CreateSecret(context.Background(), secret)
|
||||||
fmt.Println(id)
|
fmt.Println(id)
|
||||||
return err
|
return err
|
||||||
@ -140,7 +140,7 @@ func DeleteSecret(dockerCli command.Cli) *cobra.Command {
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func printList(out io.Writer, secrets []types.Secret) {
|
func printList(out io.Writer, secrets []compose.Secret) {
|
||||||
printSection(out, len(secrets), func(w io.Writer) {
|
printSection(out, len(secrets), func(w io.Writer) {
|
||||||
for _, secret := range secrets {
|
for _, secret := range secrets {
|
||||||
fmt.Fprintf(w, "%s\t%s\t%s\n", secret.ID, secret.Name, secret.Description)
|
fmt.Fprintf(w, "%s\t%s\t%s\n", secret.ID, secret.Name, secret.Description)
|
||||||
|
@ -14,7 +14,7 @@ require (
|
|||||||
github.com/bugsnag/panicwrap v1.2.0 // indirect
|
github.com/bugsnag/panicwrap v1.2.0 // indirect
|
||||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||||
github.com/cloudflare/cfssl v1.4.1 // indirect
|
github.com/cloudflare/cfssl v1.4.1 // indirect
|
||||||
github.com/compose-spec/compose-go v0.0.0-20200409090215-53c0040c9127
|
github.com/compose-spec/compose-go v0.0.0-20200622094647-0bb9a6c7d89a
|
||||||
github.com/containerd/containerd v1.3.2 // indirect
|
github.com/containerd/containerd v1.3.2 // indirect
|
||||||
github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb // indirect
|
github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb // indirect
|
||||||
github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492
|
github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492
|
||||||
@ -35,11 +35,11 @@ require (
|
|||||||
github.com/manifoldco/promptui v0.7.0
|
github.com/manifoldco/promptui v0.7.0
|
||||||
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/mitchellh/mapstructure v1.3.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
|
||||||
github.com/sirupsen/logrus v1.5.0
|
github.com/sirupsen/logrus v1.6.0
|
||||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||||
github.com/spf13/cobra v0.0.5
|
github.com/spf13/cobra v0.0.5
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
@ -52,7 +52,6 @@ require (
|
|||||||
gopkg.in/fatih/pool.v2 v2.0.0 // indirect
|
gopkg.in/fatih/pool.v2 v2.0.0 // indirect
|
||||||
gopkg.in/gorethink/gorethink.v3 v3.0.5 // indirect
|
gopkg.in/gorethink/gorethink.v3 v3.0.5 // indirect
|
||||||
gopkg.in/ini.v1 v1.55.0
|
gopkg.in/ini.v1 v1.55.0
|
||||||
gotest.tools v2.2.0+incompatible
|
|
||||||
gotest.tools/v3 v3.0.2
|
gotest.tools/v3 v3.0.2
|
||||||
vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787 // indirect
|
vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787 // indirect
|
||||||
)
|
)
|
||||||
|
29
ecs/go.sum
29
ecs/go.sum
@ -54,8 +54,12 @@ github.com/cloudflare/cfssl v1.4.1 h1:vScfU2DrIUI9VPHBVeeAQ0q5A+9yshO1Gz+3QoUQiK
|
|||||||
github.com/cloudflare/cfssl v1.4.1/go.mod h1:KManx/OJPb5QY+y0+o/898AMcM128sF0bURvoVUSjTo=
|
github.com/cloudflare/cfssl v1.4.1/go.mod h1:KManx/OJPb5QY+y0+o/898AMcM128sF0bURvoVUSjTo=
|
||||||
github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4=
|
github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4=
|
||||||
github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo=
|
github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo=
|
||||||
github.com/compose-spec/compose-go v0.0.0-20200409090215-53c0040c9127 h1:mAsQN3s19glh3KBOQjiRYBhqaX1SdzNqhB3/cuqgSbE=
|
github.com/compose-spec/compose-go v0.0.0-20200616184722-5b8dc203fd7f h1:XE6hHZdPjxN8uGaRlvdCB8YwXbz1PXnQ0CboNygdL2o=
|
||||||
github.com/compose-spec/compose-go v0.0.0-20200409090215-53c0040c9127/go.mod h1:1PUpzRF1O/65VOqXZuwpCuYY7pJxbIq1jbAvAf62FGM=
|
github.com/compose-spec/compose-go v0.0.0-20200616184722-5b8dc203fd7f/go.mod h1:d3Vb4tH01Pr4YKD3RvfwguRcezDBUYJTVYgpCSRYSVg=
|
||||||
|
github.com/compose-spec/compose-go v0.0.0-20200617133919-fca3bb55c5cc h1:jZfF+HzxW+c8Em308MvcK7j5+ZqIAWqFjN1RZnVFzck=
|
||||||
|
github.com/compose-spec/compose-go v0.0.0-20200617133919-fca3bb55c5cc/go.mod h1:d3Vb4tH01Pr4YKD3RvfwguRcezDBUYJTVYgpCSRYSVg=
|
||||||
|
github.com/compose-spec/compose-go v0.0.0-20200622094647-0bb9a6c7d89a h1:FmEuebUePUA0Kd/NSiCmdPG/n6eKdZdBtIbfejVtRS8=
|
||||||
|
github.com/compose-spec/compose-go v0.0.0-20200622094647-0bb9a6c7d89a/go.mod h1:ih9anT8po+49hrb+1j3ldIJ/YRAaBH52ErlQLTKE2Yo=
|
||||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
||||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||||
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||||
@ -134,9 +138,12 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
|||||||
github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE=
|
github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE=
|
||||||
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
|
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0=
|
||||||
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 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||||
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
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/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
@ -151,6 +158,7 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
|||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
||||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
|
github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
|
||||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
@ -183,6 +191,8 @@ github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCy
|
|||||||
github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw=
|
github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
@ -218,8 +228,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
|
|||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4=
|
github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg=
|
||||||
github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
@ -282,8 +292,8 @@ github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvH
|
|||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
|
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||||
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
|
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||||
@ -330,6 +340,7 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2
|
|||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||||
|
github.com/xeipuuv/gojsonschema v0.0.0-20181112162635-ac52e6811b56 h1:yhqBHs09SmmUoNOHc9jgK4a60T3XFRtPAkYxVnqgY50=
|
||||||
github.com/xeipuuv/gojsonschema v0.0.0-20181112162635-ac52e6811b56/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
github.com/xeipuuv/gojsonschema v0.0.0-20181112162635-ac52e6811b56/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
@ -450,6 +461,8 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E=
|
gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E=
|
||||||
|
@ -5,14 +5,9 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
ecsapi "github.com/aws/aws-sdk-go/service/ecs"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/service/elbv2"
|
"github.com/aws/aws-sdk-go/service/elbv2"
|
||||||
cloudmapapi "github.com/aws/aws-sdk-go/service/servicediscovery"
|
cloudmapapi "github.com/aws/aws-sdk-go/service/servicediscovery"
|
||||||
|
|
||||||
ecsapi "github.com/aws/aws-sdk-go/service/ecs"
|
|
||||||
"github.com/awslabs/goformation/v4/cloudformation"
|
"github.com/awslabs/goformation/v4/cloudformation"
|
||||||
"github.com/awslabs/goformation/v4/cloudformation/ec2"
|
"github.com/awslabs/goformation/v4/cloudformation/ec2"
|
||||||
"github.com/awslabs/goformation/v4/cloudformation/ecs"
|
"github.com/awslabs/goformation/v4/cloudformation/ecs"
|
||||||
@ -21,10 +16,11 @@ import (
|
|||||||
"github.com/awslabs/goformation/v4/cloudformation/logs"
|
"github.com/awslabs/goformation/v4/cloudformation/logs"
|
||||||
cloudmap "github.com/awslabs/goformation/v4/cloudformation/servicediscovery"
|
cloudmap "github.com/awslabs/goformation/v4/cloudformation/servicediscovery"
|
||||||
"github.com/awslabs/goformation/v4/cloudformation/tags"
|
"github.com/awslabs/goformation/v4/cloudformation/tags"
|
||||||
"github.com/docker/ecs-plugin/pkg/amazon/compatibility"
|
"github.com/compose-spec/compose-go/compatibility"
|
||||||
|
"github.com/compose-spec/compose-go/types"
|
||||||
sdk "github.com/docker/ecs-plugin/pkg/amazon/sdk"
|
sdk "github.com/docker/ecs-plugin/pkg/amazon/sdk"
|
||||||
btypes "github.com/docker/ecs-plugin/pkg/amazon/types"
|
|
||||||
"github.com/docker/ecs-plugin/pkg/compose"
|
"github.com/docker/ecs-plugin/pkg/compose"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -35,11 +31,38 @@ const (
|
|||||||
ParameterLoadBalancerARN = "ParameterLoadBalancerARN"
|
ParameterLoadBalancerARN = "ParameterLoadBalancerARN"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type FargateCompatibilityChecker struct {
|
||||||
|
*compatibility.AllowList
|
||||||
|
}
|
||||||
|
|
||||||
// Convert a compose project into a CloudFormation template
|
// Convert a compose project into a CloudFormation template
|
||||||
func (b Backend) Convert(project *compose.Project) (*cloudformation.Template, error) {
|
func (b Backend) Convert(project *types.Project) (*cloudformation.Template, error) {
|
||||||
warnings := compatibility.Check(project)
|
var checker compatibility.Checker = FargateCompatibilityChecker{
|
||||||
for _, w := range warnings {
|
&compatibility.AllowList{
|
||||||
logrus.Warn(w)
|
Supported: []string{
|
||||||
|
"services.command",
|
||||||
|
"services.container_name",
|
||||||
|
"services.depends_on",
|
||||||
|
"services.entrypoint",
|
||||||
|
"services.environment",
|
||||||
|
"services.healthcheck",
|
||||||
|
"services.healthcheck.interval",
|
||||||
|
"services.healthcheck.start_period",
|
||||||
|
"services.healthcheck.test",
|
||||||
|
"services.healthcheck.timeout",
|
||||||
|
"services.networks",
|
||||||
|
"services.ports",
|
||||||
|
"services.ports.mode",
|
||||||
|
"services.ports.target",
|
||||||
|
"services.ports.protocol",
|
||||||
|
"services.user",
|
||||||
|
"services.working_dir",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
compatibility.Check(project, checker)
|
||||||
|
for _, err := range checker.Errors() {
|
||||||
|
logrus.Warn(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
template := cloudformation.NewTemplate()
|
template := cloudformation.NewTemplate()
|
||||||
@ -188,7 +211,7 @@ func (b Backend) Convert(project *compose.Project) (*cloudformation.Template, er
|
|||||||
return template, nil
|
return template, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLoadBalancerType(project *compose.Project) string {
|
func getLoadBalancerType(project *types.Project) string {
|
||||||
for _, service := range project.Services {
|
for _, service := range project.Services {
|
||||||
for _, port := range service.Ports {
|
for _, port := range service.Ports {
|
||||||
if port.Published != 80 && port.Published != 443 {
|
if port.Published != 80 && port.Published != 443 {
|
||||||
@ -199,7 +222,7 @@ func getLoadBalancerType(project *compose.Project) string {
|
|||||||
return elbv2.LoadBalancerTypeEnumApplication
|
return elbv2.LoadBalancerTypeEnumApplication
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLoadBalancerSecurityGroups(project *compose.Project, template *cloudformation.Template) []string {
|
func getLoadBalancerSecurityGroups(project *types.Project, template *cloudformation.Template) []string {
|
||||||
securityGroups := []string{}
|
securityGroups := []string{}
|
||||||
for _, network := range project.Networks {
|
for _, network := range project.Networks {
|
||||||
if !network.Internal {
|
if !network.Internal {
|
||||||
@ -210,7 +233,7 @@ func getLoadBalancerSecurityGroups(project *compose.Project, template *cloudform
|
|||||||
return uniqueStrings(securityGroups)
|
return uniqueStrings(securityGroups)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createLoadBalancer(project *compose.Project, template *cloudformation.Template) string {
|
func createLoadBalancer(project *types.Project, template *cloudformation.Template) string {
|
||||||
loadBalancerName := fmt.Sprintf("%sLoadBalancer", strings.Title(project.Name))
|
loadBalancerName := fmt.Sprintf("%sLoadBalancer", strings.Title(project.Name))
|
||||||
// Create LoadBalancer if `ParameterLoadBalancerName` is not set
|
// Create LoadBalancer if `ParameterLoadBalancerName` is not set
|
||||||
template.Conditions["CreateLoadBalancer"] = cloudformation.Equals("", cloudformation.Ref(ParameterLoadBalancerARN))
|
template.Conditions["CreateLoadBalancer"] = cloudformation.Equals("", cloudformation.Ref(ParameterLoadBalancerARN))
|
||||||
@ -270,7 +293,7 @@ func createListener(service types.ServiceConfig, port types.ServicePortConfig, t
|
|||||||
return listenerName
|
return listenerName
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTargetGroup(project *compose.Project, service types.ServiceConfig, port types.ServicePortConfig, template *cloudformation.Template, protocol string) string {
|
func createTargetGroup(project *types.Project, service types.ServiceConfig, port types.ServicePortConfig, template *cloudformation.Template, protocol string) string {
|
||||||
targetGroupName := fmt.Sprintf(
|
targetGroupName := fmt.Sprintf(
|
||||||
"%s%s%dTargetGroup",
|
"%s%s%dTargetGroup",
|
||||||
normalizeResourceName(service.Name),
|
normalizeResourceName(service.Name),
|
||||||
@ -345,7 +368,7 @@ func createTaskExecutionRole(service types.ServiceConfig, err error, definition
|
|||||||
return taskExecutionRole, nil
|
return taskExecutionRole, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createCluster(project *compose.Project, template *cloudformation.Template) string {
|
func createCluster(project *types.Project, template *cloudformation.Template) string {
|
||||||
template.Resources["Cluster"] = &ecs.Cluster{
|
template.Resources["Cluster"] = &ecs.Cluster{
|
||||||
ClusterName: project.Name,
|
ClusterName: project.Name,
|
||||||
Tags: []tags.Tag{
|
Tags: []tags.Tag{
|
||||||
@ -360,7 +383,7 @@ func createCluster(project *compose.Project, template *cloudformation.Template)
|
|||||||
return cluster
|
return cluster
|
||||||
}
|
}
|
||||||
|
|
||||||
func createCloudMap(project *compose.Project, template *cloudformation.Template) {
|
func createCloudMap(project *types.Project, template *cloudformation.Template) {
|
||||||
template.Resources["CloudMap"] = &cloudmap.PrivateDnsNamespace{
|
template.Resources["CloudMap"] = &cloudmap.PrivateDnsNamespace{
|
||||||
Description: fmt.Sprintf("Service Map for Docker Compose project %s", project.Name),
|
Description: fmt.Sprintf("Service Map for Docker Compose project %s", project.Name),
|
||||||
Name: fmt.Sprintf("%s.local", project.Name),
|
Name: fmt.Sprintf("%s.local", project.Name),
|
||||||
@ -368,8 +391,8 @@ func createCloudMap(project *compose.Project, template *cloudformation.Template)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc string, template *cloudformation.Template) string {
|
func convertNetwork(project *types.Project, net types.NetworkConfig, vpc string, template *cloudformation.Template) string {
|
||||||
if sg, ok := net.Extras[btypes.ExtensionSecurityGroup]; ok {
|
if sg, ok := net.Extensions[compose.ExtensionSecurityGroup]; ok {
|
||||||
logrus.Debugf("Security Group for network %q set by user to %q", net.Name, sg)
|
logrus.Debugf("Security Group for network %q set by user to %q", net.Name, sg)
|
||||||
return sg.(string)
|
return sg.(string)
|
||||||
}
|
}
|
||||||
@ -420,7 +443,7 @@ func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc strin
|
|||||||
return cloudformation.Ref(securityGroup)
|
return cloudformation.Ref(securityGroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
func networkResourceName(project *compose.Project, network string) string {
|
func networkResourceName(project *types.Project, network string) string {
|
||||||
return fmt.Sprintf("%s%sNetwork", normalizeResourceName(project.Name), normalizeResourceName(network))
|
return fmt.Sprintf("%s%sNetwork", normalizeResourceName(project.Name), normalizeResourceName(network))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,13 +7,11 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/service/elbv2"
|
"github.com/aws/aws-sdk-go/service/elbv2"
|
||||||
"github.com/awslabs/goformation/v4/cloudformation"
|
"github.com/awslabs/goformation/v4/cloudformation"
|
||||||
"github.com/awslabs/goformation/v4/cloudformation/ec2"
|
"github.com/awslabs/goformation/v4/cloudformation/ec2"
|
||||||
"github.com/awslabs/goformation/v4/cloudformation/iam"
|
|
||||||
|
|
||||||
"github.com/awslabs/goformation/v4/cloudformation/elasticloadbalancingv2"
|
"github.com/awslabs/goformation/v4/cloudformation/elasticloadbalancingv2"
|
||||||
|
"github.com/awslabs/goformation/v4/cloudformation/iam"
|
||||||
|
"github.com/compose-spec/compose-go/cli"
|
||||||
"github.com/compose-spec/compose-go/loader"
|
"github.com/compose-spec/compose-go/loader"
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/docker/ecs-plugin/pkg/compose"
|
|
||||||
|
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
)
|
)
|
||||||
@ -58,6 +56,10 @@ version: "3"
|
|||||||
services:
|
services:
|
||||||
test:
|
test:
|
||||||
image: hello_world
|
image: hello_world
|
||||||
|
networks:
|
||||||
|
- front-tier
|
||||||
|
- back-tier
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
front-tier:
|
front-tier:
|
||||||
name: public
|
name: public
|
||||||
@ -103,7 +105,7 @@ services:
|
|||||||
assert.Check(t, lb.Type == elbv2.LoadBalancerTypeEnumNetwork)
|
assert.Check(t, lb.Type == elbv2.LoadBalancerTypeEnumNetwork)
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertResultAsString(t *testing.T, project *compose.Project, clusterName string) string {
|
func convertResultAsString(t *testing.T, project *types.Project, clusterName string) string {
|
||||||
client, err := NewBackend("", clusterName, "")
|
client, err := NewBackend("", clusterName, "")
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
result, err := client.Convert(project)
|
result, err := client.Convert(project)
|
||||||
@ -113,12 +115,12 @@ func convertResultAsString(t *testing.T, project *compose.Project, clusterName s
|
|||||||
return fmt.Sprintf("%s\n", string(resultAsJSON))
|
return fmt.Sprintf("%s\n", string(resultAsJSON))
|
||||||
}
|
}
|
||||||
|
|
||||||
func load(t *testing.T, paths ...string) *compose.Project {
|
func load(t *testing.T, paths ...string) *types.Project {
|
||||||
options := compose.ProjectOptions{
|
options := cli.ProjectOptions{
|
||||||
Name: t.Name(),
|
Name: t.Name(),
|
||||||
ConfigPaths: paths,
|
ConfigPaths: paths,
|
||||||
}
|
}
|
||||||
project, err := compose.ProjectFromOptions(&options)
|
project, err := cli.ProjectFromOptions(&options)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
return project
|
return project
|
||||||
}
|
}
|
||||||
@ -130,14 +132,11 @@ func convertYaml(t *testing.T, yaml string) *cloudformation.Template {
|
|||||||
ConfigFiles: []types.ConfigFile{
|
ConfigFiles: []types.ConfigFile{
|
||||||
{Config: dict},
|
{Config: dict},
|
||||||
},
|
},
|
||||||
|
}, func(options *loader.Options) {
|
||||||
|
options.Name = "Test"
|
||||||
})
|
})
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
err = compose.Normalize(model)
|
template, err := Backend{}.Convert(model)
|
||||||
assert.NilError(t, err)
|
|
||||||
template, err := Backend{}.Convert(&compose.Project{
|
|
||||||
Config: *model,
|
|
||||||
Name: "test",
|
|
||||||
})
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
return template
|
return template
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,14 @@ package backend
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
"github.com/compose-spec/compose-go/cli"
|
||||||
"github.com/docker/ecs-plugin/pkg/compose"
|
"github.com/docker/ecs-plugin/pkg/compose"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *Backend) Down(ctx context.Context, options compose.ProjectOptions) error {
|
func (b *Backend) Down(ctx context.Context, options cli.ProjectOptions) error {
|
||||||
name := options.Name
|
name := options.Name
|
||||||
if name == "" {
|
if name == "" {
|
||||||
project, err := compose.ProjectFromOptions(&options)
|
project, err := cli.ProjectFromOptions(&options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ func (b *Backend) Down(ctx context.Context, options compose.ProjectOptions) erro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = b.WaitStackCompletion(ctx, name, types.StackDelete)
|
err = b.WaitStackCompletion(ctx, name, compose.StackDelete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/compose-spec/compose-go/cli"
|
||||||
"github.com/docker/ecs-plugin/pkg/amazon/sdk"
|
"github.com/docker/ecs-plugin/pkg/amazon/sdk"
|
||||||
btypes "github.com/docker/ecs-plugin/pkg/amazon/types"
|
|
||||||
"github.com/docker/ecs-plugin/pkg/compose"
|
"github.com/docker/ecs-plugin/pkg/compose"
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
)
|
)
|
||||||
@ -23,10 +23,10 @@ func TestDown(t *testing.T) {
|
|||||||
recorder := m.EXPECT()
|
recorder := m.EXPECT()
|
||||||
recorder.DeleteStack(ctx, "test_project").Return(nil)
|
recorder.DeleteStack(ctx, "test_project").Return(nil)
|
||||||
recorder.GetStackID(ctx, "test_project").Return("stack-123", nil)
|
recorder.GetStackID(ctx, "test_project").Return("stack-123", nil)
|
||||||
recorder.WaitStackComplete(ctx, "stack-123", btypes.StackDelete).Return(nil)
|
recorder.WaitStackComplete(ctx, "stack-123", compose.StackDelete).Return(nil)
|
||||||
recorder.DescribeStackEvents(ctx, "stack-123").Return(nil, nil)
|
recorder.DescribeStackEvents(ctx, "stack-123").Return(nil, nil)
|
||||||
|
|
||||||
c.Down(ctx, compose.ProjectOptions{
|
c.Down(ctx, cli.ProjectOptions{
|
||||||
ConfigPaths: []string{},
|
ConfigPaths: []string{},
|
||||||
Name: "test_project",
|
Name: "test_project",
|
||||||
})
|
})
|
||||||
|
@ -6,11 +6,11 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/docker/ecs-plugin/pkg/compose"
|
"github.com/docker/ecs-plugin/pkg/compose"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *Backend) Ps(ctx context.Context, project *compose.Project) ([]types.TaskStatus, error) {
|
func (b *Backend) Ps(ctx context.Context, project *types.Project) ([]compose.TaskStatus, error) {
|
||||||
cluster := b.Cluster
|
cluster := b.Cluster
|
||||||
if cluster == "" {
|
if cluster == "" {
|
||||||
cluster = project.Name
|
cluster = project.Name
|
||||||
@ -19,17 +19,17 @@ func (b *Backend) Ps(ctx context.Context, project *compose.Project) ([]types.Tas
|
|||||||
for _, service := range project.Services {
|
for _, service := range project.Services {
|
||||||
tasks, err := b.api.ListTasks(ctx, cluster, service.Name)
|
tasks, err := b.api.ListTasks(ctx, cluster, service.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []types.TaskStatus{}, err
|
return []compose.TaskStatus{}, err
|
||||||
}
|
}
|
||||||
arns = append(arns, tasks...)
|
arns = append(arns, tasks...)
|
||||||
}
|
}
|
||||||
if len(arns) == 0 {
|
if len(arns) == 0 {
|
||||||
return []types.TaskStatus{}, nil
|
return []compose.TaskStatus{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks, err := b.api.DescribeTasks(ctx, cluster, arns...)
|
tasks, err := b.api.DescribeTasks(ctx, cluster, arns...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []types.TaskStatus{}, err
|
return []compose.TaskStatus{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
networkInterfaces := []string{}
|
networkInterfaces := []string{}
|
||||||
@ -40,21 +40,21 @@ func (b *Backend) Ps(ctx context.Context, project *compose.Project) ([]types.Tas
|
|||||||
}
|
}
|
||||||
publicIps, err := b.api.GetPublicIPs(ctx, networkInterfaces...)
|
publicIps, err := b.api.GetPublicIPs(ctx, networkInterfaces...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []types.TaskStatus{}, err
|
return []compose.TaskStatus{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(tasks, func(i, j int) bool {
|
sort.Slice(tasks, func(i, j int) bool {
|
||||||
return strings.Compare(tasks[i].Service, tasks[j].Service) < 0
|
return strings.Compare(tasks[i].Service, tasks[j].Service) < 0
|
||||||
})
|
})
|
||||||
|
|
||||||
for i, t := range tasks {
|
for i, task := range tasks {
|
||||||
ports := []string{}
|
ports := []string{}
|
||||||
s, err := project.GetService(t.Service)
|
s, err := project.GetService(task.Service)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []types.TaskStatus{}, err
|
return []compose.TaskStatus{}, err
|
||||||
}
|
}
|
||||||
for _, p := range s.Ports {
|
for _, p := range s.Ports {
|
||||||
ports = append(ports, fmt.Sprintf("%s:%d->%d/%s", publicIps[t.NetworkInterface], p.Published, p.Target, p.Protocol))
|
ports = append(ports, fmt.Sprintf("%s:%d->%d/%s", publicIps[task.NetworkInterface], p.Published, p.Target, p.Protocol))
|
||||||
}
|
}
|
||||||
tasks[i].Name = s.Name
|
tasks[i].Name = s.Name
|
||||||
tasks[i].Ports = ports
|
tasks[i].Ports = ports
|
||||||
|
@ -3,18 +3,18 @@ package backend
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
"github.com/docker/ecs-plugin/pkg/compose"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b Backend) CreateSecret(ctx context.Context, secret types.Secret) (string, error) {
|
func (b Backend) CreateSecret(ctx context.Context, secret compose.Secret) (string, error) {
|
||||||
return b.api.CreateSecret(ctx, secret)
|
return b.api.CreateSecret(ctx, secret)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Backend) InspectSecret(ctx context.Context, id string) (types.Secret, error) {
|
func (b Backend) InspectSecret(ctx context.Context, id string) (compose.Secret, error) {
|
||||||
return b.api.InspectSecret(ctx, id)
|
return b.api.InspectSecret(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Backend) ListSecrets(ctx context.Context) ([]types.Secret, error) {
|
func (b Backend) ListSecrets(ctx context.Context) ([]compose.Secret, error) {
|
||||||
return b.api.ListSecrets(ctx)
|
return b.api.ListSecrets(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,12 +4,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
"github.com/compose-spec/compose-go/cli"
|
||||||
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/docker/ecs-plugin/pkg/compose"
|
"github.com/docker/ecs-plugin/pkg/compose"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *Backend) Up(ctx context.Context, options compose.ProjectOptions) error {
|
func (b *Backend) Up(ctx context.Context, options cli.ProjectOptions) error {
|
||||||
project, err := compose.ProjectFromOptions(&options)
|
project, err := cli.ProjectFromOptions(&options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -66,12 +67,12 @@ func (b *Backend) Up(ctx context.Context, options compose.ProjectOptions) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
return b.WaitStackCompletion(ctx, project.Name, types.StackCreate)
|
return b.WaitStackCompletion(ctx, project.Name, compose.StackCreate)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Backend) GetVPC(ctx context.Context, project *compose.Project) (string, error) {
|
func (b Backend) GetVPC(ctx context.Context, project *types.Project) (string, error) {
|
||||||
//check compose file for custom VPC selected
|
//check compose file for custom VPC selected
|
||||||
if vpc, ok := project.Extras[types.ExtensionVPC]; ok {
|
if vpc, ok := project.Extensions[compose.ExtensionVPC]; ok {
|
||||||
vpcID := vpc.(string)
|
vpcID := vpc.(string)
|
||||||
ok, err := b.api.VpcExists(ctx, vpcID)
|
ok, err := b.api.VpcExists(ctx, vpcID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -88,9 +89,9 @@ func (b Backend) GetVPC(ctx context.Context, project *compose.Project) (string,
|
|||||||
return defaultVPC, nil
|
return defaultVPC, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b Backend) GetLoadBalancer(ctx context.Context, project *compose.Project) (string, error) {
|
func (b Backend) GetLoadBalancer(ctx context.Context, project *types.Project) (string, error) {
|
||||||
//check compose file for custom VPC selected
|
//check compose file for custom VPC selected
|
||||||
if lb, ok := project.Extras[types.ExtensionLB]; ok {
|
if lb, ok := project.Extensions[compose.ExtensionLB]; ok {
|
||||||
lbName := lb.(string)
|
lbName := lb.(string)
|
||||||
ok, err := b.api.LoadBalancerExists(ctx, lbName)
|
ok, err := b.api.LoadBalancerExists(ctx, lbName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
package compatibility
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
|
||||||
"github.com/docker/ecs-plugin/pkg/compose"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Warning string
|
|
||||||
type Warnings []string
|
|
||||||
|
|
||||||
type Checker interface {
|
|
||||||
CheckService(service *types.ServiceConfig)
|
|
||||||
CheckCapAdd(service *types.ServiceConfig)
|
|
||||||
CheckDNS(service *types.ServiceConfig)
|
|
||||||
CheckDNSOpts(service *types.ServiceConfig)
|
|
||||||
CheckDNSSearch(service *types.ServiceConfig)
|
|
||||||
CheckDomainName(service *types.ServiceConfig)
|
|
||||||
CheckExtraHosts(service *types.ServiceConfig)
|
|
||||||
CheckHostname(service *types.ServiceConfig)
|
|
||||||
CheckIpc(service *types.ServiceConfig)
|
|
||||||
CheckLabels(service *types.ServiceConfig)
|
|
||||||
CheckLinks(service *types.ServiceConfig)
|
|
||||||
CheckLogging(service *types.ServiceConfig)
|
|
||||||
CheckMacAddress(service *types.ServiceConfig)
|
|
||||||
CheckNetworkMode(service *types.ServiceConfig)
|
|
||||||
CheckPid(service *types.ServiceConfig)
|
|
||||||
CheckSysctls(service *types.ServiceConfig)
|
|
||||||
CheckTmpfs(service *types.ServiceConfig)
|
|
||||||
CheckUserNSMode(service *types.ServiceConfig)
|
|
||||||
Errors() []error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the compose model do not use unsupported features and inject sane defaults for ECS deployment
|
|
||||||
func Check(project *compose.Project) []error {
|
|
||||||
c := FargateCompatibilityChecker{}
|
|
||||||
for i, service := range project.Services {
|
|
||||||
c.CheckService(&service)
|
|
||||||
project.Services[i] = service
|
|
||||||
}
|
|
||||||
return c.errors
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package compatibility
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/docker/ecs-plugin/pkg/compose"
|
|
||||||
"gotest.tools/v3/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func load(t *testing.T, paths ...string) *compose.Project {
|
|
||||||
options := compose.ProjectOptions{
|
|
||||||
Name: t.Name(),
|
|
||||||
ConfigPaths: paths,
|
|
||||||
}
|
|
||||||
project, err := compose.ProjectFromOptions(&options)
|
|
||||||
assert.NilError(t, err)
|
|
||||||
return project
|
|
||||||
}
|
|
||||||
func TestInvalidNetworkMode(t *testing.T) {
|
|
||||||
project := load(t, "../backend/testdata/invalid_network_mode.yaml")
|
|
||||||
err := Check(project)
|
|
||||||
assert.Error(t, err[0], "'network_mode' \"bridge\" is not supported")
|
|
||||||
}
|
|
@ -1,171 +0,0 @@
|
|||||||
package compatibility
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/service/ecs"
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FargateCompatibilityChecker struct {
|
|
||||||
errors []error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) error(message string, args ...interface{}) {
|
|
||||||
c.errors = append(c.errors, fmt.Errorf(message, args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) Errors() []error {
|
|
||||||
return c.errors
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckService(service *types.ServiceConfig) {
|
|
||||||
c.CheckCapAdd(service)
|
|
||||||
c.CheckDNS(service)
|
|
||||||
c.CheckDNSOpts(service)
|
|
||||||
c.CheckDNSSearch(service)
|
|
||||||
c.CheckDomainName(service)
|
|
||||||
c.CheckExtraHosts(service)
|
|
||||||
c.CheckHostname(service)
|
|
||||||
c.CheckIpc(service)
|
|
||||||
c.CheckLabels(service)
|
|
||||||
c.CheckLinks(service)
|
|
||||||
c.CheckLogging(service)
|
|
||||||
c.CheckMacAddress(service)
|
|
||||||
c.CheckNetworkMode(service)
|
|
||||||
c.CheckPid(service)
|
|
||||||
c.CheckSysctls(service)
|
|
||||||
c.CheckTmpfs(service)
|
|
||||||
c.CheckUserNSMode(service)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckNetworkMode(service *types.ServiceConfig) {
|
|
||||||
if service.NetworkMode != "" && service.NetworkMode != ecs.NetworkModeAwsvpc {
|
|
||||||
c.error("'network_mode' %q is not supported", service.NetworkMode)
|
|
||||||
}
|
|
||||||
service.NetworkMode = ecs.NetworkModeAwsvpc
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckLinks(service *types.ServiceConfig) {
|
|
||||||
if len(service.Links) != 0 {
|
|
||||||
c.error("'links' is not supported")
|
|
||||||
service.Links = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckLogging(service *types.ServiceConfig) {
|
|
||||||
c.CheckLoggingDriver(service)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckLoggingDriver(service *types.ServiceConfig) {
|
|
||||||
if service.LogDriver != "" && service.LogDriver != ecs.LogDriverAwslogs {
|
|
||||||
c.error("'log_driver' %q is not supported", service.LogDriver)
|
|
||||||
service.LogDriver = ecs.LogDriverAwslogs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckPid(service *types.ServiceConfig) {
|
|
||||||
if service.Pid != "" {
|
|
||||||
c.error("'pid' is not supported")
|
|
||||||
service.Pid = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckUserNSMode(service *types.ServiceConfig) {
|
|
||||||
if service.UserNSMode != "" {
|
|
||||||
c.error("'userns_mode' is not supported")
|
|
||||||
service.UserNSMode = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckIpc(service *types.ServiceConfig) {
|
|
||||||
if service.Ipc != "" {
|
|
||||||
c.error("'ipc' is not supported")
|
|
||||||
service.Ipc = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckMacAddress(service *types.ServiceConfig) {
|
|
||||||
if service.MacAddress != "" {
|
|
||||||
c.error("'mac_address' is not supported")
|
|
||||||
service.MacAddress = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckHostname(service *types.ServiceConfig) {
|
|
||||||
if service.Hostname != "" {
|
|
||||||
c.error("'hostname' is not supported")
|
|
||||||
service.Hostname = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckDomainName(service *types.ServiceConfig) {
|
|
||||||
if service.DomainName != "" {
|
|
||||||
c.error("'domainname' is not supported")
|
|
||||||
service.DomainName = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckDNSSearch(service *types.ServiceConfig) {
|
|
||||||
if len(service.DNSSearch) > 0 {
|
|
||||||
c.error("'dns_search' is not supported")
|
|
||||||
service.DNSSearch = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckDNS(service *types.ServiceConfig) {
|
|
||||||
if len(service.DNS) > 0 {
|
|
||||||
c.error("'dns' is not supported")
|
|
||||||
service.DNS = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckDNSOpts(service *types.ServiceConfig) {
|
|
||||||
if len(service.DNSOpts) > 0 {
|
|
||||||
c.error("'dns_opt' is not supported")
|
|
||||||
service.DNSOpts = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckExtraHosts(service *types.ServiceConfig) {
|
|
||||||
if len(service.ExtraHosts) > 0 {
|
|
||||||
c.error("'extra_hosts' is not supported")
|
|
||||||
service.ExtraHosts = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckCapAdd(service *types.ServiceConfig) {
|
|
||||||
for i, v := range service.CapAdd {
|
|
||||||
if v != "SYS_PTRACE" {
|
|
||||||
c.error("'cap_add' %s is not supported", v)
|
|
||||||
l := len(service.CapAdd)
|
|
||||||
service.CapAdd[i] = service.CapAdd[l-1]
|
|
||||||
service.CapAdd = service.CapAdd[:l-1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckTmpfs(service *types.ServiceConfig) {
|
|
||||||
if len(service.Tmpfs) > 0 {
|
|
||||||
c.error("'tmpfs' is not supported")
|
|
||||||
service.Tmpfs = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckSysctls(service *types.ServiceConfig) {
|
|
||||||
if len(service.Sysctls) > 0 {
|
|
||||||
c.error("'sysctls' is not supported")
|
|
||||||
service.Sysctls = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FargateCompatibilityChecker) CheckLabels(service *types.ServiceConfig) {
|
|
||||||
for k, v := range service.Labels {
|
|
||||||
if v == "" {
|
|
||||||
c.error("'labels' with an empty value is not supported")
|
|
||||||
delete(service.Labels, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ Checker = &FargateCompatibilityChecker{}
|
|
@ -5,7 +5,7 @@ import (
|
|||||||
|
|
||||||
cf "github.com/aws/aws-sdk-go/service/cloudformation"
|
cf "github.com/aws/aws-sdk-go/service/cloudformation"
|
||||||
"github.com/awslabs/goformation/v4/cloudformation"
|
"github.com/awslabs/goformation/v4/cloudformation"
|
||||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
"github.com/docker/ecs-plugin/pkg/compose"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate mockgen -destination=./api_mock.go -self_package "github.com/docker/ecs-plugin/pkg/amazon" -package=amazon . API
|
//go:generate mockgen -destination=./api_mock.go -self_package "github.com/docker/ecs-plugin/pkg/amazon" -package=amazon . API
|
||||||
@ -38,19 +38,19 @@ type downAPI interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type logsAPI interface {
|
type logsAPI interface {
|
||||||
GetLogs(ctx context.Context, name string, consumer types.LogConsumer) error
|
GetLogs(ctx context.Context, name string, consumer compose.LogConsumer) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type secretsAPI interface {
|
type secretsAPI interface {
|
||||||
CreateSecret(ctx context.Context, secret types.Secret) (string, error)
|
CreateSecret(ctx context.Context, secret compose.Secret) (string, error)
|
||||||
InspectSecret(ctx context.Context, id string) (types.Secret, error)
|
InspectSecret(ctx context.Context, id string) (compose.Secret, error)
|
||||||
ListSecrets(ctx context.Context) ([]types.Secret, error)
|
ListSecrets(ctx context.Context) ([]compose.Secret, error)
|
||||||
DeleteSecret(ctx context.Context, id string, recover bool) error
|
DeleteSecret(ctx context.Context, id string, recover bool) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type listAPI interface {
|
type listAPI interface {
|
||||||
ListTasks(ctx context.Context, cluster string, name string) ([]string, error)
|
ListTasks(ctx context.Context, cluster string, name string) ([]string, error)
|
||||||
DescribeTasks(ctx context.Context, cluster string, arns ...string) ([]types.TaskStatus, error)
|
DescribeTasks(ctx context.Context, cluster string, arns ...string) ([]compose.TaskStatus, error)
|
||||||
GetPublicIPs(ctx context.Context, interfaces ...string) (map[string]string, error)
|
GetPublicIPs(ctx context.Context, interfaces ...string) (map[string]string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,10 @@ import (
|
|||||||
context "context"
|
context "context"
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
|
"github.com/docker/ecs-plugin/pkg/compose"
|
||||||
|
|
||||||
cloudformation "github.com/aws/aws-sdk-go/service/cloudformation"
|
cloudformation "github.com/aws/aws-sdk-go/service/cloudformation"
|
||||||
cloudformation0 "github.com/awslabs/goformation/v4/cloudformation"
|
cloudformation0 "github.com/awslabs/goformation/v4/cloudformation"
|
||||||
btypes "github.com/docker/ecs-plugin/pkg/amazon/types"
|
|
||||||
gomock "github.com/golang/mock/gomock"
|
gomock "github.com/golang/mock/gomock"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ func (mr *MockAPIMockRecorder) ClusterExists(arg0, arg1 interface{}) *gomock.Cal
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateSecret mocks base method
|
// CreateSecret mocks base method
|
||||||
func (m *MockAPI) CreateSecret(arg0 context.Context, arg1 btypes.Secret) (string, error) {
|
func (m *MockAPI) CreateSecret(arg0 context.Context, arg1 compose.Secret) (string, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "CreateSecret", arg0, arg1)
|
ret := m.ctrl.Call(m, "CreateSecret", arg0, arg1)
|
||||||
ret0, _ := ret[0].(string)
|
ret0, _ := ret[0].(string)
|
||||||
@ -139,14 +140,14 @@ func (mr *MockAPIMockRecorder) DescribeStackEvents(arg0, arg1 interface{}) *gomo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DescribeTasks mocks base method
|
// DescribeTasks mocks base method
|
||||||
func (m *MockAPI) DescribeTasks(arg0 context.Context, arg1 string, arg2 ...string) ([]btypes.TaskStatus, error) {
|
func (m *MockAPI) DescribeTasks(arg0 context.Context, arg1 string, arg2 ...string) ([]compose.TaskStatus, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
varargs := []interface{}{arg0, arg1}
|
varargs := []interface{}{arg0, arg1}
|
||||||
for _, a := range arg2 {
|
for _, a := range arg2 {
|
||||||
varargs = append(varargs, a)
|
varargs = append(varargs, a)
|
||||||
}
|
}
|
||||||
ret := m.ctrl.Call(m, "DescribeTasks", varargs...)
|
ret := m.ctrl.Call(m, "DescribeTasks", varargs...)
|
||||||
ret0, _ := ret[0].([]btypes.TaskStatus)
|
ret0, _ := ret[0].([]compose.TaskStatus)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
@ -174,7 +175,7 @@ func (mr *MockAPIMockRecorder) GetDefaultVPC(arg0 interface{}) *gomock.Call {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetLogs mocks base method
|
// GetLogs mocks base method
|
||||||
func (m *MockAPI) GetLogs(arg0 context.Context, arg1 string, arg2 btypes.LogConsumer) error {
|
func (m *MockAPI) GetLogs(arg0 context.Context, arg1 string, arg2 compose.LogConsumer) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "GetLogs", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "GetLogs", arg0, arg1, arg2)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
@ -238,10 +239,10 @@ func (mr *MockAPIMockRecorder) GetSubNets(arg0, arg1 interface{}) *gomock.Call {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// InspectSecret mocks base method
|
// InspectSecret mocks base method
|
||||||
func (m *MockAPI) InspectSecret(arg0 context.Context, arg1 string) (btypes.Secret, error) {
|
func (m *MockAPI) InspectSecret(arg0 context.Context, arg1 string) (compose.Secret, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "InspectSecret", arg0, arg1)
|
ret := m.ctrl.Call(m, "InspectSecret", arg0, arg1)
|
||||||
ret0, _ := ret[0].(btypes.Secret)
|
ret0, _ := ret[0].(compose.Secret)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
@ -253,10 +254,10 @@ func (mr *MockAPIMockRecorder) InspectSecret(arg0, arg1 interface{}) *gomock.Cal
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListSecrets mocks base method
|
// ListSecrets mocks base method
|
||||||
func (m *MockAPI) ListSecrets(arg0 context.Context) ([]btypes.Secret, error) {
|
func (m *MockAPI) ListSecrets(arg0 context.Context) ([]compose.Secret, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "ListSecrets", arg0)
|
ret := m.ctrl.Call(m, "ListSecrets", arg0)
|
||||||
ret0, _ := ret[0].([]btypes.Secret)
|
ret0, _ := ret[0].([]compose.Secret)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,10 @@ import (
|
|||||||
"github.com/awslabs/goformation/v4/cloudformation/tags"
|
"github.com/awslabs/goformation/v4/cloudformation/tags"
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
t "github.com/docker/ecs-plugin/pkg/amazon/types"
|
|
||||||
"github.com/docker/ecs-plugin/pkg/compose"
|
"github.com/docker/ecs-plugin/pkg/compose"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Convert(project *compose.Project, service types.ServiceConfig) (*ecs.TaskDefinition, error) {
|
func Convert(project *types.Project, service types.ServiceConfig) (*ecs.TaskDefinition, error) {
|
||||||
cpu, mem, err := toLimits(service)
|
cpu, mem, err := toLimits(service)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -318,8 +317,8 @@ func getImage(image string) string {
|
|||||||
|
|
||||||
func getRepoCredentials(service types.ServiceConfig) *ecs.TaskDefinition_RepositoryCredentials {
|
func getRepoCredentials(service types.ServiceConfig) *ecs.TaskDefinition_RepositoryCredentials {
|
||||||
// extract registry and namespace string from image name
|
// extract registry and namespace string from image name
|
||||||
for key, value := range service.Extras {
|
for key, value := range service.Extensions {
|
||||||
if key == t.ExtensionPullCredentials {
|
if key == compose.ExtensionPullCredentials {
|
||||||
return &ecs.TaskDefinition_RepositoryCredentials{CredentialsParameter: value.(string)}
|
return &ecs.TaskDefinition_RepositoryCredentials{CredentialsParameter: value.(string)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,8 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/service/secretsmanager"
|
"github.com/aws/aws-sdk-go/service/secretsmanager"
|
||||||
"github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface"
|
"github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface"
|
||||||
cf "github.com/awslabs/goformation/v4/cloudformation"
|
cf "github.com/awslabs/goformation/v4/cloudformation"
|
||||||
|
"github.com/docker/ecs-plugin/pkg/compose"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
|
||||||
t "github.com/docker/ecs-plugin/pkg/amazon/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type sdk struct {
|
type sdk struct {
|
||||||
@ -189,9 +187,9 @@ func (s sdk) WaitStackComplete(ctx context.Context, name string, operation int)
|
|||||||
StackName: aws.String(name),
|
StackName: aws.String(name),
|
||||||
}
|
}
|
||||||
switch operation {
|
switch operation {
|
||||||
case t.StackCreate:
|
case compose.StackCreate:
|
||||||
return s.CF.WaitUntilStackCreateCompleteWithContext(ctx, input)
|
return s.CF.WaitUntilStackCreateCompleteWithContext(ctx, input)
|
||||||
case t.StackDelete:
|
case compose.StackDelete:
|
||||||
return s.CF.WaitUntilStackDeleteCompleteWithContext(ctx, input)
|
return s.CF.WaitUntilStackDeleteCompleteWithContext(ctx, input)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("internal error: unexpected stack operation %d", operation)
|
return fmt.Errorf("internal error: unexpected stack operation %d", operation)
|
||||||
@ -236,7 +234,7 @@ func (s sdk) DeleteStack(ctx context.Context, name string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sdk) CreateSecret(ctx context.Context, secret t.Secret) (string, error) {
|
func (s sdk) CreateSecret(ctx context.Context, secret compose.Secret) (string, error) {
|
||||||
logrus.Debug("Create secret " + secret.Name)
|
logrus.Debug("Create secret " + secret.Name)
|
||||||
secretStr, err := secret.GetCredString()
|
secretStr, err := secret.GetCredString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -254,17 +252,17 @@ func (s sdk) CreateSecret(ctx context.Context, secret t.Secret) (string, error)
|
|||||||
return *response.ARN, nil
|
return *response.ARN, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sdk) InspectSecret(ctx context.Context, id string) (t.Secret, error) {
|
func (s sdk) InspectSecret(ctx context.Context, id string) (compose.Secret, error) {
|
||||||
logrus.Debug("Inspect secret " + id)
|
logrus.Debug("Inspect secret " + id)
|
||||||
response, err := s.SM.DescribeSecret(&secretsmanager.DescribeSecretInput{SecretId: &id})
|
response, err := s.SM.DescribeSecret(&secretsmanager.DescribeSecretInput{SecretId: &id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return t.Secret{}, err
|
return compose.Secret{}, err
|
||||||
}
|
}
|
||||||
labels := map[string]string{}
|
labels := map[string]string{}
|
||||||
for _, tag := range response.Tags {
|
for _, tag := range response.Tags {
|
||||||
labels[*tag.Key] = *tag.Value
|
labels[*tag.Key] = *tag.Value
|
||||||
}
|
}
|
||||||
secret := t.Secret{
|
secret := compose.Secret{
|
||||||
ID: *response.ARN,
|
ID: *response.ARN,
|
||||||
Name: *response.Name,
|
Name: *response.Name,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
@ -275,14 +273,14 @@ func (s sdk) InspectSecret(ctx context.Context, id string) (t.Secret, error) {
|
|||||||
return secret, nil
|
return secret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sdk) ListSecrets(ctx context.Context) ([]t.Secret, error) {
|
func (s sdk) ListSecrets(ctx context.Context) ([]compose.Secret, error) {
|
||||||
|
|
||||||
logrus.Debug("List secrets ...")
|
logrus.Debug("List secrets ...")
|
||||||
response, err := s.SM.ListSecrets(&secretsmanager.ListSecretsInput{})
|
response, err := s.SM.ListSecrets(&secretsmanager.ListSecretsInput{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []t.Secret{}, err
|
return []compose.Secret{}, err
|
||||||
}
|
}
|
||||||
var secrets []t.Secret
|
var secrets []compose.Secret
|
||||||
|
|
||||||
for _, sec := range response.SecretList {
|
for _, sec := range response.SecretList {
|
||||||
|
|
||||||
@ -294,7 +292,7 @@ func (s sdk) ListSecrets(ctx context.Context) ([]t.Secret, error) {
|
|||||||
if sec.Description != nil {
|
if sec.Description != nil {
|
||||||
description = *sec.Description
|
description = *sec.Description
|
||||||
}
|
}
|
||||||
secrets = append(secrets, t.Secret{
|
secrets = append(secrets, compose.Secret{
|
||||||
ID: *sec.ARN,
|
ID: *sec.ARN,
|
||||||
Name: *sec.Name,
|
Name: *sec.Name,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
@ -311,7 +309,7 @@ func (s sdk) DeleteSecret(ctx context.Context, id string, recover bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sdk) GetLogs(ctx context.Context, name string, consumer types.LogConsumer) error {
|
func (s sdk) GetLogs(ctx context.Context, name string, consumer compose.LogConsumer) error {
|
||||||
logGroup := fmt.Sprintf("/docker-compose/%s", name)
|
logGroup := fmt.Sprintf("/docker-compose/%s", name)
|
||||||
var startTime int64
|
var startTime int64
|
||||||
for {
|
for {
|
||||||
@ -357,7 +355,7 @@ func (s sdk) ListTasks(ctx context.Context, cluster string, service string) ([]s
|
|||||||
return arns, nil
|
return arns, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sdk) DescribeTasks(ctx context.Context, cluster string, arns ...string) ([]t.TaskStatus, error) {
|
func (s sdk) DescribeTasks(ctx context.Context, cluster string, arns ...string) ([]compose.TaskStatus, error) {
|
||||||
tasks, err := s.ECS.DescribeTasksWithContext(ctx, &ecs.DescribeTasksInput{
|
tasks, err := s.ECS.DescribeTasksWithContext(ctx, &ecs.DescribeTasksInput{
|
||||||
Cluster: aws.String(cluster),
|
Cluster: aws.String(cluster),
|
||||||
Tasks: aws.StringSlice(arns),
|
Tasks: aws.StringSlice(arns),
|
||||||
@ -365,7 +363,7 @@ func (s sdk) DescribeTasks(ctx context.Context, cluster string, arns ...string)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := []t.TaskStatus{}
|
result := []compose.TaskStatus{}
|
||||||
for _, task := range tasks.Tasks {
|
for _, task := range tasks.Tasks {
|
||||||
var networkInterface string
|
var networkInterface string
|
||||||
for _, attachement := range task.Attachments {
|
for _, attachement := range task.Attachments {
|
||||||
@ -377,7 +375,7 @@ func (s sdk) DescribeTasks(ctx context.Context, cluster string, arns ...string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = append(result, t.TaskStatus{
|
result = append(result, compose.TaskStatus{
|
||||||
State: *task.LastStatus,
|
State: *task.LastStatus,
|
||||||
Service: strings.Replace(*task.Group, "service:", "", 1),
|
Service: strings.Replace(*task.Group, "service:", "", 1),
|
||||||
NetworkInterface: networkInterface,
|
NetworkInterface: networkInterface,
|
||||||
|
@ -4,19 +4,20 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/awslabs/goformation/v4/cloudformation"
|
"github.com/awslabs/goformation/v4/cloudformation"
|
||||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
"github.com/compose-spec/compose-go/cli"
|
||||||
|
"github.com/compose-spec/compose-go/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type API interface {
|
type API interface {
|
||||||
Up(ctx context.Context, options ProjectOptions) error
|
Up(ctx context.Context, options cli.ProjectOptions) error
|
||||||
Down(ctx context.Context, options ProjectOptions) error
|
Down(ctx context.Context, options cli.ProjectOptions) error
|
||||||
|
|
||||||
Convert(project *Project) (*cloudformation.Template, error)
|
Convert(project *types.Project) (*cloudformation.Template, error)
|
||||||
Logs(ctx context.Context, projectName string) error
|
Logs(ctx context.Context, projectName string) error
|
||||||
Ps(background context.Context, project *Project) ([]types.TaskStatus, error)
|
Ps(background context.Context, project *types.Project) ([]TaskStatus, error)
|
||||||
|
|
||||||
CreateSecret(ctx context.Context, secret types.Secret) (string, error)
|
CreateSecret(ctx context.Context, secret Secret) (string, error)
|
||||||
InspectSecret(ctx context.Context, id string) (types.Secret, error)
|
InspectSecret(ctx context.Context, id string) (Secret, error)
|
||||||
ListSecrets(ctx context.Context) ([]types.Secret, error)
|
ListSecrets(ctx context.Context) ([]Secret, error)
|
||||||
DeleteSecret(ctx context.Context, id string, recover bool) error
|
DeleteSecret(ctx context.Context, id string, recover bool) error
|
||||||
}
|
}
|
||||||
|
@ -1,89 +0,0 @@
|
|||||||
package compose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Normalize a compose-go model to move deprecated attributes to canonical position, and introduce implicit defaults
|
|
||||||
// FIXME move this to compose-go
|
|
||||||
func Normalize(model *types.Config) error {
|
|
||||||
if len(model.Networks) == 0 {
|
|
||||||
// Compose application model implies a default network if none is explicitly set.
|
|
||||||
model.Networks["default"] = types.NetworkConfig{
|
|
||||||
Name: "default",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, s := range model.Services {
|
|
||||||
if len(s.Networks) == 0 {
|
|
||||||
// Service without explicit network attachment are implicitly exposed on default network
|
|
||||||
s.Networks = map[string]*types.ServiceNetworkConfig{"default": nil}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, p := range s.Ports {
|
|
||||||
if p.Published == 0 {
|
|
||||||
p.Published = p.Target
|
|
||||||
s.Ports[i] = p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.LogDriver != "" {
|
|
||||||
logrus.Warn("`log_driver` is deprecated. Use the `logging` attribute")
|
|
||||||
if s.Logging == nil {
|
|
||||||
s.Logging = &types.LoggingConfig{}
|
|
||||||
}
|
|
||||||
if s.Logging.Driver == "" {
|
|
||||||
s.Logging.Driver = s.LogDriver
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("can't use both 'log_driver' (deprecated) and 'logging.driver'")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(s.LogOpt) != 0 {
|
|
||||||
logrus.Warn("`log_opts` is deprecated. Use the `logging` attribute")
|
|
||||||
if s.Logging == nil {
|
|
||||||
s.Logging = &types.LoggingConfig{}
|
|
||||||
}
|
|
||||||
for k, v := range s.LogOpt {
|
|
||||||
if _, ok := s.Logging.Options[k]; !ok {
|
|
||||||
s.Logging.Options[k] = v
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("can't use both 'log_opt' (deprecated) and 'logging.options'")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
model.Services[i] = s
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, n := range model.Networks {
|
|
||||||
if n.Name == "" {
|
|
||||||
n.Name = i
|
|
||||||
model.Networks[i] = n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, v := range model.Volumes {
|
|
||||||
if v.Name == "" {
|
|
||||||
v.Name = i
|
|
||||||
model.Volumes[i] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, c := range model.Configs {
|
|
||||||
if c.Name == "" {
|
|
||||||
c.Name = i
|
|
||||||
model.Configs[i] = c
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, s := range model.Secrets {
|
|
||||||
if s.Name == "" {
|
|
||||||
s.Name = i
|
|
||||||
model.Secrets[i] = s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -1,170 +0,0 @@
|
|||||||
package compose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/loader"
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Project struct {
|
|
||||||
types.Config
|
|
||||||
projectDir string
|
|
||||||
Name string `yaml:"-" json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewProject(config types.ConfigDetails, name string) (*Project, error) {
|
|
||||||
model, err := loader.Load(config)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = Normalize(model)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
p := Project{
|
|
||||||
Config: *model,
|
|
||||||
projectDir: config.WorkingDir,
|
|
||||||
Name: name,
|
|
||||||
}
|
|
||||||
return &p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// projectFromOptions load a compose project based on command line options
|
|
||||||
func ProjectFromOptions(options *ProjectOptions) (*Project, error) {
|
|
||||||
configPath, err := getConfigPathFromOptions(options)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
name := options.Name
|
|
||||||
if name == "" {
|
|
||||||
name = os.Getenv("COMPOSE_PROJECT_NAME")
|
|
||||||
}
|
|
||||||
|
|
||||||
workingDir := filepath.Dir(configPath[0])
|
|
||||||
|
|
||||||
if name == "" {
|
|
||||||
r := regexp.MustCompile(`[^a-z0-9\\-_]+`)
|
|
||||||
name = r.ReplaceAllString(strings.ToLower(filepath.Base(workingDir)), "")
|
|
||||||
}
|
|
||||||
|
|
||||||
configs, err := parseConfigs(configPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewProject(types.ConfigDetails{
|
|
||||||
WorkingDir: workingDir,
|
|
||||||
ConfigFiles: configs,
|
|
||||||
Environment: environment(),
|
|
||||||
}, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getConfigPathFromOptions(options *ProjectOptions) ([]string, error) {
|
|
||||||
paths := []string{}
|
|
||||||
pwd, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(options.ConfigPaths) != 0 {
|
|
||||||
for _, f := range options.ConfigPaths {
|
|
||||||
if f == "-" {
|
|
||||||
paths = append(paths, f)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !filepath.IsAbs(f) {
|
|
||||||
f = filepath.Join(pwd, f)
|
|
||||||
}
|
|
||||||
if _, err := os.Stat(f); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
paths = append(paths, f)
|
|
||||||
}
|
|
||||||
return paths, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
sep := os.Getenv("COMPOSE_FILE_SEPARATOR")
|
|
||||||
if sep == "" {
|
|
||||||
sep = string(os.PathListSeparator)
|
|
||||||
}
|
|
||||||
f := os.Getenv("COMPOSE_FILE")
|
|
||||||
if f != "" {
|
|
||||||
return strings.Split(f, sep), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
candidates := []string{}
|
|
||||||
for _, n := range SupportedFilenames {
|
|
||||||
f := filepath.Join(pwd, n)
|
|
||||||
if _, err := os.Stat(f); err == nil {
|
|
||||||
candidates = append(candidates, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(candidates) > 0 {
|
|
||||||
winner := candidates[0]
|
|
||||||
if len(candidates) > 1 {
|
|
||||||
logrus.Warnf("Found multiple config files with supported names: %s", strings.Join(candidates, ", "))
|
|
||||||
logrus.Warnf("Using %s\n", winner)
|
|
||||||
}
|
|
||||||
return []string{winner}, nil
|
|
||||||
}
|
|
||||||
parent := filepath.Dir(pwd)
|
|
||||||
if parent == pwd {
|
|
||||||
return nil, fmt.Errorf("Can't find a suitable configuration file in this directory or any parent. Are you in the right directory?")
|
|
||||||
}
|
|
||||||
pwd = parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var SupportedFilenames = []string{"compose.yaml", "compose.yml", "docker-compose.yml", "docker-compose.yaml"}
|
|
||||||
|
|
||||||
func parseConfigs(configPaths []string) ([]types.ConfigFile, error) {
|
|
||||||
files := []types.ConfigFile{}
|
|
||||||
for _, f := range configPaths {
|
|
||||||
var (
|
|
||||||
b []byte
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if f == "-" {
|
|
||||||
b, err = ioutil.ReadAll(os.Stdin)
|
|
||||||
} else {
|
|
||||||
if _, err := os.Stat(f); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
b, err = ioutil.ReadFile(f)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
config, err := loader.ParseYAML(b)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
files = append(files, types.ConfigFile{Filename: f, Config: config})
|
|
||||||
}
|
|
||||||
return files, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func environment() map[string]string {
|
|
||||||
return getAsEqualsMap(os.Environ())
|
|
||||||
}
|
|
||||||
|
|
||||||
// getAsEqualsMap split key=value formatted strings into a key : value map
|
|
||||||
func getAsEqualsMap(em []string) map[string]string {
|
|
||||||
m := make(map[string]string)
|
|
||||||
for _, v := range em {
|
|
||||||
kv := strings.SplitN(v, "=", 2)
|
|
||||||
m[kv[0]] = kv[1]
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
package compose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"gotest.tools/v3/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_project_name(t *testing.T) {
|
|
||||||
p, err := ProjectFromOptions(&ProjectOptions{
|
|
||||||
Name: "my_project",
|
|
||||||
ConfigPaths: []string{"testdata/simple/compose.yaml"},
|
|
||||||
})
|
|
||||||
assert.NilError(t, err)
|
|
||||||
assert.Equal(t, p.Name, "my_project")
|
|
||||||
|
|
||||||
p, err = ProjectFromOptions(&ProjectOptions{
|
|
||||||
Name: "",
|
|
||||||
ConfigPaths: []string{"testdata/simple/compose.yaml"},
|
|
||||||
})
|
|
||||||
assert.NilError(t, err)
|
|
||||||
assert.Equal(t, p.Name, "simple")
|
|
||||||
|
|
||||||
os.Setenv("COMPOSE_PROJECT_NAME", "my_project_from_env")
|
|
||||||
p, err = ProjectFromOptions(&ProjectOptions{
|
|
||||||
Name: "",
|
|
||||||
ConfigPaths: []string{"testdata/simple/compose.yaml"},
|
|
||||||
})
|
|
||||||
assert.NilError(t, err)
|
|
||||||
assert.Equal(t, p.Name, "my_project_from_env")
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_project_from_set_of_files(t *testing.T) {
|
|
||||||
p, err := ProjectFromOptions(&ProjectOptions{
|
|
||||||
Name: "my_project",
|
|
||||||
ConfigPaths: []string{
|
|
||||||
"testdata/simple/compose.yaml",
|
|
||||||
"testdata/simple/compose-with-overrides.yaml",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
assert.NilError(t, err)
|
|
||||||
service, err := p.GetService("simple")
|
|
||||||
assert.NilError(t, err)
|
|
||||||
assert.Equal(t, service.Image, "haproxy")
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package types
|
package compose
|
||||||
|
|
||||||
import "encoding/json"
|
import "encoding/json"
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package types
|
package compose
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ExtensionSecurityGroup = "x-aws-securitygroup"
|
ExtensionSecurityGroup = "x-aws-securitygroup"
|
Loading…
x
Reference in New Issue
Block a user