Skip to content

Commit

Permalink
Adding optional request_timeout attribute (#149)
Browse files Browse the repository at this point in the history
  • Loading branch information
bendbennett committed Jul 5, 2022
1 parent 0c64a2c commit e1f8d05
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 3 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.17
require (
github.com/hashicorp/terraform-plugin-docs v0.12.0
github.com/hashicorp/terraform-plugin-framework v0.9.0
github.com/hashicorp/terraform-plugin-framework-validators v0.3.0
github.com/hashicorp/terraform-plugin-go v0.9.1
github.com/hashicorp/terraform-plugin-sdk/v2 v2.17.0
)
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ github.com/hashicorp/terraform-plugin-docs v0.12.0 h1:EAvFVEoV/wj15t/VSeKVpnAd+B
github.com/hashicorp/terraform-plugin-docs v0.12.0/go.mod h1:HVn60yjtl4XxLINPgNmPCwX8SQ4T99Ut9CTD/ac6i5w=
github.com/hashicorp/terraform-plugin-framework v0.9.0 h1:vOKG9+keJv062zGhXFgfOFEuGcfgV6LHciwleFTSek0=
github.com/hashicorp/terraform-plugin-framework v0.9.0/go.mod h1:ActelD2V6yt2m0MwIX4jESGDYJ573rAvZswGjSGm1rY=
github.com/hashicorp/terraform-plugin-framework-validators v0.3.0 h1:4gunYb8S4b2shVsL+1oS0ank+XBmUCxWwNz3cof+fXo=
github.com/hashicorp/terraform-plugin-framework-validators v0.3.0/go.mod h1:c1czSXzBmpJNhS/0WXTNPzUU8kHrHLLyrW8rXoFD0fs=
github.com/hashicorp/terraform-plugin-go v0.9.1 h1:vXdHaQ6aqL+OF076nMSBV+JKPdmXlzG5mzVDD04WyPs=
github.com/hashicorp/terraform-plugin-go v0.9.1/go.mod h1:ItjVSlQs70otlzcCwlPcU8FRXLdO973oYFRZwAOxy8M=
github.com/hashicorp/terraform-plugin-log v0.4.0/go.mod h1:9KclxdunFownr4pIm1jdmwKRmE4d6HVG2c9XDq47rpg=
Expand Down
66 changes: 66 additions & 0 deletions internal/provider/data_source_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,46 @@ package provider

import (
"context"
"errors"
"fmt"
"io/ioutil"
"mime"
"net/http"
"regexp"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
)

<<<<<<< HEAD:internal/datasources/http/data_source_http.go
<<<<<<< HEAD:internal/provider/data_source_http.go
var _ tfsdk.DataSourceType = (*httpDataSourceType)(nil)

type httpDataSourceType struct{}

func (d *httpDataSourceType) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) {
=======
func NewDataSourceType() *dataSourceType {
return &dataSourceType{}
}

var _ tfsdk.DataSourceType = (*dataSourceType)(nil)
=======
var _ tfsdk.DataSourceType = (*httpDataSourceType)(nil)
>>>>>>> fb278fb (Refactoring location of data source and using NewProtocol6WithError for tests (#93)):internal/provider/data_source_http.go

type httpDataSourceType struct{}

<<<<<<< HEAD:internal/datasources/http/data_source_http.go
func (d *dataSourceType) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) {
>>>>>>> 4f01898 (Refactoring layout (#93)):internal/datasources/http/data_source_http.go
=======
func (d *httpDataSourceType) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) {
>>>>>>> fb278fb (Refactoring location of data source and using NewProtocol6WithError for tests (#93)):internal/provider/data_source_http.go
return tfsdk.Schema{
Description: `
The ` + "`http`" + ` data source makes an HTTP GET request to the given URL and exports
Expand Down Expand Up @@ -49,6 +72,15 @@ your control should be treated as untrustworthy.`,
Optional: true,
},

"request_timeout": {
Description: "The request timeout in milliseconds.",
Type: types.Int64Type,
Optional: true,
Validators: []tfsdk.AttributeValidator{
int64validator.AtLeast(1),
},
},

"response_body": {
Description: "The response body returned as a string.",
Type: types.StringType,
Expand Down Expand Up @@ -79,15 +111,36 @@ your control should be treated as untrustworthy.`,
}, nil
}

<<<<<<< HEAD:internal/datasources/http/data_source_http.go
<<<<<<< HEAD:internal/provider/data_source_http.go
func (d *httpDataSourceType) NewDataSource(context.Context, tfsdk.Provider) (tfsdk.DataSource, diag.Diagnostics) {
return &httpDataSource{}, nil
}

var _ tfsdk.DataSource = (*httpDataSource)(nil)

type httpDataSource struct{}

func (d *httpDataSource) Read(ctx context.Context, req tfsdk.ReadDataSourceRequest, resp *tfsdk.ReadDataSourceResponse) {
=======
func (d *dataSourceType) NewDataSource(context.Context, tfsdk.Provider) (tfsdk.DataSource, diag.Diagnostics) {
return &dataSource{}, nil
=======
func (d *httpDataSourceType) NewDataSource(context.Context, tfsdk.Provider) (tfsdk.DataSource, diag.Diagnostics) {
return &httpDataSource{}, nil
>>>>>>> fb278fb (Refactoring location of data source and using NewProtocol6WithError for tests (#93)):internal/provider/data_source_http.go
}

var _ tfsdk.DataSource = (*httpDataSource)(nil)

type httpDataSource struct{}

<<<<<<< HEAD:internal/datasources/http/data_source_http.go
func (d *dataSource) Read(ctx context.Context, req tfsdk.ReadDataSourceRequest, resp *tfsdk.ReadDataSourceResponse) {
>>>>>>> 4f01898 (Refactoring layout (#93)):internal/datasources/http/data_source_http.go
=======
func (d *httpDataSource) Read(ctx context.Context, req tfsdk.ReadDataSourceRequest, resp *tfsdk.ReadDataSourceResponse) {
>>>>>>> fb278fb (Refactoring location of data source and using NewProtocol6WithError for tests (#93)):internal/provider/data_source_http.go
var model modelV0
diags := req.Config.Get(ctx, &model)
resp.Diagnostics.Append(diags...)
Expand All @@ -97,6 +150,10 @@ func (d *httpDataSource) Read(ctx context.Context, req tfsdk.ReadDataSourceReque

url := model.URL.Value
headers := model.RequestHeaders
timeout := model.RequestTimeout

ctx, cancel := context.WithTimeout(ctx, time.Duration(timeout.Value)*time.Millisecond)
defer cancel()

client := &http.Client{}

Expand All @@ -122,6 +179,14 @@ func (d *httpDataSource) Read(ctx context.Context, req tfsdk.ReadDataSourceReque

response, err := client.Do(request)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
resp.Diagnostics.AddError(
"Error making request",
fmt.Sprintf("The request exceeded the specified timeout: %d ms", timeout.Value),
)
return
}

resp.Diagnostics.AddError(
"Error making request",
fmt.Sprintf("Error making request: %s", err),
Expand Down Expand Up @@ -204,6 +269,7 @@ type modelV0 struct {
ID types.String `tfsdk:"id"`
URL types.String `tfsdk:"url"`
RequestHeaders types.Map `tfsdk:"request_headers"`
RequestTimeout types.Int64 `tfsdk:"request_timeout"`
ResponseHeaders types.Map `tfsdk:"response_headers"`
ResponseBody types.String `tfsdk:"response_body"`
StatusCode types.Int64 `tfsdk:"status_code"`
Expand Down
25 changes: 25 additions & 0 deletions internal/provider/data_source_http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"regexp"
"testing"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)
Expand Down Expand Up @@ -216,6 +218,25 @@ func TestDataSource_UpgradeFromVersion2_2_0(t *testing.T) {
})
}

func TestDataSource_Timeout(t *testing.T) {
testHttpMock := setUpMockHttpServer()
defer testHttpMock.server.Close()

resource.UnitTest(t, resource.TestCase{
ProtoV6ProviderFactories: protoV6ProviderFactories(),
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
data "http" "http_test" {
url = "%s/slow/200"
request_timeout = 5
}`, testHttpMock.server.URL),
ExpectError: regexp.MustCompile(`The request exceeded the specified timeout: 5 ms`),
},
},
})
}

type TestHttpMock struct {
server *httptest.Server
}
Expand Down Expand Up @@ -251,6 +272,10 @@ func setUpMockHttpServer() *TestHttpMock {
w.Header().Set("Content-Type", "application/x-x509-ca-cert")
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("pem"))
case "/slow/200":
time.Sleep(time.Duration(10) * time.Millisecond)
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("1.0.0"))
default:
w.WriteHeader(http.StatusNotFound)
}
Expand Down
7 changes: 4 additions & 3 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import (
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
)

func New() tfsdk.Provider {
return &provider{}
type provider struct {
}

var _ tfsdk.Provider = (*provider)(nil)

type provider struct{}
func New() tfsdk.Provider {
return &provider{}
}

func (p *provider) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) {
return tfsdk.Schema{}, nil
Expand Down
6 changes: 6 additions & 0 deletions internal/provider/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import (
//nolint:unparam
func protoV6ProviderFactories() map[string]func() (tfprotov6.ProviderServer, error) {
return map[string]func() (tfprotov6.ProviderServer, error){
<<<<<<< HEAD
"http": providerserver.NewProtocol6WithError(New()),
=======
"http": func() (tfprotov6.ProviderServer, error) {
return providerserver.NewProtocol6WithError(New())()
},
>>>>>>> fb278fb (Refactoring location of data source and using NewProtocol6WithError for tests (#93))
}
}

0 comments on commit e1f8d05

Please sign in to comment.