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?

- [ ]  Yes, it's included

## Type of change

<!--- Please check the type of change your PR introduces: --->
- [x] 🌻 Feature

## Issue(s)
* https://github.com/alcionai/corso/issues/1761

## Test Plan

<!-- How will this be tested prior to merging.-->
- [ ] 💪 Manual

---------

Co-authored-by: Keepers <ryanfkeepers@gmail.com>
Co-authored-by: aviator-app[bot] <48659329+aviator-app[bot]@users.noreply.github.com>
This commit is contained in:
neha_gupta 2023-03-03 13:47:41 +05:30 committed by GitHub
parent 61be8310c6
commit 214db6fe97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 174 additions and 89 deletions

View File

@ -260,14 +260,14 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error {
return err return err
} }
s, acct, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) 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 { 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) defer utils.CloseRepo(ctx, r)
@ -277,7 +277,7 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error {
// TODO: log/print recoverable errors // TODO: log/print recoverable errors
errs := fault.New(false) errs := fault.New(false)
users, err := m365.UserPNs(ctx, acct, errs) users, err := m365.UserPNs(ctx, cfg.Account, errs)
if err != nil { if err != nil {
return Only(ctx, errors.Wrap(err, "Failed to retrieve M365 user(s)")) 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 { func listExchangeCmd(cmd *cobra.Command, args []string) error {
ctx := cmd.Context() ctx := cmd.Context()
s, acct, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) 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 { 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) defer utils.CloseRepo(ctx, r)
@ -465,16 +465,16 @@ func detailsExchangeCmd(cmd *cobra.Command, args []string) error {
Populated: utils.GetPopulatedFlags(cmd), Populated: utils.GetPopulatedFlags(cmd),
} }
s, acct, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) return Only(ctx, err)
} }
ctrlOpts := options.Control() ctrlOpts := options.Control()
r, err := repository.Connect(ctx, acct, s, ctrlOpts) r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, ctrlOpts)
if err != nil { 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) defer utils.CloseRepo(ctx, r)
@ -549,14 +549,14 @@ func deleteExchangeCmd(cmd *cobra.Command, args []string) error {
return nil return nil
} }
s, acct, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) 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 { 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) defer utils.CloseRepo(ctx, r)

View File

@ -184,14 +184,14 @@ func createOneDriveCmd(cmd *cobra.Command, args []string) error {
return err return err
} }
s, acct, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) 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 { 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) defer utils.CloseRepo(ctx, r)
@ -201,7 +201,7 @@ func createOneDriveCmd(cmd *cobra.Command, args []string) error {
// TODO: log/print recoverable errors // TODO: log/print recoverable errors
errs := fault.New(false) errs := fault.New(false)
users, err := m365.UserPNs(ctx, acct, errs) users, err := m365.UserPNs(ctx, cfg.Account, errs)
if err != nil { if err != nil {
return Only(ctx, errors.Wrap(err, "Failed to retrieve M365 users")) 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 { func listOneDriveCmd(cmd *cobra.Command, args []string) error {
ctx := cmd.Context() ctx := cmd.Context()
s, acct, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) 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 { 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) defer utils.CloseRepo(ctx, r)
@ -345,16 +345,16 @@ func detailsOneDriveCmd(cmd *cobra.Command, args []string) error {
return nil return nil
} }
s, acct, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) return Only(ctx, err)
} }
ctrlOpts := options.Control() ctrlOpts := options.Control()
r, err := repository.Connect(ctx, acct, s, ctrlOpts) r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, ctrlOpts)
if err != nil { 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) defer utils.CloseRepo(ctx, r)
@ -438,14 +438,14 @@ func deleteOneDriveCmd(cmd *cobra.Command, args []string) error {
return nil return nil
} }
s, acct, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) 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 { 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) defer utils.CloseRepo(ctx, r)

View File

