github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/dataprotection/backup.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package dataprotection 21 22 import ( 23 "fmt" 24 25 "github.com/spf13/cobra" 26 "k8s.io/cli-runtime/pkg/genericiooptions" 27 cmdutil "k8s.io/kubectl/pkg/cmd/util" 28 "k8s.io/kubectl/pkg/util/templates" 29 30 "github.com/1aal/kubeblocks/pkg/cli/cmd/cluster" 31 "github.com/1aal/kubeblocks/pkg/cli/create" 32 "github.com/1aal/kubeblocks/pkg/cli/delete" 33 "github.com/1aal/kubeblocks/pkg/cli/list" 34 "github.com/1aal/kubeblocks/pkg/cli/printer" 35 "github.com/1aal/kubeblocks/pkg/cli/types" 36 "github.com/1aal/kubeblocks/pkg/cli/util" 37 ) 38 39 var ( 40 createBackupExample = templates.Examples(` 41 # Create a backup for the cluster, use the default backup policy and volume snapshot backup method 42 kbcli dp backup mybackup --cluster mycluster 43 44 # create a backup with a specified method, run "kbcli cluster desc-backup-policy mycluster" to show supported backup methods 45 kbcli dp backup mybackup --cluster mycluster --method mymethod 46 47 # create a backup with specified backup policy, run "kbcli cluster list-backup-policy mycluster" to show the cluster supported backup policies 48 kbcli dp backup mybackup --cluster mycluster --policy mypolicy 49 50 # create a backup from a parent backup 51 kbcli dp backup mybackup --cluster mycluster --parent-backup myparentbackup 52 `) 53 54 deleteBackupExample = templates.Examples(` 55 # delete a backup 56 kbcli dp delete-backup mybackup 57 `) 58 59 describeBackupExample = templates.Examples(` 60 # describe a backup 61 kbcli dp describe-backup mybackup 62 `) 63 64 listBackupExample = templates.Examples(` 65 # list all backups 66 kbcli dp list-backups 67 68 # list all backups of specified cluster 69 kbcli dp list-backups --cluster mycluster 70 `) 71 ) 72 73 func newBackupCommand(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 74 customOutPut := func(opt *create.CreateOptions) { 75 output := fmt.Sprintf("Backup %s created successfully, you can view the progress:", opt.Name) 76 printer.PrintLine(output) 77 nextLine := fmt.Sprintf("\tkbcli dp list-backups %s -n %s", opt.Name, opt.Namespace) 78 printer.PrintLine(nextLine) 79 } 80 81 clusterName := "" 82 83 o := &cluster.CreateBackupOptions{ 84 CreateOptions: create.CreateOptions{ 85 IOStreams: streams, 86 Factory: f, 87 GVR: types.BackupGVR(), 88 CueTemplateName: "backup_template.cue", 89 CustomOutPut: customOutPut, 90 }, 91 } 92 o.CreateOptions.Options = o 93 94 cmd := &cobra.Command{ 95 Use: "backup NAME", 96 Short: "Create a backup for the cluster.", 97 Example: createBackupExample, 98 Run: func(cmd *cobra.Command, args []string) { 99 if len(args) > 0 { 100 o.BackupName = args[0] 101 } 102 if clusterName != "" { 103 o.Args = []string{clusterName} 104 } 105 cmdutil.BehaviorOnFatal(printer.FatalWithRedColor) 106 cmdutil.CheckErr(o.CompleteBackup()) 107 cmdutil.CheckErr(o.Validate()) 108 cmdutil.CheckErr(o.Run()) 109 }, 110 } 111 112 cmd.Flags().StringVar(&o.BackupMethod, "method", "", "Backup methods are defined in backup policy (required), if only one backup method in backup policy, use it as default backup method, if multiple backup methods in backup policy, use method which volume snapshot is true as default backup method") 113 cmd.Flags().StringVar(&clusterName, "cluster", "", "Cluster name") 114 cmd.Flags().StringVar(&o.BackupPolicy, "policy", "", "Backup policy name, if not specified, use the cluster default backup policy") 115 cmd.Flags().StringVar(&o.DeletionPolicy, "deletion-policy", "Delete", "Deletion policy for backup, determine whether the backup content in backup repo will be deleted after the backup is deleted, supported values: [Delete, Retain]") 116 cmd.Flags().StringVar(&o.RetentionPeriod, "retention-period", "", "Retention period for backup, supported values: [1y, 1mo, 1d, 1h, 1m] or combine them [1y1mo1d1h1m], if not specified, the backup will not be automatically deleted, you need to manually delete it.") 117 cmd.Flags().StringVar(&o.ParentBackupName, "parent-backup", "", "Parent backup name, used for incremental backup") 118 util.RegisterClusterCompletionFunc(cmd, f) 119 o.RegisterBackupFlagCompletionFunc(cmd, f) 120 121 return cmd 122 } 123 124 func newBackupDeleteCommand(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 125 o := delete.NewDeleteOptions(f, streams, types.BackupGVR()) 126 clusterName := "" 127 cmd := &cobra.Command{ 128 Use: "delete-backup", 129 Short: "Delete a backup.", 130 Example: deleteBackupExample, 131 ValidArgsFunction: util.ResourceNameCompletionFunc(f, types.BackupGVR()), 132 Run: func(cmd *cobra.Command, args []string) { 133 o.Names = args 134 cmdutil.BehaviorOnFatal(printer.FatalWithRedColor) 135 util.CheckErr(completeForDeleteBackup(o, clusterName)) 136 util.CheckErr(o.Run()) 137 }, 138 } 139 140 o.AddFlags(cmd) 141 cmd.Flags().StringVar(&clusterName, "cluster", "", "The cluster name.") 142 util.RegisterClusterCompletionFunc(cmd, f) 143 144 return cmd 145 } 146 147 func completeForDeleteBackup(o *delete.DeleteOptions, cluster string) error { 148 if o.Force && len(o.Names) == 0 { 149 if cluster == "" { 150 return fmt.Errorf("must give a backup name or cluster name") 151 } 152 o.LabelSelector = util.BuildLabelSelectorByNames(o.LabelSelector, []string{cluster}) 153 } 154 return nil 155 } 156 157 func newBackupDescribeCommand(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 158 o := cluster.DescribeBackupOptions{ 159 Factory: f, 160 IOStreams: streams, 161 Gvr: types.BackupGVR(), 162 } 163 cmd := &cobra.Command{ 164 Use: "describe-backup NAME", 165 Short: "Describe a backup", 166 Aliases: []string{"desc-backup"}, 167 ValidArgsFunction: util.ResourceNameCompletionFunc(f, types.BackupGVR()), 168 Example: describeBackupExample, 169 Run: func(cmd *cobra.Command, args []string) { 170 cmdutil.BehaviorOnFatal(printer.FatalWithRedColor) 171 util.CheckErr(o.Complete(args)) 172 util.CheckErr(o.Run()) 173 }, 174 } 175 return cmd 176 } 177 178 func newListBackupCommand(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 179 o := &cluster.ListBackupOptions{ListOptions: list.NewListOptions(f, streams, types.BackupGVR())} 180 clusterName := "" 181 cmd := &cobra.Command{ 182 Use: "list-backups", 183 Short: "List backups.", 184 Aliases: []string{"ls-backups"}, 185 Example: listBackupExample, 186 ValidArgsFunction: util.ResourceNameCompletionFunc(f, o.GVR), 187 Run: func(cmd *cobra.Command, args []string) { 188 if clusterName != "" { 189 o.LabelSelector = util.BuildLabelSelectorByNames(o.LabelSelector, []string{clusterName}) 190 } 191 o.Names = args 192 cmdutil.BehaviorOnFatal(printer.FatalWithRedColor) 193 cmdutil.CheckErr(o.Complete()) 194 cmdutil.CheckErr(cluster.PrintBackupList(*o)) 195 }, 196 } 197 o.AddFlags(cmd, true) 198 cmd.Flags().StringVar(&clusterName, "cluster", "", "List backups in the specified cluster") 199 util.RegisterClusterCompletionFunc(cmd, f) 200 201 return cmd 202 }