From 214db6fe97858ecaf84bdb8487f9321c52d9f864 Mon Sep 17 00:00:00 2001 From: neha_gupta Date: Fri, 3 Mar 2023 13:47:41 +0530 Subject: [PATCH] add corso start event at start of cli command (#2534) ## Description Trigger an event at start of every CLI command. ## Does this PR need a docs update or release note? - [ ] :white_check_mark: Yes, it's included ## Type of change - [x] :sunflower: Feature ## Issue(s) * https://github.com/alcionai/corso/issues/1761 ## Test Plan - [ ] :muscle: Manual --------- Co-authored-by: Keepers Co-authored-by: aviator-app[bot] <48659329+aviator-app[bot]@users.noreply.github.com> --- src/cli/backup/exchange.go | 26 +++++++-------- src/cli/backup/onedrive.go | 26 +++++++-------- src/cli/backup/sharepoint.go | 26 +++++++-------- src/cli/cli.go | 28 ++++++++++++++-- src/cli/config/config.go | 61 ++++++++++++++++++++++++++--------- src/cli/config/config_test.go | 25 +++++++------- src/cli/repo/s3.go | 29 +++++++++++------ src/cli/restore/exchange.go | 6 ++-- src/cli/restore/onedrive.go | 6 ++-- src/cli/restore/sharepoint.go | 6 ++-- src/cli/utils/utils.go | 22 +++++++++++++ src/internal/events/events.go | 2 +- 12 files changed, 174 insertions(+), 89 deletions(-) diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index 9045d611e..42b6456fd 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -260,14 +260,14 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error { return err } - s, acct, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } - r, err := repository.Connect(ctx, acct, s, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) @@ -277,7 +277,7 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error { // TODO: log/print recoverable errors errs := fault.New(false) - users, err := m365.UserPNs(ctx, acct, errs) + users, err := m365.UserPNs(ctx, cfg.Account, errs) if err != nil { return Only(ctx, errors.Wrap(err, "Failed to retrieve M365 user(s)")) } @@ -384,14 +384,14 @@ func exchangeListCmd() *cobra.Command { func listExchangeCmd(cmd *cobra.Command, args []string) error { ctx := cmd.Context() - s, acct, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } - r, err := repository.Connect(ctx, acct, s, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) @@ -465,16 +465,16 @@ func detailsExchangeCmd(cmd *cobra.Command, args []string) error { Populated: utils.GetPopulatedFlags(cmd), } - s, acct, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } ctrlOpts := options.Control() - r, err := repository.Connect(ctx, acct, s, ctrlOpts) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, ctrlOpts) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) @@ -549,14 +549,14 @@ func deleteExchangeCmd(cmd *cobra.Command, args []string) error { return nil } - s, acct, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } - r, err := repository.Connect(ctx, acct, s, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) diff --git a/src/cli/backup/onedrive.go b/src/cli/backup/onedrive.go index a6bd1cb4a..e74d719be 100644 --- a/src/cli/backup/onedrive.go +++ b/src/cli/backup/onedrive.go @@ -184,14 +184,14 @@ func createOneDriveCmd(cmd *cobra.Command, args []string) error { return err } - s, acct, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } - r, err := repository.Connect(ctx, acct, s, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) @@ -201,7 +201,7 @@ func createOneDriveCmd(cmd *cobra.Command, args []string) error { // TODO: log/print recoverable errors errs := fault.New(false) - users, err := m365.UserPNs(ctx, acct, errs) + users, err := m365.UserPNs(ctx, cfg.Account, errs) if err != nil { return Only(ctx, errors.Wrap(err, "Failed to retrieve M365 users")) } @@ -285,14 +285,14 @@ func oneDriveListCmd() *cobra.Command { func listOneDriveCmd(cmd *cobra.Command, args []string) error { ctx := cmd.Context() - s, acct, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } - r, err := repository.Connect(ctx, acct, s, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) @@ -345,16 +345,16 @@ func detailsOneDriveCmd(cmd *cobra.Command, args []string) error { return nil } - s, acct, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } ctrlOpts := options.Control() - r, err := repository.Connect(ctx, acct, s, ctrlOpts) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, ctrlOpts) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) @@ -438,14 +438,14 @@ func deleteOneDriveCmd(cmd *cobra.Command, args []string) error { return nil } - s, acct, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } - r, err := repository.Connect(ctx, acct, s, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) diff --git a/src/cli/backup/sharepoint.go b/src/cli/backup/sharepoint.go index e3b4ef6d7..d6811b2e8 100644 --- a/src/cli/backup/sharepoint.go +++ b/src/cli/backup/sharepoint.go @@ -201,14 +201,14 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error { return err } - s, acct, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } - r, err := repository.Connect(ctx, acct, s, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) @@ -216,7 +216,7 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error { // TODO: log/print recoverable errors errs := fault.New(false) - gc, err := connector.NewGraphConnector(ctx, graph.HTTPClient(graph.NoTimeout()), acct, connector.Sites, errs) + gc, err := connector.NewGraphConnector(ctx, graph.HTTPClient(graph.NoTimeout()), cfg.Account, connector.Sites, errs) if err != nil { return Only(ctx, errors.Wrap(err, "Failed to connect to Microsoft APIs")) } @@ -372,14 +372,14 @@ func sharePointListCmd() *cobra.Command { func listSharePointCmd(cmd *cobra.Command, args []string) error { ctx := cmd.Context() - s, acct, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } - r, err := repository.Connect(ctx, acct, s, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) @@ -432,14 +432,14 @@ func deleteSharePointCmd(cmd *cobra.Command, args []string) error { return nil } - s, acct, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } - r, err := repository.Connect(ctx, acct, s, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) @@ -476,16 +476,16 @@ func detailsSharePointCmd(cmd *cobra.Command, args []string) error { return nil } - s, acct, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } ctrlOpts := options.Control() - r, err := repository.Connect(ctx, acct, s, ctrlOpts) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, ctrlOpts) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) diff --git a/src/cli/cli.go b/src/cli/cli.go index 77a03b1a7..9ab485632 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -42,7 +42,8 @@ func preRun(cc *cobra.Command, args []string) error { return err } - log := logger.Ctx(cc.Context()) + ctx := cc.Context() + log := logger.Ctx(ctx) flags := utils.GetPopulatedFlags(cc) flagSl := make([]string, 0, len(flags)) @@ -55,8 +56,31 @@ func preRun(cc *cobra.Command, args []string) error { avoidTheseCommands := []string{ "corso", "env", "help", "backup", "details", "list", "restore", "delete", "repo", "init", "connect", } + if len(logger.LogFile) > 0 && !slices.Contains(avoidTheseCommands, cc.Use) { - print.Info(cc.Context(), "Logging to file: "+logger.LogFile) + print.Info(ctx, "Logging to file: "+logger.LogFile) + } + + avoidTheseCommands = []string{ + "help for corso", + "Initialize a repository.", + "Initialize a S3 repository", + } + + if !slices.Contains(avoidTheseCommands, cc.Short) { + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) + if err != nil { + log.Error("Error while getting config info to run command: ", cc.Use) + return err + } + + utils.SendStartCorsoEvent( + ctx, + cfg.Storage, + cfg.Account.ID(), + map[string]any{"command": cc.CommandPath()}, + cfg.RepoID, + options.Control()) } log.Infow("cli command", "command", cc.CommandPath(), "flags", flagSl, "version", version.CurrentVersion()) diff --git a/src/cli/config/config.go b/src/cli/config/config.go index 8f532abb6..7c05190fd 100644 --- a/src/cli/config/config.go +++ b/src/cli/config/config.go @@ -24,6 +24,7 @@ const ( PrefixKey = "prefix" DisableTLSKey = "disable_tls" DisableTLSVerificationKey = "disable_tls_verification" + RepoID = "repo_id" // M365 config AccountProviderTypeKey = "account_provider" @@ -37,6 +38,14 @@ var ( displayDefaultFP = filepath.Join("$HOME", ".corso.toml") ) +// RepoDetails holds the repository configuration retrieved from +// the .corso.toml configuration file. +type RepoDetails struct { + Storage storage.Storage + Account account.Account + RepoID string +} + // Attempts to set the default dir and config file path. // Default is always $HOME. func init() { @@ -178,13 +187,23 @@ func Read(ctx context.Context) error { // WriteRepoConfig currently just persists corso config to the config file // It does not check for conflicts or existing data. -func WriteRepoConfig(ctx context.Context, s3Config storage.S3Config, m365Config account.M365Config) error { - return writeRepoConfigWithViper(GetViper(ctx), s3Config, m365Config) +func WriteRepoConfig( + ctx context.Context, + s3Config storage.S3Config, + m365Config account.M365Config, + repoID string, +) error { + return writeRepoConfigWithViper(GetViper(ctx), s3Config, m365Config, repoID) } // writeRepoConfigWithViper implements WriteRepoConfig, but takes in a viper // struct for testing. -func writeRepoConfigWithViper(vpr *viper.Viper, s3Config storage.S3Config, m365Config account.M365Config) error { +func writeRepoConfigWithViper( + vpr *viper.Viper, + s3Config storage.S3Config, + m365Config account.M365Config, + repoID string, +) error { s3Config = s3Config.Normalize() // Rudimentary support for persisting repo config // TODO: Handle conflicts, support other config types @@ -194,6 +213,7 @@ func writeRepoConfigWithViper(vpr *viper.Viper, s3Config storage.S3Config, m365C vpr.Set(PrefixKey, s3Config.Prefix) vpr.Set(DisableTLSKey, s3Config.DoNotUseTLS) vpr.Set(DisableTLSVerificationKey, s3Config.DoNotVerifyTLS) + vpr.Set(RepoID, repoID) vpr.Set(AccountProviderTypeKey, account.ProviderM365.String()) vpr.Set(AzureTenantIDKey, m365Config.AzureTenantID) @@ -211,12 +231,16 @@ func writeRepoConfigWithViper(vpr *viper.Viper, s3Config storage.S3Config, m365C // GetStorageAndAccount creates a storage and account instance by mediating all the possible // data sources (config file, env vars, flag overrides) and the config file. -func GetStorageAndAccount( +func GetConfigRepoDetails( ctx context.Context, readFromFile bool, overrides map[string]string, -) (storage.Storage, account.Account, error) { - return getStorageAndAccountWithViper(GetViper(ctx), readFromFile, overrides) +) ( + RepoDetails, + error, +) { + config, err := getStorageAndAccountWithViper(GetViper(ctx), readFromFile, overrides) + return config, err } // getSorageAndAccountWithViper implements GetSorageAndAccount, but takes in a viper @@ -225,11 +249,13 @@ func getStorageAndAccountWithViper( vpr *viper.Viper, readFromFile bool, overrides map[string]string, -) (storage.Storage, account.Account, error) { +) ( + RepoDetails, + error, +) { var ( - store storage.Storage - acct account.Account - err error + config RepoDetails + err error ) readConfigFromViper := readFromFile @@ -239,24 +265,27 @@ func getStorageAndAccountWithViper( err = vpr.ReadInConfig() if err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); !ok { - return store, acct, errors.Wrap(err, "reading corso config file: "+vpr.ConfigFileUsed()) + return config, errors.Wrap(err, "reading corso config file: "+vpr.ConfigFileUsed()) } readConfigFromViper = false } + + // in case of existing config, fetch repoid from config file + config.RepoID = vpr.GetString(RepoID) } - acct, err = configureAccount(vpr, readConfigFromViper, overrides) + config.Account, err = configureAccount(vpr, readConfigFromViper, overrides) if err != nil { - return store, acct, errors.Wrap(err, "retrieving account configuration details") + return config, errors.Wrap(err, "retrieving account configuration details") } - store, err = configureStorage(vpr, readConfigFromViper, overrides) + config.Storage, err = configureStorage(vpr, readConfigFromViper, overrides) if err != nil { - return store, acct, errors.Wrap(err, "retrieving storage provider details") + return config, errors.Wrap(err, "retrieving storage provider details") } - return store, acct, nil + return config, nil } // --------------------------------------------------------------------------- diff --git a/src/cli/config/config_test.go b/src/cli/config/config_test.go index 4e2c2e17c..0085207bb 100644 --- a/src/cli/config/config_test.go +++ b/src/cli/config/config_test.go @@ -87,8 +87,7 @@ func (suite *ConfigSuite) TestWriteReadConfig() { s3Cfg := storage.S3Config{Bucket: bkt, DoNotUseTLS: true, DoNotVerifyTLS: true} m365 := account.M365Config{AzureTenantID: tid} - - require.NoError(t, writeRepoConfigWithViper(vpr, s3Cfg, m365), "writing repo config") + require.NoError(t, writeRepoConfigWithViper(vpr, s3Cfg, m365, "repoid"), "writing repo config") require.NoError(t, vpr.ReadInConfig(), "reading repo config") readS3Cfg, err := s3ConfigsFromViper(vpr) @@ -120,7 +119,7 @@ func (suite *ConfigSuite) TestMustMatchConfig() { s3Cfg := storage.S3Config{Bucket: bkt} m365 := account.M365Config{AzureTenantID: tid} - require.NoError(t, writeRepoConfigWithViper(vpr, s3Cfg, m365), "writing repo config") + require.NoError(t, writeRepoConfigWithViper(vpr, s3Cfg, m365, "repoid"), "writing repo config") require.NoError(t, vpr.ReadInConfig(), "reading repo config") table := []struct { @@ -217,25 +216,26 @@ func (suite *ConfigIntegrationSuite) TestGetStorageAndAccount() { } m365 := account.M365Config{AzureTenantID: tid} - require.NoError(t, writeRepoConfigWithViper(vpr, s3Cfg, m365), "writing repo config") + require.NoError(t, writeRepoConfigWithViper(vpr, s3Cfg, m365, "repoid"), "writing repo config") require.NoError(t, vpr.ReadInConfig(), "reading repo config") - st, ac, err := getStorageAndAccountWithViper(vpr, true, nil) + config, err := getStorageAndAccountWithViper(vpr, true, nil) require.NoError(t, err, "getting storage and account from config") - readS3Cfg, err := st.S3Config() + readS3Cfg, err := config.Storage.S3Config() require.NoError(t, err, "reading s3 config from storage") assert.Equal(t, readS3Cfg.Bucket, s3Cfg.Bucket) assert.Equal(t, readS3Cfg.Endpoint, s3Cfg.Endpoint) assert.Equal(t, readS3Cfg.Prefix, s3Cfg.Prefix) assert.Equal(t, readS3Cfg.DoNotUseTLS, s3Cfg.DoNotUseTLS) assert.Equal(t, readS3Cfg.DoNotVerifyTLS, s3Cfg.DoNotVerifyTLS) + assert.Equal(t, config.RepoID, "repoid") - common, err := st.CommonConfig() + common, err := config.Storage.CommonConfig() require.NoError(t, err, "reading common config from storage") assert.Equal(t, common.CorsoPassphrase, os.Getenv(credentials.CorsoPassphrase)) - readM365, err := ac.M365Config() + readM365, err := config.Account.M365Config() require.NoError(t, err, "reading m365 config from account") assert.Equal(t, readM365.AzureTenantID, m365.AzureTenantID) assert.Equal(t, readM365.AzureClientID, os.Getenv(credentials.AzureClientID)) @@ -266,22 +266,23 @@ func (suite *ConfigIntegrationSuite) TestGetStorageAndAccount_noFileOnlyOverride StorageProviderTypeKey: storage.ProviderS3.String(), } - st, ac, err := getStorageAndAccountWithViper(vpr, false, overrides) + config, err := getStorageAndAccountWithViper(vpr, false, overrides) require.NoError(t, err, "getting storage and account from config") - readS3Cfg, err := st.S3Config() + readS3Cfg, err := config.Storage.S3Config() require.NoError(t, err, "reading s3 config from storage") assert.Equal(t, readS3Cfg.Bucket, bkt) + assert.Equal(t, config.RepoID, "") assert.Equal(t, readS3Cfg.Endpoint, end) assert.Equal(t, readS3Cfg.Prefix, pfx) assert.True(t, readS3Cfg.DoNotUseTLS) assert.True(t, readS3Cfg.DoNotVerifyTLS) - common, err := st.CommonConfig() + common, err := config.Storage.CommonConfig() require.NoError(t, err, "reading common config from storage") assert.Equal(t, common.CorsoPassphrase, os.Getenv(credentials.CorsoPassphrase)) - readM365, err := ac.M365Config() + readM365, err := config.Account.M365Config() require.NoError(t, err, "reading m365 config from account") assert.Equal(t, readM365.AzureTenantID, m365.AzureTenantID) assert.Equal(t, readM365.AzureClientID, os.Getenv(credentials.AzureClientID)) diff --git a/src/cli/repo/s3.go b/src/cli/repo/s3.go index 49e1bdac6..778daef4d 100644 --- a/src/cli/repo/s3.go +++ b/src/cli/repo/s3.go @@ -109,22 +109,31 @@ func initS3Cmd(cmd *cobra.Command, args []string) error { return nil } - s, a, err := config.GetStorageAndAccount(ctx, false, s3Overrides()) + cfg, err := config.GetConfigRepoDetails(ctx, false, s3Overrides()) if err != nil { return Only(ctx, err) } - s3Cfg, err := s.S3Config() + // SendStartCorsoEvent uses distict ID as tenant ID because repoID is still not generated + utils.SendStartCorsoEvent( + ctx, + cfg.Storage, + cfg.Account.ID(), + map[string]any{"command": "init repo"}, + cfg.Account.ID(), + options.Control()) + + s3Cfg, err := cfg.Storage.S3Config() if err != nil { return Only(ctx, errors.Wrap(err, "Retrieving s3 configuration")) } - m365, err := a.M365Config() + m365, err := cfg.Account.M365Config() if err != nil { return Only(ctx, errors.Wrap(err, "Failed to parse m365 account config")) } - r, err := repository.Initialize(ctx, a, s, options.Control()) + r, err := repository.Initialize(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { if succeedIfExists && errors.Is(err, repository.ErrorRepoAlreadyExists) { return nil @@ -137,7 +146,7 @@ func initS3Cmd(cmd *cobra.Command, args []string) error { Infof(ctx, "Initialized a S3 repository within bucket %s.", s3Cfg.Bucket) - if err = config.WriteRepoConfig(ctx, s3Cfg, m365); err != nil { + if err = config.WriteRepoConfig(ctx, s3Cfg, m365, r.GetID()); err != nil { return Only(ctx, errors.Wrap(err, "Failed to write repository configuration")) } @@ -168,22 +177,22 @@ func connectS3Cmd(cmd *cobra.Command, args []string) error { return nil } - s, a, err := config.GetStorageAndAccount(ctx, true, s3Overrides()) + cfg, err := config.GetConfigRepoDetails(ctx, true, s3Overrides()) if err != nil { return Only(ctx, err) } - s3Cfg, err := s.S3Config() + s3Cfg, err := cfg.Storage.S3Config() if err != nil { return Only(ctx, errors.Wrap(err, "Retrieving s3 configuration")) } - m365, err := a.M365Config() + m365, err := cfg.Account.M365Config() if err != nil { return Only(ctx, errors.Wrap(err, "Failed to parse m365 account config")) } - r, err := repository.ConnectAndSendConnectEvent(ctx, a, s, options.Control()) + r, err := repository.ConnectAndSendConnectEvent(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { return Only(ctx, errors.Wrap(err, "Failed to connect to the S3 repository")) } @@ -192,7 +201,7 @@ func connectS3Cmd(cmd *cobra.Command, args []string) error { Infof(ctx, "Connected to S3 bucket %s.", s3Cfg.Bucket) - if err = config.WriteRepoConfig(ctx, s3Cfg, m365); err != nil { + if err = config.WriteRepoConfig(ctx, s3Cfg, m365, r.GetID()); err != nil { return Only(ctx, errors.Wrap(err, "Failed to write repository configuration")) } diff --git a/src/cli/restore/exchange.go b/src/cli/restore/exchange.go index 6188ed89c..b538d6f24 100644 --- a/src/cli/restore/exchange.go +++ b/src/cli/restore/exchange.go @@ -204,14 +204,14 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error { return err } - s, a, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } - r, err := repository.Connect(ctx, a, s, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) diff --git a/src/cli/restore/onedrive.go b/src/cli/restore/onedrive.go index 7c4ac1337..56139d83d 100644 --- a/src/cli/restore/onedrive.go +++ b/src/cli/restore/onedrive.go @@ -147,14 +147,14 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error { return err } - s, a, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } - r, err := repository.Connect(ctx, a, s, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) diff --git a/src/cli/restore/sharepoint.go b/src/cli/restore/sharepoint.go index 55de9b797..a18052b37 100644 --- a/src/cli/restore/sharepoint.go +++ b/src/cli/restore/sharepoint.go @@ -158,14 +158,14 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error { return err } - s, a, err := config.GetStorageAndAccount(ctx, true, nil) + cfg, err := config.GetConfigRepoDetails(ctx, true, nil) if err != nil { return Only(ctx, err) } - r, err := repository.Connect(ctx, a, s, options.Control()) + r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, options.Control()) if err != nil { - return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", s.Provider)) + return Only(ctx, errors.Wrapf(err, "Failed to connect to the %s repository", cfg.Storage.Provider)) } defer utils.CloseRepo(ctx, r) diff --git a/src/cli/utils/utils.go b/src/cli/utils/utils.go index 029f9b2bf..3f2b58675 100644 --- a/src/cli/utils/utils.go +++ b/src/cli/utils/utils.go @@ -8,9 +8,13 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" + "github.com/alcionai/corso/src/internal/events" + "github.com/alcionai/corso/src/pkg/control" + "github.com/alcionai/corso/src/pkg/logger" "github.com/alcionai/corso/src/pkg/path" "github.com/alcionai/corso/src/pkg/repository" "github.com/alcionai/corso/src/pkg/selectors" + "github.com/alcionai/corso/src/pkg/storage" ) // common flag names @@ -136,3 +140,21 @@ func splitFoldersIntoContainsAndPrefix(folders []string) ([]string, []string) { return containsFolders, prefixFolders } + +// SendStartCorsoEvent utility sends corso start event at start of each action +func SendStartCorsoEvent( + ctx context.Context, + s storage.Storage, + tenID string, + data map[string]any, + repoID string, + opts control.Options, +) { + bus, err := events.NewBus(ctx, s, tenID, opts) + if err != nil { + logger.Ctx(ctx).Infow("analytics event failure", "err", err) + } + + bus.SetRepoID(repoID) + bus.Event(ctx, events.CorsoStart, data) +} diff --git a/src/internal/events/events.go b/src/internal/events/events.go index d91c734c9..11a7d1b01 100644 --- a/src/internal/events/events.go +++ b/src/internal/events/events.go @@ -147,7 +147,7 @@ func (b Bus) Event(ctx context.Context, key string, data map[string]any) { Properties: props, }) if err != nil { - logger.Ctx(ctx).Debugw("analytics event failure", "err", err) + logger.Ctx(ctx).Info("analytics event failure", "err", err) } }