diff --git a/README.md b/README.md
index 60931919..d3c2e600 100644
--- a/README.md
+++ b/README.md
@@ -808,6 +808,24 @@ See [advanced remote configuration](#advanced-remote-configuration) for more det
+TOFUENV_REMOTE_PASSWORD
+
+String (Default: "")
+
+Could be used with TOFUENV_REMOTE_USER to specify HTTP basic auth when same credential are used with TOFUENV_REMOTE and TOFUENV_LIST_URL (instead of `https://user:password@host.org` URL format).
+
+
+
+
+TOFUENV_REMOTE_USER
+
+String (Default: "")
+
+Could be used with TOFUENV_REMOTE_PASSWORD to specify HTTP basic auth when same credential are used with TOFUENV_REMOTE and TOFUENV_LIST_URL (instead of `https://user:password@host.org` URL format).
+
+
+
+
TOFUENV_ROOT
Same as TENV_ROOT (compatibility with [tofuenv](https://github.com/tofuutils/tofuenv)).
@@ -817,10 +835,10 @@ Same as TENV_ROOT (compatibility with [tofuenv](https://github.com/tofuutils/tof
TOFUENV_URL_TEMPLATE
-String (Default: "https://github.com/opentofu/opentofu/releases/download/v{{ .Version }}/{{ .Artifact }}")
-
-
+String (Default: `https://github.com/opentofu/opentofu/releases/download/v{{ .Version }}/{{ .Artifact }}`)
+Used when TOFUENV_INSTALL_MODE is "mirror" (see [TofuDL mirror specification](https://github.com/opentofu/tofudl/blob/mirror-spec/MIRROR-SPECIFICATION.md)).
+
@@ -959,6 +977,24 @@ See [advanced remote configuration](#advanced-remote-configuration) for more det
+TFENV_REMOTE_PASSWORD
+
+String (Default: "")
+
+Could be used with TFENV_REMOTE_USER to specify HTTP basic auth when same credential are used with TFENV_REMOTE and TFENV_LIST_URL (instead of `https://user:password@host.org` URL format).
+
+
+
+
+TFENV_REMOTE_USER
+
+String (Default: "")
+
+Could be used with TFENV_REMOTE_PASSWORD to specify HTTP basic auth when same credential are used with TFENV_REMOTE and TFENV_LIST_URL (instead of `https://user:password@host.org` URL format).
+
+
+
+
TFENV_ROOT
Same as TENV_ROOT (compatibility with [tfenv](https://github.com/tfutils/tfenv)).
@@ -1065,6 +1101,25 @@ See [advanced remote configuration](#advanced-remote-configuration) for more det
+
+TG_REMOTE_PASSWORD
+
+String (Default: "")
+
+Could be used with TG_REMOTE_USER to specify HTTP basic auth when same credential are used with TG_REMOTE and TG_LIST_URL (instead of `https://user:password@host.org` URL format).
+
+
+
+
+TG_REMOTE_USER
+
+String (Default: "")
+
+Could be used with TG_REMOTE_PASSWORD to specify HTTP basic auth when same credential are used with TG_REMOTE and TG_LIST_URL (instead of `https://user:password@host.org` URL format).
+
+
+
+
TG_DEFAULT_CONSTRAINT
String (Default: "")
@@ -1158,6 +1213,25 @@ See [advanced remote configuration](#advanced-remote-configuration) for more det
+
+ATMOS_REMOTE_PASSWORD
+
+String (Default: "")
+
+Could be used with ATMOS_REMOTE_USER to specify HTTP basic auth when same credential are used with ATMOS_REMOTE and ATMOS_LIST_URL (instead of `https://user:password@host.org` URL format).
+
+
+
+
+ATMOS_REMOTE_USER
+
+String (Default: "")
+
+Could be used with ATMOS_REMOTE_PASSWORD to specify HTTP basic auth when same credential are used with ATMOS_REMOTE and ATMOS_LIST_URL (instead of `https://user:password@host.org` URL format).
+
+
+
+
ATMOS_DEFAULT_CONSTRAINT
String (Default: "")
diff --git a/config/config.go b/config/config.go
index 0f46b465..c7c56072 100644
--- a/config/config.go
+++ b/config/config.go
@@ -47,7 +47,9 @@ const (
listURLEnvName = "LIST_URL"
logEnvName = "LOG"
quietEnvName = "QUIET"
+ remotePassEnvName = "REMOTE_PASSWORD"
remoteURLEnvName = "REMOTE"
+ remoteUserEnvName = "REMOTE_USER"
rootPathEnvName = "ROOT"
tokenEnvName = "GITHUB_TOKEN" //nolint
version = "VERSION"
@@ -58,7 +60,9 @@ const (
atmosInstallModeEnvName = atmosPrefix + installModeEnvName
atmosListModeEnvName = atmosPrefix + listModeEnvName
atmosListURLEnvName = atmosPrefix + listURLEnvName
+ AtmosRemotePassEnvName = atmosPrefix + remotePassEnvName
AtmosRemoteURLEnvName = atmosPrefix + remoteURLEnvName
+ AtmosRemoteUserEnvName = atmosPrefix + remoteUserEnvName
AtmosVersionEnvName = atmosPrefix + version
tenvPrefix = "TENV_"
@@ -82,7 +86,9 @@ const (
tfInstallModeEnvName = tfenvPrefix + installModeEnvName
tfListModeEnvName = tfenvPrefix + listModeEnvName
tfListURLEnvName = tfenvPrefix + listURLEnvName
+ TfRemotePassEnvName = tfenvPrefix + remotePassEnvName
TfRemoteURLEnvName = tfenvPrefix + remoteURLEnvName
+ TfRemoteUserEnvName = tfenvPrefix + remoteUserEnvName
tfRootPathEnvName = tfenvPrefix + rootPathEnvName
TfVersionEnvName = tfenvTerraformPrefix + version
@@ -92,7 +98,9 @@ const (
tgInstallModeEnvName = tgPrefix + installModeEnvName
tgListModeEnvName = tgPrefix + listModeEnvName
tgListURLEnvName = tgPrefix + listURLEnvName
+ TgRemotePassEnvName = tgPrefix + remotePassEnvName
TgRemoteURLEnvName = tgPrefix + remoteURLEnvName
+ TgRemoteUserEnvName = tgPrefix + remoteUserEnvName
TgVersionEnvName = tgPrefix + version
tofuenvPrefix = "TOFUENV_"
@@ -106,7 +114,9 @@ const (
tofuListModeEnvName = tofuenvPrefix + listModeEnvName
tofuListURLEnvName = tofuenvPrefix + listURLEnvName
tofuOpenTofuPGPKeyEnvName = tofuenvPrefix + "OPENTOFU_PGP_KEY"
+ TofuRemotePassEnvName = tofuenvPrefix + remotePassEnvName
TofuRemoteURLEnvName = tofuenvPrefix + remoteURLEnvName
+ TofuRemoteUserEnvName = tofuenvPrefix + remoteUserEnvName
tofuRootPathEnvName = tofuenvPrefix + rootPathEnvName
tofuTokenEnvName = tofuenvPrefix + tokenEnvName
TofuURLTemplateEnvName = tofuenvPrefix + "URL_TEMPLATE"
diff --git a/config/remote.go b/config/remote.go
index 02dc6a9a..0c0b7055 100644
--- a/config/remote.go
+++ b/config/remote.go
@@ -22,6 +22,8 @@ import (
"errors"
"os"
"strings"
+
+ "github.com/tofuutils/tenv/v3/pkg/download"
)
const (
@@ -135,3 +137,12 @@ func MapGetDefault(m map[string]string, key string, defaultValue string) string
return defaultValue
}
+
+func GetBasicAuthOption(userEnvName string, passEnvName string) []download.RequestOption {
+ username, password := os.Getenv(userEnvName), os.Getenv(passEnvName)
+ if username == "" || password == "" {
+ return nil
+ }
+
+ return []download.RequestOption{download.WithBasicAuth(username, password)}
+}
diff --git a/go.mod b/go.mod
index 45984faf..8f68a4f5 100644
--- a/go.mod
+++ b/go.mod
@@ -52,11 +52,11 @@ require (
github.com/sahilm/fuzzy v0.1.1 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
- golang.org/x/crypto v0.25.0 // indirect
- golang.org/x/mod v0.19.0 // indirect
- golang.org/x/net v0.27.0 // indirect
- golang.org/x/sync v0.7.0 // indirect
- golang.org/x/sys v0.22.0 // indirect
- golang.org/x/text v0.16.0 // indirect
- golang.org/x/tools v0.23.0 // indirect
+ golang.org/x/crypto v0.26.0 // indirect
+ golang.org/x/mod v0.20.0 // indirect
+ golang.org/x/net v0.28.0 // indirect
+ golang.org/x/sync v0.8.0 // indirect
+ golang.org/x/sys v0.24.0 // indirect
+ golang.org/x/text v0.17.0 // indirect
+ golang.org/x/tools v0.24.0 // indirect
)
diff --git a/go.sum b/go.sum
index 6684ea8d..c9aa7128 100644
--- a/go.sum
+++ b/go.sum
@@ -119,14 +119,14 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
-golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
-golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
+golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
+golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
-golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
+golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
@@ -134,13 +134,13 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
-golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
-golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
+golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
-golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -158,8 +158,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
-golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
+golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
@@ -173,14 +173,14 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
-golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
+golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
-golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
+golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
+golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/pkg/download/download.go b/pkg/download/download.go
index 0f9b62ff..37c74b61 100644
--- a/pkg/download/download.go
+++ b/pkg/download/download.go
@@ -19,11 +19,14 @@
package download
import (
+ "encoding/json"
"io"
"net/http"
"net/url"
)
+type RequestOption = func(*http.Request) *http.Request
+
func ApplyUrlTranformer(urlTransformer func(string) (string, error), baseURLs ...string) ([]string, error) {
transformedURLs := make([]string, 0, len(baseURLs))
for _, baseURL := range baseURLs {
@@ -38,10 +41,19 @@ func ApplyUrlTranformer(urlTransformer func(string) (string, error), baseURLs ..
return transformedURLs, nil
}
-func Bytes(url string, display func(string)) ([]byte, error) {
+func Bytes(url string, display func(string), requestOptions ...RequestOption) ([]byte, error) {
display("Downloading " + url)
- response, err := http.Get(url) //nolint
+ request, err := http.NewRequest(http.MethodGet, url, http.NoBody)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, option := range requestOptions {
+ request = option(request)
+ }
+
+ response, err := http.DefaultClient.Do(request)
if err != nil {
return nil, err
}
@@ -50,6 +62,20 @@ func Bytes(url string, display func(string)) ([]byte, error) {
return io.ReadAll(response.Body)
}
+func JSON(url string, display func(string), requestOptions ...RequestOption) (any, error) {
+ data, err := Bytes(url, display, requestOptions...)
+ if err != nil {
+ return nil, err
+ }
+
+ var value any
+ err = json.Unmarshal(data, &value)
+
+ return value, err
+}
+
+func NoDisplay(string) {}
+
func UrlTranformer(rewriteRule []string) func(string) (string, error) {
if len(rewriteRule) < 2 {
return noTransform
@@ -71,6 +97,14 @@ func UrlTranformer(rewriteRule []string) func(string) (string, error) {
}
}
+func WithBasicAuth(username string, password string) RequestOption {
+ return func(r *http.Request) *http.Request {
+ r.SetBasicAuth(username, password)
+
+ return r
+ }
+}
+
func noTransform(value string) (string, error) {
return value, nil
}
diff --git a/pkg/github/github.go b/pkg/github/github.go
index e372c6bc..6c532d07 100644
--- a/pkg/github/github.go
+++ b/pkg/github/github.go
@@ -19,14 +19,13 @@
package github
import (
- "encoding/json"
"errors"
- "io"
"net/http"
"net/url"
"strconv"
"github.com/tofuutils/tenv/v3/pkg/apimsg"
+ "github.com/tofuutils/tenv/v3/pkg/download"
versionfinder "github.com/tofuutils/tenv/v3/versionmanager/semantic/finder"
)
@@ -113,32 +112,15 @@ func ListReleases(githubReleaseURL string, githubToken string) ([]string, error)
}
func apiGetRequest(callURL string, authorizationHeader string) (any, error) {
- request, err := http.NewRequest(http.MethodGet, callURL, nil)
- if err != nil {
- return nil, err
- }
-
- request.Header.Set("Accept", "application/vnd.github+json")
- if authorizationHeader != "" {
- request.Header.Set("Authorization", authorizationHeader)
- }
- request.Header.Set("X-GitHub-Api-Version", "2022-11-28")
-
- response, err := http.DefaultClient.Do(request)
- if err != nil {
- return nil, err
- }
- defer response.Body.Close()
-
- data, err := io.ReadAll(response.Body)
- if err != nil {
- return nil, err
- }
-
- var value any
- err = json.Unmarshal(data, &value)
+ return download.JSON(callURL, download.NoDisplay, func(request *http.Request) *http.Request {
+ request.Header.Set("Accept", "application/vnd.github+json")
+ if authorizationHeader != "" {
+ request.Header.Set("Authorization", authorizationHeader)
+ }
+ request.Header.Set("X-GitHub-Api-Version", "2022-11-28")
- return value, err
+ return request
+ })
}
func buildAuthorizationHeader(token string) string {
diff --git a/pkg/htmlquery/html.go b/pkg/htmlquery/html.go
index 47571871..79c9ff6a 100644
--- a/pkg/htmlquery/html.go
+++ b/pkg/htmlquery/html.go
@@ -19,21 +19,21 @@
package htmlquery
import (
- "io"
- "net/http"
+ "bytes"
"strings"
"github.com/PuerkitoBio/goquery"
+
+ "github.com/tofuutils/tenv/v3/pkg/download"
)
-func Request(callURL string, selector string, extractor func(*goquery.Selection) string) ([]string, error) {
- response, err := http.Get(callURL)
+func Request(callURL string, selector string, extractor func(*goquery.Selection) string, ro ...download.RequestOption) ([]string, error) {
+ data, err := download.Bytes(callURL, download.NoDisplay, ro...)
if err != nil {
return nil, err
}
- defer response.Body.Close()
- return extractList(response.Body, selector, extractor)
+ return extractList(data, selector, extractor)
}
func SelectionExtractor(part string) func(*goquery.Selection) string {
@@ -48,8 +48,9 @@ func SelectionExtractor(part string) func(*goquery.Selection) string {
}
}
-func extractList(reader io.Reader, selector string, extractor func(*goquery.Selection) string) ([]string, error) {
- doc, err := goquery.NewDocumentFromReader(reader)
+func extractList(data []byte, selector string, extractor func(*goquery.Selection) string) ([]string, error) {
+ dataReader := bytes.NewReader(data)
+ doc, err := goquery.NewDocumentFromReader(dataReader)
if err != nil {
return nil, err
}
diff --git a/pkg/htmlquery/html_test.go b/pkg/htmlquery/html_test.go
index 606eac37..8f172de3 100644
--- a/pkg/htmlquery/html_test.go
+++ b/pkg/htmlquery/html_test.go
@@ -19,7 +19,6 @@
package htmlquery
import (
- "bytes"
_ "embed"
"slices"
"testing"
@@ -31,10 +30,8 @@ var artifactoryData []byte
func TestExtractAttr(t *testing.T) {
t.Parallel()
- artifactoryReader := bytes.NewReader(artifactoryData)
-
extractor := SelectionExtractor("style")
- extracted, err := extractList(artifactoryReader, "address", extractor)
+ extracted, err := extractList(artifactoryData, "address", extractor)
if err != nil {
t.Fatal("Unexpected extract error : ", err)
}
@@ -47,10 +44,8 @@ func TestExtractAttr(t *testing.T) {
func TestExtractText(t *testing.T) {
t.Parallel()
- artifactoryReader := bytes.NewReader(artifactoryData)
-
extractor := SelectionExtractor("#text")
- extracted, err := extractList(artifactoryReader, "address", extractor)
+ extracted, err := extractList(artifactoryData, "address", extractor)
if err != nil {
t.Fatal("Unexpected extract error : ", err)
}
@@ -63,9 +58,7 @@ func TestExtractText(t *testing.T) {
func TestExtractTexts(t *testing.T) {
t.Parallel()
- artifactoryReader := bytes.NewReader(artifactoryData)
-
- extracted, err := extractList(artifactoryReader, "a", selectionTextExtractor)
+ extracted, err := extractList(artifactoryData, "a", selectionTextExtractor)
if err != nil {
t.Fatal("Unexpected extract error : ", err)
}
diff --git a/versionmanager/retriever/api/api.go b/versionmanager/retriever/api/api.go
deleted file mode 100644
index 2ae7770e..00000000
--- a/versionmanager/retriever/api/api.go
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *
- * Copyright 2024 tofuutils authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package api
-
-import (
- "encoding/json"
- "io"
- "net/http"
-)
-
-func GetRequest(callURL string) (any, error) {
- response, err := http.Get(callURL) //nolint
- if err != nil {
- return nil, err
- }
- defer response.Body.Close()
-
- data, err := io.ReadAll(response.Body)
- if err != nil {
- return nil, err
- }
-
- var value any
- err = json.Unmarshal(data, &value)
-
- return value, err
-}
diff --git a/versionmanager/retriever/atmos/atmosretriever.go b/versionmanager/retriever/atmos/atmosretriever.go
index cee3b859..40e5137f 100644
--- a/versionmanager/retriever/atmos/atmosretriever.go
+++ b/versionmanager/retriever/atmos/atmosretriever.go
@@ -94,12 +94,13 @@ func (r AtmosRetriever) InstallRelease(versionStr string, targetPath string) err
return err
}
- data, err := download.Bytes(assetURLs[0], r.conf.Displayer.Display)
+ ro := config.GetBasicAuthOption(config.AtmosRemoteUserEnvName, config.AtmosRemotePassEnvName)
+ data, err := download.Bytes(assetURLs[0], r.conf.Displayer.Display, ro...)
if err != nil {
return err
}
- dataSums, err := download.Bytes(assetURLs[1], r.conf.Displayer.Display)
+ dataSums, err := download.Bytes(assetURLs[1], r.conf.Displayer.Display, ro...)
if err != nil {
return err
}
@@ -122,6 +123,8 @@ func (r AtmosRetriever) ListReleases() ([]string, error) {
return nil, err
}
+ ro := config.GetBasicAuthOption(config.AtmosRemoteUserEnvName, config.AtmosRemotePassEnvName)
+
listURL := r.conf.Atmos.GetListURL()
switch r.conf.Atmos.GetListMode() {
case config.ListModeHTML:
@@ -132,7 +135,7 @@ func (r AtmosRetriever) ListReleases() ([]string, error) {
r.conf.Displayer.Display(apimsg.MsgFetchAllReleases + baseURL)
- return htmlretriever.ListReleases(baseURL, r.conf.Atmos.Data)
+ return htmlretriever.ListReleases(baseURL, r.conf.Atmos.Data, ro)
case config.ModeAPI:
r.conf.Displayer.Display(apimsg.MsgFetchAllReleases + listURL)
diff --git a/versionmanager/retriever/html/htmlretriever.go b/versionmanager/retriever/html/htmlretriever.go
index c777d664..4bc71b51 100644
--- a/versionmanager/retriever/html/htmlretriever.go
+++ b/versionmanager/retriever/html/htmlretriever.go
@@ -37,12 +37,12 @@ func BuildAssetURLs(baseAssetURL string, assetNames ...string) ([]string, error)
return download.ApplyUrlTranformer(joinTransformer, assetNames...)
}
-func ListReleases(baseURL string, remoteConf map[string]string) ([]string, error) {
+func ListReleases(baseURL string, remoteConf map[string]string, ro []download.RequestOption) ([]string, error) {
selector := config.MapGetDefault(remoteConf, "selector", "a")
extractor := htmlquery.SelectionExtractor(config.MapGetDefault(remoteConf, "part", "href"))
versionExtractor := func(s *goquery.Selection) string {
return versionfinder.Find(extractor(s))
}
- return htmlquery.Request(baseURL, selector, versionExtractor)
+ return htmlquery.Request(baseURL, selector, versionExtractor, ro...)
}
diff --git a/versionmanager/retriever/terraform/terraformretriever.go b/versionmanager/retriever/terraform/terraformretriever.go
index fc25ac31..4b4984a4 100644
--- a/versionmanager/retriever/terraform/terraformretriever.go
+++ b/versionmanager/retriever/terraform/terraformretriever.go
@@ -35,7 +35,6 @@ import (
"github.com/tofuutils/tenv/v3/pkg/pathfilter"
"github.com/tofuutils/tenv/v3/pkg/winbin"
"github.com/tofuutils/tenv/v3/pkg/zip"
- "github.com/tofuutils/tenv/v3/versionmanager/retriever/api"
htmlretriever "github.com/tofuutils/tenv/v3/versionmanager/retriever/html"
releaseapi "github.com/tofuutils/tenv/v3/versionmanager/retriever/terraform/api"
)
@@ -71,6 +70,8 @@ func (r TerraformRetriever) InstallRelease(version string, targetPath string) er
return err
}
+ ro := config.GetBasicAuthOption(config.TfRemoteUserEnvName, config.TfRemotePassEnvName)
+
var fileName, shaFileName, shaSigFileName, downloadURL, downloadSumsURL, downloadSumsSigURL string
switch r.conf.Tf.GetInstallMode() {
case config.InstallModeDirect:
@@ -93,7 +94,7 @@ func (r TerraformRetriever) InstallRelease(version string, targetPath string) er
r.conf.Displayer.Display(apimsg.MsgFetchRelease + versionUrl)
- value, err := api.GetRequest(versionUrl)
+ value, err := download.JSON(versionUrl, download.NoDisplay, ro...)
if err != nil {
return err
}
@@ -123,12 +124,12 @@ func (r TerraformRetriever) InstallRelease(version string, targetPath string) er
return err
}
- data, err := download.Bytes(assetURLs[0], r.conf.Displayer.Display)
+ data, err := download.Bytes(assetURLs[0], r.conf.Displayer.Display, ro...)
if err != nil {
return err
}
- if err = r.checkSumAndSig(fileName, data, assetURLs[1], assetURLs[2]); err != nil {
+ if err = r.checkSumAndSig(fileName, data, assetURLs[1], assetURLs[2], ro); err != nil {
return err
}
@@ -146,11 +147,13 @@ func (r TerraformRetriever) ListReleases() ([]string, error) {
return nil, err
}
+ ro := config.GetBasicAuthOption(config.TfRemoteUserEnvName, config.TfRemotePassEnvName)
+
switch r.conf.Tf.GetListMode() {
case config.ListModeHTML:
r.conf.Displayer.Display(apimsg.MsgFetchAllReleases + baseURL)
- return htmlretriever.ListReleases(baseURL, r.conf.Tf.Data)
+ return htmlretriever.ListReleases(baseURL, r.conf.Tf.Data, ro)
case config.ModeAPI:
releasesURL, err := url.JoinPath(baseURL, indexJson) //nolint
if err != nil {
@@ -159,7 +162,7 @@ func (r TerraformRetriever) ListReleases() ([]string, error) {
r.conf.Displayer.Display(apimsg.MsgFetchAllReleases + releasesURL)
- value, err := api.GetRequest(releasesURL)
+ value, err := download.JSON(releasesURL, download.NoDisplay, ro...)
if err != nil {
return nil, err
}
@@ -170,8 +173,8 @@ func (r TerraformRetriever) ListReleases() ([]string, error) {
}
}
-func (r TerraformRetriever) checkSumAndSig(fileName string, data []byte, downloadSumsURL string, downloadSumsSigURL string) error {
- dataSums, err := download.Bytes(downloadSumsURL, r.conf.Displayer.Display)
+func (r TerraformRetriever) checkSumAndSig(fileName string, data []byte, downloadSumsURL string, downloadSumsSigURL string, ro []download.RequestOption) error {
+ dataSums, err := download.Bytes(downloadSumsURL, r.conf.Displayer.Display, ro...)
if err != nil {
return err
}
@@ -184,7 +187,7 @@ func (r TerraformRetriever) checkSumAndSig(fileName string, data []byte, downloa
return nil
}
- dataSumsSig, err := download.Bytes(downloadSumsSigURL, r.conf.Displayer.Display)
+ dataSumsSig, err := download.Bytes(downloadSumsSigURL, r.conf.Displayer.Display, ro...)
if err != nil {
return err
}
diff --git a/versionmanager/retriever/terragrunt/terragruntretriever.go b/versionmanager/retriever/terragrunt/terragruntretriever.go
index 3ce6c28e..9f876ad7 100644
--- a/versionmanager/retriever/terragrunt/terragruntretriever.go
+++ b/versionmanager/retriever/terragrunt/terragruntretriever.go
@@ -91,12 +91,13 @@ func (r TerragruntRetriever) InstallRelease(versionStr string, targetPath string
return err
}
- data, err := download.Bytes(assetURLs[0], r.conf.Displayer.Display)
+ ro := config.GetBasicAuthOption(config.TgRemoteUserEnvName, config.TgRemotePassEnvName)
+ data, err := download.Bytes(assetURLs[0], r.conf.Displayer.Display, ro...)
if err != nil {
return err
}
- dataSums, err := download.Bytes(assetURLs[1], r.conf.Displayer.Display)
+ dataSums, err := download.Bytes(assetURLs[1], r.conf.Displayer.Display, ro...)
if err != nil {
return err
}
@@ -119,6 +120,8 @@ func (r TerragruntRetriever) ListReleases() ([]string, error) {
return nil, err
}
+ ro := config.GetBasicAuthOption(config.TgRemoteUserEnvName, config.TgRemotePassEnvName)
+
listURL := r.conf.Tg.GetListURL()
switch r.conf.Tg.GetListMode() {
case config.ListModeHTML:
@@ -129,7 +132,7 @@ func (r TerragruntRetriever) ListReleases() ([]string, error) {
r.conf.Displayer.Display(apimsg.MsgFetchAllReleases + baseURL)
- return htmlretriever.ListReleases(baseURL, r.conf.Tg.Data)
+ return htmlretriever.ListReleases(baseURL, r.conf.Tg.Data, ro)
case config.ModeAPI:
r.conf.Displayer.Display(apimsg.MsgFetchAllReleases + listURL)
diff --git a/versionmanager/retriever/tofu/tofuretriever.go b/versionmanager/retriever/tofu/tofuretriever.go
index 2e37f9c8..68fbc987 100644
--- a/versionmanager/retriever/tofu/tofuretriever.go
+++ b/versionmanager/retriever/tofu/tofuretriever.go
@@ -38,7 +38,6 @@ import (
"github.com/tofuutils/tenv/v3/pkg/pathfilter"
"github.com/tofuutils/tenv/v3/pkg/winbin"
"github.com/tofuutils/tenv/v3/pkg/zip"
- "github.com/tofuutils/tenv/v3/versionmanager/retriever/api"
htmlretriever "github.com/tofuutils/tenv/v3/versionmanager/retriever/html"
tofudlmirroring "github.com/tofuutils/tenv/v3/versionmanager/retriever/tofu/dl"
)
@@ -130,12 +129,13 @@ func (r TofuRetriever) InstallRelease(versionStr string, targetPath string) erro
return err
}
- data, err := download.Bytes(assetURLs[0], r.conf.Displayer.Display)
+ ro := config.GetBasicAuthOption(config.TofuRemoteUserEnvName, config.TofuRemotePassEnvName)
+ data, err := download.Bytes(assetURLs[0], r.conf.Displayer.Display, ro...)
if err != nil {
return err
}
- if err = r.checkSumAndSig(v, stable, data, assetNames[0], assetURLs); err != nil {
+ if err = r.checkSumAndSig(v, stable, data, assetNames[0], assetURLs, ro); err != nil {
return err
}
@@ -148,6 +148,8 @@ func (r TofuRetriever) ListReleases() ([]string, error) {
return nil, err
}
+ ro := config.GetBasicAuthOption(config.TofuRemoteUserEnvName, config.TofuRemotePassEnvName)
+
listURL := r.conf.Tofu.GetListURL()
switch r.conf.Tofu.GetListMode() {
case config.ListModeHTML:
@@ -158,7 +160,7 @@ func (r TofuRetriever) ListReleases() ([]string, error) {
r.conf.Displayer.Display(apimsg.MsgFetchAllReleases + baseURL)
- return htmlretriever.ListReleases(baseURL, r.conf.Tofu.Data)
+ return htmlretriever.ListReleases(baseURL, r.conf.Tofu.Data, ro)
case config.ModeAPI:
r.conf.Displayer.Display(apimsg.MsgFetchAllReleases + listURL)
@@ -170,7 +172,7 @@ func (r TofuRetriever) ListReleases() ([]string, error) {
r.conf.Displayer.Display(apimsg.MsgFetchAllReleases + listURL)
- value, err := api.GetRequest(listURL)
+ value, err := download.JSON(listURL, download.NoDisplay, ro...)
if err != nil {
return nil, err
}
@@ -181,8 +183,8 @@ func (r TofuRetriever) ListReleases() ([]string, error) {
}
}
-func (r TofuRetriever) checkSumAndSig(version *version.Version, stable bool, data []byte, fileName string, assetURLs []string) error {
- dataSums, err := download.Bytes(assetURLs[1], r.conf.Displayer.Display)
+func (r TofuRetriever) checkSumAndSig(version *version.Version, stable bool, data []byte, fileName string, assetURLs []string, ro []download.RequestOption) error {
+ dataSums, err := download.Bytes(assetURLs[1], r.conf.Displayer.Display, ro...)
if err != nil {
return err
}
@@ -195,12 +197,12 @@ func (r TofuRetriever) checkSumAndSig(version *version.Version, stable bool, dat
return nil
}
- dataSumsSig, err := download.Bytes(assetURLs[3], r.conf.Displayer.Display)
+ dataSumsSig, err := download.Bytes(assetURLs[3], r.conf.Displayer.Display, ro...)
if err != nil {
return err
}
- dataSumsCert, err := download.Bytes(assetURLs[2], r.conf.Displayer.Display)
+ dataSumsCert, err := download.Bytes(assetURLs[2], r.conf.Displayer.Display, ro...)
if err != nil {
return err
}
@@ -219,7 +221,7 @@ func (r TofuRetriever) checkSumAndSig(version *version.Version, stable bool, dat
r.conf.Displayer.Display("cosign executable not found, fallback to pgp check")
- dataSumsSig, err = download.Bytes(assetURLs[4], r.conf.Displayer.Display)
+ dataSumsSig, err = download.Bytes(assetURLs[4], r.conf.Displayer.Display, ro...)
if err != nil {
return err
}