@@ -16,15 +16,24 @@ package astra
16
16
17
17
import (
18
18
"archive/zip"
19
+ "bytes"
20
+ "context"
19
21
"crypto/tls"
20
22
"crypto/x509"
21
23
"encoding/json"
24
+ "errors"
22
25
"fmt"
23
26
"io"
24
27
"io/ioutil"
28
+ "net/http"
25
29
"runtime"
30
+ "time"
31
+
32
+ "github.com/datastax/astra-client-go/v2/astra"
26
33
)
27
34
35
+ const URL = "https://api.astra.datastax.com"
36
+
28
37
type Bundle struct {
29
38
tlsConfig * tls.Config
30
39
host string
@@ -85,6 +94,68 @@ func LoadBundleZipFromPath(path string) (*Bundle, error) {
85
94
return LoadBundleZip (& reader .Reader )
86
95
}
87
96
97
+ func LoadBundleZipFromURL (url , databaseID , token string , timeout time.Duration ) (* Bundle , error ) {
98
+ ctx , cancel := context .WithDeadline (context .Background (), time .Now ().Add (timeout ))
99
+ defer cancel ()
100
+
101
+ credsURL , err := generateSecureBundleURLWithResponse (url , databaseID , token , ctx )
102
+ if err != nil {
103
+ return nil , fmt .Errorf ("error generating secure bundle zip URLs: %v" , err )
104
+ }
105
+ resp , err := http .Get (credsURL .DownloadURL )
106
+
107
+ defer resp .Body .Close ()
108
+
109
+ body , err := readAllWithTimeout (resp .Body , ctx )
110
+ if err != nil {
111
+ return nil , fmt .Errorf ("error downloading bundle zip: %v" , err )
112
+ }
113
+
114
+ reader , err := zip .NewReader (bytes .NewReader (body ), int64 (len (body )))
115
+ if err != nil {
116
+ return nil , fmt .Errorf ("error creating zip reader for bundle zip: %v" , err )
117
+ }
118
+
119
+ return LoadBundleZip (reader )
120
+ }
121
+
122
+ func readAllWithTimeout (r io.Reader , ctx context.Context ) (bytes []byte , err error ) {
123
+ ch := make (chan struct {})
124
+
125
+ go func () {
126
+ bytes , err = ioutil .ReadAll (r )
127
+ close (ch )
128
+ }()
129
+
130
+ select {
131
+ case <- ch :
132
+ case <- ctx .Done ():
133
+ return nil , errors .New ("timeout reading data" )
134
+ }
135
+
136
+ return bytes , err
137
+ }
138
+
139
+ func generateSecureBundleURLWithResponse (url , databaseID , token string , ctx context.Context ) (* astra.CredsURL , error ) {
140
+ client , err := astra .NewClientWithResponses (url , func (c * astra.Client ) error {
141
+ c .RequestEditors = append (c .RequestEditors , func (ctx context.Context , req * http.Request ) error {
142
+ req .Header .Set ("Authorization" , fmt .Sprintf ("Bearer %s" , token ))
143
+ return nil
144
+ })
145
+ return nil
146
+ })
147
+ if err != nil {
148
+ return nil , err
149
+ }
150
+ res , err := client .GenerateSecureBundleURLWithResponse (ctx , astra .DatabaseIdParam (databaseID ))
151
+
152
+ if res .StatusCode () != http .StatusOK {
153
+ return nil , fmt .Errorf ("unable to generate bundle urls, failed with status code %d" , res .StatusCode ())
154
+ }
155
+
156
+ return res .JSON200 , nil
157
+ }
158
+
88
159
func (b * Bundle ) Host () string {
89
160
return b .host
90
161
}
0 commit comments