228 lines
6.8 KiB
Go
228 lines
6.8 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"log"
|
||
|
"os"
|
||
|
"os/exec"
|
||
|
"os/user"
|
||
|
"path"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"github.com/kkyr/fig"
|
||
|
)
|
||
|
|
||
|
// Main configuration structure.
|
||
|
type Config struct {
|
||
|
// Used as the FreeIPA server hostname in multiple checks.
|
||
|
// If no address configurations for metric exporters are defined,
|
||
|
// the hostname will be used to set defaults.
|
||
|
Hostname string `fig:"hostname"`
|
||
|
|
||
|
// Metric exporters configurations.
|
||
|
LDAP LDAPConfig `fig:"ldap"`
|
||
|
FreeIPA FreeIPAConfig `fig:"freeipa"`
|
||
|
|
||
|
// Metric outputs configurations.
|
||
|
HTTP HTTPOutputConfig `fig:"http_output"`
|
||
|
Influx InfluxOutputConfig `fig:"influx_output"`
|
||
|
|
||
|
// File path configurations for binaries and config files.
|
||
|
Krb5SysConfigPath string `fig:"krb5_sysconfig_path"`
|
||
|
Krb5KeytabPath string `fig:"krb5_keytab_path"`
|
||
|
Krb5ConfigPath string `fig:"krb5_config_path"`
|
||
|
PKITomcatServerXML string `fig:"pki_tomcat_server_xml"`
|
||
|
HTTPDPKIProxyConf string `fig:"httpd_pki_proxy_conf"`
|
||
|
KInitBin string `fig:"kinit_bin"`
|
||
|
KListBin string `fig:"klist_bin"`
|
||
|
IPAGetCertBIN string `fig:"ipa_getcert_bin"`
|
||
|
}
|
||
|
|
||
|
const (
|
||
|
// Use standard LDAP connection.
|
||
|
LDAPMethodUnsecure = "Unsecure"
|
||
|
// Use LDAP over TLS.
|
||
|
LDAPMethodSecure = "Secure"
|
||
|
// Use StartTLS over standard LDAP connection.
|
||
|
LDAPMethodStartTLS = "StartTLS"
|
||
|
)
|
||
|
|
||
|
// Configurations relating to LDAP.
|
||
|
type LDAPConfig struct {
|
||
|
Address string `fig:"address"`
|
||
|
CACertificate string `fig:"ca_certificate"`
|
||
|
InsecureSkipVerify bool `fig:"insecure_skip_verify"`
|
||
|
ConnectMethod string `fig:"connect_method"`
|
||
|
BaseDN string `fig:"base_dn"`
|
||
|
BindDN string `fig:"bind_dn"`
|
||
|
BindPassword string `fig:"bind_password"`
|
||
|
SearchSizeLimit int `fig:"search_size_limit"`
|
||
|
|
||
|
DisabledMetrics []string `fig:"disabled_metrics"`
|
||
|
}
|
||
|
|
||
|
// UNIX system group members for the FreeIPA configuration check of file system state.
|
||
|
type GroupMembers struct {
|
||
|
Name string `fig:"name"`
|
||
|
Members []string `fig:"members"`
|
||
|
}
|
||
|
|
||
|
// Configurations relating to FreeIPA API and configuration testing.
|
||
|
type FreeIPAConfig struct {
|
||
|
// Kerberos config can be used for both API authentication and for kinit test.
|
||
|
// To use for API authentication, simply do not supply an username/password.
|
||
|
// It is recommended to have it configured for the kinit test to function.
|
||
|
Krb5Realm string `fig:"krb5_realm"`
|
||
|
Krb5Principal string `fig:"krb5_principal"`
|
||
|
|
||
|
Host string `fig:"host"`
|
||
|
CACertificate string `fig:"ca_certificate"`
|
||
|
InsecureSkipVerify bool `fig:"insecure_skip_verify"`
|
||
|
Username string `fig:"username"`
|
||
|
Password string `fig:"password"`
|
||
|
|
||
|
GroupMembers []GroupMembers `fig:"group_mebers"`
|
||
|
|
||
|
DisabledMetrics []string `fig:"disabled_metrics"`
|
||
|
}
|
||
|
|
||
|
// Configurations relating to HTTP server.
|
||
|
type HTTPOutputConfig struct {
|
||
|
Enabled bool `fig:"enabled"`
|
||
|
BindAddr string `fig:"bind_addr"`
|
||
|
Port uint `fig:"port"`
|
||
|
MetricsPath string `fig:"metrics_path"`
|
||
|
}
|
||
|
|
||
|
// If you want to output to InfluxDB either via Kafka or to InfluxDB API directly,
|
||
|
// these configurations allow you to set output to occur at a specified frequency.
|
||
|
type InfluxOutputConfig struct {
|
||
|
Frequency time.Duration `fig:"frequency"`
|
||
|
|
||
|
KafkaBrokers []string `fig:"kafka_brokers"`
|
||
|
KafkaTopic string `fig:"kafka_topic"`
|
||
|
KafkaUsername string `fig:"kafka_usernamne"`
|
||
|
KafkaPassword string `fig:"kafka_password"`
|
||
|
KafkaInsecureSkipVerify bool `fig:"kafka_insecure_skip_verify"`
|
||
|
KafkaOutputFormat string `fig:"kafka_output_format"` // Either lineprotocol or json. Default: lineprotocol
|
||
|
|
||
|
InfluxServer string `fig:"influx_server"`
|
||
|
Token string `fig:"token"`
|
||
|
Org string `fig:"org"`
|
||
|
Bucket string `fig:"bucket"`
|
||
|
}
|
||
|
|
||
|
// Read the configuration file.
|
||
|
func (a *App) ReadConfig() {
|
||
|
// Gets the current user for getting the home directory.
|
||
|
usr, err := user.Current()
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// Configuration paths.
|
||
|
localConfig, _ := filepath.Abs("./config.yaml")
|
||
|
homeDirConfig := usr.HomeDir + "/.config/freeipa-health-metrics/config.yaml"
|
||
|
etcConfig := "/etc/ipa/freeipa-health-metrics.yaml"
|
||
|
|
||
|
// Determine which configuration to use.
|
||
|
var configFile string
|
||
|
if _, err := os.Stat(app.flags.ConfigPath); err == nil && app.flags.ConfigPath != "" {
|
||
|
configFile = app.flags.ConfigPath
|
||
|
} else if _, err := os.Stat(localConfig); err == nil {
|
||
|
configFile = localConfig
|
||
|
} else if _, err := os.Stat(homeDirConfig); err == nil {
|
||
|
configFile = homeDirConfig
|
||
|
} else if _, err := os.Stat(etcConfig); err == nil {
|
||
|
configFile = etcConfig
|
||
|
} else {
|
||
|
log.Fatal("Unable to find a configuration file.")
|
||
|
}
|
||
|
|
||
|
// Set defaults.
|
||
|
config := &Config{
|
||
|
HTTP: HTTPOutputConfig{
|
||
|
Enabled: true,
|
||
|
Port: 9101,
|
||
|
MetricsPath: "/metrics",
|
||
|
},
|
||
|
LDAP: LDAPConfig{
|
||
|
SearchSizeLimit: 100,
|
||
|
},
|
||
|
FreeIPA: FreeIPAConfig{
|
||
|
GroupMembers: []GroupMembers{
|
||
|
{
|
||
|
Name: "apache",
|
||
|
Members: []string{"ipaapi"},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
|
||
|
Krb5SysConfigPath: "/etc/sysconfig/krb5kdc",
|
||
|
Krb5KeytabPath: "/etc/krb5.keytab",
|
||
|
Krb5ConfigPath: "/etc/krb5.conf",
|
||
|
PKITomcatServerXML: "/etc/pki/pki-tomcat/server.xml",
|
||
|
HTTPDPKIProxyConf: "/etc/httpd/conf.d/ipa-pki-proxy.conf",
|
||
|
KInitBin: "/usr/bin/kinit",
|
||
|
KListBin: "/usr/bin/klist",
|
||
|
IPAGetCertBIN: "/usr/bin/ipa-getcert",
|
||
|
}
|
||
|
|
||
|
// Load configuration.
|
||
|
filePath, fileName := path.Split(configFile)
|
||
|
err = fig.Load(config,
|
||
|
fig.File(fileName),
|
||
|
fig.Dirs(filePath),
|
||
|
)
|
||
|
if err != nil {
|
||
|
log.Printf("Error parsing configuration: %s\n", err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// If no hostname is defined in config, pull system hostname.
|
||
|
if config.Hostname == "" {
|
||
|
cmd := exec.Command("/bin/hostname", "-f")
|
||
|
var out bytes.Buffer
|
||
|
cmd.Stdout = &out
|
||
|
err = cmd.Run()
|
||
|
if err != nil {
|
||
|
log.Println("Error getting hostname:", err)
|
||
|
return
|
||
|
}
|
||
|
config.Hostname = strings.TrimRight(out.String(), "\n")
|
||
|
}
|
||
|
|
||
|
// Use configured hostname as defaults for host related configs.
|
||
|
if config.FreeIPA.Krb5Principal == "" {
|
||
|
config.FreeIPA.Krb5Principal = "host/" + config.Hostname
|
||
|
}
|
||
|
if config.LDAP.Address == "" {
|
||
|
config.LDAP.Address = "ldaps://" + config.Hostname + ":636"
|
||
|
}
|
||
|
if config.FreeIPA.Host == "" {
|
||
|
config.FreeIPA.Host = config.Hostname
|
||
|
}
|
||
|
|
||
|
// Flag Overrides.
|
||
|
if app.flags.HTTPBind != "" {
|
||
|
config.HTTP.BindAddr = app.flags.HTTPBind
|
||
|
}
|
||
|
if app.flags.HTTPPort != 0 {
|
||
|
config.HTTP.Port = app.flags.HTTPPort
|
||
|
}
|
||
|
if app.flags.HTTPMetricsPath != "" {
|
||
|
config.HTTP.MetricsPath = app.flags.HTTPMetricsPath
|
||
|
}
|
||
|
|
||
|
// Verify at least one output is enabled.
|
||
|
if !config.HTTP.Enabled && (len(app.config.Influx.KafkaBrokers) == 0 || app.config.Influx.KafkaTopic == "") && (config.Influx.InfluxServer == "" && config.Influx.Token == "" && config.Influx.Org == "" && config.Influx.Bucket == "") {
|
||
|
log.Println("No output services are configured.")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Set global config structure.
|
||
|
app.config = config
|
||
|
}
|