Skip to content
This repository has been archived by the owner on Nov 27, 2023. It is now read-only.

Commit

Permalink
Merge pull request #882 from docker/yaml
Browse files Browse the repository at this point in the history
Marshall cloudformation template as yaml
  • Loading branch information
gtardif authored Nov 6, 2020
2 parents af1dae5 + cb02622 commit 5c04e84
Show file tree
Hide file tree
Showing 11 changed files with 251 additions and 357 deletions.
2 changes: 1 addition & 1 deletion aci/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,6 @@ func (cs *aciComposeService) Logs(ctx context.Context, project string, w io.Writ
return errdefs.ErrNotImplemented
}

func (cs *aciComposeService) Convert(ctx context.Context, project *types.Project) ([]byte, error) {
func (cs *aciComposeService) Convert(ctx context.Context, project *types.Project, format string) ([]byte, error) {
return nil, errdefs.ErrNotImplemented
}
2 changes: 1 addition & 1 deletion api/client/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,6 @@ func (c *composeService) List(context.Context, string) ([]compose.Stack, error)
}

// Convert translate compose model into backend's native format
func (c *composeService) Convert(context.Context, *types.Project) ([]byte, error) {
func (c *composeService) Convert(context.Context, *types.Project, string) ([]byte, error) {
return nil, errdefs.ErrNotImplemented
}
2 changes: 1 addition & 1 deletion api/compose/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type Service interface {
// List executes the equivalent to a `docker stack ls`
List(ctx context.Context, projectName string) ([]Stack, error)
// Convert translate compose model into backend's native format
Convert(ctx context.Context, project *types.Project) ([]byte, error)
Convert(ctx context.Context, project *types.Project, format string) ([]byte, error)
}

// PortPublisher hold status about published port
Expand Down
3 changes: 2 additions & 1 deletion cli/cmd/compose/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func convertCommand() *cobra.Command {
convertCmd.Flags().StringVar(&opts.WorkingDir, "workdir", "", "Work dir")
convertCmd.Flags().StringArrayVarP(&opts.ConfigPaths, "file", "f", []string{}, "Compose configuration files")
convertCmd.Flags().StringArrayVarP(&opts.Environment, "environment", "e", []string{}, "Environment variables")
convertCmd.Flags().StringVar(&opts.Format, "format", "yaml", "Format the output. Values: [yaml | json]")

return convertCmd
}
Expand All @@ -60,7 +61,7 @@ func runConvert(ctx context.Context, opts composeOptions) error {
return err
}

json, err = c.ComposeService().Convert(ctx, project)
json, err = c.ComposeService().Convert(ctx, project, opts.Format)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions ecs/cloudformation.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ import (
"github.com/compose-spec/compose-go/types"
)

func (b *ecsAPIService) Convert(ctx context.Context, project *types.Project) ([]byte, error) {
func (b *ecsAPIService) Convert(ctx context.Context, project *types.Project, format string) ([]byte, error) {
template, err := b.convert(ctx, project)
if err != nil {
return nil, err
}

return marshall(template)
return marshall(template, format)
}

func (b *ecsAPIService) convert(ctx context.Context, project *types.Project) (*cloudformation.Template, error) {
Expand Down
2 changes: 1 addition & 1 deletion ecs/cloudformation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestSimpleConvert(t *testing.T) {
bytes, err := ioutil.ReadFile("testdata/input/simple-single-service.yaml")
assert.NilError(t, err)
template := convertYaml(t, string(bytes), useDefaultVPC)
resultAsJSON, err := marshall(template)
resultAsJSON, err := marshall(template, "yaml")
assert.NilError(t, err)
result := fmt.Sprintf("%s\n", string(resultAsJSON))
expected := "simple/simple-cloudformation-conversion.golden"
Expand Down
4 changes: 2 additions & 2 deletions ecs/local/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (e ecsLocalSimulation) Up(ctx context.Context, project *types.Project, deta
return fmt.Errorf("ECS simulation mode require Docker-compose 1.27, found %s", version)
}

converted, err := e.Convert(ctx, project)
converted, err := e.Convert(ctx, project, "yaml")
if err != nil {
return err
}
Expand All @@ -69,7 +69,7 @@ func (e ecsLocalSimulation) Up(ctx context.Context, project *types.Project, deta
return cmd.Run()
}

func (e ecsLocalSimulation) Convert(ctx context.Context, project *types.Project) ([]byte, error) {
func (e ecsLocalSimulation) Convert(ctx context.Context, project *types.Project, format string) ([]byte, error) {
project.Networks["credentials_network"] = types.NetworkConfig{
Driver: "bridge",
Ipam: types.IPAMConfig{
Expand Down
45 changes: 31 additions & 14 deletions ecs/marshall.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,50 @@ import (
"strings"

"github.com/awslabs/goformation/v4/cloudformation"
"github.com/sanathkr/go-yaml"
)

func marshall(template *cloudformation.Template) ([]byte, error) {
raw, err := template.JSON()
func marshall(template *cloudformation.Template, format string) ([]byte, error) {
var (
source func() ([]byte, error)
marshal func(in interface{}) ([]byte, error)
unmarshal func(in []byte, out interface{}) error
)
switch format {
case "yaml":
source = template.YAML
marshal = yaml.Marshal
unmarshal = yaml.Unmarshal
case "json":
source = template.JSON
marshal = func(in interface{}) ([]byte, error) {
return json.MarshalIndent(in, "", " ")
}
unmarshal = json.Unmarshal
default:
return nil, fmt.Errorf("unsupported format %q", format)
}

raw, err := source()
if err != nil {
return nil, err
}

var unmarshalled interface{}
if err := json.Unmarshal(raw, &unmarshalled); err != nil {
if err := unmarshal(raw, &unmarshalled); err != nil {
return nil, fmt.Errorf("invalid JSON: %s", err)
}

if input, ok := unmarshalled.(map[string]interface{}); ok {
if input, ok := unmarshalled.(map[interface{}]interface{}); ok {
if resources, ok := input["Resources"]; ok {
for _, uresource := range resources.(map[string]interface{}) {
if resource, ok := uresource.(map[string]interface{}); ok {
for _, uresource := range resources.(map[interface{}]interface{}) {
if resource, ok := uresource.(map[interface{}]interface{}); ok {
if resource["Type"] == "AWS::ECS::TaskDefinition" {
properties := resource["Properties"].(map[string]interface{})
properties := resource["Properties"].(map[interface{}]interface{})
for _, def := range properties["ContainerDefinitions"].([]interface{}) {
containerDefinition := def.(map[string]interface{})
containerDefinition := def.(map[interface{}]interface{})
if strings.HasSuffix(containerDefinition["Name"].(string), "_InitContainer") {
containerDefinition["Essential"] = "false"
containerDefinition["Essential"] = false
}
}
}
Expand All @@ -53,9 +74,5 @@ func marshall(template *cloudformation.Template) ([]byte, error) {
}
}

raw, err = json.MarshalIndent(unmarshalled, "", " ")
if err != nil {
return nil, fmt.Errorf("invalid JSON: %s", err)
}
return raw, err
return marshal(unmarshalled)
}
Loading

0 comments on commit 5c04e84

Please sign in to comment.