Skip to content

Commit fe79364

Browse files
committed
Log warning for unsupported v3 compose options
1 parent 7411b59 commit fe79364

File tree

5 files changed

+105
-20
lines changed

5 files changed

+105
-20
lines changed

ecs-cli/modules/cli/compose/adapter/convert.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,3 +440,20 @@ func SortedGoString(v interface{}) (string, error) {
440440
}
441441
return string(b), nil
442442
}
443+
444+
// ConvertCamelCaseToUnderScore returns an underscore-separated name for a given camelcased string
445+
// e.g., "NetworkMode" -> "network_mode"
446+
func ConvertCamelCaseToUnderScore(s string) string {
447+
camelRegex := regexp.MustCompile("(^[^A-Z]*|[A-Z]*)([A-Z][^A-Z]+|$)")
448+
449+
var chars []string
450+
for _, sub := range camelRegex.FindAllStringSubmatch(s, -1) {
451+
if sub[1] != "" {
452+
chars = append(chars, sub[1])
453+
}
454+
if sub[2] != "" {
455+
chars = append(chars, sub[2])
456+
}
457+
}
458+
return strings.ToLower(strings.Join(chars, "_"))
459+
}

ecs-cli/modules/cli/compose/adapter/convert_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,3 +548,22 @@ func TestSortedGoString(t *testing.T) {
548548

549549
assert.Equal(t, strA, strB, "Sorted inputs should match")
550550
}
551+
552+
func TestConvertCamelCaseToUnderScore(t *testing.T) {
553+
testCases := []struct {
554+
input string
555+
expected string
556+
}{
557+
{"CamelCaseString", "camel_case_string"},
558+
{"lowercase", "lowercase"},
559+
{"UPPERCASE", "uppercase"},
560+
{"CamelWithACRONYM", "camel_with_acronym"},
561+
{"Uppercase", "uppercase"},
562+
}
563+
for _, test := range testCases {
564+
t.Run(fmt.Sprintf("%s should be %s", test.input, test.expected), func(t *testing.T) {
565+
output := ConvertCamelCaseToUnderScore(test.input)
566+
assert.Equal(t, test.expected, output, "Expected output to match")
567+
})
568+
}
569+
}

ecs-cli/modules/cli/compose/logger/logger.go

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@ import (
1717
"reflect"
1818
"strings"
1919

20+
"github.com/aws/amazon-ecs-cli/ecs-cli/modules/cli/compose/adapter"
2021
"github.com/aws/amazon-ecs-cli/ecs-cli/modules/utils/value"
22+
"github.com/docker/cli/cli/compose/types"
2123
"github.com/docker/libcompose/config"
2224
"github.com/docker/libcompose/project"
2325
log "github.com/sirupsen/logrus"
2426
)
2527

