From 5dd32acc6aac1dd5e729ff7d2691828c18df8aef Mon Sep 17 00:00:00 2001 From: Deon Thomas Date: Sun, 8 May 2022 23:29:00 -0400 Subject: [PATCH] Use env variable TZ to set timezone, fallback to UTC --- api.go | 9 ++++++--- app.go | 7 +++++-- cmd/headscale/cli/api_key.go | 4 +++- cmd/headscale/cli/nodes.go | 4 +++- cmd/headscale/cli/preauthkeys.go | 4 +++- cmd/headscale/headscale.go | 14 +++++++++++++- machine.go | 4 +++- poll.go | 17 ++++++++++++----- preauth_keys.go | 4 +++- 9 files changed, 51 insertions(+), 16 deletions(-) diff --git a/api.go b/api.go index 61ec1b5f..f88fa480 100644 --- a/api.go +++ b/api.go @@ -15,6 +15,7 @@ import ( "github.com/gin-gonic/gin" "github.com/klauspost/compress/zstd" "github.com/rs/zerolog/log" + "github.com/spf13/viper" "gorm.io/gorm" "tailscale.com/tailcfg" "tailscale.com/types/key" @@ -120,7 +121,8 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { return } - now := time.Now().UTC() + location, _ := time.LoadLocation(viper.GetString("TZ")) + now := time.Now().In(location) machine, err := h.GetMachineByMachineKey(machineKey) if errors.Is(err, gorm.ErrRecordNotFound) { log.Info().Str("machine", req.Hostinfo.Hostname).Msg("New machine") @@ -189,7 +191,7 @@ func (h *Headscale) RegistrationHandler(ctx *gin.Context) { if machine.NodeKey == NodePublicKeyStripPrefix(req.NodeKey) { // The client sends an Expiry in the past if the client is requesting to expire the key (aka logout) // https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648 - if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { + if !req.Expiry.IsZero() && req.Expiry.In(location).Before(now) { h.handleMachineLogOut(ctx, machineKey, *machine) return @@ -601,7 +603,8 @@ func (h *Headscale) handleAuthKey( machine.AuthKeyID = uint(pak.ID) h.RefreshMachine(machine, registerRequest.Expiry) } else { - now := time.Now().UTC() + location, _ := time.LoadLocation(viper.GetString("TZ")) + now := time.Now().In(location) machineToRegister := Machine{ Name: registerRequest.Hostinfo.Hostname, NamespaceID: pak.Namespace.ID, diff --git a/app.go b/app.go index a96ab83a..687b80eb 100644 --- a/app.go +++ b/app.go @@ -27,6 +27,7 @@ import ( zerolog "github.com/philip-bui/grpc-zerolog" zl "github.com/rs/zerolog" "github.com/rs/zerolog/log" + "github.com/spf13/viper" ginprometheus "github.com/zsais/go-gin-prometheus" "golang.org/x/crypto/acme" "golang.org/x/crypto/acme/autocert" @@ -791,7 +792,8 @@ func (h *Headscale) getTLSSettings() (*tls.Config, error) { } func (h *Headscale) setLastStateChangeToNow(namespace string) { - now := time.Now().UTC() + location, _ := time.LoadLocation(viper.GetString("TZ")) + now := time.Now().In(location) lastStateUpdate.WithLabelValues("", "headscale").Set(float64(now.Unix())) h.lastStateChange.Store(namespace, now) } @@ -814,7 +816,8 @@ func (h *Headscale) getLastStateChange(namespaces ...string) time.Time { log.Trace().Msgf("Latest times %#v", times) if len(times) == 0 { - return time.Now().UTC() + location, _ := time.LoadLocation(viper.GetString("TZ")) + return time.Now().In(location) } else { return times[0] } diff --git a/cmd/headscale/cli/api_key.go b/cmd/headscale/cli/api_key.go index aa056c54..aea16b61 100644 --- a/cmd/headscale/cli/api_key.go +++ b/cmd/headscale/cli/api_key.go @@ -10,6 +10,7 @@ import ( "github.com/pterm/pterm" "github.com/rs/zerolog/log" "github.com/spf13/cobra" + "github.com/spf13/viper" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -119,7 +120,8 @@ If you loose a key, create a new one and revoke (expire) the old one.`, request := &v1.CreateApiKeyRequest{} duration, _ := cmd.Flags().GetDuration("expiration") - expiration := time.Now().UTC().Add(duration) + location, _ := time.LoadLocation(viper.GetString("TZ")) + expiration := time.Now().In(location).Add(duration) log.Trace().Dur("expiration", duration).Msg("expiration has been set") diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 9159b32b..726b67cd 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -12,6 +12,7 @@ import ( v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/pterm/pterm" "github.com/spf13/cobra" + "github.com/spf13/viper" "google.golang.org/grpc/status" "inet.af/netaddr" "tailscale.com/types/key" @@ -413,7 +414,8 @@ func nodesToPtables( var lastSeen time.Time var lastSeenTime string if machine.LastSeen != nil { - lastSeen = machine.LastSeen.AsTime() + location, _ := time.LoadLocation(viper.GetString("TZ")) + lastSeen = machine.LastSeen.AsTime().In(location) lastSeenTime = lastSeen.Format("2006-01-02 15:04:05") } diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go index 7efb72fb..2e9c49d3 100644 --- a/cmd/headscale/cli/preauthkeys.go +++ b/cmd/headscale/cli/preauthkeys.go @@ -9,6 +9,7 @@ import ( "github.com/pterm/pterm" "github.com/rs/zerolog/log" "github.com/spf13/cobra" + "github.com/spf13/viper" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -149,7 +150,8 @@ var createPreAuthKeyCmd = &cobra.Command{ } duration, _ := cmd.Flags().GetDuration("expiration") - expiration := time.Now().UTC().Add(duration) + location, _ := time.LoadLocation(viper.GetString("TZ")) + expiration := time.Now().In(location).Add(duration) log.Trace().Dur("expiration", duration).Msg("expiration has been set") diff --git a/cmd/headscale/headscale.go b/cmd/headscale/headscale.go index 600b186e..b7509566 100644 --- a/cmd/headscale/headscale.go +++ b/cmd/headscale/headscale.go @@ -36,7 +36,19 @@ func main() { colors = false } - zerolog.TimeFieldFormat = zerolog.TimeFormatUnix + viper.SetDefault("TZ", "UTC") + if tz := os.Getenv("TZ"); tz != "" { + _, err := time.LoadLocation(tz) + if err == nil { + viper.SetDefault("TZ", tz) + } + } + + zerolog.TimestampFunc = func() time.Time { + location, _ := time.LoadLocation(viper.GetString("TZ")) + return time.Now().In(location) + } + log.Logger = log.Output(zerolog.ConsoleWriter{ Out: os.Stdout, TimeFormat: time.RFC3339, diff --git a/machine.go b/machine.go index a637f544..360a7d77 100644 --- a/machine.go +++ b/machine.go @@ -11,6 +11,7 @@ import ( "github.com/fatih/set" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/rs/zerolog/log" + "github.com/spf13/viper" "google.golang.org/protobuf/types/known/timestamppb" "inet.af/netaddr" "tailscale.com/tailcfg" @@ -116,8 +117,9 @@ func (machine Machine) isExpired() bool { if machine.Expiry == nil || machine.Expiry.IsZero() { return false } + location, _ := time.LoadLocation(viper.GetString("TZ")) - return time.Now().UTC().After(*machine.Expiry) + return time.Now().In(location).After(*machine.Expiry) } func containsAddresses(inputs []string, addrs []string) bool { diff --git a/poll.go b/poll.go index 3bad0b89..ed538158 100644 --- a/poll.go +++ b/poll.go @@ -10,6 +10,7 @@ import ( "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" + "github.com/spf13/viper" "gorm.io/gorm" "tailscale.com/tailcfg" "tailscale.com/types/key" @@ -97,7 +98,8 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) { machine.Name = hname machine.HostInfo = HostInfo(*req.Hostinfo) machine.DiscoKey = DiscoPublicKeyStripPrefix(req.DiscoKey) - now := time.Now().UTC() + location, _ := time.LoadLocation(viper.GetString("TZ")) + now := time.Now().In(location) // update ACLRules with peer informations (to update server tags if necessary) if h.aclPolicy != nil { @@ -339,7 +341,8 @@ func (h *Headscale) PollNetMapStream( // since the stream opened, terminate connection. return false } - now := time.Now().UTC() + location, _ := time.LoadLocation(viper.GetString("TZ")) + now := time.Now().In(location) machine.LastSeen = &now lastStateUpdate.WithLabelValues(machine.Namespace.Name, machine.Name). @@ -405,7 +408,8 @@ func (h *Headscale) PollNetMapStream( // since the stream opened, terminate connection. return false } - now := time.Now().UTC() + location, _ := time.LoadLocation(viper.GetString("TZ")) + now := time.Now().In(location) machine.LastSeen = &now err = h.TouchMachine(machine) if err != nil { @@ -495,7 +499,8 @@ func (h *Headscale) PollNetMapStream( // since the stream opened, terminate connection. return false } - now := time.Now().UTC() + location, _ := time.LoadLocation(viper.GetString("TZ")) + now := time.Now().In(location) lastStateUpdate.WithLabelValues(machine.Namespace.Name, machine.Name). Set(float64(now.Unix())) @@ -546,7 +551,9 @@ func (h *Headscale) PollNetMapStream( // since the stream opened, terminate connection. return false } - now := time.Now().UTC() + + location, _ := time.LoadLocation(viper.GetString("TZ")) + now := time.Now().In(location) machine.LastSeen = &now err = h.TouchMachine(machine) if err != nil { diff --git a/preauth_keys.go b/preauth_keys.go index 55f62226..482e3b51 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -8,6 +8,7 @@ import ( "time" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" + "github.com/spf13/viper" "google.golang.org/protobuf/types/known/timestamppb" "gorm.io/gorm" ) @@ -45,7 +46,8 @@ func (h *Headscale) CreatePreAuthKey( return nil, err } - now := time.Now().UTC() + location, _ := time.LoadLocation(viper.GetString("TZ")) + now := time.Now().In(location) kstr, err := h.generateKey() if err != nil { return nil, err