diff --git a/acls.go b/acls.go index 0e01514..9ce08a1 100644 --- a/acls.go +++ b/acls.go @@ -9,7 +9,6 @@ import ( "strings" "github.com/rs/zerolog/log" - "github.com/tailscale/hujson" "inet.af/netaddr" "tailscale.com/tailcfg" @@ -25,7 +24,7 @@ const ( errorInvalidPortFormat = Error("invalid port format") ) -// LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules +// LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules. func (h *Headscale) LoadACLPolicy(path string) error { policyFile, err := os.Open(path) if err != nil { diff --git a/acls_types.go b/acls_types.go index 67b74e7..91c9a44 100644 --- a/acls_types.go +++ b/acls_types.go @@ -8,7 +8,7 @@ import ( "inet.af/netaddr" ) -// ACLPolicy represents a Tailscale ACL Policy +// ACLPolicy represents a Tailscale ACL Policy. type ACLPolicy struct { Groups Groups `json:"Groups"` Hosts Hosts `json:"Hosts"` @@ -17,30 +17,30 @@ type ACLPolicy struct { Tests []ACLTest `json:"Tests"` } -// ACL is a basic rule for the ACL Policy +// ACL is a basic rule for the ACL Policy. type ACL struct { Action string `json:"Action"` Users []string `json:"Users"` Ports []string `json:"Ports"` } -// Groups references a series of alias in the ACL rules +// Groups references a series of alias in the ACL rules. type Groups map[string][]string -// Hosts are alias for IP addresses or subnets +// Hosts are alias for IP addresses or subnets. type Hosts map[string]netaddr.IPPrefix -// TagOwners specify what users (namespaces?) are allow to use certain tags +// TagOwners specify what users (namespaces?) are allow to use certain tags. type TagOwners map[string][]string -// ACLTest is not implemented, but should be use to check if a certain rule is allowed +// ACLTest is not implemented, but should be use to check if a certain rule is allowed. type ACLTest struct { User string `json:"User"` Allow []string `json:"Allow"` Deny []string `json:"Deny,omitempty"` } -// UnmarshalJSON allows to parse the Hosts directly into netaddr objects +// UnmarshalJSON allows to parse the Hosts directly into netaddr objects. func (h *Hosts) UnmarshalJSON(data []byte) error { hosts := Hosts{} hs := make(map[string]string) @@ -68,7 +68,7 @@ func (h *Hosts) UnmarshalJSON(data []byte) error { return nil } -// IsZero is perhaps a bit naive here +// IsZero is perhaps a bit naive here. func (p ACLPolicy) IsZero() bool { if len(p.Groups) == 0 && len(p.Hosts) == 0 && len(p.ACLs) == 0 { return true diff --git a/api.go b/api.go index 25851d8..bd6b80c 100644 --- a/api.go +++ b/api.go @@ -10,23 +10,22 @@ import ( "strings" "time" - "github.com/rs/zerolog/log" - "github.com/gin-gonic/gin" "github.com/klauspost/compress/zstd" + "github.com/rs/zerolog/log" "gorm.io/gorm" "tailscale.com/tailcfg" "tailscale.com/types/wgkey" ) // KeyHandler provides the Headscale pub key -// Listens in /key +// Listens in /key. func (h *Headscale) KeyHandler(c *gin.Context) { c.Data(200, "text/plain; charset=utf-8", []byte(h.publicKey.HexString())) } // RegisterWebAPI shows a simple message in the browser to point to the CLI -// Listens in /register +// Listens in /register. func (h *Headscale) RegisterWebAPI(c *gin.Context) { mKeyStr := c.Query("key") if mKeyStr == "" { @@ -55,7 +54,7 @@ func (h *Headscale) RegisterWebAPI(c *gin.Context) { } // RegistrationHandler handles the actual registration process of a machine -// Endpoint /machine/:id +// Endpoint /machine/:id. func (h *Headscale) RegistrationHandler(c *gin.Context) { body, _ := io.ReadAll(c.Request.Body) mKeyStr := c.Param("id") @@ -111,7 +110,6 @@ func (h *Headscale) RegistrationHandler(c *gin.Context) { // We have the updated key! if m.NodeKey == wgkey.Key(req.NodeKey).HexString() { - // The client sends an Expiry in the past if the client is requesting to expire the key (aka logout) // https://github.com/tailscale/tailscale/blob/main/tailcfg/tailcfg.go#L648 if !req.Expiry.IsZero() && req.Expiry.UTC().Before(now) { diff --git a/app.go b/app.go index 94181ac..73fec92 100644 --- a/app.go +++ b/app.go @@ -18,20 +18,19 @@ import ( "time" "github.com/coreos/go-oidc/v3/oidc" - "github.com/patrickmn/go-cache" - "golang.org/x/oauth2" - "github.com/gin-gonic/gin" - "github.com/grpc-ecosystem/go-grpc-middleware" + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" v1 "github.com/juanfont/headscale/gen/go/headscale/v1" - "github.com/philip-bui/grpc-zerolog" + "github.com/patrickmn/go-cache" + zerolog "github.com/philip-bui/grpc-zerolog" zl "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/soheilhy/cmux" ginprometheus "github.com/zsais/go-gin-prometheus" "golang.org/x/crypto/acme" "golang.org/x/crypto/acme/autocert" + "golang.org/x/oauth2" "golang.org/x/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -280,7 +279,6 @@ func (h *Headscale) grpcAuthenticationInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - // Check if the request is coming from the on-server client. // This is not secure, but it is to maintain maintainability // with the "legacy" database-based client diff --git a/apple_mobileconfig.go b/apple_mobileconfig.go index 6ddd5be..3629daa 100644 --- a/apple_mobileconfig.go +++ b/apple_mobileconfig.go @@ -5,14 +5,13 @@ import ( "net/http" "text/template" - "github.com/rs/zerolog/log" - "github.com/gin-gonic/gin" "github.com/gofrs/uuid" + "github.com/rs/zerolog/log" ) // AppleMobileConfig shows a simple message in the browser to point to the CLI -// Listens in /register +// Listens in /register. func (h *Headscale) AppleMobileConfig(c *gin.Context) { t := template.Must(template.New("apple").Parse(` diff --git a/cmd/headscale/cli/routes.go b/cmd/headscale/cli/routes.go index e6c80fb..1a0ff2a 100644 --- a/cmd/headscale/cli/routes.go +++ b/cmd/headscale/cli/routes.go @@ -171,7 +171,7 @@ omit the route you do not want to enable. }, } -// routesToPtables converts the list of routes to a nice table +// routesToPtables converts the list of routes to a nice table. func routesToPtables(routes *v1.Routes) pterm.TableData { d := pterm.TableData{{"Route", "Enabled"}} diff --git a/cmd/headscale/cli/utils.go b/cmd/headscale/cli/utils.go index 16b236a..f446323 100644 --- a/cmd/headscale/cli/utils.go +++ b/cmd/headscale/cli/utils.go @@ -355,7 +355,6 @@ func getHeadscaleCLIClient() (context.Context, v1.HeadscaleServiceClient, *grpc. // If the address is not set, we assume that we are on the server hosting headscale. if address == "" { - log.Debug(). Str("socket", cfg.UnixSocket). Msgf("HEADSCALE_CLI_ADDRESS environment is not set, connecting to unix socket.") diff --git a/db.go b/db.go index 60e2f6f..d3ef683 100644 --- a/db.go +++ b/db.go @@ -84,7 +84,7 @@ func (h *Headscale) openDB() (*gorm.DB, error) { return db, nil } -// getValue returns the value for the given key in KV +// 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( @@ -96,7 +96,7 @@ func (h *Headscale) getValue(key string) (string, error) { return row.Value, nil } -// setValue sets value for the given key in KV +// setValue sets value for the given key in KV. func (h *Headscale) setValue(key string, value string) error { kv := KV{ Key: key, diff --git a/derp.go b/derp.go index 7f65832..422b1e6 100644 --- a/derp.go +++ b/derp.go @@ -10,9 +10,7 @@ import ( "time" "github.com/rs/zerolog/log" - "gopkg.in/yaml.v2" - "tailscale.com/tailcfg" ) @@ -55,7 +53,7 @@ func loadDERPMapFromURL(addr url.URL) (*tailcfg.DERPMap, error) { // DERPMap, it will _only_ look at the Regions, an integer. // If a region exists in two of the given DERPMaps, the region // form the _last_ DERPMap will be preserved. -// An empty DERPMap list will result in a DERPMap with no regions +// An empty DERPMap list will result in a DERPMap with no regions. func mergeDERPMaps(derpMaps []*tailcfg.DERPMap) *tailcfg.DERPMap { result := tailcfg.DERPMap{ OmitDefaultRegions: false, diff --git a/machine.go b/machine.go index d0c07d0..8ff0b35 100644 --- a/machine.go +++ b/machine.go @@ -10,10 +10,9 @@ import ( "time" "github.com/fatih/set" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "github.com/rs/zerolog/log" "google.golang.org/protobuf/types/known/timestamppb" - - v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "gorm.io/datatypes" "gorm.io/gorm" "inet.af/netaddr" @@ -21,7 +20,7 @@ import ( "tailscale.com/types/wgkey" ) -// Machine is a Headscale client +// Machine is a Headscale client. type Machine struct { ID uint64 `gorm:"primary_key"` MachineKey string `gorm:"type:varchar(64);unique_index"` @@ -56,12 +55,12 @@ type ( MachinesP []*Machine ) -// For the time being this method is rather naive +// For the time being this method is rather naive. func (m Machine) isAlreadyRegistered() bool { return m.Registered } -// isExpired returns whether the machine registration has expired +// isExpired returns whether the machine registration has expired. func (m Machine) isExpired() bool { return time.Now().UTC().After(*m.Expiry) } @@ -119,7 +118,7 @@ func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) { return machines, nil } -// getShared fetches machines that are shared to the `Namespace` of the machine we are getting peers for +// getShared fetches machines that are shared to the `Namespace` of the machine we are getting peers for. func (h *Headscale) getShared(m *Machine) (Machines, error) { log.Trace(). Caller(). @@ -146,7 +145,7 @@ func (h *Headscale) getShared(m *Machine) (Machines, error) { return peers, nil } -// getSharedTo fetches the machines of the namespaces this machine is shared in +// getSharedTo fetches the machines of the namespaces this machine is shared in. func (h *Headscale) getSharedTo(m *Machine) (Machines, error) { log.Trace(). Caller(). @@ -228,7 +227,7 @@ func (h *Headscale) ListMachines() ([]Machine, error) { return machines, nil } -// GetMachine finds a Machine by name and namespace and returns the Machine struct +// GetMachine finds a Machine by name and namespace and returns the Machine struct. func (h *Headscale) GetMachine(namespace string, name string) (*Machine, error) { machines, err := h.ListMachinesInNamespace(namespace) if err != nil { @@ -243,7 +242,7 @@ func (h *Headscale) GetMachine(namespace string, name string) (*Machine, error) return nil, fmt.Errorf("machine not found") } -// GetMachineByID finds a Machine by ID and returns the Machine struct +// GetMachineByID finds a Machine by ID and returns the Machine struct. func (h *Headscale) GetMachineByID(id uint64) (*Machine, error) { m := Machine{} if result := h.db.Preload("Namespace").Find(&Machine{ID: id}).First(&m); result.Error != nil { @@ -252,7 +251,7 @@ func (h *Headscale) GetMachineByID(id uint64) (*Machine, error) { return &m, nil } -// GetMachineByMachineKey finds a Machine by ID and returns the Machine struct +// GetMachineByMachineKey finds a Machine by ID and returns the Machine struct. func (h *Headscale) GetMachineByMachineKey(mKey string) (*Machine, error) { m := Machine{} if result := h.db.Preload("Namespace").First(&m, "machine_key = ?", mKey); result.Error != nil { @@ -270,7 +269,7 @@ func (h *Headscale) UpdateMachine(m *Machine) error { return nil } -// DeleteMachine softs deletes a Machine from the database +// DeleteMachine softs deletes a Machine from the database. func (h *Headscale) DeleteMachine(m *Machine) error { err := h.RemoveSharedMachineFromAllNamespaces(m) if err != nil && err != errorMachineNotShared { @@ -287,7 +286,7 @@ func (h *Headscale) DeleteMachine(m *Machine) error { return h.RequestMapUpdates(namespaceID) } -// HardDeleteMachine hard deletes a Machine from the database +// HardDeleteMachine hard deletes a Machine from the database. func (h *Headscale) HardDeleteMachine(m *Machine) error { err := h.RemoveSharedMachineFromAllNamespaces(m) if err != nil && err != errorMachineNotShared { @@ -302,7 +301,7 @@ func (h *Headscale) HardDeleteMachine(m *Machine) error { return h.RequestMapUpdates(namespaceID) } -// GetHostInfo returns a Hostinfo struct for the machine +// GetHostInfo returns a Hostinfo struct for the machine. func (m *Machine) GetHostInfo() (*tailcfg.Hostinfo, error) { hostinfo := tailcfg.Hostinfo{} if len(m.HostInfo) != 0 { @@ -397,7 +396,7 @@ 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 +// as per the expected behaviour in the official SaaS. func (m Machine) toNode( baseDomain string, dnsConfig *tailcfg.DNSConfig, @@ -572,7 +571,7 @@ func (m *Machine) toProto() *v1.Machine { return machine } -// RegisterMachine is executed from the CLI to register a new Machine using its MachineKey +// RegisterMachine is executed from the CLI to register a new Machine using its MachineKey. func (h *Headscale) RegisterMachine(key string, namespace string) (*Machine, error) { ns, err := h.GetNamespace(namespace) if err != nil { diff --git a/namespaces.go b/namespaces.go index 59a8e2e..d54e117 100644 --- a/namespaces.go +++ b/namespaces.go @@ -30,7 +30,7 @@ type Namespace struct { } // CreateNamespace creates a new Namespace. Returns error if could not be created -// or another namespace already exists +// or another namespace already exists. func (h *Headscale) CreateNamespace(name string) (*Namespace, error) { n := Namespace{} if err := h.db.Where("name = ?", name).First(&n).Error; err == nil { @@ -99,7 +99,7 @@ func (h *Headscale) RenameNamespace(oldName, newName string) error { return nil } -// GetNamespace fetches a namespace by name +// 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( @@ -111,7 +111,7 @@ func (h *Headscale) GetNamespace(name string) (*Namespace, error) { return &n, nil } -// ListNamespaces gets all the existing namespaces +// ListNamespaces gets all the existing namespaces. func (h *Headscale) ListNamespaces() ([]Namespace, error) { namespaces := []Namespace{} if err := h.db.Find(&namespaces).Error; err != nil { @@ -120,7 +120,7 @@ func (h *Headscale) ListNamespaces() ([]Namespace, error) { return namespaces, nil } -// ListMachinesInNamespace gets all the nodes in a given namespace +// ListMachinesInNamespace gets all the nodes in a given namespace. func (h *Headscale) ListMachinesInNamespace(name string) ([]Machine, error) { n, err := h.GetNamespace(name) if err != nil { @@ -134,7 +134,7 @@ func (h *Headscale) ListMachinesInNamespace(name string) ([]Machine, error) { return machines, nil } -// ListSharedMachinesInNamespace returns all the machines that are shared to the specified namespace +// ListSharedMachinesInNamespace returns all the machines that are shared to the specified namespace. func (h *Headscale) ListSharedMachinesInNamespace(name string) ([]Machine, error) { namespace, err := h.GetNamespace(name) if err != nil { @@ -158,7 +158,7 @@ func (h *Headscale) ListSharedMachinesInNamespace(name string) ([]Machine, error return machines, nil } -// SetMachineNamespace assigns a Machine to a namespace +// SetMachineNamespace assigns a Machine to a namespace. func (h *Headscale) SetMachineNamespace(m *Machine, namespaceName string) error { n, err := h.GetNamespace(namespaceName) if err != nil { @@ -169,7 +169,7 @@ func (h *Headscale) SetMachineNamespace(m *Machine, namespaceName string) error return nil } -// RequestMapUpdates signals the KV worker to update the maps for this namespace +// RequestMapUpdates signals the KV worker to update the maps for this namespace. func (h *Headscale) RequestMapUpdates(namespaceID uint) error { namespace := Namespace{} if err := h.db.First(&namespace, namespaceID).Error; err != nil { diff --git a/oidc.go b/oidc.go index c3f7c2e..49ed1b3 100644 --- a/oidc.go +++ b/oidc.go @@ -57,7 +57,7 @@ func (h *Headscale) initOIDC() error { // RegisterOIDC redirects to the OIDC provider for authentication // Puts machine key in cache so the callback can retrieve it using the oidc state param -// Listens in /oidc/register/:mKey +// Listens in /oidc/register/:mKey. func (h *Headscale) RegisterOIDC(c *gin.Context) { mKeyStr := c.Param("mkey") if mKeyStr == "" { @@ -88,7 +88,7 @@ func (h *Headscale) RegisterOIDC(c *gin.Context) { // Retrieves the mkey from the state cache and adds the machine to the users email namespace // TODO: A confirmation page for new machines should be added to avoid phishing vulnerabilities // TODO: Add groups information from OIDC tokens into machine HostInfo -// Listens in /oidc/callback +// Listens in /oidc/callback. func (h *Headscale) OIDCCallback(c *gin.Context) { code := c.Query("code") state := c.Query("state") @@ -170,7 +170,6 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { if nsName, ok := h.getNamespaceFromEmail(claims.Email); ok { // register the machine if it's new if !m.Registered { - log.Debug().Msg("Registering new machine after successful callback") ns, err := h.GetNamespace(nsName) @@ -218,7 +217,6 @@ func (h *Headscale) OIDCCallback(c *gin.Context) { `, claims.Email))) - } log.Error(). diff --git a/preauth_keys.go b/preauth_keys.go index 68664c1..2641cbc 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -7,10 +7,9 @@ import ( "strconv" "time" + v1 "github.com/juanfont/headscale/gen/go/headscale/v1" "google.golang.org/protobuf/types/known/timestamppb" "gorm.io/gorm" - - v1 "github.com/juanfont/headscale/gen/go/headscale/v1" ) const ( @@ -19,7 +18,7 @@ const ( errSingleUseAuthKeyHasBeenUsed = Error("AuthKey has already been used") ) -// PreAuthKey describes a pre-authorization key usable in a particular namespace +// PreAuthKey describes a pre-authorization key usable in a particular namespace. type PreAuthKey struct { ID uint64 `gorm:"primary_key"` Key string @@ -33,7 +32,7 @@ type PreAuthKey struct { Expiration *time.Time } -// CreatePreAuthKey creates a new PreAuthKey in a namespace, and returns it +// CreatePreAuthKey creates a new PreAuthKey in a namespace, and returns it. func (h *Headscale) CreatePreAuthKey( namespaceName string, reusable bool, @@ -65,7 +64,7 @@ func (h *Headscale) CreatePreAuthKey( return &k, nil } -// ListPreAuthKeys returns the list of PreAuthKeys for a namespace +// ListPreAuthKeys returns the list of PreAuthKeys for a namespace. func (h *Headscale) ListPreAuthKeys(namespaceName string) ([]PreAuthKey, error) { n, err := h.GetNamespace(namespaceName) if err != nil { @@ -79,7 +78,7 @@ func (h *Headscale) ListPreAuthKeys(namespaceName string) ([]PreAuthKey, error) return keys, nil } -// GetPreAuthKey returns a PreAuthKey for a given key +// GetPreAuthKey returns a PreAuthKey for a given key. func (h *Headscale) GetPreAuthKey(namespace string, key string) (*PreAuthKey, error) { pak, err := h.checkKeyValidity(key) if err != nil { @@ -93,7 +92,7 @@ func (h *Headscale) GetPreAuthKey(namespace string, key string) (*PreAuthKey, er return pak, nil } -// MarkExpirePreAuthKey marks a PreAuthKey as expired +// MarkExpirePreAuthKey marks a PreAuthKey as expired. func (h *Headscale) ExpirePreAuthKey(k *PreAuthKey) error { if err := h.db.Model(&k).Update("Expiration", time.Now()).Error; err != nil { return err @@ -102,7 +101,7 @@ func (h *Headscale) ExpirePreAuthKey(k *PreAuthKey) error { } // checkKeyValidity does the heavy lifting for validation of the PreAuthKey coming from a node -// If returns no error and a PreAuthKey, it can be used +// 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( diff --git a/routes.go b/routes.go index 84f8dfe..8b30812 100644 --- a/routes.go +++ b/routes.go @@ -10,7 +10,7 @@ import ( // Deprecated: use machine function instead // GetAdvertisedNodeRoutes returns the subnet routes advertised by a node (identified by -// namespace and node name) +// namespace and node name). func (h *Headscale) GetAdvertisedNodeRoutes( namespace string, nodeName string, @@ -29,7 +29,7 @@ func (h *Headscale) GetAdvertisedNodeRoutes( // Deprecated: use machine function instead // GetEnabledNodeRoutes returns the subnet routes enabled by a node (identified by -// namespace and node name) +// namespace and node name). func (h *Headscale) GetEnabledNodeRoutes( namespace string, nodeName string, @@ -63,7 +63,7 @@ func (h *Headscale) GetEnabledNodeRoutes( } // Deprecated: use machine function instead -// IsNodeRouteEnabled checks if a certain route has been enabled +// IsNodeRouteEnabled checks if a certain route has been enabled. func (h *Headscale) IsNodeRouteEnabled( namespace string, nodeName string, @@ -89,7 +89,7 @@ func (h *Headscale) IsNodeRouteEnabled( // Deprecated: use EnableRoute in machine.go // EnableNodeRoute enables a subnet route advertised by a node (identified by -// namespace and node name) +// namespace and node name). func (h *Headscale) EnableNodeRoute( namespace string, nodeName string, diff --git a/sharing.go b/sharing.go index 581c2af..8f65414 100644 --- a/sharing.go +++ b/sharing.go @@ -8,7 +8,7 @@ const ( errorMachineNotShared = Error("Machine not shared to this namespace") ) -// SharedMachine is a join table to support sharing nodes between namespaces +// SharedMachine is a join table to support sharing nodes between namespaces. type SharedMachine struct { gorm.Model MachineID uint64 @@ -17,7 +17,7 @@ type SharedMachine struct { Namespace Namespace } -// AddSharedMachineToNamespace adds a machine as a shared node to a namespace +// AddSharedMachineToNamespace adds a machine as a shared node to a namespace. func (h *Headscale) AddSharedMachineToNamespace(m *Machine, ns *Namespace) error { if m.NamespaceID == ns.ID { return errorSameNamespace @@ -42,7 +42,7 @@ func (h *Headscale) AddSharedMachineToNamespace(m *Machine, ns *Namespace) error return nil } -// RemoveSharedMachineFromNamespace removes a shared machine from a namespace +// RemoveSharedMachineFromNamespace removes a shared machine from a namespace. func (h *Headscale) RemoveSharedMachineFromNamespace(m *Machine, ns *Namespace) error { if m.NamespaceID == ns.ID { // Can't unshare from primary namespace @@ -69,7 +69,7 @@ func (h *Headscale) RemoveSharedMachineFromNamespace(m *Machine, ns *Namespace) return nil } -// RemoveSharedMachineFromAllNamespaces removes a machine as a shared node from all namespaces +// RemoveSharedMachineFromAllNamespaces removes a machine as a shared node from all namespaces. func (h *Headscale) RemoveSharedMachineFromAllNamespaces(m *Machine) error { sharedMachine := SharedMachine{} if result := h.db.Where("machine_id = ?", m.ID).Unscoped().Delete(&sharedMachine); result.Error != nil { diff --git a/swagger.go b/swagger.go index d3ae1b2..01c73e4 100644 --- a/swagger.go +++ b/swagger.go @@ -6,9 +6,8 @@ import ( "net/http" "text/template" - "github.com/rs/zerolog/log" - "github.com/gin-gonic/gin" + "github.com/rs/zerolog/log" ) //go:embed gen/openapiv2/headscale/v1/headscale.swagger.json diff --git a/utils.go b/utils.go index 0b76b5e..8dd6294 100644 --- a/utils.go +++ b/utils.go @@ -113,7 +113,6 @@ func (h *Headscale) getAvailableIP() (*netaddr.IP, error) { if ip.IsZero() && ip.IsLoopback() { - ip = ip.Next() continue }