mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
adcf41f076
We added the description field in 0.9 but we never parsed it because we didn't have a use for it. As we prepare to use this field, let's start parsing it out
379 lines
7.6 KiB
Go
379 lines
7.6 KiB
Go
package config
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
// TestString is a Stringer-like function that outputs a string that can
|
|
// be used to easily compare multiple Config structures in unit tests.
|
|
//
|
|
// This function has no practical use outside of unit tests and debugging.
|
|
func (c *Config) TestString() string {
|
|
if c == nil {
|
|
return "<nil config>"
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
if len(c.Modules) > 0 {
|
|
buf.WriteString("Modules:\n\n")
|
|
buf.WriteString(modulesStr(c.Modules))
|
|
buf.WriteString("\n\n")
|
|
}
|
|
|
|
if len(c.Variables) > 0 {
|
|
buf.WriteString("Variables:\n\n")
|
|
buf.WriteString(variablesStr(c.Variables))
|
|
buf.WriteString("\n\n")
|
|
}
|
|
|
|
if len(c.ProviderConfigs) > 0 {
|
|
buf.WriteString("Provider Configs:\n\n")
|
|
buf.WriteString(providerConfigsStr(c.ProviderConfigs))
|
|
buf.WriteString("\n\n")
|
|
}
|
|
|
|
if len(c.Resources) > 0 {
|
|
buf.WriteString("Resources:\n\n")
|
|
buf.WriteString(resourcesStr(c.Resources))
|
|
buf.WriteString("\n\n")
|
|
}
|
|
|
|
if len(c.Outputs) > 0 {
|
|
buf.WriteString("Outputs:\n\n")
|
|
buf.WriteString(outputsStr(c.Outputs))
|
|
buf.WriteString("\n")
|
|
}
|
|
|
|
return strings.TrimSpace(buf.String())
|
|
}
|
|
|
|
func terraformStr(t *Terraform) string {
|
|
result := ""
|
|
|
|
if b := t.Backend; b != nil {
|
|
result += fmt.Sprintf("backend (%s)\n", b.Type)
|
|
|
|
keys := make([]string, 0, len(b.RawConfig.Raw))
|
|
for k, _ := range b.RawConfig.Raw {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
for _, k := range keys {
|
|
result += fmt.Sprintf(" %s\n", k)
|
|
}
|
|
}
|
|
|
|
return strings.TrimSpace(result)
|
|
}
|
|
|
|
func modulesStr(ms []*Module) string {
|
|
result := ""
|
|
order := make([]int, 0, len(ms))
|
|
ks := make([]string, 0, len(ms))
|
|
mapping := make(map[string]int)
|
|
for i, m := range ms {
|
|
k := m.Id()
|
|
ks = append(ks, k)
|
|
mapping[k] = i
|
|
}
|
|
sort.Strings(ks)
|
|
for _, k := range ks {
|
|
order = append(order, mapping[k])
|
|
}
|
|
|
|
for _, i := range order {
|
|
m := ms[i]
|
|
result += fmt.Sprintf("%s\n", m.Id())
|
|
|
|
ks := make([]string, 0, len(m.RawConfig.Raw))
|
|
for k, _ := range m.RawConfig.Raw {
|
|
ks = append(ks, k)
|
|
}
|
|
sort.Strings(ks)
|
|
|
|
result += fmt.Sprintf(" source = %s\n", m.Source)
|
|
|
|
for _, k := range ks {
|
|
result += fmt.Sprintf(" %s\n", k)
|
|
}
|
|
}
|
|
|
|
return strings.TrimSpace(result)
|
|
}
|
|
|
|
func outputsStr(os []*Output) string {
|
|
ns := make([]string, 0, len(os))
|
|
m := make(map[string]*Output)
|
|
for _, o := range os {
|
|
ns = append(ns, o.Name)
|
|
m[o.Name] = o
|
|
}
|
|
sort.Strings(ns)
|
|
|
|
result := ""
|
|
for _, n := range ns {
|
|
o := m[n]
|
|
|
|
result += fmt.Sprintf("%s\n", n)
|
|
|
|
if len(o.DependsOn) > 0 {
|
|
result += fmt.Sprintf(" dependsOn\n")
|
|
for _, d := range o.DependsOn {
|
|
result += fmt.Sprintf(" %s\n", d)
|
|
}
|
|
}
|
|
|
|
if len(o.RawConfig.Variables) > 0 {
|
|
result += fmt.Sprintf(" vars\n")
|
|
for _, rawV := range o.RawConfig.Variables {
|
|
kind := "unknown"
|
|
str := rawV.FullKey()
|
|
|
|
switch rawV.(type) {
|
|
case *ResourceVariable:
|
|
kind = "resource"
|
|
case *UserVariable:
|
|
kind = "user"
|
|
}
|
|
|
|
result += fmt.Sprintf(" %s: %s\n", kind, str)
|
|
}
|
|
}
|
|
|
|
if o.Description != "" {
|
|
result += fmt.Sprintf(" description\n %s\n", o.Description)
|
|
}
|
|
}
|
|
|
|
return strings.TrimSpace(result)
|
|
}
|
|
|
|
func localsStr(ls []*Local) string {
|
|
ns := make([]string, 0, len(ls))
|
|
m := make(map[string]*Local)
|
|
for _, l := range ls {
|
|
ns = append(ns, l.Name)
|
|
m[l.Name] = l
|
|
}
|
|
sort.Strings(ns)
|
|
|
|
result := ""
|
|
for _, n := range ns {
|
|
l := m[n]
|
|
|
|
result += fmt.Sprintf("%s\n", n)
|
|
|
|
if len(l.RawConfig.Variables) > 0 {
|
|
result += fmt.Sprintf(" vars\n")
|
|
for _, rawV := range l.RawConfig.Variables {
|
|
kind := "unknown"
|
|
str := rawV.FullKey()
|
|
|
|
switch rawV.(type) {
|
|
case *ResourceVariable:
|
|
kind = "resource"
|
|
case *UserVariable:
|
|
kind = "user"
|
|
}
|
|
|
|
result += fmt.Sprintf(" %s: %s\n", kind, str)
|
|
}
|
|
}
|
|
}
|
|
|
|
return strings.TrimSpace(result)
|
|
}
|
|
|
|
// This helper turns a provider configs field into a deterministic
|
|
// string value for comparison in tests.
|
|
func providerConfigsStr(pcs []*ProviderConfig) string {
|
|
result := ""
|
|
|
|
ns := make([]string, 0, len(pcs))
|
|
m := make(map[string]*ProviderConfig)
|
|
for _, n := range pcs {
|
|
ns = append(ns, n.Name)
|
|
m[n.Name] = n
|
|
}
|
|
sort.Strings(ns)
|
|
|
|
for _, n := range ns {
|
|
pc := m[n]
|
|
|
|
result += fmt.Sprintf("%s\n", n)
|
|
|
|
keys := make([]string, 0, len(pc.RawConfig.Raw))
|
|
for k, _ := range pc.RawConfig.Raw {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
for _, k := range keys {
|
|
result += fmt.Sprintf(" %s\n", k)
|
|
}
|
|
|
|
if len(pc.RawConfig.Variables) > 0 {
|
|
result += fmt.Sprintf(" vars\n")
|
|
for _, rawV := range pc.RawConfig.Variables {
|
|
kind := "unknown"
|
|
str := rawV.FullKey()
|
|
|
|
switch rawV.(type) {
|
|
case *ResourceVariable:
|
|
kind = "resource"
|
|
case *UserVariable:
|
|
kind = "user"
|
|
}
|
|
|
|
result += fmt.Sprintf(" %s: %s\n", kind, str)
|
|
}
|
|
}
|
|
}
|
|
|
|
return strings.TrimSpace(result)
|
|
}
|
|
|
|
// This helper turns a resources field into a deterministic
|
|
// string value for comparison in tests.
|
|
func resourcesStr(rs []*Resource) string {
|
|
result := ""
|
|
order := make([]int, 0, len(rs))
|
|
ks := make([]string, 0, len(rs))
|
|
mapping := make(map[string]int)
|
|
for i, r := range rs {
|
|
k := r.Id()
|
|
ks = append(ks, k)
|
|
mapping[k] = i
|
|
}
|
|
sort.Strings(ks)
|
|
for _, k := range ks {
|
|
order = append(order, mapping[k])
|
|
}
|
|
|
|
for _, i := range order {
|
|
r := rs[i]
|
|
result += fmt.Sprintf(
|
|
"%s (x%s)\n",
|
|
r.Id(),
|
|
r.RawCount.Value())
|
|
|
|
ks := make([]string, 0, len(r.RawConfig.Raw))
|
|
for k, _ := range r.RawConfig.Raw {
|
|
ks = append(ks, k)
|
|
}
|
|
sort.Strings(ks)
|
|
|
|
for _, k := range ks {
|
|
result += fmt.Sprintf(" %s\n", k)
|
|
}
|
|
|
|
if len(r.Provisioners) > 0 {
|
|
result += fmt.Sprintf(" provisioners\n")
|
|
for _, p := range r.Provisioners {
|
|
when := ""
|
|
if p.When != ProvisionerWhenCreate {
|
|
when = fmt.Sprintf(" (%s)", p.When.String())
|
|
}
|
|
|
|
result += fmt.Sprintf(" %s%s\n", p.Type, when)
|
|
|
|
if p.OnFailure != ProvisionerOnFailureFail {
|
|
result += fmt.Sprintf(" on_failure = %s\n", p.OnFailure.String())
|
|
}
|
|
|
|
ks := make([]string, 0, len(p.RawConfig.Raw))
|
|
for k, _ := range p.RawConfig.Raw {
|
|
ks = append(ks, k)
|
|
}
|
|
sort.Strings(ks)
|
|
|
|
for _, k := range ks {
|
|
result += fmt.Sprintf(" %s\n", k)
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(r.DependsOn) > 0 {
|
|
result += fmt.Sprintf(" dependsOn\n")
|
|
for _, d := range r.DependsOn {
|
|
result += fmt.Sprintf(" %s\n", d)
|
|
}
|
|
}
|
|
|
|
if len(r.RawConfig.Variables) > 0 {
|
|
result += fmt.Sprintf(" vars\n")
|
|
|
|
ks := make([]string, 0, len(r.RawConfig.Variables))
|
|
for k, _ := range r.RawConfig.Variables {
|
|
ks = append(ks, k)
|
|
}
|
|
sort.Strings(ks)
|
|
|
|
for _, k := range ks {
|
|
rawV := r.RawConfig.Variables[k]
|
|
kind := "unknown"
|
|
str := rawV.FullKey()
|
|
|
|
switch rawV.(type) {
|
|
case *ResourceVariable:
|
|
kind = "resource"
|
|
case *UserVariable:
|
|
kind = "user"
|
|
}
|
|
|
|
result += fmt.Sprintf(" %s: %s\n", kind, str)
|
|
}
|
|
}
|
|
}
|
|
|
|
return strings.TrimSpace(result)
|
|
}
|
|
|
|
// This helper turns a variables field into a deterministic
|
|
// string value for comparison in tests.
|
|
func variablesStr(vs []*Variable) string {
|
|
result := ""
|
|
ks := make([]string, 0, len(vs))
|
|
m := make(map[string]*Variable)
|
|
for _, v := range vs {
|
|
ks = append(ks, v.Name)
|
|
m[v.Name] = v
|
|
}
|
|
sort.Strings(ks)
|
|
|
|
for _, k := range ks {
|
|
v := m[k]
|
|
|
|
required := ""
|
|
if v.Required() {
|
|
required = " (required)"
|
|
}
|
|
|
|
declaredType := ""
|
|
if v.DeclaredType != "" {
|
|
declaredType = fmt.Sprintf(" (%s)", v.DeclaredType)
|
|
}
|
|
|
|
if v.Default == nil || v.Default == "" {
|
|
v.Default = "<>"
|
|
}
|
|
if v.Description == "" {
|
|
v.Description = "<>"
|
|
}
|
|
|
|
result += fmt.Sprintf(
|
|
"%s%s%s\n %v\n %s\n",
|
|
k,
|
|
required,
|
|
declaredType,
|
|
v.Default,
|
|
v.Description)
|
|
}
|
|
|
|
return strings.TrimSpace(result)
|
|
}
|