-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdelete_resource.go
More file actions
218 lines (188 loc) · 7.19 KB
/
delete_resource.go
File metadata and controls
218 lines (188 loc) · 7.19 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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
package main
import (
"bufio"
"encoding/json"
"fmt"
"log"
"os"
"os/exec"
"strings"
)
var initialListCmd string
var initialListArgs []string
type BackupStorageLocation struct {
Spec Spec `json:"spec"`
}
// Spec matches the nested "spec" object.
type Spec struct {
ObjectStorage ObjectStorage `json:"objectStorage"`
}
// ObjectStorage matches the nested "objectStorage" object.
type ObjectStorage struct {
Bucket string `json:"bucket"`
}
// runCommand captures the stdout of a given command and returns it as a slice of strings,
// where each string is a line from the command's output.
func runCommand(command string, args ...string) ([]string, error) {
fmt.Printf("Executing command: %s %s\n", command, strings.Join(args, " "))
cmd := exec.Command(command, args...) // Create the command
stdout, err := cmd.StdoutPipe() // Get a pipe to read the standard output
if err != nil {
return nil, fmt.Errorf("failed to get StdoutPipe: %w", err)
}
if err := cmd.Start(); err != nil { // Start the command
return nil, fmt.Errorf("failed to start command: %w", err)
}
//var outputLines []string
var firstColumnList []string
scanner := bufio.NewScanner(stdout) // Create a scanner to read line by line
for scanner.Scan() {
line := scanner.Text() // Read a line and trim whitespace
// if line != "" { // Only add non-empty lines
// outputLines = append(outputLines, line)
// }
fields := strings.Fields(line) // Split the line by whitespace
if len(fields) > 0 {
firstColumnList = append(firstColumnList, fields[0]) // Add the first field to the list
}
}
if err := scanner.Err(); err != nil { // Check for scanner errors
return nil, fmt.Errorf("error reading command output: %w", err)
}
if err := cmd.Wait(); err != nil { // Wait for the command to finish and check for errors
return nil, fmt.Errorf("command exited with error: %w", err)
}
return firstColumnList, nil
}
// deleteBackup removes items from the original list that are present in the itemsToRemove list.
// It deletes the list items.
func deleteResource(resourceToDelete, clusterId string) {
var backupList []string
//var itemsToRemove []string
initialListCmd = "oc"
if resourceToDelete == "schedule" || resourceToDelete == "bsl" {
var cmdArgs []string
var cmdCommand = "oc"
initialListArgs = []string{"get", resourceToDelete, clusterId + "-hourly"}
fmt.Println("--- Getting Initial List ---", initialListArgs)
itemsToRemove, err := runCommand(initialListCmd, initialListArgs...)
if err != nil {
fmt.Printf("Error getting initial list: %v\n", err)
return
}
fmt.Printf("The entire list of items to remove: %s", itemsToRemove[1])
cmdArgs = []string{"delete", resourceToDelete, itemsToRemove[1]}
cmd := exec.Command(cmdCommand, cmdArgs...)
stdout, err := cmd.Output()
if err != nil {
fmt.Errorf("failed to get StdoutPipe: %w", err)
}
fmt.Printf("All good: %w", stdout)
fmt.Printf("The cmd command is: %s", cmd)
} else {
initialListArgs = []string{"get", resourceToDelete}
itemsToRemove, err := runCommand(initialListCmd, initialListArgs...)
for _, item := range itemsToRemove {
if strings.Contains(item, clusterId) {
backupList = append(backupList, item)
}
}
if err != nil {
fmt.Printf("Error getting initial list: %v\n", err)
}
fmt.Printf("The entire list of backup items to remove: %s", backupList)
var cmdArgs []string
var cmdCommand = "oc"
for _, item := range backupList {
cmdArgs = []string{"delete", resourceToDelete, item}
cmd := exec.Command(cmdCommand, cmdArgs...)
fmt.Println(cmd)
stdout, err := cmd.Output()
if err != nil {
fmt.Errorf("failed to get StdoutPipe: %w", err)
}
log.Println(string(stdout))
fmt.Printf("Resource deleted: %w", item)
}
}
}
// cleanupAWSResources performs a series of AWS cleanup operations.
// It takes the IAM role name, S3 bucket name, and KMS key ARN as input.
func cleanupAWSResources(clusterId, mcName string) error {
// --- Get S3 bucket name ---
initialListCmd = "oc"
initialListArgs = []string{"get", "bsl", clusterId + "-hourly", "-o", "json"}
cmd := exec.Command(initialListCmd, initialListArgs...)
fmt.Println(initialListArgs)
bucketNameOut, err := cmd.Output()
if err != nil {
fmt.Errorf("failed to get StdoutPipe: %w", err)
}
fmt.Println("S3 bucket name JSON is ", string(bucketNameOut))
var bsl BackupStorageLocation
// Unmarshal (parse) the JSON string into the struct.
s3bucketerr := json.Unmarshal([]byte(bucketNameOut), &bsl)
if s3bucketerr != nil {
fmt.Println("Error parsing JSON:", err)
//return
}
// Access the nested bucket value and print it.
bucketName := bsl.Spec.ObjectStorage.Bucket
fmt.Println(bucketName)
// --- IAM Operations ---
var roleNamePrefix = "rosa-hcp-bkp-"
// List all policies in the role
awsCmd := "aws"
rolePolicyListArgs := []string{"iam", "list-attached-role-policies", "--role-name", roleNamePrefix + mcName + "-" + clusterId, "|", "awk", "{print $2}"}
rolePolicycmd := exec.Command(awsCmd, rolePolicyListArgs...)
rolePolicyListOutput, err := rolePolicycmd.Output()
if err != nil {
fmt.Printf("Policies are empty or role does not exist: %s", err)
}
fmt.Printf("Role policies list Output is as follows... %s\n", rolePolicyListOutput)
for _, item := range rolePolicyListOutput {
// 1. Detach IAM Role Policy
var detachIAMRolePolicyListArgs = []string{"iam", "detach-role-policy", "--policy-arn", string(item), "--role-name", "rosa-hcp-bkp-" + mcName + "-" + clusterId}
detachPolicycmd := exec.Command(awsCmd, detachIAMRolePolicyListArgs...)
detachIAMRolePolicyOutput, err := detachPolicycmd.Output()
if err != nil {
fmt.Printf("Policies are empty or role does not exist: %s", err)
}
fmt.Printf("Role policy %s is detached successfully.\n", detachIAMRolePolicyOutput)
}
// 2. Delete IAM Role
var deleteRoleListArgs = []string{"iam", "delete-role", "--role-name", roleNamePrefix + mcName + "-" + clusterId}
deleteRoleCmd := exec.Command(awsCmd, deleteRoleListArgs...)
deleteRoleOutput, err := deleteRoleCmd.Output()
if err != nil {
fmt.Printf("failed to delete IAM role '%s': %w", roleNamePrefix+mcName+"-"+clusterId, err)
}
fmt.Printf("Successfully deleted IAM role '%s'.\n", deleteRoleOutput)
// 3. Delete S3 Bucket (and its contents first)
fmt.Printf("Attempting to delete S3 bucket '%s'...\n", bucketName)
s3CmdListArgs := []string{"s3", "rb", "s3://" + bucketName, " --force"}
// Execute the s3 command
S3Cmd := exec.Command(awsCmd, s3CmdListArgs...)
s3CmdOutput, err := S3Cmd.Output()
if err != nil {
fmt.Printf("failed to execute S3 bucket deletion: %s", err)
}
//List and delete all objects in the bucket first
fmt.Printf("Deleting all objects in bucket '%s'...\n", s3CmdOutput)
fmt.Printf("Successfully deleted S3 bucket '%s'.\n", bucketName)
return nil
}
func main() {
// os.Args[1] -> clusterId
// os.Args[2] -> mc name
var clusterId = os.Args[1]
var mcName = os.Args[2]
fmt.Println("------Delete Openshift resources-------")
cleanupAWSResources(clusterId, mcName)
fmt.Println("------Delete Openshift resources-------")
deleteResource("bsl", clusterId)
deleteResource("schedule", clusterId)
deleteResource("backup", clusterId)
deleteResource("secret", clusterId)
deleteResource("backuprepository", clusterId)
}