Skip to content

Commit a429aff

Browse files
feat: introduce warning system (#255)
1 parent 20344ec commit a429aff

File tree

5 files changed

+261
-26
lines changed

5 files changed

+261
-26
lines changed

cmd/validate_compose.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,25 @@ var validateDockerCompose = &cobra.Command{
3939
},
4040
}
4141

42+
var validateDockerComposeWithErrors = &cobra.Command{
43+
Use: "docker-compose-with-errors",
44+
Aliases: []string{"dcwe"},
45+
Short: "Verify docker-compose file for compatability with this tool with next versions of compose-go library",
46+
Run: func(cmd *cobra.Command, args []string) {
47+
dockerComposeFile, err := cmd.Flags().GetString("docker-compose")
48+
if err != nil {
49+
fmt.Println(fmt.Errorf("error reading docker-compose flag: %v", err))
50+
os.Exit(1)
51+
}
52+
53+
err = validateDockerComposeWithError(dockerComposeFile)
54+
if err != nil {
55+
fmt.Println(err.Error())
56+
os.Exit(1)
57+
}
58+
},
59+
}
60+
4261
// ValidateDockerCompose validate a docker-compose file
4362
func ValidateDockerCompose(file string, ignoreErrors, ignoreMisEnvFiles bool) error {
4463
_, _, err := lagoon.UnmarshaDockerComposeYAML(file, ignoreErrors, ignoreMisEnvFiles, map[string]string{})
@@ -48,8 +67,20 @@ func ValidateDockerCompose(file string, ignoreErrors, ignoreMisEnvFiles bool) er
4867
return nil
4968
}
5069

