ping.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Copyright (C) 2019 Nicola Murino
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU Affero General Public License as published
  5. // by the Free Software Foundation, version 3.
  6. //
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU Affero General Public License for more details.
  11. //
  12. // You should have received a copy of the GNU Affero General Public License
  13. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. package cmd
  15. import (
  16. "fmt"
  17. "net/http"
  18. "os"
  19. "github.com/rs/zerolog"
  20. "github.com/spf13/cobra"
  21. "github.com/drakkan/sftpgo/v2/internal/config"
  22. "github.com/drakkan/sftpgo/v2/internal/httpclient"
  23. "github.com/drakkan/sftpgo/v2/internal/httpd"
  24. "github.com/drakkan/sftpgo/v2/internal/logger"
  25. "github.com/drakkan/sftpgo/v2/internal/util"
  26. )
  27. func getHealthzURLFromBindings(bindings []httpd.Binding) string {
  28. for _, b := range bindings {
  29. if b.Port > 0 && b.IsValid() {
  30. var url string
  31. if b.EnableHTTPS {
  32. url = "https://"
  33. } else {
  34. url = "http://"
  35. }
  36. if b.Address == "" {
  37. url += "127.0.0.1"
  38. } else {
  39. url += b.Address
  40. }
  41. url += fmt.Sprintf(":%d", b.Port)
  42. url += "/healthz"
  43. return url
  44. }
  45. }
  46. return ""
  47. }
  48. var (
  49. pingCmd = &cobra.Command{
  50. Use: "ping",
  51. Short: "Issues an health check to SFTPGo",
  52. Long: `This command is only useful in environments where system commands like
  53. "curl", "wget" and similar are not available.
  54. Checks over UNIX domain sockets are not supported`,
  55. Run: func(_ *cobra.Command, _ []string) {
  56. logger.DisableLogger()
  57. logger.EnableConsoleLogger(zerolog.DebugLevel)
  58. configDir = util.CleanDirInput(configDir)
  59. err := config.LoadConfig(configDir, configFile)
  60. if err != nil {
  61. logger.WarnToConsole("Unable to load configuration: %v", err)
  62. os.Exit(1)
  63. }
  64. httpConfig := config.GetHTTPConfig()
  65. err = httpConfig.Initialize(configDir)
  66. if err != nil {
  67. logger.ErrorToConsole("error initializing http client: %v", err)
  68. os.Exit(1)
  69. }
  70. telemetryConfig := config.GetTelemetryConfig()
  71. var url string
  72. if telemetryConfig.BindPort > 0 {
  73. if telemetryConfig.CertificateFile != "" && telemetryConfig.CertificateKeyFile != "" {
  74. url += "https://"
  75. } else {
  76. url += "http://"
  77. }
  78. if telemetryConfig.BindAddress == "" {
  79. url += "127.0.0.1"
  80. } else {
  81. url += telemetryConfig.BindAddress
  82. }
  83. url += fmt.Sprintf(":%d", telemetryConfig.BindPort)
  84. url += "/healthz"
  85. }
  86. if url == "" {
  87. httpdConfig := config.GetHTTPDConfig()
  88. url = getHealthzURLFromBindings(httpdConfig.Bindings)
  89. }
  90. if url == "" {
  91. logger.ErrorToConsole("no suitable configuration found, please enable the telemetry server or REST API over HTTP/S")
  92. os.Exit(1)
  93. }
  94. logger.DebugToConsole("Health Check URL %q", url)
  95. resp, err := httpclient.RetryableGet(url)
  96. if err != nil {
  97. logger.ErrorToConsole("Unable to connect to SFTPGo: %v", err)
  98. os.Exit(1)
  99. }
  100. defer resp.Body.Close()
  101. if resp.StatusCode != http.StatusOK {
  102. logger.ErrorToConsole("Unexpected status code %d", resp.StatusCode)
  103. os.Exit(1)
  104. }
  105. logger.InfoToConsole("OK")
  106. },
  107. }
  108. )
  109. func init() {
  110. addConfigFlags(pingCmd)
  111. rootCmd.AddCommand(pingCmd)
  112. }