diff --git a/nomad/resource_csi_volume.go b/nomad/resource_csi_volume.go index 32d05cde..6fcb8770 100644 --- a/nomad/resource_csi_volume.go +++ b/nomad/resource_csi_volume.go @@ -9,9 +9,11 @@ import ( "fmt" "hash/crc32" "log" + "time" "github.com/dustin/go-humanize" "github.com/hashicorp/nomad/api" + "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/hashicorp/terraform-provider-nomad/nomad/helper" @@ -27,6 +29,11 @@ func resourceCSIVolume() *schema.Resource { // normal volume. Read: resourceCSIVolumeRead, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + Schema: map[string]*schema.Schema{ "namespace": { ForceNew: true, @@ -385,15 +392,18 @@ func resourceCSIVolumeCreate(d *schema.ResourceData, meta interface{}) error { if opts.Namespace == "" { opts.Namespace = "default" } - _, _, err = client.CSIVolumes().Create(volume, opts) - if err != nil { - return fmt.Errorf("error creating CSI volume: %s", err) - } - log.Printf("[DEBUG] CSI volume %q created in namespace %q", volume.ID, volume.Namespace) - d.SetId(volume.ID) + return retry.Retry(d.Timeout(schema.TimeoutCreate)-time.Minute, func() *retry.RetryError { + _, _, err = client.CSIVolumes().Create(volume, opts) + if err != nil { + return retry.RetryableError(fmt.Errorf("error creating CSI volume: %s", err)) + } - return resourceCSIVolumeRead(d, meta) // populate other computed attributes + log.Printf("[DEBUG] CSI volume %q created in namespace %q", volume.ID, volume.Namespace) + d.SetId(volume.ID) + + return retry.RetryableError(resourceCSIVolumeRead(d, meta)) // populate other computed attributes + }) } func resourceCSIVolumeDelete(d *schema.ResourceData, meta interface{}) error { @@ -408,10 +418,12 @@ func resourceCSIVolumeDelete(d *schema.ResourceData, meta interface{}) error { if opts.Namespace == "" { opts.Namespace = "default" } - err := client.CSIVolumes().Delete(id, opts) - if err != nil { - return fmt.Errorf("error deleting CSI volume: %s", err) - } - return nil + return retry.Retry(d.Timeout(schema.TimeoutDelete)-time.Minute, func() *retry.RetryError { + err := client.CSIVolumes().Delete(id, opts) + if err != nil { + return retry.RetryableError(fmt.Errorf("error deleting CSI volume: %s", err)) + } + return nil + }) } diff --git a/nomad/resource_csi_volume_registration.go b/nomad/resource_csi_volume_registration.go index 74d86c87..5897dc9a 100644 --- a/nomad/resource_csi_volume_registration.go +++ b/nomad/resource_csi_volume_registration.go @@ -10,8 +10,10 @@ import ( "hash/crc32" "log" "strings" + "time" "github.com/hashicorp/nomad/api" + "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/hashicorp/terraform-provider-nomad/nomad/helper" @@ -24,6 +26,11 @@ func resourceCSIVolumeRegistration() *schema.Resource { Delete: resourceCSIVolumeRegistrationDelete, Read: resourceCSIVolumeRead, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + Schema: map[string]*schema.Schema{ // the following cannot be updated without destroying: // - Namespace/ID @@ -342,15 +349,18 @@ func resourceCSIVolumeRegistrationCreate(d *schema.ResourceData, meta interface{ if opts.Namespace == "" { opts.Namespace = "default" } - _, err = client.CSIVolumes().Register(volume, opts) - if err != nil { - return fmt.Errorf("error registering CSI volume: %s", err) - } - log.Printf("[DEBUG] CSI volume %q registered in namespace %q", volume.ID, volume.Namespace) - d.SetId(volume.ID) + return retry.Retry(d.Timeout(schema.TimeoutCreate)-time.Minute, func() *retry.RetryError { + _, err = client.CSIVolumes().Register(volume, opts) + if err != nil { + return retry.RetryableError(fmt.Errorf("error registering CSI volume: %s", err)) + } + + log.Printf("[DEBUG] CSI volume %q registered in namespace %q", volume.ID, volume.Namespace) + d.SetId(volume.ID) - return resourceCSIVolumeRead(d, meta) // populate other computed attributes + return retry.RetryableError(resourceCSIVolumeRead(d, meta)) // populate other computed attributes + }) } func resourceCSIVolumeRegistrationDelete(d *schema.ResourceData, meta interface{}) error { @@ -374,12 +384,15 @@ func resourceCSIVolumeRegistrationDelete(d *schema.ResourceData, meta interface{ if opts.Namespace == "" { opts.Namespace = "default" } - err := client.CSIVolumes().Deregister(id, true, opts) - if err != nil { - return fmt.Errorf("error deregistering CSI volume: %s", err) - } - return nil + return retry.Retry(d.Timeout(schema.TimeoutDelete)-time.Minute, func() *retry.RetryError { + err := client.CSIVolumes().Deregister(id, true, opts) + if err != nil { + return retry.RetryableError(fmt.Errorf("error deregistering CSI volume: %s", err)) + } + + return nil + }) } func resourceCSIVolumeRead(d *schema.ResourceData, meta interface{}) error { diff --git a/nomad/resource_external_volume.go b/nomad/resource_external_volume.go index a3e1d1ab..24471204 100644 --- a/nomad/resource_external_volume.go +++ b/nomad/resource_external_volume.go @@ -9,9 +9,11 @@ import ( "fmt" "hash/crc32" "log" + "time" "github.com/dustin/go-humanize" "github.com/hashicorp/nomad/api" + "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" ) @@ -28,6 +30,11 @@ func resourceExternalVolume() *schema.Resource { // normal volume. Read: resourceVolumeRead, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + Schema: map[string]*schema.Schema{ "type": { ForceNew: true, @@ -398,15 +405,18 @@ func resourceExternalVolumeCreate(d *schema.ResourceData, meta interface{}) erro if opts.Namespace == "" { opts.Namespace = "default" } - _, _, err = client.CSIVolumes().Create(volume, opts) - if err != nil { - return fmt.Errorf("error creating volume: %s", err) - } - log.Printf("[DEBUG] volume %q created in namespace %q", volume.ID, volume.Namespace) - d.SetId(volume.ID) + return retry.Retry(d.Timeout(schema.TimeoutCreate)-time.Minute, func() *retry.RetryError { + _, _, err = client.CSIVolumes().Create(volume, opts) + if err != nil { + return retry.RetryableError(fmt.Errorf("error creating volume: %s", err)) + } + + log.Printf("[DEBUG] volume %q created in namespace %q", volume.ID, volume.Namespace) + d.SetId(volume.ID) - return resourceVolumeRead(d, meta) // populate other computed attributes + return retry.RetryableError(resourceVolumeRead(d, meta)) // populate other computed attributes + }) } func resourceExternalVolumeDelete(d *schema.ResourceData, meta interface{}) error { @@ -421,10 +431,13 @@ func resourceExternalVolumeDelete(d *schema.ResourceData, meta interface{}) erro if opts.Namespace == "" { opts.Namespace = "default" } - err := client.CSIVolumes().Delete(id, opts) - if err != nil { - return fmt.Errorf("error deleting volume: %s", err) - } - return nil + return retry.Retry(d.Timeout(schema.TimeoutDelete)-time.Minute, func() *retry.RetryError { + err := client.CSIVolumes().Delete(id, opts) + if err != nil { + return retry.RetryableError(fmt.Errorf("error deleting volume: %s", err)) + } + + return nil + }) } diff --git a/nomad/resource_volume.go b/nomad/resource_volume.go index 1f163635..89ed9700 100644 --- a/nomad/resource_volume.go +++ b/nomad/resource_volume.go @@ -11,8 +11,10 @@ import ( "hash/crc32" "log" "strings" + "time" "github.com/hashicorp/nomad/api" + "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" ) @@ -26,6 +28,11 @@ func resourceVolume() *schema.Resource { Delete: resourceVolumeDelete, Read: resourceVolumeRead, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + Schema: map[string]*schema.Schema{ // the following cannot be updated without destroying: // - Namespace/ID @@ -435,15 +442,18 @@ func resourceVolumeCreate(d *schema.ResourceData, meta interface{}) error { if opts.Namespace == "" { opts.Namespace = "default" } - _, err = client.CSIVolumes().Register(volume, opts) - if err != nil { - return fmt.Errorf("error registering volume: %s", err) - } - log.Printf("[DEBUG] volume %q registered in namespace %q", volume.ID, volume.Namespace) - d.SetId(volume.ID) + return retry.Retry(d.Timeout(schema.TimeoutCreate)-time.Minute, func() *retry.RetryError { + _, err = client.CSIVolumes().Register(volume, opts) + if err != nil { + return retry.RetryableError(fmt.Errorf("error registering volume: %s", err)) + } + + log.Printf("[DEBUG] volume %q registered in namespace %q", volume.ID, volume.Namespace) + d.SetId(volume.ID) - return resourceVolumeRead(d, meta) // populate other computed attributes + return retry.RetryableError(resourceVolumeRead(d, meta)) // populate other computed attributes + }) } func resourceVolumeDelete(d *schema.ResourceData, meta interface{}) error { @@ -467,12 +477,15 @@ func resourceVolumeDelete(d *schema.ResourceData, meta interface{}) error { if opts.Namespace == "" { opts.Namespace = "default" } - err := client.CSIVolumes().Deregister(id, true, opts) - if err != nil { - return fmt.Errorf("error deregistering volume: %s", err) - } - return nil + return retry.Retry(d.Timeout(schema.TimeoutDelete)-time.Minute, func() *retry.RetryError { + err := client.CSIVolumes().Deregister(id, true, opts) + if err != nil { + return retry.RetryableError(fmt.Errorf("error deregistering volume: %s", err)) + } + + return nil + }) } func resourceVolumeRead(d *schema.ResourceData, meta interface{}) error { diff --git a/website/docs/r/csi_volume.html.markdown b/website/docs/r/csi_volume.html.markdown index f5af2b93..8a1dab33 100644 --- a/website/docs/r/csi_volume.html.markdown +++ b/website/docs/r/csi_volume.html.markdown @@ -120,3 +120,13 @@ can be referenced: - `nodes_expected`: `(integer)` - `schedulable`: `(boolean)` - `topologies`: `(List of topologies)` + +### Timeouts + +`nomad_csi_volume` provides the following [`Timeouts`][tf_docs_timeouts] +configuration options. + +- `create` `(string: "15m")` - Timeout when creating or updating a new CSI volume. +- `delete` `(string: "15m")` - Timeout when deleting a CSI volume . + +[tf_docs_timeouts]: https://www.terraform.io/docs/configuration/blocks/resources/syntax.html#operation-timeouts diff --git a/website/docs/r/csi_volume_registration.html.markdown b/website/docs/r/csi_volume_registration.html.markdown index abce658e..d15205fc 100644 --- a/website/docs/r/csi_volume_registration.html.markdown +++ b/website/docs/r/csi_volume_registration.html.markdown @@ -119,3 +119,13 @@ can be referenced: - `nodes_expected`: `(integer)` - `schedulable`: `(boolean)` - `topologies`: `(List of topologies)` + +### Timeouts + +`nomad_csi_volume_registration` provides the following +[`Timeouts`][tf_docs_timeouts] configuration options. + +- `create` `(string: "15m")` - Timeout when registering a new CSI volume. +- `delete` `(string: "15m")` - Timeout when deregistering a CSI volume . + +[tf_docs_timeouts]: https://www.terraform.io/docs/configuration/blocks/resources/syntax.html#operation-timeouts diff --git a/website/docs/r/external_volume.html.markdown b/website/docs/r/external_volume.html.markdown index 51096fc4..38454993 100644 --- a/website/docs/r/external_volume.html.markdown +++ b/website/docs/r/external_volume.html.markdown @@ -124,3 +124,13 @@ can be referenced: - `nodes_expected`: `(integer)` - `schedulable`: `(boolean)` - `topologies`: `(List of topologies)` + +### Timeouts + +`nomad_external_volume` provides the following [`Timeouts`][tf_docs_timeouts] +configuration options. + +- `create` `(string: "15m")` - Timeout when creating or updating a new volume. +- `delete` `(string: "15m")` - Timeout when deleting a volume . + +[tf_docs_timeouts]: https://www.terraform.io/docs/configuration/blocks/resources/syntax.html#operation-timeouts diff --git a/website/docs/r/volume.html.markdown b/website/docs/r/volume.html.markdown index 69ecb709..686594a2 100644 --- a/website/docs/r/volume.html.markdown +++ b/website/docs/r/volume.html.markdown @@ -128,3 +128,13 @@ can be referenced: - `nodes_expected`: `(integer)` - `schedulable`: `(boolean)` - `topologies`: `(List of topologies)` + +### Timeouts + +`nomad_volume` provides the following [`Timeouts`][tf_docs_timeouts] +configuration options. + +- `create` `(string: "15m")` - Timeout when registering a new volume. +- `delete` `(string: "15m")` - Timeout when deregistering a volume . + +[tf_docs_timeouts]: https://www.terraform.io/docs/configuration/blocks/resources/syntax.html#operation-timeouts