mirror of
https://github.com/ente-io/ente.git
synced 2025-05-29 05:51:19 +00:00
Since museum.yaml is gitignored, loading it the last makes it easier to do ad-hoc configuration changes without marking the git tree dirty.
170 lines
4.2 KiB
Go
170 lines
4.2 KiB
Go
// The config package contains functions for configuring Viper.
|
|
//
|
|
// # Configuration
|
|
//
|
|
// We use the Viper package to read in configuration from YAML files. In
|
|
// addition, we also read in values from the OS environment. These values
|
|
// override the ones in the config files.
|
|
//
|
|
// The names of the OS environment variables should be
|
|
//
|
|
// - prefixed with 'ENTE_'
|
|
//
|
|
// - uppercased versions of the config file variable names
|
|
//
|
|
// - for nested config variables, dots should be replaced with '_'.
|
|
//
|
|
// For example, the environment variable corresponding to
|
|
//
|
|
// foo:
|
|
// bar-baz: quux
|
|
//
|
|
// would be `ENTE_FOO_BAR-BAZ`.
|
|
package config
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/ente-io/stacktrace"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
func ConfigureViper(environment string) error {
|
|
// Ask Viper to read in values from the environment. These values will
|
|
// override the values specified in the config files.
|
|
viper.AutomaticEnv()
|
|
// Set the prefix for the environment variables that Viper will look for.
|
|
viper.SetEnvPrefix("ENTE")
|
|
// Ask Viper to look for underscores (instead of dots) for nested configs.
|
|
viper.SetEnvKeyReplacer(strings.NewReplacer(`.`, `_`))
|
|
|
|
viper.SetConfigFile("configurations/" + environment + ".yaml")
|
|
err := viper.ReadInConfig()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
credentialsFile := viper.GetString("credentials-file")
|
|
if credentialsFile == "" {
|
|
credentialsFile = "credentials.yaml"
|
|
}
|
|
err = mergeConfigFileIfExists(credentialsFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = mergeConfigFileIfExists("museum.yaml")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func mergeConfigFileIfExists(configFile string) error {
|
|
configFileExists, err := doesFileExist(configFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if configFileExists {
|
|
viper.SetConfigFile(configFile)
|
|
err = viper.MergeInConfig()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func doesFileExist(path string) (bool, error) {
|
|
info, err := os.Stat(path)
|
|
if err != nil {
|
|
if errors.Is(err, os.ErrNotExist) {
|
|
return false, nil
|
|
}
|
|
return false, err
|
|
}
|
|
if info == nil {
|
|
return false, nil
|
|
}
|
|
// Return false if the stat entry exists, but is a directory.
|
|
//
|
|
// This allows us to ignore the default museum.yaml directory that gets
|
|
// mounted on a fresh checkout.
|
|
if info.IsDir() {
|
|
return false, nil
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func GetPGInfo() string {
|
|
return fmt.Sprintf("host=%s port=%d user=%s "+
|
|
"password=%s dbname=%s sslmode=%s %s",
|
|
viper.GetString("db.host"),
|
|
viper.GetInt("db.port"),
|
|
viper.GetString("db.user"),
|
|
viper.GetString("db.password"),
|
|
viper.GetString("db.name"),
|
|
viper.GetString("db.sslmode"),
|
|
viper.GetString("db.extra"))
|
|
}
|
|
|
|
func IsLocalEnvironment() bool {
|
|
evn := os.Getenv("ENVIRONMENT")
|
|
return evn == "" || evn == "local"
|
|
}
|
|
|
|
// CredentialFilePath returns the path to an existing file in the credentials
|
|
// directory.
|
|
//
|
|
// This file must exist if we're running in a non-local configuration.
|
|
//
|
|
// By default, it search in the credentials/ directory, but that can be
|
|
// customized using the "credentials-dir" config option.
|
|
func CredentialFilePath(name string) (string, error) {
|
|
credentialsDir := viper.GetString("credentials-dir")
|
|
if credentialsDir == "" {
|
|
credentialsDir = "credentials"
|
|
}
|
|
|
|
path := credentialsDir + "/" + name
|
|
return productionFilePath(path)
|
|
}
|
|
|
|
// BillingConfigFilePath returns the path to an existing file in the
|
|
// billing directory.
|
|
//
|
|
// This file must exist if we're running in a non-local configuration.
|
|
//
|
|
// By default, it search in the data/billing directory, but that can be
|
|
// customized using the "billing-config-dir" config option.
|
|
func BillingConfigFilePath(name string) (string, error) {
|
|
billingConfigDir := viper.GetString("billing-config-dir")
|
|
if billingConfigDir == "" {
|
|
billingConfigDir = "data/billing/"
|
|
}
|
|
|
|
path := billingConfigDir + name
|
|
return productionFilePath(path)
|
|
}
|
|
|
|
func productionFilePath(path string) (string, error) {
|
|
pathExists, err := doesFileExist(path)
|
|
if err != nil {
|
|
return "", stacktrace.Propagate(err, "")
|
|
}
|
|
if pathExists {
|
|
return path, nil
|
|
}
|
|
// The path must exist if we're running in production (or more precisely, in
|
|
// any non-local environment).
|
|
if IsLocalEnvironment() {
|
|
return "", nil
|
|
}
|
|
return "", fmt.Errorf("required file not found at %s", path)
|
|
}
|