Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions internal/compose/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@ type portMapping struct {
Protocol string
}

type intOrStringYaml int

func (p *intOrStringYaml) UnmarshalYAML(node *yaml.Node) error {
var s string
err := node.Decode(&s)
if err == nil {
i, err := strconv.Atoi(s)
*p = intOrStringYaml(i)
return err
}

return node.Decode(p)
}

// UnmarshalYAML unmarshals a Docker Compose port mapping in YAML to
// a portMapping.
func (p *portMapping) UnmarshalYAML(node *yaml.Node) error {
Expand All @@ -67,18 +81,18 @@ func (p *portMapping) UnmarshalYAML(node *yaml.Node) error {
}

var s struct {
HostIP string `yaml:"host_ip"`
Target int
Published int
HostIP string `yaml:"host_ip"`
Target intOrStringYaml // Docker compose v2 can define ports as strings.
Published intOrStringYaml // Docker compose v2 can define ports as strings.
Protocol string
}

if err := yaml.Unmarshal(b, &s); err != nil {
return errors.Wrap(err, "could not unmarshal YAML map node")
}

p.InternalPort = s.Target
p.ExternalPort = s.Published
p.InternalPort = int(s.Target)
p.ExternalPort = int(s.Published)
p.Protocol = s.Protocol
p.ExternalIP = s.HostIP
return nil
Expand Down
33 changes: 33 additions & 0 deletions internal/compose/compose_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.

package compose

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)

func TestIntOrStringYaml(t *testing.T) {
cases := []struct {
yaml string
expected int
}{
{`"9200"`, 9200},
{`'9200'`, 9200},
{`9200`, 9200},
}

for _, c := range cases {
t.Run(c.yaml, func(t *testing.T) {
var n intOrStringYaml
err := yaml.Unmarshal([]byte(c.yaml), &n)
require.NoError(t, err)
assert.Equal(t, c.expected, int(n))
})
}
}