Files
steampipe/pkg/steampipeconfig/modconfig/variable.go

140 lines
4.3 KiB
Go

package modconfig
import (
"fmt"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/terraform/tfdiags"
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig/var_config"
"github.com/turbot/steampipe/pkg/type_conversion"
"github.com/turbot/steampipe/pkg/utils"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/convert"
)
// TODO check DescriptionSet - still required?
// Variable is a struct representing a Variable resource
type Variable struct {
ResourceWithMetadataImpl
ModTreeItemImpl
// required to allow partial decoding
Remain hcl.Body `hcl:",remain" json:"-"`
Default cty.Value `column:"default_value,jsonb" json:"-"`
Type cty.Type `column:"var_type,text" json:"-"`
TypeString string `json:"type"`
DefaultGo any `json:"value_default"`
ValueGo any `json:"value"`
ModName string `json:"mod_name"`
// set after value resolution `column:"value,jsonb"`
Value cty.Value `column:"value,jsonb" json:"-"`
ValueSourceType string `column:"value_source,text" json:"-"`
ValueSourceFileName string `column:"value_source_file_name,text" json:"-"`
ValueSourceStartLineNumber int `column:"value_source_start_line_number,integer" json:"-"`
ValueSourceEndLineNumber int `column:"value_source_end_line_number,integer" json:"-"`
ParsingMode var_config.VariableParsingMode `json:"-"`
metadata *ResourceMetadata
}
func NewVariable(v *var_config.Variable, mod *Mod) *Variable {
var defaultGo interface{} = nil
if !v.Default.IsNull() {
defaultGo, _ = type_conversion.CtyToGo(v.Default)
}
fullName := fmt.Sprintf("%s.var.%s", mod.ShortName, v.Name)
return &Variable{
ModTreeItemImpl: ModTreeItemImpl{
HclResourceImpl: HclResourceImpl{
ShortName: v.Name,
Description: &v.Description,
FullName: fullName,
DeclRange: v.DeclRange,
UnqualifiedName: fmt.Sprintf("var.%s", v.Name),
blockType: BlockTypeVariable,
},
Mod: mod,
},
Default: v.Default,
Type: v.Type,
ParsingMode: v.ParsingMode,
ModName: mod.ShortName,
DefaultGo: defaultGo,
TypeString: type_conversion.CtyTypeToHclType(v.Type, v.Default.Type()),
}
}
func (v *Variable) Equals(other *Variable) bool {
return v.ShortName == other.ShortName &&
v.FullName == other.FullName &&
v.Description == other.Description &&
v.Default.RawEquals(other.Default) &&
v.Value.RawEquals(other.Value)
}
// OnDecoded implements HclResource
func (v *Variable) OnDecoded(block *hcl.Block, _ ResourceMapsProvider) hcl.Diagnostics {
return nil
}
// Required returns true if this variable is required to be set by the caller,
// or false if there is a default value that will be used when it isn't set.
func (v *Variable) Required() bool {
return v.Default == cty.NilVal
}
func (v *Variable) SetInputValue(value cty.Value, sourceType string, sourceRange tfdiags.SourceRange) error {
// if no type is set and a default _is_ set, use default to set the type
if v.Type.Equals(cty.DynamicPseudoType) && !v.Default.IsNull() {
v.Type = v.Default.Type()
}
// if the value type is a tuple with no elem type, and we have a type, set the variable to have our type
if value.Type().Equals(cty.Tuple(nil)) && !v.Type.Equals(cty.DynamicPseudoType) {
var err error
value, err = convert.Convert(value, v.Type)
if err != nil {
return err
}
}
v.Value = value
v.ValueSourceType = sourceType
v.ValueSourceFileName = sourceRange.Filename
v.ValueSourceStartLineNumber = sourceRange.Start.Line
v.ValueSourceEndLineNumber = sourceRange.End.Line
v.ValueGo, _ = type_conversion.CtyToGo(value)
// if type string is not set, derive from the type of value
if v.TypeString == "" {
v.TypeString = type_conversion.CtyTypeToHclType(value.Type())
}
return nil
}
func (v *Variable) Diff(other *Variable) *DashboardTreeItemDiffs {
res := &DashboardTreeItemDiffs{
Item: v,
Name: v.Name(),
}
if !utils.SafeStringsEqual(v.FullName, other.FullName) {
res.AddPropertyDiff("Name")
}
if !utils.SafeStringsEqual(v.Value, other.Value) {
res.AddPropertyDiff("Value")
}
res.populateChildDiffs(v, other)
return res
}
// CtyValue implements CtyValueProvider
func (v *Variable) CtyValue() (cty.Value, error) {
return GetCtyValue(v)
}