Skip to content

Commit

Permalink
Add provider cache offline errors handling (#3527)
Browse files Browse the repository at this point in the history
* add offline errors handling

* Improved handling of offline errors

* Cleanup

* Add test for handling offline errors

* Linter fixes

* Linter fixes

* imports update
  • Loading branch information
denis256 authored Nov 1, 2024
1 parent f32238c commit 326c325
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
27 changes: 26 additions & 1 deletion terraform/cache/handlers/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package handlers
import (
"context"
liberrors "errors"
"strings"
"syscall"

"github.com/gruntwork-io/terragrunt/terraform/cache/models"
Expand Down Expand Up @@ -31,6 +32,15 @@ var availablePlatforms []*models.Platform = []*models.Platform{
{OS: "windows", Arch: "amd64"},
}

var offlineErrors = []error{
syscall.ECONNREFUSED,
syscall.ECONNRESET,
syscall.ECONNABORTED,
syscall.EHOSTUNREACH,
syscall.ENETUNREACH,
syscall.ENETDOWN,
}

// ProviderHandlers is a slice of ProviderHandler.
type ProviderHandlers []ProviderHandler

Expand Down Expand Up @@ -120,7 +130,7 @@ func (handler *CommonProviderHandler) DiscoveryURL(ctx context.Context, registry

urls, err := DiscoveryURL(ctx, registryName)
if err != nil {
if !liberrors.As(err, &NotFoundWellKnownURL{}) && !liberrors.Is(err, syscall.ECONNREFUSED) {
if !IsOfflineError(err) {
return nil, err
}

Expand All @@ -134,3 +144,18 @@ func (handler *CommonProviderHandler) DiscoveryURL(ctx context.Context, registry

return urls, nil
}

// IsOfflineError returns true if the given error is an offline error and can be use default URL.
func IsOfflineError(err error) bool {
if liberrors.As(err, &NotFoundWellKnownURL{}) {
return true
}

for _, connErr := range offlineErrors {
if liberrors.Is(err, connErr) || strings.Contains(err.Error(), connErr.Error()) {
return true
}
}

return false
}
36 changes: 36 additions & 0 deletions terraform/cache/handlers/provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package handlers_test

import (
"errors"
"syscall"
"testing"

"github.com/gruntwork-io/terragrunt/terraform/cache/handlers"

"github.com/stretchr/testify/assert"
)

func TestIsOfflineError(t *testing.T) {
t.Parallel()
testCases := []struct {
err error
expected bool
desc string
}{
{syscall.ECONNREFUSED, true, "connection refused"},
{syscall.ECONNRESET, true, "connection reset by peer"},
{syscall.ECONNABORTED, true, "connection aborted"},
{syscall.ENETUNREACH, true, "network is unreachable"},
{errors.New("get \"https://registry.terraform.io/.well-known/terraform.json\": dial tcp: lookup registry.terraform.io on 185.12.64.1:53: dial udp 185.12.64.1:53: connect: network is unreachable"), true, "network is unreachable"},
{errors.New("get \"https://registry.terraform.io/.well-known/terraform.json\": read tcp 10.10.230.10:58328->10.245.10.15:443: read: connection reset by peer"), true, "network is unreachable"},
{errors.New("random error"), false, "a random error that should not be offline"},
}

for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
t.Parallel()
result := handlers.IsOfflineError(tc.err)
assert.Equal(t, tc.expected, result, "Expected result for %v is %v", tc.desc, tc.expected)
})
}
}

0 comments on commit 326c325

Please sign in to comment.