forked from kyma-project/Cx1ClientGo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmigration.go
128 lines (107 loc) · 3.54 KB
/
migration.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package Cx1ClientGo
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
)
func (c Cx1Client) StartMigration(dataArchive, projectMapping []byte, encryptionKey string) (string, error) {
dataUrl, err := c.UploadBytes(&dataArchive)
if err != nil {
return "", fmt.Errorf("error uploading migration data: %s", err)
}
c.logger.Debugf("Uploaded data archive to %v", dataUrl)
dataFilename := getFilenameFromURL(dataUrl)
mappingFilename := ""
if len(projectMapping) != 0 {
mappingUrl, err := c.UploadBytes(&projectMapping)
mappingFilename = getFilenameFromURL(mappingUrl)
if err != nil {
return "", fmt.Errorf("error uploading project mapping data: %s", err)
}
c.logger.Debugf("Uploaded project mapping to %v", mappingUrl)
}
return c.StartImport(dataFilename, mappingFilename, encryptionKey)
}
func (c Cx1Client) StartImport(dataFilename, mappingFilename, encryptionKey string) (string, error) {
jsonBody := map[string]interface{}{
"fileName": dataFilename,
"projectsMappingFileName": mappingFilename,
"encryptionKey": encryptionKey,
}
body, _ := json.Marshal(jsonBody)
response, err := c.sendRequest(http.MethodPost, "/imports", bytes.NewReader(body), nil)
if err != nil {
return "", err
}
var responseBody struct {
MigrationId string `json:"migrationId"`
}
err = json.Unmarshal(response, &responseBody)
if err != nil {
return "", err
}
return responseBody.MigrationId, nil
}
func (c Cx1Client) GetImports() ([]DataImport, error) {
response, err := c.sendRequest(http.MethodGet, "/imports", nil, nil)
var imports []DataImport
if err != nil {
return imports, err
}
err = json.Unmarshal(response, &imports)
return imports, err
}
func (c Cx1Client) GetImportByID(importID string) (DataImport, error) {
response, err := c.sendRequest(http.MethodGet, fmt.Sprintf("/imports/%v", importID), nil, nil)
var di DataImport
if err != nil {
return di, err
}
err = json.Unmarshal(response, &di)
return di, err
}
func (c Cx1Client) GetImportLogsByID(importID, engine string) ([]byte, error) {
c.logger.Debugf("Fetching import logs for import %v", importID)
response, err := c.sendRequest(http.MethodGet, fmt.Sprintf("/imports/%v/logs/download", importID), nil, nil)
return response, err
}
func (c Cx1Client) ImportPollingByID(importID string) (string, error) {
return c.ImportPollingByIDWithTimeout(importID, c.consts.MigrationPollingDelaySeconds, c.consts.MigrationPollingMaxSeconds)
}
func (c Cx1Client) ImportPollingByIDWithTimeout(importID string, delaySeconds, maxSeconds int) (string, error) {
pollingCounter := 0
for {
status, err := c.GetImportByID(importID)
if err != nil {
return "", err
}
switch status.Status {
case "failed":
return status.Status, fmt.Errorf("import failed: %s", status.Logs)
case "blank":
return status.Status, fmt.Errorf("import finished but nothing was imported: %s", status.Logs)
case "completed":
return status.Status, nil
case "partial":
return status.Status, nil
}
if maxSeconds != 0 && pollingCounter >= maxSeconds {
return "timeout", fmt.Errorf("import polling reached %d seconds, aborting - use cx1client.get/setclientvars to change", pollingCounter)
}
c.logger.Infof("Polling every %d seconds, up to %d", delaySeconds, maxSeconds)
time.Sleep(time.Duration(delaySeconds) * time.Second)
pollingCounter += delaySeconds
}
}
func getFilenameFromURL(url string) string {
if ind := strings.Index(url, "?"); ind > -1 {
url = url[:ind]
}
if ind := strings.LastIndex(url, "/"); ind >= -1 {
url = url[ind+1:]
}
return url
}