313 lines
9.8 KiB
Go
313 lines
9.8 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/spf13/cobra"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
const (
|
|
ViperAPITLSEnabled string = "api.tls.enabled"
|
|
FlagAPITLSEnabled string = "api-tls-enabled"
|
|
DefaultAPITLSEnabled bool = false
|
|
DescriptionAPITLSEnabled string = "Whether to use TLS or not. Requires certificate and private key files."
|
|
|
|
ViperAPITLSCertfile string = "api.tls.certfile"
|
|
FlagAPITLSCertfile string = "api-tls-certfile"
|
|
DefaultAPITLSCertfile string = "/etc/bottin/cert.pem"
|
|
DescriptionAPITLSCertfile string = "Path to TLS certificate file"
|
|
|
|
ViperAPITLSKeyfile string = "api.tls.keyfile"
|
|
FlagAPITLSKeyfile string = "api-tls-keyfile"
|
|
DefaultAPITLSKeyfile string = "/etc/bottin/key.pem"
|
|
DescriptionAPITLSKeyFile string = "Path to TLS private key file"
|
|
|
|
ViperAPIPort string = "api.port"
|
|
FlagAPIPort string = "api-port"
|
|
DefaultAPIPort int = 1312
|
|
DescriptionAPIPort string = "API server port"
|
|
|
|
ViperAPIKey string = "api.key"
|
|
FlagAPIKey string = "api-key"
|
|
DefaultAPIKey string = "bottin"
|
|
DescriptionAPIKey string = "API server key. Leave empty for no key auth (not recommended)"
|
|
|
|
ViperDBDatabase string = "db.database"
|
|
FlagDBDatabase string = "db-database"
|
|
DefaultDBDatabase string = "bottin"
|
|
DescriptionDBDatabase string = "Postgres database"
|
|
|
|
ViperDBSSLMode string = "db.sslmode"
|
|
FlagDBSSLMode string = "db-sslmode"
|
|
DefaultDBSSLMode string = "prefer"
|
|
DescriptionDBSSLMode string = "Postgres sslmode"
|
|
|
|
ViperDBHost string = "db.host"
|
|
FlagDBHost string = "db-host"
|
|
DefaultDBHost string = "db"
|
|
DescriptionDBHost string = "Postgres host"
|
|
|
|
ViperDBPassword string = "db.password"
|
|
FlagDBPassword string = "db-password"
|
|
DefaultDBPassword string = "bottin"
|
|
DescriptionDBPassword string = "Postgres password"
|
|
|
|
ViperDBPort string = "db.port"
|
|
FlagDBPort string = "db-port"
|
|
DefaultDBPort int = 5432
|
|
DescriptionDBPort string = "Postgres port"
|
|
|
|
ViperDBUser string = "db.user"
|
|
FlagDBUser string = "db-user"
|
|
DefaultDBUser string = "bottin"
|
|
DescriptionDBUser string = "Postgres user"
|
|
|
|
ViperWebUser string = "web.user"
|
|
FlagWebUser string = "web-user"
|
|
DefaultWebUser string = "bottin"
|
|
DescriptionWebUser string = "Web client basic auth user"
|
|
|
|
ViperWebPassword string = "web.password"
|
|
FlagWebPassword string = "web-password"
|
|
DefaultWebPassword string = "bottin"
|
|
DescriptionWebPassword string = "Web client basic auth password"
|
|
|
|
ViperWebPort string = "web.port"
|
|
FlagWebPort string = "web-port"
|
|
DefaultWebPort int = 2312
|
|
DescriptionWebPort string = "Web client port"
|
|
|
|
ViperWebAPIHost string = "web.api.host"
|
|
FlagWebAPIHost string = "web-api-host"
|
|
DefaultWebAPIHost string = "api"
|
|
DescriptionWebAPIHost string = "Target API server host"
|
|
|
|
ViperWebAPIKey string = "web.api.key"
|
|
FlagWebAPIKey string = "web-api-key"
|
|
DefaultWebAPIKey string = "bottin"
|
|
DescriptionWebAPIKey string = "Target API server key"
|
|
|
|
ViperWebAPIPort string = "web.api.port"
|
|
FlagWebAPIPort string = "web-api-port"
|
|
DefaultWebAPIPort int = 1312
|
|
DescriptionWebAPIPort string = "Target API server port"
|
|
|
|
ViperWebAPIProtocol string = "web.api.protocol"
|
|
FlagWebAPIProtocol string = "web-api-protocol"
|
|
DefaultWebAPIProtocol string = "http"
|
|
DescriptionWebAPIProtocol string = "Target API server protocol (http/https)"
|
|
)
|
|
|
|
type Config struct {
|
|
API struct {
|
|
TLS struct {
|
|
Enabled bool `yaml:"enabled"`
|
|
|
|
// Path to file containing TLS certificate
|
|
Certfile string `yaml:"certfile"`
|
|
|
|
// Path to file containing TLS private key
|
|
Keyfile string `yaml:"keyfile"`
|
|
} `yaml:"tls"`
|
|
Port int `yaml:"port"`
|
|
Key string `yaml:"key"`
|
|
} `yaml:"api"`
|
|
DB struct {
|
|
Database string `yaml:"database"`
|
|
Host string `yaml:"host"`
|
|
SSLMode string `yaml:"sslmode"`
|
|
Password string `yaml:"password"`
|
|
Port int `yaml:"port"`
|
|
User string `yaml:"user"`
|
|
} `yaml:"db"`
|
|
Web struct {
|
|
User string `yaml:"user"`
|
|
Password string `yaml:"password"`
|
|
Port int `yaml:"port"`
|
|
API struct {
|
|
Host string `yaml:"host"`
|
|
Key string `yaml:"key"`
|
|
Port int `yaml:"port"`
|
|
Protocol string `yaml:"protocol"`
|
|
} `yaml:"api"`
|
|
} `yaml:"web"`
|
|
}
|
|
|
|
// DefaultConfig returns a Config filled with the default values from the
|
|
// `Default*` constants defined in this file.
|
|
func DefaultConfig() (cfg Config) {
|
|
cfg.API.TLS.Enabled = DefaultAPITLSEnabled
|
|
cfg.API.TLS.Certfile = DefaultAPITLSCertfile
|
|
cfg.API.TLS.Keyfile = DefaultAPITLSKeyfile
|
|
cfg.API.Port = DefaultAPIPort
|
|
cfg.API.Key = DefaultAPIKey
|
|
cfg.DB.Database = DefaultDBDatabase
|
|
cfg.DB.Host = DefaultDBHost
|
|
cfg.DB.SSLMode = DefaultDBSSLMode
|
|
cfg.DB.Password = DefaultDBPassword
|
|
cfg.DB.Port = DefaultDBPort
|
|
cfg.DB.User = DefaultDBUser
|
|
cfg.Web.User = DefaultWebUser
|
|
cfg.Web.Password = DefaultWebPassword
|
|
cfg.Web.Port = DefaultWebPort
|
|
cfg.Web.API.Host = DefaultWebAPIHost
|
|
cfg.Web.API.Key = DefaultWebAPIKey
|
|
cfg.Web.API.Port = DefaultWebAPIPort
|
|
cfg.Web.API.Protocol = DefaultWebAPIProtocol
|
|
return
|
|
}
|
|
|
|
func init() {
|
|
// rootCmd
|
|
|
|
cobra.OnInitialize(initConfig)
|
|
|
|
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.bottin.yaml)")
|
|
|
|
// apiCmd
|
|
|
|
rootCmd.AddCommand(apiCmd)
|
|
|
|
// api.tls.enabled
|
|
apiCmd.Flags().Bool(FlagAPITLSEnabled, DefaultAPITLSEnabled, DescriptionAPITLSEnabled)
|
|
if err := viper.BindPFlag(ViperAPITLSEnabled, apiCmd.Flags().Lookup(FlagAPITLSEnabled)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// api.tls.certfile
|
|
apiCmd.Flags().String(FlagAPITLSCertfile, DefaultAPITLSCertfile, DescriptionAPITLSCertfile)
|
|
if err := viper.BindPFlag(ViperAPITLSCertfile, apiCmd.Flags().Lookup(FlagAPITLSCertfile)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// api.tls.keyfile
|
|
apiCmd.Flags().String(FlagAPITLSKeyfile, DefaultAPITLSKeyfile, DescriptionAPITLSKeyFile)
|
|
if err := viper.BindPFlag(ViperAPITLSKeyfile, apiCmd.Flags().Lookup(FlagAPITLSKeyfile)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// api.key
|
|
apiCmd.Flags().String(FlagAPIKey, DefaultAPIKey, DescriptionAPIKey)
|
|
if err := viper.BindPFlag(ViperAPIKey, apiCmd.Flags().Lookup(FlagAPIKey)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// api.port
|
|
apiCmd.Flags().Int(FlagAPIPort, DefaultAPIPort, DescriptionAPIPort)
|
|
if err := viper.BindPFlag(ViperAPIPort, apiCmd.Flags().Lookup(FlagAPIPort)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// db.database
|
|
apiCmd.Flags().String(FlagDBDatabase, DefaultDBDatabase, DescriptionDBDatabase)
|
|
if err := viper.BindPFlag(ViperDBDatabase, apiCmd.Flags().Lookup(FlagDBDatabase)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// db.sslmode
|
|
apiCmd.Flags().String(FlagDBSSLMode, DefaultDBSSLMode, DescriptionDBSSLMode)
|
|
if err := viper.BindPFlag(ViperDBSSLMode, apiCmd.Flags().Lookup(FlagDBSSLMode)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// db.host
|
|
apiCmd.Flags().String(FlagDBHost, DefaultDBHost, DescriptionDBHost)
|
|
if err := viper.BindPFlag(ViperDBHost, apiCmd.Flags().Lookup(FlagDBHost)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// db.password
|
|
apiCmd.Flags().String(FlagDBPassword, DefaultDBPassword, DescriptionDBPassword)
|
|
if err := viper.BindPFlag(ViperDBPassword, apiCmd.Flags().Lookup(FlagDBPassword)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// db.port
|
|
apiCmd.Flags().Int(FlagDBPort, DefaultDBPort, DescriptionDBPort)
|
|
if err := viper.BindPFlag(ViperDBPort, apiCmd.Flags().Lookup(FlagDBPort)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// db.user
|
|
apiCmd.Flags().String(FlagDBUser, DefaultDBUser, DescriptionDBUser)
|
|
if err := viper.BindPFlag(ViperDBUser, apiCmd.Flags().Lookup(FlagDBUser)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// WebCmd
|
|
rootCmd.AddCommand(webCmd)
|
|
|
|
// web.api.host
|
|
webCmd.Flags().String(FlagWebAPIHost, DefaultWebAPIHost, DescriptionWebAPIHost)
|
|
if err := viper.BindPFlag(ViperWebAPIHost, webCmd.Flags().Lookup(FlagWebAPIHost)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// web.api.key
|
|
webCmd.Flags().String(FlagWebAPIKey, DefaultWebAPIKey, DescriptionWebAPIKey)
|
|
if err := viper.BindPFlag(ViperWebAPIKey, webCmd.Flags().Lookup(FlagWebAPIKey)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// web.api.protocol
|
|
webCmd.Flags().String(FlagWebAPIProtocol, DefaultWebAPIProtocol, DescriptionWebAPIProtocol)
|
|
if err := viper.BindPFlag(ViperWebAPIProtocol, webCmd.Flags().Lookup(FlagWebAPIProtocol)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// web.api.port
|
|
webCmd.Flags().Int(FlagWebAPIPort, DefaultWebAPIPort, DescriptionWebAPIPort)
|
|
if err := viper.BindPFlag(ViperWebAPIPort, webCmd.Flags().Lookup(FlagWebAPIPort)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// web.password
|
|
webCmd.Flags().String(FlagWebPassword, DefaultWebPassword, DescriptionWebPassword)
|
|
if err := viper.BindPFlag(ViperWebPassword, webCmd.Flags().Lookup(FlagWebPassword)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// web.port
|
|
webCmd.Flags().Int(FlagWebPort, DefaultWebPort, DescriptionWebPort)
|
|
if err := viper.BindPFlag(ViperWebPort, webCmd.Flags().Lookup(FlagWebPort)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// web.user
|
|
webCmd.Flags().String(FlagWebUser, DefaultWebUser, DescriptionWebUser)
|
|
if err := viper.BindPFlag(ViperWebUser, webCmd.Flags().Lookup(FlagWebUser)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
var cfgFile string
|
|
|
|
// initConfig reads in config file and ENV variables if set.
|
|
func initConfig() {
|
|
if cfgFile != "" {
|
|
// Use config file from the flag.
|
|
viper.SetConfigFile(cfgFile)
|
|
} else {
|
|
// Find home directory.
|
|
home, err := os.UserHomeDir()
|
|
cobra.CheckErr(err)
|
|
|
|
// Search config in home directory with name ".bottin" (without extension).
|
|
viper.AddConfigPath(home)
|
|
viper.SetConfigType("yaml")
|
|
viper.SetConfigName(".bottin")
|
|
}
|
|
|
|
viper.SetEnvPrefix("BOTTIN")
|
|
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
|
viper.AutomaticEnv() // read in environment variables that match
|
|
|
|
// If a config file is found, read it in.
|
|
if err := viper.ReadInConfig(); err == nil {
|
|
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
|
|
}
|
|
}
|