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

198 lines
5.6 KiB
Go

package modconfig
import (
"fmt"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/terraform/tfdiags"
typehelpers "github.com/turbot/go-kit/types"
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig/var_config"
"github.com/turbot/steampipe/pkg/utils"
"github.com/zclconf/go-cty/cty"
)
// Variable is a struct representing a Variable resource
type Variable struct {
ResourceWithMetadataBase
ShortName string `json:"name"`
FullName string `column:"name,text" json:"-"`
Description string `column:"description,text" json:"description"`
Default cty.Value `column:"default_value,jsonb" json:"-"`
Type cty.Type `column:"var_type,text" json:"-"`
DescriptionSet bool ` json:"-"`
TypeString string `json:"type"`
DefaultGo interface{} `json:"value_default"`
ValueGo interface{} `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:"-"`
DeclRange hcl.Range `json:"-"`
ParsingMode var_config.VariableParsingMode `json:"-"`
Mod *Mod `json:"-"`
UnqualifiedName string `json:"-"`
Paths []NodePath `column:"path,jsonb" json:"-"`
metadata *ResourceMetadata
parents []ModTreeItem
}
func NewVariable(v *var_config.Variable, mod *Mod) *Variable {
var defaultGo interface{} = nil
if !v.Default.IsNull() {
defaultGo, _ = utils.CtyToGo(v.Default)
}
return &Variable{
ShortName: v.Name,
Description: v.Description,
FullName: fmt.Sprintf("%s.var.%s", mod.ShortName, v.Name),
UnqualifiedName: fmt.Sprintf("var.%s", v.Name),
Default: v.Default,
Type: v.Type,
ParsingMode: v.ParsingMode,
Mod: mod,
DeclRange: v.DeclRange,
ModName: mod.ShortName,
DefaultGo: defaultGo,
TypeString: utils.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)
}
// Name implements HclResource, ResourceWithMetadata
func (v *Variable) Name() string {
return v.FullName
}
// GetUnqualifiedName implements DashboardLeafNode, ModTreeItem
func (v *Variable) GetUnqualifiedName() string {
return v.UnqualifiedName
}
// OnDecoded implements HclResource
func (v *Variable) OnDecoded(block *hcl.Block, resourceMapProvider ModResourcesProvider) hcl.Diagnostics {
return nil
}
// AddReference implements HclResource
func (v *Variable) AddReference(*ResourceReference) {}
// GetReferences implements HclResource
func (v *Variable) GetReferences() []*ResourceReference {
return nil
}
// GetMod implements HclResource
func (v *Variable) GetMod() *Mod {
return v.Mod
}
// CtyValue implements HclResource
func (v *Variable) CtyValue() (cty.Value, error) {
return v.Default, nil
}
// GetDeclRange implements HclResource
func (v *Variable) GetDeclRange() *hcl.Range {
return &v.DeclRange
}
// 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) {
v.Value = value
v.ValueSourceType = sourceType
v.ValueSourceFileName = sourceRange.Filename
v.ValueSourceStartLineNumber = sourceRange.Start.Line
v.ValueSourceEndLineNumber = sourceRange.End.Line
v.ValueGo, _ = utils.CtyToGo(value)
v.TypeString = utils.CtyTypeToHclType(value.Type())
}
// AddParent implements ModTreeItem
func (v *Variable) AddParent(parent ModTreeItem) error {
v.parents = append(v.parents, parent)
return nil
}
// GetParents implements ModTreeItem
func (v *Variable) GetParents() []ModTreeItem {
return v.parents
}
// GetChildren implements ModTreeItem
func (v *Variable) GetChildren() []ModTreeItem {
return nil
}
// GetDescription implements ModTreeItem
func (v *Variable) GetDescription() string {
return ""
}
// GetTitle implements ModTreeItem
func (v *Variable) GetTitle() string {
return typehelpers.SafeString(v.ShortName)
}
// GetTags implements ModTreeItem
func (v *Variable) GetTags() map[string]string {
return nil
}
// GetPaths implements ModTreeItem
func (v *Variable) GetPaths() []NodePath {
// lazy load
if len(v.Paths) == 0 {
v.SetPaths()
}
return v.Paths
}
// SetPaths implements ModTreeItem
func (v *Variable) SetPaths() {
for _, parent := range v.parents {
for _, parentPath := range parent.GetPaths() {
v.Paths = append(v.Paths, append(parentPath, v.Name()))
}
}
}
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
}