aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/go-getter/get_gcs.go
diff options
context:
space:
mode:
authorNathan Dench <ndenc2@gmail.com>2019-05-24 15:16:44 +1000
committerNathan Dench <ndenc2@gmail.com>2019-05-24 15:16:44 +1000
commit107c1cdb09c575aa2f61d97f48d8587eb6bada4c (patch)
treeca7d008643efc555c388baeaf1d986e0b6b3e28c /vendor/github.com/hashicorp/go-getter/get_gcs.go
parent844b5a68d8af4791755b8f0ad293cc99f5959183 (diff)
downloadterraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.gz
terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.tar.zst
terraform-provider-statuscake-107c1cdb09c575aa2f61d97f48d8587eb6bada4c.zip
Upgrade to 0.12
Diffstat (limited to 'vendor/github.com/hashicorp/go-getter/get_gcs.go')
-rw-r--r--vendor/github.com/hashicorp/go-getter/get_gcs.go172
1 files changed, 172 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/go-getter/get_gcs.go b/vendor/github.com/hashicorp/go-getter/get_gcs.go
new file mode 100644
index 0000000..6faa70f
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/get_gcs.go
@@ -0,0 +1,172 @@
1package getter
2
3import (
4 "context"
5 "fmt"
6 "net/url"
7 "os"
8 "path/filepath"
9 "strings"
10
11 "cloud.google.com/go/storage"
12 "google.golang.org/api/iterator"
13)
14
15// GCSGetter is a Getter implementation that will download a module from
16// a GCS bucket.
17type GCSGetter struct {
18 getter
19}
20
21func (g *GCSGetter) ClientMode(u *url.URL) (ClientMode, error) {
22 ctx := g.Context()
23
24 // Parse URL
25 bucket, object, err := g.parseURL(u)
26 if err != nil {
27 return 0, err
28 }
29
30 client, err := storage.NewClient(ctx)
31 if err != nil {
32 return 0, err
33 }
34 iter := client.Bucket(bucket).Objects(ctx, &storage.Query{Prefix: object})
35 for {
36 obj, err := iter.Next()
37 if err != nil && err != iterator.Done {
38 return 0, err
39 }
40
41 if err == iterator.Done {
42 break
43 }
44 if strings.HasSuffix(obj.Name, "/") {
45 // A directory matched the prefix search, so this must be a directory
46 return ClientModeDir, nil
47 } else if obj.Name != object {
48 // A file matched the prefix search and doesn't have the same name
49 // as the query, so this must be a directory
50 return ClientModeDir, nil
51 }
52 }
53 // There are no directories or subdirectories, and if a match was returned,
54 // it was exactly equal to the prefix search. So return File mode
55 return ClientModeFile, nil
56}
57
58func (g *GCSGetter) Get(dst string, u *url.URL) error {
59 ctx := g.Context()
60
61 // Parse URL
62 bucket, object, err := g.parseURL(u)
63 if err != nil {
64 return err
65 }
66
67 // Remove destination if it already exists
68 _, err = os.Stat(dst)
69 if err != nil && !os.IsNotExist(err) {
70 return err
71 }
72 if err == nil {
73 // Remove the destination
74 if err := os.RemoveAll(dst); err != nil {
75 return err
76 }
77 }
78
79 // Create all the parent directories
80 if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
81 return err
82 }
83
84 client, err := storage.NewClient(ctx)
85 if err != nil {
86 return err
87 }
88
89 // Iterate through all matching objects.
90 iter := client.Bucket(bucket).Objects(ctx, &storage.Query{Prefix: object})
91 for {
92 obj, err := iter.Next()
93 if err != nil && err != iterator.Done {
94 return err
95 }
96 if err == iterator.Done {
97 break
98 }
99
100 if !strings.HasSuffix(obj.Name, "/") {
101 // Get the object destination path
102 objDst, err := filepath.Rel(object, obj.Name)
103 if err != nil {
104 return err
105 }
106 objDst = filepath.Join(dst, objDst)
107 // Download the matching object.
108 err = g.getObject(ctx, client, objDst, bucket, obj.Name)
109 if err != nil {
110 return err
111 }
112 }
113 }
114 return nil
115}
116
117func (g *GCSGetter) GetFile(dst string, u *url.URL) error {
118 ctx := g.Context()
119
120 // Parse URL
121 bucket, object, err := g.parseURL(u)
122 if err != nil {
123 return err
124 }
125
126 client, err := storage.NewClient(ctx)
127 if err != nil {
128 return err
129 }
130 return g.getObject(ctx, client, dst, bucket, object)
131}
132
133func (g *GCSGetter) getObject(ctx context.Context, client *storage.Client, dst, bucket, object string) error {
134 rc, err := client.Bucket(bucket).Object(object).NewReader(ctx)
135 if err != nil {
136 return err
137 }
138 defer rc.Close()
139
140 // Create all the parent directories
141 if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
142 return err
143 }
144
145 f, err := os.Create(dst)
146 if err != nil {
147 return err
148 }
149 defer f.Close()
150
151 _, err = Copy(ctx, f, rc)
152 return err
153}
154
155func (g *GCSGetter) parseURL(u *url.URL) (bucket, path string, err error) {
156 if strings.Contains(u.Host, "googleapis.com") {
157 hostParts := strings.Split(u.Host, ".")
158 if len(hostParts) != 3 {
159 err = fmt.Errorf("URL is not a valid GCS URL")
160 return
161 }
162
163 pathParts := strings.SplitN(u.Path, "/", 5)
164 if len(pathParts) != 5 {
165 err = fmt.Errorf("URL is not a valid GCS URL")
166 return
167 }
168 bucket = pathParts[3]
169 path = pathParts[4]
170 }
171 return
172}