Skip to content

Commit 762d46a

Browse files
committed
limayaml: add a check to verify whether the variables defined in param are actually used
This check needs to be performed before the template is expanded, so it should be added before calling `FillDefault()`. Signed-off-by: Norio Nomura <[email protected]>
1 parent 3f5501b commit 762d46a

File tree

3 files changed

+69
-2
lines changed

3 files changed

+69
-2
lines changed

pkg/limayaml/load.go

+5
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ func Load(b []byte, filePath string) (*LimaYAML, error) {
8686
return nil, err
8787
}
8888

89+
// It should be called before the `y` parameter is passed to FillDefault() that execute template.
90+
if err := ValidateParamIsUsed(&y); err != nil {
91+
return nil, err
92+
}
93+
8994
FillDefault(&y, &d, &o, filePath)
9095
return &y, nil
9196
}

pkg/limayaml/validate.go

+43-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"os"
88
"path"
99
"path/filepath"
10+
"regexp"
1011
"runtime"
1112
"strings"
1213

@@ -252,7 +253,7 @@ func Validate(y *LimaYAML, warn bool) error {
252253
}
253254
if rule.GuestSocket != "" {
254255
if !path.IsAbs(rule.GuestSocket) {
255-
return fmt.Errorf("field `%s.guestSocket` must be an absolute path", field)
256+
return fmt.Errorf("field `%s.guestSocket` must be an absolute path, but is %q", field, rule.GuestSocket)
256257
}
257258
if rule.HostSocket == "" && rule.HostPortRange[1]-rule.HostPortRange[0] > 0 {
258259
return fmt.Errorf("field `%s.guestSocket` can only be mapped to a single port or socket. not a range", field)
@@ -287,7 +288,7 @@ func Validate(y *LimaYAML, warn bool) error {
287288
field := fmt.Sprintf("CopyToHost[%d]", i)
288289
if rule.GuestFile != "" {
289290
if !path.IsAbs(rule.GuestFile) {
290-
return fmt.Errorf("field `%s.guest` must be an absolute path", field)
291+
return fmt.Errorf("field `%s.guest` must be an absolute path, but is %q", field, rule.GuestFile)
291292
}
292293
}
293294
if rule.HostFile != "" {
@@ -385,6 +386,46 @@ func validateNetwork(y *LimaYAML) error {
385386
return nil
386387
}
387388

389+
// ValidateParamIsUsed checks if the keys in the `param` field are used in any script, probe, copyToHost, or portForward.
390+
// It should be called before the `y` parameter is passed to FillDefault() that execute template.
391+
func ValidateParamIsUsed(y *LimaYAML) error {
392+
for key := range y.Param {
393+
re, err := regexp.Compile(`{{[^}]*\.Param\.` + key + `[^}]*}}`)
394+
if err != nil {
395+
return fmt.Errorf("field to compile regexp for key %q: %w", key, err)
396+
}
397+
keyIsUsed := false
398+
for _, p := range y.Provision {
399+
if re.MatchString(p.Script) {
400+
keyIsUsed = true
401+
break
402+
}
403+
}
404+
for _, p := range y.Probes {
405+
if re.MatchString(p.Script) {
406+
keyIsUsed = true
407+
break
408+
}
409+
}
410+
for _, p := range y.CopyToHost {
411+
if re.MatchString(p.GuestFile) || re.MatchString(p.HostFile) {
412+
keyIsUsed = true
413+
break
414+
}
415+
}
416+
for _, p := range y.PortForwards {
417+
if re.MatchString(p.GuestSocket) || re.MatchString(p.HostSocket) {
418+
keyIsUsed = true
419+
break
420+
}
421+
}
422+
if !keyIsUsed {
423+
return fmt.Errorf("field `param` key %q is not used in any provision, probe, copyToHost, or portForward", key)
424+
}
425+
}
426+
return nil
427+
}
428+
388429
func validatePort(field string, port int) error {
389430
switch {
390431
case port < 0:

pkg/limayaml/validate_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,24 @@ func TestValidateDefault(t *testing.T) {
3030
err = Validate(y, true)
3131
assert.NilError(t, err)
3232
}
33+
34+
func TestValidateParamIsUsed(t *testing.T) {
35+
paramYaml := `param:
36+
name: value`
37+
_, err := Load([]byte(paramYaml), "paramIsNotUsed.yaml")
38+
assert.Error(t, err, "field `param` key \"name\" is not used in any provision, probe, copyToHost, or portForward")
39+
40+
fieldsUsingParam := []string{
41+
`provision: [{"script": "echo {{ .Param.name }}"}]`,
42+
`probes: [{"script": "echo {{ .Param.name }}"}]`,
43+
`copyToHost: [{"guest": "/tmp/{{ .Param.name }}", "host": "/tmp"}]`,
44+
`copyToHost: [{"guest": "/tmp", "host": "/tmp/{{ .Param.name }}"}]`,
45+
`portForwards: [{"guestSocket": "/tmp/{{ .Param.name }}", "hostSocket": "/tmp"}]`,
46+
`portForwards: [{"guestSocket": "/tmp", "hostSocket": "/tmp/{{ .Param.name }}"}]`,
47+
}
48+
for _, fieldUsingParam := range fieldsUsingParam {
49+
_, err = Load([]byte(fieldUsingParam+"\n"+paramYaml), "paramIsUsed.yaml")
50+
//
51+
assert.NilError(t, err)
52+
}
53+
}

0 commit comments

Comments
 (0)