88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
package terraform
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"os"
|
|
"runtime"
|
|
|
|
"github.com/hashicorp/go-getter"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
type ProviderDownloaderInterface interface {
|
|
Download(url, path string) error
|
|
GetProviderUrl(name, version string) string
|
|
}
|
|
|
|
type ProviderDownloader struct {
|
|
httpclient *http.Client
|
|
unzip getter.ZipDecompressor
|
|
context context.Context
|
|
}
|
|
|
|
func NewProviderDownloader() *ProviderDownloader {
|
|
return &ProviderDownloader{
|
|
httpclient: http.DefaultClient,
|
|
unzip: getter.ZipDecompressor{},
|
|
context: context.Background(),
|
|
}
|
|
}
|
|
|
|
func (p *ProviderDownloader) GetProviderUrl(name, version string) string {
|
|
return fmt.Sprintf(
|
|
"https://releases.hashicorp.com/terraform-provider-%s/%s/terraform-provider-%s_%s_%s_%s.zip",
|
|
name,
|
|
version,
|
|
name,
|
|
version,
|
|
runtime.GOOS,
|
|
runtime.GOARCH,
|
|
)
|
|
}
|
|
|
|
func (p *ProviderDownloader) Download(url, path string) error {
|
|
logrus.WithFields(logrus.Fields{
|
|
"url": url,
|
|
"path": path,
|
|
}).Debug("Downloading provider")
|
|
|
|
req, err := http.NewRequestWithContext(p.context, "GET", url, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
resp, err := p.httpclient.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
if resp.StatusCode != http.StatusOK {
|
|
return fmt.Errorf("unsuccessful request to %s: %s", url, resp.Status)
|
|
}
|
|
f, err := ioutil.TempFile("", "terraform-provider")
|
|
if err != nil {
|
|
return fmt.Errorf("failed to open temporary file to download from %s", url)
|
|
}
|
|
defer f.Close()
|
|
defer os.Remove(f.Name())
|
|
n, err := getter.Copy(p.context, f, resp.Body)
|
|
if err == nil && n < resp.ContentLength {
|
|
err = fmt.Errorf("incorrect response size: expected %d bytes, but got %d bytes", resp.ContentLength, n)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logrus.WithFields(logrus.Fields{
|
|
"src": f.Name(),
|
|
"dst": path,
|
|
}).Debug("Decompressing archive")
|
|
err = p.unzip.Decompress(path, f.Name(), true, 0)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|