mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-10-28 10:51:44 +01:00 
			
		
		
		
	Add and fix nlreturn (new line return)
This commit is contained in:
		
							parent
							
								
									d0ef850035
								
							
						
					
					
						commit
						89eb13c6cb
					
				| @ -30,7 +30,6 @@ linters: | ||||
|     - stylecheck | ||||
|     - wrapcheck | ||||
|     - paralleltest | ||||
|     - nlreturn | ||||
|     - ifshort | ||||
|     - gomnd | ||||
|     - goerr113 | ||||
|  | ||||
							
								
								
									
										9
									
								
								acls.go
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								acls.go
									
									
									
									
									
								
							| @ -58,6 +58,7 @@ func (h *Headscale) LoadACLPolicy(path string) error { | ||||
| 		return err | ||||
| 	} | ||||
| 	h.aclRules = rules | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -77,6 +78,7 @@ func (h *Headscale) generateACLRules() ([]tailcfg.FilterRule, error) { | ||||
| 			if err != nil { | ||||
| 				log.Error(). | ||||
| 					Msgf("Error parsing ACL %d, User %d", i, j) | ||||
| 
 | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			srcIPs = append(srcIPs, srcs...) | ||||
| @ -89,6 +91,7 @@ func (h *Headscale) generateACLRules() ([]tailcfg.FilterRule, error) { | ||||
| 			if err != nil { | ||||
| 				log.Error(). | ||||
| 					Msgf("Error parsing ACL %d, Port %d", i, j) | ||||
| 
 | ||||
| 				return nil, err | ||||
| 			} | ||||
| 			destPorts = append(destPorts, dests...) | ||||
| @ -147,6 +150,7 @@ func (h *Headscale) generateACLPolicyDestPorts( | ||||
| 			dests = append(dests, pr) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return dests, nil | ||||
| } | ||||
| 
 | ||||
| @ -169,6 +173,7 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { | ||||
| 				ips = append(ips, node.IPAddress) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return ips, nil | ||||
| 	} | ||||
| 
 | ||||
| @ -200,11 +205,13 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { | ||||
| 				for _, t := range hostinfo.RequestTags { | ||||
| 					if s[4:] == t { | ||||
| 						ips = append(ips, m.IPAddress) | ||||
| 
 | ||||
| 						break | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		return ips, nil | ||||
| 	} | ||||
| 
 | ||||
| @ -218,6 +225,7 @@ func (h *Headscale) expandAlias(s string) ([]string, error) { | ||||
| 		for _, n := range nodes { | ||||
| 			ips = append(ips, n.IPAddress) | ||||
| 		} | ||||
| 
 | ||||
| 		return ips, nil | ||||
| 	} | ||||
| 
 | ||||
| @ -272,5 +280,6 @@ func (h *Headscale) expandPorts(s string) (*[]tailcfg.PortRange, error) { | ||||
| 			return nil, errorInvalidPortFormat | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &ports, nil | ||||
| } | ||||
|  | ||||
| @ -65,6 +65,7 @@ func (h *Hosts) UnmarshalJSON(data []byte) error { | ||||
| 		hosts[k] = prefix | ||||
| 	} | ||||
| 	*h = hosts | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -73,5 +74,6 @@ func (p ACLPolicy) IsZero() bool { | ||||
| 	if len(p.Groups) == 0 && len(p.Hosts) == 0 && len(p.ACLs) == 0 { | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
|  | ||||
							
								
								
									
										24
									
								
								api.go
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								api.go
									
									
									
									
									
								
							| @ -30,6 +30,7 @@ func (h *Headscale) RegisterWebAPI(c *gin.Context) { | ||||
| 	mKeyStr := c.Query("key") | ||||
| 	if mKeyStr == "" { | ||||
| 		c.String(http.StatusBadRequest, "Wrong params") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -66,6 +67,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { | ||||
| 			Msg("Cannot parse machine key") | ||||
| 		machineRegistrations.WithLabelValues("unknown", "web", "error", "unknown").Inc() | ||||
| 		c.String(http.StatusInternalServerError, "Sad!") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 	req := tailcfg.RegisterRequest{} | ||||
| @ -77,6 +79,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { | ||||
| 			Msg("Cannot decode message") | ||||
| 		machineRegistrations.WithLabelValues("unknown", "web", "error", "unknown").Inc() | ||||
| 		c.String(http.StatusInternalServerError, "Very sad!") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -96,6 +99,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { | ||||
| 				Msg("Could not create row") | ||||
| 			machineRegistrations.WithLabelValues("unknown", "web", "error", m.Namespace.Name). | ||||
| 				Inc() | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 		m = &newMachine | ||||
| @ -103,6 +107,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { | ||||
| 
 | ||||
| 	if !m.Registered && req.Auth.AuthKey != "" { | ||||
| 		h.handleAuthKey(c, h.db, mKey, req, *m) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -131,9 +136,11 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { | ||||
| 					Err(err). | ||||
| 					Msg("Cannot encode message") | ||||
| 				c.String(http.StatusInternalServerError, "") | ||||
| 
 | ||||
| 				return | ||||
| 			} | ||||
| 			c.Data(200, "application/json; charset=utf-8", respBody) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -158,11 +165,13 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { | ||||
| 				machineRegistrations.WithLabelValues("update", "web", "error", m.Namespace.Name). | ||||
| 					Inc() | ||||
| 				c.String(http.StatusInternalServerError, "") | ||||
| 
 | ||||
| 				return | ||||
| 			} | ||||
| 			machineRegistrations.WithLabelValues("update", "web", "success", m.Namespace.Name). | ||||
| 				Inc() | ||||
| 			c.Data(200, "application/json; charset=utf-8", respBody) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -199,11 +208,13 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { | ||||
| 			machineRegistrations.WithLabelValues("new", "web", "error", m.Namespace.Name). | ||||
| 				Inc() | ||||
| 			c.String(http.StatusInternalServerError, "") | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 		machineRegistrations.WithLabelValues("new", "web", "success", m.Namespace.Name). | ||||
| 			Inc() | ||||
| 		c.Data(200, "application/json; charset=utf-8", respBody) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -225,9 +236,11 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { | ||||
| 				Err(err). | ||||
| 				Msg("Cannot encode message") | ||||
| 			c.String(http.StatusInternalServerError, "Extremely sad!") | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 		c.Data(200, "application/json; charset=utf-8", respBody) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -259,6 +272,7 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { | ||||
| 			Err(err). | ||||
| 			Msg("Cannot encode message") | ||||
| 		c.String(http.StatusInternalServerError, "") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 	c.Data(200, "application/json; charset=utf-8", respBody) | ||||
| @ -279,6 +293,7 @@ func (h *Headscale) getMapResponse( | ||||
| 			Str("func", "getMapResponse"). | ||||
| 			Err(err). | ||||
| 			Msg("Cannot convert to node") | ||||
| 
 | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| @ -288,6 +303,7 @@ func (h *Headscale) getMapResponse( | ||||
| 			Str("func", "getMapResponse"). | ||||
| 			Err(err). | ||||
| 			Msg("Cannot fetch peers") | ||||
| 
 | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| @ -299,6 +315,7 @@ func (h *Headscale) getMapResponse( | ||||
| 			Str("func", "getMapResponse"). | ||||
| 			Err(err). | ||||
| 			Msg("Failed to convert peers to Tailscale nodes") | ||||
| 
 | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| @ -313,6 +330,7 @@ func (h *Headscale) getMapResponse( | ||||
| 			Str("func", "getMapResponse"). | ||||
| 			Err(err). | ||||
| 			Msg("Failed generate the DNSConfig") | ||||
| 
 | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| @ -353,6 +371,7 @@ func (h *Headscale) getMapResponse( | ||||
| 	data := make([]byte, 4) | ||||
| 	binary.LittleEndian.PutUint32(data, uint32(len(respBody))) | ||||
| 	data = append(data, respBody...) | ||||
| 
 | ||||
| 	return data, nil | ||||
| } | ||||
| 
 | ||||
| @ -383,6 +402,7 @@ func (h *Headscale) getMapKeepAliveResponse( | ||||
| 	data := make([]byte, 4) | ||||
| 	binary.LittleEndian.PutUint32(data, uint32(len(respBody))) | ||||
| 	data = append(data, respBody...) | ||||
| 
 | ||||
| 	return data, nil | ||||
| } | ||||
| 
 | ||||
| @ -416,6 +436,7 @@ func (h *Headscale) handleAuthKey( | ||||
| 			c.String(http.StatusInternalServerError, "") | ||||
| 			machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). | ||||
| 				Inc() | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 		c.Data(401, "application/json; charset=utf-8", respBody) | ||||
| @ -425,6 +446,7 @@ func (h *Headscale) handleAuthKey( | ||||
| 			Msg("Failed authentication via AuthKey") | ||||
| 		machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). | ||||
| 			Inc() | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -440,6 +462,7 @@ func (h *Headscale) handleAuthKey( | ||||
| 			Msg("Failed to find an available IP") | ||||
| 		machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). | ||||
| 			Inc() | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 	log.Info(). | ||||
| @ -471,6 +494,7 @@ func (h *Headscale) handleAuthKey( | ||||
| 		machineRegistrations.WithLabelValues("new", "authkey", "error", m.Namespace.Name). | ||||
| 			Inc() | ||||
| 		c.String(http.StatusInternalServerError, "Extremely sad!") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 	machineRegistrations.WithLabelValues("new", "authkey", "success", m.Namespace.Name). | ||||
|  | ||||
							
								
								
									
										5
									
								
								app.go
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								app.go
									
									
									
									
									
								
							| @ -297,6 +297,7 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, | ||||
| 			Caller(). | ||||
| 			Str("client_address", p.Addr.String()). | ||||
| 			Msg("Retrieving metadata is failed") | ||||
| 
 | ||||
| 		return ctx, status.Errorf( | ||||
| 			codes.InvalidArgument, | ||||
| 			"Retrieving metadata is failed", | ||||
| @ -309,6 +310,7 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, | ||||
| 			Caller(). | ||||
| 			Str("client_address", p.Addr.String()). | ||||
| 			Msg("Authorization token is not supplied") | ||||
| 
 | ||||
| 		return ctx, status.Errorf( | ||||
| 			codes.Unauthenticated, | ||||
| 			"Authorization token is not supplied", | ||||
| @ -322,6 +324,7 @@ 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`, | ||||
| @ -392,6 +395,7 @@ func (h *Headscale) ensureUnixSocketIsAbsent() error { | ||||
| 	if _, err := os.Stat(h.cfg.UnixSocket); errors.Is(err, os.ErrNotExist) { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	return os.Remove(h.cfg.UnixSocket) | ||||
| } | ||||
| 
 | ||||
| @ -568,6 +572,7 @@ func (h *Headscale) Serve() error { | ||||
| 	if tlsConfig != nil { | ||||
| 		g.Go(func() error { | ||||
| 			tlsl := tls.NewListener(httpListener, tlsConfig) | ||||
| 
 | ||||
| 			return httpServer.Serve(tlsl) | ||||
| 		}) | ||||
| 	} else { | ||||
|  | ||||
| @ -77,6 +77,7 @@ func (h *Headscale) AppleMobileConfig(c *gin.Context) { | ||||
| 			"text/html; charset=utf-8", | ||||
| 			[]byte("Could not render Apple index template"), | ||||
| 		) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -97,6 +98,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { | ||||
| 			"text/html; charset=utf-8", | ||||
| 			[]byte("Failed to create UUID"), | ||||
| 		) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -111,6 +113,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { | ||||
| 			"text/html; charset=utf-8", | ||||
| 			[]byte("Failed to create UUID"), | ||||
| 		) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -133,6 +136,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { | ||||
| 				"text/html; charset=utf-8", | ||||
| 				[]byte("Could not render Apple macOS template"), | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 	case "ios": | ||||
| @ -146,6 +150,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { | ||||
| 				"text/html; charset=utf-8", | ||||
| 				[]byte("Could not render Apple iOS template"), | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 	default: | ||||
| @ -154,6 +159,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { | ||||
| 			"text/html; charset=utf-8", | ||||
| 			[]byte("Invalid platform, only ios and macos is supported"), | ||||
| 		) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -174,6 +180,7 @@ func (h *Headscale) ApplePlatformConfig(c *gin.Context) { | ||||
| 			"text/html; charset=utf-8", | ||||
| 			[]byte("Could not render Apple platform template"), | ||||
| 		) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -48,6 +48,7 @@ var createNodeCmd = &cobra.Command{ | ||||
| 		namespace, err := cmd.Flags().GetString("namespace") | ||||
| 		if err != nil { | ||||
| 			ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -62,6 +63,7 @@ var createNodeCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Error getting node from flag: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -72,6 +74,7 @@ var createNodeCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Error getting key from flag: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -82,6 +85,7 @@ var createNodeCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Error getting routes from flag: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -99,6 +103,7 @@ var createNodeCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Cannot create machine: %s", status.Convert(err).Message()), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -31,6 +31,7 @@ var createNamespaceCmd = &cobra.Command{ | ||||
| 		if len(args) < 1 { | ||||
| 			return fmt.Errorf("Missing parameters") | ||||
| 		} | ||||
| 
 | ||||
| 		return nil | ||||
| 	}, | ||||
| 	Run: func(cmd *cobra.Command, args []string) { | ||||
| @ -57,6 +58,7 @@ var createNamespaceCmd = &cobra.Command{ | ||||
| 				), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -71,6 +73,7 @@ var destroyNamespaceCmd = &cobra.Command{ | ||||
| 		if len(args) < 1 { | ||||
| 			return fmt.Errorf("Missing parameters") | ||||
| 		} | ||||
| 
 | ||||
| 		return nil | ||||
| 	}, | ||||
| 	Run: func(cmd *cobra.Command, args []string) { | ||||
| @ -93,6 +96,7 @@ var destroyNamespaceCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Error: %s", status.Convert(err).Message()), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -124,6 +128,7 @@ var destroyNamespaceCmd = &cobra.Command{ | ||||
| 					), | ||||
| 					output, | ||||
| 				) | ||||
| 
 | ||||
| 				return | ||||
| 			} | ||||
| 			SuccessOutput(response, "Namespace destroyed", output) | ||||
| @ -152,11 +157,13 @@ var listNamespacesCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Cannot get namespaces: %s", status.Convert(err).Message()), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		if output != "" { | ||||
| 			SuccessOutput(response.Namespaces, "", output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -178,6 +185,7 @@ var listNamespacesCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Failed to render pterm table: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 	}, | ||||
| @ -190,6 +198,7 @@ var renameNamespaceCmd = &cobra.Command{ | ||||
| 		if len(args) < 2 { | ||||
| 			return fmt.Errorf("Missing parameters") | ||||
| 		} | ||||
| 
 | ||||
| 		return nil | ||||
| 	}, | ||||
| 	Run: func(cmd *cobra.Command, args []string) { | ||||
| @ -214,6 +223,7 @@ var renameNamespaceCmd = &cobra.Command{ | ||||
| 				), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -77,6 +77,7 @@ var registerNodeCmd = &cobra.Command{ | ||||
| 		namespace, err := cmd.Flags().GetString("namespace") | ||||
| 		if err != nil { | ||||
| 			ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -91,6 +92,7 @@ var registerNodeCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Error getting machine key from flag: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -109,6 +111,7 @@ var registerNodeCmd = &cobra.Command{ | ||||
| 				), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -124,6 +127,7 @@ var listNodesCmd = &cobra.Command{ | ||||
| 		namespace, err := cmd.Flags().GetString("namespace") | ||||
| 		if err != nil { | ||||
| 			ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -142,17 +146,20 @@ var listNodesCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		if output != "" { | ||||
| 			SuccessOutput(response.Machines, "", output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		d, err := nodesToPtables(namespace, response.Machines) | ||||
| 		if err != nil { | ||||
| 			ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -163,6 +170,7 @@ var listNodesCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Failed to render pterm table: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 	}, | ||||
| @ -181,6 +189,7 @@ var deleteNodeCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Error converting ID to integer: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -202,6 +211,7 @@ var deleteNodeCmd = &cobra.Command{ | ||||
| 				), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -228,6 +238,7 @@ var deleteNodeCmd = &cobra.Command{ | ||||
| 			response, err := client.DeleteMachine(ctx, deleteRequest) | ||||
| 			if output != "" { | ||||
| 				SuccessOutput(response, "", output) | ||||
| 
 | ||||
| 				return | ||||
| 			} | ||||
| 			if err != nil { | ||||
| @ -239,6 +250,7 @@ var deleteNodeCmd = &cobra.Command{ | ||||
| 					), | ||||
| 					output, | ||||
| 				) | ||||
| 
 | ||||
| 				return | ||||
| 			} | ||||
| 			SuccessOutput( | ||||
| @ -260,6 +272,7 @@ func sharingWorker( | ||||
| 	namespaceStr, err := cmd.Flags().GetString("namespace") | ||||
| 	if err != nil { | ||||
| 		ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) | ||||
| 
 | ||||
| 		return "", nil, nil, err | ||||
| 	} | ||||
| 
 | ||||
| @ -270,6 +283,7 @@ func sharingWorker( | ||||
| 	id, err := cmd.Flags().GetInt("identifier") | ||||
| 	if err != nil { | ||||
| 		ErrorOutput(err, fmt.Sprintf("Error converting ID to integer: %s", err), output) | ||||
| 
 | ||||
| 		return "", nil, nil, err | ||||
| 	} | ||||
| 
 | ||||
| @ -284,6 +298,7 @@ func sharingWorker( | ||||
| 			fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), | ||||
| 			output, | ||||
| 		) | ||||
| 
 | ||||
| 		return "", nil, nil, err | ||||
| 	} | ||||
| 
 | ||||
| @ -298,6 +313,7 @@ func sharingWorker( | ||||
| 			fmt.Sprintf("Error getting node node: %s", status.Convert(err).Message()), | ||||
| 			output, | ||||
| 		) | ||||
| 
 | ||||
| 		return "", nil, nil, err | ||||
| 	} | ||||
| 
 | ||||
| @ -315,6 +331,7 @@ var shareMachineCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Failed to fetch namespace or machine: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -334,6 +351,7 @@ var shareMachineCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Error sharing node: %s", status.Convert(err).Message()), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -352,6 +370,7 @@ var unshareMachineCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Failed to fetch namespace or machine: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -371,6 +390,7 @@ var unshareMachineCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Error unsharing node: %s", status.Convert(err).Message()), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -442,5 +462,6 @@ func nodesToPtables( | ||||
| 			}, | ||||
| 		) | ||||
| 	} | ||||
| 
 | ||||
| 	return d, nil | ||||
| } | ||||
|  | ||||
| @ -44,6 +44,7 @@ var listPreAuthKeys = &cobra.Command{ | ||||
| 		n, err := cmd.Flags().GetString("namespace") | ||||
| 		if err != nil { | ||||
| 			ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -62,11 +63,13 @@ var listPreAuthKeys = &cobra.Command{ | ||||
| 				fmt.Sprintf("Error getting the list of keys: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		if output != "" { | ||||
| 			SuccessOutput(response.PreAuthKeys, "", output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -104,6 +107,7 @@ var listPreAuthKeys = &cobra.Command{ | ||||
| 				fmt.Sprintf("Failed to render pterm table: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 	}, | ||||
| @ -118,6 +122,7 @@ var createPreAuthKeyCmd = &cobra.Command{ | ||||
| 		namespace, err := cmd.Flags().GetString("namespace") | ||||
| 		if err != nil { | ||||
| 			ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -156,6 +161,7 @@ var createPreAuthKeyCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Cannot create Pre Auth Key: %s\n", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -170,6 +176,7 @@ var expirePreAuthKeyCmd = &cobra.Command{ | ||||
| 		if len(args) < 1 { | ||||
| 			return fmt.Errorf("missing parameters") | ||||
| 		} | ||||
| 
 | ||||
| 		return nil | ||||
| 	}, | ||||
| 	Run: func(cmd *cobra.Command, args []string) { | ||||
| @ -177,6 +184,7 @@ var expirePreAuthKeyCmd = &cobra.Command{ | ||||
| 		namespace, err := cmd.Flags().GetString("namespace") | ||||
| 		if err != nil { | ||||
| 			ErrorOutput(err, fmt.Sprintf("Error getting namespace: %s", err), output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -196,6 +204,7 @@ var expirePreAuthKeyCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Cannot expire Pre Auth Key: %s\n", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -52,6 +52,7 @@ var listRoutesCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Error getting machine id from flag: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -70,17 +71,20 @@ var listRoutesCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Cannot get nodes: %s", status.Convert(err).Message()), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		if output != "" { | ||||
| 			SuccessOutput(response.Routes, "", output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		d := routesToPtables(response.Routes) | ||||
| 		if err != nil { | ||||
| 			ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -91,6 +95,7 @@ var listRoutesCmd = &cobra.Command{ | ||||
| 				fmt.Sprintf("Failed to render pterm table: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 	}, | ||||
| @ -113,6 +118,7 @@ omit the route you do not want to enable. | ||||
| 				fmt.Sprintf("Error getting machine id from flag: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -123,6 +129,7 @@ omit the route you do not want to enable. | ||||
| 				fmt.Sprintf("Error getting routes from flag: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -145,17 +152,20 @@ omit the route you do not want to enable. | ||||
| 				), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		if output != "" { | ||||
| 			SuccessOutput(response.Routes, "", output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| 		d := routesToPtables(response.Routes) | ||||
| 		if err != nil { | ||||
| 			ErrorOutput(err, fmt.Sprintf("Error converting to table: %s", err), output) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 
 | ||||
| @ -166,6 +176,7 @@ omit the route you do not want to enable. | ||||
| 				fmt.Sprintf("Failed to render pterm table: %s", err), | ||||
| 				output, | ||||
| 			) | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 	}, | ||||
| @ -180,6 +191,7 @@ func routesToPtables(routes *v1.Routes) pterm.TableData { | ||||
| 
 | ||||
| 		d = append(d, []string{route, strconv.FormatBool(enabled)}) | ||||
| 	} | ||||
| 
 | ||||
| 	return d | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -213,6 +213,7 @@ func absPath(path string) string { | ||||
| 			path = filepath.Join(dir, path) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return path | ||||
| } | ||||
| 
 | ||||
| @ -310,6 +311,7 @@ func getHeadscaleApp() (*headscale.Headscale, error) { | ||||
| 			viper.GetString("ephemeral_node_inactivity_timeout"), | ||||
| 			minInactivityTimeout, | ||||
| 		) | ||||
| 
 | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| @ -415,6 +417,7 @@ func SuccessOutput(result interface{}, override string, outputFormat string) { | ||||
| 		} | ||||
| 	default: | ||||
| 		fmt.Println(override) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -435,6 +438,7 @@ func HasMachineOutputFlag() bool { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										4
									
								
								db.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								db.go
									
									
									
									
									
								
							| @ -50,6 +50,7 @@ func (h *Headscale) initDB() error { | ||||
| 	} | ||||
| 
 | ||||
| 	err = h.setValue("db_version", dbVersion) | ||||
| 
 | ||||
| 	return err | ||||
| } | ||||
| 
 | ||||
| @ -93,6 +94,7 @@ func (h *Headscale) getValue(key string) (string, error) { | ||||
| 	) { | ||||
| 		return "", errors.New("not found") | ||||
| 	} | ||||
| 
 | ||||
| 	return row.Value, nil | ||||
| } | ||||
| 
 | ||||
| @ -106,9 +108,11 @@ func (h *Headscale) setValue(key string, value string) error { | ||||
| 	_, err := h.getValue(key) | ||||
| 	if err == nil { | ||||
| 		h.db.Model(&kv).Where("key = ?", key).Update("value", value) | ||||
| 
 | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	h.db.Create(kv) | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
							
								
								
									
										4
									
								
								derp.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								derp.go
									
									
									
									
									
								
							| @ -27,6 +27,7 @@ func loadDERPMapFromPath(path string) (*tailcfg.DERPMap, error) { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	err = yaml.Unmarshal(b, &derpMap) | ||||
| 
 | ||||
| 	return &derpMap, err | ||||
| } | ||||
| 
 | ||||
| @ -56,6 +57,7 @@ func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) { | ||||
| 
 | ||||
| 	var derpMap tailcfg.DERPMap | ||||
| 	err = json.Unmarshal(body, &derpMap) | ||||
| 
 | ||||
| 	return &derpMap, err | ||||
| } | ||||
| 
 | ||||
| @ -94,6 +96,7 @@ func GetDERPMap(cfg DERPConfig) *tailcfg.DERPMap { | ||||
| 				Str("path", path). | ||||
| 				Err(err). | ||||
| 				Msg("Could not load DERP map from path") | ||||
| 
 | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| @ -112,6 +115,7 @@ func GetDERPMap(cfg DERPConfig) *tailcfg.DERPMap { | ||||
| 				Str("url", addr.String()). | ||||
| 				Err(err). | ||||
| 				Msg("Could not load DERP map from path") | ||||
| 
 | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										2
									
								
								dns.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								dns.go
									
									
									
									
									
								
							| @ -69,6 +69,7 @@ func generateMagicDNSRootDomains( | ||||
| 		} | ||||
| 		fqdns = append(fqdns, fqdn) | ||||
| 	} | ||||
| 
 | ||||
| 	return fqdns, nil | ||||
| } | ||||
| 
 | ||||
| @ -99,5 +100,6 @@ func getMapResponseDNSConfig( | ||||
| 	} else { | ||||
| 		dnsConfig = dnsConfigOrig | ||||
| 	} | ||||
| 
 | ||||
| 	return dnsConfig, nil | ||||
| } | ||||
|  | ||||
| @ -18,6 +18,7 @@ func (s *Suite) TestMagicDNSRootDomains100(c *check.C) { | ||||
| 	for _, domain := range domains { | ||||
| 		if domain == "64.100.in-addr.arpa." { | ||||
| 			found = true | ||||
| 
 | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| @ -27,6 +28,7 @@ func (s *Suite) TestMagicDNSRootDomains100(c *check.C) { | ||||
| 	for _, domain := range domains { | ||||
| 		if domain == "100.100.in-addr.arpa." { | ||||
| 			found = true | ||||
| 
 | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| @ -36,6 +38,7 @@ func (s *Suite) TestMagicDNSRootDomains100(c *check.C) { | ||||
| 	for _, domain := range domains { | ||||
| 		if domain == "127.100.in-addr.arpa." { | ||||
| 			found = true | ||||
| 
 | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| @ -51,6 +54,7 @@ func (s *Suite) TestMagicDNSRootDomains172(c *check.C) { | ||||
| 	for _, domain := range domains { | ||||
| 		if domain == "0.16.172.in-addr.arpa." { | ||||
| 			found = true | ||||
| 
 | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| @ -60,6 +64,7 @@ func (s *Suite) TestMagicDNSRootDomains172(c *check.C) { | ||||
| 	for _, domain := range domains { | ||||
| 		if domain == "255.16.172.in-addr.arpa." { | ||||
| 			found = true | ||||
| 
 | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										19
									
								
								machine.go
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								machine.go
									
									
									
									
									
								
							| @ -106,6 +106,7 @@ func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) { | ||||
| 	if err := h.db.Preload("Namespace").Where("namespace_id = ? AND machine_key <> ? AND registered", | ||||
| 		m.NamespaceID, m.MachineKey).Find(&machines).Error; err != nil { | ||||
| 		log.Error().Err(err).Msg("Error accessing db") | ||||
| 
 | ||||
| 		return Machines{}, err | ||||
| 	} | ||||
| 
 | ||||
| @ -115,6 +116,7 @@ func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) { | ||||
| 		Caller(). | ||||
| 		Str("machine", m.Name). | ||||
| 		Msgf("Found direct machines: %s", machines.String()) | ||||
| 
 | ||||
| 	return machines, nil | ||||
| } | ||||
| 
 | ||||
| @ -142,6 +144,7 @@ func (h *Headscale) getShared(m *Machine) (Machines, error) { | ||||
| 		Caller(). | ||||
| 		Str("machine", m.Name). | ||||
| 		Msgf("Found shared peers: %s", peers.String()) | ||||
| 
 | ||||
| 	return peers, nil | ||||
| } | ||||
| 
 | ||||
| @ -175,6 +178,7 @@ func (h *Headscale) getSharedTo(m *Machine) (Machines, error) { | ||||
| 		Caller(). | ||||
| 		Str("machine", m.Name). | ||||
| 		Msgf("Found peers we are shared with: %s", peers.String()) | ||||
| 
 | ||||
| 	return peers, nil | ||||
| } | ||||
| 
 | ||||
| @ -185,6 +189,7 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { | ||||
| 			Caller(). | ||||
| 			Err(err). | ||||
| 			Msg("Cannot fetch peers") | ||||
| 
 | ||||
| 		return Machines{}, err | ||||
| 	} | ||||
| 
 | ||||
| @ -194,6 +199,7 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { | ||||
| 			Caller(). | ||||
| 			Err(err). | ||||
| 			Msg("Cannot fetch peers") | ||||
| 
 | ||||
| 		return Machines{}, err | ||||
| 	} | ||||
| 
 | ||||
| @ -203,6 +209,7 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) { | ||||
| 			Caller(). | ||||
| 			Err(err). | ||||
| 			Msg("Cannot fetch peers") | ||||
| 
 | ||||
| 		return Machines{}, err | ||||
| 	} | ||||
| 
 | ||||
| @ -224,6 +231,7 @@ func (h *Headscale) ListMachines() ([]Machine, error) { | ||||
| 	if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Find(&machines).Error; err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return machines, nil | ||||
| } | ||||
| 
 | ||||
| @ -239,6 +247,7 @@ func (h *Headscale) GetMachine(namespace string, name string) (*Machine, error) | ||||
| 			return &m, nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil, fmt.Errorf("machine not found") | ||||
| } | ||||
| 
 | ||||
| @ -248,6 +257,7 @@ func (h *Headscale) GetMachineByID(id uint64) (*Machine, error) { | ||||
| 	if result := h.db.Preload("Namespace").Find(&Machine{ID: id}).First(&m); result.Error != nil { | ||||
| 		return nil, result.Error | ||||
| 	} | ||||
| 
 | ||||
| 	return &m, nil | ||||
| } | ||||
| 
 | ||||
| @ -257,6 +267,7 @@ func (h *Headscale) GetMachineByMachineKey(mKey string) (*Machine, error) { | ||||
| 	if result := h.db.Preload("Namespace").First(&m, "machine_key = ?", mKey); result.Error != nil { | ||||
| 		return nil, result.Error | ||||
| 	} | ||||
| 
 | ||||
| 	return &m, nil | ||||
| } | ||||
| 
 | ||||
| @ -266,6 +277,7 @@ func (h *Headscale) UpdateMachine(m *Machine) error { | ||||
| 	if result := h.db.Find(m).First(&m); result.Error != nil { | ||||
| 		return result.Error | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -314,6 +326,7 @@ func (m *Machine) GetHostInfo() (*tailcfg.Hostinfo, error) { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &hostinfo, nil | ||||
| } | ||||
| 
 | ||||
| @ -348,6 +361,7 @@ func (h *Headscale) isOutdated(m *Machine) bool { | ||||
| 		Time("last_successful_update", *m.LastSuccessfulUpdate). | ||||
| 		Time("last_state_change", lastChange). | ||||
| 		Msgf("Checking if %s is missing updates", m.Name) | ||||
| 
 | ||||
| 	return m.LastSuccessfulUpdate.Before(lastChange) | ||||
| } | ||||
| 
 | ||||
| @ -429,6 +443,7 @@ func (m Machine) toNode( | ||||
| 			Caller(). | ||||
| 			Str("ip", m.IPAddress). | ||||
| 			Msgf("Failed to parse IP Prefix from IP: %s", m.IPAddress) | ||||
| 
 | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	addrs = append(addrs, ip) // missing the ipv6 ?
 | ||||
| @ -530,6 +545,7 @@ func (m Machine) toNode( | ||||
| 		MachineAuthorized: m.Registered, | ||||
| 		Capabilities:      []string{tailcfg.CapabilityFileSharing}, | ||||
| 	} | ||||
| 
 | ||||
| 	return &n, nil | ||||
| } | ||||
| 
 | ||||
| @ -613,6 +629,7 @@ func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, err | ||||
| 			Err(err). | ||||
| 			Str("machine", m.Name). | ||||
| 			Msg("Could not find IP for the new machine") | ||||
| 
 | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| @ -642,6 +659,7 @@ func (m *Machine) GetAdvertisedRoutes() ([]netaddr.IPPrefix, error) { | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return hostInfo.RoutableIPs, nil | ||||
| } | ||||
| 
 | ||||
| @ -685,6 +703,7 @@ func (m *Machine) IsRoutesEnabled(routeStr string) bool { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -42,8 +42,10 @@ func (h *Headscale) CreateNamespace(name string) (*Namespace, error) { | ||||
| 			Str("func", "CreateNamespace"). | ||||
| 			Err(err). | ||||
| 			Msg("Could not create row") | ||||
| 
 | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return &n, nil | ||||
| } | ||||
| 
 | ||||
| @ -119,6 +121,7 @@ func (h *Headscale) GetNamespace(name string) (*Namespace, error) { | ||||
| 	) { | ||||
| 		return nil, errorNamespaceNotFound | ||||
| 	} | ||||
| 
 | ||||
| 	return &n, nil | ||||
| } | ||||
| 
 | ||||
| @ -128,6 +131,7 @@ func (h *Headscale) ListNamespaces() ([]Namespace, error) { | ||||
| 	if err := h.db.Find(&namespaces).Error; err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return namespaces, nil | ||||
| } | ||||
| 
 | ||||
| @ -142,6 +146,7 @@ func (h *Headscale) ListMachinesInNamespace(name string) ([]Machine, error) { | ||||
| 	if err := h.db.Preload("AuthKey").Preload("AuthKey.Namespace").Preload("Namespace").Where(&Machine{NamespaceID: n.ID}).Find(&machines).Error; err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return machines, nil | ||||
| } | ||||
| 
 | ||||
| @ -166,6 +171,7 @@ func (h *Headscale) ListSharedMachinesInNamespace(name string) ([]Machine, error | ||||
| 		} | ||||
| 		machines = append(machines, *machine) | ||||
| 	} | ||||
| 
 | ||||
| 	return machines, nil | ||||
| } | ||||
| 
 | ||||
| @ -177,6 +183,7 @@ func (h *Headscale) SetMachineNamespace(m *Machine, namespaceName string) error | ||||
| 	} | ||||
| 	m.NamespaceID = n.ID | ||||
| 	h.db.Save(&m) | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -196,6 +203,7 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error { | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		return nil | ||||
| 	} | ||||
| 	names := []string{} | ||||
| @ -208,6 +216,7 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error { | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| @ -218,8 +227,10 @@ func (h *Headscale) RequestMapUpdates(namespaceID uint) error { | ||||
| 			Str("func", "RequestMapUpdates"). | ||||
| 			Err(err). | ||||
| 			Msg("Could not marshal namespaces_pending_updates") | ||||
| 
 | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return h.setValue("namespaces_pending_updates", string(data)) | ||||
| } | ||||
| 
 | ||||
| @ -255,6 +266,7 @@ func (h *Headscale) checkForNamespacesPendingUpdates() { | ||||
| 				Str("func", "checkForNamespacesPendingUpdates"). | ||||
| 				Err(err). | ||||
| 				Msg("Could not save to KV") | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| @ -270,6 +282,7 @@ func (n *Namespace) toUser() *tailcfg.User { | ||||
| 		Logins:        []tailcfg.LoginID{}, | ||||
| 		Created:       time.Time{}, | ||||
| 	} | ||||
| 
 | ||||
| 	return &u | ||||
| } | ||||
| 
 | ||||
| @ -281,6 +294,7 @@ func (n *Namespace) toLogin() *tailcfg.Login { | ||||
| 		ProfilePicURL: "", | ||||
| 		Domain:        "headscale.net", | ||||
| 	} | ||||
| 
 | ||||
| 	return &l | ||||
| } | ||||
| 
 | ||||
| @ -300,6 +314,7 @@ func getMapResponseUserProfiles(m Machine, peers Machines) []tailcfg.UserProfile | ||||
| 				DisplayName: namespace.Name, | ||||
| 			}) | ||||
| 	} | ||||
| 
 | ||||
| 	return profiles | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -199,6 +199,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { | ||||
| 	for _, up := range userProfiles { | ||||
| 		if up.DisplayName == n1.Name { | ||||
| 			found = true | ||||
| 
 | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| @ -208,6 +209,7 @@ func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { | ||||
| 	for _, up := range userProfiles { | ||||
| 		if up.DisplayName == n2.Name { | ||||
| 			found = true | ||||
| 
 | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										13
									
								
								oidc.go
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								oidc.go
									
									
									
									
									
								
							| @ -32,6 +32,7 @@ func (h *Headscale) initOIDC() error { | ||||
| 
 | ||||
| 		if err != nil { | ||||
| 			log.Error().Msgf("Could not retrieve OIDC Config: %s", err.Error()) | ||||
| 
 | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| @ -62,6 +63,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { | ||||
| 	mKeyStr := c.Param("mkey") | ||||
| 	if mKeyStr == "" { | ||||
| 		c.String(http.StatusBadRequest, "Wrong params") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -70,6 +72,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { | ||||
| 	if err != nil { | ||||
| 		log.Error().Msg("could not read 16 bytes from rand") | ||||
| 		c.String(http.StatusInternalServerError, "could not read 16 bytes from rand") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -95,12 +98,14 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { | ||||
| 
 | ||||
| 	if code == "" || state == "" { | ||||
| 		c.String(http.StatusBadRequest, "Wrong params") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	oauth2Token, err := h.oauth2Config.Exchange(context.Background(), code) | ||||
| 	if err != nil { | ||||
| 		c.String(http.StatusBadRequest, "Could not exchange code for token") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -109,6 +114,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { | ||||
| 	rawIDToken, rawIDTokenOK := oauth2Token.Extra("id_token").(string) | ||||
| 	if !rawIDTokenOK { | ||||
| 		c.String(http.StatusBadRequest, "Could not extract ID Token") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -117,6 +123,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { | ||||
| 	idToken, err := verifier.Verify(context.Background(), rawIDToken) | ||||
| 	if err != nil { | ||||
| 		c.String(http.StatusBadRequest, "Failed to verify id token: %s", err.Error()) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -134,6 +141,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { | ||||
| 			http.StatusBadRequest, | ||||
| 			fmt.Sprintf("Failed to decode id token claims: %s", err), | ||||
| 		) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -144,6 +152,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { | ||||
| 		log.Error(). | ||||
| 			Msg("requested machine state key expired before authorisation completed") | ||||
| 		c.String(http.StatusBadRequest, "state has expired") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 	mKeyStr, mKeyOK := mKeyIf.(string) | ||||
| @ -151,6 +160,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { | ||||
| 	if !mKeyOK { | ||||
| 		log.Error().Msg("could not get machine key from cache") | ||||
| 		c.String(http.StatusInternalServerError, "could not get machine key from cache") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -162,6 +172,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { | ||||
| 			http.StatusInternalServerError, | ||||
| 			"could not get machine info from database", | ||||
| 		) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -183,6 +194,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { | ||||
| 						http.StatusInternalServerError, | ||||
| 						"could not create new namespace", | ||||
| 					) | ||||
| 
 | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
| @ -193,6 +205,7 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { | ||||
| 					http.StatusInternalServerError, | ||||
| 					"could not get an IP from the pool", | ||||
| 				) | ||||
| 
 | ||||
| 				return | ||||
| 			} | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										14
									
								
								poll.go
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								poll.go
									
									
									
									
									
								
							| @ -38,6 +38,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { | ||||
| 			Err(err). | ||||
| 			Msg("Cannot parse client key") | ||||
| 		c.String(http.StatusBadRequest, "") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 	req := tailcfg.MapRequest{} | ||||
| @ -48,6 +49,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { | ||||
| 			Err(err). | ||||
| 			Msg("Cannot decode message") | ||||
| 		c.String(http.StatusBadRequest, "") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -58,6 +60,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { | ||||
| 				Str("handler", "PollNetMap"). | ||||
| 				Msgf("Ignoring request, cannot find machine with key %s", mKey.HexString()) | ||||
| 			c.String(http.StatusUnauthorized, "") | ||||
| 
 | ||||
| 			return | ||||
| 		} | ||||
| 		log.Error(). | ||||
| @ -101,6 +104,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { | ||||
| 			Err(err). | ||||
| 			Msg("Failed to get Map response") | ||||
| 		c.String(http.StatusInternalServerError, ":(") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -124,6 +128,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { | ||||
| 			Str("machine", m.Name). | ||||
| 			Msg("Client is starting up. Probably interested in a DERP map") | ||||
| 		c.Data(200, "application/json; charset=utf-8", data) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -161,6 +166,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { | ||||
| 		updateRequestsFromNode.WithLabelValues(m.Name, m.Namespace.Name, "endpoint-update"). | ||||
| 			Inc() | ||||
| 		go func() { updateChan <- struct{}{} }() | ||||
| 
 | ||||
| 		return | ||||
| 	} else if req.OmitPeers && req.Stream { | ||||
| 		log.Warn(). | ||||
| @ -168,6 +174,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { | ||||
| 			Str("machine", m.Name). | ||||
| 			Msg("Ignoring request, don't know how to handle it") | ||||
| 		c.String(http.StatusBadRequest, "") | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| @ -248,6 +255,7 @@ func (h *Headscale) PollNetMapStream( | ||||
| 					Str("channel", "pollData"). | ||||
| 					Err(err). | ||||
| 					Msg("Cannot write data") | ||||
| 
 | ||||
| 				return false | ||||
| 			} | ||||
| 			log.Trace(). | ||||
| @ -282,6 +290,7 @@ func (h *Headscale) PollNetMapStream( | ||||
| 				Str("channel", "pollData"). | ||||
| 				Int("bytes", len(data)). | ||||
| 				Msg("Machine entry in database updated successfully after sending pollData") | ||||
| 
 | ||||
| 			return true | ||||
| 
 | ||||
| 		case data := <-keepAliveChan: | ||||
| @ -299,6 +308,7 @@ func (h *Headscale) PollNetMapStream( | ||||
| 					Str("channel", "keepAlive"). | ||||
| 					Err(err). | ||||
| 					Msg("Cannot write keep alive message") | ||||
| 
 | ||||
| 				return false | ||||
| 			} | ||||
| 			log.Trace(). | ||||
| @ -328,6 +338,7 @@ func (h *Headscale) PollNetMapStream( | ||||
| 				Str("channel", "keepAlive"). | ||||
| 				Int("bytes", len(data)). | ||||
| 				Msg("Machine updated successfully after sending keep alive") | ||||
| 
 | ||||
| 			return true | ||||
| 
 | ||||
| 		case <-updateChan: | ||||
| @ -364,6 +375,7 @@ func (h *Headscale) PollNetMapStream( | ||||
| 						Msg("Could not write the map response") | ||||
| 					updateRequestsSentToNode.WithLabelValues(m.Name, m.Namespace.Name, "failed"). | ||||
| 						Inc() | ||||
| 
 | ||||
| 					return false | ||||
| 				} | ||||
| 				log.Trace(). | ||||
| @ -405,6 +417,7 @@ func (h *Headscale) PollNetMapStream( | ||||
| 					Time("last_state_change", h.getLastStateChange(m.Namespace.Name)). | ||||
| 					Msgf("%s is up to date", m.Name) | ||||
| 			} | ||||
| 
 | ||||
| 			return true | ||||
| 
 | ||||
| 		case <-c.Request.Context().Done(): | ||||
| @ -485,6 +498,7 @@ func (h *Headscale) scheduledPollWorker( | ||||
| 					Str("func", "keepAlive"). | ||||
| 					Err(err). | ||||
| 					Msg("Error generating the keep alive msg") | ||||
| 
 | ||||
| 				return | ||||
| 			} | ||||
| 
 | ||||
|  | ||||
| @ -75,6 +75,7 @@ func (h *Headscale) ListPreAuthKeys(namespaceName string) ([]PreAuthKey, error) | ||||
| 	if err := h.db.Preload("Namespace").Where(&PreAuthKey{NamespaceID: n.ID}).Find(&keys).Error; err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return keys, nil | ||||
| } | ||||
| 
 | ||||
| @ -107,6 +108,7 @@ func (h *Headscale) ExpirePreAuthKey(k *PreAuthKey) error { | ||||
| 	if err := h.db.Model(&k).Update("Expiration", time.Now()).Error; err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -147,6 +149,7 @@ func (h *Headscale) generateKey() (string, error) { | ||||
| 	if _, err := rand.Read(bytes); err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 
 | ||||
| 	return hex.EncodeToString(bytes), nil | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -24,6 +24,7 @@ func (h *Headscale) GetAdvertisedNodeRoutes( | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return &hostInfo.RoutableIPs, nil | ||||
| } | ||||
| 
 | ||||
| @ -84,6 +85,7 @@ func (h *Headscale) IsNodeRouteEnabled( | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -57,6 +57,7 @@ func SwaggerUI(c *gin.Context) { | ||||
| 			"text/html; charset=utf-8", | ||||
| 			[]byte("Could not render Swagger"), | ||||
| 		) | ||||
| 
 | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										6
									
								
								utils.go
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								utils.go
									
									
									
									
									
								
							| @ -48,6 +48,7 @@ func decodeMsg( | ||||
| 	if err := json.Unmarshal(decrypted, v); err != nil { | ||||
| 		return fmt.Errorf("response: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| @ -64,6 +65,7 @@ func decryptMsg(msg []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("cannot decrypt response") | ||||
| 	} | ||||
| 
 | ||||
| 	return decrypted, nil | ||||
| } | ||||
| 
 | ||||
| @ -83,6 +85,7 @@ func encodeMsg(b []byte, pubKey *wgkey.Key, privKey *wgkey.Private) ([]byte, err | ||||
| 	} | ||||
| 	pub, pri := (*[32]byte)(pubKey), (*[32]byte)(privKey) | ||||
| 	msg := box.Seal(nonce[:], b, &nonce, pub, pri) | ||||
| 
 | ||||
| 	return msg, nil | ||||
| } | ||||
| 
 | ||||
| @ -108,12 +111,14 @@ func (h *Headscale) getAvailableIP() (*netaddr.IP, error) { | ||||
| 		ipRaw := ip.As4() | ||||
| 		if ipRaw[3] == 0 || ipRaw[3] == 255 { | ||||
| 			ip = ip.Next() | ||||
| 
 | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		if ip.IsZero() && | ||||
| 			ip.IsLoopback() { | ||||
| 			ip = ip.Next() | ||||
| 
 | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| @ -174,6 +179,7 @@ func tailMapResponseToString(resp tailcfg.MapResponse) string { | ||||
| 
 | ||||
| func GrpcSocketDialer(ctx context.Context, addr string) (net.Conn, error) { | ||||
| 	var d net.Dialer | ||||
| 
 | ||||
| 	return d.DialContext(ctx, "unix", addr) | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user