diff --git a/docs/user_docs/cli/cli.md b/docs/user_docs/cli/cli.md index 41c62ee1068..1bbd94e9db4 100644 --- a/docs/user_docs/cli/cli.md +++ b/docs/user_docs/cli/cli.md @@ -92,6 +92,7 @@ Cluster command. * [kbcli cluster describe](kbcli_cluster_describe.md) - Show details of a specific cluster. * [kbcli cluster describe-account](kbcli_cluster_describe-account.md) - Describe account roles and related information * [kbcli cluster describe-backup](kbcli_cluster_describe-backup.md) - Describe a backup. +* [kbcli cluster describe-backup-policy](kbcli_cluster_describe-backup-policy.md) - Describe backup policy * [kbcli cluster describe-config](kbcli_cluster_describe-config.md) - Show details of a specific reconfiguring. * [kbcli cluster describe-ops](kbcli_cluster_describe-ops.md) - Show details of a specific OpsRequest. * [kbcli cluster diff-config](kbcli_cluster_diff-config.md) - Show the difference in parameters between the two submitted OpsRequest. diff --git a/docs/user_docs/cli/kbcli_cluster.md b/docs/user_docs/cli/kbcli_cluster.md index 3b89445f452..292f632b747 100644 --- a/docs/user_docs/cli/kbcli_cluster.md +++ b/docs/user_docs/cli/kbcli_cluster.md @@ -50,6 +50,7 @@ Cluster command. * [kbcli cluster describe](kbcli_cluster_describe.md) - Show details of a specific cluster. * [kbcli cluster describe-account](kbcli_cluster_describe-account.md) - Describe account roles and related information * [kbcli cluster describe-backup](kbcli_cluster_describe-backup.md) - Describe a backup. +* [kbcli cluster describe-backup-policy](kbcli_cluster_describe-backup-policy.md) - Describe backup policy * [kbcli cluster describe-config](kbcli_cluster_describe-config.md) - Show details of a specific reconfiguring. * [kbcli cluster describe-ops](kbcli_cluster_describe-ops.md) - Show details of a specific OpsRequest. * [kbcli cluster diff-config](kbcli_cluster_diff-config.md) - Show the difference in parameters between the two submitted OpsRequest. diff --git a/docs/user_docs/cli/kbcli_cluster_describe-backup-policy.md b/docs/user_docs/cli/kbcli_cluster_describe-backup-policy.md new file mode 100644 index 00000000000..d0f0b7c9c0d --- /dev/null +++ b/docs/user_docs/cli/kbcli_cluster_describe-backup-policy.md @@ -0,0 +1,53 @@ +--- +title: kbcli cluster describe-backup-policy +--- + +Describe backup policy + +``` +kbcli cluster describe-backup-policy +``` + +### Examples + +``` + # describe a backup policy + kbcli cluster describe-backup-policy mycluster-mysql-backup-policy +``` + +### Options + +``` + -h, --help help for describe-backup-policy +``` + +### Options inherited from parent commands + +``` + --as string Username to impersonate for the operation. User could be a regular user or a service account in a namespace. + --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --as-uid string UID to impersonate for the operation. + --cache-dir string Default cache directory (default "$HOME/.kube/cache") + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to the kubeconfig file to use for CLI requests. + --match-server-version Require server version to match client version + -n, --namespace string If present, the namespace scope for this CLI request + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + -s, --server string The address and port of the Kubernetes API server + --tls-server-name string Server name to use for server certificate validation. If it is not provided, the hostname used to contact the server is used + --token string Bearer token for authentication to the API server + --user string The name of the kubeconfig user to use +``` + +### SEE ALSO + +* [kbcli cluster](kbcli_cluster.md) - Cluster command. + +#### Go Back to [CLI Overview](cli.md) Homepage. + diff --git a/internal/cli/cmd/cluster/cluster.go b/internal/cli/cmd/cluster/cluster.go index 6ffde3d5249..0b2d53f070e 100644 --- a/internal/cli/cmd/cluster/cluster.go +++ b/internal/cli/cmd/cluster/cluster.go @@ -93,6 +93,7 @@ func NewClusterCmd(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobr Commands: []*cobra.Command{ NewListBackupPolicyCmd(f, streams), NewEditBackupPolicyCmd(f, streams), + NewDescribeBackupPolicyCmd(f, streams), NewCreateBackupCmd(f, streams), NewListBackupCmd(f, streams), NewDeleteBackupCmd(f, streams), diff --git a/internal/cli/cmd/cluster/dataprotection.go b/internal/cli/cmd/cluster/dataprotection.go index 2936247de0e..56157c2d3a7 100644 --- a/internal/cli/cmd/cluster/dataprotection.go +++ b/internal/cli/cmd/cluster/dataprotection.go @@ -25,6 +25,7 @@ import ( "fmt" "reflect" "sort" + "strconv" "strings" "time" @@ -115,6 +116,10 @@ var ( # describe a backup kbcli cluster describe-backup backup-default-mycluster-20230616190023 `) + describeBackupPolicyExample = templates.Examples(` + # describe a backup policy + kbcli cluster describe-backup-policy mycluster-mysql-backup-policy + `) ) const annotationTrueValue = "true" @@ -853,6 +858,93 @@ func (o *editBackupPolicyOptions) applyChanges(backupPolicy *dpv1alpha1.BackupPo return nil } +type describeBackupPolicyOptions struct { + namespace string + names []string + dynamic dynamic.Interface + Factory cmdutil.Factory + client clientset.Interface + + genericclioptions.IOStreams +} + +func (o *describeBackupPolicyOptions) Complete(args []string) error { + var err error + + if len(args) == 0 { + return fmt.Errorf("backupPolicy name should be specified") + } + + o.names = args + + if o.client, err = o.Factory.KubernetesClientSet(); err != nil { + return err + } + + if o.dynamic, err = o.Factory.DynamicClient(); err != nil { + return err + } + + if o.namespace, _, err = o.Factory.ToRawKubeConfigLoader().Namespace(); err != nil { + return err + } + return nil +} + +func (o *describeBackupPolicyOptions) Run() error { + for _, name := range o.names { + backupPolicyObj := &dpv1alpha1.BackupPolicy{} + if err := cluster.GetK8SClientObject(o.dynamic, backupPolicyObj, types.BackupPolicyGVR(), o.namespace, name); err != nil { + return err + } + if err := o.printBackupPolicyObj(backupPolicyObj); err != nil { + return err + } + } + return nil +} + +func (o *describeBackupPolicyOptions) printBackupPolicyObj(obj *dpv1alpha1.BackupPolicy) error { + printer.PrintLine("Summary:") + realPrintPairStringToLine("Name", obj.Name) + realPrintPairStringToLine("Cluster", obj.Labels[constant.AppInstanceLabelKey]) + realPrintPairStringToLine("Namespace", obj.Namespace) + if obj.Spec.BackupRepoName != nil { + realPrintPairStringToLine("Backup Repo Name", *obj.Spec.BackupRepoName) + } + + printer.PrintLine("\nBackup Methods:") + p := printer.NewTablePrinter(o.Out) + p.SetHeader("Name", "ActionSet", "snapshot-volumes") + for _, v := range obj.Spec.BackupMethods { + p.AddRow(v.Name, v.ActionSetName, strconv.FormatBool(*v.SnapshotVolumes)) + } + p.Print() + + return nil +} + +func NewDescribeBackupPolicyCmd(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command { + o := &describeBackupPolicyOptions{ + Factory: f, + IOStreams: streams, + } + cmd := &cobra.Command{ + Use: "describe-backup-policy", + DisableFlagsInUseLine: true, + Aliases: []string{"describe-bp"}, + Short: "Describe backup policy", + Example: describeBackupPolicyExample, + ValidArgsFunction: util.ResourceNameCompletionFunc(f, types.BackupPolicyGVR()), + Run: func(cmd *cobra.Command, args []string) { + cmdutil.BehaviorOnFatal(printer.FatalWithRedColor) + util.CheckErr(o.Complete(args)) + util.CheckErr(o.Run()) + }, + } + return cmd +} + func (o *DescribeBackupOptions) Complete(args []string) error { var err error diff --git a/internal/cli/cmd/cluster/dataprotection_test.go b/internal/cli/cmd/cluster/dataprotection_test.go index 0d808d0d3b1..c9676b842c2 100644 --- a/internal/cli/cmd/cluster/dataprotection_test.go +++ b/internal/cli/cmd/cluster/dataprotection_test.go @@ -392,6 +392,29 @@ var _ = Describe("DataProtection", func() { o.client = testing.FakeClientSet() Expect(o.Run()).Should(Succeed()) }) + + It("describe-backup-policy", func() { + cmd := NewDescribeBackupPolicyCmd(tf, streams) + Expect(cmd).ShouldNot(BeNil()) + By("test describe-backup-policy cmd with no backup policy") + tf.FakeDynamicClient = testing.FakeDynamicClient() + o := describeBackupPolicyOptions{ + Factory: tf, + IOStreams: streams, + } + args := []string{} + Expect(o.Complete(args)).Should(HaveOccurred()) + + By("test describe-backup-policy") + policyName := "test1" + policy1 := testing.FakeBackupPolicy(policyName, testing.ClusterName) + args = append(args, policyName) + tf.FakeDynamicClient = testing.FakeDynamicClient(policy1) + Expect(o.Complete(args)).Should(Succeed()) + o.client = testing.FakeClientSet() + Expect(o.Run()).Should(Succeed()) + }) + }) func mockBackupInfo(dynamic dynamic.Interface, backupName, clusterName string, timeRange map[string]any, backupMethod string) {