mirror of
https://github.com/TwiN/gatus.git
synced 2025-02-13 00:40:17 +01:00
Merge pull request #43 from mindcrime-ilab/develop
add parameterization for host and port
This commit is contained in:
commit
07312794c4
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
bin
|
bin
|
||||||
.idea
|
.idea
|
||||||
|
.vscode
|
||||||
|
@ -137,6 +137,8 @@ Note that you can also add environment variables in the configuration file (i.e.
|
|||||||
| `security.basic.username` | Username for Basic authentication | Required `""` |
|
| `security.basic.username` | Username for Basic authentication | Required `""` |
|
||||||
| `security.basic.password-sha512` | Password's SHA512 hash for Basic authentication | Required `""` |
|
| `security.basic.password-sha512` | Password's SHA512 hash for Basic authentication | Required `""` |
|
||||||
| `disable-monitoring-lock` | Whether to [disable the monitoring lock](#disable-monitoring-lock) | `false` |
|
| `disable-monitoring-lock` | Whether to [disable the monitoring lock](#disable-monitoring-lock) | `false` |
|
||||||
|
| `web.address` | Address to listen on | `0.0.0.0` |
|
||||||
|
| `web.port` | Port to listen on | `8080` |
|
||||||
|
|
||||||
For Kubernetes configuration, see [Kubernetes](#kubernetes-alpha)
|
For Kubernetes configuration, see [Kubernetes](#kubernetes-alpha)
|
||||||
|
|
||||||
|
@ -2,8 +2,10 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"math"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/TwinProduction/gatus/alerting"
|
"github.com/TwinProduction/gatus/alerting"
|
||||||
@ -22,6 +24,12 @@ const (
|
|||||||
// DefaultFallbackConfigurationFilePath is the default fallback path that will be used to search for the
|
// DefaultFallbackConfigurationFilePath is the default fallback path that will be used to search for the
|
||||||
// configuration file if DefaultConfigurationFilePath didn't work
|
// configuration file if DefaultConfigurationFilePath didn't work
|
||||||
DefaultFallbackConfigurationFilePath = "config/config.yml"
|
DefaultFallbackConfigurationFilePath = "config/config.yml"
|
||||||
|
|
||||||
|
// DefaultAddress is the default address the service will bind to
|
||||||
|
DefaultAddress = "0.0.0.0"
|
||||||
|
|
||||||
|
// DefaultPort is the default port the service will listen on
|
||||||
|
DefaultPort = 8080
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -64,6 +72,9 @@ type Config struct {
|
|||||||
|
|
||||||
// Kubernetes is the Kubernetes configuration
|
// Kubernetes is the Kubernetes configuration
|
||||||
Kubernetes *k8s.Config `yaml:"kubernetes"`
|
Kubernetes *k8s.Config `yaml:"kubernetes"`
|
||||||
|
|
||||||
|
// webConfig is the optional configuration of the web listener providing the frontend UI
|
||||||
|
Web *webConfig `yaml:"web"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the configuration, or panics if the configuration hasn't loaded yet
|
// Get returns the configuration, or panics if the configuration hasn't loaded yet
|
||||||
@ -127,10 +138,20 @@ func parseAndValidateConfigBytes(yamlBytes []byte) (config *Config, err error) {
|
|||||||
validateSecurityConfig(config)
|
validateSecurityConfig(config)
|
||||||
validateServicesConfig(config)
|
validateServicesConfig(config)
|
||||||
validateKubernetesConfig(config)
|
validateKubernetesConfig(config)
|
||||||
|
validateAddressAndPortConfig(config)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateAddressAndPortConfig(config *Config) {
|
||||||
|
if config.Web == nil {
|
||||||
|
config.Web = &webConfig{Address: DefaultAddress, Port: DefaultPort}
|
||||||
|
} else {
|
||||||
|
config.Web.validateAndSetDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func validateKubernetesConfig(config *Config) {
|
func validateKubernetesConfig(config *Config) {
|
||||||
if config.Kubernetes != nil && config.Kubernetes.AutoDiscover {
|
if config.Kubernetes != nil && config.Kubernetes.AutoDiscover {
|
||||||
if config.Kubernetes.ServiceTemplate == nil {
|
if config.Kubernetes.ServiceTemplate == nil {
|
||||||
@ -237,3 +258,27 @@ func GetAlertingProviderByAlertType(config *Config, alertType core.AlertType) pr
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// webConfig is the structure which supports the configuration of the endpoint
|
||||||
|
// which provides access to the web frontend
|
||||||
|
type webConfig struct {
|
||||||
|
// Address to listen on (defaults to 0.0.0.0 specified by DefaultAddress)
|
||||||
|
Address string `yaml:"address"`
|
||||||
|
|
||||||
|
// Port to listen on (default to 8080 specified by DefaultPort)
|
||||||
|
Port int `yaml:"port"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateAndSetDefaults checks and sets missing values based on the defaults
|
||||||
|
// in given in DefaultAddress and DefaultPort if necessary
|
||||||
|
func (web *webConfig) validateAndSetDefaults() {
|
||||||
|
if len(web.Address) == 0 {
|
||||||
|
web.Address = DefaultAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
if web.Port == 0 {
|
||||||
|
web.Port = DefaultPort
|
||||||
|
} else if web.Port < 0 || web.Port > math.MaxUint16 {
|
||||||
|
panic(fmt.Sprintf("port has an invalid value %d shoud be between %d - %d\r\n", web.Port, 0, math.MaxUint16))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -103,6 +103,137 @@ services:
|
|||||||
if config.Services[0].Interval != 60*time.Second {
|
if config.Services[0].Interval != 60*time.Second {
|
||||||
t.Errorf("Interval should have been %s, because it is the default value", 60*time.Second)
|
t.Errorf("Interval should have been %s, because it is the default value", 60*time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.Web.Address != DefaultAddress {
|
||||||
|
t.Errorf("Bind address should have been %s, because it is the default value", DefaultAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Web.Port != DefaultPort {
|
||||||
|
t.Errorf("Port should have been %d, because it is the default value", DefaultPort)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseAndValidateConfigBytesWithAddress(t *testing.T) {
|
||||||
|
config, err := parseAndValidateConfigBytes([]byte(`
|
||||||
|
web:
|
||||||
|
address: 127.0.0.1
|
||||||
|
services:
|
||||||
|
- name: twinnation
|
||||||
|
url: https://twinnation.org/actuator/health
|
||||||
|
conditions:
|
||||||
|
- "[STATUS] == 200"
|
||||||
|
`))
|
||||||
|
if err != nil {
|
||||||
|
t.Error("No error should've been returned")
|
||||||
|
}
|
||||||
|
if config == nil {
|
||||||
|
t.Fatal("Config shouldn't have been nil")
|
||||||
|
}
|
||||||
|
if config.Metrics {
|
||||||
|
t.Error("Metrics should've been false by default")
|
||||||
|
}
|
||||||
|
if config.Services[0].URL != "https://twinnation.org/actuator/health" {
|
||||||
|
t.Errorf("URL should have been %s", "https://twinnation.org/actuator/health")
|
||||||
|
}
|
||||||
|
if config.Services[0].Interval != 60*time.Second {
|
||||||
|
t.Errorf("Interval should have been %s, because it is the default value", 60*time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Web.Address != "127.0.0.1" {
|
||||||
|
t.Errorf("Bind address should have been %s, because it is specified in config", "127.0.0.1")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Web.Port != DefaultPort {
|
||||||
|
t.Errorf("Port should have been %d, because it is the default value", DefaultPort)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseAndValidateConfigBytesWithPort(t *testing.T) {
|
||||||
|
config, err := parseAndValidateConfigBytes([]byte(`
|
||||||
|
web:
|
||||||
|
port: 12345
|
||||||
|
services:
|
||||||
|
- name: twinnation
|
||||||
|
url: https://twinnation.org/actuator/health
|
||||||
|
conditions:
|
||||||
|
- "[STATUS] == 200"
|
||||||
|
`))
|
||||||
|
if err != nil {
|
||||||
|
t.Error("No error should've been returned")
|
||||||
|
}
|
||||||
|
if config == nil {
|
||||||
|
t.Fatal("Config shouldn't have been nil")
|
||||||
|
}
|
||||||
|
if config.Metrics {
|
||||||
|
t.Error("Metrics should've been false by default")
|
||||||
|
}
|
||||||
|
if config.Services[0].URL != "https://twinnation.org/actuator/health" {
|
||||||
|
t.Errorf("URL should have been %s", "https://twinnation.org/actuator/health")
|
||||||
|
}
|
||||||
|
if config.Services[0].Interval != 60*time.Second {
|
||||||
|
t.Errorf("Interval should have been %s, because it is the default value", 60*time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Web.Address != DefaultAddress {
|
||||||
|
t.Errorf("Bind address should have been %s, because it is the default value", DefaultAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Web.Port != 12345 {
|
||||||
|
t.Errorf("Port should have been %d, because it is specified in config", 12345)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseAndValidateConfigBytesWithPortAndHost(t *testing.T) {
|
||||||
|
config, err := parseAndValidateConfigBytes([]byte(`
|
||||||
|
web:
|
||||||
|
port: 12345
|
||||||
|
address: 127.0.0.1
|
||||||
|
services:
|
||||||
|
- name: twinnation
|
||||||
|
url: https://twinnation.org/actuator/health
|
||||||
|
conditions:
|
||||||
|
- "[STATUS] == 200"
|
||||||
|
`))
|
||||||
|
if err != nil {
|
||||||
|
t.Error("No error should've been returned")
|
||||||
|
}
|
||||||
|
if config == nil {
|
||||||
|
t.Fatal("Config shouldn't have been nil")
|
||||||
|
}
|
||||||
|
if config.Metrics {
|
||||||
|
t.Error("Metrics should've been false by default")
|
||||||
|
}
|
||||||
|
if config.Services[0].URL != "https://twinnation.org/actuator/health" {
|
||||||
|
t.Errorf("URL should have been %s", "https://twinnation.org/actuator/health")
|
||||||
|
}
|
||||||
|
if config.Services[0].Interval != 60*time.Second {
|
||||||
|
t.Errorf("Interval should have been %s, because it is the default value", 60*time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Web.Address != "127.0.0.1" {
|
||||||
|
t.Errorf("Bind address should have been %s, because it is specified in config", "127.0.0.1")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Web.Port != 12345 {
|
||||||
|
t.Errorf("Port should have been %d, because it is specified in config", 12345)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseAndValidateConfigBytesWithInvalidPort(t *testing.T) {
|
||||||
|
defer func() { recover() }()
|
||||||
|
|
||||||
|
parseAndValidateConfigBytes([]byte(`
|
||||||
|
web:
|
||||||
|
port: 65536
|
||||||
|
address: 127.0.0.1
|
||||||
|
services:
|
||||||
|
- name: twinnation
|
||||||
|
url: https://twinnation.org/actuator/health
|
||||||
|
conditions:
|
||||||
|
- "[STATUS] == 200"
|
||||||
|
`))
|
||||||
|
|
||||||
|
t.Fatal("Should've panicked because the configuration specifies an invalid port value")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseAndValidateConfigBytesWithMetrics(t *testing.T) {
|
func TestParseAndValidateConfigBytesWithMetrics(t *testing.T) {
|
||||||
@ -129,6 +260,51 @@ services:
|
|||||||
if config.Services[0].Interval != 60*time.Second {
|
if config.Services[0].Interval != 60*time.Second {
|
||||||
t.Errorf("Interval should have been %s, because it is the default value", 60*time.Second)
|
t.Errorf("Interval should have been %s, because it is the default value", 60*time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.Web.Address != DefaultAddress {
|
||||||
|
t.Errorf("Bind address should have been %s, because it is the default value", DefaultAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Web.Port != DefaultPort {
|
||||||
|
t.Errorf("Port should have been %d, because it is the default value", DefaultPort)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseAndValidateConfigBytesWithMetricsAndHostAndPort(t *testing.T) {
|
||||||
|
config, err := parseAndValidateConfigBytes([]byte(`
|
||||||
|
metrics: true
|
||||||
|
services:
|
||||||
|
- name: twinnation
|
||||||
|
url: https://twinnation.org/actuator/health
|
||||||
|
conditions:
|
||||||
|
- "[STATUS] == 200"
|
||||||
|
web:
|
||||||
|
address: 192.168.0.1
|
||||||
|
port: 9090
|
||||||
|
`))
|
||||||
|
if err != nil {
|
||||||
|
t.Error("No error should've been returned")
|
||||||
|
}
|
||||||
|
if config == nil {
|
||||||
|
t.Fatal("Config shouldn't have been nil")
|
||||||
|
}
|
||||||
|
if !config.Metrics {
|
||||||
|
t.Error("Metrics should have been true")
|
||||||
|
}
|
||||||
|
if config.Services[0].URL != "https://twinnation.org/actuator/health" {
|
||||||
|
t.Errorf("URL should have been %s", "https://twinnation.org/actuator/health")
|
||||||
|
}
|
||||||
|
if config.Services[0].Interval != 60*time.Second {
|
||||||
|
t.Errorf("Interval should have been %s, because it is the default value", 60*time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Web.Address != "192.168.0.1" {
|
||||||
|
t.Errorf("Bind address should have been %s, because it is the default value", "192.168.0.1")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Web.Port != 9090 {
|
||||||
|
t.Errorf("Port should have been %d, because it is specified in config", 9090)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseAndValidateBadConfigBytes(t *testing.T) {
|
func TestParseAndValidateBadConfigBytes(t *testing.T) {
|
||||||
|
6
main.go
6
main.go
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -35,9 +36,10 @@ func main() {
|
|||||||
if cfg.Metrics {
|
if cfg.Metrics {
|
||||||
http.Handle("/metrics", promhttp.Handler())
|
http.Handle("/metrics", promhttp.Handler())
|
||||||
}
|
}
|
||||||
log.Println("[main][main] Listening on port 8080")
|
|
||||||
|
log.Printf("[main][main] Listening on %s:%d\r\n", cfg.Web.Address, cfg.Web.Port)
|
||||||
go watchdog.Monitor(cfg)
|
go watchdog.Monitor(cfg)
|
||||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%d", cfg.Web.Address, cfg.Web.Port), nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadConfiguration() *config.Config {
|
func loadConfiguration() *config.Config {
|
||||||
|
Loading…
Reference in New Issue
Block a user