Implement backup details CLI (#306)
Returns RestorePointDetails Closes #297
This commit is contained in:
parent
c5f152477d
commit
acb468d0f6
@ -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()
|
||||||
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
}
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user