diff --git a/actions.go b/actions.go index 7c65ccb..234b541 100644 --- a/actions.go +++ b/actions.go @@ -429,6 +429,40 @@ func reload() error { return nil } +func reloadRemote(server string) error { + url := syncScheme + server + ":" + syncPort + "/api/reload" + req, err := http.NewRequest("POST", url, nil) + if err != nil { + log.Println(err.Error()) + return errors.New("Couldn't create new HTTP reload request for server: " + server) + } + req.Close = true + req.Header.Set("User-Agent", myUserAgent) + req.SetBasicAuth(appconf.Username, appconf.SecretKey) + //req.Header.Set("Authorization", "Bearer "+appconf.SecretKey) + //skip verification of cert, since the cert may not be setup properly at first + customTransport := http.DefaultTransport.(*http.Transport).Clone() + customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + client := &http.Client{Transport: customTransport, Timeout: timeout} + //client := &http.Client{Timeout: timeout} + response, err := client.Do(req) + if err != nil { + log.Println(err.Error()) + return errors.New("Couldn't send HTTP remote reload to server: " + server) + } + body, err := ioutil.ReadAll(response.Body) + if err != nil { + log.Println(err.Error()) + return errors.New("Couldn't parse response body on request to server: " + server) + } + if response.StatusCode != 200 { + errorString := "Problem sending remote reload to server " + server + ". Status code: " + strconv.Itoa(response.StatusCode) + " Body: " + string(body) + log.Println(errorString) + return errors.New(errorString) + } + return nil +} + func checkDomain(domain, certPath string) error { log.Println("Checking for successful installation of certificate on '" + domain + "' (verify fingerprint)...") //could do this in go with tls.Dial but using openssl is quicker and easier diff --git a/api.go b/api.go index 4bd8e03..0b43d38 100644 --- a/api.go +++ b/api.go @@ -73,6 +73,54 @@ func apiReload(c echo.Context) error { return c.JSON(okOut()) } +func apiReloadAll(c echo.Context) error { + err := reload() + if err != nil { + return c.JSON(errorOut(http.StatusInternalServerError, "Error reloading services: "+err.Error())) + } + return c.JSON(okOut()) +} + +func reloadAllServers() error { + var theError error + numservers := len(servers) + c := make(chan string) + + var wg sync.WaitGroup + wg.Add(numservers) + for n := 0; n < numservers; n++ { + go func(c chan string) { + for { + srv, more := <-c + if more == false { + wg.Done() + return + } + + log.Println("Concurrent execution send reload to server: " + srv + "...") + err := reloadRemote(srv) + if err != nil { + log.Println(err.Error()) + theError = err + } + } + }(c) + } + for _, server := range servers { //send each server to the channel + if server == appconf.Hostname { //don't send myself + continue + } + c <- server + } + close(c) + wg.Wait() + if theError == nil { + log.Println("Finished requsting reload to all servers.") + } + + return theError //if any one or more fail, return an error for it (the last one that fails) +} + func apiAddDns(c echo.Context) error { //used by getssl to add _acme-challenge DNS record input := new(ApiDomainInput) if err := c.Bind(input); err != nil { diff --git a/main.go b/main.go index 58eef5d..820d335 100644 --- a/main.go +++ b/main.go @@ -283,6 +283,9 @@ func main() { api.OPTIONS("/reload", apiReload) api.POST("/reload", apiReload) + api.OPTIONS("/reloadall", apiReloadAll) + api.POST("/reloadall", apiReloadAll) + api.POST("/dnsadd", apiAddDns) api.POST("/dnsdel", apiDelDns)