diff options
author | Nathan Dench <ndenc2@gmail.com> | 2019-05-24 15:16:44 +1000 |
---|---|---|
committer | Nathan Dench <ndenc2@gmail.com> | 2019-05-24 15:16:44 +1000 |
commit | 107c1cdb09c575aa2f61d97f48d8587eb6bada4c (patch) | |
tree | ca7d008643efc555c388baeaf1d986e0b6b3e28c /vendor/github.com/hashicorp/go-getter/get_gcs.go | |
parent | 844b5a68d8af4791755b8f0ad293cc99f5959183 (diff) | |
download | terraform-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.go | 172 |
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 @@ | |||
1 | package getter | ||
2 | |||
3 | import ( | ||
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. | ||
17 | type GCSGetter struct { | ||
18 | getter | ||
19 | } | ||
20 | |||
21 | func (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 | |||
58 | func (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 | |||
117 | func (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 | |||
133 | func (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 | |||
155 | func (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 | } | ||