diff --git a/go.mod b/go.mod index 6edeab651..040e9906e 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/hashicorp/terraform-exec v0.20.0 github.com/hashicorp/terraform-json v0.20.0 github.com/hashicorp/terraform-plugin-framework v1.5.0 + github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 github.com/hashicorp/terraform-plugin-go v0.20.0 github.com/hashicorp/terraform-plugin-mux v0.13.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.31.0 diff --git a/go.sum b/go.sum index 11ae6360c..2e39e5e26 100644 --- a/go.sum +++ b/go.sum @@ -75,6 +75,8 @@ github.com/hashicorp/terraform-json v0.20.0 h1:cJcvn4gIOTi0SD7pIy+xiofV1zFA3hza+ github.com/hashicorp/terraform-json v0.20.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk= github.com/hashicorp/terraform-plugin-framework v1.5.0 h1:8kcvqJs/x6QyOFSdeAyEgsenVOUeC/IyKpi2ul4fjTg= github.com/hashicorp/terraform-plugin-framework v1.5.0/go.mod h1:6waavirukIlFpVpthbGd2PUNYaFedB0RwW3MDzJ/rtc= +github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 h1:HOjBuMbOEzl7snOdOoUfE2Jgeto6JOjLVQ39Ls2nksc= +github.com/hashicorp/terraform-plugin-framework-validators v0.12.0/go.mod h1:jfHGE/gzjxYz6XoUwi/aYiiKrJDeutQNUtGQXkaHklg= github.com/hashicorp/terraform-plugin-go v0.20.0 h1:oqvoUlL+2EUbKNsJbIt3zqqZ7wi6lzn4ufkn/UA51xQ= github.com/hashicorp/terraform-plugin-go v0.20.0/go.mod h1:Rr8LBdMlY53a3Z/HpP+ZU3/xCDqtKNCkeI9qOyT10QE= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= diff --git a/pagerduty/data_source_pagerduty_automation_actions_action.go b/pagerduty/data_source_pagerduty_automation_actions_action.go index fe338dfe1..ed16962cc 100644 --- a/pagerduty/data_source_pagerduty_automation_actions_action.go +++ b/pagerduty/data_source_pagerduty_automation_actions_action.go @@ -5,7 +5,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -106,17 +106,17 @@ func dataSourcePagerDutyAutomationActionsActionRead(d *schema.ResourceData, meta log.Printf("[INFO] Reading PagerDuty AutomationActionsAction") - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { automationActionsAction, _, err := client.AutomationActionsAction.Get(d.Get("id").(string)) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } d.SetId(automationActionsAction.ID) @@ -131,7 +131,7 @@ func dataSourcePagerDutyAutomationActionsActionRead(d *schema.ResourceData, meta f_adr := flattenActionDataReference(automationActionsAction.ActionDataReference) if err := d.Set("action_data_reference", f_adr); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } if automationActionsAction.ModifyTime != nil { diff --git a/pagerduty/data_source_pagerduty_automation_actions_action_test.go b/pagerduty/data_source_pagerduty_automation_actions_action_test.go index fdcecd93e..fa10025b6 100644 --- a/pagerduty/data_source_pagerduty_automation_actions_action_test.go +++ b/pagerduty/data_source_pagerduty_automation_actions_action_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyAutomationActionsAction_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_automation_actions_runner.go b/pagerduty/data_source_pagerduty_automation_actions_runner.go index 6ef6944fb..b17d7b66c 100644 --- a/pagerduty/data_source_pagerduty_automation_actions_runner.go +++ b/pagerduty/data_source_pagerduty_automation_actions_runner.go @@ -5,7 +5,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -61,17 +61,17 @@ func dataSourcePagerDutyAutomationActionsRunnerRead(d *schema.ResourceData, meta log.Printf("[INFO] Reading PagerDuty automation actions runner") - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { runner, _, err := client.AutomationActionsRunner.Get(d.Get("id").(string)) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } d.SetId(runner.ID) diff --git a/pagerduty/data_source_pagerduty_automation_actions_runner_test.go b/pagerduty/data_source_pagerduty_automation_actions_runner_test.go index c6e208fa5..9c245ec28 100644 --- a/pagerduty/data_source_pagerduty_automation_actions_runner_test.go +++ b/pagerduty/data_source_pagerduty_automation_actions_runner_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyAutomationActionsRunner_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_business_service.go b/pagerduty/data_source_pagerduty_business_service.go index 2d6cf141c..953184301 100644 --- a/pagerduty/data_source_pagerduty_business_service.go +++ b/pagerduty/data_source_pagerduty_business_service.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -38,17 +38,17 @@ func dataSourcePagerDutyBusinessServiceRead(d *schema.ResourceData, meta interfa searchName := d.Get("name").(string) - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.BusinessServices.List() if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.BusinessService @@ -61,7 +61,7 @@ func dataSourcePagerDutyBusinessServiceRead(d *schema.ResourceData, meta interfa } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any business service with the name: %s", searchName), ) } @@ -72,5 +72,4 @@ func dataSourcePagerDutyBusinessServiceRead(d *schema.ResourceData, meta interfa return nil }) - } diff --git a/pagerduty/data_source_pagerduty_business_service_test.go b/pagerduty/data_source_pagerduty_business_service_test.go index d88b18812..746c1d4c2 100644 --- a/pagerduty/data_source_pagerduty_business_service_test.go +++ b/pagerduty/data_source_pagerduty_business_service_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyBusinessService_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_escalation_policy.go b/pagerduty/data_source_pagerduty_escalation_policy.go index f42316975..4fc01c7d7 100644 --- a/pagerduty/data_source_pagerduty_escalation_policy.go +++ b/pagerduty/data_source_pagerduty_escalation_policy.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -38,17 +38,17 @@ func dataSourcePagerDutyEscalationPolicyRead(d *schema.ResourceData, meta interf Query: searchName, } - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.EscalationPolicies.List(o) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.EscalationPolicy @@ -61,7 +61,7 @@ func dataSourcePagerDutyEscalationPolicyRead(d *schema.ResourceData, meta interf } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any escalation policy with the name: %s", searchName), ) } diff --git a/pagerduty/data_source_pagerduty_escalation_policy_test.go b/pagerduty/data_source_pagerduty_escalation_policy_test.go index 442791df6..11dad1513 100644 --- a/pagerduty/data_source_pagerduty_escalation_policy_test.go +++ b/pagerduty/data_source_pagerduty_escalation_policy_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyEscalationPolicy_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_event_orchestration.go b/pagerduty/data_source_pagerduty_event_orchestration.go index ac4f66d72..f67f2aed2 100644 --- a/pagerduty/data_source_pagerduty_event_orchestration.go +++ b/pagerduty/data_source_pagerduty_event_orchestration.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -67,14 +67,14 @@ func dataSourcePagerDutyEventOrchestrationRead(d *schema.ResourceData, meta inte searchName := d.Get("name").(string) - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.EventOrchestrations.List() if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.EventOrchestration @@ -87,7 +87,7 @@ func dataSourcePagerDutyEventOrchestrationRead(d *schema.ResourceData, meta inte } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any Event Orchestration with the name: %s", searchName), ) } @@ -96,7 +96,7 @@ func dataSourcePagerDutyEventOrchestrationRead(d *schema.ResourceData, meta inte // since the list ndpoint does not return it orch, _, err := client.EventOrchestrations.Get(found.ID) if err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } d.SetId(orch.ID) diff --git a/pagerduty/data_source_pagerduty_event_orchestration_integration.go b/pagerduty/data_source_pagerduty_event_orchestration_integration.go index 900bacc70..057a0d3d6 100644 --- a/pagerduty/data_source_pagerduty_event_orchestration_integration.go +++ b/pagerduty/data_source_pagerduty_event_orchestration_integration.go @@ -8,7 +8,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -82,16 +82,16 @@ func getEventOrchestrationIntegrationById(ctx context.Context, d *schema.Resourc return diag.FromErr(err) } - retryErr := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { log.Printf("[INFO] Reading Integration data source by ID '%s' for PagerDuty Event Orchestration '%s'", id, oid) if integration, _, err := client.EventOrchestrationIntegrations.GetContext(ctx, oid, id); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if integration != nil { d.SetId(integration.ID) setEventOrchestrationIntegrationProps(d, integration) @@ -116,18 +116,17 @@ func getEventOrchestrationIntegrationByLabel(ctx context.Context, d *schema.Reso return diag.FromErr(err) } - retryErr := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { log.Printf("[INFO] Reading Integration data source by label '%s' for PagerDuty Event Orchestration '%s'", lbl, oid) resp, _, err := client.EventOrchestrationIntegrations.ListContext(ctx, oid) - if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var matches []*pagerduty.EventOrchestrationIntegration @@ -141,13 +140,13 @@ func getEventOrchestrationIntegrationByLabel(ctx context.Context, d *schema.Reso count := len(matches) if count == 0 { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to find an Integration on Event Orchestration '%s' with label '%s'", oid, lbl), ) } if count > 1 { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Ambiguous Integration label: '%s'. Found %v Integrations with this label on Event Orchestration '%s'. Please use the Integration ID instead or make Integration labels unique within Event Orchestration.", lbl, count, oid), ) } diff --git a/pagerduty/data_source_pagerduty_event_orchestration_integration_test.go b/pagerduty/data_source_pagerduty_event_orchestration_integration_test.go index b25459a75..b18055902 100644 --- a/pagerduty/data_source_pagerduty_event_orchestration_integration_test.go +++ b/pagerduty/data_source_pagerduty_event_orchestration_integration_test.go @@ -5,9 +5,9 @@ import ( "regexp" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyEventOrchestrationIntegration_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_event_orchestration_test.go b/pagerduty/data_source_pagerduty_event_orchestration_test.go index 554c19037..56fb2afbe 100644 --- a/pagerduty/data_source_pagerduty_event_orchestration_test.go +++ b/pagerduty/data_source_pagerduty_event_orchestration_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyEventOrchestration_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_event_orchestrations.go b/pagerduty/data_source_pagerduty_event_orchestrations.go index 33e69a1da..434bbef82 100644 --- a/pagerduty/data_source_pagerduty_event_orchestrations.go +++ b/pagerduty/data_source_pagerduty_event_orchestrations.go @@ -7,7 +7,8 @@ import ( "regexp" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -84,19 +85,19 @@ func dataSourcePagerDutyEventOrchestrationsRead(d *schema.ResourceData, meta int nameFilter := d.Get("name_filter").(string) var eoList []*pagerduty.EventOrchestration - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { resp, _, err := client.EventOrchestrations.List() if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } re, err := regexp.Compile(nameFilter) if err != nil { - return resource.NonRetryableError(fmt.Errorf("invalid regexp for name_filter provided %s", nameFilter)) + return retry.NonRetryableError(fmt.Errorf("invalid regexp for name_filter provided %s", nameFilter)) } for _, orchestration := range resp.Orchestrations { if re.MatchString(orchestration.Name) { @@ -104,7 +105,7 @@ func dataSourcePagerDutyEventOrchestrationsRead(d *schema.ResourceData, meta int } } if len(eoList) == 0 { - return resource.NonRetryableError(fmt.Errorf("Unable to locate any Event Orchestration matching the expression: %s", nameFilter)) + return retry.NonRetryableError(fmt.Errorf("Unable to locate any Event Orchestration matching the expression: %s", nameFilter)) } return nil @@ -118,14 +119,14 @@ func dataSourcePagerDutyEventOrchestrationsRead(d *schema.ResourceData, meta int for _, orchestration := range eoList { // Get orchestration matched by ID so we can set the integrations property // since the list endpoint does not return it - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { orch, _, err := client.EventOrchestrations.Get(orchestration.ID) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } orchestrations = append(orchestrations, orch) return nil @@ -136,7 +137,7 @@ func dataSourcePagerDutyEventOrchestrationsRead(d *schema.ResourceData, meta int } } - d.SetId(resource.UniqueId()) + d.SetId(id.UniqueId()) d.Set("name_filter", nameFilter) d.Set("event_orchestrations", flattenPagerDutyEventOrchestrations(orchestrations)) diff --git a/pagerduty/data_source_pagerduty_event_orchestrations_test.go b/pagerduty/data_source_pagerduty_event_orchestrations_test.go index 3d4e9215c..b1850fec5 100644 --- a/pagerduty/data_source_pagerduty_event_orchestrations_test.go +++ b/pagerduty/data_source_pagerduty_event_orchestrations_test.go @@ -5,9 +5,9 @@ import ( "regexp" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyEventOrchestrations_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_extension_schema.go b/pagerduty/data_source_pagerduty_extension_schema.go index 96963736e..155d95442 100644 --- a/pagerduty/data_source_pagerduty_extension_schema.go +++ b/pagerduty/data_source_pagerduty_extension_schema.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -39,17 +39,17 @@ func dataSourcePagerDutyExtensionSchemaRead(d *schema.ResourceData, meta interfa searchName := d.Get("name").(string) - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.ExtensionSchemas.List(&pagerduty.ListExtensionSchemasOptions{Query: searchName}) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.ExtensionSchema @@ -62,7 +62,7 @@ func dataSourcePagerDutyExtensionSchemaRead(d *schema.ResourceData, meta interfa } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any extension schema with the name: %s", searchName), ) } diff --git a/pagerduty/data_source_pagerduty_extension_schema_test.go b/pagerduty/data_source_pagerduty_extension_schema_test.go index 3f95b888a..c7880e087 100644 --- a/pagerduty/data_source_pagerduty_extension_schema_test.go +++ b/pagerduty/data_source_pagerduty_extension_schema_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyExtensionSchema_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_incident_custom_field.go b/pagerduty/data_source_pagerduty_incident_custom_field.go index 0911f57da..54ac47eea 100644 --- a/pagerduty/data_source_pagerduty_incident_custom_field.go +++ b/pagerduty/data_source_pagerduty_incident_custom_field.go @@ -8,7 +8,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -51,17 +51,17 @@ func dataSourcePagerDutyIncidentCustomFieldRead(ctx context.Context, d *schema.R searchName := d.Get("name").(string) - err = resource.RetryContext(ctx, 5*time.Minute, func() *resource.RetryError { + err = retry.RetryContext(ctx, 5*time.Minute, func() *retry.RetryError { resp, _, err := client.IncidentCustomFields.ListContext(ctx, nil) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.IncidentCustomField @@ -74,14 +74,14 @@ func dataSourcePagerDutyIncidentCustomFieldRead(ctx context.Context, d *schema.R } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("unable to locate any field with name: %s", searchName), ) } err = flattenIncidentCustomField(d, found) if err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil diff --git a/pagerduty/data_source_pagerduty_incident_custom_field_test.go b/pagerduty/data_source_pagerduty_incident_custom_field_test.go index 91afc0a24..e4c9ac68e 100644 --- a/pagerduty/data_source_pagerduty_incident_custom_field_test.go +++ b/pagerduty/data_source_pagerduty_incident_custom_field_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccDataSourcePagerDutyIncidentCustomField(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_incident_workflow.go b/pagerduty/data_source_pagerduty_incident_workflow.go index 9469d88e9..646ae805c 100644 --- a/pagerduty/data_source_pagerduty_incident_workflow.go +++ b/pagerduty/data_source_pagerduty_incident_workflow.go @@ -8,7 +8,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -40,17 +40,17 @@ func dataSourcePagerDutyIncidentWorkflowRead(ctx context.Context, d *schema.Reso searchName := d.Get("name").(string) - err = resource.RetryContext(ctx, 5*time.Minute, func() *resource.RetryError { + err = retry.RetryContext(ctx, 5*time.Minute, func() *retry.RetryError { resp, _, err := client.IncidentWorkflows.ListContext(ctx, &pagerduty.ListIncidentWorkflowOptions{}) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.IncidentWorkflow @@ -63,14 +63,14 @@ func dataSourcePagerDutyIncidentWorkflowRead(ctx context.Context, d *schema.Reso } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("unable to locate any incident workflow with name: %s", searchName), ) } err = flattenIncidentWorkflow(d, found, false, nil) if err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil @@ -80,5 +80,4 @@ func dataSourcePagerDutyIncidentWorkflowRead(ctx context.Context, d *schema.Reso return diag.FromErr(err) } return nil - } diff --git a/pagerduty/data_source_pagerduty_incident_workflow_test.go b/pagerduty/data_source_pagerduty_incident_workflow_test.go index 8d34ce47e..4ba1ab0a3 100644 --- a/pagerduty/data_source_pagerduty_incident_workflow_test.go +++ b/pagerduty/data_source_pagerduty_incident_workflow_test.go @@ -5,8 +5,8 @@ import ( "regexp" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccDataSourcePagerDutyIncidentWorkflow(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_license.go b/pagerduty/data_source_pagerduty_license.go index e075d99dc..d3e7bfca5 100644 --- a/pagerduty/data_source_pagerduty_license.go +++ b/pagerduty/data_source_pagerduty_license.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -88,17 +88,17 @@ func dataSourcePagerDutyLicenseRead(d *schema.ResourceData, meta interface{}) er log.Printf("[INFO] Fetching PagerDuty Licenses") - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { licenses, _, err := client.Licenses.List() if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } id, name, description := d.Get("id").(string), d.Get("name").(string), d.Get("description").(string) @@ -106,7 +106,7 @@ func dataSourcePagerDutyLicenseRead(d *schema.ResourceData, meta interface{}) er if found == nil { ids := licensesToStringOfIds(licenses) - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any license with ids in [%s] with the configured id: '%s', name: '%s' or description: '%s'", ids, id, name, description)) } diff --git a/pagerduty/data_source_pagerduty_license_test.go b/pagerduty/data_source_pagerduty_license_test.go index aa5b75463..a521c6cf2 100644 --- a/pagerduty/data_source_pagerduty_license_test.go +++ b/pagerduty/data_source_pagerduty_license_test.go @@ -6,8 +6,8 @@ import ( "regexp" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyLicense_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_licenses.go b/pagerduty/data_source_pagerduty_licenses.go index f37dafa51..62b810a6a 100644 --- a/pagerduty/data_source_pagerduty_licenses.go +++ b/pagerduty/data_source_pagerduty_licenses.go @@ -5,7 +5,8 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -39,26 +40,26 @@ func dataSourcePagerDutyLicensesRead(d *schema.ResourceData, meta interface{}) e log.Printf("[INFO] Fetching PagerDuty Licenses") - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { licenses, _, err := client.Licenses.List() if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } newLicenses := flattenLicenses(licenses) d.Set("licenses", newLicenses) - if id, ok := d.GetOk("id"); !ok { - d.SetId(resource.UniqueId()) + if idValue, ok := d.GetOk("id"); !ok { + d.SetId(id.UniqueId()) } else { - d.SetId(id.(string)) + d.SetId(idValue.(string)) } return nil }) @@ -74,7 +75,7 @@ func flattenLicenses(licenses []*pagerduty.License) []map[string]interface{} { } func flattenLicense(l *pagerduty.License) map[string]interface{} { - var license = map[string]interface{}{ + license := map[string]interface{}{ "id": l.ID, "type": l.Type, "name": l.Name, diff --git a/pagerduty/data_source_pagerduty_licenses_test.go b/pagerduty/data_source_pagerduty_licenses_test.go index 9ff64e1d2..b5b45e817 100644 --- a/pagerduty/data_source_pagerduty_licenses_test.go +++ b/pagerduty/data_source_pagerduty_licenses_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyLicenses_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_priority.go b/pagerduty/data_source_pagerduty_priority.go index 2e0398a46..e969be065 100644 --- a/pagerduty/data_source_pagerduty_priority.go +++ b/pagerduty/data_source_pagerduty_priority.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -40,17 +40,17 @@ func dataSourcePagerDutyPriorityRead(d *schema.ResourceData, meta interface{}) e searchTeam := d.Get("name").(string) - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.Priorities.List() if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.Priority @@ -63,7 +63,7 @@ func dataSourcePagerDutyPriorityRead(d *schema.ResourceData, meta interface{}) e } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any priority with name: %s", searchTeam), ) } diff --git a/pagerduty/data_source_pagerduty_priority_test.go b/pagerduty/data_source_pagerduty_priority_test.go index b374a2a04..222160f0a 100644 --- a/pagerduty/data_source_pagerduty_priority_test.go +++ b/pagerduty/data_source_pagerduty_priority_test.go @@ -3,7 +3,7 @@ package pagerduty import ( "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccDataSourcePagerDutyPriority_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_ruleset.go b/pagerduty/data_source_pagerduty_ruleset.go index 17fc0af38..cf494362f 100644 --- a/pagerduty/data_source_pagerduty_ruleset.go +++ b/pagerduty/data_source_pagerduty_ruleset.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -41,17 +41,17 @@ func dataSourcePagerDutyRulesetRead(d *schema.ResourceData, meta interface{}) er searchName := d.Get("name").(string) - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.Rulesets.List() if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.Ruleset @@ -64,7 +64,7 @@ func dataSourcePagerDutyRulesetRead(d *schema.ResourceData, meta interface{}) er } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any ruleset with the name: %s", searchName), ) } diff --git a/pagerduty/data_source_pagerduty_ruleset_test.go b/pagerduty/data_source_pagerduty_ruleset_test.go index 8ec3e9c82..303445cfb 100644 --- a/pagerduty/data_source_pagerduty_ruleset_test.go +++ b/pagerduty/data_source_pagerduty_ruleset_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyRuleset_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_schedule.go b/pagerduty/data_source_pagerduty_schedule.go index 7b5b10e35..e60b63aca 100644 --- a/pagerduty/data_source_pagerduty_schedule.go +++ b/pagerduty/data_source_pagerduty_schedule.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -38,17 +38,17 @@ func dataSourcePagerDutyScheduleRead(d *schema.ResourceData, meta interface{}) e Query: searchName, } - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.Schedules.List(o) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.Schedule @@ -61,7 +61,7 @@ func dataSourcePagerDutyScheduleRead(d *schema.ResourceData, meta interface{}) e } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any schedule with the name: %s", searchName), ) } diff --git a/pagerduty/data_source_pagerduty_schedule_test.go b/pagerduty/data_source_pagerduty_schedule_test.go index 87be61eef..7abdd1b76 100644 --- a/pagerduty/data_source_pagerduty_schedule_test.go +++ b/pagerduty/data_source_pagerduty_schedule_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutySchedule_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_service.go b/pagerduty/data_source_pagerduty_service.go index a3cd8bed6..3e0bcc24f 100644 --- a/pagerduty/data_source_pagerduty_service.go +++ b/pagerduty/data_source_pagerduty_service.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -79,17 +79,17 @@ func dataSourcePagerDutyServiceRead(d *schema.ResourceData, meta interface{}) er Query: searchName, } - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.Services.List(o) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.Service @@ -102,7 +102,7 @@ func dataSourcePagerDutyServiceRead(d *schema.ResourceData, meta interface{}) er } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any service with the name: %s", searchName), ) } diff --git a/pagerduty/data_source_pagerduty_service_integration.go b/pagerduty/data_source_pagerduty_service_integration.go index 11a7b58c1..5fb031871 100644 --- a/pagerduty/data_source_pagerduty_service_integration.go +++ b/pagerduty/data_source_pagerduty_service_integration.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -50,11 +50,11 @@ func dataSourcePagerDutyServiceIntegrationRead(d *schema.ResourceData, meta inte Query: searchName, } - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.Services.List(o) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return handleError(err) @@ -70,7 +70,7 @@ func dataSourcePagerDutyServiceIntegrationRead(d *schema.ResourceData, meta inte } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("unable to locate any service with the name: %s", searchName), ) } @@ -88,15 +88,14 @@ func dataSourcePagerDutyServiceIntegrationRead(d *schema.ResourceData, meta inte return nil } - } - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("unable to locate any integration of type %s on service %s", integrationSummary, searchName), ) }) } -func handleError(err error) *resource.RetryError { +func handleError(err error) *retry.RetryError { time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } diff --git a/pagerduty/data_source_pagerduty_service_integration_test.go b/pagerduty/data_source_pagerduty_service_integration_test.go index 546f11062..9248aa3d2 100644 --- a/pagerduty/data_source_pagerduty_service_integration_test.go +++ b/pagerduty/data_source_pagerduty_service_integration_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyIntegration_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_service_test.go b/pagerduty/data_source_pagerduty_service_test.go index 6b07c2d2f..cefdf1985 100644 --- a/pagerduty/data_source_pagerduty_service_test.go +++ b/pagerduty/data_source_pagerduty_service_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyService_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_tag.go b/pagerduty/data_source_pagerduty_tag.go index 58b0ecad2..4ceb81c26 100644 --- a/pagerduty/data_source_pagerduty_tag.go +++ b/pagerduty/data_source_pagerduty_tag.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -39,17 +39,17 @@ func dataSourcePagerDutyTagRead(d *schema.ResourceData, meta interface{}) error Query: searchTag, } - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.Tags.List(o) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.Tag @@ -62,7 +62,7 @@ func dataSourcePagerDutyTagRead(d *schema.ResourceData, meta interface{}) error } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any tag with label: %s", searchTag), ) } diff --git a/pagerduty/data_source_pagerduty_tag_test.go b/pagerduty/data_source_pagerduty_tag_test.go index 0fbf8f05d..667799a40 100644 --- a/pagerduty/data_source_pagerduty_tag_test.go +++ b/pagerduty/data_source_pagerduty_tag_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyTag_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_team.go b/pagerduty/data_source_pagerduty_team.go index ad06dfb26..29b50d6fc 100644 --- a/pagerduty/data_source_pagerduty_team.go +++ b/pagerduty/data_source_pagerduty_team.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -51,17 +51,17 @@ func dataSourcePagerDutyTeamRead(d *schema.ResourceData, meta interface{}) error Query: searchTeam, } - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.Teams.List(o) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.Team @@ -74,7 +74,7 @@ func dataSourcePagerDutyTeamRead(d *schema.ResourceData, meta interface{}) error } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any team with name: %s", searchTeam), ) } diff --git a/pagerduty/data_source_pagerduty_team_members.go b/pagerduty/data_source_pagerduty_team_members.go index 508503c5e..63f8d6df7 100644 --- a/pagerduty/data_source_pagerduty_team_members.go +++ b/pagerduty/data_source_pagerduty_team_members.go @@ -8,7 +8,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -62,14 +62,14 @@ func dataSourcePagerDutyTeamMembersRead(ctx context.Context, d *schema.ResourceD log.Printf("[INFO] Reading PagerDuty team members of %s", teamID) - retryErr := resource.RetryContext(ctx, 5*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 5*time.Minute, func() *retry.RetryError { resp, _, err := client.Teams.GetMembers(teamID, &pagerduty.GetMembersOptions{}) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } var mems []map[string]interface{} diff --git a/pagerduty/data_source_pagerduty_team_members_test.go b/pagerduty/data_source_pagerduty_team_members_test.go index d7a68ce7b..be517ef7c 100644 --- a/pagerduty/data_source_pagerduty_team_members_test.go +++ b/pagerduty/data_source_pagerduty_team_members_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyTeamMembers_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_team_test.go b/pagerduty/data_source_pagerduty_team_test.go index 3e040061c..4956546c7 100644 --- a/pagerduty/data_source_pagerduty_team_test.go +++ b/pagerduty/data_source_pagerduty_team_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyTeam_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_user.go b/pagerduty/data_source_pagerduty_user.go index 516e06a68..489c58b2b 100644 --- a/pagerduty/data_source_pagerduty_user.go +++ b/pagerduty/data_source_pagerduty_user.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -42,17 +42,17 @@ func dataSourcePagerDutyUserRead(d *schema.ResourceData, meta interface{}) error Query: searchEmail, } - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, err := client.Users.ListAll(o) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.FullUser @@ -65,7 +65,7 @@ func dataSourcePagerDutyUserRead(d *schema.ResourceData, meta interface{}) error } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any user with the email: %s", searchEmail), ) } diff --git a/pagerduty/data_source_pagerduty_user_contact_method.go b/pagerduty/data_source_pagerduty_user_contact_method.go index e3b8f8685..909da3552 100644 --- a/pagerduty/data_source_pagerduty_user_contact_method.go +++ b/pagerduty/data_source_pagerduty_user_contact_method.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -71,17 +71,17 @@ func dataSourcePagerDutyUserContactMethodRead(d *schema.ResourceData, meta inter searchLabel := d.Get("label").(string) searchType := d.Get("type").(string) - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.Users.ListContactMethods(userId) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := handleNotFoundError(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -98,7 +98,7 @@ func dataSourcePagerDutyUserContactMethodRead(d *schema.ResourceData, meta inter } if found == nil { - return resource.NonRetryableError(fmt.Errorf("Unable to locate any contact methods with the label: %s", searchLabel)) + return retry.NonRetryableError(fmt.Errorf("Unable to locate any contact methods with the label: %s", searchLabel)) } d.SetId(found.ID) diff --git a/pagerduty/data_source_pagerduty_user_contact_method_test.go b/pagerduty/data_source_pagerduty_user_contact_method_test.go index 1205719a1..0a4e65dcf 100644 --- a/pagerduty/data_source_pagerduty_user_contact_method_test.go +++ b/pagerduty/data_source_pagerduty_user_contact_method_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyUserContactMethod_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_user_test.go b/pagerduty/data_source_pagerduty_user_test.go index 5f900a2cd..35f253c04 100644 --- a/pagerduty/data_source_pagerduty_user_test.go +++ b/pagerduty/data_source_pagerduty_user_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyUser_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_users.go b/pagerduty/data_source_pagerduty_users.go index 9742ebaa7..38bb50d38 100644 --- a/pagerduty/data_source_pagerduty_users.go +++ b/pagerduty/data_source_pagerduty_users.go @@ -6,7 +6,7 @@ import ( "strconv" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -66,17 +66,17 @@ func dataSourcePagerDutyUsersRead(d *schema.ResourceData, meta interface{}) erro TeamIDs: teamIds, } - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, err := client.Users.ListAll(o) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var users []map[string]interface{} diff --git a/pagerduty/data_source_pagerduty_users_test.go b/pagerduty/data_source_pagerduty_users_test.go index 78e50a61c..67642f620 100644 --- a/pagerduty/data_source_pagerduty_users_test.go +++ b/pagerduty/data_source_pagerduty_users_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccDataSourcePagerDutyUsers_Basic(t *testing.T) { diff --git a/pagerduty/data_source_pagerduty_vendor.go b/pagerduty/data_source_pagerduty_vendor.go index e7aeaf287..3c929796c 100644 --- a/pagerduty/data_source_pagerduty_vendor.go +++ b/pagerduty/data_source_pagerduty_vendor.go @@ -8,7 +8,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -43,17 +43,17 @@ func dataSourcePagerDutyVendorRead(d *schema.ResourceData, meta interface{}) err o := &pagerduty.ListVendorsOptions{ Query: searchName, } - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { resp, _, err := client.Vendors.List(o) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var found *pagerduty.Vendor @@ -77,7 +77,7 @@ func dataSourcePagerDutyVendorRead(d *schema.ResourceData, meta interface{}) err } if found == nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("Unable to locate any vendor with the name: %s", searchName), ) } diff --git a/pagerduty/data_source_pagerduty_vendor_test.go b/pagerduty/data_source_pagerduty_vendor_test.go index 78e8c1619..ed3f1df4f 100644 --- a/pagerduty/data_source_pagerduty_vendor_test.go +++ b/pagerduty/data_source_pagerduty_vendor_test.go @@ -3,7 +3,7 @@ package pagerduty import ( "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccDataSourcePagerDutyVendor_Basic(t *testing.T) { diff --git a/pagerduty/import_pagerduty_automation_actions_action_service_association_test.go b/pagerduty/import_pagerduty_automation_actions_action_service_association_test.go index 7d3a03c76..16ad5b803 100644 --- a/pagerduty/import_pagerduty_automation_actions_action_service_association_test.go +++ b/pagerduty/import_pagerduty_automation_actions_action_service_association_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyAutomationActionsActionServiceAssociation_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_automation_actions_action_team_association_test.go b/pagerduty/import_pagerduty_automation_actions_action_team_association_test.go index 822406956..cd6c50fee 100644 --- a/pagerduty/import_pagerduty_automation_actions_action_team_association_test.go +++ b/pagerduty/import_pagerduty_automation_actions_action_team_association_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyAutomationActionsActionTeamAssociation_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_automation_actions_action_test.go b/pagerduty/import_pagerduty_automation_actions_action_test.go index 4669c1ca7..baa5cab2c 100644 --- a/pagerduty/import_pagerduty_automation_actions_action_test.go +++ b/pagerduty/import_pagerduty_automation_actions_action_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyAutomationActionsAction_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_automation_actions_runner_team_association_test.go b/pagerduty/import_pagerduty_automation_actions_runner_team_association_test.go index c7bb118b0..4fcbc95ab 100644 --- a/pagerduty/import_pagerduty_automation_actions_runner_team_association_test.go +++ b/pagerduty/import_pagerduty_automation_actions_runner_team_association_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyAutomationActionsRunnerTeamAssociation_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_automation_actions_runner_test.go b/pagerduty/import_pagerduty_automation_actions_runner_test.go index 54a3744ed..eddf324e3 100644 --- a/pagerduty/import_pagerduty_automation_actions_runner_test.go +++ b/pagerduty/import_pagerduty_automation_actions_runner_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyAutomationActionsRunner_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_business_service_subscriber_test.go b/pagerduty/import_pagerduty_business_service_subscriber_test.go index a42082f7f..e601e42fd 100644 --- a/pagerduty/import_pagerduty_business_service_subscriber_test.go +++ b/pagerduty/import_pagerduty_business_service_subscriber_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyBusinessServiceSubscriber_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_business_service_test.go b/pagerduty/import_pagerduty_business_service_test.go index 74cbf0324..b2070daf3 100644 --- a/pagerduty/import_pagerduty_business_service_test.go +++ b/pagerduty/import_pagerduty_business_service_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyBusinessService_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_escalation_policy_test.go b/pagerduty/import_pagerduty_escalation_policy_test.go index d6e8820ed..eb1973747 100644 --- a/pagerduty/import_pagerduty_escalation_policy_test.go +++ b/pagerduty/import_pagerduty_escalation_policy_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyEscalationPolicy_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_event_orchestration_integration_test.go b/pagerduty/import_pagerduty_event_orchestration_integration_test.go index 2d8e982ff..ce1dca40e 100644 --- a/pagerduty/import_pagerduty_event_orchestration_integration_test.go +++ b/pagerduty/import_pagerduty_event_orchestration_integration_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyEventOrchestrationIntegration_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_event_orchestration_path_global_test.go b/pagerduty/import_pagerduty_event_orchestration_path_global_test.go index c24d70b29..c93514237 100644 --- a/pagerduty/import_pagerduty_event_orchestration_path_global_test.go +++ b/pagerduty/import_pagerduty_event_orchestration_path_global_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyEventOrchestrationPathGlobal_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_event_orchestration_path_router_test.go b/pagerduty/import_pagerduty_event_orchestration_path_router_test.go index 976e80057..5fc93df66 100644 --- a/pagerduty/import_pagerduty_event_orchestration_path_router_test.go +++ b/pagerduty/import_pagerduty_event_orchestration_path_router_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyEventOrchestrationPathRouter_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_event_orchestration_path_service_test.go b/pagerduty/import_pagerduty_event_orchestration_path_service_test.go index 579d2c957..6d377108b 100644 --- a/pagerduty/import_pagerduty_event_orchestration_path_service_test.go +++ b/pagerduty/import_pagerduty_event_orchestration_path_service_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyEventOrchestrationPathService_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_event_orchestration_path_unrouted_test.go b/pagerduty/import_pagerduty_event_orchestration_path_unrouted_test.go index 9ab539ba4..003b6f49e 100644 --- a/pagerduty/import_pagerduty_event_orchestration_path_unrouted_test.go +++ b/pagerduty/import_pagerduty_event_orchestration_path_unrouted_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyEventOrchestrationPathUnrouted_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_event_orchestration_test.go b/pagerduty/import_pagerduty_event_orchestration_test.go index d6b7c8d14..4341a3193 100644 --- a/pagerduty/import_pagerduty_event_orchestration_test.go +++ b/pagerduty/import_pagerduty_event_orchestration_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyEventOrchestration_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_event_rule_test.go b/pagerduty/import_pagerduty_event_rule_test.go index 8b30387c8..01cdd4b79 100644 --- a/pagerduty/import_pagerduty_event_rule_test.go +++ b/pagerduty/import_pagerduty_event_rule_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyEventRule_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_extension_servicenow_test.go b/pagerduty/import_pagerduty_extension_servicenow_test.go index 2136926a6..c0f0d05c5 100644 --- a/pagerduty/import_pagerduty_extension_servicenow_test.go +++ b/pagerduty/import_pagerduty_extension_servicenow_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyExtensionServiceNow_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_extension_test.go b/pagerduty/import_pagerduty_extension_test.go index 725e34a59..6db27db79 100644 --- a/pagerduty/import_pagerduty_extension_test.go +++ b/pagerduty/import_pagerduty_extension_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyExtension_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_incident_custom_field_test.go b/pagerduty/import_pagerduty_incident_custom_field_test.go index b2fe63515..9628e8e18 100644 --- a/pagerduty/import_pagerduty_incident_custom_field_test.go +++ b/pagerduty/import_pagerduty_incident_custom_field_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyIncidentCustomField_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_incident_workflow_test.go b/pagerduty/import_pagerduty_incident_workflow_test.go index 28c34f651..f21399360 100644 --- a/pagerduty/import_pagerduty_incident_workflow_test.go +++ b/pagerduty/import_pagerduty_incident_workflow_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyIncidentWorkflow_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_incident_workflow_trigger_test.go b/pagerduty/import_pagerduty_incident_workflow_trigger_test.go index bfdc0b6e1..104fbb935 100644 --- a/pagerduty/import_pagerduty_incident_workflow_trigger_test.go +++ b/pagerduty/import_pagerduty_incident_workflow_trigger_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyIncidentWorkflowTrigger_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_maintenance_window_test.go b/pagerduty/import_pagerduty_maintenance_window_test.go index ed6dec353..d967872b5 100644 --- a/pagerduty/import_pagerduty_maintenance_window_test.go +++ b/pagerduty/import_pagerduty_maintenance_window_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyMaintenanceWindow_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_response_play_test.go b/pagerduty/import_pagerduty_response_play_test.go index 3cacdf150..e0612e042 100644 --- a/pagerduty/import_pagerduty_response_play_test.go +++ b/pagerduty/import_pagerduty_response_play_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyResponsePlay_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_ruleset_rule_test.go b/pagerduty/import_pagerduty_ruleset_rule_test.go index c8598c1b7..91443b024 100644 --- a/pagerduty/import_pagerduty_ruleset_rule_test.go +++ b/pagerduty/import_pagerduty_ruleset_rule_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyRulesetRule_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_ruleset_test.go b/pagerduty/import_pagerduty_ruleset_test.go index 0a1d6bcda..9c4f1298a 100644 --- a/pagerduty/import_pagerduty_ruleset_test.go +++ b/pagerduty/import_pagerduty_ruleset_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyRuleset_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_schedule_test.go b/pagerduty/import_pagerduty_schedule_test.go index 40338bd9d..cc207840a 100644 --- a/pagerduty/import_pagerduty_schedule_test.go +++ b/pagerduty/import_pagerduty_schedule_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutySchedule_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_service_dependency_test.go b/pagerduty/import_pagerduty_service_dependency_test.go index 5f502090e..35d929ec8 100644 --- a/pagerduty/import_pagerduty_service_dependency_test.go +++ b/pagerduty/import_pagerduty_service_dependency_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyServiceDependency_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_service_event_rule_test.go b/pagerduty/import_pagerduty_service_event_rule_test.go index fda2e4a95..fe0a5819a 100644 --- a/pagerduty/import_pagerduty_service_event_rule_test.go +++ b/pagerduty/import_pagerduty_service_event_rule_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyServiceEventRule_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_service_integration_test.go b/pagerduty/import_pagerduty_service_integration_test.go index e42d4d9e1..490fa8615 100644 --- a/pagerduty/import_pagerduty_service_integration_test.go +++ b/pagerduty/import_pagerduty_service_integration_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyServiceIntegration_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_service_test.go b/pagerduty/import_pagerduty_service_test.go index 5ff7b4e38..bb64798ea 100644 --- a/pagerduty/import_pagerduty_service_test.go +++ b/pagerduty/import_pagerduty_service_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyService_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_slack_connection_test.go b/pagerduty/import_pagerduty_slack_connection_test.go index 2b363081d..71d584fc4 100644 --- a/pagerduty/import_pagerduty_slack_connection_test.go +++ b/pagerduty/import_pagerduty_slack_connection_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutySlackConnection_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_tag_assignment_test.go b/pagerduty/import_pagerduty_tag_assignment_test.go index 71b1b874a..cd125d2bd 100644 --- a/pagerduty/import_pagerduty_tag_assignment_test.go +++ b/pagerduty/import_pagerduty_tag_assignment_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyTagAssignment_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_tag_test.go b/pagerduty/import_pagerduty_tag_test.go index 9c40a0d62..e6e2ae815 100644 --- a/pagerduty/import_pagerduty_tag_test.go +++ b/pagerduty/import_pagerduty_tag_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyTag_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_team_membership_test.go b/pagerduty/import_pagerduty_team_membership_test.go index 2c1a4a220..d290db143 100644 --- a/pagerduty/import_pagerduty_team_membership_test.go +++ b/pagerduty/import_pagerduty_team_membership_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyTeamMembership_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_team_test.go b/pagerduty/import_pagerduty_team_test.go index d9894f0a8..5dbce3a58 100644 --- a/pagerduty/import_pagerduty_team_test.go +++ b/pagerduty/import_pagerduty_team_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyTeam_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_user_contact_method_test.go b/pagerduty/import_pagerduty_user_contact_method_test.go index fa33a19a7..afd754c55 100644 --- a/pagerduty/import_pagerduty_user_contact_method_test.go +++ b/pagerduty/import_pagerduty_user_contact_method_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyUserContactMethod_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_user_notification_rule_test.go b/pagerduty/import_pagerduty_user_notification_rule_test.go index 74b7206c9..134d95648 100644 --- a/pagerduty/import_pagerduty_user_notification_rule_test.go +++ b/pagerduty/import_pagerduty_user_notification_rule_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyUserNotificationRule_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_user_test.go b/pagerduty/import_pagerduty_user_test.go index 527ebf884..d6729cf8c 100644 --- a/pagerduty/import_pagerduty_user_test.go +++ b/pagerduty/import_pagerduty_user_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyUser_import(t *testing.T) { diff --git a/pagerduty/import_pagerduty_webhook_subscription_test.go b/pagerduty/import_pagerduty_webhook_subscription_test.go index 7bf88092a..fe4a230db 100644 --- a/pagerduty/import_pagerduty_webhook_subscription_test.go +++ b/pagerduty/import_pagerduty_webhook_subscription_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestAccPagerDutyWebhookSubscription_import(t *testing.T) { diff --git a/pagerduty/provider_test.go b/pagerduty/provider_test.go index 985e78a68..93996ca71 100644 --- a/pagerduty/provider_test.go +++ b/pagerduty/provider_test.go @@ -8,9 +8,9 @@ import ( "testing" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_addon.go b/pagerduty/resource_pagerduty_addon.go index 05d875671..6ddde2393 100644 --- a/pagerduty/resource_pagerduty_addon.go +++ b/pagerduty/resource_pagerduty_addon.go @@ -5,7 +5,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -48,18 +48,18 @@ func fetchPagerDutyAddon(d *schema.ResourceData, meta interface{}, errCallback f return err } - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { addon, _, err := client.Addons.Get(d.Id()) if err != nil { log.Printf("[WARN] Service read error") if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil diff --git a/pagerduty/resource_pagerduty_addon_test.go b/pagerduty/resource_pagerduty_addon_test.go index eb777f6f3..1cbe5149f 100644 --- a/pagerduty/resource_pagerduty_addon_test.go +++ b/pagerduty/resource_pagerduty_addon_test.go @@ -6,9 +6,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_automation_actions_action.go b/pagerduty/resource_pagerduty_automation_actions_action.go index 4fc6a79a6..907afdc7a 100644 --- a/pagerduty/resource_pagerduty_automation_actions_action.go +++ b/pagerduty/resource_pagerduty_automation_actions_action.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -104,7 +104,6 @@ func resourcePagerDutyAutomationActionsAction() *schema.Resource { } func buildAutomationActionsActionStruct(d *schema.ResourceData) (*pagerduty.AutomationActionsAction, error) { - automationActionsAction := pagerduty.AutomationActionsAction{ Name: d.Get("name").(string), ActionType: d.Get("action_type").(string), @@ -212,14 +211,14 @@ func resourcePagerDutyAutomationActionsActionCreate(d *schema.ResourceData, meta log.Printf("[INFO] Creating PagerDuty AutomationActionsAction %s", automationActionsAction.Name) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if automationActionsAction, _, err := client.AutomationActionsAction.Create(automationActionsAction); err != nil { if isErrCode(err, 400) || isErrCode(err, 429) { time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else if automationActionsAction != nil { d.SetId(automationActionsAction.ID) } @@ -261,14 +260,14 @@ func resourcePagerDutyAutomationActionsActionRead(d *schema.ResourceData, meta i log.Printf("[INFO] Reading PagerDuty AutomationActionsAction %s", d.Id()) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { if automationActionsAction, _, err := client.AutomationActionsAction.Get(d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if automationActionsAction != nil { d.Set("name", automationActionsAction.Name) d.Set("type", automationActionsAction.Type) @@ -281,7 +280,7 @@ func resourcePagerDutyAutomationActionsActionRead(d *schema.ResourceData, meta i f_adr := flattenActionDataReference(automationActionsAction.ActionDataReference) if err := d.Set("action_data_reference", f_adr); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } if automationActionsAction.ModifyTime != nil { @@ -338,13 +337,13 @@ func resourcePagerDutyAutomationActionsActionDelete(d *schema.ResourceData, meta log.Printf("[INFO] Deleting PagerDuty AutomationActionsAction %s", d.Id()) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.AutomationActionsAction.Delete(d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_automation_actions_action_service_association.go b/pagerduty/resource_pagerduty_automation_actions_action_service_association.go index 7a4a2db9c..4b4c4ddff 100644 --- a/pagerduty/resource_pagerduty_automation_actions_action_service_association.go +++ b/pagerduty/resource_pagerduty_automation_actions_action_service_association.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -44,14 +44,14 @@ func resourcePagerDutyAutomationActionsActionServiceAssociationCreate(d *schema. log.Printf("[INFO] Creating PagerDuty AutomationActionsActionServiceAssociation %s:%s", d.Get("action_id").(string), d.Get("service_id").(string)) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if serviceRef, _, err := client.AutomationActionsAction.AssociateToService(actionID, serviceID); err != nil { if isErrCode(err, 429) { time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else if serviceRef != nil { d.SetId(fmt.Sprintf("%s:%s", actionID, serviceID)) } @@ -76,17 +76,17 @@ func fetchPagerDutyAutomationActionsActionServiceAssociation(d *schema.ResourceD return err } - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { resp, _, err := client.AutomationActionsAction.GetAssociationToService(actionID, serviceID) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -122,13 +122,13 @@ func resourcePagerDutyAutomationActionsActionServiceAssociationDelete(d *schema. log.Printf("[INFO] Deleting PagerDuty AutomationActionsActionServiceAssociation %s", d.Id()) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.AutomationActionsAction.DissociateFromService(actionID, serviceID); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_automation_actions_action_service_association_test.go b/pagerduty/resource_pagerduty_automation_actions_action_service_association_test.go index 255e02016..9fb4b777a 100644 --- a/pagerduty/resource_pagerduty_automation_actions_action_service_association_test.go +++ b/pagerduty/resource_pagerduty_automation_actions_action_service_association_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/resource_pagerduty_automation_actions_action_team_association.go b/pagerduty/resource_pagerduty_automation_actions_action_team_association.go index bdc7de507..0cf568fc2 100644 --- a/pagerduty/resource_pagerduty_automation_actions_action_team_association.go +++ b/pagerduty/resource_pagerduty_automation_actions_action_team_association.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -44,18 +44,18 @@ func resourcePagerDutyAutomationActionsActionTeamAssociationCreate(d *schema.Res log.Printf("[INFO] Creating PagerDuty AutomationActionsActionTeamAssociation %s:%s", d.Get("action_id").(string), d.Get("team_id").(string)) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if teamRef, _, err := client.AutomationActionsAction.AssociateToTeam(actionID, teamID); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } if isErrCode(err, 429) { time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else if teamRef != nil { d.SetId(fmt.Sprintf("%s:%s", actionID, teamID)) } @@ -80,17 +80,17 @@ func fetchPagerDutyAutomationActionsActionTeamAssociation(d *schema.ResourceData return err } - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { resp, _, err := client.AutomationActionsAction.GetAssociationToTeam(actionID, teamID) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -126,13 +126,13 @@ func resourcePagerDutyAutomationActionsActionTeamAssociationDelete(d *schema.Res log.Printf("[INFO] Deleting PagerDuty AutomationActionsActionTeamAssociation %s", d.Id()) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.AutomationActionsAction.DissociateToTeam(actionID, teamID); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_automation_actions_action_team_association_test.go b/pagerduty/resource_pagerduty_automation_actions_action_team_association_test.go index 178c351e8..af0cba408 100644 --- a/pagerduty/resource_pagerduty_automation_actions_action_team_association_test.go +++ b/pagerduty/resource_pagerduty_automation_actions_action_team_association_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/resource_pagerduty_automation_actions_action_test.go b/pagerduty/resource_pagerduty_automation_actions_action_test.go index 35c2c28cc..e47e21ed6 100644 --- a/pagerduty/resource_pagerduty_automation_actions_action_test.go +++ b/pagerduty/resource_pagerduty_automation_actions_action_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/resource_pagerduty_automation_actions_runner.go b/pagerduty/resource_pagerduty_automation_actions_runner.go index 683a7bd23..f8e92aaa0 100644 --- a/pagerduty/resource_pagerduty_automation_actions_runner.go +++ b/pagerduty/resource_pagerduty_automation_actions_runner.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -65,7 +65,6 @@ func resourcePagerDutyAutomationActionsRunner() *schema.Resource { } func buildAutomationActionsRunnerStruct(d *schema.ResourceData) (*pagerduty.AutomationActionsRunner, error) { - automationActionsRunner := pagerduty.AutomationActionsRunner{ Name: d.Get("name").(string), RunnerType: d.Get("runner_type").(string), @@ -113,14 +112,14 @@ func resourcePagerDutyAutomationActionsRunnerCreate(d *schema.ResourceData, meta log.Printf("[INFO] Creating PagerDuty AutomationActionsRunner %s", automationActionsRunner.Name) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if automationActionsRunner, _, err := client.AutomationActionsRunner.Create(automationActionsRunner); err != nil { if isErrCode(err, 400) || isErrCode(err, 429) { time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else if automationActionsRunner != nil { d.SetId(automationActionsRunner.ID) } @@ -142,14 +141,14 @@ func resourcePagerDutyAutomationActionsRunnerRead(d *schema.ResourceData, meta i log.Printf("[INFO] Reading PagerDuty AutomationActionsRunner %s", d.Id()) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { if automationActionsRunner, _, err := client.AutomationActionsRunner.Get(d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if automationActionsRunner != nil { d.Set("name", automationActionsRunner.Name) d.Set("type", automationActionsRunner.Type) @@ -200,13 +199,13 @@ func resourcePagerDutyAutomationActionsRunnerDelete(d *schema.ResourceData, meta log.Printf("[INFO] Deleting PagerDuty AutomationActionsRunner %s", d.Id()) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.AutomationActionsRunner.Delete(d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_automation_actions_runner_team_association.go b/pagerduty/resource_pagerduty_automation_actions_runner_team_association.go index cf76d35a5..eecf1ba8b 100644 --- a/pagerduty/resource_pagerduty_automation_actions_runner_team_association.go +++ b/pagerduty/resource_pagerduty_automation_actions_runner_team_association.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -44,14 +44,14 @@ func resourcePagerDutyAutomationActionsRunnerTeamAssociationCreate(d *schema.Res log.Printf("[INFO] Creating PagerDuty AutomationActionsRunnerTeamAssociation %s:%s", d.Get("runner_id").(string), d.Get("team_id").(string)) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if teamRef, _, err := client.AutomationActionsRunner.AssociateToTeam(runnerID, teamID); err != nil { if isErrCode(err, 429) { time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else if teamRef != nil { d.SetId(fmt.Sprintf("%s:%s", runnerID, teamID)) } @@ -76,17 +76,17 @@ func fetchPagerDutyAutomationActionsRunnerTeamAssociation(d *schema.ResourceData return err } - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { resp, _, err := client.AutomationActionsRunner.GetAssociationToTeam(runnerID, teamID) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -122,13 +122,13 @@ func resourcePagerDutyAutomationActionsRunnerTeamAssociationDelete(d *schema.Res log.Printf("[INFO] Deleting PagerDuty AutomationActionsRunnerTeamAssociation %s", d.Id()) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.AutomationActionsRunner.DissociateFromTeam(runnerID, teamID); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_automation_actions_runner_team_association_test.go b/pagerduty/resource_pagerduty_automation_actions_runner_team_association_test.go index e2498c951..1c58f95ef 100644 --- a/pagerduty/resource_pagerduty_automation_actions_runner_team_association_test.go +++ b/pagerduty/resource_pagerduty_automation_actions_runner_team_association_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/resource_pagerduty_automation_actions_runner_test.go b/pagerduty/resource_pagerduty_automation_actions_runner_test.go index a81c60ec6..2c721747b 100644 --- a/pagerduty/resource_pagerduty_automation_actions_runner_test.go +++ b/pagerduty/resource_pagerduty_automation_actions_runner_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/resource_pagerduty_business_service.go b/pagerduty/resource_pagerduty_business_service.go index 5af0e1841..33f91700a 100644 --- a/pagerduty/resource_pagerduty_business_service.go +++ b/pagerduty/resource_pagerduty_business_service.go @@ -5,7 +5,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -99,15 +99,14 @@ func resourcePagerDutyBusinessServiceCreate(d *schema.ResourceData, meta interfa return err } - retryErr := resource.Retry(5*time.Minute, func() *resource.RetryError { - + retryErr := retry.Retry(5*time.Minute, func() *retry.RetryError { businessService, err := buildBusinessServiceStruct(d) if err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } log.Printf("[INFO] Creating PagerDuty business service %s", businessService.Name) if businessService, _, err = client.BusinessServices.Create(businessService); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } else if businessService != nil { d.SetId(businessService.ID) } @@ -129,13 +128,13 @@ func resourcePagerDutyBusinessServiceRead(d *schema.ResourceData, meta interface log.Printf("[INFO] Reading PagerDuty business service %s", d.Id()) - retryErr := resource.Retry(5*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(5*time.Minute, func() *retry.RetryError { if businessService, _, err := client.BusinessServices.Get(d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if businessService != nil { d.Set("name", businessService.Name) d.Set("html_url", businessService.HTMLUrl) diff --git a/pagerduty/resource_pagerduty_business_service_subscriber.go b/pagerduty/resource_pagerduty_business_service_subscriber.go index ef8abde8c..49a9f9f51 100644 --- a/pagerduty/resource_pagerduty_business_service_subscriber.go +++ b/pagerduty/resource_pagerduty_business_service_subscriber.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -61,16 +61,15 @@ func resourcePagerDutyBusinessServiceSubscriberCreate(d *schema.ResourceData, me businessServiceId := d.Get("business_service_id").(string) - retryErr := resource.Retry(5*time.Minute, func() *resource.RetryError { - + retryErr := retry.Retry(5*time.Minute, func() *retry.RetryError { businessServiceSubscriber, err := buildBusinessServiceSubscriberStruct(d) if err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } log.Printf("[INFO] Creating PagerDuty business service %s subscriber %s type %s", businessServiceId, businessServiceSubscriber.ID, businessServiceSubscriber.Type) if _, err = client.BusinessServiceSubscribers.Create(businessServiceId, businessServiceSubscriber); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } else if businessServiceSubscriber != nil { // create subscriber assignment it as PagerDuty API does not return one assignmentID := createSubscriberID(businessServiceId, businessServiceSubscriber.Type, businessServiceSubscriber.ID) @@ -97,14 +96,14 @@ func resourcePagerDutyBusinessServiceSubscriberRead(d *schema.ResourceData, meta log.Printf("[INFO] Reading PagerDuty business service %s subscriber %s type %s", businessServiceId, businessServiceSubscriber.ID, businessServiceSubscriber.Type) - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { if subscriberResponse, _, err := client.BusinessServiceSubscribers.List(businessServiceId); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if subscriberResponse != nil { var foundSubscriber *pagerduty.BusinessServiceSubscriber diff --git a/pagerduty/resource_pagerduty_business_service_subscriber_test.go b/pagerduty/resource_pagerduty_business_service_subscriber_test.go index edeaaa0bb..0e4618264 100644 --- a/pagerduty/resource_pagerduty_business_service_subscriber_test.go +++ b/pagerduty/resource_pagerduty_business_service_subscriber_test.go @@ -5,9 +5,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyBusinessServiceSubscriber_User(t *testing.T) { diff --git a/pagerduty/resource_pagerduty_business_service_test.go b/pagerduty/resource_pagerduty_business_service_test.go index 9ad00f364..5e42b6149 100644 --- a/pagerduty/resource_pagerduty_business_service_test.go +++ b/pagerduty/resource_pagerduty_business_service_test.go @@ -6,9 +6,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/resource_pagerduty_escalation_policy.go b/pagerduty/resource_pagerduty_escalation_policy.go index 23fd9d186..ccdd8648d 100644 --- a/pagerduty/resource_pagerduty_escalation_policy.go +++ b/pagerduty/resource_pagerduty_escalation_policy.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/heimweh/go-pagerduty/pagerduty" @@ -137,23 +137,23 @@ func resourcePagerDutyEscalationPolicyCreate(d *schema.ResourceData, meta interf log.Printf("[INFO] Creating PagerDuty escalation policy: %s", escalationPolicy.Name) - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { escalationPolicy, _, err := client.EscalationPolicies.Create(escalationPolicy) if err != nil { if isErrCode(err, 429) { // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } d.SetId(escalationPolicy.ID) readErr = fetchEscalationPolicy(d, meta, genError) if readErr != nil { - return resource.NonRetryableError(readErr) + return retry.NonRetryableError(readErr) } return nil }) @@ -172,18 +172,18 @@ func fetchEscalationPolicy(d *schema.ResourceData, meta interface{}, errCallback o := &pagerduty.GetEscalationPolicyOptions{Includes: []string{"escalation_rule_assignment_strategies"}} - return resource.Retry(5*time.Minute, func() *resource.RetryError { + return retry.Retry(5*time.Minute, func() *retry.RetryError { escalationPolicy, _, err := client.EscalationPolicies.Get(d.Id(), o) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) log.Printf("[WARN] Escalation Policy read error") if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil @@ -194,11 +194,11 @@ func fetchEscalationPolicy(d *schema.ResourceData, meta interface{}, errCallback d.Set("num_loops", escalationPolicy.NumLoops) if err := d.Set("teams", flattenTeams(escalationPolicy.Teams)); err != nil { - return resource.NonRetryableError(fmt.Errorf("error setting teams: %s", err)) + return retry.NonRetryableError(fmt.Errorf("error setting teams: %s", err)) } if err := d.Set("rule", flattenEscalationRules(escalationPolicy.EscalationRules)); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil @@ -215,9 +215,9 @@ func resourcePagerDutyEscalationPolicyUpdate(d *schema.ResourceData, meta interf log.Printf("[INFO] Updating PagerDuty escalation policy: %s", d.Id()) - retryErr := resource.Retry(5*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(5*time.Minute, func() *retry.RetryError { if _, _, err := client.EscalationPolicies.Update(d.Id(), escalationPolicy); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) @@ -238,13 +238,13 @@ func resourcePagerDutyEscalationPolicyDelete(d *schema.ResourceData, meta interf log.Printf("[INFO] Deleting PagerDuty escalation policy: %s", d.Id()) // Retrying to give other resources (such as services) to delete - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.EscalationPolicies.Delete(d.Id()); err != nil { if isErrCode(err, 400) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_escalation_policy_test.go b/pagerduty/resource_pagerduty_escalation_policy_test.go index 13d4c9e3e..f996a97a6 100644 --- a/pagerduty/resource_pagerduty_escalation_policy_test.go +++ b/pagerduty/resource_pagerduty_escalation_policy_test.go @@ -7,9 +7,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_event_orchestration.go b/pagerduty/resource_pagerduty_event_orchestration.go index 53c57b86b..3efda05a5 100644 --- a/pagerduty/resource_pagerduty_event_orchestration.go +++ b/pagerduty/resource_pagerduty_event_orchestration.go @@ -5,7 +5,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -107,13 +107,13 @@ func resourcePagerDutyEventOrchestrationCreate(d *schema.ResourceData, meta inte log.Printf("[INFO] Creating PagerDuty Event Orchestration: %s", payload.Name) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if orch, _, err := client.EventOrchestrations.Create(payload); err != nil { if isErrCode(err, 400) || isErrCode(err, 429) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else if orch != nil { d.SetId(orch.ID) orchestration = orch @@ -136,17 +136,17 @@ func resourcePagerDutyEventOrchestrationRead(d *schema.ResourceData, meta interf return err } - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { orch, _, err := client.EventOrchestrations.Get(d.Id()) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := handleNotFoundError(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -168,12 +168,12 @@ func resourcePagerDutyEventOrchestrationUpdate(d *schema.ResourceData, meta inte log.Printf("[INFO] Updating PagerDuty Event Orchestration: %s", d.Id()) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, _, err := client.EventOrchestrations.Update(d.Id(), orchestration); err != nil { if isErrCode(err, 400) || isErrCode(err, 429) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil diff --git a/pagerduty/resource_pagerduty_event_orchestration_integration.go b/pagerduty/resource_pagerduty_event_orchestration_integration.go index b8d0b14f3..bfe386e17 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_integration.go +++ b/pagerduty/resource_pagerduty_event_orchestration_integration.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -113,19 +113,19 @@ func resourcePagerDutyEventOrchestrationIntegrationCreate(ctx context.Context, d oid, payload := getEventOrchestrationIntegrationPayloadData(d) - retryErr := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { log.Printf("[INFO] Creating Integration '%s' for PagerDuty Event Orchestration '%s'", payload.Label, oid) if integration, _, err := client.EventOrchestrationIntegrations.CreateContext(ctx, oid, payload); err != nil { if isErrCode(err, 400) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if integration != nil { // Try reading an integration after creation, retry if not found: if _, readErr := fetchPagerDutyEventOrchestrationIntegration(ctx, d, meta, oid, integration.ID, true); readErr != nil { log.Printf("[WARN] Cannot locate Integration '%s' on PagerDuty Event Orchestration '%s'. Retrying creation...", integration.ID, oid) - return resource.RetryableError(readErr) + return retry.RetryableError(readErr) } } return nil @@ -143,15 +143,15 @@ func resourcePagerDutyEventOrchestrationIntegrationRead(ctx context.Context, d * id := d.Id() oid := d.Get("event_orchestration").(string) - retryErr := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { log.Printf("[INFO] Reading Integration '%s' for PagerDuty Event Orchestration: %s", id, oid) if _, err := fetchPagerDutyEventOrchestrationIntegration(ctx, d, meta, oid, id, false); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil @@ -178,14 +178,14 @@ func resourcePagerDutyEventOrchestrationIntegrationUpdate(ctx context.Context, d sourceOrchId := o.(string) destinationOrchId := n.(string) - retryErr := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { log.Printf("[INFO] Migrating Event Orchestration Integration '%s': source - '%s', destination - '%s'", id, sourceOrchId, destinationOrchId) if _, _, err := client.EventOrchestrationIntegrations.MigrateFromOrchestrationContext(ctx, destinationOrchId, sourceOrchId, id); err != nil { if isErrCode(err, 400) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else { // try reading the migrated integration from destination and source: _, _, readDestErr := client.EventOrchestrationIntegrations.GetContext(ctx, destinationOrchId, id) @@ -194,13 +194,13 @@ func resourcePagerDutyEventOrchestrationIntegrationUpdate(ctx context.Context, d // retry migration if the read request returned an error: if readDestErr != nil { log.Printf("[WARN] Integration '%s' cannot be found on the destination PagerDuty Event Orchestration '%s'. Retrying migration....", id, destinationOrchId) - return resource.RetryableError(readDestErr) + return retry.RetryableError(readDestErr) } // retry migration if the integration still exists on the source: if readSrcErr == nil && srcInt != nil { log.Printf("[WARN] Integration '%s' still exists on the source PagerDuty Event Orchestration '%s'. Retrying migration....", id, sourceOrchId) - return resource.RetryableError(fmt.Errorf("Integration '%s' still exists on the source PagerDuty Event Orchestration '%s'.", id, sourceOrchId)) + return retry.RetryableError(fmt.Errorf("Integration '%s' still exists on the source PagerDuty Event Orchestration '%s'.", id, sourceOrchId)) } } return nil @@ -216,19 +216,19 @@ func resourcePagerDutyEventOrchestrationIntegrationUpdate(ctx context.Context, d if d.HasChange("label") { oid, payload := getEventOrchestrationIntegrationPayloadData(d) - retryErr := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { log.Printf("[INFO] Updating Integration '%s' for PagerDuty Event Orchestration: %s", id, oid) if integration, _, err := client.EventOrchestrationIntegrations.UpdateContext(ctx, oid, id, payload); err != nil { if isErrCode(err, 400) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if integration != nil { // Try reading an integration after updating the label, retry if the label is not updated: if updInt, readErr := fetchPagerDutyEventOrchestrationIntegration(ctx, d, meta, oid, id, true); readErr != nil && updInt != nil { log.Printf("[WARN] Label for Integration '%s' on PagerDuty Event Orchestration '%s' was not updated. Expected: '%s', actual: '%s'. Retrying update...", id, oid, payload.Label, updInt.Label) - return resource.RetryableError(readErr) + return retry.RetryableError(readErr) } } return nil @@ -252,19 +252,19 @@ func resourcePagerDutyEventOrchestrationIntegrationDelete(ctx context.Context, d id := d.Id() oid, _ := getEventOrchestrationIntegrationPayloadData(d) - retryErr := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { log.Printf("[INFO] Deleting Integration '%s' for PagerDuty Event Orchestration: %s", id, oid) if _, err := client.EventOrchestrationIntegrations.DeleteContext(ctx, oid, id); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else { // Try reading an integration after deletion, retry if still found: if integr, _, readErr := client.EventOrchestrationIntegrations.GetContext(ctx, oid, id); readErr == nil && integr != nil { log.Printf("[WARN] Integration '%s' still exists on PagerDuty Event Orchestration '%s'. Retrying deletion...", id, oid) - return resource.RetryableError(fmt.Errorf("Integration '%s' still exists on PagerDuty Event Orchestration '%s'.", id, oid)) + return retry.RetryableError(fmt.Errorf("Integration '%s' still exists on PagerDuty Event Orchestration '%s'.", id, oid)) } } return nil @@ -290,15 +290,15 @@ func resourcePagerDutyEventOrchestrationIntegrationImport(ctx context.Context, d return []*schema.ResourceData{}, fmt.Errorf("Error importing pagerduty_event_orchestration_integration. Expected import ID format: :") } - retryErr := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { log.Printf("[INFO] Reading Integration '%s' for PagerDuty Event Orchestration: %s", id, oid) if _, err := fetchPagerDutyEventOrchestrationIntegration(ctx, d, meta, oid, id, false); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_event_orchestration_integration_test.go b/pagerduty/resource_pagerduty_event_orchestration_integration_test.go index eaea682b2..19a3f61d1 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_integration_test.go +++ b/pagerduty/resource_pagerduty_event_orchestration_integration_test.go @@ -5,9 +5,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/resource_pagerduty_event_orchestration_path_global.go b/pagerduty/resource_pagerduty_event_orchestration_path_global.go index 83a723a1d..9045800a7 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_path_global.go +++ b/pagerduty/resource_pagerduty_event_orchestration_path_global.go @@ -7,7 +7,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -170,18 +170,18 @@ func resourcePagerDutyEventOrchestrationPathGlobalRead(ctx context.Context, d *s return diag.FromErr(err) } - retryErr := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { id := d.Id() t := "global" log.Printf("[INFO] Reading PagerDuty Event Orchestration Path of type %s for orchestration: %s", t, id) if path, _, err := client.EventOrchestrationPaths.GetContext(ctx, d.Id(), t); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if path != nil { setEventOrchestrationPathGlobalProps(d, path) } @@ -193,7 +193,6 @@ func resourcePagerDutyEventOrchestrationPathGlobalRead(ctx context.Context, d *s } return diags - } func resourcePagerDutyEventOrchestrationPathGlobalCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -214,13 +213,13 @@ func resourcePagerDutyEventOrchestrationPathGlobalUpdate(ctx context.Context, d log.Printf("[INFO] Creating PagerDuty Event Orchestration Global Path: %s", payload.Parent.ID) - retryErr := resource.RetryContext(ctx, 30*time.Second, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 30*time.Second, func() *retry.RetryError { if response, _, err := client.EventOrchestrationPaths.UpdateContext(ctx, payload.Parent.ID, "global", payload); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if response != nil { d.SetId(response.OrchestrationPath.Parent.ID) globalPath = response.OrchestrationPath @@ -251,13 +250,13 @@ func resourcePagerDutyEventOrchestrationPathGlobalDelete(ctx context.Context, d log.Printf("[INFO] Deleting PagerDuty Global Event Orchestration Path: %s", orchestrationID) - retryErr := resource.RetryContext(ctx, 30*time.Second, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 30*time.Second, func() *retry.RetryError { if _, _, err := client.EventOrchestrationPaths.UpdateContext(ctx, orchestrationID, "global", emptyPath); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) @@ -337,7 +336,7 @@ func expandGlobalPathRules(v interface{}) []*pagerduty.EventOrchestrationPathRul } func expandGlobalPathCatchAll(v interface{}) *pagerduty.EventOrchestrationPathCatchAll { - var catchAll = new(pagerduty.EventOrchestrationPathCatchAll) + catchAll := new(pagerduty.EventOrchestrationPathCatchAll) for _, ca := range v.([]interface{}) { if ca != nil { @@ -350,7 +349,7 @@ func expandGlobalPathCatchAll(v interface{}) *pagerduty.EventOrchestrationPathCa } func expandGlobalPathActions(v interface{}) *pagerduty.EventOrchestrationPathRuleActions { - var actions = &pagerduty.EventOrchestrationPathRuleActions{ + actions := &pagerduty.EventOrchestrationPathRuleActions{ AutomationActions: []*pagerduty.EventOrchestrationPathAutomationAction{}, Variables: []*pagerduty.EventOrchestrationPathActionVariables{}, Extractions: []*pagerduty.EventOrchestrationPathActionExtractions{}, diff --git a/pagerduty/resource_pagerduty_event_orchestration_path_global_test.go b/pagerduty/resource_pagerduty_event_orchestration_path_global_test.go index 0312276e0..03dd94dbb 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_path_global_test.go +++ b/pagerduty/resource_pagerduty_event_orchestration_path_global_test.go @@ -6,9 +6,9 @@ import ( "regexp" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/resource_pagerduty_event_orchestration_path_router.go b/pagerduty/resource_pagerduty_event_orchestration_path_router.go index 7e34eddd4..5a1a0e8b0 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_path_router.go +++ b/pagerduty/resource_pagerduty_event_orchestration_path_router.go @@ -8,7 +8,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -60,7 +60,7 @@ func resourcePagerDutyEventOrchestrationPathRouter() *schema.Resource { "actions": { Type: schema.TypeList, Required: true, - MaxItems: 1, //there can only be one action for router + MaxItems: 1, // there can only be one action for router Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "route_to": { @@ -121,16 +121,16 @@ func resourcePagerDutyEventOrchestrationPathRouterRead(ctx context.Context, d *s return diag.FromErr(err) } - retryErr := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { log.Printf("[INFO] Reading PagerDuty Event Orchestration Path of type %s for orchestration: %s", "router", d.Id()) if routerPath, _, err := client.EventOrchestrationPaths.GetContext(ctx, d.Id(), "router"); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if routerPath != nil { d.Set("event_orchestration", routerPath.Parent.ID) @@ -170,13 +170,13 @@ func resourcePagerDutyEventOrchestrationPathRouterDelete(ctx context.Context, d log.Printf("[INFO] Deleting PagerDuty Event Orchestration Router Path: %s", routerID) - retryErr := resource.RetryContext(ctx, 30*time.Second, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 30*time.Second, func() *retry.RetryError { if _, _, err := client.EventOrchestrationPaths.UpdateContext(ctx, routerID, "router", emptyPath); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) @@ -202,17 +202,17 @@ func resourcePagerDutyEventOrchestrationPathRouterUpdate(ctx context.Context, d log.Printf("[INFO] Updating PagerDuty Event Orchestration Path of type %s for orchestration: %s", "router", routerPath.Parent.ID) - retryErr := resource.RetryContext(ctx, 30*time.Second, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 30*time.Second, func() *retry.RetryError { response, _, err := client.EventOrchestrationPaths.UpdateContext(ctx, routerPath.Parent.ID, "router", routerPath) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } if response == nil { - return resource.NonRetryableError(fmt.Errorf("No Event Orchestration Router found.")) + return retry.NonRetryableError(fmt.Errorf("No Event Orchestration Router found.")) } d.SetId(routerPath.Parent.ID) d.Set("event_orchestration", routerPath.Parent.ID) @@ -236,7 +236,6 @@ func resourcePagerDutyEventOrchestrationPathRouterUpdate(ctx context.Context, d } func buildRouterPathStructForUpdate(d *schema.ResourceData) *pagerduty.EventOrchestrationPath { - orchPath := &pagerduty.EventOrchestrationPath{ Parent: &pagerduty.EventOrchestrationPathReference{ ID: d.Get("event_orchestration").(string), @@ -292,7 +291,7 @@ func expandRules(v interface{}) []*pagerduty.EventOrchestrationPathRule { } func expandRouterActions(v interface{}) *pagerduty.EventOrchestrationPathRuleActions { - var actions = new(pagerduty.EventOrchestrationPathRuleActions) + actions := new(pagerduty.EventOrchestrationPathRuleActions) for _, ai := range v.([]interface{}) { am := ai.(map[string]interface{}) actions.RouteTo = am["route_to"].(string) @@ -302,7 +301,7 @@ func expandRouterActions(v interface{}) *pagerduty.EventOrchestrationPathRuleAct } func expandCatchAll(v interface{}) *pagerduty.EventOrchestrationPathCatchAll { - var catchAll = new(pagerduty.EventOrchestrationPathCatchAll) + catchAll := new(pagerduty.EventOrchestrationPathCatchAll) for _, ca := range v.([]interface{}) { am := ca.(map[string]interface{}) diff --git a/pagerduty/resource_pagerduty_event_orchestration_path_router_test.go b/pagerduty/resource_pagerduty_event_orchestration_path_router_test.go index 894fbc8c4..246c349d5 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_path_router_test.go +++ b/pagerduty/resource_pagerduty_event_orchestration_path_router_test.go @@ -5,9 +5,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/resource_pagerduty_event_orchestration_path_service.go b/pagerduty/resource_pagerduty_event_orchestration_path_service.go index 9bcdf3f2d..c8a029d30 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_path_service.go +++ b/pagerduty/resource_pagerduty_event_orchestration_path_service.go @@ -8,7 +8,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -185,7 +185,7 @@ func resourcePagerDutyEventOrchestrationPathServiceRead(ctx context.Context, d * id := d.Id() var path *pagerduty.EventOrchestrationPath - retryErr := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { t := "service" log.Printf("[INFO] Reading PagerDuty Event Orchestration Path of type %s for service: %s", t, id) @@ -193,11 +193,11 @@ func resourcePagerDutyEventOrchestrationPathServiceRead(ctx context.Context, d * if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil @@ -209,7 +209,7 @@ func resourcePagerDutyEventOrchestrationPathServiceRead(ctx context.Context, d * serviceID := d.Get("service").(string) if path != nil { - retryErr = resource.RetryContext(ctx, 30*time.Second, func() *resource.RetryError { + retryErr = retry.RetryContext(ctx, 30*time.Second, func() *retry.RetryError { log.Printf("[INFO] Reading PagerDuty Event Orchestration Path Service Active Status for service: %s", serviceID) pathServiceActiveStatus, _, err := client.EventOrchestrationPaths.GetServiceActiveStatusContext(ctx, serviceID) // It should not retry request to the status endpoint after it starts to @@ -220,11 +220,11 @@ func resourcePagerDutyEventOrchestrationPathServiceRead(ctx context.Context, d * } if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } d.Set("enable_event_orchestration_for_service", pathServiceActiveStatus.Active) return nil @@ -261,13 +261,13 @@ func resourcePagerDutyEventOrchestrationPathServiceUpdate(ctx context.Context, d log.Printf("[INFO] Saving PagerDuty Event Orchestration Service Path: %s", serviceID) - retryErr := resource.RetryContext(ctx, 30*time.Second, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 30*time.Second, func() *retry.RetryError { if response, _, err := client.EventOrchestrationPaths.UpdateContext(ctx, serviceID, "service", payload); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if response != nil { d.SetId(response.OrchestrationPath.Parent.ID) servicePath = response.OrchestrationPath @@ -286,22 +286,22 @@ func resourcePagerDutyEventOrchestrationPathServiceUpdate(ctx context.Context, d enableEOForService := d.Get("enable_event_orchestration_for_service").(bool) log.Printf("[INFO] Updating PagerDuty Event Orchestration Path Service Active Status for service: %s", serviceID) - retryErr = resource.RetryContext(ctx, 30*time.Second, func() *resource.RetryError { + retryErr = retry.RetryContext(ctx, 30*time.Second, func() *retry.RetryError { resp, _, err := client.EventOrchestrationPaths.UpdateServiceActiveStatusContext(ctx, serviceID, enableEOForService) if err != nil && isErrCode(err, http.StatusGone) { return nil } if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } if resp.Active != enableEOForService { time.Sleep(2 * time.Second) - return resource.RetryableError(fmt.Errorf("incosistent result received when trying to update event orchestration active status for service %q", serviceID)) + return retry.RetryableError(fmt.Errorf("incosistent result received when trying to update event orchestration active status for service %q", serviceID)) } return nil }) @@ -352,13 +352,13 @@ func resourcePagerDutyEventOrchestrationPathServiceDelete(ctx context.Context, d log.Printf("[INFO] Deleting PagerDuty Event Orchestration Service Path: %s", serviceID) - retryErr := resource.RetryContext(ctx, 30*time.Second, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 30*time.Second, func() *retry.RetryError { if _, _, err := client.EventOrchestrationPaths.UpdateContext(ctx, serviceID, "service", emptyPath); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) @@ -438,7 +438,7 @@ func expandServicePathRules(v interface{}) []*pagerduty.EventOrchestrationPathRu } func expandServicePathCatchAll(v interface{}) *pagerduty.EventOrchestrationPathCatchAll { - var catchAll = new(pagerduty.EventOrchestrationPathCatchAll) + catchAll := new(pagerduty.EventOrchestrationPathCatchAll) for _, ca := range v.([]interface{}) { if ca != nil { @@ -451,7 +451,7 @@ func expandServicePathCatchAll(v interface{}) *pagerduty.EventOrchestrationPathC } func expandServicePathActions(v interface{}) *pagerduty.EventOrchestrationPathRuleActions { - var actions = &pagerduty.EventOrchestrationPathRuleActions{ + actions := &pagerduty.EventOrchestrationPathRuleActions{ AutomationActions: []*pagerduty.EventOrchestrationPathAutomationAction{}, PagerdutyAutomationActions: []*pagerduty.EventOrchestrationPathPagerdutyAutomationAction{}, Variables: []*pagerduty.EventOrchestrationPathActionVariables{}, diff --git a/pagerduty/resource_pagerduty_event_orchestration_path_service_test.go b/pagerduty/resource_pagerduty_event_orchestration_path_service_test.go index f342904b5..c42e27b7c 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_path_service_test.go +++ b/pagerduty/resource_pagerduty_event_orchestration_path_service_test.go @@ -6,9 +6,9 @@ import ( "regexp" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { @@ -27,7 +27,7 @@ func TestAccPagerDutyEventOrchestrationPathService_Basic(t *testing.T) { // Checks that run on every step except the last one. These checks that verify the existance of the resource // and computed/default attributes. We're not checking individual resource attributes because - // according to the official docs (https://pkg.go.dev/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource#TestCheckResourceAttr) + // according to the official docs (https://pkg.go.dev/github.com/hashicorp/terraform-plugin-testing/helper/resource#TestCheckResourceAttr) // "State value checking is only recommended for testing Computed attributes and attribute defaults." baseChecks := []resource.TestCheckFunc{ testAccCheckPagerDutyEventOrchestrationPathServiceExists(resourceName), diff --git a/pagerduty/resource_pagerduty_event_orchestration_path_unrouted.go b/pagerduty/resource_pagerduty_event_orchestration_path_unrouted.go index e710e37a3..d478a2e32 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_path_unrouted.go +++ b/pagerduty/resource_pagerduty_event_orchestration_path_unrouted.go @@ -8,7 +8,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -171,17 +171,16 @@ func resourcePagerDutyEventOrchestrationPathUnroutedRead(ctx context.Context, d return diag.FromErr(err) } - retryErr := resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { - + retryErr := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { log.Printf("[INFO] Reading PagerDuty Event Orchestration Path of type: %s for orchestration: %s", "unrouted", d.Id()) if unroutedPath, _, err := client.EventOrchestrationPaths.GetContext(ctx, d.Id(), "unrouted"); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if unroutedPath != nil { if unroutedPath.Sets != nil { d.Set("set", flattenUnroutedSets(unroutedPath.Sets)) @@ -220,13 +219,13 @@ func resourcePagerDutyEventOrchestrationPathUnroutedDelete(ctx context.Context, log.Printf("[INFO] Deleting PagerDuty Unrouted Event Orchestration Path: %s", orchestrationID) - retryErr := resource.RetryContext(ctx, 30*time.Second, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 30*time.Second, func() *retry.RetryError { if _, _, err := client.EventOrchestrationPaths.UpdateContext(ctx, orchestrationID, "unrouted", emptyPath); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) @@ -252,18 +251,18 @@ func resourcePagerDutyEventOrchestrationPathUnroutedUpdate(ctx context.Context, log.Printf("[INFO] Updating PagerDuty EventOrchestrationPath of type: %s for orchestration: %s", "unrouted", unroutedPath.Parent.ID) - retryErr := resource.RetryContext(ctx, 30*time.Second, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 30*time.Second, func() *retry.RetryError { response, _, err := client.EventOrchestrationPaths.UpdateContext(ctx, unroutedPath.Parent.ID, "unrouted", unroutedPath) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } if response == nil { - return resource.NonRetryableError(fmt.Errorf("no event orchestration unrouted found")) + return retry.NonRetryableError(fmt.Errorf("no event orchestration unrouted found")) } d.SetId(unroutedPath.Parent.ID) @@ -290,7 +289,6 @@ func resourcePagerDutyEventOrchestrationPathUnroutedUpdate(ctx context.Context, } func buildUnroutedPathStructForUpdate(d *schema.ResourceData) *pagerduty.EventOrchestrationPath { - orchPath := &pagerduty.EventOrchestrationPath{ Parent: &pagerduty.EventOrchestrationPathReference{ ID: d.Get("event_orchestration").(string), @@ -346,7 +344,7 @@ func expandUnroutedRules(v interface{}) []*pagerduty.EventOrchestrationPathRule } func expandUnroutedActions(v interface{}) *pagerduty.EventOrchestrationPathRuleActions { - var actions = &pagerduty.EventOrchestrationPathRuleActions{ + actions := &pagerduty.EventOrchestrationPathRuleActions{ Variables: []*pagerduty.EventOrchestrationPathActionVariables{}, Extractions: []*pagerduty.EventOrchestrationPathActionExtractions{}, } @@ -366,7 +364,7 @@ func expandUnroutedActions(v interface{}) *pagerduty.EventOrchestrationPathRuleA } func expandUnroutedCatchAll(v interface{}) *pagerduty.EventOrchestrationPathCatchAll { - var catchAll = new(pagerduty.EventOrchestrationPathCatchAll) + catchAll := new(pagerduty.EventOrchestrationPathCatchAll) for _, ca := range v.([]interface{}) { if ca != nil { @@ -379,7 +377,7 @@ func expandUnroutedCatchAll(v interface{}) *pagerduty.EventOrchestrationPathCatc } func expandUnroutedCatchAllActions(v interface{}) *pagerduty.EventOrchestrationPathRuleActions { - var actions = new(pagerduty.EventOrchestrationPathRuleActions) + actions := new(pagerduty.EventOrchestrationPathRuleActions) for _, ai := range v.([]interface{}) { if ai != nil { am := ai.(map[string]interface{}) diff --git a/pagerduty/resource_pagerduty_event_orchestration_path_unrouted_test.go b/pagerduty/resource_pagerduty_event_orchestration_path_unrouted_test.go index 5c5db8d42..dd3daf908 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_path_unrouted_test.go +++ b/pagerduty/resource_pagerduty_event_orchestration_path_unrouted_test.go @@ -6,9 +6,9 @@ import ( "regexp" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/resource_pagerduty_event_orchestration_test.go b/pagerduty/resource_pagerduty_event_orchestration_test.go index 6e39fa640..50a1cff19 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_test.go +++ b/pagerduty/resource_pagerduty_event_orchestration_test.go @@ -6,9 +6,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/resource_pagerduty_event_rule.go b/pagerduty/resource_pagerduty_event_rule.go index 6926c8f64..68300ffca 100644 --- a/pagerduty/resource_pagerduty_event_rule.go +++ b/pagerduty/resource_pagerduty_event_rule.go @@ -5,7 +5,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -67,13 +67,13 @@ func resourcePagerDutyEventRuleCreate(d *schema.ResourceData, meta interface{}) log.Printf("[INFO] Creating PagerDuty event rule: %s", eventRule.Condition) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if eventRule, _, err := client.EventRules.Create(eventRule); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if eventRule != nil { d.SetId(eventRule.ID) } @@ -94,15 +94,15 @@ func resourcePagerDutyEventRuleRead(d *schema.ResourceData, meta interface{}) er log.Printf("[INFO] Reading PagerDuty event rule: %s", d.Id()) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { resp, _, err := client.EventRules.List() if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } var foundRule *pagerduty.EventRule @@ -128,6 +128,7 @@ func resourcePagerDutyEventRuleRead(d *schema.ResourceData, meta interface{}) er return nil }) } + func resourcePagerDutyEventRuleUpdate(d *schema.ResourceData, meta interface{}) error { client, err := meta.(*Config).Client() if err != nil { diff --git a/pagerduty/resource_pagerduty_event_rule_test.go b/pagerduty/resource_pagerduty_event_rule_test.go index 013c10d8c..f3d4cfbcc 100644 --- a/pagerduty/resource_pagerduty_event_rule_test.go +++ b/pagerduty/resource_pagerduty_event_rule_test.go @@ -5,9 +5,9 @@ import ( "log" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_extension.go b/pagerduty/resource_pagerduty_extension.go index 03ce2a312..cd76c61da 100644 --- a/pagerduty/resource_pagerduty_extension.go +++ b/pagerduty/resource_pagerduty_extension.go @@ -7,7 +7,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" @@ -93,17 +93,17 @@ func fetchPagerDutyExtension(d *schema.ResourceData, meta interface{}, errCallba return err } - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { extension, _, err := client.Extensions.Get(d.Id()) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -196,7 +196,6 @@ func resourcePagerDutyExtensionImport(d *schema.ResourceData, meta interface{}) } extension, _, err := client.Extensions.Get(d.Id()) - if err != nil { return []*schema.ResourceData{}, fmt.Errorf("error importing pagerduty_extension. Expecting an importation ID for extension") } @@ -233,6 +232,7 @@ func flattenExtensionObjects(serviceList []*pagerduty.ServiceReference) interfac } return services } + func expandExtensionConfig(v interface{}) interface{} { var config interface{} if err := json.Unmarshal([]byte(v.(string)), &config); err != nil { diff --git a/pagerduty/resource_pagerduty_extension_servicenow.go b/pagerduty/resource_pagerduty_extension_servicenow.go index 41a2d1e76..56efbb3d0 100644 --- a/pagerduty/resource_pagerduty_extension_servicenow.go +++ b/pagerduty/resource_pagerduty_extension_servicenow.go @@ -7,7 +7,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/heimweh/go-pagerduty/pagerduty" @@ -109,7 +109,7 @@ func buildExtensionServiceNowStruct(d *schema.ResourceData) *pagerduty.Extension ExtensionObjects: expandServiceNowServiceObjects(d.Get("extension_objects")), } - var config = &PagerDutyExtensionServiceNowConfig{ + config := &PagerDutyExtensionServiceNowConfig{ User: d.Get("snow_user").(string), Password: d.Get("snow_password").(string), SyncOptions: d.Get("sync_options").(string), @@ -128,17 +128,17 @@ func fetchPagerDutyExtensionServiceNowCreate(d *schema.ResourceData, meta interf return err } - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { extension, _, err := client.Extensions.Get(d.Id()) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -154,7 +154,7 @@ func fetchPagerDutyExtensionServiceNowCreate(d *schema.ResourceData, meta interf d.Set("extension_schema", extension.ExtensionSchema.ID) b, _ := json.Marshal(extension.Config) - var config = new(PagerDutyExtensionServiceNowConfig) + config := new(PagerDutyExtensionServiceNowConfig) json.Unmarshal(b, config) d.Set("snow_user", config.User) d.Set("snow_password", config.Password) @@ -236,7 +236,6 @@ func resourcePagerDutyExtensionServiceNowImport(d *schema.ResourceData, meta int } extension, _, err := client.Extensions.Get(d.Id()) - if err != nil { return []*schema.ResourceData{}, fmt.Errorf("error importing pagerduty_extension. Expecting an importation ID for extension") } diff --git a/pagerduty/resource_pagerduty_extension_servicenow_test.go b/pagerduty/resource_pagerduty_extension_servicenow_test.go index 792dc4755..ed1aea18b 100644 --- a/pagerduty/resource_pagerduty_extension_servicenow_test.go +++ b/pagerduty/resource_pagerduty_extension_servicenow_test.go @@ -6,8 +6,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -47,9 +48,9 @@ func testSweepExtensionServiceNow(region string) error { } func TestAccPagerDutyExtensionServiceNow_Basic(t *testing.T) { - extension_name := resource.PrefixedUniqueId("tf-") - extension_name_updated := resource.PrefixedUniqueId("tf-") - name := resource.PrefixedUniqueId("tf-") + extension_name := id.PrefixedUniqueId("tf-") + extension_name_updated := id.PrefixedUniqueId("tf-") + name := id.PrefixedUniqueId("tf-") url := "https://example.com/recieve_a_pagerduty_webhook" url_updated := "https://example.com/webhook_foo" diff --git a/pagerduty/resource_pagerduty_extension_test.go b/pagerduty/resource_pagerduty_extension_test.go index 1b3e822d3..207154b20 100644 --- a/pagerduty/resource_pagerduty_extension_test.go +++ b/pagerduty/resource_pagerduty_extension_test.go @@ -6,8 +6,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -47,9 +48,9 @@ func testSweepExtension(region string) error { } func TestAccPagerDutyExtension_Basic(t *testing.T) { - extension_name := resource.PrefixedUniqueId("tf-") - extension_name_updated := resource.PrefixedUniqueId("tf-") - name := resource.PrefixedUniqueId("tf-") + extension_name := id.PrefixedUniqueId("tf-") + extension_name_updated := id.PrefixedUniqueId("tf-") + name := id.PrefixedUniqueId("tf-") url := "https://example.com/recieve_a_pagerduty_webhook" url_updated := "https://example.com/webhook_foo" diff --git a/pagerduty/resource_pagerduty_incident_custom_field.go b/pagerduty/resource_pagerduty_incident_custom_field.go index ebafa6cd1..768c886f7 100644 --- a/pagerduty/resource_pagerduty_incident_custom_field.go +++ b/pagerduty/resource_pagerduty_incident_custom_field.go @@ -7,7 +7,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -130,28 +130,27 @@ func fetchField(ctx context.Context, d *schema.ResourceData, meta interface{}, e return err } - return resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + return retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { field, _, err := client.IncidentCustomFields.GetContext(ctx, d.Id(), nil) if err != nil { log.Printf("[WARN] Incident custom field read error") if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errorCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil } if err := flattenIncidentCustomField(d, field); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil - }) } diff --git a/pagerduty/resource_pagerduty_incident_custom_field_option.go b/pagerduty/resource_pagerduty_incident_custom_field_option.go index ff5bca340..a9ab936ad 100644 --- a/pagerduty/resource_pagerduty_incident_custom_field_option.go +++ b/pagerduty/resource_pagerduty_incident_custom_field_option.go @@ -8,7 +8,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -163,27 +163,26 @@ func fetchFieldOption(ctx context.Context, fieldID string, d *schema.ResourceDat return err } - return resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + return retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { fieldOption, _, err := client.IncidentCustomFields.GetFieldOptionContext(ctx, fieldID, d.Id()) if err != nil { log.Printf("[WARN] Field option read error") errResp := errorCallback(err, d) if errResp != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil } if err := flattenFieldOption(d, fieldID, fieldOption); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil - }) } diff --git a/pagerduty/resource_pagerduty_incident_custom_field_option_test.go b/pagerduty/resource_pagerduty_incident_custom_field_option_test.go index 9d2703a92..3c3147df2 100644 --- a/pagerduty/resource_pagerduty_incident_custom_field_option_test.go +++ b/pagerduty/resource_pagerduty_incident_custom_field_option_test.go @@ -7,9 +7,9 @@ import ( "regexp" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_incident_custom_field_test.go b/pagerduty/resource_pagerduty_incident_custom_field_test.go index ba583bf3f..ff5eb82a1 100644 --- a/pagerduty/resource_pagerduty_incident_custom_field_test.go +++ b/pagerduty/resource_pagerduty_incident_custom_field_test.go @@ -9,9 +9,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_incident_workflow.go b/pagerduty/resource_pagerduty_incident_workflow.go index 51fa9b2ec..f590ce5ae 100644 --- a/pagerduty/resource_pagerduty_incident_workflow.go +++ b/pagerduty/resource_pagerduty_incident_workflow.go @@ -10,7 +10,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -349,7 +349,6 @@ func customizeIncidentWorkflowDiff() schema.CustomizeDiffFunc { } } return nil - } } @@ -436,28 +435,27 @@ func fetchIncidentWorkflow(ctx context.Context, d *schema.ResourceData, meta int return err } - return resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + return retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { iw, _, err := client.IncidentWorkflows.GetContext(ctx, d.Id()) if err != nil { log.Printf("[WARN] Incident workflow read error") if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errorCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil } if err := flattenIncidentWorkflow(d, iw, true, specifiedSteps); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil - }) } diff --git a/pagerduty/resource_pagerduty_incident_workflow_test.go b/pagerduty/resource_pagerduty_incident_workflow_test.go index 301c5342a..2fe882569 100644 --- a/pagerduty/resource_pagerduty_incident_workflow_test.go +++ b/pagerduty/resource_pagerduty_incident_workflow_test.go @@ -7,9 +7,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_incident_workflow_trigger.go b/pagerduty/resource_pagerduty_incident_workflow_trigger.go index e1d48e41e..8d38aa948 100644 --- a/pagerduty/resource_pagerduty_incident_workflow_trigger.go +++ b/pagerduty/resource_pagerduty_incident_workflow_trigger.go @@ -8,7 +8,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -153,28 +153,27 @@ func fetchIncidentWorkflowTrigger(ctx context.Context, d *schema.ResourceData, m return err } - return resource.RetryContext(ctx, 2*time.Minute, func() *resource.RetryError { + return retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { iwt, _, err := client.IncidentWorkflowTriggers.GetContext(ctx, d.Id()) if err != nil { log.Printf("[WARN] Incident workflow trigger read error") if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errorCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil } if err := flattenIncidentWorkflowTrigger(d, iwt); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil - }) } diff --git a/pagerduty/resource_pagerduty_incident_workflow_trigger_test.go b/pagerduty/resource_pagerduty_incident_workflow_trigger_test.go index e621cf828..f11484eef 100644 --- a/pagerduty/resource_pagerduty_incident_workflow_trigger_test.go +++ b/pagerduty/resource_pagerduty_incident_workflow_trigger_test.go @@ -7,9 +7,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_maintenance_window.go b/pagerduty/resource_pagerduty_maintenance_window.go index eb229ae94..b62c4b6c0 100644 --- a/pagerduty/resource_pagerduty_maintenance_window.go +++ b/pagerduty/resource_pagerduty_maintenance_window.go @@ -5,7 +5,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -91,17 +91,17 @@ func resourcePagerDutyMaintenanceWindowRead(d *schema.ResourceData, meta interfa log.Printf("[INFO] Reading PagerDuty maintenance window %s", d.Id()) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { window, _, err := client.MaintenanceWindows.Get(d.Id()) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := handleNotFoundError(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -112,7 +112,7 @@ func resourcePagerDutyMaintenanceWindowRead(d *schema.ResourceData, meta interfa d.Set("end_time", window.EndTime) if err := d.Set("services", flattenServices(window.Services)); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil diff --git a/pagerduty/resource_pagerduty_maintenance_window_test.go b/pagerduty/resource_pagerduty_maintenance_window_test.go index b11c94608..22045bee8 100644 --- a/pagerduty/resource_pagerduty_maintenance_window_test.go +++ b/pagerduty/resource_pagerduty_maintenance_window_test.go @@ -7,9 +7,9 @@ import ( "testing" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_response_play.go b/pagerduty/resource_pagerduty_response_play.go index 129388a5a..be30819fc 100644 --- a/pagerduty/resource_pagerduty_response_play.go +++ b/pagerduty/resource_pagerduty_response_play.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -237,13 +237,13 @@ func resourcePagerDutyResponsePlayCreate(d *schema.ResourceData, meta interface{ log.Printf("[INFO] Creating PagerDuty response play: %s", responsePlay.ID) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if responsePlay, _, err := client.ResponsePlays.Create(responsePlay); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if responsePlay != nil { d.SetId(responsePlay.ID) d.Set("from", responsePlay.FromEmail) @@ -267,25 +267,25 @@ func resourcePagerDutyResponsePlayRead(d *schema.ResourceData, meta interface{}) from := d.Get("from").(string) log.Printf("[INFO] Reading PagerDuty response play: %s (from: %s)", d.Id(), from) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { if responsePlay, _, err := client.ResponsePlays.Get(d.Id(), from); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if responsePlay != nil { if responsePlay.Team != nil { d.Set("team", []interface{}{responsePlay.Team}) } log.Printf("[INFO] Read PagerDuty response play initial subscribers: %s", d.Get("subscriber")) if err := d.Set("subscriber", flattenSubscribers(responsePlay.Subscribers)); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } log.Printf("[INFO] Read PagerDuty response play initial responders: %s", d.Get("responder")) if err := d.Set("responder", flattenResponders(responsePlay.Responders)); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } d.Set("from", from) d.Set("name", responsePlay.Name) @@ -312,13 +312,13 @@ func resourcePagerDutyResponsePlayUpdate(d *schema.ResourceData, meta interface{ log.Printf("[INFO] Updating PagerDuty response play: %s", d.Id()) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, _, err := client.ResponsePlays.Update(d.Id(), responsePlay); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) @@ -338,13 +338,13 @@ func resourcePagerDutyResponsePlayDelete(d *schema.ResourceData, meta interface{ log.Printf("[INFO] Deleting PagerDuty response play: %s", d.Id()) from := d.Get("from").(string) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.ResponsePlays.Delete(d.Id(), from); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_response_play_test.go b/pagerduty/resource_pagerduty_response_play_test.go index bf450fb6f..0771959ba 100644 --- a/pagerduty/resource_pagerduty_response_play_test.go +++ b/pagerduty/resource_pagerduty_response_play_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyResponsePlay_Basic(t *testing.T) { diff --git a/pagerduty/resource_pagerduty_ruleset.go b/pagerduty/resource_pagerduty_ruleset.go index 1313c15b7..ae4ad3f88 100644 --- a/pagerduty/resource_pagerduty_ruleset.go +++ b/pagerduty/resource_pagerduty_ruleset.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -107,17 +107,17 @@ func fetchPagerDutyRuleset(d *schema.ResourceData, meta interface{}, errCallback return err } - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { ruleset, _, err := client.Rulesets.Get(d.Id()) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -145,13 +145,13 @@ func resourcePagerDutyRulesetCreate(d *schema.ResourceData, meta interface{}) er log.Printf("[INFO] Creating PagerDuty ruleset: %s", ruleset.Name) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if ruleset, _, err := client.Rulesets.Create(ruleset); err != nil { if isErrCode(err, 400) || isErrCode(err, 429) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else if ruleset != nil { d.SetId(ruleset.ID) } @@ -167,8 +167,8 @@ func resourcePagerDutyRulesetCreate(d *schema.ResourceData, meta interface{}) er func resourcePagerDutyRulesetRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[INFO] Reading PagerDuty ruleset: %s", d.Id()) return fetchPagerDutyRuleset(d, meta, handleNotFoundError) - } + func resourcePagerDutyRulesetUpdate(d *schema.ResourceData, meta interface{}) error { client, err := meta.(*Config).Client() if err != nil { diff --git a/pagerduty/resource_pagerduty_ruleset_rule.go b/pagerduty/resource_pagerduty_ruleset_rule.go index ae26803ec..40848434b 100644 --- a/pagerduty/resource_pagerduty_ruleset_rule.go +++ b/pagerduty/resource_pagerduty_ruleset_rule.go @@ -8,7 +8,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -369,7 +369,7 @@ func expandConditions(v interface{}) *pagerduty.RuleConditions { } func expandTimeFrame(v interface{}) *pagerduty.RuleTimeFrame { - var tFrame = new(pagerduty.RuleTimeFrame) + tFrame := new(pagerduty.RuleTimeFrame) for _, tfi := range v.([]interface{}) { tfm := tfi.(map[string]interface{}) @@ -426,7 +426,7 @@ func expandActiveBetween(v interface{}) *pagerduty.ActiveBetween { } func expandActions(v interface{}) *pagerduty.RuleActions { - var actions = new(pagerduty.RuleActions) + actions := new(pagerduty.RuleActions) for _, ai := range v.([]interface{}) { am := ai.(map[string]interface{}) @@ -475,6 +475,7 @@ func expandSubConditions(v interface{}) []*pagerduty.RuleSubcondition { } return sc } + func expandSubConditionParameters(v interface{}) *pagerduty.ConditionParameter { var parms *pagerduty.ConditionParameter @@ -502,6 +503,7 @@ func expandActionParameters(v interface{}) *pagerduty.RuleActionParameter { } return rap } + func expandActionIntParameters(v interface{}) *pagerduty.RuleActionIntParameter { var rap *pagerduty.RuleActionIntParameter @@ -546,6 +548,7 @@ func expandExtractions(v interface{}) []*pagerduty.RuleActionExtraction { } return rae } + func expandRuleVariables(v interface{}) []*pagerduty.RuleVariable { var ruleVariables []*pagerduty.RuleVariable @@ -577,6 +580,7 @@ func expandVariableParameters(v interface{}) *pagerduty.RuleVariableParameter { } return parm } + func flattenRuleVariables(v []*pagerduty.RuleVariable) []map[string]interface{} { var ruleVariables []map[string]interface{} @@ -594,7 +598,6 @@ func flattenRuleVariables(v []*pagerduty.RuleVariable) []map[string]interface{} } func flattenVariableParamters(p *pagerduty.RuleVariableParameter) []interface{} { - flattenedParams := map[string]interface{}{ "path": p.Path, "value": p.Value, @@ -629,7 +632,6 @@ func flattenSubconditions(subconditions []*pagerduty.RuleSubcondition) []interfa } func flattenSubconditionParameters(p *pagerduty.ConditionParameter) []interface{} { - flattenedParams := map[string]interface{}{ "path": p.Path, "value": p.Value, @@ -673,7 +675,6 @@ func flattenActions(actions *pagerduty.RuleActions) []map[string]interface{} { } func flattenSuppress(s *pagerduty.RuleActionSuppress) []interface{} { - sup := map[string]interface{}{ "value": s.Value, "threshold_value": s.ThresholdValue, @@ -682,15 +683,15 @@ func flattenSuppress(s *pagerduty.RuleActionSuppress) []interface{} { } return []interface{}{sup} } -func flattenActionParameter(ap *pagerduty.RuleActionParameter) []interface{} { +func flattenActionParameter(ap *pagerduty.RuleActionParameter) []interface{} { param := map[string]interface{}{ "value": ap.Value, } return []interface{}{param} } -func flattenActionIntParameter(ap *pagerduty.RuleActionIntParameter) []interface{} { +func flattenActionIntParameter(ap *pagerduty.RuleActionIntParameter) []interface{} { param := map[string]interface{}{ "value": ap.Value, } @@ -729,7 +730,6 @@ func flattenTimeFrame(timeframe *pagerduty.RuleTimeFrame) []map[string]interface } func flattenScheduledWeekly(s *pagerduty.ScheduledWeekly) []interface{} { - fsw := map[string]interface{}{ "timezone": s.Timezone, "start_time": s.StartTime, @@ -740,7 +740,6 @@ func flattenScheduledWeekly(s *pagerduty.ScheduledWeekly) []interface{} { } func flattenActiveBetween(ab *pagerduty.ActiveBetween) []interface{} { - fab := map[string]interface{}{ "start_time": ab.StartTime, "end_time": ab.EndTime, @@ -765,7 +764,6 @@ func resourcePagerDutyRulesetRuleCreate(d *schema.ResourceData, meta interface{} log.Printf("[INFO] Found catch_all rule for ruleset: %s", rule.Ruleset.ID) rulesetrules, _, err := client.Rulesets.ListRules(rule.Ruleset.ID) - if err != nil { return err } @@ -795,20 +793,20 @@ func resourcePagerDutyRulesetRuleCreate(d *schema.ResourceData, meta interface{} return resourcePagerDutyRulesetRuleRead(d, meta) } - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if rule, _, err := client.Rulesets.CreateRule(rule.Ruleset.ID, rule); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if rule != nil { d.SetId(rule.ID) // Verifying the position that was defined in terraform is the same position set in PagerDuty pos := d.Get("position").(int) if *rule.Position != pos { if err := resourcePagerDutyRulesetRuleUpdate(d, meta); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } } } @@ -830,14 +828,14 @@ func resourcePagerDutyRulesetRuleRead(d *schema.ResourceData, meta interface{}) log.Printf("[INFO] Reading PagerDuty ruleset rule: %s", d.Id()) rulesetID := d.Get("ruleset").(string) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { if rule, _, err := client.Rulesets.GetRule(rulesetID, d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if rule != nil { if rule.Conditions != nil { d.Set("conditions", flattenConditions(rule.Conditions)) @@ -874,16 +872,16 @@ func resourcePagerDutyRulesetRuleUpdate(d *schema.ResourceData, meta interface{} } func performRulesetRuleUpdate(rulesetID string, id string, rule *pagerduty.RulesetRule, client *pagerduty.Client) error { - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if updatedRule, _, err := client.Rulesets.UpdateRule(rulesetID, id, rule); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if rule.Position != nil && *updatedRule.Position != *rule.Position && rule.CatchAll != true { log.Printf("[INFO] PagerDuty ruleset rule %s position %d needs to be %d", updatedRule.ID, *updatedRule.Position, *rule.Position) - return resource.RetryableError(fmt.Errorf("Error updating ruleset rule %s position %d needs to be %d", updatedRule.ID, *updatedRule.Position, *rule.Position)) + return retry.RetryableError(fmt.Errorf("Error updating ruleset rule %s position %d needs to be %d", updatedRule.ID, *updatedRule.Position, *rule.Position)) } return nil }) @@ -908,7 +906,6 @@ func resourcePagerDutyRulesetRuleDelete(d *schema.ResourceData, meta interface{} log.Printf("[INFO] Rule %s is a catch_all rule, don't delete it, reset it instead", d.Id()) rule, _, err := client.Rulesets.GetRule(rulesetID, d.Id()) - if err != nil { return err } @@ -935,13 +932,13 @@ func resourcePagerDutyRulesetRuleDelete(d *schema.ResourceData, meta interface{} log.Printf("[INFO] Deleting PagerDuty ruleset rule: %s", d.Id()) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.Rulesets.DeleteRule(rulesetID, d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_ruleset_rule_test.go b/pagerduty/resource_pagerduty_ruleset_rule_test.go index 85aa19a35..67c3bf9b9 100644 --- a/pagerduty/resource_pagerduty_ruleset_rule_test.go +++ b/pagerduty/resource_pagerduty_ruleset_rule_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyRulesetRule_Basic(t *testing.T) { diff --git a/pagerduty/resource_pagerduty_ruleset_test.go b/pagerduty/resource_pagerduty_ruleset_test.go index 3b6df783a..03f262ad3 100644 --- a/pagerduty/resource_pagerduty_ruleset_test.go +++ b/pagerduty/resource_pagerduty_ruleset_test.go @@ -6,9 +6,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/resource_pagerduty_schedule.go b/pagerduty/resource_pagerduty_schedule.go index 29e6865c7..980c35879 100644 --- a/pagerduty/resource_pagerduty_schedule.go +++ b/pagerduty/resource_pagerduty_schedule.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/heimweh/go-pagerduty/pagerduty" @@ -269,18 +269,18 @@ func fetchSchedule(d *schema.ResourceData, meta interface{}, errCallback func(er return err } - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { schedule, _, err := client.Schedules.Get(d.Id(), &pagerduty.GetScheduleOptions{}) if err != nil { log.Printf("[WARN] Schedule read error") if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil } @@ -291,17 +291,17 @@ func fetchSchedule(d *schema.ResourceData, meta interface{}, errCallback func(er layers, err := flattenScheduleLayers(schedule.ScheduleLayers) if err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } if err := d.Set("layer", layers); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } if err := d.Set("teams", flattenShedTeams(schedule.Teams)); err != nil { - return resource.NonRetryableError(fmt.Errorf("error setting teams: %s", err)) + return retry.NonRetryableError(fmt.Errorf("error setting teams: %s", err)) } if err := d.Set("final_schedule", flattenScheFinalSchedule(schedule.FinalSchedule)); err != nil { - return resource.NonRetryableError(fmt.Errorf("error setting final_schedule: %s", err)) + return retry.NonRetryableError(fmt.Errorf("error setting final_schedule: %s", err)) } } @@ -375,9 +375,9 @@ func resourcePagerDutyScheduleUpdate(d *schema.ResourceData, meta interface{}) e log.Printf("[INFO] Updating PagerDuty schedule: %s", d.Id()) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, _, err := client.Schedules.Update(d.Id(), schedule, opts); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) @@ -398,15 +398,15 @@ func resourcePagerDutyScheduleDelete(d *schema.ResourceData, meta interface{}) e log.Printf("[INFO] Starting deletion process of Schedule %s", scheduleId) var scheduleData *pagerduty.Schedule - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { resp, _, err := client.Schedules.Get(scheduleId, &pagerduty.GetScheduleOptions{}) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } scheduleData = resp return nil @@ -424,10 +424,10 @@ func resourcePagerDutyScheduleDelete(d *schema.ResourceData, meta interface{}) e log.Printf("[INFO] Deleting PagerDuty schedule: %s", scheduleId) // Retrying to give other resources (such as escalation policies) to delete - retryErr = resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr = retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.Schedules.Delete(scheduleId); err != nil { if !isErrCode(err, 400) { - return resource.RetryableError(err) + return retry.RetryableError(err) } isErrorScheduleUsedByEP := func(e *pagerduty.Error) bool { return strings.Compare(fmt.Sprintf("%v", e.Errors), "[Schedule can't be deleted if it's being used by escalation policies]") == 0 @@ -439,7 +439,7 @@ func resourcePagerDutyScheduleDelete(d *schema.ResourceData, meta interface{}) e // Handling of specific http 400 errors from API call DELETE /schedules e, ok := err.(*pagerduty.Error) if !ok || !isErrorScheduleUsedByEP(e) && !isErrorScheduleWOpenIncidents(e) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } var workaroundErr error @@ -448,7 +448,7 @@ func resourcePagerDutyScheduleDelete(d *schema.ResourceData, meta interface{}) e linksToIncidentsOpen, workaroundErr := listIncidentsOpenedRelatedToSchedule(client, scheduleData, epsUsingThisSchedule) if workaroundErr != nil { err = fmt.Errorf("%v; %w", err, workaroundErr) - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } hasToShowIncidentRemediationMessage := len(linksToIncidentsOpen) > 0 @@ -457,24 +457,24 @@ func resourcePagerDutyScheduleDelete(d *schema.ResourceData, meta interface{}) e for _, incident := range linksToIncidentsOpen { urlLinksMessage = fmt.Sprintf("%s\n%s", urlLinksMessage, incident) } - return resource.NonRetryableError(fmt.Errorf("Before destroying Schedule %q You must first resolve or reassign the following incidents related with Escalation Policies using this Schedule... %s", scheduleId, urlLinksMessage)) + return retry.NonRetryableError(fmt.Errorf("Before destroying Schedule %q You must first resolve or reassign the following incidents related with Escalation Policies using this Schedule... %s", scheduleId, urlLinksMessage)) } // Returning at this point because the open incident (s) blocking the // deletion of the Schedule can't be tracked. if isErrorScheduleWOpenIncidents(e) && !hasToShowIncidentRemediationMessage { - return resource.NonRetryableError(e) + return retry.NonRetryableError(e) } epsDataUsingThisSchedule, errFetchingFullEPs := fetchEPsDataUsingASchedule(epsUsingThisSchedule, client) if errFetchingFullEPs != nil { err = fmt.Errorf("%v; %w", err, errFetchingFullEPs) - return resource.RetryableError(err) + return retry.RetryableError(err) } errBlockingBecauseOfEPs := detectUseOfScheduleByEPsWithOneLayer(scheduleId, epsDataUsingThisSchedule) if errBlockingBecauseOfEPs != nil { - return resource.NonRetryableError(errBlockingBecauseOfEPs) + return retry.NonRetryableError(errBlockingBecauseOfEPs) } // Workaround for Schedule being used by escalation policies error @@ -483,7 +483,7 @@ func resourcePagerDutyScheduleDelete(d *schema.ResourceData, meta interface{}) e if workaroundErr != nil { err = fmt.Errorf("%v; %w", err, workaroundErr) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) @@ -658,7 +658,7 @@ func flattenScheFinalSchedule(finalSche *pagerduty.SubSchedule) []map[string]int func listIncidentsOpenedRelatedToSchedule(c *pagerduty.Client, schedule *pagerduty.Schedule, epIDs []string) ([]string, error) { var incidents []*pagerduty.Incident - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { var err error options := &pagerduty.ListIncidentsOptions{ DateRange: "all", @@ -674,11 +674,11 @@ func listIncidentsOpenedRelatedToSchedule(c *pagerduty.Client, schedule *pagerdu incidents, err = c.Incidents.ListAll(options) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) @@ -708,6 +708,7 @@ func listIncidentsOpenedRelatedToSchedule(c *pagerduty.Client, schedule *pagerdu } return linksToIncidents, nil } + func extractEPsUsingASchedule(c *pagerduty.Client, schedule *pagerduty.Schedule) ([]string, error) { eps := []string{} for _, ep := range schedule.EscalationPolicies { @@ -765,11 +766,11 @@ func removeScheduleFromEP(c *pagerduty.Client, scheduleID string, ep *pagerduty. } ep.EscalationRules = epr - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { _, _, err := c.EscalationPolicies.Update(ep.ID, ep) if err != nil { if !isErrCode(err, 404) { - return resource.RetryableError(err) + return retry.RetryableError(err) } } return nil @@ -856,14 +857,14 @@ func detectUseOfScheduleByEPsWithOneLayer(scheduleId string, eps []*pagerduty.Es func fetchEPsDataUsingASchedule(eps []string, c *pagerduty.Client) ([]*pagerduty.EscalationPolicy, error) { fullEPs := []*pagerduty.EscalationPolicy{} for _, epID := range eps { - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { ep, _, err := c.EscalationPolicies.Get(epID, &pagerduty.GetEscalationPolicyOptions{}) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } fullEPs = append(fullEPs, ep) return nil diff --git a/pagerduty/resource_pagerduty_schedule_test.go b/pagerduty/resource_pagerduty_schedule_test.go index 969c4a345..046139e73 100644 --- a/pagerduty/resource_pagerduty_schedule_test.go +++ b/pagerduty/resource_pagerduty_schedule_test.go @@ -9,9 +9,9 @@ import ( "testing" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_service.go b/pagerduty/resource_pagerduty_service.go index 60d9256d0..db7cfb0a4 100644 --- a/pagerduty/resource_pagerduty_service.go +++ b/pagerduty/resource_pagerduty_service.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/heimweh/go-pagerduty/pagerduty" @@ -469,29 +469,28 @@ func fetchService(d *schema.ResourceData, meta interface{}, errCallback func(err return err } - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { service, _, err := client.Services.Get(d.Id(), &pagerduty.GetServiceOptions{ Includes: []string{"auto_pause_notifications_parameters"}, }) if err != nil { log.Printf("[WARN] Service read error") if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) if errResp != nil { - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil } if err := flattenService(d, service); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil - }) } @@ -686,6 +685,7 @@ func expandAlertGroupingConfig(v interface{}) *pagerduty.AlertGroupingConfig { } return alertGroupingConfig } + func flattenAlertGroupingParameters(v *pagerduty.AlertGroupingParameters) interface{} { alertGroupingParameters := map[string]interface{}{} @@ -705,8 +705,8 @@ func flattenAlertGroupingParameters(v *pagerduty.AlertGroupingParameters) interf return []interface{}{alertGroupingParameters} } -func flattenAlertGroupingConfig(v *pagerduty.AlertGroupingConfig) interface{} { +func flattenAlertGroupingConfig(v *pagerduty.AlertGroupingConfig) interface{} { alertGroupingConfig := map[string]interface{}{ "aggregate": v.Aggregate, "fields": v.Fields, diff --git a/pagerduty/resource_pagerduty_service_dependency.go b/pagerduty/resource_pagerduty_service_dependency.go index 30ede4fc1..9a6abbbdf 100644 --- a/pagerduty/resource_pagerduty_service_dependency.go +++ b/pagerduty/resource_pagerduty_service_dependency.go @@ -10,7 +10,7 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -129,6 +129,7 @@ func expandService(v interface{}) *pagerduty.ServiceObj { return so } + func resourcePagerDutyServiceDependencyAssociate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { client, err := meta.(*Config).Client() if err != nil { @@ -148,7 +149,7 @@ func resourcePagerDutyServiceDependencyAssociate(ctx context.Context, d *schema. log.Printf("[INFO] Associating PagerDuty dependency %s", serviceDependency.ID) var dependencies *pagerduty.ListServiceDependencies - retryErr := resource.RetryContext(ctx, 5*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 5*time.Minute, func() *retry.RetryError { // Lock the mutex to ensure only one API call to // `service_dependencies/associate` is done at a time dependencyAssociationMutex.Lock() @@ -157,13 +158,13 @@ func resourcePagerDutyServiceDependencyAssociate(ctx context.Context, d *schema. if err != nil { if isErrCode(err, 404) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else { for _, r := range dependencies.Relationships { if err := d.Set("dependency", flattenRelationship(r)); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } d.SetId(r.ID) } @@ -193,17 +194,17 @@ func resourcePagerDutyServiceDependencyDisassociate(ctx context.Context, d *sche var foundDep *pagerduty.ServiceDependency // listServiceRelationships by calling get dependencies using the serviceDependency.DependentService.ID - retryErr := resource.RetryContext(ctx, 5*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 5*time.Minute, func() *retry.RetryError { if dependencies, _, err := client.ServiceDependencies.GetServiceDependenciesForType(dependency.DependentService.ID, dependency.DependentService.Type); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if dependencies != nil { for _, rel := range dependencies.Relationships { if rel.ID == d.Id() { @@ -238,17 +239,17 @@ func resourcePagerDutyServiceDependencyDisassociate(ctx context.Context, d *sche input := pagerduty.ListServiceDependencies{ Relationships: r, } - retryErr = resource.RetryContext(ctx, 5*time.Minute, func() *resource.RetryError { + retryErr = retry.RetryContext(ctx, 5*time.Minute, func() *retry.RetryError { if _, _, err = client.ServiceDependencies.DisassociateServiceDependencies(&input); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) @@ -317,23 +318,23 @@ func findDependencySetState(ctx context.Context, depID, serviceID, serviceType s // Pausing to let the PD API sync. time.Sleep(1 * time.Second) - retryErr := resource.RetryContext(ctx, 5*time.Minute, func() *resource.RetryError { + retryErr := retry.RetryContext(ctx, 5*time.Minute, func() *retry.RetryError { if dependencies, _, err := client.ServiceDependencies.GetServiceDependenciesForType(serviceID, serviceType); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } // Delaying retry by 30s as recommended by PagerDuty // https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit time.Sleep(30 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if dependencies != nil { depFound := false for _, rel := range dependencies.Relationships { if rel.ID == depID { if err := d.Set("dependency", flattenRelationship(rel)); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } d.SetId(rel.ID) depFound = true diff --git a/pagerduty/resource_pagerduty_service_dependency_test.go b/pagerduty/resource_pagerduty_service_dependency_test.go index f45d2db96..f31cae7a1 100644 --- a/pagerduty/resource_pagerduty_service_dependency_test.go +++ b/pagerduty/resource_pagerduty_service_dependency_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_service_event_rule.go b/pagerduty/resource_pagerduty_service_event_rule.go index ce28dd993..cfbdc97e0 100644 --- a/pagerduty/resource_pagerduty_service_event_rule.go +++ b/pagerduty/resource_pagerduty_service_event_rule.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -330,6 +330,7 @@ func buildServiceEventRuleStruct(d *schema.ResourceData) *pagerduty.ServiceEvent return rule } + func resourcePagerDutyServiceEventRuleCreate(d *schema.ResourceData, meta interface{}) error { client, err := meta.(*Config).Client() if err != nil { @@ -340,20 +341,20 @@ func resourcePagerDutyServiceEventRuleCreate(d *schema.ResourceData, meta interf log.Printf("[INFO] Creating PagerDuty service event rule for service: %s", rule.Service.ID) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if rule, _, err := client.Services.CreateEventRule(rule.Service.ID, rule); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if rule != nil { d.SetId(rule.ID) // Verifying the position that was defined in terraform is the same position set in PagerDuty pos := d.Get("position").(int) if *rule.Position != pos { if err := resourcePagerDutyServiceEventRuleUpdate(d, meta); err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } } } @@ -375,14 +376,14 @@ func resourcePagerDutyServiceEventRuleRead(d *schema.ResourceData, meta interfac log.Printf("[INFO] Reading PagerDuty service event rule: %s", d.Id()) serviceID := d.Get("service").(string) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { if rule, _, err := client.Services.GetEventRule(serviceID, d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if rule != nil { if rule.Conditions != nil { d.Set("conditions", flattenConditions(rule.Conditions)) @@ -415,16 +416,16 @@ func resourcePagerDutyServiceEventRuleUpdate(d *schema.ResourceData, meta interf log.Printf("[INFO] Updating PagerDuty service event rule: %s", d.Id()) serviceID := d.Get("service").(string) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if updatedRule, _, err := client.Services.UpdateEventRule(serviceID, d.Id(), rule); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if rule.Position != nil && *updatedRule.Position != *rule.Position { log.Printf("[INFO] Service Event Rule %s position %v needs to be %v", updatedRule.ID, *updatedRule.Position, *rule.Position) - return resource.RetryableError(fmt.Errorf("Error updating service event rule %s position %d needs to be %d", updatedRule.ID, *updatedRule.Position, *rule.Position)) + return retry.RetryableError(fmt.Errorf("Error updating service event rule %s position %d needs to be %d", updatedRule.ID, *updatedRule.Position, *rule.Position)) } return nil @@ -445,13 +446,13 @@ func resourcePagerDutyServiceEventRuleDelete(d *schema.ResourceData, meta interf log.Printf("[INFO] Deleting PagerDuty service event rule: %s", d.Id()) serviceID := d.Get("service").(string) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.Services.DeleteEventRule(serviceID, d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_service_event_rule_test.go b/pagerduty/resource_pagerduty_service_event_rule_test.go index 199c457f3..76f210117 100644 --- a/pagerduty/resource_pagerduty_service_event_rule_test.go +++ b/pagerduty/resource_pagerduty_service_event_rule_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyServiceEventRule_Basic(t *testing.T) { diff --git a/pagerduty/resource_pagerduty_service_integration.go b/pagerduty/resource_pagerduty_service_integration.go index 86eace6e7..1b498d343 100644 --- a/pagerduty/resource_pagerduty_service_integration.go +++ b/pagerduty/resource_pagerduty_service_integration.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -457,6 +457,7 @@ func buildServiceIntegrationStruct(d *schema.ResourceData) (*pagerduty.Integrati return serviceIntegration, nil } + func expandEmailParsers(v interface{}) ([]*pagerduty.EmailParser, error) { var emailParsers []*pagerduty.EmailParser @@ -649,87 +650,87 @@ func fetchPagerDutyServiceIntegration(d *schema.ResourceData, meta interface{}, o := &pagerduty.GetIntegrationOptions{} - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { serviceIntegration, _, err := client.Services.GetIntegration(service, d.Id(), o) if err != nil { log.Printf("[WARN] Service integration read error") if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) if errResp != nil { - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil } if err := d.Set("name", serviceIntegration.Name); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } if err := d.Set("type", serviceIntegration.Type); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } if serviceIntegration.Service != nil { if err := d.Set("service", serviceIntegration.Service.ID); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } } if serviceIntegration.Vendor != nil { if err := d.Set("vendor", serviceIntegration.Vendor.ID); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } } if serviceIntegration.IntegrationKey != "" { if err := d.Set("integration_key", serviceIntegration.IntegrationKey); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } } if serviceIntegration.IntegrationEmail != "" { if err := d.Set("integration_email", serviceIntegration.IntegrationEmail); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } } if serviceIntegration.EmailIncidentCreation != "" { if err := d.Set("email_incident_creation", serviceIntegration.EmailIncidentCreation); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } } if serviceIntegration.EmailFilterMode != "" { if err := d.Set("email_filter_mode", serviceIntegration.EmailFilterMode); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } } if serviceIntegration.EmailParsingFallback != "" { if err := d.Set("email_parsing_fallback", serviceIntegration.EmailParsingFallback); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } } if serviceIntegration.HTMLURL != "" { if err := d.Set("html_url", serviceIntegration.HTMLURL); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } } if serviceIntegration.EmailFilters != nil { if err := d.Set("email_filter", flattenEmailFilters(serviceIntegration.EmailFilters)); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } } if serviceIntegration.EmailParsers != nil { if err := d.Set("email_parser", flattenEmailParsers(serviceIntegration.EmailParsers)); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } } @@ -752,13 +753,13 @@ func resourcePagerDutyServiceIntegrationCreate(d *schema.ResourceData, meta inte service := d.Get("service").(string) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if serviceIntegration, _, err := client.Services.CreateIntegration(service, serviceIntegration); err != nil { if isErrCode(err, 400) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else if serviceIntegration != nil { d.SetId(serviceIntegration.ID) } diff --git a/pagerduty/resource_pagerduty_service_integration_test.go b/pagerduty/resource_pagerduty_service_integration_test.go index e7341f999..28f0a4a4a 100644 --- a/pagerduty/resource_pagerduty_service_integration_test.go +++ b/pagerduty/resource_pagerduty_service_integration_test.go @@ -6,9 +6,9 @@ import ( "regexp" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_service_test.go b/pagerduty/resource_pagerduty_service_test.go index 03aa75be0..b62f653d9 100644 --- a/pagerduty/resource_pagerduty_service_test.go +++ b/pagerduty/resource_pagerduty_service_test.go @@ -7,9 +7,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_slack_connection.go b/pagerduty/resource_pagerduty_slack_connection.go index 8bb99bd4b..723c36f25 100644 --- a/pagerduty/resource_pagerduty_slack_connection.go +++ b/pagerduty/resource_pagerduty_slack_connection.go @@ -7,13 +7,15 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) -const AppBaseUrl = "https://app.pagerduty.com" -const StarWildcardConfig = "*" +const ( + AppBaseUrl = "https://app.pagerduty.com" + StarWildcardConfig = "*" +) func resourcePagerDutySlackConnection() *schema.Resource { return &schema.Resource{ @@ -116,16 +118,15 @@ func resourcePagerDutySlackConnectionCreate(d *schema.ResourceData, meta interfa return err } - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { - + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { slackConn, err := buildSlackConnectionStruct(d) if err != nil { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } log.Printf("[INFO] Creating PagerDuty slack connection for source %s and slack channel %s", slackConn.SourceID, slackConn.ChannelID) if slackConn, _, err = client.SlackConnections.Create(slackConn.WorkspaceID, slackConn); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } else if slackConn != nil { d.SetId(slackConn.ID) d.Set("workspace_id", slackConn.WorkspaceID) @@ -150,13 +151,13 @@ func resourcePagerDutySlackConnectionRead(d *schema.ResourceData, meta interface workspaceID := d.Get("workspace_id").(string) log.Printf("[DEBUG] Read Slack Connection: workspace_id %s", workspaceID) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if slackConn, _, err := client.SlackConnections.Get(workspaceID, d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if slackConn != nil { d.Set("source_id", slackConn.SourceID) d.Set("source_name", slackConn.SourceName) diff --git a/pagerduty/resource_pagerduty_slack_connection_test.go b/pagerduty/resource_pagerduty_slack_connection_test.go index bb80620d0..025d1d125 100644 --- a/pagerduty/resource_pagerduty_slack_connection_test.go +++ b/pagerduty/resource_pagerduty_slack_connection_test.go @@ -6,9 +6,9 @@ import ( "os" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_tag.go b/pagerduty/resource_pagerduty_tag.go index ebd20aad5..dbe1e4c5e 100644 --- a/pagerduty/resource_pagerduty_tag.go +++ b/pagerduty/resource_pagerduty_tag.go @@ -5,7 +5,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -59,13 +59,13 @@ func resourcePagerDutyTagCreate(d *schema.ResourceData, meta interface{}) error log.Printf("[INFO] Creating PagerDuty tag %s", tag.Label) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if tag, _, err := client.Tags.Create(tag); err != nil { if isErrCode(err, 400) || isErrCode(err, 429) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else if tag != nil { d.SetId(tag.ID) } @@ -77,7 +77,6 @@ func resourcePagerDutyTagCreate(d *schema.ResourceData, meta interface{}) error } return resourcePagerDutyTagRead(d, meta) - } func resourcePagerDutyTagRead(d *schema.ResourceData, meta interface{}) error { @@ -88,17 +87,17 @@ func resourcePagerDutyTagRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[INFO] Reading PagerDuty tag %s", d.Id()) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { tag, _, err := client.Tags.Get(d.Id()) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := handleNotFoundError(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -121,13 +120,13 @@ func resourcePagerDutyTagDelete(d *schema.ResourceData, meta interface{}) error log.Printf("[INFO] Deleting PagerDuty tag %s", d.Id()) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.Tags.Delete(d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_tag_assignment.go b/pagerduty/resource_pagerduty_tag_assignment.go index ec5fa05e7..2f861b0ba 100644 --- a/pagerduty/resource_pagerduty_tag_assignment.go +++ b/pagerduty/resource_pagerduty_tag_assignment.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -73,13 +73,13 @@ func resourcePagerDutyTagAssignmentCreate(d *schema.ResourceData, meta interface log.Printf("[INFO] Creating PagerDuty tag assignment with tagID %s for %s entity with ID %s", assignment.TagID, assignment.EntityType, assignment.EntityID) - retryErr := resource.Retry(5*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(5*time.Minute, func() *retry.RetryError { if _, err := client.Tags.Assign(assignment.EntityType, assignment.EntityID, assignments); err != nil { if isErrCode(err, 400) || isErrCode(err, 429) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else { // create tag_assignment id using the entityID.tagID as PagerDuty API does not return one assignmentID := createAssignmentID(assignment.EntityID, assignment.TagID) @@ -94,7 +94,6 @@ func resourcePagerDutyTagAssignmentCreate(d *schema.ResourceData, meta interface // give PagerDuty 2 seconds to save the assignment correctly time.Sleep(2 * time.Second) return resourcePagerDutyTagAssignmentRead(d, meta) - } func resourcePagerDutyTagAssignmentRead(d *schema.ResourceData, meta interface{}) error { @@ -116,14 +115,14 @@ func resourcePagerDutyTagAssignmentRead(d *schema.ResourceData, meta interface{} return nil } - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { if tagResponse, _, err := client.Tags.ListTagsForEntity(assignment.EntityType, assignment.EntityID); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if tagResponse != nil { var foundTag *pagerduty.Tag @@ -155,13 +154,13 @@ func resourcePagerDutyTagAssignmentDelete(d *schema.ResourceData, meta interface } log.Printf("[INFO] Deleting PagerDuty tag assignment with tagID %s for entityID %s", assignment.TagID, assignment.EntityID) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.Tags.Assign(assignment.EntityType, assignment.EntityID, assignments); err != nil { if isErrCode(err, 400) || isErrCode(err, 429) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else { d.SetId("") } @@ -190,7 +189,6 @@ func resourcePagerDutyTagAssignmentImport(d *schema.ResourceData, meta interface // give PagerDuty 2 seconds to save the assignment correctly time.Sleep(2 * time.Second) tagResponse, _, err := client.Tags.ListTagsForEntity(entityType, entityID) - if err != nil { return []*schema.ResourceData{}, fmt.Errorf("error importing pagerduty_tag_assignment: %s", err.Error()) } @@ -232,7 +230,7 @@ func isFoundTagAssignmentEntity(entityID, entityType string, meta interface{}) ( fetchEscalationPolicy := func(id string) (*pagerduty.EscalationPolicy, *pagerduty.Response, error) { return client.EscalationPolicies.Get(id, &pagerduty.GetEscalationPolicyOptions{}) } - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { var err error if entityType == "users" { _, _, err = fetchUser(entityID) @@ -248,10 +246,10 @@ func isFoundTagAssignmentEntity(entityID, entityType string, meta interface{}) ( return nil } if err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } isFound = true diff --git a/pagerduty/resource_pagerduty_tag_assignment_test.go b/pagerduty/resource_pagerduty_tag_assignment_test.go index c97ff209a..e1c51c591 100644 --- a/pagerduty/resource_pagerduty_tag_assignment_test.go +++ b/pagerduty/resource_pagerduty_tag_assignment_test.go @@ -5,9 +5,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_tag_test.go b/pagerduty/resource_pagerduty_tag_test.go index c09e03826..5e2f91d33 100644 --- a/pagerduty/resource_pagerduty_tag_test.go +++ b/pagerduty/resource_pagerduty_tag_test.go @@ -6,9 +6,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_team.go b/pagerduty/resource_pagerduty_team.go index 864a30d27..71dd3f8f4 100644 --- a/pagerduty/resource_pagerduty_team.go +++ b/pagerduty/resource_pagerduty_team.go @@ -5,7 +5,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -76,13 +76,13 @@ func resourcePagerDutyTeamCreate(d *schema.ResourceData, meta interface{}) error log.Printf("[INFO] Creating PagerDuty team %s", team.Name) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if team, _, err := client.Teams.Create(team); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } else if team != nil { d.SetId(team.ID) } @@ -94,7 +94,6 @@ func resourcePagerDutyTeamCreate(d *schema.ResourceData, meta interface{}) error } return resourcePagerDutyTeamRead(d, meta) - } func resourcePagerDutyTeamRead(d *schema.ResourceData, meta interface{}) error { @@ -105,16 +104,16 @@ func resourcePagerDutyTeamRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[INFO] Reading PagerDuty team %s", d.Id()) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { if team, _, err := client.Teams.Get(d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := handleNotFoundError(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } } else if team != nil { d.Set("name", team.Name) @@ -136,9 +135,9 @@ func resourcePagerDutyTeamUpdate(d *schema.ResourceData, meta interface{}) error log.Printf("[INFO] Updating PagerDuty team %s", d.Id()) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, _, err := client.Teams.Update(d.Id(), team); err != nil { - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) @@ -157,13 +156,13 @@ func resourcePagerDutyTeamDelete(d *schema.ResourceData, meta interface{}) error log.Printf("[INFO] Deleting PagerDuty team %s", d.Id()) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.Teams.Delete(d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_team_membership.go b/pagerduty/resource_pagerduty_team_membership.go index 70b411b9b..d131a7d68 100644 --- a/pagerduty/resource_pagerduty_team_membership.go +++ b/pagerduty/resource_pagerduty_team_membership.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -88,17 +88,17 @@ func fetchPagerDutyTeamMembership(d *schema.ResourceData, meta interface{}, errC } log.Printf("[DEBUG] Reading user: %s from team: %s", userID, teamID) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { resp, _, err := client.Teams.GetMembers(teamID, &pagerduty.GetMembersOptions{}) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -120,6 +120,7 @@ func fetchPagerDutyTeamMembership(d *schema.ResourceData, meta interface{}, errC return nil }) } + func resourcePagerDutyTeamMembershipCreate(d *schema.ResourceData, meta interface{}) error { client, err := meta.(*Config).Client() if err != nil { @@ -132,13 +133,13 @@ func resourcePagerDutyTeamMembershipCreate(d *schema.ResourceData, meta interfac log.Printf("[DEBUG] Adding user: %s to team: %s with role: %s", userID, teamID, role) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.Teams.AddUserWithRole(teamID, userID, role); err != nil { if isErrCode(err, 500) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil @@ -169,13 +170,13 @@ func resourcePagerDutyTeamMembershipUpdate(d *schema.ResourceData, meta interfac log.Printf("[DEBUG] Updating user: %s to team: %s with role: %s", userID, teamID, role) // To update existing membership resource, We can use the same API as creating a new membership. - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.Teams.AddUserWithRole(teamID, userID, role); err != nil { if isErrCode(err, 500) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil @@ -214,13 +215,13 @@ func resourcePagerDutyTeamMembershipDelete(d *schema.ResourceData, meta interfac } // Retrying to give other resources (such as escalation policies) to delete - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.Teams.RemoveUser(teamID, userID); err != nil { if isErrCode(err, 400) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil }) @@ -251,15 +252,15 @@ func buildEPsIdsList(l []*pagerduty.OnCall) []string { func extractEPsAssociatedToUser(c *pagerduty.Client, userID string) ([]string, error) { var oncalls []*pagerduty.OnCall - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { resp, _, err := c.OnCall.List(&pagerduty.ListOnCallOptions{UserIds: []string{userID}}) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } oncalls = resp.Oncalls return nil @@ -274,11 +275,11 @@ func extractEPsAssociatedToUser(c *pagerduty.Client, userID string) ([]string, e func dissociateEPsFromTeam(c *pagerduty.Client, teamID string, eps []string) ([]string, error) { epsDissociatedFromTeam := []string{} for _, ep := range eps { - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { _, err := c.Teams.RemoveEscalationPolicy(teamID, ep) if err != nil && !isErrCode(err, 404) { time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) @@ -299,11 +300,11 @@ func dissociateEPsFromTeam(c *pagerduty.Client, teamID string, eps []string) ([] func associateEPsBackToTeam(c *pagerduty.Client, teamID string, eps []string) error { for _, ep := range eps { - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { _, err := c.Teams.AddEscalationPolicy(teamID, ep) if err != nil && !isErrCode(err, 404) { time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } return nil }) diff --git a/pagerduty/resource_pagerduty_team_membership_test.go b/pagerduty/resource_pagerduty_team_membership_test.go index 3aaab2812..cc6b26d27 100644 --- a/pagerduty/resource_pagerduty_team_membership_test.go +++ b/pagerduty/resource_pagerduty_team_membership_test.go @@ -4,9 +4,9 @@ import ( "fmt" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_team_test.go b/pagerduty/resource_pagerduty_team_test.go index 9c2849360..883b0168e 100644 --- a/pagerduty/resource_pagerduty_team_test.go +++ b/pagerduty/resource_pagerduty_team_test.go @@ -6,9 +6,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_user.go b/pagerduty/resource_pagerduty_user.go index 60539b410..21924e963 100644 --- a/pagerduty/resource_pagerduty_user.go +++ b/pagerduty/resource_pagerduty_user.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -182,17 +182,17 @@ func resourcePagerDutyUserRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[INFO] pooh Reading PagerDuty user %s", d.Id()) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { user, err := client.Users.GetWithLicense(d.Id(), &pagerduty.GetUserOptions{}) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := handleNotFoundError(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -210,7 +210,7 @@ func resourcePagerDutyUserRead(d *schema.ResourceData, meta interface{}) error { d.Set("license", user.License.ID) if err := d.Set("teams", flattenTeams(user.Teams)); err != nil { - return resource.NonRetryableError( + return retry.NonRetryableError( fmt.Errorf("error setting teams: %s", err), ) } @@ -238,13 +238,13 @@ func resourcePagerDutyUserUpdate(d *schema.ResourceData, meta interface{}) error log.Printf("[INFO] Updating PagerDuty user %s", d.Id()) // Retrying to give other resources (such as escalation policies) to delete - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, _, err := client.Users.Update(d.Id(), user); err != nil { if isErrCode(err, 400) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil }) @@ -305,13 +305,13 @@ func resourcePagerDutyUserDelete(d *schema.ResourceData, meta interface{}) error log.Printf("[INFO] Deleting PagerDuty user %s", d.Id()) // Retrying to give other resources (such as escalation policies) to delete - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if _, err := client.Users.Delete(d.Id()); err != nil { if isErrCode(err, 400) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } return nil }) @@ -328,7 +328,7 @@ func resourcePagerDutyUserDelete(d *schema.ResourceData, meta interface{}) error } func expandLicenseReference(v interface{}) (*pagerduty.LicenseReference, error) { - var license = &pagerduty.LicenseReference{ + license := &pagerduty.LicenseReference{ ID: v.(string), Type: "license_reference", } diff --git a/pagerduty/resource_pagerduty_user_contact_method.go b/pagerduty/resource_pagerduty_user_contact_method.go index 14fec0fc6..0763a09e8 100644 --- a/pagerduty/resource_pagerduty_user_contact_method.go +++ b/pagerduty/resource_pagerduty_user_contact_method.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -147,17 +147,17 @@ func fetchPagerDutyUserContactMethod(d *schema.ResourceData, meta interface{}, e userID := d.Get("user_id").(string) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { resp, _, err := client.Users.GetContactMethod(userID, d.Id()) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := handleNotFoundError(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil diff --git a/pagerduty/resource_pagerduty_user_contact_method_test.go b/pagerduty/resource_pagerduty_user_contact_method_test.go index 9806e3863..5536479e1 100644 --- a/pagerduty/resource_pagerduty_user_contact_method_test.go +++ b/pagerduty/resource_pagerduty_user_contact_method_test.go @@ -5,9 +5,9 @@ import ( "regexp" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyUserContactMethodEmail_Basic(t *testing.T) { diff --git a/pagerduty/resource_pagerduty_user_notification_rule.go b/pagerduty/resource_pagerduty_user_notification_rule.go index 32d1cd3e0..c180e0ab7 100644 --- a/pagerduty/resource_pagerduty_user_notification_rule.go +++ b/pagerduty/resource_pagerduty_user_notification_rule.go @@ -8,7 +8,7 @@ import ( "strings" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/heimweh/go-pagerduty/pagerduty" @@ -80,17 +80,17 @@ func fetchPagerDutyUserNotificationRule(d *schema.ResourceData, meta interface{} userID := d.Get("user_id").(string) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { resp, _, err := client.Users.GetNotificationRule(userID, d.Id()) if err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) + return retry.RetryableError(errResp) } return nil @@ -217,7 +217,7 @@ func expandContactMethod(v interface{}) (*pagerduty.ContactMethodReference, erro } } - var contactMethod = &pagerduty.ContactMethodReference{ + contactMethod := &pagerduty.ContactMethodReference{ ID: cm["id"].(string), Type: cm["type"].(string), } @@ -226,8 +226,7 @@ func expandContactMethod(v interface{}) (*pagerduty.ContactMethodReference, erro } func flattenContactMethod(v *pagerduty.ContactMethodReference) map[string]interface{} { - - var contactMethod = map[string]interface{}{ + contactMethod := map[string]interface{}{ "id": v.ID, "type": v.Type, } diff --git a/pagerduty/resource_pagerduty_user_notification_rule_test.go b/pagerduty/resource_pagerduty_user_notification_rule_test.go index 59ef06337..adc6bb55d 100644 --- a/pagerduty/resource_pagerduty_user_notification_rule_test.go +++ b/pagerduty/resource_pagerduty_user_notification_rule_test.go @@ -5,9 +5,9 @@ import ( "regexp" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func TestAccPagerDutyUserNotificationRuleContactMethod_Basic(t *testing.T) { diff --git a/pagerduty/resource_pagerduty_user_test.go b/pagerduty/resource_pagerduty_user_test.go index 7419d9f04..b9cc52d99 100644 --- a/pagerduty/resource_pagerduty_user_test.go +++ b/pagerduty/resource_pagerduty_user_test.go @@ -6,9 +6,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/heimweh/go-pagerduty/pagerduty" ) diff --git a/pagerduty/resource_pagerduty_webhook_subscription.go b/pagerduty/resource_pagerduty_webhook_subscription.go index 082f17877..dc79cd5a0 100644 --- a/pagerduty/resource_pagerduty_webhook_subscription.go +++ b/pagerduty/resource_pagerduty_webhook_subscription.go @@ -5,7 +5,7 @@ import ( "net/http" "time" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/heimweh/go-pagerduty/pagerduty" ) @@ -141,13 +141,13 @@ func resourcePagerDutyWebhookSubscriptionCreate(d *schema.ResourceData, meta int log.Printf("[INFO] Creating PagerDuty webhook subscription to be delivered to %s", webhook.DeliveryMethod.URL) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + retryErr := retry.Retry(2*time.Minute, func() *retry.RetryError { if webhook, _, err := client.WebhookSubscriptions.Create(webhook); err != nil { if isErrCode(err, 400) || isErrCode(err, 429) { - return resource.RetryableError(err) + return retry.RetryableError(err) } - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } else if webhook != nil { d.SetId(webhook.ID) } @@ -159,7 +159,6 @@ func resourcePagerDutyWebhookSubscriptionCreate(d *schema.ResourceData, meta int } return resourcePagerDutyWebhookSubscriptionRead(d, meta) - } func resourcePagerDutyWebhookSubscriptionRead(d *schema.ResourceData, meta interface{}) error { @@ -170,20 +169,21 @@ func resourcePagerDutyWebhookSubscriptionRead(d *schema.ResourceData, meta inter log.Printf("[INFO] Reading PagerDuty webhook subscription %s", d.Id()) - return resource.Retry(2*time.Minute, func() *resource.RetryError { + return retry.Retry(2*time.Minute, func() *retry.RetryError { if webhook, _, err := client.WebhookSubscriptions.Get(d.Id()); err != nil { if isErrCode(err, http.StatusBadRequest) { - return resource.NonRetryableError(err) + return retry.NonRetryableError(err) } time.Sleep(2 * time.Second) - return resource.RetryableError(err) + return retry.RetryableError(err) } else if webhook != nil { setWebhookResourceData(d, webhook) } return nil }) } + func resourcePagerDutyWebhookSubscriptionUpdate(d *schema.ResourceData, meta interface{}) error { client, err := meta.(*Config).Client() if err != nil { @@ -251,6 +251,7 @@ func expandDeliveryMethod(v interface{}) pagerduty.DeliveryMethod { } return method } + func expandFilter(v interface{}) pagerduty.Filter { filterMap := v.([]interface{})[0].(map[string]interface{}) diff --git a/pagerduty/resource_pagerduty_webhook_subscription_test.go b/pagerduty/resource_pagerduty_webhook_subscription_test.go index 6a06e8f3a..f270de146 100644 --- a/pagerduty/resource_pagerduty_webhook_subscription_test.go +++ b/pagerduty/resource_pagerduty_webhook_subscription_test.go @@ -6,9 +6,9 @@ import ( "strings" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" ) func init() { diff --git a/pagerduty/sweeper_test.go b/pagerduty/sweeper_test.go index dc1a45c68..c11ff3492 100644 --- a/pagerduty/sweeper_test.go +++ b/pagerduty/sweeper_test.go @@ -5,7 +5,7 @@ import ( "os" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" ) func TestMain(m *testing.M) { diff --git a/pagerdutyplugin/data_source_pagerduty_standards_resource_scores.go b/pagerdutyplugin/data_source_pagerduty_standards_resource_scores.go new file mode 100644 index 000000000..dcb70a59b --- /dev/null +++ b/pagerdutyplugin/data_source_pagerduty_standards_resource_scores.go @@ -0,0 +1,129 @@ +package pagerduty + +import ( + "context" + + "github.com/PagerDuty/go-pagerduty" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type dataSourceStandardsResourceScores struct { + client *pagerduty.Client +} + +var _ datasource.DataSource = (*dataSourceStandardsResourceScores)(nil) + +func (d *dataSourceStandardsResourceScores) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = "pagerduty_standards_resource_scores" +} + +func (d *dataSourceStandardsResourceScores) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{Required: true}, + "resource_type": schema.StringAttribute{ + Required: true, + Validators: []validator.String{ + stringvalidator.OneOf("technical_services"), + }, + }, + "score": schema.ObjectAttribute{ + AttributeTypes: resourceScoresObjectType.AttrTypes, + Computed: true, + }, + "standards": schema.ListAttribute{ + ElementType: resourceStandardObjectType, + Computed: true, + }, + }, + } +} + +func (d *dataSourceStandardsResourceScores) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + resp.Diagnostics.Append(ConfigurePagerdutyClient(&d.client, req.ProviderData)...) +} + +func (d *dataSourceStandardsResourceScores) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data dataSourceStandardsResourceScoresModel + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + id := data.ID.ValueString() + rt := data.ResourceType.ValueString() + + scores, err := d.client.ListResourceStandardScores(ctx, id, rt) + if err != nil { + resp.Diagnostics.Append(diag.NewErrorDiagnostic( + "Error calling ListResourceStandardScores", + err.Error(), + )) + return + } + + standards, di := resourceStandardsToModel(scores.Standards) + resp.Diagnostics.Append(di...) + data.Standards = standards + + score, di := resourceScoreToModel(scores.Score) + resp.Diagnostics.Append(di...) + data.Score = score + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +type dataSourceStandardsResourceScoresModel struct { + ID types.String `tfsdk:"id"` + ResourceType types.String `tfsdk:"resource_type"` + Standards types.List `tfsdk:"standards"` + Score types.Object `tfsdk:"score"` +} + +var resourceScoresObjectType = types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "passing": types.Int64Type, + "total": types.Int64Type, + }, +} + +func resourceScoreToModel(score *pagerduty.ResourceScore) (types.Object, diag.Diagnostics) { + return types.ObjectValue(resourceScoresObjectType.AttrTypes, map[string]attr.Value{ + "passing": types.Int64Value(int64(score.Passing)), + "total": types.Int64Value(int64(score.Total)), + }) +} + +var resourceStandardObjectType = types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "active": types.BoolType, + "description": types.StringType, + "id": types.StringType, + "name": types.StringType, + "type": types.StringType, + "pass": types.BoolType, + }, +} + +func resourceStandardsToModel(standards []pagerduty.ResourceStandard) (types.List, diag.Diagnostics) { + var diags diag.Diagnostics + var list []attr.Value + for _, standard := range standards { + value, di := types.ObjectValue(resourceStandardObjectType.AttrTypes, map[string]attr.Value{ + "active": types.BoolValue(standard.Active), + "description": types.StringValue(standard.Description), + "id": types.StringValue(standard.ID), + "name": types.StringValue(standard.Name), + "pass": types.BoolValue(standard.Pass), + "type": types.StringValue(standard.Type), + }) + diags.Append(di...) + list = append(list, value) + } + modelStandards, di := types.ListValue(resourceStandardObjectType, list) + diags.Append(di...) + return modelStandards, diags +} diff --git a/pagerdutyplugin/data_source_pagerduty_standards_resource_scores_test.go b/pagerdutyplugin/data_source_pagerduty_standards_resource_scores_test.go new file mode 100644 index 000000000..7cb808889 --- /dev/null +++ b/pagerdutyplugin/data_source_pagerduty_standards_resource_scores_test.go @@ -0,0 +1,86 @@ +package pagerduty + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccDataSourcePagerDutyStandardsResourceScores_Basic(t *testing.T) { + name := fmt.Sprintf("tf-%s", acctest.RandString(5)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV5ProviderFactories: testAccProtoV5ProviderFactories(), + Steps: []resource.TestStep{ + { + Config: testAccDataSourcePagerDutyStandardsResourceScoresConfig(name), + Check: testAccCheckAttributes( + fmt.Sprintf("data.pagerduty_standards_resource_scores.%s", name), + testStandardsResourceScores, + ), + }, + }, + }) +} + +func testStandardsResourceScores(a map[string]string) error { + testAttrs := []string{ + "id", + "resource_type", + "score.passing", + "score.total", + "standards.#", + "standards.0.active", + "standards.0.description", + "standards.0.id", + "standards.0.name", + "standards.0.pass", + "standards.0.type", + } + for _, attr := range testAttrs { + if _, ok := a[attr]; !ok { + return fmt.Errorf("Expected the required attribute %s to exist", attr) + } + } + return nil +} + +func testAccDataSourcePagerDutyStandardsResourceScoresConfig(name string) string { + return fmt.Sprintf(` +resource "pagerduty_user" "foo" { + name = "Earline Greenholt" + email = "125.greenholt.earline@graham.name" +} + +resource "pagerduty_escalation_policy" "bar" { + name = "Testing Escalation Policy" + num_loops = 2 + rule { + escalation_delay_in_minutes = 10 + target { + type = "user_reference" + id = pagerduty_user.foo.id + } + } +} + +resource "pagerduty_service" "example" { + name = "My Web App test" + auto_resolve_timeout = 14400 + acknowledgement_timeout = 600 + escalation_policy = pagerduty_escalation_policy.bar.id + alert_creation = "create_alerts_and_incidents" + auto_pause_notifications_parameters { + enabled = true + timeout = 300 + } +} + +data "pagerduty_standards_resource_scores" "%s" { + resource_type = "technical_services" + id = pagerduty_service.example.id +}`, name) +} diff --git a/pagerdutyplugin/data_source_pagerduty_standards_resources_scores.go b/pagerdutyplugin/data_source_pagerduty_standards_resources_scores.go new file mode 100644 index 000000000..8368c9fd4 --- /dev/null +++ b/pagerdutyplugin/data_source_pagerduty_standards_resources_scores.go @@ -0,0 +1,121 @@ +package pagerduty + +import ( + "context" + + "github.com/PagerDuty/go-pagerduty" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +type dataSourceStandardsResourcesScores struct { + client *pagerduty.Client +} + +var _ datasource.DataSource = (*dataSourceStandardsResourcesScores)(nil) + +func (d *dataSourceStandardsResourcesScores) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = "pagerduty_standards_resources_scores" +} + +func (d *dataSourceStandardsResourcesScores) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "ids": schema.ListAttribute{ + ElementType: types.StringType, + Required: true, + }, + "resource_type": schema.StringAttribute{ + Required: true, + Validators: []validator.String{ + stringvalidator.OneOf("technical_services"), + }, + }, + "resources": schema.ListAttribute{ + ElementType: resourceStandardScoreObjectType, + Computed: true, + }, + }, + } +} + +func (d *dataSourceStandardsResourcesScores) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + resp.Diagnostics.Append(ConfigurePagerdutyClient(&d.client, req.ProviderData)...) +} + +func (d *dataSourceStandardsResourcesScores) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data dataSourceStandardsResourcesScoresModel + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + rt := data.ResourceType.ValueString() + ids := make([]string, 0) + resp.Diagnostics.Append(data.IDs.ElementsAs(ctx, &ids, true)...) + + opt := pagerduty.ListMultiResourcesStandardScoresOptions{IDs: ids} + scores, err := d.client.ListMultiResourcesStandardScores(ctx, rt, opt) + if err != nil { + resp.Diagnostics.Append(diag.NewErrorDiagnostic( + "Error calling ListResourceStandardScores", + err.Error(), + )) + return + } + + resources, di := resourceStandardScoresToModel(scores.Resources) + resp.Diagnostics.Append(di...) + data.Resources = resources + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +type dataSourceStandardsResourcesScoresModel struct { + IDs types.List `tfsdk:"ids"` + ResourceType types.String `tfsdk:"resource_type"` + Resources types.List `tfsdk:"resources"` +} + +func resourceStandardScoresToModel(data []pagerduty.ResourceStandardScore) (types.List, diag.Diagnostics) { + var diags diag.Diagnostics + var list []attr.Value + for i := range data { + resourceStandardScore, di := resourceStandardScoreToModel(&data[i]) + diags.Append(di...) + list = append(list, resourceStandardScore) + } + listValue, di := types.ListValue(resourceStandardScoreObjectType, list) + diags.Append(di...) + return listValue, diags +} + +var resourceStandardScoreObjectType = types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "resource_id": types.StringType, + "resource_type": types.StringType, + "standards": types.ListType{ElemType: resourceStandardObjectType}, + "score": resourceScoresObjectType, + }, +} + +func resourceStandardScoreToModel(data *pagerduty.ResourceStandardScore) (types.Object, diag.Diagnostics) { + var diags diag.Diagnostics + standards, di := resourceStandardsToModel(data.Standards) + diags.Append(di...) + + score, di := resourceScoreToModel(data.Score) + diags.Append(di...) + + standardScore, di := types.ObjectValue(resourceStandardScoreObjectType.AttrTypes, map[string]attr.Value{ + "resource_id": types.StringValue(data.ResourceID), + "resource_type": types.StringValue(data.ResourceType), + "score": score, + "standards": standards, + }) + diags.Append(di...) + + return standardScore, diags +} diff --git a/pagerdutyplugin/data_source_pagerduty_standards_resources_scores_test.go b/pagerdutyplugin/data_source_pagerduty_standards_resources_scores_test.go new file mode 100644 index 000000000..4d5ae2459 --- /dev/null +++ b/pagerdutyplugin/data_source_pagerduty_standards_resources_scores_test.go @@ -0,0 +1,92 @@ +package pagerduty + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccDataSourcePagerDutyStandardsResourcesScores_Basic(t *testing.T) { + name := fmt.Sprintf("tf-%s", acctest.RandString(5)) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV5ProviderFactories: testAccProtoV5ProviderFactories(), + Steps: []resource.TestStep{ + { + Config: testAccDataSourcePagerDutyStandardsResourcesScoresConfig(name), + Check: testAccCheckAttributes( + fmt.Sprintf("data.pagerduty_standards_resources_scores.%s", name), + testStandardsResourcesScores, + ), + }, + }, + }) +} + +func testStandardsResourcesScores(a map[string]string) error { + testAttrs := []string{ + "ids.#", + "ids.0", + "resource_type", + "resources.#", + "resources.0.resource_id", + "resources.0.resource_type", + "resources.0.score.passing", + "resources.0.score.total", + "resources.0.standards.#", + "resources.0.standards.0.active", + "resources.0.standards.0.description", + "resources.0.standards.0.id", + "resources.0.standards.0.name", + "resources.0.standards.0.pass", + "resources.0.standards.0.type", + } + + for _, attr := range testAttrs { + if _, ok := a[attr]; !ok { + return fmt.Errorf("Expected the required attribute %s to exist", attr) + } + } + + return nil +} + +func testAccDataSourcePagerDutyStandardsResourcesScoresConfig(name string) string { + return fmt.Sprintf(` +resource "pagerduty_user" "foo" { + name = "Earline Greenholt" + email = "125.greenholt.earline@graham.name" +} + +resource "pagerduty_escalation_policy" "bar" { + name = "Testing Escalation Policy" + num_loops = 2 + rule { + escalation_delay_in_minutes = 10 + target { + type = "user_reference" + id = pagerduty_user.foo.id + } + } +} + +resource "pagerduty_service" "example" { + name = "My Web App test" + auto_resolve_timeout = 14400 + acknowledgement_timeout = 600 + escalation_policy = pagerduty_escalation_policy.bar.id + alert_creation = "create_alerts_and_incidents" + auto_pause_notifications_parameters { + enabled = true + timeout = 300 + } +} + +data "pagerduty_standards_resources_scores" "%s" { + resource_type = "technical_services" + ids = [pagerduty_service.example.id] +}`, name) +} diff --git a/pagerdutyplugin/data_source_pagerduty_standards_test.go b/pagerdutyplugin/data_source_pagerduty_standards_test.go index 1647153c3..436837431 100644 --- a/pagerdutyplugin/data_source_pagerduty_standards_test.go +++ b/pagerdutyplugin/data_source_pagerduty_standards_test.go @@ -18,7 +18,10 @@ func TestAccDataSourcePagerDutyStandards_Basic(t *testing.T) { Steps: []resource.TestStep{ { Config: testAccDataSourcePagerDutyStandardsConfig(name), - Check: testAccDataSourcePagerDutyStandards(fmt.Sprintf("data.pagerduty_standards.%s", name)), + Check: testAccCheckAttributes( + fmt.Sprintf("data.pagerduty_standards.%s", name), + testStandards, + ), }, }, }) @@ -82,15 +85,6 @@ func testAccDataSourcePagerDutyStandardsWithResourceType(path, rt string) resour } } -func testAccDataSourcePagerDutyStandards(n string) resource.TestCheckFunc { - return func(s *terraform.State) error { - r := s.RootModule().Resources[n] - a := r.Primary.Attributes - - return testStandards(a) - } -} - func testAccDataSourcePagerDutyStandardsConfig(name string) string { return fmt.Sprintf(`data "pagerduty_standards" "%s" {}`, name) } diff --git a/pagerdutyplugin/provider.go b/pagerdutyplugin/provider.go index ccd8ed257..4f2a1e491 100644 --- a/pagerdutyplugin/provider.go +++ b/pagerdutyplugin/provider.go @@ -47,6 +47,8 @@ func (p *Provider) Schema(ctx context.Context, req provider.SchemaRequest, resp func (p *Provider) DataSources(ctx context.Context) [](func() datasource.DataSource) { return [](func() datasource.DataSource){ func() datasource.DataSource { return &dataSourceStandards{} }, + func() datasource.DataSource { return &dataSourceStandardsResourceScores{} }, + func() datasource.DataSource { return &dataSourceStandardsResourcesScores{} }, } } diff --git a/pagerdutyplugin/provider_test.go b/pagerdutyplugin/provider_test.go index 92c1c8b2f..cf6ff16f3 100644 --- a/pagerdutyplugin/provider_test.go +++ b/pagerdutyplugin/provider_test.go @@ -1,11 +1,17 @@ package pagerduty import ( + "context" "os" "testing" "github.com/hashicorp/terraform-plugin-framework/providerserver" "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-mux/tf5muxserver" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + + pd "github.com/terraform-providers/terraform-provider-pagerduty/pagerduty" ) func testAccPreCheck(t *testing.T) { @@ -22,8 +28,29 @@ func testAccPreCheck(t *testing.T) { } } +func testAccCheckAttributes(n string, fn func(map[string]string) error) resource.TestCheckFunc { + return func(s *terraform.State) error { + r := s.RootModule().Resources[n] + a := r.Primary.Attributes + return fn(a) + } +} + func testAccProtoV5ProviderFactories() map[string]func() (tfprotov5.ProviderServer, error) { return map[string]func() (tfprotov5.ProviderServer, error){ - "pagerduty": providerserver.NewProtocol5WithError(New()), + "pagerduty": func() (tfprotov5.ProviderServer, error) { + ctx := context.Background() + providers := []func() tfprotov5.ProviderServer{ + pd.Provider().GRPCProvider, + providerserver.NewProtocol5(New()), + } + + muxServer, err := tf5muxserver.NewMuxServer(ctx, providers...) + if err != nil { + return nil, err + } + + return muxServer.ProviderServer(), nil + }, } } diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/LICENSE b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/LICENSE new file mode 100644 index 000000000..0f5a4e378 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/LICENSE @@ -0,0 +1,356 @@ +Copyright (c) 2022 HashiCorp, Inc. + +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. + diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag/diag.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag/diag.go new file mode 100644 index 000000000..09a65e6bf --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag/diag.go @@ -0,0 +1,84 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package validatordiag + +import ( + "fmt" + "unicode" + "unicode/utf8" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// InvalidBlockDiagnostic returns an error Diagnostic to be used when a block is invalid +func InvalidBlockDiagnostic(path path.Path, description string) diag.Diagnostic { + return diag.NewAttributeErrorDiagnostic( + path, + "Invalid Block", + fmt.Sprintf("Block %s %s", path, description), + ) +} + +// InvalidAttributeValueDiagnostic returns an error Diagnostic to be used when an attribute has an invalid value. +func InvalidAttributeValueDiagnostic(path path.Path, description string, value string) diag.Diagnostic { + return diag.NewAttributeErrorDiagnostic( + path, + "Invalid Attribute Value", + fmt.Sprintf("Attribute %s %s, got: %s", path, description, value), + ) +} + +// InvalidAttributeValueLengthDiagnostic returns an error Diagnostic to be used when an attribute's value has an invalid length. +func InvalidAttributeValueLengthDiagnostic(path path.Path, description string, value string) diag.Diagnostic { + return diag.NewAttributeErrorDiagnostic( + path, + "Invalid Attribute Value Length", + fmt.Sprintf("Attribute %s %s, got: %s", path, description, value), + ) +} + +// InvalidAttributeValueMatchDiagnostic returns an error Diagnostic to be used when an attribute's value has an invalid match. +func InvalidAttributeValueMatchDiagnostic(path path.Path, description string, value string) diag.Diagnostic { + return diag.NewAttributeErrorDiagnostic( + path, + "Invalid Attribute Value Match", + fmt.Sprintf("Attribute %s %s, got: %s", path, description, value), + ) +} + +// InvalidAttributeCombinationDiagnostic returns an error Diagnostic to be used when a schemavalidator of attributes is invalid. +func InvalidAttributeCombinationDiagnostic(path path.Path, description string) diag.Diagnostic { + return diag.NewAttributeErrorDiagnostic( + path, + "Invalid Attribute Combination", + capitalize(description), + ) +} + +// InvalidAttributeTypeDiagnostic returns an error Diagnostic to be used when an attribute has an invalid type. +func InvalidAttributeTypeDiagnostic(path path.Path, description string, value string) diag.Diagnostic { + return diag.NewAttributeErrorDiagnostic( + path, + "Invalid Attribute Type", + fmt.Sprintf("Attribute %s %s, got: %s", path, description, value), + ) +} + +func BugInProviderDiagnostic(summary string) diag.Diagnostic { + return diag.NewErrorDiagnostic(summary, + "This is a bug in the provider, which should be reported in the provider's own issue tracker", + ) +} + +// capitalize will uppercase the first letter in a UTF-8 string. +func capitalize(str string) string { + if str == "" { + return "" + } + + firstRune, size := utf8.DecodeRuneInString(str) + + return string(unicode.ToUpper(firstRune)) + str[size:] +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag/doc.go new file mode 100644 index 000000000..c6f8dcff5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag/doc.go @@ -0,0 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package validatordiag provides diagnostics helpers for validator implementations. +package validatordiag diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/also_requires.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/also_requires.go new file mode 100644 index 000000000..2d4c38a31 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/also_requires.go @@ -0,0 +1,228 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schemavalidator + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// This type of validator must satisfy all types. +var ( + _ validator.Bool = AlsoRequiresValidator{} + _ validator.Float64 = AlsoRequiresValidator{} + _ validator.Int64 = AlsoRequiresValidator{} + _ validator.List = AlsoRequiresValidator{} + _ validator.Map = AlsoRequiresValidator{} + _ validator.Number = AlsoRequiresValidator{} + _ validator.Object = AlsoRequiresValidator{} + _ validator.Set = AlsoRequiresValidator{} + _ validator.String = AlsoRequiresValidator{} +) + +// AlsoRequiresValidator is the underlying struct implementing AlsoRequires. +type AlsoRequiresValidator struct { + PathExpressions path.Expressions +} + +type AlsoRequiresValidatorRequest struct { + Config tfsdk.Config + ConfigValue attr.Value + Path path.Path + PathExpression path.Expression +} + +type AlsoRequiresValidatorResponse struct { + Diagnostics diag.Diagnostics +} + +func (av AlsoRequiresValidator) Description(ctx context.Context) string { + return av.MarkdownDescription(ctx) +} + +func (av AlsoRequiresValidator) MarkdownDescription(_ context.Context) string { + return fmt.Sprintf("Ensure that if an attribute is set, also these are set: %q", av.PathExpressions) +} + +func (av AlsoRequiresValidator) Validate(ctx context.Context, req AlsoRequiresValidatorRequest, res *AlsoRequiresValidatorResponse) { + // If attribute configuration is null, there is nothing else to validate + if req.ConfigValue.IsNull() { + return + } + + expressions := req.PathExpression.MergeExpressions(av.PathExpressions...) + + for _, expression := range expressions { + matchedPaths, diags := req.Config.PathMatches(ctx, expression) + + res.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + continue + } + + for _, mp := range matchedPaths { + // If the user specifies the same attribute this validator is applied to, + // also as part of the input, skip it + if mp.Equal(req.Path) { + continue + } + + var mpVal attr.Value + diags := req.Config.GetAttribute(ctx, mp, &mpVal) + res.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + continue + } + + // Delay validation until all involved attribute have a known value + if mpVal.IsUnknown() { + return + } + + if mpVal.IsNull() { + res.Diagnostics.Append(validatordiag.InvalidAttributeCombinationDiagnostic( + req.Path, + fmt.Sprintf("Attribute %q must be specified when %q is specified", mp, req.Path), + )) + } + } + } +} + +func (av AlsoRequiresValidator) ValidateBool(ctx context.Context, req validator.BoolRequest, resp *validator.BoolResponse) { + validateReq := AlsoRequiresValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AlsoRequiresValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AlsoRequiresValidator) ValidateFloat64(ctx context.Context, req validator.Float64Request, resp *validator.Float64Response) { + validateReq := AlsoRequiresValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AlsoRequiresValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AlsoRequiresValidator) ValidateInt64(ctx context.Context, req validator.Int64Request, resp *validator.Int64Response) { + validateReq := AlsoRequiresValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AlsoRequiresValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AlsoRequiresValidator) ValidateList(ctx context.Context, req validator.ListRequest, resp *validator.ListResponse) { + validateReq := AlsoRequiresValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AlsoRequiresValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AlsoRequiresValidator) ValidateMap(ctx context.Context, req validator.MapRequest, resp *validator.MapResponse) { + validateReq := AlsoRequiresValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AlsoRequiresValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AlsoRequiresValidator) ValidateNumber(ctx context.Context, req validator.NumberRequest, resp *validator.NumberResponse) { + validateReq := AlsoRequiresValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AlsoRequiresValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AlsoRequiresValidator) ValidateObject(ctx context.Context, req validator.ObjectRequest, resp *validator.ObjectResponse) { + validateReq := AlsoRequiresValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AlsoRequiresValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AlsoRequiresValidator) ValidateSet(ctx context.Context, req validator.SetRequest, resp *validator.SetResponse) { + validateReq := AlsoRequiresValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AlsoRequiresValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AlsoRequiresValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + validateReq := AlsoRequiresValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AlsoRequiresValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/at_least_one_of.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/at_least_one_of.go new file mode 100644 index 000000000..708d59e0f --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/at_least_one_of.go @@ -0,0 +1,224 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schemavalidator + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// This type of validator must satisfy all types. +var ( + _ validator.Bool = AtLeastOneOfValidator{} + _ validator.Float64 = AtLeastOneOfValidator{} + _ validator.Int64 = AtLeastOneOfValidator{} + _ validator.List = AtLeastOneOfValidator{} + _ validator.Map = AtLeastOneOfValidator{} + _ validator.Number = AtLeastOneOfValidator{} + _ validator.Object = AtLeastOneOfValidator{} + _ validator.Set = AtLeastOneOfValidator{} + _ validator.String = AtLeastOneOfValidator{} +) + +// AtLeastOneOfValidator is the underlying struct implementing AtLeastOneOf. +type AtLeastOneOfValidator struct { + PathExpressions path.Expressions +} + +type AtLeastOneOfValidatorRequest struct { + Config tfsdk.Config + ConfigValue attr.Value + Path path.Path + PathExpression path.Expression +} + +type AtLeastOneOfValidatorResponse struct { + Diagnostics diag.Diagnostics +} + +func (av AtLeastOneOfValidator) Description(ctx context.Context) string { + return av.MarkdownDescription(ctx) +} + +func (av AtLeastOneOfValidator) MarkdownDescription(_ context.Context) string { + return fmt.Sprintf("Ensure that at least one attribute from this collection is set: %s", av.PathExpressions) +} + +func (av AtLeastOneOfValidator) Validate(ctx context.Context, req AtLeastOneOfValidatorRequest, res *AtLeastOneOfValidatorResponse) { + // If attribute configuration is not null, validator already succeeded. + if !req.ConfigValue.IsNull() { + return + } + + expressions := req.PathExpression.MergeExpressions(av.PathExpressions...) + + for _, expression := range expressions { + matchedPaths, diags := req.Config.PathMatches(ctx, expression) + + res.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + continue + } + + for _, mp := range matchedPaths { + var mpVal attr.Value + diags := req.Config.GetAttribute(ctx, mp, &mpVal) + res.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + continue + } + + // Delay validation until all involved attribute have a known value + if mpVal.IsUnknown() { + return + } + + if !mpVal.IsNull() { + return + } + } + } + + res.Diagnostics.Append(validatordiag.InvalidAttributeCombinationDiagnostic( + req.Path, + fmt.Sprintf("At least one attribute out of %s must be specified", expressions), + )) +} + +func (av AtLeastOneOfValidator) ValidateBool(ctx context.Context, req validator.BoolRequest, resp *validator.BoolResponse) { + validateReq := AtLeastOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AtLeastOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AtLeastOneOfValidator) ValidateFloat64(ctx context.Context, req validator.Float64Request, resp *validator.Float64Response) { + validateReq := AtLeastOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AtLeastOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AtLeastOneOfValidator) ValidateInt64(ctx context.Context, req validator.Int64Request, resp *validator.Int64Response) { + validateReq := AtLeastOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AtLeastOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AtLeastOneOfValidator) ValidateList(ctx context.Context, req validator.ListRequest, resp *validator.ListResponse) { + validateReq := AtLeastOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AtLeastOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AtLeastOneOfValidator) ValidateMap(ctx context.Context, req validator.MapRequest, resp *validator.MapResponse) { + validateReq := AtLeastOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AtLeastOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AtLeastOneOfValidator) ValidateNumber(ctx context.Context, req validator.NumberRequest, resp *validator.NumberResponse) { + validateReq := AtLeastOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AtLeastOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AtLeastOneOfValidator) ValidateObject(ctx context.Context, req validator.ObjectRequest, resp *validator.ObjectResponse) { + validateReq := AtLeastOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AtLeastOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AtLeastOneOfValidator) ValidateSet(ctx context.Context, req validator.SetRequest, resp *validator.SetResponse) { + validateReq := AtLeastOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AtLeastOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av AtLeastOneOfValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + validateReq := AtLeastOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &AtLeastOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/conflicts_with.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/conflicts_with.go new file mode 100644 index 000000000..b554953fd --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/conflicts_with.go @@ -0,0 +1,228 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schemavalidator + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// This type of validator must satisfy all types. +var ( + _ validator.Bool = ConflictsWithValidator{} + _ validator.Float64 = ConflictsWithValidator{} + _ validator.Int64 = ConflictsWithValidator{} + _ validator.List = ConflictsWithValidator{} + _ validator.Map = ConflictsWithValidator{} + _ validator.Number = ConflictsWithValidator{} + _ validator.Object = ConflictsWithValidator{} + _ validator.Set = ConflictsWithValidator{} + _ validator.String = ConflictsWithValidator{} +) + +// ConflictsWithValidator is the underlying struct implementing ConflictsWith. +type ConflictsWithValidator struct { + PathExpressions path.Expressions +} + +type ConflictsWithValidatorRequest struct { + Config tfsdk.Config + ConfigValue attr.Value + Path path.Path + PathExpression path.Expression +} + +type ConflictsWithValidatorResponse struct { + Diagnostics diag.Diagnostics +} + +func (av ConflictsWithValidator) Description(ctx context.Context) string { + return av.MarkdownDescription(ctx) +} + +func (av ConflictsWithValidator) MarkdownDescription(_ context.Context) string { + return fmt.Sprintf("Ensure that if an attribute is set, these are not set: %q", av.PathExpressions) +} + +func (av ConflictsWithValidator) Validate(ctx context.Context, req ConflictsWithValidatorRequest, res *ConflictsWithValidatorResponse) { + // If attribute configuration is null, it cannot conflict with others + if req.ConfigValue.IsNull() { + return + } + + expressions := req.PathExpression.MergeExpressions(av.PathExpressions...) + + for _, expression := range expressions { + matchedPaths, diags := req.Config.PathMatches(ctx, expression) + + res.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + continue + } + + for _, mp := range matchedPaths { + // If the user specifies the same attribute this validator is applied to, + // also as part of the input, skip it + if mp.Equal(req.Path) { + continue + } + + var mpVal attr.Value + diags := req.Config.GetAttribute(ctx, mp, &mpVal) + res.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + continue + } + + // Delay validation until all involved attribute have a known value + if mpVal.IsUnknown() { + return + } + + if !mpVal.IsNull() { + res.Diagnostics.Append(validatordiag.InvalidAttributeCombinationDiagnostic( + req.Path, + fmt.Sprintf("Attribute %q cannot be specified when %q is specified", mp, req.Path), + )) + } + } + } +} + +func (av ConflictsWithValidator) ValidateBool(ctx context.Context, req validator.BoolRequest, resp *validator.BoolResponse) { + validateReq := ConflictsWithValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ConflictsWithValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ConflictsWithValidator) ValidateFloat64(ctx context.Context, req validator.Float64Request, resp *validator.Float64Response) { + validateReq := ConflictsWithValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ConflictsWithValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ConflictsWithValidator) ValidateInt64(ctx context.Context, req validator.Int64Request, resp *validator.Int64Response) { + validateReq := ConflictsWithValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ConflictsWithValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ConflictsWithValidator) ValidateList(ctx context.Context, req validator.ListRequest, resp *validator.ListResponse) { + validateReq := ConflictsWithValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ConflictsWithValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ConflictsWithValidator) ValidateMap(ctx context.Context, req validator.MapRequest, resp *validator.MapResponse) { + validateReq := ConflictsWithValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ConflictsWithValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ConflictsWithValidator) ValidateNumber(ctx context.Context, req validator.NumberRequest, resp *validator.NumberResponse) { + validateReq := ConflictsWithValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ConflictsWithValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ConflictsWithValidator) ValidateObject(ctx context.Context, req validator.ObjectRequest, resp *validator.ObjectResponse) { + validateReq := ConflictsWithValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ConflictsWithValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ConflictsWithValidator) ValidateSet(ctx context.Context, req validator.SetRequest, resp *validator.SetResponse) { + validateReq := ConflictsWithValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ConflictsWithValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ConflictsWithValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + validateReq := ConflictsWithValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ConflictsWithValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/doc.go new file mode 100644 index 000000000..612dce36e --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/doc.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package schemavalidator provides validators to express relationships between +// multiple attributes within the schema of a resource, data source, or provider. +// For example, checking that an attribute is present when another is present, or vice-versa. +// +// These validators are implemented on a starting attribute, where +// relationships can be expressed as absolute paths to others or relative to +// the starting attribute. For multiple attribute validators that are defined +// outside the schema, which may be easier to implement in provider code +// generation situations or suit provider code preferences differently, refer +// to the datasourcevalidator, providervalidator, or resourcevalidator package. +package schemavalidator diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/exactly_one_of.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/exactly_one_of.go new file mode 100644 index 000000000..f284fe275 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator/exactly_one_of.go @@ -0,0 +1,248 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package schemavalidator + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/tfsdk" +) + +// This type of validator must satisfy all types. +var ( + _ validator.Bool = ExactlyOneOfValidator{} + _ validator.Float64 = ExactlyOneOfValidator{} + _ validator.Int64 = ExactlyOneOfValidator{} + _ validator.List = ExactlyOneOfValidator{} + _ validator.Map = ExactlyOneOfValidator{} + _ validator.Number = ExactlyOneOfValidator{} + _ validator.Object = ExactlyOneOfValidator{} + _ validator.Set = ExactlyOneOfValidator{} + _ validator.String = ExactlyOneOfValidator{} +) + +// ExactlyOneOfValidator is the underlying struct implementing ExactlyOneOf. +type ExactlyOneOfValidator struct { + PathExpressions path.Expressions +} + +type ExactlyOneOfValidatorRequest struct { + Config tfsdk.Config + ConfigValue attr.Value + Path path.Path + PathExpression path.Expression +} + +type ExactlyOneOfValidatorResponse struct { + Diagnostics diag.Diagnostics +} + +func (av ExactlyOneOfValidator) Description(ctx context.Context) string { + return av.MarkdownDescription(ctx) +} + +func (av ExactlyOneOfValidator) MarkdownDescription(_ context.Context) string { + return fmt.Sprintf("Ensure that one and only one attribute from this collection is set: %q", av.PathExpressions) +} + +func (av ExactlyOneOfValidator) Validate(ctx context.Context, req ExactlyOneOfValidatorRequest, res *ExactlyOneOfValidatorResponse) { + count := 0 + expressions := req.PathExpression.MergeExpressions(av.PathExpressions...) + + // If current attribute is unknown, delay validation + if req.ConfigValue.IsUnknown() { + return + } + + // Now that we know the current attribute is known, check whether it is + // null to determine if it should contribute to the count. Later logic + // will remove a duplicate matching path, should it be included in the + // given expressions. + if !req.ConfigValue.IsNull() { + count++ + } + + for _, expression := range expressions { + matchedPaths, diags := req.Config.PathMatches(ctx, expression) + + res.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + continue + } + + for _, mp := range matchedPaths { + // If the user specifies the same attribute this validator is applied to, + // also as part of the input, skip it + if mp.Equal(req.Path) { + continue + } + + var mpVal attr.Value + diags := req.Config.GetAttribute(ctx, mp, &mpVal) + res.Diagnostics.Append(diags...) + + // Collect all errors + if diags.HasError() { + continue + } + + // Delay validation until all involved attribute have a known value + if mpVal.IsUnknown() { + return + } + + if !mpVal.IsNull() { + count++ + } + } + } + + if count == 0 { + res.Diagnostics.Append(validatordiag.InvalidAttributeCombinationDiagnostic( + req.Path, + fmt.Sprintf("No attribute specified when one (and only one) of %s is required", expressions), + )) + } + + if count > 1 { + res.Diagnostics.Append(validatordiag.InvalidAttributeCombinationDiagnostic( + req.Path, + fmt.Sprintf("%d attributes specified when one (and only one) of %s is required", count, expressions), + )) + } +} + +func (av ExactlyOneOfValidator) ValidateBool(ctx context.Context, req validator.BoolRequest, resp *validator.BoolResponse) { + validateReq := ExactlyOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ExactlyOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ExactlyOneOfValidator) ValidateFloat64(ctx context.Context, req validator.Float64Request, resp *validator.Float64Response) { + validateReq := ExactlyOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ExactlyOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ExactlyOneOfValidator) ValidateInt64(ctx context.Context, req validator.Int64Request, resp *validator.Int64Response) { + validateReq := ExactlyOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ExactlyOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ExactlyOneOfValidator) ValidateList(ctx context.Context, req validator.ListRequest, resp *validator.ListResponse) { + validateReq := ExactlyOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ExactlyOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ExactlyOneOfValidator) ValidateMap(ctx context.Context, req validator.MapRequest, resp *validator.MapResponse) { + validateReq := ExactlyOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ExactlyOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ExactlyOneOfValidator) ValidateNumber(ctx context.Context, req validator.NumberRequest, resp *validator.NumberResponse) { + validateReq := ExactlyOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ExactlyOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ExactlyOneOfValidator) ValidateObject(ctx context.Context, req validator.ObjectRequest, resp *validator.ObjectResponse) { + validateReq := ExactlyOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ExactlyOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ExactlyOneOfValidator) ValidateSet(ctx context.Context, req validator.SetRequest, resp *validator.SetResponse) { + validateReq := ExactlyOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ExactlyOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} + +func (av ExactlyOneOfValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + validateReq := ExactlyOneOfValidatorRequest{ + Config: req.Config, + ConfigValue: req.ConfigValue, + Path: req.Path, + PathExpression: req.PathExpression, + } + validateResp := &ExactlyOneOfValidatorResponse{} + + av.Validate(ctx, validateReq, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/all.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/all.go new file mode 100644 index 000000000..f53caba25 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/all.go @@ -0,0 +1,57 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// All returns a validator which ensures that any configured attribute value +// attribute value validates against all the given validators. +// +// Use of All is only necessary when used in conjunction with Any or AnyWithAllWarnings +// as the Validators field automatically applies a logical AND. +func All(validators ...validator.String) validator.String { + return allValidator{ + validators: validators, + } +} + +var _ validator.String = allValidator{} + +// allValidator implements the validator. +type allValidator struct { + validators []validator.String +} + +// Description describes the validation in plain text formatting. +func (v allValidator) Description(ctx context.Context) string { + var descriptions []string + + for _, subValidator := range v.validators { + descriptions = append(descriptions, subValidator.Description(ctx)) + } + + return fmt.Sprintf("Value must satisfy all of the validations: %s", strings.Join(descriptions, " + ")) +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (v allValidator) MarkdownDescription(ctx context.Context) string { + return v.Description(ctx) +} + +// ValidateString performs the validation. +func (v allValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + for _, subValidator := range v.validators { + validateResp := &validator.StringResponse{} + + subValidator.ValidateString(ctx, req, validateResp) + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/also_requires.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/also_requires.go new file mode 100644 index 000000000..97ca59b73 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/also_requires.go @@ -0,0 +1,26 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// AlsoRequires checks that a set of path.Expression has a non-null value, +// if the current attribute or block also has a non-null value. +// +// This implements the validation logic declaratively within the schema. +// Refer to [datasourcevalidator.RequiredTogether], +// [providervalidator.RequiredTogether], or [resourcevalidator.RequiredTogether] +// for declaring this type of validation outside the schema definition. +// +// Relative path.Expression will be resolved using the attribute or block +// being validated. +func AlsoRequires(expressions ...path.Expression) validator.String { + return schemavalidator.AlsoRequiresValidator{ + PathExpressions: expressions, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/any.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/any.go new file mode 100644 index 000000000..ba8f218ac --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/any.go @@ -0,0 +1,65 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// Any returns a validator which ensures that any configured attribute value +// passes at least one of the given validators. +// +// To prevent practitioner confusion should non-passing validators have +// conflicting logic, only warnings from the passing validator are returned. +// Use AnyWithAllWarnings() to return warnings from non-passing validators +// as well. +func Any(validators ...validator.String) validator.String { + return anyValidator{ + validators: validators, + } +} + +var _ validator.String = anyValidator{} + +// anyValidator implements the validator. +type anyValidator struct { + validators []validator.String +} + +// Description describes the validation in plain text formatting. +func (v anyValidator) Description(ctx context.Context) string { + var descriptions []string + + for _, subValidator := range v.validators { + descriptions = append(descriptions, subValidator.Description(ctx)) + } + + return fmt.Sprintf("Value must satisfy at least one of the validations: %s", strings.Join(descriptions, " + ")) +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (v anyValidator) MarkdownDescription(ctx context.Context) string { + return v.Description(ctx) +} + +// ValidateString performs the validation. +func (v anyValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + for _, subValidator := range v.validators { + validateResp := &validator.StringResponse{} + + subValidator.ValidateString(ctx, req, validateResp) + + if !validateResp.Diagnostics.HasError() { + resp.Diagnostics = validateResp.Diagnostics + + return + } + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/any_with_all_warnings.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/any_with_all_warnings.go new file mode 100644 index 000000000..e857424c9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/any_with_all_warnings.go @@ -0,0 +1,67 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// AnyWithAllWarnings returns a validator which ensures that any configured +// attribute value passes at least one of the given validators. This validator +// returns all warnings, including failed validators. +// +// Use Any() to return warnings only from the passing validator. +func AnyWithAllWarnings(validators ...validator.String) validator.String { + return anyWithAllWarningsValidator{ + validators: validators, + } +} + +var _ validator.String = anyWithAllWarningsValidator{} + +// anyWithAllWarningsValidator implements the validator. +type anyWithAllWarningsValidator struct { + validators []validator.String +} + +// Description describes the validation in plain text formatting. +func (v anyWithAllWarningsValidator) Description(ctx context.Context) string { + var descriptions []string + + for _, subValidator := range v.validators { + descriptions = append(descriptions, subValidator.Description(ctx)) + } + + return fmt.Sprintf("Value must satisfy at least one of the validations: %s", strings.Join(descriptions, " + ")) +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (v anyWithAllWarningsValidator) MarkdownDescription(ctx context.Context) string { + return v.Description(ctx) +} + +// ValidateString performs the validation. +func (v anyWithAllWarningsValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) { + anyValid := false + + for _, subValidator := range v.validators { + validateResp := &validator.StringResponse{} + + subValidator.ValidateString(ctx, req, validateResp) + + if !validateResp.Diagnostics.HasError() { + anyValid = true + } + + resp.Diagnostics.Append(validateResp.Diagnostics...) + } + + if anyValid { + resp.Diagnostics = resp.Diagnostics.Warnings() + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/at_least_one_of.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/at_least_one_of.go new file mode 100644 index 000000000..4434fad2b --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/at_least_one_of.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// AtLeastOneOf checks that of a set of path.Expression, +// including the attribute this validator is applied to, +// at least one has a non-null value. +// +// This implements the validation logic declaratively within the tfsdk.Schema. +// Refer to [datasourcevalidator.AtLeastOneOf], +// [providervalidator.AtLeastOneOf], or [resourcevalidator.AtLeastOneOf] +// for declaring this type of validation outside the schema definition. +// +// Any relative path.Expression will be resolved using the attribute being +// validated. +func AtLeastOneOf(expressions ...path.Expression) validator.String { + return schemavalidator.AtLeastOneOfValidator{ + PathExpressions: expressions, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/conflicts_with.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/conflicts_with.go new file mode 100644 index 000000000..42f514539 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/conflicts_with.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// ConflictsWith checks that a set of path.Expression, +// including the attribute the validator is applied to, +// do not have a value simultaneously. +// +// This implements the validation logic declaratively within the schema. +// Refer to [datasourcevalidator.Conflicting], +// [providervalidator.Conflicting], or [resourcevalidator.Conflicting] +// for declaring this type of validation outside the schema definition. +// +// Relative path.Expression will be resolved using the attribute being +// validated. +func ConflictsWith(expressions ...path.Expression) validator.String { + return schemavalidator.ConflictsWithValidator{ + PathExpressions: expressions, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/doc.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/doc.go new file mode 100644 index 000000000..6d95e874d --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/doc.go @@ -0,0 +1,5 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package stringvalidator provides validators for types.String attributes. +package stringvalidator diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/exactly_one_of.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/exactly_one_of.go new file mode 100644 index 000000000..e3f557d3c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/exactly_one_of.go @@ -0,0 +1,28 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +// ExactlyOneOf checks that of a set of path.Expression, +// including the attribute the validator is applied to, +// one and only one attribute has a value. +// It will also cause a validation error if none are specified. +// +// This implements the validation logic declaratively within the schema. +// Refer to [datasourcevalidator.ExactlyOneOf], +// [providervalidator.ExactlyOneOf], or [resourcevalidator.ExactlyOneOf] +// for declaring this type of validation outside the schema definition. +// +// Relative path.Expression will be resolved using the attribute being +// validated. +func ExactlyOneOf(expressions ...path.Expression) validator.String { + return schemavalidator.ExactlyOneOfValidator{ + PathExpressions: expressions, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/length_at_least.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/length_at_least.go new file mode 100644 index 000000000..0ebaffae5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/length_at_least.go @@ -0,0 +1,65 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" +) + +var _ validator.String = lengthAtLeastValidator{} + +// stringLenAtLeastValidator validates that a string Attribute's length is at least a certain value. +type lengthAtLeastValidator struct { + minLength int +} + +// Description describes the validation in plain text formatting. +func (validator lengthAtLeastValidator) Description(_ context.Context) string { + return fmt.Sprintf("string length must be at least %d", validator.minLength) +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (validator lengthAtLeastValidator) MarkdownDescription(ctx context.Context) string { + return validator.Description(ctx) +} + +// Validate performs the validation. +func (v lengthAtLeastValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + value := request.ConfigValue.ValueString() + + if l := len(value); l < v.minLength { + response.Diagnostics.Append(validatordiag.InvalidAttributeValueLengthDiagnostic( + request.Path, + v.Description(ctx), + fmt.Sprintf("%d", l), + )) + + return + } +} + +// LengthAtLeast returns an validator which ensures that any configured +// attribute value is of single-byte character length greater than or equal +// to the given minimum. Null (unconfigured) and unknown (known after apply) +// values are skipped. +// +// Use UTF8LengthAtLeast for checking multiple-byte characters. +func LengthAtLeast(minLength int) validator.String { + if minLength < 0 { + return nil + } + + return lengthAtLeastValidator{ + minLength: minLength, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/length_at_most.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/length_at_most.go new file mode 100644 index 000000000..a793a0b09 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/length_at_most.go @@ -0,0 +1,64 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var _ validator.String = lengthAtMostValidator{} + +// lengthAtMostValidator validates that a string Attribute's length is at most a certain value. +type lengthAtMostValidator struct { + maxLength int +} + +// Description describes the validation in plain text formatting. +func (validator lengthAtMostValidator) Description(_ context.Context) string { + return fmt.Sprintf("string length must be at most %d", validator.maxLength) +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (validator lengthAtMostValidator) MarkdownDescription(ctx context.Context) string { + return validator.Description(ctx) +} + +// Validate performs the validation. +func (v lengthAtMostValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + value := request.ConfigValue.ValueString() + + if l := len(value); l > v.maxLength { + response.Diagnostics.Append(validatordiag.InvalidAttributeValueLengthDiagnostic( + request.Path, + v.Description(ctx), + fmt.Sprintf("%d", l), + )) + + return + } +} + +// LengthAtMost returns an validator which ensures that any configured +// attribute value is of single-byte character length less than or equal +// to the given maximum. Null (unconfigured) and unknown (known after apply) +// values are skipped. +// +// Use UTF8LengthAtMost for checking multiple-byte characters. +func LengthAtMost(maxLength int) validator.String { + if maxLength < 0 { + return nil + } + + return lengthAtMostValidator{ + maxLength: maxLength, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/length_between.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/length_between.go new file mode 100644 index 000000000..c70f4c05c --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/length_between.go @@ -0,0 +1,65 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var _ validator.String = lengthBetweenValidator{} + +// stringLenBetweenValidator validates that a string Attribute's length is in a range. +type lengthBetweenValidator struct { + minLength, maxLength int +} + +// Description describes the validation in plain text formatting. +func (validator lengthBetweenValidator) Description(_ context.Context) string { + return fmt.Sprintf("string length must be between %d and %d", validator.minLength, validator.maxLength) +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (validator lengthBetweenValidator) MarkdownDescription(ctx context.Context) string { + return validator.Description(ctx) +} + +// Validate performs the validation. +func (v lengthBetweenValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + value := request.ConfigValue.ValueString() + + if l := len(value); l < v.minLength || l > v.maxLength { + response.Diagnostics.Append(validatordiag.InvalidAttributeValueLengthDiagnostic( + request.Path, + v.Description(ctx), + fmt.Sprintf("%d", l), + )) + + return + } +} + +// LengthBetween returns a validator which ensures that any configured +// attribute value is of single-byte character length greater than or equal +// to the given minimum and less than or equal to the given maximum. Null +// (unconfigured) and unknown (known after apply) values are skipped. +// +// Use UTF8LengthBetween for checking multiple-byte characters. +func LengthBetween(minLength, maxLength int) validator.String { + if minLength < 0 || minLength > maxLength { + return nil + } + + return lengthBetweenValidator{ + minLength: minLength, + maxLength: maxLength, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/none_of.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/none_of.go new file mode 100644 index 000000000..6bf7dce88 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/none_of.go @@ -0,0 +1,65 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" +) + +var _ validator.String = noneOfValidator{} + +// noneOfValidator validates that the value does not match one of the values. +type noneOfValidator struct { + values []types.String +} + +func (v noneOfValidator) Description(ctx context.Context) string { + return v.MarkdownDescription(ctx) +} + +func (v noneOfValidator) MarkdownDescription(_ context.Context) string { + return fmt.Sprintf("value must be none of: %s", v.values) +} + +func (v noneOfValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + value := request.ConfigValue + + for _, otherValue := range v.values { + if !value.Equal(otherValue) { + continue + } + + response.Diagnostics.Append(validatordiag.InvalidAttributeValueMatchDiagnostic( + request.Path, + v.Description(ctx), + value.String(), + )) + + break + } +} + +// NoneOf checks that the String held in the attribute +// is none of the given `values`. +func NoneOf(values ...string) validator.String { + frameworkValues := make([]types.String, 0, len(values)) + + for _, value := range values { + frameworkValues = append(frameworkValues, types.StringValue(value)) + } + + return noneOfValidator{ + values: frameworkValues, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/none_of_case_insensitive.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/none_of_case_insensitive.go new file mode 100644 index 000000000..aedb0949a --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/none_of_case_insensitive.go @@ -0,0 +1,64 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" +) + +var _ validator.String = noneOfCaseInsensitiveValidator{} + +// noneOfCaseInsensitiveValidator validates that the value matches one of expected values. +type noneOfCaseInsensitiveValidator struct { + values []types.String +} + +func (v noneOfCaseInsensitiveValidator) Description(ctx context.Context) string { + return v.MarkdownDescription(ctx) +} + +func (v noneOfCaseInsensitiveValidator) MarkdownDescription(_ context.Context) string { + return fmt.Sprintf("value must be none of: %s", v.values) +} + +func (v noneOfCaseInsensitiveValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + value := request.ConfigValue + + for _, otherValue := range v.values { + if strings.EqualFold(value.ValueString(), otherValue.ValueString()) { + response.Diagnostics.Append(validatordiag.InvalidAttributeValueMatchDiagnostic( + request.Path, + v.Description(ctx), + value.String(), + )) + + return + } + } +} + +// NoneOfCaseInsensitive checks that the String held in the attribute +// is none of the given `values`. +func NoneOfCaseInsensitive(values ...string) validator.String { + frameworkValues := make([]types.String, 0, len(values)) + + for _, value := range values { + frameworkValues = append(frameworkValues, types.StringValue(value)) + } + + return noneOfCaseInsensitiveValidator{ + values: frameworkValues, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/one_of.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/one_of.go new file mode 100644 index 000000000..c3ae055bd --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/one_of.go @@ -0,0 +1,63 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" +) + +var _ validator.String = oneOfValidator{} + +// oneOfValidator validates that the value matches one of expected values. +type oneOfValidator struct { + values []types.String +} + +func (v oneOfValidator) Description(ctx context.Context) string { + return v.MarkdownDescription(ctx) +} + +func (v oneOfValidator) MarkdownDescription(_ context.Context) string { + return fmt.Sprintf("value must be one of: %s", v.values) +} + +func (v oneOfValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + value := request.ConfigValue + + for _, otherValue := range v.values { + if value.Equal(otherValue) { + return + } + } + + response.Diagnostics.Append(validatordiag.InvalidAttributeValueMatchDiagnostic( + request.Path, + v.Description(ctx), + value.String(), + )) +} + +// OneOf checks that the String held in the attribute +// is one of the given `values`. +func OneOf(values ...string) validator.String { + frameworkValues := make([]types.String, 0, len(values)) + + for _, value := range values { + frameworkValues = append(frameworkValues, types.StringValue(value)) + } + + return oneOfValidator{ + values: frameworkValues, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/one_of_case_insensitive.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/one_of_case_insensitive.go new file mode 100644 index 000000000..7e5912ab7 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/one_of_case_insensitive.go @@ -0,0 +1,64 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" +) + +var _ validator.String = oneOfCaseInsensitiveValidator{} + +// oneOfCaseInsensitiveValidator validates that the value matches one of expected values. +type oneOfCaseInsensitiveValidator struct { + values []types.String +} + +func (v oneOfCaseInsensitiveValidator) Description(ctx context.Context) string { + return v.MarkdownDescription(ctx) +} + +func (v oneOfCaseInsensitiveValidator) MarkdownDescription(_ context.Context) string { + return fmt.Sprintf("value must be one of: %s", v.values) +} + +func (v oneOfCaseInsensitiveValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + value := request.ConfigValue + + for _, otherValue := range v.values { + if strings.EqualFold(value.ValueString(), otherValue.ValueString()) { + return + } + } + + response.Diagnostics.Append(validatordiag.InvalidAttributeValueMatchDiagnostic( + request.Path, + v.Description(ctx), + value.String(), + )) +} + +// OneOfCaseInsensitive checks that the String held in the attribute +// is one of the given `values`. +func OneOfCaseInsensitive(values ...string) validator.String { + frameworkValues := make([]types.String, 0, len(values)) + + for _, value := range values { + frameworkValues = append(frameworkValues, types.StringValue(value)) + } + + return oneOfCaseInsensitiveValidator{ + values: frameworkValues, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/regex_matches.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/regex_matches.go new file mode 100644 index 000000000..4cab99757 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/regex_matches.go @@ -0,0 +1,67 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + "regexp" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var _ validator.String = regexMatchesValidator{} + +// regexMatchesValidator validates that a string Attribute's value matches the specified regular expression. +type regexMatchesValidator struct { + regexp *regexp.Regexp + message string +} + +// Description describes the validation in plain text formatting. +func (validator regexMatchesValidator) Description(_ context.Context) string { + if validator.message != "" { + return validator.message + } + return fmt.Sprintf("value must match regular expression '%s'", validator.regexp) +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (validator regexMatchesValidator) MarkdownDescription(ctx context.Context) string { + return validator.Description(ctx) +} + +// Validate performs the validation. +func (v regexMatchesValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + value := request.ConfigValue.ValueString() + + if !v.regexp.MatchString(value) { + response.Diagnostics.Append(validatordiag.InvalidAttributeValueMatchDiagnostic( + request.Path, + v.Description(ctx), + value, + )) + } +} + +// RegexMatches returns an AttributeValidator which ensures that any configured +// attribute value: +// +// - Is a string. +// - Matches the given regular expression https://github.com/google/re2/wiki/Syntax. +// +// Null (unconfigured) and unknown (known after apply) values are skipped. +// Optionally an error message can be provided to return something friendlier +// than "value must match regular expression 'regexp'". +func RegexMatches(regexp *regexp.Regexp, message string) validator.String { + return regexMatchesValidator{ + regexp: regexp, + message: message, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/utf8_length_at_least.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/utf8_length_at_least.go new file mode 100644 index 000000000..6159eab57 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/utf8_length_at_least.go @@ -0,0 +1,68 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + "unicode/utf8" + + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" +) + +var _ validator.String = utf8LengthAtLeastValidator{} + +// utf8LengthAtLeastValidator implements the validator. +type utf8LengthAtLeastValidator struct { + minLength int +} + +// Description describes the validation in plain text formatting. +func (validator utf8LengthAtLeastValidator) Description(_ context.Context) string { + return fmt.Sprintf("UTF-8 character count must be at least %d", validator.minLength) +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (validator utf8LengthAtLeastValidator) MarkdownDescription(ctx context.Context) string { + return validator.Description(ctx) +} + +// Validate performs the validation. +func (v utf8LengthAtLeastValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + value := request.ConfigValue.ValueString() + + count := utf8.RuneCountInString(value) + + if count < v.minLength { + response.Diagnostics.Append(validatordiag.InvalidAttributeValueLengthDiagnostic( + request.Path, + v.Description(ctx), + fmt.Sprintf("%d", count), + )) + + return + } +} + +// UTF8LengthAtLeast returns an validator which ensures that any configured +// attribute value is of UTF-8 character count greater than or equal to the +// given minimum. Null (unconfigured) and unknown (known after apply) values +// are skipped. +// +// Use LengthAtLeast for checking single-byte character counts. +func UTF8LengthAtLeast(minLength int) validator.String { + if minLength < 0 { + return nil + } + + return utf8LengthAtLeastValidator{ + minLength: minLength, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/utf8_length_at_most.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/utf8_length_at_most.go new file mode 100644 index 000000000..1653d5f88 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/utf8_length_at_most.go @@ -0,0 +1,68 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + "unicode/utf8" + + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" +) + +var _ validator.String = utf8LengthAtMostValidator{} + +// utf8LengthAtMostValidator implements the validator. +type utf8LengthAtMostValidator struct { + maxLength int +} + +// Description describes the validation in plain text formatting. +func (validator utf8LengthAtMostValidator) Description(_ context.Context) string { + return fmt.Sprintf("UTF-8 character count must be at most %d", validator.maxLength) +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (validator utf8LengthAtMostValidator) MarkdownDescription(ctx context.Context) string { + return validator.Description(ctx) +} + +// Validate performs the validation. +func (v utf8LengthAtMostValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + value := request.ConfigValue.ValueString() + + count := utf8.RuneCountInString(value) + + if count > v.maxLength { + response.Diagnostics.Append(validatordiag.InvalidAttributeValueLengthDiagnostic( + request.Path, + v.Description(ctx), + fmt.Sprintf("%d", count), + )) + + return + } +} + +// UTF8LengthAtMost returns an validator which ensures that any configured +// attribute value is of UTF-8 character count less than or equal to the +// given maximum. Null (unconfigured) and unknown (known after apply) values +// are skipped. +// +// Use LengthAtMost for checking single-byte character counts. +func UTF8LengthAtMost(maxLength int) validator.String { + if maxLength < 0 { + return nil + } + + return utf8LengthAtMostValidator{ + maxLength: maxLength, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/utf8_length_between.go b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/utf8_length_between.go new file mode 100644 index 000000000..791b9a569 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator/utf8_length_between.go @@ -0,0 +1,70 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package stringvalidator + +import ( + "context" + "fmt" + "unicode/utf8" + + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + + "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" +) + +var _ validator.String = utf8LengthBetweenValidator{} + +// utf8LengthBetweenValidator implements the validator. +type utf8LengthBetweenValidator struct { + maxLength int + minLength int +} + +// Description describes the validation in plain text formatting. +func (v utf8LengthBetweenValidator) Description(_ context.Context) string { + return fmt.Sprintf("UTF-8 character count must be between %d and %d", v.minLength, v.maxLength) +} + +// MarkdownDescription describes the validation in Markdown formatting. +func (v utf8LengthBetweenValidator) MarkdownDescription(ctx context.Context) string { + return v.Description(ctx) +} + +// Validate performs the validation. +func (v utf8LengthBetweenValidator) ValidateString(ctx context.Context, request validator.StringRequest, response *validator.StringResponse) { + if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() { + return + } + + value := request.ConfigValue.ValueString() + + count := utf8.RuneCountInString(value) + + if count < v.minLength || count > v.maxLength { + response.Diagnostics.Append(validatordiag.InvalidAttributeValueLengthDiagnostic( + request.Path, + v.Description(ctx), + fmt.Sprintf("%d", count), + )) + + return + } +} + +// UTF8LengthBetween returns an validator which ensures that any configured +// attribute value is of UTF-8 character count greater than or equal to the +// given minimum and less than or equal to the given maximum. Null +// (unconfigured) and unknown (known after apply) values are skipped. +// +// Use LengthBetween for checking single-byte character counts. +func UTF8LengthBetween(minLength int, maxLength int) validator.String { + if minLength < 0 || maxLength < 0 || minLength > maxLength { + return nil + } + + return utf8LengthBetweenValidator{ + maxLength: maxLength, + minLength: minLength, + } +} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest/random.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest/random.go deleted file mode 100644 index c26303eb6..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest/random.go +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package acctest - -import ( - "bytes" - crand "crypto/rand" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/pem" - "fmt" - "math/big" - "math/rand" - "net/netip" - "strings" - "time" - - "golang.org/x/crypto/ssh" -) - -// Helpers for generating random tidbits for use in identifiers to prevent -// collisions in acceptance tests. - -// RandInt generates a random integer -func RandInt() int { - return rand.Int() -} - -// RandomWithPrefix is used to generate a unique name with a prefix, for -// randomizing names in acceptance tests -func RandomWithPrefix(name string) string { - return fmt.Sprintf("%s-%d", name, RandInt()) -} - -// RandIntRange returns a random integer between min (inclusive) and max (exclusive) -func RandIntRange(min int, max int) int { - return rand.Intn(max-min) + min -} - -// RandString generates a random alphanumeric string of the length specified -func RandString(strlen int) string { - return RandStringFromCharSet(strlen, CharSetAlphaNum) -} - -// RandStringFromCharSet generates a random string by selecting characters from -// the charset provided -func RandStringFromCharSet(strlen int, charSet string) string { - result := make([]byte, strlen) - for i := 0; i < strlen; i++ { - result[i] = charSet[RandIntRange(0, len(charSet))] - } - return string(result) -} - -// RandSSHKeyPair generates a random public and private SSH key pair. -// -// The public key is returned in OpenSSH authorized key format, for example: -// -// ssh-rsa XXX comment -// -// The private key is RSA algorithm, 1024 bits, PEM encoded, and has no -// passphrase. Testing with different or stricter security requirements should -// use the standard library [crypto] and [golang.org/x/crypto/ssh] packages -// directly. -func RandSSHKeyPair(comment string) (string, string, error) { - privateKey, privateKeyPEM, err := genPrivateKey() - if err != nil { - return "", "", err - } - - publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey) - if err != nil { - return "", "", err - } - keyMaterial := strings.TrimSpace(string(ssh.MarshalAuthorizedKey(publicKey))) - return fmt.Sprintf("%s %s", keyMaterial, comment), privateKeyPEM, nil -} - -// RandTLSCert generates a self-signed TLS certificate with a newly created -// private key, and returns both the cert and the private key PEM encoded. -// -// The private key uses RSA algorithm, 1024 bits, and has no passphrase. -// -// The certificate expires in 24 hours, has a random serial number, and is -// set for Encipherment, Digital Signature, and Server Auth key usage. -// Only the organization name of the subject is configurable. -// -// Testing with different or stricter security requirements should -// use the standard library [crypto] and [golang.org/x/crypto] packages -// directly. -func RandTLSCert(orgName string) (string, string, error) { - template := &x509.Certificate{ - SerialNumber: big.NewInt(int64(RandInt())), - Subject: pkix.Name{ - Organization: []string{orgName}, - }, - NotBefore: time.Now(), - NotAfter: time.Now().Add(24 * time.Hour), - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, - BasicConstraintsValid: true, - } - - privateKey, privateKeyPEM, err := genPrivateKey() - if err != nil { - return "", "", err - } - - cert, err := x509.CreateCertificate(crand.Reader, template, template, &privateKey.PublicKey, privateKey) - if err != nil { - return "", "", err - } - - certPEM, err := pemEncode(cert, "CERTIFICATE") - if err != nil { - return "", "", err - } - - return certPEM, privateKeyPEM, nil -} - -// RandIpAddress returns a random IP address in the specified CIDR block. -// The prefix length must be less than 31. -func RandIpAddress(s string) (string, error) { - prefix, err := netip.ParsePrefix(s) - - if err != nil { - return "", err - } - - if prefix.IsSingleIP() { - return prefix.Addr().String(), nil - } - - prefixSizeExponent := uint(prefix.Addr().BitLen() - prefix.Bits()) - - if prefix.Addr().Is4() && prefixSizeExponent > 31 { - return "", fmt.Errorf("CIDR range is too large: %d", prefixSizeExponent) - } - - // Prevent panics with rand.Int63n(). - if prefix.Addr().Is6() && prefixSizeExponent > 63 { - return "", fmt.Errorf("CIDR range is too large: %d", prefixSizeExponent) - } - - // Calculate max random integer based on the prefix. - // Bit shift 1< 0 { - return fmt.Errorf("Modules are not supported. Found %d modules.", - len(sm.ChildModules)) - } - return nil -} - -func shimResourceStateKey(res *tfjson.StateResource) (string, error) { - if res.Index == nil { - return res.Address, nil - } - - var mode terraform.ResourceMode - switch res.Mode { - case tfjson.DataResourceMode: - mode = terraform.DataResourceMode - case tfjson.ManagedResourceMode: - mode = terraform.ManagedResourceMode - default: - return "", fmt.Errorf("unexpected resource mode for %q", res.Address) - } - - var index int - switch idx := res.Index.(type) { - case json.Number: - i, err := idx.Int64() - if err != nil { - return "", fmt.Errorf("unexpected index value (%q) for %q, ", - idx, res.Address) - } - index = int(i) - default: - return "", fmt.Errorf("unexpected index type (%T) for %q, "+ - "for_each is not supported", res.Index, res.Address) - } - - rsk := &terraform.ResourceStateKey{ - Mode: mode, - Type: res.Type, - Name: res.Name, - Index: index, - } - - return rsk.String(), nil -} - -func shimResourceState(res *tfjson.StateResource) (*terraform.ResourceState, error) { - sf := &shimmedFlatmap{} - err := sf.FromMap(res.AttributeValues) - if err != nil { - return nil, err - } - attributes := sf.Flatmap() - - if _, ok := attributes["id"]; !ok { - return nil, fmt.Errorf("no %q found in attributes", "id") - } - - return &terraform.ResourceState{ - Provider: res.ProviderName, - Type: res.Type, - Primary: &terraform.InstanceState{ - ID: attributes["id"], - Attributes: attributes, - Meta: map[string]interface{}{ - "schema_version": int(res.SchemaVersion), - }, - Tainted: res.Tainted, - }, - Dependencies: res.DependsOn, - }, nil -} - -type shimmedFlatmap struct { - m map[string]string -} - -func (sf *shimmedFlatmap) FromMap(attributes map[string]interface{}) error { - if sf.m == nil { - sf.m = make(map[string]string, len(attributes)) - } - - return sf.AddMap("", attributes) -} - -func (sf *shimmedFlatmap) AddMap(prefix string, m map[string]interface{}) error { - for key, value := range m { - k := key - if prefix != "" { - k = fmt.Sprintf("%s.%s", prefix, key) - } - - err := sf.AddEntry(k, value) - if err != nil { - return fmt.Errorf("unable to add map key %q entry: %w", k, err) - } - } - - mapLength := "%" - if prefix != "" { - mapLength = fmt.Sprintf("%s.%s", prefix, "%") - } - - if err := sf.AddEntry(mapLength, strconv.Itoa(len(m))); err != nil { - return fmt.Errorf("unable to add map length %q entry: %w", mapLength, err) - } - - return nil -} - -func (sf *shimmedFlatmap) AddSlice(name string, elements []interface{}) error { - for i, elem := range elements { - key := fmt.Sprintf("%s.%d", name, i) - err := sf.AddEntry(key, elem) - if err != nil { - return fmt.Errorf("unable to add slice key %q entry: %w", key, err) - } - } - - sliceLength := fmt.Sprintf("%s.#", name) - if err := sf.AddEntry(sliceLength, strconv.Itoa(len(elements))); err != nil { - return fmt.Errorf("unable to add slice length %q entry: %w", sliceLength, err) - } - - return nil -} - -func (sf *shimmedFlatmap) AddEntry(key string, value interface{}) error { - switch el := value.(type) { - case nil: - // omit the entry - return nil - case bool: - sf.m[key] = strconv.FormatBool(el) - case json.Number: - sf.m[key] = el.String() - case string: - sf.m[key] = el - case map[string]interface{}: - err := sf.AddMap(key, el) - if err != nil { - return err - } - case []interface{}: - err := sf.AddSlice(key, el) - if err != nil { - return err - } - default: - // This should never happen unless terraform-json - // changes how attributes (types) are represented. - // - // We handle all types which the JSON unmarshaler - // can possibly produce - // https://golang.org/pkg/encoding/json/#Unmarshal - - return fmt.Errorf("%q: unexpected type (%T)", key, el) - } - return nil -} - -func (sf *shimmedFlatmap) Flatmap() map[string]string { - return sf.m -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testcase_providers.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testcase_providers.go deleted file mode 100644 index 9639cb04d..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testcase_providers.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resource - -import ( - "context" - "fmt" - "strings" -) - -// providerConfig takes the list of providers in a TestCase and returns a -// config with only empty provider blocks. This is useful for Import, where no -// config is provided, but the providers must be defined. -func (c TestCase) providerConfig(_ context.Context, skipProviderBlock bool) string { - var providerBlocks, requiredProviderBlocks strings.Builder - - // [BF] The Providers field handling predates the logic being moved to this - // method. It's not entirely clear to me at this time why this field - // is being used and not the others, but leaving it here just in case - // it does have a special purpose that wasn't being unit tested prior. - for name := range c.Providers { - providerBlocks.WriteString(fmt.Sprintf("provider %q {}\n", name)) - } - - for name, externalProvider := range c.ExternalProviders { - if !skipProviderBlock { - providerBlocks.WriteString(fmt.Sprintf("provider %q {}\n", name)) - } - - if externalProvider.Source == "" && externalProvider.VersionConstraint == "" { - continue - } - - requiredProviderBlocks.WriteString(fmt.Sprintf(" %s = {\n", name)) - - if externalProvider.Source != "" { - requiredProviderBlocks.WriteString(fmt.Sprintf(" source = %q\n", externalProvider.Source)) - } - - if externalProvider.VersionConstraint != "" { - requiredProviderBlocks.WriteString(fmt.Sprintf(" version = %q\n", externalProvider.VersionConstraint)) - } - - requiredProviderBlocks.WriteString(" }\n") - } - - if requiredProviderBlocks.Len() > 0 { - return fmt.Sprintf(` -terraform { - required_providers { -%[1]s - } -} - -%[2]s -`, strings.TrimSuffix(requiredProviderBlocks.String(), "\n"), providerBlocks.String()) - } - - return providerBlocks.String() -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testcase_validate.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testcase_validate.go deleted file mode 100644 index 8eb85a14a..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testcase_validate.go +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resource - -import ( - "context" - "fmt" - - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging" -) - -// hasProviders returns true if the TestCase has set any of the -// ExternalProviders, ProtoV5ProviderFactories, ProtoV6ProviderFactories, -// ProviderFactories, or Providers fields. -func (c TestCase) hasProviders(_ context.Context) bool { - if len(c.ExternalProviders) > 0 { - return true - } - - if len(c.ProtoV5ProviderFactories) > 0 { - return true - } - - if len(c.ProtoV6ProviderFactories) > 0 { - return true - } - - if len(c.ProviderFactories) > 0 { - return true - } - - if len(c.Providers) > 0 { - return true - } - - return false -} - -// validate ensures the TestCase is valid based on the following criteria: -// -// - No overlapping ExternalProviders and Providers entries -// - No overlapping ExternalProviders and ProviderFactories entries -// - TestStep validations performed by the (TestStep).validate() method. -func (c TestCase) validate(ctx context.Context) error { - logging.HelperResourceTrace(ctx, "Validating TestCase") - - if len(c.Steps) == 0 { - err := fmt.Errorf("TestCase missing Steps") - logging.HelperResourceError(ctx, "TestCase validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - - for name := range c.ExternalProviders { - if _, ok := c.Providers[name]; ok { - err := fmt.Errorf("TestCase provider %q set in both ExternalProviders and Providers", name) - logging.HelperResourceError(ctx, "TestCase validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - - if _, ok := c.ProviderFactories[name]; ok { - err := fmt.Errorf("TestCase provider %q set in both ExternalProviders and ProviderFactories", name) - logging.HelperResourceError(ctx, "TestCase validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - } - - testCaseHasProviders := c.hasProviders(ctx) - - for stepIndex, step := range c.Steps { - stepNumber := stepIndex + 1 // Use 1-based index for humans - stepValidateReq := testStepValidateRequest{ - StepNumber: stepNumber, - TestCaseHasProviders: testCaseHasProviders, - } - - err := step.validate(ctx, stepValidateReq) - - if err != nil { - err := fmt.Errorf("TestStep %d/%d validation error: %w", stepNumber, len(c.Steps), err) - logging.HelperResourceError(ctx, "TestCase validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - } - - return nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing.go deleted file mode 100644 index 9bde8e22a..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing.go +++ /dev/null @@ -1,1524 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resource - -import ( - "context" - "errors" - "flag" - "fmt" - "log" - "os" - "regexp" - "strconv" - "strings" - "time" - - "github.com/mitchellh/go-testing-interface" - - "github.com/hashicorp/terraform-plugin-go/tfprotov5" - "github.com/hashicorp/terraform-plugin-go/tfprotov6" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/addrs" - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging" - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -// flagSweep is a flag available when running tests on the command line. It -// contains a comma seperated list of regions to for the sweeper functions to -// run in. This flag bypasses the normal Test path and instead runs functions designed to -// clean up any leaked resources a testing environment could have created. It is -// a best effort attempt, and relies on Provider authors to implement "Sweeper" -// methods for resources. - -// Adding Sweeper methods with AddTestSweepers will -// construct a list of sweeper funcs to be called here. We iterate through -// regions provided by the sweep flag, and for each region we iterate through the -// tests, and exit on any errors. At time of writing, sweepers are ran -// sequentially, however they can list dependencies to be ran first. We track -// the sweepers that have been ran, so as to not run a sweeper twice for a given -// region. -// -// WARNING: -// Sweepers are designed to be destructive. You should not use the -sweep flag -// in any environment that is not strictly a test environment. Resources will be -// destroyed. - -var flagSweep = flag.String("sweep", "", "List of Regions to run available Sweepers") -var flagSweepAllowFailures = flag.Bool("sweep-allow-failures", false, "Enable to allow Sweeper Tests to continue after failures") -var flagSweepRun = flag.String("sweep-run", "", "Comma seperated list of Sweeper Tests to run") -var sweeperFuncs map[string]*Sweeper - -// SweeperFunc is a signature for a function that acts as a sweeper. It -// accepts a string for the region that the sweeper is to be ran in. This -// function must be able to construct a valid client for that region. -type SweeperFunc func(r string) error - -type Sweeper struct { - // Name for sweeper. Must be unique to be ran by the Sweeper Runner - Name string - - // Dependencies list the const names of other Sweeper functions that must be ran - // prior to running this Sweeper. This is an ordered list that will be invoked - // recursively at the helper/resource level - Dependencies []string - - // Sweeper function that when invoked sweeps the Provider of specific - // resources - F SweeperFunc -} - -func init() { - sweeperFuncs = make(map[string]*Sweeper) -} - -// AddTestSweepers function adds a given name and Sweeper configuration -// pair to the internal sweeperFuncs map. Invoke this function to register a -// resource sweeper to be available for running when the -sweep flag is used -// with `go test`. Sweeper names must be unique to help ensure a given sweeper -// is only ran once per run. -func AddTestSweepers(name string, s *Sweeper) { - if _, ok := sweeperFuncs[name]; ok { - log.Fatalf("[ERR] Error adding (%s) to sweeperFuncs: function already exists in map", name) - } - - sweeperFuncs[name] = s -} - -// TestMain adds sweeper functionality to the "go test" command, otherwise -// tests are executed as normal. Most provider acceptance tests are written -// using the Test() function of this package, which imposes its own -// requirements and Terraform CLI behavior. Refer to that function's -// documentation for additional details. -// -// Sweepers enable infrastructure cleanup functions to be included with -// resource definitions, typically so developers can remove all resources of -// that resource type from testing infrastructure in case of failures that -// prevented the normal resource destruction behavior of acceptance tests. -// Use the AddTestSweepers() function to configure available sweepers. -// -// Sweeper flags added to the "go test" command: -// -// -sweep: Comma-separated list of locations/regions to run available sweepers. -// -sweep-allow-failues: Enable to allow other sweepers to run after failures. -// -sweep-run: Comma-separated list of resource type sweepers to run. Defaults -// to all sweepers. -// -// Refer to the Env prefixed constants for environment variables that further -// control testing functionality. -func TestMain(m interface { - Run() int -}) { - flag.Parse() - if *flagSweep != "" { - // parse flagSweep contents for regions to run - regions := strings.Split(*flagSweep, ",") - - // get filtered list of sweepers to run based on sweep-run flag - sweepers := filterSweepers(*flagSweepRun, sweeperFuncs) - - if _, err := runSweepers(regions, sweepers, *flagSweepAllowFailures); err != nil { - os.Exit(1) - } - } else { - exitCode := m.Run() - os.Exit(exitCode) - } -} - -func runSweepers(regions []string, sweepers map[string]*Sweeper, allowFailures bool) (map[string]map[string]error, error) { - var sweeperErrorFound bool - sweeperRunList := make(map[string]map[string]error) - - for _, region := range regions { - region = strings.TrimSpace(region) - - var regionSweeperErrorFound bool - regionSweeperRunList := make(map[string]error) - - start := time.Now() - log.Printf("[DEBUG] Running Sweepers for region (%s):\n", region) - for _, sweeper := range sweepers { - if err := runSweeperWithRegion(region, sweeper, sweepers, regionSweeperRunList, allowFailures); err != nil { - if allowFailures { - continue - } - - sweeperRunList[region] = regionSweeperRunList - return sweeperRunList, fmt.Errorf("sweeper (%s) for region (%s) failed: %s", sweeper.Name, region, err) - } - } - elapsed := time.Since(start) - log.Printf("Completed Sweepers for region (%s) in %s", region, elapsed) - - log.Printf("Sweeper Tests for region (%s) ran successfully:\n", region) - for sweeper, sweeperErr := range regionSweeperRunList { - if sweeperErr == nil { - fmt.Printf("\t- %s\n", sweeper) - } else { - regionSweeperErrorFound = true - } - } - - if regionSweeperErrorFound { - sweeperErrorFound = true - log.Printf("Sweeper Tests for region (%s) ran unsuccessfully:\n", region) - for sweeper, sweeperErr := range regionSweeperRunList { - if sweeperErr != nil { - fmt.Printf("\t- %s: %s\n", sweeper, sweeperErr) - } - } - } - - sweeperRunList[region] = regionSweeperRunList - } - - if sweeperErrorFound { - return sweeperRunList, errors.New("at least one sweeper failed") - } - - return sweeperRunList, nil -} - -// filterSweepers takes a comma seperated string listing the names of sweepers -// to be ran, and returns a filtered set from the list of all of sweepers to -// run based on the names given. -func filterSweepers(f string, source map[string]*Sweeper) map[string]*Sweeper { - filterSlice := strings.Split(strings.ToLower(f), ",") - if len(filterSlice) == 1 && filterSlice[0] == "" { - // if the filter slice is a single element of "" then no sweeper list was - // given, so just return the full list - return source - } - - sweepers := make(map[string]*Sweeper) - for name := range source { - for _, s := range filterSlice { - if strings.Contains(strings.ToLower(name), s) { - for foundName, foundSweeper := range filterSweeperWithDependencies(name, source) { - sweepers[foundName] = foundSweeper - } - } - } - } - return sweepers -} - -// filterSweeperWithDependencies recursively returns sweeper and all dependencies. -// Since filterSweepers performs fuzzy matching, this function is used -// to perform exact sweeper and dependency lookup. -func filterSweeperWithDependencies(name string, source map[string]*Sweeper) map[string]*Sweeper { - result := make(map[string]*Sweeper) - - currentSweeper, ok := source[name] - if !ok { - log.Printf("[WARN] Sweeper has dependency (%s), but that sweeper was not found", name) - return result - } - - result[name] = currentSweeper - - for _, dependency := range currentSweeper.Dependencies { - for foundName, foundSweeper := range filterSweeperWithDependencies(dependency, source) { - result[foundName] = foundSweeper - } - } - - return result -} - -// runSweeperWithRegion recieves a sweeper and a region, and recursively calls -// itself with that region for every dependency found for that sweeper. If there -// are no dependencies, invoke the contained sweeper fun with the region, and -// add the success/fail status to the sweeperRunList. -func runSweeperWithRegion(region string, s *Sweeper, sweepers map[string]*Sweeper, sweeperRunList map[string]error, allowFailures bool) error { - for _, dep := range s.Dependencies { - depSweeper, ok := sweepers[dep] - - if !ok { - log.Printf("[ERROR] Sweeper (%s) has dependency (%s), but that sweeper was not found", s.Name, dep) - return fmt.Errorf("sweeper (%s) has dependency (%s), but that sweeper was not found", s.Name, dep) - } - - log.Printf("[DEBUG] Sweeper (%s) has dependency (%s), running..", s.Name, dep) - err := runSweeperWithRegion(region, depSweeper, sweepers, sweeperRunList, allowFailures) - - if err != nil { - if allowFailures { - log.Printf("[ERROR] Error running Sweeper (%s) in region (%s): %s", depSweeper.Name, region, err) - continue - } - - return err - } - } - - if _, ok := sweeperRunList[s.Name]; ok { - log.Printf("[DEBUG] Sweeper (%s) already ran in region (%s)", s.Name, region) - return nil - } - - log.Printf("[DEBUG] Running Sweeper (%s) in region (%s)", s.Name, region) - - start := time.Now() - runE := s.F(region) - elapsed := time.Since(start) - - log.Printf("[DEBUG] Completed Sweeper (%s) in region (%s) in %s", s.Name, region, elapsed) - - sweeperRunList[s.Name] = runE - - if runE != nil { - log.Printf("[ERROR] Error running Sweeper (%s) in region (%s): %s", s.Name, region, runE) - } - - return runE -} - -// Deprecated: Use EnvTfAcc instead. -const TestEnvVar = EnvTfAcc - -// TestCheckFunc is the callback type used with acceptance tests to check -// the state of a resource. The state passed in is the latest state known, -// or in the case of being after a destroy, it is the last known state when -// it was created. -type TestCheckFunc func(*terraform.State) error - -// ImportStateCheckFunc is the check function for ImportState tests -type ImportStateCheckFunc func([]*terraform.InstanceState) error - -// ImportStateIdFunc is an ID generation function to help with complex ID -// generation for ImportState tests. -type ImportStateIdFunc func(*terraform.State) (string, error) - -// ErrorCheckFunc is a function providers can use to handle errors. -type ErrorCheckFunc func(error) error - -// TestCase is a single acceptance test case used to test the apply/destroy -// lifecycle of a resource in a specific configuration. -// -// When the destroy plan is executed, the config from the last TestStep -// is used to plan it. -// -// Refer to the Env prefixed constants for environment variables that further -// control testing functionality. -type TestCase struct { - // IsUnitTest allows a test to run regardless of the TF_ACC - // environment variable. This should be used with care - only for - // fast tests on local resources (e.g. remote state with a local - // backend) but can be used to increase confidence in correct - // operation of Terraform without waiting for a full acctest run. - IsUnitTest bool - - // PreCheck, if non-nil, will be called before any test steps are - // executed. It will only be executed in the case that the steps - // would run, so it can be used for some validation before running - // acceptance tests, such as verifying that keys are setup. - PreCheck func() - - // ProviderFactories can be specified for the providers that are valid. - // - // This can also be specified at the TestStep level to enable per-step - // differences in providers, however all provider specifications must - // be done either at the TestCase level or TestStep level, otherwise the - // testing framework will raise an error and fail the test. - // - // These are the providers that can be referenced within the test. Each key - // is an individually addressable provider. Typically you will only pass a - // single value here for the provider you are testing. Aliases are not - // supported by the test framework, so to use multiple provider instances, - // you should add additional copies to this map with unique names. To set - // their configuration, you would reference them similar to the following: - // - // provider "my_factory_key" { - // # ... - // } - // - // resource "my_resource" "mr" { - // provider = my_factory_key - // - // # ... - // } - ProviderFactories map[string]func() (*schema.Provider, error) - - // ProtoV5ProviderFactories serves the same purpose as ProviderFactories, - // but for protocol v5 providers defined using the terraform-plugin-go - // ProviderServer interface. - // - // This can also be specified at the TestStep level to enable per-step - // differences in providers, however all provider specifications must - // be done either at the TestCase level or TestStep level, otherwise the - // testing framework will raise an error and fail the test. - ProtoV5ProviderFactories map[string]func() (tfprotov5.ProviderServer, error) - - // ProtoV6ProviderFactories serves the same purpose as ProviderFactories, - // but for protocol v6 providers defined using the terraform-plugin-go - // ProviderServer interface. - // The version of Terraform used in acceptance testing must be greater - // than or equal to v0.15.4 to use ProtoV6ProviderFactories. - // - // This can also be specified at the TestStep level to enable per-step - // differences in providers, however all provider specifications must - // be done either at the TestCase level or TestStep level, otherwise the - // testing framework will raise an error and fail the test. - ProtoV6ProviderFactories map[string]func() (tfprotov6.ProviderServer, error) - - // Providers is the ResourceProvider that will be under test. - // - // Deprecated: Providers is deprecated, please use ProviderFactories - Providers map[string]*schema.Provider - - // ExternalProviders are providers the TestCase relies on that should - // be downloaded from the registry during init. - // - // This can also be specified at the TestStep level to enable per-step - // differences in providers, however all provider specifications must - // be done either at the TestCase level or TestStep level, otherwise the - // testing framework will raise an error and fail the test. - // - // This is generally unnecessary to set at the TestCase level, however - // it has existing in the testing framework prior to the introduction of - // TestStep level specification and was only necessary for performing - // import testing where the configuration contained a provider outside the - // one under test. - ExternalProviders map[string]ExternalProvider - - // PreventPostDestroyRefresh can be set to true for cases where data sources - // are tested alongside real resources - PreventPostDestroyRefresh bool - - // CheckDestroy is called after the resource is finally destroyed - // to allow the tester to test that the resource is truly gone. - CheckDestroy TestCheckFunc - - // ErrorCheck allows providers the option to handle errors such as skipping - // tests based on certain errors. - ErrorCheck ErrorCheckFunc - - // Steps are the apply sequences done within the context of the - // same state. Each step can have its own check to verify correctness. - Steps []TestStep - - // IDRefreshName is the name of the resource to check during ID-only - // refresh testing, which ensures that a resource can be refreshed solely - // by its identifier. This will default to the first non-nil primary - // resource in the state. It runs every TestStep. - // - // While not deprecated, most resource tests should instead prefer using - // TestStep.ImportState based testing as it works with multiple attribute - // identifiers and also verifies resource import functionality. - IDRefreshName string - - // IDRefreshIgnore is a list of configuration keys that will be ignored - // during ID-only refresh testing. - IDRefreshIgnore []string -} - -// ExternalProvider holds information about third-party providers that should -// be downloaded by Terraform as part of running the test step. -type ExternalProvider struct { - VersionConstraint string // the version constraint for the provider - Source string // the provider source -} - -// TestStep is a single apply sequence of a test, done within the -// context of a state. -// -// Multiple TestSteps can be sequenced in a Test to allow testing -// potentially complex update logic. In general, simply create/destroy -// tests will only need one step. -// -// Refer to the Env prefixed constants for environment variables that further -// control testing functionality. -type TestStep struct { - // ResourceName should be set to the name of the resource - // that is being tested. Example: "aws_instance.foo". Various test - // modes use this to auto-detect state information. - // - // This is only required if the test mode settings below say it is - // for the mode you're using. - ResourceName string - - // PreConfig is called before the Config is applied to perform any per-step - // setup that needs to happen. This is called regardless of "test mode" - // below. - PreConfig func() - - // Taint is a list of resource addresses to taint prior to the execution of - // the step. Be sure to only include this at a step where the referenced - // address will be present in state, as it will fail the test if the resource - // is missing. - // - // This option is ignored on ImportState tests, and currently only works for - // resources in the root module path. - Taint []string - - //--------------------------------------------------------------- - // Test modes. One of the following groups of settings must be - // set to determine what the test step will do. Ideally we would've - // used Go interfaces here but there are now hundreds of tests we don't - // want to re-type so instead we just determine which step logic - // to run based on what settings below are set. - //--------------------------------------------------------------- - - //--------------------------------------------------------------- - // Plan, Apply testing - //--------------------------------------------------------------- - - // Config a string of the configuration to give to Terraform. If this - // is set, then the TestCase will execute this step with the same logic - // as a `terraform apply`. - // - // JSON Configuration Syntax can be used and is assumed whenever Config - // contains valid JSON. - Config string - - // Check is called after the Config is applied. Use this step to - // make your own API calls to check the status of things, and to - // inspect the format of the ResourceState itself. - // - // If an error is returned, the test will fail. In this case, a - // destroy plan will still be attempted. - // - // If this is nil, no check is done on this step. - Check TestCheckFunc - - // Destroy will create a destroy plan if set to true. - Destroy bool - - // ExpectNonEmptyPlan can be set to true for specific types of tests that are - // looking to verify that a diff occurs - ExpectNonEmptyPlan bool - - // ExpectError allows the construction of test cases that we expect to fail - // with an error. The specified regexp must match against the error for the - // test to pass. - ExpectError *regexp.Regexp - - // PlanOnly can be set to only run `plan` with this configuration, and not - // actually apply it. This is useful for ensuring config changes result in - // no-op plans - PlanOnly bool - - // PreventDiskCleanup can be set to true for testing terraform modules which - // require access to disk at runtime. Note that this will leave files in the - // temp folder - PreventDiskCleanup bool - - // PreventPostDestroyRefresh can be set to true for cases where data sources - // are tested alongside real resources - PreventPostDestroyRefresh bool - - // SkipFunc enables skipping the TestStep, based on environment criteria. - // For example, this can prevent running certain steps that may be runtime - // platform or API configuration dependent. - // - // Return true with no error to skip the test step. The error return - // should be used to signify issues that prevented the function from - // completing as expected. - // - // SkipFunc is called after PreConfig but before applying the Config. - SkipFunc func() (bool, error) - - //--------------------------------------------------------------- - // ImportState testing - //--------------------------------------------------------------- - - // ImportState, if true, will test the functionality of ImportState - // by importing the resource with ResourceName (must be set) and the - // ID of that resource. - ImportState bool - - // ImportStateId is the ID to perform an ImportState operation with. - // This is optional. If it isn't set, then the resource ID is automatically - // determined by inspecting the state for ResourceName's ID. - ImportStateId string - - // ImportStateIdPrefix is the prefix added in front of ImportStateId. - // This can be useful in complex import cases, where more than one - // attribute needs to be passed on as the Import ID. Mainly in cases - // where the ID is not known, and a known prefix needs to be added to - // the unset ImportStateId field. - ImportStateIdPrefix string - - // ImportStateIdFunc is a function that can be used to dynamically generate - // the ID for the ImportState tests. It is sent the state, which can be - // checked to derive the attributes necessary and generate the string in the - // desired format. - ImportStateIdFunc ImportStateIdFunc - - // ImportStateCheck checks the results of ImportState. It should be - // used to verify that the resulting value of ImportState has the - // proper resources, IDs, and attributes. - // - // Prefer ImportStateVerify over ImportStateCheck, unless the resource - // import explicitly is expected to create multiple resources (not a - // recommended resource implementation) or if attributes are imported with - // syntactically different but semantically/functionally equivalent values - // where special logic is needed. - // - // Terraform versions 1.3 and later can include data source states during - // import, which the testing framework will skip to prevent the need for - // Terraform version specific logic in provider testing. - ImportStateCheck ImportStateCheckFunc - - // ImportStateVerify, if true, will also check that the state values - // that are finally put into the state after import match for all the - // IDs returned by the Import. Note that this checks for strict equality - // and does not respect DiffSuppressFunc or CustomizeDiff. - // - // ImportStateVerifyIgnore is a list of prefixes of fields that should - // not be verified to be equal. These can be set to ephemeral fields or - // fields that can't be refreshed and don't matter. - ImportStateVerify bool - ImportStateVerifyIgnore []string - - // ImportStatePersist, if true, will update the persisted state with the - // state generated by the import operation (i.e., terraform import). When - // false (default) the state generated by the import operation is discarded - // at the end of the test step that is verifying import behavior. - ImportStatePersist bool - - //--------------------------------------------------------------- - // RefreshState testing - //--------------------------------------------------------------- - - // RefreshState, if true, will test the functionality of `terraform - // refresh` by refreshing the state, running any checks against the - // refreshed state, and running a plan to verify against unexpected plan - // differences. - // - // If the refresh is expected to result in a non-empty plan - // ExpectNonEmptyPlan should be set to true in the same TestStep. - // - // RefreshState cannot be the first TestStep and, it is mutually exclusive - // with ImportState. - RefreshState bool - - // ProviderFactories can be specified for the providers that are valid for - // this TestStep. When providers are specified at the TestStep level, all - // TestStep within a TestCase must declare providers. - // - // This can also be specified at the TestCase level for all TestStep, - // however all provider specifications must be done either at the TestCase - // level or TestStep level, otherwise the testing framework will raise an - // error and fail the test. - // - // These are the providers that can be referenced within the test. Each key - // is an individually addressable provider. Typically you will only pass a - // single value here for the provider you are testing. Aliases are not - // supported by the test framework, so to use multiple provider instances, - // you should add additional copies to this map with unique names. To set - // their configuration, you would reference them similar to the following: - // - // provider "my_factory_key" { - // # ... - // } - // - // resource "my_resource" "mr" { - // provider = my_factory_key - // - // # ... - // } - ProviderFactories map[string]func() (*schema.Provider, error) - - // ProtoV5ProviderFactories serves the same purpose as ProviderFactories, - // but for protocol v5 providers defined using the terraform-plugin-go - // ProviderServer interface. When providers are specified at the TestStep - // level, all TestStep within a TestCase must declare providers. - // - // This can also be specified at the TestCase level for all TestStep, - // however all provider specifications must be done either at the TestCase - // level or TestStep level, otherwise the testing framework will raise an - // error and fail the test. - ProtoV5ProviderFactories map[string]func() (tfprotov5.ProviderServer, error) - - // ProtoV6ProviderFactories serves the same purpose as ProviderFactories, - // but for protocol v6 providers defined using the terraform-plugin-go - // ProviderServer interface. - // The version of Terraform used in acceptance testing must be greater - // than or equal to v0.15.4 to use ProtoV6ProviderFactories. When providers - // are specified at the TestStep level, all TestStep within a TestCase must - // declare providers. - // - // This can also be specified at the TestCase level for all TestStep, - // however all provider specifications must be done either at the TestCase - // level or TestStep level, otherwise the testing framework will raise an - // error and fail the test. - ProtoV6ProviderFactories map[string]func() (tfprotov6.ProviderServer, error) - - // ExternalProviders are providers the TestStep relies on that should - // be downloaded from the registry during init. When providers are - // specified at the TestStep level, all TestStep within a TestCase must - // declare providers. - // - // This can also be specified at the TestCase level for all TestStep, - // however all provider specifications must be done either at the TestCase - // level or TestStep level, otherwise the testing framework will raise an - // error and fail the test. - // - // Outside specifying an earlier version of the provider under test, - // typically for state upgrader testing, this is generally only necessary - // for performing import testing where the prior TestStep configuration - // contained a provider outside the one under test. - ExternalProviders map[string]ExternalProvider -} - -// ParallelTest performs an acceptance test on a resource, allowing concurrency -// with other ParallelTest. The number of concurrent tests is controlled by the -// "go test" command -parallel flag. -// -// Tests will fail if they do not properly handle conditions to allow multiple -// tests to occur against the same resource or service (e.g. random naming). -// -// Test() function requirements and documentation also apply to this function. -func ParallelTest(t testing.T, c TestCase) { - t.Helper() - t.Parallel() - Test(t, c) -} - -// Test performs an acceptance test on a resource. -// -// Tests are not run unless an environmental variable "TF_ACC" is -// set to some non-empty value. This is to avoid test cases surprising -// a user by creating real resources. -// -// Tests will fail unless the verbose flag (`go test -v`, or explicitly -// the "-test.v" flag) is set. Because some acceptance tests take quite -// long, we require the verbose flag so users are able to see progress -// output. -// -// Use the ParallelTest() function to automatically set (*testing.T).Parallel() -// to enable testing concurrency. Use the UnitTest() function to automatically -// set the TestCase type IsUnitTest field. -// -// This function will automatically find or install Terraform CLI into a -// temporary directory, based on the following behavior: -// -// - If the TF_ACC_TERRAFORM_PATH environment variable is set, that -// Terraform CLI binary is used if found and executable. If not found or -// executable, an error will be returned unless the -// TF_ACC_TERRAFORM_VERSION environment variable is also set. -// - If the TF_ACC_TERRAFORM_VERSION environment variable is set, install -// and use that Terraform CLI version. -// - If both the TF_ACC_TERRAFORM_PATH and TF_ACC_TERRAFORM_VERSION -// environment variables are unset, perform a lookup for the Terraform -// CLI binary based on the operating system PATH. If not found, the -// latest available Terraform CLI binary is installed. -// -// Refer to the Env prefixed constants for additional details about these -// environment variables, and others, that control testing functionality. -func Test(t testing.T, c TestCase) { - t.Helper() - - ctx := context.Background() - ctx = logging.InitTestContext(ctx, t) - - err := c.validate(ctx) - - if err != nil { - logging.HelperResourceError(ctx, - "Test validation error", - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("Test validation error: %s", err) - } - - // We only run acceptance tests if an env var is set because they're - // slow and generally require some outside configuration. You can opt out - // of this with OverrideEnvVar on individual TestCases. - if os.Getenv(EnvTfAcc) == "" && !c.IsUnitTest { - t.Skip(fmt.Sprintf( - "Acceptance tests skipped unless env '%s' set", - EnvTfAcc)) - return - } - - // Copy any explicitly passed providers to factories, this is for backwards compatibility. - if len(c.Providers) > 0 { - c.ProviderFactories = map[string]func() (*schema.Provider, error){} - - for name, p := range c.Providers { - prov := p - c.ProviderFactories[name] = func() (*schema.Provider, error) { //nolint:unparam // required signature - return prov, nil - } - } - } - - logging.HelperResourceDebug(ctx, "Starting TestCase") - - // Run the PreCheck if we have it. - // This is done after the auto-configure to allow providers - // to override the default auto-configure parameters. - if c.PreCheck != nil { - logging.HelperResourceDebug(ctx, "Calling TestCase PreCheck") - - c.PreCheck() - - logging.HelperResourceDebug(ctx, "Called TestCase PreCheck") - } - - sourceDir, err := os.Getwd() - if err != nil { - t.Fatalf("Error getting working dir: %s", err) - } - helper := plugintest.AutoInitProviderHelper(ctx, sourceDir) - defer func(helper *plugintest.Helper) { - err := helper.Close() - if err != nil { - logging.HelperResourceError(ctx, "Unable to clean up temporary test files", map[string]interface{}{logging.KeyError: err}) - } - }(helper) - - runNewTest(ctx, t, c, helper) - - logging.HelperResourceDebug(ctx, "Finished TestCase") -} - -// UnitTest is a helper to force the acceptance testing harness to run in the -// normal unit test suite. This should only be used for resource that don't -// have any external dependencies. -// -// Test() function requirements and documentation also apply to this function. -func UnitTest(t testing.T, c TestCase) { - t.Helper() - - c.IsUnitTest = true - Test(t, c) -} - -func testResource(c TestStep, state *terraform.State) (*terraform.ResourceState, error) { - for _, m := range state.Modules { - if len(m.Resources) > 0 { - if v, ok := m.Resources[c.ResourceName]; ok { - return v, nil - } - } - } - - return nil, fmt.Errorf( - "Resource specified by ResourceName couldn't be found: %s", c.ResourceName) -} - -// ComposeTestCheckFunc lets you compose multiple TestCheckFuncs into -// a single TestCheckFunc. -// -// As a user testing their provider, this lets you decompose your checks -// into smaller pieces more easily. -// -// ComposeTestCheckFunc returns immediately on the first TestCheckFunc error. -// To aggregrate all errors, use ComposeAggregateTestCheckFunc instead. -func ComposeTestCheckFunc(fs ...TestCheckFunc) TestCheckFunc { - return func(s *terraform.State) error { - for i, f := range fs { - if err := f(s); err != nil { - return fmt.Errorf("Check %d/%d error: %s", i+1, len(fs), err) - } - } - - return nil - } -} - -// ComposeAggregateTestCheckFunc lets you compose multiple TestCheckFuncs into -// a single TestCheckFunc. -// -// As a user testing their provider, this lets you decompose your checks -// into smaller pieces more easily. -// -// Unlike ComposeTestCheckFunc, ComposeAggergateTestCheckFunc runs _all_ of the -// TestCheckFuncs and aggregates failures. -func ComposeAggregateTestCheckFunc(fs ...TestCheckFunc) TestCheckFunc { - return func(s *terraform.State) error { - var result []error - - for i, f := range fs { - if err := f(s); err != nil { - result = append(result, fmt.Errorf("Check %d/%d error: %w", i+1, len(fs), err)) - } - } - - return errors.Join(result...) - } -} - -// TestCheckResourceAttrSet ensures any value exists in the state for the -// given name and key combination. The opposite of this TestCheckFunc is -// TestCheckNoResourceAttr. State value checking is only recommended for -// testing Computed attributes and attribute defaults. -// -// Use this as a last resort when a more specific TestCheckFunc cannot be -// implemented, such as: -// -// - TestCheckResourceAttr: Equality checking of non-TypeSet state value. -// - TestCheckResourceAttrPair: Equality checking of non-TypeSet state -// value, based on another state value. -// - TestCheckTypeSet*: Equality checking of TypeSet state values. -// - TestMatchResourceAttr: Regular expression checking of non-TypeSet -// state value. -// - TestMatchTypeSet*: Regular expression checking on TypeSet state values. -// -// For managed resources, the name parameter is combination of the resource -// type, a period (.), and the name label. The name for the below example -// configuration would be "myprovider_thing.example". -// -// resource "myprovider_thing" "example" { ... } -// -// For data sources, the name parameter is a combination of the keyword "data", -// a period (.), the data source type, a period (.), and the name label. The -// name for the below example configuration would be -// "data.myprovider_thing.example". -// -// data "myprovider_thing" "example" { ... } -// -// The key parameter is an attribute path in Terraform CLI 0.11 and earlier -// "flatmap" syntax. Keys start with the attribute name of a top-level -// attribute. Use the following special key syntax to inspect underlying -// values of a list or map attribute: -// -// - .{NUMBER}: List value at index, e.g. .0 to inspect the first element -// - .{KEY}: Map value at key, e.g. .example to inspect the example key -// value -// -// While it is possible to check nested attributes under list and map -// attributes using the special key syntax, checking a list, map, or set -// attribute directly is not supported. Use TestCheckResourceAttr with -// the special .# or .% key syntax for those situations instead. -func TestCheckResourceAttrSet(name, key string) TestCheckFunc { - return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { - is, err := primaryInstanceState(s, name) - if err != nil { - return err - } - - return testCheckResourceAttrSet(is, name, key) - }) -} - -// TestCheckModuleResourceAttrSet - as per TestCheckResourceAttrSet but with -// support for non-root modules -func TestCheckModuleResourceAttrSet(mp []string, name string, key string) TestCheckFunc { - mpt := addrs.Module(mp).UnkeyedInstanceShim() - return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { - is, err := modulePathPrimaryInstanceState(s, mpt, name) - if err != nil { - return err - } - - return testCheckResourceAttrSet(is, name, key) - }) -} - -func testCheckResourceAttrSet(is *terraform.InstanceState, name string, key string) error { - val, ok := is.Attributes[key] - - if ok && val != "" { - return nil - } - - if _, ok := is.Attributes[key+".#"]; ok { - return fmt.Errorf( - "%s: list or set attribute '%s' must be checked by element count key (%s) or element value keys (e.g. %s). Set element value checks should use TestCheckTypeSet functions instead.", - name, - key, - key+".#", - key+".0", - ) - } - - if _, ok := is.Attributes[key+".%"]; ok { - return fmt.Errorf( - "%s: map attribute '%s' must be checked by element count key (%s) or element value keys (e.g. %s).", - name, - key, - key+".%", - key+".examplekey", - ) - } - - return fmt.Errorf("%s: Attribute '%s' expected to be set", name, key) -} - -// TestCheckResourceAttr ensures a specific value is stored in state for the -// given name and key combination. State value checking is only recommended for -// testing Computed attributes and attribute defaults. -// -// For managed resources, the name parameter is combination of the resource -// type, a period (.), and the name label. The name for the below example -// configuration would be "myprovider_thing.example". -// -// resource "myprovider_thing" "example" { ... } -// -// For data sources, the name parameter is a combination of the keyword "data", -// a period (.), the data source type, a period (.), and the name label. The -// name for the below example configuration would be -// "data.myprovider_thing.example". -// -// data "myprovider_thing" "example" { ... } -// -// The key parameter is an attribute path in Terraform CLI 0.11 and earlier -// "flatmap" syntax. Keys start with the attribute name of a top-level -// attribute. Use the following special key syntax to inspect list, map, and -// set attributes: -// -// - .{NUMBER}: List value at index, e.g. .0 to inspect the first element. -// Use the TestCheckTypeSet* and TestMatchTypeSet* functions instead -// for sets. -// - .{KEY}: Map value at key, e.g. .example to inspect the example key -// value. -// - .#: Number of elements in list or set. -// - .%: Number of elements in map. -// -// The value parameter is the stringified data to check at the given key. Use -// the following attribute type rules to set the value: -// -// - Boolean: "false" or "true". -// - Float/Integer: Stringified number, such as "1.2" or "123". -// - String: No conversion necessary. -func TestCheckResourceAttr(name, key, value string) TestCheckFunc { - return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { - is, err := primaryInstanceState(s, name) - if err != nil { - return err - } - - return testCheckResourceAttr(is, name, key, value) - }) -} - -// TestCheckModuleResourceAttr - as per TestCheckResourceAttr but with -// support for non-root modules -func TestCheckModuleResourceAttr(mp []string, name string, key string, value string) TestCheckFunc { - mpt := addrs.Module(mp).UnkeyedInstanceShim() - return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { - is, err := modulePathPrimaryInstanceState(s, mpt, name) - if err != nil { - return err - } - - return testCheckResourceAttr(is, name, key, value) - }) -} - -func testCheckResourceAttr(is *terraform.InstanceState, name string, key string, value string) error { - v, ok := is.Attributes[key] - - if !ok { - // Empty containers may be elided from the state. - // If the intent here is to check for an empty container, allow the key to - // also be non-existent. - if value == "0" && (strings.HasSuffix(key, ".#") || strings.HasSuffix(key, ".%")) { - return nil - } - - if _, ok := is.Attributes[key+".#"]; ok { - return fmt.Errorf( - "%s: list or set attribute '%s' must be checked by element count key (%s) or element value keys (e.g. %s). Set element value checks should use TestCheckTypeSet functions instead.", - name, - key, - key+".#", - key+".0", - ) - } - - if _, ok := is.Attributes[key+".%"]; ok { - return fmt.Errorf( - "%s: map attribute '%s' must be checked by element count key (%s) or element value keys (e.g. %s).", - name, - key, - key+".%", - key+".examplekey", - ) - } - - return fmt.Errorf("%s: Attribute '%s' not found", name, key) - } - - if v != value { - return fmt.Errorf( - "%s: Attribute '%s' expected %#v, got %#v", - name, - key, - value, - v) - } - - return nil -} - -// CheckResourceAttrWithFunc is the callback type used to apply a custom checking logic -// when using TestCheckResourceAttrWith and a value is found for the given name and key. -// -// When this function returns an error, TestCheckResourceAttrWith will fail the check. -type CheckResourceAttrWithFunc func(value string) error - -// TestCheckResourceAttrWith ensures a value stored in state for the -// given name and key combination, is checked against a custom logic. -// State value checking is only recommended for testing Computed attributes -// and attribute defaults. -// -// For managed resources, the name parameter is combination of the resource -// type, a period (.), and the name label. The name for the below example -// configuration would be "myprovider_thing.example". -// -// resource "myprovider_thing" "example" { ... } -// -// For data sources, the name parameter is a combination of the keyword "data", -// a period (.), the data source type, a period (.), and the name label. The -// name for the below example configuration would be -// "data.myprovider_thing.example". -// -// data "myprovider_thing" "example" { ... } -// -// The key parameter is an attribute path in Terraform CLI 0.11 and earlier -// "flatmap" syntax. Keys start with the attribute name of a top-level -// attribute. Use the following special key syntax to inspect list, map, and -// set attributes: -// -// - .{NUMBER}: List value at index, e.g. .0 to inspect the first element. -// Use the TestCheckTypeSet* and TestMatchTypeSet* functions instead -// for sets. -// - .{KEY}: Map value at key, e.g. .example to inspect the example key -// value. -// - .#: Number of elements in list or set. -// - .%: Number of elements in map. -// -// The checkValueFunc parameter is a CheckResourceAttrWithFunc, -// and it's provided with the attribute value to apply a custom checking logic, -// if it was found in the state. The function must return an error for the -// check to fail, or `nil` to succeed. -func TestCheckResourceAttrWith(name, key string, checkValueFunc CheckResourceAttrWithFunc) TestCheckFunc { - return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { - is, err := primaryInstanceState(s, name) - if err != nil { - return err - } - - err = testCheckResourceAttrSet(is, name, key) - if err != nil { - return err - } - - err = checkValueFunc(is.Attributes[key]) - if err != nil { - return fmt.Errorf("%s: Attribute %q value: %w", name, key, err) - } - - return nil - }) -} - -// TestCheckNoResourceAttr ensures no value exists in the state for the -// given name and key combination. The opposite of this TestCheckFunc is -// TestCheckResourceAttrSet. State value checking is only recommended for -// testing Computed attributes and attribute defaults. -// -// For managed resources, the name parameter is combination of the resource -// type, a period (.), and the name label. The name for the below example -// configuration would be "myprovider_thing.example". -// -// resource "myprovider_thing" "example" { ... } -// -// For data sources, the name parameter is a combination of the keyword "data", -// a period (.), the data source type, a period (.), and the name label. The -// name for the below example configuration would be -// "data.myprovider_thing.example". -// -// data "myprovider_thing" "example" { ... } -// -// The key parameter is an attribute path in Terraform CLI 0.11 and earlier -// "flatmap" syntax. Keys start with the attribute name of a top-level -// attribute. Use the following special key syntax to inspect underlying -// values of a list or map attribute: -// -// - .{NUMBER}: List value at index, e.g. .0 to inspect the first element. -// - .{KEY}: Map value at key, e.g. .example to inspect the example key -// value. -// -// While it is possible to check nested attributes under list and map -// attributes using the special key syntax, checking a list, map, or set -// attribute directly is not supported. Use TestCheckResourceAttr with -// the special .# or .% key syntax for those situations instead. -func TestCheckNoResourceAttr(name, key string) TestCheckFunc { - return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { - is, err := primaryInstanceState(s, name) - if err != nil { - return err - } - - return testCheckNoResourceAttr(is, name, key) - }) -} - -// TestCheckModuleNoResourceAttr - as per TestCheckNoResourceAttr but with -// support for non-root modules -func TestCheckModuleNoResourceAttr(mp []string, name string, key string) TestCheckFunc { - mpt := addrs.Module(mp).UnkeyedInstanceShim() - return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { - is, err := modulePathPrimaryInstanceState(s, mpt, name) - if err != nil { - return err - } - - return testCheckNoResourceAttr(is, name, key) - }) -} - -func testCheckNoResourceAttr(is *terraform.InstanceState, name string, key string) error { - v, ok := is.Attributes[key] - - // Empty containers may sometimes be included in the state. - // If the intent here is to check for an empty container, allow the value to - // also be "0". - if v == "0" && (strings.HasSuffix(key, ".#") || strings.HasSuffix(key, ".%")) { - return nil - } - - if ok { - return fmt.Errorf("%s: Attribute '%s' found when not expected", name, key) - } - - if _, ok := is.Attributes[key+".#"]; ok { - return fmt.Errorf( - "%s: list or set attribute '%s' must be checked by element count key (%s) or element value keys (e.g. %s). Set element value checks should use TestCheckTypeSet functions instead.", - name, - key, - key+".#", - key+".0", - ) - } - - if _, ok := is.Attributes[key+".%"]; ok { - return fmt.Errorf( - "%s: map attribute '%s' must be checked by element count key (%s) or element value keys (e.g. %s).", - name, - key, - key+".%", - key+".examplekey", - ) - } - - return nil -} - -// TestMatchResourceAttr ensures a value matching a regular expression is -// stored in state for the given name and key combination. State value checking -// is only recommended for testing Computed attributes and attribute defaults. -// -// For managed resources, the name parameter is combination of the resource -// type, a period (.), and the name label. The name for the below example -// configuration would be "myprovider_thing.example". -// -// resource "myprovider_thing" "example" { ... } -// -// For data sources, the name parameter is a combination of the keyword "data", -// a period (.), the data source type, a period (.), and the name label. The -// name for the below example configuration would be -// "data.myprovider_thing.example". -// -// data "myprovider_thing" "example" { ... } -// -// The key parameter is an attribute path in Terraform CLI 0.11 and earlier -// "flatmap" syntax. Keys start with the attribute name of a top-level -// attribute. Use the following special key syntax to inspect list, map, and -// set attributes: -// -// - .{NUMBER}: List value at index, e.g. .0 to inspect the first element. -// Use the TestCheckTypeSet* and TestMatchTypeSet* functions instead -// for sets. -// - .{KEY}: Map value at key, e.g. .example to inspect the example key -// value. -// - .#: Number of elements in list or set. -// - .%: Number of elements in map. -// -// The value parameter is a compiled regular expression. A typical pattern is -// using the regexp.MustCompile() function, which will automatically ensure the -// regular expression is supported by the Go regular expression handlers during -// compilation. -func TestMatchResourceAttr(name, key string, r *regexp.Regexp) TestCheckFunc { - return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { - is, err := primaryInstanceState(s, name) - if err != nil { - return err - } - - return testMatchResourceAttr(is, name, key, r) - }) -} - -// TestModuleMatchResourceAttr - as per TestMatchResourceAttr but with -// support for non-root modules -func TestModuleMatchResourceAttr(mp []string, name string, key string, r *regexp.Regexp) TestCheckFunc { - mpt := addrs.Module(mp).UnkeyedInstanceShim() - return checkIfIndexesIntoTypeSet(key, func(s *terraform.State) error { - is, err := modulePathPrimaryInstanceState(s, mpt, name) - if err != nil { - return err - } - - return testMatchResourceAttr(is, name, key, r) - }) -} - -func testMatchResourceAttr(is *terraform.InstanceState, name string, key string, r *regexp.Regexp) error { - if !r.MatchString(is.Attributes[key]) { - return fmt.Errorf( - "%s: Attribute '%s' didn't match %q, got %#v", - name, - key, - r.String(), - is.Attributes[key]) - } - - return nil -} - -// TestCheckResourceAttrPtr is like TestCheckResourceAttr except the -// value is a pointer so that it can be updated while the test is running. -// It will only be dereferenced at the point this step is run. -// -// Refer to the TestCheckResourceAttr documentation for more information about -// setting the name, key, and value parameters. -func TestCheckResourceAttrPtr(name string, key string, value *string) TestCheckFunc { - return func(s *terraform.State) error { - return TestCheckResourceAttr(name, key, *value)(s) - } -} - -// TestCheckModuleResourceAttrPtr - as per TestCheckResourceAttrPtr but with -// support for non-root modules -func TestCheckModuleResourceAttrPtr(mp []string, name string, key string, value *string) TestCheckFunc { - return func(s *terraform.State) error { - return TestCheckModuleResourceAttr(mp, name, key, *value)(s) - } -} - -// TestCheckResourceAttrPair ensures value equality in state between the first -// given name and key combination and the second name and key combination. -// State value checking is only recommended for testing Computed attributes -// and attribute defaults. -// -// For managed resources, the name parameter is combination of the resource -// type, a period (.), and the name label. The name for the below example -// configuration would be "myprovider_thing.example". -// -// resource "myprovider_thing" "example" { ... } -// -// For data sources, the name parameter is a combination of the keyword "data", -// a period (.), the data source type, a period (.), and the name label. The -// name for the below example configuration would be -// "data.myprovider_thing.example". -// -// data "myprovider_thing" "example" { ... } -// -// The first and second names may use any combination of managed resources -// and/or data sources. -// -// The key parameter is an attribute path in Terraform CLI 0.11 and earlier -// "flatmap" syntax. Keys start with the attribute name of a top-level -// attribute. Use the following special key syntax to inspect list, map, and -// set attributes: -// -// - .{NUMBER}: List value at index, e.g. .0 to inspect the first element. -// Use the TestCheckTypeSet* and TestMatchTypeSet* functions instead -// for sets. -// - .{KEY}: Map value at key, e.g. .example to inspect the example key -// value. -// - .#: Number of elements in list or set. -// - .%: Number of elements in map. -func TestCheckResourceAttrPair(nameFirst, keyFirst, nameSecond, keySecond string) TestCheckFunc { - return checkIfIndexesIntoTypeSetPair(keyFirst, keySecond, func(s *terraform.State) error { - isFirst, err := primaryInstanceState(s, nameFirst) - if err != nil { - return err - } - - isSecond, err := primaryInstanceState(s, nameSecond) - if err != nil { - return err - } - - return testCheckResourceAttrPair(isFirst, nameFirst, keyFirst, isSecond, nameSecond, keySecond) - }) -} - -// TestCheckModuleResourceAttrPair - as per TestCheckResourceAttrPair but with -// support for non-root modules -func TestCheckModuleResourceAttrPair(mpFirst []string, nameFirst string, keyFirst string, mpSecond []string, nameSecond string, keySecond string) TestCheckFunc { - mptFirst := addrs.Module(mpFirst).UnkeyedInstanceShim() - mptSecond := addrs.Module(mpSecond).UnkeyedInstanceShim() - return checkIfIndexesIntoTypeSetPair(keyFirst, keySecond, func(s *terraform.State) error { - isFirst, err := modulePathPrimaryInstanceState(s, mptFirst, nameFirst) - if err != nil { - return err - } - - isSecond, err := modulePathPrimaryInstanceState(s, mptSecond, nameSecond) - if err != nil { - return err - } - - return testCheckResourceAttrPair(isFirst, nameFirst, keyFirst, isSecond, nameSecond, keySecond) - }) -} - -func testCheckResourceAttrPair(isFirst *terraform.InstanceState, nameFirst string, keyFirst string, isSecond *terraform.InstanceState, nameSecond string, keySecond string) error { - if nameFirst == nameSecond && keyFirst == keySecond { - return fmt.Errorf( - "comparing self: resource %s attribute %s", - nameFirst, - keyFirst, - ) - } - - vFirst, okFirst := isFirst.Attributes[keyFirst] - vSecond, okSecond := isSecond.Attributes[keySecond] - - // Container count values of 0 should not be relied upon, and not reliably - // maintained by helper/schema. For the purpose of tests, consider unset and - // 0 to be equal. - if len(keyFirst) > 2 && len(keySecond) > 2 && keyFirst[len(keyFirst)-2:] == keySecond[len(keySecond)-2:] && - (strings.HasSuffix(keyFirst, ".#") || strings.HasSuffix(keyFirst, ".%")) { - // they have the same suffix, and it is a collection count key. - if vFirst == "0" || vFirst == "" { - okFirst = false - } - if vSecond == "0" || vSecond == "" { - okSecond = false - } - } - - if okFirst != okSecond { - if !okFirst { - return fmt.Errorf("%s: Attribute %q not set, but %q is set in %s as %q", nameFirst, keyFirst, keySecond, nameSecond, vSecond) - } - return fmt.Errorf("%s: Attribute %q is %q, but %q is not set in %s", nameFirst, keyFirst, vFirst, keySecond, nameSecond) - } - if !(okFirst || okSecond) { - // If they both don't exist then they are equally unset, so that's okay. - return nil - } - - if vFirst != vSecond { - return fmt.Errorf( - "%s: Attribute '%s' expected %#v, got %#v", - nameFirst, - keyFirst, - vSecond, - vFirst) - } - - return nil -} - -// TestCheckOutput checks an output in the Terraform configuration -func TestCheckOutput(name, value string) TestCheckFunc { - return func(s *terraform.State) error { - ms := s.RootModule() - rs, ok := ms.Outputs[name] - if !ok { - return fmt.Errorf("Not found: %s", name) - } - - if rs.Value != value { - return fmt.Errorf( - "Output '%s': expected %#v, got %#v", - name, - value, - rs) - } - - return nil - } -} - -func TestMatchOutput(name string, r *regexp.Regexp) TestCheckFunc { - return func(s *terraform.State) error { - ms := s.RootModule() - rs, ok := ms.Outputs[name] - if !ok { - return fmt.Errorf("Not found: %s", name) - } - - if !r.MatchString(rs.Value.(string)) { - return fmt.Errorf( - "Output '%s': %#v didn't match %q", - name, - rs, - r.String()) - } - - return nil - } -} - -// modulePrimaryInstanceState returns the instance state for the given resource -// name in a ModuleState -func modulePrimaryInstanceState(ms *terraform.ModuleState, name string) (*terraform.InstanceState, error) { - rs, ok := ms.Resources[name] - if !ok { - return nil, fmt.Errorf("Not found: %s in %s", name, ms.Path) - } - - is := rs.Primary - if is == nil { - return nil, fmt.Errorf("No primary instance: %s in %s", name, ms.Path) - } - - return is, nil -} - -// modulePathPrimaryInstanceState returns the primary instance state for the -// given resource name in a given module path. -func modulePathPrimaryInstanceState(s *terraform.State, mp addrs.ModuleInstance, name string) (*terraform.InstanceState, error) { - ms := s.ModuleByPath(mp) - if ms == nil { - return nil, fmt.Errorf("No module found at: %s", mp) - } - - return modulePrimaryInstanceState(ms, name) -} - -// primaryInstanceState returns the primary instance state for the given -// resource name in the root module. -func primaryInstanceState(s *terraform.State, name string) (*terraform.InstanceState, error) { - ms := s.RootModule() - return modulePrimaryInstanceState(ms, name) -} - -// indexesIntoTypeSet is a heuristic to try and identify if a flatmap style -// string address uses a precalculated TypeSet hash, which are integers and -// typically are large and obviously not a list index -func indexesIntoTypeSet(key string) bool { - for _, part := range strings.Split(key, ".") { - if i, err := strconv.Atoi(part); err == nil && i > 100 { - return true - } - } - return false -} - -func checkIfIndexesIntoTypeSet(key string, f TestCheckFunc) TestCheckFunc { - return func(s *terraform.State) error { - err := f(s) - if err != nil && s.IsBinaryDrivenTest && indexesIntoTypeSet(key) { - return fmt.Errorf("Error in test check: %s\nTest check address %q likely indexes into TypeSet\nThis is currently not possible in the SDK", err, key) - } - return err - } -} - -func checkIfIndexesIntoTypeSetPair(keyFirst, keySecond string, f TestCheckFunc) TestCheckFunc { - return func(s *terraform.State) error { - err := f(s) - if err != nil && s.IsBinaryDrivenTest && (indexesIntoTypeSet(keyFirst) || indexesIntoTypeSet(keySecond)) { - return fmt.Errorf("Error in test check: %s\nTest check address %q or %q likely indexes into TypeSet\nThis is currently not possible in the SDK", err, keyFirst, keySecond) - } - return err - } -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_config.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_config.go deleted file mode 100644 index f56c885be..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_config.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resource - -import ( - "context" - "fmt" - - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging" - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest" -) - -func testStepTaint(ctx context.Context, step TestStep, wd *plugintest.WorkingDir) error { - if len(step.Taint) == 0 { - return nil - } - - logging.HelperResourceTrace(ctx, fmt.Sprintf("Using TestStep Taint: %v", step.Taint)) - - for _, p := range step.Taint { - err := wd.Taint(ctx, p) - if err != nil { - return fmt.Errorf("error tainting resource: %s", err) - } - } - return nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_new.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_new.go deleted file mode 100644 index 14b247306..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_new.go +++ /dev/null @@ -1,443 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resource - -import ( - "context" - "fmt" - "reflect" - "strings" - - "github.com/google/go-cmp/cmp" - tfjson "github.com/hashicorp/terraform-json" - "github.com/mitchellh/go-testing-interface" - - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging" - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -func runPostTestDestroy(ctx context.Context, t testing.T, c TestCase, wd *plugintest.WorkingDir, providers *providerFactories, statePreDestroy *terraform.State) error { - t.Helper() - - err := runProviderCommand(ctx, t, func() error { - return wd.Destroy(ctx) - }, wd, providers) - if err != nil { - return err - } - - if c.CheckDestroy != nil { - logging.HelperResourceTrace(ctx, "Using TestCase CheckDestroy") - logging.HelperResourceDebug(ctx, "Calling TestCase CheckDestroy") - - if err := c.CheckDestroy(statePreDestroy); err != nil { - return err - } - - logging.HelperResourceDebug(ctx, "Called TestCase CheckDestroy") - } - - return nil -} - -func runNewTest(ctx context.Context, t testing.T, c TestCase, helper *plugintest.Helper) { - t.Helper() - - wd := helper.RequireNewWorkingDir(ctx, t) - - ctx = logging.TestTerraformPathContext(ctx, wd.GetHelper().TerraformExecPath()) - ctx = logging.TestWorkingDirectoryContext(ctx, wd.GetHelper().WorkingDirectory()) - - providers := &providerFactories{ - legacy: c.ProviderFactories, - protov5: c.ProtoV5ProviderFactories, - protov6: c.ProtoV6ProviderFactories, - } - - defer func() { - var statePreDestroy *terraform.State - var err error - err = runProviderCommand(ctx, t, func() error { - statePreDestroy, err = getState(ctx, t, wd) - if err != nil { - return err - } - return nil - }, wd, providers) - if err != nil { - logging.HelperResourceError(ctx, - "Error retrieving state, there may be dangling resources", - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("Error retrieving state, there may be dangling resources: %s", err.Error()) - return - } - - if !stateIsEmpty(statePreDestroy) { - err := runPostTestDestroy(ctx, t, c, wd, providers, statePreDestroy) - if err != nil { - logging.HelperResourceError(ctx, - "Error running post-test destroy, there may be dangling resources", - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("Error running post-test destroy, there may be dangling resources: %s", err.Error()) - } - } - - wd.Close() - }() - - if c.hasProviders(ctx) { - err := wd.SetConfig(ctx, c.providerConfig(ctx, false)) - - if err != nil { - logging.HelperResourceError(ctx, - "TestCase error setting provider configuration", - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("TestCase error setting provider configuration: %s", err) - } - - err = runProviderCommand(ctx, t, func() error { - return wd.Init(ctx) - }, wd, providers) - - if err != nil { - logging.HelperResourceError(ctx, - "TestCase error running init", - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("TestCase error running init: %s", err.Error()) - } - } - - logging.HelperResourceDebug(ctx, "Starting TestSteps") - - // use this to track last step successfully applied - // acts as default for import tests - var appliedCfg string - - for stepIndex, step := range c.Steps { - stepNumber := stepIndex + 1 // 1-based indexing for humans - ctx = logging.TestStepNumberContext(ctx, stepNumber) - - logging.HelperResourceDebug(ctx, "Starting TestStep") - - if step.PreConfig != nil { - logging.HelperResourceDebug(ctx, "Calling TestStep PreConfig") - step.PreConfig() - logging.HelperResourceDebug(ctx, "Called TestStep PreConfig") - } - - if step.SkipFunc != nil { - logging.HelperResourceDebug(ctx, "Calling TestStep SkipFunc") - - skip, err := step.SkipFunc() - if err != nil { - logging.HelperResourceError(ctx, - "Error calling TestStep SkipFunc", - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("Error calling TestStep SkipFunc: %s", err.Error()) - } - - logging.HelperResourceDebug(ctx, "Called TestStep SkipFunc") - - if skip { - t.Logf("Skipping step %d/%d due to SkipFunc", stepNumber, len(c.Steps)) - logging.HelperResourceWarn(ctx, "Skipping TestStep due to SkipFunc") - continue - } - } - - if step.Config != "" && !step.Destroy && len(step.Taint) > 0 { - err := testStepTaint(ctx, step, wd) - - if err != nil { - logging.HelperResourceError(ctx, - "TestStep error tainting resources", - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("TestStep %d/%d error tainting resources: %s", stepNumber, len(c.Steps), err) - } - } - - if step.hasProviders(ctx) { - providers = &providerFactories{ - legacy: sdkProviderFactories(c.ProviderFactories).merge(step.ProviderFactories), - protov5: protov5ProviderFactories(c.ProtoV5ProviderFactories).merge(step.ProtoV5ProviderFactories), - protov6: protov6ProviderFactories(c.ProtoV6ProviderFactories).merge(step.ProtoV6ProviderFactories), - } - - providerCfg := step.providerConfig(ctx, step.configHasProviderBlock(ctx)) - - err := wd.SetConfig(ctx, providerCfg) - - if err != nil { - logging.HelperResourceError(ctx, - "TestStep error setting provider configuration", - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("TestStep %d/%d error setting test provider configuration: %s", stepNumber, len(c.Steps), err) - } - - err = runProviderCommand( - ctx, - t, - func() error { - return wd.Init(ctx) - }, - wd, - providers, - ) - - if err != nil { - logging.HelperResourceError(ctx, - "TestStep error running init", - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("TestStep %d/%d running init: %s", stepNumber, len(c.Steps), err.Error()) - return - } - } - - if step.ImportState { - logging.HelperResourceTrace(ctx, "TestStep is ImportState mode") - - err := testStepNewImportState(ctx, t, helper, wd, step, appliedCfg, providers) - if step.ExpectError != nil { - logging.HelperResourceDebug(ctx, "Checking TestStep ExpectError") - if err == nil { - logging.HelperResourceError(ctx, - "Error running import: expected an error but got none", - ) - t.Fatalf("Step %d/%d error running import: expected an error but got none", stepNumber, len(c.Steps)) - } - if !step.ExpectError.MatchString(err.Error()) { - logging.HelperResourceError(ctx, - fmt.Sprintf("Error running import: expected an error with pattern (%s)", step.ExpectError.String()), - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("Step %d/%d error running import, expected an error with pattern (%s), no match on: %s", stepNumber, len(c.Steps), step.ExpectError.String(), err) - } - } else { - if err != nil && c.ErrorCheck != nil { - logging.HelperResourceDebug(ctx, "Calling TestCase ErrorCheck") - err = c.ErrorCheck(err) - logging.HelperResourceDebug(ctx, "Called TestCase ErrorCheck") - } - if err != nil { - logging.HelperResourceError(ctx, - "Error running import", - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("Step %d/%d error running import: %s", stepNumber, len(c.Steps), err) - } - } - - logging.HelperResourceDebug(ctx, "Finished TestStep") - - continue - } - - if step.RefreshState { - logging.HelperResourceTrace(ctx, "TestStep is RefreshState mode") - - err := testStepNewRefreshState(ctx, t, wd, step, providers) - if step.ExpectError != nil { - logging.HelperResourceDebug(ctx, "Checking TestStep ExpectError") - if err == nil { - logging.HelperResourceError(ctx, - "Error running refresh: expected an error but got none", - ) - t.Fatalf("Step %d/%d error running refresh: expected an error but got none", stepNumber, len(c.Steps)) - } - if !step.ExpectError.MatchString(err.Error()) { - logging.HelperResourceError(ctx, - fmt.Sprintf("Error running refresh: expected an error with pattern (%s)", step.ExpectError.String()), - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("Step %d/%d error running refresh, expected an error with pattern (%s), no match on: %s", stepNumber, len(c.Steps), step.ExpectError.String(), err) - } - } else { - if err != nil && c.ErrorCheck != nil { - logging.HelperResourceDebug(ctx, "Calling TestCase ErrorCheck") - err = c.ErrorCheck(err) - logging.HelperResourceDebug(ctx, "Called TestCase ErrorCheck") - } - if err != nil { - logging.HelperResourceError(ctx, - "Error running refresh", - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("Step %d/%d error running refresh: %s", stepNumber, len(c.Steps), err) - } - } - - logging.HelperResourceDebug(ctx, "Finished TestStep") - - continue - } - - if step.Config != "" { - logging.HelperResourceTrace(ctx, "TestStep is Config mode") - - err := testStepNewConfig(ctx, t, c, wd, step, providers) - if step.ExpectError != nil { - logging.HelperResourceDebug(ctx, "Checking TestStep ExpectError") - - if err == nil { - logging.HelperResourceError(ctx, - "Expected an error but got none", - ) - t.Fatalf("Step %d/%d, expected an error but got none", stepNumber, len(c.Steps)) - } - if !step.ExpectError.MatchString(err.Error()) { - logging.HelperResourceError(ctx, - fmt.Sprintf("Expected an error with pattern (%s)", step.ExpectError.String()), - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("Step %d/%d, expected an error with pattern, no match on: %s", stepNumber, len(c.Steps), err) - } - } else { - if err != nil && c.ErrorCheck != nil { - logging.HelperResourceDebug(ctx, "Calling TestCase ErrorCheck") - - err = c.ErrorCheck(err) - - logging.HelperResourceDebug(ctx, "Called TestCase ErrorCheck") - } - if err != nil { - logging.HelperResourceError(ctx, - "Unexpected error", - map[string]interface{}{logging.KeyError: err}, - ) - t.Fatalf("Step %d/%d error: %s", stepNumber, len(c.Steps), err) - } - } - - appliedCfg = step.mergedConfig(ctx, c) - - logging.HelperResourceDebug(ctx, "Finished TestStep") - - continue - } - - t.Fatalf("Step %d/%d, unsupported test mode", stepNumber, len(c.Steps)) - } -} - -func getState(ctx context.Context, t testing.T, wd *plugintest.WorkingDir) (*terraform.State, error) { - t.Helper() - - jsonState, err := wd.State(ctx) - if err != nil { - return nil, err - } - state, err := shimStateFromJson(jsonState) - if err != nil { - t.Fatal(err) - } - return state, nil -} - -func stateIsEmpty(state *terraform.State) bool { - return state.Empty() || !state.HasResources() -} - -func planIsEmpty(plan *tfjson.Plan) bool { - for _, rc := range plan.ResourceChanges { - for _, a := range rc.Change.Actions { - if a != tfjson.ActionNoop { - return false - } - } - } - return true -} - -func testIDRefresh(ctx context.Context, t testing.T, c TestCase, wd *plugintest.WorkingDir, step TestStep, r *terraform.ResourceState, providers *providerFactories) error { - t.Helper() - - // Build the state. The state is just the resource with an ID. There - // are no attributes. We only set what is needed to perform a refresh. - state := terraform.NewState() - state.RootModule().Resources = make(map[string]*terraform.ResourceState) - state.RootModule().Resources[c.IDRefreshName] = &terraform.ResourceState{} - - // Temporarily set the config to a minimal provider config for the refresh - // test. After the refresh we can reset it. - err := wd.SetConfig(ctx, c.providerConfig(ctx, step.configHasProviderBlock(ctx))) - if err != nil { - t.Fatalf("Error setting import test config: %s", err) - } - defer func() { - err = wd.SetConfig(ctx, step.Config) - if err != nil { - t.Fatalf("Error resetting test config: %s", err) - } - }() - - // Refresh! - err = runProviderCommand(ctx, t, func() error { - err = wd.Refresh(ctx) - if err != nil { - t.Fatalf("Error running terraform refresh: %s", err) - } - state, err = getState(ctx, t, wd) - if err != nil { - return err - } - return nil - }, wd, providers) - if err != nil { - return err - } - - // Verify attribute equivalence. - actualR := state.RootModule().Resources[c.IDRefreshName] - if actualR == nil { - return fmt.Errorf("Resource gone!") - } - if actualR.Primary == nil { - return fmt.Errorf("Resource has no primary instance") - } - actual := actualR.Primary.Attributes - expected := r.Primary.Attributes - - if len(c.IDRefreshIgnore) > 0 { - logging.HelperResourceTrace(ctx, fmt.Sprintf("Using TestCase IDRefreshIgnore: %v", c.IDRefreshIgnore)) - } - - // Remove fields we're ignoring - for _, v := range c.IDRefreshIgnore { - for k := range actual { - if strings.HasPrefix(k, v) { - delete(actual, k) - } - } - for k := range expected { - if strings.HasPrefix(k, v) { - delete(expected, k) - } - } - } - - if !reflect.DeepEqual(actual, expected) { - // Determine only the different attributes - for k, v := range expected { - if av, ok := actual[k]; ok && v == av { - delete(expected, k) - delete(actual, k) - } - } - - if diff := cmp.Diff(expected, actual); diff != "" { - return fmt.Errorf("IDRefreshName attributes not equivalent. Difference is shown below. The - symbol indicates attributes missing after refresh.\n\n%s", diff) - } - } - - return nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_new_config.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_new_config.go deleted file mode 100644 index a52008768..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_new_config.go +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resource - -import ( - "context" - "errors" - "fmt" - - tfjson "github.com/hashicorp/terraform-json" - testing "github.com/mitchellh/go-testing-interface" - - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging" - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -func testStepNewConfig(ctx context.Context, t testing.T, c TestCase, wd *plugintest.WorkingDir, step TestStep, providers *providerFactories) error { - t.Helper() - - err := wd.SetConfig(ctx, step.mergedConfig(ctx, c)) - if err != nil { - return fmt.Errorf("Error setting config: %w", err) - } - - // require a refresh before applying - // failing to do this will result in data sources not being updated - err = runProviderCommand(ctx, t, func() error { - return wd.Refresh(ctx) - }, wd, providers) - if err != nil { - return fmt.Errorf("Error running pre-apply refresh: %w", err) - } - - // If this step is a PlanOnly step, skip over this first Plan and - // subsequent Apply, and use the follow-up Plan that checks for - // permadiffs - if !step.PlanOnly { - logging.HelperResourceDebug(ctx, "Running Terraform CLI plan and apply") - - // Plan! - err := runProviderCommand(ctx, t, func() error { - if step.Destroy { - return wd.CreateDestroyPlan(ctx) - } - return wd.CreatePlan(ctx) - }, wd, providers) - if err != nil { - return fmt.Errorf("Error running pre-apply plan: %w", err) - } - - // We need to keep a copy of the state prior to destroying such - // that the destroy steps can verify their behavior in the - // check function - var stateBeforeApplication *terraform.State - err = runProviderCommand(ctx, t, func() error { - stateBeforeApplication, err = getState(ctx, t, wd) - if err != nil { - return err - } - return nil - }, wd, providers) - if err != nil { - return fmt.Errorf("Error retrieving pre-apply state: %w", err) - } - - // Apply the diff, creating real resources - err = runProviderCommand(ctx, t, func() error { - return wd.Apply(ctx) - }, wd, providers) - if err != nil { - if step.Destroy { - return fmt.Errorf("Error running destroy: %w", err) - } - return fmt.Errorf("Error running apply: %w", err) - } - - // Get the new state - var state *terraform.State - err = runProviderCommand(ctx, t, func() error { - state, err = getState(ctx, t, wd) - if err != nil { - return err - } - return nil - }, wd, providers) - if err != nil { - return fmt.Errorf("Error retrieving state after apply: %w", err) - } - - // Run any configured checks - if step.Check != nil { - logging.HelperResourceTrace(ctx, "Using TestStep Check") - - state.IsBinaryDrivenTest = true - if step.Destroy { - if err := step.Check(stateBeforeApplication); err != nil { - return fmt.Errorf("Check failed: %w", err) - } - } else { - if err := step.Check(state); err != nil { - return fmt.Errorf("Check failed: %w", err) - } - } - } - } - - // Test for perpetual diffs by performing a plan, a refresh, and another plan - logging.HelperResourceDebug(ctx, "Running Terraform CLI plan to check for perpetual differences") - - // do a plan - err = runProviderCommand(ctx, t, func() error { - if step.Destroy { - return wd.CreateDestroyPlan(ctx) - } - return wd.CreatePlan(ctx) - }, wd, providers) - if err != nil { - return fmt.Errorf("Error running post-apply plan: %w", err) - } - - var plan *tfjson.Plan - err = runProviderCommand(ctx, t, func() error { - var err error - plan, err = wd.SavedPlan(ctx) - return err - }, wd, providers) - if err != nil { - return fmt.Errorf("Error retrieving post-apply plan: %w", err) - } - - if !planIsEmpty(plan) && !step.ExpectNonEmptyPlan { - var stdout string - err = runProviderCommand(ctx, t, func() error { - var err error - stdout, err = wd.SavedPlanRawStdout(ctx) - return err - }, wd, providers) - if err != nil { - return fmt.Errorf("Error retrieving formatted plan output: %w", err) - } - return fmt.Errorf("After applying this test step, the plan was not empty.\nstdout:\n\n%s", stdout) - } - - // do a refresh - if !step.Destroy || (step.Destroy && !step.PreventPostDestroyRefresh) { - err := runProviderCommand(ctx, t, func() error { - return wd.Refresh(ctx) - }, wd, providers) - if err != nil { - return fmt.Errorf("Error running post-apply refresh: %w", err) - } - } - - // do another plan - err = runProviderCommand(ctx, t, func() error { - if step.Destroy { - return wd.CreateDestroyPlan(ctx) - } - return wd.CreatePlan(ctx) - }, wd, providers) - if err != nil { - return fmt.Errorf("Error running second post-apply plan: %w", err) - } - - err = runProviderCommand(ctx, t, func() error { - var err error - plan, err = wd.SavedPlan(ctx) - return err - }, wd, providers) - if err != nil { - return fmt.Errorf("Error retrieving second post-apply plan: %w", err) - } - - // check if plan is empty - if !planIsEmpty(plan) && !step.ExpectNonEmptyPlan { - var stdout string - err = runProviderCommand(ctx, t, func() error { - var err error - stdout, err = wd.SavedPlanRawStdout(ctx) - return err - }, wd, providers) - if err != nil { - return fmt.Errorf("Error retrieving formatted second plan output: %w", err) - } - return fmt.Errorf("After applying this test step and performing a `terraform refresh`, the plan was not empty.\nstdout\n\n%s", stdout) - } else if step.ExpectNonEmptyPlan && planIsEmpty(plan) { - return errors.New("Expected a non-empty plan, but got an empty plan") - } - - // ID-ONLY REFRESH - // If we've never checked an id-only refresh and our state isn't - // empty, find the first resource and test it. - if c.IDRefreshName != "" { - logging.HelperResourceTrace(ctx, "Using TestCase IDRefreshName") - - var state *terraform.State - - err = runProviderCommand(ctx, t, func() error { - state, err = getState(ctx, t, wd) - if err != nil { - return err - } - return nil - }, wd, providers) - - if err != nil { - return err - } - - if state.Empty() { - return nil - } - - var idRefreshCheck *terraform.ResourceState - - // Find the first non-nil resource in the state - for _, m := range state.Modules { - if len(m.Resources) > 0 { - if v, ok := m.Resources[c.IDRefreshName]; ok { - idRefreshCheck = v - } - - break - } - } - - // If we have an instance to check for refreshes, do it - // immediately. We do it in the middle of another test - // because it shouldn't affect the overall state (refresh - // is read-only semantically) and we want to fail early if - // this fails. If refresh isn't read-only, then this will have - // caught a different bug. - if idRefreshCheck != nil { - if err := testIDRefresh(ctx, t, c, wd, step, idRefreshCheck, providers); err != nil { - return fmt.Errorf( - "[ERROR] Test: ID-only test failed: %s", err) - } - } - } - - return nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_new_import_state.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_new_import_state.go deleted file mode 100644 index 4ddf56c5b..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_new_import_state.go +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resource - -import ( - "context" - "fmt" - "reflect" - "strings" - - "github.com/google/go-cmp/cmp" - "github.com/mitchellh/go-testing-interface" - - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging" - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -func testStepNewImportState(ctx context.Context, t testing.T, helper *plugintest.Helper, wd *plugintest.WorkingDir, step TestStep, cfg string, providers *providerFactories) error { - t.Helper() - - if step.ResourceName == "" { - t.Fatal("ResourceName is required for an import state test") - } - - // get state from check sequence - var state *terraform.State - var err error - err = runProviderCommand(ctx, t, func() error { - state, err = getState(ctx, t, wd) - if err != nil { - return err - } - return nil - }, wd, providers) - if err != nil { - t.Fatalf("Error getting state: %s", err) - } - - // Determine the ID to import - var importId string - switch { - case step.ImportStateIdFunc != nil: - logging.HelperResourceTrace(ctx, "Using TestStep ImportStateIdFunc for import identifier") - - var err error - - logging.HelperResourceDebug(ctx, "Calling TestStep ImportStateIdFunc") - - importId, err = step.ImportStateIdFunc(state) - - if err != nil { - t.Fatal(err) - } - - logging.HelperResourceDebug(ctx, "Called TestStep ImportStateIdFunc") - case step.ImportStateId != "": - logging.HelperResourceTrace(ctx, "Using TestStep ImportStateId for import identifier") - - importId = step.ImportStateId - default: - logging.HelperResourceTrace(ctx, "Using resource identifier for import identifier") - - resource, err := testResource(step, state) - if err != nil { - t.Fatal(err) - } - importId = resource.Primary.ID - } - - if step.ImportStateIdPrefix != "" { - logging.HelperResourceTrace(ctx, "Prepending TestStep ImportStateIdPrefix for import identifier") - - importId = step.ImportStateIdPrefix + importId - } - - logging.HelperResourceTrace(ctx, fmt.Sprintf("Using import identifier: %s", importId)) - - // Create working directory for import tests - if step.Config == "" { - logging.HelperResourceTrace(ctx, "Using prior TestStep Config for import") - - step.Config = cfg - if step.Config == "" { - t.Fatal("Cannot import state with no specified config") - } - } - - var importWd *plugintest.WorkingDir - - // Use the same working directory to persist the state from import - if step.ImportStatePersist { - importWd = wd - } else { - importWd = helper.RequireNewWorkingDir(ctx, t) - defer importWd.Close() - } - - err = importWd.SetConfig(ctx, step.Config) - if err != nil { - t.Fatalf("Error setting test config: %s", err) - } - - logging.HelperResourceDebug(ctx, "Running Terraform CLI init and import") - - if !step.ImportStatePersist { - err = runProviderCommand(ctx, t, func() error { - return importWd.Init(ctx) - }, importWd, providers) - if err != nil { - t.Fatalf("Error running init: %s", err) - } - } - - err = runProviderCommand(ctx, t, func() error { - return importWd.Import(ctx, step.ResourceName, importId) - }, importWd, providers) - if err != nil { - return err - } - - var importState *terraform.State - err = runProviderCommand(ctx, t, func() error { - importState, err = getState(ctx, t, importWd) - if err != nil { - return err - } - return nil - }, importWd, providers) - if err != nil { - t.Fatalf("Error getting state: %s", err) - } - - // Go through the imported state and verify - if step.ImportStateCheck != nil { - logging.HelperResourceTrace(ctx, "Using TestStep ImportStateCheck") - - var states []*terraform.InstanceState - for address, r := range importState.RootModule().Resources { - if strings.HasPrefix(address, "data.") { - continue - } - - if r.Primary == nil { - continue - } - - is := r.Primary.DeepCopy() - is.Ephemeral.Type = r.Type // otherwise the check function cannot see the type - states = append(states, is) - } - - logging.HelperResourceDebug(ctx, "Calling TestStep ImportStateCheck") - - if err := step.ImportStateCheck(states); err != nil { - t.Fatal(err) - } - - logging.HelperResourceDebug(ctx, "Called TestStep ImportStateCheck") - } - - // Verify that all the states match - if step.ImportStateVerify { - logging.HelperResourceTrace(ctx, "Using TestStep ImportStateVerify") - - // Ensure that we do not match against data sources as they - // cannot be imported and are not what we want to verify. - // Mode is not present in ResourceState so we use the - // stringified ResourceStateKey for comparison. - newResources := make(map[string]*terraform.ResourceState) - for k, v := range importState.RootModule().Resources { - if !strings.HasPrefix(k, "data.") { - newResources[k] = v - } - } - oldResources := make(map[string]*terraform.ResourceState) - for k, v := range state.RootModule().Resources { - if !strings.HasPrefix(k, "data.") { - oldResources[k] = v - } - } - - for _, r := range newResources { - // Find the existing resource - var oldR *terraform.ResourceState - for _, r2 := range oldResources { - - if r2.Primary != nil && r2.Primary.ID == r.Primary.ID && r2.Type == r.Type && r2.Provider == r.Provider { - oldR = r2 - break - } - } - if oldR == nil || oldR.Primary == nil { - t.Fatalf( - "Failed state verification, resource with ID %s not found", - r.Primary.ID) - } - - // don't add empty flatmapped containers, so we can more easily - // compare the attributes - skipEmpty := func(k, v string) bool { - if strings.HasSuffix(k, ".#") || strings.HasSuffix(k, ".%") { - if v == "0" { - return true - } - } - return false - } - - // Compare their attributes - actual := make(map[string]string) - for k, v := range r.Primary.Attributes { - if skipEmpty(k, v) { - continue - } - actual[k] = v - } - - expected := make(map[string]string) - for k, v := range oldR.Primary.Attributes { - if skipEmpty(k, v) { - continue - } - expected[k] = v - } - - // Remove fields we're ignoring - for _, v := range step.ImportStateVerifyIgnore { - for k := range actual { - if strings.HasPrefix(k, v) { - delete(actual, k) - } - } - for k := range expected { - if strings.HasPrefix(k, v) { - delete(expected, k) - } - } - } - - // timeouts are only _sometimes_ added to state. To - // account for this, just don't compare timeouts at - // all. - for k := range actual { - if strings.HasPrefix(k, "timeouts.") { - delete(actual, k) - } - if k == "timeouts" { - delete(actual, k) - } - } - for k := range expected { - if strings.HasPrefix(k, "timeouts.") { - delete(expected, k) - } - if k == "timeouts" { - delete(expected, k) - } - } - - if !reflect.DeepEqual(actual, expected) { - // Determine only the different attributes - // go-cmp tries to show surrounding identical map key/value for - // context of differences, which may be confusing. - for k, v := range expected { - if av, ok := actual[k]; ok && v == av { - delete(expected, k) - delete(actual, k) - } - } - - if diff := cmp.Diff(expected, actual); diff != "" { - return fmt.Errorf("ImportStateVerify attributes not equivalent. Difference is shown below. The - symbol indicates attributes missing after import.\n\n%s", diff) - } - } - } - } - - return nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_new_refresh_state.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_new_refresh_state.go deleted file mode 100644 index 627190a9d..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_new_refresh_state.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resource - -import ( - "context" - "fmt" - - tfjson "github.com/hashicorp/terraform-json" - "github.com/mitchellh/go-testing-interface" - - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging" - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -func testStepNewRefreshState(ctx context.Context, t testing.T, wd *plugintest.WorkingDir, step TestStep, providers *providerFactories) error { - t.Helper() - - var err error - // Explicitly ensure prior state exists before refresh. - err = runProviderCommand(ctx, t, func() error { - _, err = getState(ctx, t, wd) - if err != nil { - return err - } - return nil - }, wd, providers) - if err != nil { - t.Fatalf("Error getting state: %s", err) - } - - err = runProviderCommand(ctx, t, func() error { - return wd.Refresh(ctx) - }, wd, providers) - if err != nil { - return err - } - - var refreshState *terraform.State - err = runProviderCommand(ctx, t, func() error { - refreshState, err = getState(ctx, t, wd) - if err != nil { - return err - } - return nil - }, wd, providers) - if err != nil { - t.Fatalf("Error getting state: %s", err) - } - - // Go through the refreshed state and verify - if step.Check != nil { - logging.HelperResourceDebug(ctx, "Calling TestStep Check for RefreshState") - - if err := step.Check(refreshState); err != nil { - t.Fatal(err) - } - - logging.HelperResourceDebug(ctx, "Called TestStep Check for RefreshState") - } - - // do a plan - err = runProviderCommand(ctx, t, func() error { - return wd.CreatePlan(ctx) - }, wd, providers) - if err != nil { - return fmt.Errorf("Error running post-apply plan: %w", err) - } - - var plan *tfjson.Plan - err = runProviderCommand(ctx, t, func() error { - var err error - plan, err = wd.SavedPlan(ctx) - return err - }, wd, providers) - if err != nil { - return fmt.Errorf("Error retrieving post-apply plan: %w", err) - } - - if !planIsEmpty(plan) && !step.ExpectNonEmptyPlan { - var stdout string - err = runProviderCommand(ctx, t, func() error { - var err error - stdout, err = wd.SavedPlanRawStdout(ctx) - return err - }, wd, providers) - if err != nil { - return fmt.Errorf("Error retrieving formatted plan output: %w", err) - } - return fmt.Errorf("After refreshing state during this test step, a followup plan was not empty.\nstdout:\n\n%s", stdout) - } - - return nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_sets.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_sets.go deleted file mode 100644 index 8f5a731c3..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/testing_sets.go +++ /dev/null @@ -1,361 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// These test helpers were developed by the AWS provider team at HashiCorp. - -package resource - -import ( - "fmt" - "regexp" - "strings" - - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -const ( - sentinelIndex = "*" -) - -// TestCheckTypeSetElemNestedAttrs ensures a subset map of values is stored in -// state for the given name and key combination of attributes nested under a -// list or set block. Use this TestCheckFunc in preference over non-set -// variants to simplify testing code and ensure compatibility with indicies, -// which can easily change with schema changes. State value checking is only -// recommended for testing Computed attributes and attribute defaults. -// -// For managed resources, the name parameter is a combination of the resource -// type, a period (.), and the name label. The name for the below example -// configuration would be "myprovider_thing.example". -// -// resource "myprovider_thing" "example" { ... } -// -// For data sources, the name parameter is a combination of the keyword "data", -// a period (.), the data source type, a period (.), and the name label. The -// name for the below example configuration would be -// "data.myprovider_thing.example". -// -// data "myprovider_thing" "example" { ... } -// -// The key parameter is an attribute path in Terraform CLI 0.11 and earlier -// "flatmap" syntax. Keys start with the attribute name of a top-level -// attribute. Use the sentinel value '*' to replace the element indexing into -// a list or set. The sentinel value can be used for each list or set index, if -// there are multiple lists or sets in the attribute path. -// -// The values parameter is the map of attribute names to attribute values -// expected to be nested under the list or set. -// -// You may check for unset nested attributes, however this will also match keys -// set to an empty string. Use a map with at least 1 non-empty value. -// -// map[string]string{ -// "key1": "value", -// "key2": "", -// } -// -// If the values map is not granular enough, it is possible to match an element -// you were not intending to in the set. Provide the most complete mapping of -// attributes possible to be sure the unique element exists. -func TestCheckTypeSetElemNestedAttrs(name, attr string, values map[string]string) TestCheckFunc { - return func(s *terraform.State) error { - is, err := primaryInstanceState(s, name) - if err != nil { - return err - } - - attrParts := strings.Split(attr, ".") - if attrParts[len(attrParts)-1] != sentinelIndex { - return fmt.Errorf("%q does not end with the special value %q", attr, sentinelIndex) - } - // account for cases where the user is trying to see if the value is unset/empty - // there may be ambiguous scenarios where a field was deliberately unset vs set - // to the empty string, this will match both, which may be a false positive. - var matchCount int - for _, v := range values { - if v != "" { - matchCount++ - } - } - if matchCount == 0 { - return fmt.Errorf("%#v has no non-empty values", values) - } - - if testCheckTypeSetElemNestedAttrsInState(is, attrParts, matchCount, values) { - return nil - } - return fmt.Errorf("%q no TypeSet element %q, with nested attrs %#v in state: %#v", name, attr, values, is.Attributes) - } -} - -// TestMatchTypeSetElemNestedAttrs ensures a subset map of values, compared by -// regular expressions, is stored in state for the given name and key -// combination of attributes nested under a list or set block. Use this -// TestCheckFunc in preference over non-set variants to simplify testing code -// and ensure compatibility with indicies, which can easily change with schema -// changes. State value checking is only recommended for testing Computed -// attributes and attribute defaults. -// -// For managed resources, the name parameter is a combination of the resource -// type, a period (.), and the name label. The name for the below example -// configuration would be "myprovider_thing.example". -// -// resource "myprovider_thing" "example" { ... } -// -// For data sources, the name parameter is a combination of the keyword "data", -// a period (.), the data source type, a period (.), and the name label. The -// name for the below example configuration would be -// "data.myprovider_thing.example". -// -// data "myprovider_thing" "example" { ... } -// -// The key parameter is an attribute path in Terraform CLI 0.11 and earlier -// "flatmap" syntax. Keys start with the attribute name of a top-level -// attribute. Use the sentinel value '*' to replace the element indexing into -// a list or set. The sentinel value can be used for each list or set index, if -// there are multiple lists or sets in the attribute path. -// -// The values parameter is the map of attribute names to regular expressions -// for matching attribute values expected to be nested under the list or set. -// -// You may check for unset nested attributes, however this will also match keys -// set to an empty string. Use a map with at least 1 non-empty value. -// -// map[string]*regexp.Regexp{ -// "key1": regexp.MustCompile(`^value`), -// "key2": regexp.MustCompile(`^$`), -// } -// -// If the values map is not granular enough, it is possible to match an element -// you were not intending to in the set. Provide the most complete mapping of -// attributes possible to be sure the unique element exists. -func TestMatchTypeSetElemNestedAttrs(name, attr string, values map[string]*regexp.Regexp) TestCheckFunc { - return func(s *terraform.State) error { - is, err := primaryInstanceState(s, name) - if err != nil { - return err - } - - attrParts := strings.Split(attr, ".") - if attrParts[len(attrParts)-1] != sentinelIndex { - return fmt.Errorf("%q does not end with the special value %q", attr, sentinelIndex) - } - // account for cases where the user is trying to see if the value is unset/empty - // there may be ambiguous scenarios where a field was deliberately unset vs set - // to the empty string, this will match both, which may be a false positive. - var matchCount int - for _, v := range values { - if v != nil { - matchCount++ - } - } - if matchCount == 0 { - return fmt.Errorf("%#v has no non-empty values", values) - } - - if testCheckTypeSetElemNestedAttrsInState(is, attrParts, matchCount, values) { - return nil - } - return fmt.Errorf("%q no TypeSet element %q, with the regex provided, match in state: %#v", name, attr, is.Attributes) - } -} - -// TestCheckTypeSetElemAttr is a TestCheckFunc that accepts a resource -// name, an attribute path, which should use the sentinel value '*' for indexing -// into a TypeSet. The function verifies that an element matches the provided -// value. -// -// Use this function over SDK provided TestCheckFunctions when validating a -// TypeSet where its elements are a simple value - -// TestCheckTypeSetElemAttr ensures a specific value is stored in state for the -// given name and key combination under a list or set. Use this TestCheckFunc -// in preference over non-set variants to simplify testing code and ensure -// compatibility with indicies, which can easily change with schema changes. -// State value checking is only recommended for testing Computed attributes and -// attribute defaults. -// -// For managed resources, the name parameter is a combination of the resource -// type, a period (.), and the name label. The name for the below example -// configuration would be "myprovider_thing.example". -// -// resource "myprovider_thing" "example" { ... } -// -// For data sources, the name parameter is a combination of the keyword "data", -// a period (.), the data source type, a period (.), and the name label. The -// name for the below example configuration would be -// "data.myprovider_thing.example". -// -// data "myprovider_thing" "example" { ... } -// -// The key parameter is an attribute path in Terraform CLI 0.11 and earlier -// "flatmap" syntax. Keys start with the attribute name of a top-level -// attribute. Use the sentinel value '*' to replace the element indexing into -// a list or set. The sentinel value can be used for each list or set index, if -// there are multiple lists or sets in the attribute path. -// -// The value parameter is the stringified data to check at the given key. Use -// the following attribute type rules to set the value: -// -// - Boolean: "false" or "true". -// - Float/Integer: Stringified number, such as "1.2" or "123". -// - String: No conversion necessary. -func TestCheckTypeSetElemAttr(name, attr, value string) TestCheckFunc { - return func(s *terraform.State) error { - is, err := primaryInstanceState(s, name) - if err != nil { - return err - } - - err = testCheckTypeSetElem(is, attr, value) - if err != nil { - return fmt.Errorf("%q error: %s", name, err) - } - - return nil - } -} - -// TestCheckTypeSetElemAttrPair ensures value equality in state between the -// first given name and key combination and the second name and key -// combination. State value checking is only recommended for testing Computed -// attributes and attribute defaults. -// -// For managed resources, the name parameter is a combination of the resource -// type, a period (.), and the name label. The name for the below example -// configuration would be "myprovider_thing.example". -// -// resource "myprovider_thing" "example" { ... } -// -// For data sources, the name parameter is a combination of the keyword "data", -// a period (.), the data source type, a period (.), and the name label. The -// name for the below example configuration would be -// "data.myprovider_thing.example". -// -// data "myprovider_thing" "example" { ... } -// -// The first and second names may use any combination of managed resources -// and/or data sources. -// -// The key parameter is an attribute path in Terraform CLI 0.11 and earlier -// "flatmap" syntax. Keys start with the attribute name of a top-level -// attribute. Use the sentinel value '*' to replace the element indexing into -// a list or set. The sentinel value can be used for each list or set index, if -// there are multiple lists or sets in the attribute path. -func TestCheckTypeSetElemAttrPair(nameFirst, keyFirst, nameSecond, keySecond string) TestCheckFunc { - return func(s *terraform.State) error { - isFirst, err := primaryInstanceState(s, nameFirst) - if err != nil { - return err - } - - isSecond, err := primaryInstanceState(s, nameSecond) - if err != nil { - return err - } - - vSecond, okSecond := isSecond.Attributes[keySecond] - if !okSecond { - return fmt.Errorf("%s: Attribute %q not set, cannot be checked against TypeSet", nameSecond, keySecond) - } - - return testCheckTypeSetElemPair(isFirst, keyFirst, vSecond) - } -} - -func testCheckTypeSetElem(is *terraform.InstanceState, attr, value string) error { - attrParts := strings.Split(attr, ".") - if attrParts[len(attrParts)-1] != sentinelIndex { - return fmt.Errorf("%q does not end with the special value %q", attr, sentinelIndex) - } - for stateKey, stateValue := range is.Attributes { - if stateValue == value { - stateKeyParts := strings.Split(stateKey, ".") - if len(stateKeyParts) == len(attrParts) { - for i := range attrParts { - if attrParts[i] != stateKeyParts[i] && attrParts[i] != sentinelIndex { - break - } - if i == len(attrParts)-1 { - return nil - } - } - } - } - } - - return fmt.Errorf("no TypeSet element %q, with value %q in state: %#v", attr, value, is.Attributes) -} - -func testCheckTypeSetElemPair(is *terraform.InstanceState, attr, value string) error { - attrParts := strings.Split(attr, ".") - for stateKey, stateValue := range is.Attributes { - if stateValue == value { - stateKeyParts := strings.Split(stateKey, ".") - if len(stateKeyParts) == len(attrParts) { - for i := range attrParts { - if attrParts[i] != stateKeyParts[i] && attrParts[i] != sentinelIndex { - break - } - if i == len(attrParts)-1 { - return nil - } - } - } - } - } - - return fmt.Errorf("no TypeSet element %q, with value %q in state: %#v", attr, value, is.Attributes) -} - -// testCheckTypeSetElemNestedAttrsInState is a helper function -// to determine if nested attributes and their values are equal to those -// in the instance state. Currently, the function accepts a "values" param of type -// map[string]string or map[string]*regexp.Regexp. -// Returns true if all attributes match, else false. -func testCheckTypeSetElemNestedAttrsInState(is *terraform.InstanceState, attrParts []string, matchCount int, values interface{}) bool { - matches := make(map[string]int) - - for stateKey, stateValue := range is.Attributes { - stateKeyParts := strings.Split(stateKey, ".") - // a Set/List item with nested attrs would have a flatmap address of - // at least length 3 - // foo.0.name = "bar" - if len(stateKeyParts) < 3 || len(attrParts) > len(stateKeyParts) { - continue - } - var pathMatch bool - for i := range attrParts { - if attrParts[i] != stateKeyParts[i] && attrParts[i] != sentinelIndex { - break - } - if i == len(attrParts)-1 { - pathMatch = true - } - } - if !pathMatch { - continue - } - id := stateKeyParts[len(attrParts)-1] - nestedAttr := strings.Join(stateKeyParts[len(attrParts):], ".") - - var match bool - switch t := values.(type) { - case map[string]string: - if v, keyExists := t[nestedAttr]; keyExists && v == stateValue { - match = true - } - case map[string]*regexp.Regexp: - if v, keyExists := t[nestedAttr]; keyExists && v != nil && v.MatchString(stateValue) { - match = true - } - } - if match { - matches[id] = matches[id] + 1 - if matches[id] == matchCount { - return true - } - } - } - return false -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/teststep_providers.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/teststep_providers.go deleted file mode 100644 index 9b759bde0..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/teststep_providers.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resource - -import ( - "context" - "fmt" - "regexp" - "strings" -) - -var configProviderBlockRegex = regexp.MustCompile(`provider "?[a-zA-Z0-9_-]+"? {`) - -// configHasProviderBlock returns true if the Config has declared a provider -// configuration block, e.g. provider "examplecloud" {...} -func (s TestStep) configHasProviderBlock(_ context.Context) bool { - return configProviderBlockRegex.MatchString(s.Config) -} - -// configHasTerraformBlock returns true if the Config has declared a terraform -// configuration block, e.g. terraform {...} -func (s TestStep) configHasTerraformBlock(_ context.Context) bool { - return strings.Contains(s.Config, "terraform {") -} - -// mergedConfig prepends any necessary terraform configuration blocks to the -// TestStep Config. -// -// If there are ExternalProviders configurations in either the TestCase or -// TestStep, the terraform configuration block should be included with the -// step configuration to prevent errors with providers outside the -// registry.terraform.io hostname or outside the hashicorp namespace. -func (s TestStep) mergedConfig(ctx context.Context, testCase TestCase) string { - var config strings.Builder - - // Prevent issues with existing configurations containing the terraform - // configuration block. - if s.configHasTerraformBlock(ctx) { - config.WriteString(s.Config) - - return config.String() - } - - if testCase.hasProviders(ctx) { - config.WriteString(testCase.providerConfig(ctx, s.configHasProviderBlock(ctx))) - } else { - config.WriteString(s.providerConfig(ctx, s.configHasProviderBlock(ctx))) - } - - config.WriteString(s.Config) - - return config.String() -} - -// providerConfig takes the list of providers in a TestStep and returns a -// config with only empty provider blocks. This is useful for Import, where no -// config is provided, but the providers must be defined. -func (s TestStep) providerConfig(_ context.Context, skipProviderBlock bool) string { - var providerBlocks, requiredProviderBlocks strings.Builder - - for name, externalProvider := range s.ExternalProviders { - if !skipProviderBlock { - providerBlocks.WriteString(fmt.Sprintf("provider %q {}\n", name)) - } - - if externalProvider.Source == "" && externalProvider.VersionConstraint == "" { - continue - } - - requiredProviderBlocks.WriteString(fmt.Sprintf(" %s = {\n", name)) - - if externalProvider.Source != "" { - requiredProviderBlocks.WriteString(fmt.Sprintf(" source = %q\n", externalProvider.Source)) - } - - if externalProvider.VersionConstraint != "" { - requiredProviderBlocks.WriteString(fmt.Sprintf(" version = %q\n", externalProvider.VersionConstraint)) - } - - requiredProviderBlocks.WriteString(" }\n") - } - - if requiredProviderBlocks.Len() > 0 { - return fmt.Sprintf(` -terraform { - required_providers { -%[1]s - } -} - -%[2]s -`, strings.TrimSuffix(requiredProviderBlocks.String(), "\n"), providerBlocks.String()) - } - - return providerBlocks.String() -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/teststep_validate.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/teststep_validate.go deleted file mode 100644 index 7dbf883b5..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource/teststep_validate.go +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resource - -import ( - "context" - "fmt" - - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging" -) - -// testStepValidateRequest contains data for the (TestStep).validate() method. -type testStepValidateRequest struct { - // StepNumber is the index of the TestStep in the TestCase.Steps. - StepNumber int - - // TestCaseHasProviders is enabled if the TestCase has set any of - // ExternalProviders, ProtoV5ProviderFactories, ProtoV6ProviderFactories, - // or ProviderFactories. - TestCaseHasProviders bool -} - -// hasProviders returns true if the TestStep has set any of the -// ExternalProviders, ProtoV5ProviderFactories, ProtoV6ProviderFactories, or -// ProviderFactories fields. -func (s TestStep) hasProviders(_ context.Context) bool { - if len(s.ExternalProviders) > 0 { - return true - } - - if len(s.ProtoV5ProviderFactories) > 0 { - return true - } - - if len(s.ProtoV6ProviderFactories) > 0 { - return true - } - - if len(s.ProviderFactories) > 0 { - return true - } - - return false -} - -// validate ensures the TestStep is valid based on the following criteria: -// -// - Config or ImportState or RefreshState is set. -// - Config and RefreshState are not both set. -// - RefreshState and Destroy are not both set. -// - RefreshState is not the first TestStep. -// - Providers are not specified (ExternalProviders, -// ProtoV5ProviderFactories, ProtoV6ProviderFactories, ProviderFactories) -// if specified at the TestCase level. -// - Providers are specified (ExternalProviders, ProtoV5ProviderFactories, -// ProtoV6ProviderFactories, ProviderFactories) if not specified at the -// TestCase level. -// - No overlapping ExternalProviders and ProviderFactories entries -// - ResourceName is not empty when ImportState is true, ImportStateIdFunc -// is not set, and ImportStateId is not set. -func (s TestStep) validate(ctx context.Context, req testStepValidateRequest) error { - ctx = logging.TestStepNumberContext(ctx, req.StepNumber) - - logging.HelperResourceTrace(ctx, "Validating TestStep") - - if s.Config == "" && !s.ImportState && !s.RefreshState { - err := fmt.Errorf("TestStep missing Config or ImportState or RefreshState") - logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - - if s.Config != "" && s.RefreshState { - err := fmt.Errorf("TestStep cannot have Config and RefreshState") - logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - - if s.RefreshState && s.Destroy { - err := fmt.Errorf("TestStep cannot have RefreshState and Destroy") - logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - - if s.RefreshState && req.StepNumber == 1 { - err := fmt.Errorf("TestStep cannot have RefreshState as first step") - logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - - if s.ImportState && s.RefreshState { - err := fmt.Errorf("TestStep cannot have ImportState and RefreshState in same step") - logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - - for name := range s.ExternalProviders { - if _, ok := s.ProviderFactories[name]; ok { - err := fmt.Errorf("TestStep provider %q set in both ExternalProviders and ProviderFactories", name) - logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - } - - hasProviders := s.hasProviders(ctx) - - if req.TestCaseHasProviders && hasProviders { - err := fmt.Errorf("Providers must only be specified either at the TestCase or TestStep level") - logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - - if !req.TestCaseHasProviders && !hasProviders { - err := fmt.Errorf("Providers must be specified at the TestCase level or in all TestStep") - logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - - if s.ImportState { - if s.ImportStateId == "" && s.ImportStateIdFunc == nil && s.ResourceName == "" { - err := fmt.Errorf("TestStep ImportState must be specified with ImportStateId, ImportStateIdFunc, or ResourceName") - logging.HelperResourceError(ctx, "TestStep validation error", map[string]interface{}{logging.KeyError: err}) - return err - } - } - - return nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/config.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/config.go deleted file mode 100644 index d3cb35bce..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/config.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package plugintest - -import ( - "context" - "fmt" - "os" - "strings" - - "github.com/hashicorp/go-version" - install "github.com/hashicorp/hc-install" - "github.com/hashicorp/hc-install/checkpoint" - "github.com/hashicorp/hc-install/fs" - "github.com/hashicorp/hc-install/product" - "github.com/hashicorp/hc-install/releases" - "github.com/hashicorp/hc-install/src" - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging" -) - -// Config is used to configure the test helper. In most normal test programs -// the configuration is discovered automatically by an Init* function using -// DiscoverConfig, but this is exposed so that more complex scenarios can be -// implemented by direct configuration. -type Config struct { - SourceDir string - TerraformExec string - execTempDir string - PreviousPluginExec string -} - -// DiscoverConfig uses environment variables and other means to automatically -// discover a reasonable test helper configuration. -func DiscoverConfig(ctx context.Context, sourceDir string) (*Config, error) { - tfVersion := strings.TrimPrefix(os.Getenv(EnvTfAccTerraformVersion), "v") - tfPath := os.Getenv(EnvTfAccTerraformPath) - - tempDir := os.Getenv(EnvTfAccTempDir) - tfDir, err := os.MkdirTemp(tempDir, "plugintest-terraform") - if err != nil { - return nil, fmt.Errorf("failed to create temp dir: %w", err) - } - - var sources []src.Source - switch { - case tfPath != "": - logging.HelperResourceTrace(ctx, fmt.Sprintf("Adding potential Terraform CLI source of exact path: %s", tfPath)) - - sources = append(sources, &fs.AnyVersion{ - ExactBinPath: tfPath, - }) - case tfVersion != "": - tfVersion, err := version.NewVersion(tfVersion) - - if err != nil { - return nil, fmt.Errorf("invalid Terraform version: %w", err) - } - - logging.HelperResourceTrace(ctx, fmt.Sprintf("Adding potential Terraform CLI source of releases.hashicorp.com exact version %q for installation in: %s", tfVersion, tfDir)) - - sources = append(sources, &releases.ExactVersion{ - InstallDir: tfDir, - Product: product.Terraform, - Version: tfVersion, - }) - default: - logging.HelperResourceTrace(ctx, "Adding potential Terraform CLI source of local filesystem PATH lookup") - logging.HelperResourceTrace(ctx, fmt.Sprintf("Adding potential Terraform CLI source of checkpoint.hashicorp.com latest version for installation in: %s", tfDir)) - - sources = append(sources, &fs.AnyVersion{ - Product: &product.Terraform, - }) - sources = append(sources, &checkpoint.LatestVersion{ - InstallDir: tfDir, - Product: product.Terraform, - }) - } - - installer := install.NewInstaller() - tfExec, err := installer.Ensure(context.Background(), sources) - if err != nil { - return nil, fmt.Errorf("failed to find or install Terraform CLI from %+v: %w", sources, err) - } - - ctx = logging.TestTerraformPathContext(ctx, tfExec) - - logging.HelperResourceDebug(ctx, "Found Terraform CLI") - - return &Config{ - SourceDir: sourceDir, - TerraformExec: tfExec, - execTempDir: tfDir, - }, nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/doc.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/doc.go deleted file mode 100644 index 1b34a0b23..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/doc.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Package plugintest contains utilities to help with writing tests for -// Terraform plugins. -// -// This is not a package for testing configurations or modules written in the -// Terraform language. It is for testing the plugins that allow Terraform to -// manage various cloud services and other APIs. -package plugintest diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/environment_variables.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/environment_variables.go deleted file mode 100644 index 6df86f89f..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/environment_variables.go +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package plugintest - -// Environment variables -const ( - // Environment variable with acceptance testing temporary directory for - // testing files and Terraform CLI installation, if installation is - // required. By default, the operating system temporary directory is used. - // - // Setting TF_ACC_TERRAFORM_PATH does not override this value for Terraform - // CLI installation, if installation is required. - EnvTfAccTempDir = "TF_ACC_TEMP_DIR" - - // Environment variable with level to filter Terraform logs during - // acceptance testing. This value sets TF_LOG in a safe manner when - // executing Terraform CLI commands, which would otherwise interfere - // with the testing framework using TF_LOG to set the Go standard library - // log package level. - // - // This value takes precedence over TF_LOG_CORE, due to precedence rules - // in the Terraform core code, so it is not possible to set this to a level - // and also TF_LOG_CORE=OFF. Use TF_LOG_CORE and TF_LOG_PROVIDER in that - // case instead. - // - // If not set, but TF_ACC_LOG_PATH or TF_LOG_PATH_MASK is set, it defaults - // to TRACE. If Terraform CLI is version 0.14 or earlier, it will have no - // separate affect from the TF_ACC_LOG_PATH or TF_LOG_PATH_MASK behavior, - // as those earlier versions of Terraform are unreliable with the logging - // level being outside TRACE. - EnvTfAccLog = "TF_ACC_LOG" - - // Environment variable with path to save Terraform logs during acceptance - // testing. This value sets TF_LOG_PATH in a safe manner when executing - // Terraform CLI commands, which would otherwise be ignored since it could - // interfere with how the underlying execution is performed. - // - // If TF_LOG_PATH_MASK is set, it takes precedence over this value. - EnvTfAccLogPath = "TF_ACC_LOG_PATH" - - // Environment variable with level to filter Terraform core logs during - // acceptance testing. This value sets TF_LOG_CORE separate from - // TF_LOG_PROVIDER when calling Terraform. - // - // This value has no affect when TF_ACC_LOG is set (which sets Terraform's - // TF_LOG), due to precedence rules in the Terraform core code. Use - // TF_LOG_CORE and TF_LOG_PROVIDER in that case instead. - // - // If not set, defaults to TF_ACC_LOG behaviors. - EnvTfLogCore = "TF_LOG_CORE" - - // Environment variable with path containing the string %s, which is - // replaced with the test name, to save separate Terraform logs during - // acceptance testing. This value sets TF_LOG_PATH in a safe manner when - // executing Terraform CLI commands, which would otherwise be ignored since - // it could interfere with how the underlying execution is performed. - // - // Takes precedence over TF_ACC_LOG_PATH. - EnvTfLogPathMask = "TF_LOG_PATH_MASK" - - // Environment variable with level to filter Terraform provider logs during - // acceptance testing. This value sets TF_LOG_PROVIDER separate from - // TF_LOG_CORE. - // - // During testing, this only affects external providers whose logging goes - // through Terraform. The logging for the provider under test is controlled - // by the testing framework as it is running the provider code. Provider - // code using the Go standard library log package is controlled by TF_LOG - // for historical compatibility. - // - // This value takes precedence over TF_ACC_LOG for external provider logs, - // due to rules in the Terraform core code. - // - // If not set, defaults to TF_ACC_LOG behaviors. - EnvTfLogProvider = "TF_LOG_PROVIDER" - - // Environment variable with acceptance testing Terraform CLI version to - // download from releases.hashicorp.com, checksum verify, and install. The - // value can be any valid Terraform CLI version, such as 1.1.6, with or - // without a prepended v character. - // - // Setting this value takes precedence over using an available Terraform - // binary in the operation system PATH, or if not found, installing the - // latest version according to checkpoint.hashicorp.com. - // - // By default, the binary is installed in the operating system temporary - // directory, however that directory can be overridden with the - // TF_ACC_TEMP_DIR environment variable. - // - // If TF_ACC_TERRAFORM_PATH is also set, this installation method is - // only invoked when a binary does not exist at that path. No version - // checks are performed against an existing TF_ACC_TERRAFORM_PATH. - EnvTfAccTerraformVersion = "TF_ACC_TERRAFORM_VERSION" - - // Acceptance testing path to Terraform CLI binary. - // - // Setting this value takes precedence over using an available Terraform - // binary in the operation system PATH, or if not found, installing the - // latest version according to checkpoint.hashicorp.com. This value does - // not override TF_ACC_TEMP_DIR for Terraform CLI installation, if - // installation is required. - // - // If TF_ACC_TERRAFORM_VERSION is not set, the binary must exist and be - // executable, or an error will be returned. - // - // If TF_ACC_TERRAFORM_VERSION is also set, that Terraform CLI version - // will be installed if a binary is not found at the given path. No version - // checks are performed against an existing binary. - EnvTfAccTerraformPath = "TF_ACC_TERRAFORM_PATH" -) diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/guard.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/guard.go deleted file mode 100644 index 77f873980..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/guard.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package plugintest - -import ( - "fmt" -) - -// TestControl is an interface requiring a subset of *testing.T which is used -// by the test guards and helpers in this package. Most callers can simply -// pass their *testing.T value here, but the interface allows other -// implementations to potentially be provided instead, for example to allow -// meta-testing (testing of the test utilities themselves). -// -// This interface also describes the subset of normal test functionality the -// guards and helpers can perform: they can only create log lines, fail tests, -// and skip tests. All other test control is the responsibility of the main -// test code. -type TestControl interface { - Helper() - Log(args ...interface{}) - FailNow() - SkipNow() - Name() string -} - -// testingT wraps a TestControl to recover some of the convenience behaviors -// that would normally come from a real *testing.T, so we can keep TestControl -// small while still having these conveniences. This is an abstraction -// inversion, but accepted because it makes the public API more convenient -// without any considerable disadvantage. -type testingT struct { - TestControl -} - -func (t testingT) Logf(f string, args ...interface{}) { - t.Helper() - t.Log(fmt.Sprintf(f, args...)) -} - -func (t testingT) Fatalf(f string, args ...interface{}) { - t.Helper() - t.Log(fmt.Sprintf(f, args...)) - t.FailNow() -} - -func (t testingT) Skipf(f string, args ...interface{}) { - t.Helper() - t.Log(fmt.Sprintf(f, args...)) - t.SkipNow() -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/helper.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/helper.go deleted file mode 100644 index f96178872..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/helper.go +++ /dev/null @@ -1,290 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package plugintest - -import ( - "context" - "errors" - "fmt" - "os" - "strings" - - "github.com/hashicorp/terraform-exec/tfexec" - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging" -) - -// AutoInitProviderHelper is the main entrypoint for testing provider plugins -// using this package. It is intended to be called during TestMain to prepare -// for provider testing. -// -// AutoInitProviderHelper will discover the location of a current Terraform CLI -// executable to test against, detect whether a prior version of the plugin is -// available for upgrade tests, and then will return an object containing the -// results of that initialization which can then be stored in a global variable -// for use in other tests. -func AutoInitProviderHelper(ctx context.Context, sourceDir string) *Helper { - helper, err := AutoInitHelper(ctx, sourceDir) - if err != nil { - fmt.Fprintf(os.Stderr, "cannot run Terraform provider tests: %s\n", err) - os.Exit(1) - } - return helper -} - -// Helper is intended as a per-package singleton created in TestMain which -// other tests in a package can use to create Terraform execution contexts -type Helper struct { - baseDir string - - // sourceDir is the dir containing the provider source code, needed - // for tests that use fixture files. - sourceDir string - terraformExec string - - // execTempDir is created during DiscoverConfig to store any downloaded - // binaries - execTempDir string -} - -// AutoInitHelper uses the auto-discovery behavior of DiscoverConfig to prepare -// a configuration and then calls InitHelper with it. This is a convenient -// way to get the standard init behavior based on environment variables, and -// callers should use this unless they have an unusual requirement that calls -// for constructing a config in a different way. -func AutoInitHelper(ctx context.Context, sourceDir string) (*Helper, error) { - config, err := DiscoverConfig(ctx, sourceDir) - if err != nil { - return nil, err - } - - return InitHelper(ctx, config) -} - -// InitHelper prepares a testing helper with the given configuration. -// -// For most callers it is sufficient to call AutoInitHelper instead, which -// will construct a configuration automatically based on certain environment -// variables. -// -// If this function returns an error then it may have left some temporary files -// behind in the system's temporary directory. There is currently no way to -// automatically clean those up. -func InitHelper(ctx context.Context, config *Config) (*Helper, error) { - tempDir := os.Getenv(EnvTfAccTempDir) - baseDir, err := os.MkdirTemp(tempDir, "plugintest") - if err != nil { - return nil, fmt.Errorf("failed to create temporary directory for test helper: %s", err) - } - - return &Helper{ - baseDir: baseDir, - sourceDir: config.SourceDir, - terraformExec: config.TerraformExec, - execTempDir: config.execTempDir, - }, nil -} - -// Close cleans up temporary files and directories created to support this -// helper, returning an error if any of the cleanup fails. -// -// Call this before returning from TestMain to minimize the amount of detritus -// left behind in the filesystem after the tests complete. -func (h *Helper) Close() error { - if h.execTempDir != "" { - err := os.RemoveAll(h.execTempDir) - if err != nil { - return err - } - } - return os.RemoveAll(h.baseDir) -} - -// NewWorkingDir creates a new working directory for use in the implementation -// of a single test, returning a WorkingDir object representing that directory. -// -// If the working directory object is not itself closed by the time the test -// program exits, the Close method on the helper itself will attempt to -// delete it. -func (h *Helper) NewWorkingDir(ctx context.Context, t TestControl) (*WorkingDir, error) { - dir, err := os.MkdirTemp(h.baseDir, "work") - if err != nil { - return nil, err - } - - ctx = logging.TestWorkingDirectoryContext(ctx, dir) - - // symlink the provider source files into the config directory - // e.g. testdata - logging.HelperResourceTrace(ctx, "Symlinking source directories to work directory") - err = symlinkDirectoriesOnly(h.sourceDir, dir) - if err != nil { - return nil, err - } - - tf, err := tfexec.NewTerraform(dir, h.terraformExec) - - if err != nil { - return nil, fmt.Errorf("unable to create terraform-exec instance: %w", err) - } - - err = tf.SetDisablePluginTLS(true) - - if err != nil { - return nil, fmt.Errorf("unable to disable terraform-exec plugin TLS: %w", err) - } - - err = tf.SetSkipProviderVerify(true) // Only required for Terraform CLI 0.12.x - - var mismatch *tfexec.ErrVersionMismatch - if err != nil && !errors.As(err, &mismatch) { - return nil, fmt.Errorf("unable to disable terraform-exec provider verification: %w", err) - } - - tfAccLog := os.Getenv(EnvTfAccLog) - tfAccLogPath := os.Getenv(EnvTfAccLogPath) - tfLogCore := os.Getenv(EnvTfLogCore) - tfLogPathMask := os.Getenv(EnvTfLogPathMask) - tfLogProvider := os.Getenv(EnvTfLogProvider) - - if tfAccLog != "" && tfLogCore != "" { - err = fmt.Errorf( - "Invalid environment variable configuration. Cannot set both TF_ACC_LOG and TF_LOG_CORE. " + - "Use TF_LOG_CORE and TF_LOG_PROVIDER to separately control the Terraform CLI logging subsystems. " + - "To control the Go standard library log package for the provider under test, use TF_LOG.", - ) - logging.HelperResourceError(ctx, err.Error()) - return nil, err - } - - if tfAccLog != "" { - logging.HelperResourceTrace( - ctx, - fmt.Sprintf("Setting terraform-exec log level via %s environment variable, if Terraform CLI is version 0.15 or later", EnvTfAccLog), - map[string]interface{}{logging.KeyTestTerraformLogLevel: tfAccLog}, - ) - - err := tf.SetLog(tfAccLog) - - if err != nil { - if !errors.As(err, new(*tfexec.ErrVersionMismatch)) { - logging.HelperResourceError( - ctx, - "Unable to set terraform-exec log level", - map[string]interface{}{logging.KeyError: err.Error()}, - ) - return nil, fmt.Errorf("unable to set terraform-exec log level (%s): %w", tfAccLog, err) - } - - logging.HelperResourceWarn( - ctx, - fmt.Sprintf("Unable to set terraform-exec log level via %s environment variable, as Terraform CLI is version 0.14 or earlier. It will default to TRACE.", EnvTfAccLog), - map[string]interface{}{logging.KeyTestTerraformLogLevel: "TRACE"}, - ) - } - } - - if tfLogCore != "" { - logging.HelperResourceTrace( - ctx, - fmt.Sprintf("Setting terraform-exec core log level via %s environment variable, if Terraform CLI is version 0.15 or later", EnvTfLogCore), - map[string]interface{}{ - logging.KeyTestTerraformLogCoreLevel: tfLogCore, - }, - ) - - err := tf.SetLogCore(tfLogCore) - - if err != nil { - logging.HelperResourceError( - ctx, - "Unable to set terraform-exec core log level", - map[string]interface{}{logging.KeyError: err.Error()}, - ) - return nil, fmt.Errorf("unable to set terraform-exec core log level (%s): %w", tfLogCore, err) - } - } - - if tfLogProvider != "" { - logging.HelperResourceTrace( - ctx, - fmt.Sprintf("Setting terraform-exec provider log level via %s environment variable, if Terraform CLI is version 0.15 or later", EnvTfLogProvider), - map[string]interface{}{ - logging.KeyTestTerraformLogCoreLevel: tfLogProvider, - }, - ) - - err := tf.SetLogProvider(tfLogProvider) - - if err != nil { - logging.HelperResourceError( - ctx, - "Unable to set terraform-exec provider log level", - map[string]interface{}{logging.KeyError: err.Error()}, - ) - return nil, fmt.Errorf("unable to set terraform-exec provider log level (%s): %w", tfLogProvider, err) - } - } - - var logPath, logPathEnvVar string - - if tfAccLogPath != "" { - logPath = tfAccLogPath - logPathEnvVar = EnvTfAccLogPath - } - - // Similar to helper/logging.LogOutput() and - // terraform-plugin-log/tfsdklog.RegisterTestSink(), the TF_LOG_PATH_MASK - // environment variable should take precedence over TF_ACC_LOG_PATH. - if tfLogPathMask != "" { - // Escape special characters which may appear if we have subtests - testName := strings.Replace(t.Name(), "/", "__", -1) - logPath = fmt.Sprintf(tfLogPathMask, testName) - logPathEnvVar = EnvTfLogPathMask - } - - if logPath != "" { - logging.HelperResourceTrace( - ctx, - fmt.Sprintf("Setting terraform-exec log path via %s environment variable", logPathEnvVar), - map[string]interface{}{logging.KeyTestTerraformLogPath: logPath}, - ) - - if err := tf.SetLogPath(logPath); err != nil { - return nil, fmt.Errorf("unable to set terraform-exec log path (%s): %w", logPath, err) - } - } - - return &WorkingDir{ - h: h, - tf: tf, - baseDir: dir, - terraformExec: h.terraformExec, - }, nil -} - -// RequireNewWorkingDir is a variant of NewWorkingDir that takes a TestControl -// object and will immediately fail the running test if the creation of the -// working directory fails. -func (h *Helper) RequireNewWorkingDir(ctx context.Context, t TestControl) *WorkingDir { - t.Helper() - - wd, err := h.NewWorkingDir(ctx, t) - if err != nil { - t := testingT{t} - t.Fatalf("failed to create new working directory: %s", err) - return nil - } - return wd -} - -// WorkingDirectory returns the working directory being used when running tests. -func (h *Helper) WorkingDirectory() string { - return h.baseDir -} - -// TerraformExecPath returns the location of the Terraform CLI executable that -// should be used when running tests. -func (h *Helper) TerraformExecPath() string { - return h.terraformExec -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/util.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/util.go deleted file mode 100644 index 0d4bbe526..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/util.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package plugintest - -import ( - "fmt" - "os" - "path/filepath" -) - -func symlinkFile(src string, dest string) error { - err := os.Symlink(src, dest) - - if err != nil { - return fmt.Errorf("unable to symlink %q to %q: %w", src, dest, err) - } - - srcInfo, err := os.Stat(src) - - if err != nil { - return fmt.Errorf("unable to stat %q: %w", src, err) - } - - err = os.Chmod(dest, srcInfo.Mode()) - - if err != nil { - return fmt.Errorf("unable to set %q permissions: %w", dest, err) - } - - return nil -} - -// symlinkDirectoriesOnly finds only the first-level child directories in srcDir -// and symlinks them into destDir. -// Unlike symlinkDir, this is done non-recursively in order to limit the number -// of file descriptors used. -func symlinkDirectoriesOnly(srcDir string, destDir string) error { - srcInfo, err := os.Stat(srcDir) - if err != nil { - return fmt.Errorf("unable to stat source directory %q: %w", srcDir, err) - } - - err = os.MkdirAll(destDir, srcInfo.Mode()) - if err != nil { - return fmt.Errorf("unable to make destination directory %q: %w", destDir, err) - } - - dirEntries, err := os.ReadDir(srcDir) - - if err != nil { - return fmt.Errorf("unable to read source directory %q: %w", srcDir, err) - } - - for _, dirEntry := range dirEntries { - if !dirEntry.IsDir() { - continue - } - - srcPath := filepath.Join(srcDir, dirEntry.Name()) - destPath := filepath.Join(destDir, dirEntry.Name()) - err := symlinkFile(srcPath, destPath) - - if err != nil { - return fmt.Errorf("unable to symlink directory %q to %q: %w", srcPath, destPath, err) - } - } - - return nil -} diff --git a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/working_dir.go b/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/working_dir.go deleted file mode 100644 index 05b028442..000000000 --- a/vendor/github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest/working_dir.go +++ /dev/null @@ -1,371 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package plugintest - -import ( - "context" - "encoding/json" - "fmt" - "os" - "path/filepath" - - "github.com/hashicorp/terraform-exec/tfexec" - tfjson "github.com/hashicorp/terraform-json" - - "github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging" -) - -const ( - ConfigFileName = "terraform_plugin_test.tf" - ConfigFileNameJSON = ConfigFileName + ".json" - PlanFileName = "tfplan" -) - -// WorkingDir represents a distinct working directory that can be used for -// running tests. Each test should construct its own WorkingDir by calling -// NewWorkingDir or RequireNewWorkingDir on its package's singleton -// plugintest.Helper. -type WorkingDir struct { - h *Helper - - // baseDir is the root of the working directory tree - baseDir string - - // configFilename is the full filename where the latest configuration - // was stored; empty until SetConfig is called. - configFilename string - - // tf is the instance of tfexec.Terraform used for running Terraform commands - tf *tfexec.Terraform - - // terraformExec is a path to a terraform binary, inherited from Helper - terraformExec string - - // reattachInfo stores the gRPC socket info required for Terraform's - // plugin reattach functionality - reattachInfo tfexec.ReattachInfo -} - -// Close deletes the directories and files created to represent the receiving -// working directory. After this method is called, the working directory object -// is invalid and may no longer be used. -func (wd *WorkingDir) Close() error { - return os.RemoveAll(wd.baseDir) -} - -func (wd *WorkingDir) SetReattachInfo(ctx context.Context, reattachInfo tfexec.ReattachInfo) { - logging.HelperResourceTrace(ctx, "Setting Terraform CLI reattach configuration", map[string]interface{}{"tf_reattach_config": reattachInfo}) - wd.reattachInfo = reattachInfo -} - -func (wd *WorkingDir) UnsetReattachInfo() { - wd.reattachInfo = nil -} - -// GetHelper returns the Helper set on the WorkingDir. -func (wd *WorkingDir) GetHelper() *Helper { - return wd.h -} - -// SetConfig sets a new configuration for the working directory. -// -// This must be called at least once before any call to Init, Plan, Apply, or -// Destroy to establish the configuration. Any previously-set configuration is -// discarded and any saved plan is cleared. -func (wd *WorkingDir) SetConfig(ctx context.Context, cfg string) error { - logging.HelperResourceTrace(ctx, "Setting Terraform configuration", map[string]any{logging.KeyTestTerraformConfiguration: cfg}) - - outFilename := filepath.Join(wd.baseDir, ConfigFileName) - rmFilename := filepath.Join(wd.baseDir, ConfigFileNameJSON) - bCfg := []byte(cfg) - if json.Valid(bCfg) { - outFilename, rmFilename = rmFilename, outFilename - } - if err := os.Remove(rmFilename); err != nil && !os.IsNotExist(err) { - return fmt.Errorf("unable to remove %q: %w", rmFilename, err) - } - err := os.WriteFile(outFilename, bCfg, 0700) - if err != nil { - return err - } - wd.configFilename = outFilename - - // Changing configuration invalidates any saved plan. - err = wd.ClearPlan(ctx) - if err != nil { - return err - } - return nil -} - -// ClearState deletes any Terraform state present in the working directory. -// -// Any remote objects tracked by the state are not destroyed first, so this -// will leave them dangling in the remote system. -func (wd *WorkingDir) ClearState(ctx context.Context) error { - logging.HelperResourceTrace(ctx, "Clearing Terraform state") - - err := os.Remove(filepath.Join(wd.baseDir, "terraform.tfstate")) - - if os.IsNotExist(err) { - logging.HelperResourceTrace(ctx, "No Terraform state to clear") - return nil - } - - if err != nil { - return err - } - - logging.HelperResourceTrace(ctx, "Cleared Terraform state") - - return nil -} - -// ClearPlan deletes any saved plan present in the working directory. -func (wd *WorkingDir) ClearPlan(ctx context.Context) error { - logging.HelperResourceTrace(ctx, "Clearing Terraform plan") - - err := os.Remove(wd.planFilename()) - - if os.IsNotExist(err) { - logging.HelperResourceTrace(ctx, "No Terraform plan to clear") - return nil - } - - if err != nil { - return err - } - - logging.HelperResourceTrace(ctx, "Cleared Terraform plan") - - return nil -} - -var errWorkingDirSetConfigNotCalled = fmt.Errorf("must call SetConfig before Init") - -// Init runs "terraform init" for the given working directory, forcing Terraform -// to use the current version of the plugin under test. -func (wd *WorkingDir) Init(ctx context.Context) error { - if wd.configFilename == "" { - return errWorkingDirSetConfigNotCalled - } - if _, err := os.Stat(wd.configFilename); err != nil { - return errWorkingDirSetConfigNotCalled - } - - logging.HelperResourceTrace(ctx, "Calling Terraform CLI init command") - - // -upgrade=true is required for per-TestStep provider version changes - // e.g. TestTest_TestStep_ExternalProviders_DifferentVersions - err := wd.tf.Init(context.Background(), tfexec.Reattach(wd.reattachInfo), tfexec.Upgrade(true)) - - logging.HelperResourceTrace(ctx, "Called Terraform CLI init command") - - return err -} - -func (wd *WorkingDir) planFilename() string { - return filepath.Join(wd.baseDir, PlanFileName) -} - -// CreatePlan runs "terraform plan" to create a saved plan file, which if successful -// will then be used for the next call to Apply. -func (wd *WorkingDir) CreatePlan(ctx context.Context) error { - logging.HelperResourceTrace(ctx, "Calling Terraform CLI plan command") - - hasChanges, err := wd.tf.Plan(context.Background(), tfexec.Reattach(wd.reattachInfo), tfexec.Refresh(false), tfexec.Out(PlanFileName)) - - logging.HelperResourceTrace(ctx, "Called Terraform CLI plan command") - - if err != nil { - return err - } - - if !hasChanges { - logging.HelperResourceTrace(ctx, "Created plan with no changes") - - return nil - } - - stdout, err := wd.SavedPlanRawStdout(ctx) - - if err != nil { - return fmt.Errorf("error retrieving formatted plan output: %w", err) - } - - logging.HelperResourceTrace(ctx, "Created plan with changes", map[string]any{logging.KeyTestTerraformPlan: stdout}) - - return nil -} - -// CreateDestroyPlan runs "terraform plan -destroy" to create a saved plan -// file, which if successful will then be used for the next call to Apply. -func (wd *WorkingDir) CreateDestroyPlan(ctx context.Context) error { - logging.HelperResourceTrace(ctx, "Calling Terraform CLI plan -destroy command") - - hasChanges, err := wd.tf.Plan(context.Background(), tfexec.Reattach(wd.reattachInfo), tfexec.Refresh(false), tfexec.Out(PlanFileName), tfexec.Destroy(true)) - - logging.HelperResourceTrace(ctx, "Called Terraform CLI plan -destroy command") - - if err != nil { - return err - } - - if !hasChanges { - logging.HelperResourceTrace(ctx, "Created destroy plan with no changes") - - return nil - } - - stdout, err := wd.SavedPlanRawStdout(ctx) - - if err != nil { - return fmt.Errorf("error retrieving formatted plan output: %w", err) - } - - logging.HelperResourceTrace(ctx, "Created destroy plan with changes", map[string]any{logging.KeyTestTerraformPlan: stdout}) - - return nil -} - -// Apply runs "terraform apply". If CreatePlan has previously completed -// successfully and the saved plan has not been cleared in the meantime then -// this will apply the saved plan. Otherwise, it will implicitly create a new -// plan and apply it. -func (wd *WorkingDir) Apply(ctx context.Context) error { - args := []tfexec.ApplyOption{tfexec.Reattach(wd.reattachInfo), tfexec.Refresh(false)} - if wd.HasSavedPlan() { - args = append(args, tfexec.DirOrPlan(PlanFileName)) - } - - logging.HelperResourceTrace(ctx, "Calling Terraform CLI apply command") - - err := wd.tf.Apply(context.Background(), args...) - - logging.HelperResourceTrace(ctx, "Called Terraform CLI apply command") - - return err -} - -// Destroy runs "terraform destroy". It does not consider or modify any saved -// plan, and is primarily for cleaning up at the end of a test run. -// -// If destroy fails then remote objects might still exist, and continue to -// exist after a particular test is concluded. -func (wd *WorkingDir) Destroy(ctx context.Context) error { - logging.HelperResourceTrace(ctx, "Calling Terraform CLI destroy command") - - err := wd.tf.Destroy(context.Background(), tfexec.Reattach(wd.reattachInfo), tfexec.Refresh(false)) - - logging.HelperResourceTrace(ctx, "Called Terraform CLI destroy command") - - return err -} - -// HasSavedPlan returns true if there is a saved plan in the working directory. If -// so, a subsequent call to Apply will apply that saved plan. -func (wd *WorkingDir) HasSavedPlan() bool { - _, err := os.Stat(wd.planFilename()) - return err == nil -} - -// SavedPlan returns an object describing the current saved plan file, if any. -// -// If no plan is saved or if the plan file cannot be read, SavedPlan returns -// an error. -func (wd *WorkingDir) SavedPlan(ctx context.Context) (*tfjson.Plan, error) { - if !wd.HasSavedPlan() { - return nil, fmt.Errorf("there is no current saved plan") - } - - logging.HelperResourceTrace(ctx, "Calling Terraform CLI show command for JSON plan") - - plan, err := wd.tf.ShowPlanFile(context.Background(), wd.planFilename(), tfexec.Reattach(wd.reattachInfo)) - - logging.HelperResourceTrace(ctx, "Calling Terraform CLI show command for JSON plan") - - return plan, err -} - -// SavedPlanRawStdout returns a human readable stdout capture of the current saved plan file, if any. -// -// If no plan is saved or if the plan file cannot be read, SavedPlanRawStdout returns -// an error. -func (wd *WorkingDir) SavedPlanRawStdout(ctx context.Context) (string, error) { - if !wd.HasSavedPlan() { - return "", fmt.Errorf("there is no current saved plan") - } - - logging.HelperResourceTrace(ctx, "Calling Terraform CLI show command for stdout plan") - - stdout, err := wd.tf.ShowPlanFileRaw(context.Background(), wd.planFilename(), tfexec.Reattach(wd.reattachInfo)) - - logging.HelperResourceTrace(ctx, "Called Terraform CLI show command for stdout plan") - - if err != nil { - return "", err - } - - return stdout, nil -} - -// State returns an object describing the current state. -// - -// If the state cannot be read, State returns an error. -func (wd *WorkingDir) State(ctx context.Context) (*tfjson.State, error) { - logging.HelperResourceTrace(ctx, "Calling Terraform CLI show command for JSON state") - - state, err := wd.tf.Show(context.Background(), tfexec.Reattach(wd.reattachInfo)) - - logging.HelperResourceTrace(ctx, "Called Terraform CLI show command for JSON state") - - return state, err -} - -// Import runs terraform import -func (wd *WorkingDir) Import(ctx context.Context, resource, id string) error { - logging.HelperResourceTrace(ctx, "Calling Terraform CLI import command") - - err := wd.tf.Import(context.Background(), resource, id, tfexec.Config(wd.baseDir), tfexec.Reattach(wd.reattachInfo)) - - logging.HelperResourceTrace(ctx, "Called Terraform CLI import command") - - return err -} - -// Taint runs terraform taint -func (wd *WorkingDir) Taint(ctx context.Context, address string) error { - logging.HelperResourceTrace(ctx, "Calling Terraform CLI taint command") - - err := wd.tf.Taint(context.Background(), address) - - logging.HelperResourceTrace(ctx, "Called Terraform CLI taint command") - - return err -} - -// Refresh runs terraform refresh -func (wd *WorkingDir) Refresh(ctx context.Context) error { - logging.HelperResourceTrace(ctx, "Calling Terraform CLI refresh command") - - err := wd.tf.Refresh(context.Background(), tfexec.Reattach(wd.reattachInfo)) - - logging.HelperResourceTrace(ctx, "Called Terraform CLI refresh command") - - return err -} - -// Schemas returns an object describing the provider schemas. -// -// If the schemas cannot be read, Schemas returns an error. -func (wd *WorkingDir) Schemas(ctx context.Context) (*tfjson.ProviderSchemas, error) { - logging.HelperResourceTrace(ctx, "Calling Terraform CLI providers schema command") - - providerSchemas, err := wd.tf.ProvidersSchema(context.Background()) - - logging.HelperResourceTrace(ctx, "Called Terraform CLI providers schema command") - - return providerSchemas, err -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 11f0cb2bf..76ec5f675 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -170,6 +170,11 @@ github.com/hashicorp/terraform-plugin-framework/schema/validator github.com/hashicorp/terraform-plugin-framework/tfsdk github.com/hashicorp/terraform-plugin-framework/types github.com/hashicorp/terraform-plugin-framework/types/basetypes +# github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 +## explicit; go 1.19 +github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag +github.com/hashicorp/terraform-plugin-framework-validators/internal/schemavalidator +github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator # github.com/hashicorp/terraform-plugin-go v0.20.0 ## explicit; go 1.20 github.com/hashicorp/terraform-plugin-go/internal/logging @@ -202,10 +207,8 @@ github.com/hashicorp/terraform-plugin-mux/tf5muxserver # github.com/hashicorp/terraform-plugin-sdk/v2 v2.31.0 ## explicit; go 1.20 github.com/hashicorp/terraform-plugin-sdk/v2/diag -github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest github.com/hashicorp/terraform-plugin-sdk/v2/helper/id github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging -github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure @@ -217,7 +220,6 @@ github.com/hashicorp/terraform-plugin-sdk/v2/internal/helper/hashcode github.com/hashicorp/terraform-plugin-sdk/v2/internal/logging github.com/hashicorp/terraform-plugin-sdk/v2/internal/plans/objchange github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugin/convert -github.com/hashicorp/terraform-plugin-sdk/v2/internal/plugintest github.com/hashicorp/terraform-plugin-sdk/v2/internal/tfdiags github.com/hashicorp/terraform-plugin-sdk/v2/meta github.com/hashicorp/terraform-plugin-sdk/v2/plugin diff --git a/website/docs/d/standards_resource_scores.html.markdown b/website/docs/d/standards_resource_scores.html.markdown new file mode 100644 index 000000000..cac22c14f --- /dev/null +++ b/website/docs/d/standards_resource_scores.html.markdown @@ -0,0 +1,55 @@ +--- +layout: "pagerduty" +page_title: "PagerDuty: pagerduty_standards_resource_scores" +sidebar_current: "docs-pagerduty-datasource-standards-resource-scores" +description: |- + Get information about the scores received for the standards associated to a + single resource. +--- + +# pagerduty\_standards\_resource\_scores + +Use this data source to get information about the [scores for the standards of a +resource][1]. + +## Example Usage + +```hcl +data "pagerduty_service" "example" { + name = "My Service" +} + +data "pagerduty_standards_resource_scores" "scores" { + resource_type = "technical_services" + id = data.pagerduty_service.example.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `resource_type` - Type of the object the standards are associated to. Allowed values are `technical_services`. +* `id` - Identifier of said resource. + +## Attributes Reference + +* `score` - Summary of the scores for standards associated with this resource. +* `standards` - The list of standards evaluated against. + +### Score (`score`) is a map with following attributes: + +* `passing` - Number of standards this resource successfully complies to. +* `total` - Number of standards associated to this resource. + +### Standards (`standards`) is a list of objects that support the following: + +* `id` - A unique identifier for the standard. +* `name` - The human-readable name of the standard. +* `active` - Indicates whether the standard is currently active and applicable to the resource. +* `description` - Provides a textual description of the standard. +* `type` - The type of the standard. +* `resource_type` - Specifies the type of resource to which the standard applies. +* `pass` - Indicates whether the resource complies to this standard. + +[1]: https://developer.pagerduty.com/api-reference/f339354b607d5-list-a-resource-s-standards-scores diff --git a/website/docs/d/standards_resources_scores.html.markdown b/website/docs/d/standards_resources_scores.html.markdown new file mode 100644 index 000000000..10aa43888 --- /dev/null +++ b/website/docs/d/standards_resources_scores.html.markdown @@ -0,0 +1,68 @@ +--- +layout: "pagerduty" +page_title: "PagerDuty: pagerduty_standards_resources_scores" +sidebar_current: "docs-pagerduty-datasource-standards-resources-scores" +description: |- + Get information about the scores received for the standards associated to + multiple resources. +--- + +# pagerduty\_standards\_resource\_scores + +Use this data source to get information about the [scores for the standards for +many resources][1]. + +## Example Usage + +```hcl +data "pagerduty_service" "foo" { + name = "foo" +} + +data "pagerduty_service" "bar" { + name = "bar" +} + +data "pagerduty_service" "baz" { + name = "baz" +} + +data "pagerduty_standards_resources_scores" "scores" { + resource_type = "technical_services" + + ids = [ + data.pagerduty_service.foo.id, + data.pagerduty_service.bar.id, + data.pagerduty_service.baz.id, + ] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `resource_type` - Type of the object the standards are associated to. Allowed values are `technical_services`. +* `ids` - List of identifiers of the resources to query. + +## Attributes Reference + +* `resources` - List of score results for each queried resource. + +### Resource (`resources`) is a map with following attributes: + +* `resource_type` - Type of the object the standards are associated to. +* `resource_id` - Unique Identifier. +* `score` - Summary of the scores for standards associated with this resource. + * `passing` - Number of standards this resource successfully complies to. + * `total` - Number of standards associated to this resource. +* `standards` - The list of standards evaluated against. + * `id` - A unique identifier for the standard. + * `name` - The human-readable name of the standard. + * `active` - Indicates whether the standard is currently active and applicable to the resource. + * `description` - Provides a textual description of the standard. + * `type` - The type of the standard. + * `resource_type` - Specifies the type of resource to which the standard applies. + * `pass` - Indicates whether the resource complies to this standard. + +[1]: https://developer.pagerduty.com/api-reference/2e832500ae129-list-resources-standards-scores