diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5f925a2..17a9dcb 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -70,7 +70,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: bufbuild/buf-setup-action@v0.7.0 + - uses: bufbuild/buf-setup-action@v1.7.0 - uses: bufbuild/buf-lint-action@v1 with: input: "proto" diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml index 70b36b1..de896cb 100644 --- a/.github/workflows/test-integration.yml +++ b/.github/workflows/test-integration.yml @@ -11,6 +11,11 @@ jobs: with: fetch-depth: 2 + - name: Set Swap Space + uses: pierotofy/set-swap-space@master + with: + swap-size-gb: 10 + - name: Get changed files id: changed-files uses: tj-actions/changed-files@v14.1 @@ -25,11 +30,29 @@ jobs: - uses: cachix/install-nix-action@v16 if: steps.changed-files.outputs.any_changed == 'true' - - name: Run Integration tests + - name: Run CLI integration tests if: steps.changed-files.outputs.any_changed == 'true' uses: nick-fields/retry@v2 with: timeout_minutes: 240 max_attempts: 5 retry_on: error - command: nix develop --command -- make test_integration + command: nix develop --command -- make test_integration_cli + + - name: Run Embedded DERP server integration tests + if: steps.changed-files.outputs.any_changed == 'true' + uses: nick-fields/retry@v2 + with: + timeout_minutes: 240 + max_attempts: 5 + retry_on: error + command: nix develop --command -- make test_integration_derp + + - name: Run general integration tests + if: steps.changed-files.outputs.any_changed == 'true' + uses: nick-fields/retry@v2 + with: + timeout_minutes: 240 + max_attempts: 5 + retry_on: error + command: nix develop --command -- make test_integration_general diff --git a/Dockerfile b/Dockerfile index 33aa578..b9139f0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Builder image -FROM --platform=$BUILDPLATFORM docker.io/golang:1.18.0-bullseye AS build +FROM docker.io/golang:1.18.0-bullseye AS build ARG VERSION=dev ENV GOPATH /go WORKDIR /go/src/headscale @@ -8,8 +8,9 @@ COPY go.mod go.sum /go/src/headscale/ RUN go mod download COPY . . -ARG TARGETOS TARGETARCH -RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o /go/bin/headscale -ldflags="-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$VERSION" -a ./cmd/headscale + +RUN CGO_ENABLED=0 GOOS=linux go install -ldflags="-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$VERSION" -a ./cmd/headscale +RUN strip /go/bin/headscale RUN test -e /go/bin/headscale # Production image diff --git a/Dockerfile.alpine b/Dockerfile.alpine index b8d9e33..de683f2 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -1,5 +1,5 @@ # Builder image -FROM --platform=$BUILDPLATFORM docker.io/golang:1.18.0-alpine AS build +FROM docker.io/golang:1.18.0-alpine AS build ARG VERSION=dev ENV GOPATH /go WORKDIR /go/src/headscale @@ -10,8 +10,8 @@ RUN go mod download COPY . . -ARG TARGETOS TARGETARCH -RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o /go/bin/headscale -ldflags="-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$VERSION" -a ./cmd/headscale +RUN CGO_ENABLED=0 GOOS=linux go install -ldflags="-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$VERSION" -a ./cmd/headscale +RUN strip /go/bin/headscale RUN test -e /go/bin/headscale # Production image diff --git a/Dockerfile.debug b/Dockerfile.debug index 4333e94..9b1b7c6 100644 --- a/Dockerfile.debug +++ b/Dockerfile.debug @@ -1,5 +1,5 @@ # Builder image -FROM --platform=$BUILDPLATFORM docker.io/golang:1.18.0-bullseye AS build +FROM docker.io/golang:1.18.0-bullseye AS build ARG VERSION=dev ENV GOPATH /go WORKDIR /go/src/headscale @@ -9,7 +9,6 @@ RUN go mod download COPY . . -ARG TARGETOS TARGETARCH RUN CGO_ENABLED=0 GOOS=linux go install -ldflags="-s -w -X github.com/juanfont/headscale/cmd/headscale/cli.Version=$VERSION" -a ./cmd/headscale RUN test -e /go/bin/headscale diff --git a/Makefile b/Makefile index 404c3c0..651ff5c 100644 --- a/Makefile +++ b/Makefile @@ -24,14 +24,16 @@ dev: lint test build test: @go test -coverprofile=coverage.out ./... -test_integration: - go test -failfast -tags integration -timeout 30m -count=1 ./... +test_integration: test_integration_cli test_integration_derp test_integration_general test_integration_cli: - go test -tags integration -v integration_cli_test.go integration_common_test.go + go test -failfast -tags integration_cli,integration -timeout 30m -count=1 ./... test_integration_derp: - go test -tags integration -v integration_embedded_derp_test.go integration_common_test.go + go test -failfast -tags integration_derp,integration -timeout 30m -count=1 ./... + +test_integration_general: + go test -failfast -tags integration_general,integration -timeout 30m -count=1 ./... coverprofile_func: go tool cover -func=coverage.out diff --git a/api_key.go b/api_key.go index c1bbce2..01291d7 100644 --- a/api_key.go +++ b/api_key.go @@ -14,7 +14,7 @@ const ( apiPrefixLength = 7 apiKeyLength = 32 - errAPIKeyFailedToParse = Error("Failed to parse ApiKey") + ErrAPIKeyFailedToParse = Error("Failed to parse ApiKey") ) // APIKey describes the datamodel for API keys used to remotely authenticate with @@ -116,7 +116,7 @@ func (h *Headscale) ExpireAPIKey(key *APIKey) error { func (h *Headscale) ValidateAPIKey(keyStr string) (bool, error) { prefix, hash, found := strings.Cut(keyStr, ".") if !found { - return false, errAPIKeyFailedToParse + return false, ErrAPIKeyFailedToParse } key, err := h.GetAPIKey(prefix) diff --git a/db.go b/db.go index 5df9c23..f0a0a59 100644 --- a/db.go +++ b/db.go @@ -248,7 +248,7 @@ func (hi *HostInfo) Scan(destination interface{}) error { return json.Unmarshal([]byte(value), hi) default: - return fmt.Errorf("%w: unexpected data type %T", errMachineAddressesInvalid, destination) + return fmt.Errorf("%w: unexpected data type %T", ErrMachineAddressesInvalid, destination) } } @@ -270,7 +270,7 @@ func (i *IPPrefixes) Scan(destination interface{}) error { return json.Unmarshal([]byte(value), i) default: - return fmt.Errorf("%w: unexpected data type %T", errMachineAddressesInvalid, destination) + return fmt.Errorf("%w: unexpected data type %T", ErrMachineAddressesInvalid, destination) } } @@ -292,7 +292,7 @@ func (i *StringList) Scan(destination interface{}) error { return json.Unmarshal([]byte(value), i) default: - return fmt.Errorf("%w: unexpected data type %T", errMachineAddressesInvalid, destination) + return fmt.Errorf("%w: unexpected data type %T", ErrMachineAddressesInvalid, destination) } } diff --git a/docs/acls.md b/docs/acls.md index d69ed8f..148f973 100644 --- a/docs/acls.md +++ b/docs/acls.md @@ -36,7 +36,7 @@ ACLs could be written either on [huJSON](https://github.com/tailscale/hujson) or YAML. Check the [test ACLs](../tests/acls) for further information. When registering the servers we will need to add the flag -`--advertised-tags=tag:,tag:`, and the user (namespace) that is +`--advertise-tags=tag:,tag:`, and the user (namespace) that is registering the server should be allowed to do it. Since anyone can add tags to a server they can register, the check of the tags is done on headscale server and only valid tags are applied. A tag is valid if the namespace that is diff --git a/docs/build-headscale-container.md b/docs/build-headscale-container.md deleted file mode 100644 index b022016..0000000 --- a/docs/build-headscale-container.md +++ /dev/null @@ -1,32 +0,0 @@ -# Build docker from scratch - -The Dockerfiles included in the repository are using the [buildx plugin](https://docs.docker.com/buildx/working-with-buildx/). This plugin is includes in docker newer than Docker-ce CLI 19.03.2. The plugin is used to be able to build different container arches. Building the Dockerfiles without buildx is not possible. - -# Build native - -To build the container on the native arch you can just use: -``` -$ sudo docker buildx build -t headscale:custom-arch . -``` - -For example: This will build a amd64(x86_64) container if your hostsystem is amd64(x86_64). Or a arm64 container on a arm64 hostsystem (raspberry pi4). - -# Build cross platform - -To build a arm64 container on a amd64 hostsystem you could use: -``` -$ sudo docker buildx build --platform linux/arm64 -t headscale:custom-arm64 . - -``` - -**Import: Currently arm32 build are not supported as there is a problem with a library used by headscale. Hopefully this will be fixed soon.** - -# Build multiple arches - -To build multiple archres you could use: - -``` -$ sudo docker buildx create --use -$ sudo docker buildx build --platform linux/amd64,linux/arm64 . - -``` diff --git a/integration_cli_test.go b/integration_cli_test.go index 2f58e71..bc7d1c1 100644 --- a/integration_cli_test.go +++ b/integration_cli_test.go @@ -1,5 +1,4 @@ -//go:build integration -// +build integration +//go:build integration_cli package headscale @@ -73,21 +72,22 @@ func (s *IntegrationCLITestSuite) SetupTest() { s.FailNow(fmt.Sprintf("Could not remove existing container before building test: %s", err), "") } - fmt.Println("Creating headscale container") + fmt.Println("Creating headscale container for CLI tests") if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil { s.headscale = *pheadscale } else { s.FailNow(fmt.Sprintf("Could not start headscale container: %s", err), "") } - fmt.Println("Created headscale container") + fmt.Println("Created headscale container for CLI tests") - fmt.Println("Waiting for headscale to be ready") + fmt.Println("Waiting for headscale to be ready for CLI tests") hostEndpoint := fmt.Sprintf("localhost:%s", s.headscale.GetPort("8080/tcp")) if err := s.pool.Retry(func() error { url := fmt.Sprintf("http://%s/health", hostEndpoint) resp, err := http.Get(url) if err != nil { + fmt.Printf("headscale for CLI test is not ready: %s\n", err) return err } if resp.StatusCode != http.StatusOK { @@ -102,7 +102,7 @@ func (s *IntegrationCLITestSuite) SetupTest() { // https://github.com/stretchr/testify/issues/849 return // fmt.Errorf("Could not connect to headscale: %s", err) } - fmt.Println("headscale container is ready") + fmt.Println("headscale container is ready for CLI tests") } func (s *IntegrationCLITestSuite) TearDownTest() { diff --git a/integration_common_test.go b/integration_common_test.go index 4ee2d3b..b0c3dbb 100644 --- a/integration_common_test.go +++ b/integration_common_test.go @@ -1,5 +1,4 @@ //go:build integration -// +build integration package headscale @@ -20,6 +19,7 @@ import ( ) const ( + headscaleHostname = "headscale-derp" DOCKER_EXECUTE_TIMEOUT = 10 * time.Second ) @@ -30,9 +30,10 @@ var ( IpPrefix6 = netaddr.MustParseIPPrefix("fd7a:115c:a1e0::/48") tailscaleVersions = []string{ - "head", - "unstable", - "1.26.0", + // "head", + // "unstable", + "1.28.0", + "1.26.2", "1.24.2", "1.22.2", "1.20.4", diff --git a/integration_embedded_derp_test.go b/integration_embedded_derp_test.go index ecca8ba..da323d8 100644 --- a/integration_embedded_derp_test.go +++ b/integration_embedded_derp_test.go @@ -1,4 +1,4 @@ -//go:build integration +//go:build integration_derp package headscale @@ -28,9 +28,8 @@ import ( ) const ( - headscaleHostname = "headscale-derp" - namespaceName = "derpnamespace" - totalContainers = 3 + namespaceName = "derpnamespace" + totalContainers = 3 ) type IntegrationDERPTestSuite struct { @@ -134,15 +133,15 @@ func (s *IntegrationDERPTestSuite) SetupSuite() { s.FailNow(fmt.Sprintf("Could not remove existing container before building test: %s", err), "") } - log.Println("Creating headscale container") + log.Println("Creating headscale container for DERP integration tests") if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil { s.headscale = *pheadscale } else { s.FailNow(fmt.Sprintf("Could not start headscale container: %s", err), "") } - log.Println("Created headscale container to test DERP") + log.Println("Created headscale container for embedded DERP tests") - log.Println("Creating tailscale containers") + log.Println("Creating tailscale containers for embedded DERP tests") for i := 0; i < totalContainers; i++ { version := tailscaleVersions[i%len(tailscaleVersions)] @@ -154,7 +153,7 @@ func (s *IntegrationDERPTestSuite) SetupSuite() { s.tailscales[hostname] = *container } - log.Println("Waiting for headscale to be ready") + log.Println("Waiting for headscale to be ready for embedded DERP tests") hostEndpoint := fmt.Sprintf("localhost:%s", s.headscale.GetPort("8443/tcp")) if err := s.pool.Retry(func() error { @@ -164,6 +163,7 @@ func (s *IntegrationDERPTestSuite) SetupSuite() { client := &http.Client{Transport: insecureTransport} resp, err := client.Get(url) if err != nil { + fmt.Printf("headscale for embedded DERP tests is not ready: %s\n", err) return err } @@ -179,7 +179,7 @@ func (s *IntegrationDERPTestSuite) SetupSuite() { // https://github.com/stretchr/testify/issues/849 return // fmt.Errorf("Could not connect to headscale: %s", err) } - log.Println("headscale container is ready") + log.Println("headscale container is ready for embedded DERP tests") log.Printf("Creating headscale namespace: %s\n", namespaceName) result, err := ExecuteCommand( diff --git a/integration_test.go b/integration_general_test.go similarity index 96% rename from integration_test.go rename to integration_general_test.go index 2214b89..4bbdf27 100644 --- a/integration_test.go +++ b/integration_general_test.go @@ -1,5 +1,4 @@ -//go:build integration -// +build integration +//go:build integration_general package headscale @@ -251,15 +250,15 @@ func (s *IntegrationTestSuite) SetupSuite() { s.FailNow(fmt.Sprintf("Could not remove existing container before building test: %s", err), "") } - log.Println("Creating headscale container") + log.Println("Creating headscale container for core integration tests") if pheadscale, err := s.pool.BuildAndRunWithBuildOptions(headscaleBuildOptions, headscaleOptions, DockerRestartPolicy); err == nil { s.headscale = *pheadscale } else { - s.FailNow(fmt.Sprintf("Could not start headscale container: %s", err), "") + s.FailNow(fmt.Sprintf("Could not start headscale container for core integration tests: %s", err), "") } - log.Println("Created headscale container") + log.Println("Created headscale container for core integration tests") - log.Println("Creating tailscale containers") + log.Println("Creating tailscale containers for core integration tests") for namespace, scales := range s.namespaces { for i := 0; i < scales.count; i++ { version := tailscaleVersions[i%len(tailscaleVersions)] @@ -273,7 +272,7 @@ func (s *IntegrationTestSuite) SetupSuite() { } } - log.Println("Waiting for headscale to be ready") + log.Println("Waiting for headscale to be ready for core integration tests") hostEndpoint := fmt.Sprintf("localhost:%s", s.headscale.GetPort("8080/tcp")) if err := s.pool.Retry(func() error { @@ -281,6 +280,7 @@ func (s *IntegrationTestSuite) SetupSuite() { resp, err := http.Get(url) if err != nil { + fmt.Printf("headscale for core integration test is not ready: %s\n", err) return err } @@ -296,7 +296,7 @@ func (s *IntegrationTestSuite) SetupSuite() { // https://github.com/stretchr/testify/issues/849 return // fmt.Errorf("Could not connect to headscale: %s", err) } - log.Println("headscale container is ready") + log.Println("headscale container is ready for core integration tests") for namespace, scales := range s.namespaces { log.Printf("Creating headscale namespace: %s\n", namespace) diff --git a/machine.go b/machine.go index dda4902..22be0da 100644 --- a/machine.go +++ b/machine.go @@ -18,14 +18,14 @@ import ( ) const ( - errMachineNotFound = Error("machine not found") - errMachineRouteIsNotAvailable = Error("route is not available on machine") - errMachineAddressesInvalid = Error("failed to parse machine addresses") - errMachineNotFoundRegistrationCache = Error( + ErrMachineNotFound = Error("machine not found") + ErrMachineRouteIsNotAvailable = Error("route is not available on machine") + ErrMachineAddressesInvalid = Error("failed to parse machine addresses") + ErrMachineNotFoundRegistrationCache = Error( "machine not found in registration cache", ) - errCouldNotConvertMachineInterface = Error("failed to convert machine interface") - errHostnameTooLong = Error("Hostname too long") + ErrCouldNotConvertMachineInterface = Error("failed to convert machine interface") + ErrHostnameTooLong = Error("Hostname too long") MachineGivenNameHashLength = 8 MachineGivenNameTrimSize = 2 ) @@ -112,7 +112,7 @@ func (ma *MachineAddresses) Scan(destination interface{}) error { return nil default: - return fmt.Errorf("%w: unexpected data type %T", errMachineAddressesInvalid, destination) + return fmt.Errorf("%w: unexpected data type %T", ErrMachineAddressesInvalid, destination) } } @@ -337,7 +337,7 @@ func (h *Headscale) GetMachine(namespace string, name string) (*Machine, error) } } - return nil, errMachineNotFound + return nil, ErrMachineNotFound } // GetMachineByID finds a Machine by ID and returns the Machine struct. @@ -635,7 +635,7 @@ func (machine Machine) toNode( return nil, fmt.Errorf( "hostname %q is too long it cannot except 255 ASCII chars: %w", hostname, - errHostnameTooLong, + ErrHostnameTooLong, ) } } else { @@ -785,11 +785,11 @@ func (h *Headscale) RegisterMachineFromAuthCallback( return machine, err } else { - return nil, errCouldNotConvertMachineInterface + return nil, ErrCouldNotConvertMachineInterface } } - return nil, errMachineNotFoundRegistrationCache + return nil, ErrMachineNotFoundRegistrationCache } // RegisterMachine is executed from the CLI to register a new Machine using its MachineKey. @@ -877,7 +877,7 @@ func (h *Headscale) EnableRoutes(machine *Machine, routeStrs ...string) error { return fmt.Errorf( "route (%s) is not available on node %s: %w", machine.Hostname, - newRoute, errMachineRouteIsNotAvailable, + newRoute, ErrMachineRouteIsNotAvailable, ) } } diff --git a/namespaces.go b/namespaces.go index 0add03f..ac8913f 100644 --- a/namespaces.go +++ b/namespaces.go @@ -16,10 +16,10 @@ import ( ) const ( - errNamespaceExists = Error("Namespace already exists") - errNamespaceNotFound = Error("Namespace not found") - errNamespaceNotEmptyOfNodes = Error("Namespace not empty: node(s) found") - errInvalidNamespaceName = Error("Invalid namespace name") + ErrNamespaceExists = Error("Namespace already exists") + ErrNamespaceNotFound = Error("Namespace not found") + ErrNamespaceNotEmptyOfNodes = Error("Namespace not empty: node(s) found") + ErrInvalidNamespaceName = Error("Invalid namespace name") ) const ( @@ -47,7 +47,7 @@ func (h *Headscale) CreateNamespace(name string) (*Namespace, error) { } namespace := Namespace{} if err := h.db.Where("name = ?", name).First(&namespace).Error; err == nil { - return nil, errNamespaceExists + return nil, ErrNamespaceExists } namespace.Name = name if err := h.db.Create(&namespace).Error; err != nil { @@ -67,7 +67,7 @@ func (h *Headscale) CreateNamespace(name string) (*Namespace, error) { func (h *Headscale) DestroyNamespace(name string) error { namespace, err := h.GetNamespace(name) if err != nil { - return errNamespaceNotFound + return ErrNamespaceNotFound } machines, err := h.ListMachinesInNamespace(name) @@ -75,7 +75,7 @@ func (h *Headscale) DestroyNamespace(name string) error { return err } if len(machines) > 0 { - return errNamespaceNotEmptyOfNodes + return ErrNamespaceNotEmptyOfNodes } keys, err := h.ListPreAuthKeys(name) @@ -110,9 +110,9 @@ func (h *Headscale) RenameNamespace(oldName, newName string) error { } _, err = h.GetNamespace(newName) if err == nil { - return errNamespaceExists + return ErrNamespaceExists } - if !errors.Is(err, errNamespaceNotFound) { + if !errors.Is(err, ErrNamespaceNotFound) { return err } @@ -132,7 +132,7 @@ func (h *Headscale) GetNamespace(name string) (*Namespace, error) { result.Error, gorm.ErrRecordNotFound, ) { - return nil, errNamespaceNotFound + return nil, ErrNamespaceNotFound } return &namespace, nil @@ -272,7 +272,7 @@ func NormalizeToFQDNRules(name string, stripEmailDomain bool) (string, error) { return "", fmt.Errorf( "label %v is more than 63 chars: %w", elt, - errInvalidNamespaceName, + ErrInvalidNamespaceName, ) } } @@ -285,21 +285,21 @@ func CheckForFQDNRules(name string) error { return fmt.Errorf( "DNS segment must not be over 63 chars. %v doesn't comply with this rule: %w", name, - errInvalidNamespaceName, + ErrInvalidNamespaceName, ) } if strings.ToLower(name) != name { return fmt.Errorf( "DNS segment should be lowercase. %v doesn't comply with this rule: %w", name, - errInvalidNamespaceName, + ErrInvalidNamespaceName, ) } if invalidCharsInNamespaceRegex.MatchString(name) { return fmt.Errorf( "DNS segment should only be composed of lowercase ASCII letters numbers, hyphen and dots. %v doesn't comply with theses rules: %w", name, - errInvalidNamespaceName, + ErrInvalidNamespaceName, ) } diff --git a/namespaces_test.go b/namespaces_test.go index f8afa15..6f33585 100644 --- a/namespaces_test.go +++ b/namespaces_test.go @@ -26,7 +26,7 @@ func (s *Suite) TestCreateAndDestroyNamespace(c *check.C) { func (s *Suite) TestDestroyNamespaceErrors(c *check.C) { err := app.DestroyNamespace("test") - c.Assert(err, check.Equals, errNamespaceNotFound) + c.Assert(err, check.Equals, ErrNamespaceNotFound) namespace, err := app.CreateNamespace("test") c.Assert(err, check.IsNil) @@ -60,7 +60,7 @@ func (s *Suite) TestDestroyNamespaceErrors(c *check.C) { app.db.Save(&machine) err = app.DestroyNamespace("test") - c.Assert(err, check.Equals, errNamespaceNotEmptyOfNodes) + c.Assert(err, check.Equals, ErrNamespaceNotEmptyOfNodes) } func (s *Suite) TestRenameNamespace(c *check.C) { @@ -76,20 +76,20 @@ func (s *Suite) TestRenameNamespace(c *check.C) { c.Assert(err, check.IsNil) _, err = app.GetNamespace("test") - c.Assert(err, check.Equals, errNamespaceNotFound) + c.Assert(err, check.Equals, ErrNamespaceNotFound) _, err = app.GetNamespace("test-renamed") c.Assert(err, check.IsNil) err = app.RenameNamespace("test-does-not-exit", "test") - c.Assert(err, check.Equals, errNamespaceNotFound) + c.Assert(err, check.Equals, ErrNamespaceNotFound) namespaceTest2, err := app.CreateNamespace("test2") c.Assert(err, check.IsNil) c.Assert(namespaceTest2.Name, check.Equals, "test2") err = app.RenameNamespace("test2", "test-renamed") - c.Assert(err, check.Equals, errNamespaceExists) + c.Assert(err, check.Equals, ErrNamespaceExists) } func (s *Suite) TestGetMapResponseUserProfiles(c *check.C) { @@ -402,7 +402,7 @@ func (s *Suite) TestSetMachineNamespace(c *check.C) { c.Assert(machine.Namespace.Name, check.Equals, newNamespace.Name) err = app.SetMachineNamespace(&machine, "non-existing-namespace") - c.Assert(err, check.Equals, errNamespaceNotFound) + c.Assert(err, check.Equals, ErrNamespaceNotFound) err = app.SetMachineNamespace(&machine, newNamespace.Name) c.Assert(err, check.IsNil) diff --git a/oidc.go b/oidc.go index 8b5f024..cd0d918 100644 --- a/oidc.go +++ b/oidc.go @@ -416,7 +416,7 @@ func (h *Headscale) OIDCCallback( log.Debug().Msg("Registering new machine after successful callback") namespace, err := h.GetNamespace(namespaceName) - if errors.Is(err, errNamespaceNotFound) { + if errors.Is(err, ErrNamespaceNotFound) { namespace, err = h.CreateNamespace(namespaceName) if err != nil { diff --git a/preauth_keys.go b/preauth_keys.go index b32ff63..f120f45 100644 --- a/preauth_keys.go +++ b/preauth_keys.go @@ -14,10 +14,10 @@ import ( ) const ( - errPreAuthKeyNotFound = Error("AuthKey not found") - errPreAuthKeyExpired = Error("AuthKey expired") - errSingleUseAuthKeyHasBeenUsed = Error("AuthKey has already been used") - errNamespaceMismatch = Error("namespace mismatch") + ErrPreAuthKeyNotFound = Error("AuthKey not found") + ErrPreAuthKeyExpired = Error("AuthKey expired") + ErrSingleUseAuthKeyHasBeenUsed = Error("AuthKey has already been used") + ErrNamespaceMismatch = Error("namespace mismatch") ) // PreAuthKey describes a pre-authorization key usable in a particular namespace. @@ -92,7 +92,7 @@ func (h *Headscale) GetPreAuthKey(namespace string, key string) (*PreAuthKey, er } if pak.Namespace.Name != namespace { - return nil, errNamespaceMismatch + return nil, ErrNamespaceMismatch } return pak, nil @@ -135,11 +135,11 @@ func (h *Headscale) checkKeyValidity(k string) (*PreAuthKey, error) { result.Error, gorm.ErrRecordNotFound, ) { - return nil, errPreAuthKeyNotFound + return nil, ErrPreAuthKeyNotFound } if pak.Expiration != nil && pak.Expiration.Before(time.Now()) { - return nil, errPreAuthKeyExpired + return nil, ErrPreAuthKeyExpired } if pak.Reusable || pak.Ephemeral { // we don't need to check if has been used before @@ -152,7 +152,7 @@ func (h *Headscale) checkKeyValidity(k string) (*PreAuthKey, error) { } if len(machines) != 0 || pak.Used { - return nil, errSingleUseAuthKeyHasBeenUsed + return nil, ErrSingleUseAuthKeyHasBeenUsed } return &pak, nil diff --git a/preauth_keys_test.go b/preauth_keys_test.go index c54c1bf..cd9c66a 100644 --- a/preauth_keys_test.go +++ b/preauth_keys_test.go @@ -44,13 +44,13 @@ func (*Suite) TestExpiredPreAuthKey(c *check.C) { c.Assert(err, check.IsNil) key, err := app.checkKeyValidity(pak.Key) - c.Assert(err, check.Equals, errPreAuthKeyExpired) + c.Assert(err, check.Equals, ErrPreAuthKeyExpired) c.Assert(key, check.IsNil) } func (*Suite) TestPreAuthKeyDoesNotExist(c *check.C) { key, err := app.checkKeyValidity("potatoKey") - c.Assert(err, check.Equals, errPreAuthKeyNotFound) + c.Assert(err, check.Equals, ErrPreAuthKeyNotFound) c.Assert(key, check.IsNil) } @@ -86,7 +86,7 @@ func (*Suite) TestAlreadyUsedKey(c *check.C) { app.db.Save(&machine) key, err := app.checkKeyValidity(pak.Key) - c.Assert(err, check.Equals, errSingleUseAuthKeyHasBeenUsed) + c.Assert(err, check.Equals, ErrSingleUseAuthKeyHasBeenUsed) c.Assert(key, check.IsNil) } @@ -174,7 +174,7 @@ func (*Suite) TestExpirePreauthKey(c *check.C) { c.Assert(pak.Expiration, check.NotNil) key, err := app.checkKeyValidity(pak.Key) - c.Assert(err, check.Equals, errPreAuthKeyExpired) + c.Assert(err, check.Equals, ErrPreAuthKeyExpired) c.Assert(key, check.IsNil) } @@ -188,5 +188,5 @@ func (*Suite) TestNotReusableMarkedAsUsed(c *check.C) { app.db.Save(&pak) _, err = app.checkKeyValidity(pak.Key) - c.Assert(err, check.Equals, errSingleUseAuthKeyHasBeenUsed) + c.Assert(err, check.Equals, ErrSingleUseAuthKeyHasBeenUsed) } diff --git a/routes.go b/routes.go index d062f82..23217ca 100644 --- a/routes.go +++ b/routes.go @@ -7,7 +7,7 @@ import ( ) const ( - errRouteIsNotAvailable = Error("route is not available") + ErrRouteIsNotAvailable = Error("route is not available") ) // Deprecated: use machine function instead @@ -106,7 +106,7 @@ func (h *Headscale) EnableNodeRoute( } if !available { - return errRouteIsNotAvailable + return ErrRouteIsNotAvailable } machine.EnabledRoutes = enabledRoutes diff --git a/utils.go b/utils.go index 87930a1..b436253 100644 --- a/utils.go +++ b/utils.go @@ -27,8 +27,8 @@ import ( ) const ( - errCannotDecryptReponse = Error("cannot decrypt response") - errCouldNotAllocateIP = Error("could not find any suitable IP") + ErrCannotDecryptResponse = Error("cannot decrypt response") + ErrCouldNotAllocateIP = Error("could not find any suitable IP") // These constants are copied from the upstream tailscale.com/types/key // library, because they are not exported. @@ -120,7 +120,7 @@ func decode( decrypted, ok := privKey.OpenFrom(*pubKey, msg) if !ok { - return errCannotDecryptReponse + return ErrCannotDecryptResponse } if err := json.Unmarshal(decrypted, output); err != nil { @@ -181,7 +181,7 @@ func (h *Headscale) getAvailableIP(ipPrefix netaddr.IPPrefix) (*netaddr.IP, erro for { if !ipPrefix.Contains(ip) { - return nil, errCouldNotAllocateIP + return nil, ErrCouldNotAllocateIP } switch {