mirror of
https://github.com/turbot/steampipe.git
synced 2025-12-19 09:58:53 -05:00
207 lines
7.6 KiB
Go
207 lines
7.6 KiB
Go
package cmdconfig
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
|
|
pfilepaths "github.com/turbot/pipe-fittings/v2/filepaths"
|
|
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
filehelpers "github.com/turbot/go-kit/files"
|
|
"github.com/turbot/go-kit/types"
|
|
pconstants "github.com/turbot/pipe-fittings/v2/constants"
|
|
"github.com/turbot/pipe-fittings/v2/parse"
|
|
"github.com/turbot/pipe-fittings/v2/workspace_profile"
|
|
"github.com/turbot/steampipe/v2/pkg/constants"
|
|
)
|
|
|
|
// Viper fetches the global viper instance
|
|
func Viper() *viper.Viper {
|
|
return viper.GetViper()
|
|
}
|
|
|
|
// bootstrapViper sets up viper with the essential path config (workspace-chdir and install-dir)
|
|
func bootstrapViper(loader *parse.WorkspaceProfileLoader[*workspace_profile.SteampipeWorkspaceProfile], cmd *cobra.Command) error {
|
|
// set defaults for keys which do not have a corresponding command flag
|
|
if err := setBaseDefaults(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// set defaults from defaultWorkspaceProfile
|
|
SetDefaultsFromConfig(loader.DefaultProfile.ConfigMap(cmd))
|
|
|
|
// set defaults for install dir and mod location from env vars
|
|
// this needs to be done since the workspace profile definitions exist in the
|
|
// default install dir
|
|
setDirectoryDefaultsFromEnv()
|
|
|
|
// NOTE: if an explicit workspace profile was set, default the install dir _now_
|
|
// All other workspace profile values are defaults _after defaulting to the connection config options
|
|
// to give them higher precedence, but these must be done now as subsequent operations depend on them
|
|
// (and they cannot be set from hcl options)
|
|
if loader.ConfiguredProfile != nil {
|
|
if loader.ConfiguredProfile.InstallDir != nil {
|
|
log.Printf("[TRACE] setting install dir from configured profile '%s' to '%s'", loader.ConfiguredProfile.Name(), *loader.ConfiguredProfile.InstallDir)
|
|
viper.SetDefault(pconstants.ArgInstallDir, *loader.ConfiguredProfile.InstallDir)
|
|
}
|
|
}
|
|
|
|
// tildefy all paths in viper
|
|
return tildefyPaths()
|
|
}
|
|
|
|
// tildefyPaths cleans all path config values and replaces '~' with the home directory
|
|
func tildefyPaths() error {
|
|
pathArgs := []string{
|
|
pconstants.ArgModLocation,
|
|
pconstants.ArgInstallDir,
|
|
}
|
|
var err error
|
|
for _, argName := range pathArgs {
|
|
if argVal := viper.GetString(argName); argVal != "" {
|
|
if argVal, err = filehelpers.Tildefy(argVal); err != nil {
|
|
return err
|
|
}
|
|
if viper.IsSet(argName) {
|
|
// if the value was already set re-set
|
|
viper.Set(argName, argVal)
|
|
} else {
|
|
// otherwise just update the default
|
|
viper.SetDefault(argName, argVal)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SetDefaultsFromConfig overrides viper default values from hcl config values
|
|
func SetDefaultsFromConfig(configMap map[string]interface{}) {
|
|
for k, v := range configMap {
|
|
viper.SetDefault(k, v)
|
|
}
|
|
}
|
|
|
|
// for keys which do not have a corresponding command flag, we need a separate defaulting mechanism
|
|
// any option setting, workspace profile property or env var which does not have a command line
|
|
// MUST have a default (unless we want the zero value to take effect)
|
|
//
|
|
// Do not add keys here which have command line defaults - the way this is setup, this value takes
|
|
// precedence over command line default
|
|
func setBaseDefaults() error {
|
|
defaults := map[string]interface{}{
|
|
// global general options
|
|
pconstants.ArgTelemetry: constants.TelemetryInfo,
|
|
pconstants.ArgUpdateCheck: true,
|
|
pconstants.ArgPipesInstallDir: pfilepaths.DefaultPipesInstallDir,
|
|
|
|
// workspace profile
|
|
pconstants.ArgAutoComplete: true,
|
|
|
|
// from global database options
|
|
pconstants.ArgDatabasePort: constants.DatabaseDefaultPort,
|
|
pconstants.ArgDatabaseStartTimeout: constants.DBStartTimeout.Seconds(),
|
|
pconstants.ArgServiceCacheEnabled: true,
|
|
pconstants.ArgCacheMaxTtl: 300,
|
|
|
|
// dashboard
|
|
pconstants.ArgDashboardStartTimeout: constants.DashboardStartTimeout.Seconds(),
|
|
|
|
// memory
|
|
pconstants.ArgMemoryMaxMbPlugin: 1024,
|
|
pconstants.ArgMemoryMaxMb: 1024,
|
|
|
|
// plugin start timeout
|
|
pconstants.ArgPluginStartTimeout: constants.PluginStartTimeout.Seconds(),
|
|
}
|
|
|
|
for k, v := range defaults {
|
|
viper.SetDefault(k, v)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type envMapping struct {
|
|
configVar []string
|
|
varType EnvVarType
|
|
}
|
|
|
|
// set default values of INSTALL_DIR and ModLocation from env vars
|
|
func setDirectoryDefaultsFromEnv() {
|
|
envMappings := map[string]envMapping{
|
|
constants.EnvInstallDir: {[]string{pconstants.ArgInstallDir}, String},
|
|
constants.EnvWorkspaceChDir: {[]string{pconstants.ArgModLocation}, String},
|
|
}
|
|
|
|
for envVar, mapping := range envMappings {
|
|
setConfigFromEnv(envVar, mapping.configVar, mapping.varType)
|
|
}
|
|
}
|
|
|
|
// setDefaultsFromEnv sets default values from env vars
|
|
func setDefaultsFromEnv() {
|
|
// NOTE: EnvWorkspaceProfile has already been set as a viper default as we have already loaded workspace profiles
|
|
// (EnvInstallDir has already been set at same time but we set it again to make sure it has the correct precedence)
|
|
|
|
// a map of known environment variables to map to viper keys
|
|
envMappings := map[string]envMapping{
|
|
constants.EnvInstallDir: {[]string{pconstants.ArgInstallDir}, String},
|
|
constants.EnvWorkspaceChDir: {[]string{pconstants.ArgModLocation}, String},
|
|
constants.EnvTelemetry: {[]string{pconstants.ArgTelemetry}, String},
|
|
constants.EnvUpdateCheck: {[]string{pconstants.ArgUpdateCheck}, Bool},
|
|
constants.EnvPipesHost: {[]string{pconstants.ArgPipesHost}, String},
|
|
constants.EnvPipesToken: {[]string{pconstants.ArgPipesToken}, String},
|
|
constants.EnvSnapshotLocation: {[]string{pconstants.ArgSnapshotLocation}, String},
|
|
constants.EnvWorkspaceDatabase: {[]string{pconstants.ArgWorkspaceDatabase}, String},
|
|
constants.EnvServicePassword: {[]string{pconstants.ArgServicePassword}, String},
|
|
constants.EnvDisplayWidth: {[]string{pconstants.ArgDisplayWidth}, Int},
|
|
constants.EnvMaxParallel: {[]string{pconstants.ArgMaxParallel}, Int},
|
|
constants.EnvQueryTimeout: {[]string{pconstants.ArgDatabaseQueryTimeout}, Int},
|
|
constants.EnvDatabaseStartTimeout: {[]string{pconstants.ArgDatabaseStartTimeout}, Int},
|
|
constants.EnvDatabaseSSLPassword: {[]string{pconstants.ArgDatabaseSSLPassword}, String},
|
|
constants.EnvDashboardStartTimeout: {[]string{pconstants.ArgDashboardStartTimeout}, Int},
|
|
constants.EnvCacheTTL: {[]string{pconstants.ArgCacheTtl}, Int},
|
|
constants.EnvCacheMaxTTL: {[]string{pconstants.ArgCacheMaxTtl}, Int},
|
|
constants.EnvMemoryMaxMb: {[]string{pconstants.ArgMemoryMaxMb}, Int},
|
|
constants.EnvMemoryMaxMbPlugin: {[]string{pconstants.ArgMemoryMaxMbPlugin}, Int},
|
|
constants.EnvPluginStartTimeout: {[]string{pconstants.ArgPluginStartTimeout}, Int},
|
|
|
|
// we need this value to go into different locations
|
|
constants.EnvCacheEnabled: {[]string{
|
|
pconstants.ArgClientCacheEnabled,
|
|
pconstants.ArgServiceCacheEnabled,
|
|
}, Bool},
|
|
}
|
|
|
|
for envVar, v := range envMappings {
|
|
setConfigFromEnv(envVar, v.configVar, v.varType)
|
|
}
|
|
}
|
|
|
|
func setConfigFromEnv(envVar string, configs []string, varType EnvVarType) {
|
|
for _, configVar := range configs {
|
|
SetDefaultFromEnv(envVar, configVar, varType)
|
|
}
|
|
}
|
|
|
|
func SetDefaultFromEnv(k string, configVar string, varType EnvVarType) {
|
|
if val, ok := os.LookupEnv(k); ok {
|
|
switch varType {
|
|
case String:
|
|
viper.SetDefault(configVar, val)
|
|
case Bool:
|
|
if boolVal, err := types.ToBool(val); err == nil {
|
|
viper.SetDefault(configVar, boolVal)
|
|
}
|
|
case Int:
|
|
if intVal, err := types.ToInt64(val); err == nil {
|
|
viper.SetDefault(configVar, intVal)
|
|
}
|
|
default:
|
|
// must be an invalid value in the map above
|
|
panic(fmt.Sprintf("invalid env var mapping type: %s", varType))
|
|
}
|
|
}
|
|
}
|