diff --git a/thousandeyes/resource_agent_to_agent.go b/thousandeyes/resource_agent_to_agent.go index 6985b20..e364644 100644 --- a/thousandeyes/resource_agent_to_agent.go +++ b/thousandeyes/resource_agent_to_agent.go @@ -36,19 +36,9 @@ func resourceAgentToAgent() *schema.Resource { } func resourceAgentAgentRead(d *schema.ResourceData, m interface{}) error { - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetAgentAgent(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetAgentAgent(id) + }) } func resourceAgentAgentUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/resource_agent_to_server.go b/thousandeyes/resource_agent_to_server.go index a7db6a7..efd8ddb 100644 --- a/thousandeyes/resource_agent_to_server.go +++ b/thousandeyes/resource_agent_to_server.go @@ -39,19 +39,9 @@ func resourceAgentToServer() *schema.Resource { } func resourceAgentServerRead(d *schema.ResourceData, m interface{}) error { - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetAgentServer(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetAgentServer(id) + }) } func resourceAgentServerUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/resource_alert_rule.go b/thousandeyes/resource_alert_rule.go index 03d8567..5b84d7c 100644 --- a/thousandeyes/resource_alert_rule.go +++ b/thousandeyes/resource_alert_rule.go @@ -25,19 +25,9 @@ func resourceAlertRule() *schema.Resource { } func resourceAlertRuleRead(d *schema.ResourceData, m interface{}) error { - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetAlertRule(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetAlertRule(id) + }) } func resourceAlertRuleUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/resource_bgp.go b/thousandeyes/resource_bgp.go index d232e8b..b8ab700 100644 --- a/thousandeyes/resource_bgp.go +++ b/thousandeyes/resource_bgp.go @@ -24,19 +24,9 @@ func resourceBGP() *schema.Resource { } func resourceBGPRead(d *schema.ResourceData, m interface{}) error { - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetBGP(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetBGP(id) + }) } func resourceBGPUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/resource_dns_server.go b/thousandeyes/resource_dns_server.go index 180350d..6015be5 100644 --- a/thousandeyes/resource_dns_server.go +++ b/thousandeyes/resource_dns_server.go @@ -24,19 +24,9 @@ func resourceDNSServer() *schema.Resource { } func resourceDNSServerRead(d *schema.ResourceData, m interface{}) error { - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetDNSServer(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetDNSServer(id) + }) } func resourceDNSServerUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/resource_dns_trace.go b/thousandeyes/resource_dns_trace.go index 1a5e84d..7b0698f 100644 --- a/thousandeyes/resource_dns_trace.go +++ b/thousandeyes/resource_dns_trace.go @@ -24,19 +24,9 @@ func resourceDNSTrace() *schema.Resource { } func resourceDNSTraceRead(d *schema.ResourceData, m interface{}) error { - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetDNSTrace(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetDNSTrace(id) + }) } func resourceDNSTraceUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/resource_dnssec.go b/thousandeyes/resource_dnssec.go index b617a74..909545b 100644 --- a/thousandeyes/resource_dnssec.go +++ b/thousandeyes/resource_dnssec.go @@ -1,10 +1,8 @@ package thousandeyes import ( - "fmt" "log" "strconv" - "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/thousandeyes/thousandeyes-sdk-go/v2" @@ -26,21 +24,9 @@ func resourceDNSSec() *schema.Resource { } func resourceDNSSecRead(d *schema.ResourceData, m interface{}) error { - log.Printf("[INFO] d object: \n\n%s", strings.Replace( - fmt.Sprintf("%#v", d), ", ", "\n", -1)) - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetDNSSec(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetDNSSec(id) + }) } func resourceDNSSecUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/resource_ftp_server.go b/thousandeyes/resource_ftp_server.go index bedb07f..dbc4c38 100644 --- a/thousandeyes/resource_ftp_server.go +++ b/thousandeyes/resource_ftp_server.go @@ -26,19 +26,9 @@ func resourceFTPServer() *schema.Resource { } func resourceFTPServerRead(d *schema.ResourceData, m interface{}) error { - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetFTPServer(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetFTPServer(id) + }) } func resourceFTPServerUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/resource_http_server.go b/thousandeyes/resource_http_server.go index 314649f..14708d4 100644 --- a/thousandeyes/resource_http_server.go +++ b/thousandeyes/resource_http_server.go @@ -24,19 +24,9 @@ func resourceHTTPServer() *schema.Resource { } func resourceHTTPServerRead(d *schema.ResourceData, m interface{}) error { - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetHTTPServer(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetHTTPServer(id) + }) } func resourceHTTPServerUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/resource_label.go b/thousandeyes/resource_label.go index b8175e4..48960fa 100644 --- a/thousandeyes/resource_label.go +++ b/thousandeyes/resource_label.go @@ -46,9 +46,15 @@ func resourceGroupLabelRead(d *schema.ResourceData, m interface{}) error { log.Printf("[INFO] Reading Thousandeyes Label %s", d.Id()) id, _ := strconv.ParseInt(d.Id(), 10, 64) remote, err := client.GetGroupLabel(id) - if err != nil { + + if err != nil && IsNotFoundError(err) { + log.Printf("[INFO] Resource was deleted - will recreate it") + d.SetId("") // Set ID to empty to mark the resource as non-existent + return nil + } else if err != nil { return err } + // In order to prevent schema conficts for test responses, we retain // the stored state for tests attached to a group to just a test ID. testIDs := []thousandeyes.GenericTest{} diff --git a/thousandeyes/resource_page_load.go b/thousandeyes/resource_page_load.go index f7949fe..7b18768 100644 --- a/thousandeyes/resource_page_load.go +++ b/thousandeyes/resource_page_load.go @@ -24,19 +24,9 @@ func resourcePageLoad() *schema.Resource { } func resourcePageLoadRead(d *schema.ResourceData, m interface{}) error { - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetPageLoad(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetPageLoad(id) + }) } func resourcePageLoadUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/resource_sip_server.go b/thousandeyes/resource_sip_server.go index 901f898..fbd4872 100644 --- a/thousandeyes/resource_sip_server.go +++ b/thousandeyes/resource_sip_server.go @@ -24,19 +24,9 @@ func resourceSIPServer() *schema.Resource { } func resourceSIPServerRead(d *schema.ResourceData, m interface{}) error { - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetSIPServer(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetSIPServer(id) + }) } func resourceSIPServerUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/resource_voice.go b/thousandeyes/resource_voice.go index e5ccb85..681d2c3 100644 --- a/thousandeyes/resource_voice.go +++ b/thousandeyes/resource_voice.go @@ -24,19 +24,9 @@ func resourceRTPStream() *schema.Resource { } func resourceRTPStreamRead(d *schema.ResourceData, m interface{}) error { - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetRTPStream(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetRTPStream(id) + }) } func resourceRTPStreamUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/resource_web_transactions.go b/thousandeyes/resource_web_transactions.go index 3ce8086..26542a5 100644 --- a/thousandeyes/resource_web_transactions.go +++ b/thousandeyes/resource_web_transactions.go @@ -24,19 +24,9 @@ func resourceWebTransaction() *schema.Resource { } func resourceWebTransactionRead(d *schema.ResourceData, m interface{}) error { - client := m.(*thousandeyes.Client) - - log.Printf("[INFO] Reading Thousandeyes Test %s", d.Id()) - id, _ := strconv.ParseInt(d.Id(), 10, 64) - remote, err := client.GetWebTransaction(id) - if err != nil { - return err - } - err = ResourceRead(d, remote) - if err != nil { - return err - } - return nil + return GetResource(d, m, func(client *thousandeyes.Client, id int64) (interface{}, error) { + return client.GetWebTransaction(id) + }) } func resourceWebTransactionUpdate(d *schema.ResourceData, m interface{}) error { diff --git a/thousandeyes/util.go b/thousandeyes/util.go index f5f6f7e..22e0353 100644 --- a/thousandeyes/util.go +++ b/thousandeyes/util.go @@ -2,6 +2,7 @@ package thousandeyes import ( "errors" + "log" "reflect" "strconv" "strings" @@ -11,6 +12,18 @@ import ( "github.com/thousandeyes/thousandeyes-sdk-go/v2" ) +type ResourceReadFunc func(client *thousandeyes.Client, id int64) (interface{}, error) + +func IsNotFoundError(err error) bool { + notFoundPatterns := []string{"404", "not found"} + for _, pattern := range notFoundPatterns { + if strings.Contains(strings.ToLower(err.Error()), pattern) { + return true + } + } + return false +} + func expandAgents(v interface{}) thousandeyes.Agents { var agents thousandeyes.Agents @@ -122,6 +135,36 @@ func ResourceBuildStruct(d *schema.ResourceData, structPtr interface{}) interfac return resourceFixups(d, structPtr) } +// resourceRead is a generic function for reading resources. +func GetResource(d *schema.ResourceData, m interface{}, readFunc ResourceReadFunc) error { + client := m.(*thousandeyes.Client) + + log.Printf("[INFO] Reading Thousandeyes Resource %s", d.Id()) + id, err := strconv.ParseInt(d.Id(), 10, 64) + if err != nil { + return err + } + + remote, err := readFunc(client, id) + + // Check if the resource no longer exists + if err != nil && IsNotFoundError(err) { + log.Printf("[INFO] Resource was deleted - will recreate it") + d.SetId("") // Set ID to empty to mark the resource as non-existent + return nil + } else if err != nil { + return err + } + + // Continue with updating the state + err = ResourceRead(d, remote) + if err != nil { + return err + } + + return nil +} + // ResourceRead sets values for a schema.ResourceData object by names derived // from the fields of the struct at the provided pointer. func ResourceRead(d *schema.ResourceData, structPtr interface{}) error {