Sfoglia il codice sorgente

Better config test (#177)

* Better config test

Previously, when using the config test option `-test`, we quit fairly
earlier in the process and would not catch a variety of additional
parsing errors (such as lighthouse IP addresses, local_range, the new
check to make sure static hosts are in the certificate's subnet, etc).

* run config test as part of smoke test

* don't need privileges for configtest

Co-authored-by: Nathan Brown <[email protected]>
Wade Simmons 5 anni fa
parent
commit
7cdbb14a18
3 ha cambiato i file con 60 aggiunte e 42 eliminazioni
  1. 4 0
      .github/workflows/smoke/smoke.sh
  2. 41 31
      main.go
  3. 15 11
      stats.go

+ 4 - 0
.github/workflows/smoke/smoke.sh

@@ -2,6 +2,10 @@
 
 
 set -e -x
 set -e -x
 
 
+docker run --name lighthouse1 --rm nebula:smoke -config lighthouse1.yml -test
+docker run --name host2 --rm nebula:smoke -config host2.yml -test
+docker run --name host3 --rm nebula:smoke -config host3.yml -test
+
 docker run --name lighthouse1 --device /dev/net/tun:/dev/net/tun --cap-add NET_ADMIN --rm nebula:smoke -config lighthouse1.yml &
 docker run --name lighthouse1 --device /dev/net/tun:/dev/net/tun --cap-add NET_ADMIN --rm nebula:smoke -config lighthouse1.yml &
 sleep 1
 sleep 1
 docker run --name host2 --device /dev/net/tun:/dev/net/tun --cap-add NET_ADMIN --rm nebula:smoke -config host2.yml &
 docker run --name host2 --device /dev/net/tun:/dev/net/tun --cap-add NET_ADMIN --rm nebula:smoke -config host2.yml &

+ 41 - 31
main.go

@@ -101,32 +101,35 @@ func Main(configPath string, configTest bool, buildVersion string) {
 	// tun config, listeners, anything modifying the computer should be below
 	// tun config, listeners, anything modifying the computer should be below
 	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-	if configTest {
-		os.Exit(0)
-	}
-
-	config.CatchHUP()
-
-	// set up our tun dev
-	tun, err := newTun(
-		config.GetString("tun.dev", ""),
-		tunCidr,
-		config.GetInt("tun.mtu", DEFAULT_MTU),
-		routes,
-		unsafeRoutes,
-		config.GetInt("tun.tx_queue", 500),
-	)
-	if err != nil {
-		l.WithError(err).Fatal("Failed to get a tun/tap device")
+	var tun *Tun
+	if !configTest {
+		config.CatchHUP()
+
+		// set up our tun dev
+		tun, err = newTun(
+			config.GetString("tun.dev", ""),
+			tunCidr,
+			config.GetInt("tun.mtu", DEFAULT_MTU),
+			routes,
+			unsafeRoutes,
+			config.GetInt("tun.tx_queue", 500),
+		)
+		if err != nil {
+			l.WithError(err).Fatal("Failed to get a tun/tap device")
+		}
 	}
 	}
 
 
 	// set up our UDP listener
 	// set up our UDP listener
 	udpQueues := config.GetInt("listen.routines", 1)
 	udpQueues := config.GetInt("listen.routines", 1)
-	udpServer, err := NewListener(config.GetString("listen.host", "0.0.0.0"), config.GetInt("listen.port", 0), udpQueues > 1)
-	if err != nil {
-		l.WithError(err).Fatal("Failed to open udp listener")
+	var udpServer *udpConn
+
+	if !configTest {
+		udpServer, err = NewListener(config.GetString("listen.host", "0.0.0.0"), config.GetInt("listen.port", 0), udpQueues > 1)
+		if err != nil {
+			l.WithError(err).Fatal("Failed to open udp listener")
+		}
+		udpServer.reloadConfig(config)
 	}
 	}
-	udpServer.reloadConfig(config)
 
 
 	// Set up my internal host map
 	// Set up my internal host map
 	var preferredRanges []*net.IPNet
 	var preferredRanges []*net.IPNet
@@ -178,14 +181,14 @@ func Main(configPath string, configTest bool, buildVersion string) {
 	*/
 	*/
 
 
 	punchy := NewPunchyFromConfig(config)
 	punchy := NewPunchyFromConfig(config)
-	if punchy.Punch {
+	if punchy.Punch && !configTest {
 		l.Info("UDP hole punching enabled")
 		l.Info("UDP hole punching enabled")
 		go hostMap.Punchy(udpServer)
 		go hostMap.Punchy(udpServer)
 	}
 	}
 
 
 	port := config.GetInt("listen.port", 0)
 	port := config.GetInt("listen.port", 0)
 	// If port is dynamic, discover it
 	// If port is dynamic, discover it
-	if port == 0 {
+	if port == 0 && !configTest {
 		uPort, err := udpServer.LocalAddr()
 		uPort, err := udpServer.LocalAddr()
 		if err != nil {
 		if err != nil {
 			l.WithError(err).Fatal("Failed to get listening port")
 			l.WithError(err).Fatal("Failed to get listening port")
@@ -306,21 +309,28 @@ func Main(configPath string, configTest bool, buildVersion string) {
 		l.Fatalf("Unknown cipher: %v", ifConfig.Cipher)
 		l.Fatalf("Unknown cipher: %v", ifConfig.Cipher)
 	}
 	}
 
 
-	ifce, err := NewInterface(ifConfig)
-	if err != nil {
-		l.WithError(err).Fatal("Failed to initialize interface")
-	}
+	var ifce *Interface
+	if !configTest {
+		ifce, err = NewInterface(ifConfig)
+		if err != nil {
+			l.WithError(err).Fatal("Failed to initialize interface")
+		}
 
 
-	ifce.RegisterConfigChangeCallbacks(config)
+		ifce.RegisterConfigChangeCallbacks(config)
 
 
-	go handshakeManager.Run(ifce)
-	go lightHouse.LhUpdateWorker(ifce)
+		go handshakeManager.Run(ifce)
+		go lightHouse.LhUpdateWorker(ifce)
+	}
 
 
-	err = startStats(config)
+	err = startStats(config, configTest)
 	if err != nil {
 	if err != nil {
 		l.WithError(err).Fatal("Failed to start stats emitter")
 		l.WithError(err).Fatal("Failed to start stats emitter")
 	}
 	}
 
 
+	if configTest {
+		os.Exit(0)
+	}
+
 	//TODO: check if we _should_ be emitting stats
 	//TODO: check if we _should_ be emitting stats
 	go ifce.emitStats(config.GetDuration("stats.interval", time.Second*10))
 	go ifce.emitStats(config.GetDuration("stats.interval", time.Second*10))
 
 

+ 15 - 11
stats.go

@@ -14,7 +14,7 @@ import (
 	"time"
 	"time"
 )
 )
 
 
-func startStats(c *Config) error {
+func startStats(c *Config, configTest bool) error {
 	mType := c.GetString("stats.type", "")
 	mType := c.GetString("stats.type", "")
 	if mType == "" || mType == "none" {
 	if mType == "" || mType == "none" {
 		return nil
 		return nil
@@ -27,9 +27,9 @@ func startStats(c *Config) error {
 
 
 	switch mType {
 	switch mType {
 	case "graphite":
 	case "graphite":
-		startGraphiteStats(interval, c)
+		startGraphiteStats(interval, c, configTest)
 	case "prometheus":
 	case "prometheus":
-		startPrometheusStats(interval, c)
+		startPrometheusStats(interval, c, configTest)
 	default:
 	default:
 		return fmt.Errorf("stats.type was not understood: %s", mType)
 		return fmt.Errorf("stats.type was not understood: %s", mType)
 	}
 	}
@@ -43,7 +43,7 @@ func startStats(c *Config) error {
 	return nil
 	return nil
 }
 }
 
 
-func startGraphiteStats(i time.Duration, c *Config) error {
+func startGraphiteStats(i time.Duration, c *Config, configTest bool) error {
 	proto := c.GetString("stats.protocol", "tcp")
 	proto := c.GetString("stats.protocol", "tcp")
 	host := c.GetString("stats.host", "")
 	host := c.GetString("stats.host", "")
 	if host == "" {
 	if host == "" {
@@ -57,11 +57,13 @@ func startGraphiteStats(i time.Duration, c *Config) error {
 	}
 	}
 
 
 	l.Infof("Starting graphite. Interval: %s, prefix: %s, addr: %s", i, prefix, addr)
 	l.Infof("Starting graphite. Interval: %s, prefix: %s, addr: %s", i, prefix, addr)
-	go graphite.Graphite(metrics.DefaultRegistry, i, prefix, addr)
+	if !configTest {
+		go graphite.Graphite(metrics.DefaultRegistry, i, prefix, addr)
+	}
 	return nil
 	return nil
 }
 }
 
 
-func startPrometheusStats(i time.Duration, c *Config) error {
+func startPrometheusStats(i time.Duration, c *Config, configTest bool) error {
 	namespace := c.GetString("stats.namespace", "")
 	namespace := c.GetString("stats.namespace", "")
 	subsystem := c.GetString("stats.subsystem", "")
 	subsystem := c.GetString("stats.subsystem", "")
 
 
@@ -79,11 +81,13 @@ func startPrometheusStats(i time.Duration, c *Config) error {
 	pClient := mp.NewPrometheusProvider(metrics.DefaultRegistry, namespace, subsystem, pr, i)
 	pClient := mp.NewPrometheusProvider(metrics.DefaultRegistry, namespace, subsystem, pr, i)
 	go pClient.UpdatePrometheusMetrics()
 	go pClient.UpdatePrometheusMetrics()
 
 
-	go func() {
-		l.Infof("Prometheus stats listening on %s at %s", listen, path)
-		http.Handle(path, promhttp.HandlerFor(pr, promhttp.HandlerOpts{ErrorLog: l}))
-		log.Fatal(http.ListenAndServe(listen, nil))
-	}()
+	if !configTest {
+		go func() {
+			l.Infof("Prometheus stats listening on %s at %s", listen, path)
+			http.Handle(path, promhttp.HandlerFor(pr, promhttp.HandlerOpts{ErrorLog: l}))
+			log.Fatal(http.ListenAndServe(listen, nil))
+		}()
+	}
 
 
 	return nil
 	return nil
 }
 }