github.com/mapuri/terraform@v0.7.6-0.20161012203214-7e0408293f97/config/loader_test.go (about) 1 package config 2 3 import ( 4 "io/ioutil" 5 "path/filepath" 6 "reflect" 7 "strings" 8 "testing" 9 ) 10 11 func TestIsEmptyDir(t *testing.T) { 12 val, err := IsEmptyDir(fixtureDir) 13 if err != nil { 14 t.Fatalf("err: %s", err) 15 } 16 if val { 17 t.Fatal("should not be empty") 18 } 19 } 20 21 func TestIsEmptyDir_noExist(t *testing.T) { 22 val, err := IsEmptyDir(filepath.Join(fixtureDir, "nopenopenope")) 23 if err != nil { 24 t.Fatalf("err: %s", err) 25 } 26 if !val { 27 t.Fatal("should be empty") 28 } 29 } 30 31 func TestIsEmptyDir_noConfigs(t *testing.T) { 32 val, err := IsEmptyDir(filepath.Join(fixtureDir, "dir-empty")) 33 if err != nil { 34 t.Fatalf("err: %s", err) 35 } 36 if !val { 37 t.Fatal("should be empty") 38 } 39 } 40 41 func TestLoadFile_badType(t *testing.T) { 42 _, err := LoadFile(filepath.Join(fixtureDir, "bad_type.tf.nope")) 43 if err == nil { 44 t.Fatal("should have error") 45 } 46 } 47 48 func TestLoadFile_lifecycleKeyCheck(t *testing.T) { 49 _, err := LoadFile(filepath.Join(fixtureDir, "lifecycle_cbd_typo.tf")) 50 if err == nil { 51 t.Fatal("should have error") 52 } 53 54 t.Logf("err: %s", err) 55 } 56 57 func TestLoadFile_resourceArityMistake(t *testing.T) { 58 _, err := LoadFile(filepath.Join(fixtureDir, "resource-arity-mistake.tf")) 59 if err == nil { 60 t.Fatal("should have error") 61 } 62 expected := "Error loading test-fixtures/resource-arity-mistake.tf: position 2:10: resource must be followed by exactly two strings, a type and a name" 63 if err.Error() != expected { 64 t.Fatalf("expected:\n%s\ngot:\n%s", expected, err) 65 } 66 } 67 68 func TestLoadFile_dataSourceArityMistake(t *testing.T) { 69 _, err := LoadFile(filepath.Join(fixtureDir, "data-source-arity-mistake.tf")) 70 if err == nil { 71 t.Fatal("should have error") 72 } 73 expected := "Error loading test-fixtures/data-source-arity-mistake.tf: position 2:6: 'data' must be followed by exactly two strings: a type and a name" 74 if err.Error() != expected { 75 t.Fatalf("expected:\n%s\ngot:\n%s", expected, err) 76 } 77 } 78 79 func TestLoadFileWindowsLineEndings(t *testing.T) { 80 testFile := filepath.Join(fixtureDir, "windows-line-endings.tf") 81 82 contents, err := ioutil.ReadFile(testFile) 83 if err != nil { 84 t.Fatalf("err: %s", err) 85 } 86 if !strings.Contains(string(contents), "\r\n") { 87 t.Fatalf("Windows line endings test file %s contains no windows line endings - this may be an autocrlf related issue.", testFile) 88 } 89 90 c, err := LoadFile(testFile) 91 if err != nil { 92 t.Fatalf("err: %s", err) 93 } 94 95 if c == nil { 96 t.Fatal("config should not be nil") 97 } 98 99 if c.Dir != "" { 100 t.Fatalf("bad: %#v", c.Dir) 101 } 102 103 actual := resourcesStr(c.Resources) 104 if actual != strings.TrimSpace(windowsHeredocResourcesStr) { 105 t.Fatalf("bad:\n%s", actual) 106 } 107 } 108 109 func TestLoadFileHeredoc(t *testing.T) { 110 c, err := LoadFile(filepath.Join(fixtureDir, "heredoc.tf")) 111 if err != nil { 112 t.Fatalf("err: %s", err) 113 } 114 115 if c == nil { 116 t.Fatal("config should not be nil") 117 } 118 119 if c.Dir != "" { 120 t.Fatalf("bad: %#v", c.Dir) 121 } 122 123 actual := providerConfigsStr(c.ProviderConfigs) 124 if actual != strings.TrimSpace(heredocProvidersStr) { 125 t.Fatalf("bad:\n%s", actual) 126 } 127 128 actual = resourcesStr(c.Resources) 129 if actual != strings.TrimSpace(heredocResourcesStr) { 130 t.Fatalf("bad:\n%s", actual) 131 } 132 } 133 134 func TestLoadFileEscapedQuotes(t *testing.T) { 135 _, err := LoadFile(filepath.Join(fixtureDir, "escapedquotes.tf")) 136 if err == nil { 137 t.Fatalf("expected syntax error as escaped quotes are no longer supported") 138 } 139 140 if !strings.Contains(err.Error(), "syntax error") { 141 t.Fatalf("expected \"syntax error\", got: %s", err) 142 } 143 } 144 145 func TestLoadFileBasic(t *testing.T) { 146 c, err := LoadFile(filepath.Join(fixtureDir, "basic.tf")) 147 if err != nil { 148 t.Fatalf("err: %s", err) 149 } 150 151 if c == nil { 152 t.Fatal("config should not be nil") 153 } 154 155 if c.Dir != "" { 156 t.Fatalf("bad: %#v", c.Dir) 157 } 158 159 expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"} 160 if !reflect.DeepEqual(c.Atlas, expectedAtlas) { 161 t.Fatalf("bad: %#v", c.Atlas) 162 } 163 164 actual := variablesStr(c.Variables) 165 if actual != strings.TrimSpace(basicVariablesStr) { 166 t.Fatalf("bad:\n%s", actual) 167 } 168 169 actual = providerConfigsStr(c.ProviderConfigs) 170 if actual != strings.TrimSpace(basicProvidersStr) { 171 t.Fatalf("bad:\n%s", actual) 172 } 173 174 actual = resourcesStr(c.Resources) 175 if actual != strings.TrimSpace(basicResourcesStr) { 176 t.Fatalf("bad:\n%s", actual) 177 } 178 179 actual = outputsStr(c.Outputs) 180 if actual != strings.TrimSpace(basicOutputsStr) { 181 t.Fatalf("bad:\n%s", actual) 182 } 183 } 184 185 func TestLoadFileBasic_empty(t *testing.T) { 186 c, err := LoadFile(filepath.Join(fixtureDir, "empty.tf")) 187 if err != nil { 188 t.Fatalf("err: %s", err) 189 } 190 191 if c == nil { 192 t.Fatal("config should not be nil") 193 } 194 } 195 196 func TestLoadFileBasic_import(t *testing.T) { 197 // Skip because we disabled importing 198 t.Skip() 199 200 c, err := LoadFile(filepath.Join(fixtureDir, "import.tf")) 201 if err != nil { 202 t.Fatalf("err: %s", err) 203 } 204 205 if c == nil { 206 t.Fatal("config should not be nil") 207 } 208 209 actual := variablesStr(c.Variables) 210 if actual != strings.TrimSpace(importVariablesStr) { 211 t.Fatalf("bad:\n%s", actual) 212 } 213 214 actual = providerConfigsStr(c.ProviderConfigs) 215 if actual != strings.TrimSpace(importProvidersStr) { 216 t.Fatalf("bad:\n%s", actual) 217 } 218 219 actual = resourcesStr(c.Resources) 220 if actual != strings.TrimSpace(importResourcesStr) { 221 t.Fatalf("bad:\n%s", actual) 222 } 223 } 224 225 func TestLoadFileBasic_json(t *testing.T) { 226 c, err := LoadFile(filepath.Join(fixtureDir, "basic.tf.json")) 227 if err != nil { 228 t.Fatalf("err: %s", err) 229 } 230 231 if c == nil { 232 t.Fatal("config should not be nil") 233 } 234 235 if c.Dir != "" { 236 t.Fatalf("bad: %#v", c.Dir) 237 } 238 239 expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"} 240 if !reflect.DeepEqual(c.Atlas, expectedAtlas) { 241 t.Fatalf("bad: %#v", c.Atlas) 242 } 243 244 actual := variablesStr(c.Variables) 245 if actual != strings.TrimSpace(basicVariablesStr) { 246 t.Fatalf("bad:\n%s", actual) 247 } 248 249 actual = providerConfigsStr(c.ProviderConfigs) 250 if actual != strings.TrimSpace(basicProvidersStr) { 251 t.Fatalf("bad:\n%s", actual) 252 } 253 254 actual = resourcesStr(c.Resources) 255 if actual != strings.TrimSpace(basicResourcesStr) { 256 t.Fatalf("bad:\n%s", actual) 257 } 258 259 actual = outputsStr(c.Outputs) 260 if actual != strings.TrimSpace(basicOutputsStr) { 261 t.Fatalf("bad:\n%s", actual) 262 } 263 } 264 265 func TestLoadFileBasic_modules(t *testing.T) { 266 c, err := LoadFile(filepath.Join(fixtureDir, "modules.tf")) 267 if err != nil { 268 t.Fatalf("err: %s", err) 269 } 270 271 if c == nil { 272 t.Fatal("config should not be nil") 273 } 274 275 if c.Dir != "" { 276 t.Fatalf("bad: %#v", c.Dir) 277 } 278 279 actual := modulesStr(c.Modules) 280 if actual != strings.TrimSpace(modulesModulesStr) { 281 t.Fatalf("bad:\n%s", actual) 282 } 283 } 284 285 func TestLoadJSONBasic(t *testing.T) { 286 raw, err := ioutil.ReadFile(filepath.Join(fixtureDir, "basic.tf.json")) 287 if err != nil { 288 t.Fatalf("err: %s", err) 289 } 290 291 c, err := LoadJSON(raw) 292 if err != nil { 293 t.Fatalf("err: %s", err) 294 } 295 296 if c == nil { 297 t.Fatal("config should not be nil") 298 } 299 300 if c.Dir != "" { 301 t.Fatalf("bad: %#v", c.Dir) 302 } 303 304 expectedAtlas := &AtlasConfig{Name: "mitchellh/foo"} 305 if !reflect.DeepEqual(c.Atlas, expectedAtlas) { 306 t.Fatalf("bad: %#v", c.Atlas) 307 } 308 309 actual := variablesStr(c.Variables) 310 if actual != strings.TrimSpace(basicVariablesStr) { 311 t.Fatalf("bad:\n%s", actual) 312 } 313 314 actual = providerConfigsStr(c.ProviderConfigs) 315 if actual != strings.TrimSpace(basicProvidersStr) { 316 t.Fatalf("bad:\n%s", actual) 317 } 318 319 actual = resourcesStr(c.Resources) 320 if actual != strings.TrimSpace(basicResourcesStr) { 321 t.Fatalf("bad:\n%s", actual) 322 } 323 324 actual = outputsStr(c.Outputs) 325 if actual != strings.TrimSpace(basicOutputsStr) { 326 t.Fatalf("bad:\n%s", actual) 327 } 328 } 329 330 func TestLoadJSONAmbiguous(t *testing.T) { 331 js := ` 332 { 333 "variable": { 334 "first": { 335 "default": { 336 "key": "val" 337 } 338 }, 339 "second": { 340 "description": "Described", 341 "default": { 342 "key": "val" 343 } 344 } 345 } 346 } 347 ` 348 349 c, err := LoadJSON([]byte(js)) 350 if err != nil { 351 t.Fatalf("err: %s", err) 352 } 353 354 if len(c.Variables) != 2 { 355 t.Fatal("config should have 2 variables, found", len(c.Variables)) 356 } 357 358 first := &Variable{ 359 Name: "first", 360 Default: map[string]interface{}{"key": "val"}, 361 } 362 second := &Variable{ 363 Name: "second", 364 Description: "Described", 365 Default: map[string]interface{}{"key": "val"}, 366 } 367 368 if !reflect.DeepEqual(first, c.Variables[0]) { 369 t.Fatalf("\nexpected: %#v\ngot: %#v", first, c.Variables[0]) 370 } 371 372 if !reflect.DeepEqual(second, c.Variables[1]) { 373 t.Fatalf("\nexpected: %#v\ngot: %#v", second, c.Variables[1]) 374 } 375 } 376 377 func TestLoadFileBasic_jsonNoName(t *testing.T) { 378 c, err := LoadFile(filepath.Join(fixtureDir, "resource-no-name.tf.json")) 379 if err != nil { 380 t.Fatalf("err: %s", err) 381 } 382 383 if c == nil { 384 t.Fatal("config should not be nil") 385 } 386 387 actual := resourcesStr(c.Resources) 388 if actual != strings.TrimSpace(basicJsonNoNameResourcesStr) { 389 t.Fatalf("bad:\n%s", actual) 390 } 391 } 392 393 func TestLoadFile_variables(t *testing.T) { 394 c, err := LoadFile(filepath.Join(fixtureDir, "variables.tf")) 395 if err != nil { 396 t.Fatalf("err: %s", err) 397 } 398 if c == nil { 399 t.Fatal("config should not be nil") 400 } 401 402 if c.Dir != "" { 403 t.Fatalf("bad: %#v", c.Dir) 404 } 405 406 actual := variablesStr(c.Variables) 407 if actual != strings.TrimSpace(variablesVariablesStr) { 408 t.Fatalf("bad:\n%s", actual) 409 } 410 } 411 412 func TestLoadDir_basic(t *testing.T) { 413 dir := filepath.Join(fixtureDir, "dir-basic") 414 c, err := LoadDir(dir) 415 if err != nil { 416 t.Fatalf("err: %s", err) 417 } 418 419 if c == nil { 420 t.Fatal("config should not be nil") 421 } 422 423 dirAbs, err := filepath.Abs(dir) 424 if err != nil { 425 t.Fatalf("err: %s", err) 426 } 427 if c.Dir != dirAbs { 428 t.Fatalf("bad: %#v", c.Dir) 429 } 430 431 actual := variablesStr(c.Variables) 432 if actual != strings.TrimSpace(dirBasicVariablesStr) { 433 t.Fatalf("bad:\n%s", actual) 434 } 435 436 actual = providerConfigsStr(c.ProviderConfigs) 437 if actual != strings.TrimSpace(dirBasicProvidersStr) { 438 t.Fatalf("bad:\n%s", actual) 439 } 440 441 actual = resourcesStr(c.Resources) 442 if actual != strings.TrimSpace(dirBasicResourcesStr) { 443 t.Fatalf("bad:\n%s", actual) 444 } 445 446 actual = outputsStr(c.Outputs) 447 if actual != strings.TrimSpace(dirBasicOutputsStr) { 448 t.Fatalf("bad:\n%s", actual) 449 } 450 } 451 452 func TestLoadDir_file(t *testing.T) { 453 _, err := LoadDir(filepath.Join(fixtureDir, "variables.tf")) 454 if err == nil { 455 t.Fatal("should error") 456 } 457 } 458 459 func TestLoadDir_noConfigs(t *testing.T) { 460 _, err := LoadDir(filepath.Join(fixtureDir, "dir-empty")) 461 if err == nil { 462 t.Fatal("should error") 463 } 464 } 465 466 func TestLoadDir_noMerge(t *testing.T) { 467 c, err := LoadDir(filepath.Join(fixtureDir, "dir-merge")) 468 if err != nil { 469 t.Fatalf("err: %s", err) 470 } 471 472 if c == nil { 473 t.Fatal("config should not be nil") 474 } 475 476 if err := c.Validate(); err == nil { 477 t.Fatal("should not be valid") 478 } 479 } 480 481 func TestLoadDir_override(t *testing.T) { 482 c, err := LoadDir(filepath.Join(fixtureDir, "dir-override")) 483 if err != nil { 484 t.Fatalf("err: %s", err) 485 } 486 487 if c == nil { 488 t.Fatal("config should not be nil") 489 } 490 491 actual := variablesStr(c.Variables) 492 if actual != strings.TrimSpace(dirOverrideVariablesStr) { 493 t.Fatalf("bad:\n%s", actual) 494 } 495 496 actual = providerConfigsStr(c.ProviderConfigs) 497 if actual != strings.TrimSpace(dirOverrideProvidersStr) { 498 t.Fatalf("bad:\n%s", actual) 499 } 500 501 actual = resourcesStr(c.Resources) 502 if actual != strings.TrimSpace(dirOverrideResourcesStr) { 503 t.Fatalf("bad:\n%s", actual) 504 } 505 506 actual = outputsStr(c.Outputs) 507 if actual != strings.TrimSpace(dirOverrideOutputsStr) { 508 t.Fatalf("bad:\n%s", actual) 509 } 510 } 511 512 func TestLoadDir_overrideVar(t *testing.T) { 513 c, err := LoadDir(filepath.Join(fixtureDir, "dir-override-var")) 514 if err != nil { 515 t.Fatalf("err: %s", err) 516 } 517 518 if c == nil { 519 t.Fatal("config should not be nil") 520 } 521 522 actual := variablesStr(c.Variables) 523 if actual != strings.TrimSpace(dirOverrideVarsVariablesStr) { 524 t.Fatalf("bad:\n%s", actual) 525 } 526 } 527 528 func TestLoadFile_mismatchedVariableTypes(t *testing.T) { 529 _, err := LoadFile(filepath.Join(fixtureDir, "variable-mismatched-type.tf")) 530 if err == nil { 531 t.Fatalf("bad: expected error") 532 } 533 534 errorStr := err.Error() 535 if !strings.Contains(errorStr, "'not_a_map' has a default value which is not of type 'string'") { 536 t.Fatalf("bad: expected error has wrong text: %s", errorStr) 537 } 538 } 539 540 func TestLoadFile_badVariableTypes(t *testing.T) { 541 _, err := LoadFile(filepath.Join(fixtureDir, "bad-variable-type.tf")) 542 if err == nil { 543 t.Fatalf("bad: expected error") 544 } 545 546 errorStr := err.Error() 547 if !strings.Contains(errorStr, "'bad_type' must be of type string") { 548 t.Fatalf("bad: expected error has wrong text: %s", errorStr) 549 } 550 } 551 552 func TestLoadFile_provisioners(t *testing.T) { 553 c, err := LoadFile(filepath.Join(fixtureDir, "provisioners.tf")) 554 if err != nil { 555 t.Fatalf("err: %s", err) 556 } 557 558 if c == nil { 559 t.Fatal("config should not be nil") 560 } 561 562 actual := resourcesStr(c.Resources) 563 if actual != strings.TrimSpace(provisionerResourcesStr) { 564 t.Fatalf("bad:\n%s", actual) 565 } 566 } 567 568 func TestLoadFile_connections(t *testing.T) { 569 c, err := LoadFile(filepath.Join(fixtureDir, "connection.tf")) 570 if err != nil { 571 t.Fatalf("err: %s", err) 572 } 573 574 if c == nil { 575 t.Fatal("config should not be nil") 576 } 577 578 actual := resourcesStr(c.Resources) 579 if actual != strings.TrimSpace(connectionResourcesStr) { 580 t.Fatalf("bad:\n%s", actual) 581 } 582 583 // Check for the connection info 584 r := c.Resources[0] 585 if r.Name != "web" && r.Type != "aws_instance" { 586 t.Fatalf("Bad: %#v", r) 587 } 588 589 p1 := r.Provisioners[0] 590 if p1.ConnInfo == nil || len(p1.ConnInfo.Raw) != 2 { 591 t.Fatalf("Bad: %#v", p1.ConnInfo) 592 } 593 if p1.ConnInfo.Raw["user"] != "nobody" { 594 t.Fatalf("Bad: %#v", p1.ConnInfo) 595 } 596 597 p2 := r.Provisioners[1] 598 if p2.ConnInfo == nil || len(p2.ConnInfo.Raw) != 2 { 599 t.Fatalf("Bad: %#v", p2.ConnInfo) 600 } 601 if p2.ConnInfo.Raw["user"] != "root" { 602 t.Fatalf("Bad: %#v", p2.ConnInfo) 603 } 604 } 605 606 func TestLoadFile_createBeforeDestroy(t *testing.T) { 607 c, err := LoadFile(filepath.Join(fixtureDir, "create-before-destroy.tf")) 608 if err != nil { 609 t.Fatalf("err: %s", err) 610 } 611 612 if c == nil { 613 t.Fatal("config should not be nil") 614 } 615 616 actual := resourcesStr(c.Resources) 617 if actual != strings.TrimSpace(createBeforeDestroyResourcesStr) { 618 t.Fatalf("bad:\n%s", actual) 619 } 620 621 // Check for the flag value 622 r := c.Resources[0] 623 if r.Name != "web" && r.Type != "aws_instance" { 624 t.Fatalf("Bad: %#v", r) 625 } 626 627 // Should enable create before destroy 628 if !r.Lifecycle.CreateBeforeDestroy { 629 t.Fatalf("Bad: %#v", r) 630 } 631 632 r = c.Resources[1] 633 if r.Name != "bar" && r.Type != "aws_instance" { 634 t.Fatalf("Bad: %#v", r) 635 } 636 637 // Should not enable create before destroy 638 if r.Lifecycle.CreateBeforeDestroy { 639 t.Fatalf("Bad: %#v", r) 640 } 641 } 642 643 func TestLoadFile_ignoreChanges(t *testing.T) { 644 c, err := LoadFile(filepath.Join(fixtureDir, "ignore-changes.tf")) 645 if err != nil { 646 t.Fatalf("err: %s", err) 647 } 648 649 if c == nil { 650 t.Fatal("config should not be nil") 651 } 652 653 actual := resourcesStr(c.Resources) 654 print(actual) 655 if actual != strings.TrimSpace(ignoreChangesResourcesStr) { 656 t.Fatalf("bad:\n%s", actual) 657 } 658 659 // Check for the flag value 660 r := c.Resources[0] 661 if r.Name != "web" && r.Type != "aws_instance" { 662 t.Fatalf("Bad: %#v", r) 663 } 664 665 // Should populate ignore changes 666 if len(r.Lifecycle.IgnoreChanges) == 0 { 667 t.Fatalf("Bad: %#v", r) 668 } 669 670 r = c.Resources[1] 671 if r.Name != "bar" && r.Type != "aws_instance" { 672 t.Fatalf("Bad: %#v", r) 673 } 674 675 // Should not populate ignore changes 676 if len(r.Lifecycle.IgnoreChanges) > 0 { 677 t.Fatalf("Bad: %#v", r) 678 } 679 680 r = c.Resources[2] 681 if r.Name != "baz" && r.Type != "aws_instance" { 682 t.Fatalf("Bad: %#v", r) 683 } 684 685 // Should not populate ignore changes 686 if len(r.Lifecycle.IgnoreChanges) > 0 { 687 t.Fatalf("Bad: %#v", r) 688 } 689 } 690 691 func TestLoad_preventDestroyString(t *testing.T) { 692 c, err := LoadFile(filepath.Join(fixtureDir, "prevent-destroy-string.tf")) 693 if err != nil { 694 t.Fatalf("err: %s", err) 695 } 696 697 if c == nil { 698 t.Fatal("config should not be nil") 699 } 700 701 actual := resourcesStr(c.Resources) 702 if actual != strings.TrimSpace(createBeforeDestroyResourcesStr) { 703 t.Fatalf("bad:\n%s", actual) 704 } 705 706 // Check for the flag value 707 r := c.Resources[0] 708 if r.Name != "web" && r.Type != "aws_instance" { 709 t.Fatalf("Bad: %#v", r) 710 } 711 712 // Should enable create before destroy 713 if !r.Lifecycle.PreventDestroy { 714 t.Fatalf("Bad: %#v", r) 715 } 716 717 r = c.Resources[1] 718 if r.Name != "bar" && r.Type != "aws_instance" { 719 t.Fatalf("Bad: %#v", r) 720 } 721 722 // Should not enable create before destroy 723 if r.Lifecycle.PreventDestroy { 724 t.Fatalf("Bad: %#v", r) 725 } 726 } 727 728 func TestLoad_temporary_files(t *testing.T) { 729 _, err := LoadDir(filepath.Join(fixtureDir, "dir-temporary-files")) 730 if err == nil { 731 t.Fatalf("Expected to see an error stating no config files found") 732 } 733 } 734 735 func TestLoad_hclAttributes(t *testing.T) { 736 c, err := LoadFile(filepath.Join(fixtureDir, "attributes.tf")) 737 if err != nil { 738 t.Fatalf("Bad: %s", err) 739 } 740 741 if c == nil { 742 t.Fatal("config should not be nil") 743 } 744 745 actual := resourcesStr(c.Resources) 746 print(actual) 747 if actual != strings.TrimSpace(jsonAttributeStr) { 748 t.Fatalf("bad:\n%s", actual) 749 } 750 751 r := c.Resources[0] 752 if r.Name != "test" && r.Type != "cloudstack_firewall" { 753 t.Fatalf("Bad: %#v", r) 754 } 755 756 raw := r.RawConfig 757 if raw.Raw["ipaddress"] != "192.168.0.1" { 758 t.Fatalf("Bad: %s", raw.Raw["ipAddress"]) 759 } 760 761 rule := raw.Raw["rule"].([]map[string]interface{})[0] 762 if rule["protocol"] != "tcp" { 763 t.Fatalf("Bad: %s", rule["protocol"]) 764 } 765 766 if rule["source_cidr"] != "10.0.0.0/8" { 767 t.Fatalf("Bad: %s", rule["source_cidr"]) 768 } 769 770 ports := rule["ports"].([]interface{}) 771 772 if ports[0] != "80" { 773 t.Fatalf("Bad ports: %s", ports[0]) 774 } 775 if ports[1] != "1000-2000" { 776 t.Fatalf("Bad ports: %s", ports[1]) 777 } 778 } 779 780 func TestLoad_jsonAttributes(t *testing.T) { 781 c, err := LoadFile(filepath.Join(fixtureDir, "attributes.tf.json")) 782 if err != nil { 783 t.Fatalf("Bad: %s", err) 784 } 785 786 if c == nil { 787 t.Fatal("config should not be nil") 788 } 789 790 actual := resourcesStr(c.Resources) 791 print(actual) 792 if actual != strings.TrimSpace(jsonAttributeStr) { 793 t.Fatalf("bad:\n%s", actual) 794 } 795 796 r := c.Resources[0] 797 if r.Name != "test" && r.Type != "cloudstack_firewall" { 798 t.Fatalf("Bad: %#v", r) 799 } 800 801 raw := r.RawConfig 802 if raw.Raw["ipaddress"] != "192.168.0.1" { 803 t.Fatalf("Bad: %s", raw.Raw["ipAddress"]) 804 } 805 806 rule := raw.Raw["rule"].([]map[string]interface{})[0] 807 if rule["protocol"] != "tcp" { 808 t.Fatalf("Bad: %s", rule["protocol"]) 809 } 810 811 if rule["source_cidr"] != "10.0.0.0/8" { 812 t.Fatalf("Bad: %s", rule["source_cidr"]) 813 } 814 815 ports := rule["ports"].([]interface{}) 816 817 if ports[0] != "80" { 818 t.Fatalf("Bad ports: %s", ports[0]) 819 } 820 if ports[1] != "1000-2000" { 821 t.Fatalf("Bad ports: %s", ports[1]) 822 } 823 } 824 825 const jsonAttributeStr = ` 826 cloudstack_firewall.test (x1) 827 ipaddress 828 rule 829 ` 830 831 const windowsHeredocResourcesStr = ` 832 aws_instance.test (x1) 833 user_data 834 ` 835 836 const heredocProvidersStr = ` 837 aws 838 access_key 839 secret_key 840 ` 841 842 const heredocResourcesStr = ` 843 aws_iam_policy.policy (x1) 844 description 845 name 846 path 847 policy 848 aws_instance.heredocwithnumbers (x1) 849 ami 850 provisioners 851 local-exec 852 command 853 aws_instance.test (x1) 854 ami 855 provisioners 856 remote-exec 857 inline 858 ` 859 860 const basicOutputsStr = ` 861 web_ip 862 vars 863 resource: aws_instance.web.private_ip 864 ` 865 866 const basicProvidersStr = ` 867 aws 868 access_key 869 secret_key 870 do 871 api_key 872 vars 873 user: var.foo 874 ` 875 876 const basicResourcesStr = ` 877 aws_instance.db (x1) 878 VPC 879 security_groups 880 provisioners 881 file 882 destination 883 source 884 dependsOn 885 aws_instance.web 886 vars 887 resource: aws_security_group.firewall.*.id 888 aws_instance.web (x1) 889 ami 890 network_interface 891 security_groups 892 provisioners 893 file 894 destination 895 source 896 vars 897 resource: aws_security_group.firewall.foo 898 user: var.foo 899 aws_security_group.firewall (x5) 900 data.do.depends (x1) 901 dependsOn 902 data.do.simple 903 data.do.simple (x1) 904 foo 905 ` 906 907 const basicVariablesStr = ` 908 bar (required) (string) 909 <> 910 <> 911 baz (map) 912 map[key:value] 913 <> 914 foo 915 bar 916 bar 917 ` 918 919 const basicJsonNoNameResourcesStr = ` 920 aws_security_group.allow_external_http_https (x1) 921 tags 922 ` 923 924 const dirBasicOutputsStr = ` 925 web_ip 926 vars 927 resource: aws_instance.web.private_ip 928 ` 929 930 const dirBasicProvidersStr = ` 931 aws 932 access_key 933 secret_key 934 do 935 api_key 936 vars 937 user: var.foo 938 ` 939 940 const dirBasicResourcesStr = ` 941 aws_instance.db (x1) 942 security_groups 943 vars 944 resource: aws_security_group.firewall.*.id 945 aws_instance.web (x1) 946 ami 947 network_interface 948 security_groups 949 vars 950 resource: aws_security_group.firewall.foo 951 user: var.foo 952 aws_security_group.firewall (x5) 953 data.do.depends (x1) 954 dependsOn 955 data.do.simple 956 data.do.simple (x1) 957 foo 958 ` 959 960 const dirBasicVariablesStr = ` 961 foo 962 bar 963 bar 964 ` 965 966 const dirOverrideOutputsStr = ` 967 web_ip 968 vars 969 resource: aws_instance.web.private_ip 970 ` 971 972 const dirOverrideProvidersStr = ` 973 aws 974 access_key 975 secret_key 976 do 977 api_key 978 vars 979 user: var.foo 980 ` 981 982 const dirOverrideResourcesStr = ` 983 aws_instance.db (x1) 984 ami 985 security_groups 986 aws_instance.web (x1) 987 ami 988 foo 989 network_interface 990 security_groups 991 vars 992 resource: aws_security_group.firewall.foo 993 user: var.foo 994 aws_security_group.firewall (x5) 995 data.do.depends (x1) 996 hello 997 dependsOn 998 data.do.simple 999 data.do.simple (x1) 1000 foo 1001 ` 1002 1003 const dirOverrideVariablesStr = ` 1004 foo 1005 bar 1006 bar 1007 ` 1008 1009 const dirOverrideVarsVariablesStr = ` 1010 foo 1011 baz 1012 bar 1013 ` 1014 1015 const importProvidersStr = ` 1016 aws 1017 bar 1018 foo 1019 ` 1020 1021 const importResourcesStr = ` 1022 aws_security_group.db (x1) 1023 aws_security_group.web (x1) 1024 ` 1025 1026 const importVariablesStr = ` 1027 bar (required) 1028 <> 1029 <> 1030 foo 1031 bar 1032 bar 1033 ` 1034 1035 const modulesModulesStr = ` 1036 bar 1037 source = baz 1038 memory 1039 ` 1040 1041 const provisionerResourcesStr = ` 1042 aws_instance.web (x1) 1043 ami 1044 security_groups 1045 provisioners 1046 shell 1047 path 1048 vars 1049 resource: aws_security_group.firewall.foo 1050 user: var.foo 1051 ` 1052 1053 const connectionResourcesStr = ` 1054 aws_instance.web (x1) 1055 ami 1056 security_groups 1057 provisioners 1058 shell 1059 path 1060 shell 1061 path 1062 vars 1063 resource: aws_security_group.firewall.foo 1064 user: var.foo 1065 ` 1066 1067 const variablesVariablesStr = ` 1068 bar 1069 <> 1070 <> 1071 baz 1072 foo 1073 <> 1074 foo (required) 1075 <> 1076 <> 1077 ` 1078 1079 const createBeforeDestroyResourcesStr = ` 1080 aws_instance.bar (x1) 1081 ami 1082 aws_instance.web (x1) 1083 ami 1084 ` 1085 1086 const ignoreChangesResourcesStr = ` 1087 aws_instance.bar (x1) 1088 ami 1089 aws_instance.baz (x1) 1090 ami 1091 aws_instance.web (x1) 1092 ami 1093 `