diff --git a/equinix/data_source_metal_facility.go b/equinix/data_source_metal_facility.go index 5ed6d0230..5398fd21a 100644 --- a/equinix/data_source_metal_facility.go +++ b/equinix/data_source_metal_facility.go @@ -4,6 +4,8 @@ import ( "fmt" "strings" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -122,7 +124,7 @@ func dataSourceMetalFacilityRead(d *schema.ResourceData, meta interface{}) error } } d.SetId(f.ID) - return setMap(d, map[string]interface{}{ + return equinix_schema.SetMap(d, map[string]interface{}{ "code": f.Code, "name": f.Name, "features": f.Features, diff --git a/equinix/data_source_metal_hardware_reservation.go b/equinix/data_source_metal_hardware_reservation.go index bf53fc971..92184a8bd 100644 --- a/equinix/data_source_metal_hardware_reservation.go +++ b/equinix/data_source_metal_hardware_reservation.go @@ -3,6 +3,8 @@ package equinix import ( "fmt" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -118,5 +120,5 @@ func dataSourceMetalHardwareReservationRead(d *schema.ResourceData, meta interfa } d.SetId(hr.ID) - return setMap(d, m) + return equinix_schema.SetMap(d, m) } diff --git a/equinix/data_source_metal_metro.go b/equinix/data_source_metal_metro.go index fa4be8505..4806eeccc 100644 --- a/equinix/data_source_metal_metro.go +++ b/equinix/data_source_metal_metro.go @@ -3,6 +3,8 @@ package equinix import ( "fmt" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -70,7 +72,7 @@ func dataSourceMetalMetroRead(d *schema.ResourceData, meta interface{}) error { for _, m := range metros { if m.Code == code { d.SetId(m.ID) - return setMap(d, map[string]interface{}{ + return equinix_schema.SetMap(d, map[string]interface{}{ "id": m.ID, "code": m.Code, "name": m.Name, diff --git a/equinix/data_source_metal_organization.go b/equinix/data_source_metal_organization.go index b47453eb3..8a2003e3a 100644 --- a/equinix/data_source_metal_organization.go +++ b/equinix/data_source_metal_organization.go @@ -4,6 +4,8 @@ import ( "fmt" "path" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -147,7 +149,7 @@ func dataSourceMetalOrganizationRead(d *schema.ResourceData, meta interface{}) e } d.SetId(org.ID) - return setMap(d, map[string]interface{}{ + return equinix_schema.SetMap(d, map[string]interface{}{ "organization_id": org.ID, "name": org.Name, "description": org.Description, diff --git a/equinix/data_source_metal_project.go b/equinix/data_source_metal_project.go index c8573b9c5..d5136425d 100644 --- a/equinix/data_source_metal_project.go +++ b/equinix/data_source_metal_project.go @@ -5,6 +5,7 @@ import ( "path" "github.com/equinix/terraform-provider-equinix/internal/config" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -157,7 +158,7 @@ func dataSourceMetalProjectRead(d *schema.ResourceData, meta interface{}) error if bgpConf.ID != "" { err := d.Set("bgp_config", flattenBGPConfig(bgpConf)) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) return err } } diff --git a/equinix/data_source_metal_project_ssh_key.go b/equinix/data_source_metal_project_ssh_key.go index f1c915197..e20013c4c 100644 --- a/equinix/data_source_metal_project_ssh_key.go +++ b/equinix/data_source_metal_project_ssh_key.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/equinix/terraform-provider-equinix/internal/config" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -86,7 +87,7 @@ func dataSourceMetalProjectSSHKeyRead(d *schema.ResourceData, meta interface{}) } keys, _, err := client.Projects.ListSSHKeys(projectID, searchOpts) if err != nil { - err = fmt.Errorf("Error listing project ssh keys: %s", friendlyError(err)) + err = fmt.Errorf("Error listing project ssh keys: %s", equinix_errors.FriendlyError(err)) return err } diff --git a/equinix/data_source_metal_spot_market_request.go b/equinix/data_source_metal_spot_market_request.go index 0d0064ea7..43071534a 100644 --- a/equinix/data_source_metal_spot_market_request.go +++ b/equinix/data_source_metal_spot_market_request.go @@ -6,6 +6,9 @@ import ( "strings" "time" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -81,8 +84,8 @@ func dataSourceMetalSpotMarketRequestRead(ctx context.Context, d *schema.Resourc smr, _, err := client.SpotMarketRequests.Get(id, &packngo.GetOptions{Includes: []string{"project", "devices", "facilities", "metro"}}) if err != nil { - err = friendlyError(err) - if isNotFound(err) { + err = equinix_errors.FriendlyError(err) + if equinix_errors.IsNotFound(err) { d.SetId("") return nil } @@ -104,7 +107,7 @@ func dataSourceMetalSpotMarketRequestRead(ctx context.Context, d *schema.Resourc d.SetId(id) - return setMap(d, map[string]interface{}{ + return equinix_schema.SetMap(d, map[string]interface{}{ "device_ids": deviceIDs, "end_at": func(d *schema.ResourceData, k string) error { if smr.EndAt != nil { diff --git a/equinix/data_source_metal_vlan.go b/equinix/data_source_metal_vlan.go index 81c81ddef..cb87258f2 100644 --- a/equinix/data_source_metal_vlan.go +++ b/equinix/data_source_metal_vlan.go @@ -3,6 +3,9 @@ package equinix import ( "fmt" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -78,7 +81,7 @@ func dataSourceMetalVlanRead(d *schema.ResourceData, meta interface{}) error { facilityRaw, facilityOk := d.GetOk("facility") if !(vlanIdOk || (vxlanOk || projectOk || metroOk || facilityOk)) { - return friendlyError(fmt.Errorf("You must set either vlan_id or a combination of vxlan, project_id, and, metro or facility")) + return equinix_errors.FriendlyError(fmt.Errorf("You must set either vlan_id or a combination of vxlan, project_id, and, metro or facility")) } var vlan *packngo.VirtualNetwork @@ -90,7 +93,7 @@ func dataSourceMetalVlanRead(d *schema.ResourceData, meta interface{}) error { &packngo.GetOptions{Includes: []string{"assigned_to"}}, ) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } else { @@ -103,12 +106,12 @@ func dataSourceMetalVlanRead(d *schema.ResourceData, meta interface{}) error { &packngo.GetOptions{Includes: []string{"assigned_to"}}, ) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } vlan, err = matchingVlan(vlans.VirtualNetworks, vxlan, projectID, facility, metro) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } @@ -119,7 +122,7 @@ func dataSourceMetalVlanRead(d *schema.ResourceData, meta interface{}) error { d.SetId(vlan.ID) - return setMap(d, map[string]interface{}{ + return equinix_schema.SetMap(d, map[string]interface{}{ "vlan_id": vlan.ID, "project_id": vlan.Project.ID, "vxlan": vlan.VXLAN, @@ -144,11 +147,11 @@ func matchingVlan(vlans []packngo.VirtualNetwork, vxlan int, projectID, facility matches = append(matches, v) } if len(matches) > 1 { - return nil, friendlyError(fmt.Errorf("Project %s has more than one matching VLAN", projectID)) + return nil, equinix_errors.FriendlyError(fmt.Errorf("Project %s has more than one matching VLAN", projectID)) } if len(matches) == 0 { - return nil, friendlyError(fmt.Errorf("Project %s does not have matching VLANs", projectID)) + return nil, equinix_errors.FriendlyError(fmt.Errorf("Project %s does not have matching VLANs", projectID)) } return &matches[0], nil } diff --git a/equinix/helpers_device.go b/equinix/helpers_device.go index fcf26c1f8..0428203bd 100644 --- a/equinix/helpers_device.go +++ b/equinix/helpers_device.go @@ -12,6 +12,8 @@ import ( "sync" "time" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + metalv1 "github.com/equinix-labs/metal-go/metal/v1" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -144,7 +146,7 @@ func hwReservationStateRefreshFunc(client *packngo.Client, reservationId, instan state := deprovisioning switch { case err != nil: - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) state = errstate case r != nil && r.Provisionable: state = provisionable diff --git a/equinix/resource_fabric_cloud_router.go b/equinix/resource_fabric_cloud_router.go index ff827a656..6e0a99b4c 100644 --- a/equinix/resource_fabric_cloud_router.go +++ b/equinix/resource_fabric_cloud_router.go @@ -7,6 +7,8 @@ import ( "strings" "time" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" v4 "github.com/equinix-labs/fabric-go/fabric/v4" @@ -98,7 +100,7 @@ func resourceCloudRouterRead(ctx context.Context, d *schema.ResourceData, meta i func setCloudRouterMap(d *schema.ResourceData, fcr v4.CloudRouter) diag.Diagnostics { diags := diag.Diagnostics{} - err := setMap(d, map[string]interface{}{ + err := equinix_schema.SetMap(d, map[string]interface{}{ "name": fcr.Name, "href": fcr.Href, "type": fcr.Type_, diff --git a/equinix/resource_fabric_connection.go b/equinix/resource_fabric_connection.go index d592726ba..d9e10635b 100644 --- a/equinix/resource_fabric_connection.go +++ b/equinix/resource_fabric_connection.go @@ -7,6 +7,8 @@ import ( "strings" "time" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" v4 "github.com/equinix-labs/fabric-go/fabric/v4" @@ -172,7 +174,7 @@ func resourceFabricConnectionRead(ctx context.Context, d *schema.ResourceData, m func setFabricMap(d *schema.ResourceData, conn v4.Connection) diag.Diagnostics { diags := diag.Diagnostics{} - err := setMap(d, map[string]interface{}{ + err := equinix_schema.SetMap(d, map[string]interface{}{ "name": conn.Name, "bandwidth": conn.Bandwidth, "href": conn.Href, diff --git a/equinix/resource_fabric_port.go b/equinix/resource_fabric_port.go index db90bb0f9..8d6228873 100644 --- a/equinix/resource_fabric_port.go +++ b/equinix/resource_fabric_port.go @@ -8,6 +8,8 @@ import ( "runtime/debug" "strings" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/antihax/optional" @@ -33,7 +35,7 @@ func resourceFabricPortRead(ctx context.Context, d *schema.ResourceData, meta in func setFabricPortMap(d *schema.ResourceData, port v4.Port) diag.Diagnostics { diags := diag.Diagnostics{} - err := setMap(d, map[string]interface{}{ + err := equinix_schema.SetMap(d, map[string]interface{}{ "name": port.Name, "bandwidth": port.Bandwidth, "available_bandwidth": port.AvailableBandwidth, @@ -60,7 +62,7 @@ func setFabricPortMap(d *schema.ResourceData, port v4.Port) diag.Diagnostics { func setPortsListMap(d *schema.ResourceData, spl v4.AllPortsResponse) diag.Diagnostics { diags := diag.Diagnostics{} - err := setMap(d, map[string]interface{}{ + err := equinix_schema.SetMap(d, map[string]interface{}{ "data": fabricPortsListToTerra(spl), }) if err != nil { diff --git a/equinix/resource_fabric_routing_protocol.go b/equinix/resource_fabric_routing_protocol.go index 21341e2b3..639e6d088 100644 --- a/equinix/resource_fabric_routing_protocol.go +++ b/equinix/resource_fabric_routing_protocol.go @@ -8,6 +8,8 @@ import ( "strings" "time" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -280,7 +282,7 @@ func setFabricRoutingProtocolMap(d *schema.ResourceData, rp v4.RoutingProtocolDa err := error(nil) if rp.Type_ == "BGP" { - err = setMap(d, map[string]interface{}{ + err = equinix_schema.SetMap(d, map[string]interface{}{ "name": rp.RoutingProtocolBgpData.Name, "href": rp.RoutingProtocolBgpData.Href, "type": rp.RoutingProtocolBgpData.Type_, @@ -296,7 +298,7 @@ func setFabricRoutingProtocolMap(d *schema.ResourceData, rp v4.RoutingProtocolDa "change_log": changeLogToTerra(rp.RoutingProtocolBgpData.Changelog), }) } else if rp.Type_ == "DIRECT" { - err = setMap(d, map[string]interface{}{ + err = equinix_schema.SetMap(d, map[string]interface{}{ "name": rp.RoutingProtocolDirectData.Name, "href": rp.RoutingProtocolDirectData.Href, "type": rp.RoutingProtocolDirectData.Type_, diff --git a/equinix/resource_fabric_service_profile.go b/equinix/resource_fabric_service_profile.go index 9d21c89e9..0883bbc30 100644 --- a/equinix/resource_fabric_service_profile.go +++ b/equinix/resource_fabric_service_profile.go @@ -9,6 +9,8 @@ import ( "strings" "time" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/antihax/optional" "github.com/equinix/terraform-provider-equinix/internal/config" @@ -236,7 +238,7 @@ func resourceFabricServiceProfileDelete(ctx context.Context, d *schema.ResourceD func setFabricServiceProfileMap(d *schema.ResourceData, sp v4.ServiceProfile) diag.Diagnostics { diags := diag.Diagnostics{} - err := setMap(d, map[string]interface{}{ + err := equinix_schema.SetMap(d, map[string]interface{}{ "href": sp.Href, "type": sp.Type_, "name": sp.Name, @@ -265,7 +267,7 @@ func setFabricServiceProfileMap(d *schema.ResourceData, sp v4.ServiceProfile) di func setFabricServiceProfilesListMap(d *schema.ResourceData, spl v4.ServiceProfiles) diag.Diagnostics { diags := diag.Diagnostics{} - err := setMap(d, map[string]interface{}{ + err := equinix_schema.SetMap(d, map[string]interface{}{ "data": fabricServiceProfilesListToTerra(spl), }) if err != nil { diff --git a/equinix/resource_metal_bgp_session.go b/equinix/resource_metal_bgp_session.go index 767776aec..f1a83e9db 100644 --- a/equinix/resource_metal_bgp_session.go +++ b/equinix/resource_metal_bgp_session.go @@ -3,6 +3,8 @@ package equinix import ( "log" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -64,7 +66,7 @@ func resourceMetalBGPSessionCreate(d *schema.ResourceData, meta interface{}) err DefaultRoute: &defaultRoute, }) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } d.SetId(bgpSession.ID) @@ -78,8 +80,8 @@ func resourceMetalBGPSessionRead(d *schema.ResourceData, meta interface{}) error bgpSession, _, err := client.BGPSessions.Get(d.Id(), &packngo.GetOptions{Includes: []string{"device"}}) if err != nil { - err = friendlyError(err) - if isNotFound(err) { + err = equinix_errors.FriendlyError(err) + if equinix_errors.IsNotFound(err) { log.Printf("[WARN] BGP Session (%s) not found, removing from state", d.Id()) d.SetId("") @@ -105,5 +107,5 @@ func resourceMetalBGPSessionDelete(d *schema.ResourceData, meta interface{}) err meta.(*config.Config).AddModuleToMetalUserAgent(d) client := meta.(*config.Config).Metal resp, err := client.BGPSessions.Delete(d.Id()) - return ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) + return equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) } diff --git a/equinix/resource_metal_connection.go b/equinix/resource_metal_connection.go index 98576b08d..1475b24b8 100644 --- a/equinix/resource_metal_connection.go +++ b/equinix/resource_metal_connection.go @@ -7,6 +7,9 @@ import ( "strconv" "strings" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -295,7 +298,7 @@ func resourceMetalConnectionCreate(d *schema.ResourceData, meta interface{}) err } proj, _, err := client.Projects.Get(projectId.(string), &packngo.GetOptions{Includes: []string{"organization"}}) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } organizationId = proj.Organization.ID } @@ -328,7 +331,7 @@ func resourceMetalConnectionUpdate(d *schema.ResourceData, meta interface{}) err action = client.Devices.Unlock } if _, err := action(d.Id()); err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } ur := packngo.ConnectionUpdateRequest{} @@ -362,13 +365,13 @@ func resourceMetalConnectionUpdate(d *schema.ResourceData, meta interface{}) err } ur.Tags = sts default: - return friendlyError(fmt.Errorf("garbage in tags: %s", ts)) + return equinix_errors.FriendlyError(fmt.Errorf("garbage in tags: %s", ts)) } } if !reflect.DeepEqual(ur, packngo.ConnectionUpdateRequest{}) { if _, _, err := client.Connections.Update(d.Id(), &ur, nil); err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } @@ -389,19 +392,19 @@ func resourceMetalConnectionUpdate(d *schema.ResourceData, meta interface{}) err if i+1 > len(newVlans) { // The VNID was removed; unassign the old VNID if _, _, err := updateHiddenVirtualCircuitVNID(client, ports[i].(map[string]interface{}), ""); err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } else { j := slices.Index(oldVlans, newVlans[i]) if j > i { // The VNID was moved to a different list index; unassign the VNID for the old index so that it is available for reassignment if _, _, err := updateHiddenVirtualCircuitVNID(client, ports[j].(map[string]interface{}), ""); err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } // Assign the VNID (whether it is new or moved) to the correct port if _, _, err := updateHiddenVirtualCircuitVNID(client, ports[i].(map[string]interface{}), strconv.Itoa(newVlans[i])); err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } } @@ -469,7 +472,7 @@ func resourceMetalConnectionRead(d *schema.ResourceData, meta interface{}) error d.Set("vlans", vlans) } - return setMap(d, map[string]interface{}{ + return equinix_schema.SetMap(d, map[string]interface{}{ "organization_id": conn.Organization.ID, "project_id": projectId, "contact_email": conn.ContactEmail, @@ -494,8 +497,8 @@ func resourceMetalConnectionDelete(d *schema.ResourceData, meta interface{}) err meta.(*config.Config).AddModuleToMetalUserAgent(d) client := meta.(*config.Config).Metal resp, err := client.Connections.Delete(d.Id(), true) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { - return friendlyError(err) + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { + return equinix_errors.FriendlyError(err) } return nil } diff --git a/equinix/resource_metal_device.go b/equinix/resource_metal_device.go index 8da8ece48..b47477428 100644 --- a/equinix/resource_metal_device.go +++ b/equinix/resource_metal_device.go @@ -12,6 +12,8 @@ import ( "sort" "time" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" @@ -534,13 +536,13 @@ func resourceMetalDeviceCreate(ctx context.Context, d *schema.ResourceData, meta } else { wfrd := "wait_for_reservation_deprovision" if d.Get(wfrd).(bool) { - return friendlyError(fmt.Errorf("You can't set %s when not using a hardware reservation", wfrd)) + return equinix_errors.FriendlyError(fmt.Errorf("You can't set %s when not using a hardware reservation", wfrd)) } } if createRequest.OS == "custom_ipxe" { if createRequest.IPXEScriptURL == "" && createRequest.UserData == "" { - return friendlyError(errors.New("\"ipxe_script_url\" or \"user_data\"" + + return equinix_errors.FriendlyError(errors.New("\"ipxe_script_url\" or \"user_data\"" + " must be provided when \"custom_ipxe\" OS is selected.")) } @@ -548,14 +550,14 @@ func resourceMetalDeviceCreate(ctx context.Context, d *schema.ResourceData, meta // which case it's an error. if createRequest.IPXEScriptURL != "" { if matchIPXEScript.MatchString(createRequest.UserData) { - return friendlyError(errors.New("\"user_data\" should not be an iPXE " + + return equinix_errors.FriendlyError(errors.New("\"user_data\" should not be an iPXE " + "script when \"ipxe_script_url\" is also provided.")) } } } if createRequest.OS != "custom_ipxe" && createRequest.IPXEScriptURL != "" { - return friendlyError(errors.New("\"ipxe_script_url\" argument provided, but" + + return equinix_errors.FriendlyError(errors.New("\"ipxe_script_url\" argument provided, but" + " OS is not \"custom_ipxe\". Please verify and fix device arguments.")) } @@ -594,8 +596,8 @@ func resourceMetalDeviceCreate(ctx context.Context, d *schema.ResourceData, meta start := time.Now() newDevice, _, err := client.Devices.Create(createRequest) if err != nil { - retErr := friendlyError(err) - if isNotFound(retErr) { + retErr := equinix_errors.FriendlyError(err) + if equinix_errors.IsNotFound(retErr) { retErr = fmt.Errorf("%s, make sure project \"%s\" exists", retErr, createRequest.ProjectID) } return retErr @@ -617,12 +619,12 @@ func resourceMetalDeviceRead(ctx context.Context, d *schema.ResourceData, meta i device, resp, err := client.DevicesApi.FindDeviceById(context.Background(), d.Id()).Include(deviceCommonIncludes).Execute() if err != nil { - err = friendlyErrorForMetalGo(err, resp) + err = equinix_errors.FriendlyErrorForMetalGo(err, resp) // If the device somehow already destroyed, mark as successfully gone. // Checking d.IsNewResource prevents the creation of a resource from failing // silently. Note d.IsNewResource is false in resource import operations. - if !d.IsNewResource() && (isNotFound(err) || isForbidden(err)) { + if !d.IsNewResource() && (equinix_errors.IsNotFound(err) || equinix_errors.IsForbidden(err)) { log.Printf("[WARN] Device (%s) not found or in failed status, removing from state", d.Id()) d.SetId("") return nil @@ -730,7 +732,7 @@ func resourceMetalDeviceUpdate(ctx context.Context, d *schema.ResourceData, meta action = client.Devices.Unlock } if _, err := action(d.Id()); err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } ur := packngo.DeviceUpdateRequest{} @@ -762,7 +764,7 @@ func resourceMetalDeviceUpdate(ctx context.Context, d *schema.ResourceData, meta } ur.Tags = &sts default: - return friendlyError(fmt.Errorf("garbage in tags: %s", ts)) + return equinix_errors.FriendlyError(fmt.Errorf("garbage in tags: %s", ts)) } } if d.HasChange("ipxe_script_url") { @@ -777,7 +779,7 @@ func resourceMetalDeviceUpdate(ctx context.Context, d *schema.ResourceData, meta start := time.Now() if !reflect.DeepEqual(ur, packngo.DeviceUpdateRequest{}) { if _, _, err := client.Devices.Update(d.Id(), &ur); err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } @@ -813,7 +815,7 @@ func doReinstall(ctx context.Context, client *packngo.Client, d *schema.Resource } if _, err := client.Devices.Reinstall(d.Id(), &reinstallOptions); err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } updateTimeout := d.Timeout(schema.TimeoutUpdate) - 30*time.Second - time.Since(start) @@ -838,8 +840,8 @@ func resourceMetalDeviceDelete(ctx context.Context, d *schema.ResourceData, meta start := time.Now() resp, err := client.Devices.Delete(d.Id(), fdv) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { - return friendlyError(err) + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { + return equinix_errors.FriendlyError(err) } resId, resIdOk := d.GetOk("deployed_hardware_reservation_id") @@ -885,8 +887,8 @@ func waitForActiveDevice(ctx context.Context, d *schema.ResourceData, meta inter state, err := waitForDeviceAttribute(ctx, d, stateConf) if err != nil { d.SetId("") - fErr := friendlyError(err) - if isForbidden(fErr) { + fErr := equinix_errors.FriendlyError(err) + if equinix_errors.IsForbidden(fErr) { // If the device doesn't get to the active state, we can't recover it from here. return errors.New("provisioning time limit exceeded; the Equinix Metal team will investigate") diff --git a/equinix/resource_metal_device_acc_test.go b/equinix/resource_metal_device_acc_test.go index 0822a1f88..df3fe412f 100644 --- a/equinix/resource_metal_device_acc_test.go +++ b/equinix/resource_metal_device_acc_test.go @@ -1038,7 +1038,7 @@ func TestAccMetalDevice_readErrorHandling(t *testing.T) { newResource: false, handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") - w.Header().Add("X-Request-Id", "needed for friendlyError") + w.Header().Add("X-Request-Id", "needed for equinix_errors.FriendlyError") w.WriteHeader(http.StatusForbidden) }, }, @@ -1050,7 +1050,7 @@ func TestAccMetalDevice_readErrorHandling(t *testing.T) { newResource: false, handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") - w.Header().Add("X-Request-Id", "needed for friendlyError") + w.Header().Add("X-Request-Id", "needed for equinix_errors.FriendlyError") w.WriteHeader(http.StatusNotFound) }, }, @@ -1062,7 +1062,7 @@ func TestAccMetalDevice_readErrorHandling(t *testing.T) { newResource: true, handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") - w.Header().Add("X-Request-Id", "needed for friendlyError") + w.Header().Add("X-Request-Id", "needed for equinix_errors.FriendlyError") w.WriteHeader(http.StatusForbidden) }, }, @@ -1074,7 +1074,7 @@ func TestAccMetalDevice_readErrorHandling(t *testing.T) { newResource: true, handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") - w.Header().Add("X-Request-Id", "needed for friendlyError") + w.Header().Add("X-Request-Id", "needed for equinix_errors.FriendlyError") w.WriteHeader(http.StatusNotFound) }, }, @@ -1086,7 +1086,7 @@ func TestAccMetalDevice_readErrorHandling(t *testing.T) { newResource: true, handler: func(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") - w.Header().Add("X-Request-Id", "needed for friendlyError") + w.Header().Add("X-Request-Id", "needed for equinix_errors.FriendlyError") w.WriteHeader(http.StatusBadRequest) }, }, diff --git a/equinix/resource_metal_device_network_type.go b/equinix/resource_metal_device_network_type.go index 87fa5dfa8..568903701 100644 --- a/equinix/resource_metal_device_network_type.go +++ b/equinix/resource_metal_device_network_type.go @@ -3,6 +3,8 @@ package equinix import ( "log" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -91,9 +93,9 @@ func resourceMetalDeviceNetworkTypeRead(d *schema.ResourceData, meta interface{} _, devNType, err := getDevIDandNetworkType(d, client) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { log.Printf("[WARN] Device (%s) for Network Type request not found, removing from state", d.Id()) d.SetId("") return nil diff --git a/equinix/resource_metal_gateway.go b/equinix/resource_metal_gateway.go index 2ca286212..0c9ceb6d9 100644 --- a/equinix/resource_metal_gateway.go +++ b/equinix/resource_metal_gateway.go @@ -4,6 +4,9 @@ import ( "fmt" "time" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" @@ -138,7 +141,7 @@ func resourceMetalGatewayRead(d *schema.ResourceData, meta interface{}) error { privateIPv4SubnetSize = 1 << (32 - mg.IPReservation.CIDR) } - return setMap(d, map[string]interface{}{ + return equinix_schema.SetMap(d, map[string]interface{}{ "project_id": mg.Project.ID, "vlan_id": mg.VirtualNetwork.ID, "ip_reservation_id": mg.IPReservation.ID, @@ -157,8 +160,8 @@ func resourceMetalGatewayDelete(d *schema.ResourceData, meta interface{}) error meta.(*config.Config).AddModuleToMetalUserAgent(d) client := meta.(*config.Config).Metal resp, err := client.MetalGateways.Delete(d.Id()) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { - return friendlyError(err) + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { + return equinix_errors.FriendlyError(err) } deleteWaiter := getGatewayStateWaiter( @@ -170,7 +173,7 @@ func resourceMetalGatewayDelete(d *schema.ResourceData, meta interface{}) error ) _, err = deleteWaiter.WaitForState() - if ignoreResponseErrors(httpForbidden, httpNotFound)(nil, err) != nil { + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(nil, err) != nil { return fmt.Errorf("Error deleting Metal Gateway %s: %s", d.Id(), err) } diff --git a/equinix/resource_metal_ip_attachment.go b/equinix/resource_metal_ip_attachment.go index 70579328a..1dfdf3370 100644 --- a/equinix/resource_metal_ip_attachment.go +++ b/equinix/resource_metal_ip_attachment.go @@ -5,6 +5,8 @@ import ( "log" "path" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -57,10 +59,10 @@ func resourceMetalIPAttachmentRead(d *schema.ResourceData, meta interface{}) err client := meta.(*config.Config).Metal assignment, _, err := client.DeviceIPs.Get(d.Id(), nil) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) // If the IP attachment was already destroyed, mark as succesfully gone. - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { log.Printf("[WARN] IP attachment (%q) not found, removing from state", d.Id()) d.SetId("") return nil @@ -93,8 +95,8 @@ func resourceMetalIPAttachmentDelete(d *schema.ResourceData, meta interface{}) e client := meta.(*config.Config).Metal resp, err := client.DeviceIPs.Unassign(d.Id()) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { - return friendlyError(err) + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { + return equinix_errors.FriendlyError(err) } d.SetId("") diff --git a/equinix/resource_metal_organization.go b/equinix/resource_metal_organization.go index 00fe088a8..d51dedf75 100644 --- a/equinix/resource_metal_organization.go +++ b/equinix/resource_metal_organization.go @@ -3,6 +3,9 @@ package equinix import ( "regexp" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -128,7 +131,7 @@ func resourceMetalOrganizationCreate(d *schema.ResourceData, meta interface{}) e org, _, err := client.Organizations.Create(createRequest) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } d.SetId(org.ID) @@ -142,10 +145,10 @@ func resourceMetalOrganizationRead(d *schema.ResourceData, meta interface{}) err key, _, err := client.Organizations.Get(d.Id(), &packngo.GetOptions{Includes: []string{"address"}}) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) // If the project somehow already destroyed, mark as succesfully gone. - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { d.SetId("") return nil @@ -155,7 +158,7 @@ func resourceMetalOrganizationRead(d *schema.ResourceData, meta interface{}) err } d.SetId(key.ID) - return setMap(d, map[string]interface{}{ + return equinix_schema.SetMap(d, map[string]interface{}{ "name": key.Name, "description": key.Description, "website": key.Website, @@ -198,7 +201,7 @@ func resourceMetalOrganizationUpdate(d *schema.ResourceData, meta interface{}) e _, _, err := client.Organizations.Update(d.Id(), updateRequest) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } return resourceMetalOrganizationRead(d, meta) @@ -209,8 +212,8 @@ func resourceMetalOrganizationDelete(d *schema.ResourceData, meta interface{}) e client := meta.(*config.Config).Metal resp, err := client.Organizations.Delete(d.Id()) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { - return friendlyError(err) + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { + return equinix_errors.FriendlyError(err) } d.SetId("") diff --git a/equinix/resource_metal_organization_member.go b/equinix/resource_metal_organization_member.go index 3e5c3abb8..b7023c554 100644 --- a/equinix/resource_metal_organization_member.go +++ b/equinix/resource_metal_organization_member.go @@ -6,6 +6,9 @@ import ( "path" "strings" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -132,7 +135,7 @@ func resourceMetalOrganizationMemberCreate(d *schema.ResourceData, meta interfac orgID := d.Get("organization_id").(string) _, _, err := client.Invitations.Create(orgID, createRequest, nil) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } d.SetId(fmt.Sprintf("%s:%s", email, orgID)) @@ -164,9 +167,9 @@ func resourceMetalOrganizationMemberRead(d *schema.ResourceData, meta interface{ listOpts := &packngo.ListOptions{Includes: []string{"user"}} invitations, _, err := client.Invitations.List(orgID, listOpts) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) // If the org was destroyed, mark as gone. - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { d.SetId("") return nil } @@ -175,9 +178,9 @@ func resourceMetalOrganizationMemberRead(d *schema.ResourceData, meta interface{ members, _, err := client.Members.List(orgID, &packngo.GetOptions{Includes: []string{"user"}}) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) // If the org was destroyed, mark as gone. - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { d.SetId("") return nil } @@ -195,7 +198,7 @@ func resourceMetalOrganizationMemberRead(d *schema.ResourceData, meta interface{ for _, project := range member.Member.Projects { projectIDs = append(projectIDs, path.Base(project.URL)) } - return setMap(d, map[string]interface{}{ + return equinix_schema.SetMap(d, map[string]interface{}{ "state": "active", "roles": stringArrToIfArr(member.Member.Roles), "projects_ids": stringArrToIfArr(projectIDs), @@ -206,7 +209,7 @@ func resourceMetalOrganizationMemberRead(d *schema.ResourceData, meta interface{ for _, project := range member.Invitation.Projects { projectIDs = append(projectIDs, path.Base(project.Href)) } - return setMap(d, map[string]interface{}{ + return equinix_schema.SetMap(d, map[string]interface{}{ "state": "invited", "organization_id": path.Base(member.Invitation.Organization.Href), "roles": member.Invitation.Roles, @@ -226,9 +229,9 @@ func resourceMetalOrganizationMemberDelete(d *schema.ResourceData, meta interfac listOpts := &packngo.ListOptions{Includes: []string{"user"}} invitations, _, err := client.Invitations.List(d.Get("organization_id").(string), listOpts) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) // If the org was destroyed, mark as gone. - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { d.SetId("") return nil } @@ -238,9 +241,9 @@ func resourceMetalOrganizationMemberDelete(d *schema.ResourceData, meta interfac orgID := d.Get("organization_id").(string) org, _, err := client.Organizations.Get(orgID, &packngo.GetOptions{Includes: []string{"members", "members.user"}}) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) // If the org was destroyed, mark as gone. - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { d.SetId("") return nil } @@ -256,9 +259,9 @@ func resourceMetalOrganizationMemberDelete(d *schema.ResourceData, meta interfac if member.isMember() { _, err = client.Members.Delete(orgID, member.Member.ID) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) // If the member was deleted, mark as gone. - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { d.SetId("") return nil } @@ -267,9 +270,9 @@ func resourceMetalOrganizationMemberDelete(d *schema.ResourceData, meta interfac } else if member.isInvitation() { _, err = client.Invitations.Delete(member.Invitation.ID) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) // If the invitation was deleted, mark as gone. - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { d.SetId("") return nil } diff --git a/equinix/resource_metal_port.go b/equinix/resource_metal_port.go index aec4fdf09..a37ef5d48 100644 --- a/equinix/resource_metal_port.go +++ b/equinix/resource_metal_port.go @@ -5,6 +5,9 @@ import ( "log" "time" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -123,7 +126,7 @@ func resourceMetalPortUpdate(ctx context.Context, d *schema.ResourceData, meta i start := time.Now() cpr, _, err := getClientPortResource(d, meta) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } for _, f := range [](func(*ClientPortResource) error){ @@ -137,7 +140,7 @@ func resourceMetalPortUpdate(ctx context.Context, d *schema.ResourceData, meta i updateNativeVlan, } { if err := f(cpr); err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } @@ -150,7 +153,7 @@ func resourceMetalPortRead(ctx context.Context, d *schema.ResourceData, meta int port, err := getPortByResourceData(d, client) if err != nil { - if isNotFound(err) || isForbidden(err) { + if equinix_errors.IsNotFound(err) || equinix_errors.IsForbidden(err) { log.Printf("[WARN] Port (%s) not accessible, removing from state", d.Id()) d.SetId("") @@ -196,7 +199,7 @@ func resourceMetalPortRead(ctx context.Context, d *schema.ResourceData, meta int } d.SetId(port.ID) - return setMap(d, m) + return equinix_schema.SetMap(d, m) } func resourceMetalPortDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) error { @@ -204,7 +207,7 @@ func resourceMetalPortDelete(ctx context.Context, d *schema.ResourceData, meta i if resetOk && resetRaw.(bool) { start := time.Now() cpr, resp, err := getClientPortResource(d, meta) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { return err } @@ -214,7 +217,7 @@ func resourceMetalPortDelete(ctx context.Context, d *schema.ResourceData, meta i port := resourceMetalPort() copy := port.Data(d.State()) cpr.Resource = copy - if err = setMap(cpr.Resource, map[string]interface{}{ + if err = equinix_schema.SetMap(cpr.Resource, map[string]interface{}{ "layer2": false, "bonded": true, "native_vlan_id": nil, diff --git a/equinix/resource_metal_port_vlan_attachment.go b/equinix/resource_metal_port_vlan_attachment.go index e72efa07b..900505567 100644 --- a/equinix/resource_metal_port_vlan_attachment.go +++ b/equinix/resource_metal_port_vlan_attachment.go @@ -4,6 +4,8 @@ import ( "fmt" "log" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -168,9 +170,9 @@ func resourceMetalPortVlanAttachmentRead(d *schema.ResourceData, meta interface{ dev, _, err := client.Devices.Get(deviceID, &packngo.GetOptions{Includes: []string{"virtual_networks,project,native_virtual_network"}}) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { log.Printf("[WARN] Device (%s) for Port Vlan Attachment not found, removing from state", d.Id()) d.SetId("") return nil @@ -244,7 +246,7 @@ func resourceMetalPortVlanAttachmentDelete(d *schema.ResourceData, meta interfac native := d.Get("native").(bool) if native { _, resp, err := client.DevicePorts.UnassignNative(pID) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { return err } } @@ -253,7 +255,7 @@ func resourceMetalPortVlanAttachmentDelete(d *schema.ResourceData, meta interfac metalMutexKV.Lock(lockId) defer metalMutexKV.Unlock(lockId) portPtr, resp, err := client.DevicePorts.Unassign(par) - if ignoreResponseErrors(httpForbidden, httpNotFound, isNotAssigned)(resp, err) != nil { + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound, equinix_errors.IsNotAssigned)(resp, err) != nil { return err } forceBond := d.Get("force_bond").(bool) @@ -262,11 +264,11 @@ func resourceMetalPortVlanAttachmentDelete(d *schema.ResourceData, meta interfac portName := d.Get("port_name").(string) port, err := client.DevicePorts.GetPortByName(deviceID, portName) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } _, _, err = client.DevicePorts.Bond(port, false) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } return nil diff --git a/equinix/resource_metal_project.go b/equinix/resource_metal_project.go index 31023a458..5a1cf3769 100644 --- a/equinix/resource_metal_project.go +++ b/equinix/resource_metal_project.go @@ -6,6 +6,8 @@ import ( "regexp" "strings" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -135,7 +137,7 @@ func resourceMetalProjectCreate(d *schema.ResourceData, meta interface{}) error project, _, err := client.Projects.Create(createRequest) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } d.SetId(project.ID) @@ -145,7 +147,7 @@ func resourceMetalProjectCreate(d *schema.ResourceData, meta interface{}) error bgpCR := expandBGPConfig(d) _, err := client.BGPConfig.Create(project.ID, bgpCR) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } @@ -154,7 +156,7 @@ func resourceMetalProjectCreate(d *schema.ResourceData, meta interface{}) error pur := packngo.ProjectUpdateRequest{BackendTransfer: &backendTransfer} _, _, err := client.Projects.Update(project.ID, &pur) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } return resourceMetalProjectRead(d, meta) @@ -166,10 +168,10 @@ func resourceMetalProjectRead(d *schema.ResourceData, meta interface{}) error { proj, _, err := client.Projects.Get(d.Id(), nil) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) // If the project somehow already destroyed, mark as successfully gone. - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { d.SetId("") return nil @@ -195,7 +197,7 @@ func resourceMetalProjectRead(d *schema.ResourceData, meta interface{}) error { if bgpConf.ID != "" { err := d.Set("bgp_config", flattenBGPConfig(bgpConf)) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) return err } } @@ -257,7 +259,7 @@ func resourceMetalProjectUpdate(d *schema.ResourceData, meta interface{}) error bgpCreateRequest := expandBGPConfig(d) _, err := client.BGPConfig.Create(d.Id(), bgpCreateRequest) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } else { if len(oldarr) == 1 { @@ -272,13 +274,13 @@ func resourceMetalProjectUpdate(d *schema.ResourceData, meta interface{}) error m["asn"].(int)) errStr := fmt.Errorf("BGP Config can not be removed from a project, please add back\n%s", bgpConfStr) - return friendlyError(errStr) + return equinix_errors.FriendlyError(errStr) } } } else { _, _, err := client.Projects.Update(d.Id(), updateRequest) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } @@ -290,8 +292,8 @@ func resourceMetalProjectDelete(d *schema.ResourceData, meta interface{}) error client := meta.(*config.Config).Metal resp, err := client.Projects.Delete(d.Id()) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { - return friendlyError(err) + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { + return equinix_errors.FriendlyError(err) } d.SetId("") diff --git a/equinix/resource_metal_project_api_key.go b/equinix/resource_metal_project_api_key.go index 6e8f078e2..2dc71b141 100644 --- a/equinix/resource_metal_project_api_key.go +++ b/equinix/resource_metal_project_api_key.go @@ -3,6 +3,9 @@ package equinix import ( "log" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -67,7 +70,7 @@ func resourceMetalAPIKeyCreate(d *schema.ResourceData, meta interface{}) error { apiKey, _, err := client.APIKeys.Create(createRequest) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } d.SetId(apiKey.ID) @@ -103,10 +106,10 @@ func resourceMetalAPIKeyRead(d *schema.ResourceData, meta interface{}) error { } if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) // If the key is somehow already destroyed, mark as // succesfully gone - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { log.Printf("[WARN] Project APIKey (%s) not found, removing from state", d.Id()) d.SetId("") return nil @@ -131,7 +134,7 @@ func resourceMetalAPIKeyRead(d *schema.ResourceData, meta interface{}) error { attrMap["user_id"] = apiKey.User.ID } - return setMap(d, attrMap) + return equinix_schema.SetMap(d, attrMap) } func resourceMetalAPIKeyDelete(d *schema.ResourceData, meta interface{}) error { @@ -139,8 +142,8 @@ func resourceMetalAPIKeyDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*config.Config).Metal resp, err := client.APIKeys.Delete(d.Id()) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { - return friendlyError(err) + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { + return equinix_errors.FriendlyError(err) } d.SetId("") diff --git a/equinix/resource_metal_reserved_ip_block.go b/equinix/resource_metal_reserved_ip_block.go index 7e37fc540..c51801811 100644 --- a/equinix/resource_metal_reserved_ip_block.go +++ b/equinix/resource_metal_reserved_ip_block.go @@ -9,6 +9,9 @@ import ( "strings" "time" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" @@ -455,7 +458,7 @@ func loadBlock(d *schema.ResourceData, reservedBlock *packngo.IPAddressReservati } } - return setMap(d, attributeMap) + return equinix_schema.SetMap(d, attributeMap) } func resourceMetalReservedIPBlockRead(ctx context.Context, d *schema.ResourceData, meta interface{}) error { @@ -468,8 +471,8 @@ func resourceMetalReservedIPBlockRead(ctx context.Context, d *schema.ResourceDat reservedBlock, _, err := client.ProjectIPs.Get(id, getOpts) if err != nil { - err = friendlyError(err) - if isNotFound(err) { + err = equinix_errors.FriendlyError(err) + if equinix_errors.IsNotFound(err) { log.Printf("[WARN] Reserved IP Block (%s) not found, removing from state", d.Id()) d.SetId("") return nil @@ -497,7 +500,7 @@ func resourceMetalReservedIPBlockDelete(ctx context.Context, d *schema.ResourceD resp, err := client.ProjectIPs.Remove(id) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { return fmt.Errorf("error deleting IP reservation block %s: %s", id, err) } diff --git a/equinix/resource_metal_spot_market_request.go b/equinix/resource_metal_spot_market_request.go index 707b434aa..4a1a4e45a 100644 --- a/equinix/resource_metal_spot_market_request.go +++ b/equinix/resource_metal_spot_market_request.go @@ -9,6 +9,9 @@ import ( "strconv" "time" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" @@ -363,8 +366,8 @@ func resourceMetalSpotMarketRequestRead(ctx context.Context, d *schema.ResourceD smr, _, err := client.SpotMarketRequests.Get(d.Id(), &packngo.GetOptions{Includes: []string{"project", "devices", "facilities", "metro"}}) if err != nil { - err = friendlyError(err) - if isNotFound(err) { + err = equinix_errors.FriendlyError(err) + if equinix_errors.IsNotFound(err) { log.Printf("[WARN] SpotMarketRequest (%s) not found, removing from state", d.Id()) d.SetId("") return nil @@ -377,7 +380,7 @@ func resourceMetalSpotMarketRequestRead(ctx context.Context, d *schema.ResourceD metro = smr.Metro.Code } - return setMap(d, map[string]interface{}{ + return equinix_schema.SetMap(d, map[string]interface{}{ "metro": metro, "project_id": smr.Project.ID, "devices_min": smr.DevicesMin, @@ -428,13 +431,13 @@ func resourceMetalSpotMarketRequestDelete(ctx context.Context, d *schema.Resourc for _, d := range smr.Devices { resp, err := client.Devices.Delete(d.ID, true) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { return err } } } resp, err := client.SpotMarketRequests.Delete(d.Id(), true) - return ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) + return equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) } func resourceStateRefreshFunc(d *schema.ResourceData, meta interface{}) retry.StateRefreshFunc { diff --git a/equinix/resource_metal_ssh_key.go b/equinix/resource_metal_ssh_key.go index 087063b87..2faaba737 100644 --- a/equinix/resource_metal_ssh_key.go +++ b/equinix/resource_metal_ssh_key.go @@ -5,6 +5,8 @@ import ( "path" "strings" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -80,7 +82,7 @@ func resourceMetalSSHKeyCreate(d *schema.ResourceData, meta interface{}) error { key, _, err := client.SSHKeys.Create(createRequest) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } d.SetId(key.ID) @@ -94,11 +96,11 @@ func resourceMetalSSHKeyRead(d *schema.ResourceData, meta interface{}) error { key, _, err := client.SSHKeys.Get(d.Id(), nil) if err != nil { - err = friendlyError(err) + err = equinix_errors.FriendlyError(err) // If the key is somehow already destroyed, mark as // succesfully gone - if isNotFound(err) { + if equinix_errors.IsNotFound(err) { log.Printf("[WARN] SSHKey (%s) not found, removing from state", d.Id()) d.SetId("") return nil @@ -142,7 +144,7 @@ func resourceMetalSSHKeyUpdate(d *schema.ResourceData, meta interface{}) error { _, _, err := client.SSHKeys.Update(d.Id(), updateRequest) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } return resourceMetalSSHKeyRead(d, meta) @@ -153,8 +155,8 @@ func resourceMetalSSHKeyDelete(d *schema.ResourceData, meta interface{}) error { client := meta.(*config.Config).Metal resp, err := client.SSHKeys.Delete(d.Id()) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { - return friendlyError(err) + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { + return equinix_errors.FriendlyError(err) } d.SetId("") diff --git a/equinix/resource_metal_virtual_circuit.go b/equinix/resource_metal_virtual_circuit.go index a832bc852..61f561c25 100644 --- a/equinix/resource_metal_virtual_circuit.go +++ b/equinix/resource_metal_virtual_circuit.go @@ -9,6 +9,9 @@ import ( "strconv" "time" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" @@ -227,7 +230,7 @@ func resourceMetalVirtualCircuitRead(ctx context.Context, d *schema.ResourceData log.Printf("[DEBUG] Could not parse connection and port ID from port href %s", vc.Port.Href.Href) } - return setMap(d, map[string]interface{}{ + return equinix_schema.SetMap(d, map[string]interface{}{ "project_id": vc.Project.ID, "port_id": portID, "vlan_id": func(d *schema.ResourceData, k string) error { @@ -317,13 +320,13 @@ func resourceMetalVirtualCircuitUpdate(ctx context.Context, d *schema.ResourceDa } ur.Tags = &sts default: - return friendlyError(fmt.Errorf("garbage in tags: %s", ts)) + return equinix_errors.FriendlyError(fmt.Errorf("garbage in tags: %s", ts)) } } if !reflect.DeepEqual(ur, packngo.VCUpdateRequest{}) { if _, _, err := client.VirtualCircuits.Update(d.Id(), &ur, nil); err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } } return resourceMetalVirtualCircuitRead(ctx, d, meta) @@ -334,8 +337,8 @@ func resourceMetalVirtualCircuitDelete(ctx context.Context, d *schema.ResourceDa client := meta.(*config.Config).Metal resp, err := client.VirtualCircuits.Delete(d.Id()) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { - return friendlyError(err) + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { + return equinix_errors.FriendlyError(err) } deleteWaiter := getVCStateWaiter( @@ -347,7 +350,7 @@ func resourceMetalVirtualCircuitDelete(ctx context.Context, d *schema.ResourceDa ) _, err = deleteWaiter.WaitForStateContext(ctx) - if ignoreResponseErrors(httpForbidden, httpNotFound)(nil, err) != nil { + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(nil, err) != nil { return fmt.Errorf("Error deleting virtual circuit %s: %s", d.Id(), err) } d.SetId("") diff --git a/equinix/resource_metal_vlan.go b/equinix/resource_metal_vlan.go index 2b39fcc36..0dc8b9511 100644 --- a/equinix/resource_metal_vlan.go +++ b/equinix/resource_metal_vlan.go @@ -4,6 +4,8 @@ import ( "errors" "path" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -86,10 +88,10 @@ func resourceMetalVlanCreate(d *schema.ResourceData, meta interface{}) error { vxlanRaw, vxlanOk := d.GetOk("vxlan") if !facOk && !metroOk { - return friendlyError(errors.New("one of facility or metro must be configured")) + return equinix_errors.FriendlyError(errors.New("one of facility or metro must be configured")) } if facOk && vxlanOk { - return friendlyError(errors.New("you can set vxlan only for metro vlans")) + return equinix_errors.FriendlyError(errors.New("you can set vxlan only for metro vlans")) } createRequest := &packngo.VirtualNetworkCreateRequest{ @@ -105,7 +107,7 @@ func resourceMetalVlanCreate(d *schema.ResourceData, meta interface{}) error { } vlan, _, err := client.ProjectVirtualNetworks.Create(createRequest) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } d.SetId(vlan.ID) return resourceMetalVlanRead(d, meta) @@ -118,8 +120,8 @@ func resourceMetalVlanRead(d *schema.ResourceData, meta interface{}) error { vlan, _, err := client.ProjectVirtualNetworks.Get(d.Id(), &packngo.GetOptions{Includes: []string{"assigned_to"}}) if err != nil { - err = friendlyError(err) - if isNotFound(err) { + err = equinix_errors.FriendlyError(err) + if equinix_errors.IsNotFound(err) { d.SetId("") return nil } @@ -140,8 +142,8 @@ func resourceMetalVlanDelete(d *schema.ResourceData, meta interface{}) error { id := d.Id() vlan, resp, err := client.ProjectVirtualNetworks.Get(id, &packngo.GetOptions{Includes: []string{"instances", "instances.network_ports.virtual_networks", "internet_gateway"}}) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { - return friendlyError(err) + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { + return equinix_errors.FriendlyError(err) } else if err != nil { // missing vlans are deleted return nil @@ -158,8 +160,8 @@ func resourceMetalVlanDelete(d *schema.ResourceData, meta interface{}) error { if aID == id { _, resp, err := client.Ports.Unassign(p.ID, id) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) != nil { - return friendlyError(err) + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) != nil { + return equinix_errors.FriendlyError(err) } } } @@ -168,5 +170,5 @@ func resourceMetalVlanDelete(d *schema.ResourceData, meta interface{}) error { // TODO(displague) do we need to unassign gateway connections before delete? - return friendlyError(ignoreResponseErrors(httpForbidden, httpNotFound)(client.ProjectVirtualNetworks.Delete(id))) + return equinix_errors.FriendlyError(equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(client.ProjectVirtualNetworks.Delete(id))) } diff --git a/equinix/resource_metal_vrf.go b/equinix/resource_metal_vrf.go index 4f3591651..559e9dfe4 100644 --- a/equinix/resource_metal_vrf.go +++ b/equinix/resource_metal_vrf.go @@ -4,6 +4,9 @@ import ( "context" "log" + equinix_errors "github.com/equinix/terraform-provider-equinix/internal/errors" + equinix_schema "github.com/equinix/terraform-provider-equinix/internal/schema" + "github.com/equinix/terraform-provider-equinix/internal/config" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/packethost/packngo" @@ -72,7 +75,7 @@ func resourceMetalVRFCreate(ctx context.Context, d *schema.ResourceData, meta in projectId := d.Get("project_id").(string) vrf, _, err := client.VRFs.Create(projectId, createRequest) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } d.SetId(vrf.ID) @@ -104,7 +107,7 @@ func resourceMetalVRFUpdate(ctx context.Context, d *schema.ResourceData, meta in _, _, err := client.VRFs.Update(d.Id(), updateRequest) if err != nil { - return friendlyError(err) + return equinix_errors.FriendlyError(err) } return resourceMetalVRFRead(ctx, d, meta) @@ -118,7 +121,7 @@ func resourceMetalVRFRead(ctx context.Context, d *schema.ResourceData, meta inte vrf, _, err := client.VRFs.Get(d.Id(), getOpts) if err != nil { - if isNotFound(err) || isForbidden(err) { + if equinix_errors.IsNotFound(err) || equinix_errors.IsForbidden(err) { log.Printf("[WARN] VRF (%s) not accessible, removing from state", d.Id()) d.SetId("") @@ -135,7 +138,7 @@ func resourceMetalVRFRead(ctx context.Context, d *schema.ResourceData, meta inte "project_id": vrf.Project.ID, } - return setMap(d, m) + return equinix_schema.SetMap(d, m) } func resourceMetalVRFDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) error { @@ -143,9 +146,9 @@ func resourceMetalVRFDelete(ctx context.Context, d *schema.ResourceData, meta in client := meta.(*config.Config).Metal resp, err := client.VRFs.Delete(d.Id()) - if ignoreResponseErrors(httpForbidden, httpNotFound)(resp, err) == nil { + if equinix_errors.IgnoreResponseErrors(equinix_errors.HttpForbidden, equinix_errors.HttpNotFound)(resp, err) == nil { d.SetId("") } - return friendlyError(err) + return equinix_errors.FriendlyError(err) } diff --git a/equinix/errors.go b/internal/errors/errors.go similarity index 66% rename from equinix/errors.go rename to internal/errors/errors.go index c3c546762..a50c7d5be 100644 --- a/equinix/errors.go +++ b/internal/errors/errors.go @@ -1,20 +1,16 @@ -package equinix +package errors import ( "fmt" "net/http" - "sort" "strings" - "github.com/hashicorp/go-multierror" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/packethost/packngo" ) -// friendlyError improves error messages when the API error is blank or in an +// FriendlyError improves error messages when the API error is blank or in an // alternate format (as is the case with invalid token or loadbalancer errors) -func friendlyError(err error) error { +func FriendlyError(err error) error { if e, ok := err.(*packngo.ErrorResponse); ok { resp := e.Response errors := Errors(e.Errors) @@ -28,7 +24,7 @@ func friendlyError(err error) error { return err } -func friendlyErrorForMetalGo(err error, resp *http.Response) error { +func FriendlyErrorForMetalGo(err error, resp *http.Response) error { errors := Errors([]string{err.Error()}) return convertToFriendlyError(errors, resp) } @@ -51,7 +47,7 @@ func convertToFriendlyError(errors Errors, resp *http.Response) error { return er } -func isForbidden(err error) bool { +func IsForbidden(err error) bool { r, ok := err.(*packngo.ErrorResponse) if ok && r.Response != nil { return r.Response.StatusCode == http.StatusForbidden @@ -62,7 +58,7 @@ func isForbidden(err error) bool { return false } -func isNotFound(err error) bool { +func IsNotFound(err error) bool { if r, ok := err.(*ErrorResponse); ok { return r.StatusCode == http.StatusNotFound && r.IsAPIError } @@ -96,36 +92,8 @@ func (er *ErrorResponse) Error() string { return ret } -// setMap sets the map of values to ResourceData, checking and returning the -// errors. Typically d.Set is not error checked. This helper makes checking -// those errors less tedious. Because this works with a map, the order of the -// errors would not be predictable, to avoid this the errors will be sorted. -func setMap(d *schema.ResourceData, m map[string]interface{}) error { - errs := &multierror.Error{} - for key, v := range m { - var err error - if f, ok := v.(setFn); ok { - err = f(d, key) - } else { - if key == "router" { - d.Set("gateway", v) - } - err = d.Set(key, v) - } - - if err != nil { - errs = multierror.Append(errs, err) - } - } - sort.Sort(errs) - - return errs.ErrorOrNil() -} - -type setFn = func(d *schema.ResourceData, key string) error - -// isNotAssigned matches errors reported from unassigned virtual networks -func isNotAssigned(resp *http.Response, err error) bool { +// IsNotAssigned matches errors reported from unassigned virtual networks +func IsNotAssigned(resp *http.Response, err error) bool { if resp.StatusCode != http.StatusUnprocessableEntity { return false } @@ -139,34 +107,34 @@ func isNotAssigned(resp *http.Response, err error) bool { return false } -func httpForbidden(resp *http.Response, err error) bool { +func HttpForbidden(resp *http.Response, err error) bool { if resp != nil && (resp.StatusCode != http.StatusForbidden) { return false } switch err := err.(type) { case *ErrorResponse, *packngo.ErrorResponse: - return isForbidden(err) + return IsForbidden(err) } return false } -func httpNotFound(resp *http.Response, err error) bool { +func HttpNotFound(resp *http.Response, err error) bool { if resp != nil && (resp.StatusCode != http.StatusNotFound) { return false } switch err := err.(type) { case *ErrorResponse, *packngo.ErrorResponse: - return isNotFound(err) + return IsNotFound(err) } return false } // ignoreResponseErrors ignores http response errors when matched by one of the // provided checks -func ignoreResponseErrors(ignore ...func(resp *http.Response, err error) bool) func(resp *packngo.Response, err error) error { +func IgnoreResponseErrors(ignore ...func(resp *http.Response, err error) bool) func(resp *packngo.Response, err error) error { return func(resp *packngo.Response, err error) error { var r *http.Response if resp != nil && resp.Response != nil { diff --git a/internal/schema/set_map.go b/internal/schema/set_map.go new file mode 100644 index 000000000..426436f89 --- /dev/null +++ b/internal/schema/set_map.go @@ -0,0 +1,36 @@ +package utils + +import ( + "sort" + + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +type setFn = func(d *schema.ResourceData, key string) error + +// setMap sets the map of values to ResourceData, checking and returning the +// errors. Typically d.Set is not error checked. This helper makes checking +// those errors less tedious. Because this works with a map, the order of the +// errors would not be predictable, to avoid this the errors will be sorted. +func SetMap(d *schema.ResourceData, m map[string]interface{}) error { + errs := &multierror.Error{} + for key, v := range m { + var err error + if f, ok := v.(setFn); ok { + err = f(d, key) + } else { + if key == "router" { + d.Set("gateway", v) + } + err = d.Set(key, v) + } + + if err != nil { + errs = multierror.Append(errs, err) + } + } + sort.Sort(errs) + + return errs.ErrorOrNil() +}