/
debug.go
100 lines (93 loc) 路 2.77 KB
/
debug.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package funcs
import (
"fmt"
"github.com/rs/zerolog"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/function"
ctyJson "github.com/zclconf/go-cty/cty/json"
)
// PrintArgs prints any number of args to the std out using fmt.
// This can be used for debugging variables/inputs at points in the Terraform evaluation.
// Example usage:
//
// infracostprint("test", 50)
//
// will print:
//
// "terraform print "test":cty.IntVal(50)
//
// PrintArgs will return any args passed unaltered so that the args are still safe to use in the evaluation context.
// e.g:
//
// locals {
// test = infracostprint("a")
// }
//
// will still have `local.test` == "a" if used by other Terraform attributes/blocks. This allows debugging to unalter the
// Terraform evaluation and not cause unwanted consequences.
var PrintArgs = function.New(&function.Spec{
Params: []function.Parameter{
{
Name: "name",
Type: cty.String,
},
{
Name: "v",
Type: cty.DynamicPseudoType,
AllowNull: true,
AllowUnknown: true,
AllowMarked: true,
AllowDynamicType: true,
},
},
Type: func(args []cty.Value) (cty.Type, error) {
return args[1].Type(), nil
},
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
fmt.Printf("terraform print %q:%s\n", args[0].AsString(), string(valueToBytes(args[1])))
return args[1], nil
},
})
func valueToBytes(v cty.Value) []byte {
simple := ctyJson.SimpleJSONValue{Value: v}
b, _ := simple.MarshalJSON()
return b
}
// LogArgs is identical to PrintArgs but writes the arguments to the Infracost log.
// This is useful to understand arguments as they change in the module evaluation.
// As the arguments will be printed next to log entries that correspond to the program runtime.
// e.g:
//
// root_block_device {
// volume_size = infracostlog("test", "foo")
// }
//
// will log:
//
// time="2022-12-06T10:27:40Z" level=debug enable_cloud_org=false ... attribute_name=volume_size provider=terraform_dir block_name=root_block_device. sync_usage=false msg="fetching attribute value"
// time="2022-12-06T10:27:40Z" level=debug ... msg="terraform print "test":cty.StringVal(\"foo\")"
func LogArgs(logger zerolog.Logger) function.Function {
return function.New(&function.Spec{
Params: []function.Parameter{
{
Name: "name",
Type: cty.String,
},
{
Name: "v",
Type: cty.DynamicPseudoType,
AllowNull: true,
AllowMarked: true,
AllowUnknown: true,
AllowDynamicType: true,
},
},
Type: func(args []cty.Value) (cty.Type, error) {
return args[1].Type(), nil
},
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
logger.Debug().Msgf("terraform print %q:%s", args[0], args[1].GoString())
return args[1], nil
},
})
}