github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/config/config_string.go (about)

     1  package config
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"sort"
     7  	"strings"
     8  )
     9  
    10  // TestString is a Stringer-like function that outputs a string that can
    11  // be used to easily compare multiple Config structures in unit tests.
    12  //
    13  // This function has no practical use outside of unit tests and debugging.
    14  func (c *Config) TestString() string {
    15  	if c == nil {
    16  		return "<nil config>"
    17  	}
    18  
    19  	var buf bytes.Buffer
    20  	if len(c.Modules) > 0 {
    21  		buf.WriteString("Modules:\n\n")
    22  		buf.WriteString(modulesStr(c.Modules))
    23  		buf.WriteString("\n\n")
    24  	}
    25  
    26  	if len(c.Variables) > 0 {
    27  		buf.WriteString("Variables:\n\n")
    28  		buf.WriteString(variablesStr(c.Variables))
    29  		buf.WriteString("\n\n")
    30  	}
    31  
    32  	if len(c.ProviderConfigs) > 0 {
    33  		buf.WriteString("Provider Configs:\n\n")
    34  		buf.WriteString(providerConfigsStr(c.ProviderConfigs))
    35  		buf.WriteString("\n\n")
    36  	}
    37  
    38  	if len(c.Resources) > 0 {
    39  		buf.WriteString("Resources:\n\n")
    40  		buf.WriteString(resourcesStr(c.Resources))
    41  		buf.WriteString("\n\n")
    42  	}
    43  
    44  	if len(c.Outputs) > 0 {
    45  		buf.WriteString("Outputs:\n\n")
    46  		buf.WriteString(outputsStr(c.Outputs))
    47  		buf.WriteString("\n")
    48  	}
    49  
    50  	return strings.TrimSpace(buf.String())
    51  }
    52  
    53  func terraformStr(t *Terraform) string {
    54  	result := ""
    55  
    56  	if b := t.Backend; b != nil {
    57  		result += fmt.Sprintf("backend (%s)\n", b.Type)
    58  
    59  		keys := make([]string, 0, len(b.RawConfig.Raw))
    60  		for k, _ := range b.RawConfig.Raw {
    61  			keys = append(keys, k)
    62  		}
    63  		sort.Strings(keys)
    64  
    65  		for _, k := range keys {
    66  			result += fmt.Sprintf("  %s\n", k)
    67  		}
    68  	}
    69  
    70  	return strings.TrimSpace(result)
    71  }
    72  
    73  func modulesStr(ms []*Module) string {
    74  	result := ""
    75  	order := make([]int, 0, len(ms))
    76  	ks := make([]string, 0, len(ms))
    77  	mapping := make(map[string]int)
    78  	for i, m := range ms {
    79  		k := m.Id()
    80  		ks = append(ks, k)
    81  		mapping[k] = i
    82  	}
    83  	sort.Strings(ks)
    84  	for _, k := range ks {
    85  		order = append(order, mapping[k])
    86  	}
    87  
    88  	for _, i := range order {
    89  		m := ms[i]
    90  		result += fmt.Sprintf("%s\n", m.Id())
    91  
    92  		ks := make([]string, 0, len(m.RawConfig.Raw))
    93  		for k, _ := range m.RawConfig.Raw {
    94  			ks = append(ks, k)
    95  		}
    96  		sort.Strings(ks)
    97  
    98  		result += fmt.Sprintf("  source = %s\n", m.Source)
    99  
   100  		for _, k := range ks {
   101  			result += fmt.Sprintf("  %s\n", k)
   102  		}
   103  	}
   104  
   105  	return strings.TrimSpace(result)
   106  }
   107  
   108  func outputsStr(os []*Output) string {
   109  	ns := make([]string, 0, len(os))
   110  	m := make(map[string]*Output)
   111  	for _, o := range os {
   112  		ns = append(ns, o.Name)
   113  		m[o.Name] = o
   114  	}
   115  	sort.Strings(ns)
   116  
   117  	result := ""
   118  	for _, n := range ns {
   119  		o := m[n]
   120  
   121  		result += fmt.Sprintf("%s\n", n)
   122  
   123  		if len(o.DependsOn) > 0 {
   124  			result += fmt.Sprintf("  dependsOn\n")
   125  			for _, d := range o.DependsOn {
   126  				result += fmt.Sprintf("    %s\n", d)
   127  			}
   128  		}
   129  
   130  		if len(o.RawConfig.Variables) > 0 {
   131  			result += fmt.Sprintf("  vars\n")
   132  			for _, rawV := range o.RawConfig.Variables {
   133  				kind := "unknown"
   134  				str := rawV.FullKey()
   135  
   136  				switch rawV.(type) {
   137  				case *ResourceVariable:
   138  					kind = "resource"
   139  				case *UserVariable:
   140  					kind = "user"
   141  				}
   142  
   143  				result += fmt.Sprintf("    %s: %s\n", kind, str)
   144  			}
   145  		}
   146  	}
   147  
   148  	return strings.TrimSpace(result)
   149  }
   150  
   151  // This helper turns a provider configs field into a deterministic
   152  // string value for comparison in tests.
   153  func providerConfigsStr(pcs []*ProviderConfig) string {
   154  	result := ""
   155  
   156  	ns := make([]string, 0, len(pcs))
   157  	m := make(map[string]*ProviderConfig)
   158  	for _, n := range pcs {
   159  		ns = append(ns, n.Name)
   160  		m[n.Name] = n
   161  	}
   162  	sort.Strings(ns)
   163  
   164  	for _, n := range ns {
   165  		pc := m[n]
   166  
   167  		result += fmt.Sprintf("%s\n", n)
   168  
   169  		keys := make([]string, 0, len(pc.RawConfig.Raw))
   170  		for k, _ := range pc.RawConfig.Raw {
   171  			keys = append(keys, k)
   172  		}
   173  		sort.Strings(keys)
   174  
   175  		for _, k := range keys {
   176  			result += fmt.Sprintf("  %s\n", k)
   177  		}
   178  
   179  		if len(pc.RawConfig.Variables) > 0 {
   180  			result += fmt.Sprintf("  vars\n")
   181  			for _, rawV := range pc.RawConfig.Variables {
   182  				kind := "unknown"
   183  				str := rawV.FullKey()
   184  
   185  				switch rawV.(type) {
   186  				case *ResourceVariable:
   187  					kind = "resource"
   188  				case *UserVariable:
   189  					kind = "user"
   190  				}
   191  
   192  				result += fmt.Sprintf("    %s: %s\n", kind, str)
   193  			}
   194  		}
   195  	}
   196  
   197  	return strings.TrimSpace(result)
   198  }
   199  
   200  // This helper turns a resources field into a deterministic
   201  // string value for comparison in tests.
   202  func resourcesStr(rs []*Resource) string {
   203  	result := ""
   204  	order := make([]int, 0, len(rs))
   205  	ks := make([]string, 0, len(rs))
   206  	mapping := make(map[string]int)
   207  	for i, r := range rs {
   208  		k := r.Id()
   209  		ks = append(ks, k)
   210  		mapping[k] = i
   211  	}
   212  	sort.Strings(ks)
   213  	for _, k := range ks {
   214  		order = append(order, mapping[k])
   215  	}
   216  
   217  	for _, i := range order {
   218  		r := rs[i]
   219  		result += fmt.Sprintf(
   220  			"%s (x%s)\n",
   221  			r.Id(),
   222  			r.RawCount.Value())
   223  
   224  		ks := make([]string, 0, len(r.RawConfig.Raw))
   225  		for k, _ := range r.RawConfig.Raw {
   226  			ks = append(ks, k)
   227  		}
   228  		sort.Strings(ks)
   229  
   230  		for _, k := range ks {
   231  			result += fmt.Sprintf("  %s\n", k)
   232  		}
   233  
   234  		if len(r.Provisioners) > 0 {
   235  			result += fmt.Sprintf("  provisioners\n")
   236  			for _, p := range r.Provisioners {
   237  				when := ""
   238  				if p.When != ProvisionerWhenCreate {
   239  					when = fmt.Sprintf(" (%s)", p.When.String())
   240  				}
   241  
   242  				result += fmt.Sprintf("    %s%s\n", p.Type, when)
   243  
   244  				if p.OnFailure != ProvisionerOnFailureFail {
   245  					result += fmt.Sprintf("      on_failure = %s\n", p.OnFailure.String())
   246  				}
   247  
   248  				ks := make([]string, 0, len(p.RawConfig.Raw))
   249  				for k, _ := range p.RawConfig.Raw {
   250  					ks = append(ks, k)
   251  				}
   252  				sort.Strings(ks)
   253  
   254  				for _, k := range ks {
   255  					result += fmt.Sprintf("      %s\n", k)
   256  				}
   257  			}
   258  		}
   259  
   260  		if len(r.DependsOn) > 0 {
   261  			result += fmt.Sprintf("  dependsOn\n")
   262  			for _, d := range r.DependsOn {
   263  				result += fmt.Sprintf("    %s\n", d)
   264  			}
   265  		}
   266  
   267  		if len(r.RawConfig.Variables) > 0 {
   268  			result += fmt.Sprintf("  vars\n")
   269  
   270  			ks := make([]string, 0, len(r.RawConfig.Variables))
   271  			for k, _ := range r.RawConfig.Variables {
   272  				ks = append(ks, k)
   273  			}
   274  			sort.Strings(ks)
   275  
   276  			for _, k := range ks {
   277  				rawV := r.RawConfig.Variables[k]
   278  				kind := "unknown"
   279  				str := rawV.FullKey()
   280  
   281  				switch rawV.(type) {
   282  				case *ResourceVariable:
   283  					kind = "resource"
   284  				case *UserVariable:
   285  					kind = "user"
   286  				}
   287  
   288  				result += fmt.Sprintf("    %s: %s\n", kind, str)
   289  			}
   290  		}
   291  	}
   292  
   293  	return strings.TrimSpace(result)
   294  }
   295  
   296  // This helper turns a variables field into a deterministic
   297  // string value for comparison in tests.
   298  func variablesStr(vs []*Variable) string {
   299  	result := ""
   300  	ks := make([]string, 0, len(vs))
   301  	m := make(map[string]*Variable)
   302  	for _, v := range vs {
   303  		ks = append(ks, v.Name)
   304  		m[v.Name] = v
   305  	}
   306  	sort.Strings(ks)
   307  
   308  	for _, k := range ks {
   309  		v := m[k]
   310  
   311  		required := ""
   312  		if v.Required() {
   313  			required = " (required)"
   314  		}
   315  
   316  		declaredType := ""
   317  		if v.DeclaredType != "" {
   318  			declaredType = fmt.Sprintf(" (%s)", v.DeclaredType)
   319  		}
   320  
   321  		if v.Default == nil || v.Default == "" {
   322  			v.Default = "<>"
   323  		}
   324  		if v.Description == "" {
   325  			v.Description = "<>"
   326  		}
   327  
   328  		result += fmt.Sprintf(
   329  			"%s%s%s\n  %v\n  %s\n",
   330  			k,
   331  			required,
   332  			declaredType,
   333  			v.Default,
   334  			v.Description)
   335  	}
   336  
   337  	return strings.TrimSpace(result)
   338  }