diff --git a/client/client.go b/client/client.go index 402031e..da4b32c 100644 --- a/client/client.go +++ b/client/client.go @@ -38,6 +38,7 @@ func CheckAndDeployLocalCertificate(logger log.Logger, acmeClient *restclient.Cl return } + _ = level.Info(logger).Log("msg", "Checking local certificates with remote server") certificates, err := acmeClient.GetAllCertificateMetadata() if err != nil { _ = level.Error(logger).Log("err", err) diff --git a/client/watcher.go b/client/watcher.go index f9e0234..a12eb6e 100644 --- a/client/watcher.go +++ b/client/watcher.go @@ -1,24 +1,64 @@ package client import ( + "fmt" + "os" + "path/filepath" "time" + "github.com/fsnotify/fsnotify" "github.com/go-kit/log" + "github.com/go-kit/log/level" "github.com/fgouteroux/acme_manager/restclient" ) -func WatchCertificate(logger log.Logger, interval time.Duration, configPath string, acmeClient *restclient.Client) { +func WatchLocalCertificate(logger log.Logger, interval time.Duration, acmeClient *restclient.Client) { // create a new Ticker tk := time.NewTicker(interval) // start the ticker for range tk.C { - - // Compare and create/update certificate from config file to remote server - CheckCertificate(logger, configPath, acmeClient) - // check local certificate are up-to-date CheckAndDeployLocalCertificate(logger, acmeClient) } } + +func WatchCertificateUpdate(logger log.Logger, configPath string, acmeClient *restclient.Client) { + watcher, err := fsnotify.NewWatcher() + if err != nil { + _ = level.Error(logger).Log("err", err) + os.Exit(1) + } + defer watcher.Close() + + fileName := filepath.Base(configPath) + if !filepath.IsAbs(configPath) { + fileName = "./" + fileName + } + + // watch the parent dir of the file to catch changes + err = watcher.Add(filepath.Dir(configPath)) + if err != nil { + _ = level.Error(logger).Log("err", err) + os.Exit(1) + } + + for { + select { + case event := <-watcher.Events: + // only work on WRITE events of the original filename + if event.Op&fsnotify.Write == fsnotify.Write && event.Name == fileName { + _ = level.Info(logger).Log("msg", fmt.Sprintf("modified file: %s", configPath)) + + // Compare and create/update certificate from config file to remote server + CheckCertificate(logger, configPath, acmeClient) + + // check local certificate are up-to-date + CheckAndDeployLocalCertificate(logger, acmeClient) + } + case err := <-watcher.Errors: + _ = level.Error(logger).Log("err", err) + } + } +} diff --git a/main.go b/main.go index 3227ea8..6051fbd 100644 --- a/main.go +++ b/main.go @@ -127,13 +127,17 @@ func main() { _ = level.Error(logger).Log("err", err) os.Exit(1) } - // Compare and create/update certificate from config file to remote server + // On startup compare and create/update certificate from config file to remote server client.CheckCertificate(logger, *clientConfigPath, acmeClient) - // check local certificate are up-to-date + // on startup check local certificate are up-to-date client.CheckAndDeployLocalCertificate(logger, acmeClient) - go client.WatchCertificate(logger, *clientCheckConfigInterval, *clientConfigPath, acmeClient) + // periodically check local certificate are up-to-date + go client.WatchLocalCertificate(logger, *clientCheckConfigInterval, acmeClient) + + // listen for config file event change + go client.WatchCertificateUpdate(logger, *clientConfigPath, acmeClient) http.Handle("/metrics", promhttp.Handler())