mirror of
https://github.com/juanfont/headscale.git
synced 2025-08-22 07:39:38 +00:00
Compare commits
48 Commits
v0.12.3
...
upstream/v
Author | SHA1 | Date | |
---|---|---|---|
![]() |
38c27f6bf8 | ||
![]() |
3af1253a65 | ||
![]() |
eb1ce64b7c | ||
![]() |
2c9ed63021 | ||
![]() |
4c779d306b | ||
![]() |
0862f60ff0 | ||
![]() |
991175f2aa | ||
![]() |
1815040d98 | ||
![]() |
71ab4c9b2c | ||
![]() |
e0c22a414b | ||
![]() |
4e63bba4fe | ||
![]() |
ccd41b9a13 | ||
![]() |
d8ce440309 | ||
![]() |
2f576b2fb1 | ||
![]() |
853a5288f1 | ||
![]() |
cd0df1e46f | ||
![]() |
b195c87418 | ||
![]() |
dbfb9e16e0 | ||
![]() |
8aa2606853 | ||
![]() |
a238a8b33a | ||
![]() |
e7b69dbf91 | ||
![]() |
13f23d2e7e | ||
![]() |
7aace7eb6b | ||
![]() |
7a6be36f46 | ||
![]() |
bb27c80bad | ||
![]() |
b122d06f12 | ||
![]() |
6f9ed958ca | ||
![]() |
39ce59fcb1 | ||
![]() |
052fccdc98 | ||
![]() |
17411b65f3 | ||
![]() |
fbe5054a67 | ||
![]() |
761147ea3b | ||
![]() |
25ccf5ef18 | ||
![]() |
b4f8961e44 | ||
![]() |
726ccc8c1f | ||
![]() |
126e694f26 | ||
![]() |
ab45cd37f8 | ||
![]() |
f59071ff1c | ||
![]() |
4d60aeae18 | ||
![]() |
67d1dd984f | ||
![]() |
b02f8dd45d | ||
![]() |
3837f1714a | ||
![]() |
ed5498ef86 | ||
![]() |
86f3f26a18 | ||
![]() |
febbb6006f | ||
![]() |
1d68509463 | ||
![]() |
b6d0c4f2aa | ||
![]() |
2c057c2d89 |
18
.github/workflows/build.yml
vendored
18
.github/workflows/build.yml
vendored
@@ -14,22 +14,38 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v14.1
|
||||
with:
|
||||
files: |
|
||||
go.*
|
||||
**/*.go
|
||||
integration_test/
|
||||
config-example.yaml
|
||||
|
||||
- name: Setup Go
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: "1.17.3"
|
||||
go-version: "1.17"
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: |
|
||||
go version
|
||||
sudo apt update
|
||||
sudo apt install -y make
|
||||
|
||||
- name: Run build
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: make build
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
with:
|
||||
name: headscale-linux
|
||||
path: headscale
|
||||
|
37
.github/workflows/lint.yml
vendored
37
.github/workflows/lint.yml
vendored
@@ -8,18 +8,55 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v14.1
|
||||
with:
|
||||
files: |
|
||||
go.*
|
||||
**/*.go
|
||||
integration_test/
|
||||
config-example.yaml
|
||||
|
||||
- name: golangci-lint
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
uses: golangci/golangci-lint-action@v2
|
||||
with:
|
||||
version: latest
|
||||
|
||||
# Only block PRs on new problems.
|
||||
# If this is not enabled, we will end up having PRs
|
||||
# blocked because new linters has appared and other
|
||||
# parts of the code is affected.
|
||||
only-new-issues: true
|
||||
|
||||
prettier-lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v14.1
|
||||
with:
|
||||
files: |
|
||||
**/*.md
|
||||
**/*.yml
|
||||
**/*.yaml
|
||||
**/*.ts
|
||||
**/*.js
|
||||
**/*.sass
|
||||
**/*.css
|
||||
**/*.scss
|
||||
**/*.html
|
||||
|
||||
- name: Prettify code
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
uses: creyD/prettier_action@v4.0
|
||||
with:
|
||||
prettier_options: >-
|
||||
|
21
.github/workflows/test-integration.yml
vendored
21
.github/workflows/test-integration.yml
vendored
@@ -3,21 +3,30 @@ name: CI
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
# The "build" workflow
|
||||
integration-test:
|
||||
# The type of runner that the job will run on
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v14.1
|
||||
with:
|
||||
files: |
|
||||
go.*
|
||||
**/*.go
|
||||
integration_test/
|
||||
config-example.yaml
|
||||
|
||||
# Setup Go
|
||||
- name: Setup Go
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: "1.17.3"
|
||||
go-version: "1.17"
|
||||
|
||||
- name: Run Integration tests
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: go test -tags integration -timeout 30m
|
||||
|
24
.github/workflows/test.yml
vendored
24
.github/workflows/test.yml
vendored
@@ -3,31 +3,41 @@ name: CI
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
# The "build" workflow
|
||||
test:
|
||||
# The type of runner that the job will run on
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v14.1
|
||||
with:
|
||||
files: |
|
||||
go.*
|
||||
**/*.go
|
||||
integration_test/
|
||||
config-example.yaml
|
||||
|
||||
# Setup Go
|
||||
- name: Setup Go
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: "1.17.3" # The Go version to download (if necessary) and use.
|
||||
go-version: "1.17"
|
||||
|
||||
# Install all the dependencies
|
||||
- name: Install dependencies
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: |
|
||||
go version
|
||||
sudo apt update
|
||||
sudo apt install -y make
|
||||
|
||||
- name: Run tests
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: make test
|
||||
|
||||
- name: Run build
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: make
|
||||
|
@@ -1,8 +1,7 @@
|
||||
# This is an example .goreleaser.yml file with some sane defaults.
|
||||
# Make sure to check the documentation at http://goreleaser.com
|
||||
---
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy
|
||||
- go mod tidy -compat=1.17
|
||||
|
||||
release:
|
||||
prerelease: auto
|
||||
@@ -33,7 +32,7 @@ builds:
|
||||
goarch:
|
||||
- arm
|
||||
goarm:
|
||||
- 7
|
||||
- "7"
|
||||
env:
|
||||
- CC=arm-linux-gnueabihf-gcc
|
||||
- CXX=arm-linux-gnueabihf-g++
|
||||
|
11
CHANGELOG.md
11
CHANGELOG.md
@@ -2,6 +2,17 @@
|
||||
|
||||
**TBD (TBD):**
|
||||
|
||||
**Changes**:
|
||||
|
||||
**0.12.4 (2022-01-29):**
|
||||
|
||||
**Changes**:
|
||||
|
||||
- Make gRPC Unix Socket permissions configurable [#292](https://github.com/juanfont/headscale/pull/292)
|
||||
- Trim whitespace before reading Private Key from file [#289](https://github.com/juanfont/headscale/pull/289)
|
||||
- Add new command to generate a private key for `headscale` [#290](https://github.com/juanfont/headscale/pull/290)
|
||||
- Fixed issue where hosts deleted from control server may be written back to the database, as long as they are connected to the control server [#278](https://github.com/juanfont/headscale/pull/278)
|
||||
|
||||
**0.12.3 (2022-01-13):**
|
||||
|
||||
**Changes**:
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# Builder image
|
||||
FROM golang:1.17.1-bullseye AS build
|
||||
FROM golang:1.17.6-bullseye AS build
|
||||
ENV GOPATH /go
|
||||
WORKDIR /go/src/headscale
|
||||
|
||||
@@ -9,6 +9,7 @@ RUN go mod download
|
||||
COPY . .
|
||||
|
||||
RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale
|
||||
RUN strip /go/bin/headscale
|
||||
RUN test -e /go/bin/headscale
|
||||
|
||||
# Production image
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# Builder image
|
||||
FROM golang:1.17.1-alpine AS build
|
||||
FROM golang:1.17.6-alpine AS build
|
||||
ENV GOPATH /go
|
||||
WORKDIR /go/src/headscale
|
||||
|
||||
@@ -10,6 +10,7 @@ RUN go mod download
|
||||
COPY . .
|
||||
|
||||
RUN go install -a -ldflags="-extldflags=-static" -tags netgo,sqlite_omit_load_extension ./cmd/headscale
|
||||
RUN strip /go/bin/headscale
|
||||
RUN test -e /go/bin/headscale
|
||||
|
||||
# Production image
|
||||
|
@@ -65,7 +65,7 @@ To contribute to Headscale you would need the lastest version of [Go](https://go
|
||||
|
||||
### Code style
|
||||
|
||||
To ensure we have some consistency with a growing number of contributes, this project has adopted linting and style/formatting rules:
|
||||
To ensure we have some consistency with a growing number of contributions, this project has adopted linting and style/formatting rules:
|
||||
|
||||
The **Go** code is linted with [`golangci-lint`](https://golangci-lint.run) and
|
||||
formatted with [`golines`](https://github.com/segmentio/golines) (width 88) and
|
||||
@@ -76,7 +76,7 @@ run `make lint` and `make fmt` before committing any code.
|
||||
The **Proto** code is linted with [`buf`](https://docs.buf.build/lint/overview) and
|
||||
formatted with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html).
|
||||
|
||||
The **rest** (markdown, yaml, etc) is formatted with [`prettier`](https://prettier.io).
|
||||
The **rest** (Markdown, YAML, etc) is formatted with [`prettier`](https://prettier.io).
|
||||
|
||||
Check out the `.golangci.yaml` and `Makefile` to see the specific configuration.
|
||||
|
||||
@@ -92,7 +92,7 @@ make install-protobuf-plugins
|
||||
|
||||
### Testing and building
|
||||
|
||||
Some parts of the project requires the generation of Go code from Protobuf (if changes is made in `proto/`) and it must be (re-)generated with:
|
||||
Some parts of the project require the generation of Go code from Protobuf (if changes are made in `proto/`) and it must be (re-)generated with:
|
||||
|
||||
```shell
|
||||
make generate
|
||||
|
3
acls.go
3
acls.go
@@ -25,8 +25,11 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
Base8 = 8
|
||||
Base10 = 10
|
||||
BitSize16 = 16
|
||||
BitSize32 = 32
|
||||
BitSize64 = 64
|
||||
portRangeBegin = 0
|
||||
portRangeEnd = 65535
|
||||
expectedTokenItems = 2
|
||||
|
10
app.go
10
app.go
@@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -96,6 +97,7 @@ type Config struct {
|
||||
DNSConfig *tailcfg.DNSConfig
|
||||
|
||||
UnixSocket string
|
||||
UnixSocketPermission fs.FileMode
|
||||
|
||||
OIDC OIDCConfig
|
||||
|
||||
@@ -426,6 +428,11 @@ func (h *Headscale) Serve() error {
|
||||
return fmt.Errorf("failed to set up gRPC socket: %w", err)
|
||||
}
|
||||
|
||||
// Change socket permissions
|
||||
if err := os.Chmod(h.cfg.UnixSocket, h.cfg.UnixSocketPermission); err != nil {
|
||||
return fmt.Errorf("failed change permission of gRPC socket: %w", err)
|
||||
}
|
||||
|
||||
// Handle common process-killing signals so we can gracefully shut down:
|
||||
sigc := make(chan os.Signal, 1)
|
||||
signal.Notify(sigc, os.Interrupt, syscall.SIGTERM)
|
||||
@@ -724,7 +731,8 @@ func readOrCreatePrivateKey(path string) (*key.MachinePrivate, error) {
|
||||
return nil, fmt.Errorf("failed to read private key file: %w", err)
|
||||
}
|
||||
|
||||
privateKeyEnsurePrefix := PrivateKeyEnsurePrefix(string(privateKey))
|
||||
trimmedPrivateKey := strings.TrimSpace(string(privateKey))
|
||||
privateKeyEnsurePrefix := PrivateKeyEnsurePrefix(trimmedPrivateKey)
|
||||
|
||||
var machineKey key.MachinePrivate
|
||||
if err = machineKey.UnmarshalText([]byte(privateKeyEnsurePrefix)); err != nil {
|
||||
|
41
cmd/headscale/cli/generate.go
Normal file
41
cmd/headscale/cli/generate.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(generateCmd)
|
||||
generateCmd.AddCommand(generatePrivateKeyCmd)
|
||||
}
|
||||
|
||||
var generateCmd = &cobra.Command{
|
||||
Use: "generate",
|
||||
Short: "Generate commands",
|
||||
}
|
||||
|
||||
var generatePrivateKeyCmd = &cobra.Command{
|
||||
Use: "private-key",
|
||||
Short: "Generate a private key for the headscale server",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
output, _ := cmd.Flags().GetString("output")
|
||||
machineKey := key.NewMachine()
|
||||
|
||||
machineKeyStr, err := machineKey.MarshalText()
|
||||
if err != nil {
|
||||
ErrorOutput(
|
||||
err,
|
||||
fmt.Sprintf("Error getting machine key from flag: %s", err),
|
||||
output,
|
||||
)
|
||||
}
|
||||
|
||||
SuccessOutput(map[string]string{
|
||||
"private_key": string(machineKeyStr),
|
||||
},
|
||||
string(machineKeyStr), output)
|
||||
},
|
||||
}
|
@@ -5,10 +5,12 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -23,6 +25,10 @@ import (
|
||||
"tailscale.com/types/dnstype"
|
||||
)
|
||||
|
||||
const (
|
||||
PermissionFallback = 0o700
|
||||
)
|
||||
|
||||
func LoadConfig(path string) error {
|
||||
viper.SetConfigName("config")
|
||||
if path == "" {
|
||||
@@ -48,6 +54,7 @@ func LoadConfig(path string) error {
|
||||
viper.SetDefault("dns_config", nil)
|
||||
|
||||
viper.SetDefault("unix_socket", "/var/run/headscale.sock")
|
||||
viper.SetDefault("unix_socket_permission", "0o770")
|
||||
|
||||
viper.SetDefault("cli.insecure", false)
|
||||
viper.SetDefault("cli.timeout", "5s")
|
||||
@@ -258,6 +265,7 @@ func getHeadscaleConfig() headscale.Config {
|
||||
ACMEURL: viper.GetString("acme_url"),
|
||||
|
||||
UnixSocket: viper.GetString("unix_socket"),
|
||||
UnixSocketPermission: GetFileMode("unix_socket_permission"),
|
||||
|
||||
OIDC: headscale.OIDCConfig{
|
||||
Issuer: viper.GetString("oidc.issuer"),
|
||||
@@ -448,3 +456,14 @@ func loadOIDCMatchMap() map[string]string {
|
||||
|
||||
return strMap
|
||||
}
|
||||
|
||||
func GetFileMode(key string) fs.FileMode {
|
||||
modeStr := viper.GetString(key)
|
||||
|
||||
mode, err := strconv.ParseUint(modeStr, headscale.Base8, headscale.BitSize64)
|
||||
if err != nil {
|
||||
return PermissionFallback
|
||||
}
|
||||
|
||||
return fs.FileMode(mode)
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -60,6 +61,7 @@ func (*Suite) TestConfigLoading(c *check.C) {
|
||||
c.Assert(viper.GetString("tls_letsencrypt_listen"), check.Equals, ":http")
|
||||
c.Assert(viper.GetString("tls_letsencrypt_challenge_type"), check.Equals, "HTTP-01")
|
||||
c.Assert(viper.GetStringSlice("dns_config.nameservers")[0], check.Equals, "1.1.1.1")
|
||||
c.Assert(cli.GetFileMode("unix_socket_permission"), check.Equals, fs.FileMode(0o770))
|
||||
}
|
||||
|
||||
func (*Suite) TestDNSConfigLoading(c *check.C) {
|
||||
|
@@ -149,6 +149,7 @@ dns_config:
|
||||
# Note: for local development, you probably want to change this to:
|
||||
# unix_socket: ./headscale.sock
|
||||
unix_socket: /var/run/headscale.sock
|
||||
unix_socket_permission: "0770"
|
||||
#
|
||||
# headscale supports experimental OpenID connect support,
|
||||
# it is still being tested and might have some bugs, please
|
||||
|
@@ -21,7 +21,7 @@ wget --output-document=/usr/local/bin/headscale \
|
||||
chmod +x /usr/local/bin/headscale
|
||||
```
|
||||
|
||||
3. Prepare a direction to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database:
|
||||
3. Prepare a directory to hold `headscale` configuration and the [SQLite](https://www.sqlite.org/) database:
|
||||
|
||||
```shell
|
||||
# Directory for configuration
|
||||
@@ -32,7 +32,7 @@ mkdir -p /etc/headscale
|
||||
mkdir -p /var/lib/headscale
|
||||
```
|
||||
|
||||
4. Create an empty SQlite datebase:
|
||||
4. Create an empty SQLite database:
|
||||
|
||||
```shell
|
||||
touch /var/lib/headscale/db.sqlite
|
||||
@@ -44,7 +44,7 @@ touch /var/lib/headscale/db.sqlite
|
||||
touch /etc/headscale/config.yaml
|
||||
```
|
||||
|
||||
It is **strongly recommended** to copy and modifiy the [example configuration](../config-example.yaml)
|
||||
It is **strongly recommended** to copy and modify the [example configuration](../config-example.yaml)
|
||||
from the [headscale repository](../)
|
||||
|
||||
6. Start the headscale server:
|
||||
@@ -106,7 +106,7 @@ tailscale up --login-server <YOUR_HEADSCALE_URL> --authkey <YOUR_AUTH_KEY>
|
||||
|
||||
## Running `headscale` in the background with SystemD
|
||||
|
||||
In this section it will be demonstrated how to run `headscale` as a service in the background with [SystemD](https://www.freedesktop.org/wiki/Software/systemd/).
|
||||
This section demonstrates how to run `headscale` as a service in the background with [SystemD](https://www.freedesktop.org/wiki/Software/systemd/).
|
||||
This should work on most modern Linux distributions.
|
||||
|
||||
1. Create a SystemD service configuration at `/etc/systemd/system/headscale.service` containing:
|
||||
|
30
go.mod
30
go.mod
@@ -21,12 +21,12 @@ require (
|
||||
github.com/rs/zerolog v1.26.0
|
||||
github.com/soheilhy/cmux v0.1.5
|
||||
github.com/spf13/cobra v1.2.1
|
||||
github.com/spf13/viper v1.8.1
|
||||
github.com/spf13/viper v1.9.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/tailscale/hujson v0.0.0-20210923003652-c3758b31534b
|
||||
github.com/tailscale/hujson v0.0.0-20211105212140-3a0adc019d83
|
||||
github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e
|
||||
github.com/zsais/go-gin-prometheus v0.1.0
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871
|
||||
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247
|
||||
@@ -40,12 +40,12 @@ require (
|
||||
gorm.io/driver/sqlite v1.1.5
|
||||
gorm.io/gorm v1.21.15
|
||||
inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6
|
||||
tailscale.com v1.18.1
|
||||
tailscale.com v1.20.3
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.1 // indirect
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||
github.com/atomicgo/cursor v0.0.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
@@ -57,7 +57,7 @@ require (
|
||||
github.com/docker/docker v20.10.8+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
@@ -92,30 +92,30 @@ require (
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/lib/pq v1.10.3 // indirect
|
||||
github.com/magiconair/properties v1.8.5 // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.8 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/opencontainers/runc v1.0.3 // indirect
|
||||
github.com/pelletier/go-toml v1.9.3 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.32.1 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.1-0.20211023094830-115ce09fd6b4 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/spf13/afero v1.6.0 // indirect
|
||||
github.com/spf13/cast v1.3.1 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.2.0 // indirect
|
||||
@@ -127,12 +127,12 @@ require (
|
||||
go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect
|
||||
go4.org/mem v0.0.0-20210711025021-927187094b94 // indirect
|
||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37 // indirect
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
|
||||
golang.org/x/net v0.0.0-20211205041911-012df41ee64c // indirect
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||
gopkg.in/ini.v1 v1.66.2 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
)
|
||||
|
@@ -28,7 +28,7 @@ import (
|
||||
"tailscale.com/ipn/ipnstate"
|
||||
)
|
||||
|
||||
var tailscaleVersions = []string{"1.18.1", "1.16.2", "1.14.3", "1.12.3"}
|
||||
var tailscaleVersions = []string{"1.20.2", "1.18.2", "1.16.2", "1.14.3", "1.12.3"}
|
||||
|
||||
type TestNamespace struct {
|
||||
count int
|
||||
|
@@ -319,6 +319,14 @@ func (h *Headscale) DeleteMachine(machine *Machine) error {
|
||||
return h.RequestMapUpdates(namespaceID)
|
||||
}
|
||||
|
||||
func (h *Headscale) TouchMachine(machine *Machine) error {
|
||||
return h.db.Updates(Machine{
|
||||
ID: machine.ID,
|
||||
LastSeen: machine.LastSeen,
|
||||
LastSuccessfulUpdate: machine.LastSuccessfulUpdate,
|
||||
}).Error
|
||||
}
|
||||
|
||||
// HardDeleteMachine hard deletes a Machine from the database.
|
||||
func (h *Headscale) HardDeleteMachine(machine *Machine) error {
|
||||
err := h.RemoveSharedMachineFromAllNamespaces(machine)
|
||||
|
62
poll.go
62
poll.go
@@ -74,6 +74,8 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) {
|
||||
Str("handler", "PollNetMap").
|
||||
Msgf("Failed to fetch machine from the database with Machine key: %s", machineKey.String())
|
||||
ctx.String(http.StatusInternalServerError, "")
|
||||
|
||||
return
|
||||
}
|
||||
log.Trace().
|
||||
Str("handler", "PollNetMap").
|
||||
@@ -100,7 +102,7 @@ func (h *Headscale) PollNetMapHandler(ctx *gin.Context) {
|
||||
machine.Endpoints = datatypes.JSON(endpoints)
|
||||
machine.LastSeen = &now
|
||||
}
|
||||
h.db.Save(&machine)
|
||||
h.db.Updates(machine)
|
||||
|
||||
data, err := h.getMapResponse(machineKey, req, machine)
|
||||
if err != nil {
|
||||
@@ -289,6 +291,10 @@ func (h *Headscale) PollNetMapStream(
|
||||
Str("channel", "pollData").
|
||||
Err(err).
|
||||
Msg("Cannot update machine from database")
|
||||
|
||||
// client has been removed from database
|
||||
// since the stream opened, terminate connection.
|
||||
return false
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
machine.LastSeen = &now
|
||||
@@ -297,13 +303,22 @@ func (h *Headscale) PollNetMapStream(
|
||||
Set(float64(now.Unix()))
|
||||
machine.LastSuccessfulUpdate = &now
|
||||
|
||||
h.db.Save(&machine)
|
||||
err = h.TouchMachine(machine)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Str("handler", "PollNetMapStream").
|
||||
Str("machine", machine.Name).
|
||||
Str("channel", "pollData").
|
||||
Err(err).
|
||||
Msg("Cannot update machine LastSuccessfulUpdate")
|
||||
} else {
|
||||
log.Trace().
|
||||
Str("handler", "PollNetMapStream").
|
||||
Str("machine", machine.Name).
|
||||
Str("channel", "pollData").
|
||||
Int("bytes", len(data)).
|
||||
Msg("Machine entry in database updated successfully after sending pollData")
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
@@ -342,16 +357,29 @@ func (h *Headscale) PollNetMapStream(
|
||||
Str("channel", "keepAlive").
|
||||
Err(err).
|
||||
Msg("Cannot update machine from database")
|
||||
|
||||
// client has been removed from database
|
||||
// since the stream opened, terminate connection.
|
||||
return false
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
machine.LastSeen = &now
|
||||
h.db.Save(&machine)
|
||||
err = h.TouchMachine(machine)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Str("handler", "PollNetMapStream").
|
||||
Str("machine", machine.Name).
|
||||
Str("channel", "keepAlive").
|
||||
Err(err).
|
||||
Msg("Cannot update machine LastSeen")
|
||||
} else {
|
||||
log.Trace().
|
||||
Str("handler", "PollNetMapStream").
|
||||
Str("machine", machine.Name).
|
||||
Str("channel", "keepAlive").
|
||||
Int("bytes", len(data)).
|
||||
Msg("Machine updated successfully after sending keep alive")
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
@@ -415,6 +443,10 @@ func (h *Headscale) PollNetMapStream(
|
||||
Str("channel", "update").
|
||||
Err(err).
|
||||
Msg("Cannot update machine from database")
|
||||
|
||||
// client has been removed from database
|
||||
// since the stream opened, terminate connection.
|
||||
return false
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
|
||||
@@ -422,7 +454,15 @@ func (h *Headscale) PollNetMapStream(
|
||||
Set(float64(now.Unix()))
|
||||
machine.LastSuccessfulUpdate = &now
|
||||
|
||||
h.db.Save(&machine)
|
||||
err = h.TouchMachine(machine)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Str("handler", "PollNetMapStream").
|
||||
Str("machine", machine.Name).
|
||||
Str("channel", "update").
|
||||
Err(err).
|
||||
Msg("Cannot update machine LastSuccessfulUpdate")
|
||||
}
|
||||
} else {
|
||||
log.Trace().
|
||||
Str("handler", "PollNetMapStream").
|
||||
@@ -450,10 +490,22 @@ func (h *Headscale) PollNetMapStream(
|
||||
Str("channel", "Done").
|
||||
Err(err).
|
||||
Msg("Cannot update machine from database")
|
||||
|
||||
// client has been removed from database
|
||||
// since the stream opened, terminate connection.
|
||||
return false
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
machine.LastSeen = &now
|
||||
h.db.Save(&machine)
|
||||
err = h.TouchMachine(machine)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Str("handler", "PollNetMapStream").
|
||||
Str("machine", machine.Name).
|
||||
Str("channel", "Done").
|
||||
Err(err).
|
||||
Msg("Cannot update machine LastSeen")
|
||||
}
|
||||
|
||||
log.Trace().
|
||||
Str("handler", "PollNetMapStream").
|
||||
|
Reference in New Issue
Block a user