70+
// validateDockerComposeWithErrors validate a docker-compose file yaml structure properly
71+
func validateDockerComposeWithError(file string) error {
72+
err := lagoon.ValidateUnmarshalDockerComposeYAML(file)
73+
if err != nil {
74+
return err
75+
}
76+
return nil
77+
}
78+
5179
func init() {
5280
validateCmd.AddCommand(validateDockerCompose)
81+
validateCmd.AddCommand(validateDockerComposeWithErrors)
5382
validateDockerCompose.Flags().StringP("docker-compose", "", "docker-compose.yml",
5483
"The docker-compose.yml file to read.")
84+
validateDockerComposeWithErrors.Flags().StringP("docker-compose", "", "docker-compose.yml",
85+
"The docker-compose.yml file to read.")
5586
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require (
1515
github.com/uselagoon/machinery v0.0.7
1616
github.com/vshn/k8up v1.99.99
1717
gopkg.in/yaml.v2 v2.4.0
18+
gopkg.in/yaml.v3 v3.0.1
1819
k8s.io/api v0.25.3
1920
k8s.io/apimachinery v0.25.3
2021
k8s.io/client-go v0.25.3
@@ -66,7 +67,6 @@ require (
6667
google.golang.org/protobuf v1.28.1 // indirect
6768
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
6869
gopkg.in/inf.v0 v0.9.1 // indirect
69-
gopkg.in/yaml.v3 v3.0.1 // indirect
7070
k8s.io/klog/v2 v2.80.1 // indirect
7171
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
7272
k8s.io/utils v0.0.0-20221012122500-cfd413dd9e85 // indirect

internal/lagoon/compose.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/compose-spec/compose-go/loader"
1010
composetypes "github.com/compose-spec/compose-go/types"
1111
goyaml "gopkg.in/yaml.v2"
12+
goyamlv3 "gopkg.in/yaml.v3"
1213
utilvalidation "k8s.io/apimachinery/pkg/util/validation"
1314
)
1415

@@ -69,6 +70,20 @@ func UnmarshalLagoonDockerComposeYAML(file string) ([]OriginalServiceOrder, erro
6970
return l, nil
7071
}
7172

73+
// use goyamlv3 that newer versions of compose-go uses to validate
74+
func ValidateUnmarshalDockerComposeYAML(file string) error {
75+
rawYAML, err := os.ReadFile(file)
76+
if err != nil {
77+
return fmt.Errorf("couldn't read %v: %v", file, err)
78+
}
79+
var m interface{}
80+
err = goyamlv3.Unmarshal(rawYAML, &m)
81+
if err != nil {
82+
return err
83+
}
84+
return nil
85+
}
86+
7287
// Checks the validity of the service name against the RFC1035 DNS label standard
7388
func CheckServiceNameValidity(v goyaml.MapItem) error {
7489
// go over the service map looking for the labels slice

internal/lagoon/compose_test.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,103 @@ func TestCheckLagoonLabel(t *testing.T) {
217217
})
218218
}
219219
}
220+
221+
func TestUnmarshalLagoonDockerComposeYAML(t *testing.T) {
222+
type args struct {
223+
file string
224+
}
225+
tests := []struct {
226+
name string
227+
args args
228+
wantErrMsg string
229+
wantErr bool
230+
}{
231+
{
232+
name: "test1 docker-compose drupal example",
233+
args: args{
234+
file: "../../test-resources/docker-compose/test1/docker-compose.yml",
235+
},
236+
wantErr: true,
237+
wantErrMsg: `line 59: mapping key "<<" already defined at line 58`,
238+
},
239+
{
240+
name: "test2 docker-compose node example",
241+
args: args{
242+
file: "../../test-resources/docker-compose/test2/docker-compose.yml",
243+
},
244+
},
245+
{
246+
name: "test3 docker-compose complex",
247+
args: args{
248+
file: "../../test-resources/docker-compose/test3/docker-compose.yml",
249+
},
250+
},
251+
{
252+
name: "test4 docker-compose complex",
253+
args: args{
254+
file: "../../test-resources/docker-compose/test4/docker-compose.yml",
255+
},
256+
},
257+
{
258+
name: "test5 docker-compose complex",
259+
args: args{
260+
file: "../../test-resources/docker-compose/test5/docker-compose.yml",
261+
},
262+
wantErr: true,
263+
wantErrMsg: `line 57: mapping key "<<" already defined at line 56`,
264+
},
265+
{
266+
name: "test6 docker-compose complex",
267+
args: args{
268+
file: "../../test-resources/docker-compose/test6/docker-compose.yml",
269+
},
270+
},
271+
// these tests are specific to docker-compose validations, but will pass yaml validations
272+
{
273+
name: "test7 check an invalid docker-compose with ignoring non-string key errors (valid yaml)",
274+
args: args{
275+
file: "../../test-resources/docker-compose/test7/docker-compose.yml",
276+
},
277+
},
278+
{
279+
name: "test8 check an invalid docker-compose (same as test7 but not ignoring the errors)",
280+
args: args{
281+
file: "../../test-resources/docker-compose/test8/docker-compose.yml",
282+
},
283+
},
284+
{
285+
name: "test9 check an valid docker-compose with missing env_files",
286+
args: args{
287+
file: "../../test-resources/docker-compose/test9/docker-compose.yml",
288+
},
289+
},
290+
{
291+
name: "test10 check an valid docker-compose with missing env_files (same as test9 but not ignoring the errors)",
292+
args: args{
293+
file: "../../test-resources/docker-compose/test10/docker-compose.yml",
294+
},
295+
},
296+
{
297+
name: "test11 docker-compose service name with '.'",
298+
args: args{
299+
file: "../../test-resources/docker-compose/test11/docker-compose.yml",
300+
},
301+
},
302+
// ^^ these tests are specific to docker-compose validations, but will pass yaml validations
303+
}
304+
for _, tt := range tests {
305+
t.Run(tt.name, func(t *testing.T) {
306+
err := ValidateUnmarshalDockerComposeYAML(tt.args.file)
307+
if (err != nil) != tt.wantErr {
308+
t.Errorf("ValidateUnmarshalDockerComposeYAML() error = %v, wantErr %v", err, tt.wantErr)
309+
return
310+
}
311+
if err != nil {
312+
if !strings.Contains(err.Error(), tt.wantErrMsg) {
313+
t.Errorf("ValidateUnmarshalDockerComposeYAML() error = %v, wantErr %v", err.Error(), tt.wantErrMsg)
314+
}
315+
return
316+
}
317+
})
318+
}
319+
}

0 commit comments

Comments
 (0)