Skip to content

Commit 4363e46

Browse files
authored
added functionality to retry (#9)
1 parent f9489e9 commit 4363e46

File tree

10 files changed

+116
-26
lines changed

10 files changed

+116
-26
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,19 @@ terraform {
2222
required_providers {
2323
curl2 = {
2424
source = "mehulgohil/curl2"
25-
version = "1.3.1"
25+
version = "1.4.0"
2626
}
2727
}
2828
}
2929
3030
provider "curl2" {
3131
# disable_tls = true
32+
# timeout_ms = 500
33+
# retry {
34+
# retry_attempts = 5
35+
# min_delay_ms = 5
36+
# max_delay_ms = 10
37+
# }
3238
}
3339
3440
data "curl2" "getPosts" {

curl2/client.go

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,55 @@ package curl2
22

33
import (
44
"crypto/tls"
5+
"github.com/hashicorp/go-retryablehttp"
6+
"github.com/hashicorp/terraform-plugin-framework/types"
57
"net/http"
68
"time"
79
)
810

911
type ApiClientOpts struct {
10-
insecure bool
11-
timeout int64
12+
insecure bool
13+
timeout int64
14+
maxRetries int
15+
minDelay types.Int64
16+
maxDelay types.Int64
1217
}
1318

1419
type HttpClient struct {
15-
httpClient *http.Client
20+
httpClient *retryablehttp.Client
1621
}
1722

18-
func NewClient(opts ApiClientOpts) (*HttpClient, error) {
23+
func NewClient(opts ApiClientOpts) *HttpClient {
24+
retryClient := retryablehttp.NewClient()
25+
retryClient.RetryMax = opts.maxRetries
26+
27+
if !opts.minDelay.IsNull() && !opts.minDelay.IsUnknown() && opts.minDelay.ValueInt64() >= 0 {
28+
retryClient.RetryWaitMin = time.Duration(opts.minDelay.ValueInt64()) * time.Millisecond
29+
}
30+
31+
if !opts.maxDelay.IsNull() && !opts.maxDelay.IsUnknown() && opts.maxDelay.ValueInt64() >= 0 {
32+
retryClient.RetryWaitMax = time.Duration(opts.maxDelay.ValueInt64()) * time.Millisecond
33+
}
34+
35+
standardClient := retryClient.StandardClient()
36+
1937
tlsConfig := &tls.Config{
2038
InsecureSkipVerify: opts.insecure,
2139
}
40+
standardClient.Transport = &http.Transport{
41+
TLSClientConfig: tlsConfig,
42+
Proxy: http.ProxyFromEnvironment,
43+
}
2244

2345
tr := &http.Transport{
2446
TLSClientConfig: tlsConfig,
2547
Proxy: http.ProxyFromEnvironment,
2648
}
49+
standardClient.Transport = tr
2750

2851
client := HttpClient{
29-
httpClient: &http.Client{
30-
Timeout: time.Millisecond * time.Duration(opts.timeout),
31-
Transport: tr,
32-
},
52+
httpClient: retryClient,
3353
}
3454

35-
return &client, nil
55+
return &client
3656
}

curl2/data_source.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7+
"github.com/hashicorp/go-retryablehttp"
78
"github.com/hashicorp/terraform-plugin-framework/attr"
89
"github.com/hashicorp/terraform-plugin-framework/datasource"
910
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
1011
"github.com/hashicorp/terraform-plugin-framework/types"
1112
"io"
12-
"net/http"
1313
)
1414

1515
var (
@@ -125,7 +125,7 @@ func (c *curl2DataSource) Read(ctx context.Context, req datasource.ReadRequest,
125125
body = bytes.NewBuffer(requestBody)
126126
}
127127

128-
newReq, err := http.NewRequest(config.HTTPMethod.ValueString(), config.URI.ValueString(), body)
128+
newReq, err := retryablehttp.NewRequest(config.HTTPMethod.ValueString(), config.URI.ValueString(), body)
129129
if err != nil {
130130
resp.Diagnostics.AddError(
131131
"Unable to create new http request",

curl2/provider.go

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
88
"github.com/hashicorp/terraform-plugin-framework/resource"
99
"github.com/hashicorp/terraform-plugin-framework/types"
10+
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
1011
"github.com/hashicorp/terraform-plugin-log/tflog"
1112
)
1213

@@ -22,8 +23,15 @@ type curl2Provider struct{}
2223

2324
// curl2ProviderModel maps provider schema data to a Go type.
2425
type curl2ProviderModel struct {
25-
DisableTLS types.Bool `tfsdk:"disable_tls"`
26-
TimeoutMS types.Int64 `tfsdk:"timeout_ms"`
26+
DisableTLS types.Bool `tfsdk:"disable_tls"`
27+
TimeoutMS types.Int64 `tfsdk:"timeout_ms"`
28+
Retry types.Object `tfsdk:"retry"`
29+
}
30+
31+
type retryModel struct {
32+
RetryAttempts types.Int64 `tfsdk:"retry_attempts"`
33+
MinDelay types.Int64 `tfsdk:"min_delay_ms"`
34+
MaxDelay types.Int64 `tfsdk:"max_delay_ms"`
2735
}
2836

2937
func (c *curl2Provider) Metadata(_ context.Context, _ provider.MetadataRequest, resp *provider.MetadataResponse) {
@@ -44,6 +52,25 @@ func (c *curl2Provider) Schema(_ context.Context, _ provider.SchemaRequest, resp
4452
Description: "Request Timeout in milliseconds. Defaults to 0, no timeout",
4553
},
4654
},
55+
Blocks: map[string]schema.Block{
56+
"retry": schema.SingleNestedBlock{
57+
Description: "Retry request configuration. By default there are no retries.",
58+
Attributes: map[string]schema.Attribute{
59+
"retry_attempts": schema.Int64Attribute{
60+
Description: "The number of times the request is to be retried. For example, if 2 is specified, the request will be tried a maximum of 3 times.",
61+
Optional: true,
62+
},
63+
"min_delay_ms": schema.Int64Attribute{
64+
Description: "The minimum delay between retry requests in milliseconds.",
65+
Optional: true,
66+
},
67+
"max_delay_ms": schema.Int64Attribute{
68+
Description: "The maximum delay between retry requests in milliseconds.",
69+
Optional: true,
70+
},
71+
},
72+
},
73+
},
4774
}
4875
}
4976

@@ -57,18 +84,21 @@ func (c *curl2Provider) Configure(ctx context.Context, req provider.ConfigureReq
5784
return
5885
}
5986

87+
var retry retryModel
88+
89+
if !config.Retry.IsNull() && !config.Retry.IsUnknown() {
90+
diags = config.Retry.As(ctx, &retry, basetypes.ObjectAsOptions{})
91+
resp.Diagnostics.Append(diags...)
92+
if resp.Diagnostics.HasError() {
93+
return
94+
}
95+
}
96+
6097
opts := ApiClientOpts{
6198
insecure: config.DisableTLS.ValueBool(),
6299
timeout: config.TimeoutMS.ValueInt64(),
63100
}
64-
client, err := NewClient(opts)
65-
if err != nil {
66-
resp.Diagnostics.AddError(
67-
"Unable to Create curl2 client",
68-
"Client Error: "+err.Error(),
69-
)
70-
return
71-
}
101+
client := NewClient(opts)
72102

73103
resp.DataSourceData = client
74104
resp.ResourceData = client

docs/data-sources/curl2.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,19 @@ terraform {
1717
required_providers {
1818
curl2 = {
1919
source = "mehulgohil/curl2"
20-
version = "1.3.1"
20+
version = "1.4.0"
2121
}
2222
}
2323
}
2424
2525
provider "curl2" {
2626
# disable_tls = true
2727
# timeout_ms = 500
28+
# retry {
29+
# retry_attempts = 5
30+
# min_delay_ms = 5
31+
# max_delay_ms = 10
32+
# }
2833
}
2934
3035
data "curl2" "getPosts" {

docs/index.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,19 @@ terraform {
1717
required_providers {
1818
curl2 = {
1919
source = "mehulgohil/curl2"
20-
version = "1.3.1"
20+
version = "1.4.0"
2121
}
2222
}
2323
}
2424
2525
provider "curl2" {
2626
# disable_tls = true
2727
# timeout_ms = 500
28+
# retry {
29+
# retry_attempts = 5
30+
# min_delay_ms = 5
31+
# max_delay_ms = 10
32+
# }
2833
}
2934
3035
data "curl2" "getPosts" {
@@ -53,4 +58,14 @@ output "all_posts_status" {
5358
### Optional
5459

5560
- `disable_tls` (Boolean) Use to disable the TLS verification. Defaults to false.
61+
- `retry` (Block, Optional) Retry request configuration. By default there are no retries. (see [below for nested schema](#nestedblock--retry))
5662
- `timeout_ms` (Number) Request Timeout in milliseconds. Defaults to 0, no timeout
63+
64+
<a id="nestedblock--retry"></a>
65+
### Nested Schema for `retry`
66+
67+
Optional:
68+
69+
- `max_delay_ms` (Number) The maximum delay between retry requests in milliseconds.
70+
- `min_delay_ms` (Number) The minimum delay between retry requests in milliseconds.
71+
- `retry_attempts` (Number) The number of times the request is to be retried. For example, if 2 is specified, the request will be tried a maximum of 3 times.

examples/data-sources/curl2/data-source.tf

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@ terraform {
22
required_providers {
33
curl2 = {
44
source = "mehulgohil/curl2"
5-
version = "1.3.1"
5+
version = "1.4.0"
66
}
77
}
88
}
99

1010
provider "curl2" {
1111
# disable_tls = true
1212
# timeout_ms = 500
13+
# retry {
14+
# retry_attempts = 5
15+
# min_delay_ms = 5
16+
# max_delay_ms = 10
17+
# }
1318
}
1419

1520
data "curl2" "getPosts" {

examples/provider/provider.tf

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@ terraform {
22
required_providers {
33
curl2 = {
44
source = "mehulgohil/curl2"
5-
version = "1.3.1"
5+
version = "1.4.0"
66
}
77
}
88
}
99

1010
provider "curl2" {
1111
# disable_tls = true
1212
# timeout_ms = 500
13+
# retry {
14+
# retry_attempts = 5
15+
# min_delay_ms = 5
16+
# max_delay_ms = 10
17+
# }
1318
}
1419

1520
data "curl2" "getPosts" {

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ require (
2323
github.com/hashicorp/go-hclog v1.4.0 // indirect
2424
github.com/hashicorp/go-multierror v1.1.1 // indirect
2525
github.com/hashicorp/go-plugin v1.4.8 // indirect
26+
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
2627
github.com/hashicorp/go-uuid v1.0.3 // indirect
2728
github.com/hashicorp/go-version v1.6.0 // indirect
2829
github.com/hashicorp/hc-install v0.5.0 // indirect

go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,16 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng
7878
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
7979
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
8080
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
81+
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
8182
github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I=
8283
github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
8384
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
8485
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
8586
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
8687
github.com/hashicorp/go-plugin v1.4.8 h1:CHGwpxYDOttQOY7HOWgETU9dyVjOXzniXDqJcYJE1zM=
8788
github.com/hashicorp/go-plugin v1.4.8/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
89+
github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0=
90+
github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
8891
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
8992
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
9093
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=

0 commit comments

Comments
 (0)