|
18 | 18 | package cmd |
19 | 19 |
|
20 | 20 | import ( |
| 21 | + "bytes" |
21 | 22 | "errors" |
22 | 23 | "fmt" |
| 24 | + "io" |
| 25 | + "mime/multipart" |
| 26 | + "net/http" |
| 27 | + "os" |
| 28 | + "path/filepath" |
| 29 | + "reflect" |
23 | 30 | "strings" |
24 | 31 | ) |
25 | 32 |
|
@@ -111,9 +118,116 @@ func init() { |
111 | 118 |
|
112 | 119 | if len(response) > 0 { |
113 | 120 | printResult(r.Config.Core.Output, response, filterKeys, excludeKeys) |
| 121 | + if r.Config.HasShell { |
| 122 | + apiName := strings.ToLower(api.Name) |
| 123 | + if apiName == "getuploadparamsforiso" || |
| 124 | + apiName == "getuploadparamsforvolume" || |
| 125 | + apiName == "getuploadparamsfotemplate" { |
| 126 | + promptForFileUpload(r, apiName, response) |
| 127 | + } |
| 128 | + } |
114 | 129 | } |
115 | | - |
116 | 130 | return nil |
117 | 131 | }, |
118 | 132 | } |
119 | 133 | } |
| 134 | + |
| 135 | +func promptForFileUpload(r *Request, api string, response map[string]interface{}) { |
| 136 | + fmt.Print("Enter path of the file(s) to upload (comma-separated): ") |
| 137 | + var filePaths string |
| 138 | + fmt.Scanln(&filePaths) |
| 139 | + filePathsList := strings.FieldsFunc(filePaths, func(r rune) bool { return r == ',' }) |
| 140 | + |
| 141 | + var missingFiles []string |
| 142 | + var validFiles []string |
| 143 | + for _, filePath := range filePathsList { |
| 144 | + filePath = strings.TrimSpace(filePath) |
| 145 | + if filePath == "" { |
| 146 | + continue |
| 147 | + } |
| 148 | + if _, err := os.Stat(filePath); os.IsNotExist(err) { |
| 149 | + missingFiles = append(missingFiles, filePath) |
| 150 | + } else { |
| 151 | + validFiles = append(validFiles, filePath) |
| 152 | + } |
| 153 | + } |
| 154 | + if len(missingFiles) > 0 { |
| 155 | + fmt.Println("File(s) do not exist or are not accessible:", strings.Join(missingFiles, ", ")) |
| 156 | + return |
| 157 | + } |
| 158 | + if len(validFiles) == 0 { |
| 159 | + fmt.Println("No valid files to upload.") |
| 160 | + return |
| 161 | + } |
| 162 | + paramsRaw, ok := response["getuploadparams"] |
| 163 | + if !ok || reflect.TypeOf(paramsRaw).Kind() != reflect.Map { |
| 164 | + fmt.Println("Invalid response format for getuploadparams.") |
| 165 | + return |
| 166 | + } |
| 167 | + params := paramsRaw.(map[string]interface{}) |
| 168 | + requiredKeys := []string{"postURL", "metadata", "signature", "expires"} |
| 169 | + for _, key := range requiredKeys { |
| 170 | + if _, ok := params[key]; !ok { |
| 171 | + fmt.Printf("Missing required key '%s' in getuploadparams response.\n", key) |
| 172 | + return |
| 173 | + } |
| 174 | + } |
| 175 | + |
| 176 | + postURL, _ := params["postURL"].(string) |
| 177 | + signature, _ := params["signature"].(string) |
| 178 | + expires, _ := params["expires"].(string) |
| 179 | + metadata, _ := params["metadata"].(string) |
| 180 | + |
| 181 | + fmt.Println("Uploading files for", api, ":", validFiles) |
| 182 | + spinner := r.Config.StartSpinner("uploading files, please wait...") |
| 183 | + defer r.Config.StopSpinner(spinner) |
| 184 | + |
| 185 | + for _, filePath := range validFiles { |
| 186 | + if err := uploadFile(postURL, filePath, signature, expires, metadata); err != nil { |
| 187 | + fmt.Println("Error uploading", filePath, ":", err) |
| 188 | + } |
| 189 | + } |
| 190 | +} |
| 191 | + |
| 192 | +// uploadFile uploads a single file to the given postURL with the required headers. |
| 193 | +func uploadFile(postURL, filePath, signature, expires, metadata string) error { |
| 194 | + file, err := os.Open(filePath) |
| 195 | + if err != nil { |
| 196 | + return err |
| 197 | + } |
| 198 | + defer file.Close() |
| 199 | + |
| 200 | + var body bytes.Buffer |
| 201 | + writer := multipart.NewWriter(&body) |
| 202 | + part, err := writer.CreateFormFile("file", filepath.Base(filePath)) |
| 203 | + if err != nil { |
| 204 | + return err |
| 205 | + } |
| 206 | + if _, err := io.Copy(part, file); err != nil { |
| 207 | + return err |
| 208 | + } |
| 209 | + writer.Close() |
| 210 | + |
| 211 | + req, err := http.NewRequest("POST", postURL, &body) |
| 212 | + if err != nil { |
| 213 | + return err |
| 214 | + } |
| 215 | + req.Header.Set("Content-Type", writer.FormDataContentType()) |
| 216 | + req.Header.Set("x-signature", signature) |
| 217 | + req.Header.Set("x-expires", expires) |
| 218 | + req.Header.Set("x-metadata", metadata) |
| 219 | + |
| 220 | + client := &http.Client{} |
| 221 | + resp, err := client.Do(req) |
| 222 | + if err != nil { |
| 223 | + return err |
| 224 | + } |
| 225 | + defer resp.Body.Close() |
| 226 | + |
| 227 | + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated { |
| 228 | + respBody, _ := io.ReadAll(resp.Body) |
| 229 | + return fmt.Errorf("upload failed: %s", string(respBody)) |
| 230 | + } |
| 231 | + fmt.Println("Upload successful for:", filePath) |
| 232 | + return nil |
| 233 | +} |
0 commit comments