Skip to content

Commit

Permalink
Adding resolving relative urls to Terragrunt Provider Cache (#3318)
Browse files Browse the repository at this point in the history
* fix: resolve relative url

* chore: code improvements
  • Loading branch information
levkohimins authored Aug 2, 2024
1 parent 8e8192a commit bb1c138
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 13 deletions.
6 changes: 5 additions & 1 deletion cli/provider_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,11 @@ func InitProviderCacheServer(opts *options.TerragruntOptions) (*ProviderCache, e
case *cliconfig.ProviderInstallationFilesystemMirror:
providerHandlers = append(providerHandlers, handlers.NewProviderFilesystemMirrorHandler(providerService, cacheProviderHTTPStatusCode, method))
case *cliconfig.ProviderInstallationNetworkMirror:
providerHandlers = append(providerHandlers, handlers.NewProviderNetworkMirrorHandler(providerService, cacheProviderHTTPStatusCode, method, cliCfg.CredentialsSource()))
networkMirrorHandler, err := handlers.NewProviderNetworkMirrorHandler(providerService, cacheProviderHTTPStatusCode, method, cliCfg.CredentialsSource())
if err != nil {
return nil, err
}
providerHandlers = append(providerHandlers, networkMirrorHandler)
case *cliconfig.ProviderInstallationDirect:
providerHandlers = append(providerHandlers, handlers.NewProviderDirectHandler(providerService, cacheProviderHTTPStatusCode, method, cliCfg.CredentialsSource()))
directIsdefined = true
Expand Down
2 changes: 1 addition & 1 deletion terraform/cache/handlers/provider_direct.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (handler *ProviderDirectHandler) GetPlatform(ctx echo.Context, provider *mo
return err
}

provider.ResponseBody = body
provider.ResponseBody = body.ResolveRelativeReferences(resp.Request.URL)

handler.providerService.CacheProvider(ctx.Request().Context(), cacheRequestID, provider)
return ctx.NoContent(handler.cacheProviderHTTPStatusCode)
Expand Down
26 changes: 15 additions & 11 deletions terraform/cache/handlers/provider_network_mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package handlers
import (
"fmt"
"net/http"
"net/url"
"path"
"path/filepath"
"strings"
Expand All @@ -23,19 +24,24 @@ type ProviderNetworkMirrorHandler struct {
*http.Client
providerService *services.ProviderService
cacheProviderHTTPStatusCode int
networkMirrorURL string
networkMirrorURL *url.URL
credsSource *cliconfig.CredentialsSource
}

func NewProviderNetworkMirrorHandler(providerService *services.ProviderService, cacheProviderHTTPStatusCode int, networkMirror *cliconfig.ProviderInstallationNetworkMirror, credsSource *cliconfig.CredentialsSource) ProviderHandler {
func NewProviderNetworkMirrorHandler(providerService *services.ProviderService, cacheProviderHTTPStatusCode int, networkMirror *cliconfig.ProviderInstallationNetworkMirror, credsSource *cliconfig.CredentialsSource) (ProviderHandler, error) {
networkMirrorURL, err := url.Parse(networkMirror.URL)
if err != nil {
return nil, errors.WithStackTrace(err)
}

return &ProviderNetworkMirrorHandler{
CommonProviderHandler: NewCommonProviderHandler(networkMirror.Include, networkMirror.Exclude),
Client: &http.Client{},
providerService: providerService,
cacheProviderHTTPStatusCode: cacheProviderHTTPStatusCode,
networkMirrorURL: networkMirror.URL,
networkMirrorURL: networkMirrorURL,
credsSource: credsSource,
}
}, nil
}

func (handler *ProviderNetworkMirrorHandler) String() string {
Expand Down Expand Up @@ -90,14 +96,12 @@ func (handler *ProviderNetworkMirrorHandler) GetPlatform(ctx echo.Context, provi
}

if archive, ok := mirrorData.Archives[provider.Platform()]; ok {
if !strings.HasPrefix(archive.URL, "http") {
archive.URL = fmt.Sprintf("%s/%s", strings.TrimRight(handler.networkMirrorURL, "/"), path.Join(provider.RegistryName, provider.Namespace, provider.Name, archive.URL))
}

provider.ResponseBody = &models.ResponseBody{
provider.ResponseBody = (&models.ResponseBody{
Filename: filepath.Base(archive.URL),
DownloadURL: archive.URL,
}
}).ResolveRelativeReferences(handler.networkMirrorURL.ResolveReference(&url.URL{
Path: path.Join(handler.networkMirrorURL.Path, provider.Address()),
}))
} else {
return ctx.NoContent(http.StatusNotFound)
}
Expand All @@ -113,7 +117,7 @@ func (handler *ProviderNetworkMirrorHandler) Download(ctx echo.Context, provider
}

func (handler *ProviderNetworkMirrorHandler) do(ctx echo.Context, method, reqPath string, value any) error {
reqURL := fmt.Sprintf("%s/%s", strings.TrimRight(handler.networkMirrorURL, "/"), reqPath)
reqURL := fmt.Sprintf("%s/%s", strings.TrimRight(handler.networkMirrorURL.String(), "/"), reqPath)

req, err := http.NewRequestWithContext(ctx.Request().Context(), method, reqURL, nil)
if err != nil {
Expand Down
14 changes: 14 additions & 0 deletions terraform/cache/models/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package models

import (
"net/url"
"path"
"strings"
)

func resolveRelativeReference(base *url.URL, link string) string {
if link != "" && !strings.HasPrefix(link, base.Scheme) {
link = base.ResolveReference(&url.URL{Path: path.Join(base.Path, link)}).String()
}
return link
}
8 changes: 8 additions & 0 deletions terraform/cache/models/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package models

import (
"fmt"
"net/url"
"path"
"strings"
)
Expand Down Expand Up @@ -73,6 +74,13 @@ type ResponseBody struct {
SigningKeys SigningKeyList `json:"signing_keys,omitempty"`
}

func (body ResponseBody) ResolveRelativeReferences(base *url.URL) *ResponseBody {
body.DownloadURL = resolveRelativeReference(base, body.DownloadURL)
body.SHA256SumsSignatureURL = resolveRelativeReference(base, body.SHA256SumsSignatureURL)
body.SHA256SumsURL = resolveRelativeReference(base, body.SHA256SumsURL)
return &body
}

// Provider represents the details of the Terraform provider.
type Provider struct {
*ResponseBody
Expand Down
61 changes: 61 additions & 0 deletions terraform/cache/models/provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package models

import (
"fmt"
"net/url"
"testing"

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

func TestResolveRelativeReferences(t *testing.T) {
t.Parallel()

testCases := []struct {
baseURL string
body ResponseBody
expectedResolved ResponseBody
}{
{
"https://releases.hashicorp.com/terraform-provider-local/2.5.1",
ResponseBody{
DownloadURL: "terraform-provider-local_2.5.1_darwin_amd64.zip",
SHA256SumsURL: "terraform-provider-local_2.5.1_SHA256SUMS",
SHA256SumsSignatureURL: "terraform-provider-local_2.5.1_SHA256SUMS.72D7468F.sig",
},
ResponseBody{
DownloadURL: "https://releases.hashicorp.com/terraform-provider-local/2.5.1/terraform-provider-local_2.5.1_darwin_amd64.zip",
SHA256SumsURL: "https://releases.hashicorp.com/terraform-provider-local/2.5.1/terraform-provider-local_2.5.1_SHA256SUMS",
SHA256SumsSignatureURL: "https://releases.hashicorp.com/terraform-provider-local/2.5.1/terraform-provider-local_2.5.1_SHA256SUMS.72D7468F.sig",
},
},
{
"https://somehost.com",
ResponseBody{
DownloadURL: "https://releases.hashicorp.com/terraform-provider-local/2.5.1/terraform-provider-local_2.5.1_darwin_amd64.zip",
SHA256SumsURL: "https://releases.hashicorp.com/terraform-provider-local/2.5.1/terraform-provider-local_2.5.1_SHA256SUMS",
SHA256SumsSignatureURL: "https://releases.hashicorp.com/terraform-provider-local/2.5.1/terraform-provider-local_2.5.1_SHA256SUMS.72D7468F.sig",
},
ResponseBody{
DownloadURL: "https://releases.hashicorp.com/terraform-provider-local/2.5.1/terraform-provider-local_2.5.1_darwin_amd64.zip",
SHA256SumsURL: "https://releases.hashicorp.com/terraform-provider-local/2.5.1/terraform-provider-local_2.5.1_SHA256SUMS",
SHA256SumsSignatureURL: "https://releases.hashicorp.com/terraform-provider-local/2.5.1/terraform-provider-local_2.5.1_SHA256SUMS.72D7468F.sig",
},
},
}

for i, testCase := range testCases {
testCase := testCase

t.Run(fmt.Sprintf("testCase-%d", i), func(t *testing.T) {
t.Parallel()

baseURL, err := url.Parse(testCase.baseURL)
require.NoError(t, err)

actualResolved := testCase.body.ResolveRelativeReferences(baseURL)
assert.Equal(t, testCase.expectedResolved, *actualResolved)
})
}
}

0 comments on commit bb1c138

Please sign in to comment.