@@ -17,52 +17,89 @@ import (
1717
1818// AnsiblePythonInput defines parameters for executing Python Ansible modules
1919type AnsiblePythonInput struct {
20- ModuleName string `yaml:"module_name" json:"module_name"`
21- Args map [ string ] interface {} `yaml:"args" json:"args"`
20+ ModuleName string `yaml:"module_name" json:"module_name"`
21+ Args interface {} `yaml:"args" json:"args"`
2222}
2323
2424func (i AnsiblePythonInput ) ToCode () string {
25- // Convert Args map to Go code format
26- argsCode := "map[string]interface{}{"
27- for k , v := range i .Args {
28- switch val := v .(type ) {
29- case string :
30- argsCode += fmt .Sprintf ("%q:%q," , k , val )
31- case bool :
32- argsCode += fmt .Sprintf ("%q:%t," , k , val )
33- case int , int32 , int64 :
34- argsCode += fmt .Sprintf ("%q:%v," , k , val )
35- case float32 , float64 :
36- argsCode += fmt .Sprintf ("%q:%v," , k , val )
37- case []interface {}:
38- // Handle slice values like ["hostname test-switch","interface Ethernet1"," no shutdown"]
39- sliceCode := "[]interface{}{"
40- for _ , item := range val {
41- switch itemVal := item .(type ) {
42- case string :
43- sliceCode += fmt .Sprintf ("%q," , itemVal )
44- default :
45- sliceCode += fmt .Sprintf ("%v," , itemVal )
46- }
47- }
48- sliceCode += "}"
49- argsCode += fmt .Sprintf ("%q:%s," , k , sliceCode )
50- default :
51- argsCode += fmt .Sprintf ("%q:interface{}(%v)," , k , val )
25+ // Convert Args (map or slice) to Go code format
26+ var argsCode string
27+ switch v := i .Args .(type ) {
28+ case map [string ]interface {}:
29+ b := strings.Builder {}
30+ b .WriteString ("map[string]interface{}{" )
31+ for mk , mv := range v {
32+ b .WriteString (fmt .Sprintf ("%q:%s," , mk , generateGoLiteral (mv )))
5233 }
34+ b .WriteString ("}" )
35+ argsCode = b .String ()
36+ case []interface {}:
37+ b := strings.Builder {}
38+ b .WriteString ("[]interface{}{" )
39+ for _ , sv := range v {
40+ b .WriteString (generateGoLiteral (sv ))
41+ b .WriteString ("," )
42+ }
43+ b .WriteString ("}" )
44+ argsCode = b .String ()
45+ case nil :
46+ argsCode = "nil"
47+ default :
48+ argsCode = fmt .Sprintf ("interface{}(%v)" , v )
5349 }
54- argsCode += "}"
5550 return fmt .Sprintf ("modules.AnsiblePythonInput{ModuleName: %q, Args: %s}" , i .ModuleName , argsCode )
5651}
5752
53+ // generateGoLiteral renders a best-effort Go code literal for common JSON/YAML-like values
54+ func generateGoLiteral (val interface {}) string {
55+ switch v := val .(type ) {
56+ case string :
57+ return fmt .Sprintf ("%q" , v )
58+ case bool :
59+ return fmt .Sprintf ("%t" , v )
60+ case int , int8 , int16 , int32 , int64 , uint , uint8 , uint16 , uint32 , uint64 , float32 , float64 :
61+ return fmt .Sprintf ("%v" , v )
62+ case map [string ]interface {}:
63+ b := strings.Builder {}
64+ b .WriteString ("map[string]interface{}{" )
65+ for mk , mv := range v {
66+ b .WriteString (fmt .Sprintf ("%q:%s," , mk , generateGoLiteral (mv )))
67+ }
68+ b .WriteString ("}" )
69+ return b .String ()
70+ case []interface {}:
71+ b := strings.Builder {}
72+ b .WriteString ("[]interface{}{" )
73+ for _ , sv := range v {
74+ b .WriteString (generateGoLiteral (sv ))
75+ b .WriteString ("," )
76+ }
77+ b .WriteString ("}" )
78+ return b .String ()
79+ default :
80+ return fmt .Sprintf ("interface{}(%v)" , v )
81+ }
82+ }
83+
5884func (i AnsiblePythonInput ) GetVariableUsage () []string {
5985 var variables []string
60- // Extract variables from arguments recursively
61- for _ , v := range i .Args {
62- if str , ok := v .(string ); ok {
63- variables = append (variables , pkg .GetVariableUsageFromTemplate (str )... )
86+ // Extract variables from arguments recursively, handling map and slice
87+ var walk func (val interface {})
88+ walk = func (val interface {}) {
89+ switch tv := val .(type ) {
90+ case string :
91+ variables = append (variables , pkg .GetVariableUsageFromTemplate (tv )... )
92+ case map [string ]interface {}:
93+ for _ , mv := range tv {
94+ walk (mv )
95+ }
96+ case []interface {}:
97+ for _ , sv := range tv {
98+ walk (sv )
99+ }
64100 }
65101 }
102+ walk (i .Args )
66103 return variables
67104}
68105
@@ -456,23 +493,23 @@ func (m PythonFallbackModule) ParameterAliases() map[string]string {
456493
457494// GetPythonFallbackForCompilation creates a Python fallback module and params for compilation phase
458495func GetPythonFallbackForCompilation (moduleName string , rawParams interface {}) (pkg.Module , interface {}) {
459- // Convert rawParams to map[string]interface{}
460- var paramsMap map [ string ] interface {}
461- if rawParams != nil {
462- if pm , ok := rawParams .( map [string ]interface {}); ok {
463- paramsMap = pm
464- } else {
465- // Try to convert other types to a simple parameter
466- paramsMap = map [ string ] interface {}{ "value" : rawParams }
467- }
468- } else {
469- paramsMap = make ( map [string ]interface {})
496+ // Preserve map or slice params as-is; fallback to map with single value otherwise
497+ var args interface {}
498+ switch v := rawParams .( type ) {
499+ case map [string ]interface {}:
500+ args = v
501+ case [] interface {}:
502+ args = v
503+ case nil :
504+ args = map [ string ] interface {}{ }
505+ default :
506+ args = map [string ]interface {}{ "value" : rawParams }
470507 }
471508
472509 // Create the AnsiblePythonInput structure directly
473510 pythonInput := AnsiblePythonInput {
474511 ModuleName : moduleName ,
475- Args : paramsMap ,
512+ Args : args ,
476513 }
477514
478515 return PythonFallbackModule {}, pythonInput
0 commit comments