From 8c7c93674fb3a220929b50220b7d6e9fc47d00d4 Mon Sep 17 00:00:00 2001 From: "Jose I. Paris" Date: Fri, 2 May 2025 14:26:48 +0200 Subject: [PATCH] fix required arguments with missing bindings Signed-off-by: Jose I. Paris --- pkg/policies/policies.go | 16 ++++++++++++++-- pkg/policies/policies_test.go | 9 +++++++++ pkg/templates/templates.go | 8 ++++++-- 3 files changed, 29 insertions(+), 4 deletions(-) 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`