Skip to content

Commit

Permalink
Refactor provider code so that we can have a resources in subdirs
Browse files Browse the repository at this point in the history
  • Loading branch information
t0mk authored and ctreatma committed Dec 7, 2023
1 parent 8ff7a88 commit 9a5b481
Show file tree
Hide file tree
Showing 40 changed files with 671 additions and 269 deletions.
83 changes: 83 additions & 0 deletions equinix/acceptance/acceptance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package acceptance

import (
"fmt"
"os"
"strconv"
"strings"
"testing"
"time"

"github.com/equinix/terraform-provider-equinix/equinix"
"github.com/equinix/terraform-provider-equinix/internal/config"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

const (
// duplicated from equinix_sweeoer_test.go
tstResourcePrefix = "tfacc"
missingMetalToken = "To run acceptance tests of Equinix Metal Resources, you must set %s"
)

var (
TestAccProvider *schema.Provider
TestAccProviders map[string]*schema.Provider
TestAccProviderFactories map[string]func() (*schema.Provider, error)
TestExternalProviders map[string]resource.ExternalProvider
)

func init() {
TestAccProvider = equinix.Provider()
TestAccProviders = map[string]*schema.Provider{
"equinix": TestAccProvider,
}
TestAccProviderFactories = map[string]func() (*schema.Provider, error){
"equinix": func() (*schema.Provider, error) {
return TestAccProvider, nil
},
}
TestExternalProviders = map[string]resource.ExternalProvider{
"random": {
Source: "hashicorp/random",
},
}
}

func TestAccPreCheckMetal(t *testing.T) {
if os.Getenv(equinix.MetalAuthTokenEnvVar) == "" {
t.Fatalf(missingMetalToken, equinix.MetalAuthTokenEnvVar)
}
}

func IsSweepableTestResource(namePrefix string) bool {
return strings.HasPrefix(namePrefix, tstResourcePrefix)
}

func getFromEnvDefault(varName string, defaultValue string) string {
if v := os.Getenv(varName); v != "" {
return v
}
return defaultValue
}

func GetConfigForNonStandardMetalTest() (*config.Config, error) {
endpoint := getFromEnvDefault(equinix.EndpointEnvVar, config.DefaultBaseURL)
clientTimeout := getFromEnvDefault(equinix.ClientTimeoutEnvVar, strconv.Itoa(config.DefaultTimeout))
clientTimeoutInt, err := strconv.Atoi(clientTimeout)
if err != nil {
return nil, fmt.Errorf("cannot convert value of '%s' env variable to int", equinix.ClientTimeoutEnvVar)
}
metalAuthToken := getFromEnvDefault(equinix.MetalAuthTokenEnvVar, "")

if metalAuthToken == "" {
return nil, fmt.Errorf(missingMetalToken, equinix.MetalAuthTokenEnvVar)
}

return &config.Config{
AuthToken: metalAuthToken,
BaseURL: endpoint,
RequestTimeout: time.Duration(clientTimeoutInt) * time.Second,
}, nil
}
119 changes: 119 additions & 0 deletions equinix/acceptance/device_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package acceptance

import (
"fmt"
"strings"
"time"
)

// list of plans and metros and os used as filter criteria to find available hardware to run tests
var (
Preferable_plans = []string{"x1.small.x86", "t1.small.x86", "c2.medium.x86", "c3.small.x86", "c3.medium.x86", "m3.small.x86"}
Preferable_metros = []string{"ch", "ny", "sv", "ty", "am"}
Preferable_os = []string{"ubuntu_20_04"}
)

func TestDeviceTerminationTime() string {
return time.Now().UTC().Add(60 * time.Minute).Format(time.RFC3339)
}

// This function should be used to find available plans in all test where a metal_device resource is needed.
//
// TODO consider adding a datasource for equinix_metal_operating_system and making the local.os conditional
//
// https://github.com/equinix/terraform-provider-equinix/pull/220#discussion_r915418418equinix_metal_operating_system
// https://github.com/equinix/terraform-provider-equinix/discussions/221
func ConfAccMetalDevice_base(plans, metros, os []string) string {
return fmt.Sprintf(`
data "equinix_metal_plans" "test" {
sort {
attribute = "id"
direction = "asc"
}
filter {
attribute = "name"
values = [%s]
}
filter {
attribute = "available_in_metros"
values = [%s]
}
filter {
attribute = "deployment_types"
values = ["on_demand", "spot_market"]
}
}
// Select a metal plan randomly and lock it in
// so that we don't pick a different one for
// every subsequent terraform plan
resource "random_integer" "plan_idx" {
min = 0
max = length(data.equinix_metal_plans.test.plans) - 1
}
resource "terraform_data" "plan" {
input = data.equinix_metal_plans.test.plans[random_integer.plan_idx.result]
lifecycle {
ignore_changes = ["input"]
}
}
resource "terraform_data" "facilities" {
input = sort(tolist(setsubtract(terraform_data.plan.output.available_in, ["nrt1", "dfw2", "ewr1", "ams1", "sjc1", "ld7", "sy4", "ny6"])))
lifecycle {
ignore_changes = ["input"]
}
}
// Select a metal facility randomly and lock it in
// so that we don't pick a different one for
// every subsequent terraform plan
resource "random_integer" "facility_idx" {
min = 0
max = length(local.facilities) - 1
}
resource "terraform_data" "facility" {
input = local.facilities[random_integer.facility_idx.result]
lifecycle {
ignore_changes = ["input"]
}
}
// Select a metal metro randomly and lock it in
// so that we don't pick a different one for
// every subsequent terraform plan
resource "random_integer" "metro_idx" {
min = 0
max = length(local.metros) - 1
}
resource "terraform_data" "metro" {
input = local.metros[random_integer.metro_idx.result]
lifecycle {
ignore_changes = ["input"]
}
}
locals {
// Select a random plan
plan = terraform_data.plan.output.slug
// Select a random facility from the facilities in which the selected plan is available, excluding decommed facilities
facilities = terraform_data.facilities.output
facility = terraform_data.facility.output
// Select a random metro from the metros in which the selected plan is available
metros = sort(tolist(terraform_data.plan.output.available_in_metros))
metro = terraform_data.metro.output
os = [%s][0]
}
`, fmt.Sprintf("\"%s\"", strings.Join(plans[:], `","`)), fmt.Sprintf("\"%s\"", strings.Join(metros[:], `","`)), fmt.Sprintf("\"%s\"", strings.Join(os[:], `","`)))
}
36 changes: 36 additions & 0 deletions equinix/acceptance/ssh_key_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package acceptance

import (
"fmt"

"github.com/equinix/terraform-provider-equinix/internal/config"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/packethost/packngo"
)

func TestAccCheckMetalSSHKeyExists(n string, key *packngo.SSHKey) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No Record ID is set")
}

