mirror of
https://github.com/juanfont/headscale.git
synced 2026-07-30 03:40:45 +09:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f90ebb8567 | |||
| 7564c4548c | |||
| 5f80d1b155 |
@@ -0,0 +1,35 @@
|
||||
name: Integration Test CLI
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
integration-test-cli:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
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@v34
|
||||
with:
|
||||
files: |
|
||||
*.nix
|
||||
go.*
|
||||
**/*.go
|
||||
integration_test/
|
||||
config-example.yaml
|
||||
|
||||
- uses: cachix/install-nix-action@v16
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
|
||||
- name: Run CLI integration tests
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: nix develop --command -- make test_integration_cli
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
+1
-16
@@ -2,20 +2,6 @@
|
||||
|
||||
## 0.23.0 (2023-XX-XX)
|
||||
|
||||
### BREAKING
|
||||
|
||||
- Code reorganisation, a lot of code has moved, please review the following PRs accordingly [#1444](https://github.com/juanfont/headscale/pull/1444)
|
||||
|
||||
### Changes
|
||||
|
||||
## 0.22.3 (2023-05-12)
|
||||
|
||||
### Changes
|
||||
|
||||
- Added missing ca-certificates in Docker image [#1463](https://github.com/juanfont/headscale/pull/1463)
|
||||
|
||||
## 0.22.2 (2023-05-10)
|
||||
|
||||
### Changes
|
||||
|
||||
- Add environment flags to enable pprof (profiling) [#1382](https://github.com/juanfont/headscale/pull/1382)
|
||||
@@ -23,14 +9,13 @@
|
||||
- Fix systemd service file location in `.deb` packages [#1391](https://github.com/juanfont/headscale/pull/1391)
|
||||
- Improvements on Noise implementation [#1379](https://github.com/juanfont/headscale/pull/1379)
|
||||
- Replace node filter logic, ensuring nodes with access can see eachother [#1381](https://github.com/juanfont/headscale/pull/1381)
|
||||
- Disable (or delete) both exit routes at the same time [#1428](https://github.com/juanfont/headscale/pull/1428)
|
||||
- Ditch distroless for Docker image, create default socket dir in `/var/run/headscale` [#1450](https://github.com/juanfont/headscale/pull/1450)
|
||||
|
||||
## 0.22.1 (2023-04-20)
|
||||
|
||||
### Changes
|
||||
|
||||
- Fix issue where systemd could not bind to port 80 [#1365](https://github.com/juanfont/headscale/pull/1365)
|
||||
- Disable (or delete) both exit routes at the same time [#1428](https://github.com/juanfont/headscale/pull/1428)
|
||||
|
||||
## 0.22.0 (2023-04-20)
|
||||
|
||||
|
||||
+1
-8
@@ -14,17 +14,10 @@ RUN strip /go/bin/headscale
|
||||
RUN test -e /go/bin/headscale
|
||||
|
||||
# Production image
|
||||
FROM docker.io/debian:bullseye-slim
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& apt-get clean
|
||||
FROM gcr.io/distroless/base-debian11
|
||||
|
||||
COPY --from=build /go/bin/headscale /bin/headscale
|
||||
ENV TZ UTC
|
||||
|
||||
RUN mkdir -p /var/run/headscale
|
||||
|
||||
EXPOSE 8080/tcp
|
||||
CMD ["headscale"]
|
||||
|
||||
@@ -18,8 +18,6 @@ FROM docker.io/golang:1.20.0-bullseye
|
||||
COPY --from=build /go/bin/headscale /bin/headscale
|
||||
ENV TZ UTC
|
||||
|
||||
RUN mkdir -p /var/run/headscale
|
||||
|
||||
# Need to reset the entrypoint or everything will run as a busybox script
|
||||
ENTRYPOINT []
|
||||
EXPOSE 8080/tcp
|
||||
|
||||
@@ -24,9 +24,21 @@ build:
|
||||
dev: lint test build
|
||||
|
||||
test:
|
||||
gotestsum -- $(TAGS) -short -coverprofile=coverage.out ./...
|
||||
@go test $(TAGS) -short -coverprofile=coverage.out ./...
|
||||
|
||||
test_integration:
|
||||
test_integration: test_integration_cli test_integration_derp test_integration_v2_general
|
||||
|
||||
test_integration_cli:
|
||||
docker network rm $$(docker network ls --filter name=headscale --quiet) || true
|
||||
docker network create headscale-test || true
|
||||
docker run -t --rm \
|
||||
--network headscale-test \
|
||||
-v ~/.cache/hs-integration-go:/go \
|
||||
-v $$PWD:$$PWD -w $$PWD \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- $(TAGS) -failfast -timeout 30m -count=1 -run IntegrationCLI ./...
|
||||
|
||||
test_integration_v2_general:
|
||||
docker run \
|
||||
-t --rm \
|
||||
-v ~/.cache/hs-integration-go:/go \
|
||||
|
||||
@@ -80,6 +80,15 @@ and container to run Headscale.**
|
||||
|
||||
Please have a look at the [`documentation`](https://headscale.net/).
|
||||
|
||||
## Graphical Control Panels
|
||||
|
||||
Headscale provides an API for complete management of your Tailnet.
|
||||
These are community projects not directly affiliated with the Headscale project.
|
||||
|
||||
| Name | Repository Link | Description | Status |
|
||||
| --------------- | ---------------------------------------------------- | ------------------------------------------------------ | ------ |
|
||||
| headscale-webui | [Github](https://github.com/ifargle/headscale-webui) | A simple Headscale web UI for small-scale deployments. | Alpha |
|
||||
|
||||
## Talks
|
||||
|
||||
- Fosdem 2023 (video): [Headscale: How we are using integration testing to reimplement Tailscale](https://fosdem.org/2023/schedule/event/goheadscale/)
|
||||
|
||||
+16
-21
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -59,8 +59,8 @@ const (
|
||||
|
||||
var featureEnableSSH = envknob.RegisterBool("HEADSCALE_EXPERIMENTAL_FEATURE_SSH")
|
||||
|
||||
// LoadACLPolicyFromPath loads the ACL policy from the specify path, and generates the ACL rules.
|
||||
func (h *Headscale) LoadACLPolicyFromPath(path string) error {
|
||||
// LoadACLPolicy loads the ACL policy from the specify path, and generates the ACL rules.
|
||||
func (h *Headscale) LoadACLPolicy(path string) error {
|
||||
log.Debug().
|
||||
Str("func", "LoadACLPolicy").
|
||||
Str("path", path).
|
||||
@@ -72,42 +72,37 @@ func (h *Headscale) LoadACLPolicyFromPath(path string) error {
|
||||
}
|
||||
defer policyFile.Close()
|
||||
|
||||
var policy ACLPolicy
|
||||
policyBytes, err := io.ReadAll(policyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debug().
|
||||
Str("path", path).
|
||||
Bytes("file", policyBytes).
|
||||
Msg("Loading ACLs")
|
||||
|
||||
switch filepath.Ext(path) {
|
||||
case ".yml", ".yaml":
|
||||
return h.LoadACLPolicyFromBytes(policyBytes, "yaml")
|
||||
}
|
||||
log.Debug().
|
||||
Str("path", path).
|
||||
Bytes("file", policyBytes).
|
||||
Msg("Loading ACLs from YAML")
|
||||
|
||||
return h.LoadACLPolicyFromBytes(policyBytes, "hujson")
|
||||
}
|
||||
|
||||
func (h *Headscale) LoadACLPolicyFromBytes(acl []byte, format string) error {
|
||||
var policy ACLPolicy
|
||||
switch format {
|
||||
case "yaml":
|
||||
err := yaml.Unmarshal(acl, &policy)
|
||||
err := yaml.Unmarshal(policyBytes, &policy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Trace().
|
||||
Interface("policy", policy).
|
||||
Msg("Loaded policy from YAML")
|
||||
|
||||
default:
|
||||
ast, err := hujson.Parse(acl)
|
||||
ast, err := hujson.Parse(policyBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ast.Standardize()
|
||||
acl = ast.Pack()
|
||||
err = json.Unmarshal(acl, &policy)
|
||||
policyBytes = ast.Pack()
|
||||
err = json.Unmarshal(policyBytes, &policy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -15,26 +15,17 @@ import (
|
||||
)
|
||||
|
||||
func (s *Suite) TestWrongPath(c *check.C) {
|
||||
err := app.LoadACLPolicyFromPath("asdfg")
|
||||
err := app.LoadACLPolicy("asdfg")
|
||||
c.Assert(err, check.NotNil)
|
||||
}
|
||||
|
||||
func (s *Suite) TestBrokenHuJson(c *check.C) {
|
||||
acl := []byte(`
|
||||
{
|
||||
`)
|
||||
err := app.LoadACLPolicyFromBytes(acl, "hujson")
|
||||
err := app.LoadACLPolicy("./tests/acls/broken.hujson")
|
||||
c.Assert(err, check.NotNil)
|
||||
}
|
||||
|
||||
func (s *Suite) TestInvalidPolicyHuson(c *check.C) {
|
||||
acl := []byte(`
|
||||
{
|
||||
"valid_json": true,
|
||||
"but_a_policy_though": false
|
||||
}
|
||||
`)
|
||||
err := app.LoadACLPolicyFromBytes(acl, "hujson")
|
||||
err := app.LoadACLPolicy("./tests/acls/invalid.hujson")
|
||||
c.Assert(err, check.NotNil)
|
||||
c.Assert(err, check.Equals, errEmptyPolicy)
|
||||
}
|
||||
@@ -58,161 +49,12 @@ func (s *Suite) TestParseInvalidCIDR(c *check.C) {
|
||||
}
|
||||
|
||||
func (s *Suite) TestRuleInvalidGeneration(c *check.C) {
|
||||
acl := []byte(`
|
||||
{
|
||||
// Declare static groups of users beyond those in the identity service.
|
||||
"groups": {
|
||||
"group:example": [
|
||||
"user1@example.com",
|
||||
"user2@example.com",
|
||||
],
|
||||
},
|
||||
// Declare hostname aliases to use in place of IP addresses or subnets.
|
||||
"hosts": {
|
||||
"example-host-1": "100.100.100.100",
|
||||
"example-host-2": "100.100.101.100/24",
|
||||
},
|
||||
// Define who is allowed to use which tags.
|
||||
"tagOwners": {
|
||||
// Everyone in the montreal-admins or global-admins group are
|
||||
// allowed to tag servers as montreal-webserver.
|
||||
"tag:montreal-webserver": [
|
||||
"group:montreal-admins",
|
||||
"group:global-admins",
|
||||
],
|
||||
// Only a few admins are allowed to create API servers.
|
||||
"tag:api-server": [
|
||||
"group:global-admins",
|
||||
"example-host-1",
|
||||
],
|
||||
},
|
||||
// Access control lists.
|
||||
"acls": [
|
||||
// Engineering users, plus the president, can access port 22 (ssh)
|
||||
// and port 3389 (remote desktop protocol) on all servers, and all
|
||||
// ports on git-server or ci-server.
|
||||
{
|
||||
"action": "accept",
|
||||
"src": [
|
||||
"group:engineering",
|
||||
"president@example.com"
|
||||
],
|
||||
"dst": [
|
||||
"*:22,3389",
|
||||
"git-server:*",
|
||||
"ci-server:*"
|
||||
],
|
||||
},
|
||||
// Allow engineer users to access any port on a device tagged with
|
||||
// tag:production.
|
||||
{
|
||||
"action": "accept",
|
||||
"src": [
|
||||
"group:engineers"
|
||||
],
|
||||
"dst": [
|
||||
"tag:production:*"
|
||||
],
|
||||
},
|
||||
// Allow servers in the my-subnet host and 192.168.1.0/24 to access hosts
|
||||
// on both networks.
|
||||
{
|
||||
"action": "accept",
|
||||
"src": [
|
||||
"my-subnet",
|
||||
"192.168.1.0/24"
|
||||
],
|
||||
"dst": [
|
||||
"my-subnet:*",
|
||||
"192.168.1.0/24:*"
|
||||
],
|
||||
},
|
||||
// Allow every user of your network to access anything on the network.
|
||||
// Comment out this section if you want to define specific ACL
|
||||
// restrictions above.
|
||||
{
|
||||
"action": "accept",
|
||||
"src": [
|
||||
"*"
|
||||
],
|
||||
"dst": [
|
||||
"*:*"
|
||||
],
|
||||
},
|
||||
// All users in Montreal are allowed to access the Montreal web
|
||||
// servers.
|
||||
{
|
||||
"action": "accept",
|
||||
"src": [
|
||||
"group:montreal-users"
|
||||
],
|
||||
"dst": [
|
||||
"tag:montreal-webserver:80,443"
|
||||
],
|
||||
},
|
||||
// Montreal web servers are allowed to make outgoing connections to
|
||||
// the API servers, but only on https port 443.
|
||||
// In contrast, this doesn't grant API servers the right to initiate
|
||||
// any connections.
|
||||
{
|
||||
"action": "accept",
|
||||
"src": [
|
||||
"tag:montreal-webserver"
|
||||
],
|
||||
"dst": [
|
||||
"tag:api-server:443"
|
||||
],
|
||||
},
|
||||
],
|
||||
// Declare tests to check functionality of ACL rules
|
||||
"tests": [
|
||||
{
|
||||
"src": "user1@example.com",
|
||||
"accept": [
|
||||
"example-host-1:22",
|
||||
"example-host-2:80"
|
||||
],
|
||||
"deny": [
|
||||
"exapmle-host-2:100"
|
||||
],
|
||||
},
|
||||
{
|
||||
"src": "user2@example.com",
|
||||
"accept": [
|
||||
"100.60.3.4:22"
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
`)
|
||||
err := app.LoadACLPolicyFromBytes(acl, "hujson")
|
||||
err := app.LoadACLPolicy("./tests/acls/acl_policy_invalid.hujson")
|
||||
c.Assert(err, check.NotNil)
|
||||
}
|
||||
|
||||
func (s *Suite) TestBasicRule(c *check.C) {
|
||||
acl := []byte(`
|
||||
{
|
||||
"hosts": {
|
||||
"host-1": "100.100.100.100",
|
||||
"subnet-1": "100.100.101.100/24",
|
||||
},
|
||||
|
||||
"acls": [
|
||||
{
|
||||
"action": "accept",
|
||||
"src": [
|
||||
"subnet-1",
|
||||
"192.168.1.0/24"
|
||||
],
|
||||
"dst": [
|
||||
"*:22,3389",
|
||||
"host-1:*",
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
`)
|
||||
err := app.LoadACLPolicyFromBytes(acl, "hujson")
|
||||
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_1.hujson")
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
|
||||
@@ -569,27 +411,7 @@ func (s *Suite) TestValidTagInvalidUser(c *check.C) {
|
||||
}
|
||||
|
||||
func (s *Suite) TestPortRange(c *check.C) {
|
||||
acl := []byte(`
|
||||
{
|
||||
"hosts": {
|
||||
"host-1": "100.100.100.100",
|
||||
"subnet-1": "100.100.101.100/24",
|
||||
},
|
||||
|
||||
"acls": [
|
||||
{
|
||||
"action": "accept",
|
||||
"src": [
|
||||
"subnet-1",
|
||||
],
|
||||
"dst": [
|
||||
"host-1:5400-5500",
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
`)
|
||||
err := app.LoadACLPolicyFromBytes(acl, "hujson")
|
||||
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_range.hujson")
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
|
||||
@@ -603,48 +425,7 @@ func (s *Suite) TestPortRange(c *check.C) {
|
||||
}
|
||||
|
||||
func (s *Suite) TestProtocolParsing(c *check.C) {
|
||||
acl := []byte(`
|
||||
{
|
||||
"hosts": {
|
||||
"host-1": "100.100.100.100",
|
||||
"subnet-1": "100.100.101.100/24",
|
||||
},
|
||||
|
||||
"acls": [
|
||||
{
|
||||
"Action": "accept",
|
||||
"src": [
|
||||
"*",
|
||||
],
|
||||
"proto": "tcp",
|
||||
"dst": [
|
||||
"host-1:*",
|
||||
],
|
||||
},
|
||||
{
|
||||
"Action": "accept",
|
||||
"src": [
|
||||
"*",
|
||||
],
|
||||
"proto": "udp",
|
||||
"dst": [
|
||||
"host-1:53",
|
||||
],
|
||||
},
|
||||
{
|
||||
"Action": "accept",
|
||||
"src": [
|
||||
"*",
|
||||
],
|
||||
"proto": "icmp",
|
||||
"dst": [
|
||||
"host-1:*",
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
`)
|
||||
err := app.LoadACLPolicyFromBytes(acl, "hujson")
|
||||
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_protocols.hujson")
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
|
||||
@@ -658,27 +439,7 @@ func (s *Suite) TestProtocolParsing(c *check.C) {
|
||||
}
|
||||
|
||||
func (s *Suite) TestPortWildcard(c *check.C) {
|
||||
acl := []byte(`
|
||||
{
|
||||
"hosts": {
|
||||
"host-1": "100.100.100.100",
|
||||
"subnet-1": "100.100.101.100/24",
|
||||
},
|
||||
|
||||
"acls": [
|
||||
{
|
||||
"Action": "accept",
|
||||
"src": [
|
||||
"*",
|
||||
],
|
||||
"dst": [
|
||||
"host-1:*",
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
`)
|
||||
err := app.LoadACLPolicyFromBytes(acl, "hujson")
|
||||
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_wildcards.hujson")
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
|
||||
@@ -694,19 +455,7 @@ func (s *Suite) TestPortWildcard(c *check.C) {
|
||||
}
|
||||
|
||||
func (s *Suite) TestPortWildcardYAML(c *check.C) {
|
||||
acl := []byte(`
|
||||
---
|
||||
hosts:
|
||||
host-1: 100.100.100.100/32
|
||||
subnet-1: 100.100.101.100/24
|
||||
acls:
|
||||
- action: accept
|
||||
src:
|
||||
- "*"
|
||||
dst:
|
||||
- host-1:*
|
||||
`)
|
||||
err := app.LoadACLPolicyFromBytes(acl, "yaml")
|
||||
err := app.LoadACLPolicy("./tests/acls/acl_policy_basic_wildcards.yaml")
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
rules, err := app.aclPolicy.generateFilterRules([]Machine{}, false)
|
||||
@@ -744,27 +493,9 @@ func (s *Suite) TestPortUser(c *check.C) {
|
||||
}
|
||||
app.db.Save(&machine)
|
||||
|
||||
acl := []byte(`
|
||||
{
|
||||
"hosts": {
|
||||
"host-1": "100.100.100.100",
|
||||
"subnet-1": "100.100.101.100/24",
|
||||
},
|
||||
|
||||
"acls": [
|
||||
{
|
||||
"action": "accept",
|
||||
"src": [
|
||||
"testuser",
|
||||
],
|
||||
"dst": [
|
||||
"host-1:*",
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
`)
|
||||
err = app.LoadACLPolicyFromBytes(acl, "hujson")
|
||||
err = app.LoadACLPolicy(
|
||||
"./tests/acls/acl_policy_basic_user_as_user.hujson",
|
||||
)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
machines, err := app.ListMachines()
|
||||
@@ -807,33 +538,7 @@ func (s *Suite) TestPortGroup(c *check.C) {
|
||||
}
|
||||
app.db.Save(&machine)
|
||||
|
||||
acl := []byte(`
|
||||
{
|
||||
"groups": {
|
||||
"group:example": [
|
||||
"testuser",
|
||||
],
|
||||
},
|
||||
|
||||
"hosts": {
|
||||
"host-1": "100.100.100.100",
|
||||
"subnet-1": "100.100.101.100/24",
|
||||
},
|
||||
|
||||
"acls": [
|
||||
{
|
||||
"action": "accept",
|
||||
"src": [
|
||||
"group:example",
|
||||
],
|
||||
"dst": [
|
||||
"host-1:*",
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
`)
|
||||
err = app.LoadACLPolicyFromBytes(acl, "hujson")
|
||||
err = app.LoadACLPolicy("./tests/acls/acl_policy_basic_groups.hujson")
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
machines, err := app.ListMachines()
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"time"
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"time"
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
grpcMiddleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/juanfont/headscale"
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/patrickmn/go-cache"
|
||||
zerolog "github.com/philip-bui/grpc-zerolog"
|
||||
@@ -508,10 +507,8 @@ func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *mux.Router {
|
||||
router.HandleFunc("/windows", h.WindowsConfigMessage).Methods(http.MethodGet)
|
||||
router.HandleFunc("/windows/tailscale.reg", h.WindowsRegConfig).
|
||||
Methods(http.MethodGet)
|
||||
|
||||
// TODO(kristoffer): move swagger into a package
|
||||
router.HandleFunc("/swagger", headscale.SwaggerUI).Methods(http.MethodGet)
|
||||
router.HandleFunc("/swagger/v1/openapiv2.json", headscale.SwaggerAPIv1).
|
||||
router.HandleFunc("/swagger", SwaggerUI).Methods(http.MethodGet)
|
||||
router.HandleFunc("/swagger/v1/openapiv2.json", SwaggerAPIv1).
|
||||
Methods(http.MethodGet)
|
||||
|
||||
if h.cfg.DERP.ServerEnabled {
|
||||
@@ -761,7 +758,7 @@ func (h *Headscale) Serve() error {
|
||||
|
||||
if h.cfg.ACL.PolicyPath != "" {
|
||||
aclPath := AbsolutePathFromConfigPath(h.cfg.ACL.PolicyPath)
|
||||
err := h.LoadACLPolicyFromPath(aclPath)
|
||||
err := h.LoadACLPolicy(aclPath)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to reload ACL policy")
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume $PWD/control_logs:/tmp/control \
|
||||
golang:1 \
|
||||
go run gotest.tools/gotestsum@latest -- ./... \
|
||||
go test ./... \
|
||||
-tags ts2019 \
|
||||
-failfast \
|
||||
-timeout 120m \
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/juanfont/headscale"
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/prometheus/common/model"
|
||||
"github.com/pterm/pterm"
|
||||
"github.com/rs/zerolog/log"
|
||||
@@ -83,7 +83,7 @@ var listAPIKeys = &cobra.Command{
|
||||
}
|
||||
|
||||
tableData = append(tableData, []string{
|
||||
strconv.FormatUint(key.GetId(), hscontrol.Base10),
|
||||
strconv.FormatUint(key.GetId(), headscale.Base10),
|
||||
key.GetPrefix(),
|
||||
expiration,
|
||||
key.GetCreatedAt().AsTime().Format(HeadscaleDateTimeFormat),
|
||||
|
||||
@@ -3,8 +3,8 @@ package cli
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/juanfont/headscale"
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/status"
|
||||
@@ -93,7 +93,7 @@ var createNodeCmd = &cobra.Command{
|
||||
|
||||
return
|
||||
}
|
||||
if !hscontrol.NodePublicKeyRegex.Match([]byte(machineKey)) {
|
||||
if !headscale.NodePublicKeyRegex.Match([]byte(machineKey)) {
|
||||
err = errPreAuthKeyMalformed
|
||||
ErrorOutput(
|
||||
err,
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"time"
|
||||
|
||||
survey "github.com/AlecAivazis/survey/v2"
|
||||
"github.com/juanfont/headscale"
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/pterm/pterm"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/status"
|
||||
@@ -529,7 +529,7 @@ func nodesToPtables(
|
||||
|
||||
var machineKey key.MachinePublic
|
||||
err := machineKey.UnmarshalText(
|
||||
[]byte(hscontrol.MachinePublicKeyEnsurePrefix(machine.MachineKey)),
|
||||
[]byte(headscale.MachinePublicKeyEnsurePrefix(machine.MachineKey)),
|
||||
)
|
||||
if err != nil {
|
||||
machineKey = key.MachinePublic{}
|
||||
@@ -537,7 +537,7 @@ func nodesToPtables(
|
||||
|
||||
var nodeKey key.NodePublic
|
||||
err = nodeKey.UnmarshalText(
|
||||
[]byte(hscontrol.NodePublicKeyEnsurePrefix(machine.NodeKey)),
|
||||
[]byte(headscale.NodePublicKeyEnsurePrefix(machine.NodeKey)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -596,7 +596,7 @@ func nodesToPtables(
|
||||
}
|
||||
|
||||
nodeData := []string{
|
||||
strconv.FormatUint(machine.Id, hscontrol.Base10),
|
||||
strconv.FormatUint(machine.Id, headscale.Base10),
|
||||
machine.Name,
|
||||
machine.GetGivenName(),
|
||||
machineKey.ShortString(),
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/juanfont/headscale"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -38,18 +38,18 @@ func initConfig() {
|
||||
cfgFile = os.Getenv("HEADSCALE_CONFIG")
|
||||
}
|
||||
if cfgFile != "" {
|
||||
err := hscontrol.LoadConfig(cfgFile, true)
|
||||
err := headscale.LoadConfig(cfgFile, true)
|
||||
if err != nil {
|
||||
log.Fatal().Caller().Err(err).Msgf("Error loading config file %s", cfgFile)
|
||||
}
|
||||
} else {
|
||||
err := hscontrol.LoadConfig("", false)
|
||||
err := headscale.LoadConfig("", false)
|
||||
if err != nil {
|
||||
log.Fatal().Caller().Err(err).Msgf("Error loading config")
|
||||
}
|
||||
}
|
||||
|
||||
cfg, err := hscontrol.GetHeadscaleConfig()
|
||||
cfg, err := headscale.GetHeadscaleConfig()
|
||||
if err != nil {
|
||||
log.Fatal().Caller().Err(err)
|
||||
}
|
||||
@@ -64,7 +64,7 @@ func initConfig() {
|
||||
zerolog.SetGlobalLevel(zerolog.Disabled)
|
||||
}
|
||||
|
||||
if cfg.Log.Format == hscontrol.JSONLogFormat {
|
||||
if cfg.Log.Format == headscale.JSONLogFormat {
|
||||
log.Logger = log.Output(os.Stdout)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"net/netip"
|
||||
"strconv"
|
||||
|
||||
"github.com/juanfont/headscale"
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/pterm/pterm"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/status"
|
||||
@@ -277,7 +277,7 @@ func routesToPtables(routes []*v1.Route) pterm.TableData {
|
||||
|
||||
continue
|
||||
}
|
||||
if prefix == hscontrol.ExitRouteV4 || prefix == hscontrol.ExitRouteV6 {
|
||||
if prefix == headscale.ExitRouteV4 || prefix == headscale.ExitRouteV6 {
|
||||
isPrimaryStr = "-"
|
||||
} else {
|
||||
isPrimaryStr = strconv.FormatBool(route.IsPrimary)
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
|
||||
survey "github.com/AlecAivazis/survey/v2"
|
||||
"github.com/juanfont/headscale"
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/pterm/pterm"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -21,7 +21,7 @@ func init() {
|
||||
}
|
||||
|
||||
const (
|
||||
errMissingParameter = hscontrol.Error("missing parameters")
|
||||
errMissingParameter = headscale.Error("missing parameters")
|
||||
)
|
||||
|
||||
var userCmd = &cobra.Command{
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
"github.com/juanfont/headscale"
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/rs/zerolog/log"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
@@ -22,8 +22,8 @@ const (
|
||||
SocketWritePermissions = 0o666
|
||||
)
|
||||
|
||||
func getHeadscaleApp() (*hscontrol.Headscale, error) {
|
||||
cfg, err := hscontrol.GetHeadscaleConfig()
|
||||
func getHeadscaleApp() (*headscale.Headscale, error) {
|
||||
cfg, err := headscale.GetHeadscaleConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"failed to load configuration while creating headscale instance: %w",
|
||||
@@ -31,7 +31,7 @@ func getHeadscaleApp() (*hscontrol.Headscale, error) {
|
||||
)
|
||||
}
|
||||
|
||||
app, err := hscontrol.NewHeadscale(cfg)
|
||||
app, err := headscale.NewHeadscale(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -39,8 +39,8 @@ func getHeadscaleApp() (*hscontrol.Headscale, error) {
|
||||
// We are doing this here, as in the future could be cool to have it also hot-reload
|
||||
|
||||
if cfg.ACL.PolicyPath != "" {
|
||||
aclPath := hscontrol.AbsolutePathFromConfigPath(cfg.ACL.PolicyPath)
|
||||
err = app.LoadACLPolicyFromPath(aclPath)
|
||||
aclPath := headscale.AbsolutePathFromConfigPath(cfg.ACL.PolicyPath)
|
||||
err = app.LoadACLPolicy(aclPath)
|
||||
if err != nil {
|
||||
log.Fatal().
|
||||
Str("path", aclPath).
|
||||
@@ -53,7 +53,7 @@ func getHeadscaleApp() (*hscontrol.Headscale, error) {
|
||||
}
|
||||
|
||||
func getHeadscaleCLIClient() (context.Context, v1.HeadscaleServiceClient, *grpc.ClientConn, context.CancelFunc) {
|
||||
cfg, err := hscontrol.GetHeadscaleConfig()
|
||||
cfg, err := headscale.GetHeadscaleConfig()
|
||||
if err != nil {
|
||||
log.Fatal().
|
||||
Err(err).
|
||||
@@ -74,7 +74,7 @@ func getHeadscaleCLIClient() (context.Context, v1.HeadscaleServiceClient, *grpc.
|
||||
|
||||
address := cfg.CLI.Address
|
||||
|
||||
// If the address is not set, we assume that we are on the server hosting hscontrol.
|
||||
// If the address is not set, we assume that we are on the server hosting headscale.
|
||||
if address == "" {
|
||||
log.Debug().
|
||||
Str("socket", cfg.UnixSocket).
|
||||
@@ -98,7 +98,7 @@ func getHeadscaleCLIClient() (context.Context, v1.HeadscaleServiceClient, *grpc.
|
||||
grpcOptions = append(
|
||||
grpcOptions,
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
grpc.WithContextDialer(hscontrol.GrpcSocketDialer),
|
||||
grpc.WithContextDialer(headscale.GrpcSocketDialer),
|
||||
)
|
||||
} else {
|
||||
// If we are not connecting to a local server, require an API key for authentication
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/juanfont/headscale"
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/check.v1"
|
||||
)
|
||||
@@ -50,7 +50,7 @@ func (*Suite) TestConfigFileLoading(c *check.C) {
|
||||
}
|
||||
|
||||
// Load example config, it should load without validation errors
|
||||
err = hscontrol.LoadConfig(cfgFile, true)
|
||||
err = headscale.LoadConfig(cfgFile, true)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
// Test that config file was interpreted correctly
|
||||
@@ -64,7 +64,7 @@ func (*Suite) TestConfigFileLoading(c *check.C) {
|
||||
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(
|
||||
hscontrol.GetFileMode("unix_socket_permission"),
|
||||
headscale.GetFileMode("unix_socket_permission"),
|
||||
check.Equals,
|
||||
fs.FileMode(0o770),
|
||||
)
|
||||
@@ -93,7 +93,7 @@ func (*Suite) TestConfigLoading(c *check.C) {
|
||||
}
|
||||
|
||||
// Load example config, it should load without validation errors
|
||||
err = hscontrol.LoadConfig(tmpDir, false)
|
||||
err = headscale.LoadConfig(tmpDir, false)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
// Test that config file was interpreted correctly
|
||||
@@ -107,7 +107,7 @@ func (*Suite) TestConfigLoading(c *check.C) {
|
||||
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(
|
||||
hscontrol.GetFileMode("unix_socket_permission"),
|
||||
headscale.GetFileMode("unix_socket_permission"),
|
||||
check.Equals,
|
||||
fs.FileMode(0o770),
|
||||
)
|
||||
@@ -137,10 +137,10 @@ func (*Suite) TestDNSConfigLoading(c *check.C) {
|
||||
}
|
||||
|
||||
// Load example config, it should load without validation errors
|
||||
err = hscontrol.LoadConfig(tmpDir, false)
|
||||
err = headscale.LoadConfig(tmpDir, false)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
dnsConfig, baseDomain := hscontrol.GetDNSConfig()
|
||||
dnsConfig, baseDomain := headscale.GetDNSConfig()
|
||||
|
||||
c.Assert(dnsConfig.Nameservers[0].String(), check.Equals, "1.1.1.1")
|
||||
c.Assert(dnsConfig.Resolvers[0].Addr, check.Equals, "1.1.1.1")
|
||||
@@ -172,7 +172,7 @@ noise:
|
||||
writeConfig(c, tmpDir, configYaml)
|
||||
|
||||
// Check configuration validation errors (1)
|
||||
err = hscontrol.LoadConfig(tmpDir, false)
|
||||
err = headscale.LoadConfig(tmpDir, false)
|
||||
c.Assert(err, check.NotNil)
|
||||
// check.Matches can not handle multiline strings
|
||||
tmp := strings.ReplaceAll(err.Error(), "\n", "***")
|
||||
@@ -201,6 +201,6 @@ tls_letsencrypt_hostname: example.com
|
||||
tls_letsencrypt_challenge_type: TLS-ALPN-01
|
||||
`)
|
||||
writeConfig(c, tmpDir, configYaml)
|
||||
err = hscontrol.LoadConfig(tmpDir, false)
|
||||
err = headscale.LoadConfig(tmpDir, false)
|
||||
c.Assert(err, check.IsNil)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -175,7 +175,7 @@ func LoadConfig(path string, isFile bool) error {
|
||||
viper.SetDefault("derp.server.enabled", false)
|
||||
viper.SetDefault("derp.server.stun.enabled", true)
|
||||
|
||||
viper.SetDefault("unix_socket", "/var/run/headscale/headscale.sock")
|
||||
viper.SetDefault("unix_socket", "/var/run/headscale.sock")
|
||||
viper.SetDefault("unix_socket_permission", "0o770")
|
||||
|
||||
viper.SetDefault("grpc_listen_addr", ":50443")
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,14 +0,0 @@
|
||||
# Headscale web interface
|
||||
|
||||
!!! warning "Community contributions"
|
||||
|
||||
This page contains community contributions. The projects listed here are not
|
||||
maintained by the Headscale authors and are written by community members.
|
||||
|
||||
| Name | Repository Link | Description | Status |
|
||||
| --------------- | ------------------------------------------------------- | ------------------------------------------------------------------------- | ------ |
|
||||
| headscale-webui | [Github](https://github.com/ifargle/headscale-webui) | A simple Headscale web UI for small-scale deployments. | Alpha |
|
||||
| headscale-ui | [Github](https://github.com/gurucomputing/headscale-ui) | A web frontend for the headscale Tailscale-compatible coordination server | Alpha |
|
||||
| HeadscaleUi | [GitHub](https://github.com/simcu/headscale-ui) | A static headscale admin ui, no backend enviroment required | Alpha |
|
||||
|
||||
You can ask for support on our dedicated [Discord channel](https://discord.com/channels/896711691637780480/1105842846386356294).
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
# When updating go.mod or go.sum, a new sha will need to be calculated,
|
||||
# update this if you have a mismatch after doing a change to thos files.
|
||||
vendorSha256 = "sha256-IOkbbFtE6+tNKnglE/8ZuNxhPSnloqM2sLgTvagMmnc=";
|
||||
vendorSha256 = "sha256-cmDNYWYTgQp6CPgpL4d3TbkpAe7rhNAF+o8njJsgL7E=";
|
||||
|
||||
ldflags = [ "-s" "-w" "-X github.com/juanfont/headscale/cmd/headscale/cli.Version=v${version}" ];
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.29.1
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc (unknown)
|
||||
// source: headscale/v1/apikey.proto
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.29.1
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc (unknown)
|
||||
// source: headscale/v1/device.proto
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.29.1
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc (unknown)
|
||||
// source: headscale/v1/headscale.proto
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.3.0
|
||||
// - protoc-gen-go-grpc v1.2.0
|
||||
// - protoc (unknown)
|
||||
// source: headscale/v1/headscale.proto
|
||||
|
||||
@@ -18,34 +18,6 @@ import (
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
HeadscaleService_GetUser_FullMethodName = "/headscale.v1.HeadscaleService/GetUser"
|
||||
HeadscaleService_CreateUser_FullMethodName = "/headscale.v1.HeadscaleService/CreateUser"
|
||||
HeadscaleService_RenameUser_FullMethodName = "/headscale.v1.HeadscaleService/RenameUser"
|
||||
HeadscaleService_DeleteUser_FullMethodName = "/headscale.v1.HeadscaleService/DeleteUser"
|
||||
HeadscaleService_ListUsers_FullMethodName = "/headscale.v1.HeadscaleService/ListUsers"
|
||||
HeadscaleService_CreatePreAuthKey_FullMethodName = "/headscale.v1.HeadscaleService/CreatePreAuthKey"
|
||||
HeadscaleService_ExpirePreAuthKey_FullMethodName = "/headscale.v1.HeadscaleService/ExpirePreAuthKey"
|
||||
HeadscaleService_ListPreAuthKeys_FullMethodName = "/headscale.v1.HeadscaleService/ListPreAuthKeys"
|
||||
HeadscaleService_DebugCreateMachine_FullMethodName = "/headscale.v1.HeadscaleService/DebugCreateMachine"
|
||||
HeadscaleService_GetMachine_FullMethodName = "/headscale.v1.HeadscaleService/GetMachine"
|
||||
HeadscaleService_SetTags_FullMethodName = "/headscale.v1.HeadscaleService/SetTags"
|
||||
HeadscaleService_RegisterMachine_FullMethodName = "/headscale.v1.HeadscaleService/RegisterMachine"
|
||||
HeadscaleService_DeleteMachine_FullMethodName = "/headscale.v1.HeadscaleService/DeleteMachine"
|
||||
HeadscaleService_ExpireMachine_FullMethodName = "/headscale.v1.HeadscaleService/ExpireMachine"
|
||||
HeadscaleService_RenameMachine_FullMethodName = "/headscale.v1.HeadscaleService/RenameMachine"
|
||||
HeadscaleService_ListMachines_FullMethodName = "/headscale.v1.HeadscaleService/ListMachines"
|
||||
HeadscaleService_MoveMachine_FullMethodName = "/headscale.v1.HeadscaleService/MoveMachine"
|
||||
HeadscaleService_GetRoutes_FullMethodName = "/headscale.v1.HeadscaleService/GetRoutes"
|
||||
HeadscaleService_EnableRoute_FullMethodName = "/headscale.v1.HeadscaleService/EnableRoute"
|
||||
HeadscaleService_DisableRoute_FullMethodName = "/headscale.v1.HeadscaleService/DisableRoute"
|
||||
HeadscaleService_GetMachineRoutes_FullMethodName = "/headscale.v1.HeadscaleService/GetMachineRoutes"
|
||||
HeadscaleService_DeleteRoute_FullMethodName = "/headscale.v1.HeadscaleService/DeleteRoute"
|
||||
HeadscaleService_CreateApiKey_FullMethodName = "/headscale.v1.HeadscaleService/CreateApiKey"
|
||||
HeadscaleService_ExpireApiKey_FullMethodName = "/headscale.v1.HeadscaleService/ExpireApiKey"
|
||||
HeadscaleService_ListApiKeys_FullMethodName = "/headscale.v1.HeadscaleService/ListApiKeys"
|
||||
)
|
||||
|
||||
// HeadscaleServiceClient is the client API for HeadscaleService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
@@ -92,7 +64,7 @@ func NewHeadscaleServiceClient(cc grpc.ClientConnInterface) HeadscaleServiceClie
|
||||
|
||||
func (c *headscaleServiceClient) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error) {
|
||||
out := new(GetUserResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_GetUser_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetUser", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -101,7 +73,7 @@ func (c *headscaleServiceClient) GetUser(ctx context.Context, in *GetUserRequest
|
||||
|
||||
func (c *headscaleServiceClient) CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) {
|
||||
out := new(CreateUserResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_CreateUser_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/CreateUser", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -110,7 +82,7 @@ func (c *headscaleServiceClient) CreateUser(ctx context.Context, in *CreateUserR
|
||||
|
||||
func (c *headscaleServiceClient) RenameUser(ctx context.Context, in *RenameUserRequest, opts ...grpc.CallOption) (*RenameUserResponse, error) {
|
||||
out := new(RenameUserResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_RenameUser_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/RenameUser", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -119,7 +91,7 @@ func (c *headscaleServiceClient) RenameUser(ctx context.Context, in *RenameUserR
|
||||
|
||||
func (c *headscaleServiceClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*DeleteUserResponse, error) {
|
||||
out := new(DeleteUserResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_DeleteUser_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DeleteUser", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -128,7 +100,7 @@ func (c *headscaleServiceClient) DeleteUser(ctx context.Context, in *DeleteUserR
|
||||
|
||||
func (c *headscaleServiceClient) ListUsers(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (*ListUsersResponse, error) {
|
||||
out := new(ListUsersResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_ListUsers_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ListUsers", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -137,7 +109,7 @@ func (c *headscaleServiceClient) ListUsers(ctx context.Context, in *ListUsersReq
|
||||
|
||||
func (c *headscaleServiceClient) CreatePreAuthKey(ctx context.Context, in *CreatePreAuthKeyRequest, opts ...grpc.CallOption) (*CreatePreAuthKeyResponse, error) {
|
||||
out := new(CreatePreAuthKeyResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_CreatePreAuthKey_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/CreatePreAuthKey", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -146,7 +118,7 @@ func (c *headscaleServiceClient) CreatePreAuthKey(ctx context.Context, in *Creat
|
||||
|
||||
func (c *headscaleServiceClient) ExpirePreAuthKey(ctx context.Context, in *ExpirePreAuthKeyRequest, opts ...grpc.CallOption) (*ExpirePreAuthKeyResponse, error) {
|
||||
out := new(ExpirePreAuthKeyResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_ExpirePreAuthKey_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ExpirePreAuthKey", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -155,7 +127,7 @@ func (c *headscaleServiceClient) ExpirePreAuthKey(ctx context.Context, in *Expir
|
||||
|
||||
func (c *headscaleServiceClient) ListPreAuthKeys(ctx context.Context, in *ListPreAuthKeysRequest, opts ...grpc.CallOption) (*ListPreAuthKeysResponse, error) {
|
||||
out := new(ListPreAuthKeysResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_ListPreAuthKeys_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ListPreAuthKeys", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -164,7 +136,7 @@ func (c *headscaleServiceClient) ListPreAuthKeys(ctx context.Context, in *ListPr
|
||||
|
||||
func (c *headscaleServiceClient) DebugCreateMachine(ctx context.Context, in *DebugCreateMachineRequest, opts ...grpc.CallOption) (*DebugCreateMachineResponse, error) {
|
||||
out := new(DebugCreateMachineResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_DebugCreateMachine_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DebugCreateMachine", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -173,7 +145,7 @@ func (c *headscaleServiceClient) DebugCreateMachine(ctx context.Context, in *Deb
|
||||
|
||||
func (c *headscaleServiceClient) GetMachine(ctx context.Context, in *GetMachineRequest, opts ...grpc.CallOption) (*GetMachineResponse, error) {
|
||||
out := new(GetMachineResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_GetMachine_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetMachine", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -182,7 +154,7 @@ func (c *headscaleServiceClient) GetMachine(ctx context.Context, in *GetMachineR
|
||||
|
||||
func (c *headscaleServiceClient) SetTags(ctx context.Context, in *SetTagsRequest, opts ...grpc.CallOption) (*SetTagsResponse, error) {
|
||||
out := new(SetTagsResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_SetTags_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/SetTags", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -191,7 +163,7 @@ func (c *headscaleServiceClient) SetTags(ctx context.Context, in *SetTagsRequest
|
||||
|
||||
func (c *headscaleServiceClient) RegisterMachine(ctx context.Context, in *RegisterMachineRequest, opts ...grpc.CallOption) (*RegisterMachineResponse, error) {
|
||||
out := new(RegisterMachineResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_RegisterMachine_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/RegisterMachine", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -200,7 +172,7 @@ func (c *headscaleServiceClient) RegisterMachine(ctx context.Context, in *Regist
|
||||
|
||||
func (c *headscaleServiceClient) DeleteMachine(ctx context.Context, in *DeleteMachineRequest, opts ...grpc.CallOption) (*DeleteMachineResponse, error) {
|
||||
out := new(DeleteMachineResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_DeleteMachine_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DeleteMachine", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -209,7 +181,7 @@ func (c *headscaleServiceClient) DeleteMachine(ctx context.Context, in *DeleteMa
|
||||
|
||||
func (c *headscaleServiceClient) ExpireMachine(ctx context.Context, in *ExpireMachineRequest, opts ...grpc.CallOption) (*ExpireMachineResponse, error) {
|
||||
out := new(ExpireMachineResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_ExpireMachine_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ExpireMachine", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -218,7 +190,7 @@ func (c *headscaleServiceClient) ExpireMachine(ctx context.Context, in *ExpireMa
|
||||
|
||||
func (c *headscaleServiceClient) RenameMachine(ctx context.Context, in *RenameMachineRequest, opts ...grpc.CallOption) (*RenameMachineResponse, error) {
|
||||
out := new(RenameMachineResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_RenameMachine_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/RenameMachine", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -227,7 +199,7 @@ func (c *headscaleServiceClient) RenameMachine(ctx context.Context, in *RenameMa
|
||||
|
||||
func (c *headscaleServiceClient) ListMachines(ctx context.Context, in *ListMachinesRequest, opts ...grpc.CallOption) (*ListMachinesResponse, error) {
|
||||
out := new(ListMachinesResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_ListMachines_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ListMachines", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -236,7 +208,7 @@ func (c *headscaleServiceClient) ListMachines(ctx context.Context, in *ListMachi
|
||||
|
||||
func (c *headscaleServiceClient) MoveMachine(ctx context.Context, in *MoveMachineRequest, opts ...grpc.CallOption) (*MoveMachineResponse, error) {
|
||||
out := new(MoveMachineResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_MoveMachine_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/MoveMachine", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -245,7 +217,7 @@ func (c *headscaleServiceClient) MoveMachine(ctx context.Context, in *MoveMachin
|
||||
|
||||
func (c *headscaleServiceClient) GetRoutes(ctx context.Context, in *GetRoutesRequest, opts ...grpc.CallOption) (*GetRoutesResponse, error) {
|
||||
out := new(GetRoutesResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_GetRoutes_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetRoutes", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -254,7 +226,7 @@ func (c *headscaleServiceClient) GetRoutes(ctx context.Context, in *GetRoutesReq
|
||||
|
||||
func (c *headscaleServiceClient) EnableRoute(ctx context.Context, in *EnableRouteRequest, opts ...grpc.CallOption) (*EnableRouteResponse, error) {
|
||||
out := new(EnableRouteResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_EnableRoute_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/EnableRoute", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -263,7 +235,7 @@ func (c *headscaleServiceClient) EnableRoute(ctx context.Context, in *EnableRout
|
||||
|
||||
func (c *headscaleServiceClient) DisableRoute(ctx context.Context, in *DisableRouteRequest, opts ...grpc.CallOption) (*DisableRouteResponse, error) {
|
||||
out := new(DisableRouteResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_DisableRoute_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DisableRoute", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -272,7 +244,7 @@ func (c *headscaleServiceClient) DisableRoute(ctx context.Context, in *DisableRo
|
||||
|
||||
func (c *headscaleServiceClient) GetMachineRoutes(ctx context.Context, in *GetMachineRoutesRequest, opts ...grpc.CallOption) (*GetMachineRoutesResponse, error) {
|
||||
out := new(GetMachineRoutesResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_GetMachineRoutes_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/GetMachineRoutes", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -281,7 +253,7 @@ func (c *headscaleServiceClient) GetMachineRoutes(ctx context.Context, in *GetMa
|
||||
|
||||
func (c *headscaleServiceClient) DeleteRoute(ctx context.Context, in *DeleteRouteRequest, opts ...grpc.CallOption) (*DeleteRouteResponse, error) {
|
||||
out := new(DeleteRouteResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_DeleteRoute_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/DeleteRoute", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -290,7 +262,7 @@ func (c *headscaleServiceClient) DeleteRoute(ctx context.Context, in *DeleteRout
|
||||
|
||||
func (c *headscaleServiceClient) CreateApiKey(ctx context.Context, in *CreateApiKeyRequest, opts ...grpc.CallOption) (*CreateApiKeyResponse, error) {
|
||||
out := new(CreateApiKeyResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_CreateApiKey_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/CreateApiKey", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -299,7 +271,7 @@ func (c *headscaleServiceClient) CreateApiKey(ctx context.Context, in *CreateApi
|
||||
|
||||
func (c *headscaleServiceClient) ExpireApiKey(ctx context.Context, in *ExpireApiKeyRequest, opts ...grpc.CallOption) (*ExpireApiKeyResponse, error) {
|
||||
out := new(ExpireApiKeyResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_ExpireApiKey_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ExpireApiKey", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -308,7 +280,7 @@ func (c *headscaleServiceClient) ExpireApiKey(ctx context.Context, in *ExpireApi
|
||||
|
||||
func (c *headscaleServiceClient) ListApiKeys(ctx context.Context, in *ListApiKeysRequest, opts ...grpc.CallOption) (*ListApiKeysResponse, error) {
|
||||
out := new(ListApiKeysResponse)
|
||||
err := c.cc.Invoke(ctx, HeadscaleService_ListApiKeys_FullMethodName, in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, "/headscale.v1.HeadscaleService/ListApiKeys", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -454,7 +426,7 @@ func _HeadscaleService_GetUser_Handler(srv interface{}, ctx context.Context, dec
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_GetUser_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/GetUser",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).GetUser(ctx, req.(*GetUserRequest))
|
||||
@@ -472,7 +444,7 @@ func _HeadscaleService_CreateUser_Handler(srv interface{}, ctx context.Context,
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_CreateUser_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/CreateUser",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).CreateUser(ctx, req.(*CreateUserRequest))
|
||||
@@ -490,7 +462,7 @@ func _HeadscaleService_RenameUser_Handler(srv interface{}, ctx context.Context,
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_RenameUser_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/RenameUser",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).RenameUser(ctx, req.(*RenameUserRequest))
|
||||
@@ -508,7 +480,7 @@ func _HeadscaleService_DeleteUser_Handler(srv interface{}, ctx context.Context,
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_DeleteUser_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/DeleteUser",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).DeleteUser(ctx, req.(*DeleteUserRequest))
|
||||
@@ -526,7 +498,7 @@ func _HeadscaleService_ListUsers_Handler(srv interface{}, ctx context.Context, d
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_ListUsers_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/ListUsers",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).ListUsers(ctx, req.(*ListUsersRequest))
|
||||
@@ -544,7 +516,7 @@ func _HeadscaleService_CreatePreAuthKey_Handler(srv interface{}, ctx context.Con
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_CreatePreAuthKey_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/CreatePreAuthKey",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).CreatePreAuthKey(ctx, req.(*CreatePreAuthKeyRequest))
|
||||
@@ -562,7 +534,7 @@ func _HeadscaleService_ExpirePreAuthKey_Handler(srv interface{}, ctx context.Con
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_ExpirePreAuthKey_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/ExpirePreAuthKey",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).ExpirePreAuthKey(ctx, req.(*ExpirePreAuthKeyRequest))
|
||||
@@ -580,7 +552,7 @@ func _HeadscaleService_ListPreAuthKeys_Handler(srv interface{}, ctx context.Cont
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_ListPreAuthKeys_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/ListPreAuthKeys",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).ListPreAuthKeys(ctx, req.(*ListPreAuthKeysRequest))
|
||||
@@ -598,7 +570,7 @@ func _HeadscaleService_DebugCreateMachine_Handler(srv interface{}, ctx context.C
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_DebugCreateMachine_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/DebugCreateMachine",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).DebugCreateMachine(ctx, req.(*DebugCreateMachineRequest))
|
||||
@@ -616,7 +588,7 @@ func _HeadscaleService_GetMachine_Handler(srv interface{}, ctx context.Context,
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_GetMachine_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/GetMachine",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).GetMachine(ctx, req.(*GetMachineRequest))
|
||||
@@ -634,7 +606,7 @@ func _HeadscaleService_SetTags_Handler(srv interface{}, ctx context.Context, dec
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_SetTags_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/SetTags",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).SetTags(ctx, req.(*SetTagsRequest))
|
||||
@@ -652,7 +624,7 @@ func _HeadscaleService_RegisterMachine_Handler(srv interface{}, ctx context.Cont
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_RegisterMachine_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/RegisterMachine",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).RegisterMachine(ctx, req.(*RegisterMachineRequest))
|
||||
@@ -670,7 +642,7 @@ func _HeadscaleService_DeleteMachine_Handler(srv interface{}, ctx context.Contex
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_DeleteMachine_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/DeleteMachine",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).DeleteMachine(ctx, req.(*DeleteMachineRequest))
|
||||
@@ -688,7 +660,7 @@ func _HeadscaleService_ExpireMachine_Handler(srv interface{}, ctx context.Contex
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_ExpireMachine_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/ExpireMachine",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).ExpireMachine(ctx, req.(*ExpireMachineRequest))
|
||||
@@ -706,7 +678,7 @@ func _HeadscaleService_RenameMachine_Handler(srv interface{}, ctx context.Contex
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_RenameMachine_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/RenameMachine",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).RenameMachine(ctx, req.(*RenameMachineRequest))
|
||||
@@ -724,7 +696,7 @@ func _HeadscaleService_ListMachines_Handler(srv interface{}, ctx context.Context
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_ListMachines_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/ListMachines",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).ListMachines(ctx, req.(*ListMachinesRequest))
|
||||
@@ -742,7 +714,7 @@ func _HeadscaleService_MoveMachine_Handler(srv interface{}, ctx context.Context,
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_MoveMachine_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/MoveMachine",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).MoveMachine(ctx, req.(*MoveMachineRequest))
|
||||
@@ -760,7 +732,7 @@ func _HeadscaleService_GetRoutes_Handler(srv interface{}, ctx context.Context, d
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_GetRoutes_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/GetRoutes",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).GetRoutes(ctx, req.(*GetRoutesRequest))
|
||||
@@ -778,7 +750,7 @@ func _HeadscaleService_EnableRoute_Handler(srv interface{}, ctx context.Context,
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_EnableRoute_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/EnableRoute",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).EnableRoute(ctx, req.(*EnableRouteRequest))
|
||||
@@ -796,7 +768,7 @@ func _HeadscaleService_DisableRoute_Handler(srv interface{}, ctx context.Context
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_DisableRoute_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/DisableRoute",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).DisableRoute(ctx, req.(*DisableRouteRequest))
|
||||
@@ -814,7 +786,7 @@ func _HeadscaleService_GetMachineRoutes_Handler(srv interface{}, ctx context.Con
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_GetMachineRoutes_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/GetMachineRoutes",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).GetMachineRoutes(ctx, req.(*GetMachineRoutesRequest))
|
||||
@@ -832,7 +804,7 @@ func _HeadscaleService_DeleteRoute_Handler(srv interface{}, ctx context.Context,
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_DeleteRoute_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/DeleteRoute",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).DeleteRoute(ctx, req.(*DeleteRouteRequest))
|
||||
@@ -850,7 +822,7 @@ func _HeadscaleService_CreateApiKey_Handler(srv interface{}, ctx context.Context
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_CreateApiKey_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/CreateApiKey",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).CreateApiKey(ctx, req.(*CreateApiKeyRequest))
|
||||
@@ -868,7 +840,7 @@ func _HeadscaleService_ExpireApiKey_Handler(srv interface{}, ctx context.Context
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_ExpireApiKey_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/ExpireApiKey",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).ExpireApiKey(ctx, req.(*ExpireApiKeyRequest))
|
||||
@@ -886,7 +858,7 @@ func _HeadscaleService_ListApiKeys_Handler(srv interface{}, ctx context.Context,
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: HeadscaleService_ListApiKeys_FullMethodName,
|
||||
FullMethod: "/headscale.v1.HeadscaleService/ListApiKeys",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HeadscaleServiceServer).ListApiKeys(ctx, req.(*ListApiKeysRequest))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.29.1
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc (unknown)
|
||||
// source: headscale/v1/machine.proto
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.29.1
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc (unknown)
|
||||
// source: headscale/v1/preauthkey.proto
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.29.1
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc (unknown)
|
||||
// source: headscale/v1/routes.proto
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.29.1
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc (unknown)
|
||||
// source: headscale/v1/user.proto
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// nolint
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import "testing"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//go:build ts2019
|
||||
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
@@ -1,6 +1,6 @@
|
||||
//go:build !ts2019
|
||||
|
||||
package hscontrol
|
||||
package headscale
|
||||
|
||||
import "github.com/gorilla/mux"
|
||||
|
||||
+44
-44
@@ -6,7 +6,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/juanfont/headscale"
|
||||
"github.com/juanfont/headscale/integration/hsic"
|
||||
"github.com/juanfont/headscale/integration/tsic"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -45,7 +45,7 @@ var veryLargeDestination = []string{
|
||||
"208.0.0.0/4:*",
|
||||
}
|
||||
|
||||
func aclScenario(t *testing.T, policy *hscontrol.ACLPolicy, clientsPerUser int) *Scenario {
|
||||
func aclScenario(t *testing.T, policy *headscale.ACLPolicy, clientsPerUser int) *Scenario {
|
||||
t.Helper()
|
||||
scenario, err := NewScenario()
|
||||
assert.NoError(t, err)
|
||||
@@ -92,7 +92,7 @@ func TestACLHostsInNetMapTable(t *testing.T) {
|
||||
// they can access minus one (them self).
|
||||
tests := map[string]struct {
|
||||
users map[string]int
|
||||
policy hscontrol.ACLPolicy
|
||||
policy headscale.ACLPolicy
|
||||
want map[string]int
|
||||
}{
|
||||
// Test that when we have no ACL, each client netmap has
|
||||
@@ -102,8 +102,8 @@ func TestACLHostsInNetMapTable(t *testing.T) {
|
||||
"user1": 2,
|
||||
"user2": 2,
|
||||
},
|
||||
policy: hscontrol.ACLPolicy{
|
||||
ACLs: []hscontrol.ACL{
|
||||
policy: headscale.ACLPolicy{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"*"},
|
||||
@@ -123,8 +123,8 @@ func TestACLHostsInNetMapTable(t *testing.T) {
|
||||
"user1": 2,
|
||||
"user2": 2,
|
||||
},
|
||||
policy: hscontrol.ACLPolicy{
|
||||
ACLs: []hscontrol.ACL{
|
||||
policy: headscale.ACLPolicy{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
@@ -149,8 +149,8 @@ func TestACLHostsInNetMapTable(t *testing.T) {
|
||||
"user1": 2,
|
||||
"user2": 2,
|
||||
},
|
||||
policy: hscontrol.ACLPolicy{
|
||||
ACLs: []hscontrol.ACL{
|
||||
policy: headscale.ACLPolicy{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
@@ -186,8 +186,8 @@ func TestACLHostsInNetMapTable(t *testing.T) {
|
||||
"user1": 2,
|
||||
"user2": 2,
|
||||
},
|
||||
policy: hscontrol.ACLPolicy{
|
||||
ACLs: []hscontrol.ACL{
|
||||
policy: headscale.ACLPolicy{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
@@ -214,8 +214,8 @@ func TestACLHostsInNetMapTable(t *testing.T) {
|
||||
"user1": 2,
|
||||
"user2": 2,
|
||||
},
|
||||
policy: hscontrol.ACLPolicy{
|
||||
ACLs: []hscontrol.ACL{
|
||||
policy: headscale.ACLPolicy{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
@@ -282,8 +282,8 @@ func TestACLAllowUser80Dst(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
|
||||
scenario := aclScenario(t,
|
||||
&hscontrol.ACLPolicy{
|
||||
ACLs: []hscontrol.ACL{
|
||||
&headscale.ACLPolicy{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
@@ -338,11 +338,11 @@ func TestACLDenyAllPort80(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
|
||||
scenario := aclScenario(t,
|
||||
&hscontrol.ACLPolicy{
|
||||
&headscale.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:integration-acl-test": {"user1", "user2"},
|
||||
},
|
||||
ACLs: []hscontrol.ACL{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"group:integration-acl-test"},
|
||||
@@ -387,8 +387,8 @@ func TestACLAllowUserDst(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
|
||||
scenario := aclScenario(t,
|
||||
&hscontrol.ACLPolicy{
|
||||
ACLs: []hscontrol.ACL{
|
||||
&headscale.ACLPolicy{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
@@ -445,8 +445,8 @@ func TestACLAllowStarDst(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
|
||||
scenario := aclScenario(t,
|
||||
&hscontrol.ACLPolicy{
|
||||
ACLs: []hscontrol.ACL{
|
||||
&headscale.ACLPolicy{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"user1"},
|
||||
@@ -504,11 +504,11 @@ func TestACLNamedHostsCanReachBySubnet(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
|
||||
scenario := aclScenario(t,
|
||||
&hscontrol.ACLPolicy{
|
||||
Hosts: hscontrol.Hosts{
|
||||
&headscale.ACLPolicy{
|
||||
Hosts: headscale.Hosts{
|
||||
"all": netip.MustParsePrefix("100.64.0.0/24"),
|
||||
},
|
||||
ACLs: []hscontrol.ACL{
|
||||
ACLs: []headscale.ACL{
|
||||
// Everyone can curl test3
|
||||
{
|
||||
Action: "accept",
|
||||
@@ -603,16 +603,16 @@ func TestACLNamedHostsCanReach(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
|
||||
tests := map[string]struct {
|
||||
policy hscontrol.ACLPolicy
|
||||
policy headscale.ACLPolicy
|
||||
}{
|
||||
"ipv4": {
|
||||
policy: hscontrol.ACLPolicy{
|
||||
Hosts: hscontrol.Hosts{
|
||||
policy: headscale.ACLPolicy{
|
||||
Hosts: headscale.Hosts{
|
||||
"test1": netip.MustParsePrefix("100.64.0.1/32"),
|
||||
"test2": netip.MustParsePrefix("100.64.0.2/32"),
|
||||
"test3": netip.MustParsePrefix("100.64.0.3/32"),
|
||||
},
|
||||
ACLs: []hscontrol.ACL{
|
||||
ACLs: []headscale.ACL{
|
||||
// Everyone can curl test3
|
||||
{
|
||||
Action: "accept",
|
||||
@@ -629,13 +629,13 @@ func TestACLNamedHostsCanReach(t *testing.T) {
|
||||
},
|
||||
},
|
||||
"ipv6": {
|
||||
policy: hscontrol.ACLPolicy{
|
||||
Hosts: hscontrol.Hosts{
|
||||
policy: headscale.ACLPolicy{
|
||||
Hosts: headscale.Hosts{
|
||||
"test1": netip.MustParsePrefix("fd7a:115c:a1e0::1/128"),
|
||||
"test2": netip.MustParsePrefix("fd7a:115c:a1e0::2/128"),
|
||||
"test3": netip.MustParsePrefix("fd7a:115c:a1e0::3/128"),
|
||||
},
|
||||
ACLs: []hscontrol.ACL{
|
||||
ACLs: []headscale.ACL{
|
||||
// Everyone can curl test3
|
||||
{
|
||||
Action: "accept",
|
||||
@@ -854,11 +854,11 @@ func TestACLDevice1CanAccessDevice2(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
|
||||
tests := map[string]struct {
|
||||
policy hscontrol.ACLPolicy
|
||||
policy headscale.ACLPolicy
|
||||
}{
|
||||
"ipv4": {
|
||||
policy: hscontrol.ACLPolicy{
|
||||
ACLs: []hscontrol.ACL{
|
||||
policy: headscale.ACLPolicy{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"100.64.0.1"},
|
||||
@@ -868,8 +868,8 @@ func TestACLDevice1CanAccessDevice2(t *testing.T) {
|
||||
},
|
||||
},
|
||||
"ipv6": {
|
||||
policy: hscontrol.ACLPolicy{
|
||||
ACLs: []hscontrol.ACL{
|
||||
policy: headscale.ACLPolicy{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"fd7a:115c:a1e0::1"},
|
||||
@@ -879,12 +879,12 @@ func TestACLDevice1CanAccessDevice2(t *testing.T) {
|
||||
},
|
||||
},
|
||||
"hostv4cidr": {
|
||||
policy: hscontrol.ACLPolicy{
|
||||
Hosts: hscontrol.Hosts{
|
||||
policy: headscale.ACLPolicy{
|
||||
Hosts: headscale.Hosts{
|
||||
"test1": netip.MustParsePrefix("100.64.0.1/32"),
|
||||
"test2": netip.MustParsePrefix("100.64.0.2/32"),
|
||||
},
|
||||
ACLs: []hscontrol.ACL{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"test1"},
|
||||
@@ -894,12 +894,12 @@ func TestACLDevice1CanAccessDevice2(t *testing.T) {
|
||||
},
|
||||
},
|
||||
"hostv6cidr": {
|
||||
policy: hscontrol.ACLPolicy{
|
||||
Hosts: hscontrol.Hosts{
|
||||
policy: headscale.ACLPolicy{
|
||||
Hosts: headscale.Hosts{
|
||||
"test1": netip.MustParsePrefix("fd7a:115c:a1e0::1/128"),
|
||||
"test2": netip.MustParsePrefix("fd7a:115c:a1e0::2/128"),
|
||||
},
|
||||
ACLs: []hscontrol.ACL{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"test1"},
|
||||
@@ -909,12 +909,12 @@ func TestACLDevice1CanAccessDevice2(t *testing.T) {
|
||||
},
|
||||
},
|
||||
"group": {
|
||||
policy: hscontrol.ACLPolicy{
|
||||
policy: headscale.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:one": {"user1"},
|
||||
"group:two": {"user2"},
|
||||
},
|
||||
ACLs: []hscontrol.ACL{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"group:one"},
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/juanfont/headscale"
|
||||
"github.com/juanfont/headscale/integration/dockertestutil"
|
||||
"github.com/juanfont/headscale/integration/hsic"
|
||||
"github.com/ory/dockertest/v3"
|
||||
@@ -213,14 +213,14 @@ func (s *AuthOIDCScenario) CreateHeadscaleEnv(
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *AuthOIDCScenario) runMockOIDC(accessTTL time.Duration) (*hscontrol.OIDCConfig, error) {
|
||||
func (s *AuthOIDCScenario) runMockOIDC(accessTTL time.Duration) (*headscale.OIDCConfig, error) {
|
||||
port, err := dockertestutil.RandomFreeHostPort()
|
||||
if err != nil {
|
||||
log.Fatalf("could not find an open port: %s", err)
|
||||
}
|
||||
portNotation := fmt.Sprintf("%d/tcp", port)
|
||||
|
||||
hash, _ := hscontrol.GenerateRandomStringDNSSafe(hsicOIDCMockHashLength)
|
||||
hash, _ := headscale.GenerateRandomStringDNSSafe(hsicOIDCMockHashLength)
|
||||
|
||||
hostname := fmt.Sprintf("hs-oidcmock-%s", hash)
|
||||
|
||||
@@ -287,7 +287,7 @@ func (s *AuthOIDCScenario) runMockOIDC(accessTTL time.Duration) (*hscontrol.OIDC
|
||||
|
||||
log.Printf("headscale mock oidc is ready for tests at %s", hostEndpoint)
|
||||
|
||||
return &hscontrol.OIDCConfig{
|
||||
return &headscale.OIDCConfig{
|
||||
Issuer: fmt.Sprintf(
|
||||
"http://%s/oidc",
|
||||
net.JoinHostPort(s.mockOIDC.GetIPInNetwork(s.network), strconv.Itoa(port)),
|
||||
|
||||
@@ -532,989 +532,3 @@ func TestEnablingRoutes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestApiKeyCommand(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
t.Parallel()
|
||||
|
||||
count := 5
|
||||
|
||||
scenario, err := NewScenario()
|
||||
assert.NoError(t, err)
|
||||
|
||||
spec := map[string]int{
|
||||
"user1": 0,
|
||||
"user2": 0,
|
||||
}
|
||||
|
||||
err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("clins"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
headscale, err := scenario.Headscale()
|
||||
assert.NoError(t, err)
|
||||
|
||||
keys := make([]string, count)
|
||||
|
||||
for idx := 0; idx < count; idx++ {
|
||||
apiResult, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"apikeys",
|
||||
"create",
|
||||
"--expiration",
|
||||
"24h",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
assert.NotEmpty(t, apiResult)
|
||||
|
||||
keys[idx] = apiResult
|
||||
}
|
||||
|
||||
assert.Len(t, keys, 5)
|
||||
|
||||
var listedAPIKeys []v1.ApiKey
|
||||
err = executeAndUnmarshal(headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"apikeys",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&listedAPIKeys,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Len(t, listedAPIKeys, 5)
|
||||
|
||||
assert.Equal(t, uint64(1), listedAPIKeys[0].Id)
|
||||
assert.Equal(t, uint64(2), listedAPIKeys[1].Id)
|
||||
assert.Equal(t, uint64(3), listedAPIKeys[2].Id)
|
||||
assert.Equal(t, uint64(4), listedAPIKeys[3].Id)
|
||||
assert.Equal(t, uint64(5), listedAPIKeys[4].Id)
|
||||
|
||||
assert.NotEmpty(t, listedAPIKeys[0].Prefix)
|
||||
assert.NotEmpty(t, listedAPIKeys[1].Prefix)
|
||||
assert.NotEmpty(t, listedAPIKeys[2].Prefix)
|
||||
assert.NotEmpty(t, listedAPIKeys[3].Prefix)
|
||||
assert.NotEmpty(t, listedAPIKeys[4].Prefix)
|
||||
|
||||
assert.True(t, listedAPIKeys[0].Expiration.AsTime().After(time.Now()))
|
||||
assert.True(t, listedAPIKeys[1].Expiration.AsTime().After(time.Now()))
|
||||
assert.True(t, listedAPIKeys[2].Expiration.AsTime().After(time.Now()))
|
||||
assert.True(t, listedAPIKeys[3].Expiration.AsTime().After(time.Now()))
|
||||
assert.True(t, listedAPIKeys[4].Expiration.AsTime().After(time.Now()))
|
||||
|
||||
assert.True(
|
||||
t,
|
||||
listedAPIKeys[0].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)),
|
||||
)
|
||||
assert.True(
|
||||
t,
|
||||
listedAPIKeys[1].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)),
|
||||
)
|
||||
assert.True(
|
||||
t,
|
||||
listedAPIKeys[2].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)),
|
||||
)
|
||||
assert.True(
|
||||
t,
|
||||
listedAPIKeys[3].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)),
|
||||
)
|
||||
assert.True(
|
||||
t,
|
||||
listedAPIKeys[4].Expiration.AsTime().Before(time.Now().Add(time.Hour*26)),
|
||||
)
|
||||
|
||||
expiredPrefixes := make(map[string]bool)
|
||||
|
||||
// Expire three keys
|
||||
for idx := 0; idx < 3; idx++ {
|
||||
_, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"apikeys",
|
||||
"expire",
|
||||
"--prefix",
|
||||
listedAPIKeys[idx].Prefix,
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
expiredPrefixes[listedAPIKeys[idx].Prefix] = true
|
||||
}
|
||||
|
||||
var listedAfterExpireAPIKeys []v1.ApiKey
|
||||
err = executeAndUnmarshal(headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"apikeys",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&listedAfterExpireAPIKeys,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
for index := range listedAfterExpireAPIKeys {
|
||||
if _, ok := expiredPrefixes[listedAfterExpireAPIKeys[index].Prefix]; ok {
|
||||
// Expired
|
||||
assert.True(
|
||||
t,
|
||||
listedAfterExpireAPIKeys[index].Expiration.AsTime().Before(time.Now()),
|
||||
)
|
||||
} else {
|
||||
// Not expired
|
||||
assert.False(
|
||||
t,
|
||||
listedAfterExpireAPIKeys[index].Expiration.AsTime().Before(time.Now()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
err = scenario.Shutdown()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestNodeTagCommand(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
t.Parallel()
|
||||
|
||||
scenario, err := NewScenario()
|
||||
assert.NoError(t, err)
|
||||
|
||||
spec := map[string]int{
|
||||
"user1": 0,
|
||||
}
|
||||
|
||||
err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("clins"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
headscale, err := scenario.Headscale()
|
||||
assert.NoError(t, err)
|
||||
|
||||
machineKeys := []string{
|
||||
"nodekey:9b2ffa7e08cc421a3d2cca9012280f6a236fd0de0b4ce005b30a98ad930306fe",
|
||||
"nodekey:6abd00bb5fdda622db51387088c68e97e71ce58e7056aa54f592b6a8219d524c",
|
||||
}
|
||||
machines := make([]*v1.Machine, len(machineKeys))
|
||||
assert.Nil(t, err)
|
||||
|
||||
for index, machineKey := range machineKeys {
|
||||
_, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"debug",
|
||||
"create-node",
|
||||
"--name",
|
||||
fmt.Sprintf("machine-%d", index+1),
|
||||
"--user",
|
||||
"user1",
|
||||
"--key",
|
||||
machineKey,
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
var machine v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"--user",
|
||||
"user1",
|
||||
"register",
|
||||
"--key",
|
||||
machineKey,
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&machine,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
machines[index] = &machine
|
||||
}
|
||||
assert.Len(t, machines, len(machineKeys))
|
||||
|
||||
var machine v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"tag",
|
||||
"-i", "1",
|
||||
"-t", "tag:test",
|
||||
"--output", "json",
|
||||
},
|
||||
&machine,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, []string{"tag:test"}, machine.ForcedTags)
|
||||
|
||||
// try to set a wrong tag and retrieve the error
|
||||
type errOutput struct {
|
||||
Error string `json:"error"`
|
||||
}
|
||||
var errorOutput errOutput
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"tag",
|
||||
"-i", "2",
|
||||
"-t", "wrong-tag",
|
||||
"--output", "json",
|
||||
},
|
||||
&errorOutput,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
assert.Contains(t, errorOutput.Error, "tag must start with the string 'tag:'")
|
||||
|
||||
// Test list all nodes after added seconds
|
||||
resultMachines := make([]*v1.Machine, len(machineKeys))
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"list",
|
||||
"--output", "json",
|
||||
},
|
||||
&resultMachines,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
found := false
|
||||
for _, machine := range resultMachines {
|
||||
if machine.ForcedTags != nil {
|
||||
for _, tag := range machine.ForcedTags {
|
||||
if tag == "tag:test" {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert.Equal(
|
||||
t,
|
||||
true,
|
||||
found,
|
||||
"should find a machine with the tag 'tag:test' in the list of machines",
|
||||
)
|
||||
|
||||
err = scenario.Shutdown()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestNodeCommand(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
t.Parallel()
|
||||
|
||||
scenario, err := NewScenario()
|
||||
assert.NoError(t, err)
|
||||
|
||||
spec := map[string]int{
|
||||
"machine-user": 0,
|
||||
"other-user": 0,
|
||||
}
|
||||
|
||||
err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("clins"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
headscale, err := scenario.Headscale()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Randomly generated machine keys
|
||||
machineKeys := []string{
|
||||
"nodekey:9b2ffa7e08cc421a3d2cca9012280f6a236fd0de0b4ce005b30a98ad930306fe",
|
||||
"nodekey:6abd00bb5fdda622db51387088c68e97e71ce58e7056aa54f592b6a8219d524c",
|
||||
"nodekey:f08305b4ee4250b95a70f3b7504d048d75d899993c624a26d422c67af0422507",
|
||||
"nodekey:8bc13285cee598acf76b1824a6f4490f7f2e3751b201e28aeb3b07fe81d5b4a1",
|
||||
"nodekey:cf7b0fd05da556fdc3bab365787b506fd82d64a70745db70e00e86c1b1c03084",
|
||||
}
|
||||
machines := make([]*v1.Machine, len(machineKeys))
|
||||
assert.Nil(t, err)
|
||||
|
||||
for index, machineKey := range machineKeys {
|
||||
_, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"debug",
|
||||
"create-node",
|
||||
"--name",
|
||||
fmt.Sprintf("machine-%d", index+1),
|
||||
"--user",
|
||||
"machine-user",
|
||||
"--key",
|
||||
machineKey,
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
var machine v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"--user",
|
||||
"machine-user",
|
||||
"register",
|
||||
"--key",
|
||||
machineKey,
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&machine,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
machines[index] = &machine
|
||||
}
|
||||
|
||||
assert.Len(t, machines, len(machineKeys))
|
||||
|
||||
// Test list all nodes after added seconds
|
||||
var listAll []v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&listAll,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Len(t, listAll, 5)
|
||||
|
||||
assert.Equal(t, uint64(1), listAll[0].Id)
|
||||
assert.Equal(t, uint64(2), listAll[1].Id)
|
||||
assert.Equal(t, uint64(3), listAll[2].Id)
|
||||
assert.Equal(t, uint64(4), listAll[3].Id)
|
||||
assert.Equal(t, uint64(5), listAll[4].Id)
|
||||
|
||||
assert.Equal(t, "machine-1", listAll[0].Name)
|
||||
assert.Equal(t, "machine-2", listAll[1].Name)
|
||||
assert.Equal(t, "machine-3", listAll[2].Name)
|
||||
assert.Equal(t, "machine-4", listAll[3].Name)
|
||||
assert.Equal(t, "machine-5", listAll[4].Name)
|
||||
|
||||
otherUserMachineKeys := []string{
|
||||
"nodekey:b5b444774186d4217adcec407563a1223929465ee2c68a4da13af0d0185b4f8e",
|
||||
"nodekey:dc721977ac7415aafa87f7d4574cbe07c6b171834a6d37375782bdc1fb6b3584",
|
||||
}
|
||||
otherUserMachines := make([]*v1.Machine, len(otherUserMachineKeys))
|
||||
assert.Nil(t, err)
|
||||
|
||||
for index, machineKey := range otherUserMachineKeys {
|
||||
_, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"debug",
|
||||
"create-node",
|
||||
"--name",
|
||||
fmt.Sprintf("otherUser-machine-%d", index+1),
|
||||
"--user",
|
||||
"other-user",
|
||||
"--key",
|
||||
machineKey,
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
var machine v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"--user",
|
||||
"other-user",
|
||||
"register",
|
||||
"--key",
|
||||
machineKey,
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&machine,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
otherUserMachines[index] = &machine
|
||||
}
|
||||
|
||||
assert.Len(t, otherUserMachines, len(otherUserMachineKeys))
|
||||
|
||||
// Test list all nodes after added otherUser
|
||||
var listAllWithotherUser []v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&listAllWithotherUser,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// All nodes, machines + otherUser
|
||||
assert.Len(t, listAllWithotherUser, 7)
|
||||
|
||||
assert.Equal(t, uint64(6), listAllWithotherUser[5].Id)
|
||||
assert.Equal(t, uint64(7), listAllWithotherUser[6].Id)
|
||||
|
||||
assert.Equal(t, "otherUser-machine-1", listAllWithotherUser[5].Name)
|
||||
assert.Equal(t, "otherUser-machine-2", listAllWithotherUser[6].Name)
|
||||
|
||||
// Test list all nodes after added otherUser
|
||||
var listOnlyotherUserMachineUser []v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"list",
|
||||
"--user",
|
||||
"other-user",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&listOnlyotherUserMachineUser,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Len(t, listOnlyotherUserMachineUser, 2)
|
||||
|
||||
assert.Equal(t, uint64(6), listOnlyotherUserMachineUser[0].Id)
|
||||
assert.Equal(t, uint64(7), listOnlyotherUserMachineUser[1].Id)
|
||||
|
||||
assert.Equal(
|
||||
t,
|
||||
"otherUser-machine-1",
|
||||
listOnlyotherUserMachineUser[0].Name,
|
||||
)
|
||||
assert.Equal(
|
||||
t,
|
||||
"otherUser-machine-2",
|
||||
listOnlyotherUserMachineUser[1].Name,
|
||||
)
|
||||
|
||||
// Delete a machines
|
||||
_, err = headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"delete",
|
||||
"--identifier",
|
||||
// Delete the last added machine
|
||||
"4",
|
||||
"--output",
|
||||
"json",
|
||||
"--force",
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// Test: list main user after machine is deleted
|
||||
var listOnlyMachineUserAfterDelete []v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"list",
|
||||
"--user",
|
||||
"machine-user",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&listOnlyMachineUserAfterDelete,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Len(t, listOnlyMachineUserAfterDelete, 4)
|
||||
|
||||
err = scenario.Shutdown()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestNodeExpireCommand(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
t.Parallel()
|
||||
|
||||
scenario, err := NewScenario()
|
||||
assert.NoError(t, err)
|
||||
|
||||
spec := map[string]int{
|
||||
"machine-expire-user": 0,
|
||||
}
|
||||
|
||||
err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("clins"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
headscale, err := scenario.Headscale()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Randomly generated machine keys
|
||||
machineKeys := []string{
|
||||
"nodekey:9b2ffa7e08cc421a3d2cca9012280f6a236fd0de0b4ce005b30a98ad930306fe",
|
||||
"nodekey:6abd00bb5fdda622db51387088c68e97e71ce58e7056aa54f592b6a8219d524c",
|
||||
"nodekey:f08305b4ee4250b95a70f3b7504d048d75d899993c624a26d422c67af0422507",
|
||||
"nodekey:8bc13285cee598acf76b1824a6f4490f7f2e3751b201e28aeb3b07fe81d5b4a1",
|
||||
"nodekey:cf7b0fd05da556fdc3bab365787b506fd82d64a70745db70e00e86c1b1c03084",
|
||||
}
|
||||
machines := make([]*v1.Machine, len(machineKeys))
|
||||
|
||||
for index, machineKey := range machineKeys {
|
||||
_, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"debug",
|
||||
"create-node",
|
||||
"--name",
|
||||
fmt.Sprintf("machine-%d", index+1),
|
||||
"--user",
|
||||
"machine-expire-user",
|
||||
"--key",
|
||||
machineKey,
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
var machine v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"--user",
|
||||
"machine-expire-user",
|
||||
"register",
|
||||
"--key",
|
||||
machineKey,
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&machine,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
machines[index] = &machine
|
||||
}
|
||||
|
||||
assert.Len(t, machines, len(machineKeys))
|
||||
|
||||
var listAll []v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&listAll,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Len(t, listAll, 5)
|
||||
|
||||
assert.True(t, listAll[0].Expiry.AsTime().IsZero())
|
||||
assert.True(t, listAll[1].Expiry.AsTime().IsZero())
|
||||
assert.True(t, listAll[2].Expiry.AsTime().IsZero())
|
||||
assert.True(t, listAll[3].Expiry.AsTime().IsZero())
|
||||
assert.True(t, listAll[4].Expiry.AsTime().IsZero())
|
||||
|
||||
for idx := 0; idx < 3; idx++ {
|
||||
_, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"expire",
|
||||
"--identifier",
|
||||
fmt.Sprintf("%d", listAll[idx].Id),
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
var listAllAfterExpiry []v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&listAllAfterExpiry,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Len(t, listAllAfterExpiry, 5)
|
||||
|
||||
assert.True(t, listAllAfterExpiry[0].Expiry.AsTime().Before(time.Now()))
|
||||
assert.True(t, listAllAfterExpiry[1].Expiry.AsTime().Before(time.Now()))
|
||||
assert.True(t, listAllAfterExpiry[2].Expiry.AsTime().Before(time.Now()))
|
||||
assert.True(t, listAllAfterExpiry[3].Expiry.AsTime().IsZero())
|
||||
assert.True(t, listAllAfterExpiry[4].Expiry.AsTime().IsZero())
|
||||
|
||||
err = scenario.Shutdown()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestNodeRenameCommand(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
t.Parallel()
|
||||
|
||||
scenario, err := NewScenario()
|
||||
assert.NoError(t, err)
|
||||
|
||||
spec := map[string]int{
|
||||
"machine-rename-command": 0,
|
||||
}
|
||||
|
||||
err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("clins"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
headscale, err := scenario.Headscale()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Randomly generated machine keys
|
||||
machineKeys := []string{
|
||||
"nodekey:cf7b0fd05da556fdc3bab365787b506fd82d64a70745db70e00e86c1b1c03084",
|
||||
"nodekey:8bc13285cee598acf76b1824a6f4490f7f2e3751b201e28aeb3b07fe81d5b4a1",
|
||||
"nodekey:f08305b4ee4250b95a70f3b7504d048d75d899993c624a26d422c67af0422507",
|
||||
"nodekey:6abd00bb5fdda622db51387088c68e97e71ce58e7056aa54f592b6a8219d524c",
|
||||
"nodekey:9b2ffa7e08cc421a3d2cca9012280f6a236fd0de0b4ce005b30a98ad930306fe",
|
||||
}
|
||||
machines := make([]*v1.Machine, len(machineKeys))
|
||||
assert.Nil(t, err)
|
||||
|
||||
for index, machineKey := range machineKeys {
|
||||
_, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"debug",
|
||||
"create-node",
|
||||
"--name",
|
||||
fmt.Sprintf("machine-%d", index+1),
|
||||
"--user",
|
||||
"machine-rename-command",
|
||||
"--key",
|
||||
machineKey,
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
var machine v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"--user",
|
||||
"machine-rename-command",
|
||||
"register",
|
||||
"--key",
|
||||
machineKey,
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&machine,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
machines[index] = &machine
|
||||
}
|
||||
|
||||
assert.Len(t, machines, len(machineKeys))
|
||||
|
||||
var listAll []v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&listAll,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Len(t, listAll, 5)
|
||||
|
||||
assert.Contains(t, listAll[0].GetGivenName(), "machine-1")
|
||||
assert.Contains(t, listAll[1].GetGivenName(), "machine-2")
|
||||
assert.Contains(t, listAll[2].GetGivenName(), "machine-3")
|
||||
assert.Contains(t, listAll[3].GetGivenName(), "machine-4")
|
||||
assert.Contains(t, listAll[4].GetGivenName(), "machine-5")
|
||||
|
||||
for idx := 0; idx < 3; idx++ {
|
||||
_, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"rename",
|
||||
"--identifier",
|
||||
fmt.Sprintf("%d", listAll[idx].Id),
|
||||
fmt.Sprintf("newmachine-%d", idx+1),
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
var listAllAfterRename []v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&listAllAfterRename,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Len(t, listAllAfterRename, 5)
|
||||
|
||||
assert.Equal(t, "newmachine-1", listAllAfterRename[0].GetGivenName())
|
||||
assert.Equal(t, "newmachine-2", listAllAfterRename[1].GetGivenName())
|
||||
assert.Equal(t, "newmachine-3", listAllAfterRename[2].GetGivenName())
|
||||
assert.Contains(t, listAllAfterRename[3].GetGivenName(), "machine-4")
|
||||
assert.Contains(t, listAllAfterRename[4].GetGivenName(), "machine-5")
|
||||
|
||||
// Test failure for too long names
|
||||
result, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"rename",
|
||||
"--identifier",
|
||||
fmt.Sprintf("%d", listAll[4].Id),
|
||||
"testmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachine12345678901234567890",
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
assert.Contains(t, result, "not be over 63 chars")
|
||||
|
||||
var listAllAfterRenameAttempt []v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&listAllAfterRenameAttempt,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Len(t, listAllAfterRenameAttempt, 5)
|
||||
|
||||
assert.Equal(t, "newmachine-1", listAllAfterRenameAttempt[0].GetGivenName())
|
||||
assert.Equal(t, "newmachine-2", listAllAfterRenameAttempt[1].GetGivenName())
|
||||
assert.Equal(t, "newmachine-3", listAllAfterRenameAttempt[2].GetGivenName())
|
||||
assert.Contains(t, listAllAfterRenameAttempt[3].GetGivenName(), "machine-4")
|
||||
assert.Contains(t, listAllAfterRenameAttempt[4].GetGivenName(), "machine-5")
|
||||
|
||||
err = scenario.Shutdown()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestNodeMoveCommand(t *testing.T) {
|
||||
IntegrationSkip(t)
|
||||
t.Parallel()
|
||||
|
||||
scenario, err := NewScenario()
|
||||
assert.NoError(t, err)
|
||||
|
||||
spec := map[string]int{
|
||||
"old-user": 0,
|
||||
"new-user": 0,
|
||||
}
|
||||
|
||||
err = scenario.CreateHeadscaleEnv(spec, []tsic.Option{}, hsic.WithTestName("clins"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
headscale, err := scenario.Headscale()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Randomly generated machine key
|
||||
machineKey := "nodekey:688411b767663479632d44140f08a9fde87383adc7cdeb518f62ce28a17ef0aa"
|
||||
|
||||
_, err = headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"debug",
|
||||
"create-node",
|
||||
"--name",
|
||||
"nomad-machine",
|
||||
"--user",
|
||||
"old-user",
|
||||
"--key",
|
||||
machineKey,
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
var machine v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"--user",
|
||||
"old-user",
|
||||
"register",
|
||||
"--key",
|
||||
machineKey,
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&machine,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, uint64(1), machine.Id)
|
||||
assert.Equal(t, "nomad-machine", machine.Name)
|
||||
assert.Equal(t, machine.User.Name, "old-user")
|
||||
|
||||
machineID := fmt.Sprintf("%d", machine.Id)
|
||||
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"move",
|
||||
"--identifier",
|
||||
machineID,
|
||||
"--user",
|
||||
"new-user",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&machine,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, machine.User.Name, "new-user")
|
||||
|
||||
var allNodes []v1.Machine
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&allNodes,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Len(t, allNodes, 1)
|
||||
|
||||
assert.Equal(t, allNodes[0].Id, machine.Id)
|
||||
assert.Equal(t, allNodes[0].User, machine.User)
|
||||
assert.Equal(t, allNodes[0].User.Name, "new-user")
|
||||
|
||||
moveToNonExistingNSResult, err := headscale.Execute(
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"move",
|
||||
"--identifier",
|
||||
machineID,
|
||||
"--user",
|
||||
"non-existing-user",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Contains(
|
||||
t,
|
||||
moveToNonExistingNSResult,
|
||||
"User not found",
|
||||
)
|
||||
assert.Equal(t, machine.User.Name, "new-user")
|
||||
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"move",
|
||||
"--identifier",
|
||||
machineID,
|
||||
"--user",
|
||||
"old-user",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&machine,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, machine.User.Name, "old-user")
|
||||
|
||||
err = executeAndUnmarshal(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"move",
|
||||
"--identifier",
|
||||
machineID,
|
||||
"--user",
|
||||
"old-user",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
&machine,
|
||||
)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, machine.User.Name, "old-user")
|
||||
|
||||
err = scenario.Shutdown()
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/juanfont/headscale"
|
||||
"github.com/juanfont/headscale/integration/dockertestutil"
|
||||
"github.com/juanfont/headscale/integration/hsic"
|
||||
"github.com/juanfont/headscale/integration/tsic"
|
||||
@@ -110,7 +110,7 @@ func (s *EmbeddedDERPServerScenario) CreateHeadscaleEnv(
|
||||
return err
|
||||
}
|
||||
|
||||
hash, err := hscontrol.GenerateRandomStringDNSSafe(scenarioHashLength)
|
||||
hash, err := headscale.GenerateRandomStringDNSSafe(scenarioHashLength)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/juanfont/headscale"
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/juanfont/headscale/integration/dockertestutil"
|
||||
"github.com/juanfont/headscale/integration/integrationutil"
|
||||
"github.com/ory/dockertest/v3"
|
||||
@@ -59,7 +59,7 @@ type HeadscaleInContainer struct {
|
||||
port int
|
||||
extraPorts []string
|
||||
hostPortBindings map[string][]string
|
||||
aclPolicy *hscontrol.ACLPolicy
|
||||
aclPolicy *headscale.ACLPolicy
|
||||
env map[string]string
|
||||
tlsCert []byte
|
||||
tlsKey []byte
|
||||
@@ -70,9 +70,9 @@ type HeadscaleInContainer struct {
|
||||
// Headscale instance.
|
||||
type Option = func(c *HeadscaleInContainer)
|
||||
|
||||
// WithACLPolicy adds a hscontrol.ACLPolicy policy to the
|
||||
// WithACLPolicy adds a headscale.ACLPolicy policy to the
|
||||
// HeadscaleInContainer instance.
|
||||
func WithACLPolicy(acl *hscontrol.ACLPolicy) Option {
|
||||
func WithACLPolicy(acl *headscale.ACLPolicy) Option {
|
||||
return func(hsic *HeadscaleInContainer) {
|
||||
// TODO(kradalby): Move somewhere appropriate
|
||||
hsic.env["HEADSCALE_ACL_POLICY_PATH"] = aclPolicyPath
|
||||
@@ -132,7 +132,7 @@ func WithHostPortBindings(bindings map[string][]string) Option {
|
||||
// in the Docker container name.
|
||||
func WithTestName(testName string) Option {
|
||||
return func(hsic *HeadscaleInContainer) {
|
||||
hash, _ := hscontrol.GenerateRandomStringDNSSafe(hsicHashLength)
|
||||
hash, _ := headscale.GenerateRandomStringDNSSafe(hsicHashLength)
|
||||
|
||||
hostname := fmt.Sprintf("hs-%s-%s", testName, hash)
|
||||
hsic.hostname = hostname
|
||||
@@ -167,7 +167,7 @@ func New(
|
||||
network *dockertest.Network,
|
||||
opts ...Option,
|
||||
) (*HeadscaleInContainer, error) {
|
||||
hash, err := hscontrol.GenerateRandomStringDNSSafe(hsicHashLength)
|
||||
hash, err := headscale.GenerateRandomStringDNSSafe(hsicHashLength)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/juanfont/headscale"
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/juanfont/headscale/integration/dockertestutil"
|
||||
"github.com/juanfont/headscale/integration/hsic"
|
||||
"github.com/juanfont/headscale/integration/tsic"
|
||||
@@ -105,7 +105,7 @@ type Scenario struct {
|
||||
// NewScenario creates a test Scenario which can be used to bootstraps a ControlServer with
|
||||
// a set of Users and TailscaleClients.
|
||||
func NewScenario() (*Scenario, error) {
|
||||
hash, err := hscontrol.GenerateRandomStringDNSSafe(scenarioHashLength)
|
||||
hash, err := headscale.GenerateRandomStringDNSSafe(scenarioHashLength)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+16
-16
@@ -6,7 +6,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/juanfont/headscale"
|
||||
"github.com/juanfont/headscale/integration/hsic"
|
||||
"github.com/juanfont/headscale/integration/tsic"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -57,18 +57,18 @@ func TestSSHOneUserAllToAll(t *testing.T) {
|
||||
err = scenario.CreateHeadscaleEnv(spec,
|
||||
[]tsic.Option{tsic.WithSSH()},
|
||||
hsic.WithACLPolicy(
|
||||
&hscontrol.ACLPolicy{
|
||||
&headscale.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:integration-test": {"user1"},
|
||||
},
|
||||
ACLs: []hscontrol.ACL{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"*"},
|
||||
Destinations: []string{"*:*"},
|
||||
},
|
||||
},
|
||||
SSHs: []hscontrol.SSH{
|
||||
SSHs: []headscale.SSH{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"group:integration-test"},
|
||||
@@ -134,18 +134,18 @@ func TestSSHMultipleUsersAllToAll(t *testing.T) {
|
||||
err = scenario.CreateHeadscaleEnv(spec,
|
||||
[]tsic.Option{tsic.WithSSH()},
|
||||
hsic.WithACLPolicy(
|
||||
&hscontrol.ACLPolicy{
|
||||
&headscale.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:integration-test": {"user1", "user2"},
|
||||
},
|
||||
ACLs: []hscontrol.ACL{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"*"},
|
||||
Destinations: []string{"*:*"},
|
||||
},
|
||||
},
|
||||
SSHs: []hscontrol.SSH{
|
||||
SSHs: []headscale.SSH{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"group:integration-test"},
|
||||
@@ -216,18 +216,18 @@ func TestSSHNoSSHConfigured(t *testing.T) {
|
||||
err = scenario.CreateHeadscaleEnv(spec,
|
||||
[]tsic.Option{tsic.WithSSH()},
|
||||
hsic.WithACLPolicy(
|
||||
&hscontrol.ACLPolicy{
|
||||
&headscale.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:integration-test": {"user1"},
|
||||
},
|
||||
ACLs: []hscontrol.ACL{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"*"},
|
||||
Destinations: []string{"*:*"},
|
||||
},
|
||||
},
|
||||
SSHs: []hscontrol.SSH{},
|
||||
SSHs: []headscale.SSH{},
|
||||
},
|
||||
),
|
||||
hsic.WithTestName("sshnoneconfigured"),
|
||||
@@ -286,18 +286,18 @@ func TestSSHIsBlockedInACL(t *testing.T) {
|
||||
err = scenario.CreateHeadscaleEnv(spec,
|
||||
[]tsic.Option{tsic.WithSSH()},
|
||||
hsic.WithACLPolicy(
|
||||
&hscontrol.ACLPolicy{
|
||||
&headscale.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:integration-test": {"user1"},
|
||||
},
|
||||
ACLs: []hscontrol.ACL{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"*"},
|
||||
Destinations: []string{"*:80"},
|
||||
},
|
||||
},
|
||||
SSHs: []hscontrol.SSH{
|
||||
SSHs: []headscale.SSH{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"group:integration-test"},
|
||||
@@ -364,19 +364,19 @@ func TestSSUserOnlyIsolation(t *testing.T) {
|
||||
err = scenario.CreateHeadscaleEnv(spec,
|
||||
[]tsic.Option{tsic.WithSSH()},
|
||||
hsic.WithACLPolicy(
|
||||
&hscontrol.ACLPolicy{
|
||||
&headscale.ACLPolicy{
|
||||
Groups: map[string][]string{
|
||||
"group:ssh1": {"useracl1"},
|
||||
"group:ssh2": {"useracl2"},
|
||||
},
|
||||
ACLs: []hscontrol.ACL{
|
||||
ACLs: []headscale.ACL{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"*"},
|
||||
Destinations: []string{"*:*"},
|
||||
},
|
||||
},
|
||||
SSHs: []hscontrol.SSH{
|
||||
SSHs: []headscale.SSH{
|
||||
{
|
||||
Action: "accept",
|
||||
Sources: []string{"group:ssh1"},
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
"github.com/juanfont/headscale/hscontrol"
|
||||
"github.com/juanfont/headscale"
|
||||
"github.com/juanfont/headscale/integration/dockertestutil"
|
||||
"github.com/juanfont/headscale/integration/integrationutil"
|
||||
"github.com/ory/dockertest/v3"
|
||||
@@ -150,7 +150,7 @@ func New(
|
||||
network *dockertest.Network,
|
||||
opts ...Option,
|
||||
) (*TailscaleInContainer, error) {
|
||||
hash, err := hscontrol.GenerateRandomStringDNSSafe(tsicHashLength)
|
||||
hash, err := headscale.GenerateRandomStringDNSSafe(tsicHashLength)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,271 @@
|
||||
// nolint
|
||||
package headscale
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
|
||||
"github.com/ory/dockertest/v3"
|
||||
"github.com/ory/dockertest/v3/docker"
|
||||
)
|
||||
|
||||
const (
|
||||
headscaleNetwork = "headscale-test"
|
||||
headscaleHostname = "headscale"
|
||||
DOCKER_EXECUTE_TIMEOUT = 10 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
errEnvVarEmpty = errors.New("getenv: environment variable empty")
|
||||
|
||||
IpPrefix4 = netip.MustParsePrefix("100.64.0.0/10")
|
||||
IpPrefix6 = netip.MustParsePrefix("fd7a:115c:a1e0::/48")
|
||||
|
||||
tailscaleVersions = []string{
|
||||
"head",
|
||||
"unstable",
|
||||
"1.38.4",
|
||||
"1.36.2",
|
||||
"1.34.2",
|
||||
"1.32.3",
|
||||
"1.30.2",
|
||||
"1.28.0",
|
||||
"1.26.2",
|
||||
"1.24.2",
|
||||
"1.22.2",
|
||||
"1.20.4",
|
||||
"1.18.2",
|
||||
"1.16.2",
|
||||
"1.14.3",
|
||||
"1.12.3",
|
||||
}
|
||||
)
|
||||
|
||||
type ExecuteCommandConfig struct {
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
type ExecuteCommandOption func(*ExecuteCommandConfig) error
|
||||
|
||||
func ExecuteCommandTimeout(timeout time.Duration) ExecuteCommandOption {
|
||||
return ExecuteCommandOption(func(conf *ExecuteCommandConfig) error {
|
||||
conf.timeout = timeout
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func ExecuteCommand(
|
||||
resource *dockertest.Resource,
|
||||
cmd []string,
|
||||
env []string,
|
||||
options ...ExecuteCommandOption,
|
||||
) (string, string, error) {
|
||||
var stdout bytes.Buffer
|
||||
var stderr bytes.Buffer
|
||||
|
||||
execConfig := ExecuteCommandConfig{
|
||||
timeout: DOCKER_EXECUTE_TIMEOUT,
|
||||
}
|
||||
|
||||
for _, opt := range options {
|
||||
if err := opt(&execConfig); err != nil {
|
||||
return "", "", fmt.Errorf("execute-command/options: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
type result struct {
|
||||
exitCode int
|
||||
err error
|
||||
}
|
||||
|
||||
resultChan := make(chan result, 1)
|
||||
|
||||
// Run your long running function in it's own goroutine and pass back it's
|
||||
// response into our channel.
|
||||
go func() {
|
||||
exitCode, err := resource.Exec(
|
||||
cmd,
|
||||
dockertest.ExecOptions{
|
||||
Env: append(env, "HEADSCALE_LOG_LEVEL=disabled"),
|
||||
StdOut: &stdout,
|
||||
StdErr: &stderr,
|
||||
},
|
||||
)
|
||||
resultChan <- result{exitCode, err}
|
||||
}()
|
||||
|
||||
// Listen on our channel AND a timeout channel - which ever happens first.
|
||||
select {
|
||||
case res := <-resultChan:
|
||||
if res.err != nil {
|
||||
return stdout.String(), stderr.String(), res.err
|
||||
}
|
||||
|
||||
if res.exitCode != 0 {
|
||||
fmt.Println("Command: ", cmd)
|
||||
fmt.Println("stdout: ", stdout.String())
|
||||
fmt.Println("stderr: ", stderr.String())
|
||||
|
||||
return stdout.String(), stderr.String(), fmt.Errorf(
|
||||
"command failed with: %s",
|
||||
stderr.String(),
|
||||
)
|
||||
}
|
||||
|
||||
return stdout.String(), stderr.String(), nil
|
||||
case <-time.After(execConfig.timeout):
|
||||
|
||||
return stdout.String(), stderr.String(), fmt.Errorf(
|
||||
"command timed out after %s",
|
||||
execConfig.timeout,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func DockerRestartPolicy(config *docker.HostConfig) {
|
||||
// set AutoRemove to true so that stopped container goes away by itself on error *immediately*.
|
||||
// when set to false, containers remain until the end of the integration test.
|
||||
config.AutoRemove = false
|
||||
config.RestartPolicy = docker.RestartPolicy{
|
||||
Name: "no",
|
||||
}
|
||||
}
|
||||
|
||||
func DockerAllowLocalIPv6(config *docker.HostConfig) {
|
||||
if config.Sysctls == nil {
|
||||
config.Sysctls = make(map[string]string, 1)
|
||||
}
|
||||
config.Sysctls["net.ipv6.conf.all.disable_ipv6"] = "0"
|
||||
}
|
||||
|
||||
func DockerAllowNetworkAdministration(config *docker.HostConfig) {
|
||||
config.CapAdd = append(config.CapAdd, "NET_ADMIN")
|
||||
config.Mounts = append(config.Mounts, docker.HostMount{
|
||||
Type: "bind",
|
||||
Source: "/dev/net/tun",
|
||||
Target: "/dev/net/tun",
|
||||
})
|
||||
}
|
||||
|
||||
func getDockerBuildOptions(version string) *dockertest.BuildOptions {
|
||||
var tailscaleBuildOptions *dockertest.BuildOptions
|
||||
switch version {
|
||||
case "head":
|
||||
tailscaleBuildOptions = &dockertest.BuildOptions{
|
||||
Dockerfile: "Dockerfile.tailscale-HEAD",
|
||||
ContextDir: ".",
|
||||
BuildArgs: []docker.BuildArg{},
|
||||
}
|
||||
case "unstable":
|
||||
tailscaleBuildOptions = &dockertest.BuildOptions{
|
||||
Dockerfile: "Dockerfile.tailscale",
|
||||
ContextDir: ".",
|
||||
BuildArgs: []docker.BuildArg{
|
||||
{
|
||||
Name: "TAILSCALE_VERSION",
|
||||
Value: "*", // Installs the latest version https://askubuntu.com/a/824926
|
||||
},
|
||||
{
|
||||
Name: "TAILSCALE_CHANNEL",
|
||||
Value: "unstable",
|
||||
},
|
||||
},
|
||||
}
|
||||
default:
|
||||
tailscaleBuildOptions = &dockertest.BuildOptions{
|
||||
Dockerfile: "Dockerfile.tailscale",
|
||||
ContextDir: ".",
|
||||
BuildArgs: []docker.BuildArg{
|
||||
{
|
||||
Name: "TAILSCALE_VERSION",
|
||||
Value: version,
|
||||
},
|
||||
{
|
||||
Name: "TAILSCALE_CHANNEL",
|
||||
Value: "stable",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return tailscaleBuildOptions
|
||||
}
|
||||
|
||||
func getDNSNames(
|
||||
headscale *dockertest.Resource,
|
||||
) ([]string, error) {
|
||||
listAllResult, _, err := ExecuteCommand(
|
||||
headscale,
|
||||
[]string{
|
||||
"headscale",
|
||||
"nodes",
|
||||
"list",
|
||||
"--output",
|
||||
"json",
|
||||
},
|
||||
[]string{},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var listAll []v1.Machine
|
||||
err = json.Unmarshal([]byte(listAllResult), &listAll)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hostnames := make([]string, len(listAll))
|
||||
|
||||
for index := range listAll {
|
||||
hostnames[index] = listAll[index].GetGivenName()
|
||||
}
|
||||
|
||||
return hostnames, nil
|
||||
}
|
||||
|
||||
func GetEnvStr(key string) (string, error) {
|
||||
v := os.Getenv(key)
|
||||
if v == "" {
|
||||
return v, errEnvVarEmpty
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func GetEnvBool(key string) (bool, error) {
|
||||
s, err := GetEnvStr(key)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
v, err := strconv.ParseBool(s)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func GetFirstOrCreateNetwork(pool *dockertest.Pool, name string) (dockertest.Network, error) {
|
||||
networks, err := pool.NetworksByName(name)
|
||||
if err != nil || len(networks) == 0 {
|
||||
if _, err := pool.CreateNetwork(name); err == nil {
|
||||
// Create does not give us an updated version of the resource, so we need to
|
||||
// get it again.
|
||||
networks, err := pool.NetworksByName(name)
|
||||
if err != nil {
|
||||
return dockertest.Network{}, err
|
||||
}
|
||||
|
||||
return networks[0], nil
|
||||
}
|
||||
}
|
||||
|
||||
return networks[0], nil
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
derp.yaml
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
@@ -0,0 +1,56 @@
|
||||
acl_policy_path: ""
|
||||
cli:
|
||||
insecure: false
|
||||
timeout: 5s
|
||||
db_path: /tmp/integration_test_db.sqlite3
|
||||
db_ssl: false
|
||||
db_type: sqlite3
|
||||
derp:
|
||||
auto_update_enabled: false
|
||||
server:
|
||||
enabled: false
|
||||
stun:
|
||||
enabled: true
|
||||
update_frequency: 1m
|
||||
urls:
|
||||
- https://controlplane.tailscale.com/derpmap/default
|
||||
dns_config:
|
||||
override_local_dns: true
|
||||
base_domain: headscale.net
|
||||
domains: []
|
||||
magic_dns: true
|
||||
nameservers:
|
||||
- 127.0.0.11
|
||||
- 1.1.1.1
|
||||
ephemeral_node_inactivity_timeout: 30m
|
||||
node_update_check_interval: 10s
|
||||
grpc_allow_insecure: false
|
||||
grpc_listen_addr: :50443
|
||||
ip_prefixes:
|
||||
- fd7a:115c:a1e0::/48
|
||||
- 100.64.0.0/10
|
||||
listen_addr: 0.0.0.0:18080
|
||||
log:
|
||||
level: disabled
|
||||
format: text
|
||||
logtail:
|
||||
enabled: false
|
||||
metrics_listen_addr: 127.0.0.1:19090
|
||||
oidc:
|
||||
expiry: 180d
|
||||
only_start_if_oidc_is_available: true
|
||||
scope:
|
||||
- openid
|
||||
- profile
|
||||
- email
|
||||
strip_email_domain: true
|
||||
use_expiry_from_token: false
|
||||
private_key_path: private.key
|
||||
noise:
|
||||
private_key_path: noise_private.key
|
||||
server_url: http://headscale:18080
|
||||
tls_letsencrypt_cache_dir: /var/www/.cache
|
||||
tls_letsencrypt_challenge_type: HTTP-01
|
||||
unix_socket: /var/run/headscale.sock
|
||||
unix_socket_permission: "0o770"
|
||||
randomize_client_port: false
|
||||
@@ -0,0 +1,31 @@
|
||||
log:
|
||||
level: trace
|
||||
acl_policy_path: ""
|
||||
db_type: sqlite3
|
||||
ephemeral_node_inactivity_timeout: 30m
|
||||
node_update_check_interval: 10s
|
||||
ip_prefixes:
|
||||
- fd7a:115c:a1e0::/48
|
||||
- 100.64.0.0/10
|
||||
dns_config:
|
||||
override_local_dns: true
|
||||
base_domain: headscale.net
|
||||
magic_dns: true
|
||||
domains: []
|
||||
nameservers:
|
||||
- 127.0.0.11
|
||||
- 1.1.1.1
|
||||
db_path: /tmp/integration_test_db.sqlite3
|
||||
db_ssl: false
|
||||
private_key_path: private.key
|
||||
noise:
|
||||
private_key_path: noise_private.key
|
||||
listen_addr: 0.0.0.0:18080
|
||||
metrics_listen_addr: 127.0.0.1:19090
|
||||
server_url: http://headscale:18080
|
||||
|
||||
derp:
|
||||
urls:
|
||||
- https://controlplane.tailscale.com/derpmap/default
|
||||
auto_update_enabled: false
|
||||
update_frequency: 1m
|
||||
@@ -0,0 +1,55 @@
|
||||
acl_policy_path: ""
|
||||
cli:
|
||||
insecure: false
|
||||
timeout: 5s
|
||||
db_path: /tmp/integration_test_db.sqlite3
|
||||
db_ssl: false
|
||||
db_type: sqlite3
|
||||
derp:
|
||||
auto_update_enabled: false
|
||||
server:
|
||||
enabled: false
|
||||
stun:
|
||||
enabled: true
|
||||
update_frequency: 1m
|
||||
urls:
|
||||
- https://controlplane.tailscale.com/derpmap/default
|
||||
dns_config:
|
||||
override_local_dns: true
|
||||
base_domain: headscale.net
|
||||
domains: []
|
||||
magic_dns: true
|
||||
nameservers:
|
||||
- 1.1.1.1
|
||||
ephemeral_node_inactivity_timeout: 30m
|
||||
node_update_check_interval: 30s
|
||||
grpc_allow_insecure: false
|
||||
grpc_listen_addr: :50443
|
||||
ip_prefixes:
|
||||
- fd7a:115c:a1e0::/48
|
||||
- 100.64.0.0/10
|
||||
listen_addr: 0.0.0.0:18080
|
||||
log:
|
||||
level: disabled
|
||||
format: text
|
||||
logtail:
|
||||
enabled: false
|
||||
metrics_listen_addr: 127.0.0.1:19090
|
||||
oidc:
|
||||
expiry: 180d
|
||||
only_start_if_oidc_is_available: true
|
||||
scope:
|
||||
- openid
|
||||
- profile
|
||||
- email
|
||||
strip_email_domain: true
|
||||
use_expiry_from_token: false
|
||||
private_key_path: private.key
|
||||
noise:
|
||||
private_key_path: noise_private.key
|
||||
server_url: http://headscale:18080
|
||||
tls_letsencrypt_cache_dir: /var/www/.cache
|
||||
tls_letsencrypt_challenge_type: HTTP-01
|
||||
unix_socket: /var/run/headscale.sock
|
||||
unix_socket_permission: "0o770"
|
||||
randomize_client_port: false
|
||||
@@ -0,0 +1,30 @@
|
||||
log:
|
||||
level: trace
|
||||
acl_policy_path: ""
|
||||
db_type: sqlite3
|
||||
ephemeral_node_inactivity_timeout: 30m
|
||||
node_update_check_interval: 30s
|
||||
ip_prefixes:
|
||||
- fd7a:115c:a1e0::/48
|
||||
- 100.64.0.0/10
|
||||
dns_config:
|
||||
override_local_dns: true
|
||||
base_domain: headscale.net
|
||||
magic_dns: true
|
||||
domains: []
|
||||
nameservers:
|
||||
- 1.1.1.1
|
||||
db_path: /tmp/integration_test_db.sqlite3
|
||||
db_ssl: false
|
||||
private_key_path: private.key
|
||||
noise:
|
||||
private_key_path: noise_private.key
|
||||
listen_addr: 0.0.0.0:18080
|
||||
metrics_listen_addr: 127.0.0.1:19090
|
||||
server_url: http://headscale:18080
|
||||
|
||||
derp:
|
||||
urls:
|
||||
- https://controlplane.tailscale.com/derpmap/default
|
||||
auto_update_enabled: false
|
||||
update_frequency: 1m
|
||||
@@ -0,0 +1,56 @@
|
||||
acl_policy_path: ""
|
||||
cli:
|
||||
insecure: false
|
||||
timeout: 5s
|
||||
db_path: /tmp/integration_test_db.sqlite3
|
||||
db_ssl: false
|
||||
db_type: sqlite3
|
||||
derp:
|
||||
auto_update_enabled: false
|
||||
server:
|
||||
enabled: false
|
||||
stun:
|
||||
enabled: true
|
||||
update_frequency: 1m
|
||||
urls:
|
||||
- https://controlplane.tailscale.com/derpmap/default
|
||||
dns_config:
|
||||
override_local_dns: true
|
||||
base_domain: headscale.net
|
||||
domains: []
|
||||
magic_dns: true
|
||||
nameservers:
|
||||
- 127.0.0.11
|
||||
- 1.1.1.1
|
||||
ephemeral_node_inactivity_timeout: 30m
|
||||
node_update_check_interval: 10s
|
||||
grpc_allow_insecure: false
|
||||
grpc_listen_addr: :50443
|
||||
ip_prefixes:
|
||||
- fd7a:115c:a1e0::/48
|
||||
- 100.64.0.0/10
|
||||
listen_addr: 0.0.0.0:8080
|
||||
log:
|
||||
format: text
|
||||
level: disabled
|
||||
logtail:
|
||||
enabled: false
|
||||
metrics_listen_addr: 127.0.0.1:9090
|
||||
oidc:
|
||||
expiry: 180d
|
||||
only_start_if_oidc_is_available: true
|
||||
scope:
|
||||
- openid
|
||||
- profile
|
||||
- email
|
||||
strip_email_domain: true
|
||||
use_expiry_from_token: false
|
||||
private_key_path: private.key
|
||||
noise:
|
||||
private_key_path: noise_private.key
|
||||
server_url: http://headscale:8080
|
||||
tls_letsencrypt_cache_dir: /var/www/.cache
|
||||
tls_letsencrypt_challenge_type: HTTP-01
|
||||
unix_socket: /var/run/headscale.sock
|
||||
unix_socket_permission: "0o770"
|
||||
randomize_client_port: false
|
||||
@@ -0,0 +1,30 @@
|
||||
log:
|
||||
level: trace
|
||||
acl_policy_path: ""
|
||||
db_type: sqlite3
|
||||
ephemeral_node_inactivity_timeout: 30m
|
||||
node_update_check_interval: 10s
|
||||
ip_prefixes:
|
||||
- fd7a:115c:a1e0::/48
|
||||
- 100.64.0.0/10
|
||||
dns_config:
|
||||
override_local_dns: true
|
||||
base_domain: headscale.net
|
||||
magic_dns: true
|
||||
domains: []
|
||||
nameservers:
|
||||
- 127.0.0.11
|
||||
- 1.1.1.1
|
||||
db_path: /tmp/integration_test_db.sqlite3
|
||||
private_key_path: private.key
|
||||
noise:
|
||||
private_key_path: noise_private.key
|
||||
listen_addr: 0.0.0.0:8080
|
||||
metrics_listen_addr: 127.0.0.1:9090
|
||||
server_url: http://headscale:8080
|
||||
|
||||
derp:
|
||||
urls:
|
||||
- https://controlplane.tailscale.com/derpmap/default
|
||||
auto_update_enabled: false
|
||||
update_frequency: 1m
|
||||
@@ -0,0 +1,31 @@
|
||||
log_level: trace
|
||||
acl_policy_path: ""
|
||||
db_type: sqlite3
|
||||
ephemeral_node_inactivity_timeout: 30m
|
||||
node_update_check_interval: 10s
|
||||
ip_prefixes:
|
||||
- fd7a:115c:a1e0::/48
|
||||
- 100.64.0.0/10
|
||||
dns_config:
|
||||
base_domain: headscale.net
|
||||
magic_dns: true
|
||||
domains: []
|
||||
nameservers:
|
||||
- 1.1.1.1
|
||||
db_path: /tmp/integration_test_db.sqlite3
|
||||
private_key_path: private.key
|
||||
noise:
|
||||
private_key_path: noise_private.key
|
||||
listen_addr: 0.0.0.0:443
|
||||
server_url: https://headscale:443
|
||||
tls_cert_path: "/etc/headscale/tls/server.crt"
|
||||
tls_key_path: "/etc/headscale/tls/server.key"
|
||||
tls_client_auth_mode: disabled
|
||||
derp:
|
||||
server:
|
||||
enabled: true
|
||||
region_id: 999
|
||||
region_code: "headscale"
|
||||
region_name: "Headscale Embedded DERP"
|
||||
|
||||
stun_listen_addr: "0.0.0.0:3478"
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC8jCCAdqgAwIBAgIULbu+UbSTMG/LtxooLLh7BgSEyqEwDQYJKoZIhvcNAQEL
|
||||
BQAwFDESMBAGA1UEAwwJaGVhZHNjYWxlMCAXDTIyMDMwNTE2NDgwM1oYDzI1MjEx
|
||||
MTA0MTY0ODAzWjAUMRIwEAYDVQQDDAloZWFkc2NhbGUwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQDqcfpToLZUF0rlNwXkkt3lbyw4Cl4TJdx36o2PKaOK
|
||||
U+tze/IjRsCWeMwrcR1o9TNZcxsD+c2J48D1WATuQJlMeg+2UJXGaTGRKkkbPMy3
|
||||
5m7AFf/Q16UEOgm2NYjZaQ8faRGIMYURG/6sXmNeETJvBixpBev9yKJuVXgqHNS4
|
||||
NpEkNwdOCuAZXrmw0HCbiusawJOay4tFvhH14rav8Uimonl8UTNVXufMzyUOuoaQ
|
||||
TGflmzYX3hIoswRnTPlIWFoqObvx2Q8H+of3uQJXy0m8I6OrIoXLNxnqYMfFls79
|
||||
9SYgVc2jPsCbh5fwyRbx2Hof7sIZ1K/mNgxJRG1E3ZiLAgMBAAGjOjA4MBQGA1Ud
|
||||
EQQNMAuCCWhlYWRzY2FsZTALBgNVHQ8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUH
|
||||
AwEwDQYJKoZIhvcNAQELBQADggEBANGlVN7NCsJaKz0k0nhlRGK+tcxn2p1PXN/i
|
||||
Iy+JX8ahixPC4ocRwOhrXgb390ZXLLwq08HrWYRB/Wi1VUzCp5d8dVxvrR43dJ+v
|
||||
L2EOBiIKgcu2C3pWW1qRR46/EoXUU9kSH2VNBvIhNufi32kEOidoDzxtQf6qVCoF
|
||||
guUt1JkAqrynv1UvR/2ZRM/WzM/oJ8qfECwrwDxyYhkqU5Z5jCWg0C6kPIBvNdzt
|
||||
B0eheWS+ZxVwkePTR4e17kIafwknth3lo+orxVrq/xC+OVM1bGrt2ZyD64ZvEqQl
|
||||
w6kgbzBdLScAQptWOFThwhnJsg0UbYKimZsnYmjVEuN59TJv92M=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
(Expires on Nov 4 16:48:03 2521 GMT)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDqcfpToLZUF0rl
|
||||
NwXkkt3lbyw4Cl4TJdx36o2PKaOKU+tze/IjRsCWeMwrcR1o9TNZcxsD+c2J48D1
|
||||
WATuQJlMeg+2UJXGaTGRKkkbPMy35m7AFf/Q16UEOgm2NYjZaQ8faRGIMYURG/6s
|
||||
XmNeETJvBixpBev9yKJuVXgqHNS4NpEkNwdOCuAZXrmw0HCbiusawJOay4tFvhH1
|
||||
4rav8Uimonl8UTNVXufMzyUOuoaQTGflmzYX3hIoswRnTPlIWFoqObvx2Q8H+of3
|
||||
uQJXy0m8I6OrIoXLNxnqYMfFls799SYgVc2jPsCbh5fwyRbx2Hof7sIZ1K/mNgxJ
|
||||
RG1E3ZiLAgMBAAECggEBALu1Ni/u5Qy++YA8ZcN0s6UXNdhItLmv/q0kZuLQ+9et
|
||||
CT8VZfFInLndTdsaXenDKLHdryunviFA8SV+q7P2lMbek+Xs735EiyMnMBFWxLIZ
|
||||
FWNGOeQERGL19QCmLEOmEi2b+iWJQHlKaMWpbPXL3w11a+lKjIBNO4ALfoJ5QveZ
|
||||
cGMKsJdm/mpqBvLeNeh2eAFk3Gp6sT1g80Ge8NkgyzFBNIqnut0eerM15kPTc6Qz
|
||||
12JLaOXUuV3PrcB4PN4nOwrTDg88GDNOQtc1Pc9r4nOHyLfr8X7QEtj1wXSwmOuK
|
||||
d6ynMnAmoxVA9wEnupLbil1bzohRzpsTpkmDruYaBEECgYEA/Z09I8D6mt2NVqIE
|
||||
KyvLjBK39ijSV9r3/lvB2Ple2OOL5YQEd+yTrIFy+3zdUnDgD1zmNnXjmjvHZ9Lc
|
||||
IFf2o06AF84QLNB5gLPdDQkGNFdDqUxljBrfAfE3oANmPS/B0SijMGOOOiDO2FtO
|
||||
xl1nfRr78mswuRs9awoUWCdNRKUCgYEA7KaTYKIQW/FEjw9lshp74q5vbn6zoXF5
|
||||
7N8VkwI+bBVNvRbM9XZ8qhfgRdu9eXs5oL/N4mSYY54I8fA//pJ0Z2vpmureMm1V
|
||||
mL5WBUmSD9DIbAchoK+sRiQhVmNMBQC6cHMABA7RfXvBeGvWrm9pKCS6ZLgLjkjp
|
||||
PsmAcaXQcW8CgYEA2inAxljjOwUK6FNGsrxhxIT1qtNC3kCGxE+6WSNq67gSR8Vg
|
||||
8qiX//T7LEslOB3RIGYRwxd2St7RkgZZRZllmOWWWuPwFhzf6E7RAL2akLvggGov
|
||||
kG4tGEagSw2hjVDfsUT73ExHtMk0Jfmlsg33UC8+PDLpHtLH6qQpDAwC8+ECgYEA
|
||||
o+AqOIWhvHmT11l7O915Ip1WzvZwYADbxLsrDnVEUsZh4epTHjvh0kvcY6PqTqCV
|
||||
ZIrOANNWb811Nkz/k8NJVoD08PFp0xPBbZeIq/qpachTsfMyRzq/mobUiyUR9Hjv
|
||||
ooUQYr78NOApNsG+lWbTNBhS9wI4BlzZIECbcJe5g4MCgYEAndRoy8S+S0Hx/S8a
|
||||
O3hzXeDmivmgWqn8NVD4AKOovpkz4PaIVVQbAQkiNfAx8/DavPvjEKAbDezJ4ECV
|
||||
j7IsOWtDVI7pd6eF9fTcECwisrda8aUoiOap8AQb48153Vx+g2N4Vy3uH0xJs4cz
|
||||
TDALZPOBg8VlV+HEFDP43sp9Bf0=
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -0,0 +1,21 @@
|
||||
log_level: trace
|
||||
acl_policy_path: ""
|
||||
db_type: sqlite3
|
||||
ephemeral_node_inactivity_timeout: 30m
|
||||
node_update_check_interval: 10s
|
||||
ip_prefixes:
|
||||
- fd7a:115c:a1e0::/48
|
||||
- 100.64.0.0/10
|
||||
db_path: /tmp/integration_test_db.sqlite3
|
||||
private_key_path: private.key
|
||||
noise:
|
||||
private_key_path: noise_private.key
|
||||
listen_addr: 0.0.0.0:8443
|
||||
server_url: https://headscale-oidc:8443
|
||||
tls_cert_path: "/etc/headscale/tls/server.crt"
|
||||
tls_key_path: "/etc/headscale/tls/server.key"
|
||||
derp:
|
||||
urls:
|
||||
- https://controlplane.tailscale.com/derpmap/default
|
||||
auto_update_enabled: true
|
||||
update_frequency: 1m
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC8jCCAdqgAwIBAgIULbu+UbSTMG/LtxooLLh7BgSEyqEwDQYJKoZIhvcNAQEL
|
||||
BQAwFDESMBAGA1UEAwwJaGVhZHNjYWxlMCAXDTIyMDMwNTE2NDgwM1oYDzI1MjEx
|
||||
MTA0MTY0ODAzWjAUMRIwEAYDVQQDDAloZWFkc2NhbGUwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQDqcfpToLZUF0rlNwXkkt3lbyw4Cl4TJdx36o2PKaOK
|
||||
U+tze/IjRsCWeMwrcR1o9TNZcxsD+c2J48D1WATuQJlMeg+2UJXGaTGRKkkbPMy3
|
||||
5m7AFf/Q16UEOgm2NYjZaQ8faRGIMYURG/6sXmNeETJvBixpBev9yKJuVXgqHNS4
|
||||
NpEkNwdOCuAZXrmw0HCbiusawJOay4tFvhH14rav8Uimonl8UTNVXufMzyUOuoaQ
|
||||
TGflmzYX3hIoswRnTPlIWFoqObvx2Q8H+of3uQJXy0m8I6OrIoXLNxnqYMfFls79
|
||||
9SYgVc2jPsCbh5fwyRbx2Hof7sIZ1K/mNgxJRG1E3ZiLAgMBAAGjOjA4MBQGA1Ud
|
||||
EQQNMAuCCWhlYWRzY2FsZTALBgNVHQ8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUH
|
||||
AwEwDQYJKoZIhvcNAQELBQADggEBANGlVN7NCsJaKz0k0nhlRGK+tcxn2p1PXN/i
|
||||
Iy+JX8ahixPC4ocRwOhrXgb390ZXLLwq08HrWYRB/Wi1VUzCp5d8dVxvrR43dJ+v
|
||||
L2EOBiIKgcu2C3pWW1qRR46/EoXUU9kSH2VNBvIhNufi32kEOidoDzxtQf6qVCoF
|
||||
guUt1JkAqrynv1UvR/2ZRM/WzM/oJ8qfECwrwDxyYhkqU5Z5jCWg0C6kPIBvNdzt
|
||||
B0eheWS+ZxVwkePTR4e17kIafwknth3lo+orxVrq/xC+OVM1bGrt2ZyD64ZvEqQl
|
||||
w6kgbzBdLScAQptWOFThwhnJsg0UbYKimZsnYmjVEuN59TJv92M=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
(Expires on Nov 4 16:48:03 2521 GMT)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDqcfpToLZUF0rl
|
||||
NwXkkt3lbyw4Cl4TJdx36o2PKaOKU+tze/IjRsCWeMwrcR1o9TNZcxsD+c2J48D1
|
||||
WATuQJlMeg+2UJXGaTGRKkkbPMy35m7AFf/Q16UEOgm2NYjZaQ8faRGIMYURG/6s
|
||||
XmNeETJvBixpBev9yKJuVXgqHNS4NpEkNwdOCuAZXrmw0HCbiusawJOay4tFvhH1
|
||||
4rav8Uimonl8UTNVXufMzyUOuoaQTGflmzYX3hIoswRnTPlIWFoqObvx2Q8H+of3
|
||||
uQJXy0m8I6OrIoXLNxnqYMfFls799SYgVc2jPsCbh5fwyRbx2Hof7sIZ1K/mNgxJ
|
||||
RG1E3ZiLAgMBAAECggEBALu1Ni/u5Qy++YA8ZcN0s6UXNdhItLmv/q0kZuLQ+9et
|
||||
CT8VZfFInLndTdsaXenDKLHdryunviFA8SV+q7P2lMbek+Xs735EiyMnMBFWxLIZ
|
||||
FWNGOeQERGL19QCmLEOmEi2b+iWJQHlKaMWpbPXL3w11a+lKjIBNO4ALfoJ5QveZ
|
||||
cGMKsJdm/mpqBvLeNeh2eAFk3Gp6sT1g80Ge8NkgyzFBNIqnut0eerM15kPTc6Qz
|
||||
12JLaOXUuV3PrcB4PN4nOwrTDg88GDNOQtc1Pc9r4nOHyLfr8X7QEtj1wXSwmOuK
|
||||
d6ynMnAmoxVA9wEnupLbil1bzohRzpsTpkmDruYaBEECgYEA/Z09I8D6mt2NVqIE
|
||||
KyvLjBK39ijSV9r3/lvB2Ple2OOL5YQEd+yTrIFy+3zdUnDgD1zmNnXjmjvHZ9Lc
|
||||
IFf2o06AF84QLNB5gLPdDQkGNFdDqUxljBrfAfE3oANmPS/B0SijMGOOOiDO2FtO
|
||||
xl1nfRr78mswuRs9awoUWCdNRKUCgYEA7KaTYKIQW/FEjw9lshp74q5vbn6zoXF5
|
||||
7N8VkwI+bBVNvRbM9XZ8qhfgRdu9eXs5oL/N4mSYY54I8fA//pJ0Z2vpmureMm1V
|
||||
mL5WBUmSD9DIbAchoK+sRiQhVmNMBQC6cHMABA7RfXvBeGvWrm9pKCS6ZLgLjkjp
|
||||
PsmAcaXQcW8CgYEA2inAxljjOwUK6FNGsrxhxIT1qtNC3kCGxE+6WSNq67gSR8Vg
|
||||
8qiX//T7LEslOB3RIGYRwxd2St7RkgZZRZllmOWWWuPwFhzf6E7RAL2akLvggGov
|
||||
kG4tGEagSw2hjVDfsUT73ExHtMk0Jfmlsg33UC8+PDLpHtLH6qQpDAwC8+ECgYEA
|
||||
o+AqOIWhvHmT11l7O915Ip1WzvZwYADbxLsrDnVEUsZh4epTHjvh0kvcY6PqTqCV
|
||||
ZIrOANNWb811Nkz/k8NJVoD08PFp0xPBbZeIq/qpachTsfMyRzq/mobUiyUR9Hjv
|
||||
ooUQYr78NOApNsG+lWbTNBhS9wI4BlzZIECbcJe5g4MCgYEAndRoy8S+S0Hx/S8a
|
||||
O3hzXeDmivmgWqn8NVD4AKOovpkz4PaIVVQbAQkiNfAx8/DavPvjEKAbDezJ4ECV
|
||||
j7IsOWtDVI7pd6eF9fTcECwisrda8aUoiOap8AQb48153Vx+g2N4Vy3uH0xJs4cz
|
||||
TDALZPOBg8VlV+HEFDP43sp9Bf0=
|
||||
-----END PRIVATE KEY-----
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user