26-
// supported fields/options from compose YAML file
27-
var supportedComposeYamlOptions = []string{
28+
// supported fields/options from compose 1/2 YAML file
29+
var supportedComposeV1V2YamlOptions = []string{
2830
"cap_add",
2931
"cap_drop",
3032
"command",
@@ -57,19 +59,47 @@ var supportedComposeYamlOptions = []string{
5759
"working_dir",
5860
}
5961

60-
var supportedComposeYamlOptionsMap = getSupportedComposeYamlOptionsMap()
62+
// supported fields/options from compose 3 YAML file
63+
var supportedFieldsInV3 = map[string]bool{
64+
"CapAdd": true,
65+
"CapDrop": true,
66+
"Command": true,
67+
"DNS": true,
68+
"DNSSearch": true,
69+
"Entrypoint": true,
70+
"Environment": true,
71+
"EnvFile": true,
72+
"ExtraHosts": true,
73+
"Hostname": true,
74+
"Image": true,
75+
"Labels": true,
76+
"Links": true,
77+
"Logging": true,
78+
"Name": true,
79+
"Ports": true,
80+
"Privileged": true,
81+
"ReadOnly": true,
82+
"SecurityOpt": true,
83+
"Tmpfs": true,
84+
"Ulimits": true,
85+
"User": true,
86+
"Volumes": true,
87+
"WorkingDir": true,
88+
}
89+
90+
var supportedComposeV1V2YamlOptionsMap = getSupportedComposeV1V2YamlOptionsMap()
6191

6292
// Create set of supported YAML fields in docker compose v2 ServiceConfigs
63-
func getSupportedComposeYamlOptionsMap() map[string]bool {
93+
func getSupportedComposeV1V2YamlOptionsMap() map[string]bool {
6494
optionsMap := make(map[string]bool)
65-
for _, value := range supportedComposeYamlOptions {
95+
for _, value := range supportedComposeV1V2YamlOptions {
6696
optionsMap[value] = true
6797
}
6898
return optionsMap
6999
}
70100

71-
// LogUnsupportedServiceConfigFields logs a warning if there is an unsupported field specified in the docker-compose file
72-
func LogUnsupportedServiceConfigFields(serviceName string, serviceConfig *config.ServiceConfig) {
101+
// LogUnsupportedV1V2ServiceConfigFields logs a warning if there is an unsupported field specified in the docker-compose file
102+
func LogUnsupportedV1V2ServiceConfigFields(serviceName string, serviceConfig *config.ServiceConfig) {
73103
configValue := reflect.ValueOf(serviceConfig).Elem()
74104
configType := configValue.Type()
75105

@@ -87,19 +117,30 @@ func LogUnsupportedServiceConfigFields(serviceName string, serviceConfig *config
87117
}
88118

89119
if tagName == "networks" && !validNetworksForService(serviceConfig) {
90-
log.WithFields(log.Fields{
91-
"option name": tagName,
92-
"service name": serviceName,
93-
}).Warn("Skipping unsupported YAML option for service...")
120+
logWarningForUnsupportedServiceOption(tagName, serviceName)
94121
}
95122

96123
zeroValue := value.IsZero(field)
97124
// if value is present for the field that is not in supportedYamlTags map, log a warning
98-
if tagName != "networks" && !zeroValue && !supportedComposeYamlOptionsMap[tagName] {
99-
log.WithFields(log.Fields{
100-
"option name": tagName,
101-
"service name": serviceName,
102-
}).Warn("Skipping unsupported YAML option for service...")
125+
if tagName != "networks" && !zeroValue && !supportedComposeV1V2YamlOptionsMap[tagName] {
126+
logWarningForUnsupportedServiceOption(tagName, serviceName)
127+
}
128+
}
129+
}
130+
131+
// LogUnsupportedV3ServiceConfigFields logs a warning if there is an unsupported field specified in the docker-compose file
132+
func LogUnsupportedV3ServiceConfigFields(servConfig types.ServiceConfig) {
133+
configValue := reflect.ValueOf(servConfig)
134+
configType := configValue.Type()
135+
136+
for i := 0; i < configValue.NumField(); i++ {
137+
field := configValue.Field(i)
138+
fieldType := configType.Field(i)
139+
140+
if supportedFieldsInV3[fieldType.Name] == false && !value.IsZero(field) {
141+
// convert field name so it more closely resembles option in yaml file
142+
optionName := adapter.ConvertCamelCaseToUnderScore(fieldType.Name)
143+
logWarningForUnsupportedServiceOption(optionName, servConfig.Name)
103144
}
104145
}
105146
}
@@ -114,6 +155,13 @@ func LogUnsupportedProjectFields(project *project.Project) {
114155
}
115156
}
116157

158+
func logWarningForUnsupportedServiceOption(tagName, serviceName string) {
159+
log.WithFields(log.Fields{
160+
"option name": tagName,
161+
"service name": serviceName,
162+
}).Warn("Skipping unsupported YAML option for service...")
163+
}
164+
117165
func validNetworksForService(config *config.ServiceConfig) bool {
118166
if config.Networks == nil {
119167
return false

ecs-cli/modules/cli/compose/project/project_parseV1V2.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func (p *ecsProject) parseV1V2() (*[]adapter.ContainerConfig, error) {
5353
}
5454

5555
func convertV1V2ToContainerConfig(context *project.Context, serviceName string, volumes *adapter.Volumes, service *config.ServiceConfig) (*adapter.ContainerConfig, error) {
56-
logger.LogUnsupportedServiceConfigFields(serviceName, service)
56+
logger.LogUnsupportedV1V2ServiceConfigFields(serviceName, service)
5757

5858
environment := adapter.ConvertToKeyValuePairs(context, service.Environment, serviceName)
5959

ecs-cli/modules/cli/compose/project/project_parseV3.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"reflect"
77

88
"github.com/aws/amazon-ecs-cli/ecs-cli/modules/cli/compose/adapter"
9+
"github.com/aws/amazon-ecs-cli/ecs-cli/modules/cli/compose/logger"
910
"github.com/aws/aws-sdk-go/aws"
1011
"github.com/aws/aws-sdk-go/service/ecs"
1112
"github.com/pkg/errors"
@@ -84,6 +85,9 @@ func getV3Config(composeFiles []string) (*types.Config, error) {
8485
}
8586

8687
func convertToContainerConfig(serviceConfig types.ServiceConfig, serviceVols *adapter.Volumes) (*adapter.ContainerConfig, error) {
88+
logger.LogUnsupportedV3ServiceConfigFields(serviceConfig)
89+
logWarningForDeployFields(serviceConfig.Deploy, serviceConfig.Name)
90+
8791
//TODO: Add Healthcheck, Devices to ContainerConfig
8892
c := &adapter.ContainerConfig{
8993
CapAdd: serviceConfig.CapAdd,
@@ -185,9 +189,6 @@ func convertToContainerConfig(serviceConfig types.ServiceConfig, serviceVols *ad
185189
c.MountPoints = mountPoints
186190
}
187191

188-
logWarningForDeployFields(serviceConfig.Deploy, serviceConfig.Name)
189-
190-
// TODO: log out unsupported fields
191192
return c, nil
192193
}
193194

0 commit comments

Comments
 (0)