client := TestAccProvider.Meta().(*config.Config).Metal

foundKey, _, err := client.SSHKeys.Get(rs.Primary.ID, nil)
if err != nil {
return err
}
if foundKey.ID != rs.Primary.ID {
return fmt.Errorf("SSh Key not found: %v - %v", rs.Primary.ID, foundKey)
}

*key = *foundKey

return nil
}
}
5 changes: 3 additions & 2 deletions equinix/data_source_ecx_l2_sellerprofiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"regexp"
"strings"

"github.com/equinix/terraform-provider-equinix/internal"
"github.com/equinix/terraform-provider-equinix/internal/config"

"github.com/equinix/ecx-go/v2"
Expand Down Expand Up @@ -98,8 +99,8 @@ func dataSourceECXL2SellerProfilesRead(ctx context.Context, d *schema.ResourceDa
}
var filteredProfiles []ecx.L2ServiceProfile
nameRegex := d.Get(ecxL2SellerProfilesSchemaNames["NameRegex"]).(string)
metros := expandSetToStringList(d.Get(ecxL2SellerProfilesSchemaNames["Metros"]).(*schema.Set))
speedBands := expandSetToStringList(d.Get(ecxL2SellerProfilesSchemaNames["SpeedBands"]).(*schema.Set))
metros := internal.ExpandSetToStringList(d.Get(ecxL2SellerProfilesSchemaNames["Metros"]).(*schema.Set))
speedBands := internal.ExpandSetToStringList(d.Get(ecxL2SellerProfilesSchemaNames["SpeedBands"]).(*schema.Set))
orgName := d.Get(ecxL2SellerProfilesSchemaNames["OrganizationName"]).(string)
globalOrgName := d.Get(ecxL2SellerProfilesSchemaNames["GlobalOrganization"]).(string)
for _, profile := range profiles {
Expand Down
9 changes: 5 additions & 4 deletions equinix/data_source_metal_device.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"sort"
"strings"

"github.com/equinix/terraform-provider-equinix/internal"
"github.com/equinix/terraform-provider-equinix/internal/config"

metalv1 "github.com/equinix-labs/metal-go/metal/v1"
Expand Down Expand Up @@ -278,7 +279,7 @@ func dataSourceMetalDeviceRead(ctx context.Context, d *schema.ResourceData, meta
if device.HardwareReservation != nil {
d.Set("hardware_reservation_id", device.HardwareReservation.GetId())
}
networkType, err := getNetworkType(device)
networkType, err := internal.GetNetworkType(device)
if err != nil {
return fmt.Errorf("[ERR] Error computing network type for device (%s): %s", d.Id(), err)
}
Expand All @@ -292,22 +293,22 @@ func dataSourceMetalDeviceRead(ctx context.Context, d *schema.ResourceData, meta
keyIDs = append(keyIDs, path.Base(k.Href))
}
d.Set("ssh_key_ids", keyIDs)
networkInfo := getNetworkInfo(device.IpAddresses)
networkInfo := internal.GetNetworkInfo(device.IpAddresses)

sort.SliceStable(networkInfo.Networks, func(i, j int) bool {
famI := networkInfo.Networks[i]["family"].(int32)
famJ := networkInfo.Networks[j]["family"].(int32)
pubI := networkInfo.Networks[i]["public"].(bool)
pubJ := networkInfo.Networks[j]["public"].(bool)
return getNetworkRank(int(famI), pubI) < getNetworkRank(int(famJ), pubJ)
return internal.GetNetworkRank(int(famI), pubI) < internal.GetNetworkRank(int(famJ), pubJ)
})

d.Set("network", networkInfo.Networks)
d.Set("access_public_ipv4", networkInfo.PublicIPv4)
d.Set("access_private_ipv4", networkInfo.PrivateIPv4)
d.Set("access_public_ipv6", networkInfo.PublicIPv6)

ports := getPorts(device.NetworkPorts)
ports := internal.GetPorts(device.NetworkPorts)
d.Set("ports", ports)

d.SetId(device.GetId())
Expand Down
3 changes: 2 additions & 1 deletion equinix/data_source_metal_devices.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"

"github.com/equinix/terraform-provider-equinix/internal"
"github.com/equinix/terraform-provider-equinix/internal/config"

metalv1 "github.com/equinix-labs/metal-go/metal/v1"
Expand Down Expand Up @@ -95,5 +96,5 @@ func flattenDevice(rawDevice interface{}, meta interface{}, extra map[string]int
if !ok {
return nil, fmt.Errorf("expected device to be of type *metalv1.Device, got %T", rawDevice)
}
return getDeviceMap(device), nil
return internal.GetDeviceMap(device), nil
}
3 changes: 2 additions & 1 deletion equinix/data_source_network_device_software.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"sort"
"time"

"github.com/equinix/terraform-provider-equinix/internal"
"github.com/equinix/terraform-provider-equinix/internal/config"

"github.com/equinix/ne-go"
Expand Down Expand Up @@ -116,7 +117,7 @@ func dataSourceNetworkDeviceSoftwareRead(ctx context.Context, d *schema.Resource
conf := m.(*config.Config)
var diags diag.Diagnostics
typeCode := d.Get(networkDeviceSoftwareSchemaNames["DeviceTypeCode"]).(string)
pkgCodes := expandSetToStringList(d.Get(networkDeviceSoftwareSchemaNames["PackageCodes"]).(*schema.Set))
pkgCodes := internal.ExpandSetToStringList(d.Get(networkDeviceSoftwareSchemaNames["PackageCodes"]).(*schema.Set))
versions, err := conf.Ne.GetDeviceSoftwareVersions(typeCode)
if err != nil {
return diag.FromErr(err)
Expand Down
4 changes: 3 additions & 1 deletion equinix/data_source_network_device_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"strings"

"github.com/equinix/terraform-provider-equinix/internal"

"github.com/equinix/terraform-provider-equinix/internal/config"

"github.com/equinix/ne-go"
Expand Down Expand Up @@ -89,7 +91,7 @@ func dataSourceNetworkDeviceTypeRead(ctx context.Context, d *schema.ResourceData
name := d.Get(networkDeviceTypeSchemaNames["Name"]).(string)
vendor := d.Get(networkDeviceTypeSchemaNames["Vendor"]).(string)
category := d.Get(networkDeviceTypeSchemaNames["Category"]).(string)
metroCodes := expandSetToStringList(d.Get(networkDeviceTypeSchemaNames["MetroCodes"]).(*schema.Set))
metroCodes := internal.ExpandSetToStringList(d.Get(networkDeviceTypeSchemaNames["MetroCodes"]).(*schema.Set))
if err != nil {
return diag.FromErr(err)
}
Expand Down
8 changes: 5 additions & 3 deletions equinix/data_source_network_platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"fmt"

"github.com/equinix/terraform-provider-equinix/internal"

"github.com/equinix/terraform-provider-equinix/internal/config"

"github.com/equinix/ne-go"
Expand Down Expand Up @@ -122,19 +124,19 @@ func dataSourceNetworkDevicePlatformRead(ctx context.Context, d *schema.Resource
continue
}
if v, ok := d.GetOk(networkDevicePlatformSchemaNames["PackageCodes"]); ok {
pkgCodes := expandSetToStringList(v.(*schema.Set))
pkgCodes := internal.ExpandSetToStringList(v.(*schema.Set))
if !stringsFound(pkgCodes, platform.PackageCodes) {
continue
}
}
if v, ok := d.GetOk(networkDevicePlatformSchemaNames["ManagementTypes"]); ok {
mgmtTypes := expandSetToStringList(v.(*schema.Set))
mgmtTypes := internal.ExpandSetToStringList(v.(*schema.Set))
if !stringsFound(mgmtTypes, platform.ManagementTypes) {
continue
}
}
if v, ok := d.GetOk(networkDevicePlatformSchemaNames["LicenseOptions"]); ok {
licOptions := expandSetToStringList(v.(*schema.Set))
licOptions := internal.ExpandSetToStringList(v.(*schema.Set))
if !stringsFound(licOptions, platform.LicenseOptions) {
continue
}
Expand Down
Loading

0 comments on commit 9a5b481

Please sign in to comment.