@@ -3,6 +3,7 @@ package load
3
3
import (
4
4
"fmt"
5
5
"slices"
6
+ "sort"
6
7
"sync"
7
8
8
9
"go.starlark.net/starlark"
@@ -34,7 +35,7 @@ func compile(programName string, src string, preDeclared []string) (*starlark.Pr
34
35
}
35
36
36
37
// validate validates a scriptlet by compiling it and checking the presence of required functions.
37
- func validate (compiler func (string , string ) (* starlark.Program , error ), programName string , src string , requiredFunctions []string ) error {
38
+ func validate (compiler func (string , string ) (* starlark.Program , error ), programName string , src string , requiredFunctions map [ string ] []string ) error {
38
39
prog , err := compiler (programName , src )
39
40
if err != nil {
40
41
return err
@@ -49,19 +50,44 @@ func validate(compiler func(string, string) (*starlark.Program, error), programN
49
50
globals .Freeze ()
50
51
51
52
var notFound []string
52
- for _ , funName := range requiredFunctions {
53
+ for funName , requiredArgs := range requiredFunctions {
53
54
// The function is missing if its name is not found in the globals.
54
- requiredFun := globals [funName ]
55
- if requiredFun == nil {
55
+ funv := globals [funName ]
56
+ if funv == nil {
56
57
notFound = append (notFound , funName )
57
58
continue
58
59
}
59
60
60
61
// The function is missing if its name is not bound to a function.
61
- _ , ok := requiredFun .(* starlark.Function )
62
+ fun , ok := funv .(* starlark.Function )
62
63
if ! ok {
63
64
notFound = append (notFound , funName )
64
65
}
66
+
67
+ // Get the function arguments.
68
+ argc := fun .NumParams ()
69
+ var args []string
70
+ for i := range argc {
71
+ arg , _ := fun .Param (i )
72
+ args = append (args , arg )
73
+ }
74
+
75
+ // Return an error early if the function does not have the right arguments.
76
+ match := len (args ) == len (requiredArgs )
77
+ if match {
78
+ sort .Strings (args )
79
+ sort .Strings (requiredArgs )
80
+ for i := range args {
81
+ if args [i ] != requiredArgs [i ] {
82
+ match = false
83
+ break
84
+ }
85
+ }
86
+ }
87
+
88
+ if ! match {
89
+ return fmt .Errorf ("The function %q defines arguments %q (expected: %q)" , funName , args , requiredArgs )
90
+ }
65
91
}
66
92
67
93
switch len (notFound ) {
@@ -130,8 +156,8 @@ func InstancePlacementCompile(name string, src string) (*starlark.Program, error
130
156
131
157
// InstancePlacementValidate validates the instance placement scriptlet.
132
158
func InstancePlacementValidate (src string ) error {
133
- return validate (InstancePlacementCompile , nameInstancePlacement , src , []string {
134
- "instance_placement" ,
159
+ return validate (InstancePlacementCompile , nameInstancePlacement , src , map [ string ] []string {
160
+ "instance_placement" : [] string { "request" , "candidate_members" } ,
135
161
})
136
162
}
137
163
@@ -173,8 +199,8 @@ func QEMUCompile(name string, src string) (*starlark.Program, error) {
173
199
174
200
// QEMUValidate validates the QEMU scriptlet.
175
201
func QEMUValidate (src string ) error {
176
- return validate (QEMUCompile , prefixQEMU , src , []string {
177
- "qemu_hook" ,
202
+ return validate (QEMUCompile , prefixQEMU , src , map [ string ] []string {
203
+ "qemu_hook" : [] string { "hook_name" } ,
178
204
})
179
205
}
180
206
@@ -200,8 +226,8 @@ func AuthorizationCompile(name string, src string) (*starlark.Program, error) {
200
226
201
227
// AuthorizationValidate validates the authorization scriptlet.
202
228
func AuthorizationValidate (src string ) error {
203
- return validate (AuthorizationCompile , nameAuthorization , src , []string {
204
- "authorize" ,
229
+ return validate (AuthorizationCompile , nameAuthorization , src , map [ string ] []string {
230
+ "authorize" : [] string { "details" , "object" , "entitlement" } ,
205
231
})
206
232
}
207
233
0 commit comments