2019-05-08 23:45:04 +02:00
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"reflect"
|
2021-12-10 15:39:22 +01:00
|
|
|
"strings"
|
2019-05-08 23:45:04 +02:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/heetch/confita"
|
|
|
|
"github.com/heetch/confita/backend"
|
|
|
|
"github.com/heetch/confita/backend/env"
|
|
|
|
"github.com/heetch/confita/backend/flags"
|
|
|
|
)
|
|
|
|
|
2019-05-09 21:11:31 +02:00
|
|
|
// Config is the exporter CLI configuration.
|
2019-05-08 23:45:04 +02:00
|
|
|
type Config struct {
|
2021-12-10 04:48:28 +01:00
|
|
|
PIHoleProtocol string `config:"pihole_protocol"`
|
|
|
|
PIHoleHostname string `config:"pihole_hostname"`
|
|
|
|
PIHolePort uint16 `config:"pihole_port"`
|
|
|
|
PIHolePassword string `config:"pihole_password"`
|
|
|
|
PIHoleApiToken string `config:"pihole_api_token"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type EnvConfig struct {
|
|
|
|
PIHoleProtocol []string `config:"pihole_protocol"`
|
|
|
|
PIHoleHostname []string `config:"pihole_hostname"`
|
|
|
|
PIHolePort []uint16 `config:"pihole_port"`
|
|
|
|
PIHolePassword []string `config:"pihole_password"`
|
|
|
|
PIHoleApiToken []string `config:"pihole_api_token"`
|
|
|
|
Port uint16 `config:"port"`
|
2020-04-07 00:31:30 +02:00
|
|
|
Interval time.Duration `config:"interval"`
|
2019-05-08 23:45:04 +02:00
|
|
|
}
|
|
|
|
|
2021-12-10 04:48:28 +01:00
|
|
|
func getDefaultEnvConfig() *EnvConfig {
|
|
|
|
return &EnvConfig{
|
|
|
|
PIHoleProtocol: []string{"http"},
|
|
|
|
PIHoleHostname: []string{"127.0.0.1"},
|
|
|
|
PIHolePort: []uint16{80},
|
|
|
|
PIHolePassword: []string{},
|
|
|
|
PIHoleApiToken: []string{},
|
|
|
|
Port: 9617,
|
2020-04-07 00:31:30 +02:00
|
|
|
Interval: 10 * time.Second,
|
2019-05-08 23:45:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-09 21:11:31 +02:00
|
|
|
// Load method loads the configuration by using both flag or environment variables.
|
2021-12-10 04:48:28 +01:00
|
|
|
func Load() (*EnvConfig, []Config) {
|
2019-05-08 23:45:04 +02:00
|
|
|
loaders := []backend.Backend{
|
|
|
|
env.NewBackend(),
|
|
|
|
flags.NewBackend(),
|
|
|
|
}
|
|
|
|
|
|
|
|
loader := confita.NewLoader(loaders...)
|
|
|
|
|
2021-12-10 04:48:28 +01:00
|
|
|
cfg := getDefaultEnvConfig()
|
2019-05-08 23:45:04 +02:00
|
|
|
err := loader.Load(context.Background(), cfg)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
cfg.show()
|
|
|
|
|
2021-12-10 04:48:28 +01:00
|
|
|
return cfg, cfg.Split()
|
2019-05-08 23:45:04 +02:00
|
|
|
}
|
|
|
|
|
2021-12-10 15:39:22 +01:00
|
|
|
func (c *Config) String() string {
|
|
|
|
ref := reflect.ValueOf(c)
|
|
|
|
fields := ref.Elem()
|
|
|
|
|
|
|
|
buffer := make([]string, fields.NumField(), fields.NumField())
|
|
|
|
for i := 0; i < fields.NumField(); i++ {
|
|
|
|
valueField := fields.Field(i)
|
|
|
|
typeField := fields.Type().Field(i)
|
|
|
|
buffer[i] = fmt.Sprintf("%s=%v", typeField.Name, valueField.Interface())
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Sprintf("<Config@%X %s>", &c, strings.Join(buffer, ", "))
|
|
|
|
}
|
|
|
|
|
2021-08-16 23:55:05 +02:00
|
|
|
//Validate check if the config is valid
|
|
|
|
func (c Config) Validate() error {
|
|
|
|
if c.PIHoleProtocol != "http" && c.PIHoleProtocol != "https" {
|
|
|
|
return fmt.Errorf("protocol %s is invalid. Must be http or https", c.PIHoleProtocol)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-12-10 04:48:28 +01:00
|
|
|
func (c EnvConfig) Split() []Config {
|
|
|
|
result := make([]Config, 0, len(c.PIHoleHostname))
|
|
|
|
|
|
|
|
for i, hostname := range c.PIHoleHostname {
|
|
|
|
config := Config{
|
|
|
|
PIHoleHostname: hostname,
|
|
|
|
PIHoleProtocol: c.PIHoleProtocol[i],
|
|
|
|
PIHolePort: c.PIHolePort[i],
|
|
|
|
}
|
|
|
|
|
2021-12-18 00:25:23 +01:00
|
|
|
if c.PIHoleApiToken != nil {
|
|
|
|
if len(c.PIHoleApiToken) == 1 {
|
|
|
|
if c.PIHoleApiToken[0] != "" {
|
|
|
|
config.PIHoleApiToken = c.PIHoleApiToken[0]
|
|
|
|
}
|
|
|
|
} else if len(c.PIHoleApiToken) > 1 {
|
|
|
|
if c.PIHoleApiToken[i] != "" {
|
|
|
|
config.PIHoleApiToken = c.PIHoleApiToken[i]
|
|
|
|
}
|
2021-12-10 04:48:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-18 00:25:23 +01:00
|
|
|
if c.PIHolePassword != nil {
|
|
|
|
if len(c.PIHolePassword) == 1 {
|
|
|
|
if c.PIHolePassword[0] != "" {
|
|
|
|
config.PIHolePassword = c.PIHolePassword[0]
|
|
|
|
}
|
|
|
|
} else if len(c.PIHolePassword) > 1 {
|
|
|
|
if c.PIHolePassword[i] != "" {
|
|
|
|
config.PIHolePassword = c.PIHolePassword[i]
|
|
|
|
}
|
2021-12-10 04:48:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result = append(result, config)
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2021-08-16 23:55:05 +02:00
|
|
|
func (c Config) hostnameURL() string {
|
|
|
|
s := fmt.Sprintf("%s://%s", c.PIHoleProtocol, c.PIHoleHostname)
|
|
|
|
if c.PIHolePort != 0 {
|
|
|
|
s += fmt.Sprintf(":%d", c.PIHolePort)
|
|
|
|
}
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
//PIHoleStatsURL returns the stats url
|
|
|
|
func (c Config) PIHoleStatsURL() string {
|
|
|
|
return c.hostnameURL() + "/admin/api.php?summaryRaw&overTimeData&topItems&recentItems&getQueryTypes&getForwardDestinations&getQuerySources&jsonForceObject"
|
|
|
|
}
|
|
|
|
|
|
|
|
//PIHoleLoginURL returns the login url
|
|
|
|
func (c Config) PIHoleLoginURL() string {
|
|
|
|
return c.hostnameURL() + "/admin/index.php?login"
|
|
|
|
}
|
|
|
|
|
2021-12-10 04:48:28 +01:00
|
|
|
func (c EnvConfig) show() {
|
2019-05-08 23:45:04 +02:00
|
|
|
val := reflect.ValueOf(&c).Elem()
|
|
|
|
log.Println("------------------------------------")
|
|
|
|
log.Println("- PI-Hole exporter configuration -")
|
|
|
|
log.Println("------------------------------------")
|
|
|
|
for i := 0; i < val.NumField(); i++ {
|
|
|
|
valueField := val.Field(i)
|
|
|
|
typeField := val.Type().Field(i)
|
|
|
|
|
2020-04-07 00:31:30 +02:00
|
|
|
// Do not print password or api token but do print the authentication method
|
|
|
|
if typeField.Name != "PIHolePassword" && typeField.Name != "PIHoleApiToken" {
|
2020-04-04 20:59:31 +02:00
|
|
|
log.Println(fmt.Sprintf("%s : %v", typeField.Name, valueField.Interface()))
|
2020-04-07 00:31:30 +02:00
|
|
|
} else {
|
2021-12-10 04:48:28 +01:00
|
|
|
showAuthenticationMethod(typeField.Name, valueField.Len())
|
2020-04-04 20:59:31 +02:00
|
|
|
}
|
2019-05-08 23:45:04 +02:00
|
|
|
}
|
|
|
|
log.Println("------------------------------------")
|
|
|
|
}
|
2020-04-07 00:31:30 +02:00
|
|
|
|
2021-12-10 04:48:28 +01:00
|
|
|
func showAuthenticationMethod(name string, length int) {
|
|
|
|
if length > 0 {
|
2020-04-27 00:38:28 +02:00
|
|
|
log.Println(fmt.Sprintf("Pi-Hole Authentication Method : %s", name))
|
2020-04-07 00:31:30 +02:00
|
|
|
}
|
|
|
|
}
|