2024-06-06 01:40:56 -04:00
|
|
|
package main
|
|
|
|
|
2024-06-06 18:07:30 -04:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/spf13/viper"
|
|
|
|
)
|
2024-06-06 17:01:16 -04:00
|
|
|
|
2024-06-06 01:40:56 -04:00
|
|
|
type Config struct {
|
2024-07-15 16:52:04 -04:00
|
|
|
Client struct {
|
|
|
|
API struct {
|
2024-06-06 01:40:56 -04:00
|
|
|
Host string `yaml:"host"`
|
|
|
|
Key string `yaml:"key"`
|
|
|
|
Port int `yaml:"port"`
|
|
|
|
Protocol string `yaml:"protocol"`
|
|
|
|
} `yaml:"api"`
|
2024-07-15 16:52:04 -04:00
|
|
|
} `yaml:"client"`
|
|
|
|
|
|
|
|
Server struct {
|
|
|
|
API struct {
|
|
|
|
DB struct {
|
|
|
|
Database string `yaml:"database"`
|
|
|
|
Host string `yaml:"host"`
|
|
|
|
Password string `yaml:"password"`
|
|
|
|
Port int `yaml:"port"`
|
|
|
|
SSLMode string `yaml:"sslmode"`
|
|
|
|
User string `yaml:"user"`
|
|
|
|
} `yaml:"db"`
|
|
|
|
Host string `yaml:"host"`
|
|
|
|
Key string `yaml:"key"`
|
|
|
|
Port int `yaml:"port"`
|
|
|
|
TLS struct {
|
|
|
|
Enabled bool `yaml:"enabled"`
|
|
|
|
Certfile string `yaml:"certfile"`
|
|
|
|
Keyfile string `yaml:"keyfile"`
|
|
|
|
} `yaml:"tls"`
|
|
|
|
} `yaml:"api"`
|
|
|
|
UI struct {
|
|
|
|
API struct {
|
|
|
|
Host string `yaml:"host"`
|
|
|
|
Key string `yaml:"key"`
|
|
|
|
Port int `yaml:"port"`
|
|
|
|
Protocol string `yaml:"protocol"`
|
2024-09-03 16:42:05 -04:00
|
|
|
TLS struct {
|
|
|
|
SkipVerify bool `yaml:"skipverify"`
|
|
|
|
} `yaml:"tls"`
|
2024-07-15 16:52:04 -04:00
|
|
|
} `yaml:"api"`
|
2024-07-23 11:46:37 -04:00
|
|
|
Host string `yaml:"host"`
|
2024-07-15 16:52:04 -04:00
|
|
|
Password string `yaml:"password"`
|
|
|
|
Port int `yaml:"port"`
|
|
|
|
TLS struct {
|
|
|
|
Enabled bool `yaml:"enabled"`
|
|
|
|
Certfile string `yaml:"certfile"`
|
|
|
|
Keyfile string `yaml:"keyfile"`
|
|
|
|
} `yaml:"tls"`
|
|
|
|
User string `yaml:"user"`
|
|
|
|
} `yaml:"ui"`
|
|
|
|
} `yaml:"server"`
|
2024-06-06 01:40:56 -04:00
|
|
|
}
|
2024-06-06 17:01:16 -04:00
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
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())
|
|
|
|
}
|
2024-06-06 17:01:16 -04:00
|
|
|
}
|
2024-06-06 18:07:30 -04:00
|
|
|
|
|
|
|
func init() {
|
|
|
|
// rootCmd
|
|
|
|
|
|
|
|
cobra.OnInitialize(initConfig)
|
|
|
|
|
|
|
|
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.bottin.yaml)")
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// client.api.host
|
|
|
|
rootCmd.PersistentFlags().String(
|
|
|
|
"client-api-host",
|
|
|
|
"api",
|
|
|
|
"API server host",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"client.api.host",
|
|
|
|
rootCmd.PersistentFlags().Lookup("client-api-host"),
|
|
|
|
); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2024-06-06 18:07:30 -04:00
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// client.api.key
|
|
|
|
rootCmd.PersistentFlags().String(
|
|
|
|
"client-api-key",
|
|
|
|
"bottin",
|
|
|
|
"API server key",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"client.api.key",
|
|
|
|
rootCmd.PersistentFlags().Lookup("client-api-key"),
|
|
|
|
); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2024-06-06 18:07:30 -04:00
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// client.api.port
|
|
|
|
rootCmd.PersistentFlags().Int(
|
|
|
|
"client-api-port",
|
|
|
|
1312,
|
|
|
|
"API server port",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"client.api.port",
|
|
|
|
rootCmd.PersistentFlags().Lookup("client-api-port"),
|
|
|
|
); err != nil {
|
2024-07-03 20:51:43 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// client.api.protocol
|
|
|
|
rootCmd.PersistentFlags().String(
|
|
|
|
"client-api-protocol",
|
|
|
|
"https",
|
|
|
|
"API server protocol",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"client.api.protocol",
|
|
|
|
rootCmd.PersistentFlags().Lookup("client-api-protocol"),
|
|
|
|
); err != nil {
|
2024-07-03 20:51:43 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server
|
|
|
|
rootCmd.AddCommand(serverCmd)
|
|
|
|
|
|
|
|
// server api
|
|
|
|
serverCmd.AddCommand(apiCmd)
|
|
|
|
|
|
|
|
// server api db
|
|
|
|
// server.api.db.database
|
|
|
|
apiCmd.PersistentFlags().String(
|
|
|
|
"server-api-db-database",
|
|
|
|
"bottin",
|
|
|
|
"Postgres database name",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.api.db.database",
|
|
|
|
apiCmd.PersistentFlags().Lookup("server-api-db-database"),
|
|
|
|
); err != nil {
|
2024-07-03 20:51:43 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.api.db.host
|
|
|
|
apiCmd.PersistentFlags().String(
|
|
|
|
"server-api-db-host",
|
|
|
|
"db",
|
|
|
|
"Postgres host name",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.api.db.host",
|
|
|
|
apiCmd.PersistentFlags().Lookup("server-api-db-host"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.api.db.password
|
|
|
|
apiCmd.PersistentFlags().String(
|
|
|
|
"server-api-db-password",
|
|
|
|
"bottin",
|
|
|
|
"Postgres password",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.api.db.password",
|
|
|
|
apiCmd.PersistentFlags().Lookup("server-api-db-password"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.api.db.port
|
|
|
|
apiCmd.PersistentFlags().Int(
|
|
|
|
"server-api-db-port",
|
|
|
|
5432,
|
|
|
|
"Postgres port",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.api.db.port",
|
|
|
|
apiCmd.PersistentFlags().Lookup("server-api-db-port"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.api.db.sslmode
|
|
|
|
apiCmd.PersistentFlags().String(
|
|
|
|
"server-api-db-sslmode",
|
|
|
|
"prefer",
|
|
|
|
"Postgres sslmode",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.api.db.sslmode",
|
|
|
|
apiCmd.PersistentFlags().Lookup("server-api-db-sslmode"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.api.db.user
|
|
|
|
apiCmd.PersistentFlags().String(
|
|
|
|
"server-api-db-user",
|
|
|
|
"bottin",
|
|
|
|
"Postgres user name",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.api.db.user",
|
|
|
|
apiCmd.PersistentFlags().Lookup("server-api-db-user"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.api.host
|
|
|
|
apiCmd.PersistentFlags().String(
|
|
|
|
"server-api-host",
|
|
|
|
"",
|
|
|
|
"API server hostname or IP to answer on (empty = any)",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.api.host",
|
|
|
|
apiCmd.PersistentFlags().Lookup("server-api-host"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.api.key
|
|
|
|
apiCmd.PersistentFlags().String(
|
|
|
|
"server-api-key",
|
|
|
|
"bottin",
|
|
|
|
"API server key",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.api.key",
|
|
|
|
apiCmd.PersistentFlags().Lookup("server-api-key"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.api.port
|
|
|
|
apiCmd.PersistentFlags().Int(
|
|
|
|
"server-api-port",
|
|
|
|
1312,
|
|
|
|
"API server port",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.api.port",
|
|
|
|
apiCmd.PersistentFlags().Lookup("server-api-port"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server api tls
|
|
|
|
// server.api.tls.enabled
|
|
|
|
apiCmd.PersistentFlags().Bool(
|
|
|
|
"server-api-tls-enabled",
|
|
|
|
true,
|
|
|
|
"Use TLS for API server connections (requires certfile and keyfile)",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.api.tls.enabled",
|
|
|
|
apiCmd.PersistentFlags().Lookup("server-api-tls-enabled"),
|
|
|
|
); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2024-06-06 18:07:30 -04:00
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.api.tls.certfile
|
|
|
|
apiCmd.PersistentFlags().String(
|
|
|
|
"server-api-tls-certfile",
|
|
|
|
"/etc/bottin/cert.pem",
|
|
|
|
"Path to certificate file",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.api.tls.certfile",
|
|
|
|
apiCmd.PersistentFlags().Lookup("server-api-tls-certfile"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.api.tls.keyfile
|
|
|
|
apiCmd.PersistentFlags().String(
|
|
|
|
"server-api-tls-keyfile",
|
|
|
|
"/etc/bottin/key.pem",
|
|
|
|
"Path to private key file",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.api.tls.keyfile",
|
|
|
|
apiCmd.PersistentFlags().Lookup("server-api-tls-keyfile"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server ui
|
|
|
|
serverCmd.AddCommand(uiCmd)
|
|
|
|
|
|
|
|
// server ui api
|
|
|
|
|
|
|
|
// server.ui.api.host
|
|
|
|
uiCmd.PersistentFlags().String(
|
|
|
|
"server-ui-api-host",
|
|
|
|
"api",
|
|
|
|
"Web UI backend API server host name",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.ui.api.host",
|
|
|
|
uiCmd.PersistentFlags().Lookup("server-ui-api-host"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.ui.api.key
|
|
|
|
uiCmd.PersistentFlags().String(
|
|
|
|
"server-ui-api-key",
|
|
|
|
"bottin",
|
|
|
|
"Web UI backend API server key",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.ui.api.key",
|
|
|
|
uiCmd.PersistentFlags().Lookup("server-ui-api-key"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.ui.api.port
|
|
|
|
uiCmd.PersistentFlags().Int(
|
|
|
|
"server-ui-api-port",
|
|
|
|
1312,
|
|
|
|
"Web UI backend API server port",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.ui.api.port",
|
|
|
|
uiCmd.PersistentFlags().Lookup("server-ui-api-port"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.ui.api.protocol
|
|
|
|
uiCmd.PersistentFlags().String(
|
|
|
|
"server-ui-api-protocol",
|
|
|
|
"https",
|
|
|
|
"Web UI backend API server protocol",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.ui.api.protocol",
|
|
|
|
uiCmd.PersistentFlags().Lookup("server-ui-api-protocol"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-09-03 16:42:05 -04:00
|
|
|
// server.ui.api.tls.skipverify
|
|
|
|
uiCmd.PersistentFlags().Bool(
|
|
|
|
"server-ui-api-tls-skipverify",
|
|
|
|
false,
|
|
|
|
"Skip API server TLS certificate verification",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.ui.api.tls.skipverify",
|
|
|
|
uiCmd.PersistentFlags().Lookup("server-ui-api-tls-skipverify"),
|
|
|
|
); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-23 11:46:37 -04:00
|
|
|
// server.ui.host
|
|
|
|
uiCmd.PersistentFlags().String(
|
|
|
|
"server-ui-host",
|
|
|
|
"",
|
|
|
|
"Web UI host",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.ui.host",
|
|
|
|
uiCmd.PersistentFlags().Lookup("server-ui-host"),
|
|
|
|
); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.ui.password
|
|
|
|
uiCmd.PersistentFlags().String(
|
|
|
|
"server-ui-password",
|
|
|
|
"bottin",
|
|
|
|
"Web UI password",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.ui.password",
|
|
|
|
uiCmd.PersistentFlags().Lookup("server-ui-password"),
|
|
|
|
); err != nil {
|
2024-06-06 18:07:30 -04:00
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.ui.port
|
|
|
|
uiCmd.PersistentFlags().Int(
|
|
|
|
"server-ui-port",
|
|
|
|
2312,
|
|
|
|
"Web UI port",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.ui.port",
|
|
|
|
uiCmd.PersistentFlags().Lookup("server-ui-port"),
|
|
|
|
); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2024-06-06 18:07:30 -04:00
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.ui.user
|
|
|
|
uiCmd.PersistentFlags().String(
|
|
|
|
"server-ui-user",
|
|
|
|
"bottin",
|
|
|
|
"Web UI user",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.ui.user",
|
|
|
|
uiCmd.PersistentFlags().Lookup("server-ui-user"),
|
|
|
|
); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2024-06-06 18:07:30 -04:00
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server ui tls
|
|
|
|
// server.ui.tls.enabled
|
|
|
|
uiCmd.PersistentFlags().Bool(
|
|
|
|
"server-ui-tls-enabled",
|
|
|
|
true,
|
|
|
|
"Web UI enable TLS (requires certfile and keyfile)",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.ui.tls.enabled",
|
|
|
|
uiCmd.PersistentFlags().Lookup("server-ui-tls-enabled"),
|
|
|
|
); err != nil {
|
|
|
|
log.Fatal(err)
|
2024-06-06 18:07:30 -04:00
|
|
|
}
|
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.ui.tls.certfile
|
|
|
|
uiCmd.PersistentFlags().String(
|
|
|
|
"server-ui-tls-certfile",
|
|
|
|
"/etc/bottin/cert.pem",
|
|
|
|
"Path to Web UI TLS certificate file",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.ui.tls.certfile",
|
|
|
|
uiCmd.PersistentFlags().Lookup("server-ui-tls-certfile"),
|
|
|
|
); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
2024-06-06 18:07:30 -04:00
|
|
|
|
2024-07-15 16:52:04 -04:00
|
|
|
// server.ui.tls.keyfile
|
|
|
|
uiCmd.PersistentFlags().String(
|
|
|
|
"server-ui-tls-keyfile",
|
|
|
|
"/etc/bottin/key.pem",
|
|
|
|
"Path to Web UI TLS private key file",
|
|
|
|
)
|
|
|
|
if err := viper.BindPFlag(
|
|
|
|
"server.ui.tls.keyfile",
|
|
|
|
uiCmd.PersistentFlags().Lookup("server-ui-tls-keyfile"),
|
|
|
|
); err != nil {
|
|
|
|
log.Fatal(err)
|
2024-06-06 18:07:30 -04:00
|
|
|
}
|
|
|
|
}
|