diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index 4475456e1..c2da42563 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -33,7 +33,7 @@ func addExchangeApp(parent *cobra.Command) *cobra.Command { // `corso backup create exchange [...]` var exchangeCreateCmd = &cobra.Command{ Use: "exchange", - Short: "Backup M365 Exchange", + Short: "Backup M365 Exchange service data", RunE: createExchangeCmd, Args: cobra.NoArgs, } diff --git a/src/cli/cli.go b/src/cli/cli.go index f6fabb848..d0d4c709f 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -11,6 +11,7 @@ import ( "github.com/alcionai/corso/cli/backup" "github.com/alcionai/corso/cli/config" "github.com/alcionai/corso/cli/repo" + "github.com/alcionai/corso/cli/restore" "github.com/alcionai/corso/pkg/logger" ) @@ -57,8 +58,11 @@ func Handle() { corsoCmd.Flags().BoolP("version", "v", version, "current version info") corsoCmd.PersistentFlags().StringVar(&cfgFile, "config-file", "", "config file (default is $HOME/.corso)") + corsoCmd.CompletionOptions.DisableDefaultCmd = true + repo.AddCommands(corsoCmd) backup.AddCommands(corsoCmd) + restore.AddCommands(corsoCmd) ctx, log := logger.Seed(context.Background()) defer log.Sync() // flush all logs in the buffer diff --git a/src/cli/config/config.go b/src/cli/config/config.go index 21de643e1..b457c3497 100644 --- a/src/cli/config/config.go +++ b/src/cli/config/config.go @@ -5,12 +5,13 @@ import ( "path" "strings" + "github.com/pkg/errors" + "github.com/spf13/viper" + "github.com/alcionai/corso/cli/utils" "github.com/alcionai/corso/pkg/credentials" "github.com/alcionai/corso/pkg/repository" "github.com/alcionai/corso/pkg/storage" - "github.com/pkg/errors" - "github.com/spf13/viper" ) const ( diff --git a/src/cli/repo/repo.go b/src/cli/repo/repo.go index 20a588b95..6836344ab 100644 --- a/src/cli/repo/repo.go +++ b/src/cli/repo/repo.go @@ -24,7 +24,7 @@ func AddCommands(parent *cobra.Command) { // `corso repo [] [...]` var repoCmd = &cobra.Command{ Use: "repo", - Short: "Manage your repositories.", + Short: "Manage your repositories", Long: `Initialize, configure, and connect to your account backup repositories.`, Run: handleRepoCmd, Args: cobra.NoArgs, diff --git a/src/cli/restore/exchange.go b/src/cli/restore/exchange.go new file mode 100644 index 000000000..dc775aebf --- /dev/null +++ b/src/cli/restore/exchange.go @@ -0,0 +1,71 @@ +package restore + +import ( + "fmt" + + "github.com/pkg/errors" + "github.com/spf13/cobra" + + "github.com/alcionai/corso/cli/config" + "github.com/alcionai/corso/cli/utils" + "github.com/alcionai/corso/pkg/credentials" + "github.com/alcionai/corso/pkg/repository" +) + +// exchange bucket info from flags +var ( + user string +) + +// called by restore.go to map parent subcommands to provider-specific handling. +func addExchangeApp(parent *cobra.Command) *cobra.Command { + parent.AddCommand(exchangeCreateCmd) + + // todo (keepers): add flags. + + return exchangeCreateCmd +} + +// `corso restore create exchange [...]` +var exchangeCreateCmd = &cobra.Command{ + Use: "exchange", + Short: "Restore M365 Exchange service data", + RunE: createExchangeCmd, + Args: cobra.NoArgs, +} + +// initializes a s3 repo. +func createExchangeCmd(cmd *cobra.Command, args []string) error { + s, cfgTenantID, err := config.MakeS3Config(true, nil) + if err != nil { + return err + } + + m365 := credentials.GetM365() + a := repository.Account{ + TenantID: m365.TenantID, + ClientID: m365.ClientID, + ClientSecret: m365.ClientSecret, + } + if len(cfgTenantID) > 0 { + a.TenantID = cfgTenantID + } + + fmt.Printf( + "Called - %s\n\t365TenantID:\t%s\n\t356Client:\t%s\n\tfound 356Secret:\t%v\n", + cmd.CommandPath(), + m365.TenantID, + m365.ClientID, + len(m365.ClientSecret) > 0) + + r, err := repository.Connect(cmd.Context(), a, s) + if err != nil { + return errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider) + } + defer utils.CloseRepo(cmd.Context(), r) + + // todo (keepers): actually restore things + + fmt.Printf("Restored Exchange in %s for user %s.\n", s.Provider, user) + return nil +} diff --git a/src/cli/restore/restore.go b/src/cli/restore/restore.go new file mode 100644 index 000000000..3c5364d95 --- /dev/null +++ b/src/cli/restore/restore.go @@ -0,0 +1,34 @@ +package restore + +import ( + "github.com/spf13/cobra" +) + +var restoreApplications = []func(parent *cobra.Command) *cobra.Command{ + addExchangeApp, +} + +// AddCommands attaches all `corso restore * *` commands to the parent. +func AddCommands(parent *cobra.Command) { + parent.AddCommand(restoreCmd) + + for _, addRestoreTo := range restoreApplications { + addRestoreTo(restoreCmd) + } +} + +// The restore category of commands. +// `corso restore [] [...]` +var restoreCmd = &cobra.Command{ + Use: "restore", + Short: "Restore your service data", + Long: `Restore the data stored in one of your M365 services.`, + Run: handleRestoreCmd, + Args: cobra.NoArgs, +} + +// Handler for flat calls to `corso restore`. +// Produces the same output as `corso restore --help`. +func handleRestoreCmd(cmd *cobra.Command, args []string) { + cmd.Help() +} diff --git a/src/go.mod b/src/go.mod index 616f521b9..02d806916 100644 --- a/src/go.mod +++ b/src/go.mod @@ -87,7 +87,7 @@ require ( golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect - golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d // indirect + golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098 // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac // indirect google.golang.org/grpc v1.47.0 // indirect diff --git a/src/go.sum b/src/go.sum index 6c60f4fb3..8e132ab8d 100644 --- a/src/go.sum +++ b/src/go.sum @@ -536,8 +536,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d h1:Zu/JngovGLVi6t2J3nmAf3AoTDwuzw85YZ3b9o4yU7s= -golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098 h1:PgOr27OhUx2IRqGJ2RxAWI4dJQ7bi9cSrB82uzFzfUA= +golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/src/internal/testing/config.go b/src/internal/testing/config.go index 7def8fda1..20af7be2c 100644 --- a/src/internal/testing/config.go +++ b/src/internal/testing/config.go @@ -5,9 +5,10 @@ import ( "path" "strings" - "github.com/alcionai/corso/pkg/credentials" "github.com/pkg/errors" "github.com/spf13/viper" + + "github.com/alcionai/corso/pkg/credentials" ) const (