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 }