Implement backup details CLI (#306)

Returns RestorePointDetails

Closes #297
This commit is contained in:
Vaibhav Kamra 2022-07-08 16:16:34 -07:00 committed by GitHub
parent c5f152477d
commit acb468d0f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 1 deletions

View File

@ -13,10 +13,12 @@ func AddCommands(parent *cobra.Command) {
parent.AddCommand(backupCmd) parent.AddCommand(backupCmd)
backupCmd.AddCommand(createCmd) backupCmd.AddCommand(createCmd)
backupCmd.AddCommand(listCmd) backupCmd.AddCommand(listCmd)
backupCmd.AddCommand(detailsCmd)
for _, addBackupTo := range backupCommands { for _, addBackupTo := range backupCommands {
addBackupTo(createCmd) addBackupTo(createCmd)
addBackupTo(listCmd) addBackupTo(listCmd)
addBackupTo(detailsCmd)
} }
} }
@ -67,3 +69,19 @@ var listCmd = &cobra.Command{
func handleListCmd(cmd *cobra.Command, args []string) { func handleListCmd(cmd *cobra.Command, args []string) {
cmd.Help() cmd.Help()
} }
// The backup details subcommand.
// `corso backup list <service> [<flag>...]`
var detailsCommand = "details"
var detailsCmd = &cobra.Command{
Use: detailsCommand,
Short: "Shows the details of a restore point for a service",
Run: handleDetailsCmd,
Args: cobra.NoArgs,
}
// Handler for calls to `corso backup details`.
// Produces the same output as `corso backup details --help`.
func handleDetailsCmd(cmd *cobra.Command, args []string) {
cmd.Help()
}

View File

@ -18,6 +18,7 @@ import (
// exchange bucket info from flags // exchange bucket info from flags
var ( var (
user string user string
rpID string
) )
// called by backup.go to map parent subcommands to provider-specific handling. // called by backup.go to map parent subcommands to provider-specific handling.
@ -32,6 +33,10 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command {
fs.StringVar(&user, "user", "", "ID of the user whose Exchange data is to be backed up.") fs.StringVar(&user, "user", "", "ID of the user whose Exchange data is to be backed up.")
case listCommand: case listCommand:
c, _ = utils.AddCommand(parent, exchangeListCmd) c, _ = utils.AddCommand(parent, exchangeListCmd)
case detailsCommand:
c, fs = utils.AddCommand(parent, exchangeDetailsCmd)
fs.StringVar(&rpID, "restore-point-details", "", "ID of the restore point details to be shown.")
c.MarkFlagRequired("restore-point-details")
} }
return c return c
} }
@ -142,3 +147,51 @@ func listExchangeCmd(cmd *cobra.Command, args []string) error {
} }
return nil return nil
} }
// `corso backup details exchange [<flag>...]`
var exchangeDetailsCmd = &cobra.Command{
Use: exchangeServiceCommand,
Short: "Shows the details of a M365 Exchange service backup",
RunE: detailsExchangeCmd,
Args: cobra.NoArgs,
}
// lists the history of backup operations
func detailsExchangeCmd(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
s, acct, err := config.GetStorageAndAccount(true, nil)
if err != nil {
return err
}
m365, err := acct.M365Config()
if err != nil {
return errors.Wrap(err, "Failed to parse m365 account config")
}
logger.Ctx(ctx).Debugw(
"Called - "+cmd.CommandPath(),
"tenantID", m365.TenantID)
r, err := repository.Connect(ctx, acct, s)
if err != nil {
return errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)
}
defer utils.CloseRepo(ctx, r)
rpd, err := r.RestorePointDetails(ctx, rpID)
if err != nil {
return errors.Wrap(err, "Failed to get restorepoint details in the repository")
}
// TODO: Can be used to print in alternative forms
p, err := cli.Format("json", os.Stdout)
if err != nil {
return err
}
defer p.Flush()
p.Print(*rpd)
return nil
}

View File

@ -30,6 +30,7 @@ func (suite *ExchangeSuite) TestAddExchangeCommands() {
}{ }{
{"create exchange", createCommand, expectUse, exchangeCreateCmd.Short, createExchangeCmd}, {"create exchange", createCommand, expectUse, exchangeCreateCmd.Short, createExchangeCmd},
{"list exchange", listCommand, expectUse, exchangeListCmd.Short, listExchangeCmd}, {"list exchange", listCommand, expectUse, exchangeListCmd.Short, listExchangeCmd},
{"details exchange", detailsCommand, expectUse, exchangeDetailsCmd.Short, detailsExchangeCmd},
} }
for _, test := range table { for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) { suite.T().Run(test.name, func(t *testing.T) {

View File

@ -104,7 +104,6 @@ func (op *BackupOperation) Run(ctx context.Context) error {
stats.writeErr = err stats.writeErr = err
return err return err
} }
return nil return nil
} }

View File

@ -5,6 +5,7 @@ import (
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/kopia/kopia/repo/manifest"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/alcionai/corso/internal/kopia" "github.com/alcionai/corso/internal/kopia"
@ -165,3 +166,13 @@ func (r Repository) RestorePoints(ctx context.Context) ([]*restorepoint.RestoreP
} }
return rps, nil return rps, nil
} }
// RestorePoints lists restorepoints in a respository
func (r Repository) RestorePointDetails(ctx context.Context, rpDetailsID string) (*restorepoint.Details, error) {
rpd := restorepoint.Details{}
err := r.modelStore.GetWithModelStoreID(ctx, kopia.RestorePointDetailsModel, manifest.ID(rpDetailsID), &rpd)
if err != nil {
return nil, err
}
return &rpd, nil
}