diff --git a/acls.go b/acls.go
index cb02e04..0e01514 100644
--- a/acls.go
+++ b/acls.go
@@ -108,7 +108,9 @@ func (h *Headscale) generateACLPolicySrcIP(u string) ([]string, error) {
return h.expandAlias(u)
}
-func (h *Headscale) generateACLPolicyDestPorts(d string) ([]tailcfg.NetPortRange, error) {
+func (h *Headscale) generateACLPolicyDestPorts(
+ d string,
+) ([]tailcfg.NetPortRange, error) {
tokens := strings.Split(d, ":")
if len(tokens) < 2 || len(tokens) > 3 {
return nil, errorInvalidPortFormat
diff --git a/acls_test.go b/acls_test.go
index da7f3ec..c178805 100644
--- a/acls_test.go
+++ b/acls_test.go
@@ -22,7 +22,11 @@ func (s *Suite) TestInvalidPolicyHuson(c *check.C) {
func (s *Suite) TestParseHosts(c *check.C) {
var hs Hosts
- err := hs.UnmarshalJSON([]byte(`{"example-host-1": "100.100.100.100","example-host-2": "100.100.101.100/24"}`))
+ err := hs.UnmarshalJSON(
+ []byte(
+ `{"example-host-1": "100.100.100.100","example-host-2": "100.100.101.100/24"}`,
+ ),
+ )
c.Assert(hs, check.NotNil)
c.Assert(err, check.IsNil)
}
diff --git a/api.go b/api.go
index 490ce25..25851d8 100644
--- a/api.go
+++ b/api.go
@@ -95,7 +95,8 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
Str("handler", "Registration").
Err(err).
Msg("Could not create row")
- machineRegistrations.WithLabelValues("unknown", "web", "error", m.Namespace.Name).Inc()
+ machineRegistrations.WithLabelValues("unknown", "web", "error", m.Namespace.Name).
+ Inc()
return
}
m = &newMachine
@@ -156,11 +157,13 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
Str("handler", "Registration").
Err(err).
Msg("Cannot encode message")
- machineRegistrations.WithLabelValues("update", "web", "error", m.Namespace.Name).Inc()
+ machineRegistrations.WithLabelValues("update", "web", "error", m.Namespace.Name).
+ Inc()
c.String(http.StatusInternalServerError, "")
return
}
- machineRegistrations.WithLabelValues("update", "web", "success", m.Namespace.Name).Inc()
+ machineRegistrations.WithLabelValues("update", "web", "success", m.Namespace.Name).
+ Inc()
c.Data(200, "application/json; charset=utf-8", respBody)
return
}
@@ -195,11 +198,13 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
Str("handler", "Registration").
Err(err).
Msg("Cannot encode message")
- machineRegistrations.WithLabelValues("new", "web", "error", m.Namespace.Name).Inc()
+ machineRegistrations.WithLabelValues("new", "web", "error", m.Namespace.Name).
+ Inc()
c.String(http.StatusInternalServerError, "")
return
}
- machineRegistrations.WithLabelValues("new", "web", "success", m.Namespace.Name).Inc()
+ machineRegistrations.WithLabelValues("new", "web", "success", m.Namespace.Name).
+ Inc()
c.Data(200, "application/json; charset=utf-8", respBody)
return
}
@@ -234,7 +239,11 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
Str("machine", m.Name).
Msg("The node is sending us a new NodeKey, sending auth url")
if h.cfg.OIDC.Issuer != "" {
- resp.AuthURL = fmt.Sprintf("%s/oidc/register/%s", strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString())
+ resp.AuthURL = fmt.Sprintf(
+ "%s/oidc/register/%s",
+ strings.TrimSuffix(h.cfg.ServerURL, "/"),
+ mKey.HexString(),
+ )
} else {
resp.AuthURL = fmt.Sprintf("%s/register?key=%s",
strings.TrimSuffix(h.cfg.ServerURL, "/"), mKey.HexString())
@@ -257,7 +266,11 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) {
c.Data(200, "application/json; charset=utf-8", respBody)
}
-func (h *Headscale) getMapResponse(mKey wgkey.Key, req tailcfg.MapRequest, m *Machine) ([]byte, error) {
+func (h *Headscale) getMapResponse(
+ mKey wgkey.Key,
+ req tailcfg.MapRequest,
+ m *Machine,
+) ([]byte, error) {
log.Trace().
Str("func", "getMapResponse").
Str("machine", req.Hostinfo.Hostname).
@@ -291,7 +304,12 @@ func (h *Headscale) getMapResponse(mKey wgkey.Key, req tailcfg.MapRequest, m *Ma
return nil, err
}
- dnsConfig, err := getMapResponseDNSConfig(h.cfg.DNSConfig, h.cfg.BaseDomain, *m, peers)
+ dnsConfig, err := getMapResponseDNSConfig(
+ h.cfg.DNSConfig,
+ h.cfg.BaseDomain,
+ *m,
+ peers,
+ )
if err != nil {
log.Error().
Str("func", "getMapResponse").
@@ -340,7 +358,11 @@ func (h *Headscale) getMapResponse(mKey wgkey.Key, req tailcfg.MapRequest, m *Ma
return data, nil
}
-func (h *Headscale) getMapKeepAliveResponse(mKey wgkey.Key, req tailcfg.MapRequest, m *Machine) ([]byte, error) {
+func (h *Headscale) getMapKeepAliveResponse(
+ mKey wgkey.Key,
+ req tailcfg.MapRequest,
+ m *Machine,
+) ([]byte, error) {
resp := tailcfg.MapResponse{
KeepAlive: true,
}
@@ -394,7 +416,8 @@ func (h *Headscale) handleAuthKey(
Err(err).
Msg("Cannot encode message")
c.String(http.StatusInternalServerError, "")
- machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name).Inc()
+ machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name).
+ Inc()
return
}
c.Data(401, "application/json; charset=utf-8", respBody)
@@ -402,7 +425,8 @@ func (h *Headscale) handleAuthKey(
Str("func", "handleAuthKey").
Str("machine", m.Name).
Msg("Failed authentication via AuthKey")
- machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name).Inc()
+ machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name).
+ Inc()
return
}
@@ -416,7 +440,8 @@ func (h *Headscale) handleAuthKey(
Str("func", "handleAuthKey").
Str("machine", m.Name).
Msg("Failed to find an available IP")
- machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name).Inc()
+ machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name).
+ Inc()
return
}
log.Info().
@@ -445,11 +470,13 @@ func (h *Headscale) handleAuthKey(
Str("machine", m.Name).
Err(err).
Msg("Cannot encode message")
- machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name).Inc()
+ machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name).
+ Inc()
c.String(http.StatusInternalServerError, "Extremely sad!")
return
}
- machineRegistrations.WithLabelValues("new", "authkey", "success", m.Namespace.Name).Inc()
+ machineRegistrations.WithLabelValues("new", "authkey", "success", m.Namespace.Name).
+ Inc()
c.Data(200, "application/json; charset=utf-8", respBody)
log.Info().
Str("func", "handleAuthKey").
diff --git a/app.go b/app.go
index c226062..94181ac 100644
--- a/app.go
+++ b/app.go
@@ -152,8 +152,14 @@ func NewHeadscale(cfg Config) (*Headscale, error) {
var dbString string
switch cfg.DBtype {
case "postgres":
- dbString = fmt.Sprintf("host=%s port=%d dbname=%s user=%s password=%s sslmode=disable", cfg.DBhost,
- cfg.DBport, cfg.DBname, cfg.DBuser, cfg.DBpass)
+ dbString = fmt.Sprintf(
+ "host=%s port=%d dbname=%s user=%s password=%s sslmode=disable",
+ cfg.DBhost,
+ cfg.DBport,
+ cfg.DBname,
+ cfg.DBuser,
+ cfg.DBpass,
+ )
case "sqlite3":
dbString = cfg.DBpath
default:
@@ -182,7 +188,10 @@ func NewHeadscale(cfg Config) (*Headscale, error) {
}
if h.cfg.DNSConfig != nil && h.cfg.DNSConfig.Proxied { // if MagicDNS
- magicDNSDomains, err := generateMagicDNSRootDomains(h.cfg.IPPrefix, h.cfg.BaseDomain)
+ magicDNSDomains, err := generateMagicDNSRootDomains(
+ h.cfg.IPPrefix,
+ h.cfg.BaseDomain,
+ )
if err != nil {
return nil, err
}
@@ -224,7 +233,10 @@ func (h *Headscale) expireEphemeralNodesWorker() {
for _, ns := range namespaces {
machines, err := h.ListMachinesInNamespace(ns.Name)
if err != nil {
- log.Error().Err(err).Str("namespace", ns.Name).Msg("Error listing machines in namespace")
+ log.Error().
+ Err(err).
+ Str("namespace", ns.Name).
+ Msg("Error listing machines in namespace")
return
}
@@ -232,7 +244,9 @@ func (h *Headscale) expireEphemeralNodesWorker() {
for _, m := range machines {
if m.AuthKey != nil && m.LastSeen != nil && m.AuthKey.Ephemeral &&
time.Now().After(m.LastSeen.Add(h.cfg.EphemeralNodeInactivityTimeout)) {
- log.Info().Str("machine", m.Name).Msg("Ephemeral client removed from database")
+ log.Info().
+ Str("machine", m.Name).
+ Msg("Ephemeral client removed from database")
err = h.db.Unscoped().Delete(m).Error
if err != nil {
@@ -274,18 +288,33 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context,
// the server
p, _ := peer.FromContext(ctx)
- log.Trace().Caller().Str("client_address", p.Addr.String()).Msg("Client is trying to authenticate")
+ log.Trace().
+ Caller().
+ Str("client_address", p.Addr.String()).
+ Msg("Client is trying to authenticate")
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
- log.Error().Caller().Str("client_address", p.Addr.String()).Msg("Retrieving metadata is failed")
- return ctx, status.Errorf(codes.InvalidArgument, "Retrieving metadata is failed")
+ log.Error().
+ Caller().
+ Str("client_address", p.Addr.String()).
+ Msg("Retrieving metadata is failed")
+ return ctx, status.Errorf(
+ codes.InvalidArgument,
+ "Retrieving metadata is failed",
+ )
}
authHeader, ok := md["authorization"]
if !ok {
- log.Error().Caller().Str("client_address", p.Addr.String()).Msg("Authorization token is not supplied")
- return ctx, status.Errorf(codes.Unauthenticated, "Authorization token is not supplied")
+ log.Error().
+ Caller().
+ Str("client_address", p.Addr.String()).
+ Msg("Authorization token is not supplied")
+ return ctx, status.Errorf(
+ codes.Unauthenticated,
+ "Authorization token is not supplied",
+ )
}
token := authHeader[0]
@@ -295,7 +324,10 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context,
Caller().
Str("client_address", p.Addr.String()).
Msg(`missing "Bearer " prefix in "Authorization" header`)
- return ctx, status.Error(codes.Unauthenticated, `missing "Bearer " prefix in "Authorization" header`)
+ return ctx, status.Error(
+ codes.Unauthenticated,
+ `missing "Bearer " prefix in "Authorization" header`,
+ )
}
// TODO(kradalby): Implement API key backend:
@@ -307,7 +339,10 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context,
// Currently all other than localhost traffic is unauthorized, this is intentional to allow
// us to make use of gRPC for our CLI, but not having to implement any of the remote capabilities
// and API key auth
- return ctx, status.Error(codes.Unauthenticated, "Authentication is not implemented yet")
+ return ctx, status.Error(
+ codes.Unauthenticated,
+ "Authentication is not implemented yet",
+ )
//if strings.TrimPrefix(token, AUTH_PREFIX) != a.Token {
// log.Error().Caller().Str("client_address", p.Addr.String()).Msg("invalid token")
@@ -405,7 +440,10 @@ func (h *Headscale) Serve() error {
// Match gRPC requests here
grpcListener := m.MatchWithWriters(
cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc"),
- cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc+proto"),
+ cmux.HTTP2MatchHeaderFieldSendSettings(
+ "content-type",
+ "application/grpc+proto",
+ ),
)
// Otherwise match regular http requests.
httpListener := m.Match(cmux.Any())
@@ -436,7 +474,10 @@ func (h *Headscale) Serve() error {
p := ginprometheus.NewPrometheus("gin")
p.Use(r)
- r.GET("/health", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"healthy": "ok"}) })
+ r.GET(
+ "/health",
+ func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"healthy": "ok"}) },
+ )
r.GET("/key", h.KeyHandler)
r.GET("/register", h.RegisterWebAPI)
r.POST("/machine/:id/map", h.PollNetMapHandler)
@@ -537,7 +578,8 @@ func (h *Headscale) Serve() error {
g.Go(func() error { return m.Serve() })
- log.Info().Msgf("listening and serving (multiplexed HTTP and gRPC) on: %s", h.cfg.Addr)
+ log.Info().
+ Msgf("listening and serving (multiplexed HTTP and gRPC) on: %s", h.cfg.Addr)
return g.Wait()
}
@@ -545,7 +587,8 @@ func (h *Headscale) Serve() error {
func (h *Headscale) getTLSSettings() (*tls.Config, error) {
if h.cfg.TLSLetsEncryptHostname != "" {
if !strings.HasPrefix(h.cfg.ServerURL, "https://") {
- log.Warn().Msg("Listening with TLS but ServerURL does not start with https://")
+ log.Warn().
+ Msg("Listening with TLS but ServerURL does not start with https://")
}
m := autocert.Manager{
diff --git a/app_test.go b/app_test.go
index 5e53f1c..ec23282 100644
--- a/app_test.go
+++ b/app_test.go
@@ -17,8 +17,10 @@ var _ = check.Suite(&Suite{})
type Suite struct{}
-var tmpDir string
-var h Headscale
+var (
+ tmpDir string
+ h Headscale
+)
func (s *Suite) SetUpTest(c *check.C) {
s.ResetDB(c)
diff --git a/apple_mobileconfig.go b/apple_mobileconfig.go
index f3956e3..6ddd5be 100644
--- a/apple_mobileconfig.go
+++ b/apple_mobileconfig.go
@@ -73,7 +73,11 @@ func (h *Headscale) AppleMobileConfig(c *gin.Context) {
Str("handler", "AppleMobileConfig").
Err(err).
Msg("Could not render Apple index template")
- c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Apple index template"))
+ c.Data(
+ http.StatusInternalServerError,
+ "text/html; charset=utf-8",
+ []byte("Could not render Apple index template"),
+ )
return
}
@@ -89,7 +93,11 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) {
Str("handler", "ApplePlatformConfig").
Err(err).
Msg("Failed not create UUID")
- c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Failed to create UUID"))
+ c.Data(
+ http.StatusInternalServerError,
+ "text/html; charset=utf-8",
+ []byte("Failed to create UUID"),
+ )
return
}
@@ -99,7 +107,11 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) {
Str("handler", "ApplePlatformConfig").
Err(err).
Msg("Failed not create UUID")
- c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Failed to create UUID"))
+ c.Data(
+ http.StatusInternalServerError,
+ "text/html; charset=utf-8",
+ []byte("Failed to create UUID"),
+ )
return
}
@@ -117,7 +129,11 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) {
Str("handler", "ApplePlatformConfig").
Err(err).
Msg("Could not render Apple macOS template")
- c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Apple macOS template"))
+ c.Data(
+ http.StatusInternalServerError,
+ "text/html; charset=utf-8",
+ []byte("Could not render Apple macOS template"),
+ )
return
}
case "ios":
@@ -126,11 +142,19 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) {
Str("handler", "ApplePlatformConfig").
Err(err).
Msg("Could not render Apple iOS template")
- c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Apple iOS template"))
+ c.Data(
+ http.StatusInternalServerError,
+ "text/html; charset=utf-8",
+ []byte("Could not render Apple iOS template"),
+ )
return
}
default:
- c.Data(http.StatusOK, "text/html; charset=utf-8", []byte("Invalid platform, only ios and macos is supported"))
+ c.Data(
+ http.StatusOK,
+ "text/html; charset=utf-8",
+ []byte("Invalid platform, only ios and macos is supported"),
+ )
return
}
@@ -146,11 +170,19 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) {
Str("handler", "ApplePlatformConfig").
Err(err).
Msg("Could not render Apple platform template")
- c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Apple platform template"))
+ c.Data(
+ http.StatusInternalServerError,
+ "text/html; charset=utf-8",
+ []byte("Could not render Apple platform template"),
+ )
return
}
- c.Data(http.StatusOK, "application/x-apple-aspen-config; charset=utf-8", content.Bytes())
+ c.Data(
+ http.StatusOK,
+ "application/x-apple-aspen-config; charset=utf-8",
+ content.Bytes(),
+ )
}
type AppleMobileConfig struct {
@@ -164,7 +196,8 @@ type AppleMobilePlatformConfig struct {
Url string
}
-var commonTemplate = template.Must(template.New("mobileconfig").Parse(`
+var commonTemplate = template.Must(
+ template.New("mobileconfig").Parse(`
@@ -187,7 +220,8 @@ var commonTemplate = template.Must(template.New("mobileconfig").Parse(`
-`))
+`),
+)
var iosTemplate = template.Must(template.New("iosTemplate").Parse(`
diff --git a/cli_test.go b/cli_test.go
index 291b5df..6c0b2bb 100644
--- a/cli_test.go
+++ b/cli_test.go
@@ -28,7 +28,10 @@ func (s *Suite) TestRegisterMachine(c *check.C) {
_, err = h.GetMachine("test", "testmachine")
c.Assert(err, check.IsNil)
- m2, err := h.RegisterMachine("8ce002a935f8c394e55e78fbbb410576575ff8ec5cfa2e627e4b807f1be15b0e", n.Name)
+ m2, err := h.RegisterMachine(
+ "8ce002a935f8c394e55e78fbbb410576575ff8ec5cfa2e627e4b807f1be15b0e",
+ n.Name,
+ )
c.Assert(err, check.IsNil)
c.Assert(m2.Registered, check.Equals, true)
diff --git a/cmd/headscale/cli/debug.go b/cmd/headscale/cli/debug.go
index e140156..f106efa 100644
--- a/cmd/headscale/cli/debug.go
+++ b/cmd/headscale/cli/debug.go
@@ -27,7 +27,8 @@ func init() {
if err != nil {
log.Fatal().Err(err).Msg("")
}
- createNodeCmd.Flags().StringSliceP("route", "r", []string{}, "List (or repeated flags) of routes to advertise")
+ createNodeCmd.Flags().
+ StringSliceP("route", "r", []string{}, "List (or repeated flags) of routes to advertise")
debugCmd.AddCommand(createNodeCmd)
}
@@ -56,19 +57,31 @@ var createNodeCmd = &cobra.Command{
name, err := cmd.Flags().GetString("name")
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error getting node from flag: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error getting node from flag: %s", err),
+ output,
+ )
return
}
machineKey, err := cmd.Flags().GetString("key")
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error getting key from flag: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error getting key from flag: %s", err),
+ output,
+ )
return
}
routes, err := cmd.Flags().GetStringSlice("route")
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error getting routes from flag: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error getting routes from flag: %s", err),
+ output,
+ )
return
}
@@ -81,7 +94,11 @@ var createNodeCmd = &cobra.Command{
response, err := client.DebugCreateMachine(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Cannot create machine: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Cannot create machine: %s", status.Convert(err).Message()),
+ output,
+ )
return
}
diff --git a/cmd/headscale/cli/namespaces.go b/cmd/headscale/cli/namespaces.go
index 752638a..3a11178 100644
--- a/cmd/headscale/cli/namespaces.go
+++ b/cmd/headscale/cli/namespaces.go
@@ -48,7 +48,14 @@ var createNamespaceCmd = &cobra.Command{
log.Trace().Interface("request", request).Msg("Sending CreateNamespace request")
response, err := client.CreateNamespace(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Cannot create namespace: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf(
+ "Cannot create namespace: %s",
+ status.Convert(err).Message(),
+ ),
+ output,
+ )
return
}
@@ -78,7 +85,14 @@ var destroyNamespaceCmd = &cobra.Command{
response, err := client.DeleteNamespace(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Cannot destroy namespace: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf(
+ "Cannot destroy namespace: %s",
+ status.Convert(err).Message(),
+ ),
+ output,
+ )
return
}
@@ -100,7 +114,11 @@ var listNamespacesCmd = &cobra.Command{
response, err := client.ListNamespaces(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Cannot get namespaces: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Cannot get namespaces: %s", status.Convert(err).Message()),
+ output,
+ )
return
}
@@ -122,7 +140,11 @@ var listNamespacesCmd = &cobra.Command{
}
err = pterm.DefaultTable.WithHasHeader().WithData(d).Render()
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Failed to render pterm table: %s", err),
+ output,
+ )
return
}
},
@@ -151,7 +173,14 @@ var renameNamespaceCmd = &cobra.Command{
response, err := client.RenameNamespace(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Cannot rename namespace: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf(
+ "Cannot rename namespace: %s",
+ status.Convert(err).Message(),
+ ),
+ output,
+ )
return
}
diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go
index 9b3f424..934ac49 100644
--- a/cmd/headscale/cli/nodes.go
+++ b/cmd/headscale/cli/nodes.go
@@ -86,7 +86,11 @@ var registerNodeCmd = &cobra.Command{
machineKey, err := cmd.Flags().GetString("key")
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error getting machine key from flag: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error getting machine key from flag: %s", err),
+ output,
+ )
return
}
@@ -97,7 +101,14 @@ var registerNodeCmd = &cobra.Command{
response, err := client.RegisterMachine(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Cannot register machine: %s\n", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf(
+ "Cannot register machine: %s\n",
+ status.Convert(err).Message(),
+ ),
+ output,
+ )
return
}
@@ -126,7 +137,11 @@ var listNodesCmd = &cobra.Command{
response, err := client.ListMachines(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()),
+ output,
+ )
return
}
@@ -143,7 +158,11 @@ var listNodesCmd = &cobra.Command{
err = pterm.DefaultTable.WithHasHeader().WithData(d).Render()
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Failed to render pterm table: %s", err),
+ output,
+ )
return
}
},
@@ -157,7 +176,11 @@ var deleteNodeCmd = &cobra.Command{
id, err := cmd.Flags().GetInt("identifier")
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error converting ID to integer: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error converting ID to integer: %s", err),
+ output,
+ )
return
}
@@ -171,7 +194,14 @@ var deleteNodeCmd = &cobra.Command{
getResponse, err := client.GetMachine(ctx, getRequest)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf(
+ "Error getting node node: %s",
+ status.Convert(err).Message(),
+ ),
+ output,
+ )
return
}
@@ -183,7 +213,10 @@ var deleteNodeCmd = &cobra.Command{
force, _ := cmd.Flags().GetBool("force")
if !force {
prompt := &survey.Confirm{
- Message: fmt.Sprintf("Do you want to remove the node %s?", getResponse.GetMachine().Name),
+ Message: fmt.Sprintf(
+ "Do you want to remove the node %s?",
+ getResponse.GetMachine().Name,
+ ),
}
err = survey.AskOne(prompt, &confirm)
if err != nil {
@@ -198,10 +231,21 @@ var deleteNodeCmd = &cobra.Command{
return
}
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error deleting node: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf(
+ "Error deleting node: %s",
+ status.Convert(err).Message(),
+ ),
+ output,
+ )
return
}
- SuccessOutput(map[string]string{"Result": "Node deleted"}, "Node deleted", output)
+ SuccessOutput(
+ map[string]string{"Result": "Node deleted"},
+ "Node deleted",
+ output,
+ )
} else {
SuccessOutput(map[string]string{"Result": "Node not deleted"}, "Node not deleted", output)
}
@@ -235,7 +279,11 @@ func sharingWorker(
machineResponse, err := client.GetMachine(ctx, machineRequest)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()),
+ output,
+ )
return "", nil, nil, err
}
@@ -245,7 +293,11 @@ func sharingWorker(
namespaceResponse, err := client.GetNamespace(ctx, namespaceRequest)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()),
+ output,
+ )
return "", nil, nil, err
}
@@ -258,7 +310,11 @@ var shareMachineCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
output, machine, namespace, err := sharingWorker(cmd, args)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Failed to fetch namespace or machine: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Failed to fetch namespace or machine: %s", err),
+ output,
+ )
return
}
@@ -273,7 +329,11 @@ var shareMachineCmd = &cobra.Command{
response, err := client.ShareMachine(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error sharing node: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error sharing node: %s", status.Convert(err).Message()),
+ output,
+ )
return
}
@@ -287,7 +347,11 @@ var unshareMachineCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
output, machine, namespace, err := sharingWorker(cmd, args)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Failed to fetch namespace or machine: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Failed to fetch namespace or machine: %s", err),
+ output,
+ )
return
}
@@ -302,7 +366,11 @@ var unshareMachineCmd = &cobra.Command{
response, err := client.UnshareMachine(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error unsharing node: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error unsharing node: %s", status.Convert(err).Message()),
+ output,
+ )
return
}
@@ -310,8 +378,22 @@ var unshareMachineCmd = &cobra.Command{
},
}
-func nodesToPtables(currentNamespace string, machines []*v1.Machine) (pterm.TableData, error) {
- d := pterm.TableData{{"ID", "Name", "NodeKey", "Namespace", "IP address", "Ephemeral", "Last seen", "Online"}}
+func nodesToPtables(
+ currentNamespace string,
+ machines []*v1.Machine,
+) (pterm.TableData, error) {
+ d := pterm.TableData{
+ {
+ "ID",
+ "Name",
+ "NodeKey",
+ "Namespace",
+ "IP address",
+ "Ephemeral",
+ "Last seen",
+ "Online",
+ },
+ }
for _, machine := range machines {
var ephemeral bool
@@ -331,7 +413,9 @@ func nodesToPtables(currentNamespace string, machines []*v1.Machine) (pterm.Tabl
nodeKey := tailcfg.NodeKey(nKey)
var online string
- if lastSeen.After(time.Now().Add(-5 * time.Minute)) { // TODO: Find a better way to reliably show if online
+ if lastSeen.After(
+ time.Now().Add(-5 * time.Minute),
+ ) { // TODO: Find a better way to reliably show if online
online = pterm.LightGreen("true")
} else {
online = pterm.LightRed("false")
diff --git a/cmd/headscale/cli/preauthkeys.go b/cmd/headscale/cli/preauthkeys.go
index a07e961..f5b3b87 100644
--- a/cmd/headscale/cli/preauthkeys.go
+++ b/cmd/headscale/cli/preauthkeys.go
@@ -22,8 +22,10 @@ func init() {
preauthkeysCmd.AddCommand(listPreAuthKeys)
preauthkeysCmd.AddCommand(createPreAuthKeyCmd)
preauthkeysCmd.AddCommand(expirePreAuthKeyCmd)
- createPreAuthKeyCmd.PersistentFlags().Bool("reusable", false, "Make the preauthkey reusable")
- createPreAuthKeyCmd.PersistentFlags().Bool("ephemeral", false, "Preauthkey for ephemeral nodes")
+ createPreAuthKeyCmd.PersistentFlags().
+ Bool("reusable", false, "Make the preauthkey reusable")
+ createPreAuthKeyCmd.PersistentFlags().
+ Bool("ephemeral", false, "Preauthkey for ephemeral nodes")
createPreAuthKeyCmd.Flags().
DurationP("expiration", "e", 24*time.Hour, "Human-readable expiration of the key (30m, 24h, 365d...)")
}
@@ -55,7 +57,11 @@ var listPreAuthKeys = &cobra.Command{
response, err := client.ListPreAuthKeys(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error getting the list of keys: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error getting the list of keys: %s", err),
+ output,
+ )
return
}
@@ -64,7 +70,9 @@ var listPreAuthKeys = &cobra.Command{
return
}
- d := pterm.TableData{{"ID", "Key", "Reusable", "Ephemeral", "Used", "Expiration", "Created"}}
+ d := pterm.TableData{
+ {"ID", "Key", "Reusable", "Ephemeral", "Used", "Expiration", "Created"},
+ }
for _, k := range response.PreAuthKeys {
expiration := "-"
if k.GetExpiration() != nil {
@@ -91,7 +99,11 @@ var listPreAuthKeys = &cobra.Command{
}
err = pterm.DefaultTable.WithHasHeader().WithData(d).Render()
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Failed to render pterm table: %s", err),
+ output,
+ )
return
}
},
@@ -139,7 +151,11 @@ var createPreAuthKeyCmd = &cobra.Command{
response, err := client.CreatePreAuthKey(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Cannot create Pre Auth Key: %s\n", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Cannot create Pre Auth Key: %s\n", err),
+ output,
+ )
return
}
@@ -175,7 +191,11 @@ var expirePreAuthKeyCmd = &cobra.Command{
response, err := client.ExpirePreAuthKey(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Cannot expire Pre Auth Key: %s\n", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Cannot expire Pre Auth Key: %s\n", err),
+ output,
+ )
return
}
diff --git a/cmd/headscale/cli/root.go b/cmd/headscale/cli/root.go
index e5115f3..99b1514 100644
--- a/cmd/headscale/cli/root.go
+++ b/cmd/headscale/cli/root.go
@@ -10,7 +10,8 @@ import (
func init() {
rootCmd.PersistentFlags().
StringP("output", "o", "", "Output format. Empty for human-readable, 'json', 'json-line' or 'yaml'")
- rootCmd.PersistentFlags().Bool("force", false, "Disable prompts and forces the execution")
+ rootCmd.PersistentFlags().
+ Bool("force", false, "Disable prompts and forces the execution")
}
var rootCmd = &cobra.Command{
diff --git a/cmd/headscale/cli/routes.go b/cmd/headscale/cli/routes.go
index 9f2e4e2..e6c80fb 100644
--- a/cmd/headscale/cli/routes.go
+++ b/cmd/headscale/cli/routes.go
@@ -21,7 +21,8 @@ func init() {
}
routesCmd.AddCommand(listRoutesCmd)
- enableRouteCmd.Flags().StringSliceP("route", "r", []string{}, "List (or repeated flags) of routes to enable")
+ enableRouteCmd.Flags().
+ StringSliceP("route", "r", []string{}, "List (or repeated flags) of routes to enable")
enableRouteCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)")
err = enableRouteCmd.MarkFlagRequired("identifier")
if err != nil {
@@ -46,7 +47,11 @@ var listRoutesCmd = &cobra.Command{
machineId, err := cmd.Flags().GetUint64("identifier")
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error getting machine id from flag: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error getting machine id from flag: %s", err),
+ output,
+ )
return
}
@@ -60,7 +65,11 @@ var listRoutesCmd = &cobra.Command{
response, err := client.GetMachineRoute(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()),
+ output,
+ )
return
}
@@ -77,7 +86,11 @@ var listRoutesCmd = &cobra.Command{
err = pterm.DefaultTable.WithHasHeader().WithData(d).Render()
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Failed to render pterm table: %s", err),
+ output,
+ )
return
}
},
@@ -95,13 +108,21 @@ omit the route you do not want to enable.
output, _ := cmd.Flags().GetString("output")
machineId, err := cmd.Flags().GetUint64("identifier")
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error getting machine id from flag: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error getting machine id from flag: %s", err),
+ output,
+ )
return
}
routes, err := cmd.Flags().GetStringSlice("route")
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Error getting routes from flag: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Error getting routes from flag: %s", err),
+ output,
+ )
return
}
@@ -116,7 +137,14 @@ omit the route you do not want to enable.
response, err := client.EnableMachineRoutes(ctx, request)
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Cannot register machine: %s\n", status.Convert(err).Message()), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf(
+ "Cannot register machine: %s\n",
+ status.Convert(err).Message(),
+ ),
+ output,
+ )
return
}
@@ -133,7 +161,11 @@ omit the route you do not want to enable.
err = pterm.DefaultTable.WithHasHeader().WithData(d).Render()
if err != nil {
- ErrorOutput(err, fmt.Sprintf("Failed to render pterm table: %s", err), output)
+ ErrorOutput(
+ err,
+ fmt.Sprintf("Failed to render pterm table: %s", err),
+ output,
+ )
return
}
},
diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go
index 30f1a78..16b236a 100644
--- a/cmd/headscale/cli/utils.go
+++ b/cmd/headscale/cli/utils.go
@@ -149,9 +149,14 @@ func GetDNSConfig() (*tailcfg.DNSConfig, string) {
if viper.IsSet("dns_config.restricted_nameservers") {
if len(dnsConfig.Nameservers) > 0 {
dnsConfig.Routes = make(map[string][]dnstype.Resolver)
- restrictedDNS := viper.GetStringMapStringSlice("dns_config.restricted_nameservers")
+ restrictedDNS := viper.GetStringMapStringSlice(
+ "dns_config.restricted_nameservers",
+ )
for domain, restrictedNameservers := range restrictedDNS {
- restrictedResolvers := make([]dnstype.Resolver, len(restrictedNameservers))
+ restrictedResolvers := make(
+ []dnstype.Resolver,
+ len(restrictedNameservers),
+ )
for index, nameserverStr := range restrictedNameservers {
nameserver, err := netaddr.ParseIP(nameserverStr)
if err != nil {
@@ -219,7 +224,9 @@ func getHeadscaleConfig() headscale.Config {
"10h",
) // use 10h here because it is the length of a standard business day plus a small amount of leeway
if viper.GetDuration("max_machine_registration_duration") >= time.Second {
- maxMachineRegistrationDuration = viper.GetDuration("max_machine_registration_duration")
+ maxMachineRegistrationDuration = viper.GetDuration(
+ "max_machine_registration_duration",
+ )
}
// defaultMachineRegistrationDuration is the default time assigned to a machine registration if one is not
@@ -229,7 +236,9 @@ func getHeadscaleConfig() headscale.Config {
"8h",
) // use 8h here because it's the length of a standard business day
if viper.GetDuration("default_machine_registration_duration") >= time.Second {
- defaultMachineRegistrationDuration = viper.GetDuration("default_machine_registration_duration")
+ defaultMachineRegistrationDuration = viper.GetDuration(
+ "default_machine_registration_duration",
+ )
}
dnsConfig, baseDomain := GetDNSConfig()
@@ -244,7 +253,9 @@ func getHeadscaleConfig() headscale.Config {
DERP: derpConfig,
- EphemeralNodeInactivityTimeout: viper.GetDuration("ephemeral_node_inactivity_timeout"),
+ EphemeralNodeInactivityTimeout: viper.GetDuration(
+ "ephemeral_node_inactivity_timeout",
+ ),
DBtype: viper.GetString("db_type"),
DBpath: absPath(viper.GetString("db_path")),
@@ -254,9 +265,11 @@ func getHeadscaleConfig() headscale.Config {
DBuser: viper.GetString("db_user"),
DBpass: viper.GetString("db_pass"),
- TLSLetsEncryptHostname: viper.GetString("tls_letsencrypt_hostname"),
- TLSLetsEncryptListen: viper.GetString("tls_letsencrypt_listen"),
- TLSLetsEncryptCacheDir: absPath(viper.GetString("tls_letsencrypt_cache_dir")),
+ TLSLetsEncryptHostname: viper.GetString("tls_letsencrypt_hostname"),
+ TLSLetsEncryptListen: viper.GetString("tls_letsencrypt_listen"),
+ TLSLetsEncryptCacheDir: absPath(
+ viper.GetString("tls_letsencrypt_cache_dir"),
+ ),
TLSLetsEncryptChallengeType: viper.GetString("tls_letsencrypt_challenge_type"),
TLSCertPath: absPath(viper.GetString("tls_cert_path")),
@@ -431,7 +444,10 @@ type tokenAuth struct {
}
// Return value is mapped to request headers.
-func (t tokenAuth) GetRequestMetadata(ctx context.Context, in ...string) (map[string]string, error) {
+func (t tokenAuth) GetRequestMetadata(
+ ctx context.Context,
+ in ...string,
+) (map[string]string, error) {
return map[string]string{
"authorization": "Bearer " + t.token,
}, nil
diff --git a/cmd/headscale/headscale.go b/cmd/headscale/headscale.go
index ed4644f..8f436b9 100644
--- a/cmd/headscale/headscale.go
+++ b/cmd/headscale/headscale.go
@@ -63,7 +63,8 @@ func main() {
}
if !viper.GetBool("disable_check_updates") && !machineOutput {
- if (runtime.GOOS == "linux" || runtime.GOOS == "darwin") && cli.Version != "dev" {
+ if (runtime.GOOS == "linux" || runtime.GOOS == "darwin") &&
+ cli.Version != "dev" {
githubTag := &latest.GithubTag{
Owner: "juanfont",
Repository: "headscale",
diff --git a/cmd/headscale/headscale_test.go b/cmd/headscale/headscale_test.go
index e3a5713..ceee3e4 100644
--- a/cmd/headscale/headscale_test.go
+++ b/cmd/headscale/headscale_test.go
@@ -40,7 +40,10 @@ func (*Suite) TestConfigLoading(c *check.C) {
}
// Symlink the example config file
- err = os.Symlink(filepath.Clean(path+"/../../config-example.yaml"), filepath.Join(tmpDir, "config.yaml"))
+ err = os.Symlink(
+ filepath.Clean(path+"/../../config-example.yaml"),
+ filepath.Join(tmpDir, "config.yaml"),
+ )
if err != nil {
c.Fatal(err)
}
@@ -74,7 +77,10 @@ func (*Suite) TestDNSConfigLoading(c *check.C) {
}
// Symlink the example config file
- err = os.Symlink(filepath.Clean(path+"/../../config-example.yaml"), filepath.Join(tmpDir, "config.yaml"))
+ err = os.Symlink(
+ filepath.Clean(path+"/../../config-example.yaml"),
+ filepath.Join(tmpDir, "config.yaml"),
+ )
if err != nil {
c.Fatal(err)
}
@@ -128,7 +134,11 @@ func (*Suite) TestTLSConfigValidation(c *check.C) {
check.Matches,
".*Fatal config error: the only supported values for tls_letsencrypt_challenge_type are.*",
)
- c.Assert(tmp, check.Matches, ".*Fatal config error: server_url must start with https:// or http://.*")
+ c.Assert(
+ tmp,
+ check.Matches,
+ ".*Fatal config error: server_url must start with https:// or http://.*",
+ )
fmt.Println(tmp)
// Check configuration validation errors (2)
diff --git a/db.go b/db.go
index 42c5eee..60e2f6f 100644
--- a/db.go
+++ b/db.go
@@ -87,7 +87,10 @@ func (h *Headscale) openDB() (*gorm.DB, error) {
// getValue returns the value for the given key in KV
func (h *Headscale) getValue(key string) (string, error) {
var row KV
- if result := h.db.First(&row, "key = ?", key); errors.Is(result.Error, gorm.ErrRecordNotFound) {
+ if result := h.db.First(&row, "key = ?", key); errors.Is(
+ result.Error,
+ gorm.ErrRecordNotFound,
+ ) {
return "", errors.New("not found")
}
return row.Value, nil
diff --git a/dns.go b/dns.go
index c7ca32a..e0e1abe 100644
--- a/dns.go
+++ b/dns.go
@@ -30,7 +30,10 @@ import (
// From the netmask we can find out the wildcard bits (the bits that are not set in the netmask).
// This allows us to then calculate the subnets included in the subsequent class block and generate the entries.
-func generateMagicDNSRootDomains(ipPrefix netaddr.IPPrefix, baseDomain string) ([]dnsname.FQDN, error) {
+func generateMagicDNSRootDomains(
+ ipPrefix netaddr.IPPrefix,
+ baseDomain string,
+) ([]dnsname.FQDN, error) {
// TODO(juanfont): we are not handing out IPv6 addresses yet
// and in fact this is Tailscale.com's range (note the fd7a:115c:a1e0: range in the fc00::/7 network)
ipv6base := dnsname.FQDN("0.e.1.a.c.5.1.1.a.7.d.f.ip6.arpa.")
@@ -69,12 +72,20 @@ func generateMagicDNSRootDomains(ipPrefix netaddr.IPPrefix, baseDomain string) (
return fqdns, nil
}
-func getMapResponseDNSConfig(dnsConfigOrig *tailcfg.DNSConfig, baseDomain string, m Machine, peers Machines) (*tailcfg.DNSConfig, error) {
+func getMapResponseDNSConfig(
+ dnsConfigOrig *tailcfg.DNSConfig,
+ baseDomain string,
+ m Machine,
+ peers Machines,
+) (*tailcfg.DNSConfig, error) {
var dnsConfig *tailcfg.DNSConfig
if dnsConfigOrig != nil && dnsConfigOrig.Proxied { // if MagicDNS is enabled
// Only inject the Search Domain of the current namespace - shared nodes should use their full FQDN
dnsConfig = dnsConfigOrig.Clone()
- dnsConfig.Domains = append(dnsConfig.Domains, fmt.Sprintf("%s.%s", m.Namespace.Name, baseDomain))
+ dnsConfig.Domains = append(
+ dnsConfig.Domains,
+ fmt.Sprintf("%s.%s", m.Namespace.Name, baseDomain),
+ )
namespaceSet := set.New(set.ThreadSafe)
namespaceSet.Add(m.Namespace)
diff --git a/grpcv1.go b/grpcv1.go
index 998f0c0..4366446 100644
--- a/grpcv1.go
+++ b/grpcv1.go
@@ -155,7 +155,10 @@ func (api headscaleV1APIServer) RegisterMachine(
ctx context.Context,
request *v1.RegisterMachineRequest,
) (*v1.RegisterMachineResponse, error) {
- log.Trace().Str("namespace", request.GetNamespace()).Str("machine_key", request.GetKey()).Msg("Registering machine")
+ log.Trace().
+ Str("namespace", request.GetNamespace()).
+ Str("machine_key", request.GetKey()).
+ Msg("Registering machine")
machine, err := api.h.RegisterMachine(
request.GetKey(),
request.GetNamespace(),
@@ -208,7 +211,9 @@ func (api headscaleV1APIServer) ListMachines(
return nil, err
}
- sharedMachines, err := api.h.ListSharedMachinesInNamespace(request.GetNamespace())
+ sharedMachines, err := api.h.ListSharedMachinesInNamespace(
+ request.GetNamespace(),
+ )
if err != nil {
return nil, err
}
@@ -338,7 +343,11 @@ func (api headscaleV1APIServer) DebugCreateMachine(
return nil, err
}
- log.Trace().Caller().Interface("route-prefix", routes).Interface("route-str", request.GetRoutes()).Msg("")
+ log.Trace().
+ Caller().
+ Interface("route-prefix", routes).
+ Interface("route-str", request.GetRoutes()).
+ Msg("")
hostinfo := tailcfg.Hostinfo{
RoutableIPs: routes,
diff --git a/integration_cli_test.go b/integration_cli_test.go
index e1b1672..335768c 100644
--- a/integration_cli_test.go
+++ b/integration_cli_test.go
@@ -109,7 +109,10 @@ func (s *IntegrationCLITestSuite) TearDownTest() {
}
}
-func (s *IntegrationCLITestSuite) HandleStats(suiteName string, stats *suite.SuiteInformation) {
+func (s *IntegrationCLITestSuite) HandleStats(
+ suiteName string,
+ stats *suite.SuiteInformation,
+) {
s.stats = stats
}
@@ -298,11 +301,26 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() {
assert.True(s.T(), listedPreAuthKeys[3].Expiration.AsTime().After(time.Now()))
assert.True(s.T(), listedPreAuthKeys[4].Expiration.AsTime().After(time.Now()))
- assert.True(s.T(), listedPreAuthKeys[0].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)))
- assert.True(s.T(), listedPreAuthKeys[1].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)))
- assert.True(s.T(), listedPreAuthKeys[2].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)))
- assert.True(s.T(), listedPreAuthKeys[3].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)))
- assert.True(s.T(), listedPreAuthKeys[4].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)))
+ assert.True(
+ s.T(),
+ listedPreAuthKeys[0].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)),
+ )
+ assert.True(
+ s.T(),
+ listedPreAuthKeys[1].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)),
+ )
+ assert.True(
+ s.T(),
+ listedPreAuthKeys[2].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)),
+ )
+ assert.True(
+ s.T(),
+ listedPreAuthKeys[3].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)),
+ )
+ assert.True(
+ s.T(),
+ listedPreAuthKeys[4].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)),
+ )
// Expire three keys
for i := 0; i < 3; i++ {
@@ -341,11 +359,26 @@ func (s *IntegrationCLITestSuite) TestPreAuthKeyCommand() {
err = json.Unmarshal([]byte(listAfterExpireResult), &listedAfterExpirePreAuthKeys)
assert.Nil(s.T(), err)
- assert.True(s.T(), listedAfterExpirePreAuthKeys[0].Expiration.AsTime().Before(time.Now()))
- assert.True(s.T(), listedAfterExpirePreAuthKeys[1].Expiration.AsTime().Before(time.Now()))
- assert.True(s.T(), listedAfterExpirePreAuthKeys[2].Expiration.AsTime().Before(time.Now()))
- assert.True(s.T(), listedAfterExpirePreAuthKeys[3].Expiration.AsTime().After(time.Now()))
- assert.True(s.T(), listedAfterExpirePreAuthKeys[4].Expiration.AsTime().After(time.Now()))
+ assert.True(
+ s.T(),
+ listedAfterExpirePreAuthKeys[0].Expiration.AsTime().Before(time.Now()),
+ )
+ assert.True(
+ s.T(),
+ listedAfterExpirePreAuthKeys[1].Expiration.AsTime().Before(time.Now()),
+ )
+ assert.True(
+ s.T(),
+ listedAfterExpirePreAuthKeys[2].Expiration.AsTime().Before(time.Now()),
+ )
+ assert.True(
+ s.T(),
+ listedAfterExpirePreAuthKeys[3].Expiration.AsTime().After(time.Now()),
+ )
+ assert.True(
+ s.T(),
+ listedAfterExpirePreAuthKeys[4].Expiration.AsTime().After(time.Now()),
+ )
}
func (s *IntegrationCLITestSuite) TestPreAuthKeyCommandWithoutExpiry() {
@@ -689,7 +722,10 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() {
assert.Nil(s.T(), err)
var listOnlySharedMachineNamespace []v1.Machine
- err = json.Unmarshal([]byte(listOnlySharedMachineNamespaceResult), &listOnlySharedMachineNamespace)
+ err = json.Unmarshal(
+ []byte(listOnlySharedMachineNamespaceResult),
+ &listOnlySharedMachineNamespace,
+ )
assert.Nil(s.T(), err)
assert.Len(s.T(), listOnlySharedMachineNamespace, 2)
@@ -738,7 +774,10 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() {
assert.Nil(s.T(), err)
var listOnlyMachineNamespaceAfterDelete []v1.Machine
- err = json.Unmarshal([]byte(listOnlyMachineNamespaceAfterDeleteResult), &listOnlyMachineNamespaceAfterDelete)
+ err = json.Unmarshal(
+ []byte(listOnlyMachineNamespaceAfterDeleteResult),
+ &listOnlyMachineNamespaceAfterDelete,
+ )
assert.Nil(s.T(), err)
assert.Len(s.T(), listOnlyMachineNamespaceAfterDelete, 4)
@@ -789,7 +828,10 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() {
assert.Nil(s.T(), err)
var listOnlyMachineNamespaceAfterShare []v1.Machine
- err = json.Unmarshal([]byte(listOnlyMachineNamespaceAfterShareResult), &listOnlyMachineNamespaceAfterShare)
+ err = json.Unmarshal(
+ []byte(listOnlyMachineNamespaceAfterShareResult),
+ &listOnlyMachineNamespaceAfterShare,
+ )
assert.Nil(s.T(), err)
assert.Len(s.T(), listOnlyMachineNamespaceAfterShare, 5)
@@ -846,7 +888,10 @@ func (s *IntegrationCLITestSuite) TestNodeCommand() {
assert.Nil(s.T(), err)
var listOnlyMachineNamespaceAfterUnshare []v1.Machine
- err = json.Unmarshal([]byte(listOnlyMachineNamespaceAfterUnshareResult), &listOnlyMachineNamespaceAfterUnshare)
+ err = json.Unmarshal(
+ []byte(listOnlyMachineNamespaceAfterUnshareResult),
+ &listOnlyMachineNamespaceAfterUnshare,
+ )
assert.Nil(s.T(), err)
assert.Len(s.T(), listOnlyMachineNamespaceAfterUnshare, 4)
@@ -1010,5 +1055,9 @@ func (s *IntegrationCLITestSuite) TestRouteCommand() {
)
assert.Nil(s.T(), err)
- assert.Contains(s.T(), string(failEnableNonAdvertisedRoute), "route (route-machine) is not available on node")
+ assert.Contains(
+ s.T(),
+ string(failEnableNonAdvertisedRoute),
+ "route (route-machine) is not available on node",
+ )
}
diff --git a/integration_common_test.go b/integration_common_test.go
index 71d4866..6540012 100644
--- a/integration_common_test.go
+++ b/integration_common_test.go
@@ -12,7 +12,11 @@ import (
"github.com/ory/dockertest/v3/docker"
)
-func ExecuteCommand(resource *dockertest.Resource, cmd []string, env []string) (string, error) {
+func ExecuteCommand(
+ resource *dockertest.Resource,
+ cmd []string,
+ env []string,
+) (string, error) {
var stdout bytes.Buffer
var stderr bytes.Buffer
diff --git a/integration_test.go b/integration_test.go
index c4f6bb4..dc5a83c 100644
--- a/integration_test.go
+++ b/integration_test.go
@@ -89,7 +89,10 @@ func TestIntegrationTestSuite(t *testing.T) {
}
}
-func (s *IntegrationTestSuite) saveLog(resource *dockertest.Resource, basePath string) error {
+func (s *IntegrationTestSuite) saveLog(
+ resource *dockertest.Resource,
+ basePath string,
+) error {
err := os.MkdirAll(basePath, os.ModePerm)
if err != nil {
return err
@@ -118,12 +121,20 @@ func (s *IntegrationTestSuite) saveLog(resource *dockertest.Resource, basePath s
fmt.Printf("Saving logs for %s to %s\n", resource.Container.Name, basePath)
- err = ioutil.WriteFile(path.Join(basePath, resource.Container.Name+".stdout.log"), []byte(stdout.String()), 0o644)
+ err = ioutil.WriteFile(
+ path.Join(basePath, resource.Container.Name+".stdout.log"),
+ []byte(stdout.String()),
+ 0o644,
+ )
if err != nil {
return err
}
- err = ioutil.WriteFile(path.Join(basePath, resource.Container.Name+".stderr.log"), []byte(stdout.String()), 0o644)
+ err = ioutil.WriteFile(
+ path.Join(basePath, resource.Container.Name+".stderr.log"),
+ []byte(stdout.String()),
+ 0o644,
+ )
if err != nil {
return err
}
@@ -144,14 +155,27 @@ func (s *IntegrationTestSuite) tailscaleContainer(
},
},
}
- hostname := fmt.Sprintf("%s-tailscale-%s-%s", namespace, strings.Replace(version, ".", "-", -1), identifier)
+ hostname := fmt.Sprintf(
+ "%s-tailscale-%s-%s",
+ namespace,
+ strings.Replace(version, ".", "-", -1),
+ identifier,
+ )
tailscaleOptions := &dockertest.RunOptions{
Name: hostname,
Networks: []*dockertest.Network{&s.network},
- Cmd: []string{"tailscaled", "--tun=userspace-networking", "--socks5-server=localhost:1055"},
+ Cmd: []string{
+ "tailscaled",
+ "--tun=userspace-networking",
+ "--socks5-server=localhost:1055",
+ },
}
- pts, err := s.pool.BuildAndRunWithBuildOptions(tailscaleBuildOptions, tailscaleOptions, DockerRestartPolicy)
+ pts, err := s.pool.BuildAndRunWithBuildOptions(
+ tailscaleBuildOptions,
+ tailscaleOptions,
+ DockerRestartPolicy,
+ )
if err != nil {
log.Fatalf("Could not start resource: %s", err)
}
@@ -210,7 +234,11 @@ func (s *IntegrationTestSuite) SetupSuite() {
for i := 0; i < scales.count; i++ {
version := tailscaleVersions[i%len(tailscaleVersions)]
- hostname, container := s.tailscaleContainer(namespace, fmt.Sprint(i), version)
+ hostname, container := s.tailscaleContainer(
+ namespace,
+ fmt.Sprint(i),
+ version,
+ )
scales.tailscales[hostname] = *container
}
}
@@ -273,7 +301,10 @@ func (s *IntegrationTestSuite) SetupSuite() {
headscaleEndpoint := "http://headscale:8080"
- fmt.Printf("Joining tailscale containers to headscale at %s\n", headscaleEndpoint)
+ fmt.Printf(
+ "Joining tailscale containers to headscale at %s\n",
+ headscaleEndpoint,
+ )
for hostname, tailscale := range scales.tailscales {
command := []string{
"tailscale",
@@ -307,7 +338,10 @@ func (s *IntegrationTestSuite) SetupSuite() {
func (s *IntegrationTestSuite) TearDownSuite() {
}
-func (s *IntegrationTestSuite) HandleStats(suiteName string, stats *suite.SuiteInformation) {
+func (s *IntegrationTestSuite) HandleStats(
+ suiteName string,
+ stats *suite.SuiteInformation,
+) {
s.stats = stats
}
@@ -427,7 +461,13 @@ func (s *IntegrationTestSuite) TestPingAllPeers() {
ip.String(),
}
- fmt.Printf("Pinging from %s (%s) to %s (%s)\n", hostname, ips[hostname], peername, ip)
+ fmt.Printf(
+ "Pinging from %s (%s) to %s (%s)\n",
+ hostname,
+ ips[hostname],
+ peername,
+ ip,
+ )
result, err := ExecuteCommand(
&tailscale,
command,
@@ -449,7 +489,15 @@ func (s *IntegrationTestSuite) TestSharedNodes() {
result, err := ExecuteCommand(
&s.headscale,
- []string{"headscale", "nodes", "list", "--output", "json", "--namespace", "shared"},
+ []string{
+ "headscale",
+ "nodes",
+ "list",
+ "--output",
+ "json",
+ "--namespace",
+ "shared",
+ },
[]string{},
)
assert.Nil(s.T(), err)
@@ -520,7 +568,13 @@ func (s *IntegrationTestSuite) TestSharedNodes() {
ip.String(),
}
- fmt.Printf("Pinging from %s (%s) to %s (%s)\n", hostname, mainIps[hostname], peername, ip)
+ fmt.Printf(
+ "Pinging from %s (%s) to %s (%s)\n",
+ hostname,
+ mainIps[hostname],
+ peername,
+ ip,
+ )
result, err := ExecuteCommand(
&tailscale,
command,
@@ -578,9 +632,19 @@ func (s *IntegrationTestSuite) TestTailDrop() {
"PUT",
"--upload-file",
fmt.Sprintf("/tmp/file_from_%s", hostname),
- fmt.Sprintf("%s/v0/put/file_from_%s", peerAPI, hostname),
+ fmt.Sprintf(
+ "%s/v0/put/file_from_%s",
+ peerAPI,
+ hostname,
+ ),
}
- fmt.Printf("Sending file from %s (%s) to %s (%s)\n", hostname, ips[hostname], peername, ip)
+ fmt.Printf(
+ "Sending file from %s (%s) to %s (%s)\n",
+ hostname,
+ ips[hostname],
+ peername,
+ ip,
+ )
_, err = ExecuteCommand(
&tailscale,
command,
@@ -621,7 +685,13 @@ func (s *IntegrationTestSuite) TestTailDrop() {
"ls",
fmt.Sprintf("/tmp/file_from_%s", peername),
}
- fmt.Printf("Checking file in %s (%s) from %s (%s)\n", hostname, ips[hostname], peername, ip)
+ fmt.Printf(
+ "Checking file in %s (%s) from %s (%s)\n",
+ hostname,
+ ips[hostname],
+ peername,
+ ip,
+ )
result, err := ExecuteCommand(
&tailscale,
command,
@@ -629,7 +699,11 @@ func (s *IntegrationTestSuite) TestTailDrop() {
)
assert.Nil(t, err)
fmt.Printf("Result for %s: %s\n", peername, result)
- assert.Equal(t, result, fmt.Sprintf("/tmp/file_from_%s\n", peername))
+ assert.Equal(
+ t,
+ result,
+ fmt.Sprintf("/tmp/file_from_%s\n", peername),
+ )
}
})
}
@@ -699,7 +773,9 @@ func getIPs(tailscales map[string]dockertest.Resource) (map[string]netaddr.IP, e
return ips, nil
}
-func getAPIURLs(tailscales map[string]dockertest.Resource) (map[netaddr.IP]string, error) {
+func getAPIURLs(
+ tailscales map[string]dockertest.Resource,
+) (map[netaddr.IP]string, error) {
fts := make(map[netaddr.IP]string)
for _, tailscale := range tailscales {
command := []string{
diff --git a/machine.go b/machine.go
index 557ab5b..d0c07d0 100644
--- a/machine.go
+++ b/machine.go
@@ -73,8 +73,12 @@ func (m Machine) isExpired() bool {
func (h *Headscale) updateMachineExpiry(m *Machine) {
if m.isExpired() {
now := time.Now().UTC()
- maxExpiry := now.Add(h.cfg.MaxMachineRegistrationDuration) // calculate the maximum expiry
- defaultExpiry := now.Add(h.cfg.DefaultMachineRegistrationDuration) // calculate the default expiry
+ maxExpiry := now.Add(
+ h.cfg.MaxMachineRegistrationDuration,
+ ) // calculate the maximum expiry
+ defaultExpiry := now.Add(
+ h.cfg.DefaultMachineRegistrationDuration,
+ ) // calculate the default expiry
// clamp the expiry time of the machine registration to the maximum allowed, or use the default if none supplied
if maxExpiry.Before(*m.RequestedExpiry) {
@@ -157,7 +161,9 @@ func (h *Headscale) getSharedTo(m *Machine) (Machines, error) {
peers := make(Machines, 0)
for _, sharedMachine := range sharedMachines {
- namespaceMachines, err := h.ListMachinesInNamespace(sharedMachine.Namespace.Name)
+ namespaceMachines, err := h.ListMachinesInNamespace(
+ sharedMachine.Namespace.Name,
+ )
if err != nil {
return Machines{}, err
}
@@ -392,7 +398,11 @@ func (ms Machines) toNodes(
// toNode converts a Machine into a Tailscale Node. includeRoutes is false for shared nodes
// as per the expected behaviour in the official SaaS
-func (m Machine) toNode(baseDomain string, dnsConfig *tailcfg.DNSConfig, includeRoutes bool) (*tailcfg.Node, error) {
+func (m Machine) toNode(
+ baseDomain string,
+ dnsConfig *tailcfg.DNSConfig,
+ includeRoutes bool,
+) (*tailcfg.Node, error) {
nKey, err := wgkey.ParseHex(m.NodeKey)
if err != nil {
return nil, err
@@ -425,7 +435,10 @@ func (m Machine) toNode(baseDomain string, dnsConfig *tailcfg.DNSConfig, include
addrs = append(addrs, ip) // missing the ipv6 ?
allowedIPs := []netaddr.IPPrefix{}
- allowedIPs = append(allowedIPs, ip) // we append the node own IP, as it is required by the clients
+ allowedIPs = append(
+ allowedIPs,
+ ip,
+ ) // we append the node own IP, as it is required by the clients
if includeRoutes {
routesStr := []string{}
@@ -571,7 +584,10 @@ func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, err
}
m := Machine{}
- if result := h.db.First(&m, "machine_key = ?", mKey.HexString()); errors.Is(result.Error, gorm.ErrRecordNotFound) {
+ if result := h.db.First(&m, "machine_key = ?", mKey.HexString()); errors.Is(
+ result.Error,
+ gorm.ErrRecordNotFound,
+ ) {
return nil, errors.New("Machine not found")
}
@@ -693,7 +709,11 @@ func (h *Headscale) EnableRoutes(m *Machine, routeStrs ...string) error {
for _, newRoute := range newRoutes {
if !containsIpPrefix(availableRoutes, newRoute) {
- return fmt.Errorf("route (%s) is not available on node %s", m.Name, newRoute)
+ return fmt.Errorf(
+ "route (%s) is not available on node %s",
+ m.Name,
+ newRoute,
+ )
}
}
diff --git a/metrics.go b/metrics.go
index 0d3dca3..f0ce16e 100644
--- a/metrics.go
+++ b/metrics.go
@@ -32,7 +32,7 @@ var (
Name: "update_request_sent_to_node_total",
Help: "The number of calls/messages issued on a specific nodes update channel",
}, []string{"namespace", "machine", "status"})
- //TODO(kradalby): This is very debugging, we might want to remove it.
+ // TODO(kradalby): This is very debugging, we might want to remove it.
updateRequestsReceivedOnChannel = promauto.NewCounterVec(prometheus.CounterOpts{
Namespace: prometheusNamespace,
Name: "update_request_received_on_channel_total",
diff --git a/namespaces.go b/namespaces.go
index 66deb1a..59a8e2e 100644
--- a/namespaces.go
+++ b/namespaces.go
@@ -102,7 +102,10 @@ func (h *Headscale) RenameNamespace(oldName, newName string) error {
// GetNamespace fetches a namespace by name
func (h *Headscale) GetNamespace(name string) (*Namespace, error) {
n := Namespace{}
- if result := h.db.First(&n, "name = ?", name); errors.Is(result.Error, gorm.ErrRecordNotFound) {
+ if result := h.db.First(&n, "name = ?", name); errors.Is(
+ result.Error,
+ gorm.ErrRecordNotFound,
+ ) {
return nil, errorNamespaceNotFound
}
return &n, nil
@@ -144,7 +147,9 @@ func (h *Headscale) ListSharedMachinesInNamespace(name string) ([]Machine, error
machines := []Machine{}
for _, sharedMachine := range sharedMachines {
- machine, err := h.GetMachineByID(sharedMachine.MachineID) // otherwise not everything comes filled
+ machine, err := h.GetMachineByID(
+ sharedMachine.MachineID,
+ ) // otherwise not everything comes filled
if err != nil {
return nil, err
}
@@ -173,7 +178,10 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error {
v, err := h.getValue("namespaces_pending_updates")
if err != nil || v == "" {
- err = h.setValue("namespaces_pending_updates", fmt.Sprintf(`["%s"]`, namespace.Name))
+ err = h.setValue(
+ "namespaces_pending_updates",
+ fmt.Sprintf(`["%s"]`, namespace.Name),
+ )
if err != nil {
return err
}
@@ -182,7 +190,10 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error {
names := []string{}
err = json.Unmarshal([]byte(v), &names)
if err != nil {
- err = h.setValue("namespaces_pending_updates", fmt.Sprintf(`["%s"]`, namespace.Name))
+ err = h.setValue(
+ "namespaces_pending_updates",
+ fmt.Sprintf(`["%s"]`, namespace.Name),
+ )
if err != nil {
return err
}
diff --git a/oidc.go b/oidc.go
index 51c443d..c3f7c2e 100644
--- a/oidc.go
+++ b/oidc.go
@@ -39,8 +39,11 @@ func (h *Headscale) initOIDC() error {
ClientID: h.cfg.OIDC.ClientID,
ClientSecret: h.cfg.OIDC.ClientSecret,
Endpoint: h.oidcProvider.Endpoint(),
- RedirectURL: fmt.Sprintf("%s/oidc/callback", strings.TrimSuffix(h.cfg.ServerURL, "/")),
- Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
+ RedirectURL: fmt.Sprintf(
+ "%s/oidc/callback",
+ strings.TrimSuffix(h.cfg.ServerURL, "/"),
+ ),
+ Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
}
}
@@ -127,7 +130,10 @@ func (h *Headscale) OIDCCallback(c *gin.Context) {
// Extract custom claims
var claims IDTokenClaims
if err = idToken.Claims(&claims); err != nil {
- c.String(http.StatusBadRequest, fmt.Sprintf("Failed to decode id token claims: %s", err))
+ c.String(
+ http.StatusBadRequest,
+ fmt.Sprintf("Failed to decode id token claims: %s", err),
+ )
return
}
@@ -135,7 +141,8 @@ func (h *Headscale) OIDCCallback(c *gin.Context) {
mKeyIf, mKeyFound := h.oidcStateCache.Get(state)
if !mKeyFound {
- log.Error().Msg("requested machine state key expired before authorisation completed")
+ log.Error().
+ Msg("requested machine state key expired before authorisation completed")
c.String(http.StatusBadRequest, "state has expired")
return
}
@@ -151,7 +158,10 @@ func (h *Headscale) OIDCCallback(c *gin.Context) {
m, err := h.GetMachineByMachineKey(mKeyStr)
if err != nil {
log.Error().Msg("machine key not found in database")
- c.String(http.StatusInternalServerError, "could not get machine info from database")
+ c.String(
+ http.StatusInternalServerError,
+ "could not get machine info from database",
+ )
return
}
@@ -168,15 +178,22 @@ func (h *Headscale) OIDCCallback(c *gin.Context) {
ns, err = h.CreateNamespace(nsName)
if err != nil {
- log.Error().Msgf("could not create new namespace '%s'", claims.Email)
- c.String(http.StatusInternalServerError, "could not create new namespace")
+ log.Error().
+ Msgf("could not create new namespace '%s'", claims.Email)
+ c.String(
+ http.StatusInternalServerError,
+ "could not create new namespace",
+ )
return
}
}
ip, err := h.getAvailableIP()
if err != nil {
- c.String(http.StatusInternalServerError, "could not get an IP from the pool")
+ c.String(
+ http.StatusInternalServerError,
+ "could not get an IP from the pool",
+ )
return
}
@@ -209,7 +226,10 @@ func (h *Headscale) OIDCCallback(c *gin.Context) {
Str("username", claims.Username).
Str("machine", m.Name).
Msg("Email could not be mapped to a namespace")
- c.String(http.StatusBadRequest, "email from claim could not be mapped to a namespace")
+ c.String(
+ http.StatusBadRequest,
+ "email from claim could not be mapped to a namespace",
+ )
}
// getNamespaceFromEmail passes the users email through a list of "matchers"
diff --git a/oidc_test.go b/oidc_test.go
index c7a29ce..6b01924 100644
--- a/oidc_test.go
+++ b/oidc_test.go
@@ -164,10 +164,18 @@ func TestHeadscale_getNamespaceFromEmail(t *testing.T) {
}
got, got1 := h.getNamespaceFromEmail(tt.args.email)
if got != tt.want {
- t.Errorf("Headscale.getNamespaceFromEmail() got = %v, want %v", got, tt.want)
+ t.Errorf(
+ "Headscale.getNamespaceFromEmail() got = %v, want %v",
+ got,
+ tt.want,
+ )
}
if got1 != tt.want1 {
- t.Errorf("Headscale.getNamespaceFromEmail() got1 = %v, want %v", got1, tt.want1)
+ t.Errorf(
+ "Headscale.getNamespaceFromEmail() got1 = %v, want %v",
+ got1,
+ tt.want1,
+ )
}
})
}
diff --git a/poll.go b/poll.go
index 6a65280..038192f 100644
--- a/poll.go
+++ b/poll.go
@@ -158,7 +158,8 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) {
// It sounds like we should update the nodes when we have received a endpoint update
// even tho the comments in the tailscale code dont explicitly say so.
- updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "endpoint-update").Inc()
+ updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "endpoint-update").
+ Inc()
go func() { updateChan <- struct{}{} }()
return
} else if req.OmitPeers && req.Stream {
@@ -184,10 +185,20 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) {
Str("handler", "PollNetMap").
Str("machine", m.Name).
Msg("Notifying peers")
- updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "full-update").Inc()
+ updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "full-update").
+ Inc()
go func() { updateChan <- struct{}{} }()
- h.PollNetMapStream(c, m, req, mKey, pollDataChan, keepAliveChan, updateChan, cancelKeepAlive)
+ h.PollNetMapStream(
+ c,
+ m,
+ req,
+ mKey,
+ pollDataChan,
+ keepAliveChan,
+ updateChan,
+ cancelKeepAlive,
+ )
log.Trace().
Str("handler", "PollNetMap").
Str("id", c.Param("id")).
@@ -260,7 +271,8 @@ func (h *Headscale) PollNetMapStream(
now := time.Now().UTC()
m.LastSeen = &now
- lastStateUpdate.WithLabelValues(m.Namespace.Name, m.Name).Set(float64(now.Unix()))
+ lastStateUpdate.WithLabelValues(m.Namespace.Name, m.Name).
+ Set(float64(now.Unix()))
m.LastSuccessfulUpdate = &now
h.db.Save(&m)
@@ -324,7 +336,8 @@ func (h *Headscale) PollNetMapStream(
Str("machine", m.Name).
Str("channel", "update").
Msg("Received a request for update")
- updateRequestsReceivedOnChannel.WithLabelValues(m.Name, m.Namespace.Name).Inc()
+ updateRequestsReceivedOnChannel.WithLabelValues(m.Name, m.Namespace.Name).
+ Inc()
if h.isOutdated(m) {
log.Debug().
Str("handler", "PollNetMapStream").
@@ -349,7 +362,8 @@ func (h *Headscale) PollNetMapStream(
Str("channel", "update").
Err(err).
Msg("Could not write the map response")
- updateRequestsSentToNode.WithLabelValues(m.Name, m.Namespace.Name, "failed").Inc()
+ updateRequestsSentToNode.WithLabelValues(m.Name, m.Namespace.Name, "failed").
+ Inc()
return false
}
log.Trace().
@@ -357,7 +371,8 @@ func (h *Headscale) PollNetMapStream(
Str("machine", m.Name).
Str("channel", "update").
Msg("Updated Map has been sent")
- updateRequestsSentToNode.WithLabelValues(m.Name, m.Namespace.Name, "success").Inc()
+ updateRequestsSentToNode.WithLabelValues(m.Name, m.Namespace.Name, "success").
+ Inc()
// Keep track of the last successful update,
// we sometimes end in a state were the update
@@ -377,7 +392,8 @@ func (h *Headscale) PollNetMapStream(
}
now := time.Now().UTC()
- lastStateUpdate.WithLabelValues(m.Namespace.Name, m.Name).Set(float64(now.Unix()))
+ lastStateUpdate.WithLabelValues(m.Namespace.Name, m.Name).
+ Set(float64(now.Unix()))
m.LastSuccessfulUpdate = &now
h.db.Save(&m)
@@ -424,7 +440,7 @@ func (h *Headscale) PollNetMapStream(
Str("machine", m.Name).
Str("channel", "Done").
Msg("Closing update channel")
- //h.closeUpdateChannel(m)
+ // h.closeUpdateChannel(m)
close(updateChan)
log.Trace().
@@ -483,7 +499,8 @@ func (h *Headscale) scheduledPollWorker(
Str("func", "scheduledPollWorker").
Str("machine", m.Name).
Msg("Sending update request")
- updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "scheduled-update").Inc()
+ updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "scheduled-update").
+ Inc()
updateChan <- struct{}{}
}
}
diff --git a/preauth_keys.go b/preauth_keys.go
index 1cb9c11..68664c1 100644
--- a/preauth_keys.go
+++ b/preauth_keys.go
@@ -105,7 +105,10 @@ func (h *Headscale) ExpirePreAuthKey(k *PreAuthKey) error {
// If returns no error and a PreAuthKey, it can be used
func (h *Headscale) checkKeyValidity(k string) (*PreAuthKey, error) {
pak := PreAuthKey{}
- if result := h.db.Preload("Namespace").First(&pak, "key = ?", k); errors.Is(result.Error, gorm.ErrRecordNotFound) {
+ if result := h.db.Preload("Namespace").First(&pak, "key = ?", k); errors.Is(
+ result.Error,
+ gorm.ErrRecordNotFound,
+ ) {
return nil, errorAuthKeyNotFound
}
diff --git a/routes.go b/routes.go
index f07b709..84f8dfe 100644
--- a/routes.go
+++ b/routes.go
@@ -11,7 +11,10 @@ import (
// Deprecated: use machine function instead
// GetAdvertisedNodeRoutes returns the subnet routes advertised by a node (identified by
// namespace and node name)
-func (h *Headscale) GetAdvertisedNodeRoutes(namespace string, nodeName string) (*[]netaddr.IPPrefix, error) {
+func (h *Headscale) GetAdvertisedNodeRoutes(
+ namespace string,
+ nodeName string,
+) (*[]netaddr.IPPrefix, error) {
m, err := h.GetMachine(namespace, nodeName)
if err != nil {
return nil, err
@@ -27,7 +30,10 @@ func (h *Headscale) GetAdvertisedNodeRoutes(namespace string, nodeName string) (
// Deprecated: use machine function instead
// GetEnabledNodeRoutes returns the subnet routes enabled by a node (identified by
// namespace and node name)
-func (h *Headscale) GetEnabledNodeRoutes(namespace string, nodeName string) ([]netaddr.IPPrefix, error) {
+func (h *Headscale) GetEnabledNodeRoutes(
+ namespace string,
+ nodeName string,
+) ([]netaddr.IPPrefix, error) {
m, err := h.GetMachine(namespace, nodeName)
if err != nil {
return nil, err
@@ -58,7 +64,11 @@ func (h *Headscale) GetEnabledNodeRoutes(namespace string, nodeName string) ([]n
// Deprecated: use machine function instead
// IsNodeRouteEnabled checks if a certain route has been enabled
-func (h *Headscale) IsNodeRouteEnabled(namespace string, nodeName string, routeStr string) bool {
+func (h *Headscale) IsNodeRouteEnabled(
+ namespace string,
+ nodeName string,
+ routeStr string,
+) bool {
route, err := netaddr.ParseIPPrefix(routeStr)
if err != nil {
return false
@@ -80,7 +90,11 @@ func (h *Headscale) IsNodeRouteEnabled(namespace string, nodeName string, routeS
// Deprecated: use EnableRoute in machine.go
// EnableNodeRoute enables a subnet route advertised by a node (identified by
// namespace and node name)
-func (h *Headscale) EnableNodeRoute(namespace string, nodeName string, routeStr string) error {
+func (h *Headscale) EnableNodeRoute(
+ namespace string,
+ nodeName string,
+ routeStr string,
+) error {
m, err := h.GetMachine(namespace, nodeName)
if err != nil {
return err
diff --git a/routes_test.go b/routes_test.go
index ad16d21..a120eda 100644
--- a/routes_test.go
+++ b/routes_test.go
@@ -93,7 +93,10 @@ func (s *Suite) TestGetEnableRoutes(c *check.C) {
}
h.db.Save(&m)
- availableRoutes, err := h.GetAdvertisedNodeRoutes("test", "test_enable_route_machine")
+ availableRoutes, err := h.GetAdvertisedNodeRoutes(
+ "test",
+ "test_enable_route_machine",
+ )
c.Assert(err, check.IsNil)
c.Assert(len(*availableRoutes), check.Equals, 2)
diff --git a/sharing.go b/sharing.go
index 5f6a8f4..581c2af 100644
--- a/sharing.go
+++ b/sharing.go
@@ -2,9 +2,11 @@ package headscale
import "gorm.io/gorm"
-const errorSameNamespace = Error("Destination namespace same as origin")
-const errorMachineAlreadyShared = Error("Node already shared to this namespace")
-const errorMachineNotShared = Error("Machine not shared to this namespace")
+const (
+ errorSameNamespace = Error("Destination namespace same as origin")
+ errorMachineAlreadyShared = Error("Node already shared to this namespace")
+ errorMachineNotShared = Error("Machine not shared to this namespace")
+)
// SharedMachine is a join table to support sharing nodes between namespaces
type SharedMachine struct {
@@ -48,7 +50,9 @@ func (h *Headscale) RemoveSharedMachineFromNamespace(m *Machine, ns *Namespace)
}
sharedMachine := SharedMachine{}
- result := h.db.Where("machine_id = ? AND namespace_id = ?", m.ID, ns.ID).Unscoped().Delete(&sharedMachine)
+ result := h.db.Where("machine_id = ? AND namespace_id = ?", m.ID, ns.ID).
+ Unscoped().
+ Delete(&sharedMachine)
if result.Error != nil {
return result.Error
}
diff --git a/sharing_test.go b/sharing_test.go
index 4d9e409..7d63a74 100644
--- a/sharing_test.go
+++ b/sharing_test.go
@@ -4,7 +4,10 @@ import (
"gopkg.in/check.v1"
)
-func CreateNodeNamespace(c *check.C, namespace, node, key, IP string) (*Namespace, *Machine) {
+func CreateNodeNamespace(
+ c *check.C,
+ namespace, node, key, IP string,
+) (*Namespace, *Machine) {
n1, err := h.CreateNamespace(namespace)
c.Assert(err, check.IsNil)
@@ -229,7 +232,11 @@ func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) {
p1sAfter, err := h.getPeers(m1)
c.Assert(err, check.IsNil)
- c.Assert(len(p1sAfter), check.Equals, 2) // node1 can see node2 (shared) and node4 (same namespace)
+ c.Assert(
+ len(p1sAfter),
+ check.Equals,
+ 2,
+ ) // node1 can see node2 (shared) and node4 (same namespace)
c.Assert(p1sAfter[0].Name, check.Equals, m2.Name)
c.Assert(p1sAfter[1].Name, check.Equals, m4.Name)
diff --git a/swagger.go b/swagger.go
index 17f5769..d3ae1b2 100644
--- a/swagger.go
+++ b/swagger.go
@@ -53,7 +53,11 @@ func SwaggerUI(c *gin.Context) {
Caller().
Err(err).
Msg("Could not render Swagger")
- c.Data(http.StatusInternalServerError, "text/html; charset=utf-8", []byte("Could not render Swagger"))
+ c.Data(
+ http.StatusInternalServerError,
+ "text/html; charset=utf-8",
+ []byte("Could not render Swagger"),
+ )
return
}
diff --git a/utils.go b/utils.go
index ad0a72d..0b76b5e 100644
--- a/utils.go
+++ b/utils.go
@@ -25,11 +25,21 @@ type Error string
func (e Error) Error() string { return string(e) }
-func decode(msg []byte, v interface{}, pubKey *wgkey.Key, privKey *wgkey.Private) error {
+func decode(
+ msg []byte,
+ v interface{},
+ pubKey *wgkey.Key,
+ privKey *wgkey.Private,
+) error {
return decodeMsg(msg, v, pubKey, privKey)
}
-func decodeMsg(msg []byte, v interface{}, pubKey *wgkey.Key, privKey *wgkey.Private) error {
+func decodeMsg(
+ msg []byte,
+ v interface{},
+ pubKey *wgkey.Key,
+ privKey *wgkey.Private,
+) error {
decrypted, err := decryptMsg(msg, pubKey, privKey)
if err != nil {
return err
@@ -156,7 +166,11 @@ func tailNodesToString(nodes []*tailcfg.Node) string {
}
func tailMapResponseToString(resp tailcfg.MapResponse) string {
- return fmt.Sprintf("{ Node: %s, Peers: %s }", resp.Node.Name, tailNodesToString(resp.Peers))
+ return fmt.Sprintf(
+ "{ Node: %s, Peers: %s }",
+ resp.Node.Name,
+ tailNodesToString(resp.Peers),
+ )
}
func GrpcSocketDialer(ctx context.Context, addr string) (net.Conn, error) {