This reverts commit 9a7213baa6f6858b92c47d5d28b8e39c180e64c0. See sanity test failure: https://github.com/alcionai/corso/actions/runs/5425405323 --- #### Does this PR need a docs update or release note? - [x] ⛔ No #### Type of change - [x] 🐛 Bugfix #### Test Plan - [x] 💚 E2E
175 lines
5.3 KiB
Go
175 lines
5.3 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
|
|
"github.com/alcionai/clues"
|
|
"github.com/aws/aws-sdk-go/aws/defaults"
|
|
"github.com/spf13/viper"
|
|
|
|
"github.com/alcionai/corso/src/cli/flags"
|
|
"github.com/alcionai/corso/src/internal/common"
|
|
"github.com/alcionai/corso/src/internal/common/str"
|
|
"github.com/alcionai/corso/src/pkg/credentials"
|
|
"github.com/alcionai/corso/src/pkg/storage"
|
|
)
|
|
|
|
// prerequisite: readRepoConfig must have been run prior to this to populate the global viper values.
|
|
func s3ConfigsFromViper(vpr *viper.Viper) (storage.S3Config, error) {
|
|
var s3Config storage.S3Config
|
|
|
|
providerType := vpr.GetString(StorageProviderTypeKey)
|
|
if providerType != storage.ProviderS3.String() {
|
|
return s3Config, clues.New("unsupported storage provider: " + providerType)
|
|
}
|
|
|
|
s3Config.Bucket = vpr.GetString(BucketNameKey)
|
|
s3Config.Endpoint = vpr.GetString(EndpointKey)
|
|
s3Config.Prefix = vpr.GetString(PrefixKey)
|
|
s3Config.DoNotUseTLS = vpr.GetBool(DisableTLSKey)
|
|
s3Config.DoNotVerifyTLS = vpr.GetBool(DisableTLSVerificationKey)
|
|
|
|
return s3Config, nil
|
|
}
|
|
|
|
// prerequisite: readRepoConfig must have been run prior to this to populate the global viper values.
|
|
func s3CredsFromViper(vpr *viper.Viper, s3Config storage.S3Config) (storage.S3Config, error) {
|
|
s3Config.AccessKey = vpr.GetString(AccessKey)
|
|
s3Config.SecretKey = vpr.GetString(SecretAccessKey)
|
|
s3Config.SessionToken = vpr.GetString(SessionToken)
|
|
|
|
return s3Config, nil
|
|
}
|
|
|
|
func s3Overrides(in map[string]string) map[string]string {
|
|
return map[string]string{
|
|
storage.Bucket: in[storage.Bucket],
|
|
storage.Endpoint: in[storage.Endpoint],
|
|
storage.Prefix: in[storage.Prefix],
|
|
storage.DoNotUseTLS: in[storage.DoNotUseTLS],
|
|
storage.DoNotVerifyTLS: in[storage.DoNotVerifyTLS],
|
|
StorageProviderTypeKey: in[StorageProviderTypeKey],
|
|
}
|
|
}
|
|
|
|
// configureStorage builds a complete storage configuration from a mix of
|
|
// viper properties and manual overrides.
|
|
func configureStorage(
|
|
vpr *viper.Viper,
|
|
readConfigFromViper bool,
|
|
matchFromConfig bool,
|
|
overrides map[string]string,
|
|
) (storage.Storage, error) {
|
|
var (
|
|
s3Cfg storage.S3Config
|
|
store storage.Storage
|
|
err error
|
|
)
|
|
|
|
if readConfigFromViper {
|
|
if s3Cfg, err = s3ConfigsFromViper(vpr); err != nil {
|
|
return store, clues.Wrap(err, "reading s3 configs from corso config file")
|
|
}
|
|
|
|
if b, ok := overrides[storage.Bucket]; ok {
|
|
overrides[storage.Bucket] = common.NormalizeBucket(b)
|
|
}
|
|
|
|
if p, ok := overrides[storage.Prefix]; ok {
|
|
overrides[storage.Prefix] = common.NormalizePrefix(p)
|
|
}
|
|
}
|
|
|
|
if matchFromConfig {
|
|
if err := mustMatchConfig(vpr, s3Overrides(overrides)); err != nil {
|
|
return store, clues.Wrap(err, "verifying s3 configs in corso config file")
|
|
}
|
|
}
|
|
|
|
if s3Cfg, err = s3CredsFromViper(vpr, s3Cfg); err != nil {
|
|
return store, clues.Wrap(err, "reading s3 configs from corso config file")
|
|
}
|
|
|
|
s3Overrides(overrides)
|
|
aws := credentials.GetAWS(overrides)
|
|
|
|
if len(aws.AccessKey) <= 0 || len(aws.SecretKey) <= 0 {
|
|
_, err = defaults.CredChain(defaults.Config().WithCredentialsChainVerboseErrors(true), defaults.Handlers()).Get()
|
|
if err != nil && (len(s3Cfg.AccessKey) > 0 || len(s3Cfg.SecretKey) > 0) {
|
|
aws = credentials.AWS{
|
|
AccessKey: s3Cfg.AccessKey,
|
|
SecretKey: s3Cfg.SecretKey,
|
|
SessionToken: s3Cfg.SessionToken,
|
|
}
|
|
err = nil
|
|
}
|
|
|
|
if err != nil {
|
|
return store, clues.Wrap(err, "validating aws credentials")
|
|
}
|
|
}
|
|
|
|
s3Cfg = storage.S3Config{
|
|
AWS: aws,
|
|
Bucket: str.First(overrides[storage.Bucket], s3Cfg.Bucket),
|
|
Endpoint: str.First(overrides[storage.Endpoint], s3Cfg.Endpoint, "s3.amazonaws.com"),
|
|
Prefix: str.First(overrides[storage.Prefix], s3Cfg.Prefix),
|
|
DoNotUseTLS: str.ParseBool(str.First(
|
|
overrides[storage.DoNotUseTLS],
|
|
strconv.FormatBool(s3Cfg.DoNotUseTLS),
|
|
"false",
|
|
)),
|
|
DoNotVerifyTLS: str.ParseBool(str.First(
|
|
overrides[storage.DoNotVerifyTLS],
|
|
strconv.FormatBool(s3Cfg.DoNotVerifyTLS),
|
|
"false",
|
|
)),
|
|
}
|
|
|
|
// compose the common config and credentials
|
|
corso := GetAndInsertCorso(vpr.GetString(CorsoPassphrase))
|
|
if err := corso.Validate(); err != nil {
|
|
return store, clues.Wrap(err, "validating corso credentials")
|
|
}
|
|
|
|
cCfg := storage.CommonConfig{
|
|
Corso: corso,
|
|
}
|
|
// the following is a hack purely for integration testing.
|
|
// the value is not required, and if empty, kopia will default
|
|
// to its routine behavior
|
|
if t, ok := vpr.Get("corso-testing").(bool); t && ok {
|
|
dir, _ := filepath.Split(vpr.ConfigFileUsed())
|
|
cCfg.KopiaCfgDir = dir
|
|
}
|
|
|
|
// ensure required properties are present
|
|
if err := requireProps(map[string]string{
|
|
storage.Bucket: s3Cfg.Bucket,
|
|
credentials.CorsoPassphrase: corso.CorsoPassphrase,
|
|
}); err != nil {
|
|
return storage.Storage{}, err
|
|
}
|
|
|
|
// build the storage
|
|
store, err = storage.NewStorage(storage.ProviderS3, s3Cfg, cCfg)
|
|
if err != nil {
|
|
return store, clues.Wrap(err, "configuring repository storage")
|
|
}
|
|
|
|
return store, nil
|
|
}
|
|
|
|
// GetCorso is a helper for aggregating Corso secrets and credentials.
|
|
func GetAndInsertCorso(passphase string) credentials.Corso {
|
|
// fetch data from flag, env var or func param giving priority to func param
|
|
// Func param generally will be value fetched from config file using viper.
|
|
corsoPassph := str.First(flags.CorsoPassphraseFV, os.Getenv(credentials.CorsoPassphrase), passphase)
|
|
|
|
return credentials.Corso{
|
|
CorsoPassphrase: corsoPassph,
|
|
}
|
|
}
|