@ -201,14 +201,14 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error {
return err return err
} }
s, acct, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) 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 { 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) defer utils.CloseRepo(ctx, r)
@ -216,7 +216,7 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error {
// TODO: log/print recoverable errors // TODO: log/print recoverable errors
errs := fault.New(false) 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 { if err != nil {
return Only(ctx, errors.Wrap(err, "Failed to connect to Microsoft APIs")) 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 { func listSharePointCmd(cmd *cobra.Command, args []string) error {
ctx := cmd.Context() ctx := cmd.Context()
s, acct, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) 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 { 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) defer utils.CloseRepo(ctx, r)
@ -432,14 +432,14 @@ func deleteSharePointCmd(cmd *cobra.Command, args []string) error {
return nil return nil
} }
s, acct, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) 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 { 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) defer utils.CloseRepo(ctx, r)
@ -476,16 +476,16 @@ func detailsSharePointCmd(cmd *cobra.Command, args []string) error {
return nil return nil
} }
s, acct, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) return Only(ctx, err)
} }
ctrlOpts := options.Control() ctrlOpts := options.Control()
r, err := repository.Connect(ctx, acct, s, ctrlOpts) r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, ctrlOpts)
if err != nil { 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) defer utils.CloseRepo(ctx, r)

View File

@ -42,7 +42,8 @@ func preRun(cc *cobra.Command, args []string) error {
return err return err
} }
log := logger.Ctx(cc.Context()) ctx := cc.Context()
log := logger.Ctx(ctx)
flags := utils.GetPopulatedFlags(cc) flags := utils.GetPopulatedFlags(cc)
flagSl := make([]string, 0, len(flags)) flagSl := make([]string, 0, len(flags))
@ -55,8 +56,31 @@ func preRun(cc *cobra.Command, args []string) error {
avoidTheseCommands := []string{ avoidTheseCommands := []string{
"corso", "env", "help", "backup", "details", "list", "restore", "delete", "repo", "init", "connect", "corso", "env", "help", "backup", "details", "list", "restore", "delete", "repo", "init", "connect",
} }
if len(logger.LogFile) > 0 && !slices.Contains(avoidTheseCommands, cc.Use) { 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()) log.Infow("cli command", "command", cc.CommandPath(), "flags", flagSl, "version", version.CurrentVersion())

View File

@ -24,6 +24,7 @@ const (
PrefixKey = "prefix" PrefixKey = "prefix"
DisableTLSKey = "disable_tls" DisableTLSKey = "disable_tls"
DisableTLSVerificationKey = "disable_tls_verification" DisableTLSVerificationKey = "disable_tls_verification"
RepoID = "repo_id"
// M365 config // M365 config
AccountProviderTypeKey = "account_provider" AccountProviderTypeKey = "account_provider"
@ -37,6 +38,14 @@ var (
displayDefaultFP = filepath.Join("$HOME", ".corso.toml") 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. // Attempts to set the default dir and config file path.
// Default is always $HOME. // Default is always $HOME.
func init() { func init() {
@ -178,13 +187,23 @@ func Read(ctx context.Context) error {
// WriteRepoConfig currently just persists corso config to the config file // WriteRepoConfig currently just persists corso config to the config file
// It does not check for conflicts or existing data. // It does not check for conflicts or existing data.
func WriteRepoConfig(ctx context.Context, s3Config storage.S3Config, m365Config account.M365Config) error { func WriteRepoConfig(
return writeRepoConfigWithViper(GetViper(ctx), s3Config, m365Config) 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 // writeRepoConfigWithViper implements WriteRepoConfig, but takes in a viper
// struct for testing. // 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() s3Config = s3Config.Normalize()
// Rudimentary support for persisting repo config // Rudimentary support for persisting repo config
// TODO: Handle conflicts, support other config types // 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(PrefixKey, s3Config.Prefix)
vpr.Set(DisableTLSKey, s3Config.DoNotUseTLS) vpr.Set(DisableTLSKey, s3Config.DoNotUseTLS)
vpr.Set(DisableTLSVerificationKey, s3Config.DoNotVerifyTLS) vpr.Set(DisableTLSVerificationKey, s3Config.DoNotVerifyTLS)
vpr.Set(RepoID, repoID)
vpr.Set(AccountProviderTypeKey, account.ProviderM365.String()) vpr.Set(AccountProviderTypeKey, account.ProviderM365.String())
vpr.Set(AzureTenantIDKey, m365Config.AzureTenantID) 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 // GetStorageAndAccount creates a storage and account instance by mediating all the possible
// data sources (config file, env vars, flag overrides) and the config file. // data sources (config file, env vars, flag overrides) and the config file.
func GetStorageAndAccount( func GetConfigRepoDetails(
ctx context.Context, ctx context.Context,
readFromFile bool, readFromFile bool,
overrides map[string]string, 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 // getSorageAndAccountWithViper implements GetSorageAndAccount, but takes in a viper
@ -225,11 +249,13 @@ func getStorageAndAccountWithViper(
vpr *viper.Viper, vpr *viper.Viper,
readFromFile bool, readFromFile bool,
overrides map[string]string, overrides map[string]string,
) (storage.Storage, account.Account, error) { ) (
RepoDetails,
error,
) {
var ( var (
store storage.Storage config RepoDetails
acct account.Account err error
err error
) )
readConfigFromViper := readFromFile readConfigFromViper := readFromFile
@ -239,24 +265,27 @@ func getStorageAndAccountWithViper(
err = vpr.ReadInConfig() err = vpr.ReadInConfig()
if err != nil { if err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok { 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 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 { 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 { 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
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -87,8 +87,7 @@ func (suite *ConfigSuite) TestWriteReadConfig() {
s3Cfg := storage.S3Config{Bucket: bkt, DoNotUseTLS: true, DoNotVerifyTLS: true} s3Cfg := storage.S3Config{Bucket: bkt, DoNotUseTLS: true, DoNotVerifyTLS: true}
m365 := account.M365Config{AzureTenantID: tid} m365 := account.M365Config{AzureTenantID: tid}
require.NoError(t, writeRepoConfigWithViper(vpr, s3Cfg, m365, "repoid"), "writing repo config")
require.NoError(t, writeRepoConfigWithViper(vpr, s3Cfg, m365), "writing repo config")
require.NoError(t, vpr.ReadInConfig(), "reading repo config") require.NoError(t, vpr.ReadInConfig(), "reading repo config")
readS3Cfg, err := s3ConfigsFromViper(vpr) readS3Cfg, err := s3ConfigsFromViper(vpr)
@ -120,7 +119,7 @@ func (suite *ConfigSuite) TestMustMatchConfig() {
s3Cfg := storage.S3Config{Bucket: bkt} s3Cfg := storage.S3Config{Bucket: bkt}
m365 := account.M365Config{AzureTenantID: tid} 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") require.NoError(t, vpr.ReadInConfig(), "reading repo config")
table := []struct { table := []struct {
@ -217,25 +216,26 @@ func (suite *ConfigIntegrationSuite) TestGetStorageAndAccount() {
} }
m365 := account.M365Config{AzureTenantID: tid} 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") 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") 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") require.NoError(t, err, "reading s3 config from storage")
assert.Equal(t, readS3Cfg.Bucket, s3Cfg.Bucket) assert.Equal(t, readS3Cfg.Bucket, s3Cfg.Bucket)
assert.Equal(t, readS3Cfg.Endpoint, s3Cfg.Endpoint) assert.Equal(t, readS3Cfg.Endpoint, s3Cfg.Endpoint)
assert.Equal(t, readS3Cfg.Prefix, s3Cfg.Prefix) assert.Equal(t, readS3Cfg.Prefix, s3Cfg.Prefix)
assert.Equal(t, readS3Cfg.DoNotUseTLS, s3Cfg.DoNotUseTLS) assert.Equal(t, readS3Cfg.DoNotUseTLS, s3Cfg.DoNotUseTLS)
assert.Equal(t, readS3Cfg.DoNotVerifyTLS, s3Cfg.DoNotVerifyTLS) 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") require.NoError(t, err, "reading common config from storage")
assert.Equal(t, common.CorsoPassphrase, os.Getenv(credentials.CorsoPassphrase)) 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") require.NoError(t, err, "reading m365 config from account")
assert.Equal(t, readM365.AzureTenantID, m365.AzureTenantID) assert.Equal(t, readM365.AzureTenantID, m365.AzureTenantID)
assert.Equal(t, readM365.AzureClientID, os.Getenv(credentials.AzureClientID)) assert.Equal(t, readM365.AzureClientID, os.Getenv(credentials.AzureClientID))
@ -266,22 +266,23 @@ func (suite *ConfigIntegrationSuite) TestGetStorageAndAccount_noFileOnlyOverride
StorageProviderTypeKey: storage.ProviderS3.String(), 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") 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") require.NoError(t, err, "reading s3 config from storage")
assert.Equal(t, readS3Cfg.Bucket, bkt) assert.Equal(t, readS3Cfg.Bucket, bkt)
assert.Equal(t, config.RepoID, "")
assert.Equal(t, readS3Cfg.Endpoint, end) assert.Equal(t, readS3Cfg.Endpoint, end)
assert.Equal(t, readS3Cfg.Prefix, pfx) assert.Equal(t, readS3Cfg.Prefix, pfx)
assert.True(t, readS3Cfg.DoNotUseTLS) assert.True(t, readS3Cfg.DoNotUseTLS)
assert.True(t, readS3Cfg.DoNotVerifyTLS) assert.True(t, readS3Cfg.DoNotVerifyTLS)
common, err := st.CommonConfig() common, err := config.Storage.CommonConfig()
require.NoError(t, err, "reading common config from storage") require.NoError(t, err, "reading common config from storage")
assert.Equal(t, common.CorsoPassphrase, os.Getenv(credentials.CorsoPassphrase)) 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") require.NoError(t, err, "reading m365 config from account")
assert.Equal(t, readM365.AzureTenantID, m365.AzureTenantID) assert.Equal(t, readM365.AzureTenantID, m365.AzureTenantID)
assert.Equal(t, readM365.AzureClientID, os.Getenv(credentials.AzureClientID)) assert.Equal(t, readM365.AzureClientID, os.Getenv(credentials.AzureClientID))

View File

@ -109,22 +109,31 @@ func initS3Cmd(cmd *cobra.Command, args []string) error {
return nil return nil
} }
s, a, err := config.GetStorageAndAccount(ctx, false, s3Overrides()) cfg, err := config.GetConfigRepoDetails(ctx, false, s3Overrides())
if err != nil { if err != nil {
return Only(ctx, err) 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 { if err != nil {
return Only(ctx, errors.Wrap(err, "Retrieving s3 configuration")) return Only(ctx, errors.Wrap(err, "Retrieving s3 configuration"))
} }
m365, err := a.M365Config() m365, err := cfg.Account.M365Config()
if err != nil { if err != nil {
return Only(ctx, errors.Wrap(err, "Failed to parse m365 account config")) 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 err != nil {
if succeedIfExists && errors.Is(err, repository.ErrorRepoAlreadyExists) { if succeedIfExists && errors.Is(err, repository.ErrorRepoAlreadyExists) {
return nil 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) 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")) 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 return nil
} }
s, a, err := config.GetStorageAndAccount(ctx, true, s3Overrides()) cfg, err := config.GetConfigRepoDetails(ctx, true, s3Overrides())
if err != nil { if err != nil {
return Only(ctx, err) return Only(ctx, err)
} }
s3Cfg, err := s.S3Config() s3Cfg, err := cfg.Storage.S3Config()
if err != nil { if err != nil {
return Only(ctx, errors.Wrap(err, "Retrieving s3 configuration")) return Only(ctx, errors.Wrap(err, "Retrieving s3 configuration"))
} }
m365, err := a.M365Config() m365, err := cfg.Account.M365Config()
if err != nil { if err != nil {
return Only(ctx, errors.Wrap(err, "Failed to parse m365 account config")) 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 { if err != nil {
return Only(ctx, errors.Wrap(err, "Failed to connect to the S3 repository")) 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) 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")) return Only(ctx, errors.Wrap(err, "Failed to write repository configuration"))
} }

View File

@ -204,14 +204,14 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error {
return err return err
} }
s, a, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) 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 { 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) defer utils.CloseRepo(ctx, r)

View File

@ -147,14 +147,14 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error {
return err return err
} }
s, a, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) 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 { 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) defer utils.CloseRepo(ctx, r)

View File

@ -158,14 +158,14 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error {
return err return err
} }
s, a, err := config.GetStorageAndAccount(ctx, true, nil) cfg, err := config.GetConfigRepoDetails(ctx, true, nil)
if err != nil { if err != nil {
return Only(ctx, err) 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 { 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) defer utils.CloseRepo(ctx, r)

View File

@ -8,9 +8,13 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "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/path"
"github.com/alcionai/corso/src/pkg/repository" "github.com/alcionai/corso/src/pkg/repository"
"github.com/alcionai/corso/src/pkg/selectors" "github.com/alcionai/corso/src/pkg/selectors"
"github.com/alcionai/corso/src/pkg/storage"
) )
// common flag names // common flag names
@ -136,3 +140,21 @@ func splitFoldersIntoContainsAndPrefix(folders []string) ([]string, []string) {
return containsFolders, prefixFolders 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)
}

View File

@ -147,7 +147,7 @@ func (b Bus) Event(ctx context.Context, key string, data map[string]any) {
Properties: props, Properties: props,
}) })
if err != nil { if err != nil {
logger.Ctx(ctx).Debugw("analytics event failure", "err", err) logger.Ctx(ctx).Info("analytics event failure", "err", err)
} }
} }