Reject compose file with unsupported features

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2020-05-18 10:53:07 +02:00
parent 8cd4a6fe9b
commit ae4dc2e0db
No known key found for this signature in database
GPG Key ID: 9858809D6F8F6E7E
6 changed files with 50 additions and 30 deletions

View File

@ -26,6 +26,11 @@ const (
// Convert a compose project into a CloudFormation template
func (c client) Convert(project *compose.Project) (*cloudformation.Template, error) {
err := Validate(project)
if err != nil {
return nil, err
}
template := cloudformation.NewTemplate()
template.Parameters[ParameterClusterName] = cloudformation.Parameter{

View File

@ -4,46 +4,42 @@ import (
"fmt"
"testing"
"gotest.tools/assert"
"github.com/docker/ecs-plugin/pkg/compose"
"gotest.tools/v3/golden"
)
func TestSimpleConvert(t *testing.T) {
options := compose.ProjectOptions{
Name: t.Name(),
ConfigPaths: []string{"testdata/input/simple-single-service.yaml"},
}
result := convertResultAsString(t, options, "TestCluster")
project := load(t, "testdata/input/simple-single-service.yaml")
result := convertResultAsString(t, project, "TestCluster")
expected := "simple/simple-cloudformation-conversion.golden"
golden.Assert(t, result, expected)
}
func TestSimpleWithOverrides(t *testing.T) {
options := compose.ProjectOptions{
Name: t.Name(),
ConfigPaths: []string{"testdata/input/simple-single-service.yaml", "testdata/input/simple-single-service-with-overrides.yaml"},
}
result := convertResultAsString(t, options, "TestCluster")
project := load(t, "testdata/input/simple-single-service.yaml", "testdata/input/simple-single-service-with-overrides.yaml")
result := convertResultAsString(t, project, "TestCluster")
expected := "simple/simple-cloudformation-with-overrides-conversion.golden"
golden.Assert(t, result, expected)
}
func convertResultAsString(t *testing.T, options compose.ProjectOptions, clusterName string) string {
project, err := compose.ProjectFromOptions(&options)
if err != nil {
t.Error(err)
}
func convertResultAsString(t *testing.T, project *compose.Project, clusterName string) string {
client, err := NewClient("", clusterName, "")
if err != nil {
t.Error(err)
}
assert.NilError(t, err)
result, err := client.Convert(project)
if err != nil {
t.Error(err)
}
assert.NilError(t, err)
resultAsJSON, err := result.JSON()
if err != nil {
t.Error(err)
}
assert.NilError(t, err)
return fmt.Sprintf("%s\n", string(resultAsJSON))
}
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
}

View File

@ -0,0 +1,5 @@
version: "3"
services:
simple:
image: nginx
network_mode: bridge

View File

@ -27,11 +27,6 @@ func (c *client) ComposeUp(ctx context.Context, project *compose.Project) error
return fmt.Errorf("we do not (yet) support updating an existing CloudFormation stack")
}
err = c.Validate(project)
if err != nil {
return err
}
template, err := c.Convert(project)
if err != nil {
return err

View File

@ -1,12 +1,14 @@
package amazon
import (
"fmt"
"github.com/compose-spec/compose-go/types"
"github.com/docker/ecs-plugin/pkg/compose"
)
// Validate check the compose model do not use unsupported features and inject sane defaults for ECS deployment
func (c *client) Validate(project *compose.Project) error {
func Validate(project *compose.Project) error {
if len(project.Networks) == 0 {
// Compose application model implies a default network if none is explicitly set.
// FIXME move this to compose-go
@ -22,6 +24,10 @@ func (c *client) Validate(project *compose.Project) error {
service.Networks = map[string]*types.ServiceNetworkConfig{"default": nil}
project.Services[i] = service
}
if service.NetworkMode != "" && service.NetworkMode != "awsvpc" {
return fmt.Errorf("ECS do not support NetworkMode %q", service.NetworkMode)
}
}
// Here we can check for incompatible attributes, inject sane defaults, etc

View File

@ -0,0 +1,13 @@
package amazon
import (
"testing"
"gotest.tools/assert"
)
func TestInvalidNetworkMode(t *testing.T) {
project := load(t, "testdata/invalid_network_mode.yaml")
err := Validate(project)
assert.Error(t, err, "ECS do not support NetworkMode \"bridge\"")
}