-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathdelete_orga.go
More file actions
196 lines (163 loc) · 4.92 KB
/
delete_orga.go
File metadata and controls
196 lines (163 loc) · 4.92 KB
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package pkg
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
log "github.com/sirupsen/logrus"
"github.com/qovery/qovery-cli/utils"
)
func printOrganizationsPreview(organizationIds []string) {
tokenType, token, err := utils.GetAccessToken()
if err != nil {
log.Warnf("Could not fetch organization details: %v", err)
for _, id := range organizationIds {
fmt.Printf(" - %s\n", id)
}
return
}
client := utils.GetQoveryClient(tokenType, token)
for _, orgId := range organizationIds {
org, _, err := client.OrganizationMainCallsAPI.GetOrganization(context.Background(), orgId).Execute()
if err != nil {
fmt.Printf(" - %s (name: unknown)\n", orgId)
} else {
fmt.Printf(" - %s (%s)\n", orgId, org.Name)
}
clusters, _, err := client.ClustersAPI.ListOrganizationCluster(context.Background(), orgId).Execute()
if err != nil {
log.Warnf("Could not fetch clusters for organization %s: %v", orgId, err)
} else if clusters != nil {
for _, c := range clusters.GetResults() {
fmt.Printf(" cluster: %s (%s)\n", c.Id, c.Name)
}
}
}
}
type DeleteOrganizationsResponse struct {
Deleted []string `json:"deleted"`
Failed []DeleteOrganizationFailure `json:"failed"`
}
type DeleteOrganizationFailure struct {
OrganizationID string `json:"organization_id"`
Reason string `json:"reason"`
}
func DeleteOrganizations(organizationIds []string, allowFailedClusters bool, dryRunDisabled bool) {
utils.GetAdminUrl()
utils.DryRunPrint(dryRunDisabled)
if len(organizationIds) == 0 {
log.Error("No organization IDs provided")
os.Exit(1)
}
fmt.Printf("The following %d organization(s) will be deleted (allowFailedClusters=%t):\n", len(organizationIds), allowFailedClusters)
printOrganizationsPreview(organizationIds)
fmt.Println()
if !dryRunDisabled {
if !utils.Validate("delete") {
return
}
log.Info("Dry run: no deletion performed")
return
}
// Build URL with allowFailedClusters parameter
url := utils.GetAdminUrl() + "/organizations"
if allowFailedClusters {
url += "?allowFailedClusters=true"
}
// Prepare JSON body with organization IDs
body, err := json.Marshal(organizationIds)
if err != nil {
log.Fatalf("Failed to marshal organization IDs: %v", err)
}
// Make HTTP request
res := deleteWithBody(url, http.MethodDelete, true, bytes.NewReader(body))
if res == nil {
log.Error("Failed to execute delete request")
return
}
defer func() {
if err := res.Body.Close(); err != nil {
log.Warnf("Failed to close response body: %v", err)
}
}()
// Handle response
if res.StatusCode != http.StatusOK {
result, _ := io.ReadAll(res.Body)
log.Errorf("Failed to delete organizations (status %d): %s", res.StatusCode, string(result))
os.Exit(1)
}
// Parse response
responseBody, err := io.ReadAll(res.Body)
if err != nil {
log.Errorf("Failed to read response: %v", err)
os.Exit(1)
}
var response DeleteOrganizationsResponse
if err := json.Unmarshal(responseBody, &response); err != nil {
log.Errorf("Failed to parse response: %v", err)
os.Exit(1)
}
// Display results
displayDeletionResults(response, len(organizationIds))
}
func displayDeletionResults(response DeleteOrganizationsResponse, totalRequested int) {
fmt.Println()
fmt.Println("====================================")
fmt.Println(" Organization Deletion Results")
fmt.Println("====================================")
fmt.Println()
successCount := len(response.Deleted)
failureCount := len(response.Failed)
fmt.Printf("Total requested: %d\n", totalRequested)
fmt.Printf("Successfully deleted: %d\n", successCount)
fmt.Printf("Failed to delete: %d\n", failureCount)
fmt.Println()
if successCount > 0 {
fmt.Println("✓ Successfully deleted organizations:")
for _, id := range response.Deleted {
fmt.Printf(" ✓ %s\n", id)
}
fmt.Println()
}
if failureCount > 0 {
fmt.Println("✗ Failed to delete organizations:")
for _, failure := range response.Failed {
fmt.Printf(" ✗ %s\n", failure.OrganizationID)
fmt.Printf(" Reason: %s\n", failure.Reason)
}
fmt.Println()
}
if failureCount > 0 {
fmt.Println("Some deletions failed. Check the reasons above.")
os.Exit(1)
} else {
fmt.Println("All organizations deleted successfully! ✓")
}
}
func httpDelete(url string, method string, dryRunDisabled bool) *http.Response {
return deleteWithBody(url, method, dryRunDisabled, nil)
}
func deleteWithBody(url string, method string, dryRunDisabled bool, body io.Reader) *http.Response {
tokenType, token, err := utils.GetAccessToken()
if err != nil {
utils.PrintlnError(err)
os.Exit(0)
}
if !dryRunDisabled {
return nil
}
req, err := http.NewRequest(method, url, body)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", utils.GetAuthorizationHeaderValue(tokenType, token))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
return res
}