github.com/hashicorp/terraform-plugin-sdk@v1.17.2/internal/plugin/discovery/get_test.go (about) 1 package discovery 2 3 import ( 4 "archive/zip" 5 "encoding/json" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "log" 10 "net" 11 "net/http" 12 "net/http/httptest" 13 "os" 14 "path/filepath" 15 "reflect" 16 "runtime" 17 "strings" 18 "testing" 19 20 "github.com/hashicorp/terraform-plugin-sdk/httpclient" 21 "github.com/hashicorp/terraform-plugin-sdk/internal/addrs" 22 "github.com/hashicorp/terraform-plugin-sdk/internal/registry" 23 "github.com/hashicorp/terraform-plugin-sdk/internal/registry/response" 24 "github.com/hashicorp/terraform-plugin-sdk/internal/version" 25 "github.com/hashicorp/terraform-svchost" 26 "github.com/hashicorp/terraform-svchost/disco" 27 "github.com/mitchellh/cli" 28 ) 29 30 const testProviderFile = "test provider binary" 31 32 func TestMain(m *testing.M) { 33 server := testReleaseServer() 34 l, err := net.Listen("tcp", "127.0.0.1:8080") 35 if err != nil { 36 log.Fatal(err) 37 } 38 39 // NewUnstartedServer creates a listener. Close that listener and replace 40 // with the one we created. 41 server.Listener.Close() 42 server.Listener = l 43 server.Start() 44 defer server.Close() 45 46 os.Exit(m.Run()) 47 } 48 49 // return the directory listing for the "test" provider 50 func testListingHandler(w http.ResponseWriter, r *http.Request) { 51 parts := strings.Split(r.URL.Path, "/") 52 if len(parts) != 6 { 53 http.Error(w, "not found", http.StatusNotFound) 54 return 55 } 56 provider := parts[4] 57 if provider == "test" { 58 js, err := json.Marshal(versionList) 59 if err != nil { 60 http.Error(w, err.Error(), http.StatusInternalServerError) 61 return 62 } 63 w.Write(js) 64 } 65 http.Error(w, ErrorNoSuchProvider.Error(), http.StatusNotFound) 66 return 67 68 } 69 70 // return the download URLs for the "test" provider 71 func testDownloadHandler(w http.ResponseWriter, r *http.Request) { 72 js, err := json.Marshal(downloadURLs) 73 if err != nil { 74 http.Error(w, err.Error(), http.StatusInternalServerError) 75 return 76 } 77 w.Write(js) 78 } 79 80 func testChecksumHandler(w http.ResponseWriter, r *http.Request) { 81 // this exact plugin has a signature and checksum file 82 if r.URL.Path == "/terraform-provider-template/0.1.0/terraform-provider-template_0.1.0_SHA256SUMS" { 83 http.ServeFile(w, r, "testdata/terraform-provider-template_0.1.0_SHA256SUMS") 84 return 85 } 86 if r.URL.Path == "/terraform-provider-template/0.1.0/terraform-provider-template_0.1.0_SHA256SUMS.sig" { 87 http.ServeFile(w, r, "testdata/terraform-provider-template_0.1.0_SHA256SUMS.sig") 88 return 89 } 90 91 // this this checksum file is corrupt and doesn't match the sig 92 if r.URL.Path == "/terraform-provider-badsig/0.1.0/terraform-provider-badsig_0.1.0_SHA256SUMS" { 93 http.ServeFile(w, r, "testdata/terraform-provider-badsig_0.1.0_SHA256SUMS") 94 return 95 } 96 if r.URL.Path == "/terraform-provider-badsig/0.1.0/terraform-provider-badsig_0.1.0_SHA256SUMS.sig" { 97 http.ServeFile(w, r, "testdata/terraform-provider-badsig_0.1.0_SHA256SUMS.sig") 98 return 99 } 100 101 http.Error(w, "signtaure files not found", http.StatusNotFound) 102 } 103 104 // returns a 200 for a valid provider url, using the patch number for the 105 // plugin protocol version. 106 func testHandler(w http.ResponseWriter, r *http.Request) { 107 if strings.HasSuffix(r.URL.Path, "/versions") { 108 testListingHandler(w, r) 109 return 110 } 111 112 if strings.Contains(r.URL.Path, "/download") { 113 testDownloadHandler(w, r) 114 return 115 } 116 117 parts := strings.Split(r.URL.Path, "/") 118 if len(parts) != 7 { 119 http.Error(w, "not found", http.StatusNotFound) 120 return 121 } 122 123 // write a dummy file 124 z := zip.NewWriter(w) 125 fn := fmt.Sprintf("%s_v%s", parts[4], parts[5]) 126 f, err := z.Create(fn) 127 if err != nil { 128 panic(err) 129 } 130 io.WriteString(f, testProviderFile) 131 z.Close() 132 } 133 134 func testReleaseServer() *httptest.Server { 135 handler := http.NewServeMux() 136 handler.HandleFunc("/v1/providers/-/", testHandler) 137 handler.HandleFunc("/v1/providers/terraform-providers/", testHandler) 138 handler.HandleFunc("/terraform-provider-template/", testChecksumHandler) 139 handler.HandleFunc("/terraform-provider-badsig/", testChecksumHandler) 140 handler.HandleFunc("/.well-known/terraform.json", func(w http.ResponseWriter, r *http.Request) { 141 w.Header().Set("Content-Type", "application/json") 142 io.WriteString(w, `{"modules.v1":"http://localhost/v1/modules/", "providers.v1":"http://localhost/v1/providers/"}`) 143 }) 144 145 return httptest.NewUnstartedServer(handler) 146 } 147 148 func TestVersionListing(t *testing.T) { 149 server := testReleaseServer() 150 server.Start() 151 defer server.Close() 152 153 i := newProviderInstaller(server) 154 155 allVersions, err := i.listProviderVersions(addrs.ProviderType{Name: "test"}) 156 157 if err != nil { 158 t.Fatal(err) 159 } 160 161 var versions []*response.TerraformProviderVersion 162 163 for _, v := range allVersions.Versions { 164 versions = append(versions, v) 165 } 166 167 response.ProviderVersionCollection(versions).Sort() 168 169 expected := []*response.TerraformProviderVersion{ 170 {Version: "1.2.4"}, 171 {Version: "1.2.3"}, 172 {Version: "1.2.1"}, 173 } 174 175 if len(versions) != len(expected) { 176 t.Fatalf("Received wrong number of versions. expected: %#v, got: %#v", expected, versions) 177 } 178 179 for i, v := range versions { 180 if v.Version != expected[i].Version { 181 t.Fatalf("incorrect version: %#v, expected %#v", v, expected[i]) 182 } 183 } 184 } 185 186 func TestCheckProtocolVersions(t *testing.T) { 187 tests := []struct { 188 VersionMeta *response.TerraformProviderVersion 189 Err bool 190 }{ 191 { 192 &response.TerraformProviderVersion{ 193 Protocols: []string{"1", "2"}, 194 }, 195 true, 196 }, 197 { 198 &response.TerraformProviderVersion{ 199 Protocols: []string{"4"}, 200 }, 201 false, 202 }, 203 { 204 &response.TerraformProviderVersion{ 205 Protocols: []string{"4.2"}, 206 }, 207 false, 208 }, 209 { 210 &response.TerraformProviderVersion{ 211 Protocols: []string{"4.0", "5.2"}, 212 }, 213 false, 214 }, 215 { 216 &response.TerraformProviderVersion{ 217 Protocols: []string{"5.0", "6.1"}, 218 }, 219 true, 220 }, 221 } 222 223 server := testReleaseServer() 224 server.Start() 225 defer server.Close() 226 i := newProviderInstaller(server) 227 228 for _, test := range tests { 229 err := i.checkPluginProtocol(test.VersionMeta) 230 if test.Err { 231 if err == nil { 232 t.Fatal("succeeded; want error") 233 } 234 } else if err != nil { 235 t.Fatalf("unexpected error: %s", err) 236 } 237 } 238 } 239 240 func TestFindClosestProtocolCompatibleVersion(t *testing.T) { 241 testCases := []struct { 242 Name string 243 PluginProtocolVersion uint 244 ProviderVersions []*response.TerraformProviderVersion 245 ExpectedVersion string 246 Err bool 247 }{ 248 { 249 "no compatible version", 250 5, 251 []*response.TerraformProviderVersion{ 252 { 253 Version: "1.0.0", 254 Protocols: []string{"4.0"}, 255 }, 256 }, 257 "", 258 true, 259 }, { 260 "equal, suggests latest", 261 4, 262 []*response.TerraformProviderVersion{ 263 { 264 Version: "1.0.0", 265 Protocols: []string{"4.0"}, 266 }, 267 { 268 Version: "1.5.0", 269 Protocols: []string{"4.0"}, 270 }, 271 }, 272 "1.5.0", 273 false, 274 }, { 275 "provider protocol too old, suggests earliest", 276 5, 277 []*response.TerraformProviderVersion{ 278 { 279 Version: "1.0.0", 280 Protocols: []string{"4.0"}, 281 }, 282 { 283 Version: "2.0.0", 284 Protocols: []string{"4.0", "5.0"}, 285 }, 286 { 287 Version: "2.5.0", 288 Protocols: []string{"4.0", "5.0"}, 289 }, 290 { 291 Version: "3.0.0", 292 Protocols: []string{"5.0"}, 293 }, 294 }, 295 "2.0.0", 296 false, 297 }, { 298 "provider protocol too new, suggests latest", 299 4, 300 []*response.TerraformProviderVersion{ 301 { 302 Version: "1.0.0", 303 Protocols: []string{"4.0"}, 304 }, 305 { 306 Version: "2.0.0", 307 Protocols: []string{"4.0", "5.0"}, 308 }, 309 { 310 Version: "2.5.0", 311 Protocols: []string{"4.0", "5.0"}, 312 }, 313 { 314 Version: "3.0.0", 315 Protocols: []string{"5.0"}, 316 }, 317 }, 318 "2.5.0", 319 false, 320 }, { 321 "compatible prereleses are filtered", 322 5, 323 []*response.TerraformProviderVersion{ 324 { 325 Version: "2.0.0-alpha", 326 Protocols: []string{"4.0", "5.0"}, 327 }, 328 }, 329 "", 330 true, 331 }, { 332 "suggests latest non-prerelease", 333 4, 334 []*response.TerraformProviderVersion{ 335 { 336 Version: "2.0.0-alpha", 337 Protocols: []string{"4.0", "5.0"}, 338 }, 339 { 340 Version: "2.0.0", 341 Protocols: []string{"4.0", "5.0"}, 342 }, 343 { 344 Version: "2.5.0-pre", 345 Protocols: []string{"4.0", "5.0"}, 346 }, 347 { 348 Version: "2.5.0", 349 Protocols: []string{"4.0", "5.0"}, 350 }, 351 }, 352 "2.5.0", 353 false, 354 }, { 355 "suggests earliest non-prerelease", 356 5, 357 []*response.TerraformProviderVersion{ 358 { 359 Version: "2.0.0-alpha", 360 Protocols: []string{"4.0", "5.0"}, 361 }, 362 { 363 Version: "2.0.0", 364 Protocols: []string{"4.0", "5.0"}, 365 }, 366 { 367 Version: "2.6.0", 368 Protocols: []string{"4.0", "5.0"}, 369 }, 370 { 371 Version: "3.0.0", 372 Protocols: []string{"5.0"}, 373 }, 374 }, 375 "2.0.0", 376 false, 377 }, 378 } 379 380 for _, tc := range testCases { 381 t.Run(tc.Name, func(t *testing.T) { 382 i := ProviderInstaller{ 383 Ui: cli.NewMockUi(), 384 PluginProtocolVersion: tc.PluginProtocolVersion, 385 } 386 387 closestMatch, err := i.findClosestProtocolCompatibleVersion(tc.ProviderVersions) 388 if err != nil { 389 if !tc.Err { 390 t.Fatalf("unexpected error: %q", err) 391 } 392 return 393 } 394 if tc.ExpectedVersion != closestMatch.Version { 395 t.Errorf("Expected %q, got %q", tc.ExpectedVersion, closestMatch.Version) 396 } 397 }) 398 } 399 } 400 401 func TestProviderInstallerGet(t *testing.T) { 402 server := testReleaseServer() 403 server.Start() 404 defer server.Close() 405 406 tmpDir, err := ioutil.TempDir("", "tf-plugin") 407 if err != nil { 408 t.Fatal(err) 409 } 410 411 defer os.RemoveAll(tmpDir) 412 413 // attempt to use an incompatible protocol version 414 i := &ProviderInstaller{ 415 Dir: tmpDir, 416 PluginProtocolVersion: 5, 417 SkipVerify: true, 418 Ui: cli.NewMockUi(), 419 registry: registry.NewClient(Disco(server), nil), 420 } 421 422 _, _, err = i.Get(addrs.ProviderType{Name: "test"}, AllVersions) 423 424 if err != ErrorNoVersionCompatibleWithPlatform { 425 t.Fatal("want error for incompatible version") 426 } 427 428 i = &ProviderInstaller{ 429 Dir: tmpDir, 430 PluginProtocolVersion: 4, 431 SkipVerify: true, 432 Ui: cli.NewMockUi(), 433 registry: registry.NewClient(Disco(server), nil), 434 OS: "mockos", 435 Arch: "mockarch", 436 } 437 438 { 439 _, _, err := i.Get(addrs.ProviderType{Name: "test"}, ConstraintStr(">9.0.0").MustParse()) 440 if err != ErrorNoSuitableVersion { 441 t.Fatal("want error for mismatching constraints") 442 } 443 } 444 445 { 446 provider := addrs.ProviderType{Name: "nonexist"} 447 _, _, err := i.Get(provider, AllVersions) 448 if err != ErrorNoSuchProvider { 449 t.Fatal("want error for no such provider") 450 } 451 } 452 453 gotMeta, _, err := i.Get(addrs.ProviderType{Name: "test"}, AllVersions) 454 if err != nil { 455 t.Fatal(err) 456 } 457 458 // we should have version 1.2.4 459 dest := filepath.Join(tmpDir, "terraform-provider-test_v1.2.4") 460 461 wantMeta := PluginMeta{ 462 Name: "test", 463 Version: VersionStr("1.2.4"), 464 Path: dest, 465 } 466 if !reflect.DeepEqual(gotMeta, wantMeta) { 467 t.Errorf("wrong result meta\ngot: %#v\nwant: %#v", gotMeta, wantMeta) 468 } 469 470 f, err := ioutil.ReadFile(dest) 471 if err != nil { 472 t.Fatal(err) 473 } 474 475 // provider should have been unzipped 476 if string(f) != testProviderFile { 477 t.Fatalf("test provider contains: %q", f) 478 } 479 480 } 481 482 // test that the provider installer can install plugins from a plugin cache dir 483 // into a target directory that does not exist. 484 // https://github.com/hashicorp/terraform-plugin-sdk/issues/20532 485 func TestProviderInstallerGet_cache(t *testing.T) { 486 server := testReleaseServer() 487 server.Start() 488 defer server.Close() 489 490 tmpDir, err := ioutil.TempDir("", "tf-plugin") 491 if err != nil { 492 t.Fatal(err) 493 } 494 495 cache := NewLocalPluginCache(filepath.Join(tmpDir, "cache")) 496 targetDir := filepath.Join(tmpDir, "non-existant-dir") 497 498 defer os.RemoveAll(tmpDir) 499 500 i := &ProviderInstaller{ 501 Dir: targetDir, 502 Cache: cache, 503 PluginProtocolVersion: 4, 504 SkipVerify: true, 505 Ui: cli.NewMockUi(), 506 registry: registry.NewClient(Disco(server), nil), 507 OS: "mockos", 508 Arch: "mockarch", 509 } 510 511 gotMeta, _, err := i.Get(addrs.ProviderType{Name: "test"}, AllVersions) 512 if err != nil { 513 t.Fatal(err) 514 } 515 516 // we should have version 1.2.4 517 dest := filepath.Join(targetDir, "terraform-provider-test_v1.2.4") 518 519 wantMeta := PluginMeta{ 520 Name: "test", 521 Version: VersionStr("1.2.4"), 522 Path: dest, 523 } 524 if !reflect.DeepEqual(gotMeta, wantMeta) { 525 t.Errorf("wrong result meta\ngot: %#v\nwant: %#v", gotMeta, wantMeta) 526 } 527 528 f, err := ioutil.ReadFile(dest) 529 if err != nil { 530 t.Fatal(err) 531 } 532 533 // provider should have been unzipped 534 if string(f) != testProviderFile { 535 t.Fatalf("test provider contains: %q", f) 536 } 537 } 538 539 func TestProviderInstallerPurgeUnused(t *testing.T) { 540 server := testReleaseServer() 541 defer server.Close() 542 543 tmpDir, err := ioutil.TempDir("", "tf-plugin") 544 if err != nil { 545 t.Fatal(err) 546 } 547 548 defer os.RemoveAll(tmpDir) 549 550 unwantedPath := filepath.Join(tmpDir, "terraform-provider-test_v0.0.1_x2") 551 wantedPath := filepath.Join(tmpDir, "terraform-provider-test_v1.2.3_x3") 552 553 f, err := os.Create(unwantedPath) 554 if err != nil { 555 t.Fatal(err) 556 } 557 f.Close() 558 f, err = os.Create(wantedPath) 559 if err != nil { 560 t.Fatal(err) 561 } 562 f.Close() 563 564 i := &ProviderInstaller{ 565 Dir: tmpDir, 566 PluginProtocolVersion: 3, 567 SkipVerify: true, 568 Ui: cli.NewMockUi(), 569 registry: registry.NewClient(Disco(server), nil), 570 } 571 purged, err := i.PurgeUnused(map[string]PluginMeta{ 572 "test": { 573 Name: "test", 574 Version: VersionStr("1.2.3"), 575 Path: wantedPath, 576 }, 577 }) 578 if err != nil { 579 t.Fatal(err) 580 } 581 582 if got, want := purged.Count(), 1; got != want { 583 t.Errorf("wrong purged count %d; want %d", got, want) 584 } 585 if got, want := purged.Newest().Path, unwantedPath; got != want { 586 t.Errorf("wrong purged path %s; want %s", got, want) 587 } 588 589 files, err := ioutil.ReadDir(tmpDir) 590 if err != nil { 591 t.Fatal(err) 592 } 593 594 gotFilenames := make([]string, len(files)) 595 for i, info := range files { 596 gotFilenames[i] = info.Name() 597 } 598 wantFilenames := []string{"terraform-provider-test_v1.2.3_x3"} 599 600 if !reflect.DeepEqual(gotFilenames, wantFilenames) { 601 t.Errorf("wrong filenames after purge\ngot: %#v\nwant: %#v", gotFilenames, wantFilenames) 602 } 603 } 604 605 // Test fetching a provider's checksum file while verifying its signature. 606 func TestProviderChecksum(t *testing.T) { 607 hashicorpKey, err := ioutil.ReadFile("testdata/hashicorp.asc") 608 if err != nil { 609 t.Fatal(err) 610 } 611 612 tests := []struct { 613 Name string 614 Resp *response.TerraformProviderPlatformLocation 615 Err bool 616 }{ 617 { 618 "good", 619 &response.TerraformProviderPlatformLocation{ 620 Filename: "terraform-provider-template_0.1.0_darwin_amd64.zip", 621 Shasum: "3c3e7df78b1f0161a3f941c271d5501f7b5e5f2c53738e7a371459712f5d4726", 622 ShasumsURL: "http://127.0.0.1:8080/terraform-provider-template/0.1.0/terraform-provider-template_0.1.0_SHA256SUMS", 623 ShasumsSignatureURL: "http://127.0.0.1:8080/terraform-provider-template/0.1.0/terraform-provider-template_0.1.0_SHA256SUMS.sig", 624 SigningKeys: response.SigningKeyList{ 625 GPGKeys: []*response.GPGKey{ 626 { 627 ASCIIArmor: string(hashicorpKey), 628 }, 629 }, 630 }, 631 }, 632 false, 633 }, 634 { 635 "bad", 636 &response.TerraformProviderPlatformLocation{ 637 Filename: "terraform-provider-template_0.1.0_darwin_amd64.zip", 638 ShasumsURL: "http://127.0.0.1:8080/terraform-provider-badsig/0.1.0/terraform-provider-badsig_0.1.0_SHA256SUMS", 639 ShasumsSignatureURL: "http://127.0.0.1:8080/terraform-provider-badsig/0.1.0/terraform-provider-badsig_0.1.0_SHA256SUMS.sig", 640 SigningKeys: response.SigningKeyList{ 641 GPGKeys: []*response.GPGKey{ 642 { 643 ASCIIArmor: string(hashicorpKey), 644 }, 645 }, 646 }, 647 }, 648 true, 649 }, 650 { 651 "no keys", 652 &response.TerraformProviderPlatformLocation{ 653 Filename: "terraform-provider-template_0.1.0_darwin_amd64.zip", 654 ShasumsURL: "http://127.0.0.1:8080/terraform-provider-template/0.1.0/terraform-provider-template_0.1.0_SHA256SUMS", 655 ShasumsSignatureURL: "http://127.0.0.1:8080/terraform-provider-template/0.1.0/terraform-provider-template_0.1.0_SHA256SUMS.sig", 656 SigningKeys: response.SigningKeyList{ 657 GPGKeys: []*response.GPGKey{}, 658 }, 659 }, 660 true, 661 }, 662 { 663 "mismatch checksum", 664 &response.TerraformProviderPlatformLocation{ 665 Filename: "terraform-provider-template_0.1.0_darwin_amd64.zip", 666 Shasum: "force mismatch", 667 ShasumsURL: "http://127.0.0.1:8080/terraform-provider-template/0.1.0/terraform-provider-template_0.1.0_SHA256SUMS", 668 ShasumsSignatureURL: "http://127.0.0.1:8080/terraform-provider-template/0.1.0/terraform-provider-template_0.1.0_SHA256SUMS.sig", 669 SigningKeys: response.SigningKeyList{ 670 GPGKeys: []*response.GPGKey{ 671 { 672 ASCIIArmor: string(hashicorpKey), 673 }, 674 }, 675 }, 676 }, 677 true, 678 }, 679 { 680 "missing checksum for file", 681 &response.TerraformProviderPlatformLocation{ 682 Filename: "terraform-provider-template_0.1.0_darwin_amd64_missing_checksum.zip", 683 Shasum: "checksum", 684 ShasumsURL: "http://127.0.0.1:8080/terraform-provider-template/0.1.0/terraform-provider-template_0.1.0_SHA256SUMS", 685 ShasumsSignatureURL: "http://127.0.0.1:8080/terraform-provider-template/0.1.0/terraform-provider-template_0.1.0_SHA256SUMS.sig", 686 SigningKeys: response.SigningKeyList{ 687 GPGKeys: []*response.GPGKey{ 688 { 689 ASCIIArmor: string(hashicorpKey), 690 }, 691 }, 692 }, 693 }, 694 true, 695 }, 696 } 697 698 i := ProviderInstaller{} 699 700 for _, test := range tests { 701 t.Run(test.Name, func(t *testing.T) { 702 sha256sum, err := i.getProviderChecksum(test.Resp) 703 if test.Err { 704 if err == nil { 705 t.Fatal("succeeded; want error") 706 } 707 return 708 } else if err != nil { 709 t.Fatalf("unexpected error: %s", err) 710 } 711 712 // get the expected checksum for our os/arch 713 sumData, err := ioutil.ReadFile("testdata/terraform-provider-template_0.1.0_SHA256SUMS") 714 if err != nil { 715 t.Fatal(err) 716 } 717 718 expected := checksumForFile(sumData, test.Resp.Filename) 719 720 if sha256sum != expected { 721 t.Fatalf("expected: %s\ngot %s\n", sha256sum, expected) 722 } 723 }) 724 } 725 } 726 727 // newProviderInstaller returns a minimally-initialized ProviderInstaller 728 func newProviderInstaller(s *httptest.Server) ProviderInstaller { 729 return ProviderInstaller{ 730 registry: registry.NewClient(Disco(s), nil), 731 OS: runtime.GOOS, 732 Arch: runtime.GOARCH, 733 PluginProtocolVersion: 4, 734 } 735 } 736 737 // Disco return a *disco.Disco mapping registry.terraform.io, localhost, 738 // localhost.localdomain, and example.com to the test server. 739 func Disco(s *httptest.Server) *disco.Disco { 740 services := map[string]interface{}{ 741 // Note that both with and without trailing slashes are supported behaviours 742 "modules.v1": fmt.Sprintf("%s/v1/modules", s.URL), 743 "providers.v1": fmt.Sprintf("%s/v1/providers", s.URL), 744 } 745 d := disco.New() 746 d.SetUserAgent(httpclient.TerraformUserAgent(version.String())) 747 748 d.ForceHostServices(svchost.Hostname("registry.terraform.io"), services) 749 d.ForceHostServices(svchost.Hostname("localhost"), services) 750 d.ForceHostServices(svchost.Hostname("localhost.localdomain"), services) 751 d.ForceHostServices(svchost.Hostname("example.com"), services) 752 return d 753 } 754 755 var versionList = response.TerraformProvider{ 756 ID: "terraform-providers/test", 757 Versions: []*response.TerraformProviderVersion{ 758 {Version: "1.2.1"}, 759 {Version: "1.2.3"}, 760 { 761 Version: "1.2.4", 762 Protocols: []string{"4"}, 763 Platforms: []*response.TerraformProviderPlatform{ 764 { 765 OS: "mockos", 766 Arch: "mockarch", 767 }, 768 }, 769 }, 770 }, 771 } 772 773 var downloadURLs = response.TerraformProviderPlatformLocation{ 774 ShasumsURL: "https://registry.terraform.io/terraform-provider-template/1.2.4/terraform-provider-test_1.2.4_SHA256SUMS", 775 ShasumsSignatureURL: "https://registry.terraform.io/terraform-provider-template/1.2.4/terraform-provider-test_1.2.4_SHA256SUMS.sig", 776 Filename: "terraform-provider-template_1.2.4_darwin_amd64.zip", 777 DownloadURL: "http://127.0.0.1:8080/v1/providers/terraform-providers/terraform-provider-test/1.2.4/terraform-provider-test_1.2.4_darwin_amd64.zip", 778 }