fetchcert/main.go
Emmanuel BENOîT 658ee30bc6 Server socket
* The UNIX socket will be listened on for control messages
  * A message containing a single 'Q' will cause it to exit
  * A message containing a single 'R' will cause a configuration reload.
    If the new configuration is incorrect, the old configuration will be
    kept. A new socket will be opened if the path has changed (failure
    when doing so will restore the previous configuration as well).
  * A message starting with 'U' requests an update. The next character
    may be '!' to force updates or anything else to update only as
    needed. The rest of the string is the selector: either a DN or '*'.
  * The selector is ignored in this commit; all certificates are
    re-examined.
2021-11-06 17:12:08 +01:00

100 lines
2.8 KiB
Go

package main
import (
"os"
"github.com/karrick/golf"
)
type (
// This structure contains all values that may be set from the command line.
cliFlags struct {
// The path to the configuration file.
cfgFile string
// Quiet mode. Will disable logging to stderr.
quiet bool
// The log level.
logLevel string
// A file to write logs into.
logFile string
// Graylog server to send logs to (using GELF/UDP). Format is <hostname>:<port>.
logGraylog string
// Send logs to syslog.
logSyslog bool
}
)
// Parse command line options.
func parseCommandLine() cliFlags {
var help bool
flags := cliFlags{}
golf.StringVarP(&flags.cfgFile, 'c', "config", "/etc/fetch-certificates.yml", "Path to the configuration file.")
golf.StringVarP(&flags.logFile, 'f', "log-file", "", "Path to the log file.")
golf.StringVarP(&flags.logGraylog, 'g', "log-graylog", "", "Log to Graylog server (format: <host>:<port>).")
golf.BoolVarP(&help, 'h', "help", false, "Display command line help and exit.")
golf.StringVarP(&flags.logLevel, 'L', "log-level", "info", "Log level to use.")
golf.BoolVarP(&flags.quiet, 'q', "quiet", false, "Quiet mode; prevents logging to stderr.")
golf.BoolVarP(&flags.logSyslog, 's', "syslog", false, "Log to local syslog.")
golf.Parse()
if help {
golf.Usage()
os.Exit(0)
}
return flags
}
func main() {
// This utility will load its configuration then start listening on
// a UNIX socket. It will be handle messages that can :
// - stop the program,
// - update the configuration,
// - check a single entry for replacement,
// - check all entries for replacement.
// Both check commands include a flag that will force replacement.
flags := parseCommandLine()
err := configureLogging(flags)
if err != nil {
log.WithField("error", err).Fatal("Failed to configure logging.")
}
cfg, err := LoadConfiguration(flags.cfgFile)
if err != nil {
log.WithField("error", err).Fatal("Failed to load initial configuration.")
}
listener, err := initSocket(cfg.Socket)
if err != nil {
log.WithField("error", err).Fatal("Failed to initialize socket.")
}
defer listener.Close()
for {
cmd := socketServer(&cfg, listener)
if cmd == CMD_QUIT {
break
} else if cmd == CMD_RELOAD {
new_cfg, err := LoadConfiguration(flags.cfgFile)
if err != nil {
log.WithField("error", err).Error("Failed to load updated configuration.")
} else {
replace_ok := true
if new_cfg.Socket.Path != cfg.Socket.Path {
new_listener, err := initSocket(new_cfg.Socket)
if err != nil {
log.WithField("error", err).Error("Failed to initialize new server socket.")
replace_ok = false
} else {
listener.Close()
listener = new_listener
}
}
if replace_ok {
cfg = new_cfg
log.Info("Configuration reloaded")
}
}
}
}
}