diff --git a/pkg/policies/policies.go b/pkg/policies/policies.go index 4ebbe8cd2..ebd173d89 100644 --- a/pkg/policies/policies.go +++ b/pkg/policies/policies.go @@ -230,12 +230,24 @@ func ComputeArguments(inputs []*v1.PolicyInput, args map[string]string, bindings if input.Required && input.Default != "" { return nil, fmt.Errorf("input %s can not be required and have a default at the same time", input.Name) } - if _, ok := args[input.Name]; !ok { + + // if the input exists, it might be an expression, apply bindings to see if it has a value + argValue := args[input.Name] + var err error + if argValue != "" { + argValue, err = templates.ApplyBinding(argValue, bindings) + if err != nil { + return nil, err + } + } + + // if the input is not present, or the computed value is empty, we need to check if it's required + if _, ok := args[input.Name]; !ok || argValue == "" { if input.Required { return nil, fmt.Errorf("missing required input %q", input.Name) } // if not required, and it has a default value, let's use it - if args[input.Name] == "" && input.Default != "" { + if argValue == "" && input.Default != "" { value, err := templates.ApplyBinding(input.Default, bindings) if err != nil { return nil, err diff --git a/pkg/policies/policies_test.go b/pkg/policies/policies_test.go index 19ce899b0..747865830 100644 --- a/pkg/policies/policies_test.go +++ b/pkg/policies/policies_test.go @@ -932,6 +932,15 @@ func (s *testSuite) TestComputePolicyArguments() { bindings: map[string]string{"foo": "world", "bar": "template"}, expected: map[string]string{"arg1": "Hello world template", "arg2": "Bye template"}, }, + { + name: "required input with missing binding", + inputs: []*v12.PolicyInput{{ + Name: "arg1", + Required: true, + }}, + args: map[string]string{"arg1": "{{ inputs.foo }}"}, + expectErr: true, + }, } for _, tc := range cases { diff --git a/pkg/templates/templates.go b/pkg/templates/templates.go index 10c5dff7a..21050a840 100644 --- a/pkg/templates/templates.go +++ b/pkg/templates/templates.go @@ -25,8 +25,12 @@ var inputsPrefixRegexp = regexp.MustCompile(`{{\s*(inputs.)`) // ApplyBinding renders an input template using bindings in Go templating format func ApplyBinding(input string, bindings map[string]string) (string, error) { - if bindings == nil || input == "" { - return input, nil + if input == "" { + return "", nil + } + + if bindings == nil { + bindings = make(map[string]string) } // Support both `.inputs.foo` and `inputs.foo`