github.com/tomaszheflik/terraform@v0.7.3-0.20160827060421-32f990b41594/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 TestLoadFileBasic_jsonNoName(t *testing.T) { 331 c, err := LoadFile(filepath.Join(fixtureDir, "resource-no-name.tf.json")) 332 if err != nil { 333 t.Fatalf("err: %s", err) 334 } 335 336 if c == nil { 337 t.Fatal("config should not be nil") 338 } 339 340 actual := resourcesStr(c.Resources) 341 if actual != strings.TrimSpace(basicJsonNoNameResourcesStr) { 342 t.Fatalf("bad:\n%s", actual) 343 } 344 } 345 346 func TestLoadFile_variables(t *testing.T) { 347 c, err := LoadFile(filepath.Join(fixtureDir, "variables.tf")) 348 if err != nil { 349 t.Fatalf("err: %s", err) 350 } 351 if c == nil { 352 t.Fatal("config should not be nil") 353 } 354 355 if c.Dir != "" { 356 t.Fatalf("bad: %#v", c.Dir) 357 } 358 359 actual := variablesStr(c.Variables) 360 if actual != strings.TrimSpace(variablesVariablesStr) { 361 t.Fatalf("bad:\n%s", actual) 362 } 363 } 364 365 func TestLoadDir_basic(t *testing.T) { 366 dir := filepath.Join(fixtureDir, "dir-basic") 367 c, err := LoadDir(dir) 368 if err != nil { 369 t.Fatalf("err: %s", err) 370 } 371 372 if c == nil { 373 t.Fatal("config should not be nil") 374 } 375 376 dirAbs, err := filepath.Abs(dir) 377 if err != nil { 378 t.Fatalf("err: %s", err) 379 } 380 if c.Dir != dirAbs { 381 t.Fatalf("bad: %#v", c.Dir) 382 } 383 384 actual := variablesStr(c.Variables) 385 if actual != strings.TrimSpace(dirBasicVariablesStr) { 386 t.Fatalf("bad:\n%s", actual) 387 } 388 389 actual = providerConfigsStr(c.ProviderConfigs) 390 if actual != strings.TrimSpace(dirBasicProvidersStr) { 391 t.Fatalf("bad:\n%s", actual) 392 } 393 394 actual = resourcesStr(c.Resources) 395 if actual != strings.TrimSpace(dirBasicResourcesStr) { 396 t.Fatalf("bad:\n%s", actual) 397 } 398 399 actual = outputsStr(c.Outputs) 400 if actual != strings.TrimSpace(dirBasicOutputsStr) { 401 t.Fatalf("bad:\n%s", actual) 402 } 403 } 404 405 func TestLoadDir_file(t *testing.T) { 406 _, err := LoadDir(filepath.Join(fixtureDir, "variables.tf")) 407 if err == nil { 408 t.Fatal("should error") 409 } 410 } 411 412 func TestLoadDir_noConfigs(t *testing.T) { 413 _, err := LoadDir(filepath.Join(fixtureDir, "dir-empty")) 414 if err == nil { 415 t.Fatal("should error") 416 } 417 } 418 419 func TestLoadDir_noMerge(t *testing.T) { 420 c, err := LoadDir(filepath.Join(fixtureDir, "dir-merge")) 421 if err != nil { 422 t.Fatalf("err: %s", err) 423 } 424 425 if c == nil { 426 t.Fatal("config should not be nil") 427 } 428 429 if err := c.Validate(); err == nil { 430 t.Fatal("should not be valid") 431 } 432 } 433 434 func TestLoadDir_override(t *testing.T) { 435 c, err := LoadDir(filepath.Join(fixtureDir, "dir-override")) 436 if err != nil { 437 t.Fatalf("err: %s", err) 438 } 439 440 if c == nil { 441 t.Fatal("config should not be nil") 442 } 443 444 actual := variablesStr(c.Variables) 445 if actual != strings.TrimSpace(dirOverrideVariablesStr) { 446 t.Fatalf("bad:\n%s", actual) 447 } 448 449 actual = providerConfigsStr(c.ProviderConfigs) 450 if actual != strings.TrimSpace(dirOverrideProvidersStr) { 451 t.Fatalf("bad:\n%s", actual) 452 } 453 454 actual = resourcesStr(c.Resources) 455 if actual != strings.TrimSpace(dirOverrideResourcesStr) { 456 t.Fatalf("bad:\n%s", actual) 457 } 458 459 actual = outputsStr(c.Outputs) 460 if actual != strings.TrimSpace(dirOverrideOutputsStr) { 461 t.Fatalf("bad:\n%s", actual) 462 } 463 } 464 465 func TestLoadDir_overrideVar(t *testing.T) { 466 c, err := LoadDir(filepath.Join(fixtureDir, "dir-override-var")) 467 if err != nil { 468 t.Fatalf("err: %s", err) 469 } 470 471 if c == nil { 472 t.Fatal("config should not be nil") 473 } 474 475 actual := variablesStr(c.Variables) 476 if actual != strings.TrimSpace(dirOverrideVarsVariablesStr) { 477 t.Fatalf("bad:\n%s", actual) 478 } 479 } 480 481 func TestLoadFile_mismatchedVariableTypes(t *testing.T) { 482 _, err := LoadFile(filepath.Join(fixtureDir, "variable-mismatched-type.tf")) 483 if err == nil { 484 t.Fatalf("bad: expected error") 485 } 486 487 errorStr := err.Error() 488 if !strings.Contains(errorStr, "'not_a_map' has a default value which is not of type 'string'") { 489 t.Fatalf("bad: expected error has wrong text: %s", errorStr) 490 } 491 } 492 493 func TestLoadFile_badVariableTypes(t *testing.T) { 494 _, err := LoadFile(filepath.Join(fixtureDir, "bad-variable-type.tf")) 495 if err == nil { 496 t.Fatalf("bad: expected error") 497 } 498 499 errorStr := err.Error() 500 if !strings.Contains(errorStr, "'bad_type' must be of type string") { 501 t.Fatalf("bad: expected error has wrong text: %s", errorStr) 502 } 503 } 504 505 func TestLoadFile_provisioners(t *testing.T) { 506 c, err := LoadFile(filepath.Join(fixtureDir, "provisioners.tf")) 507 if err != nil { 508 t.Fatalf("err: %s", err) 509 } 510 511 if c == nil { 512 t.Fatal("config should not be nil") 513 } 514 515 actual := resourcesStr(c.Resources) 516 if actual != strings.TrimSpace(provisionerResourcesStr) { 517 t.Fatalf("bad:\n%s", actual) 518 } 519 } 520 521 func TestLoadFile_connections(t *testing.T) { 522 c, err := LoadFile(filepath.Join(fixtureDir, "connection.tf")) 523 if err != nil { 524 t.Fatalf("err: %s", err) 525 } 526 527 if c == nil { 528 t.Fatal("config should not be nil") 529 } 530 531 actual := resourcesStr(c.Resources) 532 if actual != strings.TrimSpace(connectionResourcesStr) { 533 t.Fatalf("bad:\n%s", actual) 534 } 535 536 // Check for the connection info 537 r := c.Resources[0] 538 if r.Name != "web" && r.Type != "aws_instance" { 539 t.Fatalf("Bad: %#v", r) 540 } 541 542 p1 := r.Provisioners[0] 543 if p1.ConnInfo == nil || len(p1.ConnInfo.Raw) != 2 { 544 t.Fatalf("Bad: %#v", p1.ConnInfo) 545 } 546 if p1.ConnInfo.Raw["user"] != "nobody" { 547 t.Fatalf("Bad: %#v", p1.ConnInfo) 548 } 549 550 p2 := r.Provisioners[1] 551 if p2.ConnInfo == nil || len(p2.ConnInfo.Raw) != 2 { 552 t.Fatalf("Bad: %#v", p2.ConnInfo) 553 } 554 if p2.ConnInfo.Raw["user"] != "root" { 555 t.Fatalf("Bad: %#v", p2.ConnInfo) 556 } 557 } 558 559 func TestLoadFile_createBeforeDestroy(t *testing.T) { 560 c, err := LoadFile(filepath.Join(fixtureDir, "create-before-destroy.tf")) 561 if err != nil { 562 t.Fatalf("err: %s", err) 563 } 564 565 if c == nil { 566 t.Fatal("config should not be nil") 567 } 568 569 actual := resourcesStr(c.Resources) 570 if actual != strings.TrimSpace(createBeforeDestroyResourcesStr) { 571 t.Fatalf("bad:\n%s", actual) 572 } 573 574 // Check for the flag value 575 r := c.Resources[0] 576 if r.Name != "web" && r.Type != "aws_instance" { 577 t.Fatalf("Bad: %#v", r) 578 } 579 580 // Should enable create before destroy 581 if !r.Lifecycle.CreateBeforeDestroy { 582 t.Fatalf("Bad: %#v", r) 583 } 584 585 r = c.Resources[1] 586 if r.Name != "bar" && r.Type != "aws_instance" { 587 t.Fatalf("Bad: %#v", r) 588 } 589 590 // Should not enable create before destroy 591 if r.Lifecycle.CreateBeforeDestroy { 592 t.Fatalf("Bad: %#v", r) 593 } 594 } 595 596 func TestLoadFile_ignoreChanges(t *testing.T) { 597 c, err := LoadFile(filepath.Join(fixtureDir, "ignore-changes.tf")) 598 if err != nil { 599 t.Fatalf("err: %s", err) 600 } 601 602 if c == nil { 603 t.Fatal("config should not be nil") 604 } 605 606 actual := resourcesStr(c.Resources) 607 print(actual) 608 if actual != strings.TrimSpace(ignoreChangesResourcesStr) { 609 t.Fatalf("bad:\n%s", actual) 610 } 611 612 // Check for the flag value 613 r := c.Resources[0] 614 if r.Name != "web" && r.Type != "aws_instance" { 615 t.Fatalf("Bad: %#v", r) 616 } 617 618 // Should populate ignore changes 619 if len(r.Lifecycle.IgnoreChanges) == 0 { 620 t.Fatalf("Bad: %#v", r) 621 } 622 623 r = c.Resources[1] 624 if r.Name != "bar" && r.Type != "aws_instance" { 625 t.Fatalf("Bad: %#v", r) 626 } 627 628 // Should not populate ignore changes 629 if len(r.Lifecycle.IgnoreChanges) > 0 { 630 t.Fatalf("Bad: %#v", r) 631 } 632 633 r = c.Resources[2] 634 if r.Name != "baz" && r.Type != "aws_instance" { 635 t.Fatalf("Bad: %#v", r) 636 } 637 638 // Should not populate ignore changes 639 if len(r.Lifecycle.IgnoreChanges) > 0 { 640 t.Fatalf("Bad: %#v", r) 641 } 642 } 643 644 func TestLoad_preventDestroyString(t *testing.T) { 645 c, err := LoadFile(filepath.Join(fixtureDir, "prevent-destroy-string.tf")) 646 if err != nil { 647 t.Fatalf("err: %s", err) 648 } 649 650 if c == nil { 651 t.Fatal("config should not be nil") 652 } 653 654 actual := resourcesStr(c.Resources) 655 if actual != strings.TrimSpace(createBeforeDestroyResourcesStr) { 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 enable create before destroy 666 if !r.Lifecycle.PreventDestroy { 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 enable create before destroy 676 if r.Lifecycle.PreventDestroy { 677 t.Fatalf("Bad: %#v", r) 678 } 679 } 680 681 func TestLoad_temporary_files(t *testing.T) { 682 _, err := LoadDir(filepath.Join(fixtureDir, "dir-temporary-files")) 683 if err == nil { 684 t.Fatalf("Expected to see an error stating no config files found") 685 } 686 } 687 688 func TestLoad_hclAttributes(t *testing.T) { 689 c, err := LoadFile(filepath.Join(fixtureDir, "attributes.tf")) 690 if err != nil { 691 t.Fatalf("Bad: %s", err) 692 } 693 694 if c == nil { 695 t.Fatal("config should not be nil") 696 } 697 698 actual := resourcesStr(c.Resources) 699 print(actual) 700 if actual != strings.TrimSpace(jsonAttributeStr) { 701 t.Fatalf("bad:\n%s", actual) 702 } 703 704 r := c.Resources[0] 705 if r.Name != "test" && r.Type != "cloudstack_firewall" { 706 t.Fatalf("Bad: %#v", r) 707 } 708 709 raw := r.RawConfig 710 if raw.Raw["ipaddress"] != "192.168.0.1" { 711 t.Fatalf("Bad: %s", raw.Raw["ipAddress"]) 712 } 713 714 rule := raw.Raw["rule"].([]map[string]interface{})[0] 715 if rule["protocol"] != "tcp" { 716 t.Fatalf("Bad: %s", rule["protocol"]) 717 } 718 719 if rule["source_cidr"] != "10.0.0.0/8" { 720 t.Fatalf("Bad: %s", rule["source_cidr"]) 721 } 722 723 ports := rule["ports"].([]interface{}) 724 725 if ports[0] != "80" { 726 t.Fatalf("Bad ports: %s", ports[0]) 727 } 728 if ports[1] != "1000-2000" { 729 t.Fatalf("Bad ports: %s", ports[1]) 730 } 731 } 732 733 func TestLoad_jsonAttributes(t *testing.T) { 734 c, err := LoadFile(filepath.Join(fixtureDir, "attributes.tf.json")) 735 if err != nil { 736 t.Fatalf("Bad: %s", err) 737 } 738 739 if c == nil { 740 t.Fatal("config should not be nil") 741 } 742 743 actual := resourcesStr(c.Resources) 744 print(actual) 745 if actual != strings.TrimSpace(jsonAttributeStr) { 746 t.Fatalf("bad:\n%s", actual) 747 } 748 749 r := c.Resources[0] 750 if r.Name != "test" && r.Type != "cloudstack_firewall" { 751 t.Fatalf("Bad: %#v", r) 752 } 753 754 raw := r.RawConfig 755 if raw.Raw["ipaddress"] != "192.168.0.1" { 756 t.Fatalf("Bad: %s", raw.Raw["ipAddress"]) 757 } 758 759 rule := raw.Raw["rule"].([]map[string]interface{})[0] 760 if rule["protocol"] != "tcp" { 761 t.Fatalf("Bad: %s", rule["protocol"]) 762 } 763 764 if rule["source_cidr"] != "10.0.0.0/8" { 765 t.Fatalf("Bad: %s", rule["source_cidr"]) 766 } 767 768 ports := rule["ports"].([]interface{}) 769 770 if ports[0] != "80" { 771 t.Fatalf("Bad ports: %s", ports[0]) 772 } 773 if ports[1] != "1000-2000" { 774 t.Fatalf("Bad ports: %s", ports[1]) 775 } 776 } 777 778 const jsonAttributeStr = ` 779 cloudstack_firewall.test (x1) 780 ipaddress 781 rule 782 ` 783 784 const windowsHeredocResourcesStr = ` 785 aws_instance.test (x1) 786 user_data 787 ` 788 789 const heredocProvidersStr = ` 790 aws 791 access_key 792 secret_key 793 ` 794 795 const heredocResourcesStr = ` 796 aws_iam_policy.policy (x1) 797 description 798 name 799 path 800 policy 801 aws_instance.heredocwithnumbers (x1) 802 ami 803 provisioners 804 local-exec 805 command 806 aws_instance.test (x1) 807 ami 808 provisioners 809 remote-exec 810 inline 811 ` 812 813 const basicOutputsStr = ` 814 web_ip 815 vars 816 resource: aws_instance.web.private_ip 817 ` 818 819 const basicProvidersStr = ` 820 aws 821 access_key 822 secret_key 823 do 824 api_key 825 vars 826 user: var.foo 827 ` 828 829 const basicResourcesStr = ` 830 aws_instance.db (x1) 831 VPC 832 security_groups 833 provisioners 834 file 835 destination 836 source 837 dependsOn 838 aws_instance.web 839 vars 840 resource: aws_security_group.firewall.*.id 841 aws_instance.web (x1) 842 ami 843 network_interface 844 security_groups 845 provisioners 846 file 847 destination 848 source 849 vars 850 resource: aws_security_group.firewall.foo 851 user: var.foo 852 aws_security_group.firewall (x5) 853 data.do.depends (x1) 854 dependsOn 855 data.do.simple 856 data.do.simple (x1) 857 foo 858 ` 859 860 const basicVariablesStr = ` 861 bar (required) (string) 862 <> 863 <> 864 baz (map) 865 map[key:value] 866 <> 867 foo 868 bar 869 bar 870 ` 871 872 const basicJsonNoNameResourcesStr = ` 873 aws_security_group.allow_external_http_https (x1) 874 tags 875 ` 876 877 const dirBasicOutputsStr = ` 878 web_ip 879 vars 880 resource: aws_instance.web.private_ip 881 ` 882 883 const dirBasicProvidersStr = ` 884 aws 885 access_key 886 secret_key 887 do 888 api_key 889 vars 890 user: var.foo 891 ` 892 893 const dirBasicResourcesStr = ` 894 aws_instance.db (x1) 895 security_groups 896 vars 897 resource: aws_security_group.firewall.*.id 898 aws_instance.web (x1) 899 ami 900 network_interface 901 security_groups 902 vars 903 resource: aws_security_group.firewall.foo 904 user: var.foo 905 aws_security_group.firewall (x5) 906 data.do.depends (x1) 907 dependsOn 908 data.do.simple 909 data.do.simple (x1) 910 foo 911 ` 912 913 const dirBasicVariablesStr = ` 914 foo 915 bar 916 bar 917 ` 918 919 const dirOverrideOutputsStr = ` 920 web_ip 921 vars 922 resource: aws_instance.web.private_ip 923 ` 924 925 const dirOverrideProvidersStr = ` 926 aws 927 access_key 928 secret_key 929 do 930 api_key 931 vars 932 user: var.foo 933 ` 934 935 const dirOverrideResourcesStr = ` 936 aws_instance.db (x1) 937 ami 938 security_groups 939 aws_instance.web (x1) 940 ami 941 foo 942 network_interface 943 security_groups 944 vars 945 resource: aws_security_group.firewall.foo 946 user: var.foo 947 aws_security_group.firewall (x5) 948 data.do.depends (x1) 949 hello 950 dependsOn 951 data.do.simple 952 data.do.simple (x1) 953 foo 954 ` 955 956 const dirOverrideVariablesStr = ` 957 foo 958 bar 959 bar 960 ` 961 962 const dirOverrideVarsVariablesStr = ` 963 foo 964 baz 965 bar 966 ` 967 968 const importProvidersStr = ` 969 aws 970 bar 971 foo 972 ` 973 974 const importResourcesStr = ` 975 aws_security_group.db (x1) 976 aws_security_group.web (x1) 977 ` 978 979 const importVariablesStr = ` 980 bar (required) 981 <> 982 <> 983 foo 984 bar 985 bar 986 ` 987 988 const modulesModulesStr = ` 989 bar 990 source = baz 991 memory 992 ` 993 994 const provisionerResourcesStr = ` 995 aws_instance.web (x1) 996 ami 997 security_groups 998 provisioners 999 shell 1000 path 1001 vars 1002 resource: aws_security_group.firewall.foo 1003 user: var.foo 1004 ` 1005 1006 const connectionResourcesStr = ` 1007 aws_instance.web (x1) 1008 ami 1009 security_groups 1010 provisioners 1011 shell 1012 path 1013 shell 1014 path 1015 vars 1016 resource: aws_security_group.firewall.foo 1017 user: var.foo 1018 ` 1019 1020 const variablesVariablesStr = ` 1021 bar 1022 <> 1023 <> 1024 baz 1025 foo 1026 <> 1027 foo (required) 1028 <> 1029 <> 1030 ` 1031 1032 const createBeforeDestroyResourcesStr = ` 1033 aws_instance.bar (x1) 1034 ami 1035 aws_instance.web (x1) 1036 ami 1037 ` 1038 1039 const ignoreChangesResourcesStr = ` 1040 aws_instance.bar (x1) 1041 ami 1042 aws_instance.baz (x1) 1043 ami 1044 aws_instance.web (x1) 1045 ami 1046 `