diff --git a/src/cli/cli.go b/src/cli/cli.go index 09ed058b4..d1f535e76 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -41,6 +41,7 @@ func initConfig() { // Search config in home directory with name ".corso" (without extension). viper.AddConfigPath(home) + viper.SetConfigType("toml") viper.SetConfigName(".corso") } diff --git a/src/cli/config/config.go b/src/cli/config/config.go new file mode 100644 index 000000000..44bf1a38e --- /dev/null +++ b/src/cli/config/config.go @@ -0,0 +1,56 @@ +package config + +import ( + "github.com/alcionai/corso/pkg/repository" + "github.com/alcionai/corso/pkg/storage" + "github.com/pkg/errors" + "github.com/spf13/viper" +) + +const ( + // S3 config + ProviderTypeKey = "provider" + BucketNameKey = "bucket" + EndpointKey = "endpoint" + PrefixKey = "prefix" + + // M365 config + TenantIDKey = "tenantid" +) + +// WriteRepoConfig currently just persists corso config to the config file +// It does not check for conflicts or existing data. +func WriteRepoConfig(s3Config storage.S3Config, account repository.Account) error { + // Rudimentary support for persisting repo config + // TODO: Handle conflicts, support other config types + viper.Set(ProviderTypeKey, storage.ProviderS3.String()) + viper.Set(BucketNameKey, s3Config.Bucket) + viper.Set(EndpointKey, s3Config.Endpoint) + viper.Set(PrefixKey, s3Config.Prefix) + viper.Set(TenantIDKey, account.TenantID) + + if err := viper.SafeWriteConfig(); err != nil { + if _, ok := err.(viper.ConfigFileAlreadyExistsError); ok { + return viper.GetViper().WriteConfig() + } + return err + } + return nil +} + +func ReadRepoConfig() (s3Config storage.S3Config, account repository.Account, err error) { + if err = viper.ReadInConfig(); err != nil { + return s3Config, account, errors.Wrap(err, "reading config file: "+viper.ConfigFileUsed()) + } + + if providerType := viper.GetString(ProviderTypeKey); providerType != storage.ProviderS3.String() { + return s3Config, account, errors.New("Unsupported storage provider: " + providerType) + } + + s3Config.Bucket = viper.GetString(BucketNameKey) + s3Config.Endpoint = viper.GetString(EndpointKey) + s3Config.Prefix = viper.GetString(PrefixKey) + account.TenantID = viper.GetString(TenantIDKey) + + return s3Config, account, nil +} diff --git a/src/cli/repo/s3.go b/src/cli/repo/s3.go index f763d5bc5..b627f65be 100644 --- a/src/cli/repo/s3.go +++ b/src/cli/repo/s3.go @@ -5,7 +5,9 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/alcionai/corso/cli/config" "github.com/alcionai/corso/cli/utils" "github.com/alcionai/corso/pkg/credentials" "github.com/alcionai/corso/pkg/repository" @@ -82,6 +84,10 @@ func initS3Cmd(cmd *cobra.Command, args []string) error { defer utils.CloseRepo(cmd.Context(), r) fmt.Printf("Initialized a S3 repository within bucket %s.\n", s3Cfg.Bucket) + + if err = config.WriteRepoConfig(s3Cfg, a); err != nil { + return errors.Wrap(err, "Failed to write repository configuration") + } return nil } @@ -111,6 +117,14 @@ func connectS3Cmd(cmd *cobra.Command, args []string) error { len(m365.ClientSecret) > 0, len(s3Cfg.SecretKey) > 0) + // TODO: Merge/Validate any local configuration here to make sure there are no conflicts + // For now - just reading/logging the local config here (a successful repo connect will overwrite) + localS3Cfg, localAccount, err := config.ReadRepoConfig() + if err != nil { + return err + } + fmt.Printf("ConfigFile - %s\n\tbucket:\t%s\n\ttenantID:\t%s\n", viper.ConfigFileUsed(), localS3Cfg.Bucket, localAccount.TenantID) + a := repository.Account{ TenantID: m365.TenantID, ClientID: m365.ClientID, @@ -128,6 +142,10 @@ func connectS3Cmd(cmd *cobra.Command, args []string) error { defer utils.CloseRepo(cmd.Context(), r) fmt.Printf("Connected to S3 bucket %s.\n", s3Cfg.Bucket) + + if err = config.WriteRepoConfig(s3Cfg, a); err != nil { + return errors.Wrap(err, "Failed to write repository configuration") + } return nil }