diff --git a/equinix/resource_metal_spot_market_request.go b/equinix/resource_metal_spot_market_request.go index 17464e01a..b44c11017 100644 --- a/equinix/resource_metal_spot_market_request.go +++ b/equinix/resource_metal_spot_market_request.go @@ -67,10 +67,7 @@ func resourceMetalSpotMarketRequest() *schema.Resource { diffThreshold := .02 priceDiff := oldF / newF - if diffThreshold < priceDiff { - return true - } - return false + return diffThreshold < priceDiff }, }, "facilities": { diff --git a/internal/resources/metal/device/datasource.go b/internal/resources/metal/device/datasource.go index f11d412cb..fc7ef75e3 100644 --- a/internal/resources/metal/device/datasource.go +++ b/internal/resources/metal/device/datasource.go @@ -3,6 +3,7 @@ package device import ( "context" "encoding/json" + "errors" "fmt" "path" "sort" @@ -253,21 +254,23 @@ func dataSourceMetalDeviceRead(ctx context.Context, d *schema.ResourceData, meta } } - d.Set("hostname", device.GetHostname()) - d.Set("project_id", device.Project.GetId()) - d.Set("device_id", device.GetId()) - d.Set("plan", device.Plan.Slug) - d.Set("facility", device.Facility.Code) + var errs []error + + errs = append(errs, d.Set("hostname", device.GetHostname())) + errs = append(errs, d.Set("project_id", device.Project.GetId())) + errs = append(errs, d.Set("device_id", device.GetId())) + errs = append(errs, d.Set("plan", device.Plan.Slug)) + errs = append(errs, d.Set("facility", device.Facility.Code)) if device.Metro != nil { - d.Set("metro", strings.ToLower(device.Metro.GetCode())) + errs = append(errs, d.Set("metro", strings.ToLower(device.Metro.GetCode()))) } - d.Set("operating_system", device.OperatingSystem.GetSlug()) - d.Set("state", device.GetState()) - d.Set("billing_cycle", device.GetBillingCycle()) - d.Set("ipxe_script_url", device.GetIpxeScriptUrl()) - d.Set("always_pxe", device.GetAlwaysPxe()) - d.Set("root_password", device.GetRootPassword()) - d.Set("sos_hostname", device.GetSos()) + errs = append(errs, d.Set("operating_system", device.OperatingSystem.GetSlug())) + errs = append(errs, d.Set("state", device.GetState())) + errs = append(errs, d.Set("billing_cycle", device.GetBillingCycle())) + errs = append(errs, d.Set("ipxe_script_url", device.GetIpxeScriptUrl())) + errs = append(errs, d.Set("always_pxe", device.GetAlwaysPxe())) + errs = append(errs, d.Set("root_password", device.GetRootPassword())) + errs = append(errs, d.Set("sos_hostname", device.GetSos())) if device.Storage != nil { rawStorageBytes, err := json.Marshal(device.Storage) @@ -279,26 +282,26 @@ func dataSourceMetalDeviceRead(ctx context.Context, d *schema.ResourceData, meta if err != nil { return diag.Errorf("[ERR] Error normalizing storage JSON string for device (%s): %s", d.Id(), err) } - d.Set("storage", storageString) + errs = append(errs, d.Set("storage", storageString)) } if device.HardwareReservation != nil { - d.Set("hardware_reservation_id", device.HardwareReservation.GetId()) + errs = append(errs, d.Set("hardware_reservation_id", device.HardwareReservation.GetId())) } networkType, err := getNetworkType(device) if err != nil { return diag.Errorf("[ERR] Error computing network type for device (%s): %s", d.Id(), err) } - d.Set("network_type", networkType) + errs = append(errs, d.Set("network_type", networkType)) - d.Set("tags", device.Tags) + errs = append(errs, d.Set("tags", device.Tags)) keyIDs := []string{} for _, k := range device.SshKeys { keyIDs = append(keyIDs, path.Base(k.Href)) } - d.Set("ssh_key_ids", keyIDs) + errs = append(errs, d.Set("ssh_key_ids", keyIDs)) networkInfo := getNetworkInfo(device.IpAddresses) sort.SliceStable(networkInfo.Networks, func(i, j int) bool { @@ -309,15 +312,21 @@ func dataSourceMetalDeviceRead(ctx context.Context, d *schema.ResourceData, meta return getNetworkRank(int(famI), pubI) < 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) + errs = append(errs, d.Set("network", networkInfo.Networks)) + errs = append(errs, d.Set("access_public_ipv4", networkInfo.PublicIPv4)) + errs = append(errs, d.Set("access_private_ipv4", networkInfo.PrivateIPv4)) + errs = append(errs, d.Set("access_public_ipv6", networkInfo.PublicIPv6)) ports := getPorts(device.NetworkPorts) - d.Set("ports", ports) + errs = append(errs, d.Set("ports", ports)) d.SetId(device.GetId()) + + err = errors.Join(errs...) + if err != nil { + return diag.FromErr(err) + } + return nil } diff --git a/internal/resources/metal/device/helpers_test.go b/internal/resources/metal/device/helpers_test.go index 43b7a5987..c852a9b52 100644 --- a/internal/resources/metal/device/helpers_test.go +++ b/internal/resources/metal/device/helpers_test.go @@ -2,6 +2,7 @@ package device_test import ( "context" + "log" "net/http" "net/http/httptest" "strings" @@ -76,7 +77,11 @@ func Test_WaitUntilReservationProvisionable(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.Header().Add("X-Request-Id", "needed for equinix_errors.FriendlyError") w.WriteHeader(http.StatusOK) - w.Write(body) + _, err = w.Write(body) + if err != nil { + // This should never be reached and indicates a failure in the test itself + panic(err) + } } })(), }, @@ -119,7 +124,11 @@ func Test_WaitUntilReservationProvisionable(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.Header().Add("X-Request-Id", "needed for equinix_errors.FriendlyError") w.WriteHeader(http.StatusOK) - w.Write(body) + _, err = w.Write(body) + if err != nil { + // This should never be reached and indicates a failure in the test itself + panic(err) + } } })(), }, @@ -144,7 +153,11 @@ func Test_WaitUntilReservationProvisionable(t *testing.T) { w.Header().Add("Content-Type", "application/json") w.Header().Add("X-Request-Id", "needed for equinix_errors.FriendlyError") w.WriteHeader(http.StatusOK) - w.Write(body) + _, err = w.Write(body) + if err != nil { + // This should never be reached and indicates a failure in the test itself + panic(err) + } }, }, wantErr: true, @@ -160,7 +173,10 @@ func Test_WaitUntilReservationProvisionable(t *testing.T) { BaseURL: mockAPI.URL, Token: "fakeTokenForMock", } - meta.Load(ctx) + err := meta.Load(ctx) + if err != nil { + log.Printf("failed to load provider config during test: %v", err) + } client := meta.NewMetalClientForTesting() if err := device.WaitUntilReservationProvisionable(ctx, client, tt.args.reservationId, tt.args.instanceId, 50*time.Millisecond, 1*time.Second, 50*time.Millisecond); (err != nil) != tt.wantErr { diff --git a/internal/resources/metal/device/resource.go b/internal/resources/metal/device/resource.go index a4f3c0fc9..9405998aa 100644 --- a/internal/resources/metal/device/resource.go +++ b/internal/resources/metal/device/resource.go @@ -589,24 +589,25 @@ func Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Di return diag.FromErr(err) } - d.Set("hostname", device.GetHostname()) - d.Set("plan", device.Plan.GetSlug()) - d.Set("deployed_facility", device.Facility.GetCode()) - d.Set("facilities", []string{device.Facility.GetCode()}) + var errs []error + errs = append(errs, d.Set("hostname", device.GetHostname())) + errs = append(errs, d.Set("plan", device.Plan.GetSlug())) + errs = append(errs, d.Set("deployed_facility", device.Facility.GetCode())) + errs = append(errs, d.Set("facilities", []string{device.Facility.GetCode()})) if device.Metro != nil { - d.Set("metro", device.Metro.GetCode()) + errs = append(errs, d.Set("metro", device.Metro.GetCode())) } - d.Set("operating_system", device.OperatingSystem.GetSlug()) - d.Set("state", device.GetState()) - d.Set("billing_cycle", device.GetBillingCycle()) - d.Set("locked", device.GetLocked()) - d.Set("created", device.GetCreatedAt().Format(time.RFC3339)) - d.Set("updated", device.GetUpdatedAt().Format(time.RFC3339)) - d.Set("ipxe_script_url", device.GetIpxeScriptUrl()) - d.Set("always_pxe", device.GetAlwaysPxe()) - d.Set("root_password", device.GetRootPassword()) - d.Set("project_id", device.Project.GetId()) - d.Set("sos_hostname", device.GetSos()) + errs = append(errs, d.Set("operating_system", device.OperatingSystem.GetSlug())) + errs = append(errs, d.Set("state", device.GetState())) + errs = append(errs, d.Set("billing_cycle", device.GetBillingCycle())) + errs = append(errs, d.Set("locked", device.GetLocked())) + errs = append(errs, d.Set("created", device.GetCreatedAt().Format(time.RFC3339))) + errs = append(errs, d.Set("updated", device.GetUpdatedAt().Format(time.RFC3339))) + errs = append(errs, d.Set("ipxe_script_url", device.GetIpxeScriptUrl())) + errs = append(errs, d.Set("always_pxe", device.GetAlwaysPxe())) + errs = append(errs, d.Set("root_password", device.GetRootPassword())) + errs = append(errs, d.Set("project_id", device.Project.GetId())) + errs = append(errs, d.Set("sos_hostname", device.GetSos())) if device.Storage != nil { rawStorageBytes, err := json.Marshal(device.Storage) if err != nil { @@ -617,37 +618,37 @@ func Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Di if err != nil { return diag.Errorf("[ERR] Error normalizing storage JSON string for device (%s): %s", d.Id(), err) } - d.Set("storage", storageString) + errs = append(errs, d.Set("storage", storageString)) } if device.HardwareReservation != nil { - d.Set("deployed_hardware_reservation_id", device.HardwareReservation.GetId()) + errs = append(errs, d.Set("deployed_hardware_reservation_id", device.HardwareReservation.GetId())) } networkType, err := getNetworkType(device) if err != nil { return diag.Errorf("[ERR] Error computing network type for device (%s): %s", d.Id(), err) } - d.Set("network_type", networkType) + errs = append(errs, d.Set("network_type", networkType)) wfrd := "wait_for_reservation_deprovision" if _, ok := d.GetOk(wfrd); !ok { - d.Set(wfrd, nil) + errs = append(errs, d.Set(wfrd, nil)) } fdv := "force_detach_volumes" if _, ok := d.GetOk(fdv); !ok { - d.Set(fdv, nil) + errs = append(errs, d.Set(fdv, nil)) } tt := "termination_time" if _, ok := d.GetOk(tt); !ok { - d.Set(tt, nil) + errs = append(errs, d.Set(tt, nil)) } - d.Set("tags", device.Tags) + errs = append(errs, d.Set("tags", device.Tags)) keyIDs := []string{} for _, k := range device.SshKeys { keyIDs = append(keyIDs, path.Base(k.Href)) } - d.Set("ssh_key_ids", keyIDs) + errs = append(errs, d.Set("ssh_key_ids", keyIDs)) networkInfo := getNetworkInfo(device.IpAddresses) sort.SliceStable(networkInfo.Networks, func(i, j int) bool { @@ -658,13 +659,13 @@ func Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Di return getNetworkRank(int(famI), pubI) < 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) + errs = append(errs, d.Set("network", networkInfo.Networks)) + errs = append(errs, d.Set("access_public_ipv4", networkInfo.PublicIPv4)) + errs = append(errs, d.Set("access_private_ipv4", networkInfo.PrivateIPv4)) + errs = append(errs, d.Set("access_public_ipv6", networkInfo.PublicIPv6)) ports := getPorts(device.NetworkPorts) - d.Set("ports", ports) + errs = append(errs, d.Set("ports", ports)) if networkInfo.Host != "" { d.SetConnInfo(map[string]string{ @@ -673,6 +674,11 @@ func Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Di }) } + err = errors.Join(errs...) + if err != nil { + return diag.FromErr(err) + } + return nil } diff --git a/internal/resources/metal/device/resource_test.go b/internal/resources/metal/device/resource_test.go index 40e370e43..6f0c37b7f 100644 --- a/internal/resources/metal/device/resource_test.go +++ b/internal/resources/metal/device/resource_test.go @@ -3,6 +3,7 @@ package device_test import ( "context" "fmt" + "log" "net" "net/http" "net/http/httptest" @@ -118,7 +119,11 @@ func TestMetalDevice_readErrorHandling(t *testing.T) { BaseURL: mockAPI.URL, Token: "fakeTokenForMock", } - meta.Load(ctx) + + err := meta.Load(ctx) + if err != nil { + log.Printf("failed to load provider config during test: %v", err) + } if err := device.Read(ctx, d, meta); (err != nil) != tt.wantErr { t.Errorf("device.Read() error = %v, wantErr %v", err, tt.wantErr)