Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement customizable request timeout. #88

Merged
merged 2 commits into from
Sep 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ A CLI to help with managing the installation and compilation of terraform provid
- [Terraform Lockfile handling](#terraform-lockfile-handling)
- [Providing custom build commands](#providing-custom-build-commands)
- [Logging](#logging)
- [Timeouts](#timeouts)
- [Development](#development)
- [Testing](#testing)
- [Build](#build)
Expand Down Expand Up @@ -104,6 +105,10 @@ Please refer to the documentation of the provider to find out the build command.

You can enable additional log output by setting the `TF_HELPER_LOG` environment variable to `info` or `debug` log level.

### Timeouts

The `m1-terraform-provider-helper` does make HTTP calls to the terraform provider registry. The default timeout is 10 seconds. You can change that timeout by using the `TF_HELPER_REQUEST_TIMEOUT` environment variable. For example `TF_HELPER_REQUEST_TIMEOUT=15` for a timeout of 15 seconds.

## Development

### Testing
Expand Down
17 changes: 17 additions & 0 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import (
"log"
"os"
"path/filepath"
"strconv"
"strings"

"github.com/sirupsen/logrus"
)

type App struct {
Expand All @@ -20,13 +23,15 @@ type Config struct {
BaseDir string
GoPath string
ProvidersCacheDir string
RequestTimeoutInSeconds int
}

const (
DefaultProvidersCacheDir = "/.m1-terraform-provider-helper"
DefaultTerraformPluginDir = "/.terraform.d/plugins"
DefaultTerraformPluginBackupDir = "/.terraform.d/plugins_backup"
FileModePerm = 0777
DefaultRequestTimeoutInSeconds = 10
)

func New() *App {
Expand All @@ -46,6 +51,18 @@ func New() *App {
Out: os.Stdout,
}

rawValue, ok := os.LookupEnv("TF_HELPER_REQUEST_TIMEOUT")
value := DefaultRequestTimeoutInSeconds

if ok {
value, err = strconv.Atoi(rawValue)
if err != nil {
logrus.Fatalf("Error while trying to parse TF_HELPER_REQUEST_TIMEOUT. It should be a simple integer. Error: %v", err.Error())
}
}

app.Config.RequestTimeoutInSeconds = value

return app
}

Expand Down
8 changes: 3 additions & 5 deletions internal/app/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import (
"github.com/sirupsen/logrus"
)

const requestTimeoutSeconds int = 2

type Provider struct {
Repo string `json:"source"`
Description string `json:"description"`
Expand Down Expand Up @@ -71,10 +69,10 @@ func executeBashCommand(command string, baseDir string) string {
return string(output)
}

func getProviderData(providerName string) (Provider, error) {
func getProviderData(providerName string, requestTimeoutInSeconds int) (Provider, error) {
url := "https://registry.terraform.io/v1/providers/" + providerName

client := &http.Client{Timeout: time.Second * time.Duration(float64(requestTimeoutSeconds))}
client := &http.Client{Timeout: time.Second * time.Duration(float64(requestTimeoutInSeconds))}
ctx := context.Background()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)

Expand Down Expand Up @@ -308,7 +306,7 @@ func getTerraformVersion() *goversion.Version {
func (a *App) Install(providerName string, version string, customBuildCommand string) bool {
fmt.Fprintf(a.Out, "Getting provider data from terraform registry\n")

providerData, err := getProviderData(providerName)
providerData, err := getProviderData(providerName, a.Config.RequestTimeoutInSeconds)

if err != nil {
logrus.Fatalf("Error while trying to get provider data from terraform registry: %v", err.Error())
Expand Down
6 changes: 3 additions & 3 deletions internal/app/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func TestGetProviderData(t *testing.T) {
httpmock.RegisterResponder("GET", "https://registry.terraform.io/v1/providers/"+provider,
httpmock.NewStringResponder(200, `{"description": "`+description+`",
"source": "`+repo+`"}`))
providerData, err := getProviderData(provider)
providerData, err := getProviderData(provider, 2)
if err != nil {
t.Errorf("Should not have an error %s ", err)
}
Expand All @@ -89,7 +89,7 @@ func TestGetProviderData(t *testing.T) {
httpmock.RegisterResponder("GET", "https://registry.terraform.io/v1/providers/"+provider,
httpmock.NewStringResponder(200, `{"description": "`+description+`",
"source": "`+repo+`"}`).Delay(3*time.Second))
_, err := getProviderData(provider)
_, err := getProviderData(provider, 2)
if !strings.HasPrefix(err.Error(), "timeout error") {
t.Errorf("Expected \"error timeout\" but got %#v", err.Error())
}
Expand All @@ -103,7 +103,7 @@ func TestGetProviderData(t *testing.T) {
defer httpmock.DeactivateAndReset()
httpmock.RegisterResponder("GET", "https://registry.terraform.io/v1/providers/"+provider,
httpmock.NewStringResponder(200, `{"test:"812}`))
_, err := getProviderData(provider)
_, err := getProviderData(provider, 2)
if err == nil {
t.Error("Should run into JSON parse error")
}
Expand Down