diff --git a/.gitignore b/.gitignore
index 2a03df9f..783e3c1d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,5 @@ test_output/
# Nix build output
result
.direnv/
+
+integration_test/etc/config.dump.yaml
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eba5d4aa..ccd4f715 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -29,6 +29,7 @@
- Use new ACL syntax [#618](https://github.com/juanfont/headscale/pull/618)
- Add -c option to specify config file from command line [#285](https://github.com/juanfont/headscale/issues/285) [#612](https://github.com/juanfont/headscale/pull/601)
- Add configuration option to allow Tailscale clients to use a random WireGuard port. [kb/1181/firewalls](https://tailscale.com/kb/1181/firewalls) [#624](https://github.com/juanfont/headscale/pull/624)
+- Improve obtuse UX regarding missing configuration (`ephemeral_node_inactivity_timeout` not set) [#639](https://github.com/juanfont/headscale/pull/639)
- Fix nodes being shown as 'offline' in `tailscale status` [648](https://github.com/juanfont/headscale/pull/648)
## 0.15.0 (2022-03-20)
diff --git a/Makefile b/Makefile
index 3327fe66..404c3c01 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
# Calculate version
-version = $(git describe --always --tags --dirty)
+version ?= $(shell git describe --always --tags --dirty)
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
diff --git a/README.md b/README.md
index b3ade6ff..714a8053 100644
--- a/README.md
+++ b/README.md
@@ -195,6 +195,15 @@ make build
Nico
+
diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go
index f5c679c2..327c8c14 100644
--- a/cmd/headscale/cli/utils.go
+++ b/cmd/headscale/cli/utils.go
@@ -7,12 +7,10 @@ import (
"fmt"
"os"
"reflect"
- "time"
"github.com/juanfont/headscale"
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
"github.com/rs/zerolog/log"
- "github.com/spf13/viper"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
@@ -29,21 +27,6 @@ func getHeadscaleApp() (*headscale.Headscale, error) {
return nil, fmt.Errorf("failed to load configuration while creating headscale instance: %w", err)
}
- // Minimum inactivity time out is keepalive timeout (60s) plus a few seconds
- // to avoid races
- minInactivityTimeout, _ := time.ParseDuration("65s")
- if viper.GetDuration("ephemeral_node_inactivity_timeout") <= minInactivityTimeout {
- // TODO: Find a better way to return this text
- //nolint
- err := fmt.Errorf(
- "ephemeral_node_inactivity_timeout (%s) is set too low, must be more than %s",
- viper.GetString("ephemeral_node_inactivity_timeout"),
- minInactivityTimeout,
- )
-
- return nil, err
- }
-
app, err := headscale.NewHeadscale(cfg)
if err != nil {
return nil, err
diff --git a/config.go b/config.go
index 917b4734..9e71a750 100644
--- a/config.go
+++ b/config.go
@@ -160,7 +160,11 @@ func LoadConfig(path string, isFile bool) error {
viper.SetDefault("logtail.enabled", false)
viper.SetDefault("randomize_client_port", false)
+ viper.SetDefault("ephemeral_node_inactivity_timeout", "120s")
+
if err := viper.ReadInConfig(); err != nil {
+ log.Warn().Err(err).Msg("Failed to read configuration from disk")
+
return fmt.Errorf("fatal error reading config file: %w", err)
}
@@ -202,6 +206,17 @@ func LoadConfig(path string, isFile bool) error {
EnforcedClientAuth)
}
+ // Minimum inactivity time out is keepalive timeout (60s) plus a few seconds
+ // to avoid races
+ minInactivityTimeout, _ := time.ParseDuration("65s")
+ if viper.GetDuration("ephemeral_node_inactivity_timeout") <= minInactivityTimeout {
+ errorText += fmt.Sprintf(
+ "Fatal config error: ephemeral_node_inactivity_timeout (%s) is set too low, must be more than %s",
+ viper.GetString("ephemeral_node_inactivity_timeout"),
+ minInactivityTimeout,
+ )
+ }
+
if errorText != "" {
//nolint
return errors.New(strings.TrimSuffix(errorText, "\n"))
diff --git a/derp.go b/derp.go
index 7abce683..293cf81a 100644
--- a/derp.go
+++ b/derp.go
@@ -152,16 +152,7 @@ func (h *Headscale) scheduledDERPMapUpdateWorker(cancelChan <-chan struct{}) {
h.DERPMap.Regions[h.DERPServer.region.RegionID] = &h.DERPServer.region
}
- namespaces, err := h.ListNamespaces()
- if err != nil {
- log.Error().
- Err(err).
- Msg("Failed to fetch namespaces")
- }
-
- for _, namespace := range namespaces {
- h.setLastStateChangeToNow(namespace.Name)
- }
+ h.setLastStateChangeToNow()
}
}
}
diff --git a/utils.go b/utils.go
index 8d9dec5b..fd4cda86 100644
--- a/utils.go
+++ b/utils.go
@@ -325,11 +325,17 @@ func GenerateRandomStringURLSafe(n int) (string, error) {
// number generator fails to function correctly, in which
// case the caller should not continue.
func GenerateRandomStringDNSSafe(n int) (string, error) {
- str, err := GenerateRandomStringURLSafe(n)
+ var str string
+ var err error
+ for len(str) < n {
+ str, err = GenerateRandomStringURLSafe(n)
+ if err != nil {
+ return "", err
+ }
+ str = strings.ToLower(strings.ReplaceAll(strings.ReplaceAll(str, "_", ""), "-", ""))
+ }
- str = strings.ToLower(strings.ReplaceAll(strings.ReplaceAll(str, "_", ""), "-", ""))
-
- return str[:n], err
+ return str[:n], nil
}
func IsStringInSlice(slice []string, str string) bool {
diff --git a/utils_test.go b/utils_test.go
index ff85ac8a..07fa62d8 100644
--- a/utils_test.go
+++ b/utils_test.go
@@ -34,7 +34,7 @@ func (s *Suite) TestGetUsedIps(c *check.C) {
MachineKey: "foo",
NodeKey: "bar",
DiscoKey: "faa",
- Hostname: "testmachine",
+ Hostname: "testmachine",
NamespaceID: namespace.ID,
RegisterMethod: RegisterMethodAuthKey,
AuthKeyID: uint(pak.ID),
@@ -82,7 +82,7 @@ func (s *Suite) TestGetMultiIp(c *check.C) {
MachineKey: "foo",
NodeKey: "bar",
DiscoKey: "faa",
- Hostname: "testmachine",
+ Hostname: "testmachine",
NamespaceID: namespace.ID,
RegisterMethod: RegisterMethodAuthKey,
AuthKeyID: uint(pak.ID),
@@ -172,7 +172,7 @@ func (s *Suite) TestGetAvailableIpMachineWithoutIP(c *check.C) {
MachineKey: "foo",
NodeKey: "bar",
DiscoKey: "faa",
- Hostname: "testmachine",
+ Hostname: "testmachine",
NamespaceID: namespace.ID,
RegisterMethod: RegisterMethodAuthKey,
AuthKeyID: uint(pak.ID),
@@ -185,3 +185,15 @@ func (s *Suite) TestGetAvailableIpMachineWithoutIP(c *check.C) {
c.Assert(len(ips2), check.Equals, 1)
c.Assert(ips2[0].String(), check.Equals, expected.String())
}
+
+func (s *Suite) TestGenerateRandomStringDNSSafe(c *check.C) {
+ for i := 0; i < 100000; i++ {
+ str, err := GenerateRandomStringDNSSafe(8)
+ if err != nil {
+ c.Error(err)
+ }
+ if len(str) != 8 {
+ c.Error("invalid length", len(str), str)
+ }
+ }
+}
|