-
Notifications
You must be signed in to change notification settings - Fork 575
/
delete.go
560 lines (505 loc) · 18.4 KB
/
delete.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
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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
package cmd
/*
Copyright 2017 - 2022 Crunchy Data Solutions, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import (
"fmt"
"github.com/crunchydata/postgres-operator/pgo/util"
"github.com/spf13/cobra"
)
// Several prompts to help a user decide if they wish to actually delete their
// data from a cluster
const (
deleteClusterAllPromptMessage = "This will delete ALL OF YOUR DATA, including backups. Proceed?"
deleteClusterKeepBackupsPromptMessage = "This will delete your active data, but your backups will still be available. Proceed?"
deleteClusterKeepDataPromptMessage = "This will delete your cluster as well as your backups, but your data is still accessible if you recreate the cluster. Proceed?"
)
// deleteCmd represents the delete command
var deleteCmd = &cobra.Command{
Use: "delete",
Short: "Delete an Operator resource",
Long: `The delete command allows you to delete an Operator resource. For example:
pgo delete backup mycluster
pgo delete cluster mycluster
pgo delete cluster mycluster --delete-data
pgo delete cluster mycluster --delete-data --delete-backups
pgo delete label mycluster --label=env=research
pgo delete pgadmin mycluster
pgo delete pgbouncer mycluster
pgo delete pgbouncer mycluster --uninstall
pgo delete pgouser someuser
pgo delete pgorole somerole
pgo delete policy mypolicy
pgo delete namespace mynamespace
pgo delete schedule --schedule-name=mycluster-pgbackrest-full
pgo delete schedule --selector=name=mycluster
pgo delete schedule mycluster
pgo delete user --username=testuser --selector=name=mycluster`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
fmt.Println(`Error: You must specify the type of resource to delete. Valid resource types include:
* backup
* cluster
* label
* pgadmin
* pgbouncer
* pgouser
* pgorole
* namespace
* policy
* user`)
} else {
switch args[0] {
case "backup",
"cluster",
"label",
"pgadmin",
"pgbouncer",
"pgouser",
"pgorole",
"policy",
"namespace",
"schedule",
"user":
break
default:
fmt.Println(`Error: You must specify the type of resource to delete. Valid resource types include:
* backup
* cluster
* label
* pgadmin
* pgbouncer
* pgouser
* pgorole
* policy
* namespace
* user`)
}
}
},
}
// DEPRECATED deleteBackups, if set to "true", indicates that backups can be deleted.
var deleteBackups bool
// KeepBackups, If set to "true", indicates that backups should be stored even
// after a cluster is deleted
var KeepBackups bool
// NoPrompt, If set to "true", indicates that the user should not be prompted
// before executing a delete command
var NoPrompt bool
// initialize variables specific for the "pgo delete" command and subcommands
func init() {
// set the various commands that are provided by this file
// First, add the root command, i.e. "pgo delete"
RootCmd.AddCommand(deleteCmd)
// "pgo delete backup"
// used to delete backups
deleteCmd.AddCommand(deleteBackupCmd)
// "pgo delete cluster"
// used to delete clusters
deleteCmd.AddCommand(deleteClusterCmd)
// "pgo delete cluster --all"
// allows for the deletion of every cluster.
deleteClusterCmd.Flags().BoolVar(&AllFlag, "all", false,
"Delete all clusters. Backups and data subject to --delete-backups and --delete-data flags, respectively.")
// "pgo delete cluster --delete-backups"
// "pgo delete cluster -d"
// instructs that any backups associated with a cluster should be deleted
deleteClusterCmd.Flags().BoolVarP(&deleteBackups, "delete-backups", "b", false,
"Causes the backups for specified cluster to be removed permanently.")
deleteClusterCmd.Flags().MarkDeprecated("delete-backups",
"Backups are deleted by default. If you would like to keep your backups, use the --keep-backups flag")
// "pgo delete cluster --delete-data"
// "pgo delete cluster -d"
// instructs that the PostgreSQL cluster data should be deleted
deleteClusterCmd.Flags().BoolVarP(&DeleteData, "delete-data", "d", false,
"Causes the data for specified cluster to be removed permanently.")
deleteClusterCmd.Flags().MarkDeprecated("delete-data",
"Data is deleted by default. You can preserve your data by keeping your backups with the --keep-backups flag")
// "pgo delete cluster --keep-backups"
// instructs that any backups associated with a cluster should be kept and not deleted
deleteClusterCmd.Flags().BoolVar(&KeepBackups, "keep-backups", false,
"Keeps the backups available for use at a later time (e.g. recreating the cluster).")
// "pgo delete cluster --keep-data"
// instructs that any data associated with the cluster should be kept and not deleted
deleteClusterCmd.Flags().BoolVar(&KeepData, "keep-data", false,
"Keeps the data for the specified cluster. Can be reassigned to exact same cluster in the future.")
// "pgo delete cluster --no-prompt"
// does not display the warning prompt to ensure the user wishes to delete
// a cluster
deleteClusterCmd.Flags().BoolVar(&NoPrompt, "no-prompt", false,
"No command line confirmation before delete.")
// "pgo delete cluster --selector"
// "pgo delete cluster -s"
// the selector flag that filters which clusters to delete
deleteClusterCmd.Flags().StringVarP(&Selector, "selector", "s", "",
"The selector to use for cluster filtering.")
// "pgo delete label"
// delete a cluster label
deleteCmd.AddCommand(deleteLabelCmd)
// pgo delete label --label
// the label to be deleted
deleteLabelCmd.Flags().StringVar(&LabelCmdLabel, "label", "",
"The label to delete for any selected or specified clusters.")
// "pgo delete label --selector"
// "pgo delete label -s"
// the selector flag that filters which clusters to delete the cluster
// labels from
deleteLabelCmd.Flags().StringVarP(&Selector, "selector", "s", "",
"The selector to use for cluster filtering.")
// "pgo delete namespace"
// deletes a namespace and all of the objects within it (clusters, etc.)
deleteCmd.AddCommand(deleteNamespaceCmd)
// "pgo delete pgadmin"
// delete a pgAdmin instance associated with a PostgreSQL cluster
deleteCmd.AddCommand(deletePgAdminCmd)
// "pgo delete pgadmin --no-prompt"
// does not display the warning prompt to confirming pgAdmin deletion
deletePgAdminCmd.Flags().BoolVar(&NoPrompt, "no-prompt", false, "No command line confirmation before delete.")
// "pgo delete pgadmin --selector"
// "pgo delete pgadmin -s"
// the selector flag filtering clusters from which to delete the pgAdmin instances
deletePgAdminCmd.Flags().StringVarP(&Selector, "selector", "s", "", "The selector to use for cluster filtering.")
// "pgo delete pgbouncer"
// delete a pgBouncer instance that is associated with a PostgreSQL cluster
deleteCmd.AddCommand(deletePgbouncerCmd)
// "pgo delete pgbouncer --no-prompt"
// does not display the warning prompt to ensure the user wishes to delete
// a pgBouncer instance
deletePgbouncerCmd.Flags().BoolVar(&NoPrompt, "no-prompt", false, "No command line confirmation before delete.")
// "pgo delete pgbouncer --selector"
// "pgo delete pgbouncer -s"
// the selector flag that filters which clusters to delete the pgBouncer
// instances from
deletePgbouncerCmd.Flags().StringVarP(&Selector, "selector", "s", "", "The selector to use for cluster filtering.")
// "pgo delete pgbouncer --uninstall"
// this flag removes all of the pgbouncer machinery that is installed in the
// PostgreSQL cluster
deletePgbouncerCmd.Flags().BoolVar(&PgBouncerUninstall, "uninstall", false, `Used to remove any "pgbouncer" owned object and user from the PostgreSQL cluster`)
// "pgo delete pgorole"
// delete a role that is able to issue commands interface with the
// PostgreSQL Operator
deleteCmd.AddCommand(deletePgoroleCmd)
// "pgo delete pgorole --all"
// allows for the deletion of every PostgreSQL Operator role.
deletePgoroleCmd.Flags().BoolVar(&AllFlag, "all", false, "Delete all PostgreSQL Operator roles.")
// "pgo delete pgorole --no-prompt"
// does not display the warning prompt to ensure the user wishes to delete
// a PostgreSQL Operator role
deletePgoroleCmd.Flags().BoolVar(&NoPrompt, "no-prompt", false,
"No command line confirmation before delete.")
// "pgo delete pgouser"
// delete a user that is able to issue commands to the PostgreSQL Operator
deleteCmd.AddCommand(deletePgouserCmd)
// "pgo delete cluster --all"
// allows for the deletion of every PostgreSQL Operator user.
deletePgouserCmd.Flags().BoolVar(&AllFlag, "all", false,
"Delete all PostgreSQL Operator users.")
// "pgo delete pgouser --no-prompt"
// does not display the warning prompt to ensure the user wishes to delete
// a PostgreSQL Operator user
deletePgouserCmd.Flags().BoolVar(&NoPrompt, "no-prompt", false,
"No command line confirmation before delete.")
// "pgo delete policy"
// delete a SQL policy associated with a PostgreSQL cluster
deleteCmd.AddCommand(deletePolicyCmd)
// "pgo delete policy --all"
// delete all SQL policies for all clusters
deletePolicyCmd.Flags().BoolVar(&AllFlag, "all", false, "Delete all SQL policies.")
// "pgo delete policy --no-prompt"
// does not display the warning prompt to ensure the user wishes to delete
// a SQL policy
deletePolicyCmd.Flags().BoolVar(&NoPrompt, "no-prompt", false, "No command line confirmation before delete.")
// "pgo delete schedule"
// delete a scheduled job for a cluster (e.g. a daily backup)
deleteCmd.AddCommand(deleteScheduleCmd)
// "pgo delete schedule --no-prompt"
// does not display the warning prompt to ensure the user wishes to delete
// a scheduled job for a cluster
deleteScheduleCmd.Flags().BoolVar(&NoPrompt, "no-prompt", false,
"No command line confirmation before delete.")
// "pgo delete schedule --schedule-name"
// the name of the scheduled job to delete
deleteScheduleCmd.Flags().StringVar(&ScheduleName, "schedule-name", "",
"The name of the schedule to delete.")
// "pgo delete schedule --selector"
// "pgo delete schedule -s"
// the selector flag that filters which scheduled jobs should be deleted
// from which clusters
deleteScheduleCmd.Flags().StringVarP(&Selector, "selector", "s", "",
"The selector to use for cluster filtering.")
// "pgo delete user"
// Delete a user from a PostgreSQL cluster
deleteCmd.AddCommand(deleteUserCmd)
// "pgo delete user --all"
// delete all users from all PostgreSQL clusteres
deleteUserCmd.Flags().BoolVar(&AllFlag, "all", false,
"Delete all PostgreSQL users from all clusters.")
// "pgo delete user --no-prompt"
// does not display the warning prompt to ensure the user wishes to delete
// the PostgreSQL user from the cluster
deleteUserCmd.Flags().BoolVar(&NoPrompt, "no-prompt", false,
"No command line confirmation before delete.")
// "pgo delete user -o"
// selects the type of output to use, choices are "json" and any other input
// will render the text based one
deleteUserCmd.Flags().StringVarP(&OutputFormat, "output", "o", "",
`The output format. Supported types are: "json"`)
// "pgo delete schedule --selector"
// "pgo delete schedule -s"
// the selector flag that filters which PostgreSQL users should be deleted
// from which clusters
deleteUserCmd.Flags().StringVarP(&Selector, "selector", "s", "",
"The selector to use for cluster filtering.")
// "pgo delete schedule --username"
// the username of the PostgreSQL user to delete
deleteUserCmd.Flags().StringVar(&Username, "username", "",
"The username to delete.")
}
// deleteBackupCmd ...
var deleteBackupCmd = &cobra.Command{
Use: "backup",
Short: "Delete a backup",
Long: `Delete a backup. For example:
pgo delete backup mydatabase`,
Run: func(cmd *cobra.Command, args []string) {
if Namespace == "" {
Namespace = PGONamespace
}
if len(args) == 0 {
fmt.Println("Error: A database or cluster name is required for this command.")
} else {
if util.AskForConfirmation(NoPrompt, "") {
deleteBackup(args, Namespace)
} else {
fmt.Println("Aborting...")
}
}
},
}
// deleteClusterCmd ...
var deleteClusterCmd = &cobra.Command{
Use: "cluster",
Short: "Delete a PostgreSQL cluster",
Long: `Delete a PostgreSQL cluster. For example:
pgo delete cluster --all
pgo delete cluster mycluster`,
Run: func(cmd *cobra.Command, args []string) {
if Namespace == "" {
Namespace = PGONamespace
}
if len(args) == 0 && Selector == "" && !AllFlag {
fmt.Println("Error: A cluster name, selector, or --all is required for this command.")
} else {
// Set the prompt message based on whether or not "--keep-backups" is set
promptMessage := deleteClusterAllPromptMessage
if KeepBackups && KeepData {
promptMessage = ""
} else if KeepBackups {
promptMessage = deleteClusterKeepBackupsPromptMessage
} else if KeepData {
promptMessage = deleteClusterKeepDataPromptMessage
}
if util.AskForConfirmation(NoPrompt, promptMessage) {
deleteCluster(args, Namespace)
} else {
fmt.Println("Aborting...")
}
}
},
}
// deleteLabelCmd ...
var deleteLabelCmd = &cobra.Command{
Use: "label",
Short: "Delete a label from clusters",
Long: `Delete a label from clusters. For example:
pgo delete label mycluster --label=env=research
pgo delete label all --label=env=research
pgo delete label --selector=group=southwest --label=env=research`,
Run: func(cmd *cobra.Command, args []string) {
if Namespace == "" {
Namespace = PGONamespace
}
if len(args) == 0 && Selector == "" {
fmt.Println("Error: A cluster name or selector is required for this command.")
} else {
deleteLabel(args, Namespace)
}
},
}
// deleteNamespaceCmd ...
var deleteNamespaceCmd = &cobra.Command{
Use: "namespace",
Short: "Delete namespaces",
Long: `Delete namespaces. For example:
pgo delete namespace mynamespace
pgo delete namespace --selector=env=test`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 && Selector == "" {
fmt.Println("Error: namespace name or selector is required to delete a namespace.")
return
}
if util.AskForConfirmation(NoPrompt, "") {
deleteNamespace(args, Namespace)
} else {
fmt.Println("Aborting...")
}
},
}
// deletePgoroleCmd ...
var deletePgoroleCmd = &cobra.Command{
Use: "pgorole",
Short: "Delete a pgorole",
Long: `Delete a pgorole. For example:
pgo delete pgorole somerole`,
Run: func(cmd *cobra.Command, args []string) {
if Namespace == "" {
Namespace = PGONamespace
}
if len(args) == 0 {
fmt.Println("Error: A pgorole role name is required for this command.")
} else {
if util.AskForConfirmation(NoPrompt, "") {
deletePgorole(args, Namespace)
} else {
fmt.Println("Aborting...")
}
}
},
}
// deletePgouserCmd ...
var deletePgouserCmd = &cobra.Command{
Use: "pgouser",
Short: "Delete a pgouser",
Long: `Delete a pgouser. For example:
pgo delete pgouser someuser`,
Run: func(cmd *cobra.Command, args []string) {
if Namespace == "" {
Namespace = PGONamespace
}
if len(args) == 0 {
fmt.Println("Error: A pgouser username is required for this command.")
} else {
if util.AskForConfirmation(NoPrompt, "") {
deletePgouser(args, Namespace)
} else {
fmt.Println("Aborting...")
}
}
},
}
// deletePgAdminCmd ...
var deletePgAdminCmd = &cobra.Command{
Use: "pgadmin",
Short: "Delete a pgAdmin instance from a cluster",
Long: `Delete a pgAdmin instance from a cluster. For example:
pgo delete pgadmin mycluster`,
Run: func(cmd *cobra.Command, args []string) {
if Namespace == "" {
Namespace = PGONamespace
}
if len(args) == 0 && Selector == "" {
fmt.Println("Error: A cluster name or selector is required for this command.")
} else {
if util.AskForConfirmation(NoPrompt, "") {
deletePgAdmin(args, Namespace)
} else {
fmt.Println("Aborting...")
}
}
},
}
// deletePgbouncerCmd ...
var deletePgbouncerCmd = &cobra.Command{
Use: "pgbouncer",
Short: "Delete a pgbouncer from a cluster",
Long: `Delete a pgbouncer from a cluster. For example:
pgo delete pgbouncer mycluster`,
Run: func(cmd *cobra.Command, args []string) {
if Namespace == "" {
Namespace = PGONamespace
}
if len(args) == 0 && Selector == "" {
fmt.Println("Error: A cluster name or selector is required for this command.")
} else {
if util.AskForConfirmation(NoPrompt, "") {
deletePgbouncer(args, Namespace)
} else {
fmt.Println("Aborting...")
}
}
},
}
// deletePolicyCmd ...
var deletePolicyCmd = &cobra.Command{
Use: "policy",
Short: "Delete a SQL policy",
Long: `Delete a policy. For example:
pgo delete policy mypolicy`,
Run: func(cmd *cobra.Command, args []string) {
if Namespace == "" {
Namespace = PGONamespace
}
if len(args) == 0 && !AllFlag {
fmt.Println("Error: A policy name or --all is required for this command.")
} else {
if util.AskForConfirmation(NoPrompt, "") {
deletePolicy(args, Namespace)
} else {
fmt.Println("Aborting...")
}
}
},
}
// deleteScheduleCmd ...
var deleteScheduleCmd = &cobra.Command{
Use: "schedule",
Short: "Delete a schedule",
Long: `Delete a cron-like schedule. For example:
pgo delete schedule mycluster
pgo delete schedule --selector=env=test
pgo delete schedule --schedule-name=mycluster-pgbackrest-full`,
Run: func(cmd *cobra.Command, args []string) {
if Namespace == "" {
Namespace = PGONamespace
}
if len(args) == 0 && Selector == "" && ScheduleName == "" {
fmt.Println("Error: cluster name, schedule name or selector is required to delete a schedule.")
return
}
if util.AskForConfirmation(NoPrompt, "") {
deleteSchedule(args, Namespace)
} else {
fmt.Println("Aborting...")
}
},
}
// deleteUserCmd ...
var deleteUserCmd = &cobra.Command{
Use: "user",
Short: "Delete a user",
Long: `Delete a user. For example:
pgo delete user --username=someuser --selector=name=mycluster`,
Run: func(cmd *cobra.Command, args []string) {
if Namespace == "" {
Namespace = PGONamespace
}
if len(args) == 0 && AllFlag == false && Selector == "" {
fmt.Println("Error: --all, --selector, or a list of clusters is required for this command")
} else {
if util.AskForConfirmation(NoPrompt, "") {
deleteUser(args, Namespace)
} else {
fmt.Println("Aborting...")
}
}
},
}