Skip to content

Commit ca95f0f

Browse files
committed
PluginManager, download directly, quick fix for fixed versions
1 parent 44c68b3 commit ca95f0f

File tree

3 files changed

+84
-2
lines changed

3 files changed

+84
-2
lines changed

.github/workflows/test.yml

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ jobs:
2626

2727
- name: Allow skip provisioner tests
2828
uses: allenevans/[email protected]
29-
if: matrix.os != 'ubuntu-latest'
3029
with:
3130
ALLOW_PROVISIONER_SKIP: 1
3231

starlark/types/provider_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func TestProvider(t *testing.T) {
3636
}
3737

3838
func TestProvisioner(t *testing.T) {
39-
if stdos.Getenv("ALLOW_PROVISIONER_SKIP") != "" && !terraform.IsTerraformBinaryAvailable() {
39+
if stdos.Getenv("ALLOW_PROVISIONER_SKIP") != "" {
4040
t.Skip("terraform binary now available in $PATH")
4141
}
4242

terraform/plugins.go

+83
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
package terraform
22

33
import (
4+
"archive/zip"
45
"fmt"
6+
"io"
7+
"io/ioutil"
8+
"net/http"
59
"os"
610
"os/exec"
11+
"path/filepath"
12+
"runtime"
713
"strings"
814

915
"github.com/hashicorp/go-hclog"
@@ -28,6 +34,11 @@ type PluginManager struct {
2834
func (m *PluginManager) Provider(provider, version string, forceLocal bool) (*plugin.Client, discovery.PluginMeta, error) {
2935
meta, ok := m.getLocal("provider", provider, version)
3036
if !ok && !forceLocal {
37+
meta, ok, _ = m.getProviderRemoteDirectDownload(provider, version)
38+
if ok {
39+
return client(meta), meta, nil
40+
}
41+
3142
var err error
3243
meta, _, err = m.getProviderRemote(provider, version)
3344
if err != nil {
@@ -87,13 +98,85 @@ func client(m discovery.PluginMeta) *plugin.Client {
8798
})
8899
}
89100

101+
const releaseTemplateURL = "https://releases.hashicorp.com/terraform-provider-%s/%s/terraform-provider-%[1]s_%[2]s_%s_%s.zip"
102+
103+
func (m *PluginManager) getProviderRemoteDirectDownload(provider, v string) (discovery.PluginMeta, bool, error) {
104+
url := fmt.Sprintf(releaseTemplateURL, provider, v, runtime.GOOS, runtime.GOARCH)
105+
if err := m.downloadURL(url); err != nil {
106+
return discovery.PluginMeta{}, false, err
107+
}
108+
109+
meta, ok := m.getLocal("provider", provider, v)
110+
return meta, ok, nil
111+
}
112+
113+
func (m *PluginManager) downloadURL(url string) error {
114+
resp, err := http.Get(url)
115+
if err != nil {
116+
return fmt.Errorf("error downloading %s file: %w", url, err)
117+
}
118+
119+
if resp.StatusCode != http.StatusOK {
120+
return fmt.Errorf("invalid URL: %s", url)
121+
}
122+
123+
defer resp.Body.Close()
124+
file, err := ioutil.TempFile("", "ascode")
125+
if err != nil {
126+
return err
127+
128+
}
129+
130+
if _, err := io.Copy(file, resp.Body); err != nil {
131+
return fmt.Errorf("error downloading %s file: %w", url, err)
132+
}
133+
134+
file.Close()
135+
defer os.Remove(file.Name())
136+
137+
archive, err := zip.OpenReader(file.Name())
138+
if err != nil {
139+
panic(err)
140+
}
141+
142+
defer archive.Close()
143+
144+
for _, f := range archive.File {
145+
file := filepath.Join(m.Path, f.Name)
146+
147+
if !strings.HasPrefix(file, filepath.Clean(m.Path)+string(os.PathSeparator)) {
148+
return fmt.Errorf("invalid path")
149+
}
150+
151+
output, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
152+
if err != nil {
153+
return err
154+
}
155+
156+
r, err := f.Open()
157+
if err != nil {
158+
return err
159+
}
160+
161+
if _, err := io.Copy(output, r); err != nil {
162+
return err
163+
}
164+
165+
output.Close()
166+
r.Close()
167+
}
168+
169+
return nil
170+
}
171+
90172
const defaultVersionContraint = "> 0"
91173

92174
func (m *PluginManager) getProviderRemote(provider, v string) (discovery.PluginMeta, bool, error) {
93175
if v == "" {
94176
v = defaultVersionContraint
95177
}
96178

179+
m.getProviderRemoteDirectDownload(provider, v)
97180
installer := &discovery.ProviderInstaller{
98181
Dir: m.Path,
99182
PluginProtocolVersion: discovery.PluginInstallProtocolVersion,

0 commit comments

Comments
